UsersAPI::userIsMe()   A
last analyzed

Complexity

Conditions 3
Paths 3

Size

Total Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
nc 3
nop 2
dl 0
loc 5
rs 10
c 0
b 0
f 0
1
<?php
2
require_once('class.UIDForgotEmail.php');
3
require_once('class.PasswordResetEmail.php');
4
5
class UsersAPI extends ProfilesAdminAPI
6
{
7
    public function setup($app)
8
    {
9
        $app->get('[/]', array($this, 'listUsers'));
10
        $app->post('[/]', array($this, 'createUser'));
11
        $app->get('/{uid}[/]', array($this, 'showUser'));
12
        $app->patch('/{uid}[/]', array($this, 'editUser'));
13
        $app->delete('/{uid}[/]', array($this, 'deleteUser'));
14
        $app->get('/{uid}/groups[/]', array($this, 'listGroupsForUser'));
15
        $app->post('/{uid}/Actions/link[/]', array($this, 'linkUser'));
16
        $app->post('/{uid}/Actions/reset_pass[/]', array($this, 'resetUserPassword'));
17
        $app->post('/{uid}/Actions/ClearPosition[/]', array($this, 'clearPosition'));
18
        $app->post('/me/Actions/RemoveEmail[/]', array($this, 'removeEmail'));
19
        $app->post('/Actions/check_email_available[/]', array($this, 'checkEmailAvailable'));
20
        $app->post('/Actions/check_uid_available[/]', array($this, 'checkUidAvailable'));
21
        $app->post('/Actions/remind_uid[/]', array($this, 'remindUid'));
22
    }
23
24
    public function listUsers($request, $response)
25
    {
26
        $odata = $request->getAttribute('odata', new \Flipside\ODataParams(array()));
27
        if($this->validateIsAdmin($request, true) === false)
28
        {
29
            $users = array($this->user);
30
            $users = $odata->filterArrayPerSelect($users);
31
        }
32
        else
33
        {
34
            $auth = \Flipside\AuthProvider::getInstance();
35
            $users = $auth->getUsersByFilter($odata->filter, $odata->select, $odata->top, $odata->skip, 
36
                                             $odata->orderby);
37
        }
38
        return $response->withJson($users);
39
    }
40
41
    protected function validateCanCreateUser($proposedUser, $auth, &$message)
42
    {
43
        $user = $auth->getUsersByFilter(new \Flipside\Data\Filter('mail eq '.$proposedUser['mail']));
44 View Code Duplication
        if($user !== false && isset($user[0]))
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
45
        {
46
            $message = 'Email already exists!';
47
            return false;
48
        }
49
        $user = $auth->getUsersByFilter(new \Flipside\Data\Filter('uid eq '.$proposedUser['uid']));
50 View Code Duplication
        if($user !== false && isset($user[0]))
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
51
        {
52
            $message = 'Username already exists!';
53
            return false;
54
        }
55
        return true;
56
    }
57
58
    protected function validEmail($email)
59
    {
60
        if(filter_var($email) === false)
61
        {
62
            return false;
63
        }
64
        $pos = strpos($email, '@');
65
        if($pos === false)
66
        {
67
            return false;
68
        }
69
        $domain = substr($email, $pos + 1);
70
        if(checkdnsrr($domain, 'MX') === false)
71
        {
72
            return false;
73
        }
74
        return true;
75
    }
76
77
    protected function getFailArray($message)
78
    {
79
        return array('res'=>false, 'message'=>$message);
80
    }
81
82
    public function createUser($request, $response)
83
    {
84
        $this->user = $request->getAttribute('user');
85
        //This one is different. If they are logged in fail...
86
        if($this->user !== false)
87
        {
88
            return $response->withStatus(404);
89
        }
90
        $obj = $request->getParsedBody();
91
        if(!isset($obj['captcha']))
92
        {
93
            return $response->withStatus(401);
94
        }
95
        $captcha = FlipSession::getVar('captcha');
96
        if($captcha === false)
97
        {
98
            return $response->withStatus(401);
99
        }
100
        if(!$captcha->is_answer_right($obj['captcha']))
101
        {
102
            return $response->withJson($this->getFailArray('Incorrect answer to CAPTCHA!'), 412);
103
        }
104
        $auth = AuthProvider::getInstance();
105
        $message = false;
106
        if($this->validateCanCreateUser($obj, $auth, $message) === false)
107
        {
108
            return $response->withJson($this->getFailArray($message), 412);
109
        }
110
        else if($this->validEmail($obj['mail']) === false)
111
        {
112
            return $response->withJson($this->getFailArray('Invalid Email Address!'));
113
        }
114
        $ret = $auth->createPendingUser($obj);
115
        if($ret == false)
116
        {
117
            return $response->withJson($this->getFailArray('Failed to save user registration!'), 500);
118
        }
119
        return $response->withJson($ret);
120
    }
121
122
    protected function userIsMe($request, $uid)
123
    {
124
        $this->user = $request->getAttribute('user');
125
        return ($uid === 'me' || ($this->user !== false && $uid === $this->user->uid));
126
    }
127
128
    protected function hasLeadAccess()
129
    {
130
        return ($this->user->isInGroupNamed('Leads') || $this->user->isInGroupNamed('CC') || $this->user->isInGroupNamed('AFs'));
131
    }
132
133 View Code Duplication
    protected function getUserByUIDReadOnly($request, $uid)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
134
    {
135
        if($this->userIsMe($request, $uid))
136
        {
137
            return $this->user;
138
        }
139
        if($this->user->isInGroupNamed('LDAPAdmins') || $this->hasLeadAccess())
140
        {
141
            $auth = \Flipside\AuthProvider::getInstance();
142
            $filter = new \Flipside\Data\Filter("uid eq $uid");
143
            $users = $auth->getUsersByFilter($filter);
144
            if(!empty($users))
145
            {
146
                return $users[0];
147
            }
148
        }
149
        return false;
150
    }
151
152 View Code Duplication
    protected function getUserByUID($request, $uid)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
153
    {
154
        if($this->userIsMe($request, $uid))
155
        {
156
            return $this->user;
157
        }
158
        if($this->user->isInGroupNamed('LDAPAdmins'))
159
        {
160
            $auth = \Flipside\AuthProvider::getInstance();
161
            $filter = new \Flipside\Data\Filter("uid eq $uid");
162
            $users = $auth->getUsersByFilter($filter);
163
            if(!empty($users))
164
            {
165
                return $users[0];
166
            }
167
        }
168
        return false;
169
    }
170
171
    public function showUser($request, $response, $args)
172
    {
173
        $uid = $args['uid'];
174
        $user = $request->getAttribute('user');
175
        if($user === false)
176
        {
177
            if($_SERVER['SERVER_ADDR'] === $_SERVER['REMOTE_ADDR'])
178
            {
179
                $user = \Flipside\AuthProvider::getInstance()->getUsersByFilter(new \Data\Filter("uid eq $uid"));
180
                if(empty($user))
181
                {
182
                    return $response->withStatus(404);
183
                }
184
                return $response->withJson($user[0]);
185
            } 
186
            return $response->withStatus(401);
187
        }
188
        $user = $this->getUserByUIDReadOnly($request, $uid);
189
        if($user === false)
190
        {
191
            return $response->withStatus(404);
192
        }
193
        if(!is_object($user) && isset($user[0]))
194
        {
195
            $user = $user[0];
196
        }
197
        if($request->getAttribute('format') === 'vcard')
198
        {
199
            $response = $response->withHeader('Content-Type', 'text/x-vCard');
200
            $response->getBody()->write($user->getVcard());
201
            return $response;
202
        }
203
        return $response->withJson($user);
204
    }
205
206
    protected function sendPasswordResetEmail($user)
207
    {
208
        $forwardedFor = false;
209
        if(isset($_SERVER['HTTP_X_FORWARDED_FOR']))
210
        {
211
            $forwardedFor = $_SERVER['HTTP_X_FORWARDED_FOR'];
212
        }
213
        $emailMsg = new PasswordHasBeenResetEmail($user, $_SERVER['REMOTE_ADDR'], $forwardedFor);
214
        $emailProvider = \Flipside\EmailProvider::getInstance();
215
        if($emailProvider->sendEmail($emailMsg) === false)
216
        {
217
            throw new \Exception('Unable to send password reset email!');
218
        }
219
    }
220
221
    protected function exceptionCodeToHttpCode($e)
222
    {
223
        if($e->getCode() === 3)
224
        {
225
            return 401;
226
        }
227
        return 500;
228
    }
229
230
    protected function getUser($request, $uid, $payload)
231
    {
232
        $this->user = $request->getAttribute('user');
233
        if($this->user === false)
234
        {
235
            if(isset($payload['hash']))
236
            {
237
                $auth = \Flipside\AuthProvider::getInstance();
238
                $this->user = $auth->getUserByResetHash($payload['hash']);
239
                return $this->user;
240
            }
241
            return false;
242
        }
243
        return $this->getUserByUID($request, $uid);
244
    }
245
246
    public function editUser($request, $response, $args)
247
    {
248
        $uid = 'me';
249
        if(isset($args['uid']))
250
        {
251
            $uid = $args['uid'];
252
        }
253
        $obj = $request->getParsedBody();
254
        $user = $this->getUser($request, $uid, $obj);
255
        if($user === false)
256
        {
257
            return $response->withStatus(404);
258
        }
259
        try
260
        {
261
            if(isset($obj['old_uid']))
262
            {
263
                unset($obj['old_uid']);
264
            }
265
            unset($obj['uid']);
266
            if(isset($obj['password']))
267
            {
268
                $obj['userPassword'] = $obj['password'];
269
                unset($obj['password']);
270
            }
271
            $user->editUser($obj);
272
        }
273
        catch(\Exception $e)
274
        {
275
            return $response->withJson(array('error'=>array('msg'=>$e->getMessage(), 'stack'=>$e->getTraceAsString())), $this->exceptionCodeToHttpCode($e));
276
        }
277
        if($this->userIsMe($request, $uid))
278
        {
279
            \Flipside\FlipSession::setUser($user);
280
        }
281
        if(isset($obj->password))
282
        {
283
            $this->sendPasswordResetEmail($user);
284
        }
285
        return $response->withJson(array('success'=>true));
286
    }
287
288
    public function deleteUser($request, $response, $args)
289
    {
290
        $uid = 'me';
291
        if(isset($args['uid']))
292
        {
293
            $uid = $args['uid'];
294
        }
295
        $user = false;
0 ignored issues
show
Unused Code introduced by
$user is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
296
        if($this->validateIsAdmin($request, true) === false && $this->userIsMe($request, $uid))
297
        {
298
            $user = $this->user;
299
        }
300
        else
301
        {
302
            $auth = \Flipside\AuthProvider::getInstance();
303
            $filter = new \Flipside\Data\Filter("uid eq $uid");
304
            $user = $auth->getUsersByFilter($filter);
305
            if(empty($user))
306
            {
307
                $user = false;
308
            }
309
            else
310
            {
311
                $user = $user[0];
312
            }
313
        }
314
        if($user === false)
315
        {
316
            return $response->withStatus(404);
317
        }
318
        return $response->withJson($user->delete());
319
    }
320
321
    public function listGroupsForUser($request, $response, $args)
322
    {
323
        $uid = 'me';
324
        if(isset($args['uid']))
325
        {
326
            $uid = $args['uid'];
327
        }
328
        $this->validateLoggedIn($request);
329
        $user = $this->getUserByUID($request, $uid);
330
        if($user === false)
331
        {
332
            return $response->withStatus(404);
333
        }
334
        $groups = $user->getGroups();
335
        if($groups === false)
336
        {
337
            $groups = array();
338
        }
339
        return $response->withJson($groups);
340
    }
341
342
    public function linkUser($request, $response, $args)
343
    {
344
        $uid = 'me';
345
        if(isset($args['uid']))
346
        {
347
            $uid = $args['uid'];
348
        }
349
        $this->validateLoggedIn($request);
350
        $obj = $request->getParsedBody();
351
        if($this->userIsMe($request, $uid))
352
        {
353
            $this->user->addLoginProvider($obj->provider);
354
            \Flipside\AuthProvider::getInstance()->impersonateUser($this->user);
355
        }
356
        else if($this->user->isInGroupNamed("LDAPAdmins"))
357
        {
358
            $user = \Flipside\AuthProvider::getInstance()->getUser($uid);
359
            if($user === false)
360
            {
361
                return $response->withStatus(404);
362
            }
363
            $user->addLoginProvider($obj->provider);
364
        }
365
        else
366
        {
367
            return $response->withStatus(404);
368
        }
369
        return $response->withJson(array('success'=>true));
370
    }
371
372
    protected function getAllUsersByFilter($filter, &$pending)
373
    {
374
        $auth = \Flipside\AuthProvider::getInstance();
375
        $user = $auth->getUsersByFilter($filter);
376
        if(!empty($user))
377
        {
378
            $pending = false;
379
            return $user[0];
380
        }
381
        $user = $auth->getPendingUsersByFilter($filter);
382
        if(!empty($user))
383
        {
384
            $pending = true;
385
            return $user[0];
386
        }
387
        return false;
388
    }
389
390
    public function checkEmailAvailable($request, $response)
391
    {
392
        $params = $request->getQueryParams();
393
        $email = false;
394
        if(isset($params['email']))
395
        {
396
            $email = $params['email'];
397
        }
398 View Code Duplication
        if($email === false)
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
399
        {
400
            $params = $request->getParsedBody();
401
            if(isset($params['email']))
402
            {
403
                $email = $params['email'];
404
            }
405
            if($email === false)
406
            {
407
                return $response->withStatus(400);
408
            }
409
        }
410
        if(filter_var($email, FILTER_VALIDATE_EMAIL) === false || strpos($email, '@') === false)
411
        {
412
            return $response->withJson(false);
413
        }
414
        if(strstr($email, '+') !== false)
415
        {
416
            //Remove everything between the + and the @
417
            $begining = strpos($email, '+');
418
            $end = strpos($email, '@');
419
            $to_delete = substr($email, $begining, $end - $begining);
420
            $email = str_replace($to_delete, '', $email);
421
        }
422
        $filter = new \Flipside\Data\Filter('mail eq '.$email);
423
        $pending = false;
424
        $user = $this->getAllUsersByFilter($filter, $pending);
425
        if($user === false)
426
        {
427
            return $response->withJson(true);
428
        }
429
        return $response->withJson(array('res'=>false, 'email'=>$user->mail, 'pending'=>$pending));
430
    }
431
432
    public function checkUidAvailable($request, $response)
433
    {
434
        $params = $request->getQueryParams();
435
        $uid = false;
436
        if(isset($params['uid']))
437
        {
438
            $uid = $params['uid'];
439
        }
440 View Code Duplication
        if($uid === false)
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
441
        {
442
            $params = $request->getParsedBody();
443
            if(isset($params['uid']))
444
            {
445
                $uid = $params['uid'];
446
            }
447
            if($uid === false)
448
            {
449
                return $response->withStatus(400);
450
            }
451
        }
452
        if(strpos($uid, '=') !== false || strpos($uid, ',') !== false)
453
        {
454
            return $response->withJson(false);
455
        }
456
        $filter = new \Flipside\Data\Filter('uid eq '.$uid);
457
        $pending = false;
458
        $user = $this->getAllUsersByFilter($filter, $pending);
459
        if($user === false)
460
        {
461
            return $response->withJson(true);
462
        }
463
        return $response->withJson(array('res'=>false, 'uid'=>$user->uid, 'pending'=>$pending));
464
    }
465
466
    public function resetUserPassword($request, $response, $args)
467
    {
468
        $uid = false;
0 ignored issues
show
Unused Code introduced by
$uid is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
469
        if(isset($args['uid']))
470
        {
471
            $uid = $args['uid'];
472
        }
473
        else
474
        {
475
            return $response->withStatus(400);
476
        }
477
        $auth = \Flipside\AuthProvider::getInstance();
478
        $users = $auth->getUsersByFilter(new \Data\Filter('uid eq '.$uid));
479
        if(empty($users))
480
        {
481
            return $response->withStatus(404);
482
        }
483
        $email_msg = new PasswordResetEmail($users[0]);
484
        $email_provider = EmailProvider::getInstance();
485
        if($email_provider->sendEmail($email_msg) === false)
486
        {
487
            throw new \Exception('Unable to send email!');
488
        }
489
        return $response->withJson(true);
490
    }
491
492
    public function clearPosition($request, $response, $args)
493
    {
494
        $this->validateLoggedIn($request);
495
        if(!$this->user->isInGroupNamed('LDAPAdmins'))
496
        {
497
            return $response->withStatus(401);
498
        }
499
        $uid = $args['uid'];
500
        $auth = \Flipside\AuthProvider::getInstance();
501
        $filter = new \Flipside\Data\Filter("uid eq $uid");
502
        $users = $auth->getUsersByFilter($filter);
503
        if(empty($users))
504
        {
505
            return $response->withStatus(404);
506
        }
507
        $users[0]->editUser(array('title'=>null, 'ou'=>null));
508
        return $response->withStatus(204);
509
    }
510
511
    public function removeEmail($request, $response, $args)
512
    {
513
        $this->validateLoggedIn($request);
514
        $obj = $request->getParsedBody();
515
        if(!$this->userIsMe($request, 'me'))
516
        {
517
            return $response->withStatus(401);
518
        }
519
        if(!isset($this->user->allMail))
520
        {
521
            return $response->withJSON(array('error' => 'User does not have multiple email addresses'), 409);
522
        }
523
        $email = $obj['email'];
524
        if(!in_array($email, $this->user->allMail))
525
        {
526
            return $response->withJSON(array('error' => 'User does not have email address '.$email), 409);
527
        }
528
        $res = $this->user->removeEmail($email);
529
        if($res)
530
        {
531
            return $response->withStatus(204);
532
        }
533
        else
534
        {
535
            return $response->withStatus(500);
536
        }
537
    }
538
539
    public function remindUid($request, $response, $args)
540
    {
541
        $params = $request->getQueryParams();
542
        $email = false;
543
        if(isset($params['email']))
544
        {
545
            $email = $params['email'];
546
        }
547 View Code Duplication
        if($email === false)
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
548
        {
549
            $params = $request->getParsedBody();
550
            if(isset($params['email']))
551
            {
552
                $email = $params['email'];
553
            }
554
            if($email === false)
555
            {
556
                return $response->withStatus(400);
557
            }
558
        }
559
        if(filter_var($email, FILTER_VALIDATE_EMAIL) === false)
560
        {
561
            return $response->withStatus(400);
562
        }
563
        $auth = \Flipside\AuthProvider::getInstance();
564
        $users = $auth->getUsersByFilter(new \Flipside\Data\Filter('mail eq '.$email));
565
        if(empty($users))
566
        {
567
            return $response->withStatus(404);
568
        }
569
        $email_msg = new UIDForgotEmail($users[0]);
570
        $email_provider = \Flipside\EmailProvider::getInstance();
571
        if($email_provider->sendEmail($email_msg) === false)
572
        {
573
            throw new \Exception('Unable to send email!');
574
        }
575
    }
576
}
577
/* vim: set tabstop=4 shiftwidth=4 expandtab: */
578