Completed
Push — master ( 0c1faf...c6b404 )
by Raffael
02:34
created

AbstractBasic::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 5
rs 9.4285
c 0
b 0
f 0
cc 1
eloc 3
nc 1
nop 2
1
<?php
2
declare(strict_types = 1);
3
4
/**
5
 * Micro
6
 *
7
 * @author    Raffael Sahli <[email protected]>
8
 * @copyright Copyright (c) 2017 gyselroth GmbH (https://gyselroth.com)
9
 * @license   MIT https://opensource.org/licenses/MIT
10
 */
11
12
namespace Micro\Auth\Adapter\Basic;
13
14
use \Micro\Auth\Exception;
15
use \Psr\Log\LoggerInterface as Logger;
16
use \Micro\Auth\Adapter\AdapterInterface;
17
use \Micro\Auth\Adapter\AbstractAdapter;
18
19
abstract class AbstractBasic extends AbstractAdapter
20
{
21
    /**
22
     * Attributes
23
     *
24
     * @var array
25
     */
26
    protected $attributes = [];
27
28
29
    /**
30
     * Init adapter
31
     *
32
     * @param   LoggerInterface $logger
33
     * @param   Iterable $config
34
     * @return  void
0 ignored issues
show
Comprehensibility Best Practice introduced by
Adding a @return annotation to constructors is generally not recommended as a constructor does not have a meaningful return value.

Adding a @return annotation to a constructor is not recommended, since a constructor does not have a meaningful return value.

Please refer to the PHP core documentation on constructors.

Loading history...
35
     */
36
    public function __construct(LoggerInterface $logger, ?Iterable $config=null)
37
    {
38
        $this->logger = $logger;
0 ignored issues
show
Documentation Bug introduced by
It seems like $logger of type object<Micro\Auth\Adapter\Basic\LoggerInterface> is incompatible with the declared type object<Psr\Log\LoggerInterface> of property $logger.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
39
        $this->setOptions($config);
40
    }
41
42
43
    /**
44
     * Authenticate
45
     *
46
     * @return bool
47
     */
48
    public function authenticate(): bool
49
    {
50
        if (!isset($_SERVER['HTTP_AUTHORIZATION'])) {
51
            $this->logger->debug('skip auth adapter ['.get_class($this).'], no http authorization header found', [
52
                'category' => get_class($this)
53
            ]);
54
55
            return false;
56
        }
57
58
        $header = $_SERVER['HTTP_AUTHORIZATION'];
59
        $parts  = explode(' ', $header);
60
61
        if ($parts[0] == 'Basic') {
62
            $this->logger->debug('found http basic authorization header', [
63
                'category' => get_class($this)
64
            ]);
65
66
            $username = $_SERVER['PHP_AUTH_USER'];
67
            $password = $_SERVER['PHP_AUTH_PW'];
68
69
            return $this->plainAuth($username, $password);
70
        } else {
71
            $this->logger->warning('http authorization header contains no basic string or invalid authentication string', [
72
                'category' => get_class($this)
73
            ]);
74
75
            return false;
76
        }
77
    }
78
79
80
    /**
81
     * Auth
82
     *
83
     * @param   string $username
84
     * @param   string $password
85
     * @return  bool
86
     */
87
    protected function plainAuth(string $username, string $password): bool
88
    {
89
        $result = $this->findIdentity($username);
90
91
        if ($result === null) {
92
            $this->logger->info('found no user named ['.$username.'] in database', [
93
                'category' => get_class($this)
94
            ]);
95
96
            return false;
97
        }
98
99
        if (!isset($result['password']) || empty($result['password'])) {
100
            $this->logger->info('found no password for ['.$username.'] in database', [
101
                'category' => get_class($this)
102
            ]);
103
104
            return false;
105
        }
106
107
        if (!password_verify($password, $result['password'])) {
108
            $this->logger->info('failed match given password for ['.$username.'] with stored hash in database', [
109
                'category' => get_class($this)
110
            ]);
111
112
            return false;
113
        }
114
115
        $this->attributes = $result;
116
        $this->identifier = $username;
117
        return true;
118
    }
119
120
121
    /**
122
     * Find Identity
123
     *
124
     * @param  string $username
125
     * @return array
126
     */
127
    protected abstract function findIdentity(string $username): ?array;
0 ignored issues
show
Coding Style introduced by
The abstract declaration must precede the visibility declaration
Loading history...
128
129
130
    /**
131
     * Get attributes
132
     *
133
     * @return array
134
     */
135
    public function getAttributes(): array
136
    {
137
        return $this->attributes;
138
    }
139
}
140