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.
 
 
 
 
 
 

289 lines
9.6 KiB

<?php
namespace App\Http\Controllers\Api\V1;
use App\Http\Controllers\Controller;
use App\Models\ServiceToken;
use App\Services\ServiceTokenService;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Validation\Rule;
/**
* ServiceTokenController - API endpoints for service token management
*
* Provides REST API for CRUD operations on service tokens.
* All endpoints require authentication via LDAP or API token.
*/
class ServiceTokenController extends Controller
{
public function __construct(
private ServiceTokenService $serviceTokenService
) {}
/**
* List all service tokens
*
* GET /api/v1/service-tokens
*/
public function index(): JsonResponse
{
$tokens = $this->serviceTokenService->listAll();
return response()->json([
'data' => array_map(fn ($token) => [
'id' => $token->id,
'name' => $token->name,
'service' => $token->service,
'token_prefix' => $token->token_prefix,
'is_active' => $token->is_active,
'expires_at' => $token->expires_at?->toIso8601String(),
'created_by' => $token->created_by,
'created_at' => $token->created_at->toIso8601String(),
'last_used_at' => $token->last_used_at?->toIso8601String(),
'is_expired' => $token->isExpired(),
], $tokens),
]);
}
/**
* Create a new service token
*
* POST /api/v1/service-tokens
*
* @bodyParam name string required Token name (e.g., "GeoNetAgent-Production")
* @bodyParam service string required Service name (e.g., "GeoNetAgent", "Databaselist")
* @bodyParam expires_in_days int optional Expiration in days (null = never expires)
*/
public function store(Request $request): JsonResponse
{
$validated = $request->validate([
'name' => 'required|string|max:100',
'service' => 'required|string|max:50',
'expires_in_days' => 'nullable|integer|min:1',
]);
$result = $this->serviceTokenService->create(
name: $validated['name'],
service: $validated['service'],
expiresInDays: $validated['expires_in_days'] ?? null
);
return response()->json([
'data' => [
'id' => $result['model']->id,
'name' => $result['model']->name,
'service' => $result['model']->service,
'token_prefix' => $result['model']->token_prefix,
'token' => $result['token'], // Only shown once on creation
'is_active' => $result['model']->is_active,
'expires_at' => $result['model']->expires_at?->toIso8601String(),
'created_by' => $result['model']->created_by,
'created_at' => $result['model']->created_at->toIso8601String(),
],
'message' => 'Service token created successfully. Save the token securely as it will not be shown again.',
], 201);
}
/**
* Get a specific service token
*
* GET /api/v1/service-tokens/{id}
*/
public function show(string $id): JsonResponse
{
$token = $this->serviceTokenService->getById($id);
if (!$token) {
return response()->json([
'error' => [
'code' => 'NOT_FOUND',
'message' => 'Service token not found',
],
], 404);
}
return response()->json([
'data' => [
'id' => $token->id,
'name' => $token->name,
'service' => $token->service,
'token_prefix' => $token->token_prefix,
'is_active' => $token->is_active,
'expires_at' => $token->expires_at?->toIso8601String(),
'created_by' => $token->created_by,
'created_at' => $token->created_at->toIso8601String(),
'last_used_at' => $token->last_used_at?->toIso8601String(),
'is_expired' => $token->isExpired(),
],
]);
}
/**
* Revoke a service token (deactivate)
*
* POST /api/v1/service-tokens/{id}/revoke
*/
public function revoke(string $id): JsonResponse
{
$token = $this->serviceTokenService->getById($id);
if (!$token) {
return response()->json([
'error' => [
'code' => 'NOT_FOUND',
'message' => 'Service token not found',
],
], 404);
}
$this->serviceTokenService->revoke($token);
return response()->json([
'message' => 'Service token revoked successfully',
]);
}
/**
* Regenerate a service token (create new, revoke old)
*
* POST /api/v1/service-tokens/{id}/regenerate
*
* @bodyParam expires_in_days int optional New expiration in days
*/
public function regenerate(Request $request, string $id): JsonResponse
{
$validated = $request->validate([
'expires_in_days' => 'nullable|integer|min:1',
]);
$token = $this->serviceTokenService->getById($id);
if (!$token) {
return response()->json([
'error' => [
'code' => 'NOT_FOUND',
'message' => 'Service token not found',
],
], 404);
}
$result = $this->serviceTokenService->regenerate(
oldToken: $token,
expiresInDays: $validated['expires_in_days'] ?? null
);
return response()->json([
'data' => [
'id' => $result['model']->id,
'name' => $result['model']->name,
'service' => $result['model']->service,
'token_prefix' => $result['model']->token_prefix,
'token' => $result['token'], // Only shown once on regeneration
'is_active' => $result['model']->is_active,
'expires_at' => $result['model']->expires_at?->toIso8601String(),
'created_by' => $result['model']->created_by,
'created_at' => $result['model']->created_at->toIso8601String(),
],
'message' => 'Service token regenerated successfully. Save the new token securely as it will not be shown again.',
]);
}
/**
* Delete a service token permanently
*
* DELETE /api/v1/service-tokens/{id}
*/
public function destroy(string $id): JsonResponse
{
$token = $this->serviceTokenService->getById($id);
if (!$token) {
return response()->json([
'error' => [
'code' => 'NOT_FOUND',
'message' => 'Service token not found',
],
], 404);
}
$this->serviceTokenService->delete($token);
return response()->json([
'message' => 'Service token deleted successfully',
]);
}
/**
* Get tokens by service
*
* GET /api/v1/service-tokens/by-service/{service}
*/
public function getByService(string $service): JsonResponse
{
$tokens = $this->serviceTokenService->getByService($service);
return response()->json([
'data' => array_map(fn ($token) => [
'id' => $token->id,
'name' => $token->name,
'service' => $token->service,
'token_prefix' => $token->token_prefix,
'is_active' => $token->is_active,
'expires_at' => $token->expires_at?->toIso8601String(),
'created_by' => $token->created_by,
'created_at' => $token->created_at->toIso8601String(),
'last_used_at' => $token->last_used_at?->toIso8601String(),
'is_expired' => $token->isExpired(),
], $tokens),
]);
}
/**
* Get active tokens only
*
* GET /api/v1/service-tokens/active
*/
public function getActive(): JsonResponse
{
$tokens = $this->serviceTokenService->getActive();
return response()->json([
'data' => array_map(fn ($token) => [
'id' => $token->id,
'name' => $token->name,
'service' => $token->service,
'token_prefix' => $token->token_prefix,
'is_active' => $token->is_active,
'expires_at' => $token->expires_at?->toIso8601String(),
'created_by' => $token->created_by,
'created_at' => $token->created_at->toIso8601String(),
'last_used_at' => $token->last_used_at?->toIso8601String(),
], $tokens),
]);
}
/**
* Get expired tokens
*
* GET /api/v1/service-tokens/expired
*/
public function getExpired(): JsonResponse
{
$tokens = $this->serviceTokenService->getExpired();
return response()->json([
'data' => array_map(fn ($token) => [
'id' => $token->id,
'name' => $token->name,
'service' => $token->service,
'token_prefix' => $token->token_prefix,
'is_active' => $token->is_active,
'expires_at' => $token->expires_at?->toIso8601String(),
'created_by' => $token->created_by,
'created_at' => $token->created_at->toIso8601String(),
'last_used_at' => $token->last_used_at?->toIso8601String(),
], $tokens),
]);
}
}