Rails : Devise gem authentication and EULA user acceptance - ruby-on-rails

We are using Devise gem on our app and wondering how we could add a Contract acceptance in the process of the gem.
As Devise doesn't do that we thought of 2 solutions, one clean and one a bit dirty.
When user signs in, he is temporarly redirected to EULA page (using #resource from Devise). If accepts, sign in is successful and user enters the app, if rejected, the user is stuck on log in page.
When user signs in, he enters into the app and has a EULA page that he should accept. We then pass a flag to "yes" or "no" depending if he accepts or not. If not, he is redirected to sign in page.
The second solution is the easiest one but I feel it a bit unsecure (and perhaps server loads useless?).
The first one would be better, but we can't find any doc, tips to help us doing this and we are stuck in it.
Does anyone have developped similar thing? What's the best practice?
Thanks!

i think your second option is cleaner: create a bool field in your users table and check that (at login or in every request -> before_filter) and redirect if not set. that way, if you change your eula and the user has to re-accept it, you can clear all the bool flags in your users table to force your users to accept the new version.

Related

Is there a Rails gem for management of a "multi-visit pass" scenario?

I'm a Rails noob. I'm looking to implement an application where users can purchase a multi-visit pass, then spend the credits week-by-week.
For example, register and login, then purchase 10 visits at a gym - the system should list 10 remaining visits. Sign up to a class and 9 remaining visits are listed. When the credits are low, remind the user to top them up with another 10-visit pass, etc.
I know I can use Devise and CanCan to manage the authentication and authorisation aspects.
My question is whether there's already a gem to handle the management of the user's credits, or whether I'd need to write this from scratch.
I've searched https://rubygems.org/gems/rails with no luck, but it's entirely possible I'm missing something obvious.
I don't think there is a gem to do that, but it should be pretty simple to code:
Add remaining_visits to your User model and table.
Do current_user.update(remaining_visits: current_user.remaining_visits+10) when a ticket is purchased.
Copy Devise sessions controller into app/controllers/devise/sessions_controller.rb.
Inside this controller, add this kind of code to create (where the user logs in): current_user.update(remaining_visits: current_user.remaining_visits-1).
Note: Instead of copying Devise sessions controller you can just overwrite the create action.

Determine if a user has ever logged in or made an account

For UX sake, I have sign in and sign up forms on the same page.
However, I'd like to show the sign in page to people who are known to have ever logged in, and the sign up page to users who have never been known to log in.
It seems like something you could do with session and cookies, but it's not clear to me where I would place this code.
(I'm using Devise, rails 3 and mongoid)
Thankfully, Devise has thought of this for you :)
user.last_sign_in_ip
This requires the use of :trackable, which is very well detailed here:
Display last logged in details using Devise in Rails 3
If the value is nil, then the user has never signed in. I think you know where to go from there.
Hope that helps!
-- Adding more detail for clarity
If you can't find the current user's IP, then they have not logged in. So a search for
User.where :last_sign_in_ip => {current IP}
Should do you. You don't even need to know which user, just that one exists.
Now, like you said, you can also use cookies, etc. The logic would work the same way, though; you just get a bit of free lunch here from Devise.

Devise, requiring user to accept terms of service?

I want to mandate that all users accept terms of service, much like is described here:
Ruby on Rails / Devise - Bypassing custom validation option in model when resetting password
However there are 2 requirements that make the above approach not fit.
1) Users are not self registered, rather they are created by a system administrator. The administrator obviously can't accept terms and conditions on the users behalf. The user should be prompted to accept terms and conditions on their first login.
2) If the terms and conditions change after the fact. Users need to re-accept the new terms on subsequent logins.
These seem like pretty standard workflows. Does devise provide any way to accomplish this?
If not, I am thinking this check will need to be implemented in a before_filter on my application controller. (Feels dirty mixing authentication with the application logic...)
Will I have to resort to this or can anyone suggest a better way?
Thanks
this is not something devise would handle and devise should not handle this because a TOS does not pertain to authentication.
What you could do is something like implement a state machine but that may be more complex than what you need.
The simple way would be to add a accepted_tos boolean field to your user model and tie that into a before_filter then you would set the accepted_tos to false everytime the TOS is updated.
Couldn't you theoretically just disable moving further in your app using JQuery?
Disable your form "continue" or "log in" button until they have checked a box or hit a continue button, then enable your log in button once they have.
If you need to store that information just make a column in your database on the user which gets posted too when they check the box or hit the continue button, or you could even utilize the number of log in counts as a way of knowing.
If user.logs > 0 then the user has already accepted the terms.
If user.logs == 0 then the user needs to accept the terms before they log in.
I guess according to your question it seems like tying everything into Devise sounds overly complex.
Hope this helps.

Rails: how to skip validation routine on register and run it on login?

I'm trying to build the backend for a subscription-only area for a website.
When the customer first pays for the subscription, he is going to be registered automatically by a callback from an external app confirming the user has paid.
I want to create the user automatically with several blank attributes. Once the user tries to login for the first time, he has to change or update all of these attributes. Then I want to run the validation routine for the attributes.
Assume the user knows his username and first password as he completes the payment.
The authentication is currently being done with Devise, but it is subject to change.
How would you go about implementing this on Rails?
You could use :on => :update after the relevant validations to bypass them on registration. Then, create a before_filter that redirects logged in users to their profile edit page throughout your application if at least one required attribute is missing.
You can just .save(false) on creation to prevent the validation completely
Not as good of a solution for your problem, but for others like me who got here through Google...
http://guides.rubyonrails.org/v2.3.11/activerecord_validations_callbacks.html#skipping-validations

How do I implement gradual engagement using Devise and Rails 3?

I'm trying to implement a delayed-signup (aka delayed authentication aka gradual engagement) website flow using Devise + Rails.
By gradual engagement, I mean
"Don't make the user sign in until she
absolutely has to, but let her play
around and be remembered on the site"
I'm looking for a simple way to do this using devise. I feel like this is something many others have had to do, but I haven't found documentation on it.
The following approach sounds ok in my head, so I'm going to start with it:
Create users that are only "rememberable"
When certain pages are accessed, require that these users have more
data on them, like a username and
password, via something like
"before_filter :authenticate_user!" in
the appropriate controllers.
Does this approach make sense? Is there a better one? Do you have an implementation of a gradual engagement approach to signup/registration forms using Devise + Rails that you're willing to share?
I think the point of the article you gave us is to say:
only ask for sign up if necessary.
What does this mean?
Let's take an example. You're an e-commerce web site.
When does the customer has to sign up "at last"? During checkout. Never before. So you don't have to store, or remember anything about the user. Devise is never, never used here.
How do you manage the shopping cart of an unsigned in/up user? I'd say database, with session Id as primary key. Or You could store all the items ids in cookie, for later use.
In your code, if you have an action called checkout, just set in your controller a before_filter authenticate_user!, :only => [:checkout]
But maybe you have some constraints, like being able to keep your user's nickname without signing him up for example?
One alternate option is to do email-only signup, then send an email with a special link to finish registration later / bring them back to their account. There's an actively maintained tutorial on devise email-only signup at:
https://github.com/plataformatec/devise/wiki/How-To:-Email-only-sign-up
I've used this tutorial for a site I did a while back where we only asked for their email address to sign up, then later sent emails for them to complete registration / add a password.
You can keep all unsigned user's data in cookies, and transfer them to database once the user logs in, if you need to.

Resources