OAuthServerTrait   A
last analyzed

Complexity

Total Complexity 17

Size/Duplication

Total Lines 111
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 1

Test Coverage

Coverage 100%

Importance

Changes 0
Metric Value
wmc 17
lcom 1
cbo 1
dl 0
loc 111
ccs 30
cts 30
cp 1
rs 10
c 0
b 0
f 0

7 Methods

Rating   Name   Duplication   Size   Complexity  
A isInputUriOptional() 0 4 1
A setInputUriOptional() 0 4 1
A setInputUriMandatory() 0 4 1
A getResponseType() 0 4 2
A getGrantType() 0 4 2
A validateScope() 0 16 5
A selectValidRedirectUri() 0 21 5
1
<?php declare(strict_types=1);
2
3
namespace Limoncello\OAuthServer\ServerTraits;
4
5
/**
6
 * Copyright 2015-2019 [email protected]
7
 *
8
 * Licensed under the Apache License, Version 2.0 (the "License");
9
 * you may not use this file except in compliance with the License.
10
 * You may obtain a copy of the License at
11
 *
12
 * http://www.apache.org/licenses/LICENSE-2.0
13
 *
14
 * Unless required by applicable law or agreed to in writing, software
15
 * distributed under the License is distributed on an "AS IS" BASIS,
16
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17
 * See the License for the specific language governing permissions and
18
 * limitations under the License.
19
 */
20
21
use Limoncello\OAuthServer\Contracts\ClientInterface;
22
use function array_diff;
23
use function array_key_exists;
24
use function count;
25
use function in_array;
26
27
/**
28
 * @package Limoncello\OAuthServer
29
 */
30
trait OAuthServerTrait
31
{
32
    /**
33
     * If input redirect URI is optional (client default URI will be used if possible).
34
     *
35
     * @var bool
36 5
     */
37
    private $isInputUriOptional = true;
38 5
39
    /**
40
     * @return boolean
41
     */
42
    public function isInputUriOptional(): bool
43
    {
44 1
        return $this->isInputUriOptional;
45
    }
46 1
47
    /**
48
     * @return void
49
     */
50
    public function setInputUriOptional(): void
51
    {
52 1
        $this->isInputUriOptional = true;
53
    }
54 1
55
    /**
56
     * @return void
57
     */
58
    public function setInputUriMandatory(): void
59
    {
60
        $this->isInputUriOptional = false;
61
    }
62
63
    /**
64
     * @param string[] $parameters
65 15
     *
66
     * @return string|null
67 15
     *
68
     * @link https://tools.ietf.org/html/rfc6749#section-4.1.1
69
     * @link https://tools.ietf.org/html/rfc6749#section-4.2.1
70
     */
71
    protected function getResponseType(array $parameters): ?string
72
    {
73
        return array_key_exists('response_type', $parameters) === true ? $parameters['response_type'] : null;
74
    }
75
76
    /**
77
     * @param string[] $parameters
78
     *
79 28
     * @return string|null
80
     *
81 28
     * @link https://tools.ietf.org/html/rfc6749#section-4.1.3
82
     * @link https://tools.ietf.org/html/rfc6749#section-4.3.2
83
     * @link https://tools.ietf.org/html/rfc6749#section-4.4.2
84
     */
85
    protected function getGrantType(array $parameters): ?string
86
    {
87
        return array_key_exists('grant_type', $parameters) === true ? $parameters['grant_type'] : null;
88
    }
89
90 16
    /**
91
     * @param array|null           $scopes
92 16
     * @param ClientInterface|null $client
0 ignored issues
show
Documentation introduced by
Consider making the type for parameter $client a bit more specific; maybe use ClientInterface.
Loading history...
93 7
     *
94 7
     * @return array [bool $isScopeValid, string[]|null $scopeList, bool $isScopeModified]
95
     */
96 7
    protected function validateScope(ClientInterface $client, array $scopes = null): array
97 7
    {
98
        if (empty($scopes) === true) {
99
            $clientScopes = $client->getScopeIdentifiers();
100 9
            $isModified   = $clientScopes !== $scopes;
101 9
102 9
            return $client->isUseDefaultScopesOnEmptyRequest() === true ?
103
                [true, $clientScopes, $isModified] : [false, $scopes, false];
104 9
        }
105
106
        $extraScopes    = array_diff($scopes, $client->getScopeIdentifiers());
107
        $hasExtraScopes = count($extraScopes) > 0;
108
        $isInvalidScope = $hasExtraScopes === true && $client->isScopeExcessAllowed() === false;
109
110
        return $isInvalidScope === true ? [false, $scopes, false] : [true, $scopes, false];
111
    }
112
113 15
    /**
114
     * @param ClientInterface $client
115 15
     * @param string|null     $redirectUri
116 15
     *
117 15
     * @return string|null
118
     */
119
    protected function selectValidRedirectUri(ClientInterface $client, string $redirectUri = null): ?string
120 5
    {
121 2
        $validUri = null;
122
        $uris     = $client->getRedirectUriStrings();
123
        if (empty($redirectUri) === true) {
124 5
            // if no redirect provided and it's optional we require client to have
125
            // exactly 1 redirect URI so we know where to redirect.
126
            if (($this->isInputUriOptional() === true && count($uris) === 1)) {
127
                $validUri = $uris[0];
128 12
            }
129 12
130
            return $validUri;
131
        }
132 12
133
        // check client has provided redirect URI
134
        if (in_array($redirectUri, $client->getRedirectUriStrings()) === true) {
135
            $validUri = $redirectUri;
136
        }
137
138
        return $validUri;
139
    }
140
}
141