wie macht mans am besten?

Einklappen
X
 
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

  • wie macht mans am besten?

    Hallo,

    ich stehe gerade vor dem Problem einer Rechteverwaltung,
    und habe gerade nicht wirklich die Idee wie ich das umsetzen kann.

    Die Ausgangslage ist eine baumartige Struktur, in welche
    Benutzerrechte wie bei Windows NT eingebaut werden sollen.

    Dh. die Rechte sollen im Baum vererbt werden, bzw. Rechte
    in unteren Zweigen müssen weiter oben gesetzte Rechte
    überschreiben.

    Jemand eine clevere Idee, wie man sowas in Tabellenform bringt,
    möglichst so, das man mit einer SQL Abfrage bestimmen kann
    ob der User jetzt das Recht hat oder nicht.

    Gegeben ist für die Abfrage jeweils der aktuelle Menupunkt ( menu_id)

    derzeitige Tabellen:

    menu
    ========
    menu_id ( Menupunkt )
    parent_id ( übergeordneter Menupunkt, oder 0 wenn ganz oben )
    level ( Baumtiefe )
    sort ( Sortierung bei nebeneinander liegenden Menupunkten )

    menu_menu
    =========
    menu_id ( Menupunkt )
    child_id ( alle untergeordneten Menupunkte )
    TBT

    Die zwei wichtigsten Regeln für eine berufliche Karriere:
    1. Verrate niemals alles was du weißt!


    PHP 2 AllPatrizier II Browsergame

  • #2
    Dh. die Rechte sollen im Baum vererbt werden, bzw. Rechte
    in unteren Zweigen müssen weiter oben gesetzte Rechte
    überschreiben.
    mal 'ne verständnisfrage:


    zB
    admin = rechte 3 = alles
    user = rechte 2 = einiges
    gast = rechte 1 = etwas

    werte in () = rechte des menupunktes

    admin sieht:
    - main (1)
     - sub1 (2)
     - sub2 (2)
       - subsub1 (3)
       - subsub2 (1)
    - main2 (3)
    ...

    user sieht:
    - main (1)
     - sub1 (2)
     - sub2 (2)
    ...

    gast sieht:
    - main (1)
    ...

    soll das so aussehen? ^^

    oder eher so:

    admin sieht:
    - main (1)
     - sub1 (2)
     - sub2 (2)
       - subsub1 (3)
       - subsub2 (1)
    - main2 (3)
    ...

    user sieht:
    - main (1)
     - sub1 (2)
     - sub2 (2)
       - subsub2 (1)
    ...

    gast sieht:
    - main (1)
       - subsub2 (1)
    ...
    Kissolino.com

    Kommentar


    • #3
      eher so:

      - jeder darf erstmal alles sehen
      - bestimmte Menupunkte werden für einzelne User verboten

      also

      User1 - keine Verbote - zB
      Code:
      +- main1
      +- main2
      | +- sub2.1
      | +- sub2.2
      +- main3
        +- sub3.1
        +- sub3.2
          +- sub3.2.1
      	+- sub3.2.2
      für User2 wird dann bestimmt, daß main2 und sub3.2 verboten sind
      Code:
      +- main1
      +- main3
        +- sub3.1
      TBT

      Die zwei wichtigsten Regeln für eine berufliche Karriere:
      1. Verrate niemals alles was du weißt!


      PHP 2 AllPatrizier II Browsergame

      Kommentar


      • #4
        mh... mit nested sets müßtest du sowas darstellen können... lass mal überlegen...

        tab1 (nach nested sets modell)
        id (eindeutige ID)
        ... (restliche felder)

        tab2 (user)
        (was man für user so braucht)
        permID (verknüpfung in eine Jointable)

        tab3 (jointable)
        tab1.id
        tab2.permID
        permission

        ---

        so müßtest du für jeden User eigene Rechte für jeden zweig angeben können... und durch das Nested Sets modell kannst du auch den nächsten übergeordneten finden, oder gesamtübergeordneten für eine kategorie: beispiel:
        2
        2.1
        2.1.1
        die kannst du per abfrage alle referenzieren!

        meintest du sowas ??

        gruss

        EDIT:
        gerade nochmal geändert

        Kommentar


        • #5
          und wieviel SQL Abfragen benötige ich,
          wenn ich mich bei diesem Baum

          Code:
          +- main1
          +- main2
          | +- sub2.1
          | +- sub2.2
          +- main3
            +- sub3.1
            +- sub3.2
              +- sub3.2.1
              +- sub3.2.2
          an der Stelle sub3.2.2 befinde
          um den gesammten Baum korrekt darzustellen ?

          ich will zum Ende eine Abfrage bauen,
          welche mir
          1. den gesammten Baum auspuckt, egal wo ich gerade bin
          2. alle Rechte beachtet

          3. hatte ich vergessen: alle nicht benötigten Zweige, zuklappt
          also bei sub3.2.2 den Unterzweig zu main2 nicht anzeigt



          PS: ich bin glaube ich schon auf der richtigen Spur - ein paar Feinheiten noch, und dann sollte es funktionieren
          TBT

          Die zwei wichtigsten Regeln für eine berufliche Karriere:
          1. Verrate niemals alles was du weißt!


          PHP 2 AllPatrizier II Browsergame

          Kommentar


          • #6
            also für die Darstellung des baumes benötigst du eine abfrage...

            wenn du die mit 2 joines erweiterst dürftest du in einem array alle rechte für den user im jeweiligen baum vorfinden...

            also eine abfrage

            für nested sets:
            eine abfrage mit 2 joines

            +erweiterung um 2 joines für die beiden anderen tabellen (user und die jointable)

            das müßte alles sein!

            gruss

            P.S. falls du was besseres weißt, lass mich nicht dumm sterben...
            ach ja kannst auch mal sagen, ob der ansatz so passend wäre bzw. hilfreich ist!

            Kommentar


            • #7
              so, ich habe jetzt einfach eine Tabelle erzeugt
              wo eingetragen wird, welcher Knoten für welchen User
              verboten ist.
              Die Abfrage zu meiner obigen Struktur heißt dann

              Code:
              SELECT m2.menu_id, m2.level, m2.sort, m2.parent_id, 
                     if(isnull(mu.user_right),0,mu.user_right) + sum(mu2.user_right) my_user_right
              FROM  menus m 
              LEFT JOIN menus_has_menus mm 
                 ON  ( m.menu_id = mm.child_id ) 
              LEFT JOIN menus m2 
                 ON ( mm.menu_id = m2.parent_id )
              LEFT JOIN menus_has_user mu
                 ON ( m2.menu_id = mu.menu_id )
              LEFT JOIN menus_has_menus mm2
                 ON ( m2.menu_id = mm2.child_id )
              LEFT JOIN menus_has_user mu2
                 ON ( mm2.menu_id = mu2.menu_id )
              WHERE m.menu_id = 5 or m.parent_id = 5 
              GROUP BY m2.menu_id, m2.parent_id, m2.level, m2.sort 
              ORDER BY m2.parent_id, m2.level, m2.sort
              und klappt wunderbar.
              das Menu wird wie im Explorer automatisch auf und zu geklappt,
              wenn ich einen anderen Knoten wähle.
              das Recht ergibt -1, wenn der User diesen Knoten nicht sehen darf

              hier ist zB der Knoten 5 verboten, und der Knoten 7 ein Unterknoten von 5
              Code:
              "menu_id";"level";"sort";"parent_id";"my_user_right"
              1;0;1;0;"0"
              2;0;2;0;"0"
              3;0;3;0;"0"
              4;1;1;1;"0"
              5;1;2;1;"-1"
              7;2;1;5;"-1"
              TBT

              Die zwei wichtigsten Regeln für eine berufliche Karriere:
              1. Verrate niemals alles was du weißt!


              PHP 2 AllPatrizier II Browsergame

              Kommentar


              • #8
                mh... auch gut... ich glaub ich muss mir das mal nachher anschauen...

                wie siehts mit performance aus ??

                gruss

                Kommentar


                • #9
                  der DBDesigner brauch inclusive fetchen der Daten 3 ms

                  ich bin noch beim abstrakten Entwurf der Geschichte,
                  noch keine Zeile Code

                  PS: findeste 26 Tabellen für meinen derzeitigen Entwurf eines CMS übertrieben ?
                  Zuletzt geändert von TBT; 06.08.2003, 16:55.
                  TBT

                  Die zwei wichtigsten Regeln für eine berufliche Karriere:
                  1. Verrate niemals alles was du weißt!


                  PHP 2 AllPatrizier II Browsergame

                  Kommentar


                  • #10
                    muss mich nochmal anhängen.

                    stehe bald vor dem selben problem allerdings mit unterschiedlichen userleveln (3-5) ... mein ansatz wäre daher ein vergleich gewesen,
                    dem user alles freizugeben, was <= seinem level entspricht

                    das allerdings verwirrt mich:
                    Code:
                    if(isnull(mu.user_right),0,mu.user_right) + sum(mu2.user_right) my_user_right
                    @TBT
                    was passiert dort?
                    Kissolino.com

                    Kommentar


                    • #11
                      mh... 26 tabellen... kommt auf das CMS drauf an, was alles möglich sein soll/ist... inwieweit was wie konfigurierbar und handhabbar ist...

                      in der Firma wo ich gerade Praktikum mache hat das CMS 51 Tabellen in der momentanen form...

                      3ms ist ordentlich... müßte man jetzt nur wissen, was rauskommt, wenn so ein paar hundert User verwaltet werden!

                      gruss

                      Kommentar


                      • #12
                        @wurzel

                        if(isnull(mu.user_right),0,mu.user_right) => prüft ob das Feld mu.user_right NULL ist, und gibt dann 0 sonst den Inhalt zurück

                        + sum(mu2.user_right) => addiert die Summe alle mu2.user_right Felder dazu

                        my_user_right => weißt den neuen Name my_user_right zu
                        TBT

                        Die zwei wichtigsten Regeln für eine berufliche Karriere:
                        1. Verrate niemals alles was du weißt!


                        PHP 2 AllPatrizier II Browsergame

                        Kommentar


                        • #13
                          verstanden ... aber (ich hab mal die werte eingesetzt) jetzt entspricht "my_user_rights => -2" du verwendest my_user_rights
                          aber nicht weiter im sql-statement.

                          - wie blendest du dann bei der ausgabe die entsprechenden ebenen aus?
                          - warum nicht der vergleich "where ... user_rights = NULL"?
                          - woher weiss die db dass ich nur user bin?
                          - warum bin ich nur so unwissend?
                          Kissolino.com

                          Kommentar


                          • #14
                            Original geschrieben von Wurzel
                            verstanden ... aber (ich hab mal die werte eingesetzt) jetzt entspricht "my_user_rights => -2" du verwendest my_user_rights
                            aber nicht weiter im sql-statement.

                            - wie blendest du dann bei der ausgabe die entsprechenden ebenen aus?
                            - warum nicht der vergleich "where ... user_rights = NULL"?
                            - woher weiss die db dass ich nur user bin?
                            - warum bin ich nur so unwissend?
                            - my_user_rights wird auf PHP Seite weiter verarbeitet
                            - die Ebenen mit my_user_right ungleich 0 werden nicht ausgegeben, alle anderen werden bereits durch die SQL Abfrage erledigt
                            - die user_id wird anderseitig ermittelt, fehlt aber in obiger Abfrage noch
                            - keine Ahnung

                            so, mein kleines Script:

                            angelegt wurden

                            20 Menüs
                            10 Untermenüs
                            5 Unteruntermenus
                            2 Unterunteruntermenüs
                            = 3220 Menupunkte

                            außerdem 3220 User

                            und 3220 Verbote => User 1 darf Knoten 1 nicht, User 2 Knoten 2, ...


                            Laufzeit der SQL Abfrage beträgt unter 10ms
                            PHP-Code:
                            // database connection
                            $DBinfo = array('dev_cms','localhost','*****','*****');

                            // creating database connection
                            include(dirname(__FILE__).'/classes/mysql.class.php');
                            $query = new Query($DBinfo);

                            $site = isset($HTTP_GET_VARS['site'])&&is_numeric($HTTP_GET_VARS['site'])?$HTTP_GET_VARS['site']:0;

                            // getting data for menu => die user_id ist zum testen auf 1 fixiert
                            $result $query->select('
                                                SELECT m2.menu_id, m2.level, m2.sort, m2.parent_id, 
                                                    if(isnull(mu.user_right),0,mu.user_right) + 
                                                    sum(mu2.user_right) my_user_right, d.text
                                                FROM  menus m 
                                                LEFT JOIN menus_has_menus mm 
                                                    ON  ( m.menu_id = mm.child_id ) 
                                                LEFT JOIN menus m2 
                                                    ON ( mm.menu_id = m2.parent_id )
                                                LEFT JOIN menus_has_user mu
                                                    ON ( m2.menu_id = mu.menu_id AND mu.user_id = 1)
                                                LEFT JOIN menus_has_menus mm2
                                                    ON ( m2.menu_id = mm2.child_id )
                                                LEFT JOIN menus_has_user mu2
                                                    ON ( mm2.menu_id = mu2.menu_id AND mu2.user_id = 1)
                                                LEFT JOIN datas d 
                                                    ON ( m2.data_id = d.data_id ) 
                                                WHERE m.menu_id = '
                            .$site.' or m.parent_id = '.$site.
                                                GROUP BY m2.menu_id, m2.parent_id, m2.level, m2.sort 
                                                ORDER BY m2.parent_id, m2.level, m2.sort
                                                    '
                            );
                            $rows $query->rows;

                            function 
                            output(&$result,&$rows,$parent){
                                for(
                            $i=0;$i<$rows;++$i){
                                    if(
                            $result[$i]['parent_id']==$parent&&!$result[$i]['my_user_right']){
                                        echo 
                            str_repeat('&raquo; &raquo; ',$result[$i]['level']).' <a href="index.php?site='.$result[$i]['menu_id'].'">'.$result[$i]['text'].'</a><br>';
                                        
                            output($result,$rows,$result[$i]['menu_id']);
                                    }
                                }
                            }

                            output($result,$rows,0); 
                            zu testen hier http://tbt.dyndns.org/dev_cms/index.php
                            TBT

                            Die zwei wichtigsten Regeln für eine berufliche Karriere:
                            1. Verrate niemals alles was du weißt!


                            PHP 2 AllPatrizier II Browsergame

                            Kommentar


                            • #15
                              sehr geschmeidig ... da reden wir nochmal drüber

                              btw: schön, dass du nicht auf ALLE fragen eine antwort hast
                              Kissolino.com

                              Kommentar

                              Lädt...
                              X