mirror of
https://github.com/hkalexling/Mango.git
synced 2025-08-02 10:55:30 -04:00
Store token and callback URI in memory session
This commit is contained in:
parent
12c3c3f356
commit
de690fbf29
@ -28,6 +28,10 @@ shards:
|
|||||||
github: kemalcr/kemal
|
github: kemalcr/kemal
|
||||||
version: 0.26.1
|
version: 0.26.1
|
||||||
|
|
||||||
|
kemal-session:
|
||||||
|
github: kemalcr/kemal-session
|
||||||
|
version: 0.12.1
|
||||||
|
|
||||||
kilt:
|
kilt:
|
||||||
github: jeromegn/kilt
|
github: jeromegn/kilt
|
||||||
version: 0.4.0
|
version: 0.4.0
|
||||||
|
@ -15,6 +15,8 @@ license: MIT
|
|||||||
dependencies:
|
dependencies:
|
||||||
kemal:
|
kemal:
|
||||||
github: kemalcr/kemal
|
github: kemalcr/kemal
|
||||||
|
kemal-session:
|
||||||
|
github: kemalcr/kemal-session
|
||||||
sqlite3:
|
sqlite3:
|
||||||
github: crystal-lang/crystal-sqlite3
|
github: crystal-lang/crystal-sqlite3
|
||||||
baked_file_system:
|
baked_file_system:
|
||||||
|
@ -5,6 +5,7 @@ class Config
|
|||||||
|
|
||||||
property port : Int32 = 9000
|
property port : Int32 = 9000
|
||||||
property base_url : String = "/"
|
property base_url : String = "/"
|
||||||
|
property session_secret : String = "mango-session-secret"
|
||||||
property library_path : String = File.expand_path "~/mango/library",
|
property library_path : String = File.expand_path "~/mango/library",
|
||||||
home: true
|
home: true
|
||||||
property db_path : String = File.expand_path "~/mango/mango.db", home: true
|
property db_path : String = File.expand_path "~/mango/mango.db", home: true
|
||||||
|
@ -21,18 +21,14 @@ class AuthHandler < Kemal::Handler
|
|||||||
call_next env
|
call_next env
|
||||||
end
|
end
|
||||||
|
|
||||||
def validate_cookie_token(env)
|
def validate_token(env)
|
||||||
cookie = env.request.cookies.find do |c|
|
token = env.session.string? "token"
|
||||||
c.name == "token-#{Config.current.port}"
|
!token.nil? && @storage.verify_token token
|
||||||
end
|
|
||||||
!cookie.nil? && @storage.verify_token cookie.value
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def validate_cookie_token_admin(env)
|
def validate_token_admin(env)
|
||||||
cookie = env.request.cookies.find do |c|
|
token = env.session.string? "token"
|
||||||
c.name == "token-#{Config.current.port}"
|
!token.nil? && @storage.verify_admin token
|
||||||
end
|
|
||||||
!cookie.nil? && @storage.verify_admin cookie.value
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def validate_auth_header(env)
|
def validate_auth_header(env)
|
||||||
@ -42,7 +38,7 @@ class AuthHandler < Kemal::Handler
|
|||||||
token = verify_user value
|
token = verify_user value
|
||||||
return false if token.nil?
|
return false if token.nil?
|
||||||
|
|
||||||
set_token_cookie env, token
|
env.session.string "token", token
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -57,7 +53,7 @@ class AuthHandler < Kemal::Handler
|
|||||||
end
|
end
|
||||||
|
|
||||||
def handle_opds_auth(env)
|
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
|
call_next env
|
||||||
else
|
else
|
||||||
env.response.status_code = 401
|
env.response.status_code = 401
|
||||||
@ -69,12 +65,13 @@ class AuthHandler < Kemal::Handler
|
|||||||
def handle_auth(env)
|
def handle_auth(env)
|
||||||
return call_next(env) if request_path_startswith env, ["/login", "/logout"]
|
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"
|
return redirect env, "/login"
|
||||||
end
|
end
|
||||||
|
|
||||||
if request_path_startswith env, ["/admin", "/api/admin", "/download"]
|
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
|
env.response.status_code = 403
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -9,10 +9,7 @@ class MainRouter < Router
|
|||||||
|
|
||||||
get "/logout" do |env|
|
get "/logout" do |env|
|
||||||
begin
|
begin
|
||||||
cookie = env.request.cookies.find do |c|
|
env.session.delete_string "token"
|
||||||
c.name == "token-#{Config.current.port}"
|
|
||||||
end.not_nil!
|
|
||||||
@context.storage.logout cookie.value
|
|
||||||
rescue e
|
rescue e
|
||||||
@context.error "Error when attempting to log out: #{e}"
|
@context.error "Error when attempting to log out: #{e}"
|
||||||
ensure
|
ensure
|
||||||
@ -26,8 +23,15 @@ class MainRouter < Router
|
|||||||
password = env.params.body["password"]
|
password = env.params.body["password"]
|
||||||
token = @context.storage.verify_user(username, password).not_nil!
|
token = @context.storage.verify_user(username, password).not_nil!
|
||||||
|
|
||||||
set_token_cookie env, token
|
env.session.string "token", token
|
||||||
redirect env, "/"
|
|
||||||
|
callback = env.session.string? "callback"
|
||||||
|
if callback
|
||||||
|
env.session.delete_string "callback"
|
||||||
|
redirect env, callback
|
||||||
|
else
|
||||||
|
redirect env, "/"
|
||||||
|
end
|
||||||
rescue
|
rescue
|
||||||
redirect env, "/login"
|
redirect env, "/login"
|
||||||
end
|
end
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
require "kemal"
|
require "kemal"
|
||||||
|
require "kemal-session"
|
||||||
require "./library"
|
require "./library"
|
||||||
require "./handlers/*"
|
require "./handlers/*"
|
||||||
require "./util"
|
require "./util"
|
||||||
@ -65,6 +66,13 @@ class Server
|
|||||||
serve_static false
|
serve_static false
|
||||||
add_handler StaticHandler.new
|
add_handler StaticHandler.new
|
||||||
{% end %}
|
{% 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
|
end
|
||||||
|
|
||||||
def start
|
def start
|
||||||
|
20
src/util.cr
20
src/util.cr
@ -6,12 +6,9 @@ UPLOAD_URL_PREFIX = "/uploads"
|
|||||||
macro layout(name)
|
macro layout(name)
|
||||||
base_url = Config.current.base_url
|
base_url = Config.current.base_url
|
||||||
begin
|
begin
|
||||||
cookie = env.request.cookies.find do |c|
|
|
||||||
c.name == "token-#{Config.current.port}"
|
|
||||||
end
|
|
||||||
is_admin = false
|
is_admin = false
|
||||||
unless cookie.nil?
|
if token = env.session.string? "token"
|
||||||
is_admin = @context.storage.verify_admin cookie.value
|
is_admin = @context.storage.verify_admin token
|
||||||
end
|
end
|
||||||
render "src/views/#{{{name}}}.ecr", "src/views/layout.ecr"
|
render "src/views/#{{{name}}}.ecr", "src/views/layout.ecr"
|
||||||
rescue e
|
rescue e
|
||||||
@ -28,10 +25,8 @@ end
|
|||||||
macro get_username(env)
|
macro get_username(env)
|
||||||
# if the request gets here, it has gone through the auth handler, and
|
# 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
|
# we can be sure that a valid token exists, so we can use not_nil! here
|
||||||
cookie = {{env}}.request.cookies.find do |c|
|
token = env.session.string "token"
|
||||||
c.name == "token-#{Config.current.port}"
|
(@context.storage.verify_token token).not_nil!
|
||||||
end.not_nil!
|
|
||||||
(@context.storage.verify_token cookie.value).not_nil!
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def send_json(env, json)
|
def send_json(env, json)
|
||||||
@ -137,13 +132,6 @@ macro render_xml(path)
|
|||||||
send_file env, ECR.render({{path}}).to_slice, "application/xml"
|
send_file env, ECR.render({{path}}).to_slice, "application/xml"
|
||||||
end
|
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)
|
macro render_component(filename)
|
||||||
render "src/views/components/#{{{filename}}}.ecr"
|
render "src/views/components/#{{{filename}}}.ecr"
|
||||||
end
|
end
|
||||||
|
Loading…
x
Reference in New Issue
Block a user