[php/[my]sql] inherited rechtensysteem

Pagina: 1
Acties:
  • 1.294 views sinds 30-01-2008
  • Reageer

Acties:
  • 0 Henk 'm!

  • chem
  • Registratie: Oktober 2000
  • Laatst online: 18-09 22:59

chem

Reist de wereld rond

Topicstarter
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':
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]) &amp;&amp; !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.


Acties:
  • 0 Henk 'm!

  • Nielsz
  • Registratie: Maart 2001
  • Niet online
Whehe, daar zit ik ook mee :)

Ik weet niet of dit een beetje een oplossing is:

ik zet een session:
$forum_recht[$forum] = $recht;

Wil ik een topiclist doen is het heel simpel:
$recht=$forum_recht[$forum];

Nu een lijst van alle fora waar rechten zijn ingesteld of waar het een gewoon fora is:
Er is een functie die alle [$fora] in een andere array kan zetten (welke weet ik ff niet meer).
dus krijg je:
$fora=(1,2,3,4,6); de fora waar rechten zijn ingesteld.

$query="select blaat from fora where status=1 or fora in (1,2,3,4,6)"; oid.
Dus als je iets programmeert die dat laatste in de query dumpt heb je een mooie query.

Of zit ik totaal mis???

Acties:
  • 0 Henk 'm!

Verwijderd

chem: 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.
Snap ik geloof ik wel...
Nu zit ik met de volgende structuur: [MySQl blaat] Qua structuur zit dat denk ik wel in orde.
Ehmm... waarom niet booleans voor de rechten en NULL voor de groep default? :? Overzichtelijker, sneller, etc. Mis ik iets?
Voor het bepalen van bv. de rechten gebruik ik dit: [php om rechten van een gebruiker op te halen]
Die code wordt dan ook veel korter en overzichtelijker (als ik het nog volg, beetje :Z)

Misschien kan je iets meer uitleggen zodat ik het in mijn toestand van nu ook nog begrijp? ;)

Acties:
  • 0 Henk 'm!

  • chem
  • Registratie: Oktober 2000
  • Laatst online: 18-09 22:59

chem

Reist de wereld rond

Topicstarter
Op donderdag 11 oktober 2001 11:35 schreef Arien het volgende:

[..]

Snap ik geloof ik wel...
[..]

Ehmm... waarom niet booleans voor de rechten en NULL voor de groep default? :? Overzichtelijker, sneller, etc. Mis ik iets?
[..]

Die code wordt dan ook veel korter en overzichtelijker (als ik het nog volg, beetje :Z)

Misschien kan je iets meer uitleggen zodat ik het in mijn toestand van nu ook nog begrijp? ;)
daar heb je op zich gelijk in (booleans). Nadeel is dat ik nu via een get_enum og get_set functie uit m'n db-class de rechten kan uitpluizen, maar jah dat zou via een show table; oid ook moeten kunnen... zit ik nog steeds met de inheriting echter...

andere uitleg (wasigh heeft hetzelfde idee en nielsz: je oplossing is mijn 'oude' techniek en biedt te weinig mogelijkheden) vanuit de gebruiker:
iedereen komt standaard in de groep 'default'. Hiervoor stel je in dat ze een bepaald forum/aantal fora inmogen + rechten die ze hebben. Stel dat user 475 wel html mag gebruiken (zou er dus nog bijkomen qua rechtenlijstje) dan moet daar 1 extra recht voor worden gemaakt (de rest erft hij over).

Een paar notities: de actionkind 'category' en 'board' slaan eigenlijk nergens op achteraf (beidde zijn afhankelijk van de fora die erin zitten en wordne niet getoond indien er geen fora gelezen mogen worden) en 'topic' wordt denk ik omgezet naar 'topictype', hetzelfde bij message waarschijnlijk...

ik ben hier al te lang mee bezig :)

Klaar voor een nieuwe uitdaging.


Acties:
  • 0 Henk 'm!

Verwijderd

