##// END OF EJS Templates
settings: fix #3944 add password reset permission
lisaq -
r1034:d1b70f85 default
parent child Browse files
Show More
@@ -0,0 +1,42 b''
1 import logging
2 import datetime
3
4 from sqlalchemy import *
5 from sqlalchemy.exc import DatabaseError
6 from sqlalchemy.orm import relation, backref, class_mapper, joinedload
7 from sqlalchemy.orm.session import Session
8 from sqlalchemy.ext.declarative import declarative_base
9
10 from rhodecode.lib.dbmigrate.migrate import *
11 from rhodecode.lib.dbmigrate.migrate.changeset import *
12 from rhodecode.lib.utils2 import str2bool
13
14 from rhodecode.model.meta import Base
15 from rhodecode.model import meta
16 from rhodecode.lib.dbmigrate.versions import _reset_base, notify
17
18 log = logging.getLogger(__name__)
19
20
21 def upgrade(migrate_engine):
22 """
23 Upgrade operations go here.
24 Don't create your own engine; bind migrate_engine to your metadata
25 """
26 _reset_base(migrate_engine)
27 from rhodecode.lib.dbmigrate.schema import db_4_5_0_0
28
29 fixups(db_4_5_0_0, meta.Session)
30
31 def downgrade(migrate_engine):
32 meta = MetaData()
33 meta.bind = migrate_engine
34
35 def fixups(models, _SESSION):
36 # ** create default permissions ** #
37 from rhodecode.model.permission import PermissionModel
38 PermissionModel(_SESSION()).create_permissions()
39
40 res = PermissionModel(_SESSION()).create_default_user_permissions(
41 models.User.DEFAULT_USER)
42 _SESSION().commit()
@@ -51,7 +51,7 b' PYRAMID_SETTINGS = {}'
51 51 EXTENSIONS = {}
52 52
53 53 __version__ = ('.'.join((str(each) for each in VERSION[:3])))
54 __dbversion__ = 60 # defines current db version for migrations
54 __dbversion__ = 61 # defines current db version for migrations
55 55 __platform__ = platform.system()
56 56 __license__ = 'AGPLv3, and Commercial License'
57 57 __author__ = 'RhodeCode GmbH'
@@ -81,6 +81,7 b' def get_user(request, apiuser, userid=Op'
81 81 "usergroup.read",
82 82 "hg.repogroup.create.false",
83 83 "hg.create.none",
84 "hg.password_reset.enabled",
84 85 "hg.extern_activate.manual",
85 86 "hg.create.write_on_repogroup.false",
86 87 "hg.usergroup.create.false",
@@ -92,6 +92,7 b' class PermissionsController(BaseControll'
92 92 self.__load_data()
93 93 _form = ApplicationPermissionsForm(
94 94 [x[0] for x in c.register_choices],
95 [x[0] for x in c.password_reset_choices],
95 96 [x[0] for x in c.extern_activate_choices])()
96 97
97 98 try:
@@ -2314,6 +2314,10 b' class Permission(Base, BaseModel):'
2314 2314 ('hg.register.manual_activate', _('User Registration with manual account activation')),
2315 2315 ('hg.register.auto_activate', _('User Registration with automatic account activation')),
2316 2316
2317 ('hg.password_reset.enabled', _('Password reset enabled')),
2318 ('hg.password_reset.hidden', _('Password reset hidden')),
2319 ('hg.password_reset.disabled', _('Password reset disabled')),
2320
2317 2321 ('hg.extern_activate.manual', _('Manual activation of external account')),
2318 2322 ('hg.extern_activate.auto', _('Automatic activation of external account')),
2319 2323
@@ -2332,6 +2336,7 b' class Permission(Base, BaseModel):'
2332 2336 'hg.create.write_on_repogroup.true',
2333 2337 'hg.fork.repository',
2334 2338 'hg.register.manual_activate',
2339 'hg.password_reset.enabled',
2335 2340 'hg.extern_activate.auto',
2336 2341 'hg.inherit_default_perms.true',
2337 2342 ]
@@ -427,7 +427,8 b' def LabsSettingsForm():'
427 427 return _LabSettingsForm
428 428
429 429
430 def ApplicationPermissionsForm(register_choices, extern_activate_choices):
430 def ApplicationPermissionsForm(
431 register_choices, password_reset_choices, extern_activate_choices):
431 432 class _DefaultPermissionsForm(formencode.Schema):
432 433 allow_extra_fields = True
433 434 filter_extra_fields = True
@@ -435,6 +436,7 b' def ApplicationPermissionsForm(register_'
435 436 anonymous = v.StringBoolean(if_missing=False)
436 437 default_register = v.OneOf(register_choices)
437 438 default_register_message = v.UnicodeString()
439 default_password_reset = v.OneOf(password_reset_choices)
438 440 default_extern_activate = v.OneOf(extern_activate_choices)
439 441
440 442 return _DefaultPermissionsForm
@@ -51,8 +51,8 b' class PermissionModel(BaseModel):'
51 51 'default_user_group_create': None,
52 52 'default_fork_create': None,
53 53 'default_inherit_default_permissions': None,
54
55 54 'default_register': None,
55 'default_password_reset': None,
56 56 'default_extern_activate': None,
57 57
58 58 # object permissions below
@@ -85,6 +85,11 b' class PermissionModel(BaseModel):'
85 85 ('hg.register.manual_activate', translator('Allowed with manual account activation')),
86 86 ('hg.register.auto_activate', translator('Allowed with automatic account activation')),]
87 87
88 c_obj.password_reset_choices = [
89 ('hg.password_reset.enabled', translator('Allow password recovery')),
90 ('hg.password_reset.hidden', translator('Hide password recovery link')),
91 ('hg.password_reset.disabled', translator('Disable password recovery')),]
92
88 93 c_obj.extern_activate_choices = [
89 94 ('hg.extern_activate.manual', translator('Manual activation of external account')),
90 95 ('hg.extern_activate.auto', translator('Automatic activation of external account')),]
@@ -149,6 +154,9 b' class PermissionModel(BaseModel):'
149 154 if perm.permission.permission_name.startswith('hg.register.'):
150 155 defaults['default_register' + suffix] = perm.permission.permission_name
151 156
157 if perm.permission.permission_name.startswith('hg.password_reset.'):
158 defaults['default_password_reset' + suffix] = perm.permission.permission_name
159
152 160 if perm.permission.permission_name.startswith('hg.extern_activate.'):
153 161 defaults['default_extern_activate' + suffix] = perm.permission.permission_name
154 162
@@ -182,6 +190,7 b' class PermissionModel(BaseModel):'
182 190
183 191 # application perms
184 192 'default_register': 'hg.register.',
193 'default_password_reset': 'hg.password_reset.',
185 194 'default_extern_activate': 'hg.extern_activate.',
186 195
187 196 # object permissions below
@@ -383,6 +392,7 b' class PermissionModel(BaseModel):'
383 392 'default_user_group_perm',
384 393
385 394 'default_register',
395 'default_password_reset',
386 396 'default_extern_activate'])
387 397 self.sa.commit()
388 398 except (DatabaseError,):
@@ -404,6 +414,7 b' class PermissionModel(BaseModel):'
404 414 'default_user_group_perm',
405 415
406 416 'default_register',
417 'default_password_reset',
407 418 'default_extern_activate'])
408 419 self.sa.commit()
409 420 except (DatabaseError,):
@@ -429,6 +440,7 b' class PermissionModel(BaseModel):'
429 440 'default_inherit_default_permissions',
430 441
431 442 'default_register',
443 'default_password_reset',
432 444 'default_extern_activate'])
433 445
434 446 # overwrite default repo permissions
@@ -188,6 +188,10 b''
188 188 line-height: 1.5em;
189 189 }
190 190 }
191
192 p.help-block {
193 margin-left: 0;
194 }
191 195 }
192 196
193 197 .user-menu.submenu {
@@ -29,6 +29,15 b''
29 29 </div>
30 30
31 31 <div class="field">
32 <div class="label label-select">
33 <label for="default_password_reset">${_('Password Reset')}:</label>
34 </div>
35 <div class="select">
36 ${h.select('default_password_reset','',c.password_reset_choices)}
37 </div>
38 </div>
39
40 <div class="field">
32 41 <div class="label label-textarea">
33 42 <label for="default_register_message">${_('Registration Page Message')}:</label>
34 43 </div>
@@ -66,6 +75,7 b''
66 75 };
67 76
68 77 $("#default_register").select2(select2Options);
78 $("#default_password_reset").select2(select2Options);
69 79 $("#default_extern_activate").select2(select2Options);
70 80 });
71 81 </script>
@@ -308,7 +308,9 b''
308 308 <div class="field">
309 309 <div class="label">
310 310 <label for="password">${_('Password')}:</label>
311 <span class="forgot_password">${h.link_to(_('(Forgot password?)'),h.route_path('reset_password'))}</span>
311 %if h.HasPermissionAny('hg.password_reset.enabled')():
312 <span class="forgot_password">${h.link_to(_('(Forgot password?)'),h.route_path('reset_password'))}</span>
313 %endif
312 314 </div>
313 315 <div class="input">
314 316 ${h.password('password',class_='focus',tabindex=2)}
@@ -56,9 +56,17 b''
56 56 ${h.checkbox('remember', value=True, checked=defaults.get('remember'))}
57 57 <label class="checkbox" for="remember">${_('Remember me')}</label>
58 58
59 <p class="links">
60 ${h.link_to(_('Forgot your password?'), h.route_path('reset_password'))}
61 </p>
59
60 %if h.HasPermissionAny('hg.password_reset.enable')():
61 <p class="links">
62 ${h.link_to(_('Forgot your password?'), h.route_path('reset_password'))}
63 </p>
64 %elif h.HasPermissionAny('hg.password_reset.hidden')():
65 <p class="help-block">
66 ${_('Contact an administrator if you have forgotten your password.')}
67 </p>
68 %endif
69
62 70
63 71 ${h.submit('sign_in', _('Sign In'), class_="btn sign-in")}
64 72
@@ -28,39 +28,45 b''
28 28 <img class="sign-in-image" src="${h.asset('images/sign-in.png')}" alt="RhodeCode"/>
29 29 </div>
30 30
31 <div id="register" class="right-column">
32 <!-- login -->
33 <div class="sign-in-title">
34 <h1>${_('Reset your Password')}</h1>
35 <h4>${h.link_to(_("Go to the login page to sign in."), request.route_path('login'))}</h4>
31 %if h.HasPermissionAny('hg.password_reset.disabled')():
32 <div class="right-column">
33 <p>${_('Password reset has been disabled.')}</p>
36 34 </div>
37 <div class="inner form">
38 ${h.form(request.route_path('reset_password'), needs_csrf_token=False)}
39 <label for="email">${_('Email Address')}:</label>
40 ${h.text('email', defaults.get('email'))}
41 %if 'email' in errors:
42 <span class="error-message">${errors.get('email')}</span>
43 <br />
44 %endif
45
46 %if captcha_active:
47 <div class="login-captcha"
48 <label for="email">${_('Captcha')}:</label>
49 ${h.hidden('recaptcha_field')}
50 <div id="recaptcha"></div>
51 %if 'recaptcha_field' in errors:
52 <span class="error-message">${errors.get('recaptcha_field')}</span>
35 %else:
36 <div id="register" class="right-column">
37 <!-- login -->
38 <div class="sign-in-title">
39 <h1>${_('Reset your Password')}</h1>
40 <h4>${h.link_to(_("Go to the login page to sign in."), request.route_path('login'))}</h4>
41 </div>
42 <div class="inner form">
43 ${h.form(request.route_path('reset_password'), needs_csrf_token=False)}
44 <label for="email">${_('Email Address')}:</label>
45 ${h.text('email', defaults.get('email'))}
46 %if 'email' in errors:
47 <span class="error-message">${errors.get('email')}</span>
53 48 <br />
54 49 %endif
55 </div>
56 %endif
57
58 ${h.submit('send', _('Send password reset email'), class_="btn sign-in")}
59 <div class="activation_msg">${_('Password reset link will be sent to matching email address')}</div>
60
61 ${h.end_form()}
50
51 %if captcha_active:
52 <div class="login-captcha"
53 <label for="email">${_('Captcha')}:</label>
54 ${h.hidden('recaptcha_field')}
55 <div id="recaptcha"></div>
56 %if 'recaptcha_field' in errors:
57 <span class="error-message">${errors.get('recaptcha_field')}</span>
58 <br />
59 %endif
60 </div>
61 %endif
62
63 ${h.submit('send', _('Send password reset email'), class_="btn sign-in")}
64 <div class="activation_msg">${_('Password reset link will be sent to matching email address')}</div>
65
66 ${h.end_form()}
67 </div>
62 68 </div>
63 </div>
69 %endif
64 70 </div>
65 71 </div>
66 72
General Comments 0
You need to be logged in to leave comments. Login now