~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: 2010-02-25 03:18:21 UTC
  • Revision ID: grantw@unimelb.edu.au-20100225031821-mi9a2tm5679fht4d
Shuffle things around so that req.user and req.store only construct when actually retrieved, and ensure they're not retrieved for media files. Saves 50ms of DB connection time per request.

Show diffs side-by-side

added added

removed removed

Lines of Context:
22
22
from genshi.filters import HTMLFormFiller
23
23
 
24
24
from ivle.webapp import ApplicationRoot
25
 
from ivle.webapp.base.rest import JSONRESTView, require_permission
 
25
from ivle.webapp.base.forms import BaseFormView
26
26
from ivle.webapp.base.xhtml import XHTMLView
27
27
from ivle.webapp.base.plugins import ViewPlugin, MediaPlugin
28
28
from ivle.webapp.admin.publishing import root_to_user, user_url
29
29
from ivle.database import User
30
 
import ivle.database
31
30
import ivle.date
32
 
import ivle.util
33
31
 
34
32
 
35
33
class UsersView(XHTMLView):
46
44
        ctx['users'] = req.store.find(User).order_by(User.login)
47
45
 
48
46
 
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
47
class UserEditSchema(formencode.Schema):
75
48
    nick = formencode.validators.UnicodeString(not_empty=True)
76
49
    email = formencode.validators.Email(not_empty=False,
77
50
                                        if_missing=None)
78
51
 
79
 
class UserEditView(XHTMLView):
 
52
class UserEditView(BaseFormView):
80
53
    """A form to change a user's details."""
81
54
    template = 'templates/user-edit.html'
82
55
    tab = 'users'
83
56
    permission = 'edit'
84
57
 
85
 
    def filter(self, stream, ctx):
86
 
        return stream | HTMLFormFiller(data=ctx['data'])
 
58
    @property
 
59
    def validator(self):
 
60
        return UserEditSchema()
 
61
 
 
62
    def get_default_data(self, req):
 
63
        return {'nick': self.context.nick,
 
64
                'email': self.context.email
 
65
                }
 
66
 
 
67
    def save_object(self, req, data):
 
68
        self.context.nick = data['nick']
 
69
        self.context.email = unicode(data['email']) if data['email'] \
 
70
                             else None
 
71
        return self.context
87
72
 
88
73
    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
 
 
 
74
        super(UserEditView, self).populate(req, ctx)
107
75
        ctx['format_datetime'] = ivle.date.make_date_nice
108
76
        ctx['format_datetime_short'] = ivle.date.format_datetime_for_paragraph
109
77
 
110
 
        ctx['req'] = req
111
 
        ctx['user'] = self.context
112
 
        ctx['data'] = data
113
 
        ctx['errors'] = errors
114
78
 
115
79
class UserAdminSchema(formencode.Schema):
116
80
    admin = formencode.validators.StringBoolean(if_missing=False)
120
84
                                                    if_missing=None
121
85
                                                    )
122
86
 
123
 
class UserAdminView(XHTMLView):
 
87
class UserAdminView(BaseFormView):
124
88
    """A form for admins to change more of a user's details."""
125
89
    template = 'templates/user-admin.html'
126
90
    tab = 'users'
129
93
        """Only allow access if the requesting user is an admin."""
130
94
        return req.user and req.user.admin
131
95
 
132
 
    def filter(self, stream, ctx):
133
 
        return stream | HTMLFormFiller(data=ctx['data'])
 
96
    @property
 
97
    def validator(self):
 
98
        return UserAdminSchema()
 
99
 
 
100
    def get_default_data(self, req):
 
101
        return {'admin': self.context.admin,
 
102
                'disabled': self.context.state == u'disabled',
 
103
                'fullname': self.context.fullname,
 
104
                'studentid': self.context.studentid,
 
105
                }
 
106
 
 
107
    def save_object(self, req, data):
 
108
        if self.context is req.user:
 
109
            # Admin checkbox is disabled -- assume unchanged
 
110
            data['admin'] = self.context.admin
 
111
            data['disabled'] = self.context.state == u'disabled'
 
112
        else:
 
113
            self.context.admin = data['admin']
 
114
            if self.context.state in (u'enabled', u'disabled'):
 
115
                self.context.state = (u'disabled' if data['disabled']
 
116
                        else u'enabled')
 
117
        self.context.fullname = data['fullname'] \
 
118
                                if data['fullname'] else None
 
119
        self.context.studentid = data['studentid'] \
 
120
                                 if data['studentid'] else None
 
121
        return self.context
134
122
 
135
123
    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
 
124
        super(UserAdminView, self).populate(req, ctx)
 
125
 
 
126
        # Disable the admin checkbox if editing oneself
170
127
        ctx['disable_admin'] = self.context is req.user
171
 
        ctx['data'] = data
172
 
        ctx['errors'] = errors
173
128
 
174
129
class PasswordChangeView(XHTMLView):
175
130
    """A form to change a user's password, with knowledge of the old one."""
238
193
    forward_routes = (root_to_user,)
239
194
    reverse_routes = (user_url,)
240
195
    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'),
 
196
             (User, '+index', UserEditView),
 
197
             (User, '+admin', UserAdminView),
 
198
             (User, '+changepassword', PasswordChangeView),
 
199
             (User, '+resetpassword', PasswordResetView),
246
200
             ]
247
201
 
248
202
    tabs = [