ServiceClient::validateSessionId()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 2
c 0
b 0
f 0
nc 2
nop 1
dl 0
loc 4
rs 10
1
<?php
2
namespace Mezon\Service;
3
4
use Mezon\CustomClient\CustomClient;
5
use Mezon\DnsClient\DnsClient;
6
7
/**
8
 * Class ServiceClient
9
 *
10
 * @package Service
11
 * @subpackage ServiceClient
12
 * @author Dodonov A.A.
13
 * @version v.1.0 (2019/08/06)
14
 * @copyright Copyright (c) 2019, aeon.org
15
 */
16
17
/**
18
 * Service client for Service
19
 */
20
class ServiceClient extends CustomClient
21
{
22
23
    /**
24
     * Service name
25
     *
26
     * @var string
27
     */
28
    private $service = '';
29
30
    /**
31
     * Last logged in user
32
     * This is used for performance improvements in ServiceClient::loginAs method
33
     * For optimisation purposes only! Do not use in the client code
34
     *
35
     * @var string
36
     */
37
    private $login = '';
38
39
    /**
40
     * Rewrite mode.
41
     * If true, then URLs like this /part1/part2/param1/ will be used. If false, then parameter ?r=part1/part2/param1 will be passed
42
     *
43
     * @var bool
44
     */
45
    private $rewriteMode = true;
46
47
    /**
48
     * Session id
49
     *
50
     * @var string
51
     */
52
    private $sessionId = '';
53
54
    /**
55
     * Constructor
56
     *
57
     * @param string $service
58
     *            Service URL or service name
59
     * @param string $login
60
     *            Login
61
     * @param string $password
62
     *            Password
63
     * @param array $headers
64
     *            Headers
65
     */
66
    public function __construct(string $service, string $login = '', string $password = '', array $headers = [])
67
    {
68
        if (DnsClient::serviceExists($service)) {
69
            $this->service = $service;
70
            parent::__construct(DnsClient::resolveHost($service), $headers);
71
        } elseif (strpos($service, 'http://') === false && strpos($service, 'https://') === false) {
72
            throw (new \Exception('Service ' . $service . ' was not found in DNS'));
73
        } else {
74
            parent::__construct($service, $headers);
75
        }
76
77
        if ($login !== '') {
78
            $this->connect($login, $password);
79
        }
80
    }
81
82
    /**
83
     * Method validates result
84
     *
85
     * @param object $resultResult
86
     *            of the authorisation request
87
     */
88
    protected function validateSessionId(object $result): void
89
    {
90
        if (isset($result->session_id) === false) {
91
            throw (new \Exception($result->message ?? 'Undefined message', $result->code ?? - 1));
92
        }
93
    }
94
95
    /**
96
     * Method connects to the REST server via login and password pair
97
     *
98
     * @param string $login
99
     *            Login
100
     * @param string $password
101
     *            Password
102
     */
103
    public function connect(string $login, string $password): void
104
    {
105
        // authorization
106
        $data = [
107
            'login' => $login,
108
            'password' => $password
109
        ];
110
111
        $result = $this->sendPostRequest($this->getRequestUrl('connect'), $data);
112
113
        $this->validateSessionId($result);
114
115
        $this->login = $login;
116
        $this->sessionId = $result->session_id;
117
    }
118
119
    /**
120
     * Method sets token
121
     *
122
     * @param string $token
123
     *            Access token
124
     * @param string $login
125
     *            User login
126
     */
127
    public function setToken(string $token, string $login = ''): void
128
    {
129
        if ($token === '') {
130
            throw (new \Exception('Token not set', - 4));
131
        }
132
133
        $this->login = $login;
134
        $this->sessionId = $token;
135
    }
136
137
    /**
138
     * Method returns token
139
     *
140
     * @return string Session id
141
     */
142
    public function getToken(): string
143
    {
144
        return $this->sessionId;
145
    }
146
147
    /**
148
     * Method returns self id of the session
149
     *
150
     * @return string Session user's id
151
     */
152
    public function getSelfId(): string
153
    {
154
        $result = $this->sendGetRequest($this->getRequestUrl('selfId'));
155
156
        return isset($result->id) ? $result->id : $result;
157
    }
158
159
    /**
160
     * Method returns self login of the session
161
     *
162
     * @return string Session user's login
163
     */
164
    public function getSelfLogin(): string
165
    {
166
        $result = $this->sendGetRequest($this->getRequestUrl('selfLogin'));
167
168
        return isset($result->login) ? $result->login : $result;
169
    }
170
171
    /**
172
     * Method logins under another user
173
     * $field must be 'id' or 'login'
174
     *
175
     * @param string $user
176
     *            User credentials
177
     * @param string $field
178
     *            Field name for credentials
179
     */
180
    public function loginAs(string $user, string $field = 'id'): void
181
    {
182
        if ($field != 'id' && $this->login !== $user) {
183
            $result = $this->sendPostRequest($this->getRequestUrl('loginAs'), [
184
                $field => $user
185
            ]);
186
187
            $this->validateSessionId($result);
188
189
            $this->sessionId = $result->session_id;
190
        }
191
192
        if ($field == 'id') {
193
            $this->login = '';
194
        } else {
195
            $this->login = $user;
196
        }
197
    }
198
199
    /**
200
     * Method returns stored login
201
     *
202
     * @return string Stored login
203
     */
204
    public function getStoredLogin(): string
205
    {
206
        return $this->login;
207
    }
208
209
    /**
210
     * Method returns common headers
211
     *
212
     * @return array Headers
213
     */
214
    protected function getCommonHeaders(): array
215
    {
216
        $result = parent::getCommonHeaders();
217
218
        if ($this->sessionId !== '') {
219
            $result[] = "Authentication: Basic " . $this->sessionId;
220
            $result[] = "Cgi-Authorization: Basic " . $this->sessionId;
221
        }
222
223
        return $result;
224
    }
225
226
    /**
227
     * Method returns service
228
     *
229
     * @return string service
230
     */
231
    public function getService(): string
232
    {
233
        return $this->service;
234
    }
235
236
    /**
237
     * Setting rewrite mode for URLs
238
     *
239
     * @param bool $rewriteMode
240
     *            rewrite mode
241
     */
242
    public function setRewriteMode(bool $rewriteMode): void
243
    {
244
        $this->rewriteMode = $rewriteMode;
245
    }
246
247
    /**
248
     * Getting rewrite mode for URLs
249
     *
250
     * @return bool rewrite mode
251
     */
252
    public function getRewriteMode(): bool
253
    {
254
        return $this->rewriteMode;
255
    }
256
257
    /**
258
     * Method returns concrete url byit's locator
259
     *
260
     * @param string $urlLocator
261
     *            url locator
262
     * @return string concrete URL
263
     */
264
    protected function getRequestUrl(string $urlLocator): string
265
    {
266
        $urlMap = [
267
            'loginAs' => $this->rewriteMode ? '/login-as/' : '?r=login-as',
268
            'selfLogin' => $this->rewriteMode ? '/self/login/' : '?r=' . urlencode('self/login'),
269
            'selfId' => $this->rewriteMode ? '/self/id/' : '?r=' . urlencode('self/id'),
270
            'connect' => $this->rewriteMode ? '/connect/' : '?r=connect'
271
        ];
272
273
        if (isset($urlMap[$urlLocator]) === false) {
274
            throw (new \Exception('Locator ' . $urlLocator . ' was not found'));
275
        }
276
277
        return $urlMap[$urlLocator];
278
    }
279
280
    /**
281
     *
282
     * {@inheritdoc}
283
     * @see CustomClient::dispatchResult(string $url, int $code, $body)
284
     */
285
    protected function dispatchResult(string $url, int $code, $body)
286
    {
287
        $jsonBody = json_decode(parent::dispatchResult($url, $code, $body));
288
289
        if ($jsonBody === null) {
290
            throw (new \Mezon\Rest\Exception("Invalid result dispatching", - 3, $code, $body, $url));
291
        } elseif (isset($jsonBody->message)) {
292
            throw (new \Mezon\Rest\Exception($jsonBody->message, $jsonBody->code, $code, $body, $url));
293
        }
294
295
        return $jsonBody;
296
    }
297
}
298