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.
 
 
 
 
 
 

228 lines
6.0 KiB

<?php
namespace App\Services;
use App\Models\ServiceToken;
use App\Services\AuditLogService;
use Illuminate\Support\Facades\Auth;
/**
* ServiceTokenService - Manage microservice Bearer tokens
*
* Provides CRUD operations for service tokens with audit logging.
* Zero impact on existing GeoNetAgent agents (separate database).
*/
class ServiceTokenService
{
public function __construct(
private AuditLogService $auditLogService
) {}
/**
* Create a new service token
*
* @param string $name Token name (e.g., "GeoNetAgent-Production")
* @param string $service Service name (e.g., "GeoNetAgent", "Databaselist")
* @param int|null $expiresInDays Expiration in days (null = never expires)
* @return array{token: string, model: ServiceToken}
*/
public function create(string $name, string $service, ?int $expiresInDays = null): array
{
$createdBy = Auth::check() ? Auth::user()->username : 'system';
$result = ServiceToken::generate(
name: $name,
service: $service,
createdBy: $createdBy,
expiresInDays: $expiresInDays
);
// Audit log
$this->auditLogService->log(
action: 'service_token_created',
entityType: 'ServiceToken',
entityId: $result['model']->id,
details: [
'name' => $name,
'service' => $service,
'token_prefix' => $result['model']->token_prefix,
'expires_at' => $result['model']->expires_at?->toIso8601String(),
],
userId: $createdBy
);
return $result;
}
/**
* List all service tokens (without plain tokens)
*
* @return array<ServiceToken>
*/
public function listAll(): array
{
return ServiceToken::orderByDesc('created_at')->get()->all();
}
/**
* Get a specific service token by ID
*/
public function getById(string $id): ?ServiceToken
{
return ServiceToken::find($id);
}
/**
* Revoke (deactivate) a service token
*/
public function revoke(ServiceToken $token): void
{
$token->update(['is_active' => false]);
$createdBy = Auth::check() ? Auth::user()->username : 'system';
$this->auditLogService->log(
action: 'service_token_revoked',
entityType: 'ServiceToken',
entityId: $token->id,
details: [
'name' => $token->name,
'service' => $token->service,
'token_prefix' => $token->token_prefix,
],
userId: $createdBy
);
}
/**
* Permanently delete a service token
*/
public function delete(ServiceToken $token): void
{
$tokenId = $token->id;
$tokenName = $token->name;
$tokenService = $token->service;
$tokenPrefix = $token->token_prefix;
$token->delete();
$createdBy = Auth::check() ? Auth::user()->username : 'system';
$this->auditLogService->log(
action: 'service_token_deleted',
entityType: 'ServiceToken',
entityId: $tokenId,
details: [
'name' => $tokenName,
'service' => $tokenService,
'token_prefix' => $tokenPrefix,
],
userId: $createdBy
);
}
/**
* Regenerate a service token (create new, revoke old)
*
* @return array{token: string, model: ServiceToken}
*/
public function regenerate(ServiceToken $oldToken, ?int $expiresInDays = null): array
{
// Revoke old token
$this->revoke($oldToken);
// Create new token with same name and service
return $this->create(
name: $oldToken->name,
service: $oldToken->service,
expiresInDays: $expiresInDays
);
}
/**
* Verify a token (for external validation, not used in UI)
*
* @param string $plainToken Plain token to verify
* @return ServiceToken|null
*/
public function verify(string $plainToken): ?ServiceToken
{
$token = ServiceToken::verify($plainToken);
if ($token) {
$token->touchLastUsed();
}
return $token;
}
/**
* Get tokens by service
*
* @param string $service Service name
* @return array<ServiceToken>
*/
public function getByService(string $service): array
{
return ServiceToken::where('service', $service)
->orderByDesc('created_at')
->get()
->all();
}
/**
* Get active tokens only
*
* @return array<ServiceToken>
*/
public function getActive(): array
{
return ServiceToken::active()
->orderByDesc('created_at')
->get()
->all();
}
/**
* Get expired tokens
*
* @return array<ServiceToken>
*/
public function getExpired(): array
{
return ServiceToken::expired()
->orderByDesc('expires_at')
->get()
->all();
}
/**
* Clean up expired tokens (optional maintenance task)
*
* @param int $olderThanDays Delete tokens expired more than X days ago
* @return int Number of deleted tokens
*/
public function cleanupExpired(int $olderThanDays = 30): int
{
$cutoffDate = now()->subDays($olderThanDays);
$deleted = ServiceToken::expired()
->where('expires_at', '<', $cutoffDate)
->delete();
if ($deleted > 0) {
$this->auditLogService->log(
action: 'service_tokens_cleanup',
entityType: 'ServiceToken',
entityId: null,
details: [
'deleted_count' => $deleted,
'older_than_days' => $olderThanDays,
],
userId: 'system'
);
}
return $deleted;
}
}