enjoying decl_auth but having problems with Model.with_permissions_to

42 views
Skip to first unread message

walther diechmann

unread,
Apr 10, 2010, 5:30:25 PM4/10/10
to declarative_authorization
First off - thank you for a wonderful plugin/gem, Steffen et al !

Second - my views and controllers love the decl_auth

But - (there's always a but - isn't there?) - I'm sadly having
problems with my Models using the with_permissions_to -

(and I know that the error lies with me - I'm just not thatfluent ruby/
rails wise that I'm able to decipher/correct my mistakes <:(

I pray that one of you guys will be able to cut through all the
wrongdoings on my part and point me to the correct way of setting up
roles on models.

cheers,
Walther


ps. perhaps I should explain that I'm trying to say this: I will allow
users to manage organisations, that they themselves are being editors
of (ie. the editors field (which is a text field) will hold their id
or serialized object as it is)

- and I honestly do not know why the editors field has to be a
serialized field! That part did come straight out of one of the
examples...

- and finally: there will most certainly always be several editors to
an organisation (sometimes even quite a few)

part of my authorization_rules.rb is:

role :user do
includes :guest
has_permission_on :organisations, :to => :create
has_permission_on :organisations, :to => :manage do
if_attribute :editors => contains {user}
end
end

my Organisation model looks like:

class Organisation < Oxobject

using_access_control

end

My Oxobject model looks like this:

class Oxobject < ActiveRecord::Base

#
# declarative_authorization
using_access_control

#
# the access to each oxobject (and it's _field entity) is guarded
by
serialize :editors, Array

#
# filters
before_create :add_current_user_as_editor

protected
def add_current_user_as_editor
self.editors ||= []
self.editors << Authorization.current_user unless
(self.editors.size>0 && self.editors.include?
(Authorization.current_user))
end
end


and when I try a with_permissions_to in the console like this:

>> reload!
Reloading...
=> true
>> Authorization.current_user = User.find(6)
=> #<User id: 6, email: "wa...@alco.dk", encrypted_password:
"130786b5026a04fa574ec3cba807b874959cf857", salt:
"13c454186b76cb4718299daab0dfe29834e6b4c3", confirmation_token: nil,
remember_token: "5284523b7ccd778c236aeaba177cd6f9ecdf1523",
email_confirmed: true, created_at: "2010-04-05 09:31:16", updated_at:
"2010-04-09 08:55:49">
>> Organisation.with_permissions_to.all
=> []

it throws this SQL at my MySQL server:

SELECT `oxobjects`.* FROM `oxobjects` WHERE (((`oxobjects`.`editors` =
6)) AND (oxobjects.deleted_at IS NULL OR oxobjects.deleted_at >
'2010-04-10 20:49:05')) AND ( (`oxobjects`.`type` = 'Organisation' ) )

which obviously is not what I'd like it to!

Just to prove that my rules work and throws quite a bit of love my
way, I've attached a call to the MySQL for editing one of the
organisations by user 6 (one of the organisations that the user surely
is allowed to edit) - and after wards, one which he clearly is not
allowed to edit:

Processing OrganisationsController#edit (for 127.0.0.1 at 2010-04-10
23:25:46) [GET]
Parameters: {"id"=>"3"}
User Columns (1.4ms) SHOW FIELDS FROM `users`
User Load (0.3ms) SELECT * FROM `users` WHERE
(`users`.`remember_token` =
'a684f881a116dc797a001fa1a3729e8b5a0a0477') LIMIT 1
Organisation Load (0.2ms) SELECT * FROM `oxobjects` WHERE
(`oxobjects`.`id` = 3) AND (oxobjects.deleted_at IS NULL OR
oxobjects.deleted_at > '2010-04-10 21:25:46') AND
( (`oxobjects`.`type` = 'Organisation' ) )
Role Load (0.3ms) SELECT `roles`.* FROM `roles` INNER JOIN
`permissions` ON `roles`.id = `permissions`.role_id WHERE
((`permissions`.user_id = 6) AND ((domain='User')))
Role Columns (1.2ms) SHOW FIELDS FROM `roles`
CACHE (0.0ms) SELECT * FROM `oxobjects` WHERE (`oxobjects`.`id` =
3) AND (oxobjects.deleted_at IS NULL OR oxobjects.deleted_at >
'2010-04-10 21:25:46') AND ( (`oxobjects`.`type` = 'Organisation' ) )
Rendering template within layouts/organisations
Rendering organisations/edit
Completed in 124ms (View: 39, DB: 8) | 200 OK [http://localhost/
organisations/3/edit]
** has_many_polymorphs: autoload hook invoked
** has_many_polymorphs: preloading parent model Oxobjectable
SQL (0.1ms) SET NAMES 'utf8'
SQL (0.1ms) SET SQL_AUTO_IS_NULL=0
** has_many_polymorphs: associating Organisation.oxobjectables
Home Columns (1.7ms) SHOW FIELDS FROM `oxobjects`
Oxobjectable Columns (1.7ms) SHOW FIELDS FROM `oxobjectables`
** has_many_polymorphs: associating Home.oxobjectables
** has_many_polymorphs: associating Home.oxobjects
Organisation Columns (1.7ms) SHOW FIELDS FROM `oxobjects`


