Browse Source
- Add AgentTokenSyncService: push create/revoke/delete to geonetagent_dev.agent_tokens - Update ServiceTokenService: inject AgentTokenSyncService, sync on create/revoke/delete - Add database connection 'geonetagent' to config/database.php - Add GEONETAGENT_DB_* env vars to .env.example (username kosong = sync disabled) - Update context-index.md: document sync architecture and flow - Grant DELETE on agent_tokens to geonet_portal (applied on 10.100.1.25) - Set geonet_portal password on DB server (stored in server .env only) Alur: UI Create Token -> INSERT service_tokens (audit) + INSERT agent_tokens (validasi collector) Fallback: jika GEONETAGENT_DB_USERNAME kosong, sync di-skip, geonet-console tetap jalan normal.master
5 changed files with 188 additions and 5 deletions
@ -0,0 +1,120 @@ |
|||||||
|
<?php |
||||||
|
|
||||||
|
namespace App\Services; |
||||||
|
|
||||||
|
use Illuminate\Support\Facades\DB; |
||||||
|
use Illuminate\Support\Facades\Log; |
||||||
|
|
||||||
|
/** |
||||||
|
* AgentTokenSyncService |
||||||
|
* |
||||||
|
* Sinkronisasi token ke geonetagent.agent_tokens agar geonet-console |
||||||
|
* menjadi single point of control untuk microservice Bearer tokens. |
||||||
|
* |
||||||
|
* geonetagent DB connection: config/database.php -> 'geonetagent' |
||||||
|
* Env vars: GEONETAGENT_DB_HOST, GEONETAGENT_DB_DATABASE, GEONETAGENT_DB_USERNAME, GEONETAGENT_DB_PASSWORD |
||||||
|
* |
||||||
|
* Jika koneksi tidak tersedia (env kosong), sync di-skip dengan warning log |
||||||
|
* sehingga geonet-console tetap berjalan normal. |
||||||
|
*/ |
||||||
|
class AgentTokenSyncService |
||||||
|
{ |
||||||
|
private bool $enabled; |
||||||
|
|
||||||
|
public function __construct() |
||||||
|
{ |
||||||
|
$this->enabled = !empty(env('GEONETAGENT_DB_USERNAME')); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Tambah token ke geonetagent.agent_tokens |
||||||
|
* |
||||||
|
* @param string $name Token name (e.g. "GeoNetAgent-Production") |
||||||
|
* @param string $tokenHash SHA256 hash dari plain token |
||||||
|
* @return bool true jika berhasil, false jika skip/gagal |
||||||
|
*/ |
||||||
|
public function addToken(string $name, string $tokenHash): bool |
||||||
|
{ |
||||||
|
if (!$this->enabled) { |
||||||
|
Log::warning('AgentTokenSyncService: GEONETAGENT_DB_USERNAME tidak di-set, sync di-skip.'); |
||||||
|
return false; |
||||||
|
} |
||||||
|
|
||||||
|
try { |
||||||
|
DB::connection('geonetagent')->table('agent_tokens')->insert([ |
||||||
|
'id' => (string) \Illuminate\Support\Str::uuid(), |
||||||
|
'name' => $name, |
||||||
|
'token_hash' => $tokenHash, |
||||||
|
'is_active' => true, |
||||||
|
'created_at' => now(), |
||||||
|
'last_used_at' => null, |
||||||
|
]); |
||||||
|
return true; |
||||||
|
} catch (\Throwable $e) { |
||||||
|
Log::error('AgentTokenSyncService: gagal insert ke agent_tokens', [ |
||||||
|
'error' => $e->getMessage(), |
||||||
|
'name' => $name, |
||||||
|
]); |
||||||
|
return false; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Revoke token di geonetagent.agent_tokens berdasarkan hash |
||||||
|
* |
||||||
|
* @param string $tokenHash SHA256 hash dari plain token |
||||||
|
* @return bool |
||||||
|
*/ |
||||||
|
public function revokeToken(string $tokenHash): bool |
||||||
|
{ |
||||||
|
if (!$this->enabled) { |
||||||
|
Log::warning('AgentTokenSyncService: GEONETAGENT_DB_USERNAME tidak di-set, revoke sync di-skip.'); |
||||||
|
return false; |
||||||
|
} |
||||||
|
|
||||||
|
try { |
||||||
|
DB::connection('geonetagent')->table('agent_tokens') |
||||||
|
->where('token_hash', $tokenHash) |
||||||
|
->update(['is_active' => false]); |
||||||
|
return true; |
||||||
|
} catch (\Throwable $e) { |
||||||
|
Log::error('AgentTokenSyncService: gagal revoke di agent_tokens', [ |
||||||
|
'error' => $e->getMessage(), |
||||||
|
]); |
||||||
|
return false; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Hapus token dari geonetagent.agent_tokens berdasarkan hash |
||||||
|
* |
||||||
|
* @param string $tokenHash |
||||||
|
* @return bool |
||||||
|
*/ |
||||||
|
public function deleteToken(string $tokenHash): bool |
||||||
|
{ |
||||||
|
if (!$this->enabled) { |
||||||
|
return false; |
||||||
|
} |
||||||
|
|
||||||
|
try { |
||||||
|
DB::connection('geonetagent')->table('agent_tokens') |
||||||
|
->where('token_hash', $tokenHash) |
||||||
|
->delete(); |
||||||
|
return true; |
||||||
|
} catch (\Throwable $e) { |
||||||
|
Log::error('AgentTokenSyncService: gagal delete di agent_tokens', [ |
||||||
|
'error' => $e->getMessage(), |
||||||
|
]); |
||||||
|
return false; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Cek apakah sinkronisasi aktif (env terkonfigurasi) |
||||||
|
*/ |
||||||
|
public function isEnabled(): bool |
||||||
|
{ |
||||||
|
return $this->enabled; |
||||||
|
} |
||||||
|
} |
||||||
Loading…
Reference in new issue