0

I have a User model that Devise manages - i.e. all users have email addy/username/pass, etc. If a user logs in, based on their permissions they get access to different things. That works fine.

But I have a Client model, that I would like to grant a token to so they can access one specific action on one specific controller.

Ideally, I would like to generate a token for client john.brown@abc.com (keep in mind that this is not a User.email, but a Client.email) so they can access the compare action for my stages controller, where stage has an id of 7.

I don't want them to be able to access any other stages, other than id7, and I don't want them to have to sign in. i.e. once they access that specific URL (for instance, myapp.com/stages/7/compare?token={unique token generated by devise}) they can see it. But they can't take that token and go to stages/8/compare for instance.

Is it possible for me to do that using Devise ?

If so, how ?

marcamillion
  • 32,933
  • 55
  • 189
  • 380

2 Answers2

1

The purpose of Devise's TokenAuthenticatable strategy is to sign in a user that Devise manages via a token. So, devise has to already manage the model you're signing in, and it sounds like in your app that Client is not being managed by Devise. I do not think it will help you in this instance.

Michelle Tilley
  • 157,729
  • 40
  • 374
  • 311
  • You are right. My `Client` model is not being managed by Devise. But are you sure it can't be used on another model ? As I said, that was my first inclination, but someone told me otherwise and I have not been able to get them to give me more details, and the devise documentation isn't sufficient enough to educate me here. – marcamillion Apr 04 '11 at 01:54
  • I've been wrong before, but it sounds wrong to me. If Devise isn't managing the model, why would Devise sign one in? Now, perhaps you could add Devise to the `Client` model using only `token_authenticatable` as the sign in strategy, and go from there, saving some extra data related to what the client should have access to. However, be aware the Devise token is per-model, not "per permission" as it sounds like you want (e.g. a `Client` could have more than one token, each for a different compare URL). But IMO Devise is overkill for that--just give `Client` many `tokens` with associated data. – Michelle Tilley Apr 04 '11 at 01:58
  • Hrmm.....well I have started the process of giving the clients many tokens - but the next step was to create a join table that has like `stage_id`, `client_id`, `client_token` (which was generated on the Client model). I wrote a custom `generate_client_token` method, so given all of that is there any benefit to using Devise now ? My method is just a generation of the token. Nothing else like that of Devise. – marcamillion Apr 04 '11 at 03:08
  • My gut reaction is to say no, not really, but you will still need to manage saving some info in a session somewhere detailing which client is "active" (aka "logged in" :) or which stages they can access. You may be able to benefit from the one-token-per-client idea (so Devise would help there) depending on how you want the app to work. – Michelle Tilley Apr 04 '11 at 03:30
  • Once I add `:token_authenticatable` to a model, do I need to add a column to the table of that model ? – marcamillion Apr 04 '11 at 04:07
  • 1
    Yeah. See [this SO answer](http://stackoverflow.com/questions/4175988/devise-migration-on-existing-model/4249419#4249419) and [this documentation](http://rubydoc.info/github/plataformatec/devise/master/Devise/Orm/ActiveRecord). I'm not 100% sure what the "down" migration would be--I remember seeing it somewhere but I can't find it at first glance. – Michelle Tilley Apr 04 '11 at 04:15
0

Devise is doing mostly authentication. What you need an authorization plugin. Try using cancan for example (https://github.com/ryanb/cancan). That will let you grant 'roles' to your users and authorize them to do (or not do) certain actions.

There's also a Railscast available: http://railscasts.com/episodes/192-authorization-with-cancan

Zepplock
  • 28,655
  • 4
  • 35
  • 50
  • I already use decl_auth to do that. I know that Devise has token_authenticable and was told today that I could use it to do what I want, but I wasn't given any more indications. I searched the documentation for Devise but didn't see much discussion about my specific request. So figured I would ask here. This is more one off authentication - aside from things managed by decl_auth + devise for regular user authorization. – marcamillion Apr 04 '11 at 01:40