Completed
Pull Request — master (#22)
by Samuel
05:21 queued 02:25
created

MultiAuthenticate::handle()   C

Complexity

Conditions 7
Paths 11

Size

Total Lines 36
Code Lines 18

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 16
CRAP Score 7.0099

Importance

Changes 3
Bugs 0 Features 0
Metric Value
c 3
b 0
f 0
dl 0
loc 36
ccs 16
cts 17
cp 0.9412
rs 6.7272
cc 7
eloc 18
nc 11
nop 3
crap 7.0099
1
<?php
2
3
namespace SMartins\PassportMultiauth\Http\Middleware;
4
5
use Closure;
6
use Illuminate\Http\Request;
7
use League\OAuth2\Server\ResourceServer;
8
use Illuminate\Auth\AuthenticationException;
9
use Illuminate\Auth\Middleware\Authenticate;
10
use Illuminate\Contracts\Auth\Factory as Auth;
11
use Illuminate\Contracts\Auth\Authenticatable;
12
use SMartins\PassportMultiauth\Provider as Token;
13
use SMartins\PassportMultiauth\PassportMultiauth;
14
use SMartins\PassportMultiauth\ProviderRepository;
15
use SMartins\PassportMultiauth\Guards\GuardChecker;
16
use League\OAuth2\Server\Exception\OAuthServerException;
17
use Symfony\Bridge\PsrHttpMessage\Factory\DiactorosFactory;
18
19
class MultiAuthenticate extends Authenticate
20
{
21
    /**
22
     * @var \League\OAuth2\Server\ResourceServer
23
     */
24
    protected $server;
25
26
    /**
27
     * @var \SMartins\PassportMultiauth\ProviderRepository
28
     */
29
    protected $providers;
30
31
    /**
32
     * The authentication factory instance.
33
     *
34
     * @var \Illuminate\Contracts\Auth\Factory
35
     */
36
    protected $auth;
37
38 12
    public function __construct(ResourceServer $server, ProviderRepository $providers, Auth $auth)
39
    {
40 12
        $this->server = $server;
41 12
        $this->providers = $providers;
42 12
        $this->auth = $auth;
43 12
    }
44
45
    /**
46
     * Handle an incoming request. Authenticates the guard from access token
47
     * used on request.
48
     *
49
     * @param \Illuminate\Http\Request $request
50
     * @param \Closure                 $next
51
     * @param string[]                 ...$guards
52
     *
53
     * @return mixed
54
     */
55 12
    public function handle($request, Closure $next, ...$guards)
56
    {
57
        // If don't has any guard follow the flow
58 12
        if (empty($guards)) {
59 1
            return $next($request);
60
        }
61
62 11
        if ($user = PassportMultiauth::userActing()) {
63 7
            if (! $this->canBeAuthenticated($user, $guards)) {
64 2
                throw new AuthenticationException('Unauthenticated', $guards);
65
            }
66
67 5
            return $next($request);
68
        }
69
70 4
        $psrRequest = (new DiactorosFactory())->createRequest($request);
71
72
        try {
73 4
            $psrRequest = $this->server->validateAuthenticatedRequest($psrRequest);
74
75 3
            if (! $tokenId = $psrRequest->getAttribute('oauth_access_token_id')) {
76 1
                throw new AuthenticationException('Unauthenticated', $guards);
77
            }
78
79 2
            if (! $accessToken = $this->providers->findForToken($tokenId)) {
80 1
                throw new AuthenticationException('Unauthenticated', $guards);
81
            }
82
83 1
            $this->authenticateTokenGuard($accessToken, $guards);
84
85
            return $next($request);
86 4
        } catch (OAuthServerException $e) {
87
            // @todo Check if it's the best way to handle with OAuthServerException
88 1
            throw new AuthenticationException('Unauthenticated', $guards);
89
        }
90
    }
91
92
    /**
93
     * Check if user acting has the required guards and scopes on request.
94
     *
95
     * @param  \Illuminate\Foundation\Auth\User $user
96
     * @param  \Illuminate\Http\Request $request
0 ignored issues
show
Bug introduced by
There is no parameter named $request. Was it maybe removed?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

Loading history...
97
     * @return bool
98
     */
99 7
    public function canBeAuthenticated(Authenticatable $user, $guards)
100
    {
101 7
        $userGuard = PassportMultiauth::getUserGuard($user);
102
103 7
        return in_array($userGuard, $guards);
104
    }
105
106
    /**
107
     * Authenticate correct guard based on token.
108
     *
109
     * @param \SMartins\PassportMultiauth\Provider $token
110
     * @param  array $guards
111
     * @return void
112
     */
113 1
    public function authenticateTokenGuard(Token $token, $guards)
114
    {
115 1
        $providers = GuardChecker::getGuardsProviders($guards);
116
117
        // use only guard associated to access token provider
118 1
        $authGuards = $providers->has($token->provider) ? [$providers->get($token->provider)] : [];
119
120 1
        $this->authenticate($authGuards);
121
    }
122
}
123