@@ -45,8 +45,6 @@ class User implements JsonSerializable {
45
45
const OPTION_ACL_USER_MODIFY = 0x00200000 ;
46
46
const OPTION_ACL_USER_DELETE = 0x00400000 ;
47
47
48
- const VERIFICATION_TOKEN_TTL = 86400 ;
49
-
50
48
protected $ created_datetime ;
51
49
protected $ display_name ;
52
50
protected $ email ;
@@ -70,6 +68,7 @@ public function __construct($data) {
70
68
$ this ->timezone = null ;
71
69
$ this ->username = null ;
72
70
$ this ->verified_datetime = null ;
71
+ $ this ->verifier_token = null ;
73
72
$ this ->refresh ();
74
73
} else if ($ data instanceof StdClass) {
75
74
self ::normalize ($ data );
@@ -83,6 +82,7 @@ public function __construct($data) {
83
82
$ this ->timezone = $ data ->timezone ;
84
83
$ this ->username = $ data ->username ;
85
84
$ this ->verified_datetime = $ data ->verified_datetime ;
85
+ $ this ->verifier_token = $ data ->verifier_token ;
86
86
} else {
87
87
throw new InvalidArgumentException ("Cannot use data argument " );
88
88
}
@@ -111,14 +111,6 @@ public function changeDisplayName($new_display_name) {
111
111
} else {
112
112
$ this ->display_name = (string ) $ new_display_name ;
113
113
}
114
- $ key = 'bnetdocs-user- ' . $ this ->id ;
115
- $ obj = Common::$ cache ->get ($ key );
116
- if ($ obj !== false ) {
117
- $ obj = unserialize ($ obj );
118
- $ obj ->display_name = $ this ->display_name ;
119
- $ obj = serialize ($ obj );
120
- Common::$ cache ->set ($ key , $ obj , 300 );
121
- }
122
114
}
123
115
} catch (PDOException $ e ) {
124
116
throw new QueryException ('Cannot change user display name ' , $ e );
@@ -142,14 +134,6 @@ public function changeEmail($new_email) {
142
134
$ stmt ->closeCursor ();
143
135
if ($ successful ) {
144
136
$ this ->email = (string ) $ new_email ;
145
- $ key = 'bnetdocs-user- ' . $ this ->id ;
146
- $ obj = Common::$ cache ->get ($ key );
147
- if ($ obj !== false ) {
148
- $ obj = unserialize ($ obj );
149
- $ obj ->email = $ this ->email ;
150
- $ obj = serialize ($ obj );
151
- Common::$ cache ->set ($ key , $ obj , 300 );
152
- }
153
137
}
154
138
} catch (PDOException $ e ) {
155
139
throw new QueryException ('Cannot change user email ' , $ e );
@@ -176,15 +160,6 @@ public function changePassword($new_password) {
176
160
$ stmt ->closeCursor ();
177
161
if ($ successful ) {
178
162
$ this ->password_hash = (string ) $ password_hash ;
179
- $ key = "bnetdocs-user- " . $ this ->id ;
180
- $ obj = Common::$ cache ->get ($ key );
181
- if ($ obj !== false ) {
182
- $ obj = unserialize ($ obj );
183
- $ obj ->password_hash = $ this ->password_hash ;
184
- $ obj ->password_salt = null ;
185
- $ obj = serialize ($ obj );
186
- Common::$ cache ->set ($ key , $ obj , 300 );
187
- }
188
163
}
189
164
} catch (PDOException $ e ) {
190
165
throw new QueryException ("Cannot change user password " , $ e );
@@ -208,14 +183,6 @@ public function changeUsername($new_username) {
208
183
$ stmt ->closeCursor ();
209
184
if ($ successful ) {
210
185
$ this ->username = (string ) $ new_username ;
211
- $ key = 'bnetdocs-user- ' . $ this ->id ;
212
- $ obj = Common::$ cache ->get ($ key );
213
- if ($ obj !== false ) {
214
- $ obj = unserialize ($ obj );
215
- $ obj ->username = $ this ->username ;
216
- $ obj = serialize ($ obj );
217
- Common::$ cache ->set ($ key , $ obj , 300 );
218
- }
219
186
}
220
187
} catch (PDOException $ e ) {
221
188
throw new QueryException ('Cannot change username of user ' , $ e );
@@ -258,27 +225,28 @@ public static function create(
258
225
if (!isset (Common::$ database )) {
259
226
Common::$ database = DatabaseDriver::getDatabaseObject ();
260
227
}
228
+ $ verifier_token = self ::generateVerifierToken ($ username , $ email );
261
229
$ password_hash = self ::createPassword ($ password );
262
230
$ successful = false ;
263
231
try {
264
232
$ stmt = Common::$ database ->prepare ("
265
233
INSERT INTO `users` (
266
234
`id`, `email`, `username`, `display_name`, `created_datetime`,
267
- `verified_datetime`, `password_hash `, `password_salt `,
268
- `options_bitmask`, `timezone`
235
+ `verified_datetime`, `verifier_token `, `password_hash `,
236
+ `password_salt`, ` options_bitmask`, `timezone`
269
237
) VALUES (
270
238
NULL, :email, :username, :display_name, NOW(),
271
- NULL, :password_hash, NULL, :options_bitmask, NULL
239
+ NULL, :verifier, : password_hash, NULL, :options_bitmask, NULL
272
240
);
273
241
" );
274
242
$ stmt ->bindParam (":email " , $ email , PDO ::PARAM_STR );
275
243
$ stmt ->bindParam (":username " , $ username , PDO ::PARAM_STR );
276
244
$ stmt ->bindParam (":display_name " , $ display_name , PDO ::PARAM_STR );
245
+ $ stmt ->bindParam (":verifier " , $ verifier_token , PDO ::PARAM_STR );
277
246
$ stmt ->bindParam (":password_hash " , $ password_hash , PDO ::PARAM_STR );
278
247
$ stmt ->bindParam (":options_bitmask " , $ options_bitmask , PDO ::PARAM_INT );
279
248
$ successful = $ stmt ->execute ();
280
249
$ stmt ->closeCursor ();
281
- Common::$ cache ->delete ('bnetdocs-users ' );
282
250
} catch (PDOException $ e ) {
283
251
throw new QueryException ("Cannot create user " , $ e );
284
252
} finally {
@@ -343,6 +311,12 @@ public static function findIdByUsername($username) {
343
311
return null ;
344
312
}
345
313
314
+ public static function generateVerifierToken ($ username , $ email ) {
315
+ // entropy
316
+ $ digest = sprintf ('%s%s%s ' , mt_rand (), $ username , $ email );
317
+ return hash ('sha256 ' , $ digest );
318
+ }
319
+
346
320
public function getAcl ($ acl ) {
347
321
return ($ this ->options_bitmask & $ acl );
348
322
}
@@ -367,18 +341,6 @@ public static function &getAllUsers(
367
341
} else {
368
342
$ limit_clause = 'LIMIT ' . (int ) $ index . ', ' . (int ) $ limit ;
369
343
}
370
- if (empty ($ limit_clause )) {
371
- $ cache_key = 'bnetdocs-users ' ;
372
- $ cache_val = Common::$ cache ->get ($ cache_key );
373
- if ($ cache_val !== false && !empty ($ cache_val )) {
374
- $ ids = explode (', ' , $ cache_val );
375
- $ objects = [];
376
- foreach ($ ids as $ id ) {
377
- $ objects [] = new self ($ id );
378
- }
379
- return $ objects ;
380
- }
381
- }
382
344
if (!isset (Common::$ database )) {
383
345
Common::$ database = DatabaseDriver::getDatabaseObject ();
384
346
}
@@ -394,7 +356,8 @@ public static function &getAllUsers(
394
356
`password_salt`,
395
357
`timezone`,
396
358
`username`,
397
- `verified_datetime`
359
+ `verified_datetime`,
360
+ `verifier_token`
398
361
FROM `users`
399
362
ORDER BY
400
363
' . ($ order ? '` ' . $ order [0 ] . '` ' . $ order [1 ] . ', ' : '' ) . '
@@ -403,19 +366,11 @@ public static function &getAllUsers(
403
366
if (!$ stmt ->execute ()) {
404
367
throw new QueryException ('Cannot refresh all users ' );
405
368
}
406
- $ ids = [];
407
369
$ objects = [];
408
370
while ($ row = $ stmt ->fetch (PDO ::FETCH_OBJ )) {
409
- $ ids [] = (int ) $ row ->id ;
410
371
$ objects [] = new self ($ row );
411
- Common::$ cache ->set (
412
- 'bnetdocs-user- ' . $ row ->id , serialize ($ row ), 300
413
- );
414
372
}
415
373
$ stmt ->closeCursor ();
416
- if (empty ($ limit_clause )) {
417
- Common::$ cache ->set ($ cache_key , implode (', ' , $ ids ), 300 );
418
- }
419
374
return $ objects ;
420
375
} catch (PDOException $ e ) {
421
376
throw new QueryException ('Cannot refresh all users ' , $ e );
@@ -505,23 +460,6 @@ public function getUsername() {
505
460
return $ this ->username ;
506
461
}
507
462
508
- public function getVerificationToken () {
509
- $ key = 'bnetdocs-userverify- ' . $ this ->id ;
510
- $ value = Common::$ cache ->get ($ key );
511
-
512
- if ($ value === false ) {
513
- $ gmp = gmp_init (time ());
514
- $ gmp = gmp_mul ($ gmp , mt_rand ());
515
- $ gmp = gmp_mul ($ gmp , gmp_random_bits (64 ));
516
-
517
- $ value = hash ('sha256 ' , gmp_strval ($ gmp , 36 ));
518
-
519
- Common::$ cache ->set ($ key , $ value , self ::VERIFICATION_TOKEN_TTL );
520
- }
521
-
522
- return $ value ;
523
- }
524
-
525
463
public function getVerifiedDateTime () {
526
464
if (is_null ($ this ->verified_datetime )) {
527
465
return $ this ->verified_datetime ;
@@ -533,9 +471,8 @@ public function getVerifiedDateTime() {
533
471
}
534
472
}
535
473
536
- public function invalidateVerificationToken () {
537
- $ key = 'bnetdocs-userverify- ' . $ this ->id ;
538
- return Common::$ cache ->delete ($ key );
474
+ public function getVerifierToken () {
475
+ return $ this ->verifier_token ;
539
476
}
540
477
541
478
public function isDisabled () {
@@ -622,25 +559,13 @@ protected static function normalize(StdClass &$data) {
622
559
if (!is_null ($ data ->verified_datetime ))
623
560
$ data ->verified_datetime = (string ) $ data ->verified_datetime ;
624
561
562
+ if (!is_null ($ data ->verifier_token ))
563
+ $ data ->verifier_token = (string ) $ data ->verifier_token ;
564
+
625
565
return true ;
626
566
}
627
567
628
568
public function refresh () {
629
- $ cache_key = "bnetdocs-user- " . $ this ->id ;
630
- $ cache_val = Common::$ cache ->get ($ cache_key );
631
- if ($ cache_val !== false ) {
632
- $ cache_val = unserialize ($ cache_val );
633
- $ this ->created_datetime = $ cache_val ->created_datetime ;
634
- $ this ->display_name = $ cache_val ->display_name ;
635
- $ this ->email = $ cache_val ->email ;
636
- $ this ->options_bitmask = $ cache_val ->options_bitmask ;
637
- $ this ->password_hash = $ cache_val ->password_hash ;
638
- $ this ->password_salt = $ cache_val ->password_salt ;
639
- $ this ->timezone = $ cache_val ->timezone ;
640
- $ this ->username = $ cache_val ->username ;
641
- $ this ->verified_datetime = $ cache_val ->verified_datetime ;
642
- return true ;
643
- }
644
569
if (!isset (Common::$ database )) {
645
570
Common::$ database = DatabaseDriver::getDatabaseObject ();
646
571
}
@@ -656,7 +581,8 @@ public function refresh() {
656
581
`password_salt`,
657
582
`timezone`,
658
583
`username`,
659
- `verified_datetime`
584
+ `verified_datetime`,
585
+ `verifier_token`
660
586
FROM `users`
661
587
WHERE `id` = :id
662
588
LIMIT 1;
@@ -679,7 +605,7 @@ public function refresh() {
679
605
$ this ->timezone = $ row ->timezone ;
680
606
$ this ->username = $ row ->username ;
681
607
$ this ->verified_datetime = $ row ->verified_datetime ;
682
- Common:: $ cache -> set ( $ cache_key , serialize ( $ row), 300 ) ;
608
+ $ this -> verifier_token = $ row-> verifier_token ;
683
609
return true ;
684
610
} catch (PDOException $ e ) {
685
611
throw new QueryException ("Cannot refresh user " , $ e );
@@ -716,7 +642,8 @@ public function setVerified() {
716
642
$ stmt = Common::$ database ->prepare ('
717
643
UPDATE `users` SET
718
644
`options_bitmask` = :bits,
719
- `verified_datetime` = :dt
645
+ `verified_datetime` = :dt,
646
+ `verifier_token` = NULL
720
647
WHERE `id` = :user_id;
721
648
' );
722
649
$ dt = $ verified_datetime ->format ( 'Y-m-d H:i:s ' );
@@ -726,23 +653,13 @@ public function setVerified() {
726
653
$ successful = $ stmt ->execute ();
727
654
$ stmt ->closeCursor ();
728
655
if ($ successful ) {
729
- $ this ->verified_datetime = $ verified_datetime ;
730
656
$ this ->options_bitmask = $ options_bitmask ;
731
- $ key = 'bnetdocs-user- ' . $ this ->id ;
732
- $ obj = Common::$ cache ->get ($ key );
733
- if ($ obj !== false ) {
734
- $ obj = unserialize ($ obj );
735
- $ obj ->verified_datetime = $ this ->verified_datetime ;
736
- $ obj ->options_bitmask = $ this ->options_bitmask ;
737
- $ obj = serialize ($ obj );
738
- Common::$ cache ->set ($ key , $ obj , 300 );
739
- }
657
+ $ this ->verified_datetime = $ verified_datetime ;
658
+ $ this ->verifier_token = null ;
740
659
}
741
660
742
661
} catch (PDOException $ e ) {
743
-
744
662
throw new QueryException ('Cannot set user as verified ' , $ e );
745
-
746
663
} finally {
747
664
return $ successful ;
748
665
}
0 commit comments