Files
2026-04-17 14:55:32 -04:00

266 lines
10 KiB
C#

using System;
using System.Collections.Generic;
using System.Data;
using System.Globalization;
using System.Text;
namespace DatabaseExport
{
/// <summary>
/// this class encapsulates a single user
/// </summary>
public class User : TagAwareBase
{
public enum DefaultRoles
{
Administrator = 0,
PowerUser = 1,
User = 2,
Guest = 3
}
public enum UserPermissionLevels
{
Deny = 0,
Read = 1,
ReadAndExecute = 2,
Edit = 3,
Admin = 4
}
public enum Tags
{
User,
Role,
Version,
LastModified,
LastModifiedBy,
Name,
UserName,
Password,
LocalOnly,
Permissions,
Visibility,
Id
}
public enum XmlFields
{
ID,
UserName,
DisplayName,
Password,
// ReSharper disable once InconsistentNaming
IUIItemPermissions,
// ReSharper disable once InconsistentNaming
IUIItemVisibility,
Role,
LastModified,
LastModifiedBy,
Version,
LocalOnly,
UserTags
}
private const string DEFAULT_LAST_MODIFIED_BY = "---";
private const string DEFAULT_ADMIN_USERNAME = "Admin";
private const string DEFAULT_GUEST_USERNAME = "Guest";
private const string DEFAULT_POWERUSER_USERNAME = "PowerUser";
private const string DEFAULT_USER_USERNAME = "User";
private const int INVALID_ID = -1;
/// <summary>
/// a default user is a user with one of the default roles and names, like Admin or Guest
/// return true if is a default user
/// </summary>
public bool IsADefaultUser => UserName == GetDefaultUserName(Role);
/// <summary>
/// hash of password is seeded and stored in xml
/// hash is seeded with computable information known about the user
/// hash is base64encoding for xml niceness
/// xml is encrypted prior to writing to file
/// </summary>
private string _password = "";
/// <summary>
/// the user friendly name for a user, a display name
/// </summary>
private string _name;
public string Name
{
get => _name;
set => SetProperty(ref _name, value, Tags.Name.ToString());
}
/// <summary>
/// the user name for the user, a short unique name for the user
/// </summary>
private string _userName = string.Empty;
public string UserName
{
get => _userName;
set => SetProperty(ref _userName, value, Tags.UserName.ToString());
}
private int _id = INVALID_ID;
public int Id
{
get => _id;
set => SetProperty(ref _id, value, Tags.Id.ToString());
}
/// <summary>
/// the default role for the user, if a permission is not explicitly set for the user
/// it will use this default role to determine the effect permission
/// </summary>
private DefaultRoles _myRole = DefaultRoles.Guest;
public DefaultRoles Role
{
get => _myRole;
set
{
if (IsADefaultUser && _myRole != value) { throw new NotSupportedException(); }
SetProperty(ref _myRole, value, Tags.Role.ToString());
}
}
/// <summary>
/// right now the version field is updated whenever the user is updated, so it keeps
/// track of how many times it has been modified
/// </summary>
private int _version;
public int Version
{
get => _version;
set => SetProperty(ref _version, value, Tags.Version.ToString());
}
/// <summary>
/// the time the user was last modified or commited to the db
/// </summary>
private DateTime _lastModified = DateTime.MinValue;
public DateTime LastModified
{
get => _lastModified;
set => SetProperty(ref _lastModified, value, Tags.LastModified.ToString());
}
/// <summary>
/// the user that last modified the user
/// </summary>
private string _lastModifiedBy = DEFAULT_LAST_MODIFIED_BY;
public string LastModifiedBy
{
get => _lastModifiedBy;
set => SetProperty(ref _lastModifiedBy, value, Tags.LastModifiedBy.ToString());
}
/// <summary>
/// a remnant of the multiple database era, this was to mark a user as being local to this db and should never
/// be pushed to the central db
/// </summary>
private bool _bLocalOnly;
public bool LocalOnly
{
get => _bLocalOnly;
set => SetProperty(ref _bLocalOnly, value, Tags.LocalOnly.ToString());
}
/// <summary>
/// lookup of permissions by UI item
/// </summary>
private readonly Dictionary<IUIItems, UserPermissionLevels> _tabPermissions = new Dictionary<IUIItems, UserPermissionLevels>();
/// <summary>
/// lookup of visibility by UI item
/// </summary>
private readonly Dictionary<IUIItems, bool> _showTabs = new Dictionary<IUIItems, bool>();
/// <summary>
/// lock for accessing tab permissions or visibility
/// </summary>
private static readonly object TabPermissionsLock = new object();
// #endregion properties
public override ConstraintHelper[] GetConstraints()
{
return new[]
{
new ConstraintHelper
{
ColumnName = DbOperations.Users.UserFields.UserName.ToString(),
DbType = SqlDbType.NVarChar,
DbValue = UserName
}
};
}
public override string LookupTable => DbOperations.Users.USERS_TABLE;
public User(DataRow row)
{
Id = Convert.ToInt32(row[DbOperations.Users.UserFields.ID.ToString()]);
UserName = (string)row[DbOperations.Users.UserFields.UserName.ToString()];
Name = (string)row[DbOperations.Users.UserFields.DisplayName.ToString()];
_password = (string)row[DbOperations.Users.UserFields.Password.ToString()];
_myRole = (DefaultRoles)Convert.ToInt32(row[DbOperations.Users.UserFields.Role.ToString()]);
LastModified = (DateTime)row[DbOperations.Users.UserFields.LastModified.ToString()];
LastModifiedBy = (string)row[DbOperations.Users.UserFields.LastModifiedBy.ToString()];
LocalOnly = Convert.ToBoolean(row[DbOperations.Users.UserFields.LocalOnly.ToString()]);
}
public string GetPermissionSerialized()
{
var sb = new StringBuilder();
lock (TabPermissionsLock)
{
var i = _tabPermissions.GetEnumerator();
while (i.MoveNext())
{
if (sb.Length > 0) { sb.Append(","); }
sb.Append(i.Current.Key.GetName());
sb.Append("=");
sb.Append(((int)i.Current.Value).ToString());
}
}
return sb.ToString();
}
public static string GetDefaultUserName(DefaultRoles role)
{
switch (role)
{
case DefaultRoles.Administrator:
return DEFAULT_ADMIN_USERNAME;
case DefaultRoles.Guest:
return DEFAULT_GUEST_USERNAME;
case DefaultRoles.PowerUser:
return DEFAULT_POWERUSER_USERNAME;
case DefaultRoles.User:
return DEFAULT_USER_USERNAME;
default:
throw new NotSupportedException("Unknown role " + role);
}
}
public string GetVisibilitySerialized()
{
var sb = new StringBuilder();
var i2 = _showTabs.GetEnumerator();
while (i2.MoveNext())
{
if (sb.Length > 0) { sb.Append(","); }
sb.Append(i2.Current.Key.GetName());
sb.Append("=");
sb.Append(i2.Current.Value ? "1" : "0");
}
return sb.ToString();
}
public Dictionary<string, string> GetValues()
{
var elementNameValuePairs = new Dictionary<string, string>();
elementNameValuePairs[XmlFields.ID.ToString()] = Id.ToString();
elementNameValuePairs[XmlFields.UserName.ToString()] = UserName;
elementNameValuePairs[XmlFields.DisplayName.ToString()] = Name;
elementNameValuePairs[XmlFields.Password.ToString()] = _password;
elementNameValuePairs[XmlFields.IUIItemPermissions.ToString()] = GetPermissionSerialized();
elementNameValuePairs[XmlFields.IUIItemVisibility.ToString()] = GetVisibilitySerialized();
elementNameValuePairs[XmlFields.Role.ToString()] = Role.ToString();
elementNameValuePairs[XmlFields.LastModified.ToString()] = LastModified.ToString(CultureInfo.InvariantCulture);
elementNameValuePairs[XmlFields.LastModifiedBy.ToString()] = LastModifiedBy;
elementNameValuePairs[XmlFields.Version.ToString()] = Version.ToString(CultureInfo.InvariantCulture);
elementNameValuePairs[XmlFields.LocalOnly.ToString()] = LocalOnly.ToString(CultureInfo.InvariantCulture);
elementNameValuePairs[XmlFields.UserTags.ToString()] = GetTagsCommaSeperatedString();
return elementNameValuePairs;
}
}
}