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 b6703d9..6b2ed91 100644
Binary files a/.vs/Password Manager/DesignTimeBuild/.dtbcache.v2 and b/.vs/Password Manager/DesignTimeBuild/.dtbcache.v2 differ
diff --git a/.vs/Password Manager/v17/.suo b/.vs/Password Manager/v17/.suo
index 22215e2..5991f33 100644
Binary files a/.vs/Password Manager/v17/.suo and b/.vs/Password Manager/v17/.suo differ
diff --git a/Password Manager/MainForm.Designer.cs b/Password Manager/MainForm.Designer.cs
index 2f7fbb8..f7b2773 100644
--- a/Password Manager/MainForm.Designer.cs
+++ b/Password Manager/MainForm.Designer.cs
@@ -1,6 +1,6 @@
namespace Password_Manager
{
- partial class MainForm
+ sealed partial class MainForm : PasswordManagerForm
{
///
/// 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