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

« back to all changes in this revision

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

  • Committer: Matt Giuca
  • Date: 2010-07-22 02:12:36 UTC
  • mfrom: (1812.1.13 late-submit)
  • Revision ID: matt.giuca@gmail.com-20100722021236-k8kt4cqdtywzpk24
Merge from trunk late-submit.
Students may now submit projects after the deadline, but they are warned that the submission is late.
Lecturers are now given data on which submissions were made late, and how many days.
(LP: #598346)

Show diffs side-by-side

added added

removed removed

Lines of Context:
21
21
import formencode.validators
22
22
from genshi.filters import HTMLFormFiller
23
23
 
 
24
from ivle.database import User
 
25
import ivle.date
 
26
from ivle.pulldown_subj import enrol_user
24
27
from ivle.webapp import ApplicationRoot
25
 
from ivle.webapp.base.rest import JSONRESTView, require_permission
 
28
from ivle.webapp.base.forms import BaseFormView, URLNameValidator
26
29
from ivle.webapp.base.xhtml import XHTMLView
27
30
from ivle.webapp.base.plugins import ViewPlugin, MediaPlugin
28
31
from ivle.webapp.admin.publishing import root_to_user, user_url
29
 
from ivle.database import User
30
 
import ivle.database
31
 
import ivle.date
32
 
import ivle.util
33
32
 
34
33
 
35
34
class UsersView(XHTMLView):
46
45
        ctx['users'] = req.store.find(User).order_by(User.login)
47
46
 
48
47
 
49
 
# List of fields returned as part of the user JSON dictionary
50
 
# (as returned by the get_user action)
51
 
user_fields_list = (
52
 
    "login", "state", "unixid", "email", "nick", "fullname",
53
 
    "admin", "studentid", "acct_exp", "pass_exp", "last_login",
54
 
    "svn_pass"
55
 
)
56
 
 
57
 
class UserRESTView(JSONRESTView):
58
 
    """
59
 
    A REST interface to the user object.
60
 
    """
61
 
 
62
 
    @require_permission('view')
63
 
    def GET(self, req):
64
 
        # XXX Check Caps
65
 
        user = ivle.util.object_to_dict(user_fields_list, self.context)
66
 
        # Convert time stamps to nice strings
67
 
        for k in 'pass_exp', 'acct_exp', 'last_login':
68
 
            if user[k] is not None:
69
 
                user[k] = unicode(user[k])
70
 
 
71
 
        user['local_password'] = self.context.passhash is not None
72
 
        return user
73
 
 
74
48
class UserEditSchema(formencode.Schema):
75
49
    nick = formencode.validators.UnicodeString(not_empty=True)
76
50
    email = formencode.validators.Email(not_empty=False,
77
51
                                        if_missing=None)
78
52
 
79
 
class UserEditView(XHTMLView):
 
53
class UserEditView(BaseFormView):
80
54
    """A form to change a user's details."""
81
55
    template = 'templates/user-edit.html'
82
56
    tab = 'users'
83
57
    permission = 'edit'
84
58
 
85
 
    def filter(self, stream, ctx):
86
 
        return stream | HTMLFormFiller(data=ctx['data'])
 
59
    @property
 
60
    def validator(self):
 
61
        return UserEditSchema()
 
62
 
 
63
    def get_default_data(self, req):
 
64
        return {'nick': self.context.nick,
 
65
                'email': self.context.email
 
66
                }
 
67
 
 
68
    def save_object(self, req, data):
 
69
        self.context.nick = data['nick']
 
70
        self.context.email = unicode(data['email']) if data['email'] \
 
71
                             else None
 
72
        return self.context
87
73
 
88
74
    def populate(self, req, ctx):
89
 
        if req.method == 'POST':
90
 
            data = dict(req.get_fieldstorage())
91
 
            try:
92
 
                validator = UserEditSchema()
93
 
                data = validator.to_python(data, state=req)
94
 
                self.context.nick = data['nick']
95
 
                self.context.email = unicode(data['email']) if data['email'] \
96
 
                                     else None
97
 
                req.store.commit()
98
 
                req.throw_redirect(req.uri)
99
 
            except formencode.Invalid, e:
100
 
                errors = e.unpack_errors()
101
 
        else:
102
 
            data = {'nick': self.context.nick,
103
 
                    'email': self.context.email
104
 
                   }
105
 
            errors = {}
106
 
 
 
75
        super(UserEditView, self).populate(req, ctx)
107
76
        ctx['format_datetime'] = ivle.date.make_date_nice
108
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
109
80
 
110
 
        ctx['req'] = req
111
 
        ctx['user'] = self.context
112
 
        ctx['data'] = data
113
 
        ctx['errors'] = errors
114
81
 
115
82
class UserAdminSchema(formencode.Schema):
116
83
    admin = formencode.validators.StringBoolean(if_missing=False)
120
87
                                                    if_missing=None
121
88
                                                    )
122
89
 
123
 
