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 H. wrote:

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

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.

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.

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,

Marnen Laibow-Koser
http://www.marnen.org
[email protected]

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.

From: H.J. Blok
Date: Wed, 2 Jun 2010 04:46:31 -0700 (PDT)

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…

Posted via http://www.ruby-forum.com/.