Passed
Push — master ( 2c25c6...9f902b )
by Raffael
08:57
created

Http::invalidAuthentication()   B

Complexity

Conditions 4
Paths 3

Size

Total Lines 27
Code Lines 20

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 20

Importance

Changes 0
Metric Value
dl 0
loc 27
ccs 0
cts 26
cp 0
rs 8.5806
c 0
b 0
f 0
cc 4
eloc 20
nc 3
nop 0
crap 20
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->setErrorHandler();
66
        $this->logger = $logger;
67
        $this->auth = $auth;
68
        $this->hook = $hook;
69
        $this->router = $router;
70
        $this->server = $server;
71
    }
72
73
    /**
74
     * Process.
75
     *
76
     * @return Http
77
     */
78
    public function process()
79
    {
80
        $this->logger->info('processing incoming http ['.$_SERVER['REQUEST_METHOD'].'] request to ['.$_SERVER['REQUEST_URI'].']', [
81
            'category' => get_class($this),
82
        ]);
83
84
        $this->hook->run('preAuthentication', [$this->auth]);
85
86
        if ($this->auth->requireOne()) {
87
            if (!($this->auth->getIdentity()->getAdapter() instanceof AuthNone)) {
0 ignored issues
show
Bug introduced by
The class Micro\Auth\Adapter\None does not exist. Did you forget a USE statement, or did you not list all dependencies?

This error could be the result of:

1. Missing dependencies

PHP Analyzer uses your composer.json file (if available) to determine the dependencies of your project and to determine all the available classes and functions. It expects the composer.json to be in the root folder of your repository.

Are you sure this class is defined by one of your dependencies, or did you maybe not list a dependency in either the require or require-dev section?

2. Missing use statement

PHP does not complain about undefined classes in ìnstanceof checks. For example, the following PHP code will work perfectly fine:

if ($x instanceof DoesNotExist) {
    // Do something.
}

If you have not tested against this specific condition, such errors might go unnoticed.

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