userIdentity->hasPermission('user.admin')) { return new JsonResponse([ 'status' => 'error', 'data' => ['code' => 403, 'message' => 'Insufficient permissions'] ], JsonResponse::HTTP_FORBIDDEN); } $result = $this->process($operation, $data); return new JsonResponse([ 'version' => $version, 'transaction' => $transaction, 'operation' => $operation, 'status' => 'success', 'data' => $result, ], JsonResponse::HTTP_OK); } catch (\InvalidArgumentException $e) { return new JsonResponse([ 'version' => $version, 'transaction' => $transaction, 'operation' => $operation, 'status' => 'error', 'data' => ['code' => 400, 'message' => $e->getMessage()] ], JsonResponse::HTTP_BAD_REQUEST); } catch (\Throwable $e) { $this->logger->error('User manager operation failed', [ 'operation' => $operation, 'error' => $e->getMessage() ]); return new JsonResponse([ 'version' => $version, 'transaction' => $transaction, 'operation' => $operation, 'status' => 'error', 'data' => ['code' => $e->getCode(), 'message' => $e->getMessage()] ], JsonResponse::HTTP_INTERNAL_SERVER_ERROR); } } /** * Process operation */ private function process(string $operation, array $data): mixed { return match ($operation) { 'user.list' => $this->userList($data), 'user.fetch' => $this->userFetch($data), 'user.create' => $this->userCreate($data), 'user.update' => $this->userUpdate($data), 'user.delete' => $this->userDelete($data), 'user.provider.unlink' => $this->userProviderUnlink($data), default => throw new \InvalidArgumentException("Invalid operation: {$operation}"), }; } // ========================================================================= // User Operations // ========================================================================= /** * List all users for tenant */ private function userList(array $data): array { return $this->userService->listUsers($data); } /** * Fetch single user by UID */ private function userFetch(array $data): array { $uid = $data['uid'] ?? throw new \InvalidArgumentException('User ID required'); $user = $this->userService->fetchByIdentifier($uid); if (!$user) { throw new \InvalidArgumentException('User not found'); } // Get editable fields for profile $editableFields = $this->userService->getEditableFields($uid); $user['profile_editable'] = $editableFields; return $user; } /** * Create new user */ private function userCreate(array $data): array { if (!$this->userIdentity->hasPermission('user.create')) { throw new \InvalidArgumentException('Insufficient permissions to create users'); } $userData = [ 'identity' => $data['identity'] ?? throw new \InvalidArgumentException('Identity required'), 'label' => $data['label'] ?? $data['identity'], 'enabled' => $data['enabled'] ?? true, 'roles' => $data['roles'] ?? [], 'profile' => $data['profile'] ?? [], 'settings' => [], 'provider' => null, 'provider_subject' => null, 'provider_managed_fields' => [] ]; $this->logger->info('Creating user', [ 'tenant' => $this->tenantIdentity->identifier(), 'identity' => $userData['identity'], 'actor' => $this->userIdentity->identifier() ]); return $this->userService->createUser($userData); } /** * Update existing user */ private function userUpdate(array $data): bool { if (!$this->userIdentity->hasPermission('user.update')) { throw new \InvalidArgumentException('Insufficient permissions to update users'); } $uid = $data['uid'] ?? throw new \InvalidArgumentException('User ID required'); // Build updates (exclude sensitive fields) $updates = []; $allowedFields = ['label', 'enabled', 'roles', 'profile']; foreach ($allowedFields as $field) { if (isset($data[$field])) { $updates[$field] = $data[$field]; } } if (empty($updates)) { throw new \InvalidArgumentException('No valid fields to update'); } // Special handling for profile updates (respect managed fields) if (isset($updates['profile'])) { $user = $this->userService->fetchByIdentifier($uid); $managedFields = $user['provider_managed_fields'] ?? []; foreach ($managedFields as $field) { unset($updates['profile'][$field]); } } $this->logger->info('Updating user', [ 'tenant' => $this->tenantIdentity->identifier(), 'uid' => $uid, 'actor' => $this->userIdentity->identifier() ]); return $this->userService->updateUser($uid, $updates); } /** * Delete user */ private function userDelete(array $data): bool { if (!$this->userIdentity->hasPermission('user.delete')) { throw new \InvalidArgumentException('Insufficient permissions to delete users'); } $uid = $data['uid'] ?? throw new \InvalidArgumentException('User ID required'); // Prevent self-deletion if ($uid === $this->userIdentity->identifier()) { throw new \InvalidArgumentException('Cannot delete your own account'); } $this->logger->info('Deleting user', [ 'tenant' => $this->tenantIdentity->identifier(), 'uid' => $uid, 'actor' => $this->userIdentity->identifier() ]); return $this->userService->deleteUser($uid); } // ========================================================================= // Security Operations // ========================================================================= /** * Unlink external provider */ private function userProviderUnlink(array $data): bool { if (!$this->userIdentity->hasPermission('user.admin')) { throw new \InvalidArgumentException('Insufficient permissions'); } $uid = $data['uid'] ?? throw new \InvalidArgumentException('User ID required'); $updates = [ 'provider' => null, 'provider_subject' => null, 'provider_managed_fields' => [] ]; $this->logger->info('Unlinking provider', [ 'tenant' => $this->tenantIdentity->identifier(), 'uid' => $uid, 'actor' => $this->userIdentity->identifier() ]); return $this->userService->updateUser($uid, $updates); } }