I'm looking for a plugin that provides a role based authorization mechanism for securing read/write access to attributes. I'm picturing something along the lines of declarative_authorization for white listing attributes of model objects. I've spent some time looking around but have come up short, does anyone know of anything?
EDIT: I'm using declarative_authorization to control which users have access to what actions in the controller, but I need something similar that provides access control to the attributes of each model object. I'm trying to prevent information leakage through the web API or users from crafting malicious posts. I can do this through the mass_assignment_authorizer but I was hoping some plugin did this already.
CanCan Branch 2.0
https://github.com/ryanb/cancan/tree/2.0
Edit:
The continuation of CanCan is called CanCanCan.
See https://github.com/bryanrite/cancancan
What about creating a model / controller pair for each controller, and then allowing each role only to access methods in its controller(s)? Then you can make a before_filter in each controller that makes sure each user has permission to use methods in that controller.
Related
I know that there are many excellent authorization gems out there like cancan, declarative authorization, cantango etc etc. I want to know is it possible to use the model class as a role itself?
Like for e.g. let there be two resources tutor and student then is it possible to make tutor and student as roles also? I am asking this because I have different authentication pages for different resources as my resources are totally different from each other and I am not going for a single user class for authentication.
Also guide me if I am doing it totally wrong as I am new to rails :-).
The short answer is "yes". For cancan, ultimately you are defining what constitutes authorized access and you can do that however you want. Most of the automatic pieces do assume a user model but there's no hard requirement to use the helpers provided. You'd define the authorization logic in the ability.rb file as usual but manually call authorize! in your controller.
That said, why not make life simpler and go with a single user model, but make the user's role be context-dependent? Then you benefit from an established workflow for auth and probably have a clearer domain model as well.
I have a User model, but I would like another model (Client) to have unique authorization access to a particular action of another controller.
I do not want the Client model to access an action in the Client controller. I want the Client model to access the compare action of the stages controller.
How do I do that ?
Edit1: I should have specified. I have devise & decl_auth already installed. But devise & decl_auth are managing my Users. I need to have more authorization rules for another model outside of the Users model.
If you set up CanCan, this should be a fairly easy thing to do. Here's a link to the RailsCast showing how something like this can be done, http://railscasts.com/episodes/192-authorization-with-cancan.
Extensive docs are here: https://github.com/ryanb/cancan/wiki
I know there are role based authorization gems/plugins for rails to determine if a user can do things based on which role their in. However, is there a best-practice approach to hiding actions from users based on ownership? ie: the show/edit/destroy methods for a user should only be available if they're being performed on the currently logged in user id. Hopefully that makes sense, but I've written some methods to protect against non-owners accessing methods and its become a bit bloated and ugly.
Look at cancan's implementation.
I can recommend on restful_authentication( https://github.com/technoweenie/restful-authentication ). quick tutorial http://railscasts.com/episodes/67-restful-authentication
I have models A,B,C,D, etc. I have my usual controllers/views/helpers for each of these models. These are accessed by a set of content authors in a form based application to populate data into the db. The content authors will also have categories like authors, publishers, super admins etc. Essentially we have built out a mini content management system.
A set of other users (unrelated to the above set) need to access data in some of these models. But the view for those are totally different. I also do not want these users to have the edit screens for the models they are allowed to view. Essentially these guys are end users who use the application as a read only/analytics data store.
How do I accomplish this? Should I create separate controllers and invoke these models for the user website? How do I ensure the website users do not have access to the cms screens? Any pointers, design principles, routing methods, gems for such an application?
How do I accomplish this? Should I create separate controllers and invoke these models for the user website?
I would create a different set of controllers for the backend and frontend. I would move the backend controller to a namespace. More Information on namespaces: http://guides.rubyonrails.org/routing.html#controller-namespaces-and-routing
How do I ensure the website users do not have access to the cms screens? Any pointers, design principles, routing methods, gems for such an application?
For this you need some kind of authentication and authorization. Some examples:
authentication:
authlogic
devise
authorization:
cancan
declarative_authorization
aegis
acl9
There are some good screencasts on this matter:
Authlogic
Declarative Authorization
Authorization with CanCan
Introducing Devise
Customizing Devise
You need a layer of authentication.
The easiest way, and I'd say the most common one is to make separate controllers for each section, and add a before_filter method in each section authenticating and authorizing user to continue (usually a is_admin? method on the user model), or redirect back with an error message if the user is not allowed.
You can separate your controllers with namespaces (something like /admin/authors, /admin/books/1/edit and so on), and keep them RESTful this way.
If you need a more complex schema, you can use any of the authorization tools out there http://ruby-toolbox.com/categories/rails_authorization.html
I think the answer is an admin login and then check if the user has an admin flag, but I also thought of some other related questions.
Is it better to have an admin flag (attr_protected) in the same user table as non admins? or should i have an admin users table?
Should I create a separate rails application for the admin users? This might be overkill since they will both have to access the same datbase (not to mention it might be a huge pain to set up).
Any other suggestions? Right now I just need to secure a page or two so I even looked into HTTP basic or digest authentication as a temporary measure (the protected content is actually not THAT private/important). But... I don't know how to implement HTTP auth for specific actions, I have only seen how to implement it to prevent directory access.
Any direction and discussion would be great. I am sure other Stack Overflow users will benefit from this discussion.
Thanks!
Ryan Bates has a great three part series of Railscasts on this topic which should give you some food for thought:
Part 1: Where Administration Goes
Part 2: Restricting Access
Part 3: Super Simple Authentication
There are also three Railscasts on different authentication techniques:
RESTful Authentication
HTTP Basic Authentication
Authlogic
I'm using restful_authentication plugin for this purpose. And it is very simple to restrict access to any controller or any method. On example in controller add this function:
private
def authorized?
user.admin?
end
or
private
def authorized?
user.admin? if update? || create?
end
I defined admin? method in my User model. I also created update? and create? methods that check which action was called. In restful_authentication authorized? method is always run when accessing controller.
I would put everything in one application and in one table (don't create users and admin table). You can secure admin flag in your users controller by allowing to set this value only for existing admin users.
I think it depends on the type of administration.
If the view your administrators will have of the site is the same as a normal user's, but with additional privileges, I would go with an admin flag. (Or, as your needs expand, a full-fledged roles table.) This is a situation where everybody sees the same stuff, but administrators have access to various actions (delete? edit? ban? etc.) that normal users do not.
If the view your administrators need is wildly different than the normal site, I would recommend a completely separate Rails app that accesses the same database. For example, if your "administrators" are really help desk employees that are going to answer phone calls or deal with billing questions, they may have completely different views of the database (and perhaps ways to edit the data) that aren't available in the regular application.
The disadvantage to having multiple sites is that it is possible to have models (validations, associations, etc.) get out of sync. The disadvantage to having a single site is that you may end up inserting all sorts of ugly "if-admin" code in previously easy-to-understand portions of your site. Which problem is easier to handle depends on your requirements.