##// END OF EJS Templates
Rewrite of user managment, improved forms, added some user info
marcink -
r238:a55c1787 default
parent child Browse files
Show More
@@ -0,0 +1,48 b''
1 #!/usr/bin/env python
2 # encoding: utf-8
3 #
4 # Copyright (c) 2010 marcink. All rights reserved.
5 #
6 from pylons_app.model.db import User
7 from pylons_app.model.meta import Session
8 '''
9 Created on Apr 9, 2010
10
11 @author: marcink
12 '''
13
14 class UserModel(object):
15
16 def __init__(self):
17 self.sa = Session()
18
19 def get_user(self, id):
20 return self.sa.query(User).get(id)
21
22 def create(self, form_data):
23 try:
24 new_user = User()
25 for k, v in form_data.items():
26 setattr(new_user, k, v)
27
28 self.sa.add(new_user)
29 self.sa.commit()
30 except:
31 self.sa.rollback()
32 raise
33
34 def update(self, id, form_data):
35 try:
36 new_user = self.sa.query(User).get(id)
37 for k, v in form_data.items():
38 if k == 'new_password' and v != '':
39
40 new_user.password = v
41 else:
42 setattr(new_user, k, v)
43
44 self.sa.add(new_user)
45 self.sa.commit()
46 except:
47 self.sa.rollback()
48 raise
@@ -1,113 +1,117 b''
1 from formencode import htmlfill
1 from formencode import htmlfill
2 from pylons import request, response, session, tmpl_context as c, url, \
2 from pylons import request, response, session, tmpl_context as c, url, \
3 app_globals as g
3 app_globals as g
4 from pylons.i18n.translation import _
5 from pylons_app.lib import helpers as h
4 from pylons.controllers.util import abort, redirect
6 from pylons.controllers.util import abort, redirect
5 from pylons_app.lib.auth import LoginRequired
7 from pylons_app.lib.auth import LoginRequired
6 from pylons_app.lib.base import BaseController, render
8 from pylons_app.lib.base import BaseController, render
7 from pylons_app.model.db import User, UserLog
9 from pylons_app.model.db import User, UserLog
8 from pylons_app.model.forms import UserForm
10 from pylons_app.model.forms import UserForm
9 from pylons_app.model.user_model import UserModel
11 from pylons_app.model.user_model import UserModel
10 import formencode
12 import formencode
11 import logging
13 import logging
12
14
13
15
14
16
15 log = logging.getLogger(__name__)
17 log = logging.getLogger(__name__)
16
18
17 class UsersController(BaseController):
19 class UsersController(BaseController):
18 """REST Controller styled on the Atom Publishing Protocol"""
20 """REST Controller styled on the Atom Publishing Protocol"""
19 # To properly map this controller, ensure your config/routing.py
21 # To properly map this controller, ensure your config/routing.py
20 # file has a resource setup:
22 # file has a resource setup:
21 # map.resource('user', 'users')
23 # map.resource('user', 'users')
22 @LoginRequired()
24 @LoginRequired()
23 def __before__(self):
25 def __before__(self):
24 c.admin_user = session.get('admin_user')
26 c.admin_user = session.get('admin_user')
25 c.admin_username = session.get('admin_username')
27 c.admin_username = session.get('admin_username')
26 super(UsersController, self).__before__()
28 super(UsersController, self).__before__()
27
29
28 def index(self, format='html'):
30 def index(self, format='html'):
29 """GET /users: All items in the collection"""
31 """GET /users: All items in the collection"""
30 # url('users')
32 # url('users')
31
33
32 c.users_list = self.sa.query(User).all()
34 c.users_list = self.sa.query(User).all()
33 return render('admin/users/users.html')
35 return render('admin/users/users.html')
34
36
35 def create(self):
37 def create(self):
36 """POST /users: Create a new item"""
38 """POST /users: Create a new item"""
37 # url('users')
39 # url('users')
38
40
39 user_model = UserModel()
41 user_model = UserModel()
40 login_form = UserForm()
42 login_form = UserForm()()
41 try:
43 try:
42 form_result = login_form.to_python(dict(request.POST))
44 form_result = login_form.to_python(dict(request.POST))
43 user_model.create(form_result)
45 user_model.create(form_result)
46 h.flash(_('created user %s') % form_result['username'], category='success')
44 return redirect(url('users'))
47 return redirect(url('users'))
45
48
46 except formencode.Invalid as errors:
49 except formencode.Invalid as errors:
47 c.form_errors = errors.error_dict
50 c.form_errors = errors.error_dict
48 return htmlfill.render(
51 return htmlfill.render(
49 render('admin/users/user_add.html'),
52 render('admin/users/user_add.html'),
50 defaults=errors.value,
53 defaults=errors.value,
51 encoding="UTF-8")
54 encoding="UTF-8")
52
55
53 def new(self, format='html'):
56 def new(self, format='html'):
54 """GET /users/new: Form to create a new item"""
57 """GET /users/new: Form to create a new item"""
55 # url('new_user')
58 # url('new_user')
56 return render('admin/users/user_add.html')
59 return render('admin/users/user_add.html')
57
60
58 def update(self, id):
61 def update(self, id):
59 """PUT /users/id: Update an existing item"""
62 """PUT /users/id: Update an existing item"""
60 # Forms posted to this method should contain a hidden field:
63 # Forms posted to this method should contain a hidden field:
61 # <input type="hidden" name="_method" value="PUT" />
64 # <input type="hidden" name="_method" value="PUT" />
62 # Or using helpers:
65 # Or using helpers:
63 # h.form(url('user', id=ID),
66 # h.form(url('user', id=ID),
64 # method='put')
67 # method='put')
65 # url('user', id=ID)
68 # url('user', id=ID)
66 user_model = UserModel()
69 user_model = UserModel()
67 login_form = UserForm()
70 login_form = UserForm(edit=True)()
68 try:
71 try:
69 form_result = login_form.to_python(dict(request.POST))
72 form_result = login_form.to_python(dict(request.POST))
70 user_model.update(id, form_result)
73 user_model.update(id, form_result)
74 h.flash(_('User updated succesfully'), category='success')
71 return redirect(url('users'))
75 return redirect(url('users'))
72
76
73 except formencode.Invalid as errors:
77 except formencode.Invalid as errors:
74 errors.value
75 c.user = user_model.get_user(id)
78 c.user = user_model.get_user(id)
76 c.form_errors = errors.error_dict
79 c.form_errors = errors.error_dict
77 return htmlfill.render(
80 return htmlfill.render(
78 render('admin/users/user_edit.html'),
81 render('admin/users/user_edit.html'),
79 defaults=errors.value,
82 defaults=errors.value,
80 encoding="UTF-8")
83 encoding="UTF-8")
81
84
82 def delete(self, id):
85 def delete(self, id):
83 """DELETE /users/id: Delete an existing item"""
86 """DELETE /users/id: Delete an existing item"""
84 # Forms posted to this method should contain a hidden field:
87 # Forms posted to this method should contain a hidden field:
85 # <input type="hidden" name="_method" value="DELETE" />
88 # <input type="hidden" name="_method" value="DELETE" />
86 # Or using helpers:
89 # Or using helpers:
87 # h.form(url('user', id=ID),
90 # h.form(url('user', id=ID),
88 # method='delete')
91 # method='delete')
89 # url('user', id=ID)
92 # url('user', id=ID)
90 try:
93 try:
91 self.sa.delete(self.sa.query(User).get(id))
94 self.sa.delete(self.sa.query(User).get(id))
92 self.sa.commit()
95 self.sa.commit()
96 h.flash(_('sucessfully deleted user'), category='success')
93 except:
97 except:
94 self.sa.rollback()
98 self.sa.rollback()
95 raise
99 raise
96 return redirect(url('users'))
100 return redirect(url('users'))
97
101
98 def show(self, id, format='html'):
102 def show(self, id, format='html'):
99 """GET /users/id: Show a specific item"""
103 """GET /users/id: Show a specific item"""
100 # url('user', id=ID)
104 # url('user', id=ID)
101
105
102
106
103 def edit(self, id, format='html'):
107 def edit(self, id, format='html'):
104 """GET /users/id/edit: Form to edit an existing item"""
108 """GET /users/id/edit: Form to edit an existing item"""
105 # url('edit_user', id=ID)
109 # url('edit_user', id=ID)
106 c.user = self.sa.query(User).get(id)
110 c.user = self.sa.query(User).get(id)
107 defaults = c.user.__dict__
111 defaults = c.user.__dict__
108 return htmlfill.render(
112 return htmlfill.render(
109 render('admin/users/user_edit.html'),
113 render('admin/users/user_edit.html'),
110 defaults=defaults,
114 defaults=defaults,
111 encoding="UTF-8",
115 encoding="UTF-8",
112 force_defaults=False
116 force_defaults=False
113 )
117 )
@@ -1,127 +1,155 b''
1 """ this is forms validation classes
1 """ this is forms validation classes
2 http://formencode.org/module-formencode.validators.html
2 http://formencode.org/module-formencode.validators.html
3 for list off all availible validators
3 for list off all availible validators
4
4
5 we can create our own validators
5 we can create our own validators
6
6
7 The table below outlines the options which can be used in a schema in addition to the validators themselves
7 The table below outlines the options which can be used in a schema in addition to the validators themselves
8 pre_validators [] These validators will be applied before the schema
8 pre_validators [] These validators will be applied before the schema
9 chained_validators [] These validators will be applied after the schema
9 chained_validators [] These validators will be applied after the schema
10 allow_extra_fields False If True, then it is not an error when keys that aren't associated with a validator are present
10 allow_extra_fields False If True, then it is not an error when keys that aren't associated with a validator are present
11 filter_extra_fields False If True, then keys that aren't associated with a validator are removed
11 filter_extra_fields False If True, then keys that aren't associated with a validator are removed
12 if_key_missing NoDefault If this is given, then any keys that aren't available but are expected will be replaced with this value (and then validated). This does not override a present .if_missing attribute on validators. NoDefault is a special FormEncode class to mean that no default values has been specified and therefore missing keys shouldn't take a default value.
12 if_key_missing NoDefault If this is given, then any keys that aren't available but are expected will be replaced with this value (and then validated). This does not override a present .if_missing attribute on validators. NoDefault is a special FormEncode class to mean that no default values has been specified and therefore missing keys shouldn't take a default value.
13 ignore_key_missing False If True, then missing keys will be missing in the result, if the validator doesn't have .if_missing on it already
13 ignore_key_missing False If True, then missing keys will be missing in the result, if the validator doesn't have .if_missing on it already
14
14
15
15
16 <name> = formencode.validators.<name of validator>
16 <name> = formencode.validators.<name of validator>
17 <name> must equal form name
17 <name> must equal form name
18 list=[1,2,3,4,5]
18 list=[1,2,3,4,5]
19 for SELECT use formencode.All(OneOf(list), Int())
19 for SELECT use formencode.All(OneOf(list), Int())
20
20
21 """
21 """
22 from formencode.validators import UnicodeString, OneOf, Int, Number, Regex
22 from formencode.validators import UnicodeString, OneOf, Int, Number, Regex, \
23 Email, Bool, StringBoolean
24 from formencode import All
23 from pylons import session
25 from pylons import session
24 from pylons.i18n.translation import _
26 from pylons.i18n.translation import _
25 from pylons_app.lib.auth import get_crypt_password
27 from pylons_app.lib.auth import get_crypt_password
26 from pylons_app.model import meta
28 from pylons_app.model import meta
27 from pylons_app.model.db import User
29 from pylons_app.model.db import User
28 from sqlalchemy.exc import OperationalError
30 from sqlalchemy.exc import OperationalError
29 from sqlalchemy.orm.exc import NoResultFound, MultipleResultsFound
31 from sqlalchemy.orm.exc import NoResultFound, MultipleResultsFound
30 from webhelpers.pylonslib.secure_form import authentication_token
32 from webhelpers.pylonslib.secure_form import authentication_token
31 import formencode
33 import formencode
32 import logging
34 import logging
33 log = logging.getLogger(__name__)
35 log = logging.getLogger(__name__)
34
36
35
37
36 #this is needed to translate the messages using _() in validators
38 #this is needed to translate the messages using _() in validators
37 class State_obj(object):
39 class State_obj(object):
38 _ = staticmethod(_)
40 _ = staticmethod(_)
39
41
40 #===============================================================================
42 #===============================================================================
41 # VALIDATORS
43 # VALIDATORS
42 #===============================================================================
44 #===============================================================================
43 class ValidAuthToken(formencode.validators.FancyValidator):
45 class ValidAuthToken(formencode.validators.FancyValidator):
44 messages = {'invalid_token':_('Token mismatch')}
46 messages = {'invalid_token':_('Token mismatch')}
45
47
46 def validate_python(self, value, state):
48 def validate_python(self, value, state):
47
49
48 if value != authentication_token():
50 if value != authentication_token():
49 raise formencode.Invalid(self.message('invalid_token', state,
51 raise formencode.Invalid(self.message('invalid_token', state,
50 search_number=value), value, state)
52 search_number=value), value, state)
53 class ValidUsername(formencode.validators.FancyValidator):
51
54
55 def validate_python(self, value, state):
56 pass
57
58 class ValidPassword(formencode.validators.FancyValidator):
59
60 def to_python(self, value, state):
61 return get_crypt_password(value)
62
52 class ValidAuth(formencode.validators.FancyValidator):
63 class ValidAuth(formencode.validators.FancyValidator):
53 messages = {
64 messages = {
54 'invalid_password':_('invalid password'),
65 'invalid_password':_('invalid password'),
55 'invalid_login':_('invalid user name'),
66 'invalid_login':_('invalid user name'),
56 'disabled_account':_('Your acccount is disabled')
67 'disabled_account':_('Your acccount is disabled')
57
68
58 }
69 }
59 #error mapping
70 #error mapping
60 e_dict = {'username':messages['invalid_login'],
71 e_dict = {'username':messages['invalid_login'],
61 'password':messages['invalid_password']}
72 'password':messages['invalid_password']}
62 e_dict_disable = {'username':messages['disabled_account']}
73 e_dict_disable = {'username':messages['disabled_account']}
63
74
64 def validate_python(self, value, state):
75 def validate_python(self, value, state):
65 sa = meta.Session
76 sa = meta.Session
66 crypted_passwd = get_crypt_password(value['password'])
77 crypted_passwd = get_crypt_password(value['password'])
67 username = value['username']
78 username = value['username']
68 try:
79 try:
69 user = sa.query(User).filter(User.username == username).one()
80 user = sa.query(User).filter(User.username == username).one()
70 except (NoResultFound, MultipleResultsFound, OperationalError) as e:
81 except (NoResultFound, MultipleResultsFound, OperationalError) as e:
71 log.error(e)
82 log.error(e)
72 user = None
83 user = None
84 raise formencode.Invalid(self.message('invalid_password',
85 state=State_obj), value, state,
86 error_dict=self.e_dict)
73 if user:
87 if user:
74 if user.active:
88 if user.active:
75 if user.username == username and user.password == crypted_passwd:
89 if user.username == username and user.password == crypted_passwd:
76 from pylons_app.lib.auth import AuthUser
90 from pylons_app.lib.auth import AuthUser
77 auth_user = AuthUser()
91 auth_user = AuthUser()
78 auth_user.username = username
92 auth_user.username = username
79 auth_user.is_authenticated = True
93 auth_user.is_authenticated = True
80 auth_user.is_admin = user.admin
94 auth_user.is_admin = user.admin
81 session['hg_app_user'] = auth_user
95 session['hg_app_user'] = auth_user
82 session.save()
96 session.save()
83 log.info('user %s is now authenticated', username)
97 log.info('user %s is now authenticated', username)
84 return value
98 return value
85 else:
99 else:
86 log.warning('user %s not authenticated', username)
100 log.warning('user %s not authenticated', username)
87 raise formencode.Invalid(self.message('invalid_password',
101 raise formencode.Invalid(self.message('invalid_password',
88 state=State_obj), value, state,
102 state=State_obj), value, state,
89 error_dict=self.e_dict)
103 error_dict=self.e_dict)
90 else:
104 else:
91 log.warning('user %s is disabled', username)
105 log.warning('user %s is disabled', username)
92 raise formencode.Invalid(self.message('disabled_account',
106 raise formencode.Invalid(self.message('disabled_account',
93 state=State_obj),
107 state=State_obj),
94 value, state,
108 value, state,
95 error_dict=self.e_dict_disable)
109 error_dict=self.e_dict_disable)
96
110
97
111
98
112
99 #===============================================================================
113 #===============================================================================
100 # FORMS
114 # FORMS
101 #===============================================================================
115 #===============================================================================
102 class LoginForm(formencode.Schema):
116 class LoginForm(formencode.Schema):
103 allow_extra_fields = True
117 allow_extra_fields = True
104 filter_extra_fields = True
118 filter_extra_fields = True
105 username = UnicodeString(
119 username = UnicodeString(
106 strip=True,
120 strip=True,
107 min=3,
121 min=3,
108 not_empty=True,
122 not_empty=True,
109 messages={
123 messages={
110 'empty':_('Please enter a login'),
124 'empty':_('Please enter a login'),
111 'tooShort':_('Enter a value %(min)i characters long or more')}
125 'tooShort':_('Enter a value %(min)i characters long or more')}
112 )
126 )
113
127
114 password = UnicodeString(
128 password = UnicodeString(
115 strip=True,
129 strip=True,
116 min=3,
130 min=3,
117 not_empty=True,
131 not_empty=True,
118 messages={
132 messages={
119 'empty':_('Please enter a password'),
133 'empty':_('Please enter a password'),
120 'tooShort':_('Enter a value %(min)i characters long or more')}
134 'tooShort':_('Enter a value %(min)i characters long or more')}
121 )
135 )
122
136
123
137
124 #chained validators have access to all data
138 #chained validators have access to all data
125 chained_validators = [ValidAuth]
139 chained_validators = [ValidAuth]
126
140
127
141 def UserForm(edit=False):
142 class _UserForm(formencode.Schema):
143 allow_extra_fields = True
144 filter_extra_fields = True
145 username = All(UnicodeString(strip=True, min=3, not_empty=True), ValidUsername)
146 if edit:
147 new_password = All(UnicodeString(strip=True, min=3, not_empty=False), ValidPassword)
148 else:
149 password = All(UnicodeString(strip=True, min=3, not_empty=False), ValidPassword)
150 active = StringBoolean(if_missing=False)
151 name = UnicodeString(strip=True, min=3, not_empty=True)
152 lastname = UnicodeString(strip=True, min=3, not_empty=True)
153 email = Email(not_empty=True)
154
155 return _UserForm
@@ -1,41 +1,58 b''
1 ## -*- coding: utf-8 -*-
1 ## -*- coding: utf-8 -*-
2 <%inherit file="/base/base.html"/>
2 <%inherit file="/base/base.html"/>
3
3
4 <%def name="title()">
4 <%def name="title()">
5 ${_('User administration')}
5 ${_('User administration')}
6 </%def>
6 </%def>
7 <%def name="breadcrumbs()">
7 <%def name="breadcrumbs()">
8 ${h.link_to(u'Admin',h.url('admin_home'))}
8 ${h.link_to(u'Admin',h.url('admin_home'))}
9 /
9 /
10 ${_('Users')}
10 ${_('Users')}
11 </%def>
11 </%def>
12 <%def name="page_nav()">
12 <%def name="page_nav()">
13 ${self.menu('admin')}
13 ${self.menu('admin')}
14 ${self.submenu('users')}
14 ${self.submenu('users')}
15 </%def>
15 </%def>
16 <%def name="main()">
16 <%def name="main()">
17 <div>
17 <div>
18 <h2>${_('User')} - ${_('add new')}</h2>
18 <h2>${_('User')} - ${_('add new')}</h2>
19 ${h.form(url('users'))}
19 ${h.form(url('users'))}
20 <table>
20 <table>
21 <tr>
21 <tr>
22 <td>${_('Username')}</td>
22 <td>${_('Username')}</td>
23 <td>${h.text('username')}</td>
23 <td>${h.text('username')}</td>
24 <td>${self.get_form_error('username')}</td>
25 </tr>
26 <tr>
27 <td>${_('Password')}</td>
28 <td>${h.password('password')}</td>
29 <td>${self.get_form_error('password')}</td>
30 </tr>
31 <tr>
32 <td>${_('Name')}</td>
33 <td>${h.text('name')}</td>
34 <td>${self.get_form_error('name')}</td>
24 </tr>
35 </tr>
25 <tr>
36 <tr>
26 <td>${_('password')}</td>
37 <td>${_('Lastname')}</td>
27 <td>${h.text('password')}</td>
38 <td>${h.text('lastname')}</td>
39 <td>${self.get_form_error('lastname')}</td>
28 </tr>
40 </tr>
29 <tr>
41 <tr>
42 <td>${_('Email')}</td>
43 <td>${h.text('email')}</td>
44 <td>${self.get_form_error('email')}</td>
45 </tr>
46 <tr>
30 <td>${_('Active')}</td>
47 <td>${_('Active')}</td>
31 <td>${h.checkbox('active')}</td>
48 <td>${h.checkbox('active',value=True)}</td>
49 <td>${self.get_form_error('active')}</td>
32 </tr>
50 </tr>
33 <tr>
51 <tr>
34 <td></td>
52 <td></td>
35 <td>${h.submit('add','add')}</td>
53 <td>${h.submit('save','save')}</td>
36 </tr>
54 </tr>
37
38 </table>
55 </table>
39 ${h.end_form()}
56 ${h.end_form()}
40 </div>
57 </div>
41 </%def> No newline at end of file
58 </%def>
@@ -1,41 +1,59 b''
1 ## -*- coding: utf-8 -*-
1 ## -*- coding: utf-8 -*-
2 <%inherit file="/base/base.html"/>
2 <%inherit file="/base/base.html"/>
3
3
4 <%def name="title()">
4 <%def name="title()">
5 ${_('User administration')}
5 ${_('User administration')}
6 </%def>
6 </%def>
7 <%def name="breadcrumbs()">
7 <%def name="breadcrumbs()">
8 ${h.link_to(u'Admin',h.url('admin_home'))}
8 ${h.link_to(u'Admin',h.url('admin_home'))}
9 /
9 /
10 ${_('Users')}
10 ${_('Users')}
11 </%def>
11 </%def>
12 <%def name="page_nav()">
12 <%def name="page_nav()">
13 ${self.menu('admin')}
13 ${self.menu('admin')}
14 ${self.submenu('users')}
14 ${self.submenu('users')}
15 </%def>
15 </%def>
16 <%def name="main()">
16 <%def name="main()">
17 <div>
17 <div>
18 <h2>${_('User')} - ${c.user.username}</h2>
18 <h2>${_('User')} - ${c.user.username}</h2>
19 ${h.form(url('user', id=c.user.user_id),method='put')}
19 ${h.form(url('user', id=c.user.user_id),method='put')}
20 <table>
20 <table>
21 <tr>
21 <tr>
22 <td>${_('Username')}</td>
22 <td>${_('Username')}</td>
23 <td>${h.text('username')}</td>
23 <td>${h.text('username')}</td>
24 <td>${self.get_form_error('username')}</td>
24 </tr>
25 </tr>
25 <tr>
26 <tr>
26 <td>${_('New password')}</td>
27 <td>${_('New password')}</td>
27 <td>${h.text('new_password')}</td>
28 <td>${h.text('new_password')}</td>
29 <td>${self.get_form_error('new_password')}</td>
28 </tr>
30 </tr>
29 <tr>
31 <tr>
32 <td>${_('Name')}</td>
33 <td>${h.text('name')}</td>
34 <td>${self.get_form_error('name')}</td>
35 </tr>
36 <tr>
37 <td>${_('Lastname')}</td>
38 <td>${h.text('lastname')}</td>
39 <td>${self.get_form_error('lastname')}</td>
40 </tr>
41 <tr>
42 <td>${_('Email')}</td>
43 <td>${h.text('email')}</td>
44 <td>${self.get_form_error('email')}</td>
45 </tr>
46 <tr>
30 <td>${_('Active')}</td>
47 <td>${_('Active')}</td>
31 <td>${h.checkbox('active',value=True)}</td>
48 <td>${h.checkbox('active',value=True)}</td>
49 <td>${self.get_form_error('active')}</td>
32 </tr>
50 </tr>
33 <tr>
51 <tr>
34 <td></td>
52 <td></td>
35 <td>${h.submit('save','save')}</td>
53 <td>${h.submit('save','save')}</td>
36 </tr>
54 </tr>
37
55
38 </table>
56 </table>
39 ${h.end_form()}
57 ${h.end_form()}
40 </div>
58 </div>
41 </%def> No newline at end of file
59 </%def>
@@ -1,43 +1,45 b''
1 ## -*- coding: utf-8 -*-
1 ## -*- coding: utf-8 -*-
2 <%inherit file="/base/base.html"/>
2 <%inherit file="/base/base.html"/>
3
3
4 <%def name="title()">
4 <%def name="title()">
5 ${_('Users administration')}
5 ${_('Users administration')}
6 </%def>
6 </%def>
7 <%def name="breadcrumbs()">
7 <%def name="breadcrumbs()">
8 ${h.link_to(u'Admin',h.url('admin_home'))}
8 ${h.link_to(u'Admin',h.url('admin_home'))}
9 /
9 /
10 ${_('Users')}
10 ${_('Users')}
11 </%def>
11 </%def>
12 <%def name="page_nav()">
12 <%def name="page_nav()">
13 ${self.menu('admin')}
13 ${self.menu('admin')}
14 ${self.submenu('users')}
14 ${self.submenu('users')}
15 </%def>
15 </%def>
16 <%def name="main()">
16 <%def name="main()">
17 <div>
17 <div>
18 <h2>${_('Mercurial users')}</h2>
18 <h2>${_('Mercurial users')}</h2>
19 <table class="table_disp">
19 <table class="table_disp">
20 <tr class="header">
20 <tr class="header">
21 <td>${_('id')}</td>
22 <td>${_('username')}</td>
21 <td>${_('username')}</td>
22 <td>${_('name')}</td>
23 <td>${_('lastname')}</td>
23 <td>${_('active')}</td>
24 <td>${_('active')}</td>
24 <td>${_('admin')}</td>
25 <td>${_('admin')}</td>
25 <td>${_('action')}</td>
26 <td>${_('action')}</td>
26 </tr>
27 </tr>
27 %for user in c.users_list:
28 %for user in c.users_list:
28 <tr>
29 <tr>
29 <td>${user.user_id}</td>
30 <td>${h.link_to(user.username,h.url('edit_user', id=user.user_id))}</td>
30 <td>${h.link_to(user.username,h.url('edit_user', id=user.user_id))}</td>
31 <td>${user.name}</td>
32 <td>${user.lastname}</td>
31 <td>${user.active}</td>
33 <td>${user.active}</td>
32 <td>${user.admin}</td>
34 <td>${user.admin}</td>
33 <td>
35 <td>
34 ${h.form(url('user', id=user.user_id),method='delete')}
36 ${h.form(url('user', id=user.user_id),method='delete')}
35 ${h.submit('remove','delete',class_="delete_icon action_button")}
37 ${h.submit('remove','delete',class_="delete_icon action_button")}
36 ${h.end_form()}
38 ${h.end_form()}
37 </td>
39 </td>
38 </tr>
40 </tr>
39 %endfor
41 %endfor
40 </table>
42 </table>
41 <span class="add_icon">${h.link_to(u'add user',h.url('new_user'))}</span>
43 <span class="add_icon">${h.link_to(u'add user',h.url('new_user'))}</span>
42 </div>
44 </div>
43 </%def>
45 </%def>
@@ -1,42 +1,40 b''
1 ## -*- coding: utf-8 -*-
1 ## -*- coding: utf-8 -*-
2 <%!
2 <%!
3 from pylons_app.lib import filters
3 from pylons_app.lib import filters
4 %>
4 %>
5 <%inherit file="base/base.html"/>
5 <%inherit file="base/base.html"/>
6 <%def name="title()">
6 <%def name="title()">
7 ${c.repos_prefix} Mercurial Repositories
7 ${c.repos_prefix} Mercurial Repositories
8 </%def>
8 </%def>
9 <%def name="breadcrumbs()">
9 <%def name="breadcrumbs()">
10 ${c.repos_prefix} Mercurial Repositories
10 ${c.repos_prefix} Mercurial Repositories
11 </%def>
11 </%def>
12 <%def name="page_nav()">
12 <%def name="page_nav()">
13 ${self.menu('home')}
13 ${self.menu('home')}
14 </%def>
14 </%def>
15 <%def name="main()">
15 <%def name="main()">
16 <div>
16 <div>
17 <br />
17 <br />
18 <h2>${_('Login')}</h2>
18 <h2>${_('Login')}</h2>
19 ${h.form(h.url.current())}
19 ${h.form(h.url.current())}
20 <table>
20 <table>
21 <tr>
21 <tr>
22 <td>${_('Username')}</td>
22 <td>${_('Username')}</td>
23 <td>${h.text('username')}</td>
23 <td>${h.text('username')}</td>
24 <td>${self.get_form_error('username')}
24 <td>${self.get_form_error('username')}</td>
25
26 </td>
27 </tr>
25 </tr>
28 <tr>
26 <tr>
29 <td>${_('Password')}</td>
27 <td>${_('Password')}</td>
30 <td>${h.password('password')}</td>
28 <td>${h.password('password')}</td>
31 <td>${self.get_form_error('password')}</td>
29 <td>${self.get_form_error('password')}</td>
32 </tr>
30 </tr>
33 <tr>
31 <tr>
34 <td></td>
32 <td></td>
35 <td>${h.submit('login','login')}</td>
33 <td>${h.submit('login','login')}</td>
36 </tr>
34 </tr>
37 </table>
35 </table>
38 ${h.end_form()}
36 ${h.end_form()}
39 </div>
37 </div>
40 </%def>
38 </%def>
41
39
42
40
General Comments 0
You need to be logged in to leave comments. Login now