Page 1 of 4

PostPosted: Thu Jan 18, 2007 10:13 am
by maddin
hello everybody

I was wondering if it was possible to grant permissions to add/delete and edit records in a table on a role basis (maybe owner?), but only for the records he/she has added. To make it even more complicated i would like to show (view) only records which were added by this user , so that every user only can see his records.

did anybody of you ever try this? could you give me a hint towards the right direction?

cheers
martin

PostPosted: Fri Jan 19, 2007 12:47 am
by shannah
Hi Martin,

Good questions. I have been doing this sort of thing pretty regularly in my dataface apps. To have an "owner" role, you would likely need to have a column in your table called "owner" or something like it to keep track of who owns which record.

Then you could do something like:

Code: Select all
function getPermissions(&$record){
    $auth =& Dataface_AuthenticationTool::getInstance();
    $user =& $auth->getLoggedInUser();
    if ( !$user ) return Dataface_PermissionsTool::NO_ACCESS();
    if ( $user->val("username") == $record->val('owner') ){
        return Dataface_PermissionsTool::ALL();
    }
}


As far as making it so that the user can only see records created by himself, the most effective way, I have found is to sort of cut off the list view from your users, and use relationships instead.

Hence your users table would have relationships defined for all of the things that your users need to see.

-Steve

PostPosted: Sat Jan 20, 2007 9:01 am
by maddin
>hi steve and thanks for your fast reply..


I tried your code snippet but unfortunately it produces a fatal error after login

>


Fatal error: Call to a member function on a non-object in /data/mad/haschisch-online.de/www/html/df69/cdb/conf/ApplicationDelegate.php on line 32


>


>

I tried this on a windows machine and as well on a linux machine ...the result was the same

ApplicationDelegate.php line 32 is this line:
Code: Select all
if ( $user->val("username") == $record->val('owner') ){


>do you have any ideas?



cheers martin

PostPosted: Sat Jan 20, 2007 12:52 pm
by shannah
Looks like you have to to a check to make sure that $record is not null (if there are no records found then it will be null).

Something like
if ( !isset($record) ) return Dataface_PermissionsTool::ALL();

PostPosted: Mon Jan 22, 2007 5:21 pm
by maddin
hi steve
here is what i tried in my ApplicationDelegate.php:
Code: Select all
function getPermissions(&$record){
    $auth =& Dataface_AuthenticationTool::getInstance();
    $user =& $auth->getLoggedInUser();
   
   if ( !$user ) return Dataface_PermissionsTool::NO_ACCESS();
//////////////////////////////////////////////
// this works of course
// $owner = "dave";
// if ( $user->val('UserName') == $owner ){
//////////////////////////////////////////////
if ( !isset($record) ) {
    if ( $user->val('UserName') == $record->val('owner') ){
       return Dataface_PermissionsTool::ALL();
       }
   return Dataface_PermissionsTool::ALL();
   }
  }


at least I now get a nicely formattet Error message eg:
Errors
* Permission to perform action 'list' denied.
Requires permission 'view' but only granted ''


;)
and on top of the site I find these lines:

-------------error msg.-------------------------------
On line 324 of file E:\schlumpp\htdocs\df6.11\Dataface\PermissionsTool.php in function printStackTrace()
On line 341 of file E:\schlumpp\htdocs\df6.11\Dataface\PermissionsTool.php in function namesAsArray()
On line 790 of file E:\schlumpp\htdocs\df6.11\Dataface\Application.php in function namesAsString()
On line 1152 of file E:\schlumpp\htdocs\df6.11\Dataface\Application.php in function handleRequest()
On line 19 of file E:\schlumpp\htdocs\df6.11\cdb\index.php in function display()

Warning: Invalid argument supplied for foreach() in E:\schlumpp\htdocs\df6.11\Dataface\PermissionsTool.php on line 326

Warning: implode() [function.implode]: Bad arguments. in E:\schlumpp\htdocs\df6.11\Dataface\Application.php on line 792
--------------end error msg.----------------------------

i only have 2 tables : 1. questions and 2. users
the users table is simply the users table from your FacultyOfWidgetry example
and the questions table has a field named "owner" .
the table questions only contains two records and the field "owner", in both cases is not empty.

thx in advance
martin

PostPosted: Mon Jan 22, 2007 6:18 pm
by shannah
it looks like you want to have
if ( isset($record) )
rather than
if ( !isset($record) )

PostPosted: Mon Jan 22, 2007 6:42 pm
by maddin
If (isset($record)) is leading to: Fatal error: Call to a member function val() on a non-object in E:\schlumpp\htdocs\df6.11\cdb\conf\ApplicationDelegate.php on line 39

