Merge pull request #26 from PI20v/dev

0.2
This commit is contained in:
Maxim Slipenko 2022-05-23 19:50:12 +03:00 committed by GitHub
commit 94c54bc727
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
19 changed files with 1589 additions and 5 deletions

View File

@ -0,0 +1,11 @@
{
"Version": 1,
"ProjectMap": {
"fe70a2f9-d831-462e-8705-b14623544f1c": {
"ProjectGuid": "fe70a2f9-d831-462e-8705-b14623544f1c",
"DisplayName": "AwesomeEmailExtractor",
"ColorIndex": 0
}
},
"NextColorIndex": 1
}

185
Authorization.cs Normal file
View File

@ -0,0 +1,185 @@
using System;
using System.Text;
using System.IO;
using System.Security.Cryptography;
using Microsoft.Data.Sqlite;
using System.Collections.Generic;
namespace AwesomeEmailExtractor
{
public class Authorization
{
public static User Login(string login, string password)
{
SqliteCommand command = new SqliteCommand();
command.Connection = Globals.db;
command.CommandText = "SELECT id, login, role_id FROM users WHERE login = @login AND password = @password";
SqliteParameter loginParam = new SqliteParameter("@login", login);
command.Parameters.Add(loginParam);
SqliteParameter passwordParam = new SqliteParameter("@password", EncryptPassword(password));
command.Parameters.Add(passwordParam);
SqliteDataReader reader = command.ExecuteReader();
while (reader.Read())
{
return new User(reader.GetInt32(0), reader.GetString(1), (UserRoles)reader.GetInt32(2));
}
throw new Exception("Пользователь не найден!");
}
public static User Register(string login, string password)
{
SqliteCommand command = new SqliteCommand();
command.Connection = Globals.db;
command.CommandText = "INSERT INTO users (login, password, role_id) VALUES (@login, @password, 0);";
SqliteParameter loginParam = new SqliteParameter("@login", login);
command.Parameters.Add(loginParam);
SqliteParameter passwordParam = new SqliteParameter("@password", EncryptPassword(password));
command.Parameters.Add(passwordParam);
try
{
command.ExecuteNonQuery();
} catch (SqliteException e)
{
if (e.SqliteErrorCode == 19) {
throw new Exception("Имя пользователя занятно!");
}
throw new Exception($"Ошибка: {e.Message}");
};
return Login(login, password);
}
public static string EncryptPassword(string password)
{
using (MD5CryptoServiceProvider md5 = new MD5CryptoServiceProvider())
{
UTF8Encoding utf8 = new UTF8Encoding();
byte[] data = md5.ComputeHash(utf8.GetBytes(password));
return Convert.ToBase64String(data);
}
}
}
public enum UserRoles
{
DEFAULT,
ADMIN
}
public class User
{
public int ID { get; }
public string Login { get; }
public UserRoles Role { get; }
public User(int id, string login, UserRoles role)
{
ID = id;
Login = login;
Role = role;
}
public void Delete()
{
SqliteCommand command = new SqliteCommand();
command.Connection = Globals.db;
command.CommandText = "DELETE FROM users WHERE id = @id;";
SqliteParameter idParam = new SqliteParameter("@id", ID);
command.Parameters.Add(idParam);
command.ExecuteNonQuery();
}
public void ChangePassword(string password)
{
SqliteCommand command = new SqliteCommand();
command.Connection = Globals.db;
command.CommandText = "UPDATE users SET password = @password WHERE id = @id;";
SqliteParameter idParam = new SqliteParameter("@id", ID);
command.Parameters.Add(idParam);
SqliteParameter passwordParam = new SqliteParameter("@password", Authorization.EncryptPassword(password));
command.Parameters.Add(passwordParam);
command.ExecuteNonQuery();
}
}
public class AdminUtils
{
public User User { get; set; }
public AdminUtils(User user)
{
User = user;
}
public void setRole(string login, UserRoles role)
{
if (User.Role != UserRoles.ADMIN)
{
throw new Exception("Недостаточно прав!");
}
SqliteCommand command = new SqliteCommand();
command.Connection = Globals.db;
command.CommandText = "UPDATE users SET role_id = @role WHERE login = @login";
SqliteParameter roleParam = new SqliteParameter("@role", (int)role);
command.Parameters.Add(roleParam);
SqliteParameter loginParam = new SqliteParameter("@login", login);
command.Parameters.Add(loginParam);
command.ExecuteNonQuery();
}
public void deleteUser(string login)
{
if (User.Role != UserRoles.ADMIN)
{
throw new Exception("Недостаточно прав!");
}
SqliteCommand command = new SqliteCommand();
command.Connection = Globals.db;
command.CommandText = "DELETE FROM users WHERE login = @login";
SqliteParameter loginParam = new SqliteParameter("@login", login);
command.Parameters.Add(loginParam);
command.ExecuteNonQuery();
}
public List<User> getAllUsers()
{
if (User.Role != UserRoles.ADMIN)
{
throw new Exception("Недостаточно прав!");
}
SqliteCommand command = new SqliteCommand();
command.Connection = Globals.db;
command.CommandText = "SELECT * FROM users";
SqliteDataReader reader = command.ExecuteReader();
List<User> users = new List<User>();
while (reader.Read())
{
users.Add(new User(reader.GetInt32(0), reader.GetString(1), (UserRoles)reader.GetInt32(2)));
}
return users;
}
}
}

