I am rebuilding a standard app in Rails (backend + rendering) and looking into creating API-only Rails backend and Node/React frontent.
I'm a little bit riddled on best practices here.
In my old app I had 2 devise models - User and Admin (admin was a separate namespace, so User would not have access to its controllers).
How would you recommend to implement sets of different controllers for admins and users?
Thanks
It always depends in the use case. If the admin has completely other tasks, it's better to create it's own namespace for them. If the admin does the same things as a normal user but with a bit more rights, I would handle the different authorization for both.
For example a user is only authorized to delete his own posts and a admin is allowed to delete all posts.
Related
I'm working on a project that involves two Devise models (User and Admin). What I'd like to do is allow for Admin members to be able to view and manage Users in a RESTful way (i.e: index, show, create, update, destroy).
Would the best way be to create a users_controller and treat it like an average RESTful model (modifying each controller action to work with Devise where applicable)?
Any suggestions would be much appreciated.
Thanks.
CLARIFICATION UPDATE
It seems I wasn't clear about the question above. Answers below are about the authorisation of actions affecting the User model. This isn't what I'm asking about. I'm asking about the best way to facilitate the transaction itself, not the authorisation and restriction of the transaction. What would be the best way to have Admin members creating Users and updating User records without using the standard Devise self-signup. My intention is to disable self-signup so as to only allow new User registration by an Admin member creating the User account. Hopefully, this is more clear. Thanks.
I advise you take a look at the following gems Rolify and CanCan, there were integrated with devise here.
Here's a link
I'm building an API management apps where every user able to find their own token for making an API request. Every end user will have to manage their own API access, they should also have access to many other custom endpoint.
At the moment, the Rails Admin is being used for the internal administration. Such as CRUD of "AdminUser", "Payment", and other internal system management.
The question is: Should I use Rails Admin's feature for this functionality (as in exposing admin control to every regular user)? Or should I just create a separate admin section for the general user with a standard form?
I'm not very experienced in Rails Admin implementation. So, I wonder if I should use it too for the end user.
Thanks for your time & help!
Update
Some of my basic concern about using Rails Admin to me is that: Rails Admin is for developer or internal adminstration. There will be some risk of giving a wrong permission to the end user
Rails Admin is a quick and easy way to access all the data in your app. It can be customised to restrict access to certain models or fields, however you will have to use the Rails Admin DSL for that, and it kind of defeats the purpose of using Rails Admin if you need to do lots of customising.
A danger is also that if you did not set it up properly, the default is to expose all data to the users.
Since the functions you want to expose to the user doesn't sound too complex, it wouldn't be too much effort to write your own.
I'm still learning Rails, but faced with this project: Web solution should consist of three parts - the website, section for partners and admin panel. Section for partners and admin panel should be available as subdirectories (customer's requirement) like this:
somesite.com
somesite.com/partners/
somesite.com/admin/
I decided to make three separate applications with common models and business logic and deploy them in mentioned way using Passenger and Apache.
In the database should be two models: Admin (for administrators only) and User (quite fat model, common for users and partners, differs by is_partner field). Because those models are common to all three sites, I decided to put them in the Rails Engine, and then use appropriate model for each application. But now I have the issue of choosing the suitable authentication module.
Could you advice one? Should I try to use some already existing solution or I better have to implement my own authentication? Or may be my entire approach to this project is wrong from beginning?
Thank you.
I would use one User model, since you won't need to duplicate any logic, and use three roles: user, partner, and admin, unless admins are drastically different from other users. For authentication, I would suggest Devise, which is the go-to authentication system for Rails. For authorization, I would suggest CanCan.
If you're looking for a pre-made admin interface, try RailsAdmin or ActiveAdmin. RailsAdmin is simple to use and easily configurable, but not too customizable, while ActiveAdmin is a little more difficult to use but more customizable. Both of them are integrated with devise.
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.