MultiAuthenticate::__construct()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 9
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 3
nc 1
nop 3
dl 0
loc 9
ccs 4
cts 4
cp 1
crap 1
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 13
    public function __construct(
40
        ResourceServer $server,
41
        ProviderRepository $providers,
42
        Auth $auth
43
    ) {
44 13
        parent::__construct($auth);
45
46 13
        $this->server = $server;
47 13
        $this->providers = $providers;
48 13
    }
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 13
    public function handle($request, Closure $next, ...$guards)
63
    {
64
        // If don't has any guard follow the flow
65 13
        if (empty($guards)) {
66 2
            $this->authenticate($request, $guards);
67
68
            // Stop laravel from checking for a token if session is not set
69
            return $next($request);
70
        }
71
72 11
        $psrRequest = ServerRequest::createRequest($request);
73
74
        try {
75 11
            $psrRequest = $this->server->validateAuthenticatedRequest($psrRequest);
76
77 4
            if (! ($accessToken = $this->getAccessTokenFromRequest($psrRequest))) {
78 2
                throw new AuthenticationException('Unauthenticated', $guards);
79
            }
80
81 2
            $guard = $this->getTokenGuard($accessToken, $guards);
82
83 2
            $this->authenticate($request, $guard);
84 10
        } catch (OAuthServerException $e) {
85
            // If has an OAuthServerException check if has unit tests and fake
86
            // user authenticated.
87 7
            if (($user = PassportMultiauth::userActing()) &&
88 7
                $this->canBeAuthenticated($user, $guards)
89
            ) {
90 4
                return $next($request);
91
            }
92
93
            // @todo Check if it's the best way to handle with OAuthServerException
94 3
            throw new AuthenticationException('Unauthenticated', $guards);
95
        }
96
97 1
        return $next($request);
98
    }
99
100
    /**
101
     * @param ServerRequestInterface $request
102
     * @return null|Token
103
     */
104 4
    public function getAccessTokenFromRequest(ServerRequestInterface $request)
105
    {
106 4
        if (! ($tokenId = $request->getAttribute('oauth_access_token_id'))) {
107 1
            return;
108
        }
109
110 3
        return $this->providers->findForToken($tokenId);
111
    }
112
113
    /**
114
     * Check if user acting has the required guards and scopes on request.
115
     *
116
     * @param Authenticatable $user
117
     * @param  array $guards
118
     * @return bool
119
     * @throws \SMartins\PassportMultiauth\Exceptions\MissingConfigException
120
     */
121 6
    public function canBeAuthenticated(Authenticatable $user, $guards)
122
    {
123 6
        $userGuard = AuthConfigHelper::getUserGuard($user);
124
125 6
        return in_array($userGuard, $guards);
126
    }
127
128
    /**
129
     * Get guard related with token.
130
     *
131
     * @param Token $token
132
     * @param $guards
133
     * @return array
134
     */
135 2
    public function getTokenGuard(Token $token, $guards)
136
    {
137 2
        $providers = GuardChecker::getGuardsProviders($guards);
138
139
        // use only guard associated to access token provider
140 2
        return $providers->has($token->provider) ? [$providers->get($token->provider)] : [];
141
    }
142
}
143