/* * Changes password of "root" account, but only if existing root account's password * is null. Used during setup of system */ public static void SetRootPassword(ApplicationContext context, Node args) { // Retrieving password given. var password = args.GetExChildValue <string> ("password", context); // Verifying password is accepted. if (!Passwords.IsGoodPassword(context, password)) { // Password was not accepted, throwing an exception. args.FindOrInsert("password").Value = "xxx"; throw new LambdaSecurityException( "Password didn't obey by your configuration settings, which are as follows; " + Passwords.PasswordRuleDescription(context), args, context); } // Creating root account. var rootAccountNode = new Node("", "root"); rootAccountNode.Add("password", password); rootAccountNode.Add("role", "root"); Users.CreateUser(context, rootAccountNode); // Creating "guest account" section, which is needed for settings among other things. AuthFile.ModifyAuthFile( context, delegate(Node authFile) { authFile ["users"].Add(context.RaiseEvent(".p5.auth.get-default-context-username").Get <string> (context)).LastChild .Add("role", context.RaiseEvent(".p5.auth.get-default-context-role").Get <string> (context)); }); }
/* * Creates a new user. */ public static void CreateUser(ApplicationContext context, Node args) { // Retrieving arguments. var username = args.GetExValue <string> (context); var password = args.GetExChildValue <string> ("password", context); var role = args.GetExChildValue <string> ("role", context); // Sanity checking role name towards guest account name. if (role == context.RaiseEvent(".p5.auth.get-default-context-role").Get <string> (context)) { throw new LambdaException("Sorry, but that's the name of our guest account role.", args, context); } // Sanity checking username towards guest account name. if (username == context.RaiseEvent(".p5.auth.get-default-context-username").Get <string> (context)) { throw new LambdaException("Sorry, but that's the name of our guest account.", args, context); } // Making sure [password] never leaves method in case of an exception. args.FindOrInsert("password").Value = "xxx"; // Retrieving password rules from web.config, if any. if (!Passwords.IsGoodPassword(context, password)) { // New password was not accepted, throwing an exception. throw new LambdaSecurityException( "Password didn't obey by your configuration settings, which are as follows; " + Passwords.PasswordRuleDescription(context), args, context); } // Basic sanity check new user's data. if (string.IsNullOrEmpty(username) || string.IsNullOrEmpty(password) || string.IsNullOrEmpty(role)) { throw new LambdaException( "User must have username as value, [password] and [role] at the very least", args, context); } // Verifying username is valid, since we'll need to create a folder for user. VerifyUsernameValid(username); // To reduce lock time of "auth" file, we execute Blow Fish hashing before we enter lock. password = Passwords.SaltAndHashPassword(context, password); // Locking access to password file as we create new user object. AuthFile.ModifyAuthFile( context, delegate(Node authFile) { // Checking if user exist from before. if (authFile ["users"] [username] != null) { throw new LambdaException( "Sorry, that [username] is already taken by another user in the system", args, context); } // Adding user. var userNode = authFile ["users"].Add(username).LastChild; // Salting and hashing password, before storing it in "auth" file. userNode.Add("password", password); // Adding user to specified role. userNode.Add("role", role); // Adding all other specified objects to user. userNode.AddRange(args.Children.Where(ix => ix.Name != "password" && ix.Name != "role").Select(ix => ix.Clone())); }); // Creating newly created user's directory structure. CreateUserDirectory(context, username); }
/* * Edits an existing user. */ public static void EditUser(ApplicationContext context, Node args) { // Retrieving username, and sanity checking invocation. var username = args.GetExValue <string> (context); if (args ["username"] != null) { throw new LambdaSecurityException("Cannot change username for user", args, context); } // Retrieving new password and role, defaulting to null, which will not update existing values. var password = args.GetExChildValue <string> ("password", context, null); var role = args.GetExChildValue <string> ("role", context, null); // Sanity checking role name towards guest account name. if (role == context.RaiseEvent(".p5.auth.get-default-context-role").Get <string> (context)) { throw new LambdaException("Sorry, but that's the name of your system's guest account role.", args, context); } // Changing user's password, but only if a [password] argument was explicitly supplied by caller. if (!string.IsNullOrEmpty(password)) { // Verifying password conforms to password rules. if (!Passwords.IsGoodPassword(context, password)) { // New password was not accepted, throwing an exception. args.FindOrInsert("password").Value = "xxx"; var description = Passwords.PasswordRuleDescription(context); throw new LambdaSecurityException("Password didn't obey by your configuration settings, which are as follows; " + description, args, context); } } // To reduce lock time of "auth" file we execute Blow Fish hashing before we enter lock. password = password == null ? null : Passwords.SaltAndHashPassword(context, password); // Locking access to password file as we edit user object. AuthFile.ModifyAuthFile( context, delegate(Node authFile) { // Checking to see if user exist. if (authFile ["users"] [username] == null) { throw new LambdaException( "Sorry, that user does not exist", args, context); } // Updating user's password, but only if a new password was supplied by caller. if (!string.IsNullOrEmpty(password)) { authFile ["users"] [username] ["password"].Value = password; } // Updating user's role, if a new role was supplied by caller. if (role != null) { authFile ["users"] [username] ["role"].Value = role; } // Checking if caller wants to edit settings. if (args.Name == "p5.auth.users.edit") { // Removing old settings. authFile ["users"] [username].RemoveAll(ix => ix.Name != "password" && ix.Name != "role" && ix.Name != "salt"); // Adding all other specified objects to user. foreach (var idxNode in args.Children.Where(ix => ix.Name != "password" && ix.Name != "role" && ix.Name != "salt")) { authFile ["users"] [username].Add(idxNode.Clone()); } } }); }