diff --git a/src/Auth/Process/Accounting.php b/src/Auth/Process/Accounting.php index 146523a848111bf9fcbdfeefcb425c8a560f8770..a2488982fae8cc4911737a18f8f73005a6547344 100644 --- a/src/Auth/Process/Accounting.php +++ b/src/Auth/Process/Accounting.php @@ -10,10 +10,10 @@ use SimpleSAML\Module\accounting\Entities\Authentication\Event; use SimpleSAML\Module\accounting\Entities\Authentication\State; use SimpleSAML\Module\accounting\Exceptions\StoreException; use SimpleSAML\Module\accounting\ModuleConfiguration; +use SimpleSAML\Module\accounting\Services\HelpersManager; use SimpleSAML\Module\accounting\Services\Logger; use SimpleSAML\Module\accounting\Stores\Builders\JobsStoreBuilder; use SimpleSAML\Module\accounting\Trackers\Builders\AuthenticationDataTrackerBuilder; -use SimpleSAML\Module\accounting\Trackers\Interfaces\AuthenticationDataTrackerInterface; class Accounting extends ProcessingFilter { @@ -21,19 +21,23 @@ class Accounting extends ProcessingFilter protected JobsStoreBuilder $jobsStoreBuilder; protected LoggerInterface $logger; protected AuthenticationDataTrackerBuilder $authenticationDataTrackerBuilder; + protected HelpersManager $helpersManager; /** * @param array $config * @param mixed $reserved * @param ModuleConfiguration|null $moduleConfiguration * @param LoggerInterface|null $logger + * @param HelpersManager|null $helpersManager * @param JobsStoreBuilder|null $jobsStoreBuilder + * @param AuthenticationDataTrackerBuilder|null $authenticationDataTrackerBuilder */ public function __construct( array &$config, $reserved, ModuleConfiguration $moduleConfiguration = null, LoggerInterface $logger = null, + HelpersManager $helpersManager = null, JobsStoreBuilder $jobsStoreBuilder = null, AuthenticationDataTrackerBuilder $authenticationDataTrackerBuilder = null ) { @@ -41,14 +45,15 @@ class Accounting extends ProcessingFilter $this->moduleConfiguration = $moduleConfiguration ?? new ModuleConfiguration(); $this->logger = $logger ?? new Logger(); - $this->jobsStoreBuilder = $jobsStoreBuilder ?? new JobsStoreBuilder($this->moduleConfiguration, $this->logger); + $this->helpersManager = $helpersManager ?? new HelpersManager(); + $this->jobsStoreBuilder = $jobsStoreBuilder ?? + new JobsStoreBuilder($this->moduleConfiguration, $this->logger, $this->helpersManager); $this->authenticationDataTrackerBuilder = $authenticationDataTrackerBuilder ?? - new AuthenticationDataTrackerBuilder($this->moduleConfiguration, $this->logger); + new AuthenticationDataTrackerBuilder($this->moduleConfiguration, $this->logger, $this->helpersManager); } /** - * @throws StoreException */ public function process(array &$state): void { diff --git a/src/Entities/Activity.php b/src/Entities/Activity.php index 69699f56670bd73639b05f6d8f3cf430e6d1521e..7371efd47f37c1f736017ec7a2f34260b9d9170a 100644 --- a/src/Entities/Activity.php +++ b/src/Entities/Activity.php @@ -11,15 +11,18 @@ class Activity protected ServiceProvider $serviceProvider; protected User $user; protected DateTimeImmutable $happenedAt; + protected ?string $clientIpAddress; public function __construct( ServiceProvider $serviceProvider, User $user, - DateTimeImmutable $happenedAt + DateTimeImmutable $happenedAt, + ?string $clientIpAddress ) { $this->serviceProvider = $serviceProvider; $this->user = $user; $this->happenedAt = $happenedAt; + $this->clientIpAddress = $clientIpAddress; } /** @@ -45,4 +48,12 @@ class Activity { return $this->happenedAt; } + + /** + * @return string|null + */ + public function getClientIpAddress(): ?string + { + return $this->clientIpAddress; + } } diff --git a/src/Entities/Authentication/State.php b/src/Entities/Authentication/State.php index 6f0ff682e9169db82241ae27a838b52186af1987..899b3e75d51c500111e729ca8d73293fee7b7a1a 100644 --- a/src/Entities/Authentication/State.php +++ b/src/Entities/Authentication/State.php @@ -7,6 +7,7 @@ namespace SimpleSAML\Module\accounting\Entities\Authentication; use SimpleSAML\Module\accounting\Entities\Bases\AbstractProvider; use SimpleSAML\Module\accounting\Exceptions\UnexpectedValueException; use SimpleSAML\Module\accounting\Helpers\NetworkHelper; +use SimpleSAML\Module\accounting\Services\HelpersManager; class State { @@ -28,10 +29,15 @@ class State protected array $identityProviderMetadata; protected array $serviceProviderMetadata; protected ?string $clientIpAddress; + protected HelpersManager $helpersManager; - public function __construct(array $state, \DateTimeImmutable $createdAt = null) - { + public function __construct( + array $state, + \DateTimeImmutable $createdAt = null, + HelpersManager $helpersManager = null + ) { $this->createdAt = $createdAt ?? new \DateTimeImmutable(); + $this->helpersManager = $helpersManager ?? new HelpersManager(); $this->identityProviderMetadata = $this->resolveIdentityProviderMetadata($state); $this->identityProviderEntityId = $this->resolveIdentityProviderEntityId(); @@ -175,7 +181,7 @@ class State protected function resolveClientIpAddress(array $state): ?string { - return NetworkHelper::resolveClientIpAddress( + return $this->helpersManager->getNetworkHelper()->resolveClientIpAddress( isset($state[self::KEY_ACCOUNTING][self::ACCOUNTING_KEY_CLIENT_IP_ADDRESS]) ? (string)$state[self::KEY_ACCOUNTING][self::ACCOUNTING_KEY_CLIENT_IP_ADDRESS] : null diff --git a/src/Entities/Bases/AbstractProvider.php b/src/Entities/Bases/AbstractProvider.php index 63b43535bfc0c75de90730f48d0a2597e4de2123..56c0927f39e52c3a1288b6d742aec30747b3e0a1 100644 --- a/src/Entities/Bases/AbstractProvider.php +++ b/src/Entities/Bases/AbstractProvider.php @@ -8,6 +8,7 @@ abstract class AbstractProvider { public const METADATA_KEY_NAME = 'name'; public const METADATA_KEY_ENTITY_ID = 'entityid'; + public const METADATA_KEY_DESCRIPTION = 'description'; protected array $metadata; protected string $entityId; @@ -25,16 +26,7 @@ abstract class AbstractProvider public function getName(string $locale = 'en'): ?string { - if ( - isset($this->metadata[self::METADATA_KEY_NAME]) && - is_array($this->metadata[self::METADATA_KEY_NAME]) && - !empty($this->metadata[self::METADATA_KEY_NAME][$locale]) && - is_string($this->metadata[self::METADATA_KEY_NAME][$locale]) - ) { - return (string)$this->metadata[self::METADATA_KEY_NAME][$locale]; - } - - return null; + return $this->resolveOptionallyLocalizedString(self::METADATA_KEY_NAME, $locale); } public function getEntityId(): string @@ -42,10 +34,9 @@ abstract class AbstractProvider return $this->entityId; } - public function getDescription(): ?string + public function getDescription(string $locale = 'en'): ?string { - // TODO mivanci - return null; + return $this->resolveOptionallyLocalizedString(self::METADATA_KEY_DESCRIPTION, $locale); } @@ -60,4 +51,26 @@ abstract class AbstractProvider throw new UnexpectedValueException('Provider entity metadata does not contain entity ID.'); } + + protected function resolveOptionallyLocalizedString(string $key, string $locale = 'en'): ?string + { + if (!isset($this->metadata[$key])) { + return null; + } + + // Check for non-localized version. + if (is_string($this->metadata[$key])) { + return $this->metadata[$key]; + } + + if ( + is_array($this->metadata[$key]) && + !empty($this->metadata[$key][$locale]) && + is_string($this->metadata[$key][$locale]) + ) { + return $this->metadata[$key][$locale]; + } + + return null; + } } diff --git a/src/Helpers/ArrayHelper.php b/src/Helpers/ArrayHelper.php index 0b57b663bcd3158113578f9a0741b599d70caf16..7aec51f9069bec8f7991b39d8e581ed5aeb646fc 100644 --- a/src/Helpers/ArrayHelper.php +++ b/src/Helpers/ArrayHelper.php @@ -4,15 +4,14 @@ declare(strict_types=1); namespace SimpleSAML\Module\accounting\Helpers; -// TODO mivanci move to HelpersManager class ArrayHelper { - public static function recursivelySortByKey(array &$array): void + public function recursivelySortByKey(array &$array): void { /** @psalm-suppress MixedAssignment */ foreach ($array as &$value) { if (is_array($value)) { - self::recursivelySortByKey($value); + $this->recursivelySortByKey($value); } } diff --git a/src/Helpers/AttributesHelper.php b/src/Helpers/AttributesHelper.php index e3aedf3ca9f7445e77459ca6cbebc95ac5ac3f8d..8fc6806d02e6ddc926c12f2ec8a9594543009289 100644 --- a/src/Helpers/AttributesHelper.php +++ b/src/Helpers/AttributesHelper.php @@ -4,8 +4,6 @@ declare(strict_types=1); namespace SimpleSAML\Module\accounting\Helpers; -// TODO mivanci move to HelpersManager - class AttributesHelper { /** diff --git a/src/Helpers/FilesystemHelper.php b/src/Helpers/FilesystemHelper.php index f82b41c595d3cc2980cee6ceb5303c0947fcc1fb..1ee692215bc2ce4a7f4f3ecb7a03905e870dd4f8 100644 --- a/src/Helpers/FilesystemHelper.php +++ b/src/Helpers/FilesystemHelper.php @@ -6,10 +6,9 @@ namespace SimpleSAML\Module\accounting\Helpers; use SimpleSAML\Module\accounting\Exceptions\InvalidValueException; -// TODO mivanci move to HelpersManager class FilesystemHelper { - public static function getRealPath(string $path): string + public function getRealPath(string $path): string { $realpath = realpath($path); diff --git a/src/Helpers/HashHelper.php b/src/Helpers/HashHelper.php index 7421125e4bd5aaab937074a0d30d9f9f9c1dcd0e..ea38562f48cc284eed171c01817d0d30893b69da 100644 --- a/src/Helpers/HashHelper.php +++ b/src/Helpers/HashHelper.php @@ -4,17 +4,23 @@ declare(strict_types=1); namespace SimpleSAML\Module\accounting\Helpers; -// TODO mivanci move to HelpersManager class HashHelper { - public static function getSha256(string $data): string + protected ArrayHelper $arrayHelper; + + public function __construct(ArrayHelper $arrayHelper) + { + $this->arrayHelper = $arrayHelper; + } + + public function getSha256(string $data): string { return hash('sha256', $data); } - public static function getSha256ForArray(array $array): string + public function getSha256ForArray(array $array): string { - ArrayHelper::recursivelySortByKey($array); - return self::getSha256(serialize($array)); + $this->arrayHelper->recursivelySortByKey($array); + return $this->getSha256(serialize($array)); } } diff --git a/src/Helpers/InstanceBuilderUsingModuleConfigurationHelper.php b/src/Helpers/InstanceBuilderUsingModuleConfigurationHelper.php index ffdba87b2026680708a3aca7fa8ddc2917f62c5c..fed30792f71320136230bf25f825919a4c594d75 100644 --- a/src/Helpers/InstanceBuilderUsingModuleConfigurationHelper.php +++ b/src/Helpers/InstanceBuilderUsingModuleConfigurationHelper.php @@ -1,5 +1,7 @@ <?php +declare(strict_types=1); + namespace SimpleSAML\Module\accounting\Helpers; use Psr\Log\LoggerInterface; @@ -9,7 +11,6 @@ use SimpleSAML\Module\accounting\Exceptions\UnexpectedValueException; use SimpleSAML\Module\accounting\Interfaces\BuildableUsingModuleConfigurationInterface; use SimpleSAML\Module\accounting\ModuleConfiguration; -// TODO mivanci move to HelpersManager class InstanceBuilderUsingModuleConfigurationHelper { /** @@ -21,7 +22,7 @@ class InstanceBuilderUsingModuleConfigurationHelper * @return BuildableUsingModuleConfigurationInterface * @throws Exception */ - public static function build( + public function build( string $class, ModuleConfiguration $moduleConfiguration, LoggerInterface $logger, @@ -29,7 +30,7 @@ class InstanceBuilderUsingModuleConfigurationHelper string $method = BuildableUsingModuleConfigurationInterface::BUILD_METHOD ): BuildableUsingModuleConfigurationInterface { try { - self::validateClass($class); + $this->validateClass($class); $allArguments = array_merge([$moduleConfiguration, $logger], $additionalArguments); @@ -47,7 +48,7 @@ class InstanceBuilderUsingModuleConfigurationHelper return $instance; } - protected static function validateClass(string $class): void + protected function validateClass(string $class): void { if (!is_subclass_of($class, BuildableUsingModuleConfigurationInterface::class)) { $message = sprintf( diff --git a/src/Helpers/NetworkHelper.php b/src/Helpers/NetworkHelper.php index 7b245491326d1ad570d66041217a5dccb621855c..d7159a40260aa8386a9b69cbed85635a3ae8ddaf 100644 --- a/src/Helpers/NetworkHelper.php +++ b/src/Helpers/NetworkHelper.php @@ -4,10 +4,9 @@ declare(strict_types=1); namespace SimpleSAML\Module\accounting\Helpers; -// TODO mivanci move to HelpersManager class NetworkHelper { - public static function resolveClientIpAddress(string $clientIpAddress = null): ?string + public function resolveClientIpAddress(string $clientIpAddress = null): ?string { /** @var string|null $clientIpAddress */ $clientIpAddress = $clientIpAddress ?? diff --git a/src/Http/Controllers/Admin/Configuration.php b/src/Http/Controllers/Admin/Configuration.php index 6c977e30fd87e43831d3396faf9777c7c2d97d4d..3f585d1e1adb006f08f0801d243eca2c981dae07 100644 --- a/src/Http/Controllers/Admin/Configuration.php +++ b/src/Http/Controllers/Admin/Configuration.php @@ -62,7 +62,7 @@ class Configuration $moduleConfiguration = new ModuleConfiguration(); $defaultDataTrackerAndProvider = - (new AuthenticationDataTrackerBuilder($moduleConfiguration, $this->logger)) + (new AuthenticationDataTrackerBuilder($moduleConfiguration, $this->logger, $this->helpersManager)) ->build($moduleConfiguration->getDefaultDataTrackerAndProviderClass()); if ($defaultDataTrackerAndProvider->needsSetup()) { @@ -77,7 +77,7 @@ class Configuration $moduleConfiguration->getAccountingProcessingType() === ModuleConfiguration\AccountingProcessingType::VALUE_ASYNCHRONOUS ) { - $jobsStore = (new JobsStoreBuilder($moduleConfiguration, $this->logger)) + $jobsStore = (new JobsStoreBuilder($moduleConfiguration, $this->logger, $this->helpersManager)) ->build($moduleConfiguration->getJobsStoreClass()); if ($jobsStore->needsSetup()) { if ($runSetup) { diff --git a/src/Http/Controllers/User/Profile.php b/src/Http/Controllers/User/Profile.php index cbd467238459c4528d5e723ca99c0d5c3daa1b84..9f4d5ecf27a81218edb970f3330059b222a0d20c 100644 --- a/src/Http/Controllers/User/Profile.php +++ b/src/Http/Controllers/User/Profile.php @@ -12,6 +12,7 @@ use SimpleSAML\Module\accounting\ModuleConfiguration; use SimpleSAML\Module\accounting\ModuleConfiguration\ConnectionType; use SimpleSAML\Module\accounting\Providers\Builders\AuthenticationDataProviderBuilder; use SimpleSAML\Module\accounting\Providers\Interfaces\AuthenticationDataProviderInterface; +use SimpleSAML\Module\accounting\Services\HelpersManager; use SimpleSAML\Session; use SimpleSAML\XHTML\Template; use Symfony\Component\HttpFoundation\Request; @@ -29,6 +30,7 @@ class Profile protected string $defaultAuthenticationSource; protected Simple $authSimple; protected AuthenticationDataProviderBuilder $authenticationDataProviderBuilder; + protected HelpersManager $helpersManager; /** * @param ModuleConfiguration $moduleConfiguration @@ -37,6 +39,7 @@ class Profile * @param LoggerInterface $logger * @param Simple|null $authSimple * @param AuthenticationDataProviderBuilder|null $authenticationDataProviderBuilder + * @param HelpersManager|null $helpersManager */ public function __construct( ModuleConfiguration $moduleConfiguration, @@ -44,7 +47,8 @@ class Profile Session $session, LoggerInterface $logger, Simple $authSimple = null, - AuthenticationDataProviderBuilder $authenticationDataProviderBuilder = null + AuthenticationDataProviderBuilder $authenticationDataProviderBuilder = null, + HelpersManager $helpersManager = null ) { $this->moduleConfiguration = $moduleConfiguration; $this->sspConfiguration = $sspConfiguration; @@ -57,6 +61,8 @@ class Profile $this->authenticationDataProviderBuilder = $authenticationDataProviderBuilder ?? new AuthenticationDataProviderBuilder($this->moduleConfiguration, $this->logger); + $this->helpersManager = $helpersManager ?? new HelpersManager(); + // Make sure the end user is authenticated. $this->authSimple->requireAuth(); } @@ -162,7 +168,7 @@ class Profile */ protected function prepareToNameAttributeMap(): array { - return AttributesHelper::getMergedAttributeMapForFiles( + return $this->helpersManager->getAttributesHelper()->getMergedAttributeMapForFiles( $this->sspConfiguration->getBaseDir(), AttributesHelper::MAP_FILES_TO_NAME ); diff --git a/src/ModuleConfiguration.php b/src/ModuleConfiguration.php index 6b4e9abe03c9eeae99c9348f622c1be87526207e..1827a1401191fc90bc710ae3e0262940b454a5ab 100644 --- a/src/ModuleConfiguration.php +++ b/src/ModuleConfiguration.php @@ -44,11 +44,13 @@ class ModuleConfiguration /** * @throws Exception */ - public function __construct(string $fileName = null) + public function __construct(string $fileName = null, array $overrides = []) { $fileName = $fileName ?? self::FILE_NAME; - $this->configuration = Configuration::getConfig($fileName); + $fullConfigArray = array_merge(Configuration::getConfig($fileName)->toArray(), $overrides); + + $this->configuration = Configuration::loadFromArray($fullConfigArray); $this->validate(); } diff --git a/src/Providers/Builders/AuthenticationDataProviderBuilder.php b/src/Providers/Builders/AuthenticationDataProviderBuilder.php index 121bc6125edda122fc716d8a55103f77b180b85b..b064f1c2cd8efd288dfbd7643d2e75b083f951e7 100644 --- a/src/Providers/Builders/AuthenticationDataProviderBuilder.php +++ b/src/Providers/Builders/AuthenticationDataProviderBuilder.php @@ -10,17 +10,23 @@ use SimpleSAML\Module\accounting\Exceptions\UnexpectedValueException; use SimpleSAML\Module\accounting\Helpers\InstanceBuilderUsingModuleConfigurationHelper; use SimpleSAML\Module\accounting\ModuleConfiguration; use SimpleSAML\Module\accounting\Providers\Interfaces\AuthenticationDataProviderInterface; +use SimpleSAML\Module\accounting\Services\HelpersManager; use Throwable; class AuthenticationDataProviderBuilder { protected ModuleConfiguration $moduleConfiguration; protected LoggerInterface $logger; + protected HelpersManager $helpersManager; - public function __construct(ModuleConfiguration $moduleConfiguration, LoggerInterface $logger) - { + public function __construct( + ModuleConfiguration $moduleConfiguration, + LoggerInterface $logger, + HelpersManager $helpersManager + ) { $this->moduleConfiguration = $moduleConfiguration; $this->logger = $logger; + $this->helpersManager = $helpersManager; } /** @@ -43,7 +49,7 @@ class AuthenticationDataProviderBuilder // Build... /** @var AuthenticationDataProviderInterface $store */ - $store = InstanceBuilderUsingModuleConfigurationHelper::build( + $store = $this->helpersManager->getInstanceBuilderUsingModuleConfigurationHelper()->build( $class, $this->moduleConfiguration, $this->logger, diff --git a/src/Services/HelpersManager.php b/src/Services/HelpersManager.php index 43b85fecdd5b25355bfa366b115dd1b55022927e..e66518fa691269da596f533a7451013f1878c604 100644 --- a/src/Services/HelpersManager.php +++ b/src/Services/HelpersManager.php @@ -4,8 +4,14 @@ declare(strict_types=1); namespace SimpleSAML\Module\accounting\Services; +use SimpleSAML\Module\accounting\Helpers\ArrayHelper; +use SimpleSAML\Module\accounting\Helpers\AttributesHelper; use SimpleSAML\Module\accounting\Helpers\DateTimeHelper; use SimpleSAML\Module\accounting\Helpers\EnvironmentHelper; +use SimpleSAML\Module\accounting\Helpers\FilesystemHelper; +use SimpleSAML\Module\accounting\Helpers\HashHelper; +use SimpleSAML\Module\accounting\Helpers\InstanceBuilderUsingModuleConfigurationHelper; +use SimpleSAML\Module\accounting\Helpers\NetworkHelper; use SimpleSAML\Module\accounting\Helpers\RandomHelper; use SimpleSAML\Module\accounting\Helpers\ModuleRoutesHelper; @@ -15,6 +21,12 @@ class HelpersManager protected static ?EnvironmentHelper $environmentHelper; protected static ?RandomHelper $randomHelper; protected static ?ModuleRoutesHelper $routesHelper; + protected static ?ArrayHelper $arrayHelper; + protected static ?HashHelper $hashHelper; + protected static ?AttributesHelper $attributesHelper; + protected static ?FilesystemHelper $filesystemHelper; + protected static ?InstanceBuilderUsingModuleConfigurationHelper $instanceBuilderHelper; + protected static ?NetworkHelper $networkHelper; public function getDateTimeHelper(): DateTimeHelper { @@ -35,4 +47,34 @@ class HelpersManager { return self::$routesHelper ??= new ModuleRoutesHelper(); } + + public function getArrayHelper(): ArrayHelper + { + return self::$arrayHelper ??= new ArrayHelper(); + } + + public function getHashHelper(): HashHelper + { + return self::$hashHelper ??= new HashHelper($this->getArrayHelper()); + } + + public function getAttributesHelper(): AttributesHelper + { + return self::$attributesHelper ??= new AttributesHelper(); + } + + public function getFilesystemHelper(): FilesystemHelper + { + return self::$filesystemHelper ??= new FilesystemHelper(); + } + + public function getInstanceBuilderUsingModuleConfigurationHelper(): InstanceBuilderUsingModuleConfigurationHelper + { + return self::$instanceBuilderHelper ??= new InstanceBuilderUsingModuleConfigurationHelper(); + } + + public function getNetworkHelper(): NetworkHelper + { + return self::$networkHelper ??= new NetworkHelper(); + } } diff --git a/src/Services/JobRunner.php b/src/Services/JobRunner.php index 9735bfa3ce3c65c124b09265bdec2c60d4f24d3a..eb179489a113a185c12d7f411f0e188e2aa76ada 100644 --- a/src/Services/JobRunner.php +++ b/src/Services/JobRunner.php @@ -53,24 +53,25 @@ class JobRunner ModuleConfiguration $moduleConfiguration, SspConfiguration $sspConfiguration, LoggerInterface $logger = null, + HelpersManager $helpersManager = null, AuthenticationDataTrackerBuilder $authenticationDataTrackerBuilder = null, JobsStoreBuilder $jobsStoreBuilder = null, CacheInterface $cache = null, State $state = null, - RateLimiter $rateLimiter = null, - HelpersManager $helpersManager = null + RateLimiter $rateLimiter = null ) { $this->moduleConfiguration = $moduleConfiguration; $this->sspConfiguration = $sspConfiguration; $this->logger = $logger ?? new Logger(); + $this->helpersManager = $helpersManager ?? new HelpersManager(); + $this->authenticationDataTrackerBuilder = $authenticationDataTrackerBuilder ?? - new AuthenticationDataTrackerBuilder($this->moduleConfiguration, $this->logger); - $this->jobsStoreBuilder = $jobsStoreBuilder ?? new JobsStoreBuilder($this->moduleConfiguration, $this->logger); + new AuthenticationDataTrackerBuilder($this->moduleConfiguration, $this->logger, $this->helpersManager); + $this->jobsStoreBuilder = $jobsStoreBuilder ?? + new JobsStoreBuilder($this->moduleConfiguration, $this->logger, $this->helpersManager); $this->cache = $cache ?? $this->resolveCache(); - $this->helpersManager = $helpersManager ?? new HelpersManager(); - $this->jobRunnerId = $this->helpersManager->getRandomHelper()->getRandomInt(); $this->state = $state ?? new State($this->jobRunnerId); diff --git a/src/Stores/Builders/Bases/AbstractStoreBuilder.php b/src/Stores/Builders/Bases/AbstractStoreBuilder.php index 7e96d3fc0d6b1f0191935f098238ea60f6a95d97..5cce33d23c7d4e885ede1e5d9e4af5316e94ec2d 100644 --- a/src/Stores/Builders/Bases/AbstractStoreBuilder.php +++ b/src/Stores/Builders/Bases/AbstractStoreBuilder.php @@ -6,8 +6,8 @@ namespace SimpleSAML\Module\accounting\Stores\Builders\Bases; use Psr\Log\LoggerInterface; use SimpleSAML\Module\accounting\Exceptions\StoreException; -use SimpleSAML\Module\accounting\Helpers\InstanceBuilderUsingModuleConfigurationHelper; use SimpleSAML\Module\accounting\ModuleConfiguration; +use SimpleSAML\Module\accounting\Services\HelpersManager; use SimpleSAML\Module\accounting\Stores\Interfaces\StoreInterface; use Throwable; @@ -18,11 +18,16 @@ abstract class AbstractStoreBuilder { protected ModuleConfiguration $moduleConfiguration; protected LoggerInterface $logger; + protected HelpersManager $helpersManager; - public function __construct(ModuleConfiguration $moduleConfiguration, LoggerInterface $logger) - { + public function __construct( + ModuleConfiguration $moduleConfiguration, + LoggerInterface $logger, + HelpersManager $helpersManager + ) { $this->moduleConfiguration = $moduleConfiguration; $this->logger = $logger; + $this->helpersManager = $helpersManager; } abstract public function build( @@ -44,7 +49,7 @@ abstract class AbstractStoreBuilder // Build store... /** @var StoreInterface $store */ - $store = InstanceBuilderUsingModuleConfigurationHelper::build( + $store = $this->helpersManager->getInstanceBuilderUsingModuleConfigurationHelper()->build( $class, $this->moduleConfiguration, $this->logger, diff --git a/src/Stores/Connections/Bases/AbstractMigrator.php b/src/Stores/Connections/Bases/AbstractMigrator.php index 613efc1b6cd5eb47853cbe0471d6b774f54f8ff8..2cdb590c78825979a5895e3dd80a4308e57d7270 100644 --- a/src/Stores/Connections/Bases/AbstractMigrator.php +++ b/src/Stores/Connections/Bases/AbstractMigrator.php @@ -7,6 +7,7 @@ namespace SimpleSAML\Module\accounting\Stores\Connections\Bases; use SimpleSAML\Module\accounting\Exceptions\InvalidValueException; use SimpleSAML\Module\accounting\Exceptions\StoreException\MigrationException; use SimpleSAML\Module\accounting\Helpers\FilesystemHelper; +use SimpleSAML\Module\accounting\Services\HelpersManager; use SimpleSAML\Module\accounting\Stores\Interfaces\MigrationInterface; use Throwable; @@ -14,6 +15,13 @@ abstract class AbstractMigrator { public const DEFAULT_MIGRATIONS_DIRECTORY_NAME = 'Migrations'; + protected HelpersManager $helpersManager; + + public function __construct(HelpersManager $helpersManager = null) + { + $this->helpersManager = $helpersManager ?? new HelpersManager(); + } + /** * @param string $directory * @param string $namespace @@ -21,7 +29,7 @@ abstract class AbstractMigrator */ public function gatherMigrationClassesFromDirectory(string $directory, string $namespace): array { - $directory = FilesystemHelper::getRealPath($directory); + $directory = $this->helpersManager->getFilesystemHelper()->getRealPath($directory); // Get files without dot directories $files = array_values(array_diff(scandir($directory), ['..', '.'])); diff --git a/src/Stores/Connections/DoctrineDbal/Migrator.php b/src/Stores/Connections/DoctrineDbal/Migrator.php index 5c7250f2c9b8e80c51c0ee2ddef134acfb8bb742..80464462def1241e26a7e54ccee8f60c323f94d3 100644 --- a/src/Stores/Connections/DoctrineDbal/Migrator.php +++ b/src/Stores/Connections/DoctrineDbal/Migrator.php @@ -13,6 +13,7 @@ use ReflectionClass; use ReflectionException; use SimpleSAML\Module\accounting\Exceptions\InvalidValueException; use SimpleSAML\Module\accounting\Exceptions\StoreException; +use SimpleSAML\Module\accounting\Services\HelpersManager; use SimpleSAML\Module\accounting\Stores\Connections\Bases\AbstractMigrator; use SimpleSAML\Module\accounting\Stores\Connections\DoctrineDbal\Bases\AbstractMigration; use SimpleSAML\Module\accounting\Stores\Interfaces\MigrationInterface; @@ -35,8 +36,10 @@ class Migrator extends AbstractMigrator /** * @throws StoreException */ - public function __construct(Connection $connection, LoggerInterface $logger) + public function __construct(Connection $connection, LoggerInterface $logger, HelpersManager $helpersManager = null) { + parent::__construct($helpersManager); + $this->connection = $connection; $this->logger = $logger; diff --git a/src/Stores/Data/Authentication/DoctrineDbal/Versioned/Store.php b/src/Stores/Data/Authentication/DoctrineDbal/Versioned/Store.php index aecebb226923ceef769a2abac1e38ae5cee2a0f4..8bfaed51b7781c92aad3e04f82d409359a13c0c4 100644 --- a/src/Stores/Data/Authentication/DoctrineDbal/Versioned/Store.php +++ b/src/Stores/Data/Authentication/DoctrineDbal/Versioned/Store.php @@ -12,8 +12,8 @@ use SimpleSAML\Module\accounting\Entities\ServiceProvider; use SimpleSAML\Module\accounting\Entities\User; use SimpleSAML\Module\accounting\Exceptions\StoreException; use SimpleSAML\Module\accounting\Exceptions\UnexpectedValueException; -use SimpleSAML\Module\accounting\Helpers\HashHelper; use SimpleSAML\Module\accounting\ModuleConfiguration; +use SimpleSAML\Module\accounting\Services\HelpersManager; use SimpleSAML\Module\accounting\Stores\Bases\DoctrineDbal\AbstractStore; use SimpleSAML\Module\accounting\Stores\Connections\DoctrineDbal\Factory; use SimpleSAML\Module\accounting\Stores\Data\Authentication\DoctrineDbal\Versioned\Store\HashDecoratedState; @@ -25,6 +25,7 @@ use SimpleSAML\Module\accounting\Stores\Interfaces\DataStoreInterface; class Store extends AbstractStore implements DataStoreInterface { protected Repository $repository; + protected HelpersManager $helpersManager; /** * @throws StoreException @@ -35,11 +36,13 @@ class Store extends AbstractStore implements DataStoreInterface Factory $connectionFactory, string $connectionKey = null, string $connectionType = ModuleConfiguration\ConnectionType::MASTER, - Repository $repository = null + Repository $repository = null, + HelpersManager $helpersManager = null ) { parent::__construct($moduleConfiguration, $logger, $connectionFactory, $connectionKey, $connectionType); $this->repository = $repository ?? new Repository($this->connection, $this->logger); + $this->helpersManager = $helpersManager ?? new HelpersManager(); } /** @@ -76,8 +79,11 @@ class Store extends AbstractStore implements DataStoreInterface $userVersionId = $this->resolveUserVersionId($userId, $hashDecoratedState); $idpSpUserVersionId = $this->resolveIdpSpUserVersionId($idpVersionId, $spVersionId, $userVersionId); - $happenedAt = $authenticationEvent->getHappenedAt(); - $this->repository->insertAuthenticationEvent($idpSpUserVersionId, $happenedAt); + $this->repository->insertAuthenticationEvent( + $idpSpUserVersionId, + $authenticationEvent->getHappenedAt(), + $authenticationEvent->getState()->getClientIpAddress() + ); } /** @@ -308,7 +314,7 @@ class Store extends AbstractStore implements DataStoreInterface throw new UnexpectedValueException($message); } - $userIdentifierValueHashSha256 = HashHelper::getSha256($userIdentifierValue); + $userIdentifierValueHashSha256 = $this->helpersManager->getHashHelper()->getSha256($userIdentifierValue); // Check if it already exists. try { @@ -596,7 +602,12 @@ class Store extends AbstractStore implements DataStoreInterface $user = new User($rawActivity->getUserAttributes()); $activityBag->add( - new Activity($serviceProvider, $user, $rawActivity->getHappenedAt()) + new Activity( + $serviceProvider, + $user, + $rawActivity->getHappenedAt(), + $rawActivity->getClientIpAddress() + ) ); } } catch (\Throwable $exception) { diff --git a/src/Stores/Data/Authentication/DoctrineDbal/Versioned/Store/HashDecoratedState.php b/src/Stores/Data/Authentication/DoctrineDbal/Versioned/Store/HashDecoratedState.php index f349682236936540bc54a559630753096c227eb4..6811a67f59fcccdd6eac391abf89ad0480de81c5 100644 --- a/src/Stores/Data/Authentication/DoctrineDbal/Versioned/Store/HashDecoratedState.php +++ b/src/Stores/Data/Authentication/DoctrineDbal/Versioned/Store/HashDecoratedState.php @@ -1,32 +1,40 @@ <?php +declare(strict_types=1); + namespace SimpleSAML\Module\accounting\Stores\Data\Authentication\DoctrineDbal\Versioned\Store; use SimpleSAML\Module\accounting\Entities\Authentication\State; -use SimpleSAML\Module\accounting\Helpers\HashHelper; +use SimpleSAML\Module\accounting\Services\HelpersManager; class HashDecoratedState { protected State $state; + protected HelpersManager $helpersManager; + protected string $identityProviderEntityIdHashSha256; protected string $serviceProviderEntityIdHashSha256; protected string $identityProviderMetadataArrayHashSha256; protected string $serviceProviderMetadataArrayHashSha256; protected string $attributesArrayHashSha256; - public function __construct(State $state) + public function __construct(State $state, HelpersManager $helpersManager = null) { $this->state = $state; + $this->helpersManager = $helpersManager ?? new HelpersManager(); - $this->identityProviderEntityIdHashSha256 = HashHelper::getSha256($state->getIdentityProviderEntityId()); - $this->identityProviderMetadataArrayHashSha256 = - HashHelper::getSha256ForArray($state->getIdentityProviderMetadata()); + $this->identityProviderEntityIdHashSha256 = $this->helpersManager->getHashHelper() + ->getSha256($state->getIdentityProviderEntityId()); + $this->identityProviderMetadataArrayHashSha256 = $this->helpersManager->getHashHelper() + ->getSha256ForArray($state->getIdentityProviderMetadata()); - $this->serviceProviderEntityIdHashSha256 = HashHelper::getSha256($state->getServiceProviderEntityId()); - $this->serviceProviderMetadataArrayHashSha256 = - HashHelper::getSha256ForArray($state->getServiceProviderMetadata()); + $this->serviceProviderEntityIdHashSha256 = $this->helpersManager->getHashHelper() + ->getSha256($state->getServiceProviderEntityId()); + $this->serviceProviderMetadataArrayHashSha256 = $this->helpersManager->getHashHelper() + ->getSha256ForArray($state->getServiceProviderMetadata()); - $this->attributesArrayHashSha256 = HashHelper::getSha256ForArray($state->getAttributes()); + $this->attributesArrayHashSha256 = $this->helpersManager->getHashHelper() + ->getSha256ForArray($state->getAttributes()); } /** diff --git a/src/Stores/Data/Authentication/DoctrineDbal/Versioned/Store/Migrations/Version20220801000700CreateAuthenticationEventTable.php b/src/Stores/Data/Authentication/DoctrineDbal/Versioned/Store/Migrations/Version20220801000700CreateAuthenticationEventTable.php index d56082275448d94f189dfbb22b81f0b6404c3f9c..87938387f3de5f4a645b1b94e6d97928769802bd 100644 --- a/src/Stores/Data/Authentication/DoctrineDbal/Versioned/Store/Migrations/Version20220801000700CreateAuthenticationEventTable.php +++ b/src/Stores/Data/Authentication/DoctrineDbal/Versioned/Store/Migrations/Version20220801000700CreateAuthenticationEventTable.php @@ -36,6 +36,10 @@ class Version20220801000700CreateAuthenticationEventTable extends AbstractMigrat $table->addColumn('happened_at', Types::DATETIMETZ_IMMUTABLE); + $table->addColumn('client_ip_address', Types::STRING) + ->setLength(TableConstants::COLUMN_IP_ADDRESS_LENGTH) + ->setNotnull(false); + $table->addColumn('created_at', Types::DATETIMETZ_IMMUTABLE); $table->setPrimaryKey(['id']); diff --git a/src/Stores/Data/Authentication/DoctrineDbal/Versioned/Store/RawActivity.php b/src/Stores/Data/Authentication/DoctrineDbal/Versioned/Store/RawActivity.php index 8a1f7f60ece229149941f7835aca5c343a354129..17fb9e3528b47bd1e36b5a94cfabeda43328cf55 100644 --- a/src/Stores/Data/Authentication/DoctrineDbal/Versioned/Store/RawActivity.php +++ b/src/Stores/Data/Authentication/DoctrineDbal/Versioned/Store/RawActivity.php @@ -14,6 +14,7 @@ class RawActivity extends AbstractRawEntity protected array $serviceProviderMetadata; protected array $userAttributes; protected DateTimeImmutable $happenedAt; + protected ?string $clientIpAddress; public function __construct(array $rawRow, AbstractPlatform $abstractPlatform) { @@ -30,6 +31,10 @@ class RawActivity extends AbstractRawEntity $this->happenedAt = $this->resolveDateTimeImmutable( $rawRow[TableConstants::ENTITY_ACTIVITY_COLUMN_NAME_HAPPENED_AT] ); + + $this->clientIpAddress = empty($rawRow[TableConstants::ENTITY_ACTIVITY_COLUMN_NAME_CLIENT_IP_ADDRESS]) ? + null : + (string)$rawRow[TableConstants::ENTITY_ACTIVITY_COLUMN_NAME_CLIENT_IP_ADDRESS]; } /** @@ -56,6 +61,14 @@ class RawActivity extends AbstractRawEntity return $this->userAttributes; } + /** + * @return string|null + */ + public function getClientIpAddress(): ?string + { + return $this->clientIpAddress; + } + /** * @inheritDoc */ diff --git a/src/Stores/Data/Authentication/DoctrineDbal/Versioned/Store/Repository.php b/src/Stores/Data/Authentication/DoctrineDbal/Versioned/Store/Repository.php index 976837ca24ce5d01e3d89f3831ef884d98f6bae8..0c198896eea6dec297fd2b4270c15cc955bf2cb4 100644 --- a/src/Stores/Data/Authentication/DoctrineDbal/Versioned/Store/Repository.php +++ b/src/Stores/Data/Authentication/DoctrineDbal/Versioned/Store/Repository.php @@ -654,6 +654,7 @@ class Repository public function insertAuthenticationEvent( int $IdpSpUserVersionId, \DateTimeImmutable $happenedAt, + string $clientIpAddress = null, \DateTimeImmutable $createdAt = null ): void { try { @@ -668,6 +669,8 @@ class Repository TableConstants::TABLE_AUTHENTICATION_EVENT_COLUMN_NAME_IDP_SP_USER_VERSION_ID, TableConstants::TABLE_AUTHENTICATION_EVENT_COLUMN_NAME_HAPPENED_AT => ':' . TableConstants::TABLE_AUTHENTICATION_EVENT_COLUMN_NAME_HAPPENED_AT, + TableConstants::TABLE_AUTHENTICATION_EVENT_COLUMN_NAME_CLIENT_IP_ADDRESS => ':' . + TableConstants::TABLE_AUTHENTICATION_EVENT_COLUMN_NAME_CLIENT_IP_ADDRESS, TableConstants::TABLE_AUTHENTICATION_EVENT_COLUMN_NAME_CREATED_AT => ':' . TableConstants::TABLE_AUTHENTICATION_EVENT_COLUMN_NAME_CREATED_AT, ] @@ -677,6 +680,7 @@ class Repository TableConstants::TABLE_AUTHENTICATION_EVENT_COLUMN_NAME_IDP_SP_USER_VERSION_ID => $IdpSpUserVersionId, TableConstants::TABLE_AUTHENTICATION_EVENT_COLUMN_NAME_HAPPENED_AT => $happenedAt, + TableConstants::TABLE_AUTHENTICATION_EVENT_COLUMN_NAME_CLIENT_IP_ADDRESS => $clientIpAddress, TableConstants::TABLE_AUTHENTICATION_EVENT_COLUMN_NAME_CREATED_AT => $createdAt, ], [ @@ -684,6 +688,8 @@ class Repository Types::BIGINT, TableConstants::TABLE_AUTHENTICATION_EVENT_COLUMN_NAME_HAPPENED_AT => Types::DATETIMETZ_IMMUTABLE, + TableConstants::TABLE_AUTHENTICATION_EVENT_COLUMN_NAME_CLIENT_IP_ADDRESS => + Types::STRING, TableConstants::TABLE_AUTHENTICATION_EVENT_COLUMN_NAME_CREATED_AT => Types::DATETIMETZ_IMMUTABLE, ] @@ -961,6 +967,8 @@ class Repository //'vae.happened_at', TableConstants::TABLE_ALIAS_AUTHENTICATION_EVENT . '.' . TableConstants::TABLE_AUTHENTICATION_EVENT_COLUMN_NAME_HAPPENED_AT, + TableConstants::TABLE_ALIAS_AUTHENTICATION_EVENT . '.' . + TableConstants::TABLE_AUTHENTICATION_EVENT_COLUMN_NAME_CLIENT_IP_ADDRESS, //'vsv.metadata AS sp_metadata', TableConstants::TABLE_ALIAS_SP_VERSION . '.' . TableConstants::TABLE_SP_VERSION_COLUMN_NAME_METADATA . ' AS ' . TableConstants::ENTITY_ACTIVITY_COLUMN_NAME_SP_METADATA, diff --git a/src/Stores/Data/Authentication/DoctrineDbal/Versioned/Store/TableConstants.php b/src/Stores/Data/Authentication/DoctrineDbal/Versioned/Store/TableConstants.php index 30aa9a5a76a8b6114df8a7a97915d716604ee3ce..532a8c7325f7249d70cdfcc5c335db7206089fb7 100644 --- a/src/Stores/Data/Authentication/DoctrineDbal/Versioned/Store/TableConstants.php +++ b/src/Stores/Data/Authentication/DoctrineDbal/Versioned/Store/TableConstants.php @@ -12,6 +12,7 @@ class TableConstants // https://stackoverflow.com/questions/24196369/what-to-present-at-saml-entityid-url public const COLUMN_ENTITY_ID_LENGTH = 1024; public const COLUMN_HASH_SHA265_HEXITS_LENGTH = 64; + public const COLUMN_IP_ADDRESS_LENGTH = 45; // Table 'idp' @@ -82,6 +83,7 @@ class TableConstants public const TABLE_AUTHENTICATION_EVENT_COLUMN_NAME_ID = 'id'; public const TABLE_AUTHENTICATION_EVENT_COLUMN_NAME_IDP_SP_USER_VERSION_ID = 'idp_sp_user_version_id'; public const TABLE_AUTHENTICATION_EVENT_COLUMN_NAME_HAPPENED_AT = 'happened_at'; + public const TABLE_AUTHENTICATION_EVENT_COLUMN_NAME_CLIENT_IP_ADDRESS = 'client_ip_address'; public const TABLE_AUTHENTICATION_EVENT_COLUMN_NAME_CREATED_AT = 'created_at'; // Entity 'ConnectedOrganization' (service provider) related. @@ -96,4 +98,5 @@ class TableConstants public const ENTITY_ACTIVITY_COLUMN_NAME_SP_METADATA = 'sp_metadata'; public const ENTITY_ACTIVITY_COLUMN_NAME_USER_ATTRIBUTES = 'user_attributes'; public const ENTITY_ACTIVITY_COLUMN_NAME_HAPPENED_AT = 'happened_at'; + public const ENTITY_ACTIVITY_COLUMN_NAME_CLIENT_IP_ADDRESS = 'client_ip_address'; } diff --git a/src/Trackers/Authentication/DoctrineDbal/Versioned/Tracker.php b/src/Trackers/Authentication/DoctrineDbal/Versioned/Tracker.php index 6c70e4c9a4582c9f73b9a9fe0cc4a4b034a87608..e974e9a2243f587339f2f09c586e04646443bdef 100644 --- a/src/Trackers/Authentication/DoctrineDbal/Versioned/Tracker.php +++ b/src/Trackers/Authentication/DoctrineDbal/Versioned/Tracker.php @@ -8,9 +8,9 @@ use Psr\Log\LoggerInterface; use SimpleSAML\Module\accounting\Entities\Activity; use SimpleSAML\Module\accounting\Entities\Authentication\Event; use SimpleSAML\Module\accounting\Entities\ConnectedServiceProvider; -use SimpleSAML\Module\accounting\Helpers\HashHelper; use SimpleSAML\Module\accounting\ModuleConfiguration; use SimpleSAML\Module\accounting\Providers\Interfaces\AuthenticationDataProviderInterface; +use SimpleSAML\Module\accounting\Services\HelpersManager; use SimpleSAML\Module\accounting\Stores\Builders\DataStoreBuilder; use SimpleSAML\Module\accounting\Stores\Data\Authentication\DoctrineDbal\Versioned\Store; use SimpleSAML\Module\accounting\Stores\Interfaces\DataStoreInterface; @@ -21,19 +21,23 @@ class Tracker implements AuthenticationDataTrackerInterface, AuthenticationDataP protected ModuleConfiguration $moduleConfiguration; protected LoggerInterface $logger; protected DataStoreInterface $dataStore; + protected HelpersManager $helpersManager; public function __construct( ModuleConfiguration $moduleConfiguration, LoggerInterface $logger, string $connectionType = ModuleConfiguration\ConnectionType::MASTER, + HelpersManager $helpersManager = null, DataStoreInterface $dataStore = null ) { $this->moduleConfiguration = $moduleConfiguration; $this->logger = $logger; + $this->helpersManager = $helpersManager ?? new HelpersManager(); + // Use provided store or initialize default store for this tracker. $this->dataStore = $dataStore ?? - (new DataStoreBuilder($this->moduleConfiguration, $this->logger)) + (new DataStoreBuilder($this->moduleConfiguration, $this->logger, $this->helpersManager)) ->build( Store::class, $this->moduleConfiguration->getClassConnectionKey(self::class), @@ -71,13 +75,13 @@ class Tracker implements AuthenticationDataTrackerInterface, AuthenticationDataP public function getConnectedServiceProviders(string $userIdentifier): ConnectedServiceProvider\Bag { - $userIdentifierHashSha256 = HashHelper::getSha256($userIdentifier); + $userIdentifierHashSha256 = $this->helpersManager->getHashHelper()->getSha256($userIdentifier); return $this->dataStore->getConnectedOrganizations($userIdentifierHashSha256); } public function getActivity(string $userIdentifier, int $maxResults, int $firstResult): Activity\Bag { - $userIdentifierHashSha256 = HashHelper::getSha256($userIdentifier); + $userIdentifierHashSha256 = $this->helpersManager->getHashHelper()->getSha256($userIdentifier); return $this->dataStore->getActivity($userIdentifierHashSha256, $maxResults, $firstResult); } } diff --git a/src/Trackers/Builders/AuthenticationDataTrackerBuilder.php b/src/Trackers/Builders/AuthenticationDataTrackerBuilder.php index e584a6c9f8ed930200ea2a4087f4b00599b922ee..388338d13de848a44b020c25d3d9131ac541738a 100644 --- a/src/Trackers/Builders/AuthenticationDataTrackerBuilder.php +++ b/src/Trackers/Builders/AuthenticationDataTrackerBuilder.php @@ -7,6 +7,7 @@ use SimpleSAML\Module\accounting\Exceptions\Exception; use SimpleSAML\Module\accounting\Exceptions\UnexpectedValueException; use SimpleSAML\Module\accounting\Helpers\InstanceBuilderUsingModuleConfigurationHelper; use SimpleSAML\Module\accounting\ModuleConfiguration; +use SimpleSAML\Module\accounting\Services\HelpersManager; use SimpleSAML\Module\accounting\Trackers\Interfaces\AuthenticationDataTrackerInterface; use Throwable; @@ -14,11 +15,16 @@ class AuthenticationDataTrackerBuilder { protected ModuleConfiguration $moduleConfiguration; protected LoggerInterface $logger; + protected HelpersManager $helpersManager; - public function __construct(ModuleConfiguration $moduleConfiguration, LoggerInterface $logger) - { + public function __construct( + ModuleConfiguration $moduleConfiguration, + LoggerInterface $logger, + HelpersManager $helpersManager + ) { $this->moduleConfiguration = $moduleConfiguration; $this->logger = $logger; + $this->helpersManager = $helpersManager; } /** @@ -39,7 +45,7 @@ class AuthenticationDataTrackerBuilder // Build... /** @var AuthenticationDataTrackerInterface $store */ - $store = InstanceBuilderUsingModuleConfigurationHelper::build( + $store = $this->helpersManager->getInstanceBuilderUsingModuleConfigurationHelper()->build( $class, $this->moduleConfiguration, $this->logger diff --git a/templates/user/activity.twig b/templates/user/activity.twig index c505f4349b6a2125611e326c1b5dafce104a7db7..5f77015382f7be5ffaa6e3ff22e554ad33ffd11a 100644 --- a/templates/user/activity.twig +++ b/templates/user/activity.twig @@ -32,6 +32,9 @@ </tr> <tr class="panel"> <td colspan="3"> + <strong>{{ 'IP address'|trans }}</strong> + <ul><li>{{ activity.getClientIpAddress }}</li></ul> + <strong>{{ 'Information transfered to service'|trans }}</strong> <ul> {% for name, value in activity.getUser.getAttributes %} @@ -42,6 +45,10 @@ </ul> </td> </tr> + {% else %} + <tr> + <td colspan="3">{{ 'No data available'|trans }}</td> + </tr> {% endfor %} </tbody> </table> diff --git a/templates/user/connected-organizations.twig b/templates/user/connected-organizations.twig index 0229fc575914a778db484bf43d9b5b3cc70d339f..0d5a57849814c6b3e21e6f52c19dda0250ca6395 100644 --- a/templates/user/connected-organizations.twig +++ b/templates/user/connected-organizations.twig @@ -54,6 +54,10 @@ </ul> </td> </tr> + {% else %} + <tr> + <td colspan="3">{{ 'No data available'|trans }}</td> + </tr> {% endfor %} </tbody> </table> diff --git a/tests/config-templates/invalid_array_value_module_accounting.php b/tests/config-templates/invalid_array_value_module_accounting.php deleted file mode 100644 index b5f3c8a7bca75dc435b7b801a1e48d989dc0766e..0000000000000000000000000000000000000000 --- a/tests/config-templates/invalid_array_value_module_accounting.php +++ /dev/null @@ -1,37 +0,0 @@ -<?php - -declare(strict_types=1); - -use SimpleSAML\Module\accounting\ModuleConfiguration; -use SimpleSAML\Module\accounting\Stores; -use SimpleSAML\Module\accounting\Trackers; - -$config = [ - ModuleConfiguration::OPTION_USER_ID_ATTRIBUTE_NAME => 'urn:oasis:names:tc:SAML:attribute:subject-id', - - ModuleConfiguration::OPTION_ACCOUNTING_PROCESSING_TYPE => - ModuleConfiguration\AccountingProcessingType::VALUE_SYNCHRONOUS, - - ModuleConfiguration::OPTION_JOBS_STORE => Stores\Jobs\DoctrineDbal\Store::class, - - ModuleConfiguration::OPTION_DEFAULT_DATA_TRACKER_AND_PROVIDER => - Trackers\Authentication\DoctrineDbal\Versioned\Tracker::class, - - ModuleConfiguration::OPTION_CLASS_TO_CONNECTION_MAP => [ - 'invalid-array-value' => [ - 'no-master-key' => 'invalid', - ], - ], - ModuleConfiguration::OPTION_ADDITIONAL_TRACKERS => [ - 'invalid', - ], - - ModuleConfiguration::OPTION_CONNECTIONS_AND_PARAMETERS => [ - 'doctrine_dbal_pdo_mysql' => [ - 'driver' => 'pdo_mysql', - ], - 'doctrine_dbal_pdo_sqlite' => [ - 'driver' => 'pdo_sqlite', - ], - ], -]; diff --git a/tests/config-templates/invalid_async_module_accounting.php b/tests/config-templates/invalid_async_module_accounting.php deleted file mode 100644 index 77a3517abfce30e0a334f063a1ecea333492a065..0000000000000000000000000000000000000000 --- a/tests/config-templates/invalid_async_module_accounting.php +++ /dev/null @@ -1,35 +0,0 @@ -<?php - -declare(strict_types=1); - -use SimpleSAML\Module\accounting\ModuleConfiguration; -use SimpleSAML\Module\accounting\Stores; -use SimpleSAML\Module\accounting\Trackers; - -$config = [ - ModuleConfiguration::OPTION_USER_ID_ATTRIBUTE_NAME => 'urn:oasis:names:tc:SAML:attribute:subject-id', - - ModuleConfiguration::OPTION_ACCOUNTING_PROCESSING_TYPE => - ModuleConfiguration\AccountingProcessingType::VALUE_ASYNCHRONOUS, - - ModuleConfiguration::OPTION_JOBS_STORE => 'invalid', - - ModuleConfiguration::OPTION_DEFAULT_DATA_TRACKER_AND_PROVIDER => 'invalid', - - ModuleConfiguration::OPTION_ADDITIONAL_TRACKERS => [ - 'invalid', - ], - - ModuleConfiguration::OPTION_CLASS_TO_CONNECTION_MAP => [ - 'invalid' - ], - - ModuleConfiguration::OPTION_CONNECTIONS_AND_PARAMETERS => [ - 'doctrine_dbal_pdo_mysql' => [ - 'driver' => 'pdo_mysql', - ], - 'doctrine_dbal_pdo_sqlite' => [ - 'driver' => 'pdo_sqlite', - ], - ], -]; diff --git a/tests/config-templates/invalid_module_accounting.php b/tests/config-templates/invalid_module_accounting.php deleted file mode 100644 index 5a700dbcb4ea13102ed5a7bd1fe871cfa5109910..0000000000000000000000000000000000000000 --- a/tests/config-templates/invalid_module_accounting.php +++ /dev/null @@ -1,46 +0,0 @@ -<?php - -declare(strict_types=1); - -use SimpleSAML\Module\accounting\ModuleConfiguration; -use SimpleSAML\Module\accounting\Stores; -use SimpleSAML\Module\accounting\Trackers; - -$config = [ - ModuleConfiguration::OPTION_USER_ID_ATTRIBUTE_NAME => 'urn:oasis:names:tc:SAML:attribute:subject-id', - - ModuleConfiguration::OPTION_ACCOUNTING_PROCESSING_TYPE => 'invalid', - - ModuleConfiguration::OPTION_JOBS_STORE => 'invalid', - - ModuleConfiguration::OPTION_DEFAULT_DATA_TRACKER_AND_PROVIDER => 'invalid', - - ModuleConfiguration::OPTION_CLASS_TO_CONNECTION_MAP => [ - /** - * Connection key to be used by jobs store class. - */ - Stores\Jobs\DoctrineDbal\Store::class => 'invalid', - /** - * Connection key to be used by this data tracker and provider. - */ - Trackers\Authentication\DoctrineDbal\Versioned\Tracker::class => [ - ModuleConfiguration\ConnectionType::MASTER => 'invalid', - ModuleConfiguration\ConnectionType::SLAVE => [ - 'invalid', - ], - ], - ], - ModuleConfiguration::OPTION_ADDITIONAL_TRACKERS => [ - 'invalid', - ['invalid'] - ], - - ModuleConfiguration::OPTION_CONNECTIONS_AND_PARAMETERS => [ - 'doctrine_dbal_pdo_mysql' => [ - 'driver' => 'pdo_mysql', - ], - 'doctrine_dbal_pdo_sqlite' => [ - 'driver' => 'pdo_sqlite', - ], - ], -]; diff --git a/tests/config-templates/invalid_object_value_module_accounting.php b/tests/config-templates/invalid_object_value_module_accounting.php deleted file mode 100644 index 6c46610918610bac25f3adc7507da16c88cf84dc..0000000000000000000000000000000000000000 --- a/tests/config-templates/invalid_object_value_module_accounting.php +++ /dev/null @@ -1,35 +0,0 @@ -<?php - -declare(strict_types=1); - -use SimpleSAML\Module\accounting\ModuleConfiguration; -use SimpleSAML\Module\accounting\Stores; -use SimpleSAML\Module\accounting\Trackers; - -$config = [ - ModuleConfiguration::OPTION_USER_ID_ATTRIBUTE_NAME => 'urn:oasis:names:tc:SAML:attribute:subject-id', - - ModuleConfiguration::OPTION_ACCOUNTING_PROCESSING_TYPE => - ModuleConfiguration\AccountingProcessingType::VALUE_SYNCHRONOUS, - - ModuleConfiguration::OPTION_JOBS_STORE => Stores\Jobs\DoctrineDbal\Store::class, - - ModuleConfiguration::OPTION_DEFAULT_DATA_TRACKER_AND_PROVIDER => - Trackers\Authentication\DoctrineDbal\Versioned\Tracker::class, - - ModuleConfiguration::OPTION_CLASS_TO_CONNECTION_MAP => [ - 'invalid-object-value' => new stdClass(), - ], - ModuleConfiguration::OPTION_ADDITIONAL_TRACKERS => [ - 'invalid', - ], - - ModuleConfiguration::OPTION_CONNECTIONS_AND_PARAMETERS => [ - 'doctrine_dbal_pdo_mysql' => [ - 'driver' => 'pdo_mysql', - ], - 'doctrine_dbal_pdo_sqlite' => [ - 'driver' => 'pdo_sqlite', - ], - ], -]; diff --git a/tests/config-templates/module_accounting.php b/tests/config-templates/module_accounting.php index 60da309e0f79caa532a4c0f0b9d16d4972d62ad2..82daf2b42edd594c4368cf2efeb6c4019d02ff5d 100644 --- a/tests/config-templates/module_accounting.php +++ b/tests/config-templates/module_accounting.php @@ -49,4 +49,8 @@ $config = [ 'table_prefix' => '', ], ], + + ModuleConfiguration::OPTION_JOB_RUNNER_MAXIMUM_EXECUTION_TIME => null, + + ModuleConfiguration::OPTION_JOB_RUNNER_SHOULD_PAUSE_AFTER_NUMBER_OF_JOBS_PROCESSED => 10, ]; diff --git a/tests/src/Auth/Process/AccountingTest.php b/tests/src/Auth/Process/AccountingTest.php index c00dbfdc7478efe66a40a72001ba8bb845cef0fa..7e932e0856e83dfc5c9c624dbbda1d90df3ebb61 100644 --- a/tests/src/Auth/Process/AccountingTest.php +++ b/tests/src/Auth/Process/AccountingTest.php @@ -11,6 +11,7 @@ use SimpleSAML\Module\accounting\Entities\Authentication\Event; use SimpleSAML\Module\accounting\Entities\Authentication\State; use SimpleSAML\Module\accounting\Exceptions\InvalidConfigurationException; use SimpleSAML\Module\accounting\ModuleConfiguration; +use SimpleSAML\Module\accounting\Services\HelpersManager; use SimpleSAML\Module\accounting\Stores\Builders\JobsStoreBuilder; use SimpleSAML\Module\accounting\Stores\Connections\DoctrineDbal\Connection; use SimpleSAML\Module\accounting\Stores\Connections\DoctrineDbal\Factory; @@ -31,6 +32,7 @@ use SimpleSAML\Test\Module\accounting\Constants\StateArrays; * @uses \SimpleSAML\Module\accounting\Entities\Authentication\Event\Job * @uses \SimpleSAML\Module\accounting\Entities\Bases\AbstractJob * @uses \SimpleSAML\Module\accounting\Helpers\NetworkHelper + * @uses \SimpleSAML\Module\accounting\Services\HelpersManager */ class AccountingTest extends TestCase { @@ -42,6 +44,27 @@ class AccountingTest extends TestCase protected \PHPUnit\Framework\MockObject\MockObject $jobsStoreMock; protected \PHPUnit\Framework\MockObject\MockObject $trackerMock; protected array $sampleState; + protected HelpersManager $helpersManager; + + protected function setUp(): void + { + $this->moduleConfigurationStub = $this->createStub(ModuleConfiguration::class); + + $this->loggerMock = $this->createMock(LoggerInterface::class); + + $this->jobsStoreBuilderMock = $this->createMock(JobsStoreBuilder::class); + $this->authenticationDataTrackerBuilderMock = + $this->createMock(AuthenticationDataTrackerBuilder::class); + + $this->jobsStoreMock = $this->createMock(Store::class); + $this->trackerMock = $this->createMock(Tracker::class); + + $this->sampleState = StateArrays::FULL; + + $this->filterConfig = []; + + $this->helpersManager = new HelpersManager(); + } public function testCanCreateInstance(): void { @@ -64,6 +87,7 @@ class AccountingTest extends TestCase null, $this->moduleConfigurationStub, $this->loggerMock, + $this->helpersManager, $this->jobsStoreBuilderMock, $this->authenticationDataTrackerBuilderMock ) @@ -96,6 +120,7 @@ class AccountingTest extends TestCase null, $this->moduleConfigurationStub, $this->loggerMock, + $this->helpersManager, $this->jobsStoreBuilderMock, $this->authenticationDataTrackerBuilderMock ))->process($this->sampleState); @@ -130,6 +155,7 @@ class AccountingTest extends TestCase null, $this->moduleConfigurationStub, $this->loggerMock, + $this->helpersManager, $this->jobsStoreBuilderMock, $this->authenticationDataTrackerBuilderMock ))->process($this->sampleState); @@ -148,26 +174,9 @@ class AccountingTest extends TestCase null, $this->moduleConfigurationStub, $this->loggerMock, + $this->helpersManager, $this->jobsStoreBuilderMock, $this->authenticationDataTrackerBuilderMock ))->process($this->sampleState); } - - protected function setUp(): void - { - $this->moduleConfigurationStub = $this->createStub(ModuleConfiguration::class); - - $this->loggerMock = $this->createMock(LoggerInterface::class); - - $this->jobsStoreBuilderMock = $this->createMock(JobsStoreBuilder::class); - $this->authenticationDataTrackerBuilderMock = - $this->createMock(AuthenticationDataTrackerBuilder::class); - - $this->jobsStoreMock = $this->createMock(Store::class); - $this->trackerMock = $this->createMock(Tracker::class); - - $this->sampleState = StateArrays::FULL; - - $this->filterConfig = []; - } } diff --git a/tests/src/Constants/RawRowResult.php b/tests/src/Constants/RawRowResult.php index f09e6fc597070ad9b05401e60fce97c1d276979d..e4224dfa1814ffbab19be377f82b74f1831d4abc 100644 --- a/tests/src/Constants/RawRowResult.php +++ b/tests/src/Constants/RawRowResult.php @@ -22,5 +22,6 @@ class RawRowResult TableConstants::ENTITY_ACTIVITY_COLUMN_NAME_HAPPENED_AT => '2022-02-22 22:22:22', TableConstants::ENTITY_ACTIVITY_COLUMN_NAME_SP_METADATA => 'a:9:{s:19:"SingleLogoutService";a:1:{i:0;a:2:{s:7:"Binding";s:50:"urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect";s:8:"Location";s:121:"https://pc-mivancic.srce.hr:9074/simplesamlphp/simplesamlphp-2-beta-git/module.php/saml/sp/singleLogoutService/default-sp";}}s:24:"AssertionConsumerService";a:2:{i:0;a:3:{s:7:"Binding";s:46:"urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST";s:8:"Location";s:126:"https://pc-mivancic.srce.hr:9074/simplesamlphp/simplesamlphp-2-beta-git/module.php/saml/sp/assertionConsumerService/default-sp";s:5:"index";i:0;}i:1;a:3:{s:7:"Binding";s:50:"urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Artifact";s:8:"Location";s:126:"https://pc-mivancic.srce.hr:9074/simplesamlphp/simplesamlphp-2-beta-git/module.php/saml/sp/assertionConsumerService/default-sp";s:5:"index";i:1;}}s:8:"contacts";a:1:{i:0;a:3:{s:12:"emailAddress";s:15:"mivanci@srce.hr";s:9:"givenName";s:15:"Marko Ivančić";s:11:"contactType";s:9:"technical";}}s:4:"name";a:1:{s:2:"en";s:12:"Test service";}s:11:"description";a:1:{s:2:"en";s:27:"Description of test service";}s:16:"OrganizationName";a:1:{s:2:"en";s:17:"Test organization";}s:8:"entityid";s:114:"https://pc-mivancic.srce.hr:9074/simplesamlphp/simplesamlphp-2-beta-git/module.php/saml/sp/metadata.php/default-sp";s:14:"metadata-index";s:114:"https://pc-mivancic.srce.hr:9074/simplesamlphp/simplesamlphp-2-beta-git/module.php/saml/sp/metadata.php/default-sp";s:12:"metadata-set";s:16:"saml20-sp-remote";}', TableConstants::ENTITY_ACTIVITY_COLUMN_NAME_USER_ATTRIBUTES => 'a:5:{s:33:"urn:oid:0.9.2342.19200300.100.1.1";a:1:{i:0;s:11:"student-uid";}s:32:"urn:oid:1.3.6.1.4.1.5923.1.1.1.1";a:2:{i:0;s:6:"member";i:1;s:7:"student";}s:15:"urn:oid:2.5.4.4";a:1:{i:0;s:10:"student-sn";}s:19:"hrEduPersonUniqueID";a:1:{i:0;s:19:"student@example.org";}s:23:"hrEduPersonPersistentID";a:1:{i:0;s:13:"student123abc";}}', + TableConstants::ENTITY_ACTIVITY_COLUMN_NAME_CLIENT_IP_ADDRESS => '172.21.0.1', ]; } diff --git a/tests/src/Entities/ActivityTest.php b/tests/src/Entities/ActivityTest.php index 2d647655b03313da163d6b6a60e106b8afcd64b3..2a35bd27f87167858eb63debcb1409ef8db4a3e6 100644 --- a/tests/src/Entities/ActivityTest.php +++ b/tests/src/Entities/ActivityTest.php @@ -23,12 +23,14 @@ class ActivityTest extends TestCase */ protected $userStub; protected \DateTimeImmutable $happenedAt; + protected string $clientIpAddress; public function setUp(): void { $this->serviceProviderStub = $this->createStub(ServiceProvider::class); $this->userStub = $this->createStub(User::class); $this->happenedAt = new \DateTimeImmutable(); + $this->clientIpAddress = '123.123.123.123'; } public function testCanCreateInstance(): void @@ -37,11 +39,13 @@ class ActivityTest extends TestCase $activity = new Activity( $this->serviceProviderStub, $this->userStub, - $this->happenedAt + $this->happenedAt, + $this->clientIpAddress ); $this->assertSame($this->serviceProviderStub, $activity->getServiceProvider()); $this->assertSame($this->userStub, $activity->getUser()); $this->assertSame($this->happenedAt, $activity->getHappenedAt()); + $this->assertSame($this->clientIpAddress, $activity->getClientIpAddress()); } } diff --git a/tests/src/Entities/Authentication/Event/JobTest.php b/tests/src/Entities/Authentication/Event/JobTest.php index 24551ef3409badd98cd82f8387a6f3c8bc5b3704..a43e3bf892e0dfa1a2c7baae9df31c7c1d8506aa 100644 --- a/tests/src/Entities/Authentication/Event/JobTest.php +++ b/tests/src/Entities/Authentication/Event/JobTest.php @@ -16,6 +16,7 @@ use SimpleSAML\Test\Module\accounting\Constants\StateArrays; * @uses \SimpleSAML\Module\accounting\Entities\Authentication\Event * @uses \SimpleSAML\Module\accounting\Entities\Authentication\State * @uses \SimpleSAML\Module\accounting\Helpers\NetworkHelper + * @uses \SimpleSAML\Module\accounting\Services\HelpersManager */ class JobTest extends TestCase { diff --git a/tests/src/Entities/Authentication/EventTest.php b/tests/src/Entities/Authentication/EventTest.php index 0141b2d32d967c7271d3f917457d99d5e426c3cf..58b063437fb3847f9b0d66bcf3876aa6c09b358a 100644 --- a/tests/src/Entities/Authentication/EventTest.php +++ b/tests/src/Entities/Authentication/EventTest.php @@ -11,6 +11,7 @@ use SimpleSAML\Test\Module\accounting\Constants\StateArrays; * @covers \SimpleSAML\Module\accounting\Entities\Authentication\Event * @uses \SimpleSAML\Module\accounting\Entities\Authentication\State * @uses \SimpleSAML\Module\accounting\Helpers\NetworkHelper + * @uses \SimpleSAML\Module\accounting\Services\HelpersManager */ class EventTest extends TestCase { diff --git a/tests/src/Entities/Authentication/StateTest.php b/tests/src/Entities/Authentication/StateTest.php index 32ac9e230ae03527bd3026cf7993d2cbbf8916bf..5be1a12aba53891e7236d765a45758532996f529 100644 --- a/tests/src/Entities/Authentication/StateTest.php +++ b/tests/src/Entities/Authentication/StateTest.php @@ -12,6 +12,7 @@ use SimpleSAML\Test\Module\accounting\Constants\StateArrays; /** * @covers \SimpleSAML\Module\accounting\Entities\Authentication\State * @uses \SimpleSAML\Module\accounting\Helpers\NetworkHelper + * @uses \SimpleSAML\Module\accounting\Services\HelpersManager */ class StateTest extends TestCase { diff --git a/tests/src/Entities/Bases/AbstractProviderTest.php b/tests/src/Entities/Bases/AbstractProviderTest.php index ea71711d5822d35a8f173c125ac34f5c1928c4fa..f888d2384167a336bd5ff03c8a3b2dd8c12dcb0b 100644 --- a/tests/src/Entities/Bases/AbstractProviderTest.php +++ b/tests/src/Entities/Bases/AbstractProviderTest.php @@ -1,5 +1,7 @@ <?php +declare(strict_types=1); + namespace SimpleSAML\Test\Module\accounting\Entities\Bases; use SimpleSAML\Module\accounting\Entities\Bases\AbstractProvider; @@ -23,7 +25,10 @@ class AbstractProviderTest extends TestCase $this->metadata = [ AbstractProvider::METADATA_KEY_ENTITY_ID => 'http//example.org/idp', AbstractProvider::METADATA_KEY_NAME => [ - 'en' => 'Test', + 'en' => 'Example service', + ], + AbstractProvider::METADATA_KEY_DESCRIPTION => [ + 'en' => 'Example description' ], ]; } @@ -44,6 +49,30 @@ class AbstractProviderTest extends TestCase $this->metadata[AbstractProvider::METADATA_KEY_NAME]['en'], $identityProvider->getName() ); + $this->assertSame( + $this->metadata[AbstractProvider::METADATA_KEY_DESCRIPTION]['en'], + $identityProvider->getDescription() + ); + } + + public function testCanResolveNonLocalizedString(): void + { + $metadata = $this->metadata; + $metadata[AbstractProvider::METADATA_KEY_DESCRIPTION] = 'Non localized description.'; + + $identityProvider = new IdentityProvider($metadata); + + $this->assertSame($metadata[AbstractProvider::METADATA_KEY_DESCRIPTION], $identityProvider->getDescription()); + } + + public function testInvalidLocalizedDataResolvesToNull(): void + { + $metadata = $this->metadata; + $metadata[AbstractProvider::METADATA_KEY_DESCRIPTION] = false; + + $identityProvider = new IdentityProvider($metadata); + + $this->assertNull($identityProvider->getDescription()); } public function testReturnsNullIfNameNotAvailable(): void diff --git a/tests/src/Helpers/ArrayHelperTest.php b/tests/src/Helpers/ArrayHelperTest.php index 2e2d77912233193e23d6d38d327d948fb93901a1..204f2886889d694fec9808dffafa0d30bfc05a44 100644 --- a/tests/src/Helpers/ArrayHelperTest.php +++ b/tests/src/Helpers/ArrayHelperTest.php @@ -24,7 +24,7 @@ class ArrayHelperTest extends TestCase $this->assertNotSame($unsorted, $sorted); - ArrayHelper::recursivelySortByKey($unsorted); + (new ArrayHelper())->recursivelySortByKey($unsorted); $this->assertSame($unsorted, $sorted); } diff --git a/tests/src/Helpers/AttributesHelperTest.php b/tests/src/Helpers/AttributesHelperTest.php index 9d21c87a33ec8bd68ae96e513fcb8af641db0115..8400b1e042144da64a695aba893e89a5a4f65fde 100644 --- a/tests/src/Helpers/AttributesHelperTest.php +++ b/tests/src/Helpers/AttributesHelperTest.php @@ -5,10 +5,12 @@ namespace SimpleSAML\Test\Module\accounting\Helpers; use SimpleSAML\Module\accounting\Helpers\AttributesHelper; use PHPUnit\Framework\TestCase; use SimpleSAML\Module\accounting\ModuleConfiguration; +use SimpleSAML\Module\accounting\Services\HelpersManager; /** * @covers \SimpleSAML\Module\accounting\Helpers\AttributesHelper * @uses \SimpleSAML\Module\accounting\ModuleConfiguration + * @uses \SimpleSAML\Module\accounting\Services\HelpersManager */ class AttributesHelperTest extends TestCase { @@ -21,6 +23,7 @@ class AttributesHelperTest extends TestCase * @var string[] */ protected array $mapFiles; + protected HelpersManager $helpersManager; protected function setUp(): void { @@ -28,11 +31,14 @@ class AttributesHelperTest extends TestCase DIRECTORY_SEPARATOR; $this->mapFiles = ['test.php', 'test2.php']; + + $this->helpersManager = new HelpersManager(); } public function testCanLoadAttributeMaps(): void { - $fullAttributeMap = AttributesHelper::getMergedAttributeMapForFiles($this->sspBaseDir, $this->mapFiles); + $fullAttributeMap = $this->helpersManager->getAttributesHelper() + ->getMergedAttributeMapForFiles($this->sspBaseDir, $this->mapFiles); $this->assertArrayHasKey('mobile', $fullAttributeMap); $this->assertArrayHasKey('phone', $fullAttributeMap); @@ -40,7 +46,8 @@ class AttributesHelperTest extends TestCase public function testIgnoresNonExistentMaps(): void { - $fullAttributeMap = AttributesHelper::getMergedAttributeMapForFiles($this->sspBaseDir, ['invalid.php']); + $fullAttributeMap = $this->helpersManager->getAttributesHelper() + ->getMergedAttributeMapForFiles($this->sspBaseDir, ['invalid.php']); $this->assertEmpty($fullAttributeMap); } diff --git a/tests/src/Helpers/DateTimeHelperTest.php b/tests/src/Helpers/DateTimeHelperTest.php new file mode 100644 index 0000000000000000000000000000000000000000..ad82ee7fc20d4ff429a104f1d4bb097246e68a1f --- /dev/null +++ b/tests/src/Helpers/DateTimeHelperTest.php @@ -0,0 +1,28 @@ +<?php + +declare(strict_types=1); + +namespace SimpleSAML\Test\Module\accounting\Helpers; + +use SimpleSAML\Module\accounting\Helpers\DateTimeHelper; +use PHPUnit\Framework\TestCase; + +/** + * @covers \SimpleSAML\Module\accounting\Helpers\DateTimeHelper + */ +class DateTimeHelperTest extends TestCase +{ + public function testCanConvertDateIntervalToSeconds(): void + { + $interval = new \DateInterval('PT10S'); + + $this->assertSame(10, (new DateTimeHelper())->convertDateIntervalToSeconds($interval)); + } + + public function testMinimumIntervalIsOneSecond(): void + { + $interval = \DateInterval::createFromDateString('-10 seconds'); // Negative interval + + $this->assertSame(1, (new DateTimeHelper())->convertDateIntervalToSeconds($interval)); + } +} diff --git a/tests/src/Helpers/EnvironmentHelperTest.php b/tests/src/Helpers/EnvironmentHelperTest.php new file mode 100644 index 0000000000000000000000000000000000000000..223ccd1734d7bd28518ea680d17425048fed0db1 --- /dev/null +++ b/tests/src/Helpers/EnvironmentHelperTest.php @@ -0,0 +1,19 @@ +<?php + +declare(strict_types=1); + +namespace SimpleSAML\Test\Module\accounting\Helpers; + +use SimpleSAML\Module\accounting\Helpers\EnvironmentHelper; +use PHPUnit\Framework\TestCase; + +/** + * @covers \SimpleSAML\Module\accounting\Helpers\EnvironmentHelper + */ +class EnvironmentHelperTest extends TestCase +{ + public function testConfirmIsCli(): void + { + $this->assertTrue((new EnvironmentHelper())->isCli()); + } +} diff --git a/tests/src/Helpers/FilesystemHelperTest.php b/tests/src/Helpers/FilesystemHelperTest.php index 01e6be75a9d128b9e97dca3811a96ad302c487ef..e6e76ab8221e7cd97cd931f465a2acfb3458cda5 100644 --- a/tests/src/Helpers/FilesystemHelperTest.php +++ b/tests/src/Helpers/FilesystemHelperTest.php @@ -15,7 +15,7 @@ class FilesystemHelperTest extends TestCase { $path = __DIR__ . DIRECTORY_SEPARATOR . '..'; - $realPath = FilesystemHelper::getRealPath($path); + $realPath = (new FilesystemHelper())->getRealPath($path); $this->assertSame(dirname(__DIR__), $realPath); } @@ -26,6 +26,6 @@ class FilesystemHelperTest extends TestCase $this->expectException(InvalidValueException::class); - FilesystemHelper::getRealPath($path); + (new FilesystemHelper())->getRealPath($path); } } diff --git a/tests/src/Helpers/HashHelperTest.php b/tests/src/Helpers/HashHelperTest.php index 6c2bf4325f014ff34accc1ef2e20bcd004a54629..e0e620a9b35d3cf7e8fb709388281d9370365269 100644 --- a/tests/src/Helpers/HashHelperTest.php +++ b/tests/src/Helpers/HashHelperTest.php @@ -4,8 +4,10 @@ declare(strict_types=1); namespace SimpleSAML\Test\Module\accounting\Helpers; +use SimpleSAML\Module\accounting\Helpers\ArrayHelper; use SimpleSAML\Module\accounting\Helpers\HashHelper; use PHPUnit\Framework\TestCase; +use SimpleSAML\Module\accounting\Services\HelpersManager; /** * @covers \SimpleSAML\Module\accounting\Helpers\HashHelper @@ -13,6 +15,8 @@ use PHPUnit\Framework\TestCase; */ class HashHelperTest extends TestCase { + protected HashHelper $hashHelper; + protected string $data; protected string $dataSha256; /** @@ -28,6 +32,8 @@ class HashHelperTest extends TestCase protected function setUp(): void { + $this->hashHelper = new HashHelper(new ArrayHelper()); + $this->data = 'test'; $this->dataSha256 = '9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08'; $this->unsortedArrayData = ['b' => [1 => 1, 0 => 0,], 'a' => [1 => 1, 0 => 0,],]; @@ -38,14 +44,20 @@ class HashHelperTest extends TestCase public function testCanGetSha256ForString(): void { - $this->assertSame($this->dataSha256, HashHelper::getSha256($this->data)); + $this->assertSame($this->dataSha256, $this->hashHelper->getSha256($this->data)); } public function testCanGetSha256ForArray(): void { // Arrays are sorted before the hash is calculated, so the value must be the same. $this->assertSame($this->unsortedArraySha256, $this->sortedArrayDataSha256); - $this->assertSame($this->unsortedArraySha256, HashHelper::getSha256ForArray($this->unsortedArrayData)); - $this->assertSame($this->sortedArrayDataSha256, HashHelper::getSha256ForArray($this->sortedArrayData)); + $this->assertSame( + $this->unsortedArraySha256, + $this->hashHelper->getSha256ForArray($this->unsortedArrayData) + ); + $this->assertSame( + $this->sortedArrayDataSha256, + $this->hashHelper->getSha256ForArray($this->sortedArrayData) + ); } } diff --git a/tests/src/Helpers/InstanceBuilderUsingModuleConfigurationHelperTest.php b/tests/src/Helpers/InstanceBuilderUsingModuleConfigurationHelperTest.php index a1caa56d4ba6a56f6601956407ba388536ba14d3..63345edb3e418dadcc07be93790d4355498c8e22 100644 --- a/tests/src/Helpers/InstanceBuilderUsingModuleConfigurationHelperTest.php +++ b/tests/src/Helpers/InstanceBuilderUsingModuleConfigurationHelperTest.php @@ -8,6 +8,7 @@ use SimpleSAML\Module\accounting\Helpers\InstanceBuilderUsingModuleConfiguration use PHPUnit\Framework\TestCase; use SimpleSAML\Module\accounting\Interfaces\BuildableUsingModuleConfigurationInterface; use SimpleSAML\Module\accounting\ModuleConfiguration; +use SimpleSAML\Module\accounting\Services\HelpersManager; /** * @covers \SimpleSAML\Module\accounting\Helpers\InstanceBuilderUsingModuleConfigurationHelper @@ -17,7 +18,7 @@ class InstanceBuilderUsingModuleConfigurationHelperTest extends TestCase protected BuildableUsingModuleConfigurationInterface $stub; /** @var class-string */ protected string $stubClass; - protected \PHPUnit\Framework\MockObject\Stub $moduleConfigurationstub; + protected \PHPUnit\Framework\MockObject\Stub $moduleConfigurationStub; protected \PHPUnit\Framework\MockObject\Stub $loggerStub; protected function setUp(): void @@ -33,7 +34,7 @@ class InstanceBuilderUsingModuleConfigurationHelperTest extends TestCase $this->stubClass = get_class($this->stub); - $this->moduleConfigurationstub = $this->createStub(ModuleConfiguration::class); + $this->moduleConfigurationStub = $this->createStub(ModuleConfiguration::class); $this->loggerStub = $this->createStub(LoggerInterface::class); } @@ -42,9 +43,9 @@ class InstanceBuilderUsingModuleConfigurationHelperTest extends TestCase /** @psalm-suppress InvalidArgument */ $this->assertInstanceOf( BuildableUsingModuleConfigurationInterface::class, - InstanceBuilderUsingModuleConfigurationHelper::build( + (new InstanceBuilderUsingModuleConfigurationHelper())->build( $this->stubClass, - $this->moduleConfigurationstub, + $this->moduleConfigurationStub, $this->loggerStub ) ); @@ -55,9 +56,9 @@ class InstanceBuilderUsingModuleConfigurationHelperTest extends TestCase $this->expectException(Exception::class); /** @psalm-suppress InvalidArgument */ - InstanceBuilderUsingModuleConfigurationHelper::build( + (new InstanceBuilderUsingModuleConfigurationHelper())->build( ModuleConfiguration::class, // Sample class which is not buildable. - $this->moduleConfigurationstub, + $this->moduleConfigurationStub, $this->loggerStub ); } diff --git a/tests/src/Helpers/ModuleRoutesHelperTest.php b/tests/src/Helpers/ModuleRoutesHelperTest.php new file mode 100644 index 0000000000000000000000000000000000000000..e9f205958c2c41a4a812d3de336c2431d32566a9 --- /dev/null +++ b/tests/src/Helpers/ModuleRoutesHelperTest.php @@ -0,0 +1,53 @@ +<?php + +declare(strict_types=1); + +namespace SimpleSAML\Test\Module\accounting\Helpers; + +use SimpleSAML\Module\accounting\Helpers\ModuleRoutesHelper; +use PHPUnit\Framework\TestCase; +use SimpleSAML\Module\accounting\ModuleConfiguration; +use SimpleSAML\Utils\HTTP; + +/** + * @covers \SimpleSAML\Module\accounting\Helpers\ModuleRoutesHelper + */ +class ModuleRoutesHelperTest extends TestCase +{ + protected const BASE_URL = 'https://example.org/ssp/'; + /** + * @var \PHPUnit\Framework\MockObject\Stub|HTTP + */ + protected $sspHttpUtilsStub; + protected string $moduleUrl; + + protected function setUp(): void + { + $this->sspHttpUtilsStub = $this->createStub(HTTP::class); + $this->sspHttpUtilsStub->method('getBaseURL')->willReturn(self::BASE_URL); + + $this->moduleUrl = self::BASE_URL . 'module.php/' . ModuleConfiguration::MODULE_NAME; + } + + public function testCanGetModuleUrl(): void + { + $path = 'sample-path'; + $moduleUrlWithPath = $this->moduleUrl . '/' . $path; + + $moduleRoutesHelper = new ModuleRoutesHelper($this->sspHttpUtilsStub); + + $this->assertSame($moduleUrlWithPath, $moduleRoutesHelper->getUrl($path)); + } + + public function testCanCallMethodToAddParamsToModuleUrl(): void + { + $path = 'sample-path'; + $params = ['sample' => 'param']; + $fullUrl = 'full-url-with-sample-param'; + + $this->sspHttpUtilsStub->method('addURLParameters')->willReturn($fullUrl); + $moduleRoutesHelper = new ModuleRoutesHelper($this->sspHttpUtilsStub); + + $this->assertSame($fullUrl, $moduleRoutesHelper->getUrl($path, $params)); + } +} diff --git a/tests/src/Helpers/NetworkHelperTest.php b/tests/src/Helpers/NetworkHelperTest.php index d4c9abe03a73b2e5649275dc2142c684d5332fc4..98cfed24aa0f38753101dcc71ae7f9438eda739e 100644 --- a/tests/src/Helpers/NetworkHelperTest.php +++ b/tests/src/Helpers/NetworkHelperTest.php @@ -21,17 +21,17 @@ class NetworkHelperTest extends TestCase public function testCanGetIpFromParameter(): void { - $this->assertSame($this->ipAddress, NetworkHelper::resolveClientIpAddress($this->ipAddress)); + $this->assertSame($this->ipAddress, (new NetworkHelper())->resolveClientIpAddress($this->ipAddress)); } public function testReturnsNullForInvalidIp(): void { - $this->assertNull(NetworkHelper::resolveClientIpAddress('invalid')); + $this->assertNull((new NetworkHelper())->resolveClientIpAddress('invalid')); } public function testReturnsNullForNonExistentIp(): void { - $this->assertNull(NetworkHelper::resolveClientIpAddress()); + $this->assertNull((new NetworkHelper())->resolveClientIpAddress()); } /** @@ -43,6 +43,6 @@ class NetworkHelperTest extends TestCase $_SERVER['REMOTE_ADDR'] = $this->ipAddress; - $this->assertSame($this->ipAddress, NetworkHelper::resolveClientIpAddress()); + $this->assertSame($this->ipAddress, (new NetworkHelper())->resolveClientIpAddress()); } } diff --git a/tests/src/Helpers/RandomHelperTest.php b/tests/src/Helpers/RandomHelperTest.php new file mode 100644 index 0000000000000000000000000000000000000000..538b3136906ca88b5744e959d252f5f57e665ab2 --- /dev/null +++ b/tests/src/Helpers/RandomHelperTest.php @@ -0,0 +1,17 @@ +<?php + +namespace SimpleSAML\Test\Module\accounting\Helpers; + +use SimpleSAML\Module\accounting\Helpers\RandomHelper; +use PHPUnit\Framework\TestCase; + +/** + * @covers \SimpleSAML\Module\accounting\Helpers\RandomHelper + */ +class RandomHelperTest extends TestCase +{ + public function testCanGetRandomInt(): void + { + $this->assertIsInt((new RandomHelper())->getRandomInt()); + } +} diff --git a/tests/src/ModuleConfigurationTest.php b/tests/src/ModuleConfigurationTest.php index 80821ec553e3044be13026a758575a92605559ae..db2a3d286e794583904a4fa4272b0649f3432ef9 100644 --- a/tests/src/ModuleConfigurationTest.php +++ b/tests/src/ModuleConfigurationTest.php @@ -63,14 +63,26 @@ class ModuleConfigurationTest extends TestCase { $this->expectException(InvalidConfigurationException::class); - new ModuleConfiguration('invalid_module_accounting.php'); + new ModuleConfiguration( + null, + [ + ModuleConfiguration::OPTION_ACCOUNTING_PROCESSING_TYPE => 'invalid', + ] + ); } public function testThrowsForInvalidJobsStore(): void { $this->expectException(InvalidConfigurationException::class); - new ModuleConfiguration('invalid_async_module_accounting.php'); + new ModuleConfiguration( + null, + [ + ModuleConfiguration::OPTION_ACCOUNTING_PROCESSING_TYPE => + ModuleConfiguration\AccountingProcessingType::VALUE_ASYNCHRONOUS, + ModuleConfiguration::OPTION_JOBS_STORE => 'invalid', + ] + ); } public function testProperConnectionKeyIsReturned(): void @@ -96,14 +108,30 @@ class ModuleConfigurationTest extends TestCase { $this->expectException(InvalidConfigurationException::class); - new ModuleConfiguration('invalid_object_value_module_accounting.php'); + new ModuleConfiguration( + null, + [ + ModuleConfiguration::OPTION_CLASS_TO_CONNECTION_MAP => [ + 'invalid-object-value' => new \stdClass(), + ] + ] + ); } public function testThrowsForNonMasterInArrayConnection(): void { $this->expectException(InvalidConfigurationException::class); - new ModuleConfiguration('invalid_array_value_module_accounting.php'); + new ModuleConfiguration( + null, + [ + ModuleConfiguration::OPTION_CLASS_TO_CONNECTION_MAP => [ + 'invalid-array-value' => [ + 'no-master-key' => 'invalid', + ], + ] + ] + ); } public function testThrowsForInvalidConnectiontype(): void @@ -157,4 +185,143 @@ class ModuleConfigurationTest extends TestCase $this->moduleConfiguration->getModuleRootDirectory() ); } + + public function testCanGetCronTagForJobRunner(): void + { + $this->assertSame( + 'accounting_job_runner', + $this->moduleConfiguration->getCronTagForJobRunner() + ); + } + + public function testCanGetJobRunnerMaximumExecutionTime(): void + { + $this->assertNull($this->moduleConfiguration->getJobRunnerMaximumExecutionTime()); + } + + public function testThrowsForNonStringJobRunnerMaximumExecutionTime(): void + { + $moduleConfiguration = new ModuleConfiguration( + null, + [ModuleConfiguration::OPTION_JOB_RUNNER_MAXIMUM_EXECUTION_TIME => false] + ); + + $this->expectException(InvalidConfigurationException::class); + + $moduleConfiguration->getJobRunnerMaximumExecutionTime(); + } + + public function testThrowsForInvalidStringJobRunnerMaximumExecutionTime(): void + { + $moduleConfiguration = new ModuleConfiguration( + null, + [ModuleConfiguration::OPTION_JOB_RUNNER_MAXIMUM_EXECUTION_TIME => 'invalid'] + ); + + + $this->expectException(InvalidConfigurationException::class); + + $moduleConfiguration->getJobRunnerMaximumExecutionTime(); + } + + public function testCanGetJobRunnerShouldPauseAfterNumberOfJobsProcessed(): void + { + $this->assertSame(10, $this->moduleConfiguration->getJobRunnerShouldPauseAfterNumberOfJobsProcessed()); + } + + public function testCanGetNullForJobRunnerShouldPauseAfterNumberOfJobsProcessed(): void + { + $moduleConfiguration = new ModuleConfiguration( + null, + [ModuleConfiguration::OPTION_JOB_RUNNER_SHOULD_PAUSE_AFTER_NUMBER_OF_JOBS_PROCESSED => null] + ); + + $this->assertNull($moduleConfiguration->getJobRunnerShouldPauseAfterNumberOfJobsProcessed()); + } + + public function testThrowsForNonIntegerJobRunnerShouldPauseAfterNumberOfJobsProcessed(): void + { + $moduleConfiguration = new ModuleConfiguration( + null, + [ModuleConfiguration::OPTION_JOB_RUNNER_SHOULD_PAUSE_AFTER_NUMBER_OF_JOBS_PROCESSED => false] + ); + + $this->expectException(InvalidConfigurationException::class); + + $moduleConfiguration->getJobRunnerShouldPauseAfterNumberOfJobsProcessed(); + } + + public function testThrowsForNegativeIntegerJobRunnerShouldPauseAfterNumberOfJobsProcessed(): void + { + $moduleConfiguration = new ModuleConfiguration( + null, + [ModuleConfiguration::OPTION_JOB_RUNNER_SHOULD_PAUSE_AFTER_NUMBER_OF_JOBS_PROCESSED => -1] + ); + + $this->expectException(InvalidConfigurationException::class); + + $moduleConfiguration->getJobRunnerShouldPauseAfterNumberOfJobsProcessed(); + } + + public function testThrowsOnInvalidCronTag(): void + { + $this->expectException(InvalidConfigurationException::class); + + new ModuleConfiguration( + null, + [ + ModuleConfiguration::OPTION_ACCOUNTING_PROCESSING_TYPE => + ModuleConfiguration\AccountingProcessingType::VALUE_ASYNCHRONOUS, + ModuleConfiguration::OPTION_CRON_TAG_FOR_JOB_RUNNER => -1 + ] + ); + } + + public function testThrowsOnInvalidDefaultDataTrackerAndProvider(): void + { + $this->expectException(InvalidConfigurationException::class); + + new ModuleConfiguration( + null, + [ + ModuleConfiguration::OPTION_DEFAULT_DATA_TRACKER_AND_PROVIDER => 'invalid' + ] + ); + } + + public function testThrowsOnInvalidAdditionalTrackers(): void + { + $this->expectException(InvalidConfigurationException::class); + + new ModuleConfiguration( + null, + [ + ModuleConfiguration::OPTION_ADDITIONAL_TRACKERS => ['invalid'] + ] + ); + } + + public function testThrowsOnNonStringAdditionalTracker(): void + { + $this->expectException(InvalidConfigurationException::class); + + new ModuleConfiguration( + null, + [ + ModuleConfiguration::OPTION_ADDITIONAL_TRACKERS => [-1] + ] + ); + } + + public function testThrowsWhenClassHasNoConnectionParametersSet(): void + { + $this->expectException(InvalidConfigurationException::class); + + new ModuleConfiguration( + null, + [ + ModuleConfiguration::OPTION_CONNECTIONS_AND_PARAMETERS => [] + ] + ); + } } diff --git a/tests/src/Providers/Builders/AuthenticationDataProviderBuilderTest.php b/tests/src/Providers/Builders/AuthenticationDataProviderBuilderTest.php index 99c95c87613f4a9e1147195e2e56fed5967f5709..e5c615ce90d5ee9a592ac3f8dd7741f4189ea937 100644 --- a/tests/src/Providers/Builders/AuthenticationDataProviderBuilderTest.php +++ b/tests/src/Providers/Builders/AuthenticationDataProviderBuilderTest.php @@ -9,6 +9,7 @@ use SimpleSAML\Module\accounting\Exceptions\Exception; use SimpleSAML\Module\accounting\ModuleConfiguration; use SimpleSAML\Module\accounting\Providers\Builders\AuthenticationDataProviderBuilder; use PHPUnit\Framework\TestCase; +use SimpleSAML\Module\accounting\Services\HelpersManager; use SimpleSAML\Module\accounting\Trackers\Authentication\DoctrineDbal\Versioned\Tracker; use SimpleSAML\Test\Module\accounting\Constants\ConnectionParameters; @@ -24,12 +25,15 @@ use SimpleSAML\Test\Module\accounting\Constants\ConnectionParameters; * @uses \SimpleSAML\Module\accounting\Stores\Connections\DoctrineDbal\Factory * @uses \SimpleSAML\Module\accounting\Stores\Data\Authentication\DoctrineDbal\Versioned\Store * @uses \SimpleSAML\Module\accounting\Trackers\Authentication\DoctrineDbal\Versioned\Tracker + * @uses \SimpleSAML\Module\accounting\Stores\Connections\Bases\AbstractMigrator + * @uses \SimpleSAML\Module\accounting\Services\HelpersManager */ class AuthenticationDataProviderBuilderTest extends TestCase { protected \PHPUnit\Framework\MockObject\Stub $moduleConfigurationStub; protected \PHPUnit\Framework\MockObject\Stub $loggerStub; + protected HelpersManager $helpersManager; protected function setUp(): void { @@ -39,6 +43,7 @@ class AuthenticationDataProviderBuilderTest extends TestCase ->willReturn($connectionParams); $this->loggerStub = $this->createStub(LoggerInterface::class); + $this->helpersManager = new HelpersManager(); } public function testCanCreateInstance(): void @@ -46,14 +51,22 @@ class AuthenticationDataProviderBuilderTest extends TestCase /** @psalm-suppress InvalidArgument */ $this->assertInstanceOf( AuthenticationDataProviderBuilder::class, - new AuthenticationDataProviderBuilder($this->moduleConfigurationStub, $this->loggerStub) + new AuthenticationDataProviderBuilder( + $this->moduleConfigurationStub, + $this->loggerStub, + $this->helpersManager + ) ); } public function testCanBuildDataProvider(): void { /** @psalm-suppress InvalidArgument */ - $builder = new AuthenticationDataProviderBuilder($this->moduleConfigurationStub, $this->loggerStub); + $builder = new AuthenticationDataProviderBuilder( + $this->moduleConfigurationStub, + $this->loggerStub, + $this->helpersManager + ); $this->assertInstanceOf(Tracker::class, $builder->build(Tracker::class)); } @@ -63,7 +76,10 @@ class AuthenticationDataProviderBuilderTest extends TestCase $this->expectException(Exception::class); /** @psalm-suppress InvalidArgument */ - (new AuthenticationDataProviderBuilder($this->moduleConfigurationStub, $this->loggerStub)) - ->build('invalid'); + (new AuthenticationDataProviderBuilder( + $this->moduleConfigurationStub, + $this->loggerStub, + $this->helpersManager + ))->build('invalid'); } } diff --git a/tests/src/Services/HelpersManagerTest.php b/tests/src/Services/HelpersManagerTest.php new file mode 100644 index 0000000000000000000000000000000000000000..a199731970637389a04830557f170b4805735799 --- /dev/null +++ b/tests/src/Services/HelpersManagerTest.php @@ -0,0 +1,43 @@ +<?php + +namespace SimpleSAML\Test\Module\accounting\Services; + +use SimpleSAML\Module\accounting\Helpers\ArrayHelper; +use SimpleSAML\Module\accounting\Helpers\AttributesHelper; +use SimpleSAML\Module\accounting\Helpers\DateTimeHelper; +use SimpleSAML\Module\accounting\Helpers\EnvironmentHelper; +use SimpleSAML\Module\accounting\Helpers\FilesystemHelper; +use SimpleSAML\Module\accounting\Helpers\HashHelper; +use SimpleSAML\Module\accounting\Helpers\InstanceBuilderUsingModuleConfigurationHelper; +use SimpleSAML\Module\accounting\Helpers\ModuleRoutesHelper; +use SimpleSAML\Module\accounting\Helpers\NetworkHelper; +use SimpleSAML\Module\accounting\Helpers\RandomHelper; +use SimpleSAML\Module\accounting\Services\HelpersManager; +use PHPUnit\Framework\TestCase; + +/** + * @covers \SimpleSAML\Module\accounting\Services\HelpersManager + * @uses \SimpleSAML\Module\accounting\Helpers\ModuleRoutesHelper + * @uses \SimpleSAML\Module\accounting\Helpers\HashHelper + */ +class HelpersManagerTest extends TestCase +{ + public function testCanGetHelperInstances(): void + { + $helpersManager = new HelpersManager(); + + $this->assertInstanceOf(ArrayHelper::class, $helpersManager->getArrayHelper()); + $this->assertInstanceOf(AttributesHelper::class, $helpersManager->getAttributesHelper()); + $this->assertInstanceOf(DateTimeHelper::class, $helpersManager->getDateTimeHelper()); + $this->assertInstanceOf(EnvironmentHelper::class, $helpersManager->getEnvironmentHelper()); + $this->assertInstanceOf(FilesystemHelper::class, $helpersManager->getFilesystemHelper()); + $this->assertInstanceOf(HashHelper::class, $helpersManager->getHashHelper()); + $this->assertInstanceOf( + InstanceBuilderUsingModuleConfigurationHelper::class, + $helpersManager->getInstanceBuilderUsingModuleConfigurationHelper() + ); + $this->assertInstanceOf(NetworkHelper::class, $helpersManager->getNetworkHelper()); + $this->assertInstanceOf(RandomHelper::class, $helpersManager->getRandomHelper()); + $this->assertInstanceOf(ModuleRoutesHelper::class, $helpersManager->getModuleRoutesHelper()); + } +} diff --git a/tests/src/Services/JobRunner/StateTest.php b/tests/src/Services/JobRunner/StateTest.php index 061b40b4d992fd0107aa8440a62ecbcdf4ed226e..533030e6ec26da4c65dbfdc67239401e21b815fd 100644 --- a/tests/src/Services/JobRunner/StateTest.php +++ b/tests/src/Services/JobRunner/StateTest.php @@ -105,4 +105,13 @@ class StateTest extends TestCase $this->assertSame(2, count($state->getStatusMessages())); $this->assertSame('test3', $state->getLastStatusMessage()); } + + public function testCanSetGracefulInterruptInitiatedFlag(): void + { + $state = new State($this->jobRunnerId); + + $this->assertFalse($state->getIsGracefulInterruptInitiated()); + $state->setIsGracefulInterruptInitiated(true); + $this->assertTrue($state->getIsGracefulInterruptInitiated()); + } } diff --git a/tests/src/Services/JobRunnerTest.php b/tests/src/Services/JobRunnerTest.php index 8e1fbc94c3f44e15c7fb662a87b064e83d0b6d9b..ceddecc0c39a2ba53366c228814bb14116268c2a 100644 --- a/tests/src/Services/JobRunnerTest.php +++ b/tests/src/Services/JobRunnerTest.php @@ -128,12 +128,12 @@ class JobRunnerTest extends TestCase $this->moduleConfigurationStub, $this->sspConfigurationStub, $this->loggerMock, + $this->helpersManagerStub, $this->authenticationDataTrackerBuilderStub, $this->jobsStoreBuilderStub, $this->cacheMock, $this->stateStub, - $this->rateLimiterMock, - $this->helpersManagerStub + $this->rateLimiterMock ) ); } @@ -160,12 +160,12 @@ class JobRunnerTest extends TestCase $this->moduleConfigurationStub, $this->sspConfigurationStub, $this->loggerMock, + $this->helpersManagerStub, $this->authenticationDataTrackerBuilderStub, $this->jobsStoreBuilderStub, $this->cacheMock, $this->stateStub, - $this->rateLimiterMock, - $this->helpersManagerStub + $this->rateLimiterMock ); $jobRunner->run(); @@ -193,12 +193,12 @@ class JobRunnerTest extends TestCase $this->moduleConfigurationStub, $this->sspConfigurationStub, $this->loggerMock, + $this->helpersManagerStub, $this->authenticationDataTrackerBuilderStub, $this->jobsStoreBuilderStub, $this->cacheMock, $this->stateStub, - $this->rateLimiterMock, - $this->helpersManagerStub + $this->rateLimiterMock ); $jobRunner->run(); @@ -222,12 +222,12 @@ class JobRunnerTest extends TestCase $this->moduleConfigurationStub, $this->sspConfigurationStub, $this->loggerMock, + $this->helpersManagerStub, $this->authenticationDataTrackerBuilderStub, $this->jobsStoreBuilderStub, $this->cacheMock, $this->stateStub, - $this->rateLimiterMock, - $this->helpersManagerStub + $this->rateLimiterMock ); $jobRunner->run(); @@ -256,12 +256,12 @@ class JobRunnerTest extends TestCase $this->moduleConfigurationStub, $this->sspConfigurationStub, $this->loggerMock, + $this->helpersManagerStub, $this->authenticationDataTrackerBuilderStub, $this->jobsStoreBuilderStub, $this->cacheMock, $this->stateStub, - $this->rateLimiterMock, - $this->helpersManagerStub + $this->rateLimiterMock ); $jobRunner->run(); @@ -293,12 +293,12 @@ class JobRunnerTest extends TestCase $this->moduleConfigurationStub, $this->sspConfigurationStub, $this->loggerMock, + $this->helpersManagerStub, $this->authenticationDataTrackerBuilderStub, $this->jobsStoreBuilderStub, $this->cacheMock, $this->stateStub, - $this->rateLimiterMock, - $this->helpersManagerStub + $this->rateLimiterMock ); $jobRunner->run(); @@ -325,12 +325,12 @@ class JobRunnerTest extends TestCase $this->moduleConfigurationStub, $this->sspConfigurationStub, $this->loggerMock, + $this->helpersManagerStub, $this->authenticationDataTrackerBuilderStub, $this->jobsStoreBuilderStub, $this->cacheMock, $this->stateStub, - $this->rateLimiterMock, - $this->helpersManagerStub + $this->rateLimiterMock ); $jobRunner->run(); @@ -363,12 +363,12 @@ class JobRunnerTest extends TestCase $this->moduleConfigurationStub, $this->sspConfigurationStub, $this->loggerMock, + $this->helpersManagerStub, $this->authenticationDataTrackerBuilderStub, $this->jobsStoreBuilderStub, $this->cacheMock, $this->stateStub, - $this->rateLimiterMock, - $this->helpersManagerStub + $this->rateLimiterMock ); $jobRunner->run(); @@ -401,12 +401,12 @@ class JobRunnerTest extends TestCase $this->moduleConfigurationStub, $this->sspConfigurationStub, $this->loggerMock, + $this->helpersManagerStub, $this->authenticationDataTrackerBuilderStub, $this->jobsStoreBuilderStub, $this->cacheMock, $this->stateStub, - $this->rateLimiterMock, - $this->helpersManagerStub + $this->rateLimiterMock ); $jobRunner->run(); @@ -446,12 +446,12 @@ class JobRunnerTest extends TestCase $this->moduleConfigurationStub, $this->sspConfigurationStub, $this->loggerMock, + $this->helpersManagerStub, $this->authenticationDataTrackerBuilderStub, $this->jobsStoreBuilderStub, $this->cacheMock, $this->stateStub, - $this->rateLimiterMock, - $this->helpersManagerStub + $this->rateLimiterMock ); $jobRunner->run(); @@ -481,12 +481,12 @@ class JobRunnerTest extends TestCase $this->moduleConfigurationStub, $this->sspConfigurationStub, $this->loggerMock, + $this->helpersManagerStub, $this->authenticationDataTrackerBuilderStub, $this->jobsStoreBuilderStub, $this->cacheMock, $this->stateStub, - $this->rateLimiterMock, - $this->helpersManagerStub + $this->rateLimiterMock ); $jobRunner->run(); @@ -518,12 +518,12 @@ class JobRunnerTest extends TestCase $this->moduleConfigurationStub, $this->sspConfigurationStub, $this->loggerMock, + $this->helpersManagerStub, $this->authenticationDataTrackerBuilderStub, $this->jobsStoreBuilderStub, $this->cacheMock, $this->stateStub, - $this->rateLimiterMock, - $this->helpersManagerStub + $this->rateLimiterMock ); $jobRunner->run(); @@ -555,12 +555,12 @@ class JobRunnerTest extends TestCase $this->moduleConfigurationStub, $this->sspConfigurationStub, $this->loggerMock, + $this->helpersManagerStub, $this->authenticationDataTrackerBuilderStub, $this->jobsStoreBuilderStub, $this->cacheMock, $this->stateStub, - $this->rateLimiterMock, - $this->helpersManagerStub + $this->rateLimiterMock ); $jobRunner->run(); @@ -594,12 +594,12 @@ class JobRunnerTest extends TestCase $this->moduleConfigurationStub, $this->sspConfigurationStub, $this->loggerMock, + $this->helpersManagerStub, $this->authenticationDataTrackerBuilderStub, $this->jobsStoreBuilderStub, $this->cacheMock, $this->stateStub, - $this->rateLimiterMock, - $this->helpersManagerStub + $this->rateLimiterMock ); $jobRunner->run(); @@ -634,12 +634,12 @@ class JobRunnerTest extends TestCase $this->moduleConfigurationStub, $this->sspConfigurationStub, $this->loggerMock, + $this->helpersManagerStub, $this->authenticationDataTrackerBuilderStub, $this->jobsStoreBuilderStub, $this->cacheMock, $this->stateStub, - $this->rateLimiterMock, - $this->helpersManagerStub + $this->rateLimiterMock ); $jobRunner->run(); @@ -675,12 +675,12 @@ class JobRunnerTest extends TestCase $this->moduleConfigurationStub, $this->sspConfigurationStub, $this->loggerMock, + $this->helpersManagerStub, $this->authenticationDataTrackerBuilderStub, $this->jobsStoreBuilderStub, $this->cacheMock, $this->stateStub, - $this->rateLimiterMock, - $this->helpersManagerStub + $this->rateLimiterMock ); $jobRunner->run(); @@ -726,12 +726,12 @@ class JobRunnerTest extends TestCase $this->moduleConfigurationStub, $this->sspConfigurationStub, $this->loggerMock, + $this->helpersManagerStub, $this->authenticationDataTrackerBuilderStub, $this->jobsStoreBuilderStub, $this->cacheMock, $this->stateStub, - $this->rateLimiterMock, - $this->helpersManagerStub + $this->rateLimiterMock ); $jobRunner->run(); @@ -774,12 +774,12 @@ class JobRunnerTest extends TestCase $this->moduleConfigurationStub, $this->sspConfigurationStub, $this->loggerMock, + $this->helpersManagerStub, $this->authenticationDataTrackerBuilderStub, $this->jobsStoreBuilderStub, $this->cacheMock, $this->stateStub, - $this->rateLimiterMock, - $this->helpersManagerStub + $this->rateLimiterMock ); $jobRunner->run(); @@ -838,12 +838,12 @@ class JobRunnerTest extends TestCase $this->moduleConfigurationStub, $this->sspConfigurationStub, $this->loggerMock, + $this->helpersManagerStub, $this->authenticationDataTrackerBuilderStub, $this->jobsStoreBuilderStub, $this->cacheMock, $this->stateStub, - $this->rateLimiterMock, - $this->helpersManagerStub + $this->rateLimiterMock ); $jobRunner->run(); @@ -896,12 +896,12 @@ class JobRunnerTest extends TestCase $this->moduleConfigurationStub, $this->sspConfigurationStub, $this->loggerMock, + $this->helpersManagerStub, $this->authenticationDataTrackerBuilderStub, $this->jobsStoreBuilderStub, $this->cacheMock, $this->stateStub, - $this->rateLimiterMock, - $this->helpersManagerStub + $this->rateLimiterMock ); $jobRunner->run(); @@ -965,12 +965,12 @@ class JobRunnerTest extends TestCase $this->moduleConfigurationStub, $this->sspConfigurationStub, $this->loggerMock, + $this->helpersManagerStub, $this->authenticationDataTrackerBuilderStub, $this->jobsStoreBuilderStub, $this->cacheMock, $this->stateStub, - $this->rateLimiterMock, - $this->helpersManagerStub + $this->rateLimiterMock ); $jobRunner->run(); @@ -1028,12 +1028,12 @@ class JobRunnerTest extends TestCase $this->moduleConfigurationStub, $this->sspConfigurationStub, $this->loggerMock, + $this->helpersManagerStub, $this->authenticationDataTrackerBuilderStub, $this->jobsStoreBuilderStub, $this->cacheMock, $this->stateStub, - $this->rateLimiterMock, - $this->helpersManagerStub + $this->rateLimiterMock ); $jobRunner->run(); @@ -1072,12 +1072,12 @@ class JobRunnerTest extends TestCase $this->moduleConfigurationStub, $this->sspConfigurationStub, $this->loggerMock, + $this->helpersManagerStub, $this->authenticationDataTrackerBuilderStub, $this->jobsStoreBuilderStub, $this->cacheMock, $this->stateStub, - $this->rateLimiterMock, - $this->helpersManagerStub + $this->rateLimiterMock ); $jobRunner->run(); diff --git a/tests/src/Stores/Builders/DataStoreBuilderTest.php b/tests/src/Stores/Builders/DataStoreBuilderTest.php index 30b4214b86d8a0425948a2370580e1dd551d7fa1..3bcc50ab13e2649bdee5bf3e9f305616cf88ec07 100644 --- a/tests/src/Stores/Builders/DataStoreBuilderTest.php +++ b/tests/src/Stores/Builders/DataStoreBuilderTest.php @@ -5,6 +5,7 @@ namespace SimpleSAML\Test\Module\accounting\Stores\Builders; use Psr\Log\LoggerInterface; use SimpleSAML\Module\accounting\Exceptions\StoreException; use SimpleSAML\Module\accounting\ModuleConfiguration; +use SimpleSAML\Module\accounting\Services\HelpersManager; use SimpleSAML\Module\accounting\Stores\Builders\DataStoreBuilder; use PHPUnit\Framework\TestCase; use SimpleSAML\Module\accounting\Stores\Data\Authentication\DoctrineDbal\Versioned\Store; @@ -20,12 +21,15 @@ use SimpleSAML\Test\Module\accounting\Constants\ConnectionParameters; * @uses \SimpleSAML\Module\accounting\Stores\Connections\DoctrineDbal\Factory * @uses \SimpleSAML\Module\accounting\Stores\Connections\DoctrineDbal\Migrator * @uses \SimpleSAML\Module\accounting\Stores\Data\Authentication\DoctrineDbal\Versioned\Store\Repository + * @uses \SimpleSAML\Module\accounting\Stores\Connections\Bases\AbstractMigrator + * @uses \SimpleSAML\Module\accounting\Services\HelpersManager */ class DataStoreBuilderTest extends TestCase { protected \PHPUnit\Framework\MockObject\Stub $moduleConfigurationStub; protected \PHPUnit\Framework\MockObject\Stub $loggerStub; protected DataStoreBuilder $dataStoreBuilder; + protected HelpersManager $helpersManager; protected function setUp(): void { @@ -35,8 +39,14 @@ class DataStoreBuilderTest extends TestCase $this->loggerStub = $this->createStub(LoggerInterface::class); + $this->helpersManager = new HelpersManager(); + /** @psalm-suppress InvalidArgument */ - $this->dataStoreBuilder = new DataStoreBuilder($this->moduleConfigurationStub, $this->loggerStub); + $this->dataStoreBuilder = new DataStoreBuilder( + $this->moduleConfigurationStub, + $this->loggerStub, + $this->helpersManager + ); } public function testCanBuildDataStore(): void diff --git a/tests/src/Stores/Builders/JobsStoreBuilderTest.php b/tests/src/Stores/Builders/JobsStoreBuilderTest.php index 9b954a2248b22984f39fb59a4ea46de3c8042598..906f3457f3db9729775deeea43e2b3756a343b58 100644 --- a/tests/src/Stores/Builders/JobsStoreBuilderTest.php +++ b/tests/src/Stores/Builders/JobsStoreBuilderTest.php @@ -1,11 +1,14 @@ <?php +declare(strict_types=1); + namespace SimpleSAML\Test\Module\accounting\Stores\Builders; use PHPUnit\Framework\TestCase; use Psr\Log\LoggerInterface; use SimpleSAML\Module\accounting\Exceptions\StoreException; use SimpleSAML\Module\accounting\ModuleConfiguration; +use SimpleSAML\Module\accounting\Services\HelpersManager; use SimpleSAML\Module\accounting\Stores\Builders\Bases\AbstractStoreBuilder; use SimpleSAML\Module\accounting\Stores\Builders\JobsStoreBuilder; use SimpleSAML\Module\accounting\Stores\Interfaces\StoreInterface; @@ -22,12 +25,15 @@ use SimpleSAML\Test\Module\accounting\Constants\ConnectionParameters; * @uses \SimpleSAML\Module\accounting\Stores\Jobs\DoctrineDbal\Store\Repository * @uses \SimpleSAML\Module\accounting\Stores\Bases\DoctrineDbal\AbstractStore * @uses \SimpleSAML\Module\accounting\Helpers\InstanceBuilderUsingModuleConfigurationHelper + * @uses \SimpleSAML\Module\accounting\Stores\Connections\Bases\AbstractMigrator + * @uses \SimpleSAML\Module\accounting\Services\HelpersManager */ class JobsStoreBuilderTest extends TestCase { protected \PHPUnit\Framework\MockObject\Stub $moduleConfigurationStub; protected \PHPUnit\Framework\MockObject\Stub $loggerStub; protected JobsStoreBuilder $jobsStoreBuilder; + protected HelpersManager $helpersManager; protected function setUp(): void { @@ -38,8 +44,14 @@ class JobsStoreBuilderTest extends TestCase $this->loggerStub = $this->createStub(LoggerInterface::class); + $this->helpersManager = new HelpersManager(); + /** @psalm-suppress InvalidArgument */ - $this->jobsStoreBuilder = new JobsStoreBuilder($this->moduleConfigurationStub, $this->loggerStub); + $this->jobsStoreBuilder = new JobsStoreBuilder( + $this->moduleConfigurationStub, + $this->loggerStub, + $this->helpersManager + ); } public function testCanBuildJobsStore(): void @@ -57,7 +69,11 @@ class JobsStoreBuilderTest extends TestCase }; /** @psalm-suppress InvalidArgument */ - $storeBuilder = new class ($moduleConfigurationStub, $this->loggerStub) extends AbstractStoreBuilder { + $storeBuilder = new class ( + $moduleConfigurationStub, + $this->loggerStub, + $this->helpersManager + ) extends AbstractStoreBuilder { public function build( string $class, string $connectionKey = null, @@ -82,7 +98,8 @@ class JobsStoreBuilderTest extends TestCase $this->expectException(StoreException::class); /** @psalm-suppress InvalidArgument */ - (new JobsStoreBuilder($moduleConfigurationStub, $this->loggerStub))->build('invalid'); + (new JobsStoreBuilder($moduleConfigurationStub, $this->loggerStub, $this->helpersManager)) + ->build('invalid'); } public function testJobsStoreBuilderOnlyReturnsJobsStores(): void @@ -114,6 +131,7 @@ class JobsStoreBuilderTest extends TestCase $this->expectException(StoreException::class); /** @psalm-suppress InvalidArgument */ - (new JobsStoreBuilder($moduleConfigurationStub, $this->loggerStub))->build(get_class($sampleStore)); + (new JobsStoreBuilder($moduleConfigurationStub, $this->loggerStub, $this->helpersManager)) + ->build(get_class($sampleStore)); } } diff --git a/tests/src/Stores/Connections/Bases/AbstractMigratorTest.php b/tests/src/Stores/Connections/Bases/AbstractMigratorTest.php index 1f4f94dd1b7f023d4f941b7fc096aafc8854dc33..0fb3fda9f697c817da1f36fe9d763f1fc89f091e 100644 --- a/tests/src/Stores/Connections/Bases/AbstractMigratorTest.php +++ b/tests/src/Stores/Connections/Bases/AbstractMigratorTest.php @@ -26,6 +26,7 @@ use SimpleSAML\Test\Module\accounting\Constants\ConnectionParameters; * @uses \SimpleSAML\Module\accounting\Stores\Jobs\DoctrineDbal\Store\Migrations\Version20220601000100CreateJobFailedTable * @uses \SimpleSAML\Module\accounting\Stores\Connections\DoctrineDbal\Bases\AbstractMigration * @uses \SimpleSAML\Module\accounting\Stores\Jobs\DoctrineDbal\Store\Migrations\Bases\AbstractCreateJobsTable + * @uses \SimpleSAML\Module\accounting\Services\HelpersManager */ class AbstractMigratorTest extends TestCase { diff --git a/tests/src/Stores/Connections/DoctrineDbal/FactoryTest.php b/tests/src/Stores/Connections/DoctrineDbal/FactoryTest.php index 2647f6962160cf7eb0a4399235e7adbba8fea699..07dab2dbfcd72e2a5b750e9edec9b0a581d9c290 100644 --- a/tests/src/Stores/Connections/DoctrineDbal/FactoryTest.php +++ b/tests/src/Stores/Connections/DoctrineDbal/FactoryTest.php @@ -15,6 +15,8 @@ use SimpleSAML\Test\Module\accounting\Constants\ConnectionParameters; * @uses \SimpleSAML\Module\accounting\ModuleConfiguration * @uses \SimpleSAML\Module\accounting\Stores\Connections\DoctrineDbal\Connection * @uses \SimpleSAML\Module\accounting\Stores\Connections\DoctrineDbal\Migrator + * @uses \SimpleSAML\Module\accounting\Stores\Connections\Bases\AbstractMigrator + * @uses \SimpleSAML\Module\accounting\Services\HelpersManager */ class FactoryTest extends TestCase { diff --git a/tests/src/Stores/Connections/DoctrineDbal/MigratorTest.php b/tests/src/Stores/Connections/DoctrineDbal/MigratorTest.php index 008d3f139288ea393b8d86b5f1e192bc831dcf73..907e83c6b66d26e1865453145d63b11e1dc02729 100644 --- a/tests/src/Stores/Connections/DoctrineDbal/MigratorTest.php +++ b/tests/src/Stores/Connections/DoctrineDbal/MigratorTest.php @@ -28,6 +28,7 @@ use function PHPUnit\Framework\assertFalse; * @uses \SimpleSAML\Module\accounting\ModuleConfiguration * @uses \SimpleSAML\Module\accounting\Helpers\FilesystemHelper * @uses \SimpleSAML\Module\accounting\Stores\Jobs\DoctrineDbal\Store\Migrations\Bases\AbstractCreateJobsTable + * @uses \SimpleSAML\Module\accounting\Services\HelpersManager */ class MigratorTest extends TestCase { diff --git a/tests/src/Stores/Data/Authentication/DoctrineDbal/Versioned/Store/HashDecoratedStateTest.php b/tests/src/Stores/Data/Authentication/DoctrineDbal/Versioned/Store/HashDecoratedStateTest.php index 0094b57489467a56c49a3195bd1b3b5833364fd4..23cb877c07e19c1100077af13a76191ae585fdd0 100644 --- a/tests/src/Stores/Data/Authentication/DoctrineDbal/Versioned/Store/HashDecoratedStateTest.php +++ b/tests/src/Stores/Data/Authentication/DoctrineDbal/Versioned/Store/HashDecoratedStateTest.php @@ -1,5 +1,7 @@ <?php +declare(strict_types=1); + namespace SimpleSAML\Test\Module\accounting\Stores\Data\Authentication\DoctrineDbal\Versioned\Store; use SimpleSAML\Module\accounting\Entities\Authentication\State; @@ -10,6 +12,7 @@ use PHPUnit\Framework\TestCase; * @covers \SimpleSAML\Module\accounting\Stores\Data\Authentication\DoctrineDbal\Versioned\Store\HashDecoratedState * @uses \SimpleSAML\Module\accounting\Helpers\HashHelper * @uses \SimpleSAML\Module\accounting\Helpers\ArrayHelper + * @uses \SimpleSAML\Module\accounting\Services\HelpersManager */ class HashDecoratedStateTest extends TestCase { diff --git a/tests/src/Stores/Data/Authentication/DoctrineDbal/Versioned/Store/RawActivityTest.php b/tests/src/Stores/Data/Authentication/DoctrineDbal/Versioned/Store/RawActivityTest.php index 2999244c0ddd8e302190767482b1aba675f7c972..d0635ea6f734ed33db25797dc512044f70d96833 100644 --- a/tests/src/Stores/Data/Authentication/DoctrineDbal/Versioned/Store/RawActivityTest.php +++ b/tests/src/Stores/Data/Authentication/DoctrineDbal/Versioned/Store/RawActivityTest.php @@ -24,6 +24,8 @@ class RawActivityTest extends TestCase */ protected array $userAttributes; protected string $happenedAt; + protected string $clientIpAddress; + protected array $rawRow; /** * @var AbstractPlatform|AbstractPlatform&\PHPUnit\Framework\MockObject\Stub|\PHPUnit\Framework\MockObject\Stub @@ -35,10 +37,13 @@ class RawActivityTest extends TestCase $this->serviceProviderMetadata = ['sp' => 'metadata']; $this->userAttributes = ['user' => 'attribute']; $this->happenedAt = '2022-02-22 22:22:22'; + $this->clientIpAddress = '123.123.123.123'; + $this->rawRow = [ TableConstants::ENTITY_ACTIVITY_COLUMN_NAME_SP_METADATA => serialize($this->serviceProviderMetadata), TableConstants::ENTITY_ACTIVITY_COLUMN_NAME_USER_ATTRIBUTES => serialize($this->userAttributes), TableConstants::ENTITY_ACTIVITY_COLUMN_NAME_HAPPENED_AT => $this->happenedAt, + TableConstants::ENTITY_ACTIVITY_COLUMN_NAME_CLIENT_IP_ADDRESS => $this->clientIpAddress, ]; $this->abstractPlatformStub = $this->createStub(AbstractPlatform::class); $this->abstractPlatformStub->method('getDateTimeFormatString')->willReturn(DateTime::DEFAULT_FORMAT); @@ -60,6 +65,16 @@ class RawActivityTest extends TestCase $this->assertInstanceOf(\DateTimeImmutable::class, $rawActivity->getHappenedAt()); $this->assertSame($this->serviceProviderMetadata, $rawActivity->getServiceProviderMetadata()); $this->assertSame($this->userAttributes, $rawActivity->getUserAttributes()); + $this->assertSame($this->clientIpAddress, $rawActivity->getClientIpAddress()); + } + + public function testIpAddressCanBeMissing(): void + { + $rawRow = $this->rawRow; + unset($rawRow[TableConstants::ENTITY_ACTIVITY_COLUMN_NAME_CLIENT_IP_ADDRESS]); + + $rawActivity = new RawActivity($rawRow, $this->abstractPlatformStub); + $this->assertNull($rawActivity->getClientIpAddress()); } public function testThrowsIfColumnNotPresent(): void diff --git a/tests/src/Stores/Data/Authentication/DoctrineDbal/Versioned/Store/RepositoryTest.php b/tests/src/Stores/Data/Authentication/DoctrineDbal/Versioned/Store/RepositoryTest.php index ee2f160a3a3015c99e01bdcd4ae1e7300625ca65..ef1b0e1b96e6f6152dc7aa64b2f9a3b11baa92ac 100644 --- a/tests/src/Stores/Data/Authentication/DoctrineDbal/Versioned/Store/RepositoryTest.php +++ b/tests/src/Stores/Data/Authentication/DoctrineDbal/Versioned/Store/RepositoryTest.php @@ -32,6 +32,7 @@ use SimpleSAML\Test\Module\accounting\Constants\DateTime; * @uses \SimpleSAML\Module\accounting\Stores\Data\Authentication\DoctrineDbal\Versioned\Store\Migrations\Version20220801000500CreateUserVersionTable * @uses \SimpleSAML\Module\accounting\Stores\Data\Authentication\DoctrineDbal\Versioned\Store\Migrations\Version20220801000600CreateIdpSpUserVersionTable * @uses \SimpleSAML\Module\accounting\Stores\Data\Authentication\DoctrineDbal\Versioned\Store\Migrations\Version20220801000700CreateAuthenticationEventTable + * @uses \SimpleSAML\Module\accounting\Services\HelpersManager * * @psalm-suppress all */ @@ -63,6 +64,7 @@ class RepositoryTest extends TestCase protected $connectionStub; protected string $spEntityIdHash; protected string $spMetadata; + protected string $clientIpAddress; protected function setUp(): void { @@ -107,6 +109,7 @@ class RepositoryTest extends TestCase $this->userAttributesHash = 'user-attributes-hash'; $this->createdAt = new \DateTimeImmutable(); + $this->clientIpAddress = '123.123.123.123'; } public function testCanCreateInstance(): void @@ -426,7 +429,7 @@ class RepositoryTest extends TestCase $this->assertSame(0, (int)$authenticationEventCounterQueryBuilder->executeQuery()->fetchOne()); - $this->repository->insertAuthenticationEvent($idpSpUserVersionId, $happenedAt, $createdAt); + $this->repository->insertAuthenticationEvent($idpSpUserVersionId, $happenedAt, null, $createdAt); $this->assertSame(1, (int)$authenticationEventCounterQueryBuilder->executeQuery()->fetchOne()); } @@ -472,7 +475,12 @@ class RepositoryTest extends TestCase $idpSpUserVersionId = (int)$idpSpUserVersionResult[Store\TableConstants::TABLE_IDP_SP_USER_VERSION_COLUMN_NAME_ID]; - $this->repository->insertAuthenticationEvent($idpSpUserVersionId, $this->createdAt, $this->createdAt); + $this->repository->insertAuthenticationEvent( + $idpSpUserVersionId, + $this->createdAt, + $this->clientIpAddress, + $this->createdAt + ); $resultArray = $this->repository->getConnectedServiceProviders($this->userIdentifierHash); @@ -496,7 +504,12 @@ class RepositoryTest extends TestCase $resultArray = $this->repository->getConnectedServiceProviders($this->userIdentifierHash); $this->assertCount(1, $resultArray); - $this->repository->insertAuthenticationEvent($idpSpUserVersionId, $this->createdAt, $this->createdAt); + $this->repository->insertAuthenticationEvent( + $idpSpUserVersionId, + $this->createdAt, + $this->clientIpAddress, + $this->createdAt + ); $resultArray = $this->repository->getConnectedServiceProviders($this->userIdentifierHash); $this->assertCount(1, $resultArray); $this->assertSame( @@ -533,7 +546,12 @@ class RepositoryTest extends TestCase $idpSpUserVersionId = (int)$idpSpUserVersionResult[Store\TableConstants::TABLE_IDP_SP_USER_VERSION_COLUMN_NAME_ID]; - $this->repository->insertAuthenticationEvent($idpSpUserVersionId, $this->createdAt, $this->createdAt); + $this->repository->insertAuthenticationEvent( + $idpSpUserVersionId, + $this->createdAt, + $this->clientIpAddress, + $this->createdAt + ); $resultArray = $this->repository->getConnectedServiceProviders($this->userIdentifierHash); $this->assertCount(2, $resultArray); @@ -567,7 +585,12 @@ class RepositoryTest extends TestCase $idpSpUserVersionId = (int)$idpSpUserVersionResult[Store\TableConstants::TABLE_IDP_SP_USER_VERSION_COLUMN_NAME_ID]; - $this->repository->insertAuthenticationEvent($idpSpUserVersionId, $this->createdAt, $this->createdAt); + $this->repository->insertAuthenticationEvent( + $idpSpUserVersionId, + $this->createdAt, + $this->clientIpAddress, + $this->createdAt + ); $resultArray = $this->repository->getConnectedServiceProviders($this->userIdentifierHash); $this->assertCount(2, $resultArray); @@ -637,16 +660,31 @@ class RepositoryTest extends TestCase $idpSpUserVersionId = (int)$idpSpUserVersionResult[Store\TableConstants::TABLE_IDP_SP_USER_VERSION_COLUMN_NAME_ID]; - $this->repository->insertAuthenticationEvent($idpSpUserVersionId, $this->createdAt, $this->createdAt); + $this->repository->insertAuthenticationEvent( + $idpSpUserVersionId, + $this->createdAt, + $this->clientIpAddress, + $this->createdAt + ); $resultArray = $this->repository->getActivity($this->userIdentifierHash, 10, 0); $this->assertCount(1, $resultArray); - $this->repository->insertAuthenticationEvent($idpSpUserVersionId, $this->createdAt, $this->createdAt); + $this->repository->insertAuthenticationEvent( + $idpSpUserVersionId, + $this->createdAt, + $this->clientIpAddress, + $this->createdAt + ); $resultArray = $this->repository->getActivity($this->userIdentifierHash, 10, 0); $this->assertCount(2, $resultArray); - $this->repository->insertAuthenticationEvent($idpSpUserVersionId, $this->createdAt, $this->createdAt); + $this->repository->insertAuthenticationEvent( + $idpSpUserVersionId, + $this->createdAt, + $this->clientIpAddress, + $this->createdAt + ); $resultArray = $this->repository->getActivity($this->userIdentifierHash, 10, 0); $this->assertCount(3, $resultArray); @@ -669,7 +707,12 @@ class RepositoryTest extends TestCase $idpSpUserVersionId = (int)$idpSpUserVersionResult[Store\TableConstants::TABLE_IDP_SP_USER_VERSION_COLUMN_NAME_ID]; - $this->repository->insertAuthenticationEvent($idpSpUserVersionId, $this->createdAt, $this->createdAt); + $this->repository->insertAuthenticationEvent( + $idpSpUserVersionId, + $this->createdAt, + $this->clientIpAddress, + $this->createdAt + ); $resultArray = $this->repository->getActivity($this->userIdentifierHash, 10, 0); $this->assertCount(4, $resultArray); diff --git a/tests/src/Stores/Data/Authentication/DoctrineDbal/Versioned/StoreTest.php b/tests/src/Stores/Data/Authentication/DoctrineDbal/Versioned/StoreTest.php index 9919d1faf25c5b7039c63054075fe269bf2501ae..5cbed489a9c73a83a2d798d1f600840aa00b73ad 100644 --- a/tests/src/Stores/Data/Authentication/DoctrineDbal/Versioned/StoreTest.php +++ b/tests/src/Stores/Data/Authentication/DoctrineDbal/Versioned/StoreTest.php @@ -54,6 +54,7 @@ use SimpleSAML\Test\Module\accounting\Constants\StateArrays; * @uses \SimpleSAML\Module\accounting\Entities\Activity\Bag * @uses \SimpleSAML\Module\accounting\Entities\Activity * @uses \SimpleSAML\Module\accounting\Stores\Data\Authentication\DoctrineDbal\Versioned\Store\RawActivity + * @uses \SimpleSAML\Module\accounting\Services\HelpersManager * * @psalm-suppress all */ diff --git a/tests/src/Stores/Jobs/DoctrineDbal/Store/RawJobTest.php b/tests/src/Stores/Jobs/DoctrineDbal/Store/RawJobTest.php index 65b9ab9e940fffb0fd4a0806829cbbf71f026742..fa92aa61cf55074ef500e06aff7b025775bbdcf4 100644 --- a/tests/src/Stores/Jobs/DoctrineDbal/Store/RawJobTest.php +++ b/tests/src/Stores/Jobs/DoctrineDbal/Store/RawJobTest.php @@ -18,6 +18,7 @@ use SimpleSAML\Test\Module\accounting\Constants\StateArrays; * @uses \SimpleSAML\Module\accounting\Entities\Authentication\State * @uses \SimpleSAML\Module\accounting\Stores\Bases\DoctrineDbal\AbstractRawEntity * @uses \SimpleSAML\Module\accounting\Helpers\NetworkHelper + * @uses \SimpleSAML\Module\accounting\Services\HelpersManager */ class RawJobTest extends TestCase { diff --git a/tests/src/Stores/Jobs/DoctrineDbal/Store/RepositoryTest.php b/tests/src/Stores/Jobs/DoctrineDbal/Store/RepositoryTest.php index fba787b148762a3f2079904f691b54ae3e4cfc72..30a427bb3d32f4e147a1e99acb3ed55106b1a96f 100644 --- a/tests/src/Stores/Jobs/DoctrineDbal/Store/RepositoryTest.php +++ b/tests/src/Stores/Jobs/DoctrineDbal/Store/RepositoryTest.php @@ -41,6 +41,7 @@ use SimpleSAML\Test\Module\accounting\Constants\StateArrays; * @uses \SimpleSAML\Module\accounting\Entities\Authentication\State * @uses \SimpleSAML\Module\accounting\Stores\Bases\DoctrineDbal\AbstractRawEntity * @uses \SimpleSAML\Module\accounting\Helpers\NetworkHelper + * @uses \SimpleSAML\Module\accounting\Services\HelpersManager */ class RepositoryTest extends TestCase { diff --git a/tests/src/Stores/Jobs/DoctrineDbal/StoreTest.php b/tests/src/Stores/Jobs/DoctrineDbal/StoreTest.php index d4efbb85925d773f9e778e412b8b3be3776d22da..85d78ae3067fcef5cba7ea155cfa9a48d35456ab 100644 --- a/tests/src/Stores/Jobs/DoctrineDbal/StoreTest.php +++ b/tests/src/Stores/Jobs/DoctrineDbal/StoreTest.php @@ -41,6 +41,7 @@ use SimpleSAML\Test\Module\accounting\Constants\StateArrays; * @uses \SimpleSAML\Module\accounting\Entities\Authentication\State * @uses \SimpleSAML\Module\accounting\Stores\Bases\DoctrineDbal\AbstractRawEntity * @uses \SimpleSAML\Module\accounting\Helpers\NetworkHelper + * @uses \SimpleSAML\Module\accounting\Services\HelpersManager */ class StoreTest extends TestCase { @@ -301,4 +302,28 @@ class StoreTest extends TestCase $this->assertNotNull($jobsStore->dequeue()); } + + public function testCanMarkFailedJob(): void + { + /** @psalm-suppress InvalidArgument */ + $jobsStore = new Store($this->moduleConfiguration, $this->loggerStub, $this->factoryStub); + $jobsStore->runSetup(); + + $queryBuilder = $this->connection->dbal()->createQueryBuilder(); + $queryBuilder->select('COUNT(id) as jobsCount') + ->from($jobsStore->getPrefixedTableNameFailedJobs()) + ->fetchOne(); + + $this->assertSame(0, (int) $queryBuilder->executeQuery()->fetchOne()); + + /** @psalm-suppress InvalidArgument */ + $jobsStore->markFailedJob($this->jobStub); + + $this->assertSame(1, (int) $queryBuilder->executeQuery()->fetchOne()); + + /** @psalm-suppress InvalidArgument */ + $jobsStore->markFailedJob($this->jobStub); + + $this->assertSame(2, (int) $queryBuilder->executeQuery()->fetchOne()); + } } diff --git a/tests/src/Trackers/Authentication/DoctrineDbal/Versioned/TrackerTest.php b/tests/src/Trackers/Authentication/DoctrineDbal/Versioned/TrackerTest.php index 7f64ac971b218236af493c6d878aeb32eda7eef3..ba0d0317a059ca2251c028ae7dc7cbd4dbccbf02 100644 --- a/tests/src/Trackers/Authentication/DoctrineDbal/Versioned/TrackerTest.php +++ b/tests/src/Trackers/Authentication/DoctrineDbal/Versioned/TrackerTest.php @@ -9,6 +9,7 @@ use SimpleSAML\Module\accounting\Entities\Activity; use SimpleSAML\Module\accounting\Entities\Authentication\Event; use SimpleSAML\Module\accounting\Entities\ConnectedServiceProvider; use SimpleSAML\Module\accounting\ModuleConfiguration; +use SimpleSAML\Module\accounting\Services\HelpersManager; use SimpleSAML\Module\accounting\Stores\Data\Authentication\DoctrineDbal\Versioned\Store; use SimpleSAML\Module\accounting\Trackers\Authentication\DoctrineDbal\Versioned\Tracker; use PHPUnit\Framework\TestCase; @@ -26,6 +27,8 @@ use SimpleSAML\Test\Module\accounting\Constants\ConnectionParameters; * @uses \SimpleSAML\Module\accounting\Stores\Data\Authentication\DoctrineDbal\Versioned\Store * @uses \SimpleSAML\Module\accounting\Stores\Data\Authentication\DoctrineDbal\Versioned\Store\Repository * @uses \SimpleSAML\Module\accounting\Helpers\HashHelper + * @uses \SimpleSAML\Module\accounting\Services\HelpersManager + * @uses \SimpleSAML\Module\accounting\Stores\Connections\Bases\AbstractMigrator * * @psalm-suppress all */ @@ -43,6 +46,10 @@ class TrackerTest extends TestCase * @var \PHPUnit\Framework\MockObject\MockObject|Store */ protected $dataStoreMock; + /** + * @var \PHPUnit\Framework\MockObject\Stub|HelpersManager + */ + protected $helpersManagerStub; protected function setUp(): void { @@ -51,6 +58,7 @@ class TrackerTest extends TestCase ->willReturn(ConnectionParameters::DBAL_SQLITE_MEMORY); $this->loggerMock = $this->createMock(LoggerInterface::class); $this->dataStoreMock = $this->createMock(Store::class); + $this->helpersManagerStub = $this->createStub(HelpersManager::class); } /** @@ -64,6 +72,7 @@ class TrackerTest extends TestCase $this->moduleConfigurationStub, $this->loggerMock, ModuleConfiguration\ConnectionType::MASTER, + $this->helpersManagerStub, $this->dataStoreMock ) ); @@ -92,6 +101,7 @@ class TrackerTest extends TestCase $this->moduleConfigurationStub, $this->loggerMock, ModuleConfiguration\ConnectionType::MASTER, + $this->helpersManagerStub, $this->dataStoreMock ); @@ -112,6 +122,7 @@ class TrackerTest extends TestCase $this->moduleConfigurationStub, $this->loggerMock, ModuleConfiguration\ConnectionType::MASTER, + $this->helpersManagerStub, $this->dataStoreMock ); @@ -120,6 +131,26 @@ class TrackerTest extends TestCase $tracker->runSetup(); } + public function testRunningSetupIfNotNeededLogsWarning(): void + { + $this->dataStoreMock->method('needsSetup') + ->willReturn(false); + + $this->loggerMock->expects($this->once()) + ->method('warning'); + + /** @psalm-suppress PossiblyInvalidArgument */ + $tracker = new Tracker( + $this->moduleConfigurationStub, + $this->loggerMock, + ModuleConfiguration\ConnectionType::MASTER, + $this->helpersManagerStub, + $this->dataStoreMock + ); + + $tracker->runSetup(); + } + public function testGetConnectedServiceProviders(): void { $connectedOrganizationsBagStub = $this->createStub(ConnectedServiceProvider\Bag::class); @@ -132,6 +163,7 @@ class TrackerTest extends TestCase $this->moduleConfigurationStub, $this->loggerMock, ModuleConfiguration\ConnectionType::MASTER, + $this->helpersManagerStub, $this->dataStoreMock ); @@ -152,6 +184,7 @@ class TrackerTest extends TestCase $this->moduleConfigurationStub, $this->loggerMock, ModuleConfiguration\ConnectionType::MASTER, + $this->helpersManagerStub, $this->dataStoreMock ); diff --git a/tests/src/Trackers/Builders/AuthenticationDataTrackerBuilderTest.php b/tests/src/Trackers/Builders/AuthenticationDataTrackerBuilderTest.php index 6fd033f2cede8c4c430ee49c18c4dcd2d0a96003..cf3bae0c93acf0b4ca09469393c815bcbbaaab51 100644 --- a/tests/src/Trackers/Builders/AuthenticationDataTrackerBuilderTest.php +++ b/tests/src/Trackers/Builders/AuthenticationDataTrackerBuilderTest.php @@ -8,6 +8,7 @@ use Psr\Log\LoggerInterface; use SimpleSAML\Module\accounting\Entities\Authentication\Event; use SimpleSAML\Module\accounting\Exceptions\Exception; use SimpleSAML\Module\accounting\ModuleConfiguration; +use SimpleSAML\Module\accounting\Services\HelpersManager; use SimpleSAML\Module\accounting\Trackers\Builders\AuthenticationDataTrackerBuilder; use PHPUnit\Framework\TestCase; use SimpleSAML\Module\accounting\Trackers\Interfaces\AuthenticationDataTrackerInterface; @@ -16,6 +17,7 @@ use SimpleSAML\Test\Module\accounting\Constants\ConnectionParameters; /** * @covers \SimpleSAML\Module\accounting\Trackers\Builders\AuthenticationDataTrackerBuilder * @uses \SimpleSAML\Module\accounting\Helpers\InstanceBuilderUsingModuleConfigurationHelper + * @uses \SimpleSAML\Module\accounting\Services\HelpersManager * * @psalm-suppress all */ @@ -31,6 +33,7 @@ class AuthenticationDataTrackerBuilderTest extends TestCase protected $moduleConfigurationStub; protected AuthenticationDataTrackerInterface $trackerStub; + protected HelpersManager $helpersManager; protected function setUp(): void { @@ -39,6 +42,8 @@ class AuthenticationDataTrackerBuilderTest extends TestCase ->willReturn(ConnectionParameters::DBAL_SQLITE_MEMORY); $this->loggerMock = $this->createMock(LoggerInterface::class); + $this->helpersManager = new HelpersManager(); + $this->trackerStub = new class implements AuthenticationDataTrackerInterface { public static function build( ModuleConfiguration $moduleConfiguration, @@ -66,7 +71,11 @@ class AuthenticationDataTrackerBuilderTest extends TestCase { $this->assertInstanceOf( AuthenticationDataTrackerBuilder::class, - new AuthenticationDataTrackerBuilder($this->moduleConfigurationStub, $this->loggerMock) + new AuthenticationDataTrackerBuilder( + $this->moduleConfigurationStub, + $this->loggerMock, + $this->helpersManager + ) ); } @@ -74,7 +83,8 @@ class AuthenticationDataTrackerBuilderTest extends TestCase { $authenticationDataTrackerBuilder = new AuthenticationDataTrackerBuilder( $this->moduleConfigurationStub, - $this->loggerMock + $this->loggerMock, + $this->helpersManager ); $trackerClass = get_class($this->trackerStub); @@ -86,7 +96,8 @@ class AuthenticationDataTrackerBuilderTest extends TestCase { $authenticationDataTrackerBuilder = new AuthenticationDataTrackerBuilder( $this->moduleConfigurationStub, - $this->loggerMock + $this->loggerMock, + $this->helpersManager ); $this->expectException(Exception::class);