PDA

View Full Version : Refresh iforumpermission cache


Jawelin
05-14-2002, 10:10 PM
Hi.
I tried to retrieve each usergroup permission on a given forum using the getpermission(forumid,0,groupid) function.
(it would be too complex doing that uprising the inheritance at database level ... as I tried to do days ago... :hurt: )

But noticed, cycling by the usergroup, a strange behavior based upon the order I tested the groups.
Analyzing the code, I realized there's a kind of cache of permission stored each time in global environment.

So, for example, if I test first usergroups 6 and 5, I get they CAN access to some forum. If I test them later, after some other groups, I get they CAN'T do the same access to the same forum.

Question is simple: how could I bypass this 'cache-due' strange and unpredictable behavior ?

Thank you very much.
Hope someone could give an answer.
Thanks

Admin
05-15-2002, 09:29 AM
Stick:
unset($permscache, $usergroupcache);
Before calling getpermissions().

Jawelin
05-15-2002, 04:56 PM
Thanks. It seems working on cleaning cache... At least, when I
change the order of groups I call the function for, I always get
the same results...

But they are unexpected, mostly for usergroups 5 and 6 !!! :eek:

I wrote this function (used a function to avoid some side effect
coming from global variables not explicitly declared):

function testugperm($forum2test=9) {
global $DB_site;

$usergroups=$DB_site->query("SELECT usergroupid,title FROM usergroup ORDER BY usergroupid");

echo "<p><pre>";
while ($usergroup=$DB_site->fetch_array($usergroups)) {

unset($permscache, $usergroupcache);
$perms=getpermissions($forum2test,0,$usergroup[usergroupid]);

if ($perms[canview])
echo "<br>Forum <b>$forum2test</b> <b> can </b> be accessed by usergroup $usergroup[usergroupid] ($usergroup[title])";
else
echo "<br>Forum <b>$forum2test</b> <b>can't</b> be accessed by usergroup $usergroup[usergroupid] ($usergroup[title])";
}
echo "</pre></p>";
}



but - even on public forums or private without specific access
masks - I see Admin & Supermods can't access them. :rolleyes:

Besides, I think there should be some cache interference yet, as -
for example - if I test permissions by users with

unset($permscache, $usergroupcache);
$perms=getpermissions($forum2test,$userid);

for first 20 users, when the cycle passes from a group to another,
I see the new group couldn't access that forum ...
Instead, it can !

Even, i tried to unset the corresponding GLOBALS[] array
variables, as I'm within a function...
But results are the same.

Any idea ?

Thank you very much.

Admin
05-15-2002, 04:59 PM
You need global $permscache, $usergroupcache; in the function.

