diff --git a/src/config.cr b/src/config.cr index 1c80542..e85a2b7 100644 --- a/src/config.cr +++ b/src/config.cr @@ -20,6 +20,8 @@ class Config property plugin_path : String = File.expand_path "~/mango/plugins", home: true property download_timeout_seconds : Int32 = 30 + property disable_login = false + property default_username = "" property mangadex = Hash(String, String | Int32).new @[YAML::Field(ignore: true)] @@ -85,5 +87,9 @@ class Config unless base_url.ends_with? "/" @base_url += "/" end + if disable_login && default_username.empty? + raise "Login is disabled, but default username is not set. " \ + "Please set a default username" + end end end diff --git a/src/handlers/auth_handler.cr b/src/handlers/auth_handler.cr index be4f6b1..1db4376 100644 --- a/src/handlers/auth_handler.cr +++ b/src/handlers/auth_handler.cr @@ -68,13 +68,14 @@ class AuthHandler < Kemal::Handler return call_next(env) end - unless validate_token env + unless validate_token(env) || Config.current.disable_login env.session.string "callback", env.request.path return redirect env, "/login" end if request_path_startswith env, ["/admin", "/api/admin", "/download"] - unless validate_token_admin env + unless validate_token_admin(env) || + Storage.default.username_is_admin Config.current.default_username env.response.status_code = 403 end end diff --git a/src/storage.cr b/src/storage.cr index 33b751f..ffcd753 100644 --- a/src/storage.cr +++ b/src/storage.cr @@ -64,6 +64,14 @@ class Storage init_admin if init_user end + + # Verifies that the default username in config is valid + if Config.current.disable_login + username = Config.current.default_username + unless username_exists username + raise "Default username #{username} does not exist" + end + end end unless @auto_close @db = DB.open "sqlite3://#{@path}" @@ -90,6 +98,28 @@ class Storage end end + def username_exists(username) + exists = false + MainFiber.run do + get_db do |db| + exists = db.query_one("select count(*) from users where " \ + "username = (?)", username, as: Int32) > 0 + end + end + exists + end + + def username_is_admin(username) + is_admin = false + MainFiber.run do + get_db do |db| + is_admin = db.query_one("select admin from users where " \ + "username = (?)", username, as: Int32) > 0 + end + end + is_admin + end + def verify_user(username, password) out_token = nil MainFiber.run do diff --git a/src/util/web.cr b/src/util/web.cr index c384099..647a536 100644 --- a/src/util/web.cr +++ b/src/util/web.cr @@ -7,6 +7,10 @@ macro layout(name) if token = env.session.string? "token" is_admin = @context.storage.verify_admin token end + if Config.current.disable_login + is_admin = @context.storage. + username_is_admin Config.current.default_username + end page = {{name}} render "src/views/#{{{name}}}.html.ecr", "src/views/layout.html.ecr" rescue e @@ -21,10 +25,16 @@ macro send_img(env, img) 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 - token = env.session.string "token" - (@context.storage.verify_token token).not_nil! + begin + token = env.session.string "token" + (@context.storage.verify_token token).not_nil! + rescue e + if Config.current.disable_login + Config.current.default_username + else + raise e + end + end end def send_json(env, json)