aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/guff.cr139
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