chem: Nadeel is dat ik nu via een get_enum of get_set functie uit m'n db-class de rechten kan uitpluizen, maar jah dat zou via een show table; oid ook moeten kunnen...
Je kan toch gewoon je booleans opvragen en als associatief array teruggeven uit de functie? Of snap ik het probleem niet? (Zou goed kunnen :o)
Zit ik nog steeds met de inheriting echter...
Wat ik hierboven bedoelde is dat je ook de groep rechten erbij pakt en in geval van NULL in de een rechtenattribuut dat groeprecht neemt.
Andere uitleg vanuit de gebruiker: iedereen komt standaard in de groep 'default'. Hiervoor stel je in dat ze een bepaald forum/aantal fora inmogen + rechten die ze hebben. Stel dat user 475 wel html mag gebruiken (zou er dus nog bijkomen qua rechtenlijstje) dan moet daar 1 extra recht voor worden gemaakt (de rest erft hij over).
Dan wordt in mijn idee het HTML recht van user 475 op 1 gezet (vanaf NULL). Mocht iedereen HTML gebruiken maar user 475 niet meer dan van NULL naar 0 en mag 475 weer naar de default dan dus naar NULL.

Of kan je daar niets mee?
Een paar notities: [notities]
Die volg ik niet maar dat ligt denk ik aan mij...

Hoop dat je hier wat mee kunt. :)

Acties:
  • 0 Henk 'm!

  • chem
  • Registratie: Oktober 2000
  • Laatst online: 18-09 22:59

chem

Reist de wereld rond

Topicstarter
het probleem waar ik mee zit (wat je hierboven noemt is eigenlijk een variant op mijn oplossing) is: stel ik wil topic 14 aan user hotseklotsen tonen. Hij mag wel in forum 12 kijken+schrijven (topics openen) waar topic 14 inzit en hij mag topic 14 bekijken maar niet beantwoorden...

nu weet ik wel hoe ik dit in de db zet maar hoe zoek ik dit zo snel mogelijk uit?

Klaar voor een nieuwe uitdaging.


Acties:
  • 0 Henk 'm!

Verwijderd

chem: Het probleem waar ik mee zit is: stel ik wil topic 14 aan user hotseklotsen tonen. Hij mag wel in forum 12 kijken+schrijven (topics openen) waar topic 14 inzit en hij mag topic 14 bekijken maar niet beantwoorden.
Even tussendoor: zet je rechten voor gebruikers of restricties op topics of allebei? :?

Als ik je goed begrijp heb je gebruikers die in groepen zitten en gebruikers hebben een aantal rechten en als default de rechten van hun groep, klopt?
Hebben topics en fora dan per gebruiker of per groep ook weer permissies of restrticties?

Acties:
  • 0 Henk 'm!

Verwijderd

Je kan in 1 query alle rechten opvragen van alle items op een pagina, als je van de volgende dingen uitgaat:
* je hebt uit de sessie van de gebruiker zijn userid en alle id's van groups waartoe hij behoort
* je hebt alle id's van alle items op de pagina, per item soort samen in een array

Vervolgens maak je een select query met in de where clause de volgende zaken:

- Juiste nivo: (Leveltype = 'user' and LevelID = $userid) or (Leveltype = 'group' and LevelID IN ($all_user_group_ids))

