authorize state transitions

Does anybody know how to authorize state transitions? I'm using state_machine in my rails app to define the state of an Article (published or unpublished). I'm also using declarative_authorization to determine the authorizations a user has. But how do I authorize a state transistion (determine if the user has the right to publish the Article)?

Kind regards,

H.J. Blok

If you are using state_machine, this kind of thing is pretty straightforward. What you want to do is define a before_transition rule that calls a method in your model (I recommend a private method, for this, with a name ending in ?). Have that method return true when you want to allow the transition, or false when you don't. State_machine will handle the rest and set an error message on your model object.

You can also set your own errors, in the method that the before_transition calls, when you are going to return false.

-Brian

Brian, thanks for your answer. It works.

I don't know why it didn't work the first time I was trying to authorize the state transition. Maybe I've overlooked something.

Thanks,

HJ

Brian Hughes wrote:

Hey,

First of all - @Brian - I apologise for double sending this to you.. since can only reply to author, now Cc-ing the group email as well..

Ok, question as follows: I'm using Restful_Authentication plugin (generated authenticated user sessions with --include-activation and --aasm) and the Declarative_Authorization plugin..

I'm quite a beginner, so my question might be very basic.. wanted to know if there's a way to authorize AASM's trasitions? To begin with, how should I handle authorization for the state transitions (or aasm_event s) of AasmRoles of User (:active, :passive, :pending, :suspended, :unsuspended, :deleted)? and where should this be done exactly?

Thank you :slight_smile:

tino.

Unfortunately, as you can tell from my original message, I'm a state_machine user, not an aasm user. Nor have I ever used Restful_Authentication in my of my Rails apps. So, I'm not sure I can be of any help with your problem. While aasm and state_machine both allow you to add finite state machine functionality to a Ruby class, they do so in fairly different ways. What I know about state_machine doesn't transfer over to aasm...

-Brian

Thank you Brian..

I understand :slight_smile: Will keep trying or try other alternatives as well.. Still hoping to get some more suggestions here..

tino.

I can share my solution, maybe you can find the corresponding methods for AASM...

For example when you have an Article, you define a before_transition within the state definition. The before_transition uses the method is_authorized_for? to determine if the user is authorized for the transition.

class Article < ActiveRecord::Base   state_machine :initial => :unpublished do     before_transition all => all do |article, transition|       article.is_authorized_for?(transition)     end     event :publish do       transition :unpublished => :published     end     event :unpublish do       transition :published => :unpublished     end     state :unpublished     state :published   end

  ...

  # Method to check if user is authorized to do state transition   def is_authorized_for?(transition)     permitted_to?(transition.event.to_sym)   end end

In your authorization_rules.rb you will have something like this:

authorization do   role :admin do     has_permission_on [:articles], :to => [:publish, :unpublish]   end end

When a authenticated user tries to alter the state of an unpublished Article, the is_authorized_for? will only return true if the user has the :admin role.

Hope this helps...

TINODEV wrote:

Hey,

First of all - @Brian - I apologise for double sending this to you.. since can only reply to author, now Cc-ing the group email as well..

Ok, question as follows: I'm using Restful_Authentication plugin (generated authenticated user sessions with --include-activation and --aasm) and the Declarative_Authorization plugin..

A little off topic, but...get rid of restful_authentication as soon as possible! It fills your User model with unmaintainable generated code, and should never ever be used now that better alternatives exist. I use Authlogic; others seem to like Devise.

Best,

Ok..

@ Marnen - At the time when looking through Authentication Plugins didn't get the impression most developers rather use different plugins (other thena Restful_Auth) nowadays.. on the other hand - I didn't quite ask and tried to figure it all by myself while feeling a "newbie" (till two days ago I think) so I think now is a good time to ask and receive answers..

HJ - Thanks you! though currently using aasm, your description of how to use state_machine plugin was very helpful to my basic understanding..

Now following also Marnen's remark (thanks again Marnen), I'm wondering.. should I replace the plugins I'm using? Restful_Authentication and AASM included?

Can you guys recommend me of plugins you find better and better-how? (no offense to other plugins of course)? also, are they Rails 3 compatible (though currentl using InstantRails with Rails 2.3.5, but considering to move to Rails 3 when it's s table version..)

Thanks again :slight_smile:

Best,

tino.

I can share my solution, maybe you can find the corresponding methods for AASM...

For example when you have an Article, you define a before_transition within the state definition. The before_transition uses the method is_authorized_for? to determine if the user is authorized for the transition.

class Article < ActiveRecord::Base   state_machine :initial => :unpublished do     before_transition all => all do |article, transition|       article.is_authorized_for?(transition)     end     event :publish do       transition :unpublished => :published     end     event :unpublish do       transition :published => :unpublished     end     state :unpublished     state :published   end

  ...

  # Method to check if user is authorized to do state transition   def is_authorized_for?(transition)     permitted_to?(transition.event.to_sym)   end end

In your authorization_rules.rb you will have something like this:

authorization do   role :admin do     has_permission_on [:articles], :to => [:publish, :unpublish]   end end

When a authenticated user tries to alter the state of an unpublished Article, the is_authorized_for? will only return true if the user has the :admin role.

Hope this helps...