:(

PostPosted: Tue Jan 23, 2007 12:33 pm
by shannah
What is on line 39?

isset($record) will not result in that error. That error results when you do something like:
$obj->func();
but $obj is actually null or not an object.

-Steve

PostPosted: Tue Jan 23, 2007 3:23 pm
by maddin
line 39 says:
if ( $user->val('UserName') == $record->val('owner')){

the whole function looks like this:
[code]
class conf_ApplicationDelegate {
function getPermissions(&$record){
$auth =& Dataface_AuthenticationTool::getInstance();
$user =& $auth->getLoggedInUser();
if ( !$user ) return Dataface_PermissionsTool::NO_ACCESS();
if ( !isset($record) ) {
if ( $user->val('UserName') == $record->val('owner')){
return Dataface_PermissionsTool::ALL();
}
return Dataface_PermissionsTool::ALL();
}
}
}

PostPosted: Tue Jan 23, 2007 4:51 pm
by shannah
Change it to:
class conf_ApplicationDelegate {

function getPermissions(&$record){

$auth =& Dataface_AuthenticationTool::getInstance();

$user =& $auth->getLoggedInUser();

if ( !$user ) return Dataface_PermissionsTool::NO_ACCESS();

if ( isset($record) ) {

if ( $user->val('UserName') == $record->val('owner')){

return Dataface_PermissionsTool::ALL();

}

return Dataface_PermissionsTool::ALL();

}

}

}

(Note that I removed the '!' from in front of isset($record))

PostPosted: Tue Jan 23, 2007 4:53 pm
by shannah
Also, at the end, have it return no access, so that something is always returned, regardless of whether $record is set or not.

PostPosted: Wed Jan 24, 2007 9:59 am
by maddin
hi steve
thanxx for your endurance in helping me with this problem..

this morning I tried to reproduce this error on a blank install of dataface 6.11
here is what I did:
I downloaded the example file of FacultyOf Widgetry-12 (permissions),
executed the sql from that example,
added a owner field to the course table
filled the owner field with adminUser
replaced the old function with the new one from your last post
logged in as adminUser... guess what happened..

Fatal error: Call to a member function val() on a non-object in E:\schlumpp\htdocs\df6.11\FacultyOfWidgetry-12\conf\ApplicationDelegate.php on line 38

my problem is that i have no idea how to debug this..
line 38 is the good old: if ( $user->val('UserName') == $record->val('owner')){

can i echo the values of that array ($record->val('owner')) somehow for debugging?
cheers
martin

PostPosted: Wed Jan 24, 2007 3:04 pm
by shannah
Hi Martin,

Trying to output the values of $record->val('owner') will do you no good because $record is null.
That is what is causing this error.

The solution to this problem is clear. You must make sure that you don't call any methods on objects that are null (or aren't objects). Therefore, you must catch it before it executes line 39 to make sure that $record is not null. There are many ways to do this. One of the ways is described above in a previous post.

Another way would be to just check first thing:
Code: Select all
if ( !isset($record) ) {
   // we know here that there is no record.. that means that there are no
   // records in the current found set.
   // we still want our admins to be able to create new records in this
   // case so let's give permissions based on this.
   if ( $user and $user->val('role') == 'admin'){
       return Dataface_PermissionsTool::ALL();
   } else {
       return Dataface_PermissionsTool::NO_ACCESS();
   }

}

PostPosted: Mon Jan 29, 2007 5:05 pm
by maddin
hi steve
does this make sense to you?
Code: Select all
class conf_ApplicationDelegate {
function getPermissions(&$record){
$auth =& Dataface_AuthenticationTool::getInstance();
$user =& $auth->getLoggedInUser();
if ( !$user ) return Dataface_PermissionsTool::NO_ACCESS();

if ( !isset($record) ) {
   // we know here that there is no record.. that means that there are no
   // records in the current found set.
   // we still want our admins to be able to create new records in this
   // case so let's give permissions based on this.
   if ( $user and $user->val('role') == 'ADMIN'){
       return Dataface_PermissionsTool::ALL();
   } else {
       return Dataface_PermissionsTool::NO_ACCESS();
   }
// case 2:UserName matches username in owner field in questions  table
if ( isset($record) ) {
if ( $user->val('UserName') == $record->val('owner')){
return Dataface_PermissionsTool::ALL();
}else {
       return Dataface_PermissionsTool::NO_ACCESS();
   }
}
}
}
}

it gives me a "permission denied" Error
Code: Select all


    * Permission to perform action 'list' denied.
      Requires permission 'view' but only granted ''.

1.why does it say "but only granted '' " when I try to log in as admin?
as far as I understand this function,this should happen:
if ( $user and $user->val('role') == 'ADMIN'){
return Dataface_PermissionsTool::ALL();
2.why are there no records in the currend found set? I definitly know that there are some records with "admin" in the owner field.



I know I am a blockhead at this point , but I tried shifting code in this delegate class (in almost every combination possible) without success. I ended up guessing and trying more or less confused.
Maybe you have answered my questions already, but it's like to not see the wood for the trees.
So... before I give it up here is my last call for help
cheers
martin

PostPosted: Tue Jan 30, 2007 2:46 am
by shannah
What you may want to try here is putting some output in certain places of your function so that you can see which logic path is being followed. (e.g. echo "here now")

As far as your permission denied error, I suspect that it is not even reaching the if ( $user and $user->val('role') == 'ADMIN'){
code. Likely isset($record) is true, so your if (!isset($record) ) gets stepped over.

In fact, unless there is a typo in the code you just pasted, it looks like you're missing a closing brace before if ( isset($record) ) because that if statement falls inside the previous if (!isset($record)) statement - which doesn't make a lot of sense.

Code: Select all
class conf_ApplicationDelegate {

    function getPermissions(&$record){
        $app =& Dataface_Application::getInstance();
        $query =& $app->getQuery();
        $auth =& Dataface_AuthenticationTool::getInstance();
        $user =& $app->getLoggedInUser();
       
        // IF user is not logged in, he gets no access
        if (!$user ) return Dataface_PermissionsTool::NO_ACCESS();
       
        // Admins get full access
        if ( $user->val('role') == 'ADMIN' ) return Dataface_PermissionsTool::ALL();

        // Users can edit their own records
        if ( $record and $record->val('owner') == $user->val('UserName') )
            return Dataface_PermissionsTool::ALL();

        // In all other cases, there is NO ACCESS
        return Dataface_PermissionsTool::NO_ACCESS();
       
    }


The above function does what you indended and it avoids problems with null $records and null $users.