-
-
Notifications
You must be signed in to change notification settings - Fork 14
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #34 from prettyokay-software/password-change
Add password change functionality
- Loading branch information
Showing
11 changed files
with
346 additions
and
9 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,106 @@ | ||
using System; | ||
using System.DirectoryServices; | ||
using System.DirectoryServices.AccountManagement; | ||
|
||
namespace SuperLauncher | ||
{ | ||
public static class AccountInfo | ||
{ | ||
// When was last notification sent? | ||
private static DateTime lastExpirationNotify = DateTime.MinValue; | ||
// Save this to avoid polling every time the tooltip is opened | ||
public static DateTime ExpirationDate; | ||
|
||
/// <summary> | ||
/// Get date from Active Directory when password expires | ||
/// </summary> | ||
/// <returns></returns> | ||
public static DateTime GetPasswordExpirationDate() | ||
{ | ||
using (var userEntry = new DirectoryEntry("WinNT://" + Environment.UserDomainName + '/' + Environment.UserName + ",user")) | ||
{ | ||
|
||
DateTime time = (DateTime)userEntry.InvokeGet("PasswordExpirationDate"); | ||
return time.ToLocalTime(); | ||
} | ||
} | ||
|
||
// This gets the account expiration, not the password expiration | ||
//public static DateTime GetPasswordExpirationDate() | ||
//{ | ||
// using PrincipalContext pc = new PrincipalContext(ContextType.Domain); | ||
// using UserPrincipal user = UserPrincipal.FindByIdentity(pc, IdentityType.SamAccountName, Environment.UserName); | ||
|
||
// DateTime time = (DateTime)user.AccountExpirationDate; | ||
// return time.ToLocalTime(); | ||
//} | ||
|
||
/// <summary> | ||
/// Get the number of whole days until the password of the user running the application expires | ||
/// </summary> | ||
public static int GetPasswordExpirationDays() | ||
{ | ||
return (GetPasswordExpirationDate() - DateTime.Now).Days; | ||
} | ||
|
||
/// <summary> | ||
/// Check whether the provided password is correct for the current user | ||
/// </summary> | ||
/// <param name="password"></param> | ||
/// <returns></returns> | ||
/// | ||
// Unneeded when using System.DirectoryServices.AccountManagement.ChangePassword below | ||
public static bool ValidatePassword(string password) | ||
{ | ||
using (PrincipalContext pc = new PrincipalContext(ContextType.Domain)) | ||
{ | ||
// validate the credentials | ||
bool isValid = pc.ValidateCredentials(Environment.UserName, password); | ||
return isValid; | ||
} | ||
} | ||
|
||
public static string ChangePassword(string currentPassword, string newPassword) | ||
{ | ||
try | ||
{ | ||
using PrincipalContext pc = new PrincipalContext(ContextType.Domain); | ||
using UserPrincipal user = UserPrincipal.FindByIdentity(pc, IdentityType.SamAccountName, Environment.UserName); | ||
user.ChangePassword(currentPassword, newPassword); | ||
user.Save(); | ||
|
||
return "Success"; | ||
} | ||
catch (PasswordException ep) | ||
{ | ||
return ep.Message; | ||
} | ||
catch (Exception ex) | ||
{ | ||
return ex.Message; | ||
} | ||
} | ||
|
||
public static void AccountMonitorTask(Object source, System.Timers.ElapsedEventArgs e) | ||
{ | ||
// Update saved expiration date | ||
ExpirationDate = GetPasswordExpirationDate(); | ||
|
||
NotifyExpiration(GetPasswordExpirationDays()); | ||
} | ||
|
||
/// <summary> | ||
/// Notify at startup and every 12 hours | ||
/// </summary> | ||
/// <param name="daysRemain">number of days before password expires</param> | ||
public static void NotifyExpiration(int daysRemain) | ||
{ | ||
//(daysRemain <= 10) && | ||
if ((daysRemain <= 10) && (lastExpirationNotify.AddHours(12) < DateTime.Now)) | ||
{ | ||
Shared.SendDesktopToast("Password Expiration", $"The password for {Environment.UserName} expires in {daysRemain} days"); | ||
lastExpirationNotify = DateTime.Now; | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
<Window x:Class="SuperLauncher.ModernLauncherPasswordChangeUI" | ||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" | ||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" | ||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" | ||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" | ||
xmlns:local="clr-namespace:SuperLauncher" | ||
mc:Ignorable="d" | ||
Title="Super Launcher - Update Password" | ||
WindowStartupLocation="CenterScreen" | ||
WindowStyle="None" | ||
FontFamily="{DynamicResource Font}" | ||
Loaded="Window_Loaded" | ||
Height="379" | ||
Width="347" | ||
Topmost="True" > | ||
<Window.Resources> | ||
<ResourceDictionary> | ||
<ResourceDictionary.MergedDictionaries> | ||
<ResourceDictionary Source="/Themes/WinUI.xaml" /> | ||
</ResourceDictionary.MergedDictionaries> | ||
</ResourceDictionary> | ||
</Window.Resources> | ||
<WindowChrome.WindowChrome> | ||
<WindowChrome | ||
CaptionHeight="0" | ||
GlassFrameThickness="-1" | ||
ResizeBorderThickness="0" | ||
UseAeroCaptionButtons="true" | ||
/> | ||
</WindowChrome.WindowChrome> | ||
<Grid Background="{DynamicResource PanelColorBrush}"> | ||
<Grid x:Name="Grid" Background="{DynamicResource AcrylicNoise}"> | ||
<Label Content="Change Password" Foreground="{DynamicResource TextColorBrush}" FontSize="20" FontWeight="Normal" FontStyle="Normal" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="17,46,0,0" /> | ||
<Label Content="Super Launcher - Update Password" Foreground="{DynamicResource TextColorBrush}" FontWeight="Normal" FontStyle="Normal" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="32,6,0,0" /> | ||
<Label x:Name="LBUser" Content="Enter the current and new password for " Foreground="{DynamicResource TextColorBrush}" FontWeight="Normal" FontStyle="Normal" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="18,93,0,0" /> | ||
<Label Content="" Foreground="{DynamicResource TextColorBrush}" FontFamily="{DynamicResource Icons}" FontWeight="Normal" FontStyle="Normal" FontSize="16" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="6,6,0,0" /> | ||
<PasswordBox x:Name="TBCurrentPassword" Tag="" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="23,138,0,0" Width="298" Height="34" ToolTip="Current Password" /> | ||
<PasswordBox x:Name="TBNewPassword" Tag="" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="23,185,0,0" Width="298" Height="34" KeyDown="TBPassword_KeyDown" PasswordChanged="TB_PasswordChanged" /> | ||
<PasswordBox x:Name="TBConfirmPassword" Tag="" HorizontalAlignment="Center" VerticalAlignment="Top" Margin="0,233,0,0" Width="298" Height="34" KeyDown="TBPassword_KeyDown" PasswordChanged="TB_PasswordChanged" BorderThickness="1,1,1,17"/> | ||
<Button x:Name="BtnOK" IsEnabled="False" Content="Apply" HorizontalAlignment="Left" Margin="23,315,0,0" VerticalAlignment="Top" Height="35" Width="141" Click="BtnOK_Click" /> | ||
<Button x:Name="BtnCancel" Content="Cancel" HorizontalAlignment="Left" Margin="180,315,0,0" VerticalAlignment="Top" Height="35" Width="141" Click="BtnCancel_Click" /> | ||
<Border Name="TBConfirm_Border" BorderThickness="2,2,2,2" Margin="24,236,26,115" Opacity="0.85" /> | ||
<Label Name="LBError" Content="Error:" FontWeight="Normal" FontStyle="Normal" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="23,272,0,0" Visibility="Hidden"> | ||
<Label.Foreground> | ||
<SolidColorBrush Color="#FFAB0202"/> | ||
</Label.Foreground> | ||
</Label> | ||
</Grid> | ||
</Grid> | ||
</Window> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,84 @@ | ||
using System.Windows; | ||
using System.Windows.Input; | ||
using System; | ||
|
||
namespace SuperLauncher | ||
{ | ||
/// <summary> | ||
/// Interaction logic for ModernLauncherPasswordChangeUI.xaml | ||
/// </summary> | ||
public partial class ModernLauncherPasswordChangeUI : Window | ||
{ | ||
public ModernLauncherPasswordChangeUI() | ||
{ | ||
InitializeComponent(); | ||
} | ||
private void Window_Loaded(object sender, RoutedEventArgs e) | ||
{ | ||
Shared.EnableAcrylic(this); | ||
Shared.SetWindowColor(this); | ||
LBUser.Content += Environment.UserName; | ||
TBCurrentPassword.Focus(); | ||
} | ||
private void BtnCancel_Click(object sender, RoutedEventArgs e) | ||
{ | ||
Close(); | ||
} | ||
private void BtnOK_Click(object sender, RoutedEventArgs e) | ||
{ | ||
|
||
string result = AccountInfo.ChangePassword(TBCurrentPassword.Password, TBConfirmPassword.Password); | ||
|
||
if (result != "Success") | ||
{ | ||
LBError.Content = result; | ||
LBError.Visibility = Visibility.Visible; | ||
return; | ||
} | ||
|
||
if (Settings.Default.RememberMe) | ||
{ | ||
CredentialManager.CREDENTIAL cred = new() | ||
{ | ||
TargetName = "Super Launcher", | ||
Type = CredentialManager.CredType.CRED_TYPE_GENERIC, | ||
Persist = CredentialManager.CredPersist.CRED_PERSIST_LOCAL_MACHINE, | ||
UserName = RunAsHelper.GetOriginalInvokerDomainWithUserName(), | ||
Password = TBConfirmPassword.Password | ||
}; | ||
CredentialManager.CredWriteA(cred, CredentialManager.CredWriteFlags.NONE); | ||
} | ||
Program.ModernApplicationShutdown(); | ||
} | ||
private void TBPassword_KeyDown(object sender, KeyEventArgs e) | ||
{ | ||
if (e.Key == Key.Enter) BtnOK_Click(null, null); | ||
|
||
} | ||
|
||
// This highlights the textbox if they didn't match | ||
private void TB_PasswordChanged(object sender, RoutedEventArgs e) | ||
{ | ||
if (TBNewPassword.Password.Length <= 1) | ||
{ | ||
BtnOK.IsEnabled = false; | ||
TBConfirm_Border.BorderBrush = System.Windows.Media.Brushes.Transparent; | ||
return; | ||
} | ||
|
||
if (TBNewPassword.Password != TBConfirmPassword.Password) | ||
{ | ||
TBConfirm_Border.BorderBrush = System.Windows.Media.Brushes.Red; | ||
BtnOK.IsEnabled = false; | ||
LBError.Content = "New and confirm passwords don't match"; | ||
LBError.Visibility = Visibility.Visible; | ||
} | ||
else | ||
{ | ||
BtnOK.IsEnabled = true; | ||
TBConfirm_Border.BorderBrush = System.Windows.Media.Brushes.Green; | ||
LBError.Visibility = Visibility.Hidden; | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.