Changeset - 5875955def39
[Not reviewed]
beta
0 9 1
Marcin Kuzminski - 14 years ago 2011-07-04 10:59:01
marcin@python-works.com
fixes #223 improve password reset form
10 files changed with 93 insertions and 10 deletions:
0 comments (0 inline, 0 general)
rhodecode/config/routing.py
Show inline comments
 
@@ -294,6 +294,10 @@ def make_map(config):
 
    rmap.connect('reset_password', '%s/password_reset' % ADMIN_PREFIX,
 
                 controller='login', action='password_reset')
 

	
 
    rmap.connect('reset_password_confirmation',
 
                 '%s/password_reset_confirmation' % ADMIN_PREFIX,
 
                 controller='login', action='password_reset_confirmation')
 

	
 
    #FEEDS
 
    rmap.connect('rss_feed_home', '/{repo_name:.*}/feed/rss',
 
                controller='feed', action='rss',
rhodecode/controllers/login.py
Show inline comments
 
@@ -129,8 +129,8 @@ class LoginController(BaseController):
 
            password_reset_form = PasswordResetForm()()
 
            try:
 
                form_result = password_reset_form.to_python(dict(request.POST))
 
                user_model.reset_password(form_result)
 
                h.flash(_('Your new password was sent'),
 
                user_model.reset_password_link(form_result)
 
                h.flash(_('Your password reset link was sent'),
 
                            category='success')
 
                return redirect(url('login_home'))
 

	
 
@@ -144,6 +144,23 @@ class LoginController(BaseController):
 

	
 
        return render('/password_reset.html')
 

	
 
    def password_reset_confirmation(self):
 

	
 
        if request.GET and request.GET.get('key'):
 
            try:
 
                user_model = UserModel()
 
                user = User.get_by_api_key(request.GET.get('key'))
 
                data = dict(email=user.email)
 
                user_model.reset_password(data)
 
                h.flash(_('Your password reset was successful, '
 
                          'new password has been sent to your email'),
 
                            category='success')
 
            except Exception, e:
 
                log.error(e)
 
                return redirect(url('reset_password'))
 

	
 
        return redirect(url('login_home'))
 

	
 
    def logout(self):
 
        del session['rhodecode_user']
 
        session.save()
rhodecode/lib/celerylib/tasks.py
Show inline comments
 
@@ -34,7 +34,7 @@ from time import mktime
 
from operator import itemgetter
 
from string import lower
 

	
 
from pylons import config
 
from pylons import config, url
 
from pylons.i18n.translation import _
 

	
 
from rhodecode.lib import LANGUAGES_EXTENSIONS_MAP, safe_str
 
@@ -249,6 +249,45 @@ def get_commits_stats(repo_name, ts_min_
 
        log.info('LockHeld')
 
        return 'Task with key %s already running' % lockkey
 

	
 
@task(ignore_result=True)
 
def send_password_link(user_email):
 
    try:
 
        log = reset_user_password.get_logger()
 
    except:
 
        log = logging.getLogger(__name__)
 

	
 
    from rhodecode.lib import auth
 
    from rhodecode.model.db import User
 

	
 
    try:
 
        sa = get_session()
 
        user = sa.query(User).filter(User.email == user_email).scalar()
 

	
 
        if user:
 
            link = url('reset_password_confirmation', key=user.api_key,
 
                       qualified=True)
 
            tmpl = """
 
Hello %s
 

	
 
We received a request to create a new password for your account.
 

	
 
You can generate it by clicking following URL:
 

	
 
%s
 

	
 
If you didn't request new password please ignore this email.
 
            """
 
            run_task(send_email, user_email,
 
                     "RhodeCode password reset link",
 
                     tmpl % (user.short_contact, link))
 
            log.info('send new password mail to %s', user_email)
 

	
 
    except:
 
        log.error('Failed to update user password')
 
        log.error(traceback.format_exc())
 
        return False
 

	
 
    return True
 

	
 
@task(ignore_result=True)
 
def reset_user_password(user_email):
 
@@ -280,8 +319,8 @@ def reset_user_password(user_email):
 
            sa.rollback()
 

	
 
        run_task(send_email, user_email,
 
                 "Your new rhodecode password",
 
                 'Your new rhodecode password:%s' % (new_passwd))
 
                 "Your new RhodeCode password",
 
                 'Your new RhodeCode password:%s' % (new_passwd))
 
        log.info('send new password mail to %s', user_email)
 

	
 
    except:
rhodecode/lib/smtp_mailer.py
Show inline comments
 
@@ -74,13 +74,19 @@ class SmtpMailer(object):
 

	
 
        date_ = formatdate(localtime=True)
 
        msg = MIMEMultipart()
 
        msg.set_type('multipart/alternative')
 
        msg.preamble = 'You will not see this in a MIME-aware mail reader.\n'
 

	
 
        text_msg = MIMEText(body)
 
        text_msg.set_type('text/plain')
 
        text_msg.set_param('charset', 'UTF-8')
 

	
 
        msg['From'] = self.mail_from
 
        msg['To'] = ','.join(recipients)
 
        msg['Date'] = date_
 
        msg['Subject'] = subject
 
        msg.preamble = 'You will not see this in a MIME-aware mail reader.\n'
 

	
 
        msg.attach(MIMEText(body))
 
        msg.attach(text_msg)
 

	
 
        if attachment_files:
 
            self.__atach_files(msg, attachment_files)
rhodecode/model/db.py
Show inline comments
 
@@ -243,6 +243,11 @@ class User(Base, BaseModel):
 
        else:
 
            return Session.query(cls).filter(cls.username == username).one()
 

	
 
    @classmethod
 
    def get_by_api_key(cls, api_key):
 
        return Session.query(cls).filter(cls.api_key == api_key).one()
 

	
 

	
 
    def update_lastlogin(self):
 
        """Update user lastlogin"""
 

	
rhodecode/model/user.py
Show inline comments
 
@@ -213,6 +213,10 @@ class UserModel(BaseModel):
 
            self.sa.rollback()
 
            raise
 

	
 
    def reset_password_link(self, data):
 
        from rhodecode.lib.celerylib import tasks, run_task
 
        run_task(tasks.send_password_link, data['email'])
 

	
 
    def reset_password(self, data):
 
        from rhodecode.lib.celerylib import tasks, run_task
 
        run_task(tasks.reset_user_password, data['email'])
rhodecode/public/css/style.css
Show inline comments
 
@@ -198,7 +198,8 @@ margin-bottom:5px !important;
 
-moz-border-radius: 0px 0px 8px 8px;
 
border-radius: 0px 0px 8px 8px;
 
height:37px;
 
background:url("../images/header_inner.png") repeat-x scroll 0 0 #003367
 
background:url("../images/header_inner.png") repeat-x scroll 0 0 #003367;
 
box-shadow: 0 2px 2px rgba(0, 0, 0, 0.6);
 
}
 
 
#header ul#logged-user li {
 
@@ -1383,6 +1384,13 @@ position: absolute;
 
margin-left: -16px;
 
width: 281px;
 
border-radius: 0 0 8px 8px;
 
box-shadow: 0 2px 2px rgba(0, 0, 0, 0.6);
 
}
 
 
#quick_login .password_forgoten{
 
padding-right:10px;
 
padding-top:10px;
 
float:left;
 
}
 
 
#quick_login div.form div.fields{
rhodecode/templates/base/base.html
Show inline comments
 
@@ -30,7 +30,7 @@
 
			            
 
			        </div>
 
			        <div class="buttons">
 
			            ${h.submit('sign_in','Sign In',class_="ui-button")}
 
			            <div class="password_forgoten">${h.link_to(_('Forgot password ?'),h.url('reset_password'))}</div>${h.submit('sign_in','Sign In',class_="ui-button")}
 
			        </div>
 
			    </div>
 
			</div>
rhodecode/templates/password_reset.html
Show inline comments
 
@@ -28,7 +28,7 @@
 
	            <div class="buttons">
 
		            <div class="nohighlight">
 
		              ${h.submit('send','Reset my password',class_="ui-button")}
 
					  	<div class="activation_msg">${_('Your new password will be send to matching email address')}</div>
 
					  	<div class="activation_msg">${_('Password reset link will be send to matching email address')}</div>
 
		            </div>
 
	            </div>             
 
	    	</div>
rhodecode/templates/password_reset_confirmation.html
Show inline comments
 
new file 100644
0 comments (0 inline, 0 general)