Pluggable application for TurboGears2 which provides a basic user profile page with forms to allow users to edit their own profile or change their email/password
Project description
About userprofile
userprofile is a Pluggable application for TurboGears2 which provides a basic user profile page with forms to allow users to edit their own profile or change their password or email.
it’s curretly only compatible with ming but sqlalchemy compatibility can be added simply by adding the model
Installing
userprofile can be installed both from pypi or from github:
pip install tgapp-userprofile
should just work for most of the users
Plugging userprofile
In your application config/app_cfg.py import plug:
from tgext.pluggable import plug
Then at the end of the file call plug with userprofile:
plug(base_config, 'userprofile')
You will be able to access your profile at http://localhost:8080/userprofile.
Options
tgapp-userprofile supports some options that can be passed to the plug method to customize various aspects of the application:
- user_partial - Path of a partial to display into the user profile page.
Useful to add more data to the profile page without changing its template
custom_css - Path to a CSS file which will be used for the profile pages in place of the default one.
User Properties
tgapp-userprofile looks for various properties into the User class instances to drive its default behavior, the most important property is the profile_data property which can provide a dictionary with the user information to display on the profile page, but other properties are available to tune the behavior:
profile_data
A dictionary of entries to display into the profile page, the default dictionary is built with:
{'display_name':('Display Name', user.display_name), 'email_address':('Email Address', user.email_address)}
each key of the dictionary if the id of the field, in most cases it will have the same name of the user property where that field is stored. Values of the dictionary are tuples where the first value is the name of the field which will be displayed and the second one is the real value of the field.
If an avatar key is available that is expected to provide the url of the avatar image of the user. If it is not available userprofile will look for a tgapp-fbauth facebook avatar or will falleback to the default avatar.
display_name key will be used as the profile page title.
profile_form
A ToscaWidgets or tw2 form that can be used to edit the user profile. By default an autogenerated one with a text field for each entry in profile_data is provided.
save_profile
A callable which will receive the user data submitted by the edit form and is expected to update the user accordingly.
By default values will be stored as they are into the user field with the same id provided into profile_data.
Bootstrap Layout
If you want use bootstrap for beautify style of UserForm or ChangePasswordForm form layout, in your app_cfg:
def replace_profile_form_layout(): from axf.bootstrap import BootstrapFormLayout from userprofile.lib import UserForm from userprofile.lib import ChangePasswordForm UserForm.child = BootstrapFormLayout(children=UserForm.child.children) UserForm.submit.css_class = 'btn-primary form-control' ChangePasswordForm.child = BootstrapFormLayout(children=ChangePasswordForm.child.children) ChangePasswordForm.submit.css_class = 'btn-primary form-control' milestones.config_ready.register(replace_profile_form_layout)
Authentication Configuration
Since with userprofile a user can change his email address or user name, you have to configure repoze.who properly. In app_cfg.py, locate the authenticate method of ApplicationAuthMetadata: it should return the id of the user. Now repoze.who will save the user id in a cookie to identify the user and since this id will not change, the authentication process allows users to change email addresses and user names safely.
This example illustrate a login based on user name or email address with Ming:
class ApplicationAuthMetadata(TGAuthMetadata): def __init__(self, sa_auth): self.sa_auth = sa_auth def get_query(self, login): try: _id = ObjectId(login) except InvalidId: _id = login return { '$or': [{'email_address': login}, {'user_name': login}, {'_id': _id}], 'blocked': {'$ne': True}, } def authenticate(self, environ, identity): login = identity['login'] user = self.sa_auth.user_class.query.find(self.get_query(login)).first() if not user: # pragma: no cover login = None elif not user.validate_password(identity['password']): login = None if login is None: try: from urllib.parse import parse_qs, urlencode except ImportError: from urlparse import parse_qs from urllib import urlencode from tg.exceptions import HTTPFound params = parse_qs(environ['QUERY_STRING']) params.pop('password', None) # Remove password in case it was there if user is None: # pragma: no cover params['failure'] = 'user-not-found' else: params['login'] = identity['login'] params['failure'] = 'invalid-password' # When authentication fails send user to login page. environ['repoze.who.application'] = HTTPFound( location=environ['SCRIPT_NAME'] + '?'.join(('/login', urlencode(params, True))) ) return str(user._id) if user and login else login def get_user(self, identity, userid): return self.sa_auth.user_class.query.find(self.get_query(userid)).first() def get_groups(self, identity, userid): return [g.group_name for g in identity['user'].groups] def get_permissions(self, identity, userid): return [p.permission_name for p in identity['user'].permissions] base_config.sa_auth.authmetadata = ApplicationAuthMetadata(base_config.sa_auth)
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
File details
Details for the file tgapp-userprofile-0.3.5.tar.gz
.
File metadata
- Download URL: tgapp-userprofile-0.3.5.tar.gz
- Upload date:
- Size: 22.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | 5203a47e9044114304e6535e7d8f0275a4383f08222cc76b9d8870b4d5d0ec76 |
|
MD5 | c0d9a0a41cfcd48b553938990dc43692 |
|
BLAKE2b-256 | 2ffb0e0a4a3cd27558b3482d304189172d979d9d2a30e50921abcc10dfb6656f |