Passed
Push — master ( 72f710...3d12b3 )
by Vince
01:54 queued 11s
created

user::checkUpdateProperties()   B

Complexity

Conditions 7
Paths 2

Size

Total Lines 10
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 7
eloc 7
nc 2
nop 1
dl 0
loc 10
rs 8.8333
c 0
b 0
f 0
1
<?php
2
/**
3
 * ==================================
4
 * Responsible PHP API
5
 * ==================================
6
 *
7
 * @link Git https://github.com/vince-scarpa/responsibleAPI.git
8
 *
9
 * @api Responible API
10
 * @package responsible\core\user
11
 *
12
 * @author Vince scarpa <[email protected]>
13
 *
14
 */
15
namespace responsible\core\user;
16
17
use responsible\core\auth;
18
use responsible\core\configuration;
19
use responsible\core\connect;
20
use responsible\core\exception;
21
use responsible\core\headers;
22
23
class user
24
{
25
    /**
26
     * [$DB Data base object]
27
     * @var object
28
     */
29
    private $DB;
30
31
    /**
32
     * [$name Account username]
33
     * @var string
34
     */
35
    private $name;
36
37
    /**
38
     * [$name Account email address]
39
     * @var string
40
     */
41
    private $mail;
42
43
    /**
44
     * [$ACCOUNT_ID]
45
     * @var string
46
     */
47
    private $ACCOUNT_ID;
48
49
    /**
50
     * [$timestamp Time now]
51
     * @var integer
52
     */
53
    protected $timestamp;
54
55
    /**
56
     * [$bucketToken]
57
     * @var string
58
     */
59
    private $bucketToken;
60
61
    /**
62
     * [$options Resposible API options]
63
     * @var array
64
     */
65
    protected $options;
66
67
    /**
68
     * [$credentials User credentials]
69
     * @var array
70
     */
71
    protected $credentials;
72
73
    /**
74
     * [create Create a new access account]
75
     * @return array
76
     */
77
    public function create()
78
    {
79
        return (new userCreate($this->credentials))
80
            ->setOptions($this->getOptions())
81
            ->createAccount()
82
        ;
83
    }
84
85
    /**
86
     * [update Update an access account]
87
     * @return array
88
     */
89
    public function update($properties)
90
    {
91
        return $this->updateAccount($properties);
92
    }
93
94
    /**
95
     * [load Load a stored account]
96
     * @return array
97
     */
98
    public function load($property, array $options)
99
    {
100
        return (new userLoad($property, $options))
101
            ->setOptions($this->getOptions())
102
            ->account()
103
        ;
104
    }
105
106
    /**
107
     * [updateAccountAccess Update the requests account access]
108
     * @return void
109
     */
110
    public function updateAccountAccess($ACCOUNT_ID = null)
111
    {
112
        if (is_null($ACCOUNT_ID) && empty($this->ACCOUNT_ID)) {
113
            (new exception\errorException)
114
                ->message('No ACCOUNT_ID provided!')
115
                ->error('ACCOUNT_ID');
116
        }
117
118
        if (!is_null($ACCOUNT_ID)) {
119
            $this->setAccountID($ACCOUNT_ID);
120
        }
121
122
        /**
123
         * Upate the users access
124
         */
125
        $this->updateAccess();
126
    }
127
128
    /**
129
     * [updateAccess Update access for limit requests]
130
     * @return boolean
131
     */
132
    private function updateAccess()
133
    {
134
        return $this->DB()->
135
            query(
136
                "UPDATE responsible_api_users USR
137
                        JOIN responsible_token_bucket TKN
138
                            ON (USR.account_id = TKN.account_id)
139
                        set
140
                            USR.access = :unix,
141
                            TKN.bucket = :bkt
142
                        WHERE USR.account_id = :aid;",
143
                array(
144
                'unix' => (new \DateTime('now'))->getTimestamp(),
145
                'aid' => $this->getAccountID(),
146
                'bkt' => $this->getBucketToken(),
147
            )
148
        );
149
    }
150
151
    /**
152
     * [updateAccount Update access for limit requests]
153
     * @return boolean
154
     */
155
    private function updateAccount($properties)
156
    {
157
        if( is_array($properties) ) {
158
            $properties = (object) $properties;
159
        }
160
161
        $this->checkUpdateProperties($properties);
162
        
163
        $updateSet = $this->buildUpdateSet($properties);
164
        
165
        return $this->DB()->
166
            query(
167
                "UPDATE responsible_api_users USR
168
                        set {$updateSet['set']}
169
                        WHERE {$updateSet['where']}
170
                ;",
171
                $updateSet['binds']
172
        );
173
    }
174
175
    /**
176
     * [checkUpdateProperties Check if we have the correct update properties]
177
     * @param  object $properties
178
     * @return void
179
     */
180
    private function checkUpdateProperties($properties)
181
    {
182
        if (!isset($properties->update) || 
183
            !isset($properties->where) || 
184
            (isset($properties->update) && !is_array($properties->update)) ||
185
            (isset($properties->where) && !is_array($properties->where))
186
        ) {
187
            (new exception\errorException)
188
                ->message('No update property was provided. Please read the documentation on updating user accounts.')
189
                ->error('ACCOUNT_UPDATE');
190
        }
191
    }
192
193
    /**
194
     * [buildUpdateSet description]
195
     * @param  object $properties
196
     * @return array
197
     */
198
    private function buildUpdateSet($properties)
199
    {
200
        $allowedFileds = $binds = [];
201
        $set = '';
202
203
        $columns = $this->DB()->query("SHOW COLUMNS FROM responsible_api_users");
204
        
205
        foreach ($columns as $f => $field) {
206
            $allowedFileds[] = $field['Field'];
207
        }
208
209
        foreach ($properties->update as $u => $update) {
210
            if( !in_array($u, $allowedFileds) ) {
211
                unset($properties->update[$u]);
212
            }else{
213
                $set .= $u . ' = :' . $u . ',';
214
                $binds[$u] = $update;
215
            }
216
        }
217
218
        $set = rtrim($set, ',');
219
        $where =  key($properties->where) . ' = ' . $properties->where[key($properties->where)];
220
221
        return [
222
            'set' => $set,
223
            'where' => $where,
224
            'binds' => $binds
225
        ];
226
    }
227
228
    /**
229
     * [credentials Set the new account credentials]
230
     * @param  string $name 
231
     *         username
232
     * @param  string $mail 
233
     *         email address
234
     */
235
    public function credentials($name, $mail)
236
    {
237
        if (!$this->validate('name', $name) || !$this->validate('mail', $mail)) {
238
            (new exception\errorException)
239
                ->message(
240
                    'Username or email address validation error! Username must be a string and email must be valid.'
241
                )
242
                ->error('APPLICATION_ERROR');
243
        }
244
245
        $this->credentials = [
246
            'name' => $this->name,
247
            'mail' => $this->mail,
248
        ];
249
250
        return $this;
251
    }
252
253
    /**
254
     * [validate - Validate the new account credentials]
255
     * @return boolean
256
     */
257
    private function validate($type, $property)
258
    {
259
        $options = $this->getOptions();
260
        $skipValidatation = false;
261
262
        if( isset($options['validate']) && $options['validate'] == false ) {
263
            $skipValidatation = true;
264
        }
265
266
        switch ($type) {
267
268
            case 'name':
269
                if (!is_string($property) && !$skipValidatation) {
270
                    return false;
271
                }
272
                $this->name = preg_replace('/\s+/', '-', strtolower($property));
273
274
                return true;
275
                break;
0 ignored issues
show
Unused Code introduced by
break is not strictly necessary here and could be removed.

The break statement is not necessary if it is preceded for example by a return statement:

switch ($x) {
    case 1:
        return 'foo';
        break; // This break is not necessary and can be left off.
}

If you would like to keep this construct to be consistent with other case statements, you can safely mark this issue as a false-positive.

Loading history...
276
277
            case 'mail':
278
                if( !filter_var($property, FILTER_VALIDATE_EMAIL) && !$skipValidatation) {
279
                    return false;
280
                }
281
                $this->mail = $property;
282
283
                return true;
284
                break;
285
        }
286
287
        return false;
288
    }
289
290
    /**
291
     * [getJWT Get the JWT payload]
292
     * @return array
293
     */
294
    protected function getJWT($key)
295
    {
296
        $token = (new headers\header)->authorizationHeaders(true);
297
        $jwt = new auth\jwt;
298
        $decoded = $jwt->token($token)
299
            ->key($key)
300
            ->decode()
301
        ;
302
303
        return [
304
            'token' => $token,
305
            'payload' => $decoded,
306
        ];
307
    }
308
309
    /**
310
     * [DB Get DB object]
311
     */
312
    protected function DB()
313
    {
314
        if (is_null($this->DB)) {
315
            $defaults = $this->getDefaults();
316
            $config = $defaults['config'];
317
318
            $this->DB = new connect\DB($config['DB_HOST'], $config['DB_NAME'], $config['DB_USER'], $config['DB_PASSWORD']);
319
        }
320
        return $this->DB;
321
    }
322
323
    /**
324
     * [getDefaults Get the Responsible API defaults ]
325
     * @return array
326
     */
327
    protected function getDefaults()
328
    {
329
        $config = new configuration\config;
330
        $config->responsibleDefault();
331
        return $config->getDefaults();
332
    }
333
334
    /**
335
     * [setOptions Set the REsponsible API options]
336
     * @param array $options
337
     */
338
    public function setOptions($options)
339
    {
340
        $this->options = $options;
341
        return $this;
342
    }
343
344
    /**
345
     * [getOptions Get the Responsible API options]
346
     * @return array
347
     */
348
    protected function getOptions()
349
    {
350
        return $this->options;
351
    }
352
353
    /**
354
     * [timeNow Create a timestamp of now]
355
     * @return integer
356
     */
357
    protected function timeNow()
358
    {
359
        $this->timestamp = (new \DateTime('now'))->getTimestamp();
360
        return $this->timestamp;
361
    }
362
363
    /**
364
     * [setAccountID]
365
     */
366
    public function setAccountID($ACCOUNT_ID)
367
    {
368
        $this->ACCOUNT_ID = $ACCOUNT_ID;
369
        return $this;
370
    }
371
372
    /**
373
     * [getAccountID]
374
     * @return string
375
     */
376
    protected function getAccountID()
377
    {
378
        return $this->ACCOUNT_ID;
379
    }
380
381
    /**
382
     * [setBucket Bucket data token]
383
     * @param string $packed
384
     */
385
    public function setBucketToken($packed)
386
    {
387
        $this->bucketToken = $packed;
388
        return $this;
389
    }
390
391
    /**
392
     * [getBucketToken Bucket data token]
393
     * @param string $packed
394
     */
395
    public function getBucketToken()
396
    {
397
        return $this->bucketToken;
398
    }
399
400
    /**
401
     * [getClaim Check if a claim is set and not empty]
402
     * @param  string $claim
403
     * @return mixed
404
     */
405
    public function checkVal($option, $key, $default = false)
406
    {
407
        $val = isset($option[$key]) ? $option[$key] : $default;
408
409
        if ($val && empty($option[$key])) {
410
            $val = $default;
411
        }
412
413
        return $val;
414
    }
415
}
416