{= include("docs.util"); start_docs_page(docs.technical_manual.page_titles.newsletters); =}
![]() |
Sawmill Newsletter May 15, 2009 |
create_user = { label = "Create User" shortcut = "cu" parameters = { username = { shortcut = "u" required = true } pass = { shortcut = "pw" required = true } roles = { shortcut = "r" required = true } profiles_allowed = { shortcut = "pa" required = false } } expression = ` # Create a new subnode of users, named after the username node users = 'users'; node user = users{username}; # Set the "username" subnode to the username @user{'username'} = username; # Set the password checksum @user{'password_checksum'} = md5_digest(pass); # If the -pa option was specified, set which profiles this user can access if (profiles_allowed ne "(unspecified)") then ( # Build the "access.0.profiles" node from the profiles_allowed option (which is comma-separated profile names) split(profiles_allowed, ',', 'v.profiles_allowed_split'); node profile; foreach profile 'v.profiles_allowed_split' @user{'access'}{'0'}{'profiles'}{@profile} = @profile; ); # if profiles_allowed # Build the "access.0.roles" node from the roles option (which is comma-separated node names) split(roles, ',', 'v.roles_split'); node role; foreach role 'v.roles_split' @user{'access'}{'0'}{'roles'}{@role} = @role; # Save the users.cfg file save_node(users); echo("Created user " . username); ` # expression } # create_user |
create_user = { ... } # create_user |
label = "Create User" shortcut = "cu" |
parameters = { username = { shortcut = "u" required = true } pass = { shortcut = "pw" required = true } roles = { shortcut = "r" required = true } profiles_allowed = { shortcut = "pa" required = false } } |
expression = ` <Salang code> ` # expression |
# Create a new subnode of users, named after the username node users = 'users'; node user = users{username}; # Set the "username" subnode to the username @user{'username'} = username; # Set the password checksum @user{'password_checksum'} = md5_digest(pass); # If the -pa option was specified, set which profiles this user can access if (profiles_allowed ne "(unspecified)") then ( # Build the "access.0.profiles" node from the profiles_allowed option (which is comma-separated profile names) split(profiles_allowed, ',', 'v.profiles_allowed_split'); node profile; foreach profile 'v.profiles_allowed_split' @user{'access'}{'0'}{'profiles'}{@profile} = @profile; ); # if profiles_allowed # Build the "access.0.roles" node from the roles option (which is comma-separated node names) split(roles, ',', 'v.roles_split'); node role; foreach role 'v.roles_split' @user{'access'}{'0'}{'roles'}{@role} = @role; # Save the users.cfg file save_node(users); echo("Created user " . username); |
cindy = { username = "cindy" password_checksum = "794be188061e1443d2e3def9e4de88f6" access = { 0 = { profiles = { ae = "ae" ae2 = "ae2" } # profiles roles = { role_2 = "role_2" } # roles } # 0 } # access } # cindy |
# Create a new subnode of users, named after the username node users = 'users'; When used in a node context, a string is treated as a full nodename. Therefore "users", when used in node context (e.g., assigning to a node variable, as above), tells Sawmill to find the node whose full nodename is "users". The root of the node hierarchy is the LogAnalysisInfo folder, so "users" refers to the node named "users" within LogAnalysisInfo. This could be a folder called "users", whose value is its structured contents; or a file called "users.cfv" whose value is its literal contents; but since neither exist, it finds the file "users.cfg" whose value is its structured contents. So "node users = 'users'" gets a node points to users.cfg, and automatically loads it into memory, using the structured contents of the file (i.e., parsing "name = value" pairs in the text of the file, and treating {} sections as subnodes). node user = users{username}; users{username} gets a pointer to the subnode of users (which points to users.cfg), whose name is the value of the username parameter. So this finds the "cindy" subnode of "users". If it does not exist, it creates it with an empty value. Then it assigns it to the "user" variable, which can then be used through the remainder of the code to access the new user node. # Set the "username" subnode to the username @user{'username'} = username; @user{'username'} refers to the value of the "username" subnode of the user node (as opposed to user{'username'}, which would be a pointer to the node, not its value). Put another way, @ dereferences the pointer to the "username" subnode. Assigning the value of the username variable to this sets the value of that subnode. # Set the password checksum @user{'password_checksum'} = md5_digest(pass); md5_digest() is a built-in Salang function which returns the MD5 digest of its parameter; this then assigns that to the "password_checksum" subnode of the user node. # If the -pa option was specified, set which profiles this user can access if (profiles_allowed ne "(unspecified)") then ( When a custom action parameter is not specified, its value is set to literally "(unspecified)". So this checks if the -pa option was specified. # Build the "access.0.profiles" node from the profiles_allowed option (which is comma-separated profile names) split(profiles_allowed, ',', 'v.profiles_allowed_split'); split() is a built-in Salang function which is being used in this case to split the profiles_allowed list on commas into a temporary node (v.profiles_allowed_split) for use in the loop below. node profile; foreach profile 'v.profiles_allowed_split' This loop cycles through all subnodes of the temporary node created above. The variable "profile" points to each subnode in turn, so @profile is the name of each profile in turn. @user{'access'}{'0'}{'profiles'}{@profile} = @profile; By stringing together a sequence of {} operators, this line creates an "access" subnode of the user record, and within that a "0" subnode, and within that a "profiles" subnode, and within that a subnode whose name is the profile name; then it assigns the value of that bottom subnode to the name of the profile. ); # if profiles_allowed # Build the "access.0.roles" node from the roles option (which is comma-separated node names) split(roles, ',', 'v.roles_split'); node role; foreach role 'v.roles_split' @user{'access'}{'0'}{'roles'}{@role} = @role; This loop does the same as the profiles loop above, but for roles. # Save the users.cfg file save_node(users); The users.cfg was automatically loaded from disk by the reference to "users" at the top. All modifications to this node have been made in memory so far. This line writes the node back to disk, replacing the disk version of users.cfg with the memory version. echo("Created user " . username); Finally, this echoes information to the standard output stream, to describe what it just did. |