class Guff::UserModel < Guff::Model SQL = TemplateCache.new({ add_user: " INSERT INTO users(user_name) VALUES (:user_name) ", update_user: " UPDATE users SET %{sets} WHERE user_id = :user_id ", delete_login: " DELETE FROM user_logins WHERE user_id = :user_id ", add_login: " INSERT INTO user_logins(user_id, email, pass_hash) VALUES (:user_id, :email, :pass_hash) ", }) def initialize(models : Models) super(models, SQL) end def get_users r = [] of Hash(String, String) all(:get_users) do |row| r << row end r end def add_user(name : String) query(:add_user, { "user_name": name }, nil) # return user id last_insert_row_id end def update_user( user_id : Int32, name : String? = nil, active : Bool? = nil, role : String? = nil, ) sets = [] of String args = { "user_id": user_id.to_s } if name != nil args["name"] = name.not_nil! sets << "user_name = :name" end if active != nil args["is_active"] = active.not_nil! ? "1" : "0" sets << "is_active = :is_active" end if role != nil args["role_name"] = role.not_nil! sets << " role_id = (SELECT role_id FROM roles WHERE role_name = :role) " end # exec query query(:update_user, args, { "sets": sets.join(", "), }) if sets.size > 0 end def delete_login(user_id : Int32) query(:delete_login, { "user_id": user_id.to_s }, nil) end def add_login( user_id : Int32, email : String, password : String, ) # TODO: check password strength raise "password too short" if password.length < 4 # hash password pass_hash = Crypto::Bcrypt::Password.create(password, cost: 10) transaction do # clear old credentials delete_login(user_id) # add new credentials query(:add_login, { "user_id": user_id.to_s, "email": email, "pass_hash": pass_hash, }, nil) end end end