Completed
Pull Request — master (#774)
by
unknown
12:17
created

TokenGrant::getVerifyCredentialsCallback()   A

Complexity

Conditions 3
Paths 2

Size

Total Lines 8
Code Lines 4

Duplication

Lines 8
Ratio 100 %

Importance

Changes 0
Metric Value
dl 8
loc 8
rs 9.4285
c 0
b 0
f 0
cc 3
eloc 4
nc 2
nop 0
1
<?php
2
/**
3
 * OAuth 2.0 Password grant
4
 *
5
 * @package     league/oauth2-server
6
 * @author      Alex Bilbie <[email protected]>
7
 * @copyright   Copyright (c) Alex Bilbie
8
 * @license     http://mit-license.org/
9
 * @link        https://github.com/thephpleague/oauth2-server
10
 */
11
12
namespace LucaDegasperi\OAuth2Server\Grant;
13
14
use League\OAuth2\Server\Entity\AccessTokenEntity;
15
use League\OAuth2\Server\Entity\ClientEntity;
16
use League\OAuth2\Server\Entity\RefreshTokenEntity;
17
use League\OAuth2\Server\Entity\SessionEntity;
18
use League\OAuth2\Server\Event;
19
use League\OAuth2\Server\Exception;
20
use League\OAuth2\Server\Util\SecureKey;
21
use League\OAuth2\Server\ResourceServer;
22
use League\OAuth2\Server\Grant\AbstractGrant;
23
24
/**
25
 * Password grant class
26
 */
27
class TokenGrant extends AbstractGrant
28
{
29
    /**
30
     * The access token
31
     *
32
     * @var \League\OAuth2\Server\Entity\AccessTokenEntity
33
     */
34
    protected $accessToken;
35
36
    /**
37
     * The resource server (aka the checker).
38
     *
39
     * @var \League\OAuth2\Server\ResourceServer
40
     */
41
    protected $checker;
42
43
    /**
44
     * Grant identifier
45
     *
46
     * @var string
47
     */
48
    protected $identifier = 'password';
49
50
    /**
51
     * Response type
52
     *
53
     * @var string
54
     */
55
    protected $responseType;
56
57
    /**
58
     * Callback to authenticate a user's name and password
59
     *
60
     * @var callable
61
     */
62
    protected $callback;
63
64
    /**
65
     * Access token expires in override
66
     *
67
     * @var int
68
     */
69
    protected $accessTokenTTL;
70
71
    /**
72
     * Set the callback to verify a user's username and password
73
     *
74
     * @param callable $callback The callback function
75
     *
76
     * @return void
77
     */
78
    public function setVerifyCredentialsCallback(callable $callback)
79
    {
80
        $this->callback = $callback;
81
    }
82
83
    /**
84
     * Return the callback function
85
     *
86
     * @return callable
87
     *
88
     * @throws
89
     */
90 View Code Duplication
    protected function getVerifyCredentialsCallback()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
91
    {
92
        if (is_null($this->callback) || !is_callable($this->callback)) {
93
            throw new Exception\ServerErrorException('Null or non-callable callback set on Password grant');
94
        }
95
96
        return $this->callback;
97
    }
98
99
    /**
100
     * Complete the password grant
101
     *
102
     * @return array
103
     *
104
     * @throws
105
     */
106
    public function completeFlow()
107
    {
108
        // Get the required params
109
        $clientId = $this->server->getRequest()->request->get('client_id', $this->server->getRequest()->getUser());
110
        if (is_null($clientId)) {
111
            throw new Exception\InvalidRequestException('client_id');
112
        }
113
114
        $clientSecret = $this->server->getRequest()->request->get('client_secret',
115
            $this->server->getRequest()->getPassword());
116
        if (is_null($clientSecret)) {
117
            throw new Exception\InvalidRequestException('client_secret');
118
        }
119
120
        // Validate client ID and client secret
121
        $client = $this->server->getClientStorage()->get(
122
            $clientId,
123
            $clientSecret,
124
            null,
125
            $this->getIdentifier()
126
        );
127
128 View Code Duplication
        if (($client instanceof ClientEntity) === false) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
129
            $this->server->getEventEmitter()->emit(new Event\ClientAuthenticationFailedEvent($this->server->getRequest()));
0 ignored issues
show
Coding Style introduced by
This line exceeds maximum limit of 120 characters; contains 123 characters

Overly long lines are hard to read on any screen. Most code styles therefor impose a maximum limit on the number of characters in a line.

Loading history...
130
            throw new Exception\InvalidClientException();
131
        }
132
133
        $access_token = $this->server->getRequest()->headers->get('authorization',null);
134
        if ($access_token === null) {
135
            throw new Exception\AccessDeniedException();
136
        }
137
138
        $bearerToken = str_replace( 'Bearer ','',$access_token );
139
140
        // Set the access token
141
        $this->accessToken = $this->server->getAccessTokenStorage()->get($bearerToken);
142
143
        // Ensure the access token exists
144
        if (!$this->accessToken instanceof AccessTokenEntity) {
145
            throw new Exception\AccessDeniedException();
146
        }
147
        
148
        // Check the access token hasn't expired
149
        // Ensure the auth code hasn't expired
150
        if ($this->accessToken->isExpired() === true) {
151
            throw new Exception\AccessDeniedException();
152
        }
153
154
        // Get the scopes for the original session
155
        $session = $this->accessToken->getSession();
156
        $scopes = $this->formatScopes($session->getScopes());
0 ignored issues
show
Bug introduced by
It seems like $session->getScopes() targeting League\OAuth2\Server\Ent...sionEntity::getScopes() can also be of type object<Symfony\Component...oundation\ParameterBag>; however, League\OAuth2\Server\Gra...ctGrant::formatScopes() does only seem to accept array, maybe add an additional type check?

This check looks at variables that are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
157
158
        // Get and validate any requested scopes
159
        $requestedScopesString = $this->server->getRequest()->request->get('scope', '');
160
        $requestedScopes = $this->validateScopes($requestedScopesString, $client);
0 ignored issues
show
Unused Code introduced by
$requestedScopes is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
161
162
        // Generate a new access token and assign it the correct sessions
163
        $newAccessToken = new AccessTokenEntity($this->server);
164
        $newAccessToken->setId(SecureKey::generate());
165
        $newAccessToken->setExpireTime($this->getAccessTokenTTL() + time());
166
        $newAccessToken->setSession($session);
167
168
        foreach ($scopes as $newScope) {
169
            $newAccessToken->associateScope($newScope);
170
        }
171
172
        $newAccessToken->save();
173
174
        $this->server->getTokenType()->setSession($session);
175
        $this->server->getTokenType()->setParam('access_token', $newAccessToken->getId());
176
        $this->server->getTokenType()->setParam('expires_in', $this->getAccessTokenTTL());
177
178
        return $this->server->getTokenType()->generateResponse();
179
    }
180
}
181