- Van alle item types alle items op pagina: (Actionkind='board' and ActionID IN ($all_board_ids) or (Actionkind='category' and ActionID IN ($all_category_ids) or (Actionkind='forum' and ActionID IN ($all_forum_ids) or (Actionkind='topic' and ActionID IN ($all_topic_ids) or (Actionkind='message' and ActionID IN ($all_message_ids) or (Actionkind='usernotes' and ActionID IN ($all_usernotes_ids)

Nu zit je met 2 problemen:
1) Een user kan tot meerdere groups behoren die verschillende rechten hebben op eenzelfde item. Bovendien kan de user ook nogeens individueel rechten hebben. Je moet een manier vinden om uit al deze records de toepasselijke rechten voor de user te halen.
2) De volgorde van rechten op items uit de select query en de volgorde waarin je de items wil afbeelden op de pagina zijn waarschijnlijk verschillend, dus hier zal je wat op moeten vinden.

Waarschijnlijk kan je mer wat slimme ORDER BY's wel zorgen dat de ellende niet te groot wordt.

HTH :)

Acties:
  • 0 Henk 'm!

  • chem
  • Registratie: Oktober 2000
  • Laatst online: 18-09 22:59

chem

Reist de wereld rond

Topicstarter
ha! nu kom je op de vraag :)

ten eerste kan een gebruiker in meerdere groepen horen wat dus de recursiviteit van de kwestie nogal verergerd zeg maar.

ten tweede wil ik alleen opschrijven dat groep-1 in forum 4 mag schrijven en tenzij het voor een topic anders vermeld staat dat men dus OOK in dat topic mag schrijven...

Nu zit ik eigenlijk te denken over het volgende: bij een topic plaats ik een 'typeid' bv. locked/sticky/open/read-only (beschrijving in aparte table). Nu wil ik dus in 1x kunnen zeggen dat groep-1 alleen (op board level) mag reageren in 'open' topics. Enkele users uitgezonderd uiteraard...

Snap je m'n probleem onderhand? Eigenlijk wil ik het hele idee van wat wel en niet mag verhuizen naar de admin ipv dat hard te coderen in de source...

Klaar voor een nieuwe uitdaging.


Acties:
  • 0 Henk 'm!

  • Skinny
  • Registratie: Januari 2000
  • Laatst online: 16:45

Skinny

DIRECT!

Pff.. moeilijk om een gedachte of idee in je hoofd zo even te verwoorden, maar als ik het probleem goed begrijp en ik hoop van wel, kun je dan niet iets in de trant van het onderstaande gebruiken ? :

---
Ik ga ervanuit dat je een User object tijdens een sessie bewaard, als dit niet zo is kun je dit waarschijnlijk vergeten. Op deze manier heb je alleen tijdens het inloggen even een paar zware queries, maar daarna niet meer.

MAak van die ActionAllowed & ActionNotAllowed INT's en vul ze als volgt :
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
READ = 1;
WRITE = 2;
DELETE = 4;
MOVE = 8;

VB: Lezen en schrijven -> ActionAllowed = 3


Bij het inloggen, $user->rights opbouwen uit DB:

$rights[Actionkind][ActionID] = GroupAllowed + UserAllowed - GroupNotAllowed - UserNotAllowed


function HasRight(ActionKind, ActionID, Action) {

    return $user->rights[ActionKind][ActionID] AND Action;

}

VB: Mag user schrijven in forum 3 ?

print HasRight("forum",3,WRITE);

SIZE does matter.
"You're go at throttle up!"


Acties:
  • 0 Henk 'm!

  • wasigh
  • Registratie: Januari 2001
  • Niet online

wasigh

wasigh.blogspot.com

[b]Op donderdag 11 oktober 2001 12:13 schreef chem

Snap je m'n probleem onderhand? Eigenlijk wil ik het hele idee van wat wel en niet mag verhuizen naar de admin ipv dat hard te coderen in de source...
Ik snap het volledig, en ben hier ook al een tijd over na aan het denken. ;)

Ik ga het waarschijnlijk in java doen, en zorg voor een rechten object waarschijnlijk die 1 keer de database inleest en dan altijd rechten weer kan geven van een gebruiker.

Zo zet ik de business logic in een class ipv in een sql Query..

Acties:
  • 0 Henk 'm!

  • chem
  • Registratie: Oktober 2000
  • Laatst online: 18-09 22:59

chem

Reist de wereld rond

Topicstarter
Op donderdag 11 oktober 2001 12:16 schreef Skinny het volgende:
MAak van die ActionAllowed & ActionNotAllowed INT's en vul ze als volgt :
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
READ = 1;
WRITE = 2;
DELETE = 4;
MOVE = 8;

VB: Lezen en schrijven -> ActionAllowed = 3


Bij het inloggen, $user->rights opbouwen uit DB:

$rights[Actionkind][ActionID] = GroupAllowed + UserAllowed - GroupNotAllowed - UserNotAllowed


function HasRight(ActionKind, ActionID, Action) {

    return $user->rights[ActionKind][ActionID] AND Action;

}

VB: Mag user schrijven in forum 3 ?

print HasRight("forum",3,WRITE);
hier noem je dus een variant waar ik ook aan heb zitten te denken: het in 1x inlezen van alle rechten en vv. uitspitten, en/of werken met een binair stelsel (zo heet dat toch :?) zoals jij voorstelt... dit is dan eigenlijk hetzelfde als wat wasigh wil gaan doen echter dan met een andere syntax...

ik ga er even over denken!

Klaar voor een nieuwe uitdaging.


Acties:
  • 0 Henk 'm!

  • chem
  • Registratie: Oktober 2000
  • Laatst online: 18-09 22:59

chem

Reist de wereld rond

Topicstarter
Op donderdag 11 oktober 2001 12:12 schreef MrX het volgende:
Nu zit je met 2 problemen:
1) Een user kan tot meerdere groups behoren die verschillende rechten hebben op eenzelfde item. Bovendien kan de user ook nogeens individueel rechten hebben. Je moet een manier vinden om uit al deze records de toepasselijke rechten voor de user te halen.
2) De volgorde van rechten op items uit de select query en de volgorde waarin je de items wil afbeelden op de pagina zijn waarschijnlijk verschillend, dus hier zal je wat op moeten vinden.
en dat is precies 'het' probleem... hoe maak je zoiets zodat je het volgend jaar ook nog snapt :)

