diff options
Diffstat (limited to 'src/guff.cr')
-rw-r--r-- | src/guff.cr | 139 |
1 files changed, 81 insertions, 58 deletions
diff --git a/src/guff.cr b/src/guff.cr index 5fa461e..22fd52c 100644 --- a/src/guff.cr +++ b/src/guff.cr @@ -207,6 +207,10 @@ module Guff def self.test(hash : String, password : String) : Bool Crypto::Bcrypt::Password.new(hash) == password end + + def self.random_password + SecureRandom.base64(6 + rand(6)).strip.gsub(/\=+$/, "") + end end module Models @@ -362,6 +366,26 @@ module Guff class UserModel < Model SQL = { + login: " + SELECT user_id, + password + + FROM users + + WHERE is_active + AND email = ? + ", + + has_role: " + SELECT user_id + + FROM users + + WHERE is_active + AND user_id = ? + AND role_id IN (SELECT role_id FROM roles WHERE role IN (%s)) + ", + add_user: " INSERT INTO users( role_id, @@ -385,32 +409,29 @@ module Guff ", } - def login(user : String, pass : String) : String? - if @context.development? - if user == "test" && pass == "test" - "0" - else - nil + def login( + email : String, + password : String + ) : Int64? + r = nil + + if row = @context.dbs.ro.row(SQL[:login], [email]) + if Password.test(row["password"] as String, password) + # given email and password matches active user + r = row["user_id"] as Int64 end - else - # TODO: handle login - nil end + + # return result + r end - def has_role?(user_id : String?, roles : Array(String)) + def has_role?(user_id : Int64, roles : Array(String)) raise "empty role list" unless roles.size > 0 - if user_id && user_id.size > 0 - if @context.development? - user_id == "0" - else - # TODO: add role query - end - else - # empty user id - false - end + !!@context.dbs.ro.one(SQL[:has_role] % [ + (["?"] * roles.size).join(",") + ], [user_id.to_s].concat(roles)) end def add_user( @@ -745,12 +766,13 @@ module Guff @session ||= Session.new(self) end - def user_id - session["user_id"]? + def user_id : Int64? + session["user_id"]? ? session["user_id"].to_i64 : nil end def has_role?(roles : Array(String)) - models.user.has_role?(user_id, roles) + id = user_id + id ? models.user.has_role?(id, roles) : false end def development? @@ -1125,7 +1147,7 @@ module Guff # create session session_id = @context.session.create({ - "user_id": login(context.request.body), + "user_id": login(context.request.body).to_s, }) # add cookie @@ -1165,7 +1187,7 @@ module Guff Views::LoginPageView.new(@context, error).to_s(response) end - private def login(body : String?) : String + private def login(body : String?) # check body raise "empty request body" if body.nil? || body.size == 0 @@ -1196,7 +1218,7 @@ module Guff raise "invalid credentials" unless user_id # return user id - user_id + user_id.not_nil! end end @@ -1237,6 +1259,7 @@ module Guff def call(context : HTTP::Server::Context) if post_id = get_post_id(context.request) # TODO: render page + context.response.headers["x-frame-options"] = "SAMEORIGIN" context.response.content_type = "text/html; charset=utf-8" context.response.status_code = 200 context.response << "page: #{post_id}" @@ -1274,6 +1297,7 @@ module Guff if /\/$/.match(path) # TODO: render page + context.response.headers["x-frame-options"] = "SAMEORIGIN" context.response.content_type = "text/html; charset=utf-8" context.response.status_code = 200 context.response << "project: #{post_id}" @@ -1318,6 +1342,7 @@ module Guff def call(context : HTTP::Server::Context) if id = get_id(context.request) # TODO: render page + context.response.headers["x-frame-options"] = "SAMEORIGIN" context.response.content_type = "text/html; charset=utf-8" context.response.status_code = 200 context.response << "blog post id: #{id}" @@ -1361,6 +1386,7 @@ module Guff def call(context : HTTP::Server::Context) if ids = get_ids(context.request) # TODO: render page + context.response.headers["x-frame-options"] = "SAMEORIGIN" context.response.content_type = "text/html; charset=utf-8" context.response.status_code = 200 context.response << "blog list: ids = #{ids.join(", ")}" @@ -1402,34 +1428,34 @@ module Guff id: :deflate, }, { dev: false, - id: :session, + id: :assets, }, { dev: false, - id: :api, + id: :page, }, { dev: false, - id: :assets, + id: :project, }, { dev: false, - id: :admin, + id: :blog_post, }, { dev: false, - id: :login, + id: :blog_list, }, { dev: false, - id: :logout, + id: :login, }, { dev: false, - id: :page, + id: :session, }, { dev: false, - id: :project, + id: :api, }, { dev: false, - id: :blog_post, + id: :admin, }, { dev: false, - id: :blog_list, + id: :logout, }] def self.get(context : Context) : Array(HTTP::Handler) @@ -1668,36 +1694,33 @@ module Guff end # gen random password and add admin user - password = gen_password - add_admin_user(db, password) + password = Password.random_password + add_user(db, "Admin", "admin@admin", password) + add_user(db, "Test", "test@test", "test") add_test_data(db) STDERR.puts "admin user: admin@admin, password: #{password}" end end - ADD_ADMIN_USER_SQL = %{ - INSERT INTO users( - user_id, - role_id, - name, - email, - password, - is_active - ) VALUES ( - 1, - (SELECT role_id FROM roles WHERE role = 'admin'), - 'Admin', - 'admin@admin', - ?, - 1 - ) + ADD_USER_SQL = %{ + INSERT INTO users(name, email, password, role_id, is_active) VALUES + (?, ?, ?, (SELECT role_id FROM roles WHERE role = ?), 1) } - private def add_admin_user(db : Database, password : String) - pass_hash = Password.create(password) - # STDERR.puts "DEBUG: adding admin user (pass_hash = #{pass_hash}" - db.query(ADD_ADMIN_USER_SQL, [pass_hash]) + private def add_user( + db : Database, + name : String, + email : String, + password : String + ) : Int64 + db.query(ADD_USER_SQL, [ + name, + email, + Password.create(password), + "admin", + ]) + db.last_insert_row_id.to_i64 end # generate random password |