Completed
Pull Request — master (#109)
by Patrick
10:35
created

User::editUserPassword()   B

Complexity

Conditions 6
Paths 6

Size

Total Lines 26

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 6
nc 6
nop 1
dl 0
loc 26
rs 8.8817
c 0
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
    }
261
262
    /**
263
     * Update the user password if required
264
     */
265
    private function editUserPassword(&$data)
266
    {
267
        if(isset($data->password))
268
        {
269
            if(isset($data->oldpass))
270
            {
271
                $this->change_pass($data->oldpass, $data->password);
272
                unset($data->oldpass);
273
            }
274
            else if(isset($data->hash))
275
            {
276
                $this->change_pass($data->hash, $data->password, true);
277
                unset($data->hash);
278
            }
279
            unset($data->password);
280
        }
281
        else if(isset($data->userPassword))
282
        {
283
            if(isset($data->oldpass))
284
            {
285
                $this->change_pass($data->oldpass, $data->userPassword);
286
                unset($data->oldpass);
287
            }
288
            unset($data->userPassword);
289
        }
290
    }
291
292
    private function checkForUnsettableElements($data)
293
    {
294
        $count = count($this->unsettableElements);
295
        for($i = 0; $i < $count; $i++)
296
        {
297
            $propName = $this->unsettableElements[$i];
298
            if(isset($data->{$propName}))
299
            {
300
                if($data->{$propName} !== $this->{$propName})
301
                {
302
                    throw new \Exception('Unable to change '.$propName.'!');
303
                }
304
                unset($data->{$propName});
305
            }
306
        }
307
    }
308
309
    /**
310
     * Modify the user given the provided data object
311
     *
312
     * @param stdClass $data The user's new data
313
     *
314
     * @return boolean true if the user's data was changed, false otherwise
315
     */
316
    public function editUser($data)
317
    {
318
        $this->checkForUnsettableElements($data);
319
320
        $this->enableReadWrite();
321
322
        /* These elements require special handling */
323
        $this->editUserPassword($data);
324
        if(isset($data->jpegPhoto))
325
        {
326
            $this->jpegPhoto = base64_decode($data->jpegPhoto);
327
            unset($data->jpegPhoto);
328
        }
329
330
        /* These are generic elements */
331
        if(!is_array($data))
332
        {
333
            $data = get_object_vars($data);
334
        }
335
        foreach($data as $key=>$value)
336
        {
337
            $this->{$key} = $value;
338
        }
339
    }
340
341
    /**
342
     * Obtain the user's password reset hash
343
     *
344
     * @return string|false A hash if available, false otherwise
345
     */
346
    public function getPasswordResetHash()
347
    {
348
        return false;
349
    }
350
351
    /**
352
     * Serialize the user data into a format usable by the json_encode method
353
     *
354
     * @return array A simple keyed array representing the user
355
     */
356
    public function jsonSerialize()
357
    {
358
        $user = array();
359
        $user['displayName'] = $this->displayName;
360
        $user['givenName'] = $this->givenName;
361
        $user['jpegPhoto'] = base64_encode($this->jpegPhoto);
362
        $user['mail'] = $this->mail;
363
        $user['mobile'] = $this->mobile;
364
        $user['uid'] = $this->uid;
365
        $user['o'] = $this->o;
366
        $user['title'] = $this->title;
367
        $user['titlenames'] = $this->getTitleNames();
368
        $user['st'] = $this->st;
369
        $user['l'] = $this->l;
370
        $user['sn'] = $this->sn;
371
        $user['cn'] = $this->cn;
372
        $user['postalAddress'] = $this->postalAddress;
373
        $user['postalCode'] = $this->postalCode;
374
        $user['c'] = $this->c;
375
        $user['ou'] = $this->ou;
376
        $user['host'] = $this->host;
377
        $user['class'] = get_class($this);
378
        return $user;
379
    }
380
381
    /**
382
     * Serialize the user data into a VCARD 2.1 format
383
     *
384
     * @return string The VCARD for the user
385
     */
386
    public function getVcard()
387
    {
388
        $ret = "BEGIN:VCARD\nVERSION:2.1\n";
389
        $ret .= 'N:'.$this->sn.';'.$this->givenName."\n";
390
        $ret .= 'FN:'.$this->givenName."\n";
391
        $titles = $this->title;
392
        if($titles !== false)
393
        {
394
            $ret .= 'TITLE:'.implode(',', $titles)."\n";
395
        }
396
        $ret .= "ORG: Austin Artistic Reconstruction\n";
397
        $ret .= 'TEL;TYPE=MOBILE,VOICE:'.$this->mobile."\n";
398
        $ret .= 'EMAIL;TYPE=PREF,INTERNET:'.$this->mail."\n";
399
        $ret .= "END:VCARD\n";
400
        return $ret;
401
    }
402
}
403
/* vim: set tabstop=4 shiftwidth=4 expandtab: */
404