Update authentication method
This commit is contained in:
15
slices/admin/actions/sessions/create.rb
Normal file
15
slices/admin/actions/sessions/create.rb
Normal file
@@ -0,0 +1,15 @@
|
||||
module Admin
|
||||
module Actions
|
||||
module Sessions
|
||||
class Create < Action
|
||||
include Deps["commands.sessions.create"]
|
||||
|
||||
def handle(req, res)
|
||||
create.(email: req.params[:email])
|
||||
|
||||
res.redirect_to "/admin"
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
13
slices/admin/actions/sessions/new.rb
Normal file
13
slices/admin/actions/sessions/new.rb
Normal file
@@ -0,0 +1,13 @@
|
||||
module Admin
|
||||
module Actions
|
||||
module Sessions
|
||||
class New < Action
|
||||
include Deps["views.sessions.new"]
|
||||
|
||||
def handle(req, res)
|
||||
res.render new
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
18
slices/admin/actions/sessions/validate.rb
Normal file
18
slices/admin/actions/sessions/validate.rb
Normal file
@@ -0,0 +1,18 @@
|
||||
module Admin
|
||||
module Actions
|
||||
module Sessions
|
||||
class Validate < Action
|
||||
include Deps["commands.sessions.validate"]
|
||||
|
||||
def handle(req, res)
|
||||
user_id = validate.(token: req.params[:token])
|
||||
session = req.env["rack.session"]
|
||||
|
||||
session[:user_id] = user_id
|
||||
|
||||
res.redirect_to "/admin"
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
48
slices/admin/commands/sessions/create.rb
Normal file
48
slices/admin/commands/sessions/create.rb
Normal file
@@ -0,0 +1,48 @@
|
||||
require "mail"
|
||||
|
||||
module Admin
|
||||
module Commands
|
||||
module Sessions
|
||||
class Create
|
||||
include Deps[
|
||||
"repos.login_tokens_repo",
|
||||
"repos.user_repo"
|
||||
]
|
||||
|
||||
def call(email:)
|
||||
app_settings = Admin::Container["settings"]
|
||||
user = user_repo.by_email(email: email)
|
||||
|
||||
return unless user
|
||||
|
||||
login_tokens_repo.delete_all
|
||||
|
||||
token = login_tokens_repo.create(user_id: user.id, token: SecureRandom.uuid)
|
||||
|
||||
Mail.defaults do
|
||||
delivery_method :smtp, {
|
||||
address: app_settings.smtp_server,
|
||||
port: 587,
|
||||
authentication: "plain",
|
||||
openssl_verify_mode: "peer",
|
||||
enable_starttls_auto: true
|
||||
}
|
||||
end
|
||||
|
||||
Mail.delivery_method.settings[:user_name] = app_settings.smtp_username
|
||||
Mail.delivery_method.settings[:password] = app_settings.smtp_password
|
||||
|
||||
mail = Mail.new do
|
||||
subject "Login to #{app_settings.site_name}"
|
||||
body "#{app_settings.micropub_site_url}/admin/login/#{token.token}"
|
||||
end
|
||||
|
||||
mail[:to] = email
|
||||
mail[:from] = app_settings.from_email
|
||||
|
||||
mail.deliver
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
17
slices/admin/commands/sessions/validate.rb
Normal file
17
slices/admin/commands/sessions/validate.rb
Normal file
@@ -0,0 +1,17 @@
|
||||
module Admin
|
||||
module Commands
|
||||
module Sessions
|
||||
class Validate
|
||||
include Deps["repos.login_tokens_repo"]
|
||||
|
||||
def call(token:)
|
||||
user_id = login_tokens_repo.by_token(token: token).user_id
|
||||
if user_id
|
||||
login_tokens_repo.delete_all
|
||||
user_id
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
@@ -1,16 +1,12 @@
|
||||
require "adamantium/middleware/authenticate"
|
||||
|
||||
module Adamantium
|
||||
class AuthenticatedAdminAction
|
||||
def self.call(action:)
|
||||
auth_proc = -> (id) { Admin::Container["repos.user_repo"].exists(id) }
|
||||
action_proc = ->(env) { Admin::Container["actions.#{action}"].call(env) }
|
||||
|
||||
if Hanami.app.settings.basic_auth_username && Hanami.app.settings.basic_auth_password
|
||||
Rack::Auth::Basic.new(action_proc) do |username, password|
|
||||
username == Hanami.app.settings.basic_auth_username &&
|
||||
password == Hanami.app.settings.basic_auth_password
|
||||
end
|
||||
else
|
||||
Rack::Auth::Basic.new(action_proc) { |_username, _password| true }
|
||||
end
|
||||
Adamantium::Middleware::Authenticate.new(action_proc, auth_proc)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@@ -11,6 +11,10 @@ module Admin
|
||||
|
||||
get "/", to: Auth.call(action: "index")
|
||||
|
||||
get "/login", to: "sessions.new"
|
||||
get "/login/:token", to: "sessions.validate"
|
||||
post "/sessions/create", to: "sessions.create"
|
||||
|
||||
get "/pages", to: Auth.call(action: "pages.index")
|
||||
get "/pages/new", to: Auth.call(action: "pages.new")
|
||||
get "/pages/:slug/edit", to: Auth.call(action: "pages.edit")
|
||||
|
15
slices/admin/repos/login_tokens_repo.rb
Normal file
15
slices/admin/repos/login_tokens_repo.rb
Normal file
@@ -0,0 +1,15 @@
|
||||
module Admin
|
||||
module Repos
|
||||
class LoginTokensRepo < Adamantium::Repo[:login_tokens]
|
||||
commands :create
|
||||
|
||||
def by_token(token:)
|
||||
login_tokens.where(token: token).one
|
||||
end
|
||||
|
||||
def delete_all
|
||||
login_tokens.delete
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
17
slices/admin/repos/user_repo.rb
Normal file
17
slices/admin/repos/user_repo.rb
Normal file
@@ -0,0 +1,17 @@
|
||||
module Admin
|
||||
module Repos
|
||||
class UserRepo < Adamantium::Repo[:users]
|
||||
commands :create
|
||||
|
||||
def exists(id)
|
||||
!!users
|
||||
.where(id: id)
|
||||
.one
|
||||
end
|
||||
|
||||
def by_email(email:)
|
||||
users.where(email: email).one
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
24
slices/admin/templates/layouts/minimal.html.slim
Normal file
24
slices/admin/templates/layouts/minimal.html.slim
Normal file
@@ -0,0 +1,24 @@
|
||||
html
|
||||
head
|
||||
meta charest="utf-8"
|
||||
|
||||
meta name="viewport" content="width=device-width, initial-scale=1.0"
|
||||
|
||||
meta name="theme-color" content="rgb(37, 99, 235)"
|
||||
|
||||
title Admin // Daniel Nitsikopoulos
|
||||
|
||||
= stylesheet_tag "app"
|
||||
link rel="icon" type="image/x-icon" href="/assets/favicon.ico"
|
||||
|
||||
body class="bg-white dark:bg-black selection:bg-blue-100 selection:text-blue-900 dark:selection:bg-blue-600 dark:selection:text-blue-100"
|
||||
main class="pb-8 px-4 pt-4 md:pt-8"
|
||||
header class="mb-12 max-w-screen-md mx-auto"
|
||||
div class="flex items-center mb-8 md:mb-12 text-lg md:text-xl text-gray-400 dark:text-gray-600"
|
||||
div class="flex-none mx-auto md:flex-auto md:mx-0"
|
||||
div class="h-card flex items-center"
|
||||
img class="u-photo w-6 h6 md:w-10 md:h-10 rounded-full mr-1.5" src="/assets/memoji.png"
|
||||
a href="/" rel="me" class="u-url u-uid"
|
||||
h1 class="p-name uppercase text-sm md:text-sm text-gray-400 dark:text-gray-400" = Hanami.app.settings.site_name
|
||||
|
||||
== yield
|
7
slices/admin/templates/sessions/new.html.slim
Normal file
7
slices/admin/templates/sessions/new.html.slim
Normal file
@@ -0,0 +1,7 @@
|
||||
div class="max-w-prose mx-auto prose dark:prose-invert"
|
||||
form action="/admin/sessions/create" method="POST"
|
||||
div class="mb-2"
|
||||
label for="email" class="mr-2" Email
|
||||
input type="email" id="email" name="email" class="border"
|
||||
div class="mb-2"
|
||||
button Login
|
9
slices/admin/views/sessions/new.rb
Normal file
9
slices/admin/views/sessions/new.rb
Normal file
@@ -0,0 +1,9 @@
|
||||
module Admin
|
||||
module Views
|
||||
module Sessions
|
||||
class New < Admin::View
|
||||
config.layout = "minimal"
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
Reference in New Issue
Block a user