125
AuthorizationForm.Designer.cs generated Normal file
View File

@ -0,0 +1,125 @@
namespace AwesomeEmailExtractor
{
partial class AuthorizationForm
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.loginButton = new System.Windows.Forms.Button();
this.registerButton = new System.Windows.Forms.Button();
this.entryLogin = new System.Windows.Forms.TextBox();
this.label1 = new System.Windows.Forms.Label();
this.label2 = new System.Windows.Forms.Label();
this.entryPassword = new System.Windows.Forms.TextBox();
this.SuspendLayout();
//
// loginButton
//
this.loginButton.Font = new System.Drawing.Font("Microsoft Sans Serif", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(204)));
this.loginButton.Location = new System.Drawing.Point(12, 127);
this.loginButton.Name = "loginButton";
this.loginButton.Size = new System.Drawing.Size(293, 23);
this.loginButton.TabIndex = 0;
this.loginButton.Text = "Авторизоваться";
this.loginButton.UseVisualStyleBackColor = true;
this.loginButton.Click += new System.EventHandler(this.loginButton_Click);
//
// registerButton
//
this.registerButton.Font = new System.Drawing.Font("Microsoft Sans Serif", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(204)));
this.registerButton.Location = new System.Drawing.Point(12, 156);
this.registerButton.Name = "registerButton";
this.registerButton.Size = new System.Drawing.Size(293, 23);
this.registerButton.TabIndex = 1;
this.registerButton.Text = "Зарегистрироваться";
this.registerButton.UseVisualStyleBackColor = true;
this.registerButton.Click += new System.EventHandler(this.registerButton_Click);
//
// entryLogin
//
this.entryLogin.Location = new System.Drawing.Point(110, 32);
this.entryLogin.Name = "entryLogin";
this.entryLogin.Size = new System.Drawing.Size(195, 20);
this.entryLogin.TabIndex = 2;
//
// label1
//
this.label1.AutoSize = true;
this.label1.Font = new System.Drawing.Font("Microsoft Sans Serif", 15.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(204)));
this.label1.Location = new System.Drawing.Point(12, 30);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(77, 25);
this.label1.TabIndex = 3;
this.label1.Text = "Логин:";
//
// label2
//
this.label2.AutoSize = true;
this.label2.Font = new System.Drawing.Font("Microsoft Sans Serif", 15.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(204)));
this.label2.Location = new System.Drawing.Point(12, 77);
this.label2.Name = "label2";
this.label2.Size = new System.Drawing.Size(92, 25);
this.label2.TabIndex = 5;
this.label2.Text = "Пароль:";
//
// entryPassword
//
this.entryPassword.Location = new System.Drawing.Point(110, 79);
this.entryPassword.Name = "entryPassword";
this.entryPassword.Size = new System.Drawing.Size(195, 20);
this.entryPassword.TabIndex = 4;
this.entryPassword.UseSystemPasswordChar = true;
//
// AuthorizationForm
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(317, 191);
this.Controls.Add(this.label2);
this.Controls.Add(this.entryPassword);
this.Controls.Add(this.label1);
this.Controls.Add(this.entryLogin);
this.Controls.Add(this.registerButton);
this.Controls.Add(this.loginButton);
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle;
this.MaximizeBox = false;
this.Name = "AuthorizationForm";
this.Text = "Авторизоваться";
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private System.Windows.Forms.Button loginButton;
private System.Windows.Forms.Button registerButton;
private System.Windows.Forms.TextBox entryLogin;
private System.Windows.Forms.Label label1;
private System.Windows.Forms.Label label2;
private System.Windows.Forms.TextBox entryPassword;
}
}

42
AuthorizationForm.cs Normal file
View File

