132 lines
3.9 KiB
Ruby
132 lines
3.9 KiB
Ruby
require "yaml"
|
|
|
|
class LifePex::Systems::UserSystem < LifePex::Systems::AuthSystem
|
|
include JSON::API
|
|
|
|
DEFAULT_PEXS_FOR_NEW_USERS = YAML.load_file "config/default_pexs_for_new_users.yaml"
|
|
|
|
get "/login" do
|
|
slim :login
|
|
end
|
|
|
|
def setup_user_cookie!(user_id)
|
|
cookies["auth"] = JWT.encode({ "user_id" => user_id }, LifePex::SECRET)
|
|
end
|
|
|
|
def login(params)
|
|
user = LifePex::User.where(username: params["username"]).first
|
|
if user && BCrypt::Password.new(user[:hashed_password]) == params["password"]
|
|
cookies["auth"] = JWT.encode({ "user_id" => user[:id] }, LifePex::SECRET)
|
|
user
|
|
else
|
|
nil
|
|
end
|
|
end
|
|
|
|
post "/login", provides: 'html' do
|
|
if user = login(params)
|
|
cookies["auth"] = JWT.encode({ "user_id" => user[:id] }, LifePex::SECRET)
|
|
redirect "/"
|
|
else
|
|
slim :login, locals: { flash: { danger: "Failed to login" } }
|
|
end
|
|
end
|
|
|
|
get "/register" do
|
|
slim :register
|
|
end
|
|
|
|
def register(params)
|
|
user = LifePex::User.where(username: params["username"]).first
|
|
if !user
|
|
hashed_password = BCrypt::Password.create params["password"]
|
|
user_id = LifePex::User.new(username: params["username"], hashed_password: hashed_password).save
|
|
cookies["auth"] = JWT.encode({ "user_id" => user_id }, LifePex::SECRET)
|
|
DEFAULT_PEXS_FOR_NEW_USERS.each do |pex|
|
|
LifePex::Pex.new(**pex, user_id: user_id).save
|
|
end
|
|
user_id
|
|
else
|
|
nil
|
|
end
|
|
end
|
|
|
|
post "/register", provides: 'html' do
|
|
if user_id = register(params)
|
|
redirect "/"
|
|
else
|
|
slim :register, locals: { flash: { danger: "Failed to register as #{params['username']}" } }
|
|
end
|
|
end
|
|
|
|
get "/logout", auth: [] do
|
|
cookies.delete "auth"
|
|
slim :logout, locals: { flash: { success: "Logged out" } }
|
|
end
|
|
|
|
get "/password", auth: [] do
|
|
slim :password
|
|
end
|
|
|
|
def change_password(params)
|
|
hashed_password = BCrypt::Password.create params["password"]
|
|
LifePex::User.where(id: current_user_id).update(hashed_password: hashed_password)
|
|
end
|
|
|
|
post "/password", auth: [], provides: 'html' do
|
|
if params["password"] != params["password_confirmation"]
|
|
slim :password, locals: { flash: { warning: "Password don't match" } }
|
|
else
|
|
change_password(params)
|
|
slim :password, locals: { flash: { success: "Password updated" } }
|
|
end
|
|
end
|
|
|
|
get "/about" do
|
|
slim :about
|
|
end
|
|
|
|
extend DocMyRoutes::Annotatable
|
|
register Sinatra::Namespace
|
|
namespace '/api/user/v1' do
|
|
summary 'Generate a authentication cookie for a registrated account'
|
|
notes ''
|
|
produces 'application/json'
|
|
status_codes [200]
|
|
parameter :username, required: true, type: 'string', in: 'body'
|
|
parameter :password, required: true, type: 'string', in: 'body'
|
|
post "/login", provides: 'json' do
|
|
if user = login(json_params)
|
|
{ message: 'Logged in' }.to_json
|
|
else
|
|
halt 400, { message: 'Invalid credentials' }.to_json
|
|
end
|
|
end
|
|
|
|
summary 'Register a new account if the username does not exists already'
|
|
notes ''
|
|
produces 'application/json'
|
|
status_codes [200]
|
|
parameter :username, required: true, type: 'string', in: 'body'
|
|
parameter :password, required: true, type: 'string', in: 'body'
|
|
post "/register", provides: 'json' do
|
|
if user_id = register(json_params)
|
|
{ message: "Registered as user_id=#{user_id}", user: { id: user_id, username: json_params["username"] } }.to_json
|
|
else
|
|
halt 400, { message: "Failed to register as #{json_params['username']}" }.to_json
|
|
end
|
|
end
|
|
|
|
summary 'Change the authentication password of the account'
|
|
produces 'application/json'
|
|
status_codes [200]
|
|
parameter :password, required: true, type: 'string', in: 'body'
|
|
parameter :auth, required: true, type: 'string', in: 'cookies'
|
|
post "/password", auth: [], provides: 'html' do
|
|
change_password(json_params)
|
|
{ message: 'password changed' }.to_json
|
|
end
|
|
end
|
|
include LifePex::Systems::ApiList
|
|
end
|