AccessTokenAuthenticator::getUser()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 1
Metric Value
c 1
b 0
f 1
dl 0
loc 4
rs 10
cc 1
eloc 2
nc 1
nop 2
1
<?php
2
3
namespace Majora\Bundle\OAuthServerBundle\Security;
4
5
use Majora\Component\OAuth\Exception\InvalidAccessTokenException;
6
use Majora\Component\OAuth\Server\Server as OAuthServer;
7
use Symfony\Component\HttpFoundation\JsonResponse;
8
use Symfony\Component\HttpFoundation\Request;
9
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
10
use Symfony\Component\Security\Core\Exception\AuthenticationException;
11
use Symfony\Component\Security\Core\User\UserInterface;
12
use Symfony\Component\Security\Core\User\UserProviderInterface;
13
use Symfony\Component\Security\Guard\AbstractGuardAuthenticator;
14
15
/**
16
 * AccessToken authenticator class using Guard Symfony component and OAuth server.
17
 *
18
 * @link https://knpuniversity.com/screencast/guard/api-token
19
 */
20
class AccessTokenAuthenticator extends AbstractGuardAuthenticator
21
{
22
    /**
23
     * @var OAuthServer
24
     */
25
    protected $oauthServer;
26
27
    /**
28
     * @var AccessTokenInterface
29
     */
30
    protected $currentAccessToken;
31
32
    /**
33
     * Construct.
34
     *
35
     * @param OAuthServer $oauthServer
36
     */
37
    public function __construct(OAuthServer $oauthServer)
38
    {
39
        $this->oauthServer = $oauthServer;
40
    }
41
42
    /**
43
     * @see GuardAuthenticatorInterface::getCredentials()
44
     */
45
    public function getCredentials(Request $request)
46
    {
47
        switch (true) {
48
49
            // token through query params
50
            case $request->query->has('access_token') :
0 ignored issues
show
Coding Style introduced by
There must be no space before the colon in a CASE statement

As per the PSR-2 coding standard, there must not be a space in front of the colon in case statements.

switch ($selector) {
    case "A": //right
        doSomething();
        break;
    case "B" : //wrong
        doSomethingElse();
        break;
}

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
51
                $hash = $request->query->get('access_token');
52
            break;
53
54
            // token through headers
55
            case $request->headers->has('Authorization') :
0 ignored issues
show
Coding Style introduced by
There must be no space before the colon in a CASE statement

As per the PSR-2 coding standard, there must not be a space in front of the colon in case statements.

switch ($selector) {
    case "A": //right
        doSomething();
        break;
    case "B" : //wrong
        doSomethingElse();
        break;
}

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
56
                if (!preg_match('#^Bearer ([\w]+)$#', $request->headers->get('Authorization'), $matches)) {
57
                    break; // bad Authorization format
58
                }
59
60
                $hash = $matches[1];
61
            break;
62
63
            // otherwise auth failed
64
            default:
65
                return;
66
        }
67
68
        try {
69
            return $this->currentAccessToken = $this->oauthServer->check($hash);
0 ignored issues
show
Bug introduced by
The variable $hash does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
Documentation Bug introduced by
It seems like $this->oauthServer->check($hash) of type object<Majora\Component\...\Loader\TokenInterface> is incompatible with the declared type object<Majora\Bundle\OAu...y\AccessTokenInterface> of property $currentAccessToken.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
70
        } catch (InvalidAccessTokenException $e) {
71
            // log there
72
        }
73
    }
74
75
    /**
76
     * @see GuardAuthenticatorInterface::getUser()
77
     */
78
    public function getUser($accessToken, UserProviderInterface $userProvider)
79
    {
80
        return $accessToken->getAccount();
81
    }
82
83
    /**
84
     * @see GuardAuthenticatorInterface::checkCredentials()
85
     */
86
    public function checkCredentials($accessToken, UserInterface $user)
87
    {
88
        // test here if access token is valid (expiration date etc...)
89
        // or api limit isnt crossed
90
        // or anonymous allowed
91
        // etc...
92
93
        return true;
94
    }
95
96
    /**
97
     * @see GuardAuthenticatorInterface::onAuthenticationSuccess()
98
     */
99
    public function onAuthenticationSuccess(Request $request, TokenInterface $token, $providerKey)
100
    {
101
        $request->query->remove('access_token');
102
        $request->headers->remove('Authorization');
103
        $request->attributes->set('access_token', $this->currentAccessToken);
104
    }
105
106
    /**
107
     * @see GuardAuthenticatorInterface::onAuthenticationFailure()
108
     */
109
    public function onAuthenticationFailure(Request $request, AuthenticationException $exception)
110
    {
111
        return new JsonResponse(
112
            array('message' => 'OAuth authentication required.'),
113
            403
114
        );
115
    }
116
117
    /**
118
     * @see GuardAuthenticatorInterface::onAuthenticationFailure()
119
     */
120
    public function start(Request $request, AuthenticationException $authException = null)
121
    {
122
        return !$authException ? null : new JsonResponse(
123
            array('message' => 'Invalid OAuth credentials.'),
124
            401
125
        );
126
    }
127
128
    /**
129
     * @see GuardAuthenticatorInterface::supportsRememberMe()
130
     */
131
    public function supportsRememberMe()
132
    {
133
        return false;
134
    }
135
}
136