Alessandro Molina avatar Alessandro Molina committed f4f3973

Fix bypassing missing user in profile page and add change password link

Comments (0)

Files changed (7)

     "TurboGears2 >= 2.1.4",
-    "tgext.pluggable"
+    "tgext.pluggable",
+    "tgext.datahelpers"
 here = os.path.abspath(os.path.dirname(__file__))


 from tg import TGController
 from tg import expose, flash, require, url, lurl, request, redirect, validate, config
 from tg.i18n import ugettext as _, lazy_ugettext as l_
-from tg.exceptions import HTTPNotFound
     from repoze.what import predicates
 except ImportError:
     from tg import predicates
-from userprofile.model import DBSession
-from userprofile.lib import create_user_form, get_user_data, get_profile_css, update_user_data
+from userprofile.lib import create_user_form, get_user_data, get_profile_css, \
+                            update_user_data, create_change_password_form
 from tgext.pluggable import app_model, plug_url, primary_key
+from tgext.datahelpers.validators import SQLAEntityConverter
+from tgext.datahelpers.utils import fail_with
+edit_password_form = create_change_password_form()
 class RootController(TGController):
-    def default(self, uid):
-        user = DBSession.query(app_model.User).filter(primary_key(app_model.User)==uid).first()
-        if not user:
-            raise HTTPNotFound()
+    @validate({'user':SQLAEntityConverter(app_model.User)},
+              error_handler=fail_with(404))
+    def _default(self, user):
         user_data, user_avatar = get_user_data(user)
         user_displayname = user_data.pop('display_name', (None, 'Unknown'))
         user_partial = config['_pluggable_userprofile_config'].get('user_partial')
         if not profile_save:
             profile_save = update_user_data
         profile_save(user, kw)
+        flash(_('Profile successfully updated'))
+        return redirect(plug_url('userprofile', '/%s' % getattr(user, primary_key(app_model.User).name)))
+    @expose('userprofile.templates.chpasswd')
+    @require(predicates.not_anonymous())
+    def chpasswd(self, **kw):
+        user = request.identity['user']
+        return dict(user=user, profile_css=get_profile_css(config),
+                    form=edit_password_form)
+    @expose()
+    @validate(edit_password_form, error_handler=chpasswd)
+    def save_password(self, password, verify_password):
+        user = request.identity['user']
+        user.password = password
+        flash(_('Password successfully changed'))
         return redirect(plug_url('userprofile', '/%s' % getattr(user, primary_key(app_model.User).name)))


 from tg import url
 from tgext.pluggable import app_model, plug_url
-from tw.forms import ListForm, TextField
+from tw.forms import ListForm, TextField, PasswordField
 from tw.forms.validators import UnicodeString
+from sprox.formbase import FilteringSchema
+from formencode.validators import FieldsMatch
 def get_profile_css(config):
     return url(config['_pluggable_userprofile_config'].get('custom_css',
                                 action=plug_url('userprofile', '/save'))
     return profile_form
+class ChangePasswordForm(ListForm):
+    password = PasswordField(label_text='Password')
+    password_confirm = PasswordField(label_text='Confirm Password')
+_password_match = FieldsMatch('password', 'verify_password',
+                              messages={'invalidNoMatch': 'Passwords do not match'})
+if hasattr(TextField, 'req'):
+    change_password_form_validator = _password_match
+    change_password_form_validator =  FilteringSchema(chained_validators=[_password_match])
+def create_change_password_form():
+    return ListForm(fields=[PasswordField('password', label_text='Password',
+                                          validator=UnicodeString(not_empty=True)),
+                            PasswordField('verify_password', label_text='Confirm Password',
+                                          validator=UnicodeString(not_empty=True))],
+                    action=plug_url('userprofile', '/save_password', lazy=True),
+                    validator=change_password_form_validator,
+                    submit_text='Save')


     clear: both;
-#userprofile_edit_form input[type="text"] {
+#userprofile_edit_form input[type="text"],
+#userprofile_edit_form input[type="password"] {
     padding: 4px;
     border: 1px solid #CCC;
     min-width: 200px;
 #userprofile_edit_form > form > ul > li {
     margin-top: 5px;
+#userprofile_edit_form h3 {
+    margin-bottom: 20px;


+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+        "">
+<html xmlns=""
+      xmlns:py=""
+      xmlns:xi="">
+<xi:include href="master.html" />
+    <title>Change Password</title>
+    <link rel="stylesheet" type="text/css" media="screen" href="${profile_css}" />
+    <h3>Change Password</h3>
+    <div id="userprofile_container">
+        <div id="userprofile_edit_form">
+            <h3>Edit Profile</h3>
+            ${form.display()}
+        </div>
+    </div>


             <img id="userprofile_avatar" src="${user_avatar}" />
         <div id="userprofile_edit_form">
+            <h3>Edit Profile</h3>


             <div id="userprofile_title">
                 <div id="userprofile_edit" py:if="is_my_own_profile">
-                    <a href="${h.plug_url('userprofile', '/edit')}">edit</a>
+                    <a href="${h.plug_url('userprofile', '/edit')}">edit</a> -
+                    <a href="${h.plug_url('userprofile', '/chpasswd')}">change password</a>
             <div id="userprofile_other_attr">
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.