Completed
Push — master ( 93e8b1...f02d55 )
by Patrick
03:11
created

User::editNames()   B

Complexity

Conditions 5
Paths 16

Size

Total Lines 23
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Importance

Changes 3
Bugs 0 Features 0
Metric Value
cc 5
eloc 13
nc 16
nop 1
dl 0
loc 23
rs 8.5906
c 3
b 0
f 0
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
 * @property string $uid The user's ID or name
22
 * @property string $mail The user's email address
23
 * @property string $sn The user's surname (last name)
24
 * @property string $givenName The user's given name (first name)
25
 * @property string $cn The user's nick name
26
 * @property string $displayName The user's display name
27
 * @property string $postalAddress The user's mailing address
28
 * @property string $postalCode The user's postal or zip code
29
 * @property string $l The user's city
30
 * @property string $st The user's state or province
31
 * @property string $c The user's country
32
 * @property string $mobile The user's phone number
33
 * @property string $jpegPhoto The user's profile photo
34
 * @property array $host The service's the user can use to login
35
 * @property array $title The user's titles in the organization
36
 * @property string $o The user's organization
37
 * @property array $ou The user's units or areas within the organization
38
 */
39
class User extends \SerializableObject
40
{
41
    /**
42
     * An array to cache the title to string mappings so that they don't need to be pulled from the database
43
     * everytime
44
     */ 
45
    public static $titlenames = null;
46
47
    /**
48
     * An array of properties that cannot be set on a user
49
     */
50
    protected $unsettableElements = array(
51
        'uid',
52
        'email'
53
    );
54
55
    /**
56
     * Is this user in the Group or a child of that group?
57
     *
58
     * @param string $name The name of the group to check if the user is in
59
     *
60
     * @return boolean True if the user is in the group, false otherwise
61
     */
62
    public function isInGroupNamed($name)
63
    {
64
        return false;
65
    }
66
67
    public function __get($propName)
68
    {
69
        return false;
70
    }
71
72
    public function __set($propName, $value)
73
    {
74
    }
75
76
    public function __isset($propName)
77
    {
78
        return false;
79
    }
80
81
    /**
82
     * The list of titles for the user
83
     *
84
     * @return boolean|array The user's title(s) in user friendly strings
85
     *
86
     * @SuppressWarnings("StaticAccess")
87
     */
88
    public function getTitleNames()
89
    {
90
        $titles = $this->title;
91
        if($titles === false)
92
        {
93
            return false;
94
        }
95
        if(self::$titlenames === null)
96
        {
97
            $dataSet = \DataSetFactory::getDataSetByName('profiles');
98
            $dataTable = $dataSet['position'];
99
            $titlenames = $dataTable->read();
100
            self::$titlenames = array();
101
            $count = count($titlenames);
102
            for($i = 0; $i < $count; $i++)
103
            {
104
                self::$titlenames[$titlenames[$i]['short_name']] = $titlenames[$i];
105
            }
106
        }
107
        $count = count($titles);
108
        for($i = 0; $i < $count; $i++)
109
        {
110
            if(isset(self::$titlenames[$titles[$i]]))
111
            {
112
                $title = self::$titlenames[$titles[$i]];
113
                $titles[$i] = $title['name'];
114
            }
115
        }
116
        return $titles;
117
    }
118
119
    /**
120
     * The groups the user is a part of
121
     *
122
     * @return boolean|array The user's Auth\Group structures
123
     */
124
    public function getGroups()
125
    {
126
        return false;
127
    }
128
129
    /**
130
     * Add a supplemental login type that the user can use to login
131
     *
132
     * @param string $provider The hostname for the provider
133
     */
134
    public function addLoginProvider($provider)
135
    {
136
        if(isset($this->host))
137
        {
138
            $tmp = $this->host;
139
            $tmp[] = $provider;
140
            $this->host = $tmp;
141
        }
142
        else
143
        {
144
            $this->host = array($provider);
145
        }
146
    }
147
148
    /**
149
     * Can the user login with this provider?
150
     *
151
     * @param string $provider The hostname for the provider
152
     *
153
     * @return boolean true if they can login with the provider, false otherwise
154
     */
155
    public function canLoginWith($provider)
156
    {
157
        $hosts = $this->host;
158
        if($hosts === false)
159
        {
160
            return false;
161
        }
162
        $count = count($hosts);
163
        for($i = 0; $i < $count; $i++)
164
        {
165
            if(strcasecmp($hosts[$i], $provider) === 0)
166
            {
167
                return true;
168
            }
169
        }
170
        return false;
171
    }
172
173
    /**
174
     * Set the user's password without verifying the current password
175
     *
176
     * @param string $password The new user password
177
     *
178
     * @return boolean true if the user's password was changed, false otherwise
179
     */
180
    protected function setPass($password)
181
    {
182
        return false;
183
    }
184
185
    /**
186
     * Has the user completely filled out their user profile?
187
     *
188
     * @return boolean true if the user's profile is complete, false otherwise
189
     */
190
    public function isProfileComplete()
191
    {
192
        if($this->c === false || $this->postalAddress === false ||
193
           $this->postalCode === false || $this->l === false ||
194
           $this->st === false || $this->mobile === false)
195
        {
196
            return false;
197
        }
198
        return true;
199
    }
200
201
    /**
202
     * Validate that the user's password is the specified password
203
     *
204
     * @param string $password The user's current password
205
     *
206
     * @return boolean true if the user's password is correct, false otherwise
207
     *
208
     * @SuppressWarnings("UnusedFormalParameter")
209
     */
210
    public function validate_password($password)
211
    {
212
        return false;
213
    }
214
215
    /**
216
     * Validate that the user's reset hash is the sepcified hash
217
     *
218
     * @param string $hash The user's reset hash
219
     *
220
     * @return boolean true if the user's hash is correct, false otherwise
221
     *
222
     * @SuppressWarnings("UnusedFormalParameter")
223
     */
224
    public function validate_reset_hash($hash)
225
    {
226
        return false;
227
    }
228
229
    /**
230
     * Change the user's password, validating the old password or reset hash
231
     *
232
     * @param string $oldpass The user's original password or reset hash if $isHash is true
233
     * @param string $newpass The user's new password
234
     * @param boolean $isHash Is $old_pass a password or a hash
235
     *
236
     * @return boolean true if the user's password was changed, false otherwise
237
     */
238
    public function change_pass($oldpass, $newpass, $isHash = false)
239
    {
240
        if($isHash === false && $this->validate_password($oldpass) === false)
241
        {
242
            throw new \Exception('Invalid Password!', 3);
243
        }
244
        if($isHash === true && $this->validate_reset_hash($oldpass) === false)
245
        {
246
            throw new \Exception('Invalid Reset Hash!', 3);
247
        }
248
        if($this->setPass($newpass) === false)
249
        {
250
            throw new \Exception('Unable to set password!', 6);
251
        }
252
        return true;
253
    }
254
255
    /**
256
     * Allow write for the user
257
     */
258
    protected function enableReadWrite()
259
    {
260
        //Make sure we are bound in write mode
261
        $auth = \AuthProvider::getInstance();
262
        $ldap = $auth->getMethodByName('Auth\LDAPAuthenticator');
263
        if($ldap !== false)
264
        {
265
            $ldap->get_and_bind_server(true);
266
        }
267
    }
268
269
    /**
270
     * Update the user password if required
271
     */
272
    private function editUserPassword($data)
273
    {
274
        if(isset($data->password))
275
        {
276
            if(isset($data->oldpass))
277
            {
278
                $this->change_pass($data->oldpass, $data->password);
279
                unset($data->oldpass);
280
            }
281
            else if(isset($data->hash))
282
            {
283
                $this->change_pass($data->hash, $data->password, true);
284
                unset($data->hash);
285
            }
286
            unset($data->password);
287
        }
288
    }
289
290
    private function checkForUnsettableElements($data)
291
    {
292
        $count = count($this->unsettableElements);
293
        for($i = 0; $i < $count; $i++)
294
        {
295
            $propName = $this->unsettableElements[$i];
296
            if(isset($data->{$propName}))
297
            {
298
                if($data{$propName} !== $this->{$propName})
299
                {
300
                    throw new \Exception('Unable to change '.$propName.'!');
301
                }
302
                unset($data->{$propName});
303
            }
304
        }
305
    }
306
307
    /**
308
     * Modify the user given the provided data object
309
     *
310
     * @param stdClass $data The user's new data
311
     *
312
     * @return boolean true if the user's data was changed, false otherwise
313
     */
314
    public function editUser($data)
315
    {
316
        $this->checkForUnsettableElements($data);
317
318
        $this->enableReadWrite();
319
320
        /* These elements require special handling */
321
        $this->editUserPassword($data);
322
        if(isset($data->jpegPhoto))
323
        {
324
            $this->jpegPhoto = base64_decode($data->jpegPhoto);
325
            unset($data->jpegPhoto);
326
        }
327
328
        /* These are generic elements */
329
        $data = get_object_vars($data);
330
        foreach($data as $key=>$value)
331
        {
332
            $this->{$key} = $value;
333
        }
334
    }
335
336
    /**
337
     * Obtain the user's password reset hash
338
     *
339
     * @return string|false A hash if available, false otherwise
340
     */
341
    public function getPasswordResetHash()
342
    {
343
        return false;
344
    }
345
346
    /**
347
     * Serialize the user data into a format usable by the json_encode method
348
     *
349
     * @return array A simple keyed array representing the user
350
     */
351
    public function jsonSerialize()
352
    {
353
        $user = array();
354
        $user['displayName'] = $this->displayName;
355
        $user['givenName'] = $this->givenName;
356
        $user['jpegPhoto'] = base64_encode($this->jpegPhoto);
357
        $user['mail'] = $this->mail;
358
        $user['mobile'] = $this->mobile;
359
        $user['uid'] = $this->uid;
360
        $user['o'] = $this->o;
361
        $user['title'] = $this->title;
362
        $user['titlenames'] = $this->getTitleNames();
363
        $user['st'] = $this->st;
364
        $user['l'] = $this->l;
365
        $user['sn'] = $this->sn;
366
        $user['cn'] = $this->cn;
367
        $user['postalAddress'] = $this->postalAddress;
368
        $user['postalCode'] = $this->postalCode;
369
        $user['c'] = $this->c;
370
        $user['ou'] = $this->ou;
371
        $user['host'] = $this->host;
372
        $user['class'] = get_class($this);
373
        return $user;
374
    }
375
376
    /**
377
     * Serialize the user data into a VCARD 2.1 format
378
     *
379
     * @return string The VCARD for the user
380
     */
381
    public function getVcard()
382
    {
383
        $ret = "BEGIN:VCARD\nVERSION:2.1\n";
384
        $ret .= 'N:'.$this->sn.';'.$this->givenName."\n";
385
        $ret .= 'FN:'.$this->givenName."\n";
386
        $titles = $this->title;
387
        if($titles !== false)
388
        {
389
            $ret .= 'TITLE:'.implode(',', $titles)."\n";
390
        }
391
        $ret .= "ORG: Austin Artistic Reconstruction\n";
392
        $ret .= 'TEL;TYPE=MOBILE,VOICE:'.$this->mobile."\n";
393
        $ret .= 'EMAIL;TYPE=PREF,INTERNET:'.$this->mail."\n";
394
        $ret .= "END:VCARD\n";
395
        return $ret;
396
    }
397
}
398
/* vim: set tabstop=4 shiftwidth=4 expandtab: */
399