ik heb nu echter een idee dus asap een reply weer...

Klaar voor een nieuwe uitdaging.


Acties:
  • 0 Henk 'm!

Verwijderd

Voor probleem 1 kan je twee kanten uit: de meeste restrictieve rechten nemen of de meeste ehmm... die andere rechten nemen.

/me question near line 6: "2) De volgorde van rechten ... "
/me coffee, dumping eye-lids.

Acties:
  • 0 Henk 'm!

  • chem
  • Registratie: Oktober 2000
  • Laatst online: 18-09 22:59

chem

Reist de wereld rond

Topicstarter
zo, daar zijn we weer :)

en combinatie van arien, skinny en wasigh-ideeen. feedback is welkom :)
situatie:
code:
1
2
3
4
5
6
7
8
9
10
            r       w       x        m 
group1      1       1       0       1
group2      0       0       0       1
user1       NULL    NULL    NULL    0

legenda:
1 = allowed
0 = not allowed
- = not specified (NULL)
groups kunnen geen NULL bevatten

levert de volgende resultset op uit mysql:
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
<?
$rs = array(
                0 => array(    'Leveltype' => 'group',
                            'LevelID' => 1,
                            'Actionkind' => 'forum',
                            'ActionID' => 5,
                            'Read' => 1,
                            'Write' => 1,
                            'Delete' => 0,
                            'Move' => 1
                            ),
                1 => array(    'Leveltype' => 'group',
                            'LevelID' => 2,
                            'Actionkind' => 'forum',
                            'ActionID' => 5,
                            'Read' => 0,
                            'Write' => 0,
                            'Delete' => 0,
                            'Move' => 1
                            ),
                2 => array(    'Leveltype' => 'user',
                            'LevelID' => 1,
                            'Actionkind' => 'forum',
                            'ActionID' => 5,
                            'Read' => NULL,
                            'Write' => NULL,
                            'Delete' => NULL,
                            'Move' => 0
                            )
            );
?>

en de verwerkende code (danwel bij inloggen (==snel) danwel elke keer (==dynamischer) danwel bij een update (== een beetje van beiden)):
PHP:
1
2
3
4
5
6
7
<?
while($row = fetch_array($rs)) {
    foreach($actions AS $action) {
        ${$row[Leveltype]}[ $row[actionkind] ][ $row[actionid] ][ $action ] = uhhh? jah wat? :);
    }
}
?>

en de opvraagfunctie:
PHP:
1
2
3
4
5
6
7
8
<?
function hasRights($actionkind = 'board', $actionid = 0, $action = 'r') {
    if(((user[$actionkind][$actionid][$action] == NULL || user[$actionkind][$actionid][$action] == 1) &amp;amp;&amp;amp; $group[$actionkind][$actionid][$action] == 1) || $user[actionkind][$actionid][$action] == 1) {
        return true;
    }
    return false;
}
?>

