~azzar1/unity/add-show-desktop-key

« back to all changes in this revision

Viewing changes to ivle/webapp/admin/user.py

  • Committer: William Grant
  • Date: 2009-05-27 04:26:42 UTC
  • Revision ID: grantw@unimelb.edu.au-20090527042642-uta4czoewqmm1t6m
Normalise and block .. paths in to_home_path.

Show diffs side-by-side

added added

removed removed

Lines of Context:
17
17
 
18
18
# Author: Matt Giuca, Will Grant
19
19
 
20
 
import formencode
21
 
import formencode.validators
22
 
from genshi.filters import HTMLFormFiller
23
 
 
24
20
from ivle.webapp.base.rest import JSONRESTView, require_permission
25
21
from ivle.webapp.base.xhtml import XHTMLView
26
22
from ivle.webapp.base.plugins import ViewPlugin, MediaPlugin
27
23
from ivle.webapp.errors import NotFound, Unauthorized
28
24
import ivle.database
29
 
import ivle.date
30
25
import ivle.util
31
26
 
32
27
# List of fields returned as part of the user JSON dictionary
59
54
        user['local_password'] = self.context.passhash is not None
60
55
        return user
61
56
 
62
 
class UserEditSchema(formencode.Schema):
63
 
    nick = formencode.validators.UnicodeString(not_empty=True)
64
 
    email = formencode.validators.Email(not_empty=False,
65
 
                                        if_missing=None)
66
 
 
67
 
class UserEditView(XHTMLView):
68
 
    """A form to change a user's details."""
69
 
    template = 'templates/user-edit.html'
70
 
    tab = 'settings'
71
 
    permission = 'edit'
72
 
 
73
 
    def __init__(self, req, login):
74
 
        self.context = ivle.database.User.get_by_login(req.store, login)
75
 
        if self.context is None:
76
 
            raise NotFound()
77
 
 
78
 
    def filter(self, stream, ctx):
79
 
        return stream | HTMLFormFiller(data=ctx['data'])
80
 
 
81
 
    def populate(self, req, ctx):
82
 
        if req.method == 'POST':
83
 
            data = dict(req.get_fieldstorage())
84
 
            try:
85
 
                validator = UserEditSchema()
86
 
                data = validator.to_python(data, state=req)
87
 
                self.context.nick = data['nick']
88
 
                self.context.email = unicode(data['email']) if data['email'] \
89
 
                                     else None
90
 
                req.store.commit()
91
 
                req.throw_redirect(req.uri)
92
 
            except formencode.Invalid, e:
93
 
                errors = e.unpack_errors()
94
 
        else:
95
 
            data = {'nick': self.context.nick,
96
 
                    'email': self.context.email
97
 
                   }
98
 
            errors = {}
99
 
 
100
 
        ctx['format_datetime'] = ivle.date.make_date_nice
101
 
        ctx['format_datetime_short'] = ivle.date.format_datetime_for_paragraph
102
 
 
103
 
        ctx['req'] = req
104
 
        ctx['user'] = self.context
105
 
        ctx['data'] = data
106
 
        ctx['errors'] = errors
107
 
 
108
 
class UserAdminSchema(formencode.Schema):
109
 
    admin = formencode.validators.StringBoolean(if_missing=False)
110
 
    fullname = formencode.validators.UnicodeString(not_empty=True)
111
 
    studentid = formencode.validators.UnicodeString(not_empty=False,
112
 
                                                    if_missing=None
113
 
                                                    )
114
 
 
115
 
class UserAdminView(XHTMLView):
116
 
    """A form for admins to change more of a user's details."""
117
 
    template = 'templates/user-admin.html'
118
 
    tab = 'settings'
119
 
 
120
 
    def __init__(self, req, login):
121
 
        self.context = ivle.database.User.get_by_login(req.store, login)
122
 
        if self.context is None:
123
 
            raise NotFound()
124
 
 
125
 
    def authorize(self, req):
126
 
        """Only allow access if the requesting user is an admin."""
127
 
        return req.user.admin
128
 
 
129
 
    def filter(self, stream, ctx):
130
 
        return stream | HTMLFormFiller(data=ctx['data'])
131
 
 
132
 
    def populate(self, req, ctx):
133
 
        if req.method == 'POST':
134
 
            data = dict(req.get_fieldstorage())
135
 
            try:
136
 
                validator = UserAdminSchema()
137
 
                data = validator.to_python(data, state=req)
138
 
 
139
 
                self.context.admin = data['admin']
140
 
                self.context.fullname = data['fullname'] \
141
 
                                        if data['fullname'] else None
142
 
                self.context.studentid = data['studentid'] \
143
 
                                         if data['studentid'] else None
