Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions src/DefaultInjectorBindings.php
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,10 @@
use Horde\Core\Factory\OAuthFlowStoreFactory;
use Horde\Core\Factory\PermissionServiceFactory;
use Horde\Core\Factory\PrefsServiceFactory;
use Horde\Core\Service\Factory\CredentialStoreFactory;
use Horde\Core\Service\Factory\CredentialProvisioningStrategyFactory;
use Horde\Core\Service\Factory\PasswordServiceAuthorizationServiceFactory;
use Horde\Core\Service\Factory\ServiceCredentialManagerFactory;
use Horde\Core\Factory\RegistryConfigLoaderFactory;
use Horde\Core\Factory\RouteUrlWriterFactory;
use Horde\Core\Factory\RuntimeRoutesProviderFactory;
Expand All @@ -94,15 +98,19 @@
use Horde\Core\Middleware\ErrorFilter;
use Horde\Core\Middleware\OAuthConsentMiddleware;
use Horde\Core\Service\ApplicationService;
use Horde\Core\Service\CredentialStore;
use Horde\Core\Service\CredentialProvisioningStrategy;
use Horde\Core\Service\GroupService;
use Horde\Core\Service\HordeDbService;
use Horde\Core\Service\HordeLdapService;
use Horde\Core\Service\IdentityService;
use Horde\Core\Service\OAuthHttpClientService;
use Horde\Core\Service\OAuthProviderConfigRepository;
use Horde\Core\Service\OAuthTokenService;
use Horde\Core\Service\PasswordServiceAuthorizationService;
use Horde\Core\Service\PermissionService;
use Horde\Core\Service\PrefsService;
use Horde\Core\Service\ServiceCredentialManager;
use Horde\Core\Service\VersionCheck\VersionService;
use Horde\Core\Uri\RegistryRouteMapperProvider;
use Horde\Core\Uri\RouteMapperProvider;
Expand Down Expand Up @@ -288,6 +296,10 @@ public function register(Injector $injector): void
HordeLdapService::class => HordeLdapServiceFactory::class,
PermissionService::class => PermissionServiceFactory::class,
VersionService::class => VersionServiceFactory::class,
CredentialStore::class => CredentialStoreFactory::class,
CredentialProvisioningStrategy::class => CredentialProvisioningStrategyFactory::class,
PasswordServiceAuthorizationService::class => PasswordServiceAuthorizationServiceFactory::class,
ServiceCredentialManager::class => ServiceCredentialManagerFactory::class,
Tinymce::class => TinymceFactory::class,
TinymcePageBinder::class => TinymcePageBinderFactory::class,
EventDispatcherInterface::class => [EventDispatcherFactory::class, 'create'],
Expand Down
18 changes: 18 additions & 0 deletions src/Factory/ServiceAuthorizationRepositoryFactory.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<?php

declare(strict_types=1);

namespace Horde\Core\Factory;

use Horde\Core\Service\NullServiceAuthorizationRepository;
use Horde\Core\Service\ServiceAuthorizationRepository;
use Horde\Injector\Injector;

/** Factory for ServiceAuthorizationRepository - defaults to NullServiceAuthorizationRepository. */
class ServiceAuthorizationRepositoryFactory
{
public function create(Injector $injector): ServiceAuthorizationRepository
{
return new NullServiceAuthorizationRepository();
}
}
18 changes: 18 additions & 0 deletions src/Factory/ServiceAuthorizationServiceFactory.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<?php

declare(strict_types=1);

namespace Horde\Core\Factory;

use Horde\Core\Service\NullServiceAuthorizationService;
use Horde\Core\Service\ServiceAuthorizationService;
use Horde\Injector\Injector;

/** Factory for ServiceAuthorizationService - defaults to NullServiceAuthorizationService. */
class ServiceAuthorizationServiceFactory
{
public function create(Injector $injector): ServiceAuthorizationService
{
return new NullServiceAuthorizationService();
}
}
18 changes: 18 additions & 0 deletions src/Factory/TokenGrantRepositoryFactory.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<?php

declare(strict_types=1);

namespace Horde\Core\Factory;

use Horde\Core\Service\NullTokenGrantRepository;
use Horde\Core\Service\TokenGrantRepository;
use Horde\Injector\Injector;

/** Factory for TokenGrantRepository - defaults to NullTokenGrantRepository. */
class TokenGrantRepositoryFactory
{
public function create(Injector $injector): TokenGrantRepository
{
return new NullTokenGrantRepository();
}
}
18 changes: 18 additions & 0 deletions src/Service/AcquisitionAction.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<?php
/**
* Actions that can result from credential acquisition attempt.
*
* @package Horde_Core
*/

declare(strict_types=1);

namespace Horde\Core\Service;

enum AcquisitionAction
{
case Redirect; // OAuth flow
case ShowForm; // Password entry
case AlreadyExists; // No action needed
case Unavailable; // Cannot acquire
}
19 changes: 19 additions & 0 deletions src/Service/CredentialAcquisitionResult.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<?php
/**
* Result of credential acquisition attempt.
*
* @package Horde_Core
*/

declare(strict_types=1);

namespace Horde\Core\Service;

final class CredentialAcquisitionResult
{
public function __construct(
public readonly AcquisitionAction $action,
public readonly ?string $redirectUri = null,
public readonly ?array $formFields = null,
) {}
}
24 changes: 24 additions & 0 deletions src/Service/CredentialProvisioningStrategy.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<?php
/**
* Strategy interface for credential provisioning.
*
* Defines how credentials get into the system initially.
*
* @package Horde_Core
*/

