Stores a Local UserInfo object.
Inheritance: UserInfo
Exemplo n.º 1
0
        /// <summary>
        /// Writes on disk all the Users.
        /// </summary>
        /// <param name="users">The User list.</param>
        /// <remarks>This method does not lock resources, therefore a lock is need in the caller.</remarks>
        private void DumpUsers(UserInfo[] users)
        {
            lock (this) {
                BackupUsersFile();

                StringBuilder sb = new StringBuilder();
                for (int i = 0; i < users.Length; i++)
                {
                    LocalUserInfo u = (LocalUserInfo)users[i];
                    sb.Append(u.Username);
                    sb.Append("|");
                    sb.Append(u.PasswordHash);
                    sb.Append("|");
                    sb.Append(u.Email);
                    sb.Append("|");
                    sb.Append(u.Active ? "ACTIVE" : "INACTIVE");
                    sb.Append("|");
                    sb.Append(u.DateTime.ToString("yyyy'/'MM'/'dd' 'HH':'mm':'ss"));
                    // ADMIN|USER no more used in version 3.0
                    //sb.Append("|");
                    //sb.Append(u.Admin ? "ADMIN" : "USER");
                    if (!string.IsNullOrEmpty(u.DisplayName))
                    {
                        sb.Append("|");
                        sb.Append(u.DisplayName);
                    }
                    sb.Append("\r\n");
                }
                File.WriteAllText(GetFullPath(UsersFile), sb.ToString());
            }
        }
Exemplo n.º 2
0
        /// <summary>
        /// Modifies a User.
        /// </summary>
        /// <param name="user">The Username of the user to modify.</param>
        /// <param name="newDisplayName">The new display name (can be <c>null</c>).</param>
        /// <param name="newPassword">The new Password (<c>null</c> or blank to keep the current password).</param>
        /// <param name="newEmail">The new Email address.</param>
        /// <param name="newActive">A value indicating whether the account is active.</param>
        /// <returns>The correct <see cref="T:UserInfo"/> object or <c>null</c>.</returns>
        /// <exception cref="ArgumentNullException">If <b>user</b> or <b>newEmail</b> are <c>null</c>.</exception>
        /// <exception cref="ArgumentException">If <b>newEmail</b> is empty.</exception>
        public UserInfo ModifyUser(UserInfo user, string newDisplayName, string newPassword, string newEmail, bool newActive)
        {
            if (user == null)
            {
                throw new ArgumentNullException("user");
            }

            if (newEmail == null)
            {
                throw new ArgumentNullException("newEmail");
            }

            if (newEmail.Length == 0)
            {
                throw new ArgumentException("New Email cannot be empty", "newEmail");
            }

            lock (this) {
                LocalUserInfo local = LoadLocalInstance(user);
                if (local == null)
                {
                    return(null);
                }

                UserInfo[]       allUsers = GetUsers();
                UsernameComparer comp     = new UsernameComparer();

                usersCache = null;

                for (int i = 0; i < allUsers.Length; i++)
                {
                    if (comp.Compare(allUsers[i], user) == 0)
                    {
                        LocalUserInfo result = new LocalUserInfo(user.Username, newDisplayName, newEmail,
                                                                 newActive, user.DateTime, this,
                                                                 string.IsNullOrEmpty(newPassword) ? local.PasswordHash : Hash.Compute(newPassword));
                        result.Groups = allUsers[i].Groups;
                        allUsers[i]   = result;
                        DumpUsers(allUsers);
                        return(result);
                    }
                }
            }

            return(null);
        }
Exemplo n.º 3
0
        /// <summary>
        /// Gets the complete list of Users.
        /// </summary>
        /// <returns>All the Users, sorted by username.</returns>
        public IEnumerable <UserInfo> GetUsers()
        {
            lock (this)
            {
                if (usersCache == null)
                {
                    var groups = GetUserGroups();

                    var lines = File.ReadAllLines(GetFullPath(UsersFile));

                    var result = new UserInfo[lines.Length];

                    var splitter = new char[] { '|' };

                    string[] fields;
                    for (var i = 0; i < lines.Length; i++)
                    {
                        fields = lines[i].Split(splitter, StringSplitOptions.RemoveEmptyEntries);

                        // Structure (version 3.0 - file previously converted):
                        // Username|PasswordHash|Email|Active-Inactive|DateTime[|DisplayName]

                        var displayName = fields.Length == 6 ? fields[5] : null;

                        result[i] = new LocalUserInfo(fields[0], displayName, fields[2], fields[3].ToLowerInvariant().Equals("active"),
                                                      DateTime.Parse(fields[4]), this, fields[1]);

                        result[i].Groups = GetGroupsForUser(result[i].Username, groups);
                    }

                    Array.Sort(result, new UsernameComparer());

                    usersCache = result;
                }

                return(usersCache);
            }
        }
