Passed
Push — develop ( fe7945...054886 )
by nguereza
01:49
created

AuthorizationGrant   A

Complexity

Total Complexity 7

Size/Duplication

Total Lines 104
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 23
c 1
b 0
f 0
dl 0
loc 104
rs 10
wmc 7

5 Methods

Rating   Name   Duplication   Size   Complexity  
A createTokenResponse() 0 5 1
A allowPublicClients() 0 3 1
A __construct() 0 8 1
A setAuthorizationServer() 0 3 1
A createAuthorizationResponse() 0 30 3
1
<?php
2
3
/**
4
 * Platine OAuth2
5
 *
6
 * Platine OAuth2 is a library that implements the OAuth2 specification
7
 *
8
 * This content is released under the MIT License (MIT)
9
 *
10
 * Copyright (c) 2020 Platine OAuth2
11
 *
12
 * Permission is hereby granted, free of charge, to any person obtaining a copy
13
 * of this software and associated documentation files (the "Software"), to deal
14
 * in the Software without restriction, including without limitation the rights
15
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
16
 * copies of the Software, and to permit persons to whom the Software is
17
 * furnished to do so, subject to the following conditions:
18
 *
19
 * The above copyright notice and this permission notice shall be included in all
20
 * copies or substantial portions of the Software.
21
 *
22
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
23
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
25
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
26
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
27
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
28
 * SOFTWARE.
29
 */
30
31
declare(strict_types=1);
32
33
namespace Platine\OAuth2\Grant;
34
35
use Platine\Http\ResponseInterface;
36
use Platine\Http\ServerRequestInterface;
37
use Platine\OAuth2\AuthorizationServerInterface;
38
use Platine\OAuth2\Entity\Client;
39
use Platine\OAuth2\Entity\TokenOwnerInterface;
40
use Platine\OAuth2\Exception\OAuth2Exception;
41
use Platine\OAuth2\Service\AccessTokenService;
42
use Platine\OAuth2\Service\AuthorizationCodeService;
43
use Platine\OAuth2\Service\RefreshTokenService;
44
45
/**
46
 * @class AuthorizationGrant
47
 * @package Platine\OAuth2\Grant
48
 */
49
class AuthorizationGrant extends BaseGrant implements AuthorizationServerAwareInterface
50
{
51
    public const GRANT_TYPE = 'authorization_code';
52
    public const GRANT_RESPONSE_TYPE = 'code';
53
54
    /**
55
     * The AuthorizationCodeService
56
     * @var AuthorizationCodeService
57
     */
58
    protected AuthorizationCodeService $authorizationCodeService;
59
60
    /**
61
     * The AccessTokenService
62
     * @var AccessTokenService
63
     */
64
    protected AccessTokenService $accessTokenService;
65
66
    /**
67
     * The RefreshTokenService
68
     * @var RefreshTokenService
69
     */
70
    protected RefreshTokenService $refreshTokenService;
71
72
    /**
73
     * The authorization server instance
74
     * @var AuthorizationServerInterface|null
75
     */
76
    protected ?AuthorizationServerInterface $authorizationServer = null;
77
78
    /**
79
     * Create new instance
80
     * @param AuthorizationCodeService $authorizationCodeService
81
     * @param AccessTokenService $accessTokenService
82
     * @param RefreshTokenService $refreshTokenService
83
     */
84
    public function __construct(
85
        AuthorizationCodeService $authorizationCodeService,
86
        AccessTokenService $accessTokenService,
87
        RefreshTokenService $refreshTokenService
88
    ) {
89
        $this->authorizationCodeService = $authorizationCodeService;
90
        $this->accessTokenService = $accessTokenService;
91
        $this->refreshTokenService = $refreshTokenService;
92
    }
93
94
        /**
95
     * {@inheritdoc}
96
     */
97
    public function createAuthorizationResponse(
98
        ServerRequestInterface $request,
99
        Client $client,
100
        ?TokenOwnerInterface $owner = null
101
    ): ResponseInterface {
102
        $queryParams = $request->getQueryParams();
103
104
        // We must validate some parameters first
105
        $responseType = $queryParams['response_type'] ?? null;
106
        if ($responseType !== self::GRANT_RESPONSE_TYPE) {
107
            throw OAuth2Exception::invalidRequest(sprintf(
108
                'The desired grant type must be "code", but "%s" was given',
109
                $responseType
110
            ));
111
        }
112
113
        // We try to fetch the redirect URI from query param as per spec,
114
        // and if none found, we just use the first redirect URI defined in the client
115
        $clientRedirectUris = $client->getRedirectUris();
116
        $redirectUri = $queryParams['redirect_uri'] ?? $clientRedirectUris[0];
117
118
        // If the redirect URI cannot be found in the list, we throw an error
119
        // as we don't want the user to be redirected to an unauthorized URL
120
        if ($client->hasRedirectUri($redirectUri) === false) {
121
            throw OAuth2Exception::invalidRequest('Redirect URI does not match the client registered one');
122
        }
123
124
        // Scope and state allow to perform additional validation
125
        $scope = $queryParams['scope'] ?? null;
0 ignored issues
show
Unused Code introduced by
The assignment to $scope is dead and can be removed.
Loading history...
126
        $state = $queryParams['state'] ?? null;
0 ignored issues
show
Bug Best Practice introduced by
In this branch, the function will implicitly return null which is incompatible with the type-hinted return Platine\Http\ResponseInterface. Consider adding a return statement or allowing null as return value.

For hinted functions/methods where all return statements with the correct type are only reachable via conditions, ?null? gets implicitly returned which may be incompatible with the hinted type. Let?s take a look at an example:

interface ReturnsInt {
    public function returnsIntHinted(): int;
}

class MyClass implements ReturnsInt {
    public function returnsIntHinted(): int
    {
        if (foo()) {
            return 123;
        }
        // here: null is implicitly returned
    }
}
Loading history...
Unused Code introduced by
The assignment to $state is dead and can be removed.
Loading history...
127
    }
128
129
    /**
130
     * {@inheritdoc}
131
     */
132
    public function createTokenResponse(
133
        ServerRequestInterface $request,
134
        ?Client $client = null,
135
        ?TokenOwnerInterface $owner = null
136
    ): ResponseInterface {
137
    }
0 ignored issues
show
Bug Best Practice introduced by
In this branch, the function will implicitly return null which is incompatible with the type-hinted return Platine\Http\ResponseInterface. Consider adding a return statement or allowing null as return value.

For hinted functions/methods where all return statements with the correct type are only reachable via conditions, ?null? gets implicitly returned which may be incompatible with the hinted type. Let?s take a look at an example:

interface ReturnsInt {
    public function returnsIntHinted(): int;
}

class MyClass implements ReturnsInt {
    public function returnsIntHinted(): int
    {
        if (foo()) {
            return 123;
        }
        // here: null is implicitly returned
    }
}
Loading history...
138
139
    /**
140
     * {@inheritdoc}
141
     */
142
    public function setAuthorizationServer(
143
        AuthorizationServerInterface $authorizationServer
144
    ): void {
145
    }
146
147
    /**
148
     * {@inheritdoc}
149
     */
150
    public function allowPublicClients(): bool
151
    {
152
        return true;
153
    }
154
}
155