Completed
Push — master ( b03bf1...e1abb2 )
by Alex
02:07
created

ServiceClient.php (2 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 = '';
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 bool
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 validates result
81
     *
82
     * @param object $resultResult
83
     *            of the authorisation request
84
     */
85
    protected function validateSessionId(object $result): void
86
    {
87
        if (isset($result->session_id) === false) {
88
            throw (new \Exception($result->message ?? 'Undefined message', $result->code ?? - 1));
89
        }
90
    }
91
92
    /**
93
     * Method connects to the REST server via login and password pair
94
     *
95
     * @param string $login
96
     *            Login
97
     * @param string $password
98
     *            Password
99
     */
100
    public function connect(string $login, string $password): void
101
    {
102
        // authorization
103
        $data = [
104
            'login' => $login,
105
            'password' => $password
106
        ];
107
108
        $result = $this->sendPostRequest($this->getRequestUrl('connect'), $data);
109
110
        $this->validateSessionId($result);
111
112
        $this->login = $login;
113
        $this->sessionId = $result->session_id;
114
    }
115
116
    /**
117
     * Method sets token
118
     *
119
     * @param string $token
120
     *            Access token
121
     * @param string $login
122
     *            User login
123
     */
124
    public function setToken(string $token, string $login = ''): void
125
    {
126
        if ($token === '') {
127
            throw (new \Exception('Token not set', - 4));
128
        }
129
130
        $this->login = $login;
131
        $this->sessionId = $token;
132
    }
133
134
    /**
135
     * Method returns token
136
     *
137
     * @return string Session id
138
     */
139
    public function getToken(): string
140
    {
141
        return $this->sessionId;
142
    }
143
144
    /**
145
     * Method returns self id of the session
146
     *
147
     * @return string Session user's id
148
     */
149
    public function getSelfId(): string
150
    {
151
        $result = $this->sendGetRequest($this->getRequestUrl('selfId'));
152
153
        return isset($result->id) ? $result->id : $result;
154
    }
155
156
    /**
157
     * Method returns self login of the session
158
     *
159
     * @return string Session user's login
160
     */
161
    public function getSelfLogin(): string
162
    {
163
        $result = $this->sendGetRequest($this->getRequestUrl('selfLogin'));
164
165
        return isset($result->login) ? $result->login : $result;
166
    }
167
168
    /**
169
     * Method logins under another user
170
     * $field must be 'id' or 'login'
171
     *
172
     * @param string $user
173
     *            User credentials
174
     * @param string $field
175
     *            Field name for credentials
176
     */
177
    public function loginAs(string $user, string $field = 'id'): void
178
    {
179
        if ($field != 'id' && $this->login !== $user) {
180
            $result = $this->sendPostRequest($this->getRequestUrl('loginAs'), [
181
                $field => $user
182
            ]);
183
184
            $this->validateSessionId($result);
185
186
            $this->sessionId = $result->session_id;
187
        }
188
189
        if ($field == 'id') {
190
            $this->login = '';
191
        } else {
192
            $this->login = $user;
193
        }
194
    }
195
196
    /**
197
     * Method returns stored login
198
     *
199
     * @return string Stored login
200
     */
201
    public function getStoredLogin(): string
202
    {
203
        return $this->login;
204
    }
205
206
    /**
207
     * Method returns common headers
208
     *
209
     * @return array Headers
210
     */
211
    protected function getCommonHeaders(): array
212
    {
213
        $result = parent::getCommonHeaders();
214
215
        if ($this->sessionId !== false) {
0 ignored issues
show
The condition $this->sessionId !== false is always true.
Loading history...
216
            $result[] = "Authentication: Basic " . $this->sessionId;
217
            $result[] = "Cgi-Authorization: Basic " . $this->sessionId;
218
        }
219
220
        return $result;
221
    }
222
223
    /**
224
     * Method returns service
225
     *
226
     * @return string service
227
     */
228
    public function getService(): string
229
    {
230
        return $this->service;
231
    }
232
233
    /**
234
     * Setting rewrite mode for URLs
235
     *
236
     * @param bool $rewriteMode
237
     *            rewrite mode
238
     */
239
    public function setRewriteMode(bool $rewriteMode): void
240
    {
241
        $this->rewriteMode = $rewriteMode;
242
    }
243
244
    /**
245
     * Getting rewrite mode for URLs
246
     *
247
     * @return bool rewrite mode
248
     */
249
    public function getRewriteMode(): bool
250
    {
251
        return $this->rewriteMode;
252
    }
253
254
    /**
255
     * Method returns concrete url byit's locator
256
     *
257
     * @param string $urlLocator
258
     *            url locator
259
     * @return string concrete URL
260
     */
261
    protected function getRequestUrl(string $urlLocator): string
262
    {
263
        $urlMap = [
264
            'loginAs' => $this->rewriteMode ? '/login-as/' : '?r=login-as',
265
            'selfLogin' => $this->rewriteMode ? '/self/login/' : '?r=' . urlecode('self/login'),
0 ignored issues
show
The function urlecode 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

265
            'selfLogin' => $this->rewriteMode ? '/self/login/' : '?r=' . /** @scrutinizer ignore-call */ urlecode('self/login'),
Loading history...
266
            'selfId' => $this->rewriteMode ? '/self/id/' : '?r=' . urlecode('self/id'),
267
            'connect' => $this->rewriteMode ? '/connect/' : '?r=connect'
268
        ];
269
270
        if (isset($urlMap[$urlLocator]) === false) {
271
            throw (new \Exception('Locator ' . $urlLocator . ' was not found'));
272
        }
273
274
        return $urlMap[$urlLocator];
275
    }
276
277
    /**
278
     *
279
     * {@inheritdoc}
280
     * @see \Mezon\CustomClient\CustomClient::dispatchResult(string $url, int $code, string $body)
281
     */
282
    protected function dispatchResult(string $url, int $code, string $body)
283
    {
284
        $jsonBody = json_decode(parent::dispatchResult($url, $code, $body));
285
286
        if (isset($jsonBody->message)) {
287
            throw (new \Exception($jsonBody->message, $jsonBody->code));
288
        } elseif ($jsonBody === null) {
289
            throw (new \Mezon\Rest\Exception("Invalid result dispatching", - 3, $code, $body, $url));
290
        }
291
292
        return $jsonBody;
293
    }
294
}
295