Lines 90.16% 55 / 61
Methods 68.75% 11 / 16
Classes 0.00% 0 / 1
Covered by tests of size
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
36class 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    }