Processing OrganisationsController#edit (for 127.0.0.1 at 2010-04-10
23:27:15) [GET]
Parameters: {"id"=>"5"}
User Columns (1.4ms) SHOW FIELDS FROM `users`
User Load (0.3ms) SELECT * FROM `users` WHERE
(`users`.`remember_token` =
'a684f881a116dc797a001fa1a3729e8b5a0a0477') LIMIT 1
Organisation Load (0.2ms) SELECT * FROM `oxobjects` WHERE
(`oxobjects`.`id` = 5) AND (oxobjects.deleted_at IS NULL OR
oxobjects.deleted_at > '2010-04-10 21:27:15') AND
( (`oxobjects`.`type` = 'Organisation' ) )
Role Load (0.3ms) SELECT `roles`.* FROM `roles` INNER JOIN
`permissions` ON `roles`.id = `permissions`.role_id WHERE
((`permissions`.user_id = 6) AND ((domain='User')))
Role Columns (1.2ms) SHOW FIELDS FROM `roles`
Permission denied: edit not allowed for #<User id: 6, email:
"wa...@alco.dk", encrypted_password:
"130786b5026a04fa574ec3cba807b874959cf857", salt:
"13c454186b76cb4718299daab0dfe29834e6b4c3", confirmation_token: nil,
remember_token: "a684f881a116dc797a001fa1a3729e8b5a0a0477",
email_confirmed: true, created_at: "2010-04-05 09:31:16", updated_at:
"2010-04-10 21:25:26"> on #<Organisation id: 5, title: "#7 det er
mig", type: "Organisation", template: nil, fields_id: nil,
organisation_id: nil, parent_id: nil, lft: 7, rgt: 8, state: nil,
security_level: nil, created_by: nil, updated_by: nil, deleted_by:
nil, deleted_at: nil, created_at: "2010-04-07 07:17:39", updated_at:
"2010-04-07 07:17:39", readers: nil, authors: nil, moderators: nil,
editors: [#<User id: 7, email: "wal...@diechmann.net",
encrypted_password: "31a81509a69a9216c7ad6471a528b0a496d81851", salt:
"b76c911d095a364c5041e085214e03fcee05dfd5", confirmation_token: nil,
remember_token: "22006e984d69b3c4e5ba75546b9d9ee1ebe37f84",
email_confirmed: true, created_at: "2010-04-06 14:28:08", updated_at:
"2010-04-07 07:13:46">]>.
Redirected to http://localhost:3000/
Filter chain halted as [:filter_access_filter] rendered_or_redirected.
Completed in 37ms (DB: 9) | 302 Found [http://localhost/organisations/
5/edit]

Steffen Bartsch

unread,
Apr 13, 2010, 10:58:35 AM4/13/10
to declarative_...@googlegroups.com
Am Samstag, 10. April 2010 schrieb walther diechmann:
> ps. perhaps I should explain that I'm trying to say this: I will allow
> users to manage organisations, that they themselves are being editors
> of (ie. the editors field (which is a text field) will hold their id
> or serialized object as it is)
>
> - and I honestly do not know why the editors field has to be a
> serialized field! That part did come straight out of one of the
> examples...
>
> - and finally: there will most certainly always be several editors to
> an organisation (sometimes even quite a few)

with_permissions_to will not work with serialized arrays. with_permissions_to
rewrites your query to only result in those rows that the user is allowed to
access. The problem is that there is no such query for serialized arrays.

Is it possible for you to restructure your models to use a has_many :through
association instead? Then, the authorization rules should work as is.

Steffen

walther diechmann

unread,
Apr 13, 2010, 11:29:21 AM4/13/10
to declarative_authorization
>
> Is it possible for you to restructure your models to use a has_many :through
> association instead?  Then, the authorization rules should work as is.
>
> Steffen

It gets stranger by the hour <:)

I tried changing the authorization_rules.rb to say

....


has_permission_on :organisations, :to => :manage do

if_attribute :editors => is_in {user.id}
end
....

and likewise my oxobject.rb to say

....
before_create :add_current_user_as_editor

protected
def add_current_user_as_editor
e=self.editors || ""
e = e.split(",")
e << Authorization.current_user.id unless (e.include?
(Authorization.current_user.id))
self.editors= e.flatten.join(",")
end
....

- and now I get my Organisation.with_permission_to.all to do the right
thing :)

But - then my /organisations/5/edit cries out with:

Processing OrganisationsController#edit (for 127.0.0.1 at 2010-04-13
17:05:22) [GET]


Parameters: {"id"=>"5"}
User Columns (1.4ms) SHOW FIELDS FROM `users`

User Load (0.2ms) SELECT * FROM `users` WHERE


(`users`.`remember_token` =

'91f98f1c61fc8d706cb26c8a99e288cd22c6f57f') LIMIT 1


Organisation Load (0.2ms) SELECT * FROM `oxobjects` WHERE
(`oxobjects`.`id` = 5) AND (oxobjects.deleted_at IS NULL OR

oxobjects.deleted_at > '2010-04-13 15:05:22') AND


( (`oxobjects`.`type` = 'Organisation' ) )

Role Load (0.4ms) SELECT `roles`.* FROM `roles` INNER JOIN


`permissions` ON `roles`.id = `permissions`.role_id WHERE
((`permissions`.user_id = 6) AND ((domain='User')))
Role Columns (1.2ms) SHOW FIELDS FROM `roles`

Permission denied: Operator is_in requires a subclass of Enumerable as
value, got: "6" is_in 6: undefined method `include?' for 6:Fixnum


Redirected to http://localhost:3000/
Filter chain halted as [:filter_access_filter] rendered_or_redirected.

So - the way I see it - I can't both have my models and ed'it :)
(well bad joke - but I couldn't resist it - sorry) :)

I reckon I'll have to go with your suggestion <:)

Thank you very much anyways

/Walther

Reply all
Reply to author
Forward
0 new messages