smr/src/lua/endpoints/claim_post.lua

78 lines
2.5 KiB
Lua

local sql = require("lsqlite3")
local pages = require("pages")
local db = require("db")
local queries = require("queries")
local util = require("util")
local sessionlib = require("session")
local config = require("config")
local stmnt_author_create
--We prevent people from changing their password file, this way we don't really
--need to worry about logged in accounts being hijacked if someone gets at the
--database. The attacker can still paste & edit from the logged in account for
--a while, but whatever.
local oldconfigure = configure
function configure(...)
stmnt_author_create = db.sqlassert(db.conn:prepare(queries.insert_author))
return oldconfigure(...)
end
local function claim_post(req)
--Actually claim a name
http_request_populate_post(req)
local name = assert(http_argument_get_string(req,"user"))
local text
--What in the world, Kore should be rejecting names that
--are not lower case & no symbols, but some still get through somehow.
if not name:match("^[a-z0-9]*$") then
log(LOG_DEBUG,"Bad username:" .. name)
text = pages.claim{
err = "Usernames must match ^[a-z0-9]{1,30}$"
}
http_response(req,200,text)
return
end
local rngf = assert(io.open("/dev/urandom","rb"))
local passlength = string.byte(rngf:read(1)) + 64
local salt = rngf:read(64)
local password = rngf:read(passlength)
rngf:close()
local hash = sha3(salt .. password)
stmnt_author_create:bind_names{
name = name,
}
stmnt_author_create:bind_blob(2,salt)
stmnt_author_create:bind_blob(3,hash)
local err = db.do_sql(stmnt_author_create)
if err == sql.DONE then
log(LOG_INFO,"Account creation successful:" .. name)
--We sucessfully made the new author
local id = stmnt_author_create:last_insert_rowid()
stmnt_author_create:reset()
--Give them a file back
http_response_header(req,"Content-Type","application/octet-stream")
http_response_header(req,"Content-Disposition","attachment; filename=\"" .. name .. "." .. config.domain .. ".passfile\"")
local session = sessionlib.start(id)
text = password
http_response(req,200,text)
return
elseif err == sql.CONSTRAINT then
--If the creation failed, they probably just tried
--to use a name that was already taken
text = pages.claim {
err = "Failed to claim. That name may already be taken."
}
elseif err == sql.ERROR or err == sql.MISUSE then
log(LOG_ALERT,"Account creation failed in an unusual way:" .. err)
--This is bad though
text = pages.claim {
err = "Failed to claim"
}
end
stmnt_author_create:reset()
http_response(req,200,text)
end
return claim_post