Completed
Push — master ( 83a2a5...ced03c )
by Patrick
03:16
created

users.php ➔ getUser()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 13
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 3
eloc 7
c 1
b 0
f 0
nc 3
nop 3
dl 0
loc 13
rs 9.4285
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
function create_user()
64
{
65
    global $app;
66
    //This one is different. If they are logged in fail...
67
    if($app->user)
68
    {
69
        $app->response->setStatus(404);
70
        return;
71
    }
72
    $body = $app->request->getBody();
73
    $obj  = json_decode($body);
74
    if(!isset($obj->captcha))
75
    {
76
        $app->response->setStatus(401);
77
        return;
78
    }
79
    $captcha = FlipSession::getVar('captcha');
80
    if($captcha === false)
81
    {
82
        $app->response->setStatus(401);
83
        return;
84
    }
85
    if(!$captcha->is_answer_right($obj->captcha))
86
    {
87
        echo json_encode(array('res'=>false, 'message'=>'Incorrect answer to CAPTCHA!'));
88
        return;
89
    }
90
    $auth = AuthProvider::getInstance();
91
    $message = false;
92
    if(validateCanCreateUser($obj, $auth, $message) === false)
93
    {
94
        echo json_encode(array('res'=>false, 'message'=>$message));
95
        return;
96
    }
97
    $ret = $auth->createPendingUser($obj);
98
    echo json_encode($ret);
99
}
100
101
function userIsMe($app, $uid)
102
{
103
    return ($uid === 'me' || $uid === $app->user->uid);
104
}
105
106
function getUserByUIDReadOnly($app, $uid)
107
{
108
    if(userIsMe($app, $uid))
109
    {
110
        return $app->user;
111
    }
112
    if($app->user->isInGroupNamed('LDAPAdmins') || $app->user->isInGroupNamed('Leads') || $app->user->isInGroupNamed('CC'))
113
    {
114
        $auth = \AuthProvider::getInstance();
115
        $filter = new \Data\Filter("uid eq $uid");
116
        $users = $auth->getUsersByFilter($filter);
117
        if($users !== false && isset($users[0]))
118
        {
119
            return $users[0];
120
        }
121
    }
122
    return false;
123
}
124
125
function getUserByUID($app, $uid)
126
{
127
    if(userIsMe($app, $uid))
128
    {
129
        return $app->user;
130
    }
131 View Code Duplication
    if($app->user->isInGroupNamed('LDAPAdmins'))
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...
132
    {
133
        $auth = \AuthProvider::getInstance();
134
        $filter = new \Data\Filter("uid eq $uid");
135
        $users = $auth->getUsersByFilter($filter);
136
        if($users !== false && isset($users[0]))
137
        {
138
            return $users[0];
139
        }
140
    }
141
    return false;
142
}
143
144
function show_user($uid = 'me')
145
{
146
    global $app;
147
    if(!$app->user)
148
    {
149
        $app->response->setStatus(401);
150
        return;
151
    }
152
    $user = getUserByUIDReadOnly($app, $uid);
153
    if($user === false)
154
    {
155
        $app->halt(404);
156
    }
157
    if(!is_object($user) && isset($user[0]))
158
    {
159
        $user = $user[0];
160
    }
161
    if($app->fmt === 'vcard')
162
    {
163
        $app->response->headers->set('Content-Type', 'text/x-vCard');
164
        echo $user->getVcard();
165
        $app->fmt = 'passthru';
166
    }
167
    else
168
    {
169
        echo $user->serializeObject();
170
    }
171
}
172
173
function sendPasswordResetEmail($user)
174
{
175
    $forwardedFor = false;
176
    if(isset($_SERVER['HTTP_X_FORWARDED_FOR']))
177
    {
178
        $forwardedFor = $_SERVER['HTTP_X_FORWARDED_FOR'];
179
    }
180
    $emailMsg = new PasswordHasBeenResetEmail($user, $_SERVER['REMOTE_ADDR'], $forwardedFor);
181
    $emailProvider = EmailProvider::getInstance();
182
    if($emailProvider->sendEmail($emailMsg) === false)
183
    {
184
        throw new \Exception('Unable to send password reset email!');
185
    }
186
}
187
188
function exceptionCodeToHttpCode($e)
189
{
190
    if($e->getCode() === 3)
191
    {
192
        return 401;
193
    }
194
    return 500;
195
}
196
197
function getUser($app, $uid, $payload)
198
{
199
    if(!$app->user)
200
    {
201
        if(isset($payload->hash))
202
        {
203
            $auth = AuthProvider::getInstance();
204
            $app->user = $auth->getUserByResetHash($payload->hash);
205
        }
206
        return false;
207
    }
208
    return getUserByUID($app, $uid);
209
}
210
211
function editUser($uid = 'me')
212
{
213
    global $app;
214
    $obj = $app->request->getJsonBody();
215
    $user = getUser($app, $uid, $obj);
216
    if($user === false)
217
    {
218
        $app->response->setStatus(404);
219
        return;
220
    }
221
    try
222
    {
223
        $user->editUser($obj);
224
    }
225
    catch(\Exception $e)
226
    {
227
        $app->response->setStatus(exceptionCodeToHttpCode($e));
228
        echo json_encode($e);
229
        return;
230
    }
231
    if(userIsMe($app, $uid))
232
    {
233
        \FlipSession::setUser($user);
234
    }
235
    if(isset($obj->password))
236
    {
237
        sendPasswordResetEmail($user);
238
    }
239
    echo json_encode(array('success'=>true));
240
}
241
242
function deleteUser($uid = 'me')
243
{
244
    global $app;
245
    if(!$app->user)
246
    {
247
        $app->response->setStatus(401);
248
        return;
249
    }
250
    $user = false;
251
    if(userIsMe($app, $uid))
252
    {
253
        $user = $app->user;
254
    }
255 View Code Duplication
    else if($app->user->isInGroupNamed("LDAPAdmins"))
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...
256
    {
257
        $auth = AuthProvider::getInstance();
258
        $filter = new \Data\Filter("uid eq $uid");
259
        $user = $auth->getUsersByFilter($filter);
260
        if(isset($user[0]))
261
        {
262
            $user = $user[0];
263
        }
264
    }
265
    return $user->delete();
266
}
267
268
function list_groups_for_user($uid = 'me')
269
{
270
    global $app;
271
    if(!$app->user)
272
    {
273
        $app->response->setStatus(401);
274
        return;
275
    }
276
    $user = getUserByUID($app, $uid);
277
    if($user === false)
278
    {
279
        $app->response->setStatus(404);
280
        return;
281
    }
282
    $groups = $user->getGroups();
283
    if($groups === false)
284
    {
285
        echo json_encode(array());
286
    }
287
    else
288
    {
289
        echo json_encode($groups);
290
    }
291
}
292
293
function link_user($uid = 'me')
294
{
295
    global $app;
296
    if(!$app->user)
297
    {
298
        $app->response->setStatus(401);
299
        return;
300
    }
301
    $body = $app->request->getBody();
302
    $obj  = json_decode($body);
303
    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...
304
    {
305
        $app->user->addLoginProvider($obj->provider);
306
        AuthProvider::getInstance()->impersonateUser($app->user);
307
    }
308
    else if($app->user->isInGroupNamed("LDAPAdmins"))
309
    {
310
        $user = AuthProvider::getInstance()->getUser($uid);
311
        if($user === false)
312
        {
313
            $app->response->setStatus(404);
314
            return;
315
        }
316
        $user->addLoginProvider($obj->provider);
317
    }
318
    else
319
    {
320
        $app->response->setStatus(404);
321
        return;
322
    }
323
    echo json_encode(array('success'=>true));
324
}
325
326
function getAllUsersByFilter($filter, &$pending)
327
{
328
    $auth = AuthProvider::getInstance();
329
    $user = $auth->getUsersByFilter($filter);
330 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...
331
    {
332
        $pending = false;
333
        return $user[0];
334
    }
335
    $user = $auth->getPendingUsersByFilter($filter);
336 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...
337
    {
338
        $pending = true;
339
        return $user[0];
340
    }
341
    return false;
342
}
343
344
function check_email_available()
345
{
346
    global $app;
347
    $email = $app->request->params('email');
348
    if(strpos($email, '@') === false)
349
    {
350
        //Not a valid email
351
        echo 'false';
352
    }
353
    if(strstr($email, '+') !== false)
354
    {
355
        //Remove everything between the + and the @
356
        $begining = strpos($email, '+');
357
        $end = strpos($email, '@');
358
        $to_delete = substr($email, $begining, $end - $begining);
359
        $email = str_replace($to_delete, '', $email);
360
    }
361
    $filter = new \Data\Filter('mail eq '.$email);
362
    $pending = false;
363
    $user = getAllUsersByFilter($filter, $pending);
364
    if($user === false)
365
    {
366
        echo 'true';
367
        return;
368
    }
369
    echo json_encode(array('res'=>false, 'email'=>$user->mail, 'pending'=>$pending));
370
}
371
372
function check_uid_available()
373
{
374
    global $app;
375
    $uid = $app->request->params('uid');
376
    if(strpos($uid, '=') !== false || strpos($uid, ',') !== false)
377
    {
378
        return false;
379
    }
380
    $filter = new \Data\Filter('uid eq '.$uid);
381
    $pending = false;
382
    $user = getAllUsersByFilter($filter, $pending);
383
    if($user === false)
384
    {
385
        echo 'true';
386
        return;
387
    }
388
    echo json_encode(array('res'=>false, 'uidl'=>$user->uid, 'pending'=>$pending));
389
}
390
391 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...
392
{
393
    global $app;
394
    $auth = AuthProvider::getInstance();
395
    $users = $auth->getUsersByFilter(new \Data\Filter('uid eq '.$uid));
396
    if($users === false || !isset($users[0]))
397
    {
398
        $app->response->setStatus(404);
399
        return;
400
    }
401
    else
402
    {
403
        $email_msg = new PasswordResetEmail($users[0]);
404
        $email_provider = EmailProvider::getInstance();
405
        if($email_provider->sendEmail($email_msg) === false)
406
        {
407
            throw new \Exception('Unable to send email!');
408
        }
409
    }
410
}
411
412 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...
413
{
414
    global $app;
415
    $email = $app->request->params('email');
416
    $auth = AuthProvider::getInstance();
417
    $users = $auth->getUsersByFilter(new \Data\Filter('mail eq '.$email));
418
    if($users === false || !isset($users[0]))
419
    {
420
        $app->response->setStatus(404);
421
        return;
422
    }
423
    else
424
    {
425
        $email_msg = new UIDForgotEmail($users[0]);
426
        $email_provider = EmailProvider::getInstance();
427
        if($email_provider->sendEmail($email_msg) === false)
428
        {
429
            throw new \Exception('Unable to send email!');
430
        }
431
    }
432
}
433
/* vim: set tabstop=4 shiftwidth=4 expandtab: */
434
?>
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...
435