tbf/SharedDatabase/Forms/LoginDlg.cs

359 lines
11 KiB
C#
Raw Normal View History

///
/// Copyright (c) 2017-2021 Sensus Slovensko a.s.
///
using System;
using System.Drawing;
using System.Windows.Forms;
using log4net;
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 LoginDlg : Form
{
private static readonly ILog log = LogManager.GetLogger(typeof(LoginDlg));
/// Public readonly
public string UserName { get { return user; } }
/// Private fields
string user;
string password;
GID[] requiredGroupMembership;
Form parentForm;
bool noDatabase;
Color oriBackColor;
/// Smart card support, card S/N is used as user.Tag
CardNative card;
string smartCardReader;
public LoginMethod Method;
public string VersionString;
/// <summary>
/// Constructor.
/// </summary>
public LoginDlg()
{
InitializeComponent();
2026-03-04 07:37:27 +00:00
this.Icon = Properties.Resources.TBF_icon;
oriBackColor = BackColor;
}
/// <summary>
/// Constructor with a predefined user.
/// </summary>
public LoginDlg(string predefinedUser, Form parentForm)
: this()
{
user = predefinedUser;
userNameTextBox.Text = predefinedUser;
this.parentForm = parentForm;
}
/// <summary>
/// Constructor with 'no Database' flag.
/// </summary>
public LoginDlg(bool noDatabase)
: this()
{
this.noDatabase = noDatabase;
}
/// <summary>
/// Constructor when a specific group membership is required.
/// </summary>
public LoginDlg(GID[] requiredGroupMembership, Form parentForm)
: this()
{
this.requiredGroupMembership = requiredGroupMembership;
this.parentForm = parentForm;
#if DEBUG
2022-01-11 19:27:06 +00:00
user = "milan";
userNameTextBox.Text = "milan";
2022-11-21 11:41:29 +00:00
passwordTextBox.Text = "kraken";
#endif
}
/// <summary>
/// Constructor with a predefined user when a specific group membership is required.
/// </summary>
public LoginDlg(string predefinedUser, GID[] requiredGroupMembership, Form parentForm)
: this()
{
user = predefinedUser;
userNameTextBox.Text = predefinedUser;
this.requiredGroupMembership = requiredGroupMembership;
this.parentForm = parentForm;
}
private void LoginDlg_Load(object sender, EventArgs e)
{
Localize();
if (user == null)
userNameTextBox.Select();
else
passwordTextBox.Select();
///
/// Smart card reader detection
///
smartCardReader = null; /// null = No smart card reader detected
#if SMART_CARD_READER_SUPPORT
try
{
card = new CardNative();
/// Find NFC smart card reader
string[] cardReaders = card.ListReaders();
if (cardReaders != null)
{
foreach (var crd in cardReaders)
{
log.WarnFormat("SMART card reader found: {0}", crd);
}
foreach (var crd in cardReaders)
{
if (crd.Contains("NFC"))
{
log.ErrorFormat("SMART card reader selected: {0}", crd);
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;
}
#endif
}
void Localize()
{
Text = Strings.User_Login + (string.IsNullOrEmpty(VersionString) ? "" : (" " + VersionString));
aliasLabel.Text = GetAliasLabel();
passwordLabel.Text = Strings.Password;
okButton.Text = Strings.OkBtnText;
cancelButton.Text = Strings.CancelBtnText;
}
string GetAliasLabel()
{
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 = userNameTextBox.Text;
password = passwordTextBox.Text;
AuthorizedAs authorizedAs = AuthorizedAs.PowerUser;
bool authorized = Common.Utils.IsPowerUser(user, password);
if (authorized)
{
CurrentUser.Change(new Entities.User(user, 6, true), parentForm);
}
if (!authorized && !noDatabase)
{
DBSettings[] dbs = new DBSettings[] { CurrentUser.RemoteUsersDB, CurrentUser.LocalUsersDB };
authorizedAs = AuthorizedAs.RemoteUser;
foreach (var db in dbs)
{
try
{
switch (Method)
{
case LoginMethod.UserName:
default:
var usr1 = Entities.User.LoadUserByName(user, db);
if (usr1 != null) { authorized = usr1.Authorize(user, password, requiredGroupMembership, parentForm); }
break;
case LoginMethod.FullName:
var usr2 = Entities.User.LoadUserByFullName(user, db);
if (usr2 != null) { authorized = usr2.AuthorizeFullName(user, password, requiredGroupMembership, parentForm); }
if (authorized) { user = usr2.UserName; }
break;
case LoginMethod.Number:
int number;
if (!int.TryParse(user, out number)) break;
var usr3 = Entities.User.LoadUserByNumber(number, db);
if (usr3 != null) { authorized = usr3.AuthorizeNumber(number, password, requiredGroupMembership, parentForm); }
if (authorized) { user = usr3.UserName; }
break;
}
}
catch (Exception) { }
if (authorized) break;
authorizedAs = AuthorizedAs.LocalUser;
}
}
if (authorized)
{
CurrentUser.AuthorizedAs = authorizedAs;
DialogResult = DialogResult.OK;
Close();
return;
}
MessageBox.Show(Strings.Invalid_username_or_password, Strings.Error, MessageBoxButtons.OK);
DialogResult = DialogResult.None;
return;
}
/// <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 aliasLabel_Click(object sender, EventArgs e)
{
if (++Method == LoginMethod.Count) Method = 0;
aliasLabel.Text = GetAliasLabel();
}
private void userNameTextBox_KeyPress(object sender, KeyPressEventArgs e)
{
if (Convert.ToInt32(e.KeyChar) == 13)
{
passwordTextBox.Focus();
}
}
private void passwordTextBox_KeyPress(object sender, KeyPressEventArgs e)
{
if (Convert.ToInt32(e.KeyChar) == 13)
{
okButton_Click(sender, e);
}
}
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);
DBSettings[] dbs = new DBSettings[] { CurrentUser.RemoteUsersDB, CurrentUser.LocalUsersDB };
bool authorized = false;
AuthorizedAs authorizedAs = AuthorizedAs.RemoteUser;
///
foreach (var db in dbs)
{
try
{
Entities.User loadedUser = Entities.User.LoadUserByTag(tag, db);
if (loadedUser != null)
{
authorized = loadedUser.AuthorizeTag(tag, requiredGroupMembership, parentForm);
if (authorized)
{
user = loadedUser.UserName;
break;
}
}
}
catch (Exception) { }
authorizedAs = AuthorizedAs.LocalUser;
}
if (authorized)
{
CurrentUser.AuthorizedAs = authorizedAs;
DialogResult = DialogResult.OK;
Close();
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();
}
}
}
}