From 311a5cc4cae65291be546b81185953823e000597 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miskolczi=20Rich=C3=A1rd?= Date: Mon, 27 Mar 2023 09:17:06 +0200 Subject: [PATCH] bro i can't even keep track anymore --- .gitignore | 1 + .../DesignTimeBuild/.dtbcache.v2 | Bin 97423 -> 97606 bytes .vs/Password Manager/v17/.suo | Bin 76800 -> 86016 bytes Password Manager/MainForm.Designer.cs | 130 +++++++++--------- Password Manager/MainForm.cs | 72 ++++------ Password Manager/NewProfileForm.cs | 12 +- Password Manager/Password Manager.csproj.user | 3 + Password Manager/PasswordManagerForm.cs | 61 ++++++++ Password Manager/Profiles/IList.cs | 16 ++- Password Manager/Profiles/ProfileHandler.cs | 75 ++++++++-- Password Manager/Profiles/ProfileList.cs | 2 +- Password Manager/Program.cs | 7 +- 12 files changed, 248 insertions(+), 131 deletions(-) create mode 100644 Password Manager/PasswordManagerForm.cs diff --git a/.gitignore b/.gitignore index defecbd..3bd6e85 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ Password\ Manager/bin Password\ Manager/obj .vs/ +Password\ Manager/PasswordManagerForm.resx diff --git a/.vs/Password Manager/DesignTimeBuild/.dtbcache.v2 b/.vs/Password Manager/DesignTimeBuild/.dtbcache.v2 index b6703d90c47155a017f419459b17a483f51e1bda..6b2ed91fec9659bc35125698314d720420b913f7 100644 GIT binary patch delta 8994 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 RlxQTl4X*NvLmOAE`ahZ;EBycf delta 9398 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 M#2^nP1PcrQ2Uuawu>b%7 diff --git a/.vs/Password Manager/v17/.suo b/.vs/Password Manager/v17/.suo index 22215e2f7bf648f5bf42c5d12ad0dd3a27770712..5991f339a9fc961338fddd1132accdac497d1ea8 100644 GIT binary patch delta 8338 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 /// Required designer variable. @@ -28,9 +28,9 @@ /// private void InitializeComponent() { - searchBox = new TextBox(); - resultList = new PasswordListBox(); - profileSelection = new ComboBox(); + SearchBox = new TextBox(); + ResultList = new PasswordListBox(); + ProfileSelection = new ComboBox(); addProfile = new Button(); removeProfile = new Button(); generatePassword = new Button(); @@ -38,82 +38,82 @@ // // searchBox // - searchBox.Location = new Point(10, 20); - searchBox.Margin = new Padding(3, 2, 3, 2); - searchBox.Name = "searchBox"; - searchBox.PlaceholderText = "Search for a password"; - searchBox.Size = new Size(225, 23); - searchBox.TabIndex = 0; - searchBox.TextChanged += resultList.ReloadResults; + SearchBox.Location = new Point(10, 20); + SearchBox.Margin = new Padding(3, 2, 3, 2); + SearchBox.Name = "searchBox"; + SearchBox.PlaceholderText = "Search for a password"; + SearchBox.Size = new Size(225, 23); + SearchBox.TabIndex = 0; + SearchBox.TextChanged += ResultList.ReloadResults; // // resultList // - resultList.FormattingEnabled = true; - resultList.ItemHeight = 15; - resultList.Location = new Point(10, 45); - resultList.Margin = new Padding(3, 2, 3, 2); - resultList.Name = "resultList"; - resultList.Size = new Size(225, 274); - resultList.TabIndex = 1; - resultList.CurrentProfilePathRequest += CurrentProfilePathRequest; - resultList.SearchQueryRequest += () => searchBox.Text; + ResultList.FormattingEnabled = true; + ResultList.ItemHeight = 15; + ResultList.Location = new Point(10, 45); + ResultList.Margin = new Padding(3, 2, 3, 2); + ResultList.Name = "resultList"; + ResultList.Size = new Size(225, 274); + ResultList.TabIndex = 1; + ResultList.CurrentProfilePathRequest += () => CurrentProfilePathRequest(); + ResultList.SearchQueryRequest += () => SearchBox.Text; // // profileSelection // - profileSelection.DisplayMember = "Name"; - profileSelection.DropDownHeight = 100; - profileSelection.DropDownWidth = 200; - profileSelection.FormattingEnabled = true; - profileSelection.IntegralHeight = false; - profileSelection.Location = new Point(513, 20); - profileSelection.Margin = new Padding(3, 2, 3, 2); - profileSelection.Name = "profileSelection"; - profileSelection.Size = new Size(176, 23); - profileSelection.TabIndex = 2; - profileSelection.SelectionChangeCommitted += ChangeProfile; + ProfileSelection.DisplayMember = "Name"; + ProfileSelection.DropDownHeight = 100; + ProfileSelection.DropDownWidth = 176; + ProfileSelection.FormattingEnabled = true; + ProfileSelection.IntegralHeight = false; + ProfileSelection.Location = new Point(513, 20); + ProfileSelection.Margin = new Padding(3, 2, 3, 2); + ProfileSelection.Name = "profileSelection"; + ProfileSelection.Size = new Size(176, 23); + ProfileSelection.TabIndex = 2; + ProfileSelection.SelectionChangeCommitted += ChangeProfile; // // addProfile // - addProfile.Location = new Point(513, 45); - addProfile.Margin = new Padding(3, 2, 3, 2); - addProfile.Name = "addProfile"; - addProfile.Size = new Size(83, 22); - addProfile.TabIndex = 3; - addProfile.Text = "Add"; - addProfile.UseVisualStyleBackColor = true; - addProfile.Click += AddProfile; + AddProfile.Location = new Point(513, 45); + AddProfile.Margin = new Padding(3, 2, 3, 2); + AddProfile.Name = "addProfile"; + AddProfile.Size = new Size(83, 22); + AddProfile.TabIndex = 3; + AddProfile.Text = "Add"; + AddProfile.UseVisualStyleBackColor = true; + AddProfile.Click += OpenProfileCreator; // // removeProfile // - removeProfile.Location = new Point(605, 45); - removeProfile.Margin = new Padding(3, 2, 3, 2); - removeProfile.Name = "removeProfile"; - removeProfile.Size = new Size(83, 22); - removeProfile.TabIndex = 4; - removeProfile.Text = "Delete"; - removeProfile.UseVisualStyleBackColor = true; + DeleteProfile.Location = new Point(605, 45); + DeleteProfile.Margin = new Padding(3, 2, 3, 2); + DeleteProfile.Name = "removeProfile"; + DeleteProfile.Size = new Size(83, 22); + DeleteProfile.TabIndex = 4; + DeleteProfile.Text = "Delete"; + DeleteProfile.UseVisualStyleBackColor = true; // // button1 // - generatePassword.Location = new Point(241, 20); - generatePassword.Name = "button1"; - generatePassword.Size = new Size(75, 23); - generatePassword.TabIndex = 5; - generatePassword.Text = "Generate"; - generatePassword.UseVisualStyleBackColor = true; - generatePassword.Click += Generate; + GeneratePassword.Location = new Point(241, 20); + GeneratePassword.Name = "button1"; + GeneratePassword.Size = new Size(75, 23); + GeneratePassword.TabIndex = 5; + GeneratePassword.Text = "Generate"; + GeneratePassword.UseVisualStyleBackColor = true; + GeneratePassword.Click += OpenPasswordGenerator; // // MainForm // AutoScaleDimensions = new SizeF(7F, 15F); AutoScaleMode = AutoScaleMode.Font; ClientSize = new Size(700, 338); - Controls.Add(generatePassword); - Controls.Add(removeProfile); - Controls.Add(addProfile); - Controls.Add(profileSelection); - Controls.Add(resultList); - Controls.Add(searchBox); + Controls.Add(GeneratePassword); + Controls.Add(DeleteProfile); + Controls.Add(AddProfile); + Controls.Add(ProfileSelection); + Controls.Add(ResultList); + Controls.Add(SearchBox); Margin = new Padding(3, 2, 3, 2); Name = "MainForm"; Text = "Password Manager"; @@ -123,11 +123,11 @@ #endregion - private TextBox searchBox; - private PasswordListBox resultList; - private ComboBox profileSelection; - private Button addProfile; - private Button removeProfile; - private Button generatePassword; + protected override TextBox SearchBox { get; } + protected override PasswordListBox ResultList { get; } + protected override ComboBox ProfileSelection { get; } + protected override Button AddProfile { get; } + protected override Button DeleteProfile { get; } + protected override Button GeneratePassword { get; } } } \ No newline at end of file diff --git a/Password Manager/MainForm.cs b/Password Manager/MainForm.cs index 0bdf045..97c0c25 100644 --- a/Password Manager/MainForm.cs +++ b/Password Manager/MainForm.cs @@ -1,61 +1,43 @@ namespace Password_Manager { - public delegate void ProfileChanges(string profileName); - public delegate string[] ProfileList(); - public delegate void Save(); - public partial class MainForm : Form + sealed public partial class MainForm : PasswordManagerForm { - public event ProfileDataRequest? CurrentProfilePathRequest; - public event ProfileDataRequest? CurrentProfileNameRequest; - public event ProfileList? CurrentProfileListRequest; - public event ProfileChanges? CurrentProfileChanged; - public event Save? SaveRequest; + public override event ProfileDataRequest CurrentProfilePathRequest; + public override event ProfileDataRequest CurrentProfileNameRequest; + public override event ProfileList CurrentProfileListRequest; + public override event ProfileChange CurrentProfileChanged; + public override event Save SaveRequest; + public override event NewProfile NewProfileRequest; - public MainForm(ProfileDataRequest CurrentProfileNameRequest, ProfileDataRequest CurrentProfilePathRequest, ProfileList CurrentProfileListRequest, ProfileChanges CurrentProfileChanged) + public MainForm(ProfileDataRequest CurrentProfileNameRequest, ProfileDataRequest CurrentProfilePathRequest, ProfileList CurrentProfileListRequest, ProfileChange CurrentProfileChanged, Save SaveRequest, NewProfile NewProfileRequest) + : base(CurrentProfileNameRequest, CurrentProfilePathRequest, CurrentProfileListRequest, CurrentProfileChanged, SaveRequest, NewProfileRequest) { - this.CurrentProfileNameRequest = CurrentProfileNameRequest; - this.CurrentProfilePathRequest = CurrentProfilePathRequest; - this.CurrentProfileListRequest = CurrentProfileListRequest; - this.CurrentProfileChanged = CurrentProfileChanged; InitializeComponent(); - LoadCurrentProfile(); - - foreach (string s in CurrentProfileListRequest?.Invoke()) - { - profileSelection.Items.Add(s); - } - profileSelection.SelectedIndex = 0; - - SaveRequest?.Invoke(); + RefreshCurrentProfile(); + SaveRequest(); } - private void LoadCurrentProfile() - { - this.Text = CurrentProfileNameRequest?.Invoke(); - resultList.ReloadResults(); - } - - private void ChangeProfile(object sender, EventArgs e) - { - CurrentProfileChanged?.Invoke(profileSelection.Text); - - foreach (string s in CurrentProfileListRequest?.Invoke()) - { - profileSelection.Items.Add(s); - } - } - - private void AddProfile(object sender, EventArgs e) + private void OpenProfileCreator(object sender, EventArgs e) { NewProfileForm npf = new NewProfileForm(); - npf.ReloadPasswordsRequest += () => resultList.ReloadResults(); - npf.Show(); + npf.ReloadMainFormRequest += () => RefreshCurrentProfile(); + npf.SaveRequest += this.SaveRequest; + npf.NewProfileRequest += this.NewProfileRequest; + npf.ShowDialog(); } - private void Generate(object sender, EventArgs e) + private void OpenPasswordGenerator(object sender, EventArgs e) { - GeneratePassword gp = new GeneratePassword(searchBox.Text, CurrentProfilePathRequest?.Invoke()); - gp.Show(); + string? tmp = CurrentProfilePathRequest(); + if (tmp != null) + { + GeneratePassword gp = new GeneratePassword(SearchBox.Text, tmp); + gp.ShowDialog(); + } + else + { + MessageBox.Show("No path specified", "Event error", MessageBoxButtons.OK, MessageBoxIcon.Error); + } } } } \ No newline at end of file diff --git a/Password Manager/NewProfileForm.cs b/Password Manager/NewProfileForm.cs index f3d1222..4bb854e 100644 --- a/Password Manager/NewProfileForm.cs +++ b/Password Manager/NewProfileForm.cs @@ -1,14 +1,16 @@ namespace Password_Manager { - public delegate void NewProfile(string profileName, string profilePath); public delegate void ReloadPasswords(); public partial class NewProfileForm : Form { - public event NewProfile NewProfileRequest; - public event ReloadPasswords ReloadPasswordsRequest; + public event NewProfile? NewProfileRequest; + public event ReloadPasswords? ReloadMainFormRequest; + public event Save? SaveRequest; public NewProfileForm() { + //test + MessageBox.Show(this.Parent.Text, this.Parent.Text); InitializeComponent(); } @@ -26,13 +28,15 @@ if (nameTextBox.Text != "" && pathTextBox.Text != "") { NewProfileRequest?.Invoke(nameTextBox.Text, pathTextBox.Text); - ReloadPasswordsRequest?.Invoke(); + ReloadMainFormRequest?.Invoke(); this.Close(); } else { MessageBox.Show("You must fill in all fields to continue.", "Error: Empty fields", MessageBoxButtons.OK, MessageBoxIcon.Error); } + + SaveRequest?.Invoke(); } private void Cancel(object sender, EventArgs e) diff --git a/Password Manager/Password Manager.csproj.user b/Password Manager/Password Manager.csproj.user index b307696..f096714 100644 --- a/Password Manager/Password Manager.csproj.user +++ b/Password Manager/Password Manager.csproj.user @@ -13,5 +13,8 @@ Component + + Form + \ No newline at end of file diff --git a/Password Manager/PasswordManagerForm.cs b/Password Manager/PasswordManagerForm.cs new file mode 100644 index 0000000..c7e22a0 --- /dev/null +++ b/Password Manager/PasswordManagerForm.cs @@ -0,0 +1,61 @@ +namespace Password_Manager +{ + public delegate void ProfileChange(string profileName); //Fires when we want to change the CurrentProfile field of ProfileHandler based on the combobox selection + public delegate string[] ProfileList(); //Fires when we need a list of Profile names, like for the combobox items + public delegate void Save(); //Fire whenever we want to save the current state of profiles + public delegate void NewProfile(string profileName, string profilePath); //Fires whenever a NewProfileForm has requested the creation of a new profile. This just forwards that request to ProfileHandler + + public abstract class PasswordManagerForm : Form + { + protected abstract ComboBox ProfileSelection { get; } + protected abstract PasswordListBox ResultList { get; } + protected abstract TextBox SearchBox { get; } + protected abstract Button AddProfile { get; } + protected abstract Button DeleteProfile { get; } + protected abstract Button GeneratePassword { get; } + + public abstract event ProfileDataRequest CurrentProfilePathRequest; + public abstract event ProfileDataRequest CurrentProfileNameRequest; + public abstract event ProfileList CurrentProfileListRequest; + public abstract event ProfileChange CurrentProfileChanged; + public abstract event Save SaveRequest; + public abstract event NewProfile NewProfileRequest; + + public PasswordManagerForm( + ProfileDataRequest CurrentProfileNameRequest, + ProfileDataRequest CurrentProfilePathRequest, + ProfileList CurrentProfileListRequest, + ProfileChange CurrentProfileChanged, + Save SaveRequest, + NewProfile NewProfileRequest) + { + this.CurrentProfileNameRequest = CurrentProfileNameRequest; + this.CurrentProfilePathRequest = CurrentProfilePathRequest; + this.CurrentProfileListRequest = CurrentProfileListRequest; + this.CurrentProfileChanged = CurrentProfileChanged; + this.SaveRequest = SaveRequest; + this.NewProfileRequest = NewProfileRequest; + } + + protected virtual void ChangeProfile(object sender, EventArgs e) + { + CurrentProfileChanged(ProfileSelection.Text); + } + + public virtual void RefreshCurrentProfile() + { + ProfileSelection.SelectedIndex = -1; + string[] items = CurrentProfileListRequest(); + for (int i = 0; i < items.Length; i++) + { + ProfileSelection.Items.Add(items[i]); + if (items[i] == CurrentProfileNameRequest()) + { + ProfileSelection.SelectedIndex = i; + } + } + this.Text = CurrentProfileNameRequest(); + ResultList.ReloadResults(); + } + } +} diff --git a/Password Manager/Profiles/IList.cs b/Password Manager/Profiles/IList.cs index 0d89055..bfba39f 100644 --- a/Password Manager/Profiles/IList.cs +++ b/Password Manager/Profiles/IList.cs @@ -1,6 +1,8 @@ -namespace Profiles +using System.Collections; + +namespace Profiles { - abstract class IList + abstract class IList : IEnumerable { protected T[] list; @@ -32,5 +34,15 @@ { list = new T[0]; } + + public IEnumerator GetEnumerator() + { + return ((IEnumerable)list).GetEnumerator(); + } + + IEnumerator IEnumerable.GetEnumerator() + { + return list.GetEnumerator(); + } } } diff --git a/Password Manager/Profiles/ProfileHandler.cs b/Password Manager/Profiles/ProfileHandler.cs index d14d3f2..df0fc6b 100644 --- a/Password Manager/Profiles/ProfileHandler.cs +++ b/Password Manager/Profiles/ProfileHandler.cs @@ -7,11 +7,23 @@ namespace Profiles { public static Profile CurrentProfile; public static ProfileList ListOfProfiles; - private static string filePath = SpecialDirectories.CurrentUserApplicationData + "Profiles.csv"; + private static string filePath = SpecialDirectories.CurrentUserApplicationData + "\\Profiles.csv"; + + public static void AddProfile(string profileName, string profilePath) + { + ListOfProfiles.Add(new Profile(profileName, profilePath)); + ChangeProfiles(profileName); + } public static void ChangeProfiles(string profileName) { - CurrentProfile = ListOfProfiles.SearchByName(profileName); + try + { + CurrentProfile = ListOfProfiles.SearchByName(profileName); + } catch (ProfileNotFoundException) + { + MessageBox.Show("The selected profile cannot be found", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); + } } public static void Init() @@ -20,14 +32,14 @@ namespace Profiles if (File.Exists(filePath)) { - LoadProfiles(); + LoadProfilesFile(); } else { - CreateProfiles(); + CreateProfilesFile(); } } - private static void LoadProfiles() + private static void LoadProfilesFile() { try { @@ -43,7 +55,7 @@ namespace Profiles { //File is messed up, creating new one sr.Close(); - CreateProfiles(); + CreateProfilesFile(); break; } } @@ -56,11 +68,53 @@ namespace Profiles private static void TrimLastLine() { - List lines = File.ReadAllLines(filePath).ToList(); - File.WriteAllLines(filePath, lines.GetRange(0, lines.Count - 1).ToArray()); + try + { + StreamReader sr = new StreamReader(filePath); + List validLines = new List(); + + while (!sr.EndOfStream) + { + string? line = sr.ReadLine(); + if (line != null) + { + validLines.Add(line); + } + } + + sr.Close(); + File.WriteAllLines(filePath, validLines); + } catch (IOException e) + { + MessageBox.Show(e.ToString(), "IO Error", MessageBoxButtons.OK, MessageBoxIcon.Error); + } catch (UnauthorizedAccessException e) + { + MessageBox.Show(e.ToString(), "Can't access profiles file", MessageBoxButtons.OK, MessageBoxIcon.Error); + } } - private static void CreateProfiles() + public static void SaveProfiles() + { + try + { + StreamWriter sw = new StreamWriter(filePath); + + foreach (Profile p in ListOfProfiles) + { + sw.WriteLine($"{p.Name},{p.Path}"); + } + + sw.Close(); + } catch (IOException e) + { + MessageBox.Show(e.ToString(), "IO Error", MessageBoxButtons.OK, MessageBoxIcon.Error); + } catch (UnauthorizedAccessException e) + { + MessageBox.Show(e.ToString(), "Can't access profiles file", MessageBoxButtons.OK, MessageBoxIcon.Error); + } + } + + private static void CreateProfilesFile() { try { @@ -69,10 +123,9 @@ namespace Profiles string[] parameters = new string[2]; NewProfileForm np = new NewProfileForm(); - Profile firstProfile = null; np.NewProfileRequest += (string profileName, string profilePath) => { - firstProfile = new Profile(profileName, profilePath); + Profile firstProfile = new Profile(profileName, profilePath); ListOfProfiles.Add(firstProfile); ChangeProfiles(firstProfile.Name); sw.WriteLine($"{firstProfile.Name},{firstProfile.Path}"); diff --git a/Password Manager/Profiles/ProfileList.cs b/Password Manager/Profiles/ProfileList.cs index ee8073e..5bc1a3c 100644 --- a/Password Manager/Profiles/ProfileList.cs +++ b/Password Manager/Profiles/ProfileList.cs @@ -38,7 +38,7 @@ public override Profile SearchByName(string name) { - Profile result = null; + Profile? result = null; for (int i = 0; i < this.Length; i++) { diff --git a/Password Manager/Program.cs b/Password Manager/Program.cs index 6e90c91..5105163 100644 --- a/Password Manager/Program.cs +++ b/Password Manager/Program.cs @@ -2,7 +2,7 @@ using Profiles; namespace Password_Manager { - public delegate string ProfileDataRequest(); + public delegate string ProfileDataRequest(); //Fire whenever a specific field of ProfileHandler.CurrentProfile is needed internal static class Program { /// @@ -13,7 +13,6 @@ namespace Password_Manager { ApplicationConfiguration.Initialize(); ProfileHandler.Init(); - Application.Run(mainForm); } @@ -21,7 +20,9 @@ namespace Password_Manager () => ProfileHandler.CurrentProfile.Name, () => ProfileHandler.CurrentProfile.Path, () => ProfileHandler.ListOfProfiles.GetNameList(), - (profileName) => ProfileHandler.ChangeProfiles(profileName) + (profileName) => ProfileHandler.ChangeProfiles(profileName), + () => ProfileHandler.SaveProfiles(), + (profileName, profilePath) => ProfileHandler.AddProfile(profileName, profilePath) ); //needed at creation so that MainForm may pass this method down to other classes in its constructor } } \ No newline at end of file