Jawelin
05-15-2002, 05:08 PM
Btw, OUTSIDE the function,
getpermission($forumid,$userid) doesn't work even on first 20 users. I get 'canview' access only for Admins...
When the counter switches to Supermods, I get a "CAN'T" ... :(

If I reverse the sort (counting users from 20 to 1), I get userids 6-8 (supermods) can access... Admins can't .... :eek

Thnx

Jawelin
05-16-2002, 09:03 PM
For usergroup permissions (in particular for Mods & Supermods) the function behavior is unpredictable.
Where could I find into db such informations ?

Thanks.
Need help .... :(

Jawelin
05-18-2002, 07:11 AM
FF, you're very avaricious when we're talking about enhanced MySQL DB queries ... aren't you ? :D

After all, you can do it... Don't ?
We have done so much, for so long, with so little, we are now qualified to do anything with nothing.

Thanks
:p

Jawelin
05-18-2002, 10:43 AM
Originally posted by FireFly
Stick:
unset($permscache, $usergroupcache);
Before calling getpermissions().

There's something not working. I can't manage to clean the
cache, even outside the function...

If want, please try to upload this code to the admin/ directory
and try to execute vs. some private/protected forum (&forumid=xx) and with moderator or supermods usergroup (&grpid=y).
Even, a single user (&singleuser=uuu) can be specified.

<?php
error_reporting(E_ALL);

require("./global.php");
cpheader();

echo "<p>Group <b>$grpid</b> crossed with Forum <b>$forumid</b></p>";

if (isset($forumid) and isset($grpid)) {

$forum2test=$forumid;

$usergroups=$DB_site->query("SELECT usergroupid,title FROM usergroup where usergroupid=$grpid");

echo "<p>";
while ($usergroup=$DB_site->fetch_array($usergroups)) {

$id=$usergroup[usergroupid];

$perms[$id]=getpermissions($forum2test,0,$id);

$k=$perms[$id];
if ($k[canview])
echo "<br>Forum <b>$forum2test</b> <b> can </b> be accessed by usergroup $usergroup[usergroupid] ($usergroup[title])";
else
echo "<br>Forum <b>$forum2test</b> <b>can't</b> be accessed by usergroup $usergroup[usergroupid] ($usergroup[title])";
}
echo "</p>";


$users=$DB_site->query("SELECT userid,username FROM user WHERE usergroupid=$grpid ORDER BY userid");

echo "<p>";
while ($user=$DB_site->fetch_array($users)) {

unset($permscache, $usergroupcache);

$id=$user[userid];

$permuser[$id]=getpermissions($forum2test,$id);

$k=$permuser[$id];
if ($k[canview])
echo "<br>Forum <b>$forum2test</b> <b> can </b> be accessed by user $user[userid] ($user[username])";
else
echo "<br>Forum <b>$forum2test</b> <b>can't</b> be accessed by user $user[userid] ($user[username])";
}
echo "</p>";


// copy this code right before the first select...
if (isset($singleuser)) {

unset($permscache, $usergroupcache);

$user[userid]=$singleuser;
$permsingleuser=getpermissions($forum2test,$user[userid]);

if ($permsingleuser[canview])
echo "<br>Forum <b>$forum2test</b> <b> can </b> be accessed by user $user[userid]";
else
echo "<br>Forum <b>$forum2test</b> <b>can't</b> be accessed by user $user[userid]";

}
// ... and if run with an user of the usergroup specified,
// you'll get different values for same instructions.

}

echo "<br><br><p>Performance stats: <b>".number_format($query_count)."</b> queries done in <b>".number_format($querytime,7)."</b> seconds</p>";

cpfooter();

?>



You can notice if run with a single user, that:
- if the user belongs to the specified group, permissions are
cached (i.e. wrong results if such user has single access mask
set)
- if not, permissions returned are true (reflecting the actual user ones)
- if you copy the same section of $singleuser also before the first
getpermissions(), you'll obtain true values ANY CASE, much
different from the same code at the end of the script.


It means that permissions are cached per usergroup and per
forum. And the unsets aren't enough .... :(

Thank you for attention.

Any idea ?
Bye

Admin
05-18-2002, 12:03 PM
Ok, now I understand what is wrong. I'll try and fix it...

Jawelin
05-20-2002, 08:04 AM
Originally posted by FireFly
Ok, now I understand what is wrong. I'll try and fix it...
Here I'm ! I rely on you... :)
Thanks.
Let me know.
Bye

Admin
05-20-2002, 11:22 AM
This is the weirdest issue, I have no idea...

Jawelin
05-21-2002, 01:57 PM
Please, try and give a look if u have time.
I would manage to understand whether a group (and its members) has access to a forum analyzing only the DB....
Thanks

Jawelin
05-29-2002, 08:40 AM
Originally posted by FireFly
This is the weirdest issue, I have no idea...

:cry: BUMP

Logician
05-29-2002, 09:21 AM
I neither check the code extensively, nor tested it, but at first glance, doesnt that seem wrong to you:


$perms[$id]=getpermissions($forum2test,0,$id);
$k=$perms[$id];
if ($k[canview])



What about using this instead:


$k=getpermissions($forum2test,0,$id);

if ($k[canview])


this should work..

Logician

Jawelin
05-29-2002, 09:47 AM
Yes, of course...
Simply I used that array to obtain PER GROUP permission scheme.

Btw, there's a strange cache staying in memory every time I call the getpermission() function that make it returns strange and wrong results, depending on the order I check groups, for example, or users themselves...

That's the point of this thread and I can't get on...
;(

Thank you very much.
Bye

Admin
05-29-2002, 10:13 AM
Originally posted by Logician
I neither check the code extensively, nor tested it, but at first glance, doesnt that seem wrong to you:

What about using this instead:

this should work..

Logician
It doesn't really matter, he was just using the $perms array to store informatin for each usergroup, so he used it as an intermediate variable.

Jawelin
05-31-2002, 09:43 AM
I GOT IT !!!
:laugh: :laugh: :laugh:

Finally I managed to create a almost simple algorithm to perform a search of all users having access to a given forum, at any level (usergroup/forumpermission/accessmask), with the right priority order, I think.

Chen, as it's an extension of your hack "List users by access masks (https://vborg.vbsupport.ru/showthread.php?s=&threadid=28248)", if you agree, I would post my 'version' following that thread, or as a new thread as 3rd party addon to your version ??

Here are the simple starting thesis:[list=1]
All usergroups have default 'usergroup.canview=[0/1]' access to each forum, unless different specification somewhere else. Table 'usergroup'; lowest priority.
Search for group-forum crossed permissions in 'forumpermission' table. First for forum parent items, later (w/ major priority) child forums. Different forumpermission.canview=[0/1]' specification than the previous default could revert it for that usergroup; medium priority.
As a result, I'll obtain all the usergroups with canview access [0/1] to the desired forum.
Exploding users for these groups, now I have all the users with group-level rights.
Now I can check per-user based auths, checking the 'access' table. Based upon the status of 'access.canview=[0/1]' for each user, I can remove or add that user to the previous list. Highest security priority.
Finally I have the complete (unordered, but isn't a problem for sql IN statement) list of users having (or not) access to that particular forum.
[/list=1]

This way, with ONLY four (4) queries (even they could be reduced with some nice LEFT JOIN, but wouldn't overload my algorithm complexity at this time... if someone... :D ), I should have taken care of any security items in the VBulletin scheme.

This version works only for two-level categories, but I think an easy extension could be done for recursive multi-level approach.
Iteration is human, recursion is divine...

Hope this will work.
Thank you.
Bye