diff options
author | Mario <mario@mariovavti.com> | 2023-03-19 13:55:18 +0000 |
---|---|---|
committer | Mario <mario@mariovavti.com> | 2023-03-19 13:55:18 +0000 |
commit | 89285f1408d21091bb80d45b391ddcbe06ba8d0f (patch) | |
tree | b2eb07d9f3d91d77f89a4565a58e6e5231b20c1c /vendor/spomky-labs/otphp/src/Factory.php | |
parent | 0a679e503ef367eda3085c44af103ee53869a94f (diff) | |
parent | 17c0bb2069dcfe35d3febc5bfdb3a7295f15d49c (diff) | |
download | volse-hubzilla-89285f1408d21091bb80d45b391ddcbe06ba8d0f.tar.gz volse-hubzilla-89285f1408d21091bb80d45b391ddcbe06ba8d0f.tar.bz2 volse-hubzilla-89285f1408d21091bb80d45b391ddcbe06ba8d0f.zip |
Merge branch '8.2RC'8.2
Diffstat (limited to 'vendor/spomky-labs/otphp/src/Factory.php')
-rw-r--r-- | vendor/spomky-labs/otphp/src/Factory.php | 85 |
1 files changed, 85 insertions, 0 deletions
diff --git a/vendor/spomky-labs/otphp/src/Factory.php b/vendor/spomky-labs/otphp/src/Factory.php new file mode 100644 index 000000000..d5c60cc34 --- /dev/null +++ b/vendor/spomky-labs/otphp/src/Factory.php @@ -0,0 +1,85 @@ +<?php + +declare(strict_types=1); + +namespace OTPHP; + +use function count; +use InvalidArgumentException; +use Throwable; + +/** + * This class is used to load OTP object from a provisioning Uri. + * + * @see \OTPHP\Test\FactoryTest + */ +final class Factory implements FactoryInterface +{ + public static function loadFromProvisioningUri(string $uri): OTPInterface + { + try { + $parsed_url = Url::fromString($uri); + $parsed_url->getScheme() === 'otpauth' || throw new InvalidArgumentException('Invalid scheme.'); + } catch (Throwable $throwable) { + throw new InvalidArgumentException('Not a valid OTP provisioning URI', $throwable->getCode(), $throwable); + } + + $otp = self::createOTP($parsed_url); + + self::populateOTP($otp, $parsed_url); + + return $otp; + } + + private static function populateParameters(OTPInterface $otp, Url $data): void + { + foreach ($data->getQuery() as $key => $value) { + $otp->setParameter($key, $value); + } + } + + private static function populateOTP(OTPInterface $otp, Url $data): void + { + self::populateParameters($otp, $data); + $result = explode(':', rawurldecode(mb_substr($data->getPath(), 1))); + + if (count($result) < 2) { + $otp->setIssuerIncludedAsParameter(false); + + return; + } + + if ($otp->getIssuer() !== null) { + $result[0] === $otp->getIssuer() || throw new InvalidArgumentException( + 'Invalid OTP: invalid issuer in parameter' + ); + $otp->setIssuerIncludedAsParameter(true); + } + $otp->setIssuer($result[0]); + } + + private static function createOTP(Url $parsed_url): OTPInterface + { + switch ($parsed_url->getHost()) { + case 'totp': + $totp = TOTP::createFromSecret($parsed_url->getSecret()); + $totp->setLabel(self::getLabel($parsed_url->getPath())); + + return $totp; + case 'hotp': + $hotp = HOTP::createFromSecret($parsed_url->getSecret()); + $hotp->setLabel(self::getLabel($parsed_url->getPath())); + + return $hotp; + default: + throw new InvalidArgumentException(sprintf('Unsupported "%s" OTP type', $parsed_url->getHost())); + } + } + + private static function getLabel(string $data): string + { + $result = explode(':', rawurldecode(mb_substr($data, 1))); + + return count($result) === 2 ? $result[1] : $result[0]; + } +} |