Test Failed
Pull Request — 3.0 (#56)
by
unknown
04:06
created

MultiAuthenticate::authenticateTokenGuard()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 8
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 2

Importance

Changes 0
Metric Value
cc 2
eloc 3
nc 2
nop 2
dl 0
loc 8
ccs 4
cts 4
cp 1
crap 2
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace SMartins\PassportMultiauth\Http\Middleware;
4
5
use Closure;
6
use League\OAuth2\Server\ResourceServer;
7
use Illuminate\Auth\AuthenticationException;
8
use Illuminate\Auth\Middleware\Authenticate;
9
use Psr\Http\Message\ServerRequestInterface;
10
use Illuminate\Contracts\Auth\Authenticatable;
11
use Illuminate\Contracts\Auth\Factory as Auth;
12
use SMartins\PassportMultiauth\PassportMultiauth;
13
use SMartins\PassportMultiauth\Provider as Token;
14
use SMartins\PassportMultiauth\ProviderRepository;
15
use SMartins\PassportMultiauth\Guards\GuardChecker;
16
use SMartins\PassportMultiauth\Facades\ServerRequest;
17
use SMartins\PassportMultiauth\Config\AuthConfigHelper;
18
use League\OAuth2\Server\Exception\OAuthServerException;
19
20
class MultiAuthenticate extends Authenticate
21
{
22
    /**
23
     * @var ResourceServer
24
     */
25
    protected $server;
26
27
    /**
28
     * @var ProviderRepository
29
     */
30
    protected $providers;
31
32
    /**
33
     * Create a new middleware instance.
34
     *
35
     * @param ResourceServer $server
36
     * @param ProviderRepository $providers
37
     * @param Auth $auth
38
     */
39 12
    public function __construct(
40
        ResourceServer $server,
41
        ProviderRepository $providers,
42
        Auth $auth
43
    ) {
44 12
        parent::__construct($auth);
45
46 12
        $this->server = $server;
47 12
        $this->providers = $providers;
48 12
    }
49
50
    /**
51
     * Handle an incoming request. Authenticates the guard from access token
52
     * used on request.
53
     *
54
     * @param \Illuminate\Http\Request $request
55
     * @param \Closure $next
56
     * @param string[] ...$guards
57
     * @return mixed
58
     *
59
     * @throws \Illuminate\Auth\AuthenticationException
60
     * @throws \SMartins\PassportMultiauth\Exceptions\MissingConfigException
61
     */
62 12
    public function handle($request, Closure $next, ...$guards)
63
    {
64
        // If don't has any guard follow the flow
65 12
        if (empty($guards)) {
66 2
            $this->authenticate($guards);
67
68
            // Stop laravel from checking for a token if session is not set
69
            return $next($request);
70
        }
71
72 10
        $psrRequest = ServerRequest::createRequest($request);
73
74
        try {
75 10
            $psrRequest = $this->server->validateAuthenticatedRequest($psrRequest);
76
77 3
            if (! ($accessToken = $this->getAccessTokenFromRequest($psrRequest))) {
78 2
                throw new AuthenticationException('Unauthenticated', $guards);
79
            }
80
81 1
            $this->authenticateTokenGuard($accessToken, $guards);
82 10
        } catch (OAuthServerException $e) {
83
            // If has an OAuthServerException check if has unit tests and fake
84
            // user authenticated.
85 7
            if (($user = PassportMultiauth::userActing()) &&
86 7
                $this->canBeAuthenticated($user, $guards)
87
            ) {
88 4
                return $next($request);
89
            }
90
91
            // @todo Check if it's the best way to handle with OAuthServerException
92 3
            throw new AuthenticationException('Unauthenticated', $guards);
93
        }
94
95
        return $next($request);
96
    }
97
98
    /**
99
     * @param ServerRequestInterface $request
100
     * @return null|Token
101
     */
102 3
    public function getAccessTokenFromRequest(ServerRequestInterface $request)
103
    {
104 3
        if (! ($tokenId = $request->getAttribute('oauth_access_token_id'))) {
105 1
            return;
106
        }
107
108 2
        return $this->providers->findForToken($tokenId);
109
    }
110
111
    /**
112
     * Check if user acting has the required guards and scopes on request.
113
     *
114
     * @param Authenticatable $user
115
     * @param  array $guards
116
     * @return bool
117
     * @throws \SMartins\PassportMultiauth\Exceptions\MissingConfigException
118
     */
119 6
    public function canBeAuthenticated(Authenticatable $user, $guards)
120
    {
121 6
        $userGuard = AuthConfigHelper::getUserGuard($user);
122
123 6
        return in_array($userGuard, $guards);
124
    }
125
126
    /**
127
     * Authenticate correct guard based on token.
128
     *
129
     * @param \SMartins\PassportMultiauth\Provider $token
130
     * @param  array $guards
131
     * @return void
132
     * @throws \Illuminate\Auth\AuthenticationException
133
     */
134 1
    public function authenticateTokenGuard(Token $token, $guards)
135
    {
136 1
        $providers = GuardChecker::getGuardsProviders($guards);
137
138
        // use only guard associated to access token provider
139 1
        $authGuards = $providers->has($token->provider) ? [$providers->get($token->provider)] : [];
140
141 1
        $this->authenticate($token, $authGuards);
0 ignored issues
show
Bug introduced by
$token of type SMartins\PassportMultiauth\Provider is incompatible with the type array expected by parameter $guards of Illuminate\Auth\Middlewa...nticate::authenticate(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

141
        $this->authenticate(/** @scrutinizer ignore-type */ $token, $authGuards);
Loading history...
Unused Code introduced by
The call to Illuminate\Auth\Middlewa...nticate::authenticate() has too many arguments starting with $authGuards. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

141
        $this->/** @scrutinizer ignore-call */ 
142
               authenticate($token, $authGuards);

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
142
    }
143
}
144