Completed
Push — master ( 1828f5...c85070 )
by Alex
03:11
created

ServiceClient.php (3 issues)

1
<?php
2
namespace Mezon\Service;
3
4
/**
5
 * Class ServiceClient
6
 *
7
 * @package Service
8
 * @subpackage ServiceClient
9
 * @author Dodonov A.A.
10
 * @version v.1.0 (2019/08/06)
11
 * @copyright Copyright (c) 2019, aeon.org
12
 */
13
14
/**
15
 * Service client for Service
16
 */
17
class ServiceClient extends \Mezon\CustomClient\CustomClient
18
{
19
20
    /**
21
     * Service name
22
     *
23
     * @var string
24
     */
25
    private $service = '';
26
27
    /**
28
     * Last logged in user
29
     * This is used for performance improvements in ServiceClient::loginAs method
30
     * For optimisation purposes only! Do not use in the client code
31
     *
32
     * @var string
33
     */
34
    private $login = false;
35
36
    /**
37
     * Rewrite mode.
38
     * If true, then URLs like this /part1/part2/param1/ will be used. If false, then parameter ?r=part1/part2/param1 will be passed
39
     *
40
     * @var string
41
     */
42
    private $rewriteMode = true;
43
44
    /**
45
     * Session id
46
     *
47
     * @var string
48
     */
49
    private $sessionId = false;
50
51
    /**
52
     * Constructor
53
     *
54
     * @param string $service
55
     *            Service URL or service name
56
     * @param string $login
57
     *            Login
58
     * @param string $password
59
     *            Password
60
     * @param array $headers
61
     *            Headers
62
     */
63
    public function __construct(string $service, string $login = '', string $password = '', array $headers = [])
64
    {
65
        if (\Mezon\DnsClient\DnsClient::serviceExists($service)) {
66
            $this->service = $service;
67
            parent::__construct(\Mezon\DnsClient\DnsClient::resolveHost($service), $headers);
68
        } elseif (strpos($service, 'http://') === false && strpos($service, 'https://') === false) {
69
            throw (new \Exception('Service ' . $service . ' was not found in DNS'));
70
        } else {
71
            parent::__construct($service, $headers);
72
        }
73
74
        if ($login !== '') {
75
            $this->connect($login, $password);
76
        }
77
    }
78
79
    /**
80
     * Method sends POST request to server
81
     *
82
     * @param string $endpoint
83
     *            Calling endpoint
84
     * @param array $data
85
     *            Request data
86
     * @return mixed Result of the request
87
     */
88
    public function sendPostRequest(string $endpoint, array $data = [])
89
    {
90
        $result = parent::sendPostRequest($endpoint, $data);
91
92
        return json_decode($result);
93
    }
94
95
    /**
96
     * Method sends GET request to server
97
     *
98
     * @param string $endpoint
99
     *            Calling endpoint
100
     * @return mixed Result of the remote call
101
     */
102
    public function sendGetRequest(string $endpoint)
103
    {
104
        $result = parent::sendGetRequest($endpoint);
105
106
        return json_decode($result);
107
    }
108
109
    /**
110
     * Method sends PUT request to server
111
     *
112
     * @param string $endpoint
113
     *            Calling endpoint
114
     * @param array $data
115
     *            Request data
116
     * @return mixed Result of the request
117
     */
118
    public function sendPutRequest(string $endpoint, array $data = [])
119
    {
120
        $result = parent::sendPutRequest($endpoint, $data);
121
122
        return json_decode($result);
123
    }
124
125
    /**
126
     * Method sends DELETE request to server
127
     *
128
     * @param string $endpoint
129
     *            Calling endpoint
130
     * @param array $data
131
     *            Request data
132
     * @return mixed Result of the remote call
133
     */
134
    public function sendDeleteRequest(string $endpoint, array $data = [])
135
    {
136
        $result = parent::sendDeleteRequest($endpoint, $data);
137
138
        return json_decode($result);
139
    }
140
141
    /**
142
     * Method validates result
143
     *
144
     * @param object $resultResult
145
     *            of the authorisation request
146
     */
147
    protected function validateSessionId(object $result)
148
    {
149
        if (isset($result->session_id) === false) {
150
            throw (new \Exception($result->message ?? 'Undefined message', $result->code ?? - 1));
151
        }
152
    }
153
154
    /**
155
     * Method connects to the REST server via login and password pair
156
     *
157
     * @param string $login
158
     *            Login
159
     * @param string $password
160
     *            Password
161
     */
162
    public function connect(string $login, string $password)
163
    {
164
        // authorization
165
        $data = [
166
            'login' => $login,
167
            'password' => $password
168
        ];
169
170
        $result = $this->sendPostRequest($this->getRequestUrl('connect'), $data);
171
172
        $this->validateSessionId($result);
173
174
        $this->login = $login;
175
        $this->sessionId = $result->session_id;
176
    }
177
178
    /**
179
     * Method sets token
180
     *
181
     * @param string $token
182
     *            Access token
183
     * @param string $login
184
     *            User login
185
     */
186
    public function setToken(string $token, string $login = '')
187
    {
188
        if ($token === '') {
189
            throw (new \Exception('Token not set', - 4));
190
        }
191
192
        $this->login = $login;
193
        $this->sessionId = $token;
194
    }
195
196
    /**
197
     * Method returns token
198
     *
199
     * @return string Session id
200
     */
201
    public function getToken(): string
202
    {
203
        return $this->sessionId;
204
    }
205
206
    /**
207
     * Method returns self id of the session
208
     *
209
     * @return string Session user's id
210
     */
211
    public function getSelfId(): string
212
    {
213
        $result = $this->sendGetRequest($this->getRequestUrl('selfId'));
214
215
        return isset($result->id) ? $result->id : $result;
216
    }
217
218
    /**
219
     * Method returns self login of the session
220
     *
221
     * @return string Session user's login
222
     */
223
    public function getSelfLogin(): string
224
    {
225
        $result = $this->sendGetRequest($this->getRequestUrl('selfLogin'));
226
227
        return isset($result->login) ? $result->login : $result;
228
    }
229
230
    /**
231
     * Method logins under another user
232
     * $field must be 'id' or 'login'
233
     *
234
     * @param string $user
235
     *            User credentials
236
     * @param string $field
237
     *            Field name for credentials
238
     */
239
    public function loginAs(string $user, string $field = 'id')
240
    {
241
        if ($field != 'id' && $this->login !== $user) {
242
            $result = $this->sendPostRequest($this->getRequestUrl('loginAs'), [
243
                $field => $user
244
            ]);
245
246
            $this->validateSessionId($result);
247
248
            $this->sessionId = $result->session_id;
249
        }
250
251
        if ($field == 'id') {
252
            $this->login = false;
0 ignored issues
show
Documentation Bug introduced by
The property $login was declared of type string, but false is of type false. Maybe add a type cast?

This check looks for assignments to scalar types that may be of the wrong type.

To ensure the code behaves as expected, it may be a good idea to add an explicit type cast.

$answer = 42;

$correct = false;

$correct = (bool) $answer;
Loading history...
253
        } else {
254
            $this->login = $user;
255
        }
256
    }
257
258
    /**
259
     * Method returns stored login
260
     *
261
     * @return string Stored login
262
     */
263
    public function getStoredLogin()
264
    {
265
        return $this->login;
266
    }
267
268
    /**
269
     * Method returns common headers
270
     *
271
     * @return array Headers
272
     */
273
    protected function getCommonHeaders(): array
274
    {
275
        $result = parent::getCommonHeaders();
276
277
        if ($this->sessionId !== false) {
278
            $result[] = "Authentication: Basic " . $this->sessionId;
279
            $result[] = "Cgi-Authorization: Basic " . $this->sessionId;
280
        }
281
282
        return $result;
283
    }
284
285
    /**
286
     * Method returns service
287
     *
288
     * @return string service
289
     */
290
    public function getService(): string
291
    {
292
        return $this->service;
293
    }
294
295
    /**
296
     * Setting rewrite mode for URLs
297
     *
298
     * @param bool $rewriteMode
299
     *            rewrite mode
300
     */
301
    public function setRewriteMode(bool $rewriteMode): void
302
    {
303
        $this->rewriteMode = $rewriteMode;
0 ignored issues
show
Documentation Bug introduced by
The property $rewriteMode was declared of type string, but $rewriteMode is of type boolean. Maybe add a type cast?

This check looks for assignments to scalar types that may be of the wrong type.

To ensure the code behaves as expected, it may be a good idea to add an explicit type cast.

$answer = 42;

$correct = false;

$correct = (bool) $answer;
Loading history...
304
    }
305
306
    /**
307
     * Getting rewrite mode for URLs
308
     *
309
     * @return bool rewrite mode
310
     */
311
    public function getRewriteMode(): bool
312
    {
313
        return $this->rewriteMode;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->rewriteMode returns the type string which is incompatible with the type-hinted return boolean.
Loading history...
314
    }
315
316
    /**
317
     * Method returns concrete url byit's locator
318
     *
319
     * @param string $urlLocator
320
     *            url locator
321
     * @return string concrete URL
322
     */
323
    protected function getRequestUrl(string $urlLocator): string
324
    {
325
        $urlMap = [
326
            'loginAs' => $this->rewriteMode ? '/login-as/' : '?r=login-as',
327
            'selfLogin' => $this->rewriteMode ? '/self/login/' : '?r=' . urlecode('self/login'),
328
            'selfId' => $this->rewriteMode ? '/self/id/' : '?r=' . urlecode('self/id'),
329
            'connect' => $this->rewriteMode ? '/connect/' : '?r=connect'
330
        ];
331
332
        if (isset($urlMap[$urlLocator]) === false) {
333
            throw (new \Exception('Locator ' . $urlLocator . ' was not found'));
334
        }
335
336
        return $urlMap[$urlLocator];
337
    }
338
}
339