class UserAdminView(XHTMLView):
 
90
class UserAdminView(BaseFormView):
124
91
    """A form for admins to change more of a user's details."""
125
92
    template = 'templates/user-admin.html'
126
93
    tab = 'users'
129
96
        """Only allow access if the requesting user is an admin."""
130
97
        return req.user and req.user.admin
131
98
 
132
 
    def filter(self, stream, ctx):
133
 
        return stream | HTMLFormFiller(data=ctx['data'])
 
99
    @property
 
100
    def validator(self):
 
101
        return UserAdminSchema()
 
102
 
 
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,
 
108
                }
 
109
 
 
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'
 
115
        else:
 
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']
 
119
                        else u'enabled')
 
120
        self.context.fullname = data['fullname'] \
 
121
                                if data['fullname'] else None
 
122
        self.context.studentid = data['studentid'] \
 
123
                                 if data['studentid'] else None
 
124
        return self.context
134
125
 
135
126
    def populate(self, req, ctx):
136
 
        if req.method == 'POST':
137
 
            data = dict(req.get_fieldstorage())
138
 
            try:
139
 
                validator = UserAdminSchema()
140
 
                data = validator.to_python(data, state=req)
141
 
 
142
 
                if self.context is req.user:
143
 
                    # Admin checkbox is disabled -- assume unchanged
144
 
                    data['admin'] = self.context.admin
145
 
                    data['disabled'] = self.context.state == u'disabled'
146
 
                else:
147
 
                    self.context.admin = data['admin']
148
 
                    if self.context.state in (u'enabled', u'disabled'):
149
 
                        self.context.state = (u'disabled' if data['disabled']
150
 
                                else u'enabled')
151
 
                self.context.fullname = data['fullname'] \
152
 
                                        if data['fullname'] else None
153
 
                self.context.studentid = data['studentid'] \
154
 
                                         if data['studentid'] else None
155
 
                req.store.commit()
156
 
                req.throw_redirect(req.uri)
157
 
            except formencode.Invalid, e:
158
 
                errors = e.unpack_errors()
159
 
        else:
160
 
            data = {'admin': self.context.admin,
161
 
                    'disabled': self.context.state == u'disabled',
162
 
                    'fullname': self.context.fullname,
163
 
                    'studentid': self.context.studentid,
164
 
                   }
165
 
            errors = {}
166
 
 
167
 
        ctx['req'] = req
168
 
        ctx['user'] = self.context
169
 
        # Disable the Admin checkbox if editing oneself
 
127
        super(UserAdminView, self).populate(req, ctx)
 
128
 
 
129
        # Disable the admin checkbox if editing oneself
170
130
        ctx['disable_admin'] = self.context is req.user
171
 
        ctx['data'] = data
172
 
        ctx['errors'] = errors
173
131
 
174
132
class PasswordChangeView(XHTMLView):
175
133
    """A form to change a user's password, with knowledge of the old one."""
230
188
        ctx['user'] = self.context
231
189
        ctx['error'] = error
232
190
 
 
191
 
 
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,
 
197
                                                    if_missing=None
 
198
                                                    )
 
199
    email = formencode.validators.Email(not_empty=False,
 
200
                                        if_missing=None)
 
201
 
 
202
 
 
203
class UserNewView(BaseFormView):
 
204
    """A form for admins to create new users."""
 
205
    template = 'templates/user-new.html'
 
206
    tab = 'users'
 
207
 
 
208
    def authorize(self, req):
 
209
        """Only allow access if the requesting user is an admin."""
 
210
        return req.user and req.user.admin
 
211
 
 
212
    @property
 
213
    def validator(self):
 
214
        return UserNewSchema()
 
215
 
 
216
    def get_default_data(self, req):
 
217
        return {}
 
218
 
 
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)
 
225
 
 
226
        return userobj
 
227
 
 
228
 
233
229
class Plugin(ViewPlugin, MediaPlugin):
234
230
    """
235
231
    The Plugin class for the user plugin.
237
233
 
238
234
    forward_routes = (root_to_user,)
239
235
    reverse_routes = (user_url,)
240
 
    views = [(ApplicationRoot, 'users', UsersView),
241
 
             (ivle.database.User, '+index', UserEditView),
242
 
             (ivle.database.User, '+admin', UserAdminView),
243
 
             (ivle.database.User, '+changepassword', PasswordChangeView),
244
 
             (ivle.database.User, '+resetpassword', PasswordResetView),
245
 
             (ivle.database.User, '+index', UserRESTView, 'api'),
 
236
    views = [(ApplicationRoot, ('users', '+index'), UsersView),
 
237
             (ApplicationRoot, ('users', '+new'), UserNewView),
 
238
             (User, '+index', UserEditView),
 
239
             (User, '+admin', UserAdminView),
 
240
             (User, '+changepassword', PasswordChangeView),
 
241
             (User, '+resetpassword', PasswordResetView),
246
242
             ]
247
243
 
248
244
    tabs = [