Laravel, Groups und Berechtigungen

Werner S

Mitglied
Grüße,

nach dem man mir hier gut geholfen hat, ein großes Danke an @JR Cologne , habe ich noch eine weitere Frage.

Aus einem bestehenden System ohne Framework oder der gleichen möchte ich das Berechtigungssystem das in meinen Augen recht Simple System übernehmen.
In der Usertabelle wird eine neue Spalte angelegt mit der Gruppen ID "user_perm_grp". Die Gruppentabelle wird angelegt mit Spalten alla "project_add", "show_event" etc.

Tabellen
PHP:
Schema::table('users', function (Blueprint $table) {
            $table->integer('user_perm_grp')->nullable()->unsigned()->after('password');
            $table->foreign('user_perm_grp')->references('id')->on('groups')->onDelete('cascade');
        });

Schema::create('groups', function (Blueprint $table) {
            $table->increments('id');
            $table->string('auth_name');
            $table->tinyInteger('user_add')->default(0);
            $table->tinyInteger('show_event')->default(0);
            $table->tinyInteger('project_add')->default(0);
            $table->timestamps();
        });


PHP:
//model/Group.php
public function user()
    {
        return $this->belongsToMany(User::class, 'user_perm_grp', 'id');
    }

//model/User.php
public function group() {
        return $this->hasOne(Group::class, 'user_perm_grp', 'id');

    }

Jeder User kann nur einer Gruppe zugehören.
Nehmen wir den ProjectController.php. Hier soll überprüft werden ob der User zu der Gruppe gehört die die entsprechenden Berechtigungen besitzt.
Dazu befinden sich die Abfrage im ProjectController.php index()

PHP:
/**
     * Display a listing of the resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function index()
    {
        // GruppenID aus der Usertabelle laden
        $user_auth = Auth::user()->user_perm_grp;

        // Gruppe anhand der ID Lesen
        $acl = Group::find($user_auth); // Gruppen Infos
        
        /*
         * Gibt der Wert project_add aus der group Tabelle
         * kein true (1) zurück, gibt es ein 403er
         * Wurde anhand der GruppenID nix gefunden,
         * gibt es auch ein 403er
         */
        if(is_null($acl) or !$acl->project_add) {
            return view('access');
            exit;
        }

        return view('project.index');
    }

Das ganze funktioniert 1A. Da ich aber nicht in jedem Controller in jeder public function die ganzen 6 Zeilen (reiner Code) einfügen will, möchte ich die abfrage gerne in die GroupController.php auslagern.

Dazu habe ich mir in der GroupController.php eine neue public function angelegt

PHP:
/**
     * Display a listing of the resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function access_check()
    {


    }

und würde gerne im ProjectController.php mit sowas Arbeiten Group::access_check(Auth::user()->user_perm_grp, 'project_add'); Erster Wert ist die GruppenID aus der Usertabelle, 2 Wert ist die Spalte aus der Group Tabelle. Hat die Spalte die 1, passiert gar nichts, hat die Spalte den Wert 0 soll die view('access') aufgerufen werden.

Ich weiss das es nicht die beste Lösung ist, möchte aber erst mal darauf bauen da mein Wissen bezüglich Laravel noch recht klein ist und ich so besser in die Materie einsteigen kann. Was ich dazu finden konnte ist leider alles in Englisch in dieser Sprache bin ich nicht leider so mächtig.
 

JR Cologne

Administrator
Teammitglied
Sorry, ich hoffe, ich bin nicht zu spät dran...

Das ganze funktioniert 1A. Da ich aber nicht in jedem Controller in jeder public function die ganzen 6 Zeilen (reiner Code) einfügen will, möchte ich die abfrage gerne in die GroupController.php auslagern.

Dazu habe ich mir in der GroupController.php eine neue public function angelegt

Eine Auslagerung in einen Controller ergibt eigentlich nie Sinn.
Ein Controller ist dafür da, für bestimmte Routen gewünschte Funktionen auszuführen bzw. Views zu rendern.
Der Controller wird dabei niemals aus anderen Controllern aufgerufen, sondern immer nur durch das Routing.

Wenn du eine Methode á la Group::access_check(Auth::user()->user_perm_grp, 'project_add'); konstruieren möchtest, sollte schon anhand des Aufrufs ersichtlich sein, dass du eigentlich das Group-Model meinst bzw. dort deine Methode zu implementieren ist.

Mein Vorschlag wäre entsprechend, im Modal eine Methode zu implementieren, die die Gruppe heraussucht und anschließend überprüft, ob der übergebene String (z.B. "project_add") als Permission-Property für die Gruppe existiert und bei der jeweiligen Gruppe truthy/aktiviert ist oder nicht.
Die Entscheidung, welche View gerendert wird, sollte dann aber dem Controller überlassen sein.

PHP:
// model/Group.php
public function access_check(int $groupId, string $permission): bool
{
    $acl = self::find($groupId);

    if (is_null($acl)) {
        return false;
    }
 
    if (!isset($acl->{$permission}) || !$acl->{$permission}) {
       return false;
    }

    return true;
}

// ProjectController.php
public function index()
{
   /*
    * Gibt der Wert project_add aus der group Tabelle
    * kein true (1) zurück, gibt es ein 403er
    * Wurde anhand der GruppenID nix gefunden,
    * gibt es auch ein 403er
    */
    if(!Group::access_check(Auth::user()->user_perm_grp, 'project_add')) {
        return view('access');
        exit;
    }

    return view('project.index');
}
 
Oben Unten