132 lines
3.4 KiB
PHP
132 lines
3.4 KiB
PHP
<?php
|
|
|
|
namespace App\Services;
|
|
|
|
use App\Models\PersonalAccessToken;
|
|
use Modules\Auth\Entities\User;
|
|
use Modules\Role\Entities\Role;
|
|
|
|
class ActiveRoleService
|
|
{
|
|
public static function resolveDefaultRole(User $user): ?Role
|
|
{
|
|
$roles = $user->roles;
|
|
|
|
if ($roles->isEmpty()) {
|
|
return null;
|
|
}
|
|
|
|
if ($roles->count() === 1) {
|
|
return $roles->first();
|
|
}
|
|
|
|
if (config('active_role.prefer_member_on_login', true)) {
|
|
$memberRole = $roles->first(fn (Role $role) => self::roleContext($role) === 'member');
|
|
|
|
if ($memberRole) {
|
|
return $memberRole;
|
|
}
|
|
}
|
|
|
|
return $roles->first();
|
|
}
|
|
|
|
public static function assignToCurrentToken(User $user, Role $role): void
|
|
{
|
|
$token = $user->currentAccessToken();
|
|
|
|
if ($token instanceof PersonalAccessToken) {
|
|
$token->forceFill(['active_role_id' => $role->id])->save();
|
|
}
|
|
}
|
|
|
|
public static function assignDefaultToToken(User $user, PersonalAccessToken $accessToken): void
|
|
{
|
|
$user->loadMissing('roles');
|
|
|
|
$role = self::resolveDefaultRole($user);
|
|
|
|
if ($role) {
|
|
$accessToken->forceFill(['active_role_id' => $role->id])->save();
|
|
}
|
|
}
|
|
|
|
public static function getActiveRole(User $user): ?Role
|
|
{
|
|
$user->loadMissing(['roles.permissions']);
|
|
|
|
$token = $user->currentAccessToken();
|
|
|
|
if ($token instanceof PersonalAccessToken && $token->active_role_id) {
|
|
$role = $user->roles->firstWhere('id', $token->active_role_id);
|
|
|
|
if ($role) {
|
|
return $role;
|
|
}
|
|
}
|
|
|
|
return self::resolveDefaultRole($user);
|
|
}
|
|
|
|
public static function switchRole(User $user, string $roleId): ?Role
|
|
{
|
|
$role = $user->roles()->where('roles.id', $roleId)->first();
|
|
|
|
if (! $role) {
|
|
return null;
|
|
}
|
|
|
|
self::assignToCurrentToken($user, $role);
|
|
|
|
return $role->load('permissions');
|
|
}
|
|
|
|
public static function roleContext(Role $role): string
|
|
{
|
|
$context = $role->context ?? 'member';
|
|
|
|
return in_array($context, ['admin', 'member'], true) ? $context : 'member';
|
|
}
|
|
|
|
public static function redirectPathForRole(Role $role): string
|
|
{
|
|
return self::roleContext($role) === 'admin'
|
|
? config('active_role.admin_redirect', '/profile')
|
|
: config('active_role.member_redirect', '/profile');
|
|
}
|
|
|
|
/**
|
|
* @return array<string, mixed>|null
|
|
*/
|
|
public static function formatRole(?Role $role): ?array
|
|
{
|
|
if (! $role) {
|
|
return null;
|
|
}
|
|
|
|
return [
|
|
'id' => $role->id,
|
|
'name' => $role->name,
|
|
'fullname' => $role->fullname ?? null,
|
|
'guard_name' => $role->guard_name,
|
|
'context' => self::roleContext($role),
|
|
];
|
|
}
|
|
|
|
/**
|
|
* @return array<string, mixed>
|
|
*/
|
|
public static function sessionMeta(User $user): array
|
|
{
|
|
$activeRole = self::getActiveRole($user);
|
|
|
|
return [
|
|
'active_role' => self::formatRole($activeRole),
|
|
'can_switch_role' => $user->roles->count() > 1,
|
|
'redirect_path' => $activeRole
|
|
? self::redirectPathForRole($activeRole)
|
|
: config('active_role.member_redirect', '/profile'),
|
|
];
|
|
}
|
|
}
|