TeacherControlPlugin.cs - изменения (улучшение регистрации - почти Release)

This commit is contained in:
Mikhalkovich Stanislav 2022-08-19 13:33:49 +03:00
parent 2b858c6246
commit 2ea7972bc4
9 changed files with 268 additions and 183 deletions

View file

@ -15,7 +15,7 @@ internal static class RevisionClass
public const string Major = "3";
public const string Minor = "8";
public const string Build = "3";
public const string Revision = "3158";
public const string Revision = "3159";
public const string MainVersion = Major + "." + Minor;
public const string FullVersion = Major + "." + Minor + "." + Build + "." + Revision;

View file

@ -1,4 +1,4 @@
%COREVERSION%=3
%REVISION%=3158
%MINOR%=8
%REVISION%=3159
%COREVERSION%=3
%MAJOR%=3

View file

@ -1 +1 @@
3.8.3.3158
3.8.3.3159

View file

@ -1 +1 @@
!define VERSION '3.8.3.3158'
!define VERSION '3.8.3.3159'

View file

@ -30,17 +30,11 @@ namespace DBAccessPluginNamespace
try
{
var encryptedstring = login + (char)10 + pass;
var encr = TeacherPluginUtils.Encrypt(encryptedstring);
using (var fs = new FileStream(filename, FileMode.Create))
var encr = TeacherPluginUtils.Encrypt(encryptedstring); // Здесь м.б. исключение
using (var fs = new FileStream(filename, FileMode.Create)) // Здесь м.б. исключение
{
fs.Write(encr, 0, encr.Length);
}
// записать массив байт в бинарный файл
/*using (var sw = new System.IO.StreamWriter(filename))
{
sw.WriteLine(login);
sw.WriteLine(pass);
}*/
}
catch (Exception e)
{
@ -52,7 +46,7 @@ namespace DBAccessPluginNamespace
public bool IsRootDirectory(string path)
{
var isroot = false;
/*var isroot = false;
try
{
var full = Path.GetFullPath(path);
@ -64,7 +58,8 @@ namespace DBAccessPluginNamespace
{
Plugin.AddMessage(e);
}
return isroot;
return isroot;*/
return Directory.GetParent(path) == null;
}
public bool CalcParentDirectory(string path, out string parent)
@ -73,16 +68,14 @@ namespace DBAccessPluginNamespace
if (IsRootDirectory(path))
return false;
var hasparent = false;
try
{
var full = Path.GetFullPath(path);
parent = Directory.GetParent(full).FullName;
hasparent = true;
}
catch (Exception e)
{
Plugin.AddMessage(e);
}
var full = Path.GetFullPath(path);
var di = Directory.GetParent(full);
if (di != null)
parent = di.FullName;
hasparent = true;
return hasparent;
}
@ -96,7 +89,7 @@ namespace DBAccessPluginNamespace
// После этого перейти в корень диска и там создать этот файл
// SSM 11.08.22 При ручной авторизации - сохранение
// Мехмат: auth сохраняется в корень сетевого диска
// Мехмат: auth сохраняется в корень сетевого диска. Думаю, достаточно того же алгоритма что и дома!!!
// Дома: auth сохраняется в папке на уровень выше текущей. Если это невозможно, то в текущей папке.
// Если это диск C, то тоже не сохранять и тогда сохранять в текущей
@ -106,8 +99,11 @@ namespace DBAccessPluginNamespace
// это происходит тогда когда школьник смонтировал сетевой диск, но зашел в Паскаль по кнопке Пуск или с рабочего стола
// можно попробовать поискать сетевой диск
var AuthFileFullName = "";
if (Plugin.IsMechmath())
// Упрощаем. Дома сохраняем на уровень выше, а если нельзя или это корень, то в текущий
// На мехмате если в текущем есть lightpt.dat - сохраняем на уровень выше, а если нельзя или это корень, то в текущий
// Если в текущем нет lightpt.dat - сохраняем в корень первого сетевого диска
/*if (Plugin.IsMechmath)
{
// Найти корень сетевого диска
// Если сетевой - текущий, то в него (это как правило)
@ -117,7 +113,7 @@ namespace DBAccessPluginNamespace
bool b = false;
if (di.DriveType == System.IO.DriveType.Network)
{
var auth = System.IO.Path.Combine(root, "auth.dat");
var auth = Path.Combine(root, "auth.dat");
b = TryCreateAuthFile(auth, login, pass);
}
@ -125,13 +121,13 @@ namespace DBAccessPluginNamespace
if (!b) // Если не удалось записать
{
string authName = "";
foreach (var drive in System.IO.DriveInfo.GetDrives())
foreach (var drive in DriveInfo.GetDrives())
{
if (drive.DriveType != System.IO.DriveType.Network)
if (drive.DriveType != DriveType.Network)
continue;
// Проверять, что диск сетевой!!! Для несетевых - нет!
var auth = System.IO.Path.Combine(drive.Name, "auth.dat");
if (System.IO.File.Exists(auth))
var auth = Path.Combine(drive.Name, "auth.dat");
if (File.Exists(auth))
authName = auth;
}
b = TryCreateAuthFile(authName, login, pass);
@ -145,7 +141,7 @@ namespace DBAccessPluginNamespace
if (drive.DriveType != System.IO.DriveType.Network)
continue;
// Найти первый сетевой куда можно записать
b = TryCreateAuthFile(authName, login, pass);
b = TryCreateAuthFile(authName, login, pass); // тут ошибка!!!
if (b)
break;
}
@ -154,21 +150,17 @@ namespace DBAccessPluginNamespace
}
else // это домашний компьютер
{
//System.IO.Directory.GetParent
var workDir = Plugin.WorkingDirectory();
//Path.GetFullPath
///
// сохранить пароль в каталоге на уровень выше WorkingDir. Если это корни дисков или уровнем выше нельзя, то в текущем
//
//var auth = System.IO.Path.Combine(workDir, "auth.dat");
var b1 = CalcParentDirectory(workDir, out string parent);
bool b = false;
if (b1 && !IsRootDirectory(parent))
if (b1 && !IsRootDirectory(parent)) // IsRootDirectory - parent = null !!
{
// пытаемся в родительском
var auth = System.IO.Path.Combine(parent, "auth.dat");
var auth = Path.Combine(parent, "auth.dat");
b = TryCreateAuthFile(auth, login, pass);
if (b)
AuthFileFullName = auth; // Эта информация нигде не используется - только для тестирования
@ -176,11 +168,73 @@ namespace DBAccessPluginNamespace
if (!b)
{
// пытаемся в текущем. Если он корень - ну, человек так хотел
var auth = System.IO.Path.Combine(workDir, "auth.dat");
var auth = Path.Combine(workDir, "auth.dat");
b = TryCreateAuthFile(auth, login, pass);
if (b)
AuthFileFullName = auth; // Эта информация нигде не используется - только для тестирования
}
}*/
// ПО НОВОМУ SSM 19.08.22
var AuthFileFullName = "";
var workDir = Plugin.WorkingDirectory();
var parentDir = "";
var parentDirExists = false;
var parentIsRoot = true;
var fullworkDir = Path.GetFullPath(workDir);
var di = Directory.GetParent(fullworkDir);
if (di != null)
{
parentDir = di.FullName;
parentDirExists = true;
parentIsRoot = Directory.GetParent(parentDir) != null;
}
// На мехмате проверяем lightPT
var isLightPT = Plugin.IsLightPTInWorkingDirectiry();
// Первый вариант - в родительский или текущий
var authCreated = false;
// Если в текущем есть lightpt.dat то мехмат или не мехмат - пытаемся создать файл авторизации в родительском или в текущем
if (isLightPT)
{
// пытаемся создать в родительском
if (parentDirExists)
{
var auth = Path.Combine(parentDir, "auth.dat");
authCreated = TryCreateAuthFile(auth, login, pass);
if (authCreated)
AuthFileFullName = auth; // Эта информация нигде не используется - только для тестирования
}
// если не получилось, пытаемся создать в текущем
if (!authCreated)
{
var auth = Path.Combine(workDir, "auth.dat");
authCreated = TryCreateAuthFile(auth, login, pass);
if (authCreated)
AuthFileFullName = auth; // Эта информация нигде не используется - только для тестирования
}
}
// Бывает так, что auth файл не создался. Обычно это означает, что в текущем нет lightPT.
// Но может записать нельзя
// Тогда остается последняя возможность. Если это мехмат, то ищем сетевой диск и пишем в корень туда
if (!authCreated && Plugin.IsMechmath)
{
foreach (var drive in DriveInfo.GetDrives())
{
if (drive.DriveType != System.IO.DriveType.Network)
continue;
var auth = Path.Combine(drive.Name, "auth.dat");
// Найти первый сетевой куда можно записать
authCreated = TryCreateAuthFile(auth, login, pass);
if (authCreated)
{
AuthFileFullName = auth; // Эта информация нигде не используется - только для тестирования
break;
}
}
}
}
@ -247,6 +301,7 @@ namespace DBAccessPluginNamespace
if (Text.StartsWith("Авторизация: нет связи с сервером"))
Text = "Авторизация";
var answer = await SiteProvider.Login("", usersNamesBox.Text, passwordBox.Text);
if (answer == "Success")
{

View file

@ -37,7 +37,9 @@ namespace VisualPascalABCPlugins
public ToolStripMenuItem menuItem = null;
public ToolStripButton toolStripButton = null;
public string AuthFileFullName = "";
// public string AuthFileFullName = "";
public bool IsMechmath = System.Environment.MachineName.ToLower().StartsWith("mil8a-");
public VisualPascalABCPlugin_TeacherControlPlugin(IWorkbench Workbench)
{
@ -45,8 +47,6 @@ namespace VisualPascalABCPlugins
loginForm = new LoginForm(this);
this.Workbench = Workbench;
VisualEnvironmentCompiler = Workbench.VisualEnvironmentCompiler;
//Workbench.CompilerConsoleWindow.
//var tbitem = Workbench.MainForm.Controls.Find("", true);
// RegisterForm.VisualEnvironmentCompiler = VisualEnvironmentCompiler; // Пока форма регистрации никак не связана с компилятором
// Регистрация обработчика
@ -59,28 +59,6 @@ namespace VisualPascalABCPlugins
loginForm.ShowDialog(); // OK никогда не будет
}
public string FullAuthNameFromNETDisk()
{
string authName = "";
try
{
foreach (var drive in System.IO.DriveInfo.GetDrives())
{
if (drive.DriveType != System.IO.DriveType.Network)
continue;
// Проверять, что диск сетевой!!! Для несетевых - нет!
var auth = System.IO.Path.Combine(drive.Name, "auth.dat");
if (System.IO.File.Exists(auth))
authName = auth;
}
}
catch (Exception e)
{
AddMessage(e);
}
return authName;
}
public void AddMessage(string text)
{
Workbench.CompilerConsoleWindow.AddTextToCompilerMessages(text + Environment.NewLine);
@ -96,12 +74,19 @@ namespace VisualPascalABCPlugins
public string FullLightPTName()
{
var WorkingDir = WorkingDirectory();
var lightptname = System.IO.Path.Combine(WorkingDir, "lightpt.dat");
if (System.IO.File.Exists(lightptname))
var lightptname = Path.Combine(WorkingDir, "lightpt.dat");
if (File.Exists(lightptname))
return lightptname;
return "";
}
public bool IsLightPTInWorkingDirectiry()
{
var WorkingDir = WorkingDirectory();
var lightptname = Path.Combine(WorkingDir, "lightpt.dat");
return File.Exists(lightptname);
}
public /*async*/ void TryLogin(string login, string pass)
{
// Гасим все исключения
@ -119,7 +104,74 @@ namespace VisualPascalABCPlugins
}
}
public bool IsMechmath() => System.Environment.MachineName.ToLower().StartsWith("mil8a-");
public string FullAuthNameFromNETDisk()
{
var AuthFileFullName = "";
try
{
foreach (var drive in System.IO.DriveInfo.GetDrives())
{
if (drive.DriveType != System.IO.DriveType.Network)
continue;
// Проверять, что диск сетевой!!! Для несетевых - нет!
var auth = System.IO.Path.Combine(drive.Name, "auth.dat");
if (System.IO.File.Exists(auth))
AuthFileFullName = auth;
}
}
catch (Exception)
{ } // Тут исключение быть не может и даже если, то неинформативно
return AuthFileFullName;
}
public string FullAuthNameFromWorkingDirOrParent()
{
var AuthFileFullName = "";
try
{
var WorkingDir = WorkingDirectory();
var auth = Path.Combine(WorkingDir, "auth.dat");
var exists = false;
if (File.Exists(auth)) // искать auth в текущей папке. Если нет, то
exists = true;
else
{
auth = Path.Combine(WorkingDir, "..", "auth.dat"); // искать auth в папке на уровень выше
if (File.Exists(auth))
exists = true;
}
if (exists) // то в auth - его путь Преобразуем его в полный путь
{
var fi = new System.IO.FileInfo(auth);
AuthFileFullName = fi.FullName;
}
}
catch (Exception)
{ }
return AuthFileFullName;
}
public string CalcAuthFullName()
{
var AuthFileFullName = "";
// На мехмате - проверяю все диски на предмет существования в корне файла auth.dat
if (IsMechmath)
AuthFileFullName = FullAuthNameFromNETDisk();
else // Это домашний компьютер
AuthFileFullName = FullAuthNameFromWorkingDirOrParent();
return AuthFileFullName;
}
public void InitItems(List<IPluginGUIItem> MenuItems, List<IPluginGUIItem> ToolBarItems)
{
Item = new PluginGUIItem(StringsPrefix + "NAME", StringsPrefix + "DESCRIPTION", loginForm.PluginImage.Image, loginForm.PluginImage.BackColor, Execute);
MenuItems.Add(Item);
ToolBarItems.Add(Item);
}
public void GetGUI(List<IPluginGUIItem> MenuItems, List<IPluginGUIItem> ToolBarItems)
{
@ -131,115 +183,69 @@ namespace VisualPascalABCPlugins
// Find NET disk with auth.dat in root
// if not - return
//var WorkingDirectory = Workbench.VisualEnvironmentCompiler.Compiler.CompilerOptions.SourceFileDirectory;
var LightPTExists = false;
var AuthExists = false;
try
{
// Только на мехмате - проверяю все диски на предмет существования в корне файла auth.dat
if (IsMechmath())
AuthFileFullName = FullAuthNameFromNETDisk();
LightPTExists = FullLightPTName() != "";
AuthExists = AuthFileFullName != "";
}
catch (Exception)
{
// Погасили исключение
}
// При запуске иконка плагина показывается
// Мехмат: при наличии auth.dat в корне сетевого диска или при наличии lightpt в текущей папке !!!
// Дома: всегда у тех, у кого установлен плагин
// При запуске auth.dat ищется
// Мехмат: в корне сетевого диска (только!). Если находится, делается попытка авторизации
// Дома: в текущей папке. Если нет, ищется в папке на уровень выше. Если находится, делается попытка авторизации
// При ручной авторизации - сохранение
// Мехмат: auth сохраняется в корень сетевого диска
// Дома: auth сохраняется в папке на уровень выше текущей. Если это невозможно, то в текущей папке.
// Если это диск C, то тоже не сохранять и тогда сохранять в текущей
// Мехмат: auth сохраняется в корень сетевого диска
// Дома: auth сохраняется в папке на уровень выше текущей. Если это невозможно, то в текущей папке.
// Если это диск C, то тоже не сохранять и тогда сохранять в текущей
if (
(IsMechmath() && (LightPTExists || AuthExists)) ||
!IsMechmath() // дома - всегда
)
// При запуске кнопки плагина показываются
// Дома: всегда у тех, у кого установлен плагин
// Мехмат: при наличии lightpt в текущей папке или при наличии auth.dat в корне сетевого диска !!!
if (!IsMechmath) // дома - всегда
InitItems(MenuItems, ToolBarItems);
else // это мехмат
{
Item = new PluginGUIItem(StringsPrefix + "NAME", StringsPrefix + "DESCRIPTION", loginForm.PluginImage.Image, loginForm.PluginImage.BackColor, Execute);
MenuItems.Add(Item);
ToolBarItems.Add(Item);
}
}
string[] ReadLoginPassFromAuth(string AuthFileFullName)
{
string[] lparr = new string[0];
try
{
var n = 10000;
var arr = new byte[n];
int nbytes;
// Здесь может быть ьисключение если с файлом или путем проблемы
using (var fs = new FileStream(AuthFileFullName, FileMode.Open))
if (IsLightPTInWorkingDirectiry()) // если lightpt.dat существует в текущем
InitItems(MenuItems, ToolBarItems);
else
{
nbytes = fs.Read(arr, 0, n);
var AuthFileFullName = FullAuthNameFromNETDisk();
if (AuthFileFullName != "") // если auth.dat существует в корне сетевого диска
InitItems(MenuItems, ToolBarItems);
}
var data = new byte[nbytes];
System.Array.Copy(arr, data, nbytes);
// Здесь может быть исключение если ключ неправильный
var lp = LoginUtils.Decrypt(data);
lparr = lp.Split((char)10);
}
catch (Exception e)
{
AddMessage(e);
}
return lparr;
}
public void AfterAddInGUI()
{
if (Item == null)
if (Item == null) // Если не показали кнопки, то нет смысла в дальнейших действиях - плагин неактивен
{
AddMessage("Плагин Teacher Control отключён. Не выполнено условие LightPTExists || AuthExists");
return;
}
menuItem = (ToolStripMenuItem)Item.menuItem;
toolStripButton = (ToolStripButton)Item.toolStripButton;
// Попытка выполнить автоматический вход из информации в auth.dat
// Прочитать логин и хеш пароля в auth.dat
// По идее в БД надо хранить хеш пароля.
// Авторизоваться по этому паролю через БД
// Непонятно, как сделать эту часть асинхронно
// В AuthFileFullName только auth с сетевого диска. Если он пустой, то для дома попытаться добавить сюда
// текущую папку и потом корневую папку
try {
if (!IsMechmath()) // если дома, то искать auth в текущей папке
// При запуске auth.dat ищется и делается попытка авторизации:
// Мехмат: в корне сетевого диска (только!). Если находится, делается попытка авторизации
// Дома: в текущей папке. Если нет, ищется в папке на уровень выше. Если находится, делается попытка авторизации
// При этом на мехмате не ищется lightpt.dat в текущем
// Версия. Разрешить на мехмате автоматически авторизоваться если заходим из папки с lightpt.dat
// А если его нет, то ищем auth в корне сетевого
// Последовательность поиска auth.dat на мехмате:
// В текущем, на уровень выше (только если в текущем есть lightpt) и на сетевом
try
{
// Попытка автоматического входа
// AuthFileFullName для мехмата был запомнен в GetGUI
// Нет - только на мехмате. Заполнить если дома!!!
// Думаю, здесь всё надо перевычислить. Начать с текущего, потом на уровень выше и потом в корень сетевого диска
// !!! НАДО ТУТ ИСКАТЬ lightpt.dat в текущем!!!
var AuthFileFullName = "";
if (IsLightPTInWorkingDirectiry()) // Только если lightPT.dat в текущем, ищем auth.dat в текущем или выше
AuthFileFullName = FullAuthNameFromWorkingDirOrParent();
if (AuthFileFullName == "" && IsMechmath)
{
var WorkingDir = WorkingDirectory();
var auth = System.IO.Path.Combine(WorkingDir,"auth.dat");
// искать auth в текущей папке
if (System.IO.File.Exists(auth))
AuthFileFullName = auth;
else
{
// искать auth в папке на уровень выше
auth = System.IO.Path.Combine(WorkingDir, "..", "auth.dat");
if (System.IO.File.Exists(auth))
{
var fi = new System.IO.FileInfo(auth);
AuthFileFullName = fi.FullName;
}
}
AuthFileFullName = FullAuthNameFromNETDisk();
}
// Попытка автоматического входа
if (AuthFileFullName != "")
{
//var ss = System.IO.File.ReadAllLines(AuthFileFullName);
var ss = ReadLoginPassFromAuth(AuthFileFullName);
//var ss = File.ReadAllLines(AuthFileFullName);
var ss = TeacherPluginUtils.ReadLoginPassFromAuth(AuthFileFullName);
if (ss.Length >= 2)
{
var login = ss[0];
@ -251,16 +257,12 @@ namespace VisualPascalABCPlugins
}
catch (Exception e)
{
AddMessage(e);
AddMessage(e); // И тут уже вывести причину. Она только в ReadLoginPassFromAuth может быть
}
}
private void RunStartingHandler(string filename)
{
/*if (RegisterForm.Registered)
{
System.IO.File.AppendAllText("d:\\runs.txt", filename + " " + DateTime.Now + '\n');
}*/
}
}
}

View file

@ -72,7 +72,7 @@
<Compile Include="LoginForm.designer.cs">
<DependentUpon>LoginForm.cs</DependentUpon>
</Compile>
<Compile Include="LoginUtils.cs" />
<Compile Include="TeacherPluginUtils.cs" />
<Compile Include="Properties\Resources.Designer.cs">
<AutoGen>True</AutoGen>
<DesignTime>True</DesignTime>

View file

@ -8,7 +8,7 @@ using System.IO;
namespace VisualPascalABCPlugins
{
public static class LoginUtils
public static class TeacherPluginUtils
{
public static string ProcessorId()
{
@ -55,5 +55,25 @@ namespace VisualPascalABCPlugins
}
return text;
}
public static string[] ReadLoginPassFromAuth(string AuthFileFullName)
{
// Исключения обрабатываются уровнем выше
string[] lparr = new string[0];
var n = 10000;
var arr = new byte[n];
int nbytes;
// Здесь может быть исключение если с файлом или путем проблемы
using (var fs = new FileStream(AuthFileFullName, FileMode.Open))
{
nbytes = fs.Read(arr, 0, n);
}
var data = new byte[nbytes];
System.Array.Copy(arr, data, nbytes);
// Здесь может быть исключение если ключ неправильный
var lp = Decrypt(data);
lparr = lp.Split((char)10);
return lparr;
}
}
}

View file

@ -70,8 +70,8 @@ type
( 'FIO', FullFIO ),
( 'taskName', TaskName ),
( 'lessonName', LessonName ),
( 'type', TaskResult ),
( 'resultInfo', TaskResultInfo ),
( 'taskResult', TaskResult ),
( 'taskResultInfo', TaskResultInfo ),
( 'content', '' ),
( 'password', Password )
);
@ -1101,27 +1101,34 @@ begin
WriteInfoCallBack(LessonName,TName, TaskResult, TaskResultInfo);
end;
procedure WriteInfoToRemoteDatabase(auth: string; LessonName, TaskName, TaskResult, AdditionalInfo: string);
begin
// Считать логин пароль из auth
var f: file of byte;
Reset(f,auth);
var data := f.Elements.ToArray;
var arr := Decrypt(data).Split(#10);
var login,pass: string;
if arr.Length >= 2 then
begin
login := arr[0];
pass := arr[1];
// Теперь как-то записать в БД информацию
var User := new ServerAccessProvider(ServerAddr);
var t2 := User.SendPostRequest(login, pass, LessonName, TaskName, TaskResult, AdditionalInfo);
var v := t2.Result;
//Console.WriteLine(v);
end;
end;
procedure WriteInfoToDatabases(LessonName,TaskName: string; TaskResult: TaskStatus; AdditionalInfo: string := '');
begin
try
System.IO.File.AppendAllText('db.txt', $'{LessonName} {TaskName} {dateTime.Now.ToString(''u'')} {TaskResult.ToString} {AdditionalInfo}' + #10);
var auth := FindAuthDat;
// Считать логин пароль из auth
var f: file of byte;
Reset(f,auth);
var data := f.Elements.ToArray;
var arr := Decrypt(data).Split(#10);
var login,pass: string;
if arr.Length >= 2 then
begin
login := arr[0];
pass := arr[1];
// Теперь как-то записать в БД информацию
var User := new ServerAccessProvider(ServerAddr);
var t2 := User.SendPostRequest(login, pass, LessonName, TaskName, TaskResult.ToString, AdditionalInfo);
var v := t2.Result;
//Console.WriteLine(v);
end;
var auth := FindAuthDat();
if auth<>'' then
// Есть проблема паузы при плохой сети
WriteInfoToRemoteDatabase(auth,LessonName,TaskName,TaskResult.ToString, AdditionalInfo);
except
on e: Exception do
Console.WriteLine(e.Message);
@ -1146,7 +1153,8 @@ begin
if LessonName = '' then
begin
// Имя текущей папки. Плохо - в lightpt забыли написать имя урока
var ttt := ExtractFileDir(System.Environment.GetCommandLineArgs[0]);
//var ttt := ExtractFileDir(System.Environment.GetCommandLineArgs[0]);
var ttt := ExpandFileName('.');
var LastDir := ttt.ToWords(System.IO.Path.DirectorySeparatorChar).LastOrDefault;
// Каталог может содержать пробелы. Брать первое слово
if LastDir<>nil then