Klaar voor een nieuwe uitdaging.


Acties:
  • 0 Henk 'm!

  • corani
  • Registratie: December 2000
  • Laatst online: 05-10-2017

corani

__,,,_(^_^)_,,,__

[mark]

Laat me nou toch eens met rust man!
Iedereen die in telekinese gelooft, steek a.u.b. mijn hand op


Acties:
  • 0 Henk 'm!

  • Skinny
  • Registratie: Januari 2000
  • Laatst online: 16:45

Skinny

DIRECT!

Uit DB, of gewoon hard coded :
PHP:
1
2
3
4
5
6
<?
$actions = array("read" => 1,
         "write"=> 2,
         "modify"=> 4,
         "delete" => 8);
?>

dient op te leveren uit mysql:
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<?
$rs = array(
                0 => array( 'Leveltype' => 'group',
                            'LevelID' => 1,
                            'Actionkind' => 'forum',
                            'ActionID' => 5,
                            'Rights' => 7
                            ),
                1 => array(    'Leveltype' => 'group',
                            'LevelID' => 2,
                            'Actionkind' => 'forum',
                            'ActionID' => 5,
                            'Rights' => 4
                            ),
                2 => array( 'Leveltype' => 'user',
                            'LevelID' => 1,
                            'Actionkind' => 'forum',
                            'ActionID' => 5,
                            'Rights' => 0
                            )
            );
?>


PHP:
1
2
3
4
5
6
7
8
<?
while($row = fetch_array($rs)) {
    while (list ($action, $value)) = each ($actions) {
        if ( $rights[ $row[actionkind] ][ $row[actionid] ] AND $value == 0)     
            $rights[ $row[actionkind] ][ $row[actionid] ] += $value;
    }
}
?>

en de opvraagfunctie:
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<?
function hasRights($actionkind = 'board', $actionid = 0, $action = 'read') {
    if ($rights[$actionkind][$actionid] AND $actions[$action] == $actions[$action])
        return true;
    }
    return false;
}

function getRights($actionkind = 'board', $actionid = 0) {

    $result = "";

    while (list ($action, $value)) = each ($actions) {
        if ( $rights[ $row[actionkind] ][ $row[actionid] ] AND $value == $value)
            result[] = $action;
    }
    return $result';
}    
?>

Disclaimer : Uit het hoofd gedaan, niet getest dus >:)

SIZE does matter.
"You're go at throttle up!"


Acties:
  • 0 Henk 'm!

  • chem
  • Registratie: Oktober 2000
  • Laatst online: 18-09 22:59

chem

Reist de wereld rond

Topicstarter
wat als een user in 2 groepen zit?

Klaar voor een nieuwe uitdaging.


Acties:
  • 0 Henk 'm!

  • Skinny
  • Registratie: Januari 2000
  • Laatst online: 16:45

Skinny

DIRECT!

Op donderdag 11 oktober 2001 14:29 schreef chem het volgende:
wat als een user in 2 groepen zit?
PHP:
1
2
3
4
5
6
7
8
<?
while($row = fetch_array($rs)) {
    while (list ($action, $value)) = each ($actions) {
        if ( $rights[ $row[actionkind] ][ $row[actionid] ] AND $value == 0)     
            $rights[ $row[actionkind] ][ $row[actionid] ] += $value;
    }
}
?>

Worden nu bij elkaar opgeteld. Als Groep1 mag lezen en Groep2 mag schrijven en een user is lid van 1&2 dan mag de user lezen en schrijven.

Eerst check je of een recht (read, write ... etc) al aanwezig is, zo nee, voeg dan toe.

Dat lijkt mij het meest logische. Je kun bovenstaande stukje code natuurlijk aanpassen om bepaalde rechten boven andere te laten gelden.

Waar het om gaat is dat het uiteindelijk niet uitmaakt of een user een recht krijgt uit de userrechten of uit de grouprechten. (dunkt mij ;) )

SIZE does matter.
"You're go at throttle up!"


Acties:
  • 0 Henk 'm!

  • Nielsz
  • Registratie: Maart 2001
  • Niet online
