using System; using System.Collections.Generic; using System.Data; using System.Globalization; using System.Text; namespace DatabaseExport { /// /// this class encapsulates a single user /// 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; /// /// 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 /// public bool IsADefaultUser => UserName == GetDefaultUserName(Role); /// /// 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 /// private string _password = ""; /// /// the user friendly name for a user, a display name /// private string _name; public string Name { get => _name; set => SetProperty(ref _name, value, Tags.Name.ToString()); } /// /// the user name for the user, a short unique name for the user /// 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()); } /// /// 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 /// 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()); } } /// /// right now the version field is updated whenever the user is updated, so it keeps /// track of how many times it has been modified /// private int _version; public int Version { get => _version; set => SetProperty(ref _version, value, Tags.Version.ToString()); } /// /// the time the user was last modified or commited to the db /// private DateTime _lastModified = DateTime.MinValue; public DateTime LastModified { get => _lastModified; set => SetProperty(ref _lastModified, value, Tags.LastModified.ToString()); } /// /// the user that last modified the user /// private string _lastModifiedBy = DEFAULT_LAST_MODIFIED_BY; public string LastModifiedBy { get => _lastModifiedBy; set => SetProperty(ref _lastModifiedBy, value, Tags.LastModifiedBy.ToString()); } /// /// 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 /// private bool _bLocalOnly; public bool LocalOnly { get => _bLocalOnly; set => SetProperty(ref _bLocalOnly, value, Tags.LocalOnly.ToString()); } /// /// lookup of permissions by UI item /// private readonly Dictionary _tabPermissions = new Dictionary(); /// /// lookup of visibility by UI item /// private readonly Dictionary _showTabs = new Dictionary(); /// /// lock for accessing tab permissions or visibility /// 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 GetValues() { var elementNameValuePairs = new Dictionary(); 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; } } }