Initial Version
This commit is contained in:
137
core/lib/Service/UserManagerService.php
Normal file
137
core/lib/Service/UserManagerService.php
Normal file
@@ -0,0 +1,137 @@
|
||||
<?php
|
||||
|
||||
namespace KTXC\Service;
|
||||
|
||||
use KTXC\Identity\Provider\DefaultIdentityProvider;
|
||||
use KTXC\Models\Identity\User;
|
||||
use KTXC\Server;
|
||||
use KTXC\SessionTenant;
|
||||
|
||||
/**
|
||||
* User Manager Service
|
||||
* Manages authentication providers and user operations across domains
|
||||
*/
|
||||
class UserManagerService
|
||||
{
|
||||
private array $availableIdentityProviders = [];
|
||||
private array $cachedIdentityProviders = [];
|
||||
|
||||
public function __construct(
|
||||
private readonly SessionTenant $tenant,
|
||||
private readonly UserService $userService
|
||||
) {
|
||||
// Register the default identity provider
|
||||
$this->providerRegister('default', DefaultIdentityProvider::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Register an authentication provider
|
||||
*/
|
||||
public function providerRegister(string $identifier, string $class): void
|
||||
{
|
||||
$this->availableIdentityProviders[$identifier] = $class;
|
||||
}
|
||||
|
||||
public function providerList(?array $filter = null): array
|
||||
{
|
||||
$requestedProviders = $filter ? $filter : array_keys($this->availableIdentityProviders);
|
||||
$result = [];
|
||||
|
||||
foreach ($requestedProviders as $identifier) {
|
||||
// Check if provider is available
|
||||
if (!isset($this->availableIdentityProviders[$identifier])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Check cache first
|
||||
if (isset($this->cachedIdentityProviders[$identifier])) {
|
||||
$result[$identifier] = $this->cachedIdentityProviders[$identifier];
|
||||
} else {
|
||||
// Instantiate the provider and cache it
|
||||
$providerClass = $this->availableIdentityProviders[$identifier];
|
||||
|
||||
try {
|
||||
// Server::get automatically detects context from calling object
|
||||
$providerInstance = Server::runtimeContainer()->get($providerClass);
|
||||
|
||||
// Cache the instance
|
||||
$this->cachedIdentityProviders[$identifier] = $providerInstance;
|
||||
$result[$identifier] = $providerInstance;
|
||||
} catch (\Exception $e) {
|
||||
// Skip providers that can't be resolved
|
||||
error_log("Failed to resolve identity provider {$providerClass}: " . $e->getMessage());
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Authenticate user against enabled providers
|
||||
*/
|
||||
public function authenticate(string $identity, string $credential): User | null
|
||||
{
|
||||
// validate identity and credential
|
||||
if (empty($identity) || empty($credential)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// retrieve user by identity
|
||||
$user = $this->userService->fetchByIdentity($identity);
|
||||
|
||||
// determine if user has logged in before
|
||||
if (!$user) {
|
||||
return null;
|
||||
}
|
||||
// determine if user has a identity provider assigned
|
||||
if ($user->getProvider() === null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$authenticated = $this->authenticateExtant($user->getProvider(), $identity, $credential);
|
||||
|
||||
if ($authenticated) {
|
||||
return $user;
|
||||
}
|
||||
|
||||
return null;
|
||||
|
||||
}
|
||||
|
||||
public function authenticateExtant(string $provider, string $identity, string $credential): bool {
|
||||
// determine if provider is enabled
|
||||
$providers = $this->providerList([$provider]);
|
||||
if (empty($providers)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Get the first (and should be only) provider
|
||||
$provider = reset($providers);
|
||||
|
||||
// authenticate user against provider
|
||||
$user = $provider->authenticate($identity, $credential);
|
||||
|
||||
return $user;
|
||||
}
|
||||
|
||||
public function validate(string $identifier): Bool
|
||||
{
|
||||
$data = $this->userService->fetchByIdentifier($identifier);
|
||||
if (!$data) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($data['enabled'] !== true) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($data['tid'] !== $this->tenant->identifier()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user