From de690fbf29bdac95dde6965e2609bb1d88725b22 Mon Sep 17 00:00:00 2001 From: Alex Ling Date: Sun, 7 Jun 2020 16:18:34 +0000 Subject: [PATCH] Store token and callback URI in memory session --- shard.lock | 4 ++++ shard.yml | 2 ++ src/config.cr | 1 + src/handlers/auth_handler.cr | 25 +++++++++++-------------- src/routes/main.cr | 16 ++++++++++------ src/server.cr | 8 ++++++++ src/util.cr | 20 ++++---------------- 7 files changed, 40 insertions(+), 36 deletions(-) diff --git a/shard.lock b/shard.lock index baa3256..2d95a6f 100644 --- a/shard.lock +++ b/shard.lock @@ -28,6 +28,10 @@ shards: github: kemalcr/kemal version: 0.26.1 + kemal-session: + github: kemalcr/kemal-session + version: 0.12.1 + kilt: github: jeromegn/kilt version: 0.4.0 diff --git a/shard.yml b/shard.yml index 2550b73..7218c0e 100644 --- a/shard.yml +++ b/shard.yml @@ -15,6 +15,8 @@ license: MIT dependencies: kemal: github: kemalcr/kemal + kemal-session: + github: kemalcr/kemal-session sqlite3: github: crystal-lang/crystal-sqlite3 baked_file_system: diff --git a/src/config.cr b/src/config.cr index e1a6cae..72faab7 100644 --- a/src/config.cr +++ b/src/config.cr @@ -5,6 +5,7 @@ class Config property port : Int32 = 9000 property base_url : String = "/" + property session_secret : String = "mango-session-secret" property library_path : String = File.expand_path "~/mango/library", home: true property db_path : String = File.expand_path "~/mango/mango.db", home: true diff --git a/src/handlers/auth_handler.cr b/src/handlers/auth_handler.cr index 66f89ef..45e84a2 100644 --- a/src/handlers/auth_handler.cr +++ b/src/handlers/auth_handler.cr @@ -21,18 +21,14 @@ class AuthHandler < Kemal::Handler call_next env end - def validate_cookie_token(env) - cookie = env.request.cookies.find do |c| - c.name == "token-#{Config.current.port}" - end - !cookie.nil? && @storage.verify_token cookie.value + def validate_token(env) + token = env.session.string? "token" + !token.nil? && @storage.verify_token token end - def validate_cookie_token_admin(env) - cookie = env.request.cookies.find do |c| - c.name == "token-#{Config.current.port}" - end - !cookie.nil? && @storage.verify_admin cookie.value + def validate_token_admin(env) + token = env.session.string? "token" + !token.nil? && @storage.verify_admin token end def validate_auth_header(env) @@ -42,7 +38,7 @@ class AuthHandler < Kemal::Handler token = verify_user value return false if token.nil? - set_token_cookie env, token + env.session.string "token", token return true end end @@ -57,7 +53,7 @@ class AuthHandler < Kemal::Handler end def handle_opds_auth(env) - if validate_cookie_token(env) || validate_auth_header(env) + if validate_token(env) || validate_auth_header(env) call_next env else env.response.status_code = 401 @@ -69,12 +65,13 @@ class AuthHandler < Kemal::Handler def handle_auth(env) return call_next(env) if request_path_startswith env, ["/login", "/logout"] - unless validate_cookie_token env + unless validate_token env + env.session.string "callback", env.request.path return redirect env, "/login" end if request_path_startswith env, ["/admin", "/api/admin", "/download"] - unless validate_cookie_token_admin env + unless validate_token_admin env env.response.status_code = 403 end end diff --git a/src/routes/main.cr b/src/routes/main.cr index cbcab43..33ed6ba 100644 --- a/src/routes/main.cr +++ b/src/routes/main.cr @@ -9,10 +9,7 @@ class MainRouter < Router get "/logout" do |env| begin - cookie = env.request.cookies.find do |c| - c.name == "token-#{Config.current.port}" - end.not_nil! - @context.storage.logout cookie.value + env.session.delete_string "token" rescue e @context.error "Error when attempting to log out: #{e}" ensure @@ -26,8 +23,15 @@ class MainRouter < Router password = env.params.body["password"] token = @context.storage.verify_user(username, password).not_nil! - set_token_cookie env, token - redirect env, "/" + env.session.string "token", token + + callback = env.session.string? "callback" + if callback + env.session.delete_string "callback" + redirect env, callback + else + redirect env, "/" + end rescue redirect env, "/login" end diff --git a/src/server.cr b/src/server.cr index f12d470..68195f9 100644 --- a/src/server.cr +++ b/src/server.cr @@ -1,4 +1,5 @@ require "kemal" +require "kemal-session" require "./library" require "./handlers/*" require "./util" @@ -65,6 +66,13 @@ class Server serve_static false add_handler StaticHandler.new {% end %} + + Kemal::Session.config do |c| + c.timeout = 365.days + c.secret = Config.current.session_secret + c.cookie_name = "mango-sessid-#{Config.current.port}" + c.path = Config.current.base_url + end end def start diff --git a/src/util.cr b/src/util.cr index 50ad6d0..aa22251 100644 --- a/src/util.cr +++ b/src/util.cr @@ -6,12 +6,9 @@ UPLOAD_URL_PREFIX = "/uploads" macro layout(name) base_url = Config.current.base_url begin - cookie = env.request.cookies.find do |c| - c.name == "token-#{Config.current.port}" - end is_admin = false - unless cookie.nil? - is_admin = @context.storage.verify_admin cookie.value + if token = env.session.string? "token" + is_admin = @context.storage.verify_admin token end render "src/views/#{{{name}}}.ecr", "src/views/layout.ecr" rescue e @@ -28,10 +25,8 @@ end macro get_username(env) # if the request gets here, it has gone through the auth handler, and # we can be sure that a valid token exists, so we can use not_nil! here - cookie = {{env}}.request.cookies.find do |c| - c.name == "token-#{Config.current.port}" - end.not_nil! - (@context.storage.verify_token cookie.value).not_nil! + token = env.session.string "token" + (@context.storage.verify_token token).not_nil! end def send_json(env, json) @@ -137,13 +132,6 @@ macro render_xml(path) send_file env, ECR.render({{path}}).to_slice, "application/xml" end -def set_token_cookie(env, token) - cookie = HTTP::Cookie.new "token-#{Config.current.port}", token - cookie.path = Config.current.base_url - cookie.expires = Time.local.shift years: 1 - env.response.cookies << cookie -end - macro render_component(filename) render "src/views/components/#{{{filename}}}.ecr" end