Skip to content

Commit 32c40ef

Browse files
authored
Merge pull request #68 from BornToBeRoot/credentialmanager-lockui
Lock credential interface
2 parents 32b6c49 + 5d25b4c commit 32c40ef

6 files changed

Lines changed: 216 additions & 75 deletions

File tree

Source/NETworkManager/Resources/Localization/Resources.de-DE.xaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -319,6 +319,8 @@
319319
<system:String x:Key="String_Multicast">Multicast</system:String>
320320
<system:String x:Key="String_CredentialSecuritySupportProvider">Aktiviere Credential Security Support Provider</system:String>
321321
<system:String x:Key="String_AuthenticationLevel">Authentifizierungsebene</system:String>
322+
<system:String x:Key="String_RemainingTime">Verbleibende Zeit</system:String>
323+
<system:String x:Key="String_UserInterfaceLocked">Benutzeroberfläche gesperrt!</system:String>
322324

323325
<!-- Help message -->
324326
<system:String x:Key="String_HelpMessage_ParameterHelp">Zeigt diesen Dialog an.</system:String>

Source/NETworkManager/Resources/Localization/Resources.en-US.xaml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -319,7 +319,9 @@
319319
<system:String x:Key="String_Multicast">Multicast</system:String>
320320
<system:String x:Key="String_CredentialSecuritySupportProvider">Enable Credential Security Support Provider</system:String>
321321
<system:String x:Key="String_AuthenticationLevel">Authentication level</system:String>
322-
322+
<system:String x:Key="String_RemainingTime">Remaining time</system:String>
323+
<system:String x:Key="String_UserInterfaceLocked">User interface locked!</system:String>
324+
323325
<!-- Help message -->
324326
<system:String x:Key="String_HelpMessage_ParameterHelp">Displays this dialog.</system:String>
325327
<system:String x:Key="String_HelpMessage_ParameterResetSettings">Reset all settings.</system:String>

Source/NETworkManager/ViewModels/Settings/CredentialsViewModel.cs

Lines changed: 129 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,6 @@
77
using MahApps.Metro.Controls.Dialogs;
88
using NETworkManager.ViewModels.Dialogs;
99
using NETworkManager.Views.Dialogs;
10-
using System.Diagnostics;
11-
using NETworkManager.Helpers;
1210
using System;
1311
using System.Windows.Threading;
1412

@@ -18,6 +16,7 @@ public class CredentialsViewModel : ViewModelBase
1816
{
1917
#region Variables
2018
private IDialogCoordinator dialogCoordinator;
19+
DispatcherTimer _dispatcherTimer;
2120

2221
private bool _credentialsFileExists;
2322
public bool CredentialsFileExists
@@ -47,6 +46,35 @@ public bool CredentialsLoaded
4746
}
4847
}
4948

49+
// Indicates that the UI is locked
50+
private bool _locked = true;
51+
public bool Locked
52+
{
53+
get { return _locked; }
54+
set
55+
{
56+
if (value == _locked)
57+
return;
58+
59+
_locked = value;
60+
OnPropertyChanged();
61+
}
62+
}
63+
64+
private TimeSpan _timeRemaining;
65+
public TimeSpan TimeRemaining
66+
{
67+
get { return _timeRemaining; }
68+
set
69+
{
70+
if (value == _timeRemaining)
71+
return;
72+
73+
_timeRemaining = value;
74+
OnPropertyChanged();
75+
}
76+
}
77+
5078
ICollectionView _credentials;
5179
public ICollectionView Credentials
5280
{
@@ -106,12 +134,31 @@ public CredentialsViewModel(IDialogCoordinator instance)
106134
};
107135

108136
CheckCredentialsLoaded();
137+
138+
// Set up dispatcher timer
139+
_dispatcherTimer = new DispatcherTimer();
140+
_dispatcherTimer.Tick += _dispatcherTimer_Tick;
141+
_dispatcherTimer.Interval = new TimeSpan(0, 0, 1);
109142
}
110143

