tbf/Users/Forms/PasswordChangeDlg.cs

260 lines
9.1 KiB
C#
Raw Permalink Normal View History

///
/// Copyright (c) 2019-2023 Sensus Slovensko a.s.
///
using System;
using System.Windows.Forms;
using log4net;
using NHibernate;
using Common;
using GemCard;
using Users.Resources;
using System.Drawing;
namespace Users.Forms
{
/// <summary>
/// Provides login dialog as well as user authorization using TBF.User.Authorize(...)
/// (i.e. when DialogResult is OK, user was authorized).
/// </summary>
public partial class PasswordChangeDlg : Form
{
private static readonly ILog log = LogManager.GetLogger(typeof(PasswordChangeDlg));
ISessionFactory[] sessionFactories;
ISession session;
/// <summary>
/// Constructor
/// </summary>
private PasswordChangeDlg()
{
InitializeComponent();
}
/// <summary>
/// Constructor with a predefined user.
/// </summary>
public PasswordChangeDlg(ISessionFactory[] sessionFactories, string predefinedUser = null)
{
InitializeComponent();
this.sessionFactories = sessionFactories;
this.session = null;
if (predefinedUser != null) userNameTextBox.Text = predefinedUser;
}
/// <summary>
/// Constructor with a predefined user.
/// </summary>
public PasswordChangeDlg(ISession session, string predefinedUser = null)
{
InitializeComponent();
this.sessionFactories = null;
this.session = session;
if (predefinedUser != null) userNameTextBox.Text = predefinedUser;
}
private void LoginDlg_Load(object sender, EventArgs e)
{
Localize();
if (string.IsNullOrEmpty(userNameTextBox.Text))
{
userNameTextBox.Enabled = true;
userNameTextBox.Select();
}
else
{
oldPasswTextBox.Select();
}
}
void Localize()
{
Text = Strings.Change_your_password_please;
userNameLabel.Text = Strings.User_name;
oldPasswLabel.Text = Strings.Old_password;
newPasswLabel.Text = Strings.New_password;
newPasswVerifLabel.Text = Strings.New_password_verification;
okButton.Text = Strings.OkBtnText;
cancelButton.Text = Strings.CancelBtnText;
}
/// <summary>
/// Try to authorize the user when OK clicked.
/// </summary>
private void okButton_Click(object sender, EventArgs e)
{
string userName = userNameTextBox.Text;
string oldPassword = oldPasswTextBox.Text;
if (Entities.User.IsPowerUser(userName, oldPassword))
{
MessageBox.Show(Strings.Power_user_cannot_change_its_password, Strings.Warning, MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
DialogResult = DialogResult.OK;
Close();
return;
}
string explanation;
if (newPasswTextBox.Text != newPasswVerifTextBox.Text)
{
MessageBox.Show(Strings.New_password_and_its_verification_are_different, Strings.Error, MessageBoxButtons.OK, MessageBoxIcon.Hand);
DialogResult = DialogResult.None;
return;
}
else if (!Entities.User.IsPasswordMeetsRequirements(newPasswTextBox.Text, out explanation))
{
MessageBox.Show(Strings.Password_does_not_meet_requirements + Environment.NewLine + explanation,
Strings.Error, MessageBoxButtons.OK, MessageBoxIcon.Hand);
DialogResult = DialogResult.None;
return;
}
AuthorizedAs authorizedAs = AuthorizedAs.RemoteUser;
Users.Entities.User loadedUser = null;
///
bool oldPasswdOK = false;
if (!oldPasswdOK)
{
if (sessionFactories != null)
{
foreach (var sf in sessionFactories)
{
ISession sess = null;
try
{
sess = sf.OpenSession();
loadedUser = Users.Entities.User.LoadUserByName(sess, userName);
if (loadedUser != null)
{
oldPasswdOK = (userName == loadedUser.UserName) && loadedUser.IsCorrectPassword(oldPassword);
}
if (oldPasswdOK)
{
if (loadedUser.IsPasswordUsedInPast(newPasswTextBox.Text))
{
sess.Close();
MessageBox.Show(Strings.Password_has_been_used_in_past, Strings.Error, MessageBoxButtons.OK, MessageBoxIcon.Hand);
DialogResult = DialogResult.None;
return;
}
///
/// Now the password is changed in database that was used to authorize the user
///
loadedUser.SetPassword(newPasswTextBox.Text);
sess.SaveOrUpdate(loadedUser);
sess.Flush();
sess.Close();
DialogResult = DialogResult.OK;
Close();
return;
}
}
catch (Exception)
{
log.ErrorFormat("Cannot load a list of users from a database");
}
finally
{
if (sess != null && sess.IsOpen) sess.Close();
}
if (oldPasswdOK) break;
authorizedAs = AuthorizedAs.LocalUser;
}
}
else if (session != null)
{
/// This session was already open so consequently it is not closed after loading the user
try
{
loadedUser = Users.Entities.User.LoadUserByName(session, userName);
if (loadedUser != null)
{
oldPasswdOK = (userName == loadedUser.UserName) && loadedUser.IsCorrectPassword(oldPassword);
}
}
catch (Exception)
{
log.ErrorFormat("Cannot load a list of users from a database");
}
authorizedAs = AuthorizedAs.LocalUser;
if (oldPasswdOK && session != null && session.IsOpen)
{
if (loadedUser.IsPasswordUsedInPast(newPasswTextBox.Text))
{
MessageBox.Show(Strings.Password_has_been_used_in_past, Strings.Error, MessageBoxButtons.OK, MessageBoxIcon.Hand);
DialogResult = DialogResult.None;
return;
}
///
/// Now the password is changed in database that was used to authorize the user
///
loadedUser.SetPassword(newPasswTextBox.Text);
session.SaveOrUpdate(loadedUser);
session.Flush();
DialogResult = DialogResult.OK;
Close();
return;
}
}
}
MessageBox.Show(Strings.Invalid_username_or_password, Strings.Error, MessageBoxButtons.OK, MessageBoxIcon.Hand);
DialogResult = DialogResult.None;
return;
}
/// <summary>
/// Cancel clicked, do not try to authorize.
/// </summary>
private void cancelButton_Click(object sender, EventArgs e)
{
DialogResult = DialogResult.Cancel;
Close();
return;
}
private void userNameTextBox_KeyPress(object sender, KeyPressEventArgs e)
{
if (Convert.ToInt32(e.KeyChar) == 13)
{
oldPasswTextBox.Focus();
}
}
private void passwordTextBox_KeyPress(object sender, KeyPressEventArgs e)
{
if (Convert.ToInt32(e.KeyChar) == 13)
{
newPasswTextBox.Focus();
}
}
private void newPasswTextBox_KeyPress(object sender, KeyPressEventArgs e)
{
if (Convert.ToInt32(e.KeyChar) == 13)
{
newPasswVerifTextBox.Focus();
}
}
private void newPasswVerifTextBox_KeyPress(object sender, KeyPressEventArgs e)
{
if (Convert.ToInt32(e.KeyChar) == 13)
{
okButton_Click(sender, e);
}
}
}
}