Rails 3 Devise confirmation filter - ruby-on-rails

I'm wondering if it's possible to selectively require confirmation for certain controller actions using Devise.
Basically: I want users to sign up for an account (which will trigger a confirmation email), be automatically logged in, and be able to immediately explore certain parts of the site as a signed in (but still unconfirmed) user. Access to certain areas (e.g., payment) would require the user to first confirm their email.
I'm hoping for something like before_filter: user_is_confirmed, only: [payment_related_stuff]
I searched for a while and could not find a way to do this out of the box, so I thought creating a hacky solution in which all possibly protected areas would still require before_filter: authenticate!, but I would override the Devise SessionsController's create to permissibly allow access to certain areas before confirmation. However, I'm not sure if this is the right way to go.

Using built in solution in devise, you could use allow_unconfirmed_access_for 1.year in combination with current_user.confirmed? in your before filter

Related

How to make the whole site accessible by the single admin only

How can I achieve the following behavior in Ruby on Rails?
I need to make the whole site accessible by the single admin only, so I need to show the authorization page on every not signed in user's action.
What is the best way to do it? Maybe cancancan or smth like this? Can you give me an example, please?
I'm using Ruby on Rails 4.1.4 btw.
Thanks in advance.
You could use Devise to set it up. Since you want a single user system you donĀ“t need cancancan which authorises resources.
Basically you lock down the app by adding a before filter which requires the use to be authenticated:
before_action :authenticate_user!
There is a guide on how to set up the registration to only accept one user on the Devise wiki. https://github.com/plataformatec/devise/wiki/How-To:-Set-up-devise-as-a-single-user-system
I am big fan of ActiveAdmin. You can manage whole site's content and users through Active Admin even it's provide search, filter & sorting facility. as you described that whole site accessible by the single admin only, not signed in user's action
For your reference:
Live Demo
Active Admin Site
Documentation
RailsCast
If you wanted to authorized user for signed in then as papirtiger answered you can simply use that before_action :authenticate_user! method
Update:
As you mentioned that all users can access the page then in this case I would like to suggest to use cancancan for Rails 4. You can simply assign the roles and as per the roles you can give access to use actions. Provide Role Management System
OR
In your Users table append one column of roles as boolean type and assign admin user to false and by default all users to true. This is the easiest way to achieve your goal.
In your controller set If user's role false then he can access everything..
For E.g. Add an Admin Role
If you have only one user that can access your site then you can use devise gem also. Just create simple user using devise. and use before_filter :authenticate_user! on your applications_controller.rb . So each request will checked before reaching to controller.

How to redirect based on the type of model in devise?

I am working on a new rails 3 application. In this application I have 2 different types of resources(admin and garage) both with different views and with 2 different login screens using devise. The admin can create a garage and can generate a password for the garage using which the garage manager can login to the application. Till now I am able to implement this.
One problem that I am facing in the above implementation is that the garage manager, once logged in, is able to view the admin section by changing the url in the browser and can make changes like an admin user.
Now what I am trying to implement is to have a single log in/sign in form for both the models and when someone logs in, depending on their model type they should be redirected to their respective views. Also, I would like to restrict all the users but admin from using the admin section.
What should be my approach to implement this. I am using devise for authentication.
resource is an instance of one of your models here:
def after_sign_in_path_for(resource)
return admin_route_path if resource.is_a?(Admin)
return garage_route_path if resource.is_a?(Garage)
end
resource is a symbol of the model name here:
def after_sign_out_path_for(resource)
return "/admin" if resource == :admin
return "/" if resource == :garage
end
Normally goes in application_controller.rb
One problem that I am facing in the above implementation is that the garage manager, once logged in, is able to view the admin section by changing the url in the browser and can make changes like an admin user.
As for this, it's an authorization problem and not an authentication problem. Though you can do some simple stuff within devise to manage this, like an admin flag or something of that nature so you can differentiate the two. Just redirecting won't solve this issue entirely.
Take a look at cancan, declarative authorization and I'm sure there are many others.

Creating new users through Devise with an admin user who is already logged in

