<?php
declare(strict_types=1);
namespace SHServ\Integrations\GAuth;
use GNexus\GAuth\DTO\AuthenticatedUser;
use GNexus\GAuth\DTO\ClientAccess;
final class UserResolver
{
/**
* Upsert user from AuthenticatedUser DTO into shserv_users.
* Returns local user ID.
*/
public function resolve(AuthenticatedUser $user): int
{
$tb = app()->thin_builder;
// Find existing by gauth_user_id
$existing = $tb->select('shserv_users', ['id'], [['gauth_user_id', '=', $user->userId]]);
// Extract client access for this Client
$clientAccess = $this->findClientAccess($user);
$systemRole = $user->systemRole ?? 'user';
$status = $user->status ?? 'active';
$displayName = $user->profile['display_name'] ?? ($user->profile['username'] ?? $user->email);
$avatarUrl = $user->avatarUrl();
$data = [
'email' => $user->email,
'display_name' => $displayName,
'avatar_url' => $avatarUrl,
'system_role' => $systemRole,
'status' => $status,
];
if ($existing) {
$userId = (int) $existing[0]['id'];
$tb->update('shserv_users', $data, [['id', '=', $userId]]);
// Sync permissions from client access
$this->syncPermissions($userId, $clientAccess);
return $userId;
}
$data['gauth_user_id'] = $user->userId;
$data['created_at'] = date('Y-m-d H:i:s');
$tb->insert('shserv_users', $data);
$userId = (int) $tb->getLastInsertedId();
$this->syncPermissions($userId, $clientAccess);
return $userId;
}
private function findClientAccess(AuthenticatedUser $user): ?ClientAccess
{
$clientId = FCONF['gauth']['client_id'] ?? '';
foreach ($user->clientAccessList as $access) {
if ($access->clientId === $clientId) {
return $access;
}
}
return null;
}
private function syncPermissions(int $userId, ?ClientAccess $access): void
{
if (!$access) {
return;
}
$tb = app()->thin_builder;
// Remove old auto-synced permissions (those without set_by_user_id = manual override)
$tb->query("
DELETE FROM shserv_user_permissions
WHERE user_id = {$userId} AND set_by_user_id IS NULL
");
// Insert current permissions from gnexus-auth
foreach ($access->permissionIds as $permId) {
$permSlug = $this->mapPermissionIdToSlug($permId);
if (!$permSlug) {
continue;
}
$tb->insert('shserv_user_permissions', [
'user_id' => $userId,
'permission_slug' => $permSlug,
'granted' => 1,
'set_by_user_id' => null,
]);
}
}
private function mapPermissionIdToSlug(string $permId): ?string
{
// In first version, gnexus-auth permissionIds might be slugs already.
// If they are numeric IDs, we would need a mapping table.
// For now, assume they are strings like "devices.view".
$tb = app()->thin_builder;
$exists = $tb->select('shserv_permissions', ['slug'], [['slug', '=', $permId]], [], '', [0, 1]);
return $exists ? $exists[0]['slug'] : null;
}
}