111-
private void CheckCredentialsLoaded()
144+
private void _dispatcherTimer_Tick(object sender, EventArgs e)
112145
{
113-
CredentialsFileExists = File.Exists(CredentialManager.GetCredentialsFilePath());
114-
CredentialsLoaded = CredentialManager.Loaded;
146+
if (TimeRemaining == TimeSpan.Zero)
147+
TimerLockUIStop();
148+
149+
TimeRemaining = TimeRemaining.Add(TimeSpan.FromSeconds(-1));
150+
}
151+
152+
public void CheckCredentialsLoaded()
153+
{
154+
if (!CredentialsLoaded)
155+
{
156+
// If file exists, view to decrypt the file is shown
157+
CredentialsFileExists = File.Exists(CredentialManager.GetCredentialsFilePath());
158+
159+
// IF credentials are loaded, view to add/edit/remove is shown
160+
CredentialsLoaded = CredentialManager.Loaded;
161+
}
115162
}
116163
#endregion
117164

@@ -137,6 +184,8 @@ private async void SetMasterPasswordAction()
137184
CredentialManager.CredentialsChanged = true; // Save to file when application is closed
138185

139186
CheckCredentialsLoaded();
187+
188+
TimerLockUIStart();
140189
}, instance =>
141190
{
142191
dialogCoordinator.HideMetroDialogAsync(this, customDialog);
@@ -170,6 +219,8 @@ private async void DecryptAndLoadAction()
170219
await dialogCoordinator.ShowMessageAsync(this, Application.Current.Resources["String_Header_WrongPassword"] as string, Application.Current.Resources["String_WrongPasswordDecryptionFailed"] as string, MessageDialogStyle.Affirmative, AppearanceManager.MetroDialog);
171220

172221
CheckCredentialsLoaded();
222+
223+
TimerLockUIStart();
173224
}, instance =>
174225
{
175226
dialogCoordinator.HideMetroDialogAsync(this, customDialog);
@@ -190,58 +241,28 @@ public ICommand ChangeMasterPasswordCommand
190241

191242
private async void ChangeMasterPasswordAction()
192243
{
193-
CustomDialog customDialogMasterPassword = new CustomDialog()
244+
CustomDialog customDialogSetMasterPassword = new CustomDialog()
194245
{
195-
Title = Application.Current.Resources["String_Header_MasterPassword"] as string
246+
Title = Application.Current.Resources["String_Header_SetMasterPassword"] as string
196247
};
197248

198-
CredentialsMasterPasswordViewModel credentialsMasterPasswordViewModel = new CredentialsMasterPasswordViewModel(async instance =>
249+
CredentialsSetMasterPasswordViewModel credentialsSetMasterPasswordViewModel = new CredentialsSetMasterPasswordViewModel(instance =>
199250
{
200-
await dialogCoordinator.HideMetroDialogAsync(this, customDialogMasterPassword);
251+
dialogCoordinator.HideMetroDialogAsync(this, customDialogSetMasterPassword);
201252

202-
if (CredentialManager.VerifyMasterPasword(instance.Password))
203-
{
204-
CustomDialog customDialogSetMasterPassword = new CustomDialog()
205-
{
206-
Title = Application.Current.Resources["String_Header_SetMasterPassword"] as string
207-
};
208-
209-
CredentialsSetMasterPasswordViewModel credentialsSetMasterPasswordViewModel = new CredentialsSetMasterPasswordViewModel(instance2 =>
210-
{
211-
dialogCoordinator.HideMetroDialogAsync(this, customDialogSetMasterPassword);
212-
213-
// Set the new master password
214-
CredentialManager.SetMasterPassword(instance2.Password);
215-
216-
// Save to file
217-
CredentialManager.Save();
218-
}, instance2 =>
219-
{
220-
dialogCoordinator.HideMetroDialogAsync(this, customDialogSetMasterPassword);
221-
});
222-
223-
customDialogSetMasterPassword.Content = new CredentialsSetMasterPasswordDialog
224-
{
225-
DataContext = credentialsSetMasterPasswordViewModel
226-
};
227-
228-
await dialogCoordinator.ShowMetroDialogAsync(this, customDialogSetMasterPassword);
229-
}
230-
else
231-
{
232-
await dialogCoordinator.ShowMessageAsync(this, Application.Current.Resources["String_Header_WrongPassword"] as string, Application.Current.Resources["String_WrongPassword"] as string, MessageDialogStyle.Affirmative, AppearanceManager.MetroDialog);
233-
}
253+
// Set the new master password
254+
CredentialManager.SetMasterPassword(instance.Password);
234255
}, instance =>
235256
{
236-
dialogCoordinator.HideMetroDialogAsync(this, customDialogMasterPassword);
257+
dialogCoordinator.HideMetroDialogAsync(this, customDialogSetMasterPassword);
237258
});
238259

239-
customDialogMasterPassword.Content = new CredentialsMasterPasswordDialog
260+
customDialogSetMasterPassword.Content = new CredentialsSetMasterPasswordDialog
240261
{
241-
DataContext = credentialsMasterPasswordViewModel
262+
DataContext = credentialsSetMasterPasswordViewModel
242263
};
243264

244-
await dialogCoordinator.ShowMetroDialogAsync(this, customDialogMasterPassword);
265+
await dialogCoordinator.ShowMetroDialogAsync(this, customDialogSetMasterPassword);
245266
}
246267

247268
public ICommand AddCommand
@@ -269,6 +290,8 @@ private async void AddAction()
269290
};
270291

271292
CredentialManager.AddCredential(credentialInfo);
293+
294+
TimerLockUIStart(); // Reset timer
272295
}, instance =>
273296
{
274297
dialogCoordinator.HideMetroDialogAsync(this, customDialog);
@@ -310,7 +333,7 @@ private async void EditAction()
310333

311334
CredentialManager.AddCredential(credentialInfo);
312335

313-
Debug.WriteLine(SecureStringHelper.ConvertToString(instance.Password));
336+
TimerLockUIStart(); // Reset timer
314337
}, instance =>
315338
{
316339
dialogCoordinator.HideMetroDialogAsync(this, customDialog);
@@ -341,6 +364,8 @@ private async void DeleteAction()
341364
dialogCoordinator.HideMetroDialogAsync(this, customDialog);
342365

343366
CredentialManager.RemoveCredential(SelectedCredential);
367+
368+
TimerLockUIStart(); // Reset timer
344369
}, instance =>
345370
{
346371
dialogCoordinator.HideMetroDialogAsync(this, customDialog);
@@ -353,6 +378,64 @@ private async void DeleteAction()
353378

354379
await dialogCoordinator.ShowMetroDialogAsync(this, customDialog);
355380
}
381+
382+
public ICommand LockUnlockCommand
383+
{
384+
get { return new RelayCommand(p => LockUnlockAction()); }
385+
}
386+
387+
private async void LockUnlockAction()
388+
{
389+
if (Locked)
390+
{
391+
CustomDialog customDialogMasterPassword = new CustomDialog()
392+
{
393+
Title = Application.Current.Resources["String_Header_MasterPassword"] as string
394+
};
395+
396+
CredentialsMasterPasswordViewModel credentialsMasterPasswordViewModel = new CredentialsMasterPasswordViewModel(async instance =>
397+
{
398+
await dialogCoordinator.HideMetroDialogAsync(this, customDialogMasterPassword);
399+
400+
if (CredentialManager.VerifyMasterPasword(instance.Password))
401+
TimerLockUIStart();
402+
else
403+
await dialogCoordinator.ShowMessageAsync(this, Application.Current.Resources["String_Header_WrongPassword"] as string, Application.Current.Resources["String_WrongPassword"] as string, MessageDialogStyle.Affirmative, AppearanceManager.MetroDialog);
404+
}, instance =>
405+
{
406+
dialogCoordinator.HideMetroDialogAsync(this, customDialogMasterPassword);
407+
});
408+
409+
customDialogMasterPassword.Content = new CredentialsMasterPasswordDialog
410+
{
411+
DataContext = credentialsMasterPasswordViewModel
412+
};
413+
414+
await dialogCoordinator.ShowMetroDialogAsync(this, customDialogMasterPassword);
415+
}
416+
else
417+
{
418+
TimerLockUIStop();
419+
}
420+
}
421+
#endregion
422+
423+
#region Methods
424+
private void TimerLockUIStart()
425+
{
426+
Locked = false;
427+
428+
TimeRemaining = TimeSpan.FromSeconds(10);
429+
430+
_dispatcherTimer.Start();
431+
}
432+
433+
private void TimerLockUIStop()
434+
{
435+
_dispatcherTimer.Stop();
436+
437+
Locked = true;
438+
}
356439
#endregion
357440
}
358441
}

0 commit comments

Comments
 (0)