Completed
Push — master ( ff5a05...9fc508 )
by Artem
06:17 queued 01:22
created

AuthService::setClient()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 1
dl 0
loc 3
ccs 0
cts 2
cp 0
crap 2
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace Slides\Connector\Auth;
4
5
use Illuminate\Support\Facades\DB;
6
use Illuminate\Contracts\Auth\Guard as GuardContract;
7
8
/**
9
 * Class AuthService
10
 *
11
 * @package Slides\Connector\Auth
12
 */
13
class AuthService
14
{
15
    const HANDLER_USER_CREATE      = 'create';
16
    const HANDLER_USER_UPDATE      = 'update';
17
    const HANDLER_USER_DELETE      = 'delete';
18
    const HANDLER_USER_SYNC_CREATE = 'sync.create';
19
    const HANDLER_USER_SYNC_UPDATE = 'sync.update';
20
    const HANDLER_USER_SYNC_DELETE = 'sync.delete';
21
22
    /**
23
     * The class with handler methods
24
     *
25
     * @var object
26
     */
27
    protected $handlersContainer;
28
29
    /**
30
     * HTTP Client
31
     *
32
     * @var Client
33
     */
34
    protected $client;
35
36
    /**
37
     * The authentication guard.
38
     *
39
     * @var TokenGuard
40
     */
41
    protected $guard;
42
43
    /**
44
     * The fallback authentication guard.
45
     *
46
     * @var GuardContract
47
     */
48
    protected $fallbackGuard;
49
50
    /**
51
     * Checks whether a service is disabled
52
     *
53
     * @return bool
54
     */
55 8
    public function disabled(): bool
56
    {
57 8
        return !config('connector.auth.enabled', true);
58
    }
59
60
    /**
61
     * AuthService constructor.
62
     *
63
     * @param Client $client
64
     */
65 15
    public function __construct(Client $client)
66
    {
67 15
        $this->client = $client;
68 15
    }
69
70
    /**
71
     * Authenticate a user.
72
     *
73
     * @param string $email
74
     * @param string $password
75
     * @param bool $remember
76
     *
77
     * @return mixed
78
     *
79
     * @throws
80
     */
81 3
    public function login(string $email, string $password, bool $remember = false)
82
    {
83 3
        if($this->disabled()) {
84
            return $this->handleFallback('login', compact('email', 'password', 'remember'));
85
        }
86
87 3
        return $this->guard->login($email, $password, $remember);
88
    }
89
90
    /**
91
     * Logout a user.
92
     *
93
     * @return mixed
94
     *
95
     * @throws
96
     */
97
    public function logout()
98
    {
99
        if($this->disabled()) {
100
            return $this->handleFallback('logout');
101
        }
102
103
        $this->guard->logout();
104
105
        return null;
106
    }
107
108
    /**
109
     * Create a remote user.
110
     *
111
     * @param int $userId
112
     * @param string $name
113
     * @param string $email
114
     * @param string $password
115
     *
116
     * @return array
117
     */
118 2
    public function register(int $userId, string $name, string $email, string $password)
119
    {
120 2
        if($this->disabled()) {
121
            return [];
122
        }
123
124 2
        return $this->client->request('register', compact('userId', 'name', 'email', 'password'));
125
    }
126
127
    /**
128
     * Send an email with a password resetting link
129
     *
130
     * @param string $email
131
     *
132
     * @return bool
133
     *
134
     * @throws
135
     */
136 2
    public function forgot(string $email)
137
    {
138 2
        if($this->disabled()) {
139
            return $this->handleFallback('forgot', compact('email'));
140
        }
141
142 2
        $this->client->request('forgot', compact('email'));
143
144 2
        return $this->client->success(true);
145
    }
146
147
    /**
148
     * Checks whether password reset token is valid
149
     *
150
     * @param string $token
151
     * @param string $email
152
     *
153
     * @return string|false
154
     *
155
     * @throws
156
     */
157 2
    public function validatePasswordResetToken(string $token, string $email)
158
    {
159 2
        if($this->disabled()) {
160
            return $this->handleFallback('validateReset', compact('token', 'email'));
161
        }
162
163 2
        $response = $this->client->request('validateReset', compact('token', 'email'));
164
165 2
        if(!$this->client->success(true)) {
166 1
            return false;
167
        }
168
169 1
        return array_get($response, 'user.email');
170
    }
171
172
    /**
173
     * Checks whether password reset token is valid
174
     *
175
     * @param string $token
176
     * @param string $email
177
     * @param string $password
178
     * @param string $confirmation
179
     *
180
     * @return array|false
181
     *
182
     * @throws
183
     */
184 2
    public function resetPassword(string $token, string $email, string $password, string $confirmation)
185
    {
186 2
        $parameters = compact('token', 'email', 'password', 'confirmation');
187
188 2
        if($this->disabled()) {
189
            return $this->handleFallback('resetPassword', $parameters);
190
        }
191
192 2
        $response = $this->client->request('reset', $parameters);
193
194 2
        if(!$this->client->success(true)) {
195 1
            return false;
196
        }
197
198 1
        return $response;
199
    }
200
201
    /**
202
     * Update a remote user
203
     *
204
     * @param int $id Local user ID
205
     * @param string|null $name
206
     * @param string|null $email
207
     * @param string|null $password Raw password, in case if changed
208
     *
209
     * @return array|false
210
     */
211 2
    public function update(int $id, ?string $name, ?string $email, ?string $password)
212
    {
213 2
        if($this->disabled()) {
214
            return false;
215
        }
216
217 2
        $attributes = array_filter(compact('id', 'name', 'email', 'password'));
218
219 2
        $response = $this->client->request('update', compact('id', 'attributes'));
220
221 2
        if(!$this->client->success(true)) {
222 1
            return false;
223
        }
224
225 1
        return $response;
226
    }
227
228
    /**
229
     * Load handlers from the given container.
230
     *
231
     * @param $container
232
     *
233
     * @return void
234
     */
235 15
    public function loadHandlers($container)
236
    {
237 15
        $this->handlersContainer = $container;
238 15
    }
239
240
    /**
241
     * Run a handler
242
     *
243
     * @param string $key
244
     * @param array $parameters
245
     * @param \Closure|null $fallback
246
     *
247
     * @return mixed
248
     *
249
     * @throws \Exception
250
     */
251 7
    public function handle(string $key, array $parameters = [], \Closure $fallback = null)
252
    {
253 7
        $handler = camel_case(str_replace('.', ' ', $key));
254
255 7
        if(!method_exists($this->handlersContainer, $handler)) {
256 1
            throw new \InvalidArgumentException("Handler `{$handler}` cannot be found");
257
        }
258
259
        return $this->ensure(function() use ($handler, $parameters) {
260 6
            return call_user_func_array([$this->handlersContainer, $handler], $parameters);
261 6
        }, $fallback);
262
    }
263
264
    /**
265
     * Run a fallback handler
266
     *
267
     * @param string $key
268
     * @param array $parameters
269
     * @param \Closure|null $fallback
270
     *
271
     * @return mixed
272
     *
273
     * @throws \Exception
274
     */
275 2
    public function handleFallback(string $key, array $parameters = [], \Closure $fallback = null)
276
    {
277 2
        $key = 'fallback' . studly_case($key);
278 2
        $parameters = array_merge(['guard' => $this->fallbackGuard], $parameters);
279
280 2
        return $this->handle($key, $parameters, $fallback);
281
    }
282
283
    /**
284
     * Performs a callback logic within database transaction.
285
     *
286
     * @param \Closure $callback
287
     * @param \Closure|null $fallback The callback which should fired when exception throws.
288
     *
289
     * @return mixed
290
     *
291
     * @throws \Exception
292
     */
293 6
    protected function ensure(\Closure $callback, \Closure $fallback = null)
294
    {
295 6
        DB::beginTransaction();
296
297
        try {
298 6
            $output = $callback();
299
        }
300 3
        catch(\Exception $e) {
301 2
            DB::rollBack();
302
303 2
            if(is_null($fallback)) {
304
                throw $e;
305
            }
306
307 2
            $output = $fallback($e);
308
        }
309
310 5
        DB::commit();
311
312 5
        return $output;
313
    }
314
315
    /**
316
     * Set authentication guard.
317
     *
318
     * @param \Slides\Connector\Auth\TokenGuard $guard
319
     */
320 15
    public function setGuard(TokenGuard $guard): void
321
    {
322 15
        $this->guard = $guard;
323 15
    }
324
325
    /**
326
     * Set fallback authentication guard.
327
     *
328
     * @param GuardContract $guard
329
     */
330
    public function setFallbackGuard(GuardContract $guard): void
331
    {
332
        $this->fallbackGuard = $guard;
333
    }
334
335
    /**
336
     * Set HTTP Client.
337
     *
338
     * @param Client $client
339
     */
340
    public function setClient(Client $client): void
341
    {
342
        $this->client = $client;
343
    }
344
345
    /**
346
     * Get HTTP client.
347
     *
348
     * @return Client
349
     */
350 15
    public function getClient(): Client
351
    {
352 15
        return $this->client;
353
    }
354
}