Completed
Branch dev (d5d70c)
by Raffael
11:00
created

Http   A

Complexity

Total Complexity 8

Size/Duplication

Total Lines 83
Duplicated Lines 0 %

Coupling/Cohesion

Components 0
Dependencies 3

Importance

Changes 0
Metric Value
wmc 8
lcom 0
dl 0
loc 83
rs 10
c 0
b 0
f 0
cbo 3

3 Methods

Rating   Name   Duplication   Size   Complexity  
B __construct() 0 27 3
A invalidAuthentication() 0 21 4
A setExceptionHandler() 0 19 1
1
<?php
2
3
declare(strict_types=1);
4
5
/**
6
 * balloon
7
 *
8
 * @copyright   Copryright (c) 2012-2018 gyselroth GmbH (https://gyselroth.com)
9
 * @license     GPL-3.0 https://opensource.org/licenses/GPL-3.0
10
 */
11
12
namespace Balloon\Bootstrap;
13
14
use Balloon\Hook;
15
use Balloon\Server;
16
use Composer\Autoload\ClassLoader as Composer;
17
use Micro\Auth\Adapter\None as AuthNone;
18
use Micro\Auth\Auth;
19
use Micro\Http\Response;
20
use Micro\Http\Router;
21
use MongoDB\BSON\Binary;
22
use Psr\Log\LoggerInterface;
23
24
class Http extends AbstractBootstrap
25
{
26
    /**
27
     * {@inheritdoc}
28
     */
29
    public function __construct(Composer $composer)
30
    {
31
        parent::__construct($composer);
32
        $this->setExceptionHandler();
33
34
        $this->container->get(LoggerInterface::class)->info('processing incoming http ['.$_SERVER['REQUEST_METHOD'].'] request to ['.$_SERVER['REQUEST_URI'].']', [
35
            'category' => get_class($this),
36
        ]);
37
38
        $auth = $this->container->get(Auth::class);
39
40
        $this->container->get(Hook::class)->run('preAuthentication', [$auth]);
41
42
        if ($auth->requireOne()) {
43
            if (!($auth->getIdentity()->getAdapter() instanceof AuthNone)) {
44
                $auth->getIdentity()->getAttributeMap()->addMapper('binary', function ($value) {
45
                    return new Binary($value, Binary::TYPE_GENERIC);
46
                });
47
48
                $this->container->get(Server::class)->setIdentity($auth->getIdentity());
49
            }
50
51
            $this->container->get(Router::class)->run();
52
        } else {
53
            $this->invalidAuthentication();
54
        }
55
    }
56
57
    /**
58
     * Send invalid authentication response.
59
     */
60
    protected function invalidAuthentication(): void
61
    {
62
        if (isset($_SERVER['PHP_AUTH_USER']) && '_logout' === $_SERVER['PHP_AUTH_USER']) {
63
            (new Response())
64
                ->setCode(401)
65
                ->setBody('Unauthorized')
66
                ->send();
67
        } else {
68
            if ('/api/auth' === $_SERVER['PATH_INFO']) {
69
                $code = 403;
70
            } else {
71
                $code = 401;
72
            }
73
74
            (new Response())
75
                ->setHeader('WWW-Authenticate', 'Basic realm="balloon"')
76
                ->setCode($code)
77
                ->setBody('Unauthorized')
78
                ->send();
79
        }
80
    }
81
82
    /**
83
     * Set exception handler.
84
     *
85
     * @return Http
86
     */
87
    protected function setExceptionHandler(): self
88
    {
89
        set_exception_handler(function ($e) {
90
            $this->container->get(LoggerInterface::class)->emergency('uncaught exception: '.$e->getMessage(), [
91
                'category' => get_class($this),
92
                'exception' => $e,
93
            ]);
94
95
            (new Response())
96
                ->setCode(500)
97
                ->setBody([
98
                    'error' => get_class($e),
99
                    'message' => $e->getMessage(),
100
                ])
101
                ->send();
102
        });
103
104
        return $this;
105
    }
106
}
107