Allow only one user to be an admin with devise - ruby-on-rails

I`m creating a webpage with rails 6 , devise and cancan .
I need an admin role but i do not want to create a separate model instead i added a Boolean column to user is table , but here`s the thing ,
If any user sign up then it would be a security concern that any user would grant admin privileges only by changing the value of this column to true .
So i thought perhaps i would remove "admin" from "user_params" but then i would have to make this change from the console which is not good enough.
How i should only grant admin to specific user , my thoughts where i would only allow it for the first user only, or specific email but it feels stupid , there must be a smarter way.
How i get the application to have only one admin who can make any other user admin but only him who can do that and if any normal user signed up , no matter what he ca not manipulate this column in any way?
Best Regards

Remove admin from user_params in signup controller. You don't want users to become admin just by preparing request.
Introduce third column super_admin, and grant this role from the console if you have to do it only once.
Create views and controllers only accessible to super_admin where she can update admin for all users.

Related

I am trying to create a secure way to make specific users admins

I have a functioning rails app with devise Admins and Users, and I want to create a secure way that will only allow users with specific IDs to become authorized to become admins. Currently, I have a static link that is not very secure that will make the current user an admin(website.com/make_admin), but I want to find the most secure method to turn specific users into administrators (I am open to all options that could accomplish this). What would be the best way for me to do this?
I'd recommend adding an admin field to the user form to select if they're an admin user, but do a check in the update/create actions on your users controller to check if the current_user (if using Devise) is another admin user (or whatever role type they need to be to update other admin permissions).
You would also probably want to do a check to make sure they can't set themselves as admin=false, otherwise you could end up with no admin users left on the site and no-one with permission to change this. That said, depending on the app you could always just manually manage admin users - my company will do this depending on the client and their needs.
You can use Rolify to give roles to the user's and CanCanCan for access control.
You can assign roles to user either from rails console or you can generate a view for it, and restrict it to admin and assign roles to each individual user.
You could add an admin boolean to your user model, and update it through the rails console
rails g migration add_admin_to_users admin:boolean

Ask for admin password when an ordinary user tries to perform admin only tasks

I have an application built using Ruby on Rails. I use Devise for authentication and CanCanCan for authorization.
My users have two roles, admin and common user. Admin can do everything on the system and common can do limited tasks.
Now a need that everytime a common user tries to do something that needs admin privileges the application asks for an admin password to authorize only that operation.
I have made a research about the topic, but nothing relevant have been found.
I want to know if anyone have done something like this before and how, or if you have suggestions of other approaches to solve this. Thanks in advance.
The easiest way I see is to create a view and a field in database for those purposes.
You can add a field authorized_as_admin_at with a datetime type to the users table.
When you realize that the user needs admin access you:
Check if authorized_as_admin_at was not more than N hours/minutes ago (this method should be in before_filter in ApplicationController or smth identical in your case if you have more complex structure).
If it was, allow them to do what they want, otherwise:
Save the request path in the cookie
Redirect them to the page where they can input admin credentials
If credentials are right, you set autorized_as_admin_at to a current time
Redirect them to the path stored in the cookie.
You can try to store smth like this in session, but that does not look very secure.

Separate Users class [Parse]

I'm building an app that users have to register before they can view the content, I am using Parse for my database needs.
What I need is have a class of Users (Parse.User) for regular users and a class of Users (Parse.User) for admins. The regular users would only be able to access the app, the admins would only be able to access an admin website where they will add the content (products) that will show up in the app.
Is it possible to create 2 different classes of Users with Parse? Or should I create the admin user class manually (not using Parse.User)?
Thanks for the help! I'm pretty new at this databases and user thing haha
What you really want is to create a Role for Administrators. You can assign ACL permissions to this Role and it will be respected throughout Parse. As you add/remove Users from this Role they automatically have the permissions of their current Role(s).
You can read more about Roles in the documentation, there's a whole chapter about it.
I'm fairly certain that you can't create 2 different User classes. (Though I may be wrong.)
But regardless, the easiest way to do this would probably be to keep all the users in the same class and just add an admin boolean key to indicate whether or not the user is an administrator; then log the user in (to access the current user's keys) but only proceed with the actions following a successful app login if the admin value is set to false and, likewise, only proceed with the actions following a successful website login if the admin value is set to true. If the admin value indicates that the user shouldn't be logged in on that platform, don't proceed with the login and instead log the user out.
In my App, a user can take on more than one role. My solution to this is to have a User class and then a pointer for each type of user (could be a regular object pointer, but I use something similar). So there would be an "adminLink" pointing to the Admin role-specific object and a userLink pointing to the user role-specific object. The pointer designates the object containing the attributes relevant to that role (user or admin). Attributes common to all roles are stored in the User object.
"Roles" (capital R) are needed to control access to objects. So for each User, you may need to create a user Role and an Admin Role if the person performs both roles (small r). You have to have a reference for each Role. These can be stored either with the User object in separate attributes or in the role-specific user objects.
-Bob

How can I have a users role change when they enter a pass code?

I have a table of users where each has a role (provided by the cancan gem). All new users are given the role of author.
I would like to be able to issue a sort of voucher code to certain users which when entered will change their role from author to admin.
Is there a way of doing this?
All the roles are already set up and can be changed by an existing admin by editing the users profile.
Thanks very much for any help its much appreciated!
Here is an idea:
Generate a token for each user in the system and store it in the database. Make a form where user can submit his code. Then, in a controller, you may add role you want, if the code supplied by user corresponds to the one written in the database.

Preventing users from making themselves admins

In my app, I have a "User" model, which includes a number of attributes including "has_admin_rights". If true, the user is an admin, if false, they aren't.
Each user has a profile, with their login name, email address, profile pic, etc.
If I'm logged in as a regular user, I can click on a page called "profile", and I can edit my own account, e.g. updating my email address, profile pic, password, whatever. I can ONLY edit my account, and no other.
If I'm logged in as an admin, I can do a little more: for example, I can make ANOTHER user an admin, or take away their admin rights.
Now, only an admin has access to the view where the "make admin" check box appears, but I have a feeling that simply restricting access to the view isn't sufficient.
What I'm concerned about is, since any user can edit their own profile, what's there to stop a user from submitting a custom form post, which has in it the "has_admin_rights"=>"1" parameter on their own account - thereby granting themselves admin access?
What I'm thinking is that, in the User controller, before applying any changes to the "has_admin_rights" field, that I need to check to make sure the user making the request is currently an admin - otherwise I ignore the request altogether, and make no changes.
in the User controller, before applying any changes to the "has_admin_rights" field, that I need to check to make sure the user making the request is currently an admin - otherwise I ignore the request altogether, and make no changes.
yes, exactly. Never trust the client; remember that anybody can just tweak the page directly with Firebug or whatever.
I'd also suggest that you consider adding an audit trail, and log something whenever one admin makes another user into an admin. Maybe also send email to all the admins for a particular group to let them know that an admin has been created (or that rights have been revoked).
attr_protected is pretty useful, too
class User < ActiveRecord::Base
attr_protected :is_admin
end
Add a before_save in your User model that performs this validation .
Ue attr_accessible which white list of model attributes that can be set via mass-assignment
class User < ActiveRecord::Base
attr_accessible :has_admin_rights
end
& in controller
#user.has_admin_rights = current_user.is_admin? "1" : "0"

Resources