summaryrefslogtreecommitdiff
path: root/lib/gitano/usercommand.lua
diff options
context:
space:
mode:
Diffstat (limited to 'lib/gitano/usercommand.lua')
-rw-r--r--lib/gitano/usercommand.lua168
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 {