GeoNetAgent, LDAPWeb, server-audit, server-connection
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

134 lines
3.5 KiB

<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
/**
* ServiceToken - Bearer token management for microservices
*
* This model manages Bearer tokens for microservices like GeoNetAgent,
* Databaselist, SQLServerCheck, etc. Tokens are stored as SHA256 hashes
* with a prefix for UI display.
*
* Zero impact on existing GeoNetAgent agents (they use separate database).
*/
class ServiceToken extends Model
{
protected $fillable = [
'name',
'service',
'token_prefix',
'token_hash',
'is_active',
'expires_at',
'created_by',
'last_used_at',
];
protected function casts(): array
{
return [
'is_active' => 'boolean',
'expires_at' => 'datetime',
'created_at' => 'datetime',
'last_used_at' => 'datetime',
];
}
/**
* Generate a new service token
*
* @param string $name Token name (e.g., "GeoNetAgent-Production")
* @param string $service Service name (e.g., "GeoNetAgent")
* @param string|null $createdBy User who created the token
* @param int|null $expiresInDays Expiration in days (null = never expires)
* @return array ['token' => string, 'model' => ServiceToken]
*/
public static function generate(
string $name,
string $service,
?string $createdBy = null,
?int $expiresInDays = null
): array {
$token = bin2hex(random_bytes(32)); // 64 chars hex
$tokenPrefix = substr($token, 0, 16);
$tokenHash = hash('sha256', $token);
$expiresAt = $expiresInDays
? now()->addDays($expiresInDays)
: null;
$model = self::create([
'id' => (string) \Illuminate\Support\Str::uuid(),
'name' => $name,
'service' => $service,
'token_prefix' => $tokenPrefix,
'token_hash' => $tokenHash,
'is_active' => true,
'expires_at' => $expiresAt,
'created_by' => $createdBy,
]);
return [
'token' => $token,
'model' => $model,
];
}
/**
* Verify a token against the hash
*
* @param string $token Plain token
* @return ServiceToken|null
*/
public static function verify(string $token): ?self
{
$tokenHash = hash('sha256', $token);
return self::where('token_hash', $tokenHash)
->where('is_active', true)
->where(function ($query) {
$query->whereNull('expires_at')
->orWhere('expires_at', '>', now());
})
->first();
}
/**
* Update last used timestamp
*/
public function touchLastUsed(): void
{
$this->update(['last_used_at' => now()]);
}
/**
* Scope for active tokens
*/
public function scopeActive($query)
{
return $query->where('is_active', true)
->where(function ($query) {
$query->whereNull('expires_at')
->orWhere('expires_at', '>', now());
});
}
/**
* Scope for expired tokens
*/
public function scopeExpired($query)
{
return $query->where('expires_at', '<', now());
}
/**
* Check if token is expired
*/
public function isExpired(): bool
{
return $this->expires_at !== null && $this->expires_at->isPast();
}
}