Lines
90.16%
55 / 61
Methods
68.75%
11 / 16
Classes
0.00%
0 / 1
| Name | Lines | Methods | CRAP | ||||
|---|---|---|---|---|---|---|---|
| __construct | 100.00% | 4 / 4 | 100.00% | 1 / 1 | 1 | ||
| create | 100.00% | 9 / 9 | 100.00% | 1 / 1 | 2 | ||
| update | 100.00% | 1 / 1 | 100.00% | 1 / 1 | 1 | ||
| delete | 100.00% | 1 / 1 | 100.00% | 1 / 1 | 1 | ||
| checkCredentials | 100.00% | 10 / 10 | 100.00% | 1 / 1 | 5 | ||
| isValidLogin | 100.00% | 1 / 1 | 100.00% | 1 / 1 | 2 | ||
| createLdapAuth | 80.00% | 4 / 5 | 0.00% | 0 / 1 | 3.07 | ||
| createUser | 80.00% | 4 / 5 | 0.00% | 0 / 1 | 3.07 | ||
| [phpMyFAQ\Auth] getEncryptionContainer | 100.00% | 2 / 2 | 100.00% | 1 / 1 | 1 | ||
| [phpMyFAQ\Auth] getErrors | 100.00% | 2 / 2 | 100.00% | 1 / 1 | 3 | ||
| [phpMyFAQ\Auth] addError | 0.00% | 0 / 1 | 0.00% | 0 / 1 | 2 | ||
| [phpMyFAQ\Auth] selectAuth | 80.00% | 8 / 10 | 0.00% | 0 / 1 | 4.13 | ||
| [phpMyFAQ\Auth] enableReadOnly | 100.00% | 3 / 3 | 100.00% | 1 / 1 | 1 | ||
| [phpMyFAQ\Auth] disableReadOnly | 100.00% | 3 / 3 | 100.00% | 1 / 1 | 1 | ||
| [phpMyFAQ\Auth] isReadOnly | 100.00% | 1 / 1 | 100.00% | 1 / 1 | 1 | ||
| [phpMyFAQ\Auth] encrypt | 66.66% | 2 / 3 | 0.00% | 0 / 1 | 2.15 | ||
| 36 | class AuthSso extends Auth implements AuthDriverInterface | |
| 37 | { | |
| 38 | private readonly Request $request; | |
| 39 | private readonly ?Closure $ldapFactory; | |
| 40 | private readonly ?Closure $userFactory; | |
| 41 | ||
| 42 | /** | |
| 43 | * @inheritDoc | |
| 44 | */ | |
| 45 | public function __construct( | |
| 46 | Configuration $configuration, | |
| 47 | ?Request $request = null, | |
| 48 | ?Closure $ldapFactory = null, | |
| 49 | ?Closure $userFactory = null, | |
| 50 | ) { | |
| 51 | parent::__construct($configuration); | |
| 52 | ||
| 53 | $this->request = $request ?? Request::createFromGlobals(); | |
| 54 | $this->ldapFactory = $ldapFactory; | |
| 55 | $this->userFactory = $userFactory; | |
| 56 | } | |
| 57 | ||
| 58 | /** | |
| 59 | * @inheritDoc | |
| 60 | * @throws Exception | |
| 61 | */ | |
| 62 | public function create(string $login, #[SensitiveParameter] string $password, string $domain = ''): bool | |
| 63 | { | |
| 64 | if ($this->configuration->isLdapActive()) { | |
| 65 | // LDAP/AD + SSO | |
| 66 | $authLdap = $this->createLdapAuth(); | |
| 67 | return $authLdap->create($login, '', $domain); | |
| 68 | } | |
| 69 | ||
| 70 | // SSO without LDAP/AD | |
| 71 | $user = $this->createUser(); | |
| 72 | $result = $user->createUser($login, '', $domain); | |
| 73 | $user->setStatus('active'); | |
| 74 | $user->setAuthSource(AuthenticationSourceType::AUTH_SSO->value); | |
| 75 | // Set user information | |
| 76 | $user->setUserData(['display_name' => $login]); | |
| 77 | return $result; | |
| 78 | } | |
| 79 | ||
| 80 | /** | |
| 81 | * @inheritDoc | |
| 82 | */ | |
| 83 | public function update(string $login, #[SensitiveParameter] string $password): bool | |
| 84 | { | |
| 85 | return true; | |
| 86 | } | |
| 87 | ||
| 88 | /** | |
| 89 | * @inheritDoc | |
| 90 | */ | |
| 91 | public function delete(string $login): bool | |
| 92 | { | |
| 93 | return true; | |
| 94 | } | |
| 95 | ||
| 96 | /** | |
| 97 | * @inheritDoc | |
| 98 | * @throws AuthException | |
| 99 | * @throws Exception | |
| 100 | */ | |
| 101 | public function checkCredentials( | |
| 102 | string $login, | |
| 103 | #[SensitiveParameter] | |
| 104 | string $password, | |
| 105 | ?array $optionalData = null, | |
| 106 | ): bool { | |
| 107 | if ($this->request->server->get('REMOTE_USER') === null) { | |
| 108 | throw new AuthException('Remote User not set!'); | |
| 109 | } | |
| 110 | ||
| 111 | // Check if "DOMAIN\user", "user@DOMAIN" or only "user" | |
| 112 | $remote = explode('\\', (string) $this->request->server->get('REMOTE_USER')); | |
| 113 | $user = $this->request->server->get('REMOTE_USER'); | |
| 114 | if (count($remote) > 1) { | |
| 115 | $user = $remote[1]; | |
| 116 | } | |
| 117 | ||
| 118 | if (count($remote) <= 1) { | |
| 119 | $remote = explode('@', (string) $this->request->server->get('REMOTE_USER')); | |
| 120 | $user = count($remote) > 1 ? $remote[0] : $this->request->server->get('REMOTE_USER'); | |
| 121 | } | |
| 122 | ||
| 123 | return $user === $login; | |
| 124 | } | |
| 125 | ||
| 126 | /** | |
| 127 | * @inheritDoc | |
| 128 | */ | |
| 129 | public function isValidLogin(string $login, ?array $optionalData = null): int | |
| 130 | { | |
| 131 | return $this->request->server->get('PHP_AUTH_USER') !== null ? 1 : 0; | |
| 132 | } | |
| 133 | ||
| 134 | private function createLdapAuth(): AuthLdap | |
| 135 | { | |
| 136 | if ($this->ldapFactory instanceof Closure) { | |
| 137 | $authLdap = ($this->ldapFactory)(); | |
| 138 | if ($authLdap instanceof AuthLdap) { | |
| 139 | return $authLdap; | |
| 140 | } | |
| 141 | } | |
| 142 | ||
| 143 | return new AuthLdap($this->configuration); | |
| 144 | } | |
| 145 | ||
| 146 | private function createUser(): User | |
| 147 | { | |
| 148 | if ($this->userFactory instanceof Closure) { | |
| 149 | $user = ($this->userFactory)(); | |
| 150 | if ($user instanceof User) { | |
| 151 | return $user; | |
| 152 | } | |
| 153 | } | |
| 154 | ||
| 155 | return new User($this->configuration); | |
| 156 | } | |
| 157 | } |
Inherited from phpMyFAQ\Auth
| 73 | public function getEncryptionContainer(string $encType): Encryption | |
| 74 | { | |
| 75 | $this->encContainer = Encryption::getInstance($encType, $this->configuration); | |
| 76 | return $this->encContainer; | |
| 77 | } |
| 82 | public function getErrors(): string | |
| 83 | { | |
| 84 | $message = $this->errors !== [] ? implode(separator: PHP_EOL, array: $this->errors) . PHP_EOL : ''; | |
| 85 | return $message . ($this->encContainer instanceof \phpMyFAQ\Encryption ? $this->encContainer->error() : ''); | |
| 86 | } |
| 91 | public function addError(string $message): void | |
| 92 | { | |
| 93 | $this->errors[] = $message; | |
| 94 | } |
| 101 | public function selectAuth(string $method): Auth&AuthDriverInterface | |
| 102 | { | |
| 103 | $method = ucfirst(strtolower($method)); | |
| 104 | $authClass = '\\phpMyFAQ\\Auth\\Auth' . $method; | |
| 105 | ||
| 106 | if (!class_exists($authClass) || !is_subclass_of($authClass, self::class)) { | |
| 107 | $this->errors[] = self::PMF_ERROR_USER_NO_AUTH_TYPE; | |
| 108 | throw new Exception(message: self::PMF_ERROR_USER_NO_AUTH_TYPE); | |
| 109 | } | |
| 110 | ||
| 111 | $auth = new $authClass($this->configuration); | |
| 112 | if (!$auth instanceof AuthDriverInterface) { | |
| 113 | $this->errors[] = self::PMF_ERROR_USER_NO_AUTH_TYPE; | |
| 114 | throw new Exception(message: self::PMF_ERROR_USER_NO_AUTH_TYPE); | |
| 115 | } | |
| 116 | ||
| 117 | return $auth; | |
| 118 | } |
| 123 | public function enableReadOnly(): bool | |
| 124 | { | |
| 125 | $oldReadOnly = $this->readOnly; | |
| 126 | $this->readOnly = true; | |
| 127 | ||
| 128 | return $oldReadOnly; | |
| 129 | } |
| 134 | public function disableReadOnly(): bool | |
| 135 | { | |
| 136 | $oldReadOnly = $this->readOnly; | |
| 137 | $this->readOnly = false; | |
| 138 | ||
| 139 | return $oldReadOnly; | |
| 140 | } |
| 145 | public function isReadOnly(): bool | |
| 146 | { | |
| 147 | return $this->readOnly; | |
| 148 | } |
| 155 | public function encrypt(#[SensitiveParameter] string $string): string | |
| 156 | { | |
| 157 | if (!$this->encContainer instanceof \phpMyFAQ\Encryption) { | |
| 158 | throw new Exception(message: 'No encryption container configured. Call getEncryptionContainer() first.'); | |
| 159 | } | |
| 160 | ||
| 161 | return $this->encContainer->encrypt($string); | |
| 162 | } |