Completed
Pull Request — master (#22)
by Samuel
06:06 queued 02:41
created

MultiAuthenticate::canBeAuthenticated()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 6
ccs 3
cts 3
cp 1
rs 9.4285
cc 1
eloc 3
nc 1
nop 2
crap 1
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
     * @return mixed
53
     *
54
     * @throws \Illuminate\Auth\AuthenticationException
55
     */
56 12
    public function handle($request, Closure $next, ...$guards)
57
    {
58
        // If don't has any guard follow the flow
59 12
        if (empty($guards)) {
60 1
            return $next($request);
61
        }
62
63 11
        $psrRequest = (new DiactorosFactory())->createRequest($request);
64
65
        try {
66 11
            $psrRequest = $this->server->validateAuthenticatedRequest($psrRequest);
67
68 4
            if (! $tokenId = $psrRequest->getAttribute('oauth_access_token_id')) {
69 1
                throw new AuthenticationException('Unauthenticated', $guards);
70
            }
71
72 3
            if (! $accessToken = $this->providers->findForToken($tokenId)) {
73 1
                throw new AuthenticationException('Unauthenticated', $guards);
74
            }
75
76 2
            $this->authenticateTokenGuard($accessToken, $guards);
77 10
        } catch (OAuthServerException $e) {
78
            // If has an OAuthServerException check if has unit tests and fake
79
            // user authenticated.
80 7
            if ($user = PassportMultiauth::userActing()) {
81 6
                if ($this->canBeAuthenticated($user, $guards)) {
82 4
                    return $next($request);
83
                    // throw new AuthenticationException('Unauthenticated', $guards);
0 ignored issues
show
Unused Code Comprehensibility introduced by
62% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
84
                }
85
            }
86
87
            // @todo Check if it's the best way to handle with OAuthServerException
88 3
            throw new AuthenticationException('Unauthenticated', $guards);
89
        }
90
91 1
        return $next($request);
92
    }
93
94
    /**
95
     * Check if user acting has the required guards and scopes on request.
96
     *
97
     * @param  \Illuminate\Foundation\Auth\User $user
98
     * @param  array $guards
99
     * @return bool
100
     */
101 6
    public function canBeAuthenticated(Authenticatable $user, $guards)
102
    {
103 6
        $userGuard = PassportMultiauth::getUserGuard($user);
104
105 6
        return in_array($userGuard, $guards);
106
    }
107
108
    /**
109
     * Authenticate correct guard based on token.
110
     *
111
     * @param \SMartins\PassportMultiauth\Provider $token
112
     * @param  array $guards
113
     * @return void
114
     *
115
     * @throws \Illuminate\Auth\AuthenticationException
116
     */
117 2
    public function authenticateTokenGuard(Token $token, $guards)
118
    {
119 2
        $providers = GuardChecker::getGuardsProviders($guards);
120
121
        // use only guard associated to access token provider
122 2
        $authGuards = $providers->has($token->provider) ? [$providers->get($token->provider)] : [];
123
124 2
        return $this->authenticate($authGuards);
125
    }
126
}
127