@ -0,0 +1,42 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace AwesomeEmailExtractor
{
public partial class AuthorizationForm : Form
{
public AuthorizationForm()
{
InitializeComponent();
}
private void loginButton_Click(object sender, EventArgs e)
{
try
{
Globals.currentUser = Authorization.Login(entryLogin.Text, entryPassword.Text);
Logs.Log(Globals.currentUser, Logs.Action.Login, new Dictionary<string, object>());
var mainForm = FormManager.Current.CreateForm<MainForm>();
FormManager.Current.Navigate(this, mainForm);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
private void registerButton_Click(object sender, EventArgs e)
{
var form = FormManager.Current.CreateForm<RegistrationForm>();
FormManager.Current.Navigate(this, form);
}
}
}

120
AuthorizationForm.resx Normal file
View File

@ -0,0 +1,120 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>

View File

@ -12,6 +12,8 @@
<FileAlignment>512</FileAlignment>
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
<Deterministic>true</Deterministic>
<NuGetPackageImportStamp>
</NuGetPackageImportStamp>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
@ -33,8 +35,36 @@
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="Microsoft.Data.Sqlite, Version=5.0.3.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL">
<HintPath>packages\Microsoft.Data.Sqlite.Core.5.0.3\lib\netstandard2.0\Microsoft.Data.Sqlite.dll</HintPath>
</Reference>
<Reference Include="SQLitePCLRaw.batteries_v2, Version=2.0.4.976, Culture=neutral, PublicKeyToken=8226ea5df37bcae9, processorArchitecture=MSIL">
<HintPath>packages\SQLitePCLRaw.bundle_e_sqlite3.2.0.4\lib\net461\SQLitePCLRaw.batteries_v2.dll</HintPath>
</Reference>
<Reference Include="SQLitePCLRaw.core, Version=2.0.4.976, Culture=neutral, PublicKeyToken=1488e028ca7ab535, processorArchitecture=MSIL">
<HintPath>packages\SQLitePCLRaw.core.2.0.4\lib\netstandard2.0\SQLitePCLRaw.core.dll</HintPath>
</Reference>
<Reference Include="SQLitePCLRaw.nativelibrary, Version=2.0.4.976, Culture=neutral, PublicKeyToken=502ed628492ab262, processorArchitecture=MSIL">
<HintPath>packages\SQLitePCLRaw.bundle_e_sqlite3.2.0.4\lib\net461\SQLitePCLRaw.nativelibrary.dll</HintPath>
</Reference>
<Reference Include="SQLitePCLRaw.provider.dynamic_cdecl, Version=2.0.4.976, Culture=neutral, PublicKeyToken=b68184102cba0b3b, processorArchitecture=MSIL">
<HintPath>packages\SQLitePCLRaw.provider.dynamic_cdecl.2.0.4\lib\netstandard2.0\SQLitePCLRaw.provider.dynamic_cdecl.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Buffers, Version=4.0.2.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
<HintPath>packages\System.Buffers.4.4.0\lib\netstandard2.0\System.Buffers.dll</HintPath>
</Reference>
<Reference Include="System.Core" />
<Reference Include="System.Memory, Version=4.0.1.1, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
<HintPath>packages\System.Memory.4.5.3\lib\netstandard2.0\System.Memory.dll</HintPath>
</Reference>
<Reference Include="System.Numerics" />
<Reference Include="System.Numerics.Vectors, Version=4.1.3.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>packages\System.Numerics.Vectors.4.4.0\lib\net46\System.Numerics.Vectors.dll</HintPath>
</Reference>
<Reference Include="System.Runtime.CompilerServices.Unsafe, Version=4.0.4.1, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>packages\System.Runtime.CompilerServices.Unsafe.4.5.2\lib\netstandard2.0\System.Runtime.CompilerServices.Unsafe.dll</HintPath>
</Reference>
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
@ -46,7 +76,17 @@
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="Authorization.cs" />
<Compile Include="AuthorizationForm.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="AuthorizationForm.Designer.cs">
<DependentUpon>AuthorizationForm.cs</DependentUpon>
</Compile>
<Compile Include="ExtactEmailsAlgorithm.cs" />
<Compile Include="FormManager.cs" />
<Compile Include="Globals.cs" />
<Compile Include="Logs.cs" />
<Compile Include="MainForm.cs">
<SubType>Form</SubType>
</Compile>
@ -55,6 +95,21 @@
</Compile>
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="RegistrationForm.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="RegistrationForm.Designer.cs">
<DependentUpon>RegistrationForm.cs</DependentUpon>
</Compile>
<Compile Include="SettingsForm.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="SettingsForm.Designer.cs">
<DependentUpon>SettingsForm.cs</DependentUpon>
</Compile>
<EmbeddedResource Include="AuthorizationForm.resx">
<DependentUpon>AuthorizationForm.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="MainForm.resx">
<DependentUpon>MainForm.cs</DependentUpon>
</EmbeddedResource>
@ -67,6 +122,13 @@
<AutoGen>True</AutoGen>
<DependentUpon>Resources.resx</DependentUpon>
</Compile>
<EmbeddedResource Include="SettingsForm.resx">
<DependentUpon>SettingsForm.cs</DependentUpon>
</EmbeddedResource>
<None Include="packages.config" />
<EmbeddedResource Include="RegistrationForm.resx">
<DependentUpon>RegistrationForm.cs</DependentUpon>
</EmbeddedResource>
<None Include="Properties\Settings.settings">
<Generator>SettingsSingleFileGenerator</Generator>
<LastGenOutput>Settings.Designer.cs</LastGenOutput>
@ -81,4 +143,11 @@
<None Include="App.config" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<Import Project="packages\SQLitePCLRaw.lib.e_sqlite3.2.0.4\build\net461\SQLitePCLRaw.lib.e_sqlite3.targets" Condition="Exists('packages\SQLitePCLRaw.lib.e_sqlite3.2.0.4\build\net461\SQLitePCLRaw.lib.e_sqlite3.targets')" />
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
<PropertyGroup>
<ErrorText>Данный проект ссылается на пакеты NuGet, отсутствующие на этом компьютере. Используйте восстановление пакетов NuGet, чтобы скачать их. Дополнительную информацию см. по адресу: http://go.microsoft.com/fwlink/?LinkID=322105. Отсутствует следующий файл: {0}.</ErrorText>
</PropertyGroup>
<Error Condition="!Exists('packages\SQLitePCLRaw.lib.e_sqlite3.2.0.4\build\net461\SQLitePCLRaw.lib.e_sqlite3.targets')" Text="$([System.String]::Format('$(ErrorText)', 'packages\SQLitePCLRaw.lib.e_sqlite3.2.0.4\build\net461\SQLitePCLRaw.lib.e_sqlite3.targets'))" />
</Target>
</Project>

46
FormManager.cs Normal file
View File

@ -0,0 +1,46 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace AwesomeEmailExtractor
{
public class FormManager : ApplicationContext
{
private void onFormClosed(object sender, EventArgs e)
{
if (Application.OpenForms.Count == 0)
{
if (((Form)sender).Name == currentForm)
ExitThread();
}
}
public T CreateForm<T>() where T : Form, new()
{
var ret = new T();
ret.FormClosed += onFormClosed;
return ret;
}
public void Navigate(Form from, Form to)
{
currentForm = to.Name;
from.Close();
to.Show();
}
public string currentForm = "AuthorizationForm";
private static Lazy<FormManager> _current = new Lazy<FormManager>();
public static FormManager Current => _current.Value;
public FormManager()
{
var authorization = CreateForm<AuthorizationForm>();
authorization.Show();
}
}
}

124
Globals.cs Normal file
View File

@ -0,0 +1,124 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
using Microsoft.Data.Sqlite;
namespace AwesomeEmailExtractor
{
internal class Globals
{
// Getter and setter for SQLite database connection
public static SqliteConnection db { get; set; }
public static SqliteConnection logsDb { get; set; }
public static User currentUser { get; set; }
public static string getAppDirectory()
{
return Path.Combine(
Environment.GetFolderPath(
Environment.SpecialFolder.ApplicationData
),
"AwesomeEmailExtractor"
);
}
public static string getAppDatabase()
{
return Path.Combine(
getAppDirectory(),
"database.db"
);
}
public static string getDefaultPathAppLogs()
{
return Path.Combine(
getAppDirectory(),
"logs.db"
);
}
public static string getPathAppLogs()
{
SqliteCommand command = new SqliteCommand();
command.Connection = db;
command.CommandText = "SELECT logs_db_path FROM app_settings LIMIT 1";
SqliteDataReader reader = command.ExecuteReader();
while (reader.Read())
{
return reader["logs_db_path"].ToString();
}
return getDefaultPathAppLogs();
}
public static void CreateLogsTable()
{
SqliteCommand command = new SqliteCommand();
command.Connection = logsDb;
command.CommandText = "CREATE TABLE IF NOT EXISTS logs_actions (id INTEGER PRIMARY KEY, name TEXT NOT NULL)";
command.ExecuteNonQuery();
command.CommandText = "INSERT OR IGNORE INTO logs_actions (id, name) VALUES (0, 'Выполнение'), (1, 'Вход'), (2, 'Регистрация');";
command.ExecuteNonQuery();
command.CommandText = "CREATE TABLE IF NOT EXISTS logs (id INTEGER PRIMARY KEY AUTOINCREMENT, user_id INTEGER NOT NULL, date TEXT NOT NULL, action INTEGER NOT NULL, message TEXT NOT NULL, FOREIGN KEY(action) REFERENCES logs_actions(id));";
command.ExecuteNonQuery();
}
public static void CreateTables()
{
SqliteCommand command = new SqliteCommand();
command.Connection = db;
// Создать таблицу для хранения ролей
command.CommandText = "CREATE TABLE IF NOT EXISTS roles (id INTEGER PRIMARY KEY, name TEXT NOT NULL);";
command.ExecuteNonQuery();
// Добавить роли
command.CommandText = "INSERT OR IGNORE INTO roles (id, name) VALUES (0, 'Обычный'), (1, 'Администратор');";
command.ExecuteNonQuery();
// Создать таблицу для хранения настроек (знаю, так плохо, но сойдет)
command.CommandText = "CREATE TABLE IF NOT EXISTS app_settings (logs_db_path TEXT);";
command.ExecuteNonQuery();
// Создать таблицу для хранения пользователей
command.CommandText = "CREATE TABLE IF NOT EXISTS users (id INTEGER PRIMARY KEY AUTOINCREMENT, login TEXT NOT NULL UNIQUE, password TEXT NOT NULL, role_id INTEGER NOT NULL, FOREIGN KEY(role_id) REFERENCES roles(id));";
command.ExecuteNonQuery();
// Если таблица пуста - добавить пользователя по умолчанию
command.CommandText = "SELECT COUNT(*) FROM users";
if (Convert.ToInt32(command.ExecuteScalar()) == 0)
{
command.CommandText = "INSERT INTO users (login, password, role_id) VALUES ('admin', @password, 1);";
SqliteParameter passwordParam = new SqliteParameter("@password", Authorization.EncryptPassword("admin"));
command.Parameters.Add(passwordParam);
command.ExecuteNonQuery();
command.Parameters.Clear();
}
command.CommandText = "SELECT COUNT(*) FROM app_settings";
if (Convert.ToInt32(command.ExecuteScalar()) == 0)
{
command.CommandText = "INSERT INTO app_settings (logs_db_path) VALUES (@logs_db_path);";
SqliteParameter logsDbPathParam = new SqliteParameter("@logs_db_path", getDefaultPathAppLogs());
command.Parameters.Add(logsDbPathParam);
command.ExecuteNonQuery();
command.Parameters.Clear();
}
}
}
}

125
Logs.cs Normal file
View File

@ -0,0 +1,125 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.Data.Sqlite;
namespace AwesomeEmailExtractor
{
public class Logs
{
public class LogData {
public User user;
public string date;
public Action action;
public string message;
}
public enum Action
{
Execute,
Login,
Registration
}
public static void Log(User user, Action action, Dictionary<string, object> options)
{
SqliteCommand command = new SqliteCommand();
command.Connection = Globals.logsDb;
command.CommandText = "INSERT INTO logs (user_id, date, action, message) VALUES (@user_id, strftime('%Y-%m-%d %H:%M:%S', datetime('now')), @action, @message)";
command.Parameters.AddWithValue("@user_id", user.ID);
command.Parameters.AddWithValue("@action", action);
command.Parameters.AddWithValue("@message", GetLogMessage(action, options));
command.ExecuteNonQuery();
}
public static List<LogData> GetLogs(User user)
{
SqliteCommand command = new SqliteCommand();
command.Connection = Globals.logsDb;
command.CommandText = "SELECT date, action, message FROM logs WHERE user_id = @user_id ORDER BY date DESC";
command.Parameters.AddWithValue("@user_id", user.ID);
SqliteDataReader reader = command.ExecuteReader();
List<LogData> logs = new List<LogData>();
while (reader.Read())
{
logs.Add(new LogData()
{
user = user,
date = reader.GetString(0),
action = (Action)reader.GetInt32(1),
message = reader.GetString(2)
});
}
return logs;
}
public static List<LogData> GetLogs()
{
SqliteCommand command = new SqliteCommand();
command.Connection = Globals.logsDb;
command.CommandText = "ATTACH DATABASE @dbpath AS appDB";
command.Parameters.AddWithValue("@dbpath", Globals.getAppDatabase());
command.ExecuteNonQuery();
command.CommandText = @"
SELECT
user_id,
CASE WHEN appDB.users.login is NULL THEN 'Deleted_' || user_id ELSE appDB.users.login END AS login
appDB.users.role,
date,
action,
message
from logs LEFT JOIN appDB.users on logs.user_id = appDB.users.id ORDER BY date DESC";
SqliteDataReader reader = command.ExecuteReader();
List<LogData> logs = new List<LogData>();
while (reader.Read())
{
logs.Add(new LogData()
{
user = new User(reader.GetInt32(0), reader.GetString(1), (UserRoles)reader.GetInt32(2)),
date = reader.GetString(3),
action = (Action)reader.GetInt32(4),
message = reader.GetString(5)
});
}
return logs;
}
public static string GetLogMessage(Action action, Dictionary<string, object> options)
{
if (action == Action.Execute)
{
string sourceText = (string)options["sourceText"];
int count = (int)options["count"];
List<string> uniqueEmails = options["uniqueEmails"] as List<string>;
return $"Пользователь выполнил поиск email-ов c таким исходным текстом: [ {sourceText}. ]\n" +
$"Найдено {count} email-ов.\n" +
$"Список уникальных: {String.Join(", ", uniqueEmails)}.";
}
if (action == Action.Login)
{
return "Пользователь вошел в систему.";
}
if (action == Action.Registration)
{
return "Пользователь зарегистрировался в системе.";
}
return "";
}
}
}

39
MainForm.Designer.cs generated
View File

@ -36,6 +36,10 @@
this.toolStripStatusLabel = new System.Windows.Forms.ToolStripStatusLabel();
this.menuStrip1 = new System.Windows.Forms.MenuStrip();
this.fileToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.аккаунтToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.settingsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.administrationToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.exitToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.helpToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.resultStatusStrip.SuspendLayout();
this.menuStrip1.SuspendLayout();
@ -112,6 +116,7 @@
//
this.menuStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.fileToolStripMenuItem,
this.аккаунтToolStripMenuItem,
this.helpToolStripMenuItem});
this.menuStrip1.Location = new System.Drawing.Point(0, 0);
this.menuStrip1.Name = "menuStrip1";
@ -125,6 +130,36 @@
this.fileToolStripMenuItem.Size = new System.Drawing.Size(48, 20);
this.fileToolStripMenuItem.Text = "Файл";
//
// аккаунтToolStripMenuItem
//
this.аккаунтToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.settingsToolStripMenuItem,
this.administrationToolStripMenuItem,
this.exitToolStripMenuItem});
this.аккаунтToolStripMenuItem.Name = "аккаунтToolStripMenuItem";
this.аккаунтToolStripMenuItem.Size = new System.Drawing.Size(63, 20);
this.аккаунтToolStripMenuItem.Text = "Аккаунт";
//
// settingsToolStripMenuItem
//
this.settingsToolStripMenuItem.Name = "settingsToolStripMenuItem";
this.settingsToolStripMenuItem.Size = new System.Drawing.Size(189, 22);
this.settingsToolStripMenuItem.Text = "Настройки";
this.settingsToolStripMenuItem.Click += new System.EventHandler(this.settingsToolStripMenuItem_Click);
//
// administrationToolStripMenuItem
//
this.administrationToolStripMenuItem.Name = "administrationToolStripMenuItem";
this.administrationToolStripMenuItem.Size = new System.Drawing.Size(189, 22);
this.administrationToolStripMenuItem.Text = "Администрирование";
//
// exitToolStripMenuItem
//
this.exitToolStripMenuItem.Name = "exitToolStripMenuItem";
this.exitToolStripMenuItem.Size = new System.Drawing.Size(189, 22);
this.exitToolStripMenuItem.Text = "Выход";
this.exitToolStripMenuItem.Click += new System.EventHandler(this.exitToolStripMenuItem_Click);
//
// helpToolStripMenuItem
//
this.helpToolStripMenuItem.Name = "helpToolStripMenuItem";
@ -166,6 +201,10 @@
private System.Windows.Forms.ToolStripMenuItem fileToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem helpToolStripMenuItem;
private System.Windows.Forms.ToolStripStatusLabel toolStripStatusLabel;
private System.Windows.Forms.ToolStripMenuItem аккаунтToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem settingsToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem administrationToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem exitToolStripMenuItem;
}
}

