191 lines
5.0 KiB
PHP
191 lines
5.0 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace App\Models;
|
|
|
|
use Illuminate\Database\Eloquent\Builder;
|
|
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
|
use Illuminate\Database\Eloquent\Model;
|
|
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
|
|
|
class SupportAccessGrant extends Model
|
|
{
|
|
/** @use HasFactory<\Database\Factories\SupportAccessGrantFactory> */
|
|
use HasFactory;
|
|
|
|
public const SCOPE_AUDIT_VIEW = 'audit_view';
|
|
|
|
public const SCOPE_WORKSPACE_RECOVERY = 'workspace_recovery';
|
|
|
|
public const STATUS_REQUESTED = 'requested';
|
|
|
|
public const STATUS_ACTIVE = 'active';
|
|
|
|
public const STATUS_DENIED = 'denied';
|
|
|
|
public const STATUS_EXPIRED = 'expired';
|
|
|
|
public const STATUS_ENDED = 'ended';
|
|
|
|
public const APPROVAL_MODE_AUTO = 'auto';
|
|
|
|
public const APPROVAL_MODE_OWNER_REQUIRED = 'owner_required';
|
|
|
|
public const APPROVAL_MODE_OWNERLESS_WAIVER = 'ownerless_waiver';
|
|
|
|
protected $guarded = [];
|
|
|
|
protected function casts(): array
|
|
{
|
|
return [
|
|
'requested_at' => 'datetime',
|
|
'approved_at' => 'datetime',
|
|
'starts_at' => 'datetime',
|
|
'expires_at' => 'datetime',
|
|
'ended_at' => 'datetime',
|
|
'denied_at' => 'datetime',
|
|
];
|
|
}
|
|
|
|
/**
|
|
* @return BelongsTo<Workspace, $this>
|
|
*/
|
|
public function workspace(): BelongsTo
|
|
{
|
|
return $this->belongsTo(Workspace::class);
|
|
}
|
|
|
|
/**
|
|
* @return BelongsTo<PlatformUser, $this>
|
|
*/
|
|
public function requester(): BelongsTo
|
|
{
|
|
return $this->belongsTo(PlatformUser::class, 'requested_by_platform_user_id');
|
|
}
|
|
|
|
/**
|
|
* @return BelongsTo<User, $this>
|
|
*/
|
|
public function approver(): BelongsTo
|
|
{
|
|
return $this->belongsTo(User::class, 'approved_by_user_id');
|
|
}
|
|
|
|
public function scopeOpen(Builder $query): Builder
|
|
{
|
|
return $query->whereIn('status', [
|
|
self::STATUS_REQUESTED,
|
|
self::STATUS_ACTIVE,
|
|
]);
|
|
}
|
|
|
|
public function isActive(): bool
|
|
{
|
|
return $this->status === self::STATUS_ACTIVE
|
|
&& $this->expires_at !== null
|
|
&& $this->expires_at->isFuture();
|
|
}
|
|
|
|
public function isPending(): bool
|
|
{
|
|
return $this->status === self::STATUS_REQUESTED;
|
|
}
|
|
|
|
public function needsBreakGlass(): bool
|
|
{
|
|
return $this->scope === self::SCOPE_WORKSPACE_RECOVERY;
|
|
}
|
|
|
|
/**
|
|
* @return array<string, string>
|
|
*/
|
|
public static function scopeLabels(): array
|
|
{
|
|
return [
|
|
self::SCOPE_AUDIT_VIEW => 'Audit trail review',
|
|
self::SCOPE_WORKSPACE_RECOVERY => 'Workspace recovery',
|
|
];
|
|
}
|
|
|
|
public static function scopeLabel(string $scope): string
|
|
{
|
|
return self::scopeLabels()[$scope] ?? str($scope)->replace('_', ' ')->title()->toString();
|
|
}
|
|
|
|
/**
|
|
* @return array<string, string>
|
|
*/
|
|
public static function statusLabels(): array
|
|
{
|
|
return [
|
|
self::STATUS_REQUESTED => 'Pending approval',
|
|
self::STATUS_ACTIVE => 'Active',
|
|
self::STATUS_DENIED => 'Denied',
|
|
self::STATUS_EXPIRED => 'Expired',
|
|
self::STATUS_ENDED => 'Ended',
|
|
];
|
|
}
|
|
|
|
public static function statusLabel(string $status): string
|
|
{
|
|
return self::statusLabels()[$status] ?? str($status)->replace('_', ' ')->title()->toString();
|
|
}
|
|
|
|
/**
|
|
* @return array<string, string>
|
|
*/
|
|
public static function approvalModeLabels(): array
|
|
{
|
|
return [
|
|
self::APPROVAL_MODE_AUTO => 'Auto-approved low-risk access',
|
|
self::APPROVAL_MODE_OWNER_REQUIRED => 'Workspace owner approval required',
|
|
self::APPROVAL_MODE_OWNERLESS_WAIVER => 'Ownerless recovery waiver',
|
|
];
|
|
}
|
|
|
|
public static function approvalModeLabel(string $approvalMode): string
|
|
{
|
|
return self::approvalModeLabels()[$approvalMode] ?? str($approvalMode)->replace('_', ' ')->title()->toString();
|
|
}
|
|
|
|
/**
|
|
* @return list<string>
|
|
*/
|
|
public static function scopes(): array
|
|
{
|
|
return [
|
|
self::SCOPE_AUDIT_VIEW,
|
|
self::SCOPE_WORKSPACE_RECOVERY,
|
|
];
|
|
}
|
|
|
|
/**
|
|
* @return list<string>
|
|
*/
|
|
public static function terminalStatuses(): array
|
|
{
|
|
return [
|
|
self::STATUS_DENIED,
|
|
self::STATUS_EXPIRED,
|
|
self::STATUS_ENDED,
|
|
];
|
|
}
|
|
|
|
/**
|
|
* @return list<string>
|
|
*/
|
|
public static function supportAccessAuditActions(): array
|
|
{
|
|
return [
|
|
\App\Support\Audit\AuditActionId::SupportAccessRequested->value,
|
|
\App\Support\Audit\AuditActionId::SupportAccessActivated->value,
|
|
\App\Support\Audit\AuditActionId::SupportAccessApproved->value,
|
|
\App\Support\Audit\AuditActionId::SupportAccessDenied->value,
|
|
\App\Support\Audit\AuditActionId::SupportAccessEnded->value,
|
|
\App\Support\Audit\AuditActionId::SupportAccessExpired->value,
|
|
\App\Support\Audit\AuditActionId::SupportAccessOwnerlessWaiverUsed->value,
|
|
];
|
|
}
|
|
}
|