SAFweb2-Release 2.1.17

Das Rechtesystem (Permissions)

Das einfachste, aber noch managebare Rechtesystem enthält für die Anwender Gruppen, denen Rechte (Persmissions) zugeordnet sind. Lässt man die Gruppen weg, müsste für jeden Anwender alle erlaubten Rechte separat zugewiesen werden. Das ist kaum noch zu verwalten. Daher werden die Rechte üblichweise in Gruppen aufgeteilt, und die Anwender werden dann den entsprechenden Gruppen zugewiesen.

Granularität erhöhen

Um die Rechte aber etwas präziser verteilen zu können und die Anzahl der Gruppen auf eine Mindestmass zu reduzieren, kann eine weitere Ebene eingefügt werden. Die Rollen. Diese Rollen entsprechen dann den personellen Funktionen im Unternehmen. Gruppen sind dann die Funktionalen Bereiche (Abteilungen) im Unternehmen.

Schema der Permissions

img.png

Rollen

Die Rollen entsprechen am ehesten den funktionalen Posten von Menschen im Unternehmen. Von der Geschäftsführung, die sicher Einblick in alle relevanten Unternehmenszahlen besitzt, über den Systemadmin, der wahrscheinlich alles sehen können muss, bis hin zur Person an der Rezeption, die nur bestimmte Kontakte sehen muss, sollen alle Rollen im Unternehmen abgebildet werden.

Gruppen

Gruppen dienen in erster Linie dazu, Rechte sinnvoll in Funktionseinheiten zu gruppieren. Man kann Gruppen an den Abteilungen orientieren. Controlling, Einkauf, Verkauf, Produktion und Lager sind typische Kandidaten für bestimmte Kombinationen von Zugriffsrechten.

Zugriffsrechte / Permissions

Zugriffsrechte werden anhand Ihrer Bedeutung vergeben. Es sollte möglich sein, für bestimmte Personengruppen ganz Module unsichtbar zu halten, genauso wie es möglich sein muss, bestimmte Felder in Ansichten zu verbergen oder zu erlauben. Beispielsweise sind Preisinformationen nicht für alle Personen im Unternehmen relevant. Diese Spalte sollte in bestimmten Listen oder Masken für manche Personen ausgeblendet werden können. Das Prinzip gilt für alle anderen Felder ebenso.

Namensgebung

Rechte werden in großem Umfang vergeben, für jedes Modul, für jede Unterfunktion und ggf. für bestimmte Felder in Modulen und Funktionen. Wird hier eine simple Namensgebung verwendet, kann es schnell zu Verwechslungen kommen oder Zweideutigkeiten.
Daher ist es wichtig, auf eine sinnvolle Namensvergabe zu achten, von der man leicht auf die Bedeutung des Zugriffsrechtes schliessen kann.
Damit hier eine gewisse Konsistenz angewendet werden kann, ist ein gewisse Kodierung sinnvoll. Die Bezeichnung des jeweiligen Zugriffsrechtes wird in Segmente unterteilt.

Drei Segmente für eine Hierarchie:
MODUL . BEREICH . SUBFUNKTION . ACTION

MODUL:
Hier gilt entweder der Modulname (neo, mis, admin, …) oder wenn es global ist, das Schlüsselwort global.

BEREICH:
Modulbereich bzw. Hauptfunktionsbereich.

SUBFUNKTION:
Hier kann ein Modulbereich oder eine bestimmte Funktion adressiert werden.

ACTION:
Letztlich wird hier festgelegt, was der User darf, oder nicht darf. Beispielsweise show_price. D.h. Anwender die dieses Recht haben, sehen den Preis, alle anderen nicht.

Beispiele:
mis.vk.rgjournal.hk-preise
mis.ek.bestellungen.preise

Anwenden von Gates

Gates (definieren)

Die einfachste Methode, Berechtigungen zu prüfen, ist das Gate. Gates werden im Provider in der Methode register() definiert.

Gate::define('name_des_gates', function(User $user) {
    return $user->isAdmin; // z.B.
})

Gate:.define('manage-articles', function(User $user, Article $article){
    return Gate::allowes('name_des_gates') || $user->id === $article->author->id;
})

Mit der Definition von Gates werden im Grunde Actions definiert und nach Berechtigung befragt. Das ist sehr kleinteilig. Wenn man in größeren Anwendungen die Berechtigung regeln will, dann ist das über Routes und Roles besser möglich.

Abfragen des Gates

View
@can('name_des_gates')
    {- Code, wenn Gate erlaubt ist -}
@endcan

// mit Daten

@can('name_des_gates', $article)
    {- Code, wenn Gate erlaubt ist -}
@endcan
Controller
...
if (Gate::denies('name_des_gates')) {
    return response('Unauthorized.', 401);
}
...
Route

Route::middleware('can:name_des_gates')->resource('users', UserController::class)->except(['show', 'create', 'store']);

oder

Route::middleware('can:name_des_gates')->group(function(){
    Route::get(...)
});
FormRequest
public function authorize(): bool
{
    // return true;
    $article = $this->route('article');
    return Gate::allows('name_des_gates', $article);
}

Anwenden von Roles

View

In der View kann die Middelware verwendet werden.

@if(Auth::user()->hasAnyRole('dieRolle')
    {- Code, wenn Gate erlaubt ist -}
@endif

Die Middelware muss aber eingerichtet werden. Das passiert in app.php -> ->withMiddleware...

->withMiddelware(function (Middelware $middleware) {
    $middleware->alias([
        'role' => \App\Http\Middleware\RoleAcccessMiddleware::class,
    ]);
})

Verwenden in der Route Definition:

Route::middleware(['role:admin,...'])->group
Custom Directives
AppServiceProvider#register()

Blade::directive('role', function($expression){
    return "<?php if (Auth::user()->hasAnyRole([$expression])): ?>";
})
Blade::directive('endrole', function($expression){
    return "<?php endif; ?>";
})