##// END OF EJS Templates
fixed password refill in login form when wrong password was given...
marcink -
r4095:b59568e9 default
parent child Browse files
Show More
@@ -1,204 +1,207 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.lib.exceptions import UserCreationError
40 from rhodecode.lib.exceptions import UserCreationError
41 from rhodecode.model.db import User
41 from rhodecode.model.db import User
42 from rhodecode.model.forms import LoginForm, RegisterForm, PasswordResetForm
42 from rhodecode.model.forms import LoginForm, RegisterForm, PasswordResetForm
43 from rhodecode.model.user import UserModel
43 from rhodecode.model.user import UserModel
44 from rhodecode.model.meta import Session
44 from rhodecode.model.meta import Session
45
45
46
46
47 log = logging.getLogger(__name__)
47 log = logging.getLogger(__name__)
48
48
49
49
50 class LoginController(BaseController):
50 class LoginController(BaseController):
51
51
52 def __before__(self):
52 def __before__(self):
53 super(LoginController, self).__before__()
53 super(LoginController, self).__before__()
54
54
55 def index(self):
55 def index(self):
56 # redirect if already logged in
56 # redirect if already logged in
57 c.came_from = request.GET.get('came_from')
57 c.came_from = request.GET.get('came_from')
58 not_default = self.rhodecode_user.username != 'default'
58 not_default = self.rhodecode_user.username != 'default'
59 ip_allowed = self.rhodecode_user.ip_allowed
59 ip_allowed = self.rhodecode_user.ip_allowed
60 if self.rhodecode_user.is_authenticated and not_default and ip_allowed:
60 if self.rhodecode_user.is_authenticated and not_default and ip_allowed:
61 return redirect(url('home'))
61 return redirect(url('home'))
62
62
63 if request.POST:
63 if request.POST:
64 # import Login Form validator class
64 # import Login Form validator class
65 login_form = LoginForm()
65 login_form = LoginForm()
66 try:
66 try:
67 session.invalidate()
67 session.invalidate()
68 c.form_result = login_form.to_python(dict(request.POST))
68 c.form_result = login_form.to_python(dict(request.POST))
69 # form checks for username/password, now we're authenticated
69 # form checks for username/password, now we're authenticated
70 username = c.form_result['username']
70 username = c.form_result['username']
71 user = User.get_by_username(username, case_insensitive=True)
71 user = User.get_by_username(username, case_insensitive=True)
72 auth_user = AuthUser(user.user_id)
72 auth_user = AuthUser(user.user_id)
73 auth_user.set_authenticated()
73 auth_user.set_authenticated()
74 cs = auth_user.get_cookie_store()
74 cs = auth_user.get_cookie_store()
75 session['rhodecode_user'] = cs
75 session['rhodecode_user'] = cs
76 user.update_lastlogin()
76 user.update_lastlogin()
77 Session().commit()
77 Session().commit()
78
78
79 # If they want to be remembered, update the cookie
79 # If they want to be remembered, update the cookie
80 if c.form_result['remember']:
80 if c.form_result['remember']:
81 _year = (datetime.datetime.now() +
81 _year = (datetime.datetime.now() +
82 datetime.timedelta(seconds=60 * 60 * 24 * 365))
82 datetime.timedelta(seconds=60 * 60 * 24 * 365))
83 session._set_cookie_expires(_year)
83 session._set_cookie_expires(_year)
84
84
85 session.save()
85 session.save()
86
86
87 log.info('user %s is now authenticated and stored in '
87 log.info('user %s is now authenticated and stored in '
88 'session, session attrs %s' % (username, cs))
88 'session, session attrs %s' % (username, cs))
89
89
90 # dumps session attrs back to cookie
90 # dumps session attrs back to cookie
91 session._update_cookie_out()
91 session._update_cookie_out()
92
92
93 # we set new cookie
93 # we set new cookie
94 headers = None
94 headers = None
95 if session.request['set_cookie']:
95 if session.request['set_cookie']:
96 # send set-cookie headers back to response to update cookie
96 # send set-cookie headers back to response to update cookie
97 headers = [('Set-Cookie', session.request['cookie_out'])]
97 headers = [('Set-Cookie', session.request['cookie_out'])]
98
98
99 allowed_schemes = ['http', 'https']
99 allowed_schemes = ['http', 'https']
100 if c.came_from:
100 if c.came_from:
101 parsed = urlparse.urlparse(c.came_from)
101 parsed = urlparse.urlparse(c.came_from)
102 server_parsed = urlparse.urlparse(url.current())
102 server_parsed = urlparse.urlparse(url.current())
103 if parsed.scheme and parsed.scheme not in allowed_schemes:
103 if parsed.scheme and parsed.scheme not in allowed_schemes:
104 log.error(
104 log.error(
105 'Suspicious URL scheme detected %s for url %s' %
105 'Suspicious URL scheme detected %s for url %s' %
106 (parsed.scheme, parsed))
106 (parsed.scheme, parsed))
107 c.came_from = url('home')
107 c.came_from = url('home')
108 elif server_parsed.netloc != parsed.netloc:
108 elif server_parsed.netloc != parsed.netloc:
109 log.error('Suspicious NETLOC detected %s for url %s'
109 log.error('Suspicious NETLOC detected %s for url %s'
110 'server url is: %s' %
110 'server url is: %s' %
111 (parsed.netloc, parsed, server_parsed))
111 (parsed.netloc, parsed, server_parsed))
112 c.came_from = url('home')
112 c.came_from = url('home')
113 raise HTTPFound(location=c.came_from, headers=headers)
113 raise HTTPFound(location=c.came_from, headers=headers)
114 else:
114 else:
115 raise HTTPFound(location=url('home'), headers=headers)
115 raise HTTPFound(location=url('home'), headers=headers)
116
116
117 except formencode.Invalid, errors:
117 except formencode.Invalid, errors:
118 defaults = errors.value
119 # remove password from filling in form again
120 del defaults['password']
118 return htmlfill.render(
121 return htmlfill.render(
119 render('/login.html'),
122 render('/login.html'),
120 defaults=errors.value,
123 defaults=errors.value,
121 errors=errors.error_dict or {},
124 errors=errors.error_dict or {},
122 prefix_error=False,
125 prefix_error=False,
123 encoding="UTF-8")
126 encoding="UTF-8")
124 except UserCreationError, e:
127 except UserCreationError, e:
125 # container auth or other auth functions that create users on
128 # container auth or other auth functions that create users on
126 # the fly can throw this exception signaling that there's issue
129 # the fly can throw this exception signaling that there's issue
127 # with user creation, explanation should be provided in
130 # with user creation, explanation should be provided in
128 # Exception itself
131 # Exception itself
129 h.flash(e, 'error')
132 h.flash(e, 'error')
130
133
131 return render('/login.html')
134 return render('/login.html')
132
135
133 @HasPermissionAnyDecorator('hg.admin', 'hg.register.auto_activate',
136 @HasPermissionAnyDecorator('hg.admin', 'hg.register.auto_activate',
134 'hg.register.manual_activate')
137 'hg.register.manual_activate')
135 def register(self):
138 def register(self):
136 c.auto_active = 'hg.register.auto_activate' in User.get_default_user()\
139 c.auto_active = 'hg.register.auto_activate' in User.get_default_user()\
137 .AuthUser.permissions['global']
140 .AuthUser.permissions['global']
138
141
139 if request.POST:
142 if request.POST:
140 register_form = RegisterForm()()
143 register_form = RegisterForm()()
141 try:
144 try:
142 form_result = register_form.to_python(dict(request.POST))
145 form_result = register_form.to_python(dict(request.POST))
143 form_result['active'] = c.auto_active
146 form_result['active'] = c.auto_active
144 UserModel().create_registration(form_result)
147 UserModel().create_registration(form_result)
145 h.flash(_('You have successfully registered into RhodeCode'),
148 h.flash(_('You have successfully registered into RhodeCode'),
146 category='success')
149 category='success')
147 Session().commit()
150 Session().commit()
148 return redirect(url('login_home'))
151 return redirect(url('login_home'))
149
152
150 except formencode.Invalid, errors:
153 except formencode.Invalid, errors:
151 return htmlfill.render(
154 return htmlfill.render(
152 render('/register.html'),
155 render('/register.html'),
153 defaults=errors.value,
156 defaults=errors.value,
154 errors=errors.error_dict or {},
157 errors=errors.error_dict or {},
155 prefix_error=False,
158 prefix_error=False,
156 encoding="UTF-8")
159 encoding="UTF-8")
157 except UserCreationError, e:
160 except UserCreationError, e:
158 # container auth or other auth functions that create users on
161 # container auth or other auth functions that create users on
159 # the fly can throw this exception signaling that there's issue
162 # the fly can throw this exception signaling that there's issue
160 # with user creation, explanation should be provided in
163 # with user creation, explanation should be provided in
161 # Exception itself
164 # Exception itself
162 h.flash(e, 'error')
165 h.flash(e, 'error')
163
166
164 return render('/register.html')
167 return render('/register.html')
165
168
166 def password_reset(self):
169 def password_reset(self):
167 if request.POST:
170 if request.POST:
168 password_reset_form = PasswordResetForm()()
171 password_reset_form = PasswordResetForm()()
169 try:
172 try:
170 form_result = password_reset_form.to_python(dict(request.POST))
173 form_result = password_reset_form.to_python(dict(request.POST))
171 UserModel().reset_password_link(form_result)
174 UserModel().reset_password_link(form_result)
172 h.flash(_('Your password reset link was sent'),
175 h.flash(_('Your password reset link was sent'),
173 category='success')
176 category='success')
174 return redirect(url('login_home'))
177 return redirect(url('login_home'))
175
178
176 except formencode.Invalid, errors:
179 except formencode.Invalid, errors:
177 return htmlfill.render(
180 return htmlfill.render(
178 render('/password_reset.html'),
181 render('/password_reset.html'),
179 defaults=errors.value,
182 defaults=errors.value,
180 errors=errors.error_dict or {},
183 errors=errors.error_dict or {},
181 prefix_error=False,
184 prefix_error=False,
182 encoding="UTF-8")
185 encoding="UTF-8")
183
186
184 return render('/password_reset.html')
187 return render('/password_reset.html')
185
188
186 def password_reset_confirmation(self):
189 def password_reset_confirmation(self):
187 if request.GET and request.GET.get('key'):
190 if request.GET and request.GET.get('key'):
188 try:
191 try:
189 user = User.get_by_api_key(request.GET.get('key'))
192 user = User.get_by_api_key(request.GET.get('key'))
190 data = dict(email=user.email)
193 data = dict(email=user.email)
191 UserModel().reset_password(data)
194 UserModel().reset_password(data)
192 h.flash(_('Your password reset was successful, '
195 h.flash(_('Your password reset was successful, '
193 'new password has been sent to your email'),
196 'new password has been sent to your email'),
194 category='success')
197 category='success')
195 except Exception, e:
198 except Exception, e:
196 log.error(e)
199 log.error(e)
197 return redirect(url('reset_password'))
200 return redirect(url('reset_password'))
198
201
199 return redirect(url('login_home'))
202 return redirect(url('login_home'))
200
203
201 def logout(self):
204 def logout(self):
202 session.delete()
205 session.delete()
203 log.info('Logging out and deleting session for user')
206 log.info('Logging out and deleting session for user')
204 redirect(url('home'))
207 redirect(url('home'))
General Comments 0
You need to be logged in to leave comments. Login now