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
78
ctx['svn_url'] = req.user.get_svn_url(req.config)
79
ctx['svn_pass'] = req.user.svn_pass
83
ctx['user'] = self.context
85
ctx['errors'] = errors
87
82
class UserAdminSchema(formencode.Schema):
88
83
admin = formencode.validators.StringBoolean(if_missing=False)
101
96
"""Only allow access if the requesting user is an admin."""
102
97
return req.user and req.user.admin
104
def filter(self, stream, ctx):
105
return stream | HTMLFormFiller(data=ctx['data'])
101
return UserAdminSchema()
103
def get_default_data(self, req):
104
return {'admin': self.context.admin,
105
'disabled': self.context.state == u'disabled',
106
'fullname': self.context.fullname,
107
'studentid': self.context.studentid,
110
def save_object(self, req, data):
111
if self.context is req.user:
112
# Admin checkbox is disabled -- assume unchanged
113
data['admin'] = self.context.admin
114
data['disabled'] = self.context.state == u'disabled'
116
self.context.admin = data['admin']
117
if self.context.state in (u'enabled', u'disabled'):
118
self.context.state = (u'disabled' if data['disabled']
120
self.context.fullname = data['fullname'] \
121
if data['fullname'] else None
122
self.context.studentid = data['studentid'] \
123
if data['studentid'] else None
107
126
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
127
super(UserAdminView, self).populate(req, ctx)
129
# Disable the admin checkbox if editing oneself
142
130
ctx['disable_admin'] = self.context is req.user
144
ctx['errors'] = errors
146
132
class PasswordChangeView(XHTMLView):
147
133
"""A form to change a user's password, with knowledge of the old one."""
202
188
ctx['user'] = self.context
203
189
ctx['error'] = error
192
class UserNewSchema(formencode.Schema):
193
login = URLNameValidator() # XXX: Validate uniqueness.
194
admin = formencode.validators.StringBoolean(if_missing=False)
195
fullname = formencode.validators.UnicodeString(not_empty=True)
196
studentid = formencode.validators.UnicodeString(not_empty=False,
199
email = formencode.validators.Email(not_empty=False,
203
class UserNewView(BaseFormView):
204
"""A form for admins to create new users."""
205
template = 'templates/user-new.html'
208
def authorize(self, req):
209
"""Only allow access if the requesting user is an admin."""
210
return req.user and req.user.admin
214
return UserNewSchema()
216
def get_default_data(self, req):
219
def save_object(self, req, data):
220
data['nick'] = data['fullname']
221
data['email'] = unicode(data['email']) if data['email'] else None
222
userobj = User(**data)
223
req.store.add(userobj)
224
enrol_user(req.config, req.store, userobj)
205
229
class Plugin(ViewPlugin, MediaPlugin):
207
231
The Plugin class for the user plugin.
210
234
forward_routes = (root_to_user,)
211
235
reverse_routes = (user_url,)
212
views = [(ApplicationRoot, 'users', UsersView),
236
views = [(ApplicationRoot, ('users', '+index'), UsersView),
237
(ApplicationRoot, ('users', '+new'), UserNewView),
213
238
(User, '+index', UserEditView),
214
239
(User, '+admin', UserAdminView),
215
240
(User, '+changepassword', PasswordChangeView),