Exemplo n.º 4
0
        /// <summary>
        /// Verifies the need for a data upgrade, and performs it when needed.
        /// </summary>
        private void VerifyAndPerformUpgrade()
        {
            // Load file lines
            // Parse first line (if any) with old (v2) algorithm
            // If parsing is successful, then the file must be converted
            // Conversion consists in removing the 'ADMIN|USER' field, creating the proper default groups and setting user membership

            // Structure v2:
            // Username|PasswordHash|Email|Active-Inactive|DateTime|Admin-User

            //string[] lines = File.ReadAllLines(GetFullPath(UsersFile));
            // Use this method because version 2.0 file might have started with a blank line
            string[] lines = File.ReadAllText(GetFullPath(UsersFile)).Replace("\r", "").Split(new char[] { '\n' }, StringSplitOptions.RemoveEmptyEntries);

            if (lines.Length > 0)
            {
                bool            upgradeIsNeeded = false;
                LocalUserInfo[] users           = new LocalUserInfo[lines.Length];
                bool[]          oldStyleAdmin   = new bool[lines.Length];      // Values are valid only if upgradeIsNeeded=true

                char[] splitter = new char[] { '|' };

                for (int i = 0; i < lines.Length; i++)
                {
                    string line = lines[i];

                    string[] fields = line.Split(splitter, StringSplitOptions.RemoveEmptyEntries);

                    string displayName = null;

                    if (fields.Length == 6)
                    {
                        if (fields[5] == "ADMIN" || fields[5] == "USER")
                        {
                            // Version 2.0
                            upgradeIsNeeded  = true;
                            oldStyleAdmin[i] = fields[5] == "ADMIN";
                        }
                        else
                        {
                            // Version 3.0 with DisplayName specified
                            oldStyleAdmin[i] = false;
                            displayName      = fields[5];
                        }
                    }
                    else
                    {
                        // Can be a version 3.0 file, with empty DisplayName
                        oldStyleAdmin[i] = false;
                    }

                    users[i] = new LocalUserInfo(fields[0], displayName, fields[2],
                                                 fields[3].ToLowerInvariant() == "active", DateTime.Parse(fields[4]), this, fields[1]);
                }

                if (upgradeIsNeeded)
                {
                    // Dump users
                    // Create default groups
                    // Set membership for old users
                    // Tell the host to set the permissions for the default groups

                    string backupFile = GetFullPath(Path.GetFileNameWithoutExtension(UsersFile) + "_v2" + Path.GetExtension(UsersFile));
                    File.Copy(GetFullPath(UsersFile), backupFile);

                    host.LogEntry("Upgrading users format from 2.0 to 3.0", LogEntryType.General, null, this);

                    DumpUsers(users);
                    UserGroup adminsGroup = AddUserGroup(host.GetSettingValue(SettingName.AdministratorsGroup), "Built-in Administrators");
                    UserGroup usersGroup  = AddUserGroup(host.GetSettingValue(SettingName.UsersGroup), "Built-in Users");

                    for (int i = 0; i < users.Length; i++)
                    {
                        if (oldStyleAdmin[i])
                        {
                            SetUserMembership(users[i], new string[] { adminsGroup.Name });
                        }
                        else
                        {
                            SetUserMembership(users[i], new string[] { usersGroup.Name });
                        }
                    }

                    host.UpgradeSecurityFlagsToGroupsAcl(adminsGroup, usersGroup);
                }
            }
        }
