35
35
import logbook
36
36
import redis
37
37
import rq
38
+ import operator
38
39
import coil .tasks
39
40
from nikola .utils import (unicode_str , get_logger , ColorfulStderrHandler ,
40
41
write_metadata , TranslatableSetting )
@@ -207,7 +208,10 @@ def password_hash(password):
207
208
:return: password hash
208
209
:rtype: str
209
210
"""
210
- return bcrypt_sha256 .encrypt (password )
211
+ try :
212
+ return bcrypt_sha256 .encrypt (password )
213
+ except TypeError :
214
+ return bcrypt_sha256 .encrypt (password .decode ('utf-8' ))
211
215
212
216
213
217
def check_password (pwdhash , password ):
@@ -341,6 +345,14 @@ def render(template_name, context=None, code=200, headers=None):
341
345
headers ['Pragma' ] = 'no-cache'
342
346
headers ['Cache-Control' ] = 'private, max-age=0, no-cache'
343
347
348
+ try :
349
+ mcp = current_user .must_change_password in (True , '1' )
350
+ except AttributeError :
351
+ mcp = False
352
+
353
+ if mcp and not context .get ('pwdchange_skip' , False ):
354
+ return redirect (url_for ('acp_account' ) + '?status=pwdchange' )
355
+
344
356
return _site .render_template (template_name , None , context ), code , headers
345
357
346
358
@@ -457,11 +469,25 @@ def get_user(uid):
457
469
:raises KeyError: if user does not exist
458
470
"""
459
471
if db is not None :
472
+ try :
473
+ uid = uid .decode ('utf-8' )
474
+ except AttributeError :
475
+ pass
460
476
d = db .hgetall ('user:{0}' .format (uid ))
461
477
if d :
478
+ nd = {}
479
+ # strings everywhere
480
+ for k in d :
481
+ try :
482
+ nd [k .decode ('utf-8' )] = d [k ].decode ('utf-8' )
483
+ except AttributeError :
484
+ try :
485
+ nd [k .decode ('utf-8' )] = d [k ]
486
+ except AttributeError :
487
+ nd [k ] = d [k ]
462
488
for p in PERMISSIONS :
463
- d [p ] = d .get (p ) == '1'
464
- return User (uid = uid , ** d )
489
+ nd [p ] = nd .get (p ) == '1'
490
+ return User (uid = uid , ** nd )
465
491
else :
466
492
return None
467
493
else :
@@ -557,7 +583,8 @@ def login():
557
583
alert = 'Logged out successfully.'
558
584
alert_status = 'success'
559
585
return render ('coil_login.tmpl' , {'title' : 'Login' , 'alert' : alert , 'form' :
560
- form , 'alert_status' : alert_status },
586
+ form , 'alert_status' : alert_status ,
587
+ 'pwdchange_skip' : True },
561
588
code )
562
589
563
590
@@ -576,9 +603,6 @@ def index():
576
603
577
604
:param int all: Whether or not should show all posts
578
605
"""
579
- if current_user .must_change_password :
580
- return redirect (url_for ('acp_account' ) + '?status=pwdchange' )
581
-
582
606
context = {'postform' : NewPostForm (),
583
607
'pageform' : NewPageForm (),
584
608
'delform' : DeleteForm ()}
@@ -627,9 +651,6 @@ def edit(path):
627
651
628
652
:param path: Path to post to edit.
629
653
"""
630
- if current_user .must_change_password :
631
- return redirect (url_for ('acp_account' ) + '?status=pwdchange' )
632
-
633
654
context = {'path' : path , 'site' : site }
634
655
post = find_post (path )
635
656
if post is None :
@@ -709,9 +730,6 @@ def edit(path):
709
730
@login_required
710
731
def delete ():
711
732
"""Delete a post."""
712
- if current_user .must_change_password :
713
- return redirect (url_for ('acp_account' ) + '?status=pwdchange' )
714
-
715
733
form = DeleteForm ()
716
734
path = request .form ['path' ]
717
735
post = find_post (path )
@@ -776,9 +794,6 @@ def api_rebuild():
776
794
@login_required
777
795
def rebuild (mode = '' ):
778
796
"""Rebuild the site with a nice UI."""
779
- if current_user .must_change_password :
780
- return redirect (url_for ('acp_account' ) + '?status=pwdchange' )
781
-
782
797
scan_site () # for good measure
783
798
if not current_user .can_rebuild_site :
784
799
return error ('You are not permitted to rebuild the site.</p>'
@@ -812,9 +827,6 @@ def new(obj):
812
827
813
828
:param str obj: Object to create (post or page)
814
829
"""
815
- if current_user .must_change_password :
816
- return redirect (url_for ('acp_account' ) + '?status=pwdchange' )
817
-
818
830
title = request .form ['title' ]
819
831
_site .config ['ADDITIONAL_METADATA' ]['author.uid' ] = current_user .uid
820
832
try :
@@ -905,9 +917,11 @@ def acp_account():
905
917
if request .args .get ('status' ) == 'pwdchange' :
906
918
alert = 'You must change your password before proceeding.'
907
919
alert_status = 'danger'
920
+ pwdchange_skip = True
908
921
else :
909
922
alert = ''
910
923
alert_status = ''
924
+ pwdchange_skip = False
911
925
912
926
if db is None :
913
927
form = PwdHashForm ()
@@ -936,6 +950,7 @@ def acp_account():
936
950
if data ['newpwd1' ] == data ['newpwd2' ] and pwd_ok :
937
951
current_user .password = password_hash (data ['newpwd1' ])
938
952
current_user .must_change_password = False
953
+ pwdchange_skip = True
939
954
else :
940
955
alert = 'Passwords don’t match.'
941
956
alert_status = 'danger'
@@ -950,7 +965,8 @@ def acp_account():
950
965
'action' : action ,
951
966
'alert' : alert ,
952
967
'alert_status' : alert_status ,
953
- 'form' : form })
968
+ 'form' : form ,
969
+ 'pwdchange_skip' : pwdchange_skip })
954
970
955
971
956
972
@app .route ('/account/pwdhash' , methods = ['POST' ])
@@ -974,8 +990,6 @@ def acp_pwdhash():
974
990
@login_required
975
991
def acp_users ():
976
992
"""List all users."""
977
- if current_user .must_change_password :
978
- return redirect (url_for ('acp_account' ) + '?status=pwdchange' )
979
993
if not current_user .is_admin :
980
994
return error ("Not authorized to edit users." , 401 )
981
995
if not db :
@@ -991,7 +1005,7 @@ def acp_users():
991
1005
alert_status = 'success'
992
1006
else :
993
1007
uids = db .hgetall ('users' ).values ()
994
- USERS = sorted ([(i , get_user (i )) for i in uids ])
1008
+ USERS = sorted ([(int ( i ) , get_user (i )) for i in uids ], key = operator . itemgetter ( 0 ) )
995
1009
return render ('coil_users.tmpl' ,
996
1010
context = {'title' : 'Users' ,
997
1011
'USERS' : USERS ,
@@ -1007,8 +1021,6 @@ def acp_users():
1007
1021
def acp_users_edit ():
1008
1022
"""Edit an user account."""
1009
1023
global current_user
1010
- if current_user .must_change_password :
1011
- return redirect (url_for ('acp_account' ) + '?status=pwdchange' )
1012
1024
if not current_user .is_admin :
1013
1025
return error ("Not authorized to edit users." , 401 )
1014
1026
if not db :
@@ -1023,7 +1035,7 @@ def acp_users_edit():
1023
1035
if action == 'new' :
1024
1036
if not data ['username' ]:
1025
1037
return error ("No username to create specified." , 400 )
1026
- uid = max (db .hgetall ('users' ).values ()) + 1
1038
+ uid = max (int ( i ) for i in db .hgetall ('users' ).values ()) + 1
1027
1039
pf = [False for p in PERMISSIONS ]
1028
1040
pf [0 ] = True # active
1029
1041
pf [7 ] = True # must_change_password
@@ -1083,8 +1095,6 @@ def acp_users_edit():
1083
1095
@login_required
1084
1096
def acp_users_import ():
1085
1097
"""Import users from a TSV file."""
1086
- if current_user .must_change_password :
1087
- return redirect (url_for ('acp_account' ) + '?status=pwdchange' )
1088
1098
if not current_user .is_admin :
1089
1099
return error ("Not authorized to edit users." , 401 )
1090
1100
if not db :
@@ -1103,8 +1113,6 @@ def acp_users_import():
1103
1113
@login_required
1104
1114
def acp_users_delete ():
1105
1115
"""Delete or undelete an user account."""
1106
- if current_user .must_change_password :
1107
- return redirect (url_for ('acp_account' ) + '?status=pwdchange' )
1108
1116
if not current_user .is_admin :
1109
1117
return error ("Not authorized to edit users." , 401 )
1110
1118
if not db :
@@ -1130,8 +1138,6 @@ def acp_users_delete():
1130
1138
@login_required
1131
1139
def acp_users_permissions ():
1132
1140
"""Change user permissions."""
1133
- if current_user .must_change_password :
1134
- return redirect (url_for ('acp_account' ) + '?status=pwdchange' )
1135
1141
if not current_user .is_admin :
1136
1142
return error ("Not authorized to edit users." , 401 )
1137
1143
if not db :
0 commit comments