Completed
Push — master ( 55d0bf...bd8278 )
by Andrii
15:19
created

OAuth2Middleware   A

Complexity

Total Complexity 12

Size/Duplication

Total Lines 78
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 3

Importance

Changes 0
Metric Value
wmc 12
lcom 1
cbo 3
dl 0
loc 78
rs 10
c 0
b 0
f 0

7 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 4 1
A authenticate() 0 13 3
A findIdentity() 0 17 3
A getUserInfo() 0 8 1
A getClient() 0 7 1
A getAccessToken() 0 9 2
A getParam() 0 4 1
1
<?php
2
3
namespace hiapi\Core\Auth;
4
5
use hiapi\exceptions\NotAuthenticatedException;
6
use Psr\Http\Message\ServerRequestInterface;
7
use yii\web\User;
8
use GuzzleHttp\Client;
9
use yii\web\IdentityInterface;
10
11
/**
12
 * XXX Think if authentication can be done deferred?
13
 * XXX Does it make sence?
14
 */
15
class OAuth2Middleware extends AuthMiddleware
16
{
17
    public $userinfoUrl;
18
19
    /**
20
     * @var User
21
     */
22
    private $user;
23
24
    public function __construct(User $user)
25
    {
26
        $this->user = $user;
27
    }
28
29
    public function authenticate(ServerRequestInterface $request)
30
    {
31
        $identity = $this->findIdentity($request);
32
33
        if (empty($identity)) {
34
            throw new NotAuthenticatedException('failed login by token');
35
        }
36
37
        $ok = $this->user->login($identity);
38
        if ($ok !== true) {
39
            throw new NotAuthenticatedException('failed login by token');
40
        }
41
    }
42
43
    private function findIdentity(ServerRequestInterface $request): ?IdentityInterface
44
    {
45
        $token = $this->getAccessToken($request);
46
        if (empty($token)) {
47
            throw new NotAuthenticatedException('no access token given');
48
        }
49
50
        try {
51
            $info = $this->getUserInfo($token);
52
        } catch (\Throwable $e) {
0 ignored issues
show
Bug introduced by
The class Throwable does not exist. Did you forget a USE statement, or did you not list all dependencies?

Scrutinizer analyzes your composer.json/composer.lock file if available to determine the classes, and functions that are defined by your dependencies.

It seems like the listed class was neither found in your dependencies, nor was it found in the analyzed files in your repository. If you are using some other form of dependency management, you might want to disable this analysis.

Loading history...
53
            throw new NotAuthenticatedException($e->getMessage());
54
        }
55
56
        $class = $this->user->identityClass;
57
58
        return $class::fromArray($info);
59
    }
60
61
    private function getUserInfo(string $token)
62
    {
63
        $res = $this->getClient()->request('GET', '', ['headers' => [
64
            'Authorization' => 'Bearer ' . $token,
65
        ]]);
66
67
        return \json_decode((string)$res->getBody(), true);
68
    }
69
70
    private function getClient(): Client
71
    {
72
        return new Client([
73
            'base_uri' => $this->userinfoUrl,
74
            'timeout' => 1.0,
75
        ]);
76
    }
77
78
    private function getAccessToken(ServerRequestInterface $request): ?string
79
    {
80
        $header = $request->getHeaderLine('Authorization');
81
        if (preg_match('/^Bearer\s+([a-fA-F0-9]{30,50})$/', $header, $matches)) {
82
            return $matches[1];
83
        }
84
85
        return $this->getParam($request, 'access_token');
86
    }
87
88
    public function getParam(ServerRequestInterface $request, string $name): ?string
89
    {
90
        return $request->getParsedBody()[$name] ?? $request->getQueryParams()[$name] ?? null;
91
    }
92
}
93