Re: Best way to accomplish acl for database records owned by a user

2009-09-25 Thread rOger

Thanks for your answers!!

@brian: It looks rather complex to accomplish such a easy task so I
think there must be an easier way to get the same result...

@Rick: Your solution is the one I used before but I thought that there
must be a solution that is integrated into the ACO/ACL concept...

It's always the same problem with every framework; simple tasks are
easy; real world scenarios are big challenges. It would be interesting
to know how the developers of cakePHP/ACL-system would accomplish this
task...

regards,
rOger


On 24 Sep., 16:09, Rick will...@gmail.com wrote:
 I know that globals are bad but...

 I just set a global $gblCurrentUser when the user logs in.  Then
 accessing that in models, I can add a select condition for that user
 in the beforeFind etc..

 You get the idea?

 Rick

 On Sep 24, 12:20 am, brian bally.z...@gmail.com wrote:

  I did something similar to this. However, I was so overwhelmed by the
  contradictory and/or incomplete information I found about Cake's ACL
  (mostly because it was quite dated) that I really don't know for sure
  that I did it the best way.

  My app is an extranet that has several different Groups. The
  navigation consists of many Sections that are stored as a tree (MPTT).
  Some Sections may not be seen by certain Groups. So, to display this
  navigation tree, I called this method in my SectionsController:

  public function nav($group_id = null)
  {
          if (is_null($group_id))
          {
                  if (!$this-params['admin'])
                  {
                          $group_id = $this-Auth-user('group_id');
                  }
          }
          $this-Session-write('group_id_for_nav', $group_id);

          /* try getting the nodes from the cache
           */
          $sections = Cache::read(group_sections_${group_id}, 'default');

          if (!$sections)
          {
                  /* fetch the permissions for this group
                   */
                  $perms = $this-Acl-Aco-find(
                          'all',
                          array(
                                  'fields' = array('Aco.foreign_key'),
                                  'conditions' = array(
                                          'Aco.model' = 'Section',
                                          'Aco.id = Permission.aco_id'
                                  ),
                                  'recursive' = -1,
                                  'joins' = array(
                                          array(
                                                  'table' = 'aros',
                                                  'alias' = 'Aro',
                                                  'type' = 'INNER',
                                                  'conditions'= array(
                                                          'Aro.model' = 
  'Group',
                                                          Aro.foreign_key = 
  ${group_id}
                                                  )
                                          ),
                                          array(
                                                  'table' = 'aros_acos',
                                                  'alias' = 'Permission',
                                                  'type' = 'INNER',
                                                  'conditions'= array(
                                                          'Permission.aro_id 
  = Aro.id',
                                                          'Permission._read 
  = 0'
                                                  )
                                          )
                                  )                                      
                          )
                  );

                  $section_ids = Set::extract($perms, '{n}.Aco.foreign_key');

                  /* we don't want to see the root node
                   */
                  unset($section_ids[0]);

                  /* now grab the sections these permissions allow
                   */
                  $sections = $this-Section-threaded($section_ids);

                  /* save this group's allowed sections
                   */
                  Cache::write(group_sections_${group_id}, $sections, 
  'default');
          }
          return $sections;

  }

  So, the Aco.foreign_key fields I'm after correspond to Section.ids.
  Once i have those, I fetch the relevant Sections as a threaded list.
  Obviously, you'd just be interested in the record IDs.

  What I'm storing in the cache is the Sections themselves. For your
  case, you'd likely want to save the record IDs in the session instead
  of caching them.

  Anyway, the important thing is the joins used to get at the model IDs
  for your record-level ACL through the ACO.foreign_key.

  Let me know if you want more info.

  On Wed, Sep 23, 2009 at 5:19 PM, rOger roger.eisenec...@icer.ch wrote:

   Hi @all,

   I'm really 

Re: Best way to accomplish acl for database records owned by a user

2009-09-25 Thread FrederickD

I came across this same issue. You can call it row level access. An
article that pointed me in the right direction was this one:
http://teknoid.wordpress.com/2009/04/22/simplistic-example-of-row-level-access-control-with-auth-security-and-app-model-in-cakephp/.

