~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 07:34:50 UTC
  • Revision ID: grantw@unimelb.edu.au-20100225073450-zcl8ev5hlyhbszeu
Activate the Storm C extensions if possible. Moar speed.

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.webapp.base.rest import JSONRESTView, require_permission
 
24
from ivle.webapp import ApplicationRoot
 
25
from ivle.webapp.base.forms import BaseFormView
25
26
from ivle.webapp.base.xhtml import XHTMLView
26
27
from ivle.webapp.base.plugins import ViewPlugin, MediaPlugin
27
 
from ivle.webapp.errors import NotFound, Unauthorized
28
 
import ivle.database
 
28
from ivle.webapp.admin.publishing import root_to_user, user_url
 
29
from ivle.database import User
29
30
import ivle.date
30
 
import ivle.util
31
 
 
32
 
# List of fields returned as part of the user JSON dictionary
33
 
# (as returned by the get_user action)
34
 
user_fields_list = (
35
 
    "login", "state", "unixid", "email", "nick", "fullname",
36
 
    "admin", "studentid", "acct_exp", "pass_exp", "last_login",
37
 
    "svn_pass"
38
 
)
39
 
 
40
 
class UserRESTView(JSONRESTView):
41
 
    """
42
 
    A REST interface to the user object.
43
 
    """
44
 
    def __init__(self, req, login):
45
 
        super(UserRESTView, self).__init__(self, req, login)
46
 
        self.context = ivle.database.User.get_by_login(req.store, login)
47
 
        if self.context is None:
48
 
            raise NotFound()
49
 
 
50
 
    @require_permission('view')
51
 
    def GET(self, req):
52
 
        # XXX Check Caps
53
 
        user = ivle.util.object_to_dict(user_fields_list, self.context)
54
 
        # Convert time stamps to nice strings
55
 
        for k in 'pass_exp', 'acct_exp', 'last_login':
56
 
            if user[k] is not None:
57
 
                user[k] = unicode(user[k])
58
 
 
59
 
        user['local_password'] = self.context.passhash is not None
60
 
        return user
 
31
 
 
32
 
 
33
class UsersView(XHTMLView):
 
34
    """A list of all IVLE users."""
 
35
    template = 'templates/users.html'
 
36
    tab = 'users'
 
37
    breadcrumb_text = 'Users'
 
38
 
 
39
    def authorize(self, req):
 
40
        return req.user and req.user.admin
 
41
 
 
42
    def populate(self, req, ctx):
 
43
        ctx['req'] = req
 
44
        ctx['users'] = req.store.find(User).order_by(User.login)
 
45
 
61
46
 
62
47
class UserEditSchema(formencode.Schema):
63
48
    nick = formencode.validators.UnicodeString(not_empty=True)
64
49
    email = formencode.validators.Email(not_empty=False,
65
50
                                        if_missing=None)
66
51
 
67
 
class UserEditView(XHTMLView):
 
52
class UserEditView(BaseFormView):
68
53
    """A form to change a user's details."""
69
54
    template = 'templates/user-edit.html'
70
 
    tab = 'settings'
 
55
    tab = 'users'
71
56
    permission = 'edit'
72
57
 
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'])
 
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
80
72
 
81
73
    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
 
 
 
74
        super(UserEditView, self).populate(req, ctx)
100
75
        ctx['format_datetime'] = ivle.date.make_date_nice
101
76
        ctx['format_datetime_short'] = ivle.date.format_datetime_for_paragraph
102
77
 
103
 
        ctx['req'] = req
104
 
        ctx['user'] = self.context
105
 
        ctx['data'] = data
106
 
        ctx['errors'] = errors
107
78
 
108
79
class UserAdminSchema(formencode.Schema):
109
80
    admin = formencode.validators.StringBoolean(if_missing=False)
 
81
    disabled = formencode.validators.StringBoolean(if_missing=False)
110
82
    fullname = formencode.validators.UnicodeString(not_empty=True)
111
83
    studentid = formencode.validators.UnicodeString(not_empty=False,
112
84
                                                    if_missing=None
113
85
                                                    )
114
86
 
115
 
class UserAdminView(XHTMLView):
 
87
class UserAdminView(BaseFormView):
116
88
    """A form for admins to change more of a user's details."""
117
89
    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()
 
90
    tab = 'users'
124
91
 
125
92
    def authorize(self, req):
126
93
        """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'])
 
94
        return req.user and req.user.admin
 
95
 
 
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
131
122
 
132
123
    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
 
124
        super(UserAdminView, self).populate(req, ctx)
 
125
 
 
126
        # Disable the admin checkbox if editing oneself
 
127
        ctx['disable_admin'] = self.context is req.user
159
128
 
160
129
class PasswordChangeView(XHTMLView):
161
130
    """A form to change a user's password, with knowledge of the old one."""
162
131
    template = 'templates/user-password-change.html'
163
 
    tab = 'settings'
 
132
    tab = 'users'
164
133
    permission = 'edit'
165
134
 
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
135
    def authorize(self, req):
172
136
        """Only allow access if the requesting user holds the permission,
173
137
           and the target user has a password set. Otherwise we might be
199
163
class PasswordResetView(XHTMLView):
200
164
    """A form to reset a user's password, without knowledge of the old one."""
201
165
    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()
 
166
    tab = 'users'
208
167
 
209
168
    def authorize(self, req):
210
169
        """Only allow access if the requesting user is an admin."""
211
 
        return req.user.admin
 
170
        return req.user and req.user.admin
212
171
 
213
172
    def populate(self, req, ctx):
214
173
        error = None
230
189
    """
231
190
    The Plugin class for the user plugin.
232
191
    """
233
 
    # Magic attribute: urls
234
 
    # Sequence of pairs/triples of
235
 
    # (regex str, handler class, kwargs dict)
236
 
    # The kwargs dict is passed to the __init__ of the view object
237
 
    urls = [
238
 
        ('~:login/+edit', UserEditView),
239
 
        ('~:login/+admin', UserAdminView),
240
 
        ('~:login/+changepassword', PasswordChangeView),
241
 
        ('~:login/+resetpassword', PasswordResetView),
242
 
        ('api/~:login', UserRESTView),
 
192
 
 
193
    forward_routes = (root_to_user,)
 
194
    reverse_routes = (user_url,)
 
195
    views = [(ApplicationRoot, 'users', UsersView),
 
196
             (User, '+index', UserEditView),
 
197
             (User, '+admin', UserAdminView),
 
198
             (User, '+changepassword', PasswordChangeView),
 
199
             (User, '+resetpassword', PasswordResetView),
 
200
             ]
 
201
 
 
202
    tabs = [
 
203
        ('users', 'Users', 'Display and edit all users',
 
204
         'users.png', 'users', 90, True)
243
205
    ]
244
206
 
 
207
    public_forward_routes = forward_routes
 
208
    public_reverse_routes = reverse_routes
 
209
 
245
210
    media = 'user-media'