Closed henrikbjorn closed 2 months ago
Good question! PRs welcome ❤️
on a custom app that I built, something like this works for me:
# app/constraints/user_constraint.rb
class UserConstraint
def initialize(&block)
@block = block
end
def matches?(request)
user = current_user(request)
user.present? && @block.call(user)
end
def current_user(request)
User.find_by(id: request.session[:user_id])
end
end
# config/routes.rb
# authenticate :user, ->(user) { user.admin? } do # <- devise syntax
constraints UserConstraint.new { |user| user.admin? } do
mount GoodJob::Engine, at: "good_job"
mount Avo::Engine, at: Avo.configuration.root_path
end
# authenticated :user do # <- devise syntax
constraints UserConstraint.new { |user| user.present? } do
get 'dashboard', to: 'static#dashboard'
end
Similarly to the above, but the following works for me with Passwordless:
# app/constraints/user_constraint.rb
class PasswordlessConstraint
include Passwordless::ControllerHelpers
attr_reader :authenticatable_type, :session, :lambda
def initialize(authenticatable_type, lambda)
@authenticatable_type = authenticatable_type
@lambda = lambda
end
def matches?(request)
@session = request.session
authenticatable = authenticate_by_session(authenticatable_type)
authenticatable.present? && lambda.call(authenticatable)
end
end
# config/routes.rb
constraints PasswordlessConstraint.new(User, ->(user) { user.has_role?("admin") }) do
root to: 'admin/dashboard#show', as: :admin_root
end
The rest is syntactic sugar, but a bit too much magic.
@tdegrunt That's amazing! Would love to include it if you're up for creating a PR with a test and some docs?
Will this re-query the database for the user?
We might want to think about using env
as warden does.
Took me a while, been on holiday, but added a PR for this.
When using devise they have helpers that can be used in
config/routes.rb
like:Which i personally like very much and better than doing
require_user!
in my controllers.Would be a awesome addition to
passwordless
.Not sure how it would work with Passwordless as most the user finding and authorizing etc. is in the ControllerHelper where Devise calls Warden e.g: https://github.com/heartcombo/devise/blob/main/lib/devise/rails/routes.rb#L477