Completed
Branch master (3adcdb)
by Raffael
08:09 queued 04:17
created

Http   A

Complexity

Total Complexity 9

Size/Duplication

Total Lines 129
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 9

Importance

Changes 0
Metric Value
wmc 9
lcom 1
cbo 9
dl 0
loc 129
rs 10
c 0
b 0
f 0

4 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 9 1
B process() 0 24 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 Micro\Auth\Adapter\None as AuthNone;
17
use Micro\Auth\Auth;
18
use Micro\Http\Response;
19
use Micro\Http\Router;
20
use MongoDB\BSON\Binary;
21
use Psr\Log\LoggerInterface;
22
23
class Http extends AbstractBootstrap
24
{
25
    /**
26
     * Auth.
27
     *
28
     * @var Auth
29
     */
30
    protected $auth;
31
32
    /**
33
     * Hook.
34
     *
35
     * @var Hook
36
     */
37
    protected $hook;
38
39
    /**
40
     * Router.
41
     *
42
     * @var Router
43
     */
44
    protected $router;
45
46
    /**
47
     * Server.
48
     *
49
     * @var Server
50
     */
51
    protected $server;
52
53
    /**
54
     * Http.
55
     *
56
     * @param LoggerInterface $logger
57
     * @param Auth            $auth
58
     * @param Hook            $hook
59
     * @param Router          $router
60
     * @param Server          $server
61
     */
62
    public function __construct(LoggerInterface $logger, Auth $auth, Hook $hook, Router $router, Server $server)
63
    {
64
        $this->setExceptionHandler();
65
        $this->logger = $logger;
66
        $this->auth = $auth;
67
        $this->hook = $hook;
68
        $this->router = $router;
69
        $this->server = $server;
70
    }
71
72
    /**
73
     * Process.
74
     *
75
     * @return Http
76
     */
77
    public function process()
78
    {
79
        $this->logger->info('processing incoming http ['.$_SERVER['REQUEST_METHOD'].'] request to ['.$_SERVER['REQUEST_URI'].']', [
80
            'category' => get_class($this),
81
        ]);
82
83
        $this->hook->run('preAuthentication', [$this->auth]);
84
85
        if ($this->auth->requireOne()) {
86
            if (!($this->auth->getIdentity()->getAdapter() instanceof AuthNone)) {
87
                $this->auth->getIdentity()->getAttributeMap()->addMapper('binary', function ($value) {
88
                    return new Binary($value, Binary::TYPE_GENERIC);
89
                });
90
91
                $this->server->setIdentity($this->auth->getIdentity());
0 ignored issues
show
Compatibility introduced by
$this->auth->getIdentity() of type object<Micro\Auth\IdentityInterface> is not a sub-type of object<Micro\Auth\Identity>. It seems like you assume a concrete implementation of the interface Micro\Auth\IdentityInterface to be always present.

This check looks for parameters that are defined as one type in their type hint or doc comment but seem to be used as a narrower type, i.e an implementation of an interface or a subclass.

Consider changing the type of the parameter or doing an instanceof check before assuming your parameter is of the expected type.

Loading history...
92
            }
93
94
            $this->router->run();
95
        } else {
96
            $this->invalidAuthentication();
97
        }
98
99
        return $this;
100
    }
101
102
    /**
103
     * Send invalid authentication response.
104
     */
105
    protected function invalidAuthentication(): void
106
    {
107
        if (isset($_SERVER['PHP_AUTH_USER']) && '_logout' === $_SERVER['PHP_AUTH_USER']) {
108
            (new Response())
109
                ->setCode(401)
110
                ->setBody('Unauthorized')
111
                ->send();
112
        } else {
113
            if ('/api/auth' === $_SERVER['PATH_INFO']) {
114
                $code = 403;
115
            } else {
116
                $code = 401;
117
            }
118
119
            (new Response())
120
                ->setHeader('WWW-Authenticate', 'Basic realm="balloon"')
121
                ->setCode($code)
122
                ->setBody('Unauthorized')
123
                ->send();
124
        }
125
    }
126
127
    /**
128
     * Set exception handler.
129
     *
130
     * @return Http
131
     */
132
    protected function setExceptionHandler(): self
133
    {
134
        set_exception_handler(function ($e) {
135
            $this->logger->emergency('uncaught exception: '.$e->getMessage(), [
136
                'category' => get_class($this),
137
                'exception' => $e,
138
            ]);
139
140
            (new Response())
141
                ->setCode(500)
142
                ->setBody([
143
                    'error' => get_class($e),
144
                    'message' => $e->getMessage(),
145
                ])
146
                ->send();
147
        });
148
149
        return $this;
150
    }
151
}
152