View File

@ -15,10 +15,21 @@ namespace AwesomeEmailExtractor
public MainForm()
{
InitializeComponent();
}
administrationToolStripMenuItem.Enabled = Globals.currentUser.Role == UserRoles.ADMIN;
}
private void executeButton_Click(object sender, EventArgs e)
{
// Получаем исходный текст из sourceRichTextBox
string sourceText = sourceRichTextBox.Text;
if (sourceText.Length == 0)
{
MessageBox.Show("Введите текст в поле исходного текста", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
// Чистим предыдущий результат
toolStripStatusLabel.Text = "";
resultCountLabel.Text = "";
@ -27,9 +38,6 @@ namespace AwesomeEmailExtractor
// Объявляем список уникальных e-mail-ов
List<string> uniqueEmails = new List<string>();
// Получаем исходный текст из sourceRichTextBox
string sourceText = sourceRichTextBox.Text;
// Вызываем метод для извлечения e-mail-ов
int count = ExtactEmailsAlgorithm.Extract(sourceText, out uniqueEmails);
@ -37,6 +45,28 @@ namespace AwesomeEmailExtractor
toolStripStatusLabel.Text = "Успех!";
resultCountLabel.Text = $"Количество e-mail-ов в тексте: {count}";
uniqueListBox.DataSource = uniqueEmails;
Logs.Log(
Globals.currentUser,
Logs.Action.Execute,
new Dictionary<string, object>() {
{ "sourceText", sourceText },
{ "count", count },
{ "uniqueEmails", uniqueEmails }
});
}
private void settingsToolStripMenuItem_Click(object sender, EventArgs e)
{
SettingsForm settingsForm = FormManager.Current.CreateForm<SettingsForm>();
settingsForm.ShowDialog(this);
}
private void exitToolStripMenuItem_Click(object sender, EventArgs e)
{
Globals.currentUser = null;
AuthorizationForm authorization = FormManager.Current.CreateForm<AuthorizationForm>();
FormManager.Current.Navigate(this, authorization);
}
}
}