I took that article and expanded on it. The key for my application was
the design of the database. My application has distributors that own
dealers that then have service advisers. A distributor should be able
to access only his distributor record and the associated dealers and
the associated service advisers. A dealer can access only his dealer
record and his service advisers. Etc., etc.

Distributors and dealers and service advisers are individual group
records. There are users belonging to those groups. Currently I don't
allow a user to be in multiple groups, but I could.

So using the article above I was able to build in internal security
using the group_id as a first cut for access to the record being
requested, and then the user_id as well to make sure it was their
record. For the security on associated records this is where having
the 'belongsTo' and 'hasMany' relationships really helped. But the
real key discovery for me was in my dealers_controller.php. I needed
to reach back and get the associated distributor for the dealer record
being requested to compare if it was the same distributor. If not, no
access. I found I could use var $uses = array('Dealers'
'Distributors') to allow me to bring in the distributor (only one
field actually, the 'id') to my security check.

It is some code. I'm sure it could be cleaned up a bit and maybe put
more into the model to have a skinnier controller, but it is working
well and seems to be a flexible approach that does not involve the
complexities of ACL.

Maybe some of this helps.


On Sep 25, 1:25 am, rOger roger.eisenec...@icer.ch wrote:
 Thanks for your answers!!

 @brian: It looks rather complex to accomplish such a easy task so I
 think there must be an easier way to get the same result...

 @Rick: Your solution is the one I used before but I thought that there
 must be a solution that is integrated into the ACO/ACL concept...

 It's always the same problem with every framework; simple tasks are
 easy; real world scenarios are big challenges. It would be interesting
 to know how the developers of cakePHP/ACL-system would accomplish this
 task...

 regards,
 rOger

 On 24 Sep., 16:09, Rick will...@gmail.com wrote:

  I know that globals are bad but...

  I just set a global $gblCurrentUser when the user logs in.  Then
  accessing that in models, I can add a select condition for that user
  in the beforeFind etc..

  You get the idea?

  Rick

  On Sep 24, 12:20 am, brian bally.z...@gmail.com wrote:

   I did something similar to this. However, I was so overwhelmed by the
   contradictory and/or incomplete information I found about Cake's ACL
   (mostly because it was quite dated) that I really don't know for sure
   that I did it the best way.

   My app is an extranet that has several different Groups. The
   navigation consists of many Sections that are stored as a tree (MPTT).
   Some Sections may not be seen by certain Groups. So, to display this
   navigation tree, I called this method in my SectionsController:

   public function nav($group_id = null)
   {
           if (is_null($group_id))
           {
                   if (!$this-params['admin'])
                   {
                           $group_id = $this-Auth-user('group_id');
                   }
           }
           $this-Session-write('group_id_for_nav', $group_id);

           /* try getting the nodes from the cache
            */
           $sections = Cache::read(group_sections_${group_id}, 'default');

           if (!$sections)
           {
                   /* fetch the permissions for this group
                    */
                   $perms = $this-Acl-Aco-find(
                           'all',
                           array(
                                   'fields' = array('Aco.foreign_key'),
                                   'conditions' = array(
                                           'Aco.model' = 'Section',
                                           'Aco.id = Permission.aco_id'
                                   ),
                                   'recursive' = -1,
                                   'joins' = array(
                                           array(
                                                   'table' = 'aros',
                                                   'alias' = 'Aro',
                                                   'type' = 'INNER',
                                                   'conditions'= array(
                                                           'Aro.model' = 
   'Group',
                                                           Aro.foreign_key 
   = ${group_id}
                                                   )
                                   

Re: Best way to accomplish acl for database records owned by a user

2009-09-25 Thread brian

On Fri, Sep 25, 2009 at 2:25 AM, rOger roger.eisenec...@icer.ch wrote:

 Thanks for your answers!!

 @brian: It looks rather complex to accomplish such a easy task so I
 think there must be an easier way to get the same result...

Yeah, sure it's complex. As I pointed out, though, the example I
posted goes a little further than what you're looking for. But I
wanted to post it in full so you'd see the context. The nutshell
version is to query the ACO table using inner joins on both aros 
aros_acos. The record ID you're checking access to corresponds to
Aro.foreign_key.

I have no idea if this is THE way to do it, as I couldn't find
anything much about record-level ACL and Cake. This is what I figured
out on my own and it seems to work great (at least, for my app).

--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
CakePHP group.
To post to this group, send email to cake-php@googlegroups.com
To unsubscribe from this group, send email to 
cake-php+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/cake-php?hl=en
-~--~~~~--~~--~--~---



Re: Best way to accomplish acl for database records owned by a user

2009-09-25 Thread rOger

Thanks again for additional pointers.

I got many interesting information how to create a row level based
access. We are going to make some tests to see which is the best
solution in our case.

rOger


On Sep 25, 10:23 pm, brian bally.z...@gmail.com wrote:
 On Fri, Sep 25, 2009 at 2:25 AM, rOger roger.eisenec...@icer.ch wrote:

  Thanks for your answers!!

  @brian: It looks rather complex to accomplish such a easy task so I
  think there must be an easier way to get the same result...

 Yeah, sure it's complex. As I pointed out, though, the example I
 posted goes a little further than what you're looking for. But I
 wanted to post it in full so you'd see the context. The nutshell
 version is to query the ACO table using inner joins on both aros 
 aros_acos. The record ID you're checking access to corresponds to
 Aro.foreign_key.

 I have no idea if this is THE way to do it, as I couldn't find
 anything much about record-level ACL and Cake. This is what I figured
 out on my own and it seems to work great (at least, for my app).
--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
CakePHP group.
To post to this group, send email to cake-php@googlegroups.com
To unsubscribe from this group, send email to 
cake-php+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/cake-php?hl=en
-~--~~~~--~~--~--~---



Re: Best way to accomplish acl for database records owned by a user

2009-09-24 Thread Rick

I know that globals are bad but...

I just set a global $gblCurrentUser when the user logs in.  Then
accessing that in models, I can add a select condition for that user
in the beforeFind etc..

You get the idea?

Rick




On Sep 24, 12:20 am, brian bally.z...@gmail.com wrote:
 I did something similar to this. However, I was so overwhelmed by the
 contradictory and/or incomplete information I found about Cake's ACL
 (mostly because it was quite dated) that I really don't know for sure
 that I did it the best way.

 My app is an extranet that has several different Groups. The
 navigation consists of many Sections that are stored as a tree (MPTT).
 Some Sections may not be seen by certain Groups. So, to display this
 navigation tree, I called this method in my SectionsController:

 public function nav($group_id = null)
 {
         if (is_null($group_id))
         {
                 if (!$this-params['admin'])
                 {
                         $group_id = $this-Auth-user('group_id');
                 }
         }
         $this-Session-write('group_id_for_nav', $group_id);

         /* try getting the nodes from the cache
          */
         $sections = Cache::read(group_sections_${group_id}, 'default');

         if (!$sections)
         {
                 /* fetch the permissions for this group
                  */
                 $perms = $this-Acl-Aco-find(
                         'all',
                         array(
                                 'fields' = array('Aco.foreign_key'),
                                 'conditions' = array(
                                         'Aco.model' = 'Section',
                                         'Aco.id = Permission.aco_id'
                                 ),
                                 'recursive' = -1,
                                 'joins' = array(
                                         array(
                                                 'table' = 'aros',
                                                 'alias' = 'Aro',
                                                 'type' = 'INNER',
                                                 'conditions'= array(
                                                         'Aro.model' = 
 'Group',
                                                         Aro.foreign_key = 
 ${group_id}
                                                 )
                                         ),
                                         array(
                                                 'table' = 'aros_acos',
                                                 'alias' = 'Permission',
                                                 'type' = 'INNER',
                                                 'conditions'= array(
                                                         'Permission.aro_id = 
 Aro.id',
                                                         'Permission._read = 
 0'
                                                 )
                                         )
                                 )                                      
                         )
                 );

                 $section_ids = Set::extract($perms, '{n}.Aco.foreign_key');

                 /* we don't want to see the root node
                  */
                 unset($section_ids[0]);

                 /* now grab the sections these permissions allow
                  */
                 $sections = $this-Section-threaded($section_ids);

                 /* save this group's allowed sections
                  */
                 Cache::write(group_sections_${group_id}, $sections, 
 'default');
         }
         return $sections;

 }

 So, the Aco.foreign_key fields I'm after correspond to Section.ids.
 Once i have those, I fetch the relevant Sections as a threaded list.
 Obviously, you'd just be interested in the record IDs.

 What I'm storing in the cache is the Sections themselves. For your
 case, you'd likely want to save the record IDs in the session instead
 of caching them.

 Anyway, the important thing is the joins used to get at the model IDs
 for your record-level ACL through the ACO.foreign_key.

 Let me know if you want more info.

 On Wed, Sep 23, 2009 at 5:19 PM, rOger roger.eisenec...@icer.ch wrote:

  Hi @all,

  I'm really new to CakePHP and I read about the ACL modell of CakePHP.
  As usual also the examples seems to be simple so it is easy to
  understand the system. I'm evaluating cakePHP for a new project where
  I have records which belongs to a given user = that is the owner of
  the record. Now I want to have a ACL system which enables some groups
  (like Administrators) full access to these records. That is the easy
  part and is well documented. The second part is a little bit more
  tricky (in my opinion): The owner should also have full access to his
  record details (means should be editable) but other users should have
  no access. That means that the ACL system has to 

Re: Best way to accomplish acl for database records owned by a user

2009-09-24 Thread brian
You could also just use $this-Auth-user('id') which gets the info
from the session.

On Thu, Sep 24, 2009 at 10:09 AM, Rick will...@gmail.com wrote:

 I know that globals are bad but...

 I just set a global $gblCurrentUser when the user logs in.  Then
 accessing that in models, I can add a select condition for that user
 in the beforeFind etc..

 You get the idea?

 Rick




 On Sep 24, 12:20 am, brian bally.z...@gmail.com wrote:
 I did something similar to this. However, I was so overwhelmed by the
 contradictory and/or incomplete information I found about Cake's ACL
 (mostly because it was quite dated) that I really don't know for sure
 that I did it the best way.

 My app is an extranet that has several different Groups. The
 navigation consists of many Sections that are stored as a tree (MPTT).
 Some Sections may not be seen by certain Groups. So, to display this
 navigation tree, I called this method in my SectionsController:

 public function nav($group_id = null)
 {
         if (is_null($group_id))
         {
                 if (!$this-params['admin'])
                 {
                         $group_id = $this-Auth-user('group_id');
                 }
         }
         $this-Session-write('group_id_for_nav', $group_id);

         /* try getting the nodes from the cache
          */
         $sections = Cache::read(group_sections_${group_id}, 'default');

         if (!$sections)
         {
                 /* fetch the permissions for this group
                  */
                 $perms = $this-Acl-Aco-find(
                         'all',
                         array(
                                 'fields' = array('Aco.foreign_key'),
                                 'conditions' = array(
                                         'Aco.model' = 'Section',
                                         'Aco.id = Permission.aco_id'
                                 ),
                                 'recursive' = -1,
                                 'joins' = array(
                                         array(
                                                 'table' = 'aros',
                                                 'alias' = 'Aro',
                                                 'type' = 'INNER',
                                                 'conditions'= array(
                                                         'Aro.model' = 
 'Group',
                                                         Aro.foreign_key = 
 ${group_id}
                                                 )
                                         ),
                                         array(
                                                 'table' = 'aros_acos',
                                                 'alias' = 'Permission',
                                                 'type' = 'INNER',
                                                 'conditions'= array(
                                                         'Permission.aro_id = 
 Aro.id',
                                                         'Permission._read = 
 0'
                                                 )
                                         )
                                 )
                         )
                 );

                 $section_ids = Set::extract($perms, '{n}.Aco.foreign_key');

                 /* we don't want to see the root node
                  */
                 unset($section_ids[0]);

                 /* now grab the sections these permissions allow
                  */
                 $sections = $this-Section-threaded($section_ids);

                 /* save this group's allowed sections
                  */
                 Cache::write(group_sections_${group_id}, $sections, 
 'default');
         }
         return $sections;

 }

 So, the Aco.foreign_key fields I'm after correspond to Section.ids.
 Once i have those, I fetch the relevant Sections as a threaded list.
 Obviously, you'd just be interested in the record IDs.

 What I'm storing in the cache is the Sections themselves. For your
 case, you'd likely want to save the record IDs in the session instead
 of caching them.

 Anyway, the important thing is the joins used to get at the model IDs
 for your record-level ACL through the ACO.foreign_key.

 Let me know if you want more info.

 On Wed, Sep 23, 2009 at 5:19 PM, rOger roger.eisenec...@icer.ch wrote:

  Hi @all,

  I'm really new to CakePHP and I read about the ACL modell of CakePHP.
  As usual also the examples seems to be simple so it is easy to
  understand the system. I'm evaluating cakePHP for a new project where
  I have records which belongs to a given user = that is the owner of
  the record. Now I want to have a ACL system which enables some groups
  (like Administrators) full access to these records. That is the easy
  part and is well documented. The second part is a little bit more
  tricky (in my opinion): The owner should also have full access to his
  

Re: Best way to accomplish acl for database records owned by a user

2009-09-23 Thread brian

I did something similar to this. However, I was so overwhelmed by the
contradictory and/or incomplete information I found about Cake's ACL
(mostly because it was quite dated) that I really don't know for sure
that I did it the best way.

My app is an extranet that has several different Groups. The
navigation consists of many Sections that are stored as a tree (MPTT).
Some Sections may not be seen by certain Groups. So, to display this
navigation tree, I called this method in my SectionsController:

public function nav($group_id = null)
{
if (is_null($group_id))
{
if (!$this-params['admin'])
{
$group_id = $this-Auth-user('group_id');
}
}
$this-Session-write('group_id_for_nav', $group_id);

/* try getting the nodes from the cache
 */
$sections = Cache::read(group_sections_${group_id}, 'default');

if (!$sections)
{
/* fetch the permissions for this group
 */
$perms = $this-Acl-Aco-find(
'all',
array(
'fields' = array('Aco.foreign_key'),
'conditions' = array(
'Aco.model' = 'Section',
'Aco.id = Permission.aco_id'
),
'recursive' = -1,
'joins' = array(
array(
'table' = 'aros',
'alias' = 'Aro',
'type' = 'INNER',
'conditions'= array(
'Aro.model' = 'Group',
Aro.foreign_key = 
${group_id}
)
),
array(
'table' = 'aros_acos',
'alias' = 'Permission',
'type' = 'INNER',
'conditions'= array(
'Permission.aro_id = 
Aro.id',
'Permission._read = 0'
)
)
)   
)
);

$section_ids = Set::extract($perms, '{n}.Aco.foreign_key');

/* we don't want to see the root node
 */
unset($section_ids[0]);

/* now grab the sections these permissions allow
 */
$sections = $this-Section-threaded($section_ids);

/* save this group's allowed sections
 */
Cache::write(group_sections_${group_id}, $sections, 
'default');
}
return $sections;
}

So, the Aco.foreign_key fields I'm after correspond to Section.ids.
Once i have those, I fetch the relevant Sections as a threaded list.
Obviously, you'd just be interested in the record IDs.

What I'm storing in the cache is the Sections themselves. For your
case, you'd likely want to save the record IDs in the session instead
of caching them.

Anyway, the important thing is the joins used to get at the model IDs
for your record-level ACL through the ACO.foreign_key.

Let me know if you want more info.

On Wed, Sep 23, 2009 at 5:19 PM, rOger roger.eisenec...@icer.ch wrote:

 Hi @all,

 I'm really new to CakePHP and I read about the ACL modell of CakePHP.
 As usual also the examples seems to be simple so it is easy to
 understand the system. I'm evaluating cakePHP for a new project where
 I have records which belongs to a given user = that is the owner of
 the record. Now I want to have a ACL system which enables some groups
 (like Administrators) full access to these records. That is the easy
 part and is well documented. The second part is a little bit more
 tricky (in my opinion): The owner should also have full access to his
 record details (means should be editable) but other users should have
 no access. That means that the ACL system has to decide according to a
 field value of a record if the user has access to or not.

 I hope it is clear what I need and hope that someone can spend some
 light on this issue.

 Thanks in advance,
 rOger

 


--~--~-~--~~~---~--~~
You received this message because