Cancan + Devise, best way to have admin manage users - ruby-on-rails-3

I am working on an app where a company admin should be able to create and update users in his company. (Users can also create and update their accounts independently).
I used Devise and Cancan for registration and permission management. I configured Devise to get the required signup and user update processes. I created a namespace for the admin views.
My admin controller (/app/controllers/admin/base_controller.rb) looks like this:
class Admin::BaseController < ApplicationController
authorize_resource :class => false
layout 'admin'
def dashboard
end
end
In addition to my "regular" users_controller, I have a controller (/app/controllers/admin/users_controller.rb) and associated views dedicated to Admin user management.
class Admin::UsersController < Admin::BaseController
...
end
Now, what's the cleanest way to implement Devise-related user admin features (at this point, create and update users)?
Have a conditional (based on user permissions) in my "regular" registrations_controller and confirmations_controller to render and redirect different views? (cf. Devise form within a different controller)
Or create new controllers in my admin namespace? If the latest is better, what are the main steps to follow?

Herein lies your issue, once you namespace or move any user management to another controller, you leave the scope of Devise. So at the point where you are in Admin::UsersController, Devise doesn't care about what you do, there are no 'devise-related' admin features as you stated. You can implement your Admin::UsersController as a standard RESTful controller if you wish.
In this manner, creating users through a namespaced controller, Devise will still perform actions such as confirmations. There is one small thing to keep in mind when creating and updating users this way. If you do not set a password as the admin, you will have to delete the password and password_confirmation from the params hash. To do so, the start of your create and update actions would look like so:
if params[:user][:password].blank?
params[:user].delete(:password)
params[:user].delete(:password_confirmation)
end
I employ this same method in many of my applications, and have yet to have it fail.
EDIT
namespace :admin do
resources :users
end

Related

Create Custome Template in Devise and Rails4

I have devise with single table inheritance,
Class User
end
class a < user
end
class b < user
end
class c < user
end
I wanted sign_up page for each class a,b,c and sign_in page.
How to achieve in Devise!!!
How to create custom templates in user devise folder.
I am not sure about purposes you'd like to implement it to, but I think you should consider splitting your users' roles into separate models according to devise multiple models readme
and creating different views for them if you need it:
If you have more than one Devise model in your application (such as "User" and "Admin"), you will notice that Devise uses the same views for all models. Fortunately, Devise offers an easy way to customize views. All you need to do is set "config.scoped_views = true" inside "config/initializers/devise.rb".
After doing so, you will be able to have views based on the role like "users/sessions/new" and "admins/sessions/new". If no view is found within the scope, Devise will use the default view at "devise/sessions/new"
Keep in mind that those models will have completely different routes. They do not and cannot share the same controller for sign in, sign out and so on. In case you want to have different roles sharing the same actions, we recommend you to use a role-based approach, by either providing a role column or using CanCan.

rails access signed in user and the user id for the profile for a multi-page profile

Hi clever programmers,
I've been searching and reading a couple days, but I need some Rails help-
Here is my goal: I want to make a multi-page profile for each user, and I'd like to handle this profile with a profile controller.
The problem? How do I make the 'show' REST action apply to an entire controller instead of just one page? Specifically, how can I have both a #current_user and a #user variable available in the Profile controller that correspond to the signed-in user and the current user's page.
I'm not sure if I should be making routes with multiple :id s in the route or if there is some way to persist the signed-in-user in something like #current_user when they sign in that is just available everywhere and then I would use the :id of the user who's profile it is in the route. I'm pretty sure facebook does something like facebook.com/{your_id}/{their_id}/ for example.
I tried accessing #current_user from my session_helper.rb class but it came up nil and I'm not sure how to pass the :id to use User.find(params[:id]) because the profile controller is not affiliated with the resource for the User model.
Any protips or links to helpful readings would be much appreciated. I'm a beginner so feel free to suggest a better course of action if I'm going against the rails way. Thanks in advance!
You may not know but you can store session data, and user_id it's really common thing that people saves on it.
So for saving at the sign in
session[user_id] = ....
Then you could have something like this on a helper
def current_user
User.find(session[user_id]) if session[user_id]
end
You should check the gem called devise. It provides all the functionality for aunthentication and it also provides a current_user method everywhere. You should check it at least to see how they have implemented that method.

Merging ActiveAdmin users with existing user model

I've set up ActiveAdmin early in my project and used the default admin_users model for authentication. I've since used Devise to set up a separate User model and have realized it would probably be much smarter to merge the two tables, such that an Administrator can have administrative actions both in Activeadmin and in the front end of the site. How can I configure ActiveAdmin to use the Users model with maybe a column to flag an administrator (eg. is_admin or event a permissions level to make Administrators and Moderators)?
Rails 3.1
ActiveAdmin 0.3.3
Devise 1.4.9
For a quick code block of how to do this using an existing "User" model with activeadmin, the answer is actually really easy. In the ApplicationController:
class ApplicationController < ActionController::Base
def authenticate_admin_user! #use predefined method name
redirect_to '/' and return if user_signed_in? && !current_user.is_admin?
authenticate_user!
end
def current_admin_user #use predefined method name
return nil if user_signed_in? && !current_user.is_admin?
current_user
end
end
And just use what Devise already has set up for authentication. The redirect_to is where you want to send users who ARE signed in and DO NOT have administrative privileges.
ActiveAdmin let's you define your own authentication methods. You can migrate your user tables to have an additional admin column and mark the existing admins as such in it, then set your authentication methods (as specified) in config/initializers/active_admin.rb.

Rails: How to link a model to an authenticated user

I want to link a model Tasks to a User properly, to make sure that only an authenticated user can access only the Tasks and dependent models that belong_to User and Task
My user model was generated using nifty authentication from Railscasts' Ryan B
I'm having a lot of trouble finding a guide on how to set up these views to be secure.
Any suggestions SO?
I think you are looking for an authorization solution. If this is a simple app, you should set up your controllers to return only tasks belong to the user like so:
#tasks = current_user.tasks
Presumably you have a has_many association set up on your User model. If you do this for all your controllers, they will be scoped to your user, so you don't have to worry about authorization.
If you are looking for a more complex solution, look towards something like cancan.

Have CanCan use Active Admin user?

I'm using Devise and CanCan for authorization on the frontend of a Rails 3 app. I also have Active Admin as the interface for the backend. I'm trying to create different roles for admins in the backend. Both ends have a login form that uses different 'user' models & tables. The problem is that CanCan fetches the current user from the frontend (grabbing the current user object) and uses that to see if someone in the backend has the correct permissions.
So, how I can have CanCan correctly grab the admin user that's logged in?
If anyone needs more information, I'll be glad to supply it.
I have not used ActiveAdmin before, but have used Devise and Cancan in a couple of projects before.
Having looked at Active Admin Documentation,
Set the method that controllers should call to authenticate the current user with:
# config/initializers/active_admin.rb
config.authentication_method = :authenticate_admin_user!
Set the method to call within the view to access the current admin user
# config/initializers/active_admin.rb
config.current_user_method = :current_admin_user
You can override Cancan behaviour in your application, by looking at :current_admin_user instead of :current_user.
Refer here Cancan changing defaults.
If you still can't get it, post your problems, where you are stuck.