Show More
@@ -185,7 +185,7 b' class AdminUsersView(BaseAppView, DataGr' | |||||
185 | def users_new(self): |
|
185 | def users_new(self): | |
186 | _ = self.request.translate |
|
186 | _ = self.request.translate | |
187 | c = self.load_default_context() |
|
187 | c = self.load_default_context() | |
188 |
c.default_extern_type = auth_rhodecode.RhodeCodeAuthPlugin. |
|
188 | c.default_extern_type = auth_rhodecode.RhodeCodeAuthPlugin.uid | |
189 | self._set_personal_repo_group_template_vars(c) |
|
189 | self._set_personal_repo_group_template_vars(c) | |
190 | return self._get_template_context(c) |
|
190 | return self._get_template_context(c) | |
191 |
|
191 | |||
@@ -198,7 +198,7 b' class AdminUsersView(BaseAppView, DataGr' | |||||
198 | def users_create(self): |
|
198 | def users_create(self): | |
199 | _ = self.request.translate |
|
199 | _ = self.request.translate | |
200 | c = self.load_default_context() |
|
200 | c = self.load_default_context() | |
201 |
c.default_extern_type = auth_rhodecode.RhodeCodeAuthPlugin. |
|
201 | c.default_extern_type = auth_rhodecode.RhodeCodeAuthPlugin.uid | |
202 | user_model = UserModel() |
|
202 | user_model = UserModel() | |
203 | user_form = UserForm(self.request.translate)() |
|
203 | user_form = UserForm(self.request.translate)() | |
204 | try: |
|
204 | try: |
@@ -32,6 +32,7 b' from pyramid.view import view_config' | |||||
32 |
|
32 | |||
33 | from rhodecode.apps._base import BaseAppView |
|
33 | from rhodecode.apps._base import BaseAppView | |
34 | from rhodecode.authentication.base import authenticate, HTTP_TYPE |
|
34 | from rhodecode.authentication.base import authenticate, HTTP_TYPE | |
|
35 | from rhodecode.authentication.plugins import auth_rhodecode | |||
35 | from rhodecode.events import UserRegistered, trigger |
|
36 | from rhodecode.events import UserRegistered, trigger | |
36 | from rhodecode.lib import helpers as h |
|
37 | from rhodecode.lib import helpers as h | |
37 | from rhodecode.lib import audit_logger |
|
38 | from rhodecode.lib import audit_logger | |
@@ -367,15 +368,24 b' class LoginView(BaseAppView):' | |||||
367 | # matching emails |
|
368 | # matching emails | |
368 | msg = _('If such email exists, a password reset link was sent to it.') |
|
369 | msg = _('If such email exists, a password reset link was sent to it.') | |
369 |
|
370 | |||
|
371 | def default_response(): | |||
|
372 | log.debug('faking response on invalid password reset') | |||
|
373 | # make this take 2s, to prevent brute forcing. | |||
|
374 | time.sleep(2) | |||
|
375 | h.flash(msg, category='success') | |||
|
376 | return HTTPFound(self.request.route_path('reset_password')) | |||
|
377 | ||||
370 | if self.request.POST: |
|
378 | if self.request.POST: | |
371 | if h.HasPermissionAny('hg.password_reset.disabled')(): |
|
379 | if h.HasPermissionAny('hg.password_reset.disabled')(): | |
372 | _email = self.request.POST.get('email', '') |
|
380 | _email = self.request.POST.get('email', '') | |
373 | log.error('Failed attempt to reset password for `%s`.', _email) |
|
381 | log.error('Failed attempt to reset password for `%s`.', _email) | |
374 | h.flash(_('Password reset has been disabled.'), |
|
382 | h.flash(_('Password reset has been disabled.'), category='error') | |
375 | category='error') |
|
|||
376 | return HTTPFound(self.request.route_path('reset_password')) |
|
383 | return HTTPFound(self.request.route_path('reset_password')) | |
377 |
|
384 | |||
378 | password_reset_form = PasswordResetForm(self.request.translate)() |
|
385 | password_reset_form = PasswordResetForm(self.request.translate)() | |
|
386 | description = u'Generated token for password reset from {}'.format( | |||
|
387 | datetime.datetime.now().isoformat()) | |||
|
388 | ||||
379 | try: |
|
389 | try: | |
380 | form_result = password_reset_form.to_python( |
|
390 | form_result = password_reset_form.to_python( | |
381 | self.request.POST) |
|
391 | self.request.POST) | |
@@ -395,10 +405,14 b' class LoginView(BaseAppView):' | |||||
395 | # Generate reset URL and send mail. |
|
405 | # Generate reset URL and send mail. | |
396 | user = User.get_by_email(user_email) |
|
406 | user = User.get_by_email(user_email) | |
397 |
|
407 | |||
|
408 | # only allow rhodecode based users to reset their password | |||
|
409 | # external auth shouldn't allow password reset | |||
|
410 | if user and user.extern_type != auth_rhodecode.RhodeCodeAuthPlugin.uid: | |||
|
411 | log.warning('User %s with external type `%s` tried a password reset. ' | |||
|
412 | 'This try was rejected', user, user.extern_type) | |||
|
413 | return default_response() | |||
|
414 | ||||
398 | # generate password reset token that expires in 10 minutes |
|
415 | # generate password reset token that expires in 10 minutes | |
399 | description = u'Generated token for password reset from {}'.format( |
|
|||
400 | datetime.datetime.now().isoformat()) |
|
|||
401 |
|
||||
402 | reset_token = UserModel().add_auth_token( |
|
416 | reset_token = UserModel().add_auth_token( | |
403 | user=user, lifetime_minutes=10, |
|
417 | user=user, lifetime_minutes=10, | |
404 | role=UserModel.auth_token_role.ROLE_PASSWORD_RESET, |
|
418 | role=UserModel.auth_token_role.ROLE_PASSWORD_RESET, | |
@@ -411,15 +425,14 b' class LoginView(BaseAppView):' | |||||
411 | _query={'key': reset_token.api_key}) |
|
425 | _query={'key': reset_token.api_key}) | |
412 | UserModel().reset_password_link( |
|
426 | UserModel().reset_password_link( | |
413 | form_result, password_reset_url) |
|
427 | form_result, password_reset_url) | |
414 | # Display success message and redirect. |
|
|||
415 | h.flash(msg, category='success') |
|
|||
416 |
|
428 | |||
417 | action_data = {'email': user_email, |
|
429 | action_data = {'email': user_email, | |
418 | 'user_agent': self.request.user_agent} |
|
430 | 'user_agent': self.request.user_agent} | |
419 | audit_logger.store_web( |
|
431 | audit_logger.store_web( | |
420 | 'user.password.reset_request', action_data=action_data, |
|
432 | 'user.password.reset_request', action_data=action_data, | |
421 | user=self._rhodecode_user, commit=True) |
|
433 | user=self._rhodecode_user, commit=True) | |
422 | return HTTPFound(self.request.route_path('reset_password')) |
|
434 | ||
|
435 | return default_response() | |||
423 |
|
436 | |||
424 | except formencode.Invalid as errors: |
|
437 | except formencode.Invalid as errors: | |
425 | template_context.update({ |
|
438 | template_context.update({ | |
@@ -434,11 +447,7 b' class LoginView(BaseAppView):' | |||||
434 | # case of failed captcha |
|
447 | # case of failed captcha | |
435 | return self._get_template_context(c, **template_context) |
|
448 | return self._get_template_context(c, **template_context) | |
436 |
|
449 | |||
437 | log.debug('faking response on invalid password reset') |
|
450 | return default_response() | |
438 | # make this take 2s, to prevent brute forcing. |
|
|||
439 | time.sleep(2) |
|
|||
440 | h.flash(msg, category='success') |
|
|||
441 | return HTTPFound(self.request.route_path('reset_password')) |
|
|||
442 |
|
451 | |||
443 | return self._get_template_context(c, **template_context) |
|
452 | return self._get_template_context(c, **template_context) | |
444 |
|
453 |
@@ -103,11 +103,12 b'' | |||||
103 | </div> |
|
103 | </div> | |
104 | <div class="field"> |
|
104 | <div class="field"> | |
105 | <div class="label-text"> |
|
105 | <div class="label-text"> | |
106 |
${_(' |
|
106 | ${_('Authentication type')}: | |
107 | </div> |
|
107 | </div> | |
108 | <div class="input"> |
|
108 | <div class="input"> | |
109 | <p>${c.extern_type}</p> |
|
109 | <p>${c.extern_type}</p> | |
110 | ${h.hidden('extern_type', readonly="readonly")} |
|
110 | ${h.hidden('extern_type', readonly="readonly")} | |
|
111 | <p class="help-block">${_('User was created using an external source. He is bound to authentication using this method.')}</p> | |||
111 | </div> |
|
112 | </div> | |
112 | </div> |
|
113 | </div> | |
113 | <div class="field"> |
|
114 | <div class="field"> | |
@@ -127,7 +128,7 b'' | |||||
127 | ## allowed_languages is defined in the users.py |
|
128 | ## allowed_languages is defined in the users.py | |
128 | ## c.language comes from base.py as a default language |
|
129 | ## c.language comes from base.py as a default language | |
129 | ${h.select('language', c.language, c.allowed_languages)} |
|
130 | ${h.select('language', c.language, c.allowed_languages)} | |
130 | <p class="help-block">${h.literal(_('Help translate %(rc_link)s into your language.') % {'rc_link': h.link_to('RhodeCode Enterprise', h.route_url('rhodecode_translations'))})}</p> |
|
131 | <p class="help-block">${h.literal(_('User interface language. Help translate %(rc_link)s into your language.') % {'rc_link': h.link_to('RhodeCode Enterprise', h.route_url('rhodecode_translations'))})}</p> | |
131 | </div> |
|
132 | </div> | |
132 | </div> |
|
133 | </div> | |
133 | <div class="buttons"> |
|
134 | <div class="buttons"> |
General Comments 0
You need to be logged in to leave comments.
Login now