Config::configureAuth()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 7
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 2

Importance

Changes 0
Metric Value
cc 2
eloc 5
c 0
b 0
f 0
nc 2
nop 0
dl 0
loc 7
ccs 5
cts 5
cp 1
crap 2
rs 10
1
<?php
2
3
namespace CybozuHttp;
4
5
use CybozuHttp\Exception\NotExistRequiredException;
6
use CybozuHttp\Middleware\FinishMiddleware;
7
use GuzzleHttp\HandlerStack;
8
9
/**
10
 * @author ochi51 <[email protected]>
11
 */
12
class Config
13
{
14
15
    /**
16
     * @var array $config
17
     */
18
    private $config;
19
20
    /**
21
     * @var array $default
22
     */
23
    private static $default = [
24
        'domain' => 'cybozu.com',
25
        'use_api_token' => false,
26
        'use_basic' => false,
27
        'use_client_cert' => false,
28
        'base_uri' => null,
29
        'concurrency' => 1,
30
        'response_middleware' => true,
31
        'debug' => false
32
    ];
33
34
    /**
35
     * @var array $required
36
     */
37
    private static $required = [
38
        'handler',
39
        'domain',
40
        'subdomain',
41
        'use_api_token',
42
        'use_basic',
43
        'use_client_cert',
44
        'base_uri',
45
        'debug'
46
    ];
47
48
    /**
49
     * Config constructor.
50
     * @param array $config
51
     */
52 11
    public function __construct(array $config)
53
    {
54 11
        $this->config = array_merge(self::$default, $config);
55
56 11
        $this->config['base_uri'] = $this->getBaseUri();
57 11
        $this->config['handler'] = $handler = $config['handler'] ?? HandlerStack::create();
58
59 11
        $this->configureAuth();
60 11
        $this->configureBasicAuth();
61 11
        $this->configureCert();
62
63 11
        if ($this->config['response_middleware']) {
64 11
            $handler->before('http_errors', new FinishMiddleware(), 'cybozu_http.finish');
65
        }
66
    }
67
68
69 11
    private function configureAuth(): void
70
    {
71 11
        if ($this->get('use_api_token')) {
72 2
            $this->config['headers']['X-Cybozu-API-Token'] = $this->get('token');
73
        } else {
74 11
            $this->config['headers']['X-Cybozu-Authorization'] =
75 11
                base64_encode($this->get('login') . ':' . $this->get('password'));
76
        }
77
    }
78
79 11
    private function configureBasicAuth(): void
80
    {
81 11
        if ($this->get('use_basic')) {
82 5
            $this->config['auth'] = $this->getBasicAuthOptions();
83
        }
84
    }
85
86 11
    private function configureCert(): void
87
    {
88 11
        if ($this->get('use_client_cert')) {
89 4
            $this->config['verify'] = true;
90 4
            $this->config['cert'] = $this->getCertOptions();
91
        } else {
92 8
            $this->config['verify'] = false;
93
        }
94
    }
95
96
    /**
97
     * @return array
98
     * @throws NotExistRequiredException
99
     */
100 5
    private function getBasicAuthOptions(): array
101
    {
102 5
        if ($this->hasRequiredOnBasicAuth()) {
103 5
            return [
104 5
                $this->get('basic_login'),
105 5
                $this->get('basic_password')
106 5
            ];
107
        }
108 1
        throw new NotExistRequiredException('kintone.empty_basic_password');
109
    }
110
111
    /**
112
     * @return array
113
     * @throws NotExistRequiredException
114
     */
115 4
    private function getCertOptions(): array
116
    {
117 4
        if ($this->hasRequiredOnCert()) {
118 4
            return [
119 4
                $this->get('cert_file'),
120 4
                $this->get('cert_password')
121 4
            ];
122
        }
123 1
        throw new NotExistRequiredException('kintone.empty_cert');
124
    }
125
126
    /**
127
     * @return array
128
     */
129 4
    public function toGuzzleConfig(): array
130
    {
131 4
        $config = [
132 4
            'handler' => $this->get('handler'),
133 4
            'base_uri' => $this->get('base_uri'),
134 4
            'headers' => $this->get('headers'),
135 4
            'debug' => $this->get('debug') ? fopen($this->get('logfile'), 'ab') : false,
0 ignored issues
show
Bug introduced by
It seems like $this->get('logfile') can also be of type boolean; however, parameter $filename of fopen() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

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

135
            'debug' => $this->get('debug') ? fopen(/** @scrutinizer ignore-type */ $this->get('logfile'), 'ab') : false,
Loading history...
136 4
            'concurrency' => $this->get('concurrency'),
137 4
            'timeout' => $this->get('timeout')
138 4
        ];
139 4
        if ($this->get('auth')) {
140 3
            $config['auth'] = $this->get('auth');
141
        }
142 4
        $config['verify'] = $this->get('verify');
143 4
        if ($this->get('cert')) {
144 1
            $config['cert'] = $this->get('cert');
145
        }
146
147 4
        return $config;
148
    }
149
150
    /**
151
     * @param $key
152
     * @return string|bool
153
     */
154 11
    public function get($key)
155
    {
156 11
        return $this->config[$key] ?? false;
157
    }
158
159
    /**
160
     * @return array
161
     */
162 1
    public function getConfig(): array
163
    {
164 1
        return $this->config;
165
    }
166
167
    /**
168
     * @return bool
169
     */
170 4
    public function hasRequired(): bool
171
    {
172 4
        foreach (self::$required as $r) {
173 4
            if (!array_key_exists($r, $this->config)) {
174 1
                return false;
175
            }
176
        }
177
178 4
        return $this->hasRequiredOnAuth()
179 4
                && $this->hasRequiredOnBasicAuth()
180 4
                && $this->hasRequiredOnCert();
181
    }
182
183
    /**
184
     * @return bool
185
     */
186 4
    private function hasRequiredOnAuth(): bool
187
    {
188 4
        if ($this->get('use_api_token')) {
189 1
            return !empty($this->get('token'));
190
        }
191
192 4
        return $this->get('login') && $this->get('password');
193
    }
194
195
    /**
196
     * @return bool
197
     */
198 7
    private function hasRequiredOnBasicAuth(): bool
199
    {
200 7
        return $this->hasKeysByUse('use_basic', ['basic_login', 'basic_password']);
201
    }
202
203
    /**
204
     * @return bool
205
     */
206 8
    private function hasRequiredOnCert(): bool
207
    {
208 8
        return $this->hasKeysByUse('use_client_cert', ['cert_file', 'cert_password']);
209
    }
210
211
    /**
212
     * @param string $use
213
     * @param string[] $keys
214
     * @return bool
215
     */
216 9
    private function hasKeysByUse($use, array $keys): bool
217
    {
218 9
        if (!$this->get($use)) {
219 4
            return true;
220
        }
221
222 7
        foreach ($keys as $key) {
223 7
            if (!$this->get($key)) {
224 2
                return false;
225
            }
226
        }
227
228 7
        return true;
229
    }
230
231
    /**
232
     * @return string
233
     */
234 11
    public function getBaseUri(): string
235
    {
236 11
        $subdomain = $this->get('subdomain');
237 11
        $uri = 'https://'. $subdomain;
238
239 11
        if (strpos($subdomain, '.') === false) {
0 ignored issues
show
Bug introduced by
It seems like $subdomain can also be of type boolean; however, parameter $haystack of strpos() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

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

239
        if (strpos(/** @scrutinizer ignore-type */ $subdomain, '.') === false) {
Loading history...
240 11
            if ($this->get('use_client_cert')) {
241 4
                $uri .= '.s';
242
            }
243
244 11
            $uri .= '.'. $this->get('domain');
245
        }
246
247 11
        return $uri;
248
    }
249
}
250