View File

@ -3,6 +3,8 @@ using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO;
using Microsoft.Data.Sqlite;
namespace AwesomeEmailExtractor
{
@ -14,9 +16,36 @@ namespace AwesomeEmailExtractor
[STAThread]
static void Main()
{
preMain();
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new MainForm());
Application.Run(FormManager.Current);
postMain();
}
static void preMain()
{
if (!Directory.Exists(Globals.getAppDirectory()))
{
Directory.CreateDirectory(Globals.getAppDirectory());
}
Globals.db = new SqliteConnection("Data Source=" + Globals.getAppDatabase());
Globals.db.Open();
Globals.CreateTables();
Globals.logsDb = new SqliteConnection("Data Source=" + Globals.getPathAppLogs());
Globals.logsDb.Open();
Globals.CreateLogsTable();
}
static void postMain()
{
Globals.db.Close();
}
}
}

162
RegistrationForm.Designer.cs generated Normal file
View File

@ -0,0 +1,162 @@
namespace AwesomeEmailExtractor
{
partial class RegistrationForm
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.label2 = new System.Windows.Forms.Label();
this.entryPassword = new System.Windows.Forms.TextBox();
this.label1 = new System.Windows.Forms.Label();
this.entryLogin = new System.Windows.Forms.TextBox();
this.registerButton = new System.Windows.Forms.Button();
this.loginButton = new System.Windows.Forms.Button();
this.label3 = new System.Windows.Forms.Label();
this.entryRePassword = new System.Windows.Forms.TextBox();
this.label4 = new System.Windows.Forms.Label();
this.SuspendLayout();
//
// label2
//
this.label2.AutoSize = true;
this.label2.Font = new System.Drawing.Font("Microsoft Sans Serif", 15.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(204)));
this.label2.Location = new System.Drawing.Point(9, 52);
this.label2.Name = "label2";
this.label2.Size = new System.Drawing.Size(92, 25);
this.label2.TabIndex = 11;
this.label2.Text = "Пароль:";
//
// entryPassword
//
this.entryPassword.Location = new System.Drawing.Point(183, 52);
this.entryPassword.Name = "entryPassword";
this.entryPassword.Size = new System.Drawing.Size(195, 20);
this.entryPassword.TabIndex = 10;
this.entryPassword.UseSystemPasswordChar = true;
//
// label1
//
this.label1.AutoSize = true;
this.label1.Font = new System.Drawing.Font("Microsoft Sans Serif", 15.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(204)));
this.label1.Location = new System.Drawing.Point(9, 10);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(77, 25);
this.label1.TabIndex = 9;
this.label1.Text = "Логин:";
//
// entryLogin
//
this.entryLogin.Location = new System.Drawing.Point(183, 10);
this.entryLogin.Name = "entryLogin";
this.entryLogin.Size = new System.Drawing.Size(195, 20);
this.entryLogin.TabIndex = 8;
//
// registerButton
//
this.registerButton.Font = new System.Drawing.Font("Microsoft Sans Serif", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(204)));
this.registerButton.Location = new System.Drawing.Point(14, 135);
this.registerButton.Name = "registerButton";
this.registerButton.Size = new System.Drawing.Size(364, 23);
this.registerButton.TabIndex = 6;
this.registerButton.Text = "Зарегистрироваться";
this.registerButton.UseVisualStyleBackColor = true;
this.registerButton.Click += new System.EventHandler(this.registerButton_Click);
//
// loginButton
//
this.loginButton.Font = new System.Drawing.Font("Microsoft Sans Serif", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(204)));
this.loginButton.Location = new System.Drawing.Point(14, 187);
this.loginButton.Name = "loginButton";
this.loginButton.Size = new System.Drawing.Size(364, 23);
this.loginButton.TabIndex = 7;
this.loginButton.Text = "Авторизоваться";
this.loginButton.UseVisualStyleBackColor = true;
this.loginButton.Click += new System.EventHandler(this.loginButton_Click);
//
// label3
//
this.label3.AutoSize = true;
this.label3.Font = new System.Drawing.Font("Microsoft Sans Serif", 15.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(204)));
this.label3.Location = new System.Drawing.Point(9, 94);
this.label3.Name = "label3";
this.label3.Size = new System.Drawing.Size(167, 25);
this.label3.TabIndex = 13;
this.label3.Text = "Повтор пароля:";
//
// entryRePassword
//
this.entryRePassword.Location = new System.Drawing.Point(183, 94);
this.entryRePassword.Name = "entryRePassword";
this.entryRePassword.Size = new System.Drawing.Size(195, 20);
this.entryRePassword.TabIndex = 12;
this.entryRePassword.UseSystemPasswordChar = true;
//
// label4
//
this.label4.AutoSize = true;
this.label4.Font = new System.Drawing.Font("Microsoft Sans Serif", 11.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(204)));
this.label4.Location = new System.Drawing.Point(12, 166);
this.label4.Name = "label4";
this.label4.Size = new System.Drawing.Size(178, 18);
this.label4.TabIndex = 14;
this.label4.Text = "Уже зарегистрированы?";
//
// RegistrationForm
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(391, 222);
this.Controls.Add(this.label4);
this.Controls.Add(this.label3);
this.Controls.Add(this.entryRePassword);
this.Controls.Add(this.label2);
this.Controls.Add(this.entryPassword);
this.Controls.Add(this.label1);
this.Controls.Add(this.entryLogin);
this.Controls.Add(this.registerButton);
this.Controls.Add(this.loginButton);
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle;
this.Name = "RegistrationForm";
this.Text = "Зарегистрироваться";
this.FormClosed += new System.Windows.Forms.FormClosedEventHandler(this.RegistrationForm_FormClosed);
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private System.Windows.Forms.Label label2;
private System.Windows.Forms.TextBox entryPassword;
private System.Windows.Forms.Label label1;
private System.Windows.Forms.TextBox entryLogin;
private System.Windows.Forms.Button registerButton;
private System.Windows.Forms.Button loginButton;
private System.Windows.Forms.Label label3;
private System.Windows.Forms.TextBox entryRePassword;
private System.Windows.Forms.Label label4;
}
}

