Lines 0.00% 0 / 22
Functions and Methods 0.00% 0 / 3
Classes and Traits 0.00% 0 / 1
Name Lines Functions and Methods CRAP Classes and Traits
HttpBasicAuth 0.00% 0 / 22 0.00% 0 / 3 132 0.00% 0 / 1
 __construct 0.00% 0 / 4 0.00% 0 / 1 20
 useAppConfig 0.00% 0 / 7 0.00% 0 / 1 20
 __invoke 0.00% 0 / 11 0.00% 0 / 1 12
1<?php
2
3/**
4 * HTTP Basic Authentication
5 *
6 * inspired by https://github.com/codeguy/Slim-Extras/blob/master/Middleware/HttpBasicAuth.php
7 *
8 * Usage:
9 *   \App::httpBasicAuth['username'] = password_hash('password', PASSWORD_DEFAULT);
10 *   // better pre-calculate hash in the config with `php -r "echo password_hash('password', PASSWORD_DEFAULT);"`
11 *   \App::$slim->add(new \BO\Slim\Middleware\HttpBasicAuth(\BO\Slim\Middleware\HttpBasicAuth::useAppConfig());
12 */
13
14namespace BO\Slim\Middleware;
15
16use Psr\Http\Message\ServerRequestInterface;
17use Psr\Http\Message\ResponseInterface;
18use Psr\Http\Server\RequestHandlerInterface;
19use BO\Slim\Factory\ResponseFactory;
20
21class HttpBasicAuth
22{
23    /**
24     * @var string
25     */
26    protected $realm;
27
28    /**
29     * @var Callable
30     */
31    protected $isAuthorized;
32
33    public function __construct(callable $isAuthorized, ?string $realm = null)
34    {
35        $this->isAuthorized = $isAuthorized;
36        $this->realm = ($realm !== null && $realm !== '' && $realm !== '0')
37            ? $realm
38            : "Password " . \App::IDENTIFIER;
39    }
40
41    public static function useAppConfig(): callable
42    {
43        return function (string $authUser, string $authPass) {
44            if (!count(\App::$httpBasicAuth)) {
45                return true;
46            }
47            if (isset(\App::$httpBasicAuth[$authUser]) && password_verify($authPass, \App::$httpBasicAuth[$authUser])) {
48                return true;
49            }
50            return false;
51        };
52    }
53
54    public function __invoke(ServerRequestInterface $request, RequestHandlerInterface $next): ResponseInterface
55    {
56        $serverParams = $request->getServerParams();
57        $authUser = $serverParams['PHP_AUTH_USER'] ?? '';
58        $authPass = $serverParams['PHP_AUTH_PW'] ?? '';
59
60        if ($this->isAuthorized instanceof \Closure) {
61            $authorized = $this->isAuthorized->call($this, $authUser, $authPass);
62        } else {
63            $authorized = ($this->isAuthorized)($authUser, $authPass);
64        }
65        if ($authorized) {
66            $response = $next->handle($request);
67        } else {
68            $response = (new ResponseFactory())->createResponse(401, 'Unauthorized');
69            $response = $response->withHeader('WWW-Authenticate', sprintf('Basic realm="%s"', $this->realm));
70        }
71
72        return $response;
73    }
74}