diff options
Diffstat (limited to 'lib/gitano/usercommand.lua')
-rw-r--r-- | lib/gitano/usercommand.lua | 168 |
1 files changed, 143 insertions, 25 deletions
diff --git a/lib/gitano/usercommand.lua b/lib/gitano/usercommand.lua index d28b203..3c8b467 100644 --- a/lib/gitano/usercommand.lua +++ b/lib/gitano/usercommand.lua @@ -10,6 +10,7 @@ local repository = require 'gitano.repository' local config = require 'gitano.config' local sio = require 'luxio.simple' +local subprocess = require 'luxio.subprocess' local builtin_whoami_short = "Find out how Gitano identifies you" @@ -20,15 +21,19 @@ Tells you who you are, what your email address is set to, what keys you have registered etc. ]] -local function builtin_whoami_validate(config, repo, cmdline) - -- whoami +local function validate_single_argcmd(cmdline, msg) if #cmdline > 1 then - log.error("usage: whoami") + log.error(msg) return false end + return true end +local function builtin_whoami_validate(_, _, cmdline) + return validate_single_argcmd(cmdline, "usage: whoami") +end + local function builtin_whoami_prep(config, repo, cmdline, context) context.operation = "whoami" return config.repo:run_lace(context) @@ -37,6 +42,11 @@ end local function builtin_whoami_run(config, repo, cmdline, env) local username = env["GITANO_USER"] local userdata = config.users[username] + + if not userdata then + return "I don't know who you are", 1 + end + log.stdout(" User name:", username) log.stdout(" Real name:", userdata.real_name or "Unknown") log.stdout("Email address:", userdata.email_address or "unknown@example.com") @@ -159,53 +169,158 @@ local function builtin_sshkey_run(conf, _, cmdline, env) local utab = conf.users[env.GITANO_USER] if cmdline[2] == "list" then if not next(utab.keys) then - log.warn("There are no SSH keys registered for", env.GITANO_USER .. ", sorry") + log.warn("There are no SSH keys registered for", env.GITANO_USER + .. ", sorry") else - local pfx = " SSH key:" - for tagname, keydata in pairs(utab.keys) do - local suffix = (env.GITANO_KEYTAG == tagname) and " [*]" or "" - log.state(pfx, tagname, "=>", keydata.keytag .. suffix) - pfx = " " - end + local pfx = " SSH key:" + for tagname, keydata in pairs(utab.keys) do + local suffix = (env.GITANO_KEYTAG == tagname) and " [*]" or "" + log.state(pfx, tagname, "=>", keydata.keytag .. suffix) + pfx = " " + end end elseif cmdline[2] == "add" then local sshkey = sio.stdin:read("*l") local keytype, keydata, keytag = sshkey:match("^([^ ]+) ([^ ]+) ([^ ].*)$") if not (keytype and keydata and keytag) then - log.error("Unable to parse key,", filename, - "did not smell like an OpenSSH v2 key") - return "exit", 1 + log.error("Unable to parse key,", filename, + "did not smell like an OpenSSH v2 key") + return "exit", 1 end + if (keytype ~= "ssh-rsa") and (keytype ~= "ssh-dss") and - (keytype ~= "ecdsa-sha2-nistp256") and - (keytype ~= "ecdsa-sha2-nistp384") and - (keytype ~= "ecdsa-sha2-nistp521") then - log.error("Unknown key type", keytype) - return "exit", 1 + (keytype ~= "ecdsa-sha2-nistp256") and + (keytype ~= "ecdsa-sha2-nistp384") and + (keytype ~= "ecdsa-sha2-nistp521") then + log.error("Unknown key type", keytype) + return "exit", 1 end + local keytab = { - data = sshkey, - keyname = cmdline[3], - username = env.GITANO_USER, - keytag = keytag, + data = sshkey, + keyname = cmdline[3], + username = env.GITANO_USER, + keytag = keytag, } + utab.keys[cmdline[3]] = keytab - elseif cmdline[2] == "del" then utab.keys[cmdline[3]] = nil end if cmdline[2] ~= "list" then -- Store the config back. + local action = (cmdline[2] == "add") and "Added" or "Deleted" action = action .. " " .. cmdline[3] .. " for " .. env.GITANO_USER local ok, msg = config.commit(conf, action, env.GITANO_USER) + + if not ok then + log.error(msg) + return "exit", 1 + end + end + + return "exit", 0 +end + +local builtin_passwd_short = "Set your password" + +local builtin_passwd_helptext = [[ +usage: passwd + +Sets your password, the password is read from stdin. + +If no password is provided your password is removed (if you have one). +]] + +local function builtin_passwd_validate(_, _, cmdline) + return validate_single_argcmd(cmdline, "usage: passwd") +end + +local function builtin_passwd_prep(conf, repo, cmdline, context) + context.operation = "passwd" + + local action, reason = conf.repo:run_lace(context) + if action == "deny" then + return reason + end + + return action, reason +end + +local function update_htpasswd(user, passwd) + local htpasswd_path = os.getenv("HOME") .. "/htpasswd" + local flags = io.open(htpasswd_path, "r") and "" or "-c" + local exit_code + + if passwd ~= '' then + local proc = subprocess.spawn_simple({ + "htpasswd", flags, htpasswd_path, user, + stdin = passwd .. '\n' .. passwd .. '\n', + stdout = subprocess.PIPE, + stderr = subprocess.PIPE + }) + + _, exit_code = proc:wait() + else + local proc = subprocess.spawn_simple({ + "htpasswd", "-D", htpasswd_path, user, + stdout = subprocess.PIPE, + stderr = subprocess.PIPE + }) + + _, exit_code = proc:wait() + end + + return exit_code == 0 +end + +local function builtin_passwd_run(conf, _, cmdline, env) + local user = env.GITANO_USER + + local password = sio.stdin:read("*l") + local method, hash = util.hash_password(password) + + if conf.users[user].hash == nil and password == "" then + log.chat(string.format("Password for %s is not set and no password was" + .. " provided, no action taken.", user)) + return "exit", 0 + end + + if password ~= "" then + conf.users[user].method = method + conf.users[user].hash = hash + else + -- user's password will be removed + conf.users[user].method = nil + conf.users[user].hash = nil + end + + local ok, msg + + if conf.clod.settings["use_htpasswd"] == "yes" then + ok = update_htpasswd(user, password) + if not ok then - log.error(msg) - return "exit", 1 + log.error("Failed to update htpasswd file") + return "exit", 1 end end + local action = string.format("%s password for %s", + password ~= '' and "Update" or "Remove", user) + + ok, msg = config.commit(conf, action, user) + + if not ok then + log.error(msg) + return "exit", 1 + end + + log.chat(string.format("%s password for %s", + password ~= '' and "Updated" or "Removed", user)) + return "exit", 0 end @@ -216,6 +331,9 @@ local function register_commands(reg) assert(reg("sshkey", builtin_sshkey_short, builtin_sshkey_helptext, builtin_sshkey_validate, builtin_sshkey_prep, builtin_sshkey_run, false, false)) + assert(reg("passwd", builtin_passwd_short, builtin_passwd_helptext, + builtin_passwd_validate, builtin_passwd_prep, + builtin_passwd_run, false, false)) end return { |