Devise Invitable invitation to accept an event? - ruby-on-rails

I'm trying to wrap my head around Devise_Invitable controller. It looks like it uses a good deal of reflection but it seems that it assumes that any sublcass you create will be a User (of some kind - perhaps an admin, etc).
What I would like to do is leverage the gem to invite users to accept (presumably by overriding the update method) or reject an event (presumably by creating a new "reject" method that works a lot like update).
Is this a reasonable thing to try to do or am I totallybarking up the wrong tree? I feel like I have enough knowledge to get myself into deep trouble but not get myself out at this point in my rails learning.

I think devise_invitable is not designed for your use case; it's intended use is for invitation-only user registration. That is, you only want people to be able to sign up for an account on your site if they've been invited to do so and have a special invitation code. That's an authentication problem (which is why there's a devise addon that's a solution for it) -- you need to use tokens in order to authenticate invited users who have not yet registered a password.
Your problem appears very different, at least superficially -- it sounds like you just want to implement a user interface for already-authenticated users.

Related

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.

what is the omniauth & email-password registration best practice?

What is the best practice for combining Facebook login (let's say I'll use Omniauth gem) and email+password login?
I saw a few blogs, saw the Railscasts, I know everyone is using Devise gem with Omniauth. But I'm looking for some different perspective.
subquestions:
I'm considering creating email+password sign-up from scratch (not using any gem for this, lets keep it fast and light) so do you have any advice for this ? Or if you have particular gem in mind, please let it be fast.
And do you have any other recommendations for Oauth2 gems (alternative to Omniauth) handling authentication to Facebook ?
I'm sorry I'm asking this fundamental questions here, but I didn't found many answers (and most of them I found are based on Devise)
This is how I saw it's done in most examples on the web
basicly when you signup with email+password, you are creating row directly to User model (not touching the Authent. model) and when signing up with Omniauth, than you are creating new authentication that communicates with User model.
And basicly on next login you are doing something like this :
if (user.password == 'xxx')
login
elsif user.authentication.uid == 'xxx'
login
else
'hello signup !'
end
so you are swiching between 2 models, and raping (sorry for the term) the User model witch should hold only user info
The solution, in a way, I think is correct (from my experience and discussions with my colleagues but I'm still not 100% sure this is the right answer)
as you see even the user+password is going trough Authent. model, that means the site user+password is acting as a provider on its own
so to be absolutly correct it should be look like this
scenario 1
signing up with FB: you save FB uid and authKey to authentication table, then create user
scenario 2
signing up with password: you create new row in AppPass table, then you create row in Authentication table (as a access to provider witch is actually your app) and than you create user
Why?
because now when user logs in, is always going trough Authent. model, not making condition between 2 models (the Authent. and the User model)
now can anyone please tell me, ...is this a good approach :D ?
Intridea offers an email & password strategy to enable this:
https://github.com/intridea/omniauth-identity
:-)
Omniauth is great, so you should probably use that for any/all social media logins.
As far as setting up your own authentication this shouldn't be too hard. Ryan Bates has a great screencast on this: Authentication from scratch
Here is a pretty good omniauth article (you will have to adapt it to your own users table though but its still a great resource) Omniauth rails rumble. Please note that I believe the article author uses the term authorization in the wrong context here. Omniauth has nothing to do with authorization, only authentication and this is a subtle but very important difference.
Here's a link to the ruby toolbox page for the most popular authentication gems: http://ruby-toolbox.com/categories/rails_authentication.html. You probably aren't going to find the exact functionality you are looking for right out of the box with any of the solutions.
I don't think that you are correct that having the different authentication methods go to different tables will put too much strain (perhaps a better term) on the models.
It seems to me that if everyone is doing this using devise, there is a reason for it. You could probably get better performance by writing something scaled down yourself, but it's a big time investment. My guess is that the small performance improvement in your application is not going to be worth the time you spend writing something yourself.
If you're working on a current project with many thousands of concurrent users that is having difficulty scaling, please ignore my advice, since I am not familiar with those type of problems.
I kinda dig in to these problematic more deeply an done some research on my own, these are the conclusions.
The problem is that I'm trying to combine my authentication functionality with site login/signup functionality, witch are two different behaviors. At the end of the FB signup with omniauth, you will have in your Authentication table the facebook uid and that is all that it takes to back login to FB for next time (of course you can store other info (like email) ... but logicly they are more users attributes and should go to user table).
note: its ok to store user information from provider, in Authentication table,
but if you want to work with them you should copy these informations to Users table
When you are signing up with email/password solution, you are writing information that define User on your site. (Authentication is just pointing to User) If we wanted to do password signup trough Authentication table, we would have to store the username & password inside authentications table, and this way merging User model and Authentication to one model. It will be much uglier solution, not talking about problem how to store multiple rows to one user. Also you the Authentication or Oauth are synonyms for "accessing your application trough other site" ( watch these oauth2 videos if you cannot imagine it http://www.youtube.com/view_play_list?p … 0139F609), yet with normal login you are accessing the site directly.
The only way around this problem is making a small app, that will handle the email/password or the user/password signup, generate password provider UID, and write those data to Users table, and than with our main applycation we will request trough omniauth to access the miniapp and store the UID in authentications table.
http://eq8scrapbook.heroku.com/equivalents_article/on_omniauth_and_password_login_best_practice

How to access logged in user from controller in rails 3

I'm trying to create a login system in Rails 3 where I can access the logged in user not only from the views but also from the controller/model level. The reason is that I want to adapt functionality according to a privilege system where logged in users may execute different functions than those that are not logged in.
Up to this point, I tried to implement the login system from railstutorial.com, chapter 9.
When I use the login system only from the view, it works. However, if I try to use the system via a controller, I get the error undefined method 'cookie_jar' for nil:NilClass.
Thank you for any help or best practices you can provide for creating an authentication system where the logged in user can be identified from a controller.
The best advice here is probably "don't". If you want an authentication system, use something like Devise - which has had a lot of time and effort spent making sure that evildoers can't get in
If you want different users to execute different functions, this is access control, and for that you probably want something like cancan or ACL
And you want access to the logged in user from the model level? Again, the best practice is "don't". The model should have no interest in the currently logged in user - that is a matter for the controller.
(That said, rules are sometimes made to be broken - if you are doing an audit trail and need to store information about the user who made a change, for example, passing the currently logged in user to the model may be the best answer ....)
And finally, if you really, really want to do it all from scratch, take a look at this railscast
An extremely simple way is to do it as mentioned in railscast episode : http://railscasts.com/episodes/20-restricting-access
As mentioned in the screen cast, you can use the plugin acts as authenticated (http://www.railsrocket.com/acts_as_authenticated-plugin) for all your user model needs.
If everything done according to the tutorial you should be able to get current_user from both controllers and views. There's also another tutorial on authentication on asciicasts.com by Ryan Bates. You may want to explore it if you are just starting Rails, but for real-life applications it's highly recommended to use Devise or AuthLogic, which are thoroughly tested and constantly evolving.

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

Using Devise to implement a front-door on a website, does Rails allow concurrent sessions?

First, my obligatory "I'm new to rails" statement: I'm new to rails.
Sorry for the following long-winded expository stuff, but I want to make sure I'm asking my question clearly. I'm building a sample manager for a small analytical lab. So far I have built the core user stuff using devise to manage sessions (Basically so I can use all of Devise's nice helper methods throughout my app). The users don't need to be securely separated, so there is no sign in form, it just automatically signs them in for whatever action the user wishes to do.
I would like to put a front door on the website for macro-security that signs in to either the user version of the site (described above) or the admin version. I understand how to implement this using Devise, however, I am unsure as to whether Rails allows this sort of double-session where there's a macro-security session on constantly while a bunch of internal sessions are created and destroyed. Again, sorry for the long-windedness and thanks for your time and help!
Decided to just give it a shot and it turns out it worked. I have to test to see if there are any kinks in the functionality, but as it stands it works well as a front-door while allowing the internal transient sessions.

Resources