Cert::__construct()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 5
c 0
b 0
f 0
ccs 4
cts 4
cp 1
rs 9.4285
cc 1
eloc 3
nc 1
nop 2
crap 1
1
<?php
2
declare(strict_types=1);
3
/**
4
 * Caridea
5
 *
6
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
7
 * use this file except in compliance with the License. You may obtain a copy of
8
 * the License at
9
 *
10
 * http://www.apache.org/licenses/LICENSE-2.0
11
 *
12
 * Unless required by applicable law or agreed to in writing, software
13
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
14
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
15
 * License for the specific language governing permissions and limitations under
16
 * the License.
17
 *
18
 * @copyright 2015-2018 LibreWorks contributors
19
 * @license   Apache-2.0
20
 */
21
namespace Caridea\Auth\Adapter;
22
23
/**
24
 * Client SSL certificate authentication adapter.
25
 *
26
 * @copyright 2015-2018 LibreWorks contributors
27
 * @license   Apache-2.0
28
 */
29
class Cert extends AbstractAdapter
30
{
31
    /**
32
     * @var string The `$_SERVER` key which contains the DN
33
     */
34
    protected $name;
35
    /**
36
     * @var string Regex to match username from DN
37
     */
38
    protected $regex;
39
    
40
    /**
41
     * Creates a new client certificate authentication adapter.
42
     *
43
     * ```php
44
     * // $_SERVER['SSL_CLIENT_S_DN'] = '/O=Acme, Inc/CN=Bob';
45
     * $adapter = new Cert();
46
     * $adapter->login($request); // username: "/O=Acme, Inc/CN=Bob"
47
     *
48
     * // $_SERVER['DN'] = '/O=Acme, Inc/CN=Bob';
49
     * $adapter = new Cert('DN', '#CN=(.+)$#');
50
     * $adapter->login($request); // username: "Bob"
51
     * ```
52
     *
53
     * @param string $name The `$_SERVER` key which contains the user cert DN
54
     * @param string $regex A regex to match a username inside the DN (if not
55
     *     specified, username is the entire DN). Must have one capture pattern.
56
     */
57 5
    public function __construct(string $name = 'SSL_CLIENT_S_DN', string $regex = null)
58
    {
59 5
        $this->name = $this->checkBlank($name, "name");
60 4
        $this->regex = $regex;
61 4
    }
62
    
63
    /**
64
     * Authenticates the current principal using the provided credentials.
65
     *
66
     * This method will retrieve a value from the SERVER attributes in the
67
     * offset at `$this->name`.
68
     *
69
     * The principal details will include `ip` (remote IP address), `ua` (remote
70
     * User Agent), and `dn` (client SSL distinguished name).
71
     *
72
     * @param \Psr\Http\Message\ServerRequestInterface $request The Server Request message containing credentials
73
     * @return \Caridea\Auth\Principal An authenticated principal
74
     * @throws \Caridea\Auth\Exception\MissingCredentials if no value was found
75
     *     in the SERVER field or the provided regular expression doesn't match
76
     */
77 4
    public function login(\Psr\Http\Message\ServerRequestInterface $request): \Caridea\Auth\Principal
78
    {
79 4
        $server = $request->getServerParams();
80 4
        $username = $dn = $this->ensure($server, $this->name);
81 3
        if ($this->regex) {
82 2
            if (preg_match($this->regex, $dn, $matches)) {
83 1
                $username = $matches[1];
84
            } else {
85 1
                throw new \Caridea\Auth\Exception\MissingCredentials();
86
            }
87
        }
88 2
        return \Caridea\Auth\Principal::get(
89 2
            $username,
90 2
            $this->details($request, ['dn' => $dn])
91
        );
92
    }
93
}
94