tbf/SharedDatabase/Forms/TripleLoginDlg.cs

640 lines
22 KiB
C#

///
/// Copyright (c) 2019 Sensus Slovensko a.s.
///
using System;
using System.Drawing;
using System.Windows.Forms;
using Common;
using GemCard;
using SharedDatabase.Entities;
using SharedDatabase.Resources;
namespace SharedDatabase.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 TripleLoginDlg : Form
{
// Private fields
string predefinedUser;
GID[] requiredGroupMembership;
Form parentForm;
bool noDatabase;
Color oriBackColor;
/// Smart card support, card S/N is used as user.Tag
GemCard.CardNative card;
string[] cardReaders;
string smartCardReader;
User authorizedUser1; /// Authorized user 1 or null
User authorizedUser2; /// Authorized user 2 or null
User authorizedUser3; /// Authorized user 3 or null
public LoginMethod Method1;
public LoginMethod Method2;
public LoginMethod Method3;
public string VersionString;
/// <summary>
/// Constructor.
/// </summary>
public TripleLoginDlg()
{
InitializeComponent();
this.Icon = Properties.Resources.TBF_icon;
loginStatePictureBox1.Image = Properties.Resources.questionMark;
loginStatePictureBox2.Image = Properties.Resources.questionMark;
loginStatePictureBox3.Image = Properties.Resources.questionMark;
authorizedUser1 = null;
authorizedUser2 = null;
authorizedUser3 = null;
oriBackColor = BackColor;
}
/// <summary>
/// Constructor with a predefined user.
/// </summary>
public TripleLoginDlg(string predefinedUser, Form parentForm)
: this()
{
this.predefinedUser = predefinedUser;
this.parentForm = parentForm;
userNameTextBox1.Text = predefinedUser;
}
/// <summary>
/// Constructor with two owrkplace names.
/// </summary>
/// <param name="workplace1">Name of workplace A</param>
/// <param name="workplace2">Name of workplace B</param>
public TripleLoginDlg(string workplace1, string workplace2, string workplace3, Form parentForm)
: this()
{
this.parentForm = parentForm;
workplaceGroupBox1.Text = workplace1;
workplaceGroupBox2.Text = workplace2;
workplaceGroupBox3.Text = workplace3;
}
/// <summary>
/// Constructor with 'no Database' flag.
/// </summary>
public TripleLoginDlg(bool noDatabase)
: this()
{
this.noDatabase = noDatabase;
}
/// <summary>
/// Constructor when a specific group membership is required.
/// </summary>
public TripleLoginDlg(GID[] requiredGroupMembership, Form parentForm)
: this()
{
this.requiredGroupMembership = requiredGroupMembership;
this.parentForm = parentForm;
}
/// <summary>
/// Constructor with a predefined user when a specific group membership is required.
/// </summary>
public TripleLoginDlg(string predefinedUser, GID[] requiredGroupMembership, Form parentForm)
: this()
{
this.predefinedUser = predefinedUser;
this.requiredGroupMembership = requiredGroupMembership;
this.parentForm = parentForm;
userNameTextBox1.Text = predefinedUser;
}
private void LoginDlg_Load(object sender, EventArgs e)
{
Localize();
if (predefinedUser == null)
{
userNameTextBox1.Select();
}
else
{
passwordTextBox1.Select();
}
///
/// Smart card reader detection
///
smartCardReader = null; /// null = No smart card reader detected
try
{
card = new CardNative();
/// Find NFC smart card reader
cardReaders = card.ListReaders();
foreach (var crd in cardReaders)
{
if (crd.Contains("NFC"))
{
smartCardReader = crd; /// NFC smart card reader detected
break;
}
}
if (!string.IsNullOrEmpty(smartCardReader))
{
/// Reader found, initialize NFC smart card reader
card.OnCardInserted += delegate(object sndr, CardInsertedEventArgs args)
{
if (InvokeRequired) { Invoke(new EventHandler<CardInsertedEventArgs>(OnCardInserted), sndr, args); }
else OnCardInserted(sndr, args);
};
card.OnCardRemoved += delegate(object sndr, CardRemovedEventArgs args)
{
if (InvokeRequired) { Invoke(new EventHandler<CardRemovedEventArgs>(OnCardRemoved), sndr, args); }
else OnCardRemoved(sndr, args);
};
card.StartCardEvents(smartCardReader);
Text += " (NFC)";
}
}
catch (Exception)
{
smartCardReader = null;
}
}
void Localize()
{
Text = Strings.User_Login + (string.IsNullOrEmpty(VersionString) ? "" : (" " + VersionString));
aliasLabel1.Text = GetAliasLabel(Method1);
aliasLabel2.Text = GetAliasLabel(Method2);
aliasLabel3.Text = GetAliasLabel(Method3);
passwordLabel1.Text = Strings.Password;
passwordLabel2.Text = Strings.Password;
passwordLabel3.Text = Strings.Password;
okButton.Text = Strings.OkBtnText;
cancelButton.Text = Strings.CancelBtnText;
}
string GetAliasLabel(LoginMethod method)
{
switch (method)
{
default:
case LoginMethod.UserName: return Strings.User_name;
case LoginMethod.FullName: return Strings.Full_name;
case LoginMethod.Number: return Strings.User_code;
}
}
/// <summary>
/// Try to authorize the user when OK clicked.
/// </summary>
private void okButton_Click(object sender, EventArgs e)
{
User tempUser;
if (authorizedUser1 == null)
{
if (string.IsNullOrEmpty(userNameTextBox1.Text) || string.IsNullOrEmpty(passwordTextBox1.Text))
{
loginStatePictureBox1.Image = Properties.Resources.questionMark;
}
else if ((tempUser = TryAuthorize(userNameTextBox1.Text, passwordTextBox1.Text, Method1)) != null)
{
authorizedUser1 = tempUser;
loginStatePictureBox1.Image = Properties.Resources.accepted;
}
else
{
authorizedUser1 = null;
loginStatePictureBox1.Image = Properties.Resources.rejected;
}
}
if (authorizedUser2 == null)
{
if (string.IsNullOrEmpty(userNameTextBox2.Text) || string.IsNullOrEmpty(passwordTextBox2.Text))
{
loginStatePictureBox2.Image = Properties.Resources.questionMark;
}
else if ((tempUser = TryAuthorize(userNameTextBox2.Text, passwordTextBox2.Text, Method2)) != null)
{
authorizedUser2 = tempUser;
loginStatePictureBox2.Image = Properties.Resources.accepted;
}
else
{
authorizedUser2 = null;
loginStatePictureBox2.Image = Properties.Resources.rejected;
}
}
if (authorizedUser3 == null)
{
if (string.IsNullOrEmpty(userNameTextBox3.Text) || string.IsNullOrEmpty(passwordTextBox3.Text))
{
loginStatePictureBox3.Image = Properties.Resources.questionMark;
}
else if ((tempUser = TryAuthorize(userNameTextBox3.Text, passwordTextBox3.Text, Method3)) != null)
{
authorizedUser3 = tempUser;
loginStatePictureBox3.Image = Properties.Resources.accepted;
}
else
{
authorizedUser3 = null;
loginStatePictureBox3.Image = Properties.Resources.rejected;
}
}
if (AreAllUsersKnown())
{
PrepareClosingDlg();
return;
}
MessageBox.Show(Strings.Invalid_username_or_password, Strings.Error, MessageBoxButtons.OK);
DialogResult = DialogResult.None;
return;
}
User TryAuthorize(string user, string password, LoginMethod method)
{
if (Common.Utils.IsPowerUser(user, password))
{
return new User(user, 6, true);
}
User loadedUser = null;
bool authorized = false;
if (!noDatabase)
{
DBSettings db = CurrentUser.LocalUsersDB;
loadedUser = User.LoadUserByName(user, db);
if (loadedUser != null)
{
switch (method)
{
default:
case LoginMethod.UserName:
authorized = loadedUser.Authorize(user, password, requiredGroupMembership, parentForm);
break;
case LoginMethod.FullName:
authorized = loadedUser.AuthorizeFullName(user, password, requiredGroupMembership, parentForm);
break;
case LoginMethod.Number:
int number;
if (!int.TryParse(user, out number)) break;
authorized = loadedUser.AuthorizeNumber(number, password, requiredGroupMembership, parentForm);
break;
}
}
}
return authorized ? loadedUser : null;
}
/// <summary>
/// Cancel clicked, do not try to authorize.
/// </summary>
private void cancelButton_Click(object sender, EventArgs e)
{
if (requiredGroupMembership == null)
{
Entities.User.Unauthorize(parentForm);
}
DialogResult = DialogResult.Cancel;
Close();
return;
}
private void aliasLabel1_Click(object sender, EventArgs e)
{
if (++Method1 == LoginMethod.Count) Method1 = 0;
aliasLabel1.Text = GetAliasLabel(Method1);
}
private void aliasLabel2_Click(object sender, EventArgs e)
{
if (++Method2 == LoginMethod.Count) Method2 = 0;
aliasLabel2.Text = GetAliasLabel(Method2);
}
private void aliasLabel3_Click(object sender, EventArgs e)
{
if (++Method3 == LoginMethod.Count) Method3 = 0;
aliasLabel3.Text = GetAliasLabel(Method3);
}
void OnCardInserted(object sender, CardInsertedEventArgs args)
{
BackColor = Color.Green;
card.Connect(smartCardReader, SHARE.Shared, PROTOCOL.T0orT1);
/// Read the serial number of the card
APDUResponse response = card.Transmit(new APDUCommand(0xFF, 0xCA, 0x00, 0x00, null, 7));
string tag = response.ToString();
card.Disconnect(DISCONNECT.Leave);
bool authorized = false;
DBSettings db = CurrentUser.LocalUsersDB;
User loadedUser = User.LoadUserByTag(tag, db);
if (loadedUser != null)
{
authorized = loadedUser.AuthorizeTag(tag, requiredGroupMembership, parentForm);
}
if (ActiveControl == userNameTextBox1 || ActiveControl == passwordTextBox1)
{
if (authorized)
{
userNameTextBox1.Text = loadedUser.UserName;
passwordTextBox1.Text = string.Empty;
authorizedUser1 = loadedUser;
loginStatePictureBox1.Image = Properties.Resources.accepted;
userNameTextBox2.Focus();
}
else
{
userNameTextBox1.Text = string.Empty;
passwordTextBox1.Text = string.Empty;
authorizedUser1 = null;
loginStatePictureBox1.Image = Properties.Resources.rejected;
}
}
else if (ActiveControl == userNameTextBox2 || ActiveControl == passwordTextBox2)
{
if (authorized)
{
userNameTextBox2.Text = loadedUser.UserName;
passwordTextBox2.Text = string.Empty;
authorizedUser2 = loadedUser;
loginStatePictureBox2.Image = Properties.Resources.accepted;
userNameTextBox3.Focus();
}
else
{
userNameTextBox2.Text = string.Empty;
passwordTextBox2.Text = string.Empty;
authorizedUser2 = null;
loginStatePictureBox2.Image = Properties.Resources.rejected;
}
}
else if (ActiveControl == userNameTextBox3 || ActiveControl == passwordTextBox3)
{
if (authorized)
{
userNameTextBox3.Text = loadedUser.UserName;
passwordTextBox3.Text = string.Empty;
authorizedUser3 = loadedUser;
loginStatePictureBox3.Image = Properties.Resources.accepted;
userNameTextBox1.Focus();
}
else
{
userNameTextBox3.Text = string.Empty;
passwordTextBox3.Text = string.Empty;
authorizedUser3 = null;
loginStatePictureBox3.Image = Properties.Resources.rejected;
}
}
if (authorizedUser1 == null && !string.IsNullOrEmpty(userNameTextBox1.Text) && !string.IsNullOrEmpty(passwordTextBox1.Text))
{
authorizedUser1 = TryAuthorize(userNameTextBox1.Text, passwordTextBox1.Text, Method1);
loginStatePictureBox1.Image = (authorizedUser1 != null) ? Properties.Resources.accepted : Properties.Resources.rejected;
}
if (authorizedUser2 == null && !string.IsNullOrEmpty(userNameTextBox2.Text) && !string.IsNullOrEmpty(passwordTextBox2.Text))
{
authorizedUser2 = TryAuthorize(userNameTextBox2.Text, passwordTextBox2.Text, Method2);
loginStatePictureBox2.Image = (authorizedUser2 != null) ? Properties.Resources.accepted : Properties.Resources.rejected;
}
if (authorizedUser3 == null && !string.IsNullOrEmpty(userNameTextBox3.Text) && !string.IsNullOrEmpty(passwordTextBox3.Text))
{
authorizedUser3 = TryAuthorize(userNameTextBox3.Text, passwordTextBox3.Text, Method3);
loginStatePictureBox3.Image = (authorizedUser3 != null) ? Properties.Resources.accepted : Properties.Resources.rejected;
}
if (AreAllUsersKnown())
{
PrepareClosingDlg();
return;
}
//MessageBox.Show(Strings.Invalid_username_or_password, Strings.Error, MessageBoxButtons.OK);
DialogResult = DialogResult.None;
return;
}
void OnCardRemoved(object sender, CardRemovedEventArgs args)
{
BackColor = oriBackColor;
}
private void LoginDlg_FormClosing(object sender, FormClosingEventArgs e)
{
if (!string.IsNullOrEmpty(smartCardReader))
{
card.StopCardEvents();
}
}
///
/// 1st user / password TextBox processing
///
private void userNameTextBox1_KeyPress(object sender, KeyPressEventArgs e)
{
if (Convert.ToInt32(e.KeyChar) == 13)
{
passwordTextBox1.Focus();
}
}
private void passwordTextBox1_KeyPress(object sender, KeyPressEventArgs e)
{
if (Convert.ToInt32(e.KeyChar) == 13)
{
User tempUser;
if (string.IsNullOrEmpty(userNameTextBox1.Text) || string.IsNullOrEmpty(passwordTextBox1.Text))
{
loginStatePictureBox1.Image = Properties.Resources.questionMark;
}
else if ((tempUser = TryAuthorize(userNameTextBox1.Text, passwordTextBox1.Text, Method1)) != null)
{
authorizedUser1 = tempUser;
loginStatePictureBox1.Image = Properties.Resources.accepted;
}
else
{
authorizedUser1 = null;
loginStatePictureBox1.Image = Properties.Resources.rejected;
}
if (AreAllUsersKnown())
{
PrepareClosingDlg();
return;
}
userNameTextBox2.Focus();
}
}
private void userNameTextBox1_TextChanged(object sender, EventArgs e)
{
authorizedUser1 = null;
loginStatePictureBox1.Image = Properties.Resources.questionMark;
}
private void passwordTextBox1_TextChanged(object sender, EventArgs e)
{
authorizedUser1 = null;
loginStatePictureBox1.Image = Properties.Resources.questionMark;
}
///
/// 2nd user / password TextBox processing
///
private void userNameTextBox2_KeyPress(object sender, KeyPressEventArgs e)
{
if (Convert.ToInt32(e.KeyChar) == 13)
{
passwordTextBox2.Focus();
}
}
private void passwordTextBox2_KeyPress(object sender, KeyPressEventArgs e)
{
if (Convert.ToInt32(e.KeyChar) == 13)
{
User tempUser;
if (string.IsNullOrEmpty(userNameTextBox2.Text) || string.IsNullOrEmpty(passwordTextBox2.Text))
{
loginStatePictureBox2.Image = Properties.Resources.questionMark;
}
else if ((tempUser = TryAuthorize(userNameTextBox2.Text, passwordTextBox2.Text, Method2)) != null)
{
authorizedUser2 = tempUser;
loginStatePictureBox2.Image = Properties.Resources.accepted;
}
else
{
authorizedUser2 = null;
loginStatePictureBox2.Image = Properties.Resources.rejected;
}
if (AreAllUsersKnown())
{
PrepareClosingDlg();
return;
}
userNameTextBox3.Focus();
}
}
private void userNameTextBox2_TextChanged(object sender, EventArgs e)
{
authorizedUser2 = null;
loginStatePictureBox2.Image = Properties.Resources.questionMark;
}
private void passwordTextBox2_TextChanged(object sender, EventArgs e)
{
authorizedUser2 = null;
loginStatePictureBox2.Image = Properties.Resources.questionMark;
}
///
/// 3rd user / password TextBox processing
///
private void userNameTextBox3_KeyPress(object sender, KeyPressEventArgs e)
{
if (Convert.ToInt32(e.KeyChar) == 13)
{
passwordTextBox3.Focus();
}
}
private void passwordTextBox3_KeyPress(object sender, KeyPressEventArgs e)
{
if (Convert.ToInt32(e.KeyChar) == 13)
{
User tempUser;
if (string.IsNullOrEmpty(userNameTextBox3.Text) || string.IsNullOrEmpty(passwordTextBox3.Text))
{
loginStatePictureBox3.Image = Properties.Resources.questionMark;
}
else if ((tempUser = TryAuthorize(userNameTextBox3.Text, passwordTextBox3.Text, Method3)) != null)
{
authorizedUser3 = tempUser;
loginStatePictureBox3.Image = Properties.Resources.accepted;
}
else
{
authorizedUser3 = null;
loginStatePictureBox3.Image = Properties.Resources.rejected;
}
if (AreAllUsersKnown())
{
PrepareClosingDlg();
return;
}
userNameTextBox1.Focus();
}
}
private void userNameTextBox3_TextChanged(object sender, EventArgs e)
{
authorizedUser3 = null;
loginStatePictureBox3.Image = Properties.Resources.questionMark;
}
private void passwordTextBox3_TextChanged(object sender, EventArgs e)
{
authorizedUser3 = null;
loginStatePictureBox3.Image = Properties.Resources.questionMark;
}
/// <summary>
/// Returns true when all 3 users are already logged in
/// </summary>
bool AreAllUsersKnown()
{
return (authorizedUser1 != null) && (authorizedUser2 != null) && (authorizedUser3 != null);
}
/// <summary>
/// Actions before closing this dialog on successful login of all users
/// </summary>
void PrepareClosingDlg()
{
CurrentUser.Change(authorizedUser1, parentForm);
CurrentUser.User2 = authorizedUser2;
CurrentUser.User3 = authorizedUser3;
DialogResult = DialogResult.OK;
Close();
}
}
}