Passed
Push — main ( 7e2218...a00e1e )
by Peter
04:13
created

Credentials::addAuthToRequest()   B

Complexity

Conditions 10
Paths 8

Size

Total Lines 30
Code Lines 16

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 14
CRAP Score 11.097

Importance

Changes 2
Bugs 0 Features 0
Metric Value
cc 10
eloc 16
nc 8
nop 2
dl 0
loc 30
ccs 14
cts 18
cp 0.7778
crap 11.097
rs 7.6666
c 2
b 0
f 0

How to fix   Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
namespace Pelmered\LaravelHttpOAuthHelper;
4
5
use Closure;
6
use Illuminate\Http\Client\PendingRequest;
7
use Illuminate\Support\Facades\Validator;
8
use InvalidArgumentException;
9
10
class Credentials
11
{
12
    public const AUTH_TYPE_BODY = 'body';
13
14
    public const AUTH_TYPE_QUERY = 'query';
15
16
    public const AUTH_TYPE_BASIC = 'basic';
17
18
    public const AUTH_TYPE_BEARER = 'Bearer';
19
20
    public const AUTH_TYPE_CUSTOM = 'custom';
21
22
    public const GRANT_TYPE_CLIENT_CREDENTIALS = 'client_credentials';
23
24
    public const GRANT_TYPE_PASSWORD_CREDENTIALS = 'password_credentials';
25
26
    //TODO: Add support for authorization_code and implicit grants
27
    public const GRANT_TYPE_AUTHORIZATION_CODE = 'authorization_code';
28
29
    public const GRANT_TYPE_IMPLICIT = 'implicit';
30
31
    private ?Closure $customCallback = null;
32
33
    protected ?Options $options;
34
35
    /**
36
     * @param  array<string, mixed>  $credentials
37
     */
38 21
    public function __construct(
39
        string|array|callable $credentials = [],
40
        protected ?string $token = null,
41
        protected ?string $clientId = null,
42
        protected ?string $clientSecret = null,
43
    ) {
44 21
        if (! empty($credentials)) {
45 17
            $this->parseCredentialsArray($credentials);
46
        }
47
48 19
        $this->validate();
49
    }
50
51
    /**
52
     * @return array<string, string>
53
     */
54 19
    public function toArray(): array
55
    {
56 19
        return get_object_vars($this);
57
    }
58
59 19
    protected function validate(): void
60
    {
61 19
        Validator::make($this->toArray(), [
62 19
            'token'          => 'required_without_all:clientId,clientSecret,customCallback|string|nullable',
63 19
            'clientId'       => 'required_with:clientSecret|string|nullable',
64 19
            'clientSecret'   => 'required_with:clientId|string|nullable',
65 19
            'customCallback' => 'required_without_all:token,clientId,clientSecret|nullable',
66 19
        ])->validate();
67
    }
68
69 5
    public function setOptions(Options $options): self
70
    {
71 5
        $this->options = $options;
72
73 5
        return $this;
74
    }
75
76
    /**
77
     * @param  string|array<string, mixed>|callable  $credentials
78
     */
79 17
    public function parseCredentialsArray(string|array|callable $credentials): void
80
    {
81 17
        if (is_string($credentials)) {
0 ignored issues
show
introduced by
The condition is_string($credentials) is always false.
Loading history...
82 2
            $this->setRefreshToken($credentials);
83
84 2
            return;
85
        }
86
87 15
        if (is_callable($credentials)) {
88
            //$this->authType       = self::AUTH_TYPE_CUSTOM;
89 2
            $this->customCallback = $credentials(...);
90
91 2
            return;
92
        }
93
94 13
        $credentials = array_filter($credentials);
95 13
        $arrayLength = count($credentials);
96
97 13
        if ($arrayLength > 0 && array_is_list($credentials)) {
0 ignored issues
show
Bug introduced by
The function array_is_list was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

97
        if ($arrayLength > 0 && /** @scrutinizer ignore-call */ array_is_list($credentials)) {
Loading history...
98 13
            match ($arrayLength) {
99 4
                1       => $this->setRefreshToken($credentials[0]),
0 ignored issues
show
Bug introduced by
Are you sure the usage of $this->setRefreshToken($credentials[0]) targeting Pelmered\LaravelHttpOAut...ials::setRefreshToken() seems to always return null.

This check looks for function or method calls that always return null and whose return value is used.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
if ($a->getObject()) {

The method getObject() can return nothing but null, so it makes no sense to use the return value.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
100 7
                2       => $this->setClientCredentialsPair($credentials[0], $credentials[1]),
0 ignored issues
show
Bug introduced by
Are you sure the usage of $this->setClientCredenti...ls[0], $credentials[1]) targeting Pelmered\LaravelHttpOAut...ClientCredentialsPair() seems to always return null.

This check looks for function or method calls that always return null and whose return value is used.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
if ($a->getObject()) {

The method getObject() can return nothing but null, so it makes no sense to use the return value.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
101 2
                default => throw new InvalidArgumentException('Invalid credentials. Check documentation/readme.'),
102 13
            };
103
104 11
            return;
105
        }
106
    }
107
108 18
    public function addAuthToRequest(PendingRequest $httpClient, Options $options): PendingRequest
109
    {
110 18
        if ($options->authType === self::AUTH_TYPE_BODY) {
111 3
            return $httpClient;
112
        }
113 15
        if (is_callable($this->customCallback)) {
114 2
            return ($this->customCallback)($httpClient);
115
116
        }
117 13
        if ($this->token) {
118 6
            if ($options->authType === self::AUTH_TYPE_QUERY) {
119 1
                return $httpClient->withQueryParameters([
120 1
                    $options->tokenName => $this->token,
121 1
                ]);
122
            }
123
124 5
            return $httpClient->withToken($this->token, $options->authType);
125
        }
126 7
        if ($options->authType === self::AUTH_TYPE_BASIC) {
127 7
            if (! $this->clientId || ! $this->clientSecret) {
128
                throw new InvalidArgumentException('Basic auth requires client id and client secret. Check documentation/readme. ');
129
            }
130
131 7
            return $httpClient->withBasicAuth($this->clientId, $this->clientSecret);
132
        }
133
        if ($options->authType === self::AUTH_TYPE_CUSTOM && is_callable($this->customCallback)) {
134
            return ($this->customCallback)($httpClient);
135
        }
136
137
        return $httpClient;
138
    }
139
140
    /**
141
     * @param  array<string, string>  $requestBody
142
     * @return array<string, string>
143
     */
144 18
    public function addAuthToBody(array $requestBody, Options $options): array
145
    {
146 18
        if ($options->authType !== self::AUTH_TYPE_BODY) {
147 15
            return $requestBody;
148
        }
149 3
        if ($this->clientId && $this->clientSecret) {
150 2
            return $requestBody + ['client_id' => $this->clientId, 'client_secret' => $this->clientSecret];
151
        }
152 1
        if ($this->token) {
153 1
            return $requestBody + [$options->tokenName => $this->token];
154
        }
155
156
        throw new InvalidArgumentException('Invalid credentials. Check documentation/readme.');
157
    }
158
159 6
    public function setRefreshToken(string $token): void
160
    {
161 6
        $this->token = $token;
162
        /*
163
        if (empty($this->options->authType)) {
164
            $this->options->authType = self::AUTH_TYPE_BEARER;
165
        }
166
        */
167
    }
168
169 7
    public function setClientCredentialsPair(string $clientId, string $clientSecret): void
170
    {
171 7
        $this->clientId     = $clientId;
172 7
        $this->clientSecret = $clientSecret;
173
174
        /*
175
        if ($tokenType) {
176
            //$this->options->authType = $tokenType;
177
        }
178
179
        if (empty($this->authType)) {
180
            $this->options->authType = self::AUTH_TYPE_BASIC;
181
        }
182
        */
183
    }
184
}
185