require "uri" require "http-session" include CrystalGauntlet CrystalGauntlet.template_endpoints[{ name: "login", path: "/login", methods: ["get", "post"] }] = ->(context : HTTP::Server::Context, params : Hash(String, String?)) { if session = CrystalGauntlet.sessions.get(context) logged_in = true account_id = session.account_id user_id = session.user_id username = session.username else logged_in = false account_id = nil user_id = nil username = nil end body = context.request.body if body begin params = URI::Params.parse(body.gets_to_end) username = params["username"].strip password = params["password"].strip if username.empty? || password.empty? raise "Invalid username or password" end # todo: dedup this code with the login account endpoint maybe result = DATABASE.query_all("select id, password from accounts where username = ?", username, as: {Int32, String}) if result.size > 0 account_id, hash = result[0] bcrypt = Crypto::Bcrypt::Password.new(hash) if bcrypt.verify(password) user_id = Accounts.get_user_id(account_id) logged_in = true LOG.debug { "#{username} logged in" } CrystalGauntlet.sessions.set(context, UserSession.new(username, account_id, user_id)) else raise "Invalid password" end else raise "No such user exists" end rescue error LOG.error(exception: error) {"whar...."} end end if logged_in context.response.headers.add("Location", "#{context.request.query_params["redir"]? || "/accounts"}") context.response.status = HTTP::Status::SEE_OTHER return else ECR.embed("./public/template/login.ecr", context.response) end }