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.
 
 
 
 
 
 

120 lines
3.9 KiB

<?php
namespace App\Http\Controllers\Api\V1;
use App\Http\Controllers\Api\Concerns\RespondsWithJson;
use App\Http\Controllers\Controller;
use App\Services\AuditLogService;
use App\Services\LdapAuthService;
use App\Services\LdapJwtService;
use App\Services\LdapPasswordResetService;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
class AuthController extends Controller
{
use RespondsWithJson;
public function __construct(
private readonly LdapAuthService $ldapAuth,
private readonly LdapJwtService $ldapJwt,
private readonly AuditLogService $audit,
private readonly LdapPasswordResetService $passwordReset,
) {
}
public function refresh(Request $request): JsonResponse
{
$authHeader = $request->header('Authorization', '');
$jwt = str_starts_with($authHeader, 'Bearer ')
? substr($authHeader, 7)
: '';
if (empty($jwt)) {
return $this->fail('No token provided.', 'missing_token', 401);
}
$payload = $this->ldapJwt->validate($jwt);
if ($payload === null) {
return $this->fail('Token invalid or expired.', 'invalid_token', 401);
}
$newToken = $this->ldapJwt->issue(
$payload['username'],
$payload['is_admin'],
$payload['groups'] ?? []
);
$this->audit->logPublic('api.v1.auth.refresh', $payload['username'], $request, [
'username' => $payload['username'],
]);
return $this->ok([
'access_token' => $newToken,
'token_type' => 'Bearer',
'expires_in' => config('api.ldap_jwt_ttl'),
'auth_type' => 'ldap_jwt',
]);
}
public function login(Request $request): JsonResponse
{
$credentials = $request->validate([
'username' => ['required', 'string', 'max:100'],
'password' => ['required', 'string', 'max:255'],
]);
$user = $this->ldapAuth->attempt($credentials['username'], $credentials['password']);
if ($user === null) {
$this->audit->logPublic('api.v1.auth.login.failed', $credentials['username'], $request, [
'username' => $credentials['username'],
]);
return $this->fail('Invalid LDAP credentials.', 'invalid_credentials', 401);
}
$profile = $this->ldapAuth->lookupUser($user['username']);
$groups = $profile['groups'] ?? [];
$token = $this->ldapJwt->issue($user['username'], $user['is_admin'], $groups);
$this->audit->logPublic('api.v1.auth.login', $user['username'], $request, [
'username' => $user['username'],
'is_admin' => $user['is_admin'],
]);
return $this->ok([
'access_token' => $token,
'token_type' => 'Bearer',
'expires_in' => config('api.ldap_jwt_ttl'),
'auth_type' => 'ldap_jwt',
'user' => [
'username' => $user['username'],
'display_name' => $user['display_name'],
'is_admin' => $user['is_admin'],
],
]);
}
public function apiForgotPassword(Request $request): JsonResponse
{
$data = $request->validate([
'username' => ['required', 'string', 'max:100', 'regex:/^[a-zA-Z0-9._-]+$/'],
]);
try {
$this->passwordReset->sendResetLink($data['username']);
$this->audit->logPublic('api.v1.auth.password.forgot', $data['username'], $request, [
'username' => $data['username'],
'source' => 'api',
]);
} catch (\Throwable) {
// Do not reveal whether user exists or email failed.
}
return $this->ok([
'message' => 'Jika akun ditemukan dan memiliki email terdaftar, link reset password telah dikirim. Link berlaku selama 60 menit.',
]);
}
}