Passed
Pull Request — master (#19)
by
unknown
02:09
created

MultiAuthenticate::authenticate()   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 14
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 20

Importance

Changes 0
Metric Value
dl 0
loc 14
ccs 0
cts 12
cp 0
rs 9.2
c 0
b 0
f 0
cc 4
eloc 7
nc 4
nop 1
crap 20
1
<?php
2
3
namespace SMartins\PassportMultiauth\Http\Middleware;
4
5
use Closure;
6
use Illuminate\Http\Request;
7
use Illuminate\Support\Facades\App;
8
use League\OAuth2\Server\ResourceServer;
9
use Illuminate\Auth\AuthenticationException;
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
17
{
18
    /**
19
     * The authentication factory instance.
20
     *
21
     * @var \Illuminate\Contracts\Auth\Factory
22
     */
23
    protected $auth;
24
    /**
25
     * The application instance.
26
     *
27
     * @var \Illuminate\Foundation\Application
28
     */
29
    private $app;
30
31
    /**
32
     * @var \League\OAuth2\Server\ResourceServer
33
     */
34
    private $server;
35
36
    /**
37
     * @var \SMartins\PassportMultiauth\ProviderRepository
38
     */
39
    private $providers;
40
41
    public function __construct(ResourceServer $server, ProviderRepository $providers, App $app, Auth $auth)
0 ignored issues
show
Unused Code introduced by
The parameter $app is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
42
    {
43
        $this->server = $server;
44
        $this->providers = $providers;
45
        $this->app = App::getFacadeRoot();
46
        $this->auth = $auth;
47
    }
48
49
    /**
50
     * Handle an incoming request.
51
     *
52
     * @param \Illuminate\Http\Request $request
53
     * @param \Closure                 $next
54
     * @param string[]                 ...$guards
55
     *
56
     * @return mixed
57
     */
58
    public function handle(Request $request, Closure $next, ...$guards)
0 ignored issues
show
Unused Code introduced by
The parameter $guards is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
59
    {
60
        // Get the auth guard if has to check the default guard
61
        $guards = GuardChecker::getAuthGuards($request);
62
63
        // If don't has any guard follow the flow
64
        if (0 === count($guards)) {
65
            return $next($request);
66
        }
67
68
        $psr = (new DiactorosFactory())->createRequest($request);
69
70
        try {
71
            $psr = $this->server->validateAuthenticatedRequest($psr);
72
73
            $tokenId = $psr->getAttribute('oauth_access_token_id');
74
75
            if (! $tokenId) {
76
                throw new AuthenticationException('Unauthenticated', $guards);
77
            }
78
79
            $accessToken = $this->providers->findForToken($tokenId);
80
81
            if (! $accessToken) {
82
                throw new AuthenticationException('Unauthenticated', $guards);
83
            }
84
85
            $providers = collect($guards)->mapWithKeys(function ($guard) {
86
                return [GuardChecker::defaultGuardProvider($guard) => $guard];
87
            });
88
89
            // use only guard associated to access token provider
90
            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...
91
                $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...
92
            } else {
93
                $this->authenticate([]);
94
            }
95
96
            return $next($request);
97
        } catch (OAuthServerException $e) {
0 ignored issues
show
Coding Style Comprehensibility introduced by
Consider adding a comment why this CATCH block is empty.
Loading history...
98
        }
99
100
        return $next($request);
101
    }
102
103
    /**
104
     * Determine if the user is logged in to any of the given guards.
105
     *
106
     * @param array $guards
107
     *
108
     * @throws \Illuminate\Auth\AuthenticationException
109
     */
110
    protected function authenticate(array $guards)
111
    {
112
        if (empty($guards)) {
113
            return $this->auth->authenticate();
0 ignored issues
show
Bug introduced by
The method authenticate() does not seem to exist on object<Illuminate\Contracts\Auth\Factory>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
114
        }
115
116
        foreach ($guards as $guard) {
117
            if ($this->auth->guard($guard)->check()) {
118
                return $this->auth->shouldUse($guard);
119
            }
120
        }
121
122
        throw new AuthenticationException('Unauthenticated.', $guards);
123
    }
124
}
125