Op donderdag 11 oktober 2001 14:34 schreef Skinny het volgende:
Waar het om gaat is dat het uiteindelijk niet uitmaakt of een user een recht krijgt uit de userrechten of uit de grouprechten. (dunkt mij ;) )
Me dunkt dat de userrechten dominant horen te zijn boven de grouprechten. :)

Acties:
  • 0 Henk 'm!

  • Skinny
  • Registratie: Januari 2000
  • Laatst online: 16:45

Skinny

DIRECT!

Op donderdag 11 oktober 2001 14:36 schreef Nielsz het volgende:

[..]

Me dunkt dat de userrechten dominant horen te zijn boven de grouprechten. :)
Stimt! maar dat gebeurt nu ook. Wat ik bedoel is dat als je in een script opvraagt of een user rechten heeft, dat het voor het resultaat niet uitmaakt waar dat recht vandaan komt (uit het wetboek :P ?) ...

SIZE does matter.
"You're go at throttle up!"


Acties:
  • 0 Henk 'm!

Verwijderd

Op donderdag 11 oktober 2001 14:36 schreef Nielsz het volgende:
Me dunkt dat de userrechten dominant horen te zijn boven de grouprechten. :)
Maar hoe los je dat bij lidmaatschap van meerdere groepen dan op?
Stel groep 1 weigert privilege A en staat B toe. Groep 2 staat privilege A juist toe en weigert B. De gebruiker zit in beide groepen
Tijd om te exploderen?

Acties:
  • 0 Henk 'm!

Verwijderd

het idee van Skinny (binaire representatie) zit ik ook al een tijdje over te denken, alleen wil ik het dan gebruiken om de groepen aan te geven i.p.v. de mogelijke acties. Een probleem is echter dat je dan maximaal 31 verschillende groepen kan hebben als je een int als datatype gebruikt...
Iemand hier een slimme oplossing voor?

Acties:
  • 0 Henk 'm!

  • Nielsz
  • Registratie: Maart 2001
  • Niet online
Op donderdag 11 oktober 2001 14:41 schreef gnufnork het volgende:

[..]

Maar hoe los je dat bij lidmaatschap van meerdere groepen dan op?
Stel groep 1 weigert privilege A en staat B toe. Groep 2 staat privilege A juist toe en weigert B. De gebruiker zit in beide groepen
Tijd om te exploderen?
Neuh, tijd om na te denken :P :)
Groups >> worst of all
Users >> best of all

(en dit dat was in het engels :) )

Acties:
  • 0 Henk 'm!

  • wasigh
  • Registratie: Januari 2001
  • Niet online

wasigh

wasigh.blogspot.com

verbieden dat een user in meerdere eventueel tegenstrijdige groepen mag.

Acties:
  • 0 Henk 'm!

  • Nielsz
  • Registratie: Maart 2001
  • Niet online
Op donderdag 11 oktober 2001 15:18 schreef wasigh het volgende:
verbieden dat een user in meerdere eventueel tegenstrijdige groepen mag.
Maar je wilt dus wel dat een user in

group a: modforum1 &
group b: modforum2

terecht kan. Dus hoe moet dat opgelost worden?
Niet op mijn manier bedenk ik me net...

Acties:
  • 0 Henk 'm!

  • Skinny
  • Registratie: Januari 2000
  • Laatst online: 16:45

Skinny

DIRECT!

