I have both Pundit and Devise setup and working correctly in my rails app. However I am unsure about how to let the user decide their role when signing up.
At the moment:
This works.
But I am concerned that a malicious user could change this param to say "Admin" and now they are an admin.
How should I handle this? I don't want to put a restriction in the model as that will cause issues when I want to create an admin. Should I override the devise registrations controller to put a check in there?
After a fair amount of googling I have an answer. First stick some validation in your model for the roles Active Record Validations Guide: See 2.6 inclusion: validator option
After this your roles are validated to ensure they are correct, you could of course have a lookup table as well. Then you have two options:
So either way you need to override the registrations controller, its just a case of how much.
I suspect there is a way to do this with just Pundit. But I have yet to be able to get it to work.
You don't need to override Devise's RegistrationsController
for what you're trying to do.
If you want admins to be able to create users that have an arbitrary role set, you could simply use your own controller. Devise still makes it easy to create a user yourself , so you'll just have to make a controller handling this. Of course, don't forget to protect it using Pundit so only admins can use this functionality.
This approach still works if you use the Confirmable
module. As no confirmation e-mail will be sent on user creation, though, you'll either have to call user.confirm!
after saving the model to immediately unlock the account, or manually send the confirmation e-mail using user.send_confirmation_instructions
.
Edit:
This Pundit policy may or may not work for what you're trying to do. You will have to override the create
action of Devise's RegistrationsController
here in order to use Pundit's authorize
method. For dryness' sake, you should also move the roles list elsewhere, perhaps into the model.
class UserPolicy < Struct.new(:current_user, :target_user)
def create?
registration_roles.include?(target_user.role) if current_user.nil?
end
private
def registration_roles
%w(RED BLU Spectator)
end
end
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.