Completed
Pull Request — master (#6)
by Patrick
02:25
created

users.php ➔ validEmail()   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 18
Code Lines 10

Duplication

Lines 18
Ratio 100 %

Importance

Changes 0
Metric Value
cc 4
eloc 10
nc 4
nop 1
dl 18
loc 18
rs 9.2
c 0
b 0
f 0
1
<?php
2
require('class.UIDForgotEmail.php');
3
require('class.PasswordResetEmail.php');
4
require('class.PasswordHasBeenResetEmail.php');
5
6
function users()
7
{
8
    global $app;
9
    $app->get('', 'list_users');
10
    $app->post('', 'create_user');
11
    $app->get('/me', 'show_user');
12
    $app->get('/:uid', 'show_user');
13
    $app->patch('/:uid', 'editUser');
14
    $app->delete('/:uid', 'deleteUser');
15
    $app->get('/me/groups', 'list_groups_for_user');
16
    $app->get('/:uid/groups', 'list_groups_for_user');
17
    $app->post('/me/Actions/link', 'link_user');
18
    $app->post('/:uid/Actions/link', 'link_user');
19
    $app->post('/:uid/Actions/reset_pass', 'reset_pass');
20
    $app->post('/Actions/check_email_available', 'check_email_available');
21
    $app->post('/Actions/check_uid_available', 'check_uid_available');
22
    $app->post('/Actions/remind_uid', 'remind_uid');
23
}
24
25
function list_users()
26
{
27
    global $app;
28
    if(!$app->user)
29
    {
30
        $app->response->setStatus(401);
31
        return;
32
    }
33
    if($app->user && !$app->user->isInGroupNamed('LDAPAdmins'))
34
    {
35
        //Only return this user. This user doesn't have access to other accounts
36
        echo json_encode(array($app->user));
37
    }
38 View Code Duplication
    else
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...
39
    {
40
        $auth = AuthProvider::getInstance();
41
        $users = $auth->getUsersByFilter($app->odata->filter, $app->odata->select, $app->odata->top, $app->odata->skip, $app->odata->orderby);
42
        echo json_encode($users);
43
    }
44
}
45
46
function validateCanCreateUser($proposedUser, $auth, &$message)
47
{
48
    $user = $auth->getUsersByFilter(new \Data\Filter('mail eq '.$proposedUser->mail));
49 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...
50
    {
51
        $message = 'Email already exists!';
52
        return false;
53
    }
54
    $user = $auth->getUsersByFilter(new \Data\Filter('uid eq '.$proposedUser->uid));
55 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...
56
    {
57
        $message = 'Username already exists!';
58
        return false;
59
    }
60
    return true;
61
}
62
63 View Code Duplication
function validEmail($email)
0 ignored issues
show
Duplication introduced by
This function 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...
64
{
65
    if(filter_var($email) === false)
66
    {
67
        return false;
68
    }
69
    $pos = strpos($email, '@');
70
    if($pos === false)
71
    {
72
        return false;
73
    }
74
    $domain = substr($email, $pos+1);
75
    if(checkdnsrr($domain, 'MX') === false)
76
    {
77
        return false;
78
    }
79
    return true;
80
}
81
82
function create_user()
83
{
84
    global $app;
85
    //This one is different. If they are logged in fail...
86
    if($app->user)
87
    {
88
        $app->response->setStatus(404);
89
        return;
90
    }
91
    $body = $app->request->getBody();
92
    $obj  = json_decode($body);
93
    if(!isset($obj->captcha))
94
    {
95
        $app->response->setStatus(401);
96
        return;
97
    }
98
    $captcha = FlipSession::getVar('captcha');
99
    if($captcha === false)
100
    {
101
        $app->response->setStatus(401);
102
        return;
103
    }
104
    if(!$captcha->is_answer_right($obj->captcha))
105
    {
106
        echo json_encode(array('res'=>false, 'message'=>'Incorrect answer to CAPTCHA!'));
107
        return;
108
    }
109
    $auth = AuthProvider::getInstance();
110
    $message = false;
111
    if(validateCanCreateUser($obj, $auth, $message) === false)
112
    {
113
        echo json_encode(array('res'=>false, 'message'=>$message));
114
        return;
115
    }
116
    else if(validEmail($obj->mail) === false)
117
    {
118
        echo json_encode(array('res'=>false, 'message'=>'Invalid Email Address!'));
119
        return;
120
    }
121
    $ret = $auth->createPendingUser($obj);
122
    echo json_encode($ret);
123
}
124
125
function userIsMe($app, $uid)
126
{
127
    return ($uid === 'me' || $uid === $app->user->uid);
128
}
129
130 View Code Duplication
function getUserByUIDReadOnly($app, $uid)
0 ignored issues
show
Duplication introduced by
This function 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...
131
{
132
    if(userIsMe($app, $uid))
133
    {
134
        return $app->user;
135
    }
136
    if($app->user->isInGroupNamed('LDAPAdmins') || hasLeadAccess($app))
137
    {
138
        $auth = \AuthProvider::getInstance();
139
        $filter = new \Data\Filter("uid eq $uid");
140
        $users = $auth->getUsersByFilter($filter);
141
        if($users !== false && isset($users[0]))
142
        {
143
            return $users[0];
144
        }
145
    }
146
    return false;
147
}
148
149 View Code Duplication
function getUserByUID($app, $uid)
0 ignored issues
show
Duplication introduced by
This function 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...
150
{
151
    if(userIsMe($app, $uid))
152
    {
153
        return $app->user;
154
    }
155
    if($app->user->isInGroupNamed('LDAPAdmins'))
156
    {
157
        $auth = \AuthProvider::getInstance();
158
        $filter = new \Data\Filter("uid eq $uid");
159
        $users = $auth->getUsersByFilter($filter);
160
        if($users !== false && isset($users[0]))
161
        {
162
            return $users[0];
163
        }
164
    }
165
    return false;
166
}
167
168
function show_user($uid = 'me')
169
{
170
    global $app;
171
    if(!$app->user)
172
    {
173
        if($_SERVER['SERVER_ADDR'] === $_SERVER['REMOTE_ADDR'])
174
        {
175
            $user = \AuthProvider::getInstance()->getUsersByFilter(new \Data\Filter("uid eq $uid"));
176
            if($user === false || !isset($user[0]))
177
            {
178
                $app->notFound();
179
            }
180
            echo $user[0]->serializeObject();
181
            return;
182
        } 
183
        $app->response->setStatus(401);
184
        return;
185
    }
186
    $user = getUserByUIDReadOnly($app, $uid);
187
    if($user === false)
188
    {
189
        $app->halt(404);
190
    }
191
    if(!is_object($user) && isset($user[0]))
192
    {
193
        $user = $user[0];
194
    }
195
    if($app->fmt === 'vcard')
196
    {
197
        $app->response->headers->set('Content-Type', 'text/x-vCard');
198
        echo $user->getVcard();
199
        $app->fmt = 'passthru';
200
    }
201
    else
202
    {
203
        echo $user->serializeObject();
204
    }
205
}
206
207
function sendPasswordResetEmail($user)
208
{
209
    $forwardedFor = false;
210
    if(isset($_SERVER['HTTP_X_FORWARDED_FOR']))
211
    {
212
        $forwardedFor = $_SERVER['HTTP_X_FORWARDED_FOR'];
213
    }
214
    $emailMsg = new PasswordHasBeenResetEmail($user, $_SERVER['REMOTE_ADDR'], $forwardedFor);
215
    $emailProvider = EmailProvider::getInstance();
216
    if($emailProvider->sendEmail($emailMsg) === false)
217
    {
218
        throw new \Exception('Unable to send password reset email!');
219
    }
220
}
221
222
function exceptionCodeToHttpCode($e)
223
{
224
    if($e->getCode() === 3)
225
    {
226
        return 401;
227
    }
228
    return 500;
229
}
230
231
function getUser($app, $uid, $payload)
232
{
233
    if(!$app->user)
234
    {
235
        if(isset($payload->hash))
236
        {
237
            $auth = AuthProvider::getInstance();
238
            $app->user = $auth->getUserByResetHash($payload->hash);
239
            return $app->user;
240
        }
241
        return false;
242
    }
243
    return getUserByUID($app, $uid);
244
}
245
246
function editUser($uid = 'me')
247
{
248
    global $app;
249
    $obj = $app->getJsonBody();
250
    $user = getUser($app, $uid, $obj);
251
    if($user === false)
252
    {
253
        $app->response->setStatus(404);
254
        return;
255
    }
256
    try
257
    {
258
        if(isset($obj->old_uid))
259
        {
260
            unset($obj->old_uid);
261
        }
262
        $user->editUser($obj);
263
    }
264
    catch(\Exception $e)
265
    {
266
        $app->response->setStatus(exceptionCodeToHttpCode($e));
267
        echo json_encode($e);
268
        return;
269
    }
270
    if(userIsMe($app, $uid))
271
    {
272
        \FlipSession::setUser($user);
273
    }
274
    if(isset($obj->password))
275
    {
276
        sendPasswordResetEmail($user);
277
    }
278
    echo json_encode(array('success'=>true));
279
}
280
281
function deleteUser($uid = 'me')
282
{
283
    global $app;
284
    if(!$app->user)
285
    {
286
        $app->response->setStatus(401);
287
        return;
288
    }
289
    $user = false;
290
    if(userIsMe($app, $uid))
291
    {
292
        $user = $app->user;
293
    }
294
    else if($app->user->isInGroupNamed("LDAPAdmins"))
295
    {
296
        $auth = AuthProvider::getInstance();
297
        $filter = new \Data\Filter("uid eq $uid");
298
        $user = $auth->getUsersByFilter($filter);
299
        if(isset($user[0]))
300
        {
301
            $user = $user[0];
302
        }
303
    }
304
    return $user->delete();
305
}
306
307
function list_groups_for_user($uid = 'me')
308
{
309
    global $app;
310
    if(!$app->user)
311
    {
312
        $app->response->setStatus(401);
313
        return;
314
    }
315
    $user = getUserByUID($app, $uid);
316
    if($user === false)
317
    {
318
        $app->response->setStatus(404);
319
        return;
320
    }
321
    $groups = $user->getGroups();
322
    if($groups === false)
323
    {
324
        echo json_encode(array());
325
    }
326
    else
327
    {
328
        echo json_encode($groups);
329
    }
330
}
331
332
function link_user($uid = 'me')
333
{
334
    global $app;
335
    if(!$app->user)
336
    {
337
        $app->response->setStatus(401);
338
        return;
339
    }
340
    $body = $app->request->getBody();
341
    $obj  = json_decode($body);
342
    if(userIsMe($uid))
0 ignored issues
show
Bug introduced by
The call to userIsMe() misses a required argument $uid.

This check looks for function calls that miss required arguments.

Loading history...
343
    {
344
        $app->user->addLoginProvider($obj->provider);
345
        AuthProvider::getInstance()->impersonateUser($app->user);
346
    }
347
    else if($app->user->isInGroupNamed("LDAPAdmins"))
348
    {
349
        $user = AuthProvider::getInstance()->getUser($uid);
350
        if($user === false)
351
        {
352
            $app->response->setStatus(404);
353
            return;
354
        }
355
        $user->addLoginProvider($obj->provider);
356
    }
357
    else
358
    {
359
        $app->response->setStatus(404);
360
        return;
361
    }
362
    echo json_encode(array('success'=>true));
363
}
364
365
function getAllUsersByFilter($filter, &$pending)
366
{
367
    $auth = AuthProvider::getInstance();
368
    $user = $auth->getUsersByFilter($filter);
369 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...
370
    {
371
        $pending = false;
372
        return $user[0];
373
    }
374
    $user = $auth->getPendingUsersByFilter($filter);
375 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...
376
    {
377
        $pending = true;
378
        return $user[0];
379
    }
380
    return false;
381
}
382
383
function check_email_available()
384
{
385
    global $app;
386
    $email = $app->request->params('email');
387
    if(strpos($email, '@') === false)
388
    {
389
        //Not a valid email
390
        echo 'false';
391
    }
392
    if(strstr($email, '+') !== false)
393
    {
394
        //Remove everything between the + and the @
395
        $begining = strpos($email, '+');
396
        $end = strpos($email, '@');
397
        $to_delete = substr($email, $begining, $end - $begining);
398
        $email = str_replace($to_delete, '', $email);
399
    }
400
    $filter = new \Data\Filter('mail eq '.$email);
401
    $pending = false;
402
    $user = getAllUsersByFilter($filter, $pending);
403
    if($user === false)
404
    {
405
        echo 'true';
406
        return;
407
    }
408
    echo json_encode(array('res'=>false, 'email'=>$user->mail, 'pending'=>$pending));
409
}
410
411
function check_uid_available()
412
{
413
    global $app;
414
    $uid = $app->request->params('uid');
415
    if(strpos($uid, '=') !== false || strpos($uid, ',') !== false)
416
    {
417
        return false;
418
    }
419
    $filter = new \Data\Filter('uid eq '.$uid);
420
    $pending = false;
421
    $user = getAllUsersByFilter($filter, $pending);
422
    if($user === false)
423
    {
424
        echo 'true';
425
        return;
426
    }
427
    echo json_encode(array('res'=>false, 'uidl'=>$user->uid, 'pending'=>$pending));
428
}
429
430 View Code Duplication
function reset_pass($uid)
0 ignored issues
show
Duplication introduced by
This function 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...
431
{
432
    global $app;
433
    $auth = AuthProvider::getInstance();
434
    $users = $auth->getUsersByFilter(new \Data\Filter('uid eq '.$uid));
435
    if($users === false || !isset($users[0]))
436
    {
437
        $app->response->setStatus(404);
438
        return;
439
    }
440
    else
441
    {
442
        $email_msg = new PasswordResetEmail($users[0]);
443
        $email_provider = EmailProvider::getInstance();
444
        if($email_provider->sendEmail($email_msg) === false)
445
        {
446
            throw new \Exception('Unable to send email!');
447
        }
448
    }
449
}
450
451 View Code Duplication
function remind_uid()
0 ignored issues
show
Duplication introduced by
This function 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...
452
{
453
    global $app;
454
    $email = $app->request->params('email');
455
    $auth = AuthProvider::getInstance();
456
    $users = $auth->getUsersByFilter(new \Data\Filter('mail eq '.$email));
457
    if($users === false || !isset($users[0]))
458
    {
459
        $app->response->setStatus(404);
460
        return;
461
    }
462
    else
463
    {
464
        $email_msg = new UIDForgotEmail($users[0]);
465
        $email_provider = EmailProvider::getInstance();
466
        if($email_provider->sendEmail($email_msg) === false)
467
        {
468
            throw new \Exception('Unable to send email!');
469
        }
470
    }
471
}
472
/* vim: set tabstop=4 shiftwidth=4 expandtab: */
473
?>
0 ignored issues
show
Best Practice introduced by
It is not recommended to use PHP's closing tag ?> in files other than templates.

Using a closing tag in PHP files that only contain PHP code is not recommended as you might accidentally add whitespace after the closing tag which would then be output by PHP. This can cause severe problems, for example headers cannot be sent anymore.

A simple precaution is to leave off the closing tag as it is not required, and it also has no negative effects whatsoever.

Loading history...
474