##// END OF EJS Templates
removed ftp from allowed schemas...
marcink -
r2679:dffb9222 beta
parent child Browse files
Show More
@@ -1,197 +1,196 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2 """
2 """
3 rhodecode.controllers.login
3 rhodecode.controllers.login
4 ~~~~~~~~~~~~~~~~~~~~~~~~~~~
4 ~~~~~~~~~~~~~~~~~~~~~~~~~~~
5
5
6 Login controller for rhodeocode
6 Login controller for rhodeocode
7
7
8 :created_on: Apr 22, 2010
8 :created_on: Apr 22, 2010
9 :author: marcink
9 :author: marcink
10 :copyright: (C) 2010-2012 Marcin Kuzminski <marcin@python-works.com>
10 :copyright: (C) 2010-2012 Marcin Kuzminski <marcin@python-works.com>
11 :license: GPLv3, see COPYING for more details.
11 :license: GPLv3, see COPYING for more details.
12 """
12 """
13 # This program is free software: you can redistribute it and/or modify
13 # This program is free software: you can redistribute it and/or modify
14 # it under the terms of the GNU General Public License as published by
14 # it under the terms of the GNU General Public License as published by
15 # the Free Software Foundation, either version 3 of the License, or
15 # the Free Software Foundation, either version 3 of the License, or
16 # (at your option) any later version.
16 # (at your option) any later version.
17 #
17 #
18 # This program is distributed in the hope that it will be useful,
18 # This program is distributed in the hope that it will be useful,
19 # but WITHOUT ANY WARRANTY; without even the implied warranty of
19 # but WITHOUT ANY WARRANTY; without even the implied warranty of
20 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 # GNU General Public License for more details.
21 # GNU General Public License for more details.
22 #
22 #
23 # You should have received a copy of the GNU General Public License
23 # You should have received a copy of the GNU General Public License
24 # along with this program. If not, see <http://www.gnu.org/licenses/>.
24 # along with this program. If not, see <http://www.gnu.org/licenses/>.
25
25
26 import logging
26 import logging
27 import formencode
27 import formencode
28 import datetime
28 import datetime
29 import urlparse
29 import urlparse
30
30
31 from formencode import htmlfill
31 from formencode import htmlfill
32 from webob.exc import HTTPFound
32 from webob.exc import HTTPFound
33 from pylons.i18n.translation import _
33 from pylons.i18n.translation import _
34 from pylons.controllers.util import abort, redirect
34 from pylons.controllers.util import abort, redirect
35 from pylons import request, response, session, tmpl_context as c, url
35 from pylons import request, response, session, tmpl_context as c, url
36
36
37 import rhodecode.lib.helpers as h
37 import rhodecode.lib.helpers as h
38 from rhodecode.lib.auth import AuthUser, HasPermissionAnyDecorator
38 from rhodecode.lib.auth import AuthUser, HasPermissionAnyDecorator
39 from rhodecode.lib.base import BaseController, render
39 from rhodecode.lib.base import BaseController, render
40 from rhodecode.model.db import User
40 from rhodecode.model.db import User
41 from rhodecode.model.forms import LoginForm, RegisterForm, PasswordResetForm
41 from rhodecode.model.forms import LoginForm, RegisterForm, PasswordResetForm
42 from rhodecode.model.user import UserModel
42 from rhodecode.model.user import UserModel
43 from rhodecode.model.meta import Session
43 from rhodecode.model.meta import Session
44
44
45
45
46
47 log = logging.getLogger(__name__)
46 log = logging.getLogger(__name__)
48
47
49
48
50 class LoginController(BaseController):
49 class LoginController(BaseController):
51
50
52 def __before__(self):
51 def __before__(self):
53 super(LoginController, self).__before__()
52 super(LoginController, self).__before__()
54
53
55 def index(self):
54 def index(self):
56 # redirect if already logged in
55 # redirect if already logged in
57 c.came_from = request.GET.get('came_from', None)
56 c.came_from = request.GET.get('came_from')
58
57
59 if self.rhodecode_user.is_authenticated \
58 if self.rhodecode_user.is_authenticated \
60 and self.rhodecode_user.username != 'default':
59 and self.rhodecode_user.username != 'default':
61
60
62 return redirect(url('home'))
61 return redirect(url('home'))
63
62
64 if request.POST:
63 if request.POST:
65 # import Login Form validator class
64 # import Login Form validator class
66 login_form = LoginForm()
65 login_form = LoginForm()
67 try:
66 try:
68 session.invalidate()
67 session.invalidate()
69 c.form_result = login_form.to_python(dict(request.POST))
68 c.form_result = login_form.to_python(dict(request.POST))
70 # form checks for username/password, now we're authenticated
69 # form checks for username/password, now we're authenticated
71 username = c.form_result['username']
70 username = c.form_result['username']
72 user = User.get_by_username(username, case_insensitive=True)
71 user = User.get_by_username(username, case_insensitive=True)
73 auth_user = AuthUser(user.user_id)
72 auth_user = AuthUser(user.user_id)
74 auth_user.set_authenticated()
73 auth_user.set_authenticated()
75 cs = auth_user.get_cookie_store()
74 cs = auth_user.get_cookie_store()
76 session['rhodecode_user'] = cs
75 session['rhodecode_user'] = cs
77 user.update_lastlogin()
76 user.update_lastlogin()
78 Session().commit()
77 Session().commit()
79
78
80 # If they want to be remembered, update the cookie
79 # If they want to be remembered, update the cookie
81 if c.form_result['remember'] is not False:
80 if c.form_result['remember'] is not False:
82 _year = (datetime.datetime.now() +
81 _year = (datetime.datetime.now() +
83 datetime.timedelta(seconds=60 * 60 * 24 * 365))
82 datetime.timedelta(seconds=60 * 60 * 24 * 365))
84 session._set_cookie_expires(_year)
83 session._set_cookie_expires(_year)
85
84
86 session.save()
85 session.save()
87
86
88 log.info('user %s is now authenticated and stored in '
87 log.info('user %s is now authenticated and stored in '
89 'session, session attrs %s' % (username, cs))
88 'session, session attrs %s' % (username, cs))
90
89
91 # dumps session attrs back to cookie
90 # dumps session attrs back to cookie
92 session._update_cookie_out()
91 session._update_cookie_out()
93
92
94 # we set new cookie
93 # we set new cookie
95 headers = None
94 headers = None
96 if session.request['set_cookie']:
95 if session.request['set_cookie']:
97 # send set-cookie headers back to response to update cookie
96 # send set-cookie headers back to response to update cookie
98 headers = [('Set-Cookie', session.request['cookie_out'])]
97 headers = [('Set-Cookie', session.request['cookie_out'])]
99
98
100 allowed_schemes = ['http', 'https', 'ftp']
99 allowed_schemes = ['http', 'https']
101 parsed = urlparse.urlparse(c.came_from)
102 server_parsed = urlparse.urlparse(url.current())
103
104 if parsed.scheme and parsed.scheme not in allowed_schemes:
105 log.error('Suspicious URL scheme detected %s for url %s' %
106 (parsed.scheme, parsed))
107 c.came_from = url('home')
108 elif server_parsed.netloc != parsed.netloc:
109 log.error('Suspicious NETLOC detected %s for url %s'
110 'server url is: %s' %
111 (parsed.netloc, parsed, server_parsed))
112 c.came_from = url('home')
113 if c.came_from:
100 if c.came_from:
101 parsed = urlparse.urlparse(c.came_from)
102 server_parsed = urlparse.urlparse(url.current())
103 if parsed.scheme and parsed.scheme not in allowed_schemes:
104 log.error(
105 'Suspicious URL scheme detected %s for url %s' %
106 (parsed.scheme, parsed))
107 c.came_from = url('home')
108 elif server_parsed.netloc != parsed.netloc:
109 log.error('Suspicious NETLOC detected %s for url %s'
110 'server url is: %s' %
111 (parsed.netloc, parsed, server_parsed))
112 c.came_from = url('home')
114 raise HTTPFound(location=c.came_from, headers=headers)
113 raise HTTPFound(location=c.came_from, headers=headers)
115 else:
114 else:
116 raise HTTPFound(location=url('home'), headers=headers)
115 raise HTTPFound(location=url('home'), headers=headers)
117
116
118 except formencode.Invalid, errors:
117 except formencode.Invalid, errors:
119 return htmlfill.render(
118 return htmlfill.render(
120 render('/login.html'),
119 render('/login.html'),
121 defaults=errors.value,
120 defaults=errors.value,
122 errors=errors.error_dict or {},
121 errors=errors.error_dict or {},
123 prefix_error=False,
122 prefix_error=False,
124 encoding="UTF-8")
123 encoding="UTF-8")
125
124
126 return render('/login.html')
125 return render('/login.html')
127
126
128 @HasPermissionAnyDecorator('hg.admin', 'hg.register.auto_activate',
127 @HasPermissionAnyDecorator('hg.admin', 'hg.register.auto_activate',
129 'hg.register.manual_activate')
128 'hg.register.manual_activate')
130 def register(self):
129 def register(self):
131 c.auto_active = False
130 c.auto_active = False
132 for perm in User.get_by_username('default').user_perms:
131 for perm in User.get_by_username('default').user_perms:
133 if perm.permission.permission_name == 'hg.register.auto_activate':
132 if perm.permission.permission_name == 'hg.register.auto_activate':
134 c.auto_active = True
133 c.auto_active = True
135 break
134 break
136
135
137 if request.POST:
136 if request.POST:
138
137
139 register_form = RegisterForm()()
138 register_form = RegisterForm()()
140 try:
139 try:
141 form_result = register_form.to_python(dict(request.POST))
140 form_result = register_form.to_python(dict(request.POST))
142 form_result['active'] = c.auto_active
141 form_result['active'] = c.auto_active
143 UserModel().create_registration(form_result)
142 UserModel().create_registration(form_result)
144 h.flash(_('You have successfully registered into rhodecode'),
143 h.flash(_('You have successfully registered into rhodecode'),
145 category='success')
144 category='success')
146 Session().commit()
145 Session().commit()
147 return redirect(url('login_home'))
146 return redirect(url('login_home'))
148
147
149 except formencode.Invalid, errors:
148 except formencode.Invalid, errors:
150 return htmlfill.render(
149 return htmlfill.render(
151 render('/register.html'),
150 render('/register.html'),
152 defaults=errors.value,
151 defaults=errors.value,
153 errors=errors.error_dict or {},
152 errors=errors.error_dict or {},
154 prefix_error=False,
153 prefix_error=False,
155 encoding="UTF-8")
154 encoding="UTF-8")
156
155
157 return render('/register.html')
156 return render('/register.html')
158
157
159 def password_reset(self):
158 def password_reset(self):
160 if request.POST:
159 if request.POST:
161 password_reset_form = PasswordResetForm()()
160 password_reset_form = PasswordResetForm()()
162 try:
161 try:
163 form_result = password_reset_form.to_python(dict(request.POST))
162 form_result = password_reset_form.to_python(dict(request.POST))
164 UserModel().reset_password_link(form_result)
163 UserModel().reset_password_link(form_result)
165 h.flash(_('Your password reset link was sent'),
164 h.flash(_('Your password reset link was sent'),
166 category='success')
165 category='success')
167 return redirect(url('login_home'))
166 return redirect(url('login_home'))
168
167
169 except formencode.Invalid, errors:
168 except formencode.Invalid, errors:
170 return htmlfill.render(
169 return htmlfill.render(
171 render('/password_reset.html'),
170 render('/password_reset.html'),
172 defaults=errors.value,
171 defaults=errors.value,
173 errors=errors.error_dict or {},
172 errors=errors.error_dict or {},
174 prefix_error=False,
173 prefix_error=False,
175 encoding="UTF-8")
174 encoding="UTF-8")
176
175
177 return render('/password_reset.html')
176 return render('/password_reset.html')
178
177
179 def password_reset_confirmation(self):
178 def password_reset_confirmation(self):
180 if request.GET and request.GET.get('key'):
179 if request.GET and request.GET.get('key'):
181 try:
180 try:
182 user = User.get_by_api_key(request.GET.get('key'))
181 user = User.get_by_api_key(request.GET.get('key'))
183 data = dict(email=user.email)
182 data = dict(email=user.email)
184 UserModel().reset_password(data)
183 UserModel().reset_password(data)
185 h.flash(_('Your password reset was successful, '
184 h.flash(_('Your password reset was successful, '
186 'new password has been sent to your email'),
185 'new password has been sent to your email'),
187 category='success')
186 category='success')
188 except Exception, e:
187 except Exception, e:
189 log.error(e)
188 log.error(e)
190 return redirect(url('reset_password'))
189 return redirect(url('reset_password'))
191
190
192 return redirect(url('login_home'))
191 return redirect(url('login_home'))
193
192
194 def logout(self):
193 def logout(self):
195 session.delete()
194 session.delete()
196 log.info('Logging out and deleting session for user')
195 log.info('Logging out and deleting session for user')
197 redirect(url('home'))
196 redirect(url('home'))
@@ -1,272 +1,291 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2 from rhodecode.tests import *
2 from rhodecode.tests import *
3 from rhodecode.model.db import User, Notification
3 from rhodecode.model.db import User, Notification
4 from rhodecode.lib.utils2 import generate_api_key
4 from rhodecode.lib.utils2 import generate_api_key
5 from rhodecode.lib.auth import check_password
5 from rhodecode.lib.auth import check_password
6 from rhodecode.lib import helpers as h
6 from rhodecode.lib import helpers as h
7 from rhodecode.model import validators
7 from rhodecode.model import validators
8
8
9
9
10 class TestLoginController(TestController):
10 class TestLoginController(TestController):
11
11
12 def tearDown(self):
12 def tearDown(self):
13 for n in Notification.query().all():
13 for n in Notification.query().all():
14 self.Session().delete(n)
14 self.Session().delete(n)
15
15
16 self.Session().commit()
16 self.Session().commit()
17 self.assertEqual(Notification.query().all(), [])
17 self.assertEqual(Notification.query().all(), [])
18
18
19 def test_index(self):
19 def test_index(self):
20 response = self.app.get(url(controller='login', action='index'))
20 response = self.app.get(url(controller='login', action='index'))
21 self.assertEqual(response.status, '200 OK')
21 self.assertEqual(response.status, '200 OK')
22 # Test response...
22 # Test response...
23
23
24 def test_login_admin_ok(self):
24 def test_login_admin_ok(self):
25 response = self.app.post(url(controller='login', action='index'),
25 response = self.app.post(url(controller='login', action='index'),
26 {'username': 'test_admin',
26 {'username': 'test_admin',
27 'password': 'test12'})
27 'password': 'test12'})
28 self.assertEqual(response.status, '302 Found')
28 self.assertEqual(response.status, '302 Found')
29 self.assertEqual(response.session['rhodecode_user'].get('username'),
29 self.assertEqual(response.session['rhodecode_user'].get('username'),
30 'test_admin')
30 'test_admin')
31 response = response.follow()
31 response = response.follow()
32 self.assertTrue('%s repository' % HG_REPO in response.body)
32 self.assertTrue('%s repository' % HG_REPO in response.body)
33
33
34 def test_login_regular_ok(self):
34 def test_login_regular_ok(self):
35 response = self.app.post(url(controller='login', action='index'),
35 response = self.app.post(url(controller='login', action='index'),
36 {'username': 'test_regular',
36 {'username': 'test_regular',
37 'password': 'test12'})
37 'password': 'test12'})
38
38
39 self.assertEqual(response.status, '302 Found')
39 self.assertEqual(response.status, '302 Found')
40 self.assertEqual(response.session['rhodecode_user'].get('username'),
40 self.assertEqual(response.session['rhodecode_user'].get('username'),
41 'test_regular')
41 'test_regular')
42 response = response.follow()
42 response = response.follow()
43 self.assertTrue('%s repository' % HG_REPO in response.body)
43 self.assertTrue('%s repository' % HG_REPO in response.body)
44 self.assertTrue('<a title="Admin" href="/_admin">' not in response.body)
44 self.assertTrue('<a title="Admin" href="/_admin">' not in response.body)
45
45
46 def test_login_ok_came_from(self):
46 def test_login_ok_came_from(self):
47 test_came_from = '/_admin/users'
47 test_came_from = '/_admin/users'
48 response = self.app.post(url(controller='login', action='index',
48 response = self.app.post(url(controller='login', action='index',
49 came_from=test_came_from),
49 came_from=test_came_from),
50 {'username': 'test_admin',
50 {'username': 'test_admin',
51 'password': 'test12'})
51 'password': 'test12'})
52 self.assertEqual(response.status, '302 Found')
52 self.assertEqual(response.status, '302 Found')
53 response = response.follow()
53 response = response.follow()
54
54
55 self.assertEqual(response.status, '200 OK')
55 self.assertEqual(response.status, '200 OK')
56 self.assertTrue('Users administration' in response.body)
56 self.assertTrue('Users administration' in response.body)
57
57
58 @parameterized.expand([
59 ('data:text/html,<script>window.alert("xss")</script>',),
60 ('mailto:test@rhodecode.org',),
61 ('file:///etc/passwd',),
62 ('ftp://some.ftp.server',),
63 ('http://other.domain',),
64 ])
65 def test_login_bad_came_froms(self, url_came_from):
66 response = self.app.post(url(controller='login', action='index',
67 came_from=url_came_from),
68 {'username': 'test_admin',
69 'password': 'test12'})
70 self.assertEqual(response.status, '302 Found')
71 self.assertEqual(response._environ['paste.testing_variables']
72 ['tmpl_context'].came_from, '/')
73 response = response.follow()
74
75 self.assertEqual(response.status, '200 OK')
76
58 def test_login_short_password(self):
77 def test_login_short_password(self):
59 response = self.app.post(url(controller='login', action='index'),
78 response = self.app.post(url(controller='login', action='index'),
60 {'username': 'test_admin',
79 {'username': 'test_admin',
61 'password': 'as'})
80 'password': 'as'})
62 self.assertEqual(response.status, '200 OK')
81 self.assertEqual(response.status, '200 OK')
63
82
64 self.assertTrue('Enter 3 characters or more' in response.body)
83 self.assertTrue('Enter 3 characters or more' in response.body)
65
84
66 def test_login_wrong_username_password(self):
85 def test_login_wrong_username_password(self):
67 response = self.app.post(url(controller='login', action='index'),
86 response = self.app.post(url(controller='login', action='index'),
68 {'username': 'error',
87 {'username': 'error',
69 'password': 'test12'})
88 'password': 'test12'})
70
89
71 self.assertTrue('invalid user name' in response.body)
90 self.assertTrue('invalid user name' in response.body)
72 self.assertTrue('invalid password' in response.body)
91 self.assertTrue('invalid password' in response.body)
73
92
74 #==========================================================================
93 #==========================================================================
75 # REGISTRATIONS
94 # REGISTRATIONS
76 #==========================================================================
95 #==========================================================================
77 def test_register(self):
96 def test_register(self):
78 response = self.app.get(url(controller='login', action='register'))
97 response = self.app.get(url(controller='login', action='register'))
79 self.assertTrue('Sign Up to RhodeCode' in response.body)
98 self.assertTrue('Sign Up to RhodeCode' in response.body)
80
99
81 def test_register_err_same_username(self):
100 def test_register_err_same_username(self):
82 uname = 'test_admin'
101 uname = 'test_admin'
83 response = self.app.post(url(controller='login', action='register'),
102 response = self.app.post(url(controller='login', action='register'),
84 {'username': uname,
103 {'username': uname,
85 'password': 'test12',
104 'password': 'test12',
86 'password_confirmation': 'test12',
105 'password_confirmation': 'test12',
87 'email': 'goodmail@domain.com',
106 'email': 'goodmail@domain.com',
88 'firstname': 'test',
107 'firstname': 'test',
89 'lastname': 'test'})
108 'lastname': 'test'})
90
109
91 msg = validators.ValidUsername()._messages['username_exists']
110 msg = validators.ValidUsername()._messages['username_exists']
92 msg = h.html_escape(msg % {'username': uname})
111 msg = h.html_escape(msg % {'username': uname})
93 response.mustcontain(msg)
112 response.mustcontain(msg)
94
113
95 def test_register_err_same_email(self):
114 def test_register_err_same_email(self):
96 response = self.app.post(url(controller='login', action='register'),
115 response = self.app.post(url(controller='login', action='register'),
97 {'username': 'test_admin_0',
116 {'username': 'test_admin_0',
98 'password': 'test12',
117 'password': 'test12',
99 'password_confirmation': 'test12',
118 'password_confirmation': 'test12',
100 'email': 'test_admin@mail.com',
119 'email': 'test_admin@mail.com',
101 'firstname': 'test',
120 'firstname': 'test',
102 'lastname': 'test'})
121 'lastname': 'test'})
103
122
104 msg = validators.UniqSystemEmail()()._messages['email_taken']
123 msg = validators.UniqSystemEmail()()._messages['email_taken']
105 response.mustcontain(msg)
124 response.mustcontain(msg)
106
125
107 def test_register_err_same_email_case_sensitive(self):
126 def test_register_err_same_email_case_sensitive(self):
108 response = self.app.post(url(controller='login', action='register'),
127 response = self.app.post(url(controller='login', action='register'),
109 {'username': 'test_admin_1',
128 {'username': 'test_admin_1',
110 'password': 'test12',
129 'password': 'test12',
111 'password_confirmation': 'test12',
130 'password_confirmation': 'test12',
112 'email': 'TesT_Admin@mail.COM',
131 'email': 'TesT_Admin@mail.COM',
113 'firstname': 'test',
132 'firstname': 'test',
114 'lastname': 'test'})
133 'lastname': 'test'})
115 msg = validators.UniqSystemEmail()()._messages['email_taken']
134 msg = validators.UniqSystemEmail()()._messages['email_taken']
116 response.mustcontain(msg)
135 response.mustcontain(msg)
117
136
118 def test_register_err_wrong_data(self):
137 def test_register_err_wrong_data(self):
119 response = self.app.post(url(controller='login', action='register'),
138 response = self.app.post(url(controller='login', action='register'),
120 {'username': 'xs',
139 {'username': 'xs',
121 'password': 'test',
140 'password': 'test',
122 'password_confirmation': 'test',
141 'password_confirmation': 'test',
123 'email': 'goodmailm',
142 'email': 'goodmailm',
124 'firstname': 'test',
143 'firstname': 'test',
125 'lastname': 'test'})
144 'lastname': 'test'})
126 self.assertEqual(response.status, '200 OK')
145 self.assertEqual(response.status, '200 OK')
127 response.mustcontain('An email address must contain a single @')
146 response.mustcontain('An email address must contain a single @')
128 response.mustcontain('Enter a value 6 characters long or more')
147 response.mustcontain('Enter a value 6 characters long or more')
129
148
130 def test_register_err_username(self):
149 def test_register_err_username(self):
131 response = self.app.post(url(controller='login', action='register'),
150 response = self.app.post(url(controller='login', action='register'),
132 {'username': 'error user',
151 {'username': 'error user',
133 'password': 'test12',
152 'password': 'test12',
134 'password_confirmation': 'test12',
153 'password_confirmation': 'test12',
135 'email': 'goodmailm',
154 'email': 'goodmailm',
136 'firstname': 'test',
155 'firstname': 'test',
137 'lastname': 'test'})
156 'lastname': 'test'})
138
157
139 response.mustcontain('An email address must contain a single @')
158 response.mustcontain('An email address must contain a single @')
140 response.mustcontain('Username may only contain '
159 response.mustcontain('Username may only contain '
141 'alphanumeric characters underscores, '
160 'alphanumeric characters underscores, '
142 'periods or dashes and must begin with '
161 'periods or dashes and must begin with '
143 'alphanumeric character')
162 'alphanumeric character')
144
163
145 def test_register_err_case_sensitive(self):
164 def test_register_err_case_sensitive(self):
146 usr = 'Test_Admin'
165 usr = 'Test_Admin'
147 response = self.app.post(url(controller='login', action='register'),
166 response = self.app.post(url(controller='login', action='register'),
148 {'username': usr,
167 {'username': usr,
149 'password': 'test12',
168 'password': 'test12',
150 'password_confirmation': 'test12',
169 'password_confirmation': 'test12',
151 'email': 'goodmailm',
170 'email': 'goodmailm',
152 'firstname': 'test',
171 'firstname': 'test',
153 'lastname': 'test'})
172 'lastname': 'test'})
154
173
155 response.mustcontain('An email address must contain a single @')
174 response.mustcontain('An email address must contain a single @')
156 msg = validators.ValidUsername()._messages['username_exists']
175 msg = validators.ValidUsername()._messages['username_exists']
157 msg = h.html_escape(msg % {'username': usr})
176 msg = h.html_escape(msg % {'username': usr})
158 response.mustcontain(msg)
177 response.mustcontain(msg)
159
178
160 def test_register_special_chars(self):
179 def test_register_special_chars(self):
161 response = self.app.post(url(controller='login', action='register'),
180 response = self.app.post(url(controller='login', action='register'),
162 {'username': 'xxxaxn',
181 {'username': 'xxxaxn',
163 'password': 'Δ…Δ‡ΕΊΕΌΔ…Ε›Ε›Ε›Ε›',
182 'password': 'Δ…Δ‡ΕΊΕΌΔ…Ε›Ε›Ε›Ε›',
164 'password_confirmation': 'Δ…Δ‡ΕΊΕΌΔ…Ε›Ε›Ε›Ε›',
183 'password_confirmation': 'Δ…Δ‡ΕΊΕΌΔ…Ε›Ε›Ε›Ε›',
165 'email': 'goodmailm@test.plx',
184 'email': 'goodmailm@test.plx',
166 'firstname': 'test',
185 'firstname': 'test',
167 'lastname': 'test'})
186 'lastname': 'test'})
168
187
169 msg = validators.ValidPassword()._messages['invalid_password']
188 msg = validators.ValidPassword()._messages['invalid_password']
170 response.mustcontain(msg)
189 response.mustcontain(msg)
171
190
172 def test_register_password_mismatch(self):
191 def test_register_password_mismatch(self):
173 response = self.app.post(url(controller='login', action='register'),
192 response = self.app.post(url(controller='login', action='register'),
174 {'username': 'xs',
193 {'username': 'xs',
175 'password': '123qwe',
194 'password': '123qwe',
176 'password_confirmation': 'qwe123',
195 'password_confirmation': 'qwe123',
177 'email': 'goodmailm@test.plxa',
196 'email': 'goodmailm@test.plxa',
178 'firstname': 'test',
197 'firstname': 'test',
179 'lastname': 'test'})
198 'lastname': 'test'})
180 msg = validators.ValidPasswordsMatch()._messages['password_mismatch']
199 msg = validators.ValidPasswordsMatch()._messages['password_mismatch']
181 response.mustcontain(msg)
200 response.mustcontain(msg)
182
201
183 def test_register_ok(self):
202 def test_register_ok(self):
184 username = 'test_regular4'
203 username = 'test_regular4'
185 password = 'qweqwe'
204 password = 'qweqwe'
186 email = 'marcin@test.com'
205 email = 'marcin@test.com'
187 name = 'testname'
206 name = 'testname'
188 lastname = 'testlastname'
207 lastname = 'testlastname'
189
208
190 response = self.app.post(url(controller='login', action='register'),
209 response = self.app.post(url(controller='login', action='register'),
191 {'username': username,
210 {'username': username,
192 'password': password,
211 'password': password,
193 'password_confirmation': password,
212 'password_confirmation': password,
194 'email': email,
213 'email': email,
195 'firstname': name,
214 'firstname': name,
196 'lastname': lastname,
215 'lastname': lastname,
197 'admin': True}) # This should be overriden
216 'admin': True}) # This should be overriden
198 self.assertEqual(response.status, '302 Found')
217 self.assertEqual(response.status, '302 Found')
199 self.checkSessionFlash(response, 'You have successfully registered into rhodecode')
218 self.checkSessionFlash(response, 'You have successfully registered into rhodecode')
200
219
201 ret = self.Session().query(User).filter(User.username == 'test_regular4').one()
220 ret = self.Session().query(User).filter(User.username == 'test_regular4').one()
202 self.assertEqual(ret.username, username)
221 self.assertEqual(ret.username, username)
203 self.assertEqual(check_password(password, ret.password), True)
222 self.assertEqual(check_password(password, ret.password), True)
204 self.assertEqual(ret.email, email)
223 self.assertEqual(ret.email, email)
205 self.assertEqual(ret.name, name)
224 self.assertEqual(ret.name, name)
206 self.assertEqual(ret.lastname, lastname)
225 self.assertEqual(ret.lastname, lastname)
207 self.assertNotEqual(ret.api_key, None)
226 self.assertNotEqual(ret.api_key, None)
208 self.assertEqual(ret.admin, False)
227 self.assertEqual(ret.admin, False)
209
228
210 def test_forgot_password_wrong_mail(self):
229 def test_forgot_password_wrong_mail(self):
211 bad_email = 'marcin@wrongmail.org'
230 bad_email = 'marcin@wrongmail.org'
212 response = self.app.post(
231 response = self.app.post(
213 url(controller='login', action='password_reset'),
232 url(controller='login', action='password_reset'),
214 {'email': bad_email, }
233 {'email': bad_email, }
215 )
234 )
216
235
217 msg = validators.ValidSystemEmail()._messages['non_existing_email']
236 msg = validators.ValidSystemEmail()._messages['non_existing_email']
218 msg = h.html_escape(msg % {'email': bad_email})
237 msg = h.html_escape(msg % {'email': bad_email})
219 response.mustcontain()
238 response.mustcontain()
220
239
221 def test_forgot_password(self):
240 def test_forgot_password(self):
222 response = self.app.get(url(controller='login',
241 response = self.app.get(url(controller='login',
223 action='password_reset'))
242 action='password_reset'))
224 self.assertEqual(response.status, '200 OK')
243 self.assertEqual(response.status, '200 OK')
225
244
226 username = 'test_password_reset_1'
245 username = 'test_password_reset_1'
227 password = 'qweqwe'
246 password = 'qweqwe'
228 email = 'marcin@python-works.com'
247 email = 'marcin@python-works.com'
229 name = 'passwd'
248 name = 'passwd'
230 lastname = 'reset'
249 lastname = 'reset'
231
250
232 new = User()
251 new = User()
233 new.username = username
252 new.username = username
234 new.password = password
253 new.password = password
235 new.email = email
254 new.email = email
236 new.name = name
255 new.name = name
237 new.lastname = lastname
256 new.lastname = lastname
238 new.api_key = generate_api_key(username)
257 new.api_key = generate_api_key(username)
239 self.Session().add(new)
258 self.Session().add(new)
240 self.Session().commit()
259 self.Session().commit()
241
260
242 response = self.app.post(url(controller='login',
261 response = self.app.post(url(controller='login',
243 action='password_reset'),
262 action='password_reset'),
244 {'email': email, })
263 {'email': email, })
245
264
246 self.checkSessionFlash(response, 'Your password reset link was sent')
265 self.checkSessionFlash(response, 'Your password reset link was sent')
247
266
248 response = response.follow()
267 response = response.follow()
249
268
250 # BAD KEY
269 # BAD KEY
251
270
252 key = "bad"
271 key = "bad"
253 response = self.app.get(url(controller='login',
272 response = self.app.get(url(controller='login',
254 action='password_reset_confirmation',
273 action='password_reset_confirmation',
255 key=key))
274 key=key))
256 self.assertEqual(response.status, '302 Found')
275 self.assertEqual(response.status, '302 Found')
257 self.assertTrue(response.location.endswith(url('reset_password')))
276 self.assertTrue(response.location.endswith(url('reset_password')))
258
277
259 # GOOD KEY
278 # GOOD KEY
260
279
261 key = User.get_by_username(username).api_key
280 key = User.get_by_username(username).api_key
262 response = self.app.get(url(controller='login',
281 response = self.app.get(url(controller='login',
263 action='password_reset_confirmation',
282 action='password_reset_confirmation',
264 key=key))
283 key=key))
265 self.assertEqual(response.status, '302 Found')
284 self.assertEqual(response.status, '302 Found')
266 self.assertTrue(response.location.endswith(url('login_home')))
285 self.assertTrue(response.location.endswith(url('login_home')))
267
286
268 self.checkSessionFlash(response,
287 self.checkSessionFlash(response,
269 ('Your password reset was successful, '
288 ('Your password reset was successful, '
270 'new password has been sent to your email'))
289 'new password has been sent to your email'))
271
290
272 response = response.follow()
291 response = response.follow()
General Comments 0
You need to be logged in to leave comments. Login now