Show More
@@ -0,0 +1,137 b'' | |||||
|
1 | # -*- coding: utf-8 -*- | |||
|
2 | ||||
|
3 | # Copyright (C) 2010-2017 RhodeCode GmbH | |||
|
4 | # | |||
|
5 | # This program is free software: you can redistribute it and/or modify | |||
|
6 | # it under the terms of the GNU Affero General Public License, version 3 | |||
|
7 | # (only), as published by the Free Software Foundation. | |||
|
8 | # | |||
|
9 | # This program is distributed in the hope that it will be useful, | |||
|
10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
|
11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
|
12 | # GNU General Public License for more details. | |||
|
13 | # | |||
|
14 | # You should have received a copy of the GNU Affero General Public License | |||
|
15 | # along with this program. If not, see <http://www.gnu.org/licenses/>. | |||
|
16 | # | |||
|
17 | # This program is dual-licensed. If you wish to learn more about the | |||
|
18 | # RhodeCode Enterprise Edition, including its added features, Support services, | |||
|
19 | # and proprietary license terms, please see https://rhodecode.com/licenses/ | |||
|
20 | ||||
|
21 | import pytest | |||
|
22 | import mock | |||
|
23 | ||||
|
24 | from rhodecode.apps._base import ADMIN_PREFIX | |||
|
25 | from rhodecode.lib import helpers as h | |||
|
26 | from rhodecode.lib.auth import check_password | |||
|
27 | from rhodecode.model.meta import Session | |||
|
28 | from rhodecode.model.user import UserModel | |||
|
29 | from rhodecode.tests import assert_session_flash | |||
|
30 | from rhodecode.tests.fixture import Fixture, TestController, error_function | |||
|
31 | ||||
|
32 | fixture = Fixture() | |||
|
33 | ||||
|
34 | ||||
|
35 | def route_path(name, **kwargs): | |||
|
36 | return { | |||
|
37 | 'home': '/', | |||
|
38 | 'my_account_password': | |||
|
39 | ADMIN_PREFIX + '/my_account/password', | |||
|
40 | }[name].format(**kwargs) | |||
|
41 | ||||
|
42 | ||||
|
43 | test_user_1 = 'testme' | |||
|
44 | test_user_1_password = '0jd83nHNS/d23n' | |||
|
45 | ||||
|
46 | ||||
|
47 | class TestMyAccountPassword(TestController): | |||
|
48 | def test_valid_change_password(self, user_util): | |||
|
49 | new_password = 'my_new_valid_password' | |||
|
50 | user = user_util.create_user(password=test_user_1_password) | |||
|
51 | self.log_user(user.username, test_user_1_password) | |||
|
52 | ||||
|
53 | form_data = [ | |||
|
54 | ('current_password', test_user_1_password), | |||
|
55 | ('__start__', 'new_password:mapping'), | |||
|
56 | ('new_password', new_password), | |||
|
57 | ('new_password-confirm', new_password), | |||
|
58 | ('__end__', 'new_password:mapping'), | |||
|
59 | ('csrf_token', self.csrf_token), | |||
|
60 | ] | |||
|
61 | response = self.app.post(route_path('my_account_password'), form_data).follow() | |||
|
62 | assert 'Successfully updated password' in response | |||
|
63 | ||||
|
64 | # check_password depends on user being in session | |||
|
65 | Session().add(user) | |||
|
66 | try: | |||
|
67 | assert check_password(new_password, user.password) | |||
|
68 | finally: | |||
|
69 | Session().expunge(user) | |||
|
70 | ||||
|
71 | @pytest.mark.parametrize('current_pw, new_pw, confirm_pw', [ | |||
|
72 | ('', 'abcdef123', 'abcdef123'), | |||
|
73 | ('wrong_pw', 'abcdef123', 'abcdef123'), | |||
|
74 | (test_user_1_password, test_user_1_password, test_user_1_password), | |||
|
75 | (test_user_1_password, '', ''), | |||
|
76 | (test_user_1_password, 'abcdef123', ''), | |||
|
77 | (test_user_1_password, '', 'abcdef123'), | |||
|
78 | (test_user_1_password, 'not_the', 'same_pw'), | |||
|
79 | (test_user_1_password, 'short', 'short'), | |||
|
80 | ]) | |||
|
81 | def test_invalid_change_password(self, current_pw, new_pw, confirm_pw, | |||
|
82 | user_util): | |||
|
83 | user = user_util.create_user(password=test_user_1_password) | |||
|
84 | self.log_user(user.username, test_user_1_password) | |||
|
85 | ||||
|
86 | form_data = [ | |||
|
87 | ('current_password', current_pw), | |||
|
88 | ('__start__', 'new_password:mapping'), | |||
|
89 | ('new_password', new_pw), | |||
|
90 | ('new_password-confirm', confirm_pw), | |||
|
91 | ('__end__', 'new_password:mapping'), | |||
|
92 | ('csrf_token', self.csrf_token), | |||
|
93 | ] | |||
|
94 | response = self.app.post(route_path('my_account_password'), form_data) | |||
|
95 | ||||
|
96 | assert_response = response.assert_response() | |||
|
97 | assert assert_response.get_elements('.error-block') | |||
|
98 | ||||
|
99 | @mock.patch.object(UserModel, 'update_user', error_function) | |||
|
100 | def test_invalid_change_password_exception(self, user_util): | |||
|
101 | user = user_util.create_user(password=test_user_1_password) | |||
|
102 | self.log_user(user.username, test_user_1_password) | |||
|
103 | ||||
|
104 | form_data = [ | |||
|
105 | ('current_password', test_user_1_password), | |||
|
106 | ('__start__', 'new_password:mapping'), | |||
|
107 | ('new_password', '123456'), | |||
|
108 | ('new_password-confirm', '123456'), | |||
|
109 | ('__end__', 'new_password:mapping'), | |||
|
110 | ('csrf_token', self.csrf_token), | |||
|
111 | ] | |||
|
112 | response = self.app.post(route_path('my_account_password'), form_data) | |||
|
113 | assert_session_flash( | |||
|
114 | response, 'Error occurred during update of user password') | |||
|
115 | ||||
|
116 | def test_password_is_updated_in_session_on_password_change(self, user_util): | |||
|
117 | old_password = 'abcdef123' | |||
|
118 | new_password = 'abcdef124' | |||
|
119 | ||||
|
120 | user = user_util.create_user(password=old_password) | |||
|
121 | session = self.log_user(user.username, old_password) | |||
|
122 | old_password_hash = session['password'] | |||
|
123 | ||||
|
124 | form_data = [ | |||
|
125 | ('current_password', old_password), | |||
|
126 | ('__start__', 'new_password:mapping'), | |||
|
127 | ('new_password', new_password), | |||
|
128 | ('new_password-confirm', new_password), | |||
|
129 | ('__end__', 'new_password:mapping'), | |||
|
130 | ('csrf_token', self.csrf_token), | |||
|
131 | ] | |||
|
132 | self.app.post(route_path('my_account_password'), form_data) | |||
|
133 | ||||
|
134 | response = self.app.get(route_path('home')) | |||
|
135 | new_password_hash = response.session['rhodecode_user']['password'] | |||
|
136 | ||||
|
137 | assert old_password_hash != new_password_hash No newline at end of file |
@@ -20,6 +20,7 b'' | |||||
20 |
|
20 | |||
21 | import logging |
|
21 | import logging | |
22 | from pylons import tmpl_context as c |
|
22 | from pylons import tmpl_context as c | |
|
23 | from pyramid.httpexceptions import HTTPFound | |||
23 |
|
24 | |||
24 | from rhodecode.lib.utils2 import StrictAttributeDict |
|
25 | from rhodecode.lib.utils2 import StrictAttributeDict | |
25 |
|
26 | |||
@@ -41,6 +42,7 b' class BaseAppView(object):' | |||||
41 | self.context = context |
|
42 | self.context = context | |
42 | self.session = request.session |
|
43 | self.session = request.session | |
43 | self._rhodecode_user = request.user # auth user |
|
44 | self._rhodecode_user = request.user # auth user | |
|
45 | self._rhodecode_db_user = self._rhodecode_user.get_instance() | |||
44 |
|
46 | |||
45 | def _get_local_tmpl_context(self): |
|
47 | def _get_local_tmpl_context(self): | |
46 | c = TemplateArgs() |
|
48 | c = TemplateArgs() |
@@ -23,6 +23,15 b' from rhodecode.apps._base import ADMIN_P' | |||||
23 |
|
23 | |||
24 |
|
24 | |||
25 | def includeme(config): |
|
25 | def includeme(config): | |
|
26 | ||||
|
27 | config.add_route( | |||
|
28 | name='my_account_password', | |||
|
29 | pattern=ADMIN_PREFIX + '/my_account/password') | |||
|
30 | ||||
|
31 | config.add_route( | |||
|
32 | name='my_account_password_update', | |||
|
33 | pattern=ADMIN_PREFIX + '/my_account/password') | |||
|
34 | ||||
26 | config.add_route( |
|
35 | config.add_route( | |
27 | name='my_account_auth_tokens', |
|
36 | name='my_account_auth_tokens', | |
28 | pattern=ADMIN_PREFIX + '/my_account/auth_tokens') |
|
37 | pattern=ADMIN_PREFIX + '/my_account/auth_tokens') |
@@ -24,11 +24,14 b' from pyramid.httpexceptions import HTTPF' | |||||
24 | from pyramid.view import view_config |
|
24 | from pyramid.view import view_config | |
25 |
|
25 | |||
26 | from rhodecode.apps._base import BaseAppView |
|
26 | from rhodecode.apps._base import BaseAppView | |
|
27 | from rhodecode import forms | |||
27 | from rhodecode.lib.auth import LoginRequired, NotAnonymous, CSRFRequired |
|
28 | from rhodecode.lib.auth import LoginRequired, NotAnonymous, CSRFRequired | |
28 | from rhodecode.lib.utils2 import safe_int |
|
|||
29 | from rhodecode.lib import helpers as h |
|
29 | from rhodecode.lib import helpers as h | |
|
30 | from rhodecode.lib.utils2 import safe_int, md5 | |||
30 | from rhodecode.model.auth_token import AuthTokenModel |
|
31 | from rhodecode.model.auth_token import AuthTokenModel | |
31 | from rhodecode.model.meta import Session |
|
32 | from rhodecode.model.meta import Session | |
|
33 | from rhodecode.model.user import UserModel | |||
|
34 | from rhodecode.model.validation_schema.schemas import user_schema | |||
32 |
|
35 | |||
33 | log = logging.getLogger(__name__) |
|
36 | log = logging.getLogger(__name__) | |
34 |
|
37 | |||
@@ -42,7 +45,6 b' class MyAccountView(BaseAppView):' | |||||
42 |
|
45 | |||
43 | def load_default_context(self): |
|
46 | def load_default_context(self): | |
44 | c = self._get_local_tmpl_context() |
|
47 | c = self._get_local_tmpl_context() | |
45 |
|
||||
46 | c.user = c.auth_user.get_instance() |
|
48 | c.user = c.auth_user.get_instance() | |
47 | c.allow_scoped_tokens = self.ALLOW_SCOPED_TOKENS |
|
49 | c.allow_scoped_tokens = self.ALLOW_SCOPED_TOKENS | |
48 | self._register_global_c(c) |
|
50 | self._register_global_c(c) | |
@@ -51,6 +53,69 b' class MyAccountView(BaseAppView):' | |||||
51 | @LoginRequired() |
|
53 | @LoginRequired() | |
52 | @NotAnonymous() |
|
54 | @NotAnonymous() | |
53 | @view_config( |
|
55 | @view_config( | |
|
56 | route_name='my_account_password', request_method='GET', | |||
|
57 | renderer='rhodecode:templates/admin/my_account/my_account.mako') | |||
|
58 | def my_account_password(self): | |||
|
59 | c = self.load_default_context() | |||
|
60 | c.active = 'password' | |||
|
61 | c.extern_type = c.user.extern_type | |||
|
62 | ||||
|
63 | schema = user_schema.ChangePasswordSchema().bind( | |||
|
64 | username=c.user.username) | |||
|
65 | ||||
|
66 | form = forms.Form( | |||
|
67 | schema, buttons=(forms.buttons.save, forms.buttons.reset)) | |||
|
68 | ||||
|
69 | c.form = form | |||
|
70 | return self._get_template_context(c) | |||
|
71 | ||||
|
72 | @LoginRequired() | |||
|
73 | @NotAnonymous() | |||
|
74 | @CSRFRequired() | |||
|
75 | @view_config( | |||
|
76 | route_name='my_account_password', request_method='POST', | |||
|
77 | renderer='rhodecode:templates/admin/my_account/my_account.mako') | |||
|
78 | def my_account_password_update(self): | |||
|
79 | _ = self.request.translate | |||
|
80 | c = self.load_default_context() | |||
|
81 | c.active = 'password' | |||
|
82 | c.extern_type = c.user.extern_type | |||
|
83 | ||||
|
84 | schema = user_schema.ChangePasswordSchema().bind( | |||
|
85 | username=c.user.username) | |||
|
86 | ||||
|
87 | form = forms.Form( | |||
|
88 | schema, buttons=(forms.buttons.save, forms.buttons.reset)) | |||
|
89 | ||||
|
90 | if c.extern_type != 'rhodecode': | |||
|
91 | raise HTTPFound(self.request.route_path('my_account_password')) | |||
|
92 | ||||
|
93 | controls = self.request.POST.items() | |||
|
94 | try: | |||
|
95 | valid_data = form.validate(controls) | |||
|
96 | UserModel().update_user(c.user.user_id, **valid_data) | |||
|
97 | c.user.update_userdata(force_password_change=False) | |||
|
98 | Session().commit() | |||
|
99 | except forms.ValidationFailure as e: | |||
|
100 | c.form = e | |||
|
101 | return self._get_template_context(c) | |||
|
102 | ||||
|
103 | except Exception: | |||
|
104 | log.exception("Exception updating password") | |||
|
105 | h.flash(_('Error occurred during update of user password'), | |||
|
106 | category='error') | |||
|
107 | else: | |||
|
108 | instance = c.auth_user.get_instance() | |||
|
109 | self.session.setdefault('rhodecode_user', {}).update( | |||
|
110 | {'password': md5(instance.password)}) | |||
|
111 | self.session.save() | |||
|
112 | h.flash(_("Successfully updated password"), category='success') | |||
|
113 | ||||
|
114 | raise HTTPFound(self.request.route_path('my_account_password')) | |||
|
115 | ||||
|
116 | @LoginRequired() | |||
|
117 | @NotAnonymous() | |||
|
118 | @view_config( | |||
54 | route_name='my_account_auth_tokens', request_method='GET', |
|
119 | route_name='my_account_auth_tokens', request_method='GET', | |
55 | renderer='rhodecode:templates/admin/my_account/my_account.mako') |
|
120 | renderer='rhodecode:templates/admin/my_account/my_account.mako') | |
56 | def my_account_auth_tokens(self): |
|
121 | def my_account_auth_tokens(self): |
@@ -512,8 +512,10 b' def make_map(config):' | |||||
512 | m.connect('my_account', '/my_account', |
|
512 | m.connect('my_account', '/my_account', | |
513 | action='my_account_update', conditions={'method': ['POST']}) |
|
513 | action='my_account_update', conditions={'method': ['POST']}) | |
514 |
|
514 | |||
|
515 | # NOTE(marcink): this needs to be kept for password force flag to be | |||
|
516 | # handler, remove after migration to pyramid | |||
515 | m.connect('my_account_password', '/my_account/password', |
|
517 | m.connect('my_account_password', '/my_account/password', | |
516 |
action='my_account_password', conditions={'method': ['GET' |
|
518 | action='my_account_password', conditions={'method': ['GET']}) | |
517 |
|
519 | |||
518 | m.connect('my_account_repos', '/my_account/repos', |
|
520 | m.connect('my_account_repos', '/my_account/repos', | |
519 | action='my_account_repos', conditions={'method': ['GET']}) |
|
521 | action='my_account_repos', conditions={'method': ['GET']}) |
@@ -34,19 +34,17 b' from pylons.controllers.util import redi' | |||||
34 | from pylons.i18n.translation import _ |
|
34 | from pylons.i18n.translation import _ | |
35 | from sqlalchemy.orm import joinedload |
|
35 | from sqlalchemy.orm import joinedload | |
36 |
|
36 | |||
37 | from rhodecode import forms |
|
|||
38 | from rhodecode.lib import helpers as h |
|
37 | from rhodecode.lib import helpers as h | |
39 | from rhodecode.lib import auth |
|
38 | from rhodecode.lib import auth | |
40 | from rhodecode.lib.auth import ( |
|
39 | from rhodecode.lib.auth import ( | |
41 | LoginRequired, NotAnonymous, AuthUser) |
|
40 | LoginRequired, NotAnonymous, AuthUser) | |
42 | from rhodecode.lib.base import BaseController, render |
|
41 | from rhodecode.lib.base import BaseController, render | |
43 | from rhodecode.lib.utils import jsonify |
|
42 | from rhodecode.lib.utils import jsonify | |
44 |
from rhodecode.lib.utils2 import safe_int, |
|
43 | from rhodecode.lib.utils2 import safe_int, str2bool | |
45 | from rhodecode.lib.ext_json import json |
|
44 | from rhodecode.lib.ext_json import json | |
46 | from rhodecode.lib.channelstream import channelstream_request, \ |
|
45 | from rhodecode.lib.channelstream import channelstream_request, \ | |
47 | ChannelstreamException |
|
46 | ChannelstreamException | |
48 |
|
47 | |||
49 | from rhodecode.model.validation_schema.schemas import user_schema |
|
|||
50 | from rhodecode.model.db import ( |
|
48 | from rhodecode.model.db import ( | |
51 | Repository, PullRequest, UserEmailMap, User, UserFollowing) |
|
49 | Repository, PullRequest, UserEmailMap, User, UserFollowing) | |
52 | from rhodecode.model.forms import UserForm |
|
50 | from rhodecode.model.forms import UserForm | |
@@ -194,47 +192,6 b' class MyAccountController(BaseController' | |||||
194 | force_defaults=False |
|
192 | force_defaults=False | |
195 | ) |
|
193 | ) | |
196 |
|
194 | |||
197 | @auth.CSRFRequired(except_methods=['GET']) |
|
|||
198 | def my_account_password(self): |
|
|||
199 | c.active = 'password' |
|
|||
200 | self.__load_data() |
|
|||
201 | c.extern_type = c.user.extern_type |
|
|||
202 |
|
||||
203 | schema = user_schema.ChangePasswordSchema().bind( |
|
|||
204 | username=c.rhodecode_user.username) |
|
|||
205 |
|
||||
206 | form = forms.Form(schema, |
|
|||
207 | buttons=(forms.buttons.save, forms.buttons.reset)) |
|
|||
208 |
|
||||
209 | if request.method == 'POST' and c.extern_type == 'rhodecode': |
|
|||
210 | controls = request.POST.items() |
|
|||
211 | try: |
|
|||
212 | valid_data = form.validate(controls) |
|
|||
213 | UserModel().update_user(c.rhodecode_user.user_id, **valid_data) |
|
|||
214 | instance = c.rhodecode_user.get_instance() |
|
|||
215 | instance.update_userdata(force_password_change=False) |
|
|||
216 | Session().commit() |
|
|||
217 | except forms.ValidationFailure as e: |
|
|||
218 | request.session.flash( |
|
|||
219 | _('Error occurred during update of user password'), |
|
|||
220 | queue='error') |
|
|||
221 | form = e |
|
|||
222 | except Exception: |
|
|||
223 | log.exception("Exception updating password") |
|
|||
224 | request.session.flash( |
|
|||
225 | _('Error occurred during update of user password'), |
|
|||
226 | queue='error') |
|
|||
227 | else: |
|
|||
228 | session.setdefault('rhodecode_user', {}).update( |
|
|||
229 | {'password': md5(instance.password)}) |
|
|||
230 | session.save() |
|
|||
231 | request.session.flash( |
|
|||
232 | _("Successfully updated password"), queue='success') |
|
|||
233 | return redirect(url('my_account_password')) |
|
|||
234 |
|
||||
235 | c.form = form |
|
|||
236 | return render('admin/my_account/my_account.mako') |
|
|||
237 |
|
||||
238 | def my_account_repos(self): |
|
195 | def my_account_repos(self): | |
239 | c.active = 'repos' |
|
196 | c.active = 'repos' | |
240 | self.__load_data() |
|
197 | self.__load_data() |
@@ -27,7 +27,7 b'' | |||||
27 | <div class="sidebar"> |
|
27 | <div class="sidebar"> | |
28 | <ul class="nav nav-pills nav-stacked"> |
|
28 | <ul class="nav nav-pills nav-stacked"> | |
29 | <li class="${'active' if c.active=='profile' or c.active=='profile_edit' else ''}"><a href="${h.url('my_account')}">${_('Profile')}</a></li> |
|
29 | <li class="${'active' if c.active=='profile' or c.active=='profile_edit' else ''}"><a href="${h.url('my_account')}">${_('Profile')}</a></li> | |
30 |
<li class="${'active' if c.active=='password' else ''}"><a href="${h. |
|
30 | <li class="${'active' if c.active=='password' else ''}"><a href="${h.route_path('my_account_password')}">${_('Password')}</a></li> | |
31 | <li class="${'active' if c.active=='auth_tokens' else ''}"><a href="${h.route_path('my_account_auth_tokens')}">${_('Auth Tokens')}</a></li> |
|
31 | <li class="${'active' if c.active=='auth_tokens' else ''}"><a href="${h.route_path('my_account_auth_tokens')}">${_('Auth Tokens')}</a></li> | |
32 | ## TODO: Find a better integration of oauth views into navigation. |
|
32 | ## TODO: Find a better integration of oauth views into navigation. | |
33 | <% my_account_oauth_url = h.route_path_or_none('my_account_oauth') %> |
|
33 | <% my_account_oauth_url = h.route_path_or_none('my_account_oauth') %> |
@@ -21,9 +21,7 b'' | |||||
21 | import pytest |
|
21 | import pytest | |
22 |
|
22 | |||
23 | from rhodecode.lib import helpers as h |
|
23 | from rhodecode.lib import helpers as h | |
24 | from rhodecode.lib.auth import check_password |
|
24 | from rhodecode.model.db import User, UserFollowing, Repository | |
25 | from rhodecode.model.db import User, UserFollowing, Repository, UserApiKeys |
|
|||
26 | from rhodecode.model.meta import Session |
|
|||
27 | from rhodecode.tests import ( |
|
25 | from rhodecode.tests import ( | |
28 | TestController, url, TEST_USER_ADMIN_LOGIN, TEST_USER_REGULAR_EMAIL, |
|
26 | TestController, url, TEST_USER_ADMIN_LOGIN, TEST_USER_REGULAR_EMAIL, | |
29 | assert_session_flash) |
|
27 | assert_session_flash) | |
@@ -253,74 +251,3 b' class TestMyAccountController(TestContro' | |||||
253 | edit=False, old_data={})._messages['username_exists'] |
|
251 | edit=False, old_data={})._messages['username_exists'] | |
254 | msg = h.html_escape(msg % {'username': 'test_admin'}) |
|
252 | msg = h.html_escape(msg % {'username': 'test_admin'}) | |
255 | response.mustcontain(u"%s" % msg) |
|
253 | response.mustcontain(u"%s" % msg) | |
256 |
|
||||
257 | def test_valid_change_password(self, user_util): |
|
|||
258 | new_password = 'my_new_valid_password' |
|
|||
259 | user = user_util.create_user(password=self.test_user_1_password) |
|
|||
260 | session = self.log_user(user.username, self.test_user_1_password) |
|
|||
261 | form_data = [ |
|
|||
262 | ('current_password', self.test_user_1_password), |
|
|||
263 | ('__start__', 'new_password:mapping'), |
|
|||
264 | ('new_password', new_password), |
|
|||
265 | ('new_password-confirm', new_password), |
|
|||
266 | ('__end__', 'new_password:mapping'), |
|
|||
267 | ('csrf_token', self.csrf_token), |
|
|||
268 | ] |
|
|||
269 | response = self.app.post(url('my_account_password'), form_data).follow() |
|
|||
270 | assert 'Successfully updated password' in response |
|
|||
271 |
|
||||
272 | # check_password depends on user being in session |
|
|||
273 | Session().add(user) |
|
|||
274 | try: |
|
|||
275 | assert check_password(new_password, user.password) |
|
|||
276 | finally: |
|
|||
277 | Session().expunge(user) |
|
|||
278 |
|
||||
279 | @pytest.mark.parametrize('current_pw,new_pw,confirm_pw', [ |
|
|||
280 | ('', 'abcdef123', 'abcdef123'), |
|
|||
281 | ('wrong_pw', 'abcdef123', 'abcdef123'), |
|
|||
282 | (test_user_1_password, test_user_1_password, test_user_1_password), |
|
|||
283 | (test_user_1_password, '', ''), |
|
|||
284 | (test_user_1_password, 'abcdef123', ''), |
|
|||
285 | (test_user_1_password, '', 'abcdef123'), |
|
|||
286 | (test_user_1_password, 'not_the', 'same_pw'), |
|
|||
287 | (test_user_1_password, 'short', 'short'), |
|
|||
288 | ]) |
|
|||
289 | def test_invalid_change_password(self, current_pw, new_pw, confirm_pw, |
|
|||
290 | user_util): |
|
|||
291 | user = user_util.create_user(password=self.test_user_1_password) |
|
|||
292 | session = self.log_user(user.username, self.test_user_1_password) |
|
|||
293 | old_password_hash = session['password'] |
|
|||
294 | form_data = [ |
|
|||
295 | ('current_password', current_pw), |
|
|||
296 | ('__start__', 'new_password:mapping'), |
|
|||
297 | ('new_password', new_pw), |
|
|||
298 | ('new_password-confirm', confirm_pw), |
|
|||
299 | ('__end__', 'new_password:mapping'), |
|
|||
300 | ('csrf_token', self.csrf_token), |
|
|||
301 | ] |
|
|||
302 | response = self.app.post(url('my_account_password'), form_data) |
|
|||
303 | assert 'Error occurred' in response |
|
|||
304 |
|
||||
305 | def test_password_is_updated_in_session_on_password_change(self, user_util): |
|
|||
306 | old_password = 'abcdef123' |
|
|||
307 | new_password = 'abcdef124' |
|
|||
308 |
|
||||
309 | user = user_util.create_user(password=old_password) |
|
|||
310 | session = self.log_user(user.username, old_password) |
|
|||
311 | old_password_hash = session['password'] |
|
|||
312 |
|
||||
313 | form_data = [ |
|
|||
314 | ('current_password', old_password), |
|
|||
315 | ('__start__', 'new_password:mapping'), |
|
|||
316 | ('new_password', new_password), |
|
|||
317 | ('new_password-confirm', new_password), |
|
|||
318 | ('__end__', 'new_password:mapping'), |
|
|||
319 | ('csrf_token', self.csrf_token), |
|
|||
320 | ] |
|
|||
321 | self.app.post(url('my_account_password'), form_data) |
|
|||
322 |
|
||||
323 | response = self.app.get(url('home')) |
|
|||
324 | new_password_hash = response.session['rhodecode_user']['password'] |
|
|||
325 |
|
||||
326 | assert old_password_hash != new_password_hash |
|
General Comments 0
You need to be logged in to leave comments.
Login now