declare(strict_types=1);

namespace Horde\Core\Service;

interface CredentialProvisioningStrategy
{
/**
* Attempt to provision credentials for given context.
*/
public function provision(
string $userId,
string $providerId,
ServicePurpose $purpose
): ProvisioningResult;
}
68 changes: 68 additions & 0 deletions src/Service/CredentialStore.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
<?php
/**
* Repository interface for password credential storage.
*
* Abstracts storage/retrieval from service logic. Implementations handle
* encryption/decryption internally and return fully-decrypted credentials.
*
* @package Horde_Core
*/

declare(strict_types=1);

namespace Horde\Core\Service;

interface CredentialStore
{
/**
* Find credential for specific user/provider/purpose.
*/
public function find(
string $userId,
string $providerId,
ServicePurpose $purpose
): ?PasswordCredential;

/**
* Find all credentials for a user.
*
* @return PasswordCredential[]
*/
public function findAll(string $userId): array;

/**
* Find all credentials for a user+provider.
*
* @return PasswordCredential[]
*/
public function findAllForProvider(
string $userId,
string $providerId
): array;

/**
* Store new credential.
*
* @param array|string $credential Array for structured {'username','password'}, string for opaque
*/
public function store(
string $userId,
string $providerId,
ServicePurpose $purpose,
array|string $credential
): PasswordCredential;

/**
* Update existing credential.
*
* @param array|string $credential Array for structured, string for opaque
*/
public function update(
string $credentialId,
array|string $credential
): PasswordCredential;

public function delete(string $credentialId): void;

public function deleteAll(string $userId, string $providerId): void;
}
16 changes: 16 additions & 0 deletions src/Service/CredentialType.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<?php
/**
* Credential types supported by unified manager.
*
* @package Horde_Core
*/

declare(strict_types=1);

namespace Horde\Core\Service;

enum CredentialType
{
case OAuth;
case Password;
}
30 changes: 29 additions & 1 deletion src/Service/Exception/OAuthTokenRefreshException.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,39 @@

namespace Horde\Core\Service\Exception;

use Horde\Core\Service\TokenGrant;
use RuntimeException;

/**
* Thrown when an OAuth token refresh fails (e.g. refresh token revoked).
*
* Callers should prompt the user to re-authorize.
*/
class OAuthTokenRefreshException extends RuntimeException {}
class OAuthTokenRefreshException extends RuntimeException
{
public function __construct(
string $message,
private readonly string $userId,
private readonly string $providerId,
private readonly ?TokenGrant $grant = null,
int $code = 0,
?\Throwable $previous = null
) {
parent::__construct($message, $code, $previous);
}

public function userId(): string
{
return $this->userId;
}

public function providerId(): string
{
return $this->providerId;
}

public function grant(): ?TokenGrant
{
return $this->grant;
}
}
22 changes: 22 additions & 0 deletions src/Service/Factory/CredentialProvisioningStrategyFactory.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<?php
/**
* Factory for CredentialProvisioningStrategy.
*
* @package Horde_Core
*/

declare(strict_types=1);

namespace Horde\Core\Service\Factory;

use Horde\Core\Service\CredentialProvisioningStrategy;
use Horde\Core\Service\NullCredentialProvisioningStrategy;
use Horde_Injector;

class CredentialProvisioningStrategyFactory
{
public function create(Horde_Injector $injector): CredentialProvisioningStrategy
{
return new NullCredentialProvisioningStrategy();
}
}
22 changes: 22 additions & 0 deletions src/Service/Factory/CredentialStoreFactory.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<?php
/**
* Factory for CredentialStore.
*
* @package Horde_Core
*/

declare(strict_types=1);

namespace Horde\Core\Service\Factory;

use Horde\Core\Service\CredentialStore;
use Horde\Core\Service\NullCredentialStore;
use Horde_Injector;

class CredentialStoreFactory
{
public function create(Horde_Injector $injector): CredentialStore
{
return new NullCredentialStore();
}
}
22 changes: 22 additions & 0 deletions src/Service/Factory/PasswordServiceAuthorizationServiceFactory.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<?php
/**
* Factory for PasswordServiceAuthorizationService.
*
* @package Horde_Core
*/

declare(strict_types=1);

namespace Horde\Core\Service\Factory;

use Horde\Core\Service\NullPasswordServiceAuthorizationService;
use Horde\Core\Service\PasswordServiceAuthorizationService;
use Horde_Injector;

class PasswordServiceAuthorizationServiceFactory
{
public function create(Horde_Injector $injector): PasswordServiceAuthorizationService
{
return new NullPasswordServiceAuthorizationService();
}
}
22 changes: 22 additions & 0 deletions src/Service/Factory/ServiceCredentialManagerFactory.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<?php
/**
* Factory for ServiceCredentialManager.
*
* @package Horde_Core
*/

declare(strict_types=1);

namespace Horde\Core\Service\Factory;

use Horde\Core\Service\NullServiceCredentialManager;
use Horde\Core\Service\ServiceCredentialManager;
use Horde_Injector;

class ServiceCredentialManagerFactory
{
public function create(Horde_Injector $injector): ServiceCredentialManager
{
return new NullServiceCredentialManager();
}
}
Loading
Loading