53
RegistrationForm.cs Normal file
View File

@ -0,0 +1,53 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace AwesomeEmailExtractor
{
public partial class RegistrationForm : Form
{
public RegistrationForm()
{
InitializeComponent();
}
private void registerButton_Click(object sender, EventArgs e)
{
if (!string.Equals(entryPassword.Text, entryRePassword.Text))
{
MessageBox.Show("Пароли не совпадают!");
return;
}
try
{
Globals.currentUser = Authorization.Register(entryLogin.Text, entryPassword.Text);
Logs.Log(Globals.currentUser, Logs.Action.Registration, new Dictionary<string, object>());
var form = FormManager.Current.CreateForm<MainForm>();
FormManager.Current.Navigate(this, form);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
private void loginButton_Click(object sender, EventArgs e)
{
AuthorizationForm form = FormManager.Current.CreateForm<AuthorizationForm>();
FormManager.Current.Navigate(this, form);
}
private void RegistrationForm_FormClosed(object sender, FormClosedEventArgs e)
{
}
}
}

120
RegistrationForm.resx Normal file
View File

@ -0,0 +1,120 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>

123
SettingsForm.Designer.cs generated Normal file
View File

@ -0,0 +1,123 @@
namespace AwesomeEmailExtractor
{
partial class SettingsForm
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.changePasswordButton = new System.Windows.Forms.Button();
this.entryNewPassword = new System.Windows.Forms.TextBox();
this.label2 = new System.Windows.Forms.Label();
this.label3 = new System.Windows.Forms.Label();
this.entryRePassword = new System.Windows.Forms.TextBox();
this.deleteAccountButton = new System.Windows.Forms.Button();
this.SuspendLayout();
//
// changePasswordButton
//
this.changePasswordButton.Location = new System.Drawing.Point(34, 96);
this.changePasswordButton.Name = "changePasswordButton";
this.changePasswordButton.Size = new System.Drawing.Size(275, 26);
this.changePasswordButton.TabIndex = 0;
this.changePasswordButton.Text = "Изменить пароль";
this.changePasswordButton.UseVisualStyleBackColor = true;
this.changePasswordButton.Click += new System.EventHandler(this.changePasswordButton_Click);
//
// entryNewPassword
//
this.entryNewPassword.Location = new System.Drawing.Point(158, 12);
this.entryNewPassword.Name = "entryNewPassword";
this.entryNewPassword.Size = new System.Drawing.Size(151, 20);
this.entryNewPassword.TabIndex = 2;
this.entryNewPassword.UseSystemPasswordChar = true;
//
// label2
//
this.label2.AutoSize = true;
this.label2.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(204)));
this.label2.Location = new System.Drawing.Point(30, 12);
this.label2.Name = "label2";
this.label2.Size = new System.Drawing.Size(118, 20);
this.label2.TabIndex = 4;
this.label2.Text = "Новый пароль";
//
// label3
//
this.label3.AutoSize = true;
this.label3.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(204)));
this.label3.Location = new System.Drawing.Point(30, 53);
this.label3.Name = "label3";
this.label3.Size = new System.Drawing.Size(125, 20);
this.label3.TabIndex = 5;
this.label3.Text = "Повтор пароля";
//
// entryRePassword
//
this.entryRePassword.Location = new System.Drawing.Point(158, 53);
this.entryRePassword.Name = "entryRePassword";
this.entryRePassword.Size = new System.Drawing.Size(151, 20);
this.entryRePassword.TabIndex = 6;
this.entryRePassword.UseSystemPasswordChar = true;
//
// deleteAccountButton
//
this.deleteAccountButton.Location = new System.Drawing.Point(34, 137);
this.deleteAccountButton.Name = "deleteAccountButton";
this.deleteAccountButton.Size = new System.Drawing.Size(275, 26);
this.deleteAccountButton.TabIndex = 7;
this.deleteAccountButton.Text = "Удалить аккаунт";
this.deleteAccountButton.UseVisualStyleBackColor = true;
this.deleteAccountButton.Click += new System.EventHandler(this.deleteAccountButton_Click);
//
// SettingsForm
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(338, 184);
this.Controls.Add(this.deleteAccountButton);
this.Controls.Add(this.entryRePassword);
this.Controls.Add(this.label3);
this.Controls.Add(this.label2);
this.Controls.Add(this.entryNewPassword);
this.Controls.Add(this.changePasswordButton);
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle;
this.Name = "SettingsForm";
this.Text = "Настройки";
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private System.Windows.Forms.Button changePasswordButton;
private System.Windows.Forms.TextBox entryNewPassword;
private System.Windows.Forms.Label label2;
private System.Windows.Forms.Label label3;
private System.Windows.Forms.TextBox entryRePassword;
private System.Windows.Forms.Button deleteAccountButton;
}
}

