diff --git a/features/fakes/FakeIdBrokerClient.php b/features/fakes/FakeIdBrokerClient.php index 31899b3a..78654f93 100644 --- a/features/fakes/FakeIdBrokerClient.php +++ b/features/fakes/FakeIdBrokerClient.php @@ -12,7 +12,7 @@ class FakeIdBrokerClient const CORRECT_VALUE = '111111'; const INCORRECT_VALUE = '999999'; - const RATE_LIMITED_MFA_ID = '987'; + const RATE_LIMITED_MFA_ID = 987; /** * Constructor. diff --git a/modules/expirychecker/lib/Auth/Process/ExpiryDate.php b/modules/expirychecker/lib/Auth/Process/ExpiryDate.php index da8edfc4..30322af4 100644 --- a/modules/expirychecker/lib/Auth/Process/ExpiryDate.php +++ b/modules/expirychecker/lib/Auth/Process/ExpiryDate.php @@ -25,16 +25,15 @@ class ExpiryDate extends ProcessingFilter const HAS_SEEN_SPLASH_PAGE = 'has_seen_splash_page'; const SESSION_TYPE = 'expirychecker'; - private $warnDaysBefore = 14; - private $originalUrlParam = 'originalurl'; - private $passwordChangeUrl = null; - private $accountNameAttr = null; - private $employeeIdAttr = 'employeeNumber'; - private $expiryDateAttr = null; - private $dateFormat = 'Y-m-d'; + private int $warnDaysBefore = 14; + private string $originalUrlParam = 'originalurl'; + private string|null $passwordChangeUrl = null; + private string|null $accountNameAttr = null; + private string $employeeIdAttr = 'employeeNumber'; + private string|null $expiryDateAttr = null; + private string $dateFormat = 'Y-m-d'; - /** @var LoggerInterface */ - protected $logger; + protected LoggerInterface $logger; /** * Initialize this filter. @@ -42,7 +41,7 @@ class ExpiryDate extends ProcessingFilter * @param array $config Configuration information about this filter. * @param mixed $reserved For future use. */ - public function __construct($config, $reserved) + public function __construct(array $config, mixed $reserved) { parent::__construct($config, $reserved); @@ -77,7 +76,7 @@ public function __construct($config, $reserved) ]); } - protected function loadValuesFromConfig($config, $attributeRules) + protected function loadValuesFromConfig(array $config, array $attributeRules): void { foreach ($attributeRules as $attribute => $rules) { if (array_key_exists($attribute, $config)) { @@ -99,7 +98,7 @@ protected function loadValuesFromConfig($config, $attributeRules) * @param array $state The state data. * @return mixed The attribute value, or null if not found. */ - protected function getAttribute($attributeName, $state) + protected function getAttribute(string $attributeName, array $state): mixed { $attributeData = $state['Attributes'][$attributeName] ?? null; @@ -118,7 +117,7 @@ protected function getAttribute($attributeName, $state) * expire. * @return int The number of days remaining */ - protected function getDaysLeftBeforeExpiry($expiryTimestamp): int + protected function getDaysLeftBeforeExpiry(int $expiryTimestamp): int { $now = time(); $end = $expiryTimestamp; @@ -135,7 +134,7 @@ protected function getDaysLeftBeforeExpiry($expiryTimestamp): int * @return int The expiration timestamp. * @throws \Exception */ - protected function getExpiryTimestamp($expiryDateAttr, $state) + protected function getExpiryTimestamp(string $expiryDateAttr, array $state): int { $expiryDateString = $this->getAttribute($expiryDateAttr, $state); @@ -153,7 +152,7 @@ protected function getExpiryTimestamp($expiryDateAttr, $state) return $expiryTimestamp; } - public static function hasSeenSplashPageRecently() + public static function hasSeenSplashPageRecently(): bool { $session = Session::getSessionFromRequest(); return (bool)$session->getData( @@ -162,7 +161,7 @@ public static function hasSeenSplashPageRecently() ); } - public static function skipSplashPagesFor($seconds) + public static function skipSplashPagesFor(int $seconds): void { $session = Session::getSessionFromRequest(); $session->setData( @@ -174,7 +173,7 @@ public static function skipSplashPagesFor($seconds) $session->save(); } - protected function initLogger($config) + protected function initLogger(array $config): void { $loggerClass = $config['loggerClass'] ?? Psr3SamlLogger::class; $this->logger = new $loggerClass(); @@ -193,7 +192,7 @@ protected function initLogger($config) * @param int $timestamp The timestamp to check. * @return bool */ - public function isDateInPast(int $timestamp) + public function isDateInPast(int $timestamp): bool { return ($timestamp < time()); } @@ -205,7 +204,7 @@ public function isDateInPast(int $timestamp) * will expire. * @return bool */ - public function isExpired(int $expiryTimestamp) + public function isExpired(int $expiryTimestamp): bool { return $this->isDateInPast($expiryTimestamp); } @@ -219,7 +218,7 @@ public function isExpired(int $expiryTimestamp) * warn the user. * @return boolean */ - public function isTimeToWarn($expiryTimestamp, $warnDaysBefore) + public function isTimeToWarn(int $expiryTimestamp, int $warnDaysBefore): bool { $daysLeft = $this->getDaysLeftBeforeExpiry($expiryTimestamp); return ($daysLeft <= $warnDaysBefore); @@ -235,12 +234,13 @@ public function isTimeToWarn($expiryTimestamp, $warnDaysBefore) * @param int $expiryTimestamp The timestamp when the password will expire. */ public function redirect2PasswordChange( - &$state, - $accountName, - $passwordChangeUrl, - $change_pwd_session, - $expiryTimestamp - ) { + array &$state, + string $accountName, + string $passwordChangeUrl, + string $change_pwd_session, + int $expiryTimestamp + ): void + { $sessionType = 'expirychecker'; /* Save state and redirect. */ $state['expiresAtTimestamp'] = $expiryTimestamp; @@ -302,7 +302,7 @@ public function redirect2PasswordChange( * * @param array &$state The current state. */ - public function process(&$state) + public function process(&$state): void { $employeeId = $this->getAttribute($this->employeeIdAttr, $state); @@ -351,7 +351,7 @@ public function process(&$state) * @param string $accountName The name of the user account. * @param int $expiryTimestamp When the password expired. */ - public function redirectToExpiredPage(&$state, $accountName, $expiryTimestamp) + public function redirectToExpiredPage(array &$state, string $accountName, int $expiryTimestamp): void { assert('is_array($state)'); @@ -379,7 +379,7 @@ public function redirectToExpiredPage(&$state, $accountName, $expiryTimestamp) * @param string $accountName The name of the user account. * @param int $expiryTimestamp When the password will expire. */ - protected function redirectToWarningPage(&$state, $accountName, $expiryTimestamp) + protected function redirectToWarningPage(array &$state, string $accountName, int $expiryTimestamp): void { assert('is_array($state)'); diff --git a/modules/expirychecker/lib/Utilities.php b/modules/expirychecker/lib/Utilities.php index 0e2b80b6..72b8a95b 100644 --- a/modules/expirychecker/lib/Utilities.php +++ b/modules/expirychecker/lib/Utilities.php @@ -10,8 +10,8 @@ class Utilities { * * Returns a string with the domain portion of the url (e.g. www.insitehome.org) */ - public static function getUrlDomain($in_url, $start_marker='//', - $end_marker='/') { + public static function getUrlDomain(string $in_url, string $start_marker='//', string $end_marker='/'): string + { $sm_len = strlen($start_marker); $em_len = strlen($end_marker); @@ -29,9 +29,10 @@ public static function getUrlDomain($in_url, $start_marker='//', * * Returns 1 if the domains of the two urls are the same and 0 otherwise. */ - public static function haveSameDomain($url1, $start_marker1, - $end_marker1, $url2, $start_marker2='//', - $end_marker2='/') { + public static function haveSameDomain(string $url1, string $start_marker1, + string $end_marker1, string $url2, string $start_marker2='//', + string $end_marker2='/'): int + { $domain1 = self::getUrlDomain($url1, $start_marker1, $end_marker1); $domain2 = self::getUrlDomain($url2, $start_marker2, $end_marker2); @@ -51,8 +52,9 @@ public static function haveSameDomain($url1, $start_marker1, * for apex to use. If the domains of the change password url and the * original url are different, it appends the StateId to the output. */ - public static function convertOriginalUrl($passwordChangeUrl, - $originalUrlParam, $originalUrl, $stateId ) { + public static function convertOriginalUrl(string $passwordChangeUrl, + string $originalUrlParam, string $originalUrl, string $stateId ): array|string + { $sameDomain = self::haveSameDomain($passwordChangeUrl, '//', '/', $originalUrl, '//', '/'); $original = $originalUrlParam . ":" . urlencode($originalUrl); @@ -80,7 +82,8 @@ public static function convertOriginalUrl($passwordChangeUrl, * @param string $relayState * @return string **/ - public static function getUrlFromRelayState($relayState) { + public static function getUrlFromRelayState(string $relayState): string + { if (strpos($relayState, "http") === 0) { return $relayState; } diff --git a/modules/expirychecker/lib/Validator.php b/modules/expirychecker/lib/Validator.php index ba0020ac..f17be246 100644 --- a/modules/expirychecker/lib/Validator.php +++ b/modules/expirychecker/lib/Validator.php @@ -20,7 +20,7 @@ class Validator * @param LoggerInterface $logger The logger. * @throws Exception */ - public static function validate($value, $rules, $logger, $attribute) + public static function validate(mixed $value, array $rules, LoggerInterface $logger, string $attribute): void { foreach ($rules as $rule) { if ( ! self::isValid($value, $rule, $logger)) { @@ -47,7 +47,7 @@ public static function validate($value, $rules, $logger, $attribute) * @return bool * @throws InvalidArgumentException */ - protected static function isValid($value, $rule, $logger) + protected static function isValid(mixed $value, string $rule, LoggerInterface $logger): bool { switch ($rule) { case self::INT: diff --git a/modules/mfa/lib/Assert.php b/modules/mfa/lib/Assert.php index 7d0ef245..82285d1c 100644 --- a/modules/mfa/lib/Assert.php +++ b/modules/mfa/lib/Assert.php @@ -15,7 +15,7 @@ class Assert * @param string $className The name of the class in question. * @throws InvalidArgumentException */ - public static function classExists(string $className) + public static function classExists(string $className): void { if (! class_exists($className)) { throw new InvalidArgumentException(sprintf( @@ -32,7 +32,7 @@ public static function classExists(string $className) * @param mixed $value The value in question. * @return string */ - protected static function describe($value) + protected static function describe(mixed $value): string { return is_object($value) ? get_class($value) : var_export($value, true); } @@ -44,7 +44,7 @@ protected static function describe($value) * @param string $className The name/classpath of the class in question. * @throws InvalidArgumentException */ - public static function isInstanceOf($object, string $className) + public static function isInstanceOf(mixed $object, string $className): void { if (! ($object instanceof $className)) { throw new InvalidArgumentException(sprintf( diff --git a/modules/mfa/lib/Auth/Process/Mfa.php b/modules/mfa/lib/Auth/Process/Mfa.php index ce6f38ac..0f1d681a 100644 --- a/modules/mfa/lib/Auth/Process/Mfa.php +++ b/modules/mfa/lib/Auth/Process/Mfa.php @@ -3,10 +3,13 @@ namespace SimpleSAML\Module\mfa\Auth\Process; use Psr\Log\LoggerInterface; +use Sil\Idp\IdBroker\Client\BaseClient; use Sil\PhpEnv\Env; use Sil\Idp\IdBroker\Client\ServiceException; use Sil\Idp\IdBroker\Client\IdBrokerClient; +use Sil\PhpEnv\EnvVarNotFoundException; use Sil\Psr3Adapters\Psr3SamlLogger; +use Sil\SspBase\Features\fakes\FakeIdBrokerClient; use SimpleSAML\Module\mfa\LoggerFactory; use SimpleSAML\Module\mfa\LoginBrowser; use SimpleSAML\Auth\ProcessingChain; @@ -30,21 +33,19 @@ class Mfa extends ProcessingFilter const STAGE_SENT_TO_NEW_BACKUP_CODES_PAGE = 'mfa:sent_to_new_backup_codes_page'; const STAGE_SENT_TO_OUT_OF_BACKUP_CODES_MESSAGE = 'mfa:sent_to_out_of_backup_codes_message'; - private $employeeIdAttr = null; - private $idpDomainName = null; - private $mfaSetupUrl = null; + private string|null $employeeIdAttr = null; + private string|null $idpDomainName = null; + private string|null $mfaSetupUrl = null; - private $idBrokerAccessToken = null; - private $idBrokerAssertValidIp; - private $idBrokerBaseUri = null; - private $idBrokerClientClass = null; - private $idBrokerTrustedIpRanges = []; + private string|null $idBrokerAccessToken = null; + private bool $idBrokerAssertValidIp; + private string|null $idBrokerBaseUri = null; + private string|null $idBrokerClientClass = null; + private array $idBrokerTrustedIpRanges = []; - /** @var LoggerInterface */ - protected $logger; + protected LoggerInterface $logger; - /** @var string */ - protected $loggerClass; + protected string $loggerClass; /** * Initialize this filter. @@ -53,7 +54,7 @@ class Mfa extends ProcessingFilter * @param mixed $reserved For future use. * @throws \Exception */ - public function __construct($config, $reserved) + public function __construct(array $config, mixed $reserved) { parent::__construct($config, $reserved); $this->initComposerAutoloader(); @@ -78,7 +79,7 @@ public function __construct($config, $reserved) $this->idBrokerClientClass = $config['idBrokerClientClass'] ?? IdBrokerClient::class; } - protected function loadValuesFromConfig($config, $attributes) + protected function loadValuesFromConfig(array $config, array $attributes): void { foreach ($attributes as $attribute) { $this->$attribute = $config[$attribute] ?? null; @@ -99,7 +100,7 @@ protected function loadValuesFromConfig($config, $attributes) * @param LoggerInterface $logger The logger. * @throws \Exception */ - public static function validateConfigValue($attribute, $value, $logger) + public static function validateConfigValue(string $attribute, mixed $value, LoggerInterface $logger): void { if (empty($value) || !is_string($value)) { $exception = new \Exception(sprintf( @@ -124,7 +125,7 @@ public static function validateConfigValue($attribute, $value, $logger) * @param array $state The state data. * @return mixed The attribute value, or null if not found. */ - protected function getAttribute($attributeName, $state) + protected function getAttribute(string $attributeName, array $state): mixed { $attributeData = $state['Attributes'][$attributeName] ?? null; @@ -147,7 +148,7 @@ protected function getAttribute($attributeName, $state) * @return array|null The attribute's value(s), or null if the attribute was * not found. */ - protected function getAttributeAllValues($attributeName, $state) + protected function getAttributeAllValues(string $attributeName, array $state): ?array { $attributeData = $state['Attributes'][$attributeName] ?? null; @@ -160,7 +161,7 @@ protected function getAttributeAllValues($attributeName, $state) * @param array $idBrokerConfig * @return IdBrokerClient */ - protected static function getIdBrokerClient($idBrokerConfig) + protected static function getIdBrokerClient(array $idBrokerConfig): IdBrokerClient|FakeIdBrokerClient { $clientClass = $idBrokerConfig['clientClass']; $baseUri = $idBrokerConfig['baseUri']; @@ -186,7 +187,7 @@ protected static function getIdBrokerClient($idBrokerConfig) * @throws \InvalidArgumentException * @throws \Exception */ - public static function getMfaOptionById($mfaOptions, $mfaId) + public static function getMfaOptionById(array $mfaOptions, int $mfaId): array { if (empty($mfaId)) { throw new \Exception('No MFA ID was provided.'); @@ -213,7 +214,7 @@ public static function getMfaOptionById($mfaOptions, $mfaId) * @throws \InvalidArgumentException * @throws \Exception */ - public static function getMfaOptionToUse($mfaOptions, $userAgent) + public static function getMfaOptionToUse(array $mfaOptions, string $userAgent): array { if (empty($mfaOptions)) { throw new \Exception('No MFA options were provided.'); @@ -253,7 +254,8 @@ public static function getMfaOptionToUse($mfaOptions, $userAgent) * @param array[] $mfaOptions The available MFA options. * @return ?array The MFA option to use. */ - private static function getMostRecentUsedMfaOption($mfaOptions) { + private static function getMostRecentUsedMfaOption(array $mfaOptions): ?array + { $recentMfa = null; $recentDate = '1991-01-01T00:00:00Z'; @@ -270,10 +272,9 @@ private static function getMostRecentUsedMfaOption($mfaOptions) { * Get the number of backup codes that the user had left PRIOR to this login. * * @param array $mfaOptions The list of MFA options. - * @return int The number of backup codes that the user HAD (prior to this - * login). + * @return int The number of backup codes that the user HAD (prior to this login). */ - public static function getNumBackupCodesUserHad(array $mfaOptions) + public static function getNumBackupCodesUserHad(array $mfaOptions): int { $numBackupCodes = 0; foreach ($mfaOptions as $mfaOption) { @@ -293,7 +294,7 @@ public static function getNumBackupCodesUserHad(array $mfaOptions) * @return string * @throws \InvalidArgumentException */ - public static function getTemplateFor($mfaType) + public static function getTemplateFor(string $mfaType): string { $mfaOptionTemplates = [ 'backupcode' => 'mfa:prompt-for-mfa-backupcode.php', @@ -344,7 +345,7 @@ public static function getRelayStateUrl(array $state): string * @param array $state The state data. * @param LoggerInterface $logger A PSR-3 compatible logger. */ - public static function giveUserNewBackupCodes(array &$state, $logger) + public static function giveUserNewBackupCodes(array &$state, LoggerInterface $logger): void { try { $idBrokerClient = self::getIdBrokerClient($state['idBrokerConfig']); @@ -375,7 +376,7 @@ public static function giveUserNewBackupCodes(array &$state, $logger) HTTP::redirectTrustedURL($url, ['StateId' => $stateId]); } - protected static function hasMfaOptions($mfa) + protected static function hasMfaOptions(array $mfa): bool { return (count($mfa['options']) > 0); } @@ -387,7 +388,7 @@ protected static function hasMfaOptions($mfa) * @param array $state * @return bool */ - public static function hasMfaOptionsOtherThan($excludedMfaType, $state) + public static function hasMfaOptionsOtherThan(string $excludedMfaType, array $state): bool { $mfaOptions = $state['mfaOptions'] ?? []; foreach ($mfaOptions as $mfaOption) { @@ -398,7 +399,7 @@ public static function hasMfaOptionsOtherThan($excludedMfaType, $state) return false; } - protected function initComposerAutoloader() + protected function initComposerAutoloader(): void { $path = __DIR__ . '/../../../vendor/autoload.php'; if (file_exists($path)) { @@ -430,20 +431,20 @@ public static function isHeadedToUrl(array $state, string $url): bool * @param LoggerInterface $logger A PSR-3 compatible logger. * @param string $mfaType The type of the MFA ('webauthn', 'totp', 'backupcode'). * @param string $rpOrigin The Relying Party Origin (for WebAuthn) - * @return void|string If validation fails, an error message to show to the + * @return string If validation fails, an error message to show to the * end user will be returned. * @throws \Sil\PhpEnv\EnvVarNotFoundException */ public static function validateMfaSubmission( - $mfaId, - $employeeId, - $mfaSubmission, - $state, - $rememberMe, + int $mfaId, + string $employeeId, + string $mfaSubmission, + array $state, + bool $rememberMe, LoggerInterface $logger, string $mfaType, string $rpOrigin - ) { + ): string { if (empty($mfaId)) { return 'No MFA ID was provided.'; } elseif (empty($employeeId)) { @@ -543,7 +544,7 @@ public static function validateMfaSubmission( * * @param array $state */ - public static function redirectToMfaSetup(&$state) + public static function redirectToMfaSetup(array &$state): void { $mfaSetupUrl = $state['mfaSetupUrl']; @@ -573,7 +574,7 @@ public static function redirectToMfaSetup(&$state) * * @param array &$state The current state. */ - public function process(&$state) + public function process(&$state): void { // Get the necessary info from the state data. $employeeId = $this->getAttribute($this->employeeIdAttr, $state); @@ -621,7 +622,7 @@ public function process(&$state) * @param string $employeeId The Employee ID of the user account. * @param string $mfaSetupUrl URL to MFA setup process */ - protected function redirectToMfaNeededMessage(&$state, $employeeId, $mfaSetupUrl) + protected function redirectToMfaNeededMessage(array &$state, string $employeeId, string $mfaSetupUrl): void { assert('is_array($state)'); @@ -648,7 +649,7 @@ protected function redirectToMfaNeededMessage(&$state, $employeeId, $mfaSetupUrl * @param array $mfaOptions Array of MFA options * @throws \Exception */ - protected function redirectToMfaPrompt(&$state, $employeeId, $mfaOptions) + protected function redirectToMfaPrompt(array &$state, string $employeeId, array $mfaOptions): void { assert('is_array($state)'); @@ -696,16 +697,16 @@ protected function redirectToMfaPrompt(&$state, $employeeId, $mfaOptions) * Validate that remember me cookie values are legit and valid * @param string $cookieHash * @param string $expireDate - * @param $mfaOptions - * @param $state + * @param array $mfaOptions + * @param array $state * @return bool - * @throws \Sil\PhpEnv\EnvVarNotFoundException + * @throws EnvVarNotFoundException */ public static function isRememberMeCookieValid( string $cookieHash, string $expireDate, - $mfaOptions, - $state + array $mfaOptions, + array $state ): bool { $rememberSecret = Env::requireEnv('REMEMBER_ME_SECRET'); if (! empty($cookieHash) && ! empty($expireDate) && is_numeric($expireDate)) { @@ -757,9 +758,9 @@ public static function generateRememberMeCookieString( */ protected static function redirectToLowOnBackupCodesNag( array &$state, - $employeeId, - $numBackupCodesRemaining - ) { + string $employeeId, + int $numBackupCodesRemaining + ): void { $state['employeeId'] = $employeeId; $state['numBackupCodesRemaining'] = (string)$numBackupCodesRemaining; @@ -778,7 +779,7 @@ protected static function redirectToLowOnBackupCodesNag( * @param array $state The state data. * @param string $employeeId The Employee ID of the user account. */ - protected static function redirectToOutOfBackupCodesMessage(array &$state, $employeeId) + protected static function redirectToOutOfBackupCodesMessage(array &$state, string $employeeId): void { $state['employeeId'] = $employeeId; @@ -799,7 +800,7 @@ public static function setRememberMeCookies( string $employeeId, array $mfaOptions, string $rememberDuration = '+30 days' - ) { + ): void { $rememberSecret = Env::requireEnv('REMEMBER_ME_SECRET'); $secureCookie = Env::get('SECURE_COOKIE', true); $expireDate = strtotime($rememberDuration); @@ -809,7 +810,7 @@ public static function setRememberMeCookies( setcookie('c2', $expireDate, $expireDate, '/', null, $secureCookie, true); } - protected static function shouldPromptForMfa($mfa) + protected static function shouldPromptForMfa(array $mfa): bool { return (strtolower($mfa['prompt']) !== 'no'); } @@ -823,7 +824,7 @@ protected static function shouldPromptForMfa($mfa) * @param array $state The state data. * @param LoggerInterface $logger A PSR-3 compatible logger. */ - public static function sendManagerCode(array &$state, $logger) + public static function sendManagerCode(array &$state, LoggerInterface $logger): void { try { $idBrokerClient = self::getIdBrokerClient($state['idBrokerConfig']); @@ -864,7 +865,7 @@ public static function sendManagerCode(array &$state, $logger) * @param array $state * @return string|null */ - public static function getManagerEmail($state) + public static function getManagerEmail(array $state): ?string { $managerEmail = $state['Attributes']['manager_email'] ?? ['']; if (empty($managerEmail[0])) { @@ -880,7 +881,7 @@ public static function getManagerEmail($state) * @return array The manager MFA. * @throws \InvalidArgumentException */ - public static function getManagerMfa($mfaOptions) + public static function getManagerMfa(array $mfaOptions): ?array { foreach ($mfaOptions as $mfaOption) { if ($mfaOption['type'] === 'manager') { @@ -895,7 +896,7 @@ public static function getManagerMfa($mfaOptions) * @param string $email an email address * @return string with most letters changed to asterisks */ - public static function maskEmail($email) + public static function maskEmail(string $email): string { list($part1, $domain) = explode('@', $email); $newEmail = ''; @@ -942,7 +943,7 @@ public static function maskEmail($email) * @param array $state * @param LoggerInterface $logger */ - protected static function updateStateWithNewMfaData(&$state, $logger) + protected static function updateStateWithNewMfaData(array &$state, LoggerInterface $logger): void { $idBrokerClient = self::getIdBrokerClient($state['idBrokerConfig']); diff --git a/modules/mfa/lib/LoggerFactory.php b/modules/mfa/lib/LoggerFactory.php index ffdadd6b..b42c6beb 100644 --- a/modules/mfa/lib/LoggerFactory.php +++ b/modules/mfa/lib/LoggerFactory.php @@ -16,7 +16,7 @@ class LoggerFactory * * @throws InvalidArgumentException */ - public static function get($loggerClass) + public static function get(string $loggerClass): LoggerInterface { Assert::classExists($loggerClass); $logger = new $loggerClass(); @@ -34,7 +34,7 @@ public static function get($loggerClass) * * @throws InvalidArgumentException */ - public static function getAccordingToState($state) + public static function getAccordingToState(array $state): LoggerInterface { return self::get($state['loggerClass'] ?? Psr3SamlLogger::class); } diff --git a/modules/mfa/lib/LoginBrowser.php b/modules/mfa/lib/LoginBrowser.php index 77b1abca..19c57b37 100644 --- a/modules/mfa/lib/LoginBrowser.php +++ b/modules/mfa/lib/LoginBrowser.php @@ -13,13 +13,13 @@ class LoginBrowser * * @return string|null */ - public static function getUserAgent() + public static function getUserAgent(): ?string { return filter_input(INPUT_SERVER, 'HTTP_USER_AGENT') ?: null; } // TODO: Replace this with client-side feature detection. - public static function supportsWebAuthn($userAgent) + public static function supportsWebAuthn(string $userAgent): bool { $browser = new Browser($userAgent); $browserName = $browser->getName(); diff --git a/modules/profilereview/lib/Assert.php b/modules/profilereview/lib/Assert.php index f20dff99..af7bf7dc 100644 --- a/modules/profilereview/lib/Assert.php +++ b/modules/profilereview/lib/Assert.php @@ -13,7 +13,7 @@ class Assert * @param string $className The name of the class in question. * @throws InvalidArgumentException */ - public static function classExists(string $className) + public static function classExists(string $className): void { if (! class_exists($className)) { throw new InvalidArgumentException(sprintf( @@ -30,7 +30,7 @@ public static function classExists(string $className) * @param mixed $value The value in question. * @return string */ - protected static function describe($value) + protected static function describe(mixed $value): string { return is_object($value) ? get_class($value) : var_export($value, true); } @@ -42,7 +42,7 @@ protected static function describe($value) * @param string $className The name/classpath of the class in question. * @throws InvalidArgumentException */ - public static function isInstanceOf($object, string $className) + public static function isInstanceOf(mixed $object, string $className): void { if (! ($object instanceof $className)) { throw new InvalidArgumentException(sprintf( diff --git a/modules/profilereview/lib/Auth/Process/ProfileReview.php b/modules/profilereview/lib/Auth/Process/ProfileReview.php index 87a62cd3..b34e0567 100644 --- a/modules/profilereview/lib/Auth/Process/ProfileReview.php +++ b/modules/profilereview/lib/Auth/Process/ProfileReview.php @@ -26,15 +26,13 @@ class ProfileReview extends ProcessingFilter const MFA_ADD_PAGE = 'nag-for-mfa.php'; const METHOD_ADD_PAGE = 'nag-for-method.php'; - private $employeeIdAttr = null; - private $mfaLearnMoreUrl = null; - private $profileUrl = null; + private string|null $employeeIdAttr = null; + private string|null $mfaLearnMoreUrl = null; + private string|null $profileUrl = null; - /** @var LoggerInterface */ - protected $logger; + protected LoggerInterface $logger; - /** @var string */ - protected $loggerClass; + protected string $loggerClass; /** * Initialize this filter. @@ -43,7 +41,7 @@ class ProfileReview extends ProcessingFilter * @param mixed $reserved For future use. * @throws \Exception */ - public function __construct($config, $reserved) + public function __construct(array $config, mixed $reserved) { parent::__construct($config, $reserved); $this->initComposerAutoloader(); @@ -66,7 +64,7 @@ public function __construct($config, $reserved) * @param $attributes * @throws \Exception */ - protected function loadValuesFromConfig($config, $attributes) + protected function loadValuesFromConfig(array $config, array $attributes): void { foreach ($attributes as $attribute) { $this->$attribute = $config[$attribute] ?? null; diff --git a/modules/profilereview/lib/LoggerFactory.php b/modules/profilereview/lib/LoggerFactory.php index 83e335d1..8381476a 100644 --- a/modules/profilereview/lib/LoggerFactory.php +++ b/modules/profilereview/lib/LoggerFactory.php @@ -14,7 +14,7 @@ class LoggerFactory * * @throws InvalidArgumentException */ - public static function get($loggerClass) + public static function get(string $loggerClass): LoggerInterface { Assert::classExists($loggerClass); $logger = new $loggerClass(); @@ -32,7 +32,7 @@ public static function get($loggerClass) * * @throws InvalidArgumentException */ - public static function getAccordingToState($state) + public static function getAccordingToState(array $state): LoggerInterface { return self::get($state['loggerClass'] ?? Psr3SamlLogger::class); } diff --git a/modules/silauth/lib/Auth/Source/SilAuth.php b/modules/silauth/lib/Auth/Source/SilAuth.php index 6560b4d9..f7c0624f 100644 --- a/modules/silauth/lib/Auth/Source/SilAuth.php +++ b/modules/silauth/lib/Auth/Source/SilAuth.php @@ -23,11 +23,11 @@ */ class SilAuth extends UserPassBase { - protected $authConfig; - protected $idBrokerConfig; - protected $mysqlConfig; - protected $recaptchaConfig; - protected $templateData; + protected array $authConfig; + protected array $idBrokerConfig; + protected array $mysqlConfig; + protected array $recaptchaConfig; + protected array $templateData; /** * Constructor for this authentication source. @@ -38,7 +38,7 @@ class SilAuth extends UserPassBase * @param array $info Information about this authentication source. * @param array $config Configuration for this authentication source. */ - public function __construct($info, $config) + public function __construct(array $info, array $config) { parent::__construct($info, $config); @@ -67,7 +67,7 @@ public function __construct($info, $config) * * @param array &$state Information about the current authentication. */ - public function authenticate(&$state) + public function authenticate(&$state): void { assert('is_array($state)'); @@ -95,7 +95,7 @@ public function authenticate(&$state) assert('FALSE'); } - protected function getTrustedIpAddresses() + protected function getTrustedIpAddresses(): array { $trustedIpAddresses = []; $ipAddressesString = $this->authConfig['trustedIpAddresses'] ?? ''; @@ -108,7 +108,7 @@ protected function getTrustedIpAddresses() return $trustedIpAddresses; } - protected function login($username, $password) + protected function login($username, $password): ?array { $logger = new Psr3StdOutLogger(); $captcha = new Captcha($this->recaptchaConfig['secret'] ?? null); diff --git a/modules/silauth/lib/Auth/Source/auth/AuthError.php b/modules/silauth/lib/Auth/Source/auth/AuthError.php index e46a4abb..6eefe024 100644 --- a/modules/silauth/lib/Auth/Source/auth/AuthError.php +++ b/modules/silauth/lib/Auth/Source/auth/AuthError.php @@ -16,8 +16,8 @@ class AuthError const CODE_RATE_LIMIT_1_MINUTE = 'rate_limit_1_minute'; const CODE_RATE_LIMIT_MINUTES = 'rate_limit_minutes'; - private $code = null; - private $messageParams = []; + private string $code; + private array $messageParams = []; /** * Constructor. @@ -25,7 +25,7 @@ class AuthError * @param string $code One of the AuthError::CODE_* constants. * @param array $messageParams The error message parameters. */ - public function __construct($code, $messageParams = []) + public function __construct(string $code, array $messageParams = []) { $this->code = $code; $this->messageParams = $messageParams; @@ -44,7 +44,7 @@ public function __toString() * * @return string */ - public function getCode() + public function getCode(): string { return $this->code; } @@ -56,7 +56,7 @@ public function getCode() * * @return string Example: '{silauth:error:generic_try_later}' */ - public function getFullSspErrorTag() + public function getFullSspErrorTag(): string { return sprintf( '{%s:%s}', @@ -65,7 +65,7 @@ public function getFullSspErrorTag() ); } - public function getMessageParams() + public function getMessageParams(): array { return $this->messageParams; } diff --git a/modules/silauth/lib/Auth/Source/auth/Authenticator.php b/modules/silauth/lib/Auth/Source/auth/Authenticator.php index 82ca08fa..2e91ed7e 100644 --- a/modules/silauth/lib/Auth/Source/auth/Authenticator.php +++ b/modules/silauth/lib/Auth/Source/auth/Authenticator.php @@ -21,13 +21,9 @@ class Authenticator const BLOCK_AFTER_NTH_FAILED_LOGIN = 50; const MAX_SECONDS_TO_BLOCK = 3600; // 3600 seconds = 1 hour - /** @var AuthError|null */ - private $authError = null; - - /** @var LoggerInterface */ - protected $logger; - - private $userAttributes = null; + private ?AuthError $authError = null; + protected LoggerInterface $logger; + private ?array $userAttributes = null; /** * Attempt to authenticate using the given username and password. Check @@ -41,12 +37,12 @@ class Authenticator * @param LoggerInterface $logger A PSR-3 compliant logger. */ public function __construct( - $username, - $password, - Request $request, - Captcha $captcha, - IdBroker $idBroker, - LoggerInterface $logger + string $username, + string $password, + Request $request, + Captcha $captcha, + IdBroker $idBroker, + LoggerInterface $logger ) { $this->logger = $logger; @@ -143,7 +139,7 @@ public function __construct( * @return int The number of seconds to delay before allowing another such * login attempt. */ - public static function calculateSecondsToDelay($numRecentFailures) + public static function calculateSecondsToDelay(int $numRecentFailures): int { if ( ! self::isEnoughFailedLoginsToBlock($numRecentFailures)) { return 0; @@ -164,7 +160,7 @@ public static function calculateSecondsToDelay($numRecentFailures) * * @return AuthError|null */ - public function getAuthError() + public function getAuthError(): ?AuthError { return $this->authError; } @@ -184,8 +180,9 @@ public function getAuthError() */ public static function getSecondsUntilUnblocked( int $numRecentFailures, - $mostRecentFailureAt - ) { + ?string $mostRecentFailureAt + ): int + { if ($mostRecentFailureAt === null) { return 0; } @@ -216,7 +213,7 @@ public static function getSecondsUntilUnblocked( * * @throws \Exception */ - public function getUserAttributes() + public function getUserAttributes(): ?array { if ($this->userAttributes === null) { throw new \Exception( @@ -242,7 +239,7 @@ public function getUserAttributes() * this request). * @return WaitTime */ - protected function getWaitTimeUntilUnblocked($username, array $ipAddresses) + protected function getWaitTimeUntilUnblocked(string $username, array $ipAddresses): WaitTime { $durationsInSeconds = [ FailedLoginUsername::getSecondsUntilUnblocked($username), @@ -255,7 +252,7 @@ protected function getWaitTimeUntilUnblocked($username, array $ipAddresses) return WaitTime::getLongestWaitTime($durationsInSeconds); } - protected function hasError() + protected function hasError(): bool { return ($this->authError !== null); } @@ -266,46 +263,46 @@ protected function hasError() * * @return bool */ - public function isAuthenticated() + public function isAuthenticated(): bool { return ( ! $this->hasError()); } - protected function isBlockedByRateLimit($username, array $ipAddresses) + protected function isBlockedByRateLimit(string $username, array $ipAddresses): bool { return FailedLoginUsername::isRateLimitBlocking($username) || FailedLoginIpAddress::isRateLimitBlockingAnyOfThese($ipAddresses); } - public static function isCaptchaRequired($username, array $ipAddresses) + public static function isCaptchaRequired(string $username, array $ipAddresses): bool { return FailedLoginUsername::isCaptchaRequiredFor($username) || FailedLoginIpAddress::isCaptchaRequiredForAnyOfThese($ipAddresses); } - public static function isEnoughFailedLoginsToBlock($numFailedLogins) + public static function isEnoughFailedLoginsToBlock(int $numFailedLogins): bool { return ($numFailedLogins >= self::BLOCK_AFTER_NTH_FAILED_LOGIN); } - public static function isEnoughFailedLoginsToRequireCaptcha($numFailedLogins) + public static function isEnoughFailedLoginsToRequireCaptcha(int $numFailedLogins): bool { return ($numFailedLogins >= self::REQUIRE_CAPTCHA_AFTER_NTH_FAILED_LOGIN); } - protected function recordFailedLoginBy($username, array $ipAddresses) + protected function recordFailedLoginBy(string $username, array $ipAddresses): void { FailedLoginUsername::recordFailedLoginBy($username, $this->logger); FailedLoginIpAddress::recordFailedLoginBy($ipAddresses, $this->logger); } - protected function resetFailedLoginsBy($username, array $ipAddresses) + protected function resetFailedLoginsBy(string $username, array $ipAddresses): void { FailedLoginUsername::resetFailedLoginsBy($username); FailedLoginIpAddress::resetFailedLoginsBy($ipAddresses); } - protected function setError($code, $messageParams = []) + protected function setError(string $code, array $messageParams = []): void { $this->authError = new AuthError($code, $messageParams); } @@ -313,7 +310,7 @@ protected function setError($code, $messageParams = []) /** * @param WaitTime $waitTime */ - protected function setErrorBlockedByRateLimit($waitTime) + protected function setErrorBlockedByRateLimit(WaitTime $waitTime): void { $unit = $waitTime->getUnit(); $number = $waitTime->getFriendlyNumber(); @@ -331,32 +328,32 @@ protected function setErrorBlockedByRateLimit($waitTime) $this->setError($errorCode, ['{number}' => $number]); } - protected function setErrorGenericTryLater() + protected function setErrorGenericTryLater(): void { $this->setError(AuthError::CODE_GENERIC_TRY_LATER); } - protected function setErrorInvalidLogin() + protected function setErrorInvalidLogin(): void { $this->setError(AuthError::CODE_INVALID_LOGIN); } - protected function setErrorNeedToSetAcctPassword() + protected function setErrorNeedToSetAcctPassword(): void { $this->setError(AuthError::CODE_NEED_TO_SET_ACCT_PASSWORD); } - protected function setErrorPasswordRequired() + protected function setErrorPasswordRequired(): void { $this->setError(AuthError::CODE_PASSWORD_REQUIRED); } - protected function setErrorUsernameRequired() + protected function setErrorUsernameRequired(): void { $this->setError(AuthError::CODE_USERNAME_REQUIRED); } - protected function setUserAttributes($attributes) + protected function setUserAttributes($attributes): void { $this->userAttributes = $attributes; } diff --git a/modules/silauth/lib/Auth/Source/auth/IdBroker.php b/modules/silauth/lib/Auth/Source/auth/IdBroker.php index 78f1cbd4..d542efa5 100644 --- a/modules/silauth/lib/Auth/Source/auth/IdBroker.php +++ b/modules/silauth/lib/Auth/Source/auth/IdBroker.php @@ -3,17 +3,17 @@ use Psr\Log\LoggerInterface; use Sil\Idp\IdBroker\Client\IdBrokerClient; +use Sil\SspBase\Features\fakes\FakeIdBrokerClient; use SimpleSAML\Module\silauth\Auth\Source\saml\User as SamlUser; class IdBroker { - /** @var IdBrokerClient */ - protected $client; + protected IdBrokerClient|FakeIdBrokerClient $client; /** @var LoggerInterface */ - protected $logger; + protected LoggerInterface $logger; - protected $idpDomainName; + protected string $idpDomainName; /** * @@ -64,7 +64,7 @@ public function __construct( * @return array|null The user's attributes (if successful), otherwise null. * @throws \Exception */ - public function getAuthenticatedUser(string $username, string $password) + public function getAuthenticatedUser(string $username, string $password): ?array { $rpOrigin = 'https://' . $this->idpDomainName; $userInfo = $this->client->authenticate($username, $password, $rpOrigin); @@ -102,7 +102,7 @@ public function getAuthenticatedUser(string $username, string $password) * @return string "OK" * @throws Exception */ - public function getSiteStatus() + public function getSiteStatus(): string { return $this->client->getSiteStatus(); } diff --git a/modules/silauth/lib/Auth/Source/captcha/Captcha.php b/modules/silauth/lib/Auth/Source/captcha/Captcha.php index bffc6d46..3d001b8d 100644 --- a/modules/silauth/lib/Auth/Source/captcha/Captcha.php +++ b/modules/silauth/lib/Auth/Source/captcha/Captcha.php @@ -5,14 +5,14 @@ class Captcha { - private $secret; + private ?string $secret; - public function __construct($secret = null) + public function __construct(?string $secret = null) { $this->secret = $secret; } - public function isValidIn(Request $request) + public function isValidIn(Request $request): bool { if (empty($this->secret)) { throw new \RuntimeException('No captcha secret available.', 1487342411); diff --git a/modules/silauth/lib/Auth/Source/config/ConfigManager.php b/modules/silauth/lib/Auth/Source/config/ConfigManager.php index 0e95ecb7..553cac78 100644 --- a/modules/silauth/lib/Auth/Source/config/ConfigManager.php +++ b/modules/silauth/lib/Auth/Source/config/ConfigManager.php @@ -2,6 +2,7 @@ namespace SimpleSAML\Module\silauth\Auth\Source\config; use SimpleSAML\Module\silauth\Auth\Source\text\Text; +use yii\console\Application; class ConfigManager { @@ -12,7 +13,7 @@ class ConfigManager * * @return array */ - public static function getSspConfig() + public static function getSspConfig(): array { return require __DIR__ . '/ssp-config.php'; } @@ -26,7 +27,7 @@ public static function getSspConfig() * prefix will have been removed, so 'mysql.database' will be returned * as 'database', etc. */ - public static function getSspConfigFor($category) + public static function getSspConfigFor(string $category): array { return self::getConfigFor($category, self::getSspConfig()); } @@ -41,7 +42,7 @@ public static function getSspConfigFor($category) * prefix will have been removed, so 'mysql.database' will be returned * as 'database', etc. */ - public static function getConfigFor($category, $config) + public static function getConfigFor(string $category, array $config): array { $categoryPrefix = $category . self::SEPARATOR; $categoryConfig = []; @@ -60,7 +61,7 @@ public static function getConfigFor($category, $config) * @param array $customConfig * @return array */ - public static function getMergedYii2Config($customConfig) + public static function getMergedYii2Config(array $customConfig): array { $defaultConfig = require __DIR__ . '/yii2-config.php'; return array_replace_recursive( @@ -69,21 +70,21 @@ public static function getMergedYii2Config($customConfig) ); } - private static function initializeYiiClass() + private static function initializeYiiClass(): void { if ( ! class_exists('Yii')) { require_once __DIR__ . '/../../vendor/yiisoft/yii2/Yii.php'; } } - public static function getYii2ConsoleApp($customConfig) + public static function getYii2ConsoleApp(array $customConfig): Application { self::initializeYiiClass(); $mergedYii2Config = self::getMergedYii2Config($customConfig); - return new \yii\console\Application($mergedYii2Config); + return new Application($mergedYii2Config); } - public static function initializeYii2WebApp($customConfig = []) + public static function initializeYii2WebApp(array $customConfig = []): void { self::initializeYiiClass(); @@ -99,7 +100,7 @@ public static function initializeYii2WebApp($customConfig = []) $app->log->getLogger(); } - public static function removeCategory($key) + public static function removeCategory($key): bool|string|null { if ($key === null) { return null; diff --git a/modules/silauth/lib/Auth/Source/csrf/CsrfProtector.php b/modules/silauth/lib/Auth/Source/csrf/CsrfProtector.php index b913d51f..966b36ed 100644 --- a/modules/silauth/lib/Auth/Source/csrf/CsrfProtector.php +++ b/modules/silauth/lib/Auth/Source/csrf/CsrfProtector.php @@ -9,9 +9,9 @@ */ class CsrfProtector { - protected $csrfSessionKey = 'silauth.csrfToken'; - protected $csrfTokenDataType = 'string'; - private $session; + protected string $csrfSessionKey = 'silauth.csrfToken'; + protected string $csrfTokenDataType = 'string'; + private Session $session; /** * Constructor. @@ -23,13 +23,13 @@ public function __construct(Session $session) $this->session = $session; } - public function changeMasterToken() + public function changeMasterToken(): void { $newMasterToken = $this->generateToken(); $this->setTokenInSession($newMasterToken); } - protected function generateToken() + protected function generateToken(): string { return bin2hex(random_bytes(32)); } @@ -40,7 +40,7 @@ protected function generateToken() * * @return string The master (aka. authoritative) CSRF token. */ - public function getMasterToken() + public function getMasterToken(): string { $masterToken = $this->getTokenFromSession(); if (empty($masterToken)) { @@ -50,7 +50,7 @@ public function getMasterToken() return $masterToken; } - protected function getTokenFromSession() + protected function getTokenFromSession(): mixed { return $this->session->getData( $this->csrfTokenDataType, @@ -65,12 +65,12 @@ protected function getTokenFromSession() * HTTP request. * @return bool */ - public function isTokenCorrect($submittedToken) + public function isTokenCorrect(string $submittedToken): bool { return hash_equals($this->getMasterToken(), $submittedToken); } - protected function setTokenInSession($masterToken) + protected function setTokenInSession(string $masterToken): void { $this->session->setData( $this->csrfTokenDataType, diff --git a/modules/silauth/lib/Auth/Source/http/Request.php b/modules/silauth/lib/Auth/Source/http/Request.php index fe6f242c..fda2d155 100644 --- a/modules/silauth/lib/Auth/Source/http/Request.php +++ b/modules/silauth/lib/Auth/Source/http/Request.php @@ -12,14 +12,14 @@ class Request * * @var IP[] */ - private $trustedIpAddresses = []; + private array $trustedIpAddresses = []; /** * The list of trusted IP address ranges (aka. blocks). * * @var IPBlock[] */ - private $trustedIpAddressRanges = []; + private array $trustedIpAddressRanges = []; /** * Constructor. @@ -39,7 +39,7 @@ public function __construct(array $ipAddressesToTrust = []) } } - public function getCaptchaResponse() + public function getCaptchaResponse(): string { return self::sanitizeInputString(INPUT_POST, 'g-recaptcha-response'); } @@ -53,7 +53,7 @@ public function getCaptchaResponse() * * @return string[] A list of IP addresses. */ - public function getIpAddresses() + public function getIpAddresses(): array { $ipAddresses = []; @@ -84,7 +84,7 @@ public function getIpAddresses() * * @return string|null An IP address, or null if none was available. */ - public function getMostLikelyIpAddress() + public function getMostLikelyIpAddress(): ?string { $untrustedIpAddresses = $this->getUntrustedIpAddresses(); @@ -117,13 +117,13 @@ public function getMostLikelyIpAddress() * @param string $variableName Example: 'username' * @return string */ - public static function getRawInputString(int $inputType, string $variableName) + public static function getRawInputString(int $inputType, string $variableName): string { $input = filter_input($inputType, $variableName); return is_string($input) ? $input : ''; } - public function getUntrustedIpAddresses() + public function getUntrustedIpAddresses(): array { $untrustedIpAddresses = []; foreach ($this->getIpAddresses() as $ipAddress) { @@ -139,7 +139,7 @@ public function getUntrustedIpAddresses() * * @return string The UA string, or an empty string if not found. */ - public static function getUserAgent() + public static function getUserAgent(): string { return self::sanitizeInputString(INPUT_SERVER, 'HTTP_USER_AGENT'); } @@ -151,7 +151,7 @@ public static function getUserAgent() * @param string $ipAddress The IP address in question. * @return bool */ - public function isTrustedIpAddress($ipAddress) + public function isTrustedIpAddress(string $ipAddress): bool { foreach ($this->trustedIpAddresses as $trustedIp) { if ($trustedIp->numeric() === IP::create($ipAddress)->numeric()) { @@ -174,7 +174,7 @@ public function isTrustedIpAddress($ipAddress) * @param string $ipAddress The IP address in question. * @return bool */ - public static function isValidIpAddress($ipAddress) + public static function isValidIpAddress(string $ipAddress): bool { $flags = FILTER_FLAG_IPV4 | FILTER_FLAG_IPV6; return (filter_var($ipAddress, FILTER_VALIDATE_IP, $flags) !== false); @@ -188,12 +188,12 @@ public static function isValidIpAddress($ipAddress) * @param string $variableName Example: 'username' * @return string */ - public static function sanitizeInputString(int $inputType, string $variableName) + public static function sanitizeInputString(int $inputType, string $variableName): string { return Text::sanitizeString(filter_input($inputType, $variableName)); } - public function trustIpAddress($ipAddress) + public function trustIpAddress(string $ipAddress): void { if ( ! self::isValidIpAddress($ipAddress)) { throw new \InvalidArgumentException(sprintf( @@ -204,7 +204,7 @@ public function trustIpAddress($ipAddress) $this->trustedIpAddresses[] = IP::create($ipAddress); } - public function trustIpAddressRange($ipAddressRangeString) + public function trustIpAddressRange(string $ipAddressRangeString): void { $ipBlock = IPBlock::create($ipAddressRangeString); $this->trustedIpAddressRanges[] = $ipBlock; diff --git a/modules/silauth/lib/Auth/Source/migrations/M161213135750CreateInitialTables.php b/modules/silauth/lib/Auth/Source/migrations/M161213135750CreateInitialTables.php index bc0dab3d..efd4a2b3 100644 --- a/modules/silauth/lib/Auth/Source/migrations/M161213135750CreateInitialTables.php +++ b/modules/silauth/lib/Auth/Source/migrations/M161213135750CreateInitialTables.php @@ -6,7 +6,7 @@ class M161213135750CreateInitialTables extends Migration { - public function safeUp() + public function safeUp(): void { $this->createTable('{{user}}', [ 'id' => 'pk', @@ -45,7 +45,7 @@ public function safeUp() ); } - public function safeDown() + public function safeDown(): void { $this->dropForeignKey( 'fk_prev_pw_user_user_id', diff --git a/modules/silauth/lib/Auth/Source/migrations/M161213150831SwitchToUtcForDateTimes.php b/modules/silauth/lib/Auth/Source/migrations/M161213150831SwitchToUtcForDateTimes.php index c9d38f96..c1075306 100644 --- a/modules/silauth/lib/Auth/Source/migrations/M161213150831SwitchToUtcForDateTimes.php +++ b/modules/silauth/lib/Auth/Source/migrations/M161213150831SwitchToUtcForDateTimes.php @@ -6,14 +6,14 @@ class M161213150831SwitchToUtcForDateTimes extends Migration { - public function safeUp() + public function safeUp(): void { $this->renameColumn('{{user}}', 'block_until', 'block_until_utc'); $this->renameColumn('{{user}}', 'last_updated', 'last_updated_utc'); $this->renameColumn('{{previous_password}}', 'created', 'created_utc'); } - public function safeDown() + public function safeDown(): void { $this->renameColumn('{{previous_password}}', 'created_utc', 'created'); $this->renameColumn('{{user}}', 'last_updated_utc', 'last_updated'); diff --git a/modules/silauth/lib/Auth/Source/migrations/M170214141109CreateFailedLoginsTable.php b/modules/silauth/lib/Auth/Source/migrations/M170214141109CreateFailedLoginsTable.php index acba2e8a..169a2117 100644 --- a/modules/silauth/lib/Auth/Source/migrations/M170214141109CreateFailedLoginsTable.php +++ b/modules/silauth/lib/Auth/Source/migrations/M170214141109CreateFailedLoginsTable.php @@ -6,7 +6,7 @@ class M170214141109CreateFailedLoginsTable extends Migration { - public function safeUp() + public function safeUp(): void { /* The max length needed to store an IP address is 45 characters. See * http://stackoverflow.com/a/1076755/3813891 for details. */ @@ -30,7 +30,7 @@ public function safeUp() ); } - public function safeDown() + public function safeDown(): void { $this->dropIndex('idx_failed_logins_ip_address', '{{failed_logins}}'); $this->dropIndex('idx_failed_logins_username', '{{failed_logins}}'); diff --git a/modules/silauth/lib/Auth/Source/migrations/M170214145629RemoveOldTables.php b/modules/silauth/lib/Auth/Source/migrations/M170214145629RemoveOldTables.php index 0b407f9d..a2c327c2 100644 --- a/modules/silauth/lib/Auth/Source/migrations/M170214145629RemoveOldTables.php +++ b/modules/silauth/lib/Auth/Source/migrations/M170214145629RemoveOldTables.php @@ -6,7 +6,7 @@ class M170214145629RemoveOldTables extends Migration { - public function safeUp() + public function safeUp(): void { $this->dropForeignKey( 'fk_prev_pw_user_user_id', @@ -21,7 +21,7 @@ public function safeUp() $this->dropTable('{{user}}'); } - public function safeDown() + public function safeDown(): bool { echo "M170214145629RemoveOldTables cannot be reverted.\n"; diff --git a/modules/silauth/lib/Auth/Source/migrations/M170215141724SplitFailedLoginsTable.php b/modules/silauth/lib/Auth/Source/migrations/M170215141724SplitFailedLoginsTable.php index 305e21fe..4d894c1d 100644 --- a/modules/silauth/lib/Auth/Source/migrations/M170215141724SplitFailedLoginsTable.php +++ b/modules/silauth/lib/Auth/Source/migrations/M170215141724SplitFailedLoginsTable.php @@ -6,7 +6,7 @@ class M170215141724SplitFailedLoginsTable extends Migration { - public function safeUp() + public function safeUp(): void { // Remove old indexes. $this->dropIndex('idx_failed_logins_ip_address', '{{failed_logins}}'); @@ -36,7 +36,7 @@ public function safeUp() ); } - public function safeDown() + public function safeDown(): bool { echo "M170215141724SplitFailedLoginsTable cannot be reverted.\n"; return false; diff --git a/modules/silauth/lib/Auth/Source/models/FailedLoginIpAddress.php b/modules/silauth/lib/Auth/Source/models/FailedLoginIpAddress.php index ce192668..e62a0ef0 100644 --- a/modules/silauth/lib/Auth/Source/models/FailedLoginIpAddress.php +++ b/modules/silauth/lib/Auth/Source/models/FailedLoginIpAddress.php @@ -18,7 +18,7 @@ class FailedLoginIpAddress extends FailedLoginIpAddressBase implements LoggerAwa /** * @inheritdoc */ - public function attributeLabels() + public function attributeLabels(): array { return ArrayHelper::merge(parent::attributeLabels(), [ 'ip_address' => Yii::t('app', 'IP Address'), @@ -26,7 +26,7 @@ public function attributeLabels() ]); } - public function behaviors() + public function behaviors(): array { return [ [ @@ -38,7 +38,7 @@ public function behaviors() ]; } - public static function countRecentFailedLoginsFor($ipAddress) + public static function countRecentFailedLoginsFor(string $ipAddress): string|int|bool|null { return self::find()->where([ 'ip_address' => strtolower($ipAddress), @@ -47,7 +47,7 @@ public static function countRecentFailedLoginsFor($ipAddress) ])->count(); } - public static function getFailedLoginsFor($ipAddress) + public static function getFailedLoginsFor(string $ipAddress): array { if ( ! Request::isValidIpAddress($ipAddress)) { throw new \InvalidArgumentException(sprintf( @@ -66,7 +66,7 @@ public static function getFailedLoginsFor($ipAddress) * @param string $ipAddress The IP address. * @return FailedLoginIpAddress|null */ - public static function getMostRecentFailedLoginFor($ipAddress) + public static function getMostRecentFailedLoginFor(string $ipAddress): ?FailedLoginIpAddress { return self::find()->where([ 'ip_address' => strtolower($ipAddress), @@ -83,7 +83,7 @@ public static function getMostRecentFailedLoginFor($ipAddress) * @param string $ipAddress The IP address in question * @return int The number of seconds */ - public static function getSecondsUntilUnblocked($ipAddress) + public static function getSecondsUntilUnblocked(string $ipAddress): int { $failedLogin = self::getMostRecentFailedLoginFor($ipAddress); @@ -93,20 +93,20 @@ public static function getSecondsUntilUnblocked($ipAddress) ); } - public function init() + public function init(): void { $this->initializeLogger(); parent::init(); } - public static function isCaptchaRequiredFor($ipAddress) + public static function isCaptchaRequiredFor(string $ipAddress): bool { return Authenticator::isEnoughFailedLoginsToRequireCaptcha( self::countRecentFailedLoginsFor($ipAddress) ); } - public static function isCaptchaRequiredForAnyOfThese(array $ipAddresses) + public static function isCaptchaRequiredForAnyOfThese(array $ipAddresses): bool { foreach ($ipAddresses as $ipAddress) { if (self::isCaptchaRequiredFor($ipAddress)) { @@ -116,13 +116,13 @@ public static function isCaptchaRequiredForAnyOfThese(array $ipAddresses) return false; } - public static function isRateLimitBlocking($ipAddress) + public static function isRateLimitBlocking(string $ipAddress): bool { $secondsUntilUnblocked = self::getSecondsUntilUnblocked($ipAddress); return ($secondsUntilUnblocked > 0); } - public static function isRateLimitBlockingAnyOfThese($ipAddresses) + public static function isRateLimitBlockingAnyOfThese(array $ipAddresses): bool { foreach ($ipAddresses as $ipAddress) { if (self::isRateLimitBlocking($ipAddress)) { @@ -135,7 +135,8 @@ public static function isRateLimitBlockingAnyOfThese($ipAddresses) public static function recordFailedLoginBy( array $ipAddresses, LoggerInterface $logger - ) { + ): void + { foreach ($ipAddresses as $ipAddress) { $newRecord = new FailedLoginIpAddress(['ip_address' => strtolower($ipAddress)]); @@ -150,7 +151,7 @@ public static function recordFailedLoginBy( } } - public static function resetFailedLoginsBy(array $ipAddresses) + public static function resetFailedLoginsBy(array $ipAddresses): void { foreach ($ipAddresses as $ipAddress) { self::deleteAll(['ip_address' => strtolower($ipAddress)]); diff --git a/modules/silauth/lib/Auth/Source/models/FailedLoginIpAddressBase.php b/modules/silauth/lib/Auth/Source/models/FailedLoginIpAddressBase.php index 0675e2e0..25f2b5b1 100644 --- a/modules/silauth/lib/Auth/Source/models/FailedLoginIpAddressBase.php +++ b/modules/silauth/lib/Auth/Source/models/FailedLoginIpAddressBase.php @@ -16,7 +16,7 @@ class FailedLoginIpAddressBase extends \yii\db\ActiveRecord /** * @inheritdoc */ - public static function tableName() + public static function tableName(): string { return 'failed_login_ip_address'; } @@ -24,7 +24,7 @@ public static function tableName() /** * @inheritdoc */ - public function rules() + public function rules(): array { return [ [['ip_address', 'occurred_at_utc'], 'required'], @@ -36,7 +36,7 @@ public function rules() /** * @inheritdoc */ - public function attributeLabels() + public function attributeLabels(): array { return [ 'id' => Yii::t('app', 'ID'), diff --git a/modules/silauth/lib/Auth/Source/models/FailedLoginUsername.php b/modules/silauth/lib/Auth/Source/models/FailedLoginUsername.php index 771132fc..26615487 100644 --- a/modules/silauth/lib/Auth/Source/models/FailedLoginUsername.php +++ b/modules/silauth/lib/Auth/Source/models/FailedLoginUsername.php @@ -17,14 +17,14 @@ class FailedLoginUsername extends FailedLoginUsernameBase implements LoggerAware /** * @inheritdoc */ - public function attributeLabels() + public function attributeLabels(): array { return ArrayHelper::merge(parent::attributeLabels(), [ 'occurred_at_utc' => Yii::t('app', 'Occurred At (UTC)'), ]); } - public function behaviors() + public function behaviors(): array { return [ [ @@ -36,7 +36,7 @@ public function behaviors() ]; } - public static function countRecentFailedLoginsFor($username) + public static function countRecentFailedLoginsFor(string $username): bool|int|string|null { return self::find()->where([ 'username' => strtolower($username), @@ -51,7 +51,7 @@ public static function countRecentFailedLoginsFor($username) * @param string $username The username. * @return FailedLoginUsername[] An array of any matching records. */ - public static function getFailedLoginsFor($username) + public static function getFailedLoginsFor(string $username): array { return self::findAll(['username' => strtolower($username)]); } @@ -63,7 +63,7 @@ public static function getFailedLoginsFor($username) * @param string $username The username. * @return FailedLoginUsername|null */ - public static function getMostRecentFailedLoginFor($username) + public static function getMostRecentFailedLoginFor(string $username): ?FailedLoginUsername { return self::find()->where([ 'username' => strtolower($username), @@ -80,7 +80,7 @@ public static function getMostRecentFailedLoginFor($username) * @param string $username The username in question * @return int The number of seconds */ - public static function getSecondsUntilUnblocked($username) + public static function getSecondsUntilUnblocked(string $username): int { $failedLogin = self::getMostRecentFailedLoginFor($username); @@ -90,7 +90,7 @@ public static function getSecondsUntilUnblocked($username) ); } - public function init() + public function init(): void { $this->initializeLogger(); parent::init(); @@ -102,13 +102,13 @@ public function init() * @param string $username The username * @return bool */ - public static function isRateLimitBlocking($username) + public static function isRateLimitBlocking(string $username): bool { $secondsUntilUnblocked = self::getSecondsUntilUnblocked($username); return ($secondsUntilUnblocked > 0); } - public static function isCaptchaRequiredFor($username) + public static function isCaptchaRequiredFor(string $username): bool { if (empty($username)) { return false; @@ -119,9 +119,10 @@ public static function isCaptchaRequiredFor($username) } public static function recordFailedLoginBy( - $username, + string $username, LoggerInterface $logger - ) { + ): void + { $newRecord = new FailedLoginUsername(['username' => strtolower($username)]); if ( ! $newRecord->save()) { $logger->critical(json_encode([ @@ -133,7 +134,7 @@ public static function recordFailedLoginBy( } } - public static function resetFailedLoginsBy($username) + public static function resetFailedLoginsBy(string $username): void { self::deleteAll(['username' => strtolower($username)]); } diff --git a/modules/silauth/lib/Auth/Source/models/FailedLoginUsernameBase.php b/modules/silauth/lib/Auth/Source/models/FailedLoginUsernameBase.php index a774ed47..a3c32cae 100644 --- a/modules/silauth/lib/Auth/Source/models/FailedLoginUsernameBase.php +++ b/modules/silauth/lib/Auth/Source/models/FailedLoginUsernameBase.php @@ -16,7 +16,7 @@ class FailedLoginUsernameBase extends \yii\db\ActiveRecord /** * @inheritdoc */ - public static function tableName() + public static function tableName(): string { return 'failed_login_username'; } @@ -24,7 +24,7 @@ public static function tableName() /** * @inheritdoc */ - public function rules() + public function rules(): array { return [ [['username', 'occurred_at_utc'], 'required'], @@ -36,7 +36,7 @@ public function rules() /** * @inheritdoc */ - public function attributeLabels() + public function attributeLabels(): array { return [ 'id' => Yii::t('app', 'ID'), diff --git a/modules/silauth/lib/Auth/Source/saml/User.php b/modules/silauth/lib/Auth/Source/saml/User.php index 5986f5d1..864fe118 100644 --- a/modules/silauth/lib/Auth/Source/saml/User.php +++ b/modules/silauth/lib/Auth/Source/saml/User.php @@ -11,13 +11,14 @@ public static function convertToSamlFieldNames( string $email, string $uuid, string $idpDomainName, - $passwordExpirationDate, + ?string $passwordExpirationDate, array $mfa, array $method, - $managerEmail, - $profileReview, + ?string $managerEmail, + string $profileReview, array $member - ) { + ): array + { // eduPersonUniqueId (only alphanumeric allowed) $alphaNumericUuid = str_replace('-', '', $uuid); diff --git a/modules/silauth/lib/Auth/Source/system/System.php b/modules/silauth/lib/Auth/Source/system/System.php index ea576186..cfe11950 100644 --- a/modules/silauth/lib/Auth/Source/system/System.php +++ b/modules/silauth/lib/Auth/Source/system/System.php @@ -11,19 +11,19 @@ class System { - protected $logger; + protected LoggerInterface|NullLogger $logger; /** * Constructor. * * @param LoggerInterface|null $logger (Optional:) A PSR-3 compatible logger. */ - public function __construct($logger = null) + public function __construct(LoggerInterface $logger = null) { $this->logger = $logger ?? new NullLogger(); } - protected function isDatabaseOkay() + protected function isDatabaseOkay(): bool { try { FailedLoginIpAddress::getMostRecentFailedLoginFor(''); @@ -34,7 +34,7 @@ protected function isDatabaseOkay() } } - protected function isRequiredConfigPresent() + protected function isRequiredConfigPresent(): bool { $globalConfig = Configuration::getInstance(); @@ -57,7 +57,7 @@ protected function isRequiredConfigPresent() * * @throws \Exception */ - public function reportStatus() + public function reportStatus(): void { if ( ! $this->isRequiredConfigPresent()) { $this->reportError('Config problem', 1485984755); @@ -75,7 +75,7 @@ public function reportStatus() * * @param string $message The error message. */ - protected function logError($message) + protected function logError(string $message): void { $this->logger->error($message); } @@ -88,7 +88,7 @@ protected function logError($message) * @param int $code An error code. * @throws \Exception */ - protected function reportError($message, $code) + protected function reportError(string $message, int $code): void { $this->logError($message); throw new \Exception($message, $code); diff --git a/modules/silauth/lib/Auth/Source/tests/fakes/FakeFailedIdBroker.php b/modules/silauth/lib/Auth/Source/tests/fakes/FakeFailedIdBroker.php index a2a04fc7..aee14acd 100644 --- a/modules/silauth/lib/Auth/Source/tests/fakes/FakeFailedIdBroker.php +++ b/modules/silauth/lib/Auth/Source/tests/fakes/FakeFailedIdBroker.php @@ -5,7 +5,7 @@ class FakeFailedIdBroker extends FakeIdBroker { - public function getAuthenticatedUser(string $username, string $password) + public function getAuthenticatedUser(string $username, string $password): ?array { $this->logger->info('FAKE FAILURE: rejecting {username} and {password}.', [ 'username' => var_export($username, true), @@ -14,7 +14,7 @@ public function getAuthenticatedUser(string $username, string $password) return parent::getAuthenticatedUser($username, $password); } - protected function getDesiredResponse() + protected function getDesiredResponse(): Response { return new Response(400); } diff --git a/modules/silauth/lib/Auth/Source/tests/fakes/FakeInvalidIdBroker.php b/modules/silauth/lib/Auth/Source/tests/fakes/FakeInvalidIdBroker.php index 8e54e8f7..a22c85c1 100644 --- a/modules/silauth/lib/Auth/Source/tests/fakes/FakeInvalidIdBroker.php +++ b/modules/silauth/lib/Auth/Source/tests/fakes/FakeInvalidIdBroker.php @@ -5,13 +5,13 @@ class FakeInvalidIdBroker extends FakeIdBroker { - public function getAuthenticatedUser(string $username, string $password) + public function getAuthenticatedUser(string $username, string $password): ?array { $this->logger->info('FAKE ERROR: invalid/unexpected response.'); return parent::getAuthenticatedUser($username, $password); } - protected function getDesiredResponse() + protected function getDesiredResponse(): Response { return new Response(404); } diff --git a/modules/silauth/lib/Auth/Source/tests/fakes/FakeSuccessfulIdBroker.php b/modules/silauth/lib/Auth/Source/tests/fakes/FakeSuccessfulIdBroker.php index 21d36b25..d385fa11 100644 --- a/modules/silauth/lib/Auth/Source/tests/fakes/FakeSuccessfulIdBroker.php +++ b/modules/silauth/lib/Auth/Source/tests/fakes/FakeSuccessfulIdBroker.php @@ -5,7 +5,7 @@ class FakeSuccessfulIdBroker extends FakeIdBroker { - public function getAuthenticatedUser(string $username, string $password) + public function getAuthenticatedUser(string $username, string $password): ?array { $this->logger->info('FAKE SUCCESS: accepting {username} and {password}.', [ 'username' => var_export($username, true), @@ -14,7 +14,7 @@ public function getAuthenticatedUser(string $username, string $password) return parent::getAuthenticatedUser($username, $password); } - protected function getDesiredResponse() + protected function getDesiredResponse(): Response { return new Response(200, [], json_encode([ 'uuid' => '11111111-aaaa-1111-aaaa-111111111111', diff --git a/modules/silauth/lib/Auth/Source/tests/unit/captcha/DummyFailedCaptcha.php b/modules/silauth/lib/Auth/Source/tests/unit/captcha/DummyFailedCaptcha.php index b6d5387c..9ddb58e6 100644 --- a/modules/silauth/lib/Auth/Source/tests/unit/captcha/DummyFailedCaptcha.php +++ b/modules/silauth/lib/Auth/Source/tests/unit/captcha/DummyFailedCaptcha.php @@ -6,7 +6,7 @@ class DummyFailedCaptcha extends Captcha { - public function isValidIn(Request $request) + public function isValidIn(Request $request): bool { return false; } diff --git a/modules/silauth/lib/Auth/Source/tests/unit/captcha/DummySuccessfulCaptcha.php b/modules/silauth/lib/Auth/Source/tests/unit/captcha/DummySuccessfulCaptcha.php index 7a68b3d4..1bdfded2 100644 --- a/modules/silauth/lib/Auth/Source/tests/unit/captcha/DummySuccessfulCaptcha.php +++ b/modules/silauth/lib/Auth/Source/tests/unit/captcha/DummySuccessfulCaptcha.php @@ -6,7 +6,7 @@ class DummySuccessfulCaptcha extends Captcha { - public function isValidIn(Request $request) + public function isValidIn(Request $request): bool { return true; } diff --git a/modules/silauth/lib/Auth/Source/tests/unit/http/DummyRequest.php b/modules/silauth/lib/Auth/Source/tests/unit/http/DummyRequest.php index ae2cfbf7..f2334110 100644 --- a/modules/silauth/lib/Auth/Source/tests/unit/http/DummyRequest.php +++ b/modules/silauth/lib/Auth/Source/tests/unit/http/DummyRequest.php @@ -12,12 +12,12 @@ class DummyRequest extends Request * * @return string[] A list containing the dummy IP address. */ - public function getIpAddresses() + public function getIpAddresses(): array { return [$this->dummyIpAddress]; } - public function setDummyIpAddress($dummyIpAddress) + public function setDummyIpAddress(string $dummyIpAddress): void { if ( ! self::isValidIpAddress($dummyIpAddress)) { throw new \InvalidArgumentException(sprintf( diff --git a/modules/silauth/lib/Auth/Source/tests/unit/models/FailedLoginIpAddressTest.php b/modules/silauth/lib/Auth/Source/tests/unit/models/FailedLoginIpAddressTest.php index 84f2163d..8b1c3daf 100644 --- a/modules/silauth/lib/Auth/Source/tests/unit/models/FailedLoginIpAddressTest.php +++ b/modules/silauth/lib/Auth/Source/tests/unit/models/FailedLoginIpAddressTest.php @@ -9,7 +9,7 @@ class FailedLoginIpAddressTest extends TestCase { - protected function setDbFixture($recordsData) + protected function setDbFixture(array $recordsData): void { FailedLoginIpAddress::deleteAll(); foreach ($recordsData as $recordData) { diff --git a/modules/silauth/lib/Auth/Source/tests/unit/models/FailedLoginUsernameTest.php b/modules/silauth/lib/Auth/Source/tests/unit/models/FailedLoginUsernameTest.php index bd403eff..b5b571c2 100644 --- a/modules/silauth/lib/Auth/Source/tests/unit/models/FailedLoginUsernameTest.php +++ b/modules/silauth/lib/Auth/Source/tests/unit/models/FailedLoginUsernameTest.php @@ -9,7 +9,7 @@ class FailedLoginUsernameTest extends TestCase { - protected function setDbFixture($recordsData) + protected function setDbFixture(array $recordsData): void { FailedLoginUsername::deleteAll(); foreach ($recordsData as $recordData) { diff --git a/modules/silauth/lib/Auth/Source/text/Text.php b/modules/silauth/lib/Auth/Source/text/Text.php index eed1282c..6649ca65 100644 --- a/modules/silauth/lib/Auth/Source/text/Text.php +++ b/modules/silauth/lib/Auth/Source/text/Text.php @@ -10,7 +10,7 @@ class Text * @param string|mixed $input The input. * @return string The sanitized string. */ - public static function sanitizeString($input) + public static function sanitizeString(mixed $input): string { $inputAsString = is_string($input) ? $input : ''; $output = filter_var($inputAsString, FILTER_SANITIZE_STRING, [ @@ -26,7 +26,7 @@ public static function sanitizeString($input) * @param string $needle The string to search for. * @return boolean */ - public static function startsWith(string $haystack, string $needle) + public static function startsWith(string $haystack, string $needle): bool { $length = mb_strlen($needle); return (mb_substr($haystack, 0, $length) === $needle); diff --git a/modules/silauth/lib/Auth/Source/time/UtcTime.php b/modules/silauth/lib/Auth/Source/time/UtcTime.php index af727882..e269c14e 100644 --- a/modules/silauth/lib/Auth/Source/time/UtcTime.php +++ b/modules/silauth/lib/Auth/Source/time/UtcTime.php @@ -39,7 +39,7 @@ public function __toString() * @throws Exception If an invalid date/time string is provided, an * \Exception will be thrown. */ - public static function format(string $dateTimeString = 'now') + public static function format(string $dateTimeString = 'now'): string { return (string)(new UtcTime($dateTimeString)); } @@ -55,7 +55,7 @@ public static function format(string $dateTimeString = 'now') * passed. * @return int The number of seconds remaining. */ - public static function getRemainingSeconds(int $totalSeconds, int $elapsedSeconds) + public static function getRemainingSeconds(int $totalSeconds, int $elapsedSeconds): int { $remainingSeconds = $totalSeconds - $elapsedSeconds; return max($remainingSeconds, 0); @@ -71,7 +71,7 @@ public static function getRemainingSeconds(int $totalSeconds, int $elapsedSecond * (presumably in the past, though not necessarily). * @return int The number of seconds */ - public function getSecondsSince(UtcTime $otherUtcTime) + public function getSecondsSince(UtcTime $otherUtcTime): int { return $this->getTimestamp() - $otherUtcTime->getTimestamp(); } @@ -85,7 +85,7 @@ public function getSecondsSince(UtcTime $otherUtcTime) * \Exception will be thrown. * @throws \InvalidArgumentException */ - public static function getSecondsSinceDateTime(string $dateTimeString) + public static function getSecondsSinceDateTime(string $dateTimeString): int { if (empty($dateTimeString)) { throw new \InvalidArgumentException(sprintf( @@ -98,12 +98,12 @@ public static function getSecondsSinceDateTime(string $dateTimeString) return $nowUtc->getSecondsSince($dateTimeUtc); } - public function getSecondsUntil(UtcTime $otherUtcTime) + public function getSecondsUntil(UtcTime $otherUtcTime): int { return $otherUtcTime->getTimestamp() - $this->getTimestamp(); } - public function getTimestamp() + public function getTimestamp(): int { return $this->dateTime->getTimestamp(); } @@ -113,7 +113,7 @@ public function getTimestamp() * * @return string */ - public static function now() + public static function now(): string { return self::format('now'); } diff --git a/modules/silauth/lib/Auth/Source/time/WaitTime.php b/modules/silauth/lib/Auth/Source/time/WaitTime.php index ba5094f3..216b46ba 100644 --- a/modules/silauth/lib/Auth/Source/time/WaitTime.php +++ b/modules/silauth/lib/Auth/Source/time/WaitTime.php @@ -11,8 +11,8 @@ class WaitTime const UNIT_MINUTE = 'minute'; const UNIT_SECOND = 'second'; - private $friendlyNumber = null; - private $unit = null; + private int $friendlyNumber; + private string $unit; /** * Constructor. @@ -22,7 +22,7 @@ class WaitTime * * @param int $secondsToWait The number of seconds the user must wait. */ - public function __construct($secondsToWait) + public function __construct(int $secondsToWait) { if ($secondsToWait <= 5) { $this->friendlyNumber = 5; @@ -36,7 +36,7 @@ public function __construct($secondsToWait) } } - public function getFriendlyNumber() + public function getFriendlyNumber(): int { return $this->friendlyNumber; } @@ -48,7 +48,7 @@ public function getFriendlyNumber() * seconds. * @return WaitTime */ - public static function getLongestWaitTime(array $durationsInSeconds) + public static function getLongestWaitTime(array $durationsInSeconds): WaitTime { if (empty($durationsInSeconds)) { throw new \InvalidArgumentException('No durations given.', 1487605801); @@ -56,7 +56,7 @@ public static function getLongestWaitTime(array $durationsInSeconds) return new WaitTime(max($durationsInSeconds)); } - public function getUnit() + public function getUnit(): string { return $this->unit; } diff --git a/modules/silauth/lib/Auth/Source/traits/LoggerAwareTrait.php b/modules/silauth/lib/Auth/Source/traits/LoggerAwareTrait.php index 65fabe5a..c07c72c8 100644 --- a/modules/silauth/lib/Auth/Source/traits/LoggerAwareTrait.php +++ b/modules/silauth/lib/Auth/Source/traits/LoggerAwareTrait.php @@ -7,9 +7,9 @@ trait LoggerAwareTrait { /** @var LoggerInterface */ - protected $logger; + protected LoggerInterface $logger; - public function initializeLogger() + public function initializeLogger(): void { if (empty($this->logger)) { $this->logger = new NullLogger(); @@ -22,7 +22,7 @@ public function initializeLogger() * @param LoggerInterface $logger A PSR-3 compliant logger. * @return null */ - public function setLogger(LoggerInterface $logger) + public function setLogger(LoggerInterface $logger): void { $this->logger = $logger; } diff --git a/modules/sildisco/lib/Auth/Process/AddIdp2NameId.php b/modules/sildisco/lib/Auth/Process/AddIdp2NameId.php index 0f816211..e3c8408e 100644 --- a/modules/sildisco/lib/Auth/Process/AddIdp2NameId.php +++ b/modules/sildisco/lib/Auth/Process/AddIdp2NameId.php @@ -2,6 +2,7 @@ namespace SimpleSAML\Module\sildisco\Auth\Process; +use SAML2\XML\saml\NameID; use Sil\SspUtils\Metadata; /** @@ -39,7 +40,7 @@ class AddIdp2NameId extends \SimpleSAML\Auth\ProcessingFilter { * * @var string|bool */ - private $nameQualifier; + private string|bool $nameQualifier; /** @@ -51,7 +52,7 @@ class AddIdp2NameId extends \SimpleSAML\Auth\ProcessingFilter { * * @var string|bool */ - private $spNameQualifier; + private sring|bool $spNameQualifier; /** @@ -61,7 +62,7 @@ class AddIdp2NameId extends \SimpleSAML\Auth\ProcessingFilter { * * @var string */ - protected $format; + protected ?string $format; /** @@ -70,7 +71,7 @@ class AddIdp2NameId extends \SimpleSAML\Auth\ProcessingFilter { * @param array $config Configuration information about this filter. * @param mixed $reserved For future use. */ - public function __construct($config, $reserved) { + public function __construct(array $config, mixed $reserved) { parent::__construct($config, $reserved); assert('is_array($config)'); @@ -93,12 +94,13 @@ public function __construct($config, $reserved) { } /** - * @param $nameId \SAML2\XML\saml\NameID + * @param $nameId NameID * @param $IDPNamespace string * * Modifies the nameID object by adding text to the end of its value attribute */ - public function appendIdp($nameId, $IDPNamespace) { + public function appendIdp(NameID $nameId, string $IDPNamespace): void + { $suffix = self::DELIMITER . $IDPNamespace; $value = $nameId->getValue(); @@ -112,7 +114,8 @@ public function appendIdp($nameId, $IDPNamespace) { * * @param array &$state The current state array */ - public function process(&$state) { + public function process(&$state): void + { assert('is_array($state)'); $samlIDP = $state[self::IDP_KEY]; diff --git a/modules/sildisco/lib/Auth/Process/LogUser.php b/modules/sildisco/lib/Auth/Process/LogUser.php index c1cc2a55..ce65fd29 100644 --- a/modules/sildisco/lib/Auth/Process/LogUser.php +++ b/modules/sildisco/lib/Auth/Process/LogUser.php @@ -38,13 +38,13 @@ class LogUser extends \SimpleSAML\Auth\ProcessingFilter // The host of the aws dynamodb - private $dynamoEndpoint; + private ?string $dynamoEndpoint; // The region of the aws dynamodb - private $dynamoRegion; + private ?string $dynamoRegion; // The name of the aws dynamodb table that stores the login data - private $dynamoLogTable; + private ?string $dynamoLogTable; /** * Initialize this filter, parse configuration. @@ -52,9 +52,9 @@ class LogUser extends \SimpleSAML\Auth\ProcessingFilter * @param array $config Configuration information about this filter. * @param mixed $reserved For future use. */ - public function __construct($config, $reserved) { + public function __construct(array $config, mixed $reserved) + { parent::__construct($config, $reserved); - assert(is_array($config)); $this->dynamoEndpoint = $config[self::DYNAMO_ENDPOINT_KEY] ?? null; $this->dynamoRegion = $config[self::DYNAMO_REGION_KEY] ?? null; @@ -62,11 +62,12 @@ public function __construct($config, $reserved) { } /** - * Log info for a user's login to Dyanmodb + * Log info for a user's login to Dynamodb * * @param array &$state The current state array */ - public function process(&$state) { + public function process(&$state): void + { if (! $this->configsAreValid()) { return; } @@ -137,7 +138,8 @@ public function process(&$state) { } } - private function configsAreValid() { + private function configsAreValid(): bool + { $msg = ' config value not provided to LogUser.'; if (empty($this->dynamoRegion)) { @@ -153,7 +155,8 @@ private function configsAreValid() { return true; } - private function getIdp(&$state) { + private function getIdp(array &$state) + { if (empty($state[self::IDP_KEY])) { return 'No IDP available'; } @@ -182,7 +185,8 @@ private function getIdp(&$state) { } // Get the current user's common name attribute and/or eduPersonPrincipalName and/or employeeNumber - private function getUserAttributes($state) { + private function getUserAttributes(array $state): array + { $attributes = $state['Attributes']; $cn = $this->getAttributeFrom($attributes, 'urn:oid:2.5.4.3', 'cn'); @@ -208,7 +212,8 @@ private function getUserAttributes($state) { return $userAttrs; } - private function getAttributeFrom($attributes, $oidKey, $friendlyKey) { + private function getAttributeFrom(array $attributes, string $oidKey, string $friendlyKey): string + { if (!empty($attributes[$oidKey])) { return $attributes[$oidKey][0]; } @@ -222,7 +227,7 @@ private function getAttributeFrom($attributes, $oidKey, $friendlyKey) { // Dynamodb seems to complain when a value is an empty string. // This ensures that only attributes with a non empty value get included. - private function addUserAttribute($attributes, $attrKey, $attr) { + private function addUserAttribute(array $attributes, string $attrKey, string $attr): array { if (!empty($attr)) { $attributes[$attrKey] = $attr; } diff --git a/modules/sildisco/lib/Auth/Process/TagGroup.php b/modules/sildisco/lib/Auth/Process/TagGroup.php index 59402907..5d8ccf68 100644 --- a/modules/sildisco/lib/Auth/Process/TagGroup.php +++ b/modules/sildisco/lib/Auth/Process/TagGroup.php @@ -16,7 +16,8 @@ class TagGroup extends \SimpleSAML\Auth\ProcessingFilter { const IDP_CODE_KEY = 'IDPNamespace'; - public function prependIdp2Groups($attributes, $attributeLabel, $idpLabel) { + public function prependIdp2Groups(array $attributes, string $attributeLabel, string $idpLabel): array + { $newGroups = []; $delimiter = '|'; diff --git a/modules/sildisco/lib/IdPDisco.php b/modules/sildisco/lib/IdPDisco.php index d1f735a8..4808a8ff 100644 --- a/modules/sildisco/lib/IdPDisco.php +++ b/modules/sildisco/lib/IdPDisco.php @@ -18,23 +18,23 @@ class IdPDisco extends \SimpleSAML\XHTML\IdPDisco { /* The session type for this class */ - public static $sessionType = 'sildisco:authentication'; + public static string $sessionType = 'sildisco:authentication'; /* The session key for checking if the current user has the beta_tester cookie */ - public static $betaTesterSessionKey = 'beta_tester'; + public static string $betaTesterSessionKey = 'beta_tester'; /* The idp metadata key that says whether an IDP is betaEnabled */ - public static $betaEnabledMdKey = 'betaEnabled'; + public static string $betaEnabledMdKey = 'betaEnabled'; /* The idp metadata key that says whether an IDP is enabled */ - public static $enabledMdKey = 'enabled'; + public static string $enabledMdKey = 'enabled'; /* The sp metadata key that gives the name of the SP */ - public static $spNameMdKey = 'name'; + public static string $spNameMdKey = 'name'; /* Used to get the SP Entity ID, e.g. $spEntityId = $this->session->getData($sessionDataType, $sessionKeyForSP); */ - public static $sessionDataType = 'sildisco:authentication'; - public static $sessionKeyForSP = 'spentityid'; + public static string $sessionDataType = 'sildisco:authentication'; + public static string $sessionKeyForSP = 'spentityid'; /** @@ -44,7 +44,7 @@ class IdPDisco extends \SimpleSAML\XHTML\IdPDisco * * @param string $message The message which should be logged. */ - protected function log($message) + protected function log($message): void { \SimpleSAML\Logger::info('SildiscoIdPDisco.'.$this->instance.': '.$message); } @@ -54,7 +54,7 @@ private function getMetadataPath() { return __DIR__ . '/../../../metadata/'; } - private function getSPEntityIDAndReducedIdpList() + private function getSPEntityIDAndReducedIdpList(): array { $idpList = $this->getIdPList(); @@ -76,7 +76,7 @@ private function getSPEntityIDAndReducedIdpList() * * The IdP disco parameters should be set before calling this function. */ - public function handleRequest() + public function handleRequest(): void { $this->start(); @@ -127,14 +127,15 @@ public function handleRequest() /** * @param array $idpList the IDPs with their metadata - * @param bool $isBetaTester optional (default=null) just for unit testing + * @param bool|null $isBetaTester optional (default=null) just for unit testing * @return array $idpList * * If the current user has the beta_tester cookie, then for each IDP in * the idpList that has 'betaEnabled' => true, give it 'enabled' => true * */ - public static function enableBetaEnabled($idpList, $isBetaTester=null) { + public static function enableBetaEnabled(array $idpList, ?bool $isBetaTester=null): array + { if ( $isBetaTester === null) { $session = \SimpleSAML\Session::getSessionFromRequest(); @@ -168,7 +169,7 @@ public static function enableBetaEnabled($idpList, $isBetaTester=null) { * * @return string|null The entity id if it is valid, null if not. */ - protected function validateIdP($idp) + protected function validateIdP($idp): ?string { if ($idp === null) { return null; @@ -203,7 +204,6 @@ protected function validateIdP($idp) return null; } - if (array_key_exists($idp, $idpList) && $idpList[$idp]['enabled']) { return $idp; }