Passed
Pull Request — master (#19)
by Samuel
02:03
created

MultiAuthenticate::handle()   B

Complexity

Conditions 6
Paths 14

Size

Total Lines 46
Code Lines 23

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 42

Importance

Changes 1
Bugs 0 Features 0
Metric Value
dl 0
loc 46
ccs 0
cts 31
cp 0
rs 8.4751
c 1
b 0
f 0
cc 6
eloc 23
nc 14
nop 3
crap 42
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 SMartins\PassportMultiauth\ProviderRepository;
12
use SMartins\PassportMultiauth\Guards\GuardChecker;
13
use League\OAuth2\Server\Exception\OAuthServerException;
14
use Symfony\Bridge\PsrHttpMessage\Factory\DiactorosFactory;
15
16
class MultiAuthenticate extends Authenticate
17
{
18
    /**
19
     * The authentication factory instance.
20
     *
21
     * @var \Illuminate\Contracts\Auth\Factory
22
     */
23
    protected $auth;
24
25
    /**
26
     * @var \League\OAuth2\Server\ResourceServer
27
     */
28
    private $server;
29
30
    /**
31
     * @var \SMartins\PassportMultiauth\ProviderRepository
32
     */
33
    private $providers;
34
35
    public function __construct(ResourceServer $server, ProviderRepository $providers, Auth $auth)
36
    {
37
        $this->server = $server;
38
        $this->providers = $providers;
39
        $this->auth = $auth;
40
    }
41
42
    /**
43
     * Handle an incoming request. Authenticates the guard from access token
44
     * used on request.
45
     *
46
     * @param \Illuminate\Http\Request $request
47
     * @param \Closure                 $next
48
     * @param string[]                 ...$guards
49
     *
50
     * @return mixed
51
     */
52
    public function handle($request, Closure $next, ...$guards)
53
    {
54
        // Get the auth guard if has to check the default guard
55
        $guards = GuardChecker::getAuthGuards($request);
56
57
        // If don't has any guard follow the flow
58
        if (0 === count($guards)) {
59
            return $next($request);
60
        }
61
62
        $psr = (new DiactorosFactory())->createRequest($request);
63
64
        try {
65
            $psr = $this->server->validateAuthenticatedRequest($psr);
66
67
            $tokenId = $psr->getAttribute('oauth_access_token_id');
68
69
            if (! $tokenId) {
70
                throw new AuthenticationException('Unauthenticated', $guards);
71
            }
72
73
            $accessToken = $this->providers->findForToken($tokenId);
74
75
            if (! $accessToken) {
76
                throw new AuthenticationException('Unauthenticated', $guards);
77
            }
78
79
            $providers = collect($guards)->mapWithKeys(function ($guard) {
80
                return [GuardChecker::defaultGuardProvider($guard) => $guard];
81
            });
82
83
            // use only guard associated to access token provider
84
            if ($providers->has($accessToken->provider)) {
0 ignored issues
show
Documentation introduced by
The property provider does not exist on object<SMartins\PassportMultiauth\Provider>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
85
                $this->authenticate([$providers->get($accessToken->provider)]);
0 ignored issues
show
Documentation introduced by
The property provider does not exist on object<SMartins\PassportMultiauth\Provider>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
86
            } else {
87
                $this->authenticate([]);
88
            }
89
90
            return $next($request);
91
        } catch (OAuthServerException $e) {
92
            // @todo Check if it's the best way to handle with OAuthServerException
93
            throw new AuthenticationException('Unauthenticated', $guards);
94
        }
95
96
        return $next($request);
0 ignored issues
show
Unused Code introduced by
return $next($request); does not seem to be reachable.

This check looks for unreachable code. It uses sophisticated control flow analysis techniques to find statements which will never be executed.

Unreachable code is most often the result of return, die or exit statements that have been added for debug purposes.

function fx() {
    try {
        doSomething();
        return true;
    }
    catch (\Exception $e) {
        return false;
    }

    return false;
}

In the above example, the last return false will never be executed, because a return statement has already been met in every possible execution path.

Loading history...
97
    }
98
}
99