Nieuwe uit-het-hoofd versie (geen php omgeving hier :( )
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
50
51
52
53
54
<?
$actions = array("read" => 1,
         "write"=> 2,
         "modify"=> 4,
         "delete" => 8);

$rs = array(
                0 => array( 'Leveltype' => 'group',
                            'LevelID' => 1,
                            'Actionkind' => 'forum',
                            'ActionID' => 5,
                            'Rights' => 7
                'Deny' => 0
                            ),
                1 => array(    'Leveltype' => 'group',
                            'LevelID' => 2,
                            'Actionkind' => 'forum',
                            'ActionID' => 5,
                            'Rights' => 4,
                'Deny' => 2
                            ),
                2 => array( 'Leveltype' => 'user',
                            'LevelID' => 1,
                            'Actionkind' => 'forum',
                            'ActionID' => 5,
                            'Rights' => 0,
                'Deny' => 4
                            )
            );


while($row = fetch_array($rs)) {
    while (list ($action, $value)) = each ($actions) {

    if ( $row[rights] AND $value == 0 ) // recht toevoegen indien nog niet aanwezig
        $$row[leveltype][ $row[actionkind] ][ $row[actionid] ] += value;

    if ( $row[deny] AND $value == $value) // recht intrekken als aanwezig
        $$row[leveltype][ $row[actionkind] ][ $row[actionid] ] -= value;

    }     

}

// Optellen maar


while (list ($actionkind, $actionkind_value)) = each ($group_rights) {
    while ( list($actionid, $actionid_value)) = each($group_rights[$actionkind]) {
    
        $user_rights[$actionkind][$actionid] = $group_rights[$actionkind][$actionid] + $user_rights[$actionkind][$actionid];
    }
}
?>

$user_rights [actionkind][actionid]
bevat het totaal aantal rechten voor een bepaald item.

Met HasRights (Zie boven) kan je dan de rechten opvragen.

SIZE does matter.
"You're go at throttle up!"


Acties:
  • 0 Henk 'm!

  • chem
  • Registratie: Oktober 2000
  • Laatst online: 18-09 22:59

chem

Reist de wereld rond

Topicstarter
skinny> ik snap een aantal dingen in je code niet... als je wil heb ik een php omgeving voor je :) en ik zou heel graag een 'werkende' versie van je code zien...

Klaar voor een nieuwe uitdaging.


Acties:
  • 0 Henk 'm!

  • Skinny
  • Registratie: Januari 2000
  • Laatst online: 16:45

Skinny

DIRECT!

hehe... zo onduidelijk ? :P

Nee, ik zit op het werk (Daar heb ik geen PHP).. Thuis wel, dus vanavond kan ik wel ff wat online zetten..

Deal ? :)

SIZE does matter.
"You're go at throttle up!"


Acties:
  • +1 Henk 'm!

  • chem
  • Registratie: Oktober 2000
  • Laatst online: 18-09 22:59

chem

Reist de wereld rond

Topicstarter
het is al getackled, als je het beter kan hoor ik het graag :)
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
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',
  `ActionID` int(11) unsigned NOT NULL default '0',
  `view` set('1','0') default NULL,
  `move` set('1','0') default NULL,
  `del` set('1','0') default NULL,
  `make` set('1','0') default NULL,
  `edit` set('1','0') default NULL,
  PRIMARY KEY  (`RuleID`)
) TYPE=MyISAM;