48
SettingsForm.cs Normal file
View File

@ -0,0 +1,48 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace AwesomeEmailExtractor
{
public partial class SettingsForm : Form
{
public SettingsForm()
{
InitializeComponent();
}
private void deleteAccountButton_Click(object sender, EventArgs e)
{
DialogResult result = MessageBox.Show("Вы уверены что хотите удалить аккаунт?", "Удаление аккаунта", MessageBoxButtons.YesNo);
if (result == DialogResult.Yes)
{
Globals.currentUser.Delete();
MessageBox.Show("Аккаунт удален!");
this.Close();
AuthorizationForm authorization = FormManager.Current.CreateForm<AuthorizationForm>();
FormManager.Current.Navigate(this.Owner, authorization);
}
}
private void changePasswordButton_Click(object sender, EventArgs e)
{
if (!string.Equals(entryNewPassword.Text, entryRePassword.Text))
{
MessageBox.Show("Пароли не совпадают!");
return;
}
Globals.currentUser.ChangePassword(entryNewPassword.Text);
MessageBox.Show("Пароль изменен!");
}
}
}

120
SettingsForm.resx Normal file
View File

@ -0,0 +1,120 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>

13
packages.config Normal file
View File

@ -0,0 +1,13 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Microsoft.Data.Sqlite" version="5.0.3" targetFramework="net472" />
<package id="Microsoft.Data.Sqlite.Core" version="5.0.3" targetFramework="net472" />
<package id="SQLitePCLRaw.bundle_e_sqlite3" version="2.0.4" targetFramework="net472" />
<package id="SQLitePCLRaw.core" version="2.0.4" targetFramework="net472" />
<package id="SQLitePCLRaw.lib.e_sqlite3" version="2.0.4" targetFramework="net472" />
<package id="SQLitePCLRaw.provider.dynamic_cdecl" version="2.0.4" targetFramework="net472" />
<package id="System.Buffers" version="4.4.0" targetFramework="net472" />
<package id="System.Memory" version="4.5.3" targetFramework="net472" />
<package id="System.Numerics.Vectors" version="4.4.0" targetFramework="net472" />
<package id="System.Runtime.CompilerServices.Unsafe" version="4.5.2" targetFramework="net472" />
</packages>