Skip to content

Authorization

Introduction

Qore.works Business comes default with roles (Admin and Super Admin) and permissions. The default roles and permissions are build on top of the Spatie package.

The admin users that have access to the backoffice are separated into the qore_users table. Also those are separated with a different Guard with value qore. The platform users kept to default, table users and Guard with value web.

Usage for backoffice users

For authorization, Filament will observe any model policies that are registered in your app. For more information you can visit the Filament authorization page.

Policies auto resolve

The policy for the specific model you need to place inside the Admin folder. For example:

txt
- app
    - Application
        - Admin
            - Policies
                - FaqPolicy.php
        - Models
            - Faq
                - Faq.php

When extending models, for example the Local company inside the Development application. You should add the existing policy to your application but you can extend from the origin:

php
namespace App\Application\Admin\Policies;

use QoreWorksBusiness\QoreRelation\Policies\CompanyPolicy as QoreCompanyPolicy;

class CompanyPolicy extends QoreCompanyPolicy
{
}

Protecting widgets

To protect the widgets you can implement a trait from the base. This will protect the widget with the canView method.

php
use QoreWorksBusiness\QoreAdminBase\Concerns\AuthorizesWidgetAccess;

class WidgetName extends BaseWidget
{
    use AuthorizesWidgetAccess;
}

You can either define the permission to check with $permission.

php
protected static UnitEnum $permission = CompanyPermission::VIEW;

Or you can define the model what is checking the policy on the view ability.

php
protected static ?string $model = Company::class;

Super admin

In the QoreAdminBaseServiceProvider the policies check are skipped for this role. Therefore, the super-admin role doesn't have any permissions attached.

Usage for platform users

Every model can be attached to the user model. For example; a relation can have a user for authentication. On your relation model you can include the HasUser trait.

Model has one user

  1. Add the trait on model
php
use QoreWorksBusiness\QoreAdminBase\Concerns\HasUser;

class Relation extends Model
{
    use HasUser;
}
  1. Add the reverse relation on the User model
php
use Illuminate\Database\Eloquent\Relations\HasOneThrough;
use QoreWorksBusiness\QoreAdminBase\Models\ModelHasUsers;

class User extends Authenticatable
{
    public function relation(): HasOneThrough
    {
        return $this->hasOneThrough(
            Relation::class,
            ModelHasUsers::class,
            'user_id',
            'id',
            'id',
            'model_id',
        )->where('model_type', '=', (new Relation())->getMorphClass());
    }
}
  1. Add 'make platform user' button to your edit page for example. Button is only visible when no user is attached.
php
use QoreWorksBusiness\QoreAdminBase\Resources\UserResource\Actions\CreateUserAction;

class EditRelation extends EditRecord
{
    protected static string $resource = RelationResource::class;

    protected function getHeaderActions(): array
    {
        return [
            CreateUserAction::make(),
        ];
    }
}
  1. Listening to the event

After creating a user, an event UserCreated is dispatched. You can listen to this event to perform some additional actions. For example; send a verification mail or adding some roles.

Password reset broker

The qore password broker (used for the admin Filament panel) is registered automatically by QoreAdminBaseServiceProvider. Both the token lifetime and the throttle between reset requests are configurable through config/qore.php:

php
// config/qore.php
'password_reset' => [
    'expire' => (int) env('QORE_PASSWORD_RESET_EXPIRE', 60),
    'throttle' => (int) env('QORE_PASSWORD_RESET_THROTTLE', 60),
],
KeyUnitDefaultPurpose
expireminutes60Lifetime of the reset token row in qore_password_resets. Once exceeded, the link returns "This password reset token is invalid.".
throttleseconds60Minimum wait between two reset requests for the same email address.

Override via environment in .env:

dotenv
QORE_PASSWORD_RESET_EXPIRE=120
QORE_PASSWORD_RESET_THROTTLE=30

After changing the values, clear the cached config:

bash
php artisan config:clear

Filament builds the reset URL with URL::signedRoute (no signature expiry), so the link lifetime is fully controlled by the expire value above.

Middlewares

To make use of the Spatie Laravel permissions middlewares, register them in bootstrap/app.php:

php
->withMiddleware(function (Middleware $middleware) {
    $middleware->alias([
        'permission' => \Spatie\Permission\Middleware\PermissionMiddleware::class,
        'role' => \Spatie\Permission\Middleware\RoleMiddleware::class,
        'role_or_permission' => \Spatie\Permission\Middleware\RoleOrPermissionMiddleware::class,
    ]);
})

After that you can make use of the middleware:

php
Route::group(['middleware' => ['role:relation']], function () {
    //
});

For more information see the documentation of Spatie Laravel permissions.

Permissions

Make sure you also create a default set of permissions for you package if it's needed to be controlled in the backoffice. You can easily create the permissions with actions on your migration. For example:

php
use QoreWorksBusiness\QoreAdminBase\Actions\CreatePermissionsAction;
use QoreWorksBusiness\QoreAdminBase\Actions\RevokePermissionsAction;
use QoreWorksBusiness\QoreAdminBase\Enums\AssetPermission;

return new class() extends Migration
{
    protected static array $permissions = [
        AssetPermission::VIEW,
        AssetPermission::EDIT,
        AssetPermission::DELETE,
    ];

    public function up(): void
    {
        ...

        CreatePermissionsAction::run(self::$permissions);
    }

    public function down(): void
    {
        ...

        RevokePermissionsAction::run(self::$permissions);
    }
};