en de verwerk functie:
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
50
51
52
53
54
55
56
<?
/**
*    Retrieves rights for this user
*
*    Returns an error object, or an array of rights
*
*    @author Michiel Roding <michiel@parse.nl>
*/
function get_rights() {
    $query = "    SELECT *
                 FROM F_Rules
                 WHERE (    Leveltype = 'group' AND LevelID IN (0, ". implode(',',(array)$this->groups) .") OR
                          (Leveltype = 'user' AND LevelID = '". $this->userid ."') )
                 ORDER BY Leveltype DESC";

    $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('view','move','del','make','edit');

    while($row = $this->db->fetch_array($result)) {
        foreach($actions AS $action) {

            if($row[Leveltype] == 'group') {
                if($rights[ $row[Actionkind] ][ $row[ActionID] ][ $action ] == 1) {
                    ;
                }
                elseif($row[$action] == 1) {
                    $rights[ $row[Actionkind] ][ $row[ActionID] ][ $action ] = 1;
                }
                else {
                    $rights[ $row[Actionkind] ][ $row[ActionID] ][ $action ] = 0;
                }
            }
            else {
                if($row[$action] === NULL) {
                    ;
                }
                elseif($row[$action] == 1) {
                    $rights[ $row[Actionkind] ][ $row[ActionID] ][ $action ] = 1;
                }
                else {
                    $rights[ $row[Actionkind] ][ $row[ActionID] ][ $action ] = 0;
                }
            }

        }
    }

    return true;
}
`
?>

dit geeft een multi-dim array terug met overerving van rechten.

ik zeg nu vast tegen iedereen die dit later tegenkomt en wil gaan gebruiken, dat ik geen support of uitleg geef. Zij die dit moeten gebruiken of schrijven zouden allang moeten snappen HOE het werkt...

Ik denk nog over een sneller alternatief, suggesties zijn weer welkom :)

Klaar voor een nieuwe uitdaging.


Acties:
  • 0 Henk 'm!

  • Nielsz
  • Registratie: Maart 2001
  • Niet online
Chem >> gaaaaaaaaap :D

Ik wil wel graag van je weten wat je tegenstond aan je oude systeem (wat ik dus gebruik) dat je er vanaf gestapt bent?

Acties:
  • 0 Henk 'm!

  • Jasper
  • Registratie: Juni 1999
  • Laatst online: 18-09 14:17
Chem: Snap je het niet, nielsz?

Acties:
  • 0 Henk 'm!

  • chem
  • Registratie: Oktober 2000
  • Laatst online: 18-09 22:59

chem

Reist de wereld rond

Topicstarter
het probleem is dat jouw suggestie/methode te weinig ruimte biedt en je beschrijft enkel de laatste stap in het proces.

Als je veel meer rechten en type rechten wilt beheren kom je met jouw methode al snel in de knoop...

Klaar voor een nieuwe uitdaging.


Acties:
  • 0 Henk 'm!

  • Nielsz
  • Registratie: Maart 2001
  • Niet online
Daar hebben we het dan nog wel eens een keer over :)

Acties:
  • 0 Henk 'm!

  • justmental
  • Registratie: April 2000
  • Niet online

justmental

my heart, the beat

Mijn oplossing:
-tabel met users
-tabel met rollen
-koppeltabel users/rollen
-tabel met privileges
-hierarchische tabel met domeinen
-koppeltabel domain/user/privs
-koppeltabel domain/rol/privs

Door de hierarchische tabel hoef ik de hoogste rol alleen maar de het privilege all op het root object in de domain tabel te geven.
Door te registreren dat iemand 'geen rechten' ergens op heeft krijg je die conflictsituaties. Ik registreer dan ook alleen additionele rechten per user.
Deze structuur heeft als voordeel dat als ik later makkelijk privs of domeinen toe kan voegen.
Ik heb ook een functie om de privs van 1 domein in een keer in een array te zetten om zo het aantal functie-aanroepen te beperken.

Dit is wel in Oracle, ik heb geen idee of hierarchische tabellen in mysql wel kunnen.

Who is John Galt?


Acties:
  • 0 Henk 'm!

Verwijderd

Ben nu wat wakkerder dan gisteren.... :P
chem: Wat als een user in 2 groepen zit?
Een groep is een verzameling gebruikers die dezelfde eigenschappen hebben, anders heeft het idee van een groep geen zin.

Dus een gebruiker heeft individuele rechten die het sterkst zijn, vervolgens groepsrechten die per recht een OR zijn van alle groepen waar hij in zit.

Voorbeeldje:
code:
1
2
3
Gebruiker foo heeft gebruikersrechten: r--
Groepsrechten (normale gebruiker): rw-
Groepsrechten (admin): rwm

Dan heeft hij op basis van zijn groepsrechten: rwm (per recht een OR voor alle groepen waar hij in zit), maar door zijn gebruikersrechten blijft er maar r-- van over.

Als voor een gebruiker een bepaald recht gedefinieerd is, betekent dat dat groepsrechten niet van belang zijn (waarom zou je anders voor de gebruiker zijn rechten definieren? Je zou ze gewoon op NULL kunnen laten.)

Ander voorbeeld:
code:
1
2
Gebruiker bar heeft gebruikersrechten: ??-
Groepsrechten (moderator): rwm

Geeft de gebruiker de volgende rechten: rw-. r en w door zijn groep en geen m doordat zijn gebruikersrechten de groepsrechten overrulen. (Dit zou een moderator zijn die niet meer kan modden ofzo? :?)

Ik denk dat het hebben van individuele rechten alleen maar voor verwarring zorgt en het datamodel niet mooier maakt, of je zou die groepen ook nog ergens anders voor willen gebruiken? :?
Pagina: 1