1 of 2
1
Permission Check not taking ‘member_id’ into consideration
Posted: 08 June 2007 04:46 PM   [ Ignore ]
Newbie
Rank
Total Posts:  18
Joined  2007-06-08

exp:permission:check didn’t seem to be working as advertised, so I made this very simple test:

{segment_3}
{exp
:permission:check name="crsi_rim" member_id="{segment_3}"}
{if approved}approved{
/if}
{
/exp:permission:check}

When I am logged in as an administrator and I view this page, no matter what segment_3 is, it displays approved.  While logged out, I never see it.

Profile
 
 
Posted: 08 June 2007 05:05 PM   [ Ignore ]   [ # 1 ]
Newbie
Rank
Total Posts:  18
Joined  2007-06-08

*sigh*

the problem is the last two lines of the function:

$cond['approved']        = ( $query->num_rows > 0 OR $SESS->userdata['group_id'] == '1' ) ? TRUE: FALSE;
$cond['not_approved']    = ( $query->num_rows > 0 OR $SESS->userdata['group_id'] == '1' ) ? FALSE: TRUE;

this is testing whether or not the CURRENT user (ie, the one BROWSING the site) is in the administrator group, not the member in question.

Profile
 
 
Posted: 08 June 2007 05:29 PM   [ Ignore ]   [ # 2 ]
Newbie
Rank
Total Posts:  18
Joined  2007-06-08

I changed the code as follows to gain the proper functionality:

$isAdmin = ($DB->query("SELECT member_id FROM exp_members where member_id = " . ($TMPL->fetch_param('member_id') ? $TMPL->fetch_param('member_id') : $SESS->userdata['member_id']) . " AND group_id = 1;")->num_rows > 0);
$cond['approved'] = ( $query->num_rows > 0 OR $isAdmin);
$cond['not_approved'] = !($cond['approved']);

//note: $query->num_rows refers to a query found earlier in the code, not to the query in this snippet.

This is pretty frustrating to have the most fundamental features of the module not working properly, especially considering this is a commercial solution.

Profile
 
 
Posted: 11 June 2007 12:55 AM   [ Ignore ]   [ # 3 ]
Sr. Member
Avatar
RankRankRankRank
Total Posts:  336
Joined  2005-07-09

Daryl, thank you for your feedback and for filing such good bug reports (and fixes, too!). I have invited the lead programmer to comment and am currently awaiting his answer.

 Signature 

Ingmar Greil

Profile
 
 
Posted: 11 June 2007 02:20 PM   [ Ignore ]   [ # 4 ]
Administrator
Avatar
Rank
Total Posts:  17
Joined  2005-03-22

daryl, Permission is Mitchell’s project, but he is away on his honeymoon until later this month. In the meantime, I went ahead and took a look at the code for the “check” method. The reason the original code didn’t work is on line 1781. Change this:

if ( $member_id = $TMPL->fetch_param('member_id') )

to this:

$member_id = ( ! $TMPL->fetch_param('member_id')) ? '' : $TMPL->fetch_param('member_id');
if (
$member_id != '' )

And revert your fix back to:

$cond['approved']        = ( $query->num_rows > 0 OR $SESS->userdata['group_id'] == '1' ) ? TRUE : FALSE;
$cond['not_approved']    = ( $query->num_rows > 0 OR $SESS->userdata['group_id'] == '1' ) ? FALSE : TRUE;

The original line 1781 would always evaluate to false if the member_id parameter was passed, so instead of checking for a specified member, it would always check against the current user.

Let me know if this solves the problem for you.

Profile
 
 
Posted: 11 June 2007 02:28 PM   [ Ignore ]   [ # 5 ]
Newbie
Rank
Total Posts:  18
Joined  2007-06-08

I already made a similar change this morning and changed that line to:

if ( $SESS->userdata['member_id'] == 0 && !($member_id = $TMPL->fetch_param('member_id')))

However, the problem still lies at the bottom two lines. 

$cond['approved']        = ( $query->num_rows > 0 OR $SESS->userdata['group_id'] == '1' ) ? TRUE: FALSE;
$cond['not_approved']    = ( $query->num_rows > 0 OR $SESS->userdata['group_id'] == '1' ) ? FALSE: TRUE;

regardless of the truth value of ($query->num_rows > 0), the conditional will be true if the currently logged in user is a superadmin ($SESS->userdata[’group_id’] == 1).  My fix is still correct.

Profile
 
 
Posted: 11 June 2007 02:38 PM   [ Ignore ]   [ # 6 ]
Administrator
Avatar
Rank
Total Posts:  17
Joined  2005-03-22

I believe that’s the intended functionality. If you’re a superadmin, you should be able to see the content no matter what. I’ll have to double-check with Mitchell on that, but I won’t get the answer until late this month.

Profile
 
 
Posted: 11 June 2007 02:40 PM   [ Ignore ]   [ # 7 ]
Newbie
Rank
Total Posts:  18
Joined  2007-06-08
Chris Ruzin - 11 June 2007 02:38 PM

I believe that’s the intended functionality. If you’re a superadmin, you should be able to see the content no matter what. I’ll have to double-check with Mitchell on that, but I won’t get the answer until late this month.

Not according to the documentation.  Yes, a superadmin should always be able to access content, but thats why you check the actual member-id.  Its important when creating a permission management page that the admin be able to differentiate between those who are authorized and those who are not.

When you test a user-id against a permission point, you should get the same result no matter who is logged in.

Profile
 
 
Posted: 11 June 2007 02:48 PM   [ Ignore ]   [ # 8 ]
Administrator
Avatar
Rank
Total Posts:  17
Joined  2005-03-22

Where in the documentation is the check method used in a permissions management page? The docs only say to use the check method to “Wrap the contents of your templates inside the check function to control access to those contents.” It looks like the member_list method would be used in a member management page.

I’m not saying your fix is incorrect, especially since it seems you’re using the check method in an unsupported way according to the docs. All I’m saying is those two lines appear to be correct according to the docs.

Profile
 
 
Posted: 11 June 2007 02:51 PM   [ Ignore ]   [ # 9 ]
Newbie
Rank
Total Posts:  18
Joined  2007-06-08

I’m not using it in an unsupported way.

http://solspace.com/docs/entry/permission_10_check/

The ‘member_id’ parameter allows you to check the permissions of a specific member. The default is to check the permissions of the currently logged in member viewing the page.

Meaning, that if a member_id is not specified, the currently logged in user is checked.  If it is provided, the member_id is checked.

Profile
 
 
Posted: 11 June 2007 03:06 PM   [ Ignore ]   [ # 10 ]
Administrator
Avatar
Rank
Total Posts:  17
Joined  2005-03-22

Hmm… you’re right. How about this in place of the original two lines:

if ( $member_id == '' && $SESS->userdata['group_id'] == '1' )
{
    $cond[
'approved']        = TRUE;
    
$cond['not_approved']    = FALSE;
}
else
{
    $cond[
'approved']        = ( $query->num_rows > 0 ) ? TRUE : FALSE;
    
$cond['not_approved']    = ( $query->num_rows > 0 ) ? FALSE : TRUE;    
}

Profile
 
 
Posted: 11 June 2007 03:12 PM   [ Ignore ]   [ # 11 ]
Newbie
Rank
Total Posts:  18
Joined  2007-06-08

That doesn’t quite do it.

If you test a superadmin, it should return true, regardless of whether or not they have been added to a permission point.

You will have to go to the DB with the member_id in order to see if they are a superadmin.

Profile
 
 
Posted: 11 June 2007 03:42 PM   [ Ignore ]   [ # 12 ]
Administrator
Avatar
Rank
Total Posts:  17
Joined  2005-03-22

You’re right again.

One question on your line 1781. Won’t that always evaluate to false? Unless you rewrote the earlier check for $SESS->userdata[’member_id’] == 0 in the check method too. If you did, can you show me your entire check code?

Mitchell will be interested to see your many fixes/code improvements to the code.

Profile
 
 
Posted: 11 June 2007 03:49 PM   [ Ignore ]   [ # 13 ]
Newbie
Rank
Total Posts:  18
Joined  2007-06-08

($SESS->userdata[’member_id’] == 0) is true if the user is not logged in.
($member_id = $TMPL->fetch_param(’member_id’)) is true if a member_id has been passed

so my if ( $SESS->userdata[’member_id’] == 0 && !($member_id = $TMPL->fetch_param(’member_id’)))

if (<user is not logged in>  AND <no member_id is provided>) {
$cond[
'approved'] = FALSE;
$cond['not_approved'] = TRUE;
}

Profile
 
 
Posted: 11 June 2007 04:09 PM   [ Ignore ]   [ # 14 ]
Administrator
Avatar
Rank
Total Posts:  17
Joined  2005-03-22

Is that line 1751 or 1781? It looks more like 1751, but that would mean a person who isn’t logged in could see the content by passing along a permitted member_id in the URL.

All my questions would be answered if you could show me your entire check method code. I’m sure you’ve thought this out, but it’s confusing the hell out of me without seeing the rest of your code.

Profile
 
 
Posted: 11 June 2007 04:39 PM   [ Ignore ]   [ # 15 ]
Newbie
Rank
Total Posts:  18
Joined  2007-06-08

function check()
    
{
        
global $DB, $FNS, $IN, $LANG, $SESS, $TMPL;
        
// -------------------------------------------
        //    Logged in?
        // -------------------------------------------

        //drch edit
                
        
if ( $SESS->userdata['member_id'] == 0 && !($member_id = $TMPL->fetch_param('member_id')))
        
{
        
//end drch        
            // -------------------------------------------
            //  Set conditionals
            // -------------------------------------------
            
            
$cond['approved']        = FALSE;
            
$cond['not_approved']    = TRUE;
        
}
        
else
        
{
            
// -------------------------------------------
            //  Permission point?
            // -------------------------------------------
            
            
if ( ! $name = $TMPL->fetch_param('name') )
            
{
                
return $this->_fetch_error( $LANG->line('no_permission_point'), $TMPL->fetch_param('template') );
            
}
            
            
// -------------------------------------------
            //  Start SQL
            // -------------------------------------------
            
            
$sql    = "SELECT pt.* FROM exp_permission_posts ps LEFT JOIN exp_permission_points pt ON pt.permission_id = ps.permission_id WHERE approved = 'y'";
            
            
// -------------------------------------------
            //  Member ID
            // -------------------------------------------

            
if ( $member_id = $TMPL->fetch_param('member_id') )
            
{
                $sql
.= " AND ps.member_id = '".$member_id."' ";
            
}
            
else
            
{
                $sql
.= " AND ps.member_id = '".$SESS->userdata['member_id']."' ";
            
}
            
            
// -------------------------------------------
            //  Process name
            // -------------------------------------------
            
            
$sql    .= $FNS->sql_andor_string( $name, 'pt.name' );
                    
            
// -------------------------------------------
            //  Limit
            // -------------------------------------------
            
            
$sql    .= " LIMIT 1";

            
            
// -------------------------------------------
            //  Fetch permission id
            // -------------------------------------------
            
            
$query    = $DB->query( $sql );
            
            
// -------------------------------------------
            //  Set conditionals
            // -------------------------------------------
//drch edit
//function was improperly checking the currently logged in user for admin rights, when it should have been testing the
//checked user.    
            
$isAdmin = ($DB->query("SELECT member_id FROM exp_members where member_id = " . ($TMPL->fetch_param('member_id') ? $TMPL->fetch_param('member_id') : $SESS->userdata['member_id']) . " AND group_id = 1;")->num_rows > 0);
//            $cond['approved']        = ( $query->num_rows > 0 OR $SESS->userdata['group_id'] == '1' ) ? TRUE: FALSE;
//            $cond['not_approved']    = ( $query->num_rows > 0 OR $SESS->userdata['group_id'] == '1' ) ? FALSE: TRUE;
            
$cond['approved']        = ( $query->num_rows > 0 OR $isAdmin);
            
$cond['not_approved']    = !($cond['approved']);

//end drch            
        
}
        
        
// -------------------------------------------
        //  Parse
        // -------------------------------------------
        
        
$tagdata    = $TMPL->tagdata;
        
        
$tagdata    = $FNS->prep_conditionals( $tagdata, $cond );
        
        
// -------------------------------------------
        //  Single vars
        // -------------------------------------------
        
        
$vars        = array( 'description', 'name', 'label', 'permission_id' );
        
        foreach (
$vars as $var )
        
{
            
if ( isset( $query ) AND isset( $query->row[$var] ) )
            
{
                $tagdata    
= str_replace( LD.$var.RD, $query->row[$var], $tagdata );
            
}
            
else
            
{
                $tagdata    
= str_replace( LD.$var.RD, '', $tagdata );
            
}
        }
        
        
// -------------------------------------------
        //  Return
        // -------------------------------------------
        
return $tagdata;
    
}

Profile
 
 
   
1 of 2
1