I'm building a service on Rails using Devise which requires an 'admin' user to add regular users to their organization account.
The default behaviour of Devise doesn't support this, as the ':require_no_authentication' method is called when a logged in admin user tries to create a regular user account.
What would be the recommended method of achieving the functionality I am looking for?
:require_no_authentication is called by prepend_before_filter in the
Devise::RegistrationsController class, rather that in one of the
RegistrationsController methods, so I do not know if this can be
overridden (correct me if I'm wrong).
I believe separating the admin users from the regular users would
work, however these users will share very similar properties, so I
believe doing this will add unnecessary repetition.
I am currently trying to create new admin users (who in turn create
the organization that regular users belong to) using the regular
Devise sign up flow with 'users#new' and 'users#create' controller
actions, and allowing admins to add new users through a 'users#add'
action.
If there is perhaps another good user authentication gem that would better suit my needs, I would be happy to take a look at switching to that.
This seems to be more of an authorization problem than an authentication problem. You can use an authorization gem, such as cancan, to assign roles to users (such as admin) and grant abilities to those roles. This works really well alongside Devise. Here's a tutorial:
http://www.tonyamoyal.com/2010/07/28/rails-authentication-with-devise-and-cancan-customizing-devise-controllers/
EDIT: I think I may have misunderstood your problem. Maybe what you need is just another controller to handle the creating of users outside of the Devise controllers. You could use cancan to restrict access to this controller to only admins.

Devise - limit registrations by using the password reset mechanism?

I'm looking for a way to allow private registrations, or registrations that require manual approval. The latter can be done using the strategy as described here, but I figure the former method might be more convenient if I could somehow take advantage of the password reset module to simplify the process (send an email with a one-time use token but for the purpose of account creation). Has anyone attempted anything like this, or possibly have a better strategy that makes greater use of existing components in devise?
possibly related: Ruby on rails: Devise, want to add invite code?
I have to admit I am not a big fan of using features in a framework that are designed for other uses to accomplish some other goal.
What I usually do when I want a private Sign-Up where you have to be invited to the App is to simply put the user creation/registration inside the Application. After all Devise is just an authentication mechanism ontop of the User model.
So in my current app for example there is a explicit way inside the app for existing users to invite a friend.
The inviting User has a form that creates an entry in the Users table for the new guy with his email address and a field that tells me if the user has finished his registration. I create a little Token that also gets saved to the Database (SecureRandom.hex(8) is a nice way to create such Tokens).
The system shoots the new guy a email telling him where to sign up (with a URL that contains the token), and the sign up is just a form that sets password and additional fields.
All of this is no real magic in Rails, it's all in all 2 controller actions, 2 views and 1 mailer to accomplish it and you are in no way constrained by any API Devise is or is not giving you.
I only had to make sure Devise won't authenticate Users that have not yet redeemed their invitation token but that's it then.
Sure not having to write the sign up view is convenient, but especially when you are dealing with partial information (the inviting User in my case has to fill in some information about the new user already) that gets only complemented by the new user it's quite convenient to just have regular forms where you can do anything with them.
Unless someone writes a Gem that extends Devise to do exactly this, I think I'll stick to this approach.
Turns out there was a third strategy - I could simply lock new accounts (lockable, before_create filter) and provide a manual unlock facility.

Using Devise for Two Different Models but the same Login Form

I have seen lots of similar questions here but nothing that quite fits my need.
I am a pretty experience rails developer but this new project is my first time using both Rails 3 and Devise (I'm normally on authlogic).
My app has two different models that I want to authenticate via devise.
One, User is just a standard users model
Two, Business is similar to a user, (it has an email address column too) but it has additional info in the database (address, phone number, etc..)
I want to be able to log them both in via the same login form. Then obviously once they are logged in they will be presented with different info depending on what type of Model has logged in.
It may or may not be relevant that I was planning on using OmniAuth to allow Users (though probably not businesses) to sign up/on via facebook.
Thanks!
What's the easiest way to go about doing this?
I think the only way to handle this would be to have your own custom sign in form and controller that determined the type of user and then sign them in correctly. I would recommend an approach like what mark mentioned for simplicity (take a look at something like CanCan to manage roles).
Another potential problem with having multiple user models is that you will have multiple versions of all the devise helper methods. So for current_<resource> and <resource>_signed_in? you would have current_user, current_business_user, user_signed_in? and business_user_signed_in?. Then you would either have to implement your own versions of these methods or you would need to check both versions everywhere you used them.
Can do this in application_controller?
current_user = current_resource_a || current_resource_b

Resources