Best authentication for modular Rails project - ruby-on-rails

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.

Related

Do Rails5 API mode app and non API mode app share codes each other?

I'm goint to create a RESTfull service app is made of Rails5 with API mode.
I also need an admin app that provides web views for managing users and contents.
These two apps will share codes each other.
I know a way of creating the API mode app.
$ rails new apiapp --api
How do I create the other project?
The way I would implement this kind of functionality is like so:
RAIL API for your model, database, validation and relationships logic.
Client side MVC for Admin app with RESTful calls. For this I would use Backbone Marionette.
this is the cleanest, least code repetition implementation I can think of, which follows industry standards.
this is as per the software mantra 'consume your own dog food' - if you create an api, use its interface to do your stuff. this way you test and improve it as you go.
If you want RAILS only on both ends, you would be better off implementing your ADMIN and your API as one app, for least code repetition. Create an API controller name space for all your exterior calls, and code normal rails for your admin views and stuff. this way your database and model validation and relationship logic is shared, but controllers and route namespaces are not.
Toodles.
You build the other project as a normal rails project. The thing to understand about Rails 5 api mode is that you cannot have normal html stuff as part of it. The entire rendering pipeline (assets and such) is missing. Rails 5 api mode is fast because big parts of the environment are just plain gone.
What you want to do is have 2 projects:
admin
api
And figure out a way to share your model logic across them.
If you use devise for authentication this is particularly tricky since devise adds things into your user model that you cannot have in an api project. Here's how I got around it:
If Rails.application.class.parent_name == "admin"
# devise crap goes here
end
How exactly you easily share a directory of models across 2 git repos? I have no good answer. I have a rake task which sync's things manually by copying them from the canonical source to the destination but that's a hack.

Ruby on rails admin actions

I'm learning Rails 4 and I'm looking to build in some basic admin functionality such as creating and viewing users. I can think of a few ways to do it manually, (such as creating a new controller or adding filters) but I'm pretty sure there's a "Rails Way" to do this easily. I've been digging through the docs and I see references to "built in authentication" that support my hunch, but I can't find the actual documentation.
For example, in CakePHP you can just prefix actions with admin_ and /admin/controller/action will work automatically. Is there a similar convention for Rails? If so, where can I find it?
Update:
As I continue to research this, I start to get the impression that admin authorization in Rails is commonly not handled by the Rails core, but rather in a gem like cancan. Perhaps this is why I was striking out by searching the Rails docs.
Update2:
This question wasn't intended to be a round-up of authorization gems, but since it appears gems are the typical way to handle even basic admin authorization, I'd like to find the simplest, most basic (and hopefully universal) option. A couple options have been proposed below which come bundled with default dashboard views and elaborate configurations. I don't need all that. Just a simple, reliable strategy for dividing users into admins and non-admins with different scopes of allowed actions.
Check out the awesome rails_admin gem. It automatically generates just about everything you could need. Very handy and awesome project. https://github.com/sferik/rails_admin
Authentication is handled via the devise gem and authorization via cancan.
It's no replacement for custom admin functionality if you have very specific requirements, but it's great for general admin tasks you described.

Rails Design Question: How should I structure my controllers for multiple privilege levels?

I am writing a site with multiple levels of privileges. There are basically 3 kinds of users in my system. They are Admin, Business, and Consumers (normal users). Let's just say that I am building an advertising site.
So I have a model "Campaign" which has a RESTful API that comes with rails scaffold. Businesses can create campaigns, users can only see which campaigns they want to join, and admins can do everything.
Now, I know how to apply before_filter and check rigorously for the type of users that can access a particular view.
However, each level of privilege has its own unique views.
Businesses can see the insights and analytics of their campaigns. (let's call this campaigns/analytics)
Consumers can see all the campaigns that they have participated in. (let's call this campaigns/your)
And admins have special views where they can monitor the site's activity. (let's call this campaigns/monitor_businesses).
Right now, my CampaignController has the usual RESTful views + analytics + your + monitor_businesses. Of course, I have multiple data models (not just campaigns) and this makes my RESTful controllers for those data models to be really messy.
What should I do? I am seriously considering starting a ConsumerController and then a BusinessController and put all associated views in these controllers. I don't know if this violates "RESTful" principles but I want to know what better patterns exists to deal with my problem.
I am open to all kinds of suggestions.
Why dont you try the CanCan gem for role management?
You can install as you would any gem using bundler.
It is easy to set up and keeps you from creating the same boilerplate code that you normally would by creating extra controllers or actions.
To get you started I suggest that you visit the documentation on the main page. There is more information about defining what a user can do here and you can see how to check for abilities here.
You also need to add one line to controllers you want to enforce permissions on which you can read about here.
If the standard documentation isnt enough to get you started why don't you take a look at Railscast 192. It shows you how to get up and running with CanCan and it is a great source because Ryan Bates is the creator of the screencast as well as the creator of CanCan. If the video moves too fast for you there is a text version here.
y dont you try the cancan gem for role management http://rubygems.org/gems/cancan
or do gem install cancan I hope this helps.

Need help with design of a Rails 2 app having two partitions

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

Authorization model for Ruby on Rails

I am building a project management app and I am not sure which is the best/correct authorization model to implement given I am new to Rails (and programming in general). Here is what I am trying to do.
I want to be able to add a "client" to the application and then multiple projects to a client. I would like to be able to add users (that are essentially representatives of the client) to view that clients multiple projects but not other clients. I intend on having controllers for time tracking, notes, comments and images all to be associated with both clients and project of that client.
In addition, I would like to set up the account to control who is able to have one. I don't need the user to establish an account on their own.
Does that make sense?
I believe what you are mentioning is called Authorization not Authentication, anyway:
I would suggest acl9 for authorization and authlogic for authentication.
These (free) Railscasts should give you some food for thought. There are lots of great RubyGems/plugins out there for this sort of thing.
The Ruby Toolbox gives you an overview of tools and their popularity in the rails community (rated by watchers and forkers on GitHub). As you can see there, the suggested plugins restful_authentication and authlogic are almost on the same level.
Restful Authentication is still the golden standard for user authentication in ruby on rails.
I have used Authorization plug-in in the past and like it because it gives some nice meta methods such as:
user.is_eligible_for_what --> returns array of authorizable objects for which user has role "eligible"
user.is_moderator_of? group --> returns true/false
user.is_moderator_of group --> sets user to have role "moderator" for object group.
user.is_administrator --> sets user to have role "administrator" not really tied to any object.
There's also a brand new RailsCast on CanCan.
I'd use AuthLogic for authentication (logging in users and making sure they are who they claim to be) and declarative_authorization for authorization (making sure they have access to resources). See Ryan Bates' excellent Railscasts on AuthLogic and restful_authentication for more info.

Resources