Ankündigung

Einklappen
Keine Ankündigung bisher.

Problem bei binärem Rechtesystem

Einklappen

Neue Werbung 2019

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

  • Problem bei binärem Rechtesystem

    Hi,

    wie schon im Titel zu lesen ist, habe ich ein Problem mit der Rechteverwaltung.
    Diese wird binär verglichen.

    Bsp.
    Forenadmin: 001 // 1
    Gästebuchverwaltung: 010 // 2
    Benutzerverwaltung: 100 // 4
    ...

    Wenn der Benutzer also Forenadmin ist und auch noch die Benutzer verwalten darf, hat er das Recht 5.

    Ich habe folgende Funktion um anzeigen zu lassen, ob entweder der eingeloggte Benutzer, oder ein mit dem zweiten Parameter übergebener Benutzer ein Recht haben (Parameter 1):

    PHP-Code:
    function getRight($userright$uid NULL) {
        
    $rights_sel mysql_query('SELECT * FROM rights');
        
    $rights = array();
            
        while(
    $rights_fetch mysql_fetch_assoc($rights_sel)) {
            
    $rights[$rights_fetch['name']] = $rights_fetch['bit'];
        }
            
        if(isset(
    $uid)) {
            
    $user_sel mysql_query('SELECT rights FROM accounts WHERE id = "'.$uid.'"');
        } else {
            
    $user_sel mysql_query('SELECT rights FROM accounts WHERE id = "'.$_SESSION['uid'].'"');
        }
            
        
    $user mysql_fetch_assoc($user_sel);

        foreach(
    $rights as $name => $bit) {
            if((
    $user['rights'] & $userright) == $bit) {
                return 
    true;
            }
        }
            
        return 
    false;

    Und meine Datenbankstruktur "rights" sieht so aus:

    Code:
    name    | bit
    Recht 1 | 1
    Recht 2 | 2
    Recht 3 | 4
    Recht 4 | 8
    Recht 5 | 16
    Recht 6 | 32
    Meine Rechte-Abfrage in der Benutzerverwaltung sieht so aus:

    PHP-Code:
    for($i 0$right mysql_fetch_assoc($userrights); $i++) {
        echo 
    '<input type="checkbox" name="rights[]" id="right_'.$i.'" value="'.$right['bit'].'" '.((getRight($right['bit'], $_GET['uid']) ? 'checked="checked"' '').' /><label for="right_'.$i.'"> '.$right['name'].'</label><br />';

    Die uid ist in der URL mitgegeben, und die Benutzerrechte wurden davor schon mit einer SQL-Query ausgelesen.

    Leider werden immer Checkboxen ausgewählt, welche ich nicht nachvollziehen kann...

    Vll. kann mir ja einer von euch sagen, warum meine Funktion nicht funktioniert...

    Ich freue mich über jede Antwort.

    Grüße SilentSight

  • #2
    Hallo,
    theoretisch müsste das funktionieren, praktisch leider nicht. Das liegt daran, dass PHP mit so großen Zahlen nicht mehr rechnen kann. Das ganze funktioniert nur bis 31. Danach gibt PHP auf.
    Wenn du größere zahlen brauchst, musst du es in einzelne Pakete aufteilen. Diese multiplizierst du dann. Bei 32 wäre das also:

    ($userrights & (1 << 31)) * ($userrights & (1 << 1))
    Refining Linux: “[url=http://www.refining-linux.org/archives/65/Performing-push-backups-Part-1-rdiff-backup/]Performing Push Backups – Part 1: rdiff-backup[/url]”

    Kommentar


    • #3
      Ich dachte dass PHP nur ab 32-stelligen Zahlen nicht mehr rechnen kann?
      Ich probier deine Möglichkeit trotzdem mal aus...

      Kommentar


      • #4
        Mag auch sein, dass ich deinen Ansatz falsch verstanden habe.
        PHP macht bis zum Recht 31 mit. Danach nicht mehr.
        Refining Linux: “[url=http://www.refining-linux.org/archives/65/Performing-push-backups-Part-1-rdiff-backup/]Performing Push Backups – Part 1: rdiff-backup[/url]”

        Kommentar


        • #5
          Achso, ich hab ja garnich gesagt, dass ich nur 6 Rechte hab...
          Aber trotzdem gehts nicht...

          Kommentar


          • #6
            Versuche statt

            if(($user['rights'] & $userright) == $bit)

            mal

            if(($user['rights'] & (1 << $userright)) > 0)

            Dann müsste es gehen.
            Refining Linux: “[url=http://www.refining-linux.org/archives/65/Performing-push-backups-Part-1-rdiff-backup/]Performing Push Backups – Part 1: rdiff-backup[/url]”

            Kommentar


            • #7
              Ne geht immernoch nich...
              Jetz sind andere Boxen aktiv...

              Hab echt keine Ahnung was da immer schief läuft

              Kommentar


              • #8
                Ich habe deine Funktion mal auf ein Minimum heruntergebrochen. Das gibt zurück, ob der User das übergeben Recht hat oder nicht:
                PHP-Code:
                function getRight($userright$uid null) {
                    
                $uid $uid ? (int)$uid : (int)$_SESSION['uid'];
                    
                    
                $result mysql_query("SELECT rights FROM accounts WHERE id = $uid");    
                    
                $rights mysql_fetch_object($result)->rights;
                    
                    return ((
                $rights & (<< $userright)) > 0);

                Refining Linux: “[url=http://www.refining-linux.org/archives/65/Performing-push-backups-Part-1-rdiff-backup/]Performing Push Backups – Part 1: rdiff-backup[/url]”

                Kommentar


                • #9
                  Zitat von Manko10 Beitrag anzeigen
                  Das gibt zurück, ob der User das übergeben Recht hat oder nicht:

                  PHP-Code:
                  function getRight($userright$uid null) {
                      
                  $uid $uid ? (int)$uid : (int)$_SESSION['uid'];
                      
                      
                  $result mysql_query("SELECT rights FROM accounts WHERE id = $uid");    
                      
                  $rights mysql_fetch_object($result)->rights;
                      
                      return ((
                  $rights & (<< $userright)) > 0);

                  Dadurch sind trotzdem noch die selben Boxen aktiv
                  Das muss doch irgendwie funktionieren...
                  Google spukt auch nix aus

                  Kommentar


                  • #10
                    Hast du die Rechte denn auch auf die richtige Art und Weise errechnet?
                    Die Syntax zum setzen ist für jedes Recht

                    2^recht * hat_dieses_recht

                    Diese Werte werden addiert. Also z.B.

                    2^1 * 1 = 1
                    2^2 * 1 = 4
                    2^3 * 0 = 0
                    2^4 * 1 = 16
                    2^5 * 0 = 0
                    2^6 * 1 = 64
                    ----------------
                    Summe: 85

                    Die Summe repräsentiert die Rechte.

                    Und beachte auch, dass in PHP zum potenzieren nicht der Operator ^ verwendet wird (der steht nämlich für das bitweise XOR). Um in PHP Zahlen zu potenzieren, ist die Funktion pow($basis, $expontent) da.
                    Refining Linux: “[url=http://www.refining-linux.org/archives/65/Performing-push-backups-Part-1-rdiff-backup/]Performing Push Backups – Part 1: rdiff-backup[/url]”

                    Kommentar


                    • #11
                      Ist es nicht eigentlich so:

                      2^0 * 1 = 1
                      2^1 * 1 = 2
                      2^2 * 0 = 0
                      2^3 * 1 = 8
                      2^4 * 0 = 0
                      2^5 * 1 = 32

                      ??


                      So hab ich des zumindest gemacht.

                      Kommentar


                      • #12
                        Das kommt ganz auf die Rechte an. Wenn die einzelnen Rechte bei dir von 0 bis 5 gehen, musst du es so machen. Wenn sie von 1 bis 6 gehen, so, wie ich es gemacht habe.
                        Im übrigen kannst du die Rechte, die nicht gesetzt sind, auch komplett weglassen.

                        In deinem Falle also

                        2^0 = 1
                        2^1 = 2
                        2^3 = 8
                        2^5 = 32

                        Die Summe dessen ist der Rechte-Code.
                        Un bedenke: in PHP heißt es nicht
                        PHP-Code:
                        $recht += 2^1
                        sondern
                        PHP-Code:
                        $recht += pow(21); 
                        Refining Linux: “[url=http://www.refining-linux.org/archives/65/Performing-push-backups-Part-1-rdiff-backup/]Performing Push Backups – Part 1: rdiff-backup[/url]”

                        Kommentar


                        • #13
                          Ja so hab ich es ja gemacht...
                          Es funktioniert ja auch, bis auf die Recheverwaltung in der immer Boxen gecheckt werden, welche ich nicht nachvollziehen kann...

                          PHP-Code:
                          <form method="post" action="<?php echo this(); ?>">
                              <?php
                                  
                          for($i 0$right $userrights->fetch(); $i++) {
                                      echo 
                          '<input type="checkbox" name="rights[]" id="right_'.$i.'" value="'.$right['bit'].'" '.(getRight($right['bit'], $_GET['uid']) ? 'checked="checked"' '').' /><label for="right_'.$i.'"> '.$right['name'].'</label><br />';
                                  }
                              
                          ?>
                              
                              <input type="submit" name="saveButton" value="Speichern" />
                          </form>
                          Und nach einem klick auf "Speichern":

                          PHP-Code:
                          $userrights 0;
                                              
                          foreach(
                          $_POST['rights'] as $right) {
                              
                          $userrights += $right;
                          }
                                              
                          $update = new sqlQuery('UPDATE accounts SET rights = "'.$userrights.'" WHERE id = "'.$_GET['uid'].'"');
                                              
                          if(
                          $update->error()) {
                              
                          $update->getError();
                          } else {
                              echo 
                          'OK';

                          Was die sqlQuery-Klasse macht ist hoffe ich, selbsterklärend.

                          Kommentar


                          • #14
                            PHP-Code:
                            foreach($_POST['rights'] as $right) {
                                
                            $userrights += $right;

                            sollte das nicht eher
                            PHP-Code:
                            foreach($_POST['rights'] as $right) {
                                
                            $userrights += pow(2$right);

                            heißen?
                            Refining Linux: “[url=http://www.refining-linux.org/archives/65/Performing-push-backups-Part-1-rdiff-backup/]Performing Push Backups – Part 1: rdiff-backup[/url]”

                            Kommentar


                            • #15
                              Code:
                              
                              name="rights[]" value="'.$right['bit'].'"
                              
                              SQL-Tabelle:
                              Code:
                              bit
                              1
                              2
                              4
                              8
                              16
                              32
                              Das is schon richtig.

                              Es geht ja auch um die Ausgabe.
                              Die Rechte werden richtig eingetragen, aber nicht richtig ausgelesen.
                              Oder in der Funktion getRight() stimmt was nich.

                              Die Problemzone:
                              PHP-Code:
                              echo '<input type="checkbox" name="rights[]" id="right_'.$i.'" value="'.$right['bit'].'" '.(getRight($right['bit'], $_GET['uid']) ? 'checked="checked"' '').' /><label for="right_'.$i.'"> '.$right['name'].'</label><br />'

                              Kommentar

                              Lädt...
                              X