144
 
                req.store.commit()
145
 
                req.throw_redirect(req.uri)
146
 
            except formencode.Invalid, e:
147
 
                errors = e.unpack_errors()
148
 
        else:
149
 
            data = {'admin': self.context.admin,
150
 
                    'fullname': self.context.fullname,
151
 
                    'studentid': self.context.studentid,
152
 
                   }
153
 
            errors = {}
154
 
 
155
 
        ctx['req'] = req
156
 
        ctx['user'] = self.context
157
 
        ctx['data'] = data
158
 
        ctx['errors'] = errors
159
 
 
160
 
class PasswordChangeView(XHTMLView):
161
 
    """A form to change a user's password, with knowledge of the old one."""
162
 
    template = 'templates/user-password-change.html'
163
 
    tab = 'settings'
164
 
    permission = 'edit'
165
 
 
166
 
    def __init__(self, req, login):
167
 
        self.context = ivle.database.User.get_by_login(req.store, login)
168
 
        if self.context is None:
169
 
            raise NotFound()
170
 
 
171
 
    def authorize(self, req):
172
 
        """Only allow access if the requesting user holds the permission,
173
 
           and the target user has a password set. Otherwise we might be
174
 
           clobbering external authn.
175
 
        """
176
 
        return super(PasswordChangeView, self).authorize(req) and \
177
 
               self.context.passhash is not None
178
 
 
179
 
    def populate(self, req, ctx):
180
 
        error = None
181
 
        if req.method == 'POST':
182
 
            data = dict(req.get_fieldstorage())
183
 
            if data.get('old_password') is None or \
184
 
               not self.context.authenticate(data.get('old_password')):
185
 
                error = 'Incorrect password.'
186
 
            elif data.get('new_password') != data.get('new_password_again'):
187
 
                error = 'New passwords do not match.'
188
 
            elif not data.get('new_password'):
189
 
                error = 'New password cannot be empty.'
190
 
            else:
191
 
                self.context.password = data['new_password']
192
 
                req.store.commit()
193
 
                req.throw_redirect(req.uri)
194
 
 
195
 
        ctx['req'] = req
196
 
        ctx['user'] = self.context
197
 
        ctx['error'] = error
198
 
 
199
 
class PasswordResetView(XHTMLView):
200
 
    """A form to reset a user's password, without knowledge of the old one."""
201
 
    template = 'templates/user-password-reset.html'
202
 
    tab = 'settings'
203
 
 
204
 
    def __init__(self, req, login):
205
 
        self.context = ivle.database.User.get_by_login(req.store, login)
206
 
        if self.context is None:
207
 
            raise NotFound()
208
 
 
209
 
    def authorize(self, req):
210
 
        """Only allow access if the requesting user is an admin."""
211
 
        return req.user.admin
212
 
 
213
 
    def populate(self, req, ctx):
214
 
        error = None
215
 
        if req.method == 'POST':
216
 
            data = dict(req.get_fieldstorage())
217
 
            if data.get('new_password') != data.get('new_password_again'):
218
 
                error = 'New passwords do not match.'
219
 
            elif not data.get('new_password'):
220
 
                error = 'New password cannot be empty.'
221
 
            else:
222
 
                self.context.password = data['new_password']
223
 
                req.store.commit()
224
 
                req.throw_redirect(req.uri)
225
 
 
226
 
        ctx['user'] = self.context
227
 
        ctx['error'] = error
 
57
class UserSettingsView(XHTMLView):
 
58
    template = 'templates/user-settings.html'
 
59
    tab = 'settings'
 
60
    permission = 'edit'
 
61
 
 
62
    def __init__(self, req, login):
 
63
        self.context = ivle.database.User.get_by_login(req.store, login)
 
64
        if self.context is None:
 
65
            raise NotFound()
 
66
 
 
67
    def populate(self, req, ctx):
 
68
        self.plugin_scripts[Plugin] = ['settings.js']
 
69
        req.scripts_init = ['revert_settings']
 
70
 
 
71
        ctx['login'] = self.context.login
228
72
 
229
73
class Plugin(ViewPlugin, MediaPlugin):
230
74
    """
235
79
    # (regex str, handler class, kwargs dict)
236
80
    # The kwargs dict is passed to the __init__ of the view object
237
81
    urls = [
238
 
        ('~:login/+edit', UserEditView),
239
 
        ('~:login/+admin', UserAdminView),
240
 
        ('~:login/+changepassword', PasswordChangeView),
241
 
        ('~:login/+resetpassword', PasswordResetView),
 
82
        ('~:login/+settings', UserSettingsView),
242
83
        ('api/~:login', UserRESTView),
243
84
    ]
244
85