21
21
import formencode.validators
22
22
from genshi.filters import HTMLFormFiller
24
from ivle.database import User
26
from ivle.pulldown_subj import enrol_user
24
27
from ivle.webapp import ApplicationRoot
28
from ivle.webapp.base.forms import BaseFormView, URLNameValidator
25
29
from ivle.webapp.base.xhtml import XHTMLView
26
30
from ivle.webapp.base.plugins import ViewPlugin, MediaPlugin
27
31
from ivle.webapp.admin.publishing import root_to_user, user_url
28
from ivle.database import User
32
34
class UsersView(XHTMLView):
48
50
email = formencode.validators.Email(not_empty=False,
51
class UserEditView(XHTMLView):
53
class UserEditView(BaseFormView):
52
54
"""A form to change a user's details."""
53
55
template = 'templates/user-edit.html'
55
57
permission = 'edit'
57
def filter(self, stream, ctx):
58
return stream | HTMLFormFiller(data=ctx['data'])
61
return UserEditSchema()
63
def get_default_data(self, req):
64
return {'nick': self.context.nick,
65
'email': self.context.email
68
def save_object(self, req, data):
69
self.context.nick = data['nick']
70
self.context.email = unicode(data['email']) if data['email'] \
60
74
def populate(self, req, ctx):
61
if req.method == 'POST':
62
data = dict(req.get_fieldstorage())
64
validator = UserEditSchema()
65
data = validator.to_python(data, state=req)
66
self.context.nick = data['nick']
67
self.context.email = unicode(data['email']) if data['email'] \
70
req.throw_redirect(req.uri)
71
except formencode.Invalid, e:
72
errors = e.unpack_errors()
74
data = {'nick': self.context.nick,
75
'email': self.context.email
75
super(UserEditView, self).populate(req, ctx)
79
76
ctx['format_datetime'] = ivle.date.make_date_nice
80
77
ctx['format_datetime_short'] = ivle.date.format_datetime_for_paragraph
83
ctx['user'] = self.context
85
ctx['errors'] = errors
87
80
class UserAdminSchema(formencode.Schema):
88
81
admin = formencode.validators.StringBoolean(if_missing=False)
101
94
"""Only allow access if the requesting user is an admin."""
102
95
return req.user and req.user.admin
104
def filter(self, stream, ctx):
105
return stream | HTMLFormFiller(data=ctx['data'])
99
return UserAdminSchema()
101
def get_default_data(self, req):
102
return {'admin': self.context.admin,
103
'disabled': self.context.state == u'disabled',
104
'fullname': self.context.fullname,
105
'studentid': self.context.studentid,
108
def save_object(self, req, data):
109
if self.context is req.user:
110
# Admin checkbox is disabled -- assume unchanged
111
data['admin'] = self.context.admin
112
data['disabled'] = self.context.state == u'disabled'
114
self.context.admin = data['admin']
115
if self.context.state in (u'enabled', u'disabled'):
116
self.context.state = (u'disabled' if data['disabled']
118
self.context.fullname = data['fullname'] \
119
if data['fullname'] else None
120
self.context.studentid = data['studentid'] \
121
if data['studentid'] else None
107
124
def populate(self, req, ctx):
108
if req.method == 'POST':
109
data = dict(req.get_fieldstorage())
111
validator = UserAdminSchema()
112
data = validator.to_python(data, state=req)
114
if self.context is req.user:
115
# Admin checkbox is disabled -- assume unchanged
116
data['admin'] = self.context.admin
117
data['disabled'] = self.context.state == u'disabled'
119
self.context.admin = data['admin']
120
if self.context.state in (u'enabled', u'disabled'):
121
self.context.state = (u'disabled' if data['disabled']
123
self.context.fullname = data['fullname'] \
124
if data['fullname'] else None
125
self.context.studentid = data['studentid'] \
126
if data['studentid'] else None
128
req.throw_redirect(req.uri)
129
except formencode.Invalid, e:
130
errors = e.unpack_errors()
132
data = {'admin': self.context.admin,
133
'disabled': self.context.state == u'disabled',
134
'fullname': self.context.fullname,
135
'studentid': self.context.studentid,
140
ctx['user'] = self.context
141
# Disable the Admin checkbox if editing oneself
125
super(UserAdminView, self).populate(req, ctx)
127
# Disable the admin checkbox if editing oneself
142
128
ctx['disable_admin'] = self.context is req.user
144
ctx['errors'] = errors
146
130
class PasswordChangeView(XHTMLView):
147
131
"""A form to change a user's password, with knowledge of the old one."""
202
186
ctx['user'] = self.context
203
187
ctx['error'] = error
190
class UserNewSchema(formencode.Schema):
191
login = URLNameValidator() # XXX: Validate uniqueness.
192
admin = formencode.validators.StringBoolean(if_missing=False)
193
fullname = formencode.validators.UnicodeString(not_empty=True)
194
studentid = formencode.validators.UnicodeString(not_empty=False,
197
email = formencode.validators.Email(not_empty=False,
201
class UserNewView(BaseFormView):
202
"""A form for admins to create new users."""
203
template = 'templates/user-new.html'
206
def authorize(self, req):
207
"""Only allow access if the requesting user is an admin."""
208
return req.user and req.user.admin
212
return UserNewSchema()
214
def get_default_data(self, req):
217
def save_object(self, req, data):
218
data['nick'] = data['fullname']
219
data['email'] = unicode(data['email']) if data['email'] else None
220
userobj = User(**data)
221
req.store.add(userobj)
222
enrol_user(req.config, req.store, userobj)
205
227
class Plugin(ViewPlugin, MediaPlugin):
207
229
The Plugin class for the user plugin.
210
232
forward_routes = (root_to_user,)
211
233
reverse_routes = (user_url,)
212
views = [(ApplicationRoot, 'users', UsersView),
234
views = [(ApplicationRoot, ('users', '+index'), UsersView),
235
(ApplicationRoot, ('users', '+new'), UserNewView),
213
236
(User, '+index', UserEditView),
214
237
(User, '+admin', UserAdminView),
215
238
(User, '+changepassword', PasswordChangeView),