Passed
Push — main ( 542219...09815c )
by Peter
05:44 queued 01:48
created

Credentials::addAuthToRequest()   B

Complexity

Conditions 10
Paths 8

Size

Total Lines 29
Code Lines 16

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 11
CRAP Score 15.8818

Importance

Changes 2
Bugs 0 Features 0
Metric Value
cc 10
eloc 16
c 2
b 0
f 0
nc 8
nop 2
dl 0
loc 29
ccs 11
cts 18
cp 0.6111
crap 15.8818
rs 7.6666

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 13
    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 13
        if (! empty($credentials)) {
45 10
            $this->parseCredentialsArray($credentials);
46
        }
47
48 12
        $this->validate();
49
    }
50
51
    /**
52
     * @return array<string, string>
53
     */
54 12
    public function toArray(): array
55
    {
56 12
        return get_object_vars($this);
57
    }
58
59 12
    protected function validate(): void
60
    {
61 12
        Validator::make($this->toArray(), [
62 12
            'token'          => 'required_without_all:clientId,clientSecret,customCallback|string|nullable',
63 12
            'clientId'       => 'required_with:clientSecret|string|nullable',
64 12
            'clientSecret'   => 'required_with:clientId|string|nullable',
65 12
            'customCallback' => 'required_without_all:token,clientId,clientSecret|nullable',
66 12
        ])->validate();
67
    }
68
69 4
    public function setOptions(Options $options): self
70
    {
71 4
        $this->options = $options;
72
73 4
        return $this;
74
    }
75
76
    /**
77
     * @param  string|array<string, mixed>|callable  $credentials
78
     */
79 10
    public function parseCredentialsArray(string|array|callable $credentials): void
80
    {
81 10
        if (is_string($credentials)) {
0 ignored issues
show
introduced by
The condition is_string($credentials) is always false.
Loading history...
82 1
            $this->setRefreshToken($credentials);
83
84 1
            return;
85
        }
86
87 9
        if (is_callable($credentials)) {
88
            //$this->authType       = self::AUTH_TYPE_CUSTOM;
89 1
            $this->customCallback = $credentials(...);
90
91 1
            return;
92
        }
93
94 8
        $credentials = array_filter($credentials);
95 8
        $arrayLength = count($credentials);
96
97 8
        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 8
            match ($arrayLength) {
99 1
                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 6
                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 1
                default => throw new InvalidArgumentException('Invalid credentials. Check documentation/readme. '),
102 8
            };
103
104 7
            return;
105
        }
106
    }
107
108 12
    public function addAuthToRequest(PendingRequest $httpClient, Options $options): PendingRequest
109
    {
110 12
        if ($options->authType === self::AUTH_TYPE_BODY) {
111 3
            return $httpClient;
112
        }
113 9
        if (is_callable($this->customCallback)) {
114 1
            return ($this->customCallback)($httpClient);
115
116
        }
117 8
        if ($this->token) {
118 2
            if ($options->authType === self::AUTH_TYPE_QUERY) {
119
                return $httpClient->withQueryParameters([
120
                    $options->tokenName => $this->token,
121
                ]);
122
            }
123 2
            return $httpClient->withToken($this->token, $options->authType);
124
        }
125 6
        if ($options->authType === self::AUTH_TYPE_BASIC) {
126 6
            if (! $this->clientId || ! $this->clientSecret) {
127
                throw new InvalidArgumentException('Basic auth requires client id and client secret. Check documentation/readme. ');
128
            }
129
130 6
            return $httpClient->withBasicAuth($this->clientId, $this->clientSecret);
131
        }
132
        if ($options->authType === self::AUTH_TYPE_CUSTOM && is_callable($this->customCallback)) {
133
            return ($this->customCallback)($httpClient);
134
        }
135
136
        return $httpClient;
137
    }
138
139
    /**
140
     * @param  array<string, string>  $requestBody
141
     * @return array<string, string>
142
     */
143 12
    public function addAuthToBody(array $requestBody, Options $options): array
144
    {
145 12
        if ($options->authType !== self::AUTH_TYPE_BODY) {
146 9
            return $requestBody;
147
        }
148 3
        if ($this->clientId && $this->clientSecret) {
149 2
            return $requestBody + ['client_id' => $this->clientId, 'client_secret' => $this->clientSecret];
150
        }
151 1
        if ($this->token) {
152 1
            return $requestBody + [$options->tokenName => $this->token];
153
        }
154
155
        throw new InvalidArgumentException('Invalid credentials. Check documentation/readme.');
156
    }
157
158 2
    public function setRefreshToken(string $token): void
159
    {
160 2
        $this->token = $token;
161 2
        if (empty($this->options->authType)) {
162
            //$this->options->authType = self::AUTH_TYPE_BEARER;
163
        }
164
    }
165
166 6
    public function setClientCredentialsPair(string $clientId, string $clientSecret): void
167
    {
168 6
        $this->clientId     = $clientId;
169 6
        $this->clientSecret = $clientSecret;
170
171
        /*
172
        if ($tokenType) {
173
            //$this->options->authType = $tokenType;
174
        }
175
176
        if (empty($this->authType)) {
177
            $this->options->authType = self::AUTH_TYPE_BASIC;
178
        }
179
        */
180
    }
181
}
182