Exemplo n.º 5
0
        /// <summary>
        /// Sets the group memberships of a user account.
        /// </summary>
        /// <param name="user">The user account.</param>
        /// <param name="groups">The groups the user account is member of.</param>
        /// <returns>The correct <see cref="T:UserGroup"/> object or <c>null</c>.</returns>
        /// <exception cref="ArgumentNullException">If <b>user</b> or <b>groups</b> are <c>null</c>.</exception>
        public UserInfo SetUserMembership(UserInfo user, string[] groups)
        {
            if (user == null)
            {
                throw new ArgumentNullException("user");
            }

            if (groups == null)
            {
                throw new ArgumentNullException("groups");
            }

            lock (this) {
                foreach (string g in groups)
                {
                    if (FindGroup(g) == null)
                    {
                        return(null);
                    }
                }

                LocalUserInfo local = LoadLocalInstance(user);
                if (local == null)
                {
                    return(null);
                }

                UserGroup[] allGroups = GetUserGroups();

                List <string> users;
                for (int i = 0; i < allGroups.Length; i++)
                {
                    users = new List <string>(allGroups[i].Users);

                    if (IsSelected(allGroups[i], groups))
                    {
                        // Current group is one of the selected, add user to it
                        if (!users.Contains(user.Username))
                        {
                            users.Add(user.Username);
                        }
                    }
                    else
                    {
                        // Current group is not bound with the user, remove user
                        users.Remove(user.Username);
                    }

                    allGroups[i].Users = users.ToArray();
                }

                groupsCache = null;
                usersCache  = null;

                DumpUserGroups(allGroups);

                LocalUserInfo result = new LocalUserInfo(local.Username, local.DisplayName, local.Email, local.Active,
                                                         local.DateTime, this, local.PasswordHash);
                result.Groups = groups;

                return(result);
            }
        }
        /// <summary>
        /// Verifies the need for a data upgrade, and performs it when needed.
        /// </summary>
        private void VerifyAndPerformUpgrade()
        {
            // Load file lines
            // Parse first line (if any) with old (v2) algorithm
            // If parsing is successful, then the file must be converted
            // Conversion consists in removing the 'ADMIN|USER' field, creating the proper default groups and setting user membership

            // Structure v2:
            // Username|PasswordHash|Email|Active-Inactive|DateTime|Admin-User

            //string[] lines = File.ReadAllLines(GetFullPath(UsersFile));
            // Use this method because version 2.0 file might have started with a blank line
            string[] lines = File.ReadAllText(GetFullPath(UsersFile)).Replace("\r", "").Split(new char[] { '\n' }, StringSplitOptions.RemoveEmptyEntries);

            if(lines.Length > 0) {
                bool upgradeIsNeeded = false;
                LocalUserInfo[] users = new LocalUserInfo[lines.Length];
                bool[] oldStyleAdmin = new bool[lines.Length]; // Values are valid only if upgradeIsNeeded=true

                char[] splitter = new char[] { '|' };

                for(int i = 0; i < lines.Length; i++) {
                    string line = lines[i];

                    string[] fields = line.Split(splitter, StringSplitOptions.RemoveEmptyEntries);

                    string displayName = null;

                    if(fields.Length == 6) {
                        if(fields[5] == "ADMIN" || fields[5] == "USER") {
                            // Version 2.0
                            upgradeIsNeeded = true;
                            oldStyleAdmin[i] = fields[5] == "ADMIN";
                        }
                        else {
                            // Version 3.0 with DisplayName specified
                            oldStyleAdmin[i] = false;
                            displayName = fields[5];
                        }
                    }
                    else {
                        // Can be a version 3.0 file, with empty DisplayName
                        oldStyleAdmin[i] = false;
                    }

                    users[i] = new LocalUserInfo(fields[0], displayName, fields[2],
                        fields[3].ToLowerInvariant() == "active", DateTime.Parse(fields[4]), this, fields[1]);
                }

                if(upgradeIsNeeded) {
                    // Dump users
                    // Create default groups
                    // Set membership for old users
                    // Tell the host to set the permissions for the default groups

                    string backupFile = GetFullPath(Path.GetFileNameWithoutExtension(UsersFile) + "_v2" + Path.GetExtension(UsersFile));
                    File.Copy(GetFullPath(UsersFile), backupFile);

                    host.LogEntry("Upgrading users format from 2.0 to 3.0", LogEntryType.General, null, this);

                    DumpUsers(users);
                    UserGroup adminsGroup = AddUserGroup(host.GetSettingValue(SettingName.AdministratorsGroup), "Built-in Administrators");
                    UserGroup usersGroup = AddUserGroup(host.GetSettingValue(SettingName.UsersGroup), "Built-in Users");

                    for(int i = 0; i < users.Length; i++) {
                        if(oldStyleAdmin[i]) {
                            SetUserMembership(users[i], new string[] { adminsGroup.Name });
                        }
                        else {
                            SetUserMembership(users[i], new string[] { usersGroup.Name });
                        }
                    }

                    host.UpgradeSecurityFlagsToGroupsAcl(adminsGroup, usersGroup);
                }
            }
        }
        /// <summary>
        /// Sets the group memberships of a user account.
        /// </summary>
        /// <param name="user">The user account.</param>
        /// <param name="groups">The groups the user account is member of.</param>
        /// <returns>The correct <see cref="T:UserGroup"/> object or <c>null</c>.</returns>
        /// <exception cref="ArgumentNullException">If <b>user</b> or <b>groups</b> are <c>null</c>.</exception>
        public UserInfo SetUserMembership(UserInfo user, string[] groups)
        {
            if(user == null) throw new ArgumentNullException("user");
            if(groups == null) throw new ArgumentNullException("groups");

            lock(this) {
                foreach(string g in groups) {
                    if(FindGroup(g) == null) return null;
                }

                LocalUserInfo local = LoadLocalInstance(user);
                if(local == null) return null;

                UserGroup[] allGroups = GetUserGroups();

                List<string> users;
                for(int i = 0; i < allGroups.Length; i++) {

                    users = new List<string>(allGroups[i].Users);

                    if(IsSelected(allGroups[i], groups)) {
                        // Current group is one of the selected, add user to it
                        if(!users.Contains(user.Username)) users.Add(user.Username);
                    }
                    else {
                        // Current group is not bound with the user, remove user
                        users.Remove(user.Username);
                    }

                    allGroups[i].Users = users.ToArray();
                }

                groupsCache = null;
                usersCache = null;

                DumpUserGroups(allGroups);

                LocalUserInfo result = new LocalUserInfo(local.Username, local.DisplayName, local.Email, local.Active,
                    local.DateTime, this, local.PasswordHash);
                result.Groups = groups;

                return result;
            }
        }
        /// <summary>
        /// Modifies a User.
        /// </summary>
        /// <param name="user">The Username of the user to modify.</param>
        /// <param name="newDisplayName">The new display name (can be <c>null</c>).</param>
        /// <param name="newPassword">The new Password (<c>null</c> or blank to keep the current password).</param>
        /// <param name="newEmail">The new Email address.</param>
        /// <param name="newActive">A value indicating whether the account is active.</param>
        /// <returns>The correct <see cref="T:UserInfo"/> object or <c>null</c>.</returns>
        /// <exception cref="ArgumentNullException">If <b>user</b> or <b>newEmail</b> are <c>null</c>.</exception>
        /// <exception cref="ArgumentException">If <b>newEmail</b> is empty.</exception>
        public UserInfo ModifyUser(UserInfo user, string newDisplayName, string newPassword, string newEmail, bool newActive)
        {
            if(user == null) throw new ArgumentNullException("user");
            if(newEmail == null) throw new ArgumentNullException("newEmail");
            if(newEmail.Length == 0) throw new ArgumentException("New Email cannot be empty", "newEmail");

            lock(this) {
                LocalUserInfo local = LoadLocalInstance(user);
                if(local == null) return null;

                UserInfo[] allUsers = GetUsers();
                UsernameComparer comp = new UsernameComparer();

                usersCache = null;

                for(int i = 0; i < allUsers.Length; i++) {
                    if(comp.Compare(allUsers[i], user) == 0) {
                        LocalUserInfo result = new LocalUserInfo(user.Username, newDisplayName, newEmail,
                            newActive, user.DateTime, this,
                            string.IsNullOrEmpty(newPassword) ? local.PasswordHash : Hash.Compute(newPassword));
                        result.Groups = allUsers[i].Groups;
                        allUsers[i] = result;
                        DumpUsers(allUsers);
                        return result;
                    }
                }
            }

            return null;
        }
        /// <summary>
        /// Gets the complete list of Users.
        /// </summary>
        /// <returns>All the Users, sorted by username.</returns>
        public UserInfo[] GetUsers()
        {
            lock(this) {
                if(usersCache == null) {

                    UserGroup[] groups = GetUserGroups();

                    string[] lines = File.ReadAllLines(GetFullPath(UsersFile));

                    UserInfo[] result = new UserInfo[lines.Length];

                    char[] splitter = new char[] { '|' };

                    string[] fields;
                    for(int i = 0; i < lines.Length; i++) {
                        fields = lines[i].Split(splitter, StringSplitOptions.RemoveEmptyEntries);

                        // Structure (version 3.0 - file previously converted):
                        // Username|PasswordHash|Email|Active-Inactive|DateTime[|DisplayName]

                        string displayName = fields.Length == 6 ? fields[5] : null;

                        result[i] = new LocalUserInfo(fields[0], displayName, fields[2], fields[3].ToLowerInvariant().Equals("active"),
                            DateTime.Parse(fields[4]), this, fields[1]);

                        result[i].Groups = GetGroupsForUser(result[i].Username, groups);
                    }

                    Array.Sort(result, new UsernameComparer());

                    usersCache = result;
                }

                return usersCache;
            }
        }