Passed
Push — main ( a27a58...542219 )
by Peter
04:05
created

Credentials::setOptions()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 2
nc 1
nop 1
dl 0
loc 5
ccs 3
cts 3
cp 1
crap 1
rs 10
c 0
b 0
f 0
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
            return $httpClient->withToken($this->token, $options->authType);
119
        }
120 6
        if ($options->authType === self::AUTH_TYPE_BASIC) {
121 6
            if (! $this->clientId || ! $this->clientSecret) {
122
                throw new InvalidArgumentException('Basic auth requires client id and client secret. Check documentation/readme. ');
123
            }
124
125 6
            return $httpClient->withBasicAuth($this->clientId, $this->clientSecret);
126
        }
127
        if ($options->authType === self::AUTH_TYPE_QUERY && $this->token) {
128
            return $httpClient->withQueryParameters([
129
                $options->tokenName => $this->token,
130
            ]);
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