| Server IP : 35.80.110.71 / Your IP : 216.73.216.221 Web Server : Apache/2.4.58 (Ubuntu) System : Linux ip-172-31-21-44 6.17.0-1019-aws #19~24.04.1-Ubuntu SMP Tue Jun 23 18:53:06 UTC 2026 x86_64 User : ubuntu ( 1000) PHP Version : 8.3.31 Disable Function : NONE MySQL : OFF | cURL : ON | WGET : ON | Perl : ON | Python : OFF | Sudo : ON | Pkexec : OFF Directory : /var/www/switchyard/releases/20260707190617/app/Models/ |
Upload File : |
<?php
namespace App\Models;
use App\Models\Concerns\BelongsToWorkspace;
use App\Models\Scopes\WorkspaceScope;
use Illuminate\Database\Eloquent\Concerns\HasUlids;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Support\Str;
class ApiKey extends Model
{
use HasUlids, BelongsToWorkspace, HasFactory;
public const SCOPE_READ = 'read';
public const SCOPE_ADMIN_READ = 'admin_read';
public const SCOPE_ADMIN_WRITE = 'admin_write';
public const SCOPES = [
self::SCOPE_READ,
self::SCOPE_ADMIN_READ,
self::SCOPE_ADMIN_WRITE,
];
private const SCOPE_RANK = [
self::SCOPE_READ => 1,
self::SCOPE_ADMIN_READ => 2,
self::SCOPE_ADMIN_WRITE => 3,
];
protected $fillable = [
'workspace_id',
'name',
'prefix',
'key_hash',
'last_four',
'scope',
'ip_allowlist',
'expires_at',
'last_used_at',
'revoked_at',
];
protected function casts(): array
{
return [
'ip_allowlist' => 'array',
'expires_at' => 'datetime',
'last_used_at' => 'datetime',
'revoked_at' => 'datetime',
];
}
public static function generateToken(string $scope = self::SCOPE_READ): array
{
$prefix = 'swy_'.Str::lower(Str::random(8));
$secret = Str::random(40);
$token = "{$prefix}_{$secret}";
return [
'token' => $token,
'prefix' => $prefix,
'key_hash' => hash('sha256', $token),
'last_four' => substr($secret, -4),
'scope' => $scope,
];
}
public static function findByPlaintext(string $token): ?self
{
$hash = hash('sha256', $token);
return self::withoutGlobalScope(WorkspaceScope::class)
->where('key_hash', $hash)
->whereNull('revoked_at')
->first();
}
public function hasScope(string $required): bool
{
$have = self::SCOPE_RANK[$this->scope] ?? 0;
$need = self::SCOPE_RANK[$required] ?? PHP_INT_MAX;
return $have >= $need;
}
public function isExpired(): bool
{
return $this->expires_at !== null && $this->expires_at->isPast();
}
public function ipAllowed(string $ip): bool
{
$allowlist = $this->ip_allowlist ?? [];
if (empty($allowlist)) {
return true;
}
return in_array($ip, $allowlist, true);
}
public function workspace(): BelongsTo
{
return $this->belongsTo(Workspace::class);
}
protected static function booted(): void
{
static::addGlobalScope(new WorkspaceScope);
}
}