haaai...
ik ben bezig met het maken van een op een database gebaseerd rechtensysteem [voor een forum].
Het idee is dat gebruikers in groepen vallen, en dat een gebruiker de rechten van de groep overneemt maar ook uitzonderingen kan bevatten. Bv.: groep A mag move'n behalve user 18 in die groep.
Nu zit ik met de volgende structuur:
een table users, een table groups en een kruistable.
Daarnaast heb ik een table met 'rules':
De namen van de columns zijn niet al te briljant dus ik zal het even uitleggen:
stel dat group 4 mag read/write/delete doen in forum 8 dan is dit de insert:
Qua structuur zit dat denk ik wel in orde. Voor het bepalen van bv. de rechten gebruik ik dit:
waarbij ik opgeef welke action ik wil hebben en een evt. actionid erbij. Bv. als ik wil weten wat de rechten zijn voor deze user op category-nivo (welke cats hij inmag):
snappie?
Nu zit ik met het volgende probleem: als ik nu bv. een lijst wil genereren (frontpage) van alle cats + fora waar de user inmag zit ik met een 'shitload' aan queries... ik kan me maar geen snelle en effectieve methode bedenken.
Als iemand in pseudo-code een oplossing kan aandragen om op basis van bovenstaand idee (wat, als het werkt, naadloos te integreren is in m'n forum) dan maakt hij/zij mij heel blij
Het grote probleem is nl. dat als ik bv. 1 bericht wil laten zien dat ik dan ook moet checken of die user categorie-forum-topic-bericht lees-rechten heeft en dat kost VEEL tijd... Ik zoek dus een oplossing met een zo laag mogelijk load en zo min mogelijk queries...
ik ben bezig met het maken van een op een database gebaseerd rechtensysteem [voor een forum].
Het idee is dat gebruikers in groepen vallen, en dat een gebruiker de rechten van de groep overneemt maar ook uitzonderingen kan bevatten. Bv.: groep A mag move'n behalve user 18 in die groep.
Nu zit ik met de volgende structuur:
een table users, een table groups en een kruistable.
Daarnaast heb ik een table met 'rules':
code:
1
2
3
4
5
6
7
8
9
10
| CREATE TABLE `F_Rules` ( `RuleID` int(11) unsigned NOT NULL auto_increment, `Leveltype` enum('user','group') NOT NULL default 'group', `LevelID` int(11) unsigned NOT NULL default '0', `Actionkind` enum('board','category','forum','topic','message','usernotes') NOT NULL default 'board', `Actionallowed` set('read','write','delete','move','edit') NOT NULL default '', `Actionnotallowed` set('read','write','delete','move','edit') NOT NULL default '', `ActionID` int(11) unsigned NOT NULL default '0', PRIMARY KEY (`RuleID`) ) TYPE=MyISAM; |
De namen van de columns zijn niet al te briljant dus ik zal het even uitleggen:
stel dat group 4 mag read/write/delete doen in forum 8 dan is dit de insert:
code:
1
| INSERT INTO F_Rules VALUES ('','group',4,'forum','read,write,delete','',8); |
Qua structuur zit dat denk ik wel in orde. Voor het bepalen van bv. de rechten gebruik ik dit:
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
| <? /** * Retrieves rights for this user * * Returns an error object, or an array of rights * * @author Michiel Roding <michiel@parse.nl> */ function get_rights($actionkind = 'board',$actionid = 0) { if(sizeof($this->groups) > 0) $groups = "Leveltype = 'group' AND LevelID IN (". implode(',',(array)$this->groups) .") OR "; if($actionid > 0) $aid = "AND ActionID = '". (int)$actionid ."' "; $query = " SELECT * FROM F_Rules WHERE ( $groups (Leveltype = 'user' AND LevelID = '". $this->userid ."') ) AND Actionkind = '". $this->engine->ins($actionkind) ."' $aid"; $result = $this->db->query( $query ); if($this->db->num_rows($result) == 0) { return new error("No rules where found for this user",'no_rules'); } $actions = (array)$this->db->get_set('F_Rules','Actionallowed'); while($row = $this->db->fetch_array($result)) { foreach($actions as $action) { if(in_array($action,(array)explode(',',$row['Actionallowed']))) { $right[$row["Leveltype"]]["Actionallowed"][$action] = $row["ActionID"]; } if(in_array($action,(array)explode(',',$row['Actionnotallowed']))) { $right[$row['Leveltype']]['Actionnotallowed'][$action] = $row["ActionID"]; } } } foreach($actions as $action) { if((isset($right['group']['Actionallowed'][$action]) && !isset($right['user']['Actionnotallowed'][$action])) || isset($right['user']['Actionallowed'][$action])) { $actionid = $right['group']['Actionallowed'][$action] > 0 ? $right['group']['Actionallowed'][$action] : $right['user']['Actionallowed'][$action]; $rights[$actionid][$action] = true; } } return $rights; } ?> |
waarbij ik opgeef welke action ik wil hebben en een evt. actionid erbij. Bv. als ik wil weten wat de rechten zijn voor deze user op category-nivo (welke cats hij inmag):
PHP:
1
2
3
4
5
6
| <? $rights = $this->user->get_rights('category'); foreach((array)$rights as $categoryid => $boolean) { $categoryids[] = $categoryid; } ?> |
snappie?
Nu zit ik met het volgende probleem: als ik nu bv. een lijst wil genereren (frontpage) van alle cats + fora waar de user inmag zit ik met een 'shitload' aan queries... ik kan me maar geen snelle en effectieve methode bedenken.
Als iemand in pseudo-code een oplossing kan aandragen om op basis van bovenstaand idee (wat, als het werkt, naadloos te integreren is in m'n forum) dan maakt hij/zij mij heel blij
Het grote probleem is nl. dat als ik bv. 1 bericht wil laten zien dat ik dan ook moet checken of die user categorie-forum-topic-bericht lees-rechten heeft en dat kost VEEL tijd... Ik zoek dus een oplossing met een zo laag mogelijk load en zo min mogelijk queries...
Klaar voor een nieuwe uitdaging.