Completed
Push — master ( f2ef51...ef379e )
by Patrick
03:21
created

User::getOrganization()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %
Metric Value
cc 1
eloc 2
nc 1
nop 0
dl 0
loc 4
rs 10
1
<?php
2
/**
3
 * User class
4
 *
5
 * This file describes the User classes
6
 *
7
 * PHP version 5 and 7
8
 *
9
 * @author Patrick Boyd / [email protected]
10
 * @copyright Copyright (c) 2015, Austin Artistic Reconstruction
11
 * @license http://www.apache.org/licenses/ Apache 2.0 License
12
 */
13
14
namespace Auth;
15
16
/**
17
 * A class to abstract access to Users regardless of the Authentication type used.
18
 *
19
 * This class is the primary method to access user information.
20
 */
21
class User extends \SerializableObject
22
{
23
    /**
24
     * An array to cache the title to string mappings so that they don't need to be pulled from the database
25
     * everytime
26
     */ 
27
    public static $titlenames = null;
28
29
    /**
30
     * Is this user in the Group or a child of that group?
31
     *
32
     * @param string $name The name of the group to check if the user is in
33
     *
34
     * @return true|false True if the user is in the group, false otherwise
35
     */
36
    public function isInGroupNamed($name)
37
    {
38
        return false;
39
    }
40
41
    /**
42
     * The name the user should be displayed as
43
     *
44
     * @return string The name the user should be displayed as
45
     */
46
    public function getDisplayName()
47
    {
48
        return $this->getNickName();
49
    }
50
51
    /**
52
     * The given (or first) name for the user
53
     *
54
     * @return string The user's first name
55
     */
56
    public function getGivenName()
57
    {
58
        return $this->getUid();
59
    }
60
61
    /**
62
     * The email address for the user
63
     *
64
     * @return string The user's email address
65
     */
66
    public function getEmail()
67
    {
68
        return false;
69
    }
70
71
    /**
72
     * The user ID for the user
73
     *
74
     * @return string The user's ID or username
75
     */
76
    public function getUid()
77
    {
78
        return $this->getEmail();
79
    }
80
81
    /**
82
     * The photo for the user
83
     *
84
     * @return string The user's photo as a binary string
85
     */ 
86
    public function getPhoto()
87
    {
88
        return false;
89
    }
90
91
    /**
92
     * The phone number for the user
93
     *
94
     * @return false|string The user's phone number
95
     */
96
    public function getPhoneNumber()
97
    {
98
        return false;
99
    }
100
101
    /**
102
     * The organziation for the user
103
     *
104
     * @return false|string The user's organization
105
     */
106
    public function getOrganization()
107
    {
108
        return false;
109
    }
110
111
    /**
112
     * The list of titles for the user
113
     *
114
     * @return array The user's title(s) in short format
115
     */
116
    public function getTitles()
117
    {
118
        return false;
119
    }
120
121
    /**
122
     * The list of titles for the user
123
     *
124
     * @return array The user's title(s) in user friendly strings
125
     *
126
     * @SuppressWarnings("StaticAccess")
127
     */
128
    public function getTitleNames()
129
    {
130
        $titles = $this->getTitles();
131
        if($titles === false)
132
        {
133
            return false;
134
        }
135
        if(self::$titlenames === null)
136
        {
137
            $dataSet = \DataSetFactory::getDataSetByName('profiles');
138
            $dataTable = $dataSet['position'];
139
            $titlenames = $dataTable->read();
140
            self::$titlenames = array();
141
            $count = count($titlenames);
142
            for($i = 0; $i < $count; $i++)
143
            {
144
                self::$titlenames[$titlenames[$i]['short_name']] = $titlenames[$i];
145
            }
146
        }
147
        $count = count($titles);
148
        for($i = 0; $i < $count; $i++)
149
        {
150
            if(isset(self::$titlenames[$titles[$i]]))
151
            {
152
                $title = self::$titlenames[$titles[$i]];
153
                $titles[$i] = $title['name'];
154
            }
155
        }
156
        return $titles;
157
    }
158
159
    /**
160
     * The state the user's mailing address is in
161
     *
162
     * @return string The user's state from their mailing address
163
     */
164
    public function getState()
165
    {
166
        return false;
167
    }
168
169
    /**
170
     * The city the user's mailing address is in
171
     *
172
     * @return string The user's city from their mailing address
173
     */
174
    public function getCity()
175
    {
176
        return false;
177
    }
178
179
    /**
180
     * The last name for the user
181
     *
182
     * @return string The user's last name
183
     */
184
    public function getLastName()
185
    {
186
        return false;
187
    }
188
189
    /**
190
     * The nick name for the user
191
     *
192
     * @return string The user's nick name
193
     */
194
    public function getNickName()
195
    {
196
        return $this->getUid();
197
    }
198
199
    /**
200
     * The street address for the user
201
     *
202
     * @return string The user's street address
203
     */
204
    public function getAddress()
205
    {
206
        return false;
207
    }
208
209
    /**
210
     * The postal (zip) code for the user's mailing address
211
     *
212
     * @return string The user's postal code
213
     */
214
    public function getPostalCode()
215
    {
216
        return false;
217
    }
218
219
    /**
220
     * The country the user's mailing address is in
221
     *
222
     * @return string The user's country from their mailing address
223
     */
224
    public function getCountry()
225
    {
226
        return false;
227
    }
228
229
    /**
230
     * The organizational units the user is in
231
     *
232
     * This is the same as Areas in Flipside speak. 
233
     *
234
     * @return array The user's orgnaiational units
235
     */
236
    public function getOrganizationUnits()
237
    {
238
        return false;
239
    }
240
241
    /**
242
     * The supplemental login types that the user can use to login
243
     *
244
     * @return array The user's login providers
245
     */
246
    public function getLoginProviders()
247
    {
248
        return false;
249
    }
250
251
    /**
252
     * The groups the user is a part of
253
     *
254
     * @return false|array The user's Auth\Group structures
255
     */
256
    public function getGroups()
257
    {
258
        return false;
259
    }
260
261
    /**
262
     * Add a supplemental login type that the user can use to login
263
     *
264
     * @param string $provider The hostname for the provider
265
     *
266
     * @return true|false true if the addition worked, false otherwise
267
     */
268
    public function addLoginProvider($provider)
269
    {
270
        throw new \Exception('Cannot add provider for this login type!');
271
    }
272
273
    /**
274
     * Can the user login with this provider?
275
     *
276
     * @param string $provider The hostname for the provider
277
     *
278
     * @return true|false true if they can login with the provider, false otherwise
279
     */
280
    public function canLoginWith($provider)
281
    {
282
        $hosts = $this->getLoginProviders();
283
        if($hosts === false) return false;
284
        $count = count($hosts);
285
        for($i = 0; $i < $count; $i++)
286
        {
287
            if(strcasecmp($hosts[$i], $provider) === 0) return true;
288
        }
289
        return false;
290
    }
291
292
    /**
293
     * Set the user's password without verifying the current password
294
     *
295
     * @param string $password The new user password
296
     *
297
     * @return true|false true if the user's password was changed, false otherwise
298
     */
299
    protected function setPass($password)
300
    {
301
        return false;
302
    }
303
304
    /**
305
     * Has the user completely filled out their user profile?
306
     *
307
     * @return true|false true if the user's profile is complete, false otherwise
308
     */
309
    public function isProfileComplete()
310
    {
311
        if($this->getCountry() === false    || $this->getAddress() === false ||
312
           $this->getPostalCode() === false || $this->getCity() === false ||
313
           $this->getState() === false      || $this->getPhoneNumber() === false)
314
        {
315
            return false;
316
        }
317
        return true;
318
    }
319
320
    /**
321
     * Validate that the user's password is the specified password
322
     *
323
     * @param string $password The user's current password
324
     *
325
     * @return true|false true if the user's password is correct, false otherwise
326
     *
327
     * @SuppressWarnings("UnusedFormalParameter")
328
     */
329
    public function validate_password($password)
330
    {
331
        return false;
332
    }
333
334
    /**
335
     * Validate that the user's reset hash is the sepcified hash
336
     *
337
     * @param string $hash The user's reset hash
338
     *
339
     * @return true|false true if the user's hash is correct, false otherwise
340
     *
341
     * @SuppressWarnings("UnusedFormalParameter")
342
     */
343
    public function validate_reset_hash($hash)
344
    {
345
        return false;
346
    }
347
348
    /**
349
     * Change the user's password, validating the old password or reset hash
350
     *
351
     * @param string $oldpass The user's original password or reset hash if $isHash is true
352
     * @param string $newpass The user's new password
353
     * @param boolean $isHash Is $old_pass a password or a hash
354
     *
355
     * @return true|false true if the user's password was changed, false otherwise
356
     */
357
    public function change_pass($oldpass, $newpass, $isHash=false)
358
    {
359
        if($isHash === false && $this->validate_password($oldpass) === false)
360
        {
361
            throw new \Exception('Invalid Password!', 3);
362
        }
363
        if($isHash === true && $this->validate_reset_hash($oldpass) === false)
364
        {
365
            throw new \Exception('Invalid Reset Hash!', 3);
366
        }
367
        if($this->setPass($newpass) === false)
368
        {
369
            throw new \Exception('Unable to set password!', 6);
370
        }
371
        return true;
372
    }
373
374
    /**
375
     * Set the user's display name
376
     *
377
     * @param string $name The user's new display name
378
     *
379
     * @return true|false true if the user's display name was changed, false otherwise
380
     */
381
    public function setDisplayName($name)
382
    {
383
        return $this->setNickName($name);
384
    }
385
386
    /**
387
     * Set the user's given (first) name
388
     *
389
     * @param string $name The user's new given name
390
     *
391
     * @return true|false true if the user's given name was changed, false otherwise
392
     */
393
    public function setGivenName($name)
394
    {
395
        return $this->setUid($name);
396
    }
397
398
    /**
399
     * Set the user's email address
400
     *
401
     * @param string $email The user's new email address
402
     *
403
     * @return true|false true if the user's email address was changed, false otherwise
404
     *
405
     * @SuppressWarnings("UnusedFormalParameter")
406
     */
407
    public function setEmail($email)
408
    {
409
        return false;
410
    }
411
412
    /**
413
     * Set the user's user ID or user name
414
     *
415
     * @param string $uid The user's new user ID
416
     *
417
     * @return true|false true if the user's ID was changed, false otherwise
418
     *
419
     * @SuppressWarnings("UnusedFormalParameter")
420
     */
421
    public function setUid($uid)
422
    {
423
        return false;
424
    }
425
426
    /**
427
     * Set the user's photo
428
     *
429
     * @param string $photo The user's new photo as a binary string
430
     *
431
     * @return true|false true if the user's photo was changed, false otherwise
432
     *
433
     * @SuppressWarnings("UnusedFormalParameter")
434
     */
435
    public function setPhoto($photo)
436
    {
437
        return false;
438
    }
439
440
    /**
441
     * Set the user's phone number
442
     *
443
     * @param string $phone The user's new phonew number
444
     *
445
     * @return true|false true if the user's phone number was changed, false otherwise
446
     *
447
     * @SuppressWarnings("UnusedFormalParameter")
448
     */
449
    public function setPhoneNumber($phone)
450
    {
451
        return false;
452
    }
453
454
    /**
455
     * Set the user's organization
456
     *
457
     * @param string $org The user's new organization
458
     *
459
     * @return true|false true if the user's organization was changed, false otherwise
460
     *
461
     * @SuppressWarnings("UnusedFormalParameter")
462
     */
463
    public function setOrganization($org)
1 ignored issue
show
Unused Code introduced by
The parameter $org is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
464
    {
465
        return false;
466
    }
467
468
    /**
469
     * Set the user's titles
470
     *
471
     * @param string $titles The user's new titles
472
     *
473
     * @return true|false true if the user's titles were changed, false otherwise
474
     *
475
     * @SuppressWarnings("UnusedFormalParameter")
476
     */
477
    public function setTitles($titles)
478
    {
479
        return false;
480
    }
481
482
    /**
483
     * Set the user's state
484
     *
485
     * @param string $state The user's new state
486
     *
487
     * @return true|false true if the user's state was changed, false otherwise
488
     *
489
     * @SuppressWarnings("UnusedFormalParameter")
490
     */
491
    public function setState($state)
492
    {
493
        return false;
494
    }
495
496
    /**
497
     * Set the user's city
498
     *
499
     * @param string $city The user's new city
500
     *
501
     * @return true|false true if the user's city was changed, false otherwise
502
     *
503
     * @SuppressWarnings("UnusedFormalParameter")
504
     */
505
    public function setCity($city)
506
    {
507
        return false;
508
    }
509
510
    /**
511
     * Set the user's last name
512
     *
513
     * @param string $sn The user's new last name
514
     *
515
     * @return true|false true if the user's last name was changed, false otherwise
516
     *
517
     * @SuppressWarnings("UnusedFormalParameter")
518
     */
519
    public function setLastName($sn)
520
    {
521
        return false;
522
    }
523
524
    /**
525
     * Set the user's nick name
526
     *
527
     * @param string $displayName The user's new nick name
528
     *
529
     * @return true|false true if the user's nick name was changed, false otherwise
530
     */
531
    public function setNickName($displayName)
532
    {
533
        return $this->setUid($displayName);
534
    }
535
536
    /**
537
     * Set the user's mailing address
538
     *
539
     * @param string $address The user's new mailing address
540
     *
541
     * @return true|false true if the user's mailing address was changed, false otherwise
542
     *
543
     * @SuppressWarnings("UnusedFormalParameter")
544
     */
545
    public function setAddress($address)
546
    {
547
        return false;
548
    }
549
550
    /**
551
     * Set the user's postal or zip code
552
     *
553
     * @param string $postalcode The user's new postal code
554
     *
555
     * @return true|false true if the user's postal code was changed, false otherwise
556
     *
557
     * @SuppressWarnings("UnusedFormalParameter")
558
     */
559
    public function setPostalCode($postalcode)
560
    {
561
        return false;
562
    }
563
564
    /**
565
     * Set the user's country
566
     *
567
     * @param string $country The user's new country
568
     *
569
     * @return true|false true if the user's country was changed, false otherwise
570
     *
571
     * @SuppressWarnings("UnusedFormalParameter")
572
     */
573
    public function setCountry($country)
574
    {
575
        return false;
576
    }
577
578
    /**
579
     * Set the user's organizations
580
     *
581
     * @param string $ous The user's new organizations
582
     *
583
     * @return true|false true if the user's organizations was changed, false otherwise
584
     *
585
     * @SuppressWarnings("UnusedFormalParameter")
586
     */
587
    public function setOrganizationUnits($ous)
588
    {
589
        return false;
590
    }
591
592
    /**
593
     * Allow write for the user
594
     */
595
    protected function enableReadWrite()
596
    {
597
        //Make sure we are bound in write mode
598
        $auth = \AuthProvider::getInstance();
599
        $ldap = $auth->getAuthenticator('Auth\LDAPAuthenticator');
600
        $ldap->get_and_bind_server(true);
601
    }
602
603
    /**
604
     * Update the user password if required
605
     */
606
    private function editUserPassword($data)
607
    {
608
        if(isset($data->password))
609
        {
610
            if(isset($data->oldpass))
611
            {
612
                $this->change_pass($data->oldpass, $data->password);
613
                unset($data->oldpass);
614
            }
615
            else if(isset($data->hash))
616
            {
617
                $this->change_pass($data->hash, $data->password, true);
618
                unset($data->hash);
619
            }
620
            unset($data->password);
621
        }
622
    }
623
624
    private function editNames($data)
625
    {
626
        if(isset($data->displayName))
627
        {
628
            $this->setDisplayName($data->displayName);
629
            unset($data->displayName);
630
        }
631
        if(isset($data->givenName))
632
        {
633
            $this->setGivenName($data->givenName);
634
            unset($data->givenName);
635
        }
636
        if(isset($data->sn))
637
        {
638
            $this->setLastName($data->sn);
639
            unset($data->sn);
640
        }
641
        if(isset($data->cn))
642
        {
643
            $this->setNickName($data->cn);
1 ignored issue
show
Unused Code introduced by
The call to the method Auth\User::setNickName() seems un-needed as the method has no side-effects.

PHP Analyzer performs a side-effects analysis of your code. A side-effect is basically anything that might be visible after the scope of the method is left.

Let’s take a look at an example:

class User
{
    private $email;

    public function getEmail()
    {
        return $this->email;
    }

    public function setEmail($email)
    {
        $this->email = $email;
    }
}

If we look at the getEmail() method, we can see that it has no side-effect. Whether you call this method or not, no future calls to other methods are affected by this. As such code as the following is useless:

$user = new User();
$user->getEmail(); // This line could safely be removed as it has no effect.

On the hand, if we look at the setEmail(), this method _has_ side-effects. In the following case, we could not remove the method call:

$user = new User();
$user->setEmail('email@domain'); // This line has a side-effect (it changes an
                                 // instance variable).
Loading history...
644
            unset($data->cn);
645
        }
646
    }
647
648
    private function checkForUnsettableElements($data)
649
    {
650
        if(isset($data->mail))
651
        {
652
            if($data->mail !== $this->getEmail())
653
            {
654
                throw new \Exception('Unable to change email!');
655
            }
656
            unset($data->mail);
657
        }
658
        if(isset($data->uid))
659
        {
660
            if($data->uid !== $this->getUid())
661
            {
662
                throw new \Exception('Unable to change uid!');
663
            }
664
            unset($data->uid);
665
        }
666
    }
667
668
    private function editAddressElements($data)
669
    {
670
        if(isset($data->postalAddress))
671
        {
672
            $this->setAddress($data->postalAddress);
673
            unset($data->postalAddress);
674
        }
675
        if(isset($data->l))
676
        {
677
            $this->setCity($data->l);
678
            unset($data->l);
679
        }
680
        if(isset($data->st))
681
        {
682
            $this->setState($data->st);
683
            unset($data->st);
684
        }
685
        if(isset($data->postalCode))
686
        {
687
            $this->setPostalCode($data->postalCode);
688
            unset($data->postalCode);
689
        }
690
        if(isset($data->c))
691
        {
692
            $this->setCountry($data->c);
693
            unset($data->c);
694
        }
695
    }
696
697
    private function editOrganizationElements($data)
698
    {
699
        if(isset($data->o))
700
        {
701
            $this->setOrganization($data->o);
1 ignored issue
show
Unused Code introduced by
The call to the method Auth\User::setOrganization() seems un-needed as the method has no side-effects.

PHP Analyzer performs a side-effects analysis of your code. A side-effect is basically anything that might be visible after the scope of the method is left.

Let’s take a look at an example:

class User
{
    private $email;

    public function getEmail()
    {
        return $this->email;
    }

    public function setEmail($email)
    {
        $this->email = $email;
    }
}

If we look at the getEmail() method, we can see that it has no side-effect. Whether you call this method or not, no future calls to other methods are affected by this. As such code as the following is useless:

$user = new User();
$user->getEmail(); // This line could safely be removed as it has no effect.

On the hand, if we look at the setEmail(), this method _has_ side-effects. In the following case, we could not remove the method call:

$user = new User();
$user->setEmail('email@domain'); // This line has a side-effect (it changes an
                                 // instance variable).
Loading history...
702
            unset($data->o);
703
        }
704
        if(isset($data->title))
705
        {
706
            $this->setTitles($data->title);
707
            unset($data->title);
708
        }
709
        if(isset($data->ou))
710
        {
711
            $this->setOrganizationUnits($data->ou);
712
            unset($data->ou);
713
        }
714
    }
715
716
    /**
717
     * Modify the user given the provided data object
718
     *
719
     * @param stdClass $data The user's new data
720
     *
721
     * @return true|false true if the user's data was changed, false otherwise
722
     */
723
    public function editUser($data)
724
    {
725
        $this->enableReadWrite();
726
727
        $this->checkForUnsettableElements($data);
728
        $this->editUserPassword($data);
729
        $this->editNames($data);
730
        $this->editAddressElements($data);
731
        $this->editOrganizationElements($data);
732
733
        if(isset($data->jpegPhoto))
734
        {
735
            $this->setPhoto(base64_decode($data->jpegPhoto));
736
            unset($data->jpegPhoto);
737
        }
738
        if(isset($data->mobile))
739
        {
740
            $this->setPhoneNumber($data->mobile);
741
            unset($data->mobile);
742
        }
743
    }
744
745
    /**
746
     * Obtain the user's password reset hash
747
     *
748
     * @return string|false A hash if available, false otherwise
749
     */
750
    public function getPasswordResetHash()
751
    {
752
        return false;
753
    }
754
755
    /**
756
     * Serialize the user data into a format usable by the json_encode method
757
     *
758
     * @return array A simple keyed array representing the user
759
     */
760
    public function jsonSerialize()
761
    {
762
        $user = array();
763
        $user['displayName'] = $this->getDisplayName();
764
        $user['givenName'] = $this->getGivenName();
765
        $user['jpegPhoto'] = base64_encode($this->getPhoto());
766
        $user['mail'] = $this->getEmail();
767
        $user['mobile'] = $this->getPhoneNumber();
768
        $user['uid'] = $this->getUid();
769
        $user['o'] = $this->getOrganization();
770
        $user['title'] = $this->getTitles();
771
        $user['titlenames'] = $this->getTitleNames();
772
        $user['st'] = $this->getState();
773
        $user['l'] = $this->getCity();
774
        $user['sn'] = $this->getLastName();
775
        $user['cn'] = $this->getNickName();
776
        $user['postalAddress'] = $this->getAddress();
777
        $user['postalCode'] = $this->getPostalCode();
778
        $user['c'] = $this->getCountry();
779
        $user['ou'] = $this->getOrganizationUnits();
780
        $user['host'] = $this->getLoginProviders();
781
        $user['class'] = get_class($this);
782
        return $user;
0 ignored issues
show
Bug Best Practice introduced by
The return type of return $user; (array<string,boolean|string>) is incompatible with the return type of the parent method SerializableObject::jsonSerialize of type SerializableObject.

If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design.

Let’s take a look at an example:

class Author {
    private $name;

    public function __construct($name) {
        $this->name = $name;
    }

    public function getName() {
        return $this->name;
    }
}

abstract class Post {
    public function getAuthor() {
        return 'Johannes';
    }
}

class BlogPost extends Post {
    public function getAuthor() {
        return new Author('Johannes');
    }
}

class ForumPost extends Post { /* ... */ }

function my_function(Post $post) {
    echo strtoupper($post->getAuthor());
}

Our function my_function expects a Post object, and outputs the author of the post. The base class Post returns a simple string and outputting a simple string will work just fine. However, the child class BlogPost which is a sub-type of Post instead decided to return an object, and is therefore violating the SOLID principles. If a BlogPost were passed to my_function, PHP would not complain, but ultimately fail when executing the strtoupper call in its body.

Loading history...
783
    }
784
785
    /**
786
     * Serialize the user data into a VCARD 2.1 format
787
     *
788
     * @return string The VCARD for the user
789
     */
790
    public function getVcard()
791
    {
792
        $ret = "BEGIN:VCARD\nVERSION:2.1\n";
793
        $ret.= 'N:'.$this->getLastName().';'.$this->getGivenName()."\n";
794
        $ret.= 'FN:'.$this->getGivenName()."\n";
795
        $ret.= 'TITLE:'.implode(',', $this->getTitles())."\n";
796
        $ret.= "ORG: Austin Artistic Reconstruction\n";
797
        $ret.= 'TEL;TYPE=MOBILE,VOICE:'.$this->getPhoneNumber()."\n";
798
        $ret.= 'EMAIL;TYPE=PREF,INTERNET:'.$this->getEmail()."\n";
799
        $ret.= "END:VCARD\n";
800
        return $ret;
801
    }
802
}
803
/* vim: set tabstop=4 shiftwidth=4 expandtab: */
804
?>
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...
805