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

1099.1.1 by Matt Giuca
Began implementing new dispatch framework (with Will Grant and Nick Chadwick).
1
# IVLE - Informatics Virtual Learning Environment
2
# Copyright (C) 2007-2009 The University of Melbourne
3
#
4
# This program is free software; you can redistribute it and/or modify
5
# it under the terms of the GNU General Public License as published by
6
# the Free Software Foundation; either version 2 of the License, or
7
# (at your option) any later version.
8
#
9
# This program is distributed in the hope that it will be useful,
10
# but WITHOUT ANY WARRANTY; without even the implied warranty of
11
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
# GNU General Public License for more details.
13
#
14
# You should have received a copy of the GNU General Public License
15
# along with this program; if not, write to the Free Software
16
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
17
18
# Author: Matt Giuca, Will Grant
19
1294.1.1 by William Grant
Add UserEditView, a non-AJAX partial replacement of UserSettingsView.
20
import formencode
21
import formencode.validators
22
from genshi.filters import HTMLFormFiller
23
1375 by William Grant
Add a user list -- as yet unlinked.
24
from ivle.webapp import ApplicationRoot
1680 by William Grant
Refactor UserAdminView to use BaseFormView.
25
from ivle.webapp.base.forms import BaseFormView
1099.1.34 by William Grant
Split up ivle.webapp.base.views into ivle.webapp.base.{rest,xhtml}, as it was
26
from ivle.webapp.base.xhtml import XHTMLView
1099.1.99 by William Grant
Require that plugins providing media subclass MediaPlugin.
27
from ivle.webapp.base.plugins import ViewPlugin, MediaPlugin
1294.3.2 by William Grant
Router->Publisher
28
from ivle.webapp.admin.publishing import root_to_user, user_url
1375 by William Grant
Add a user list -- as yet unlinked.
29
from ivle.database import User
1294.1.7 by William Grant
Display account/password expiry times on +edit.
30
import ivle.date
1099.1.1 by Matt Giuca
Began implementing new dispatch framework (with Will Grant and Nick Chadwick).
31
1375 by William Grant
Add a user list -- as yet unlinked.
32
33
class UsersView(XHTMLView):
34
    """A list of all IVLE users."""
35
    template = 'templates/users.html'
1497 by Matt Giuca
Added Users tab to drop-down menu, for admins only.
36
    tab = 'users'
1472 by William Grant
Add a 'Users' breadcrumb.
37
    breadcrumb_text = 'Users'
1375 by William Grant
Add a user list -- as yet unlinked.
38
39
    def authorize(self, req):
1504 by Matt Giuca
ivle/webapp/admin/user.py: Fixed crash when visiting admin-only user pages while logged out (None dereference).
40
        return req.user and req.user.admin
1375 by William Grant
Add a user list -- as yet unlinked.
41
42
    def populate(self, req, ctx):
43
        ctx['req'] = req
44
        ctx['users'] = req.store.find(User).order_by(User.login)
45
46
1294.1.1 by William Grant
Add UserEditView, a non-AJAX partial replacement of UserSettingsView.
47
class UserEditSchema(formencode.Schema):
48
    nick = formencode.validators.UnicodeString(not_empty=True)
49
    email = formencode.validators.Email(not_empty=False,
50
                                        if_missing=None)
51
1681 by William Grant
Refactor UserEditView to use BaseFormView.
52
class UserEditView(BaseFormView):
1294.1.1 by William Grant
Add UserEditView, a non-AJAX partial replacement of UserSettingsView.
53
    """A form to change a user's details."""
54
    template = 'templates/user-edit.html'
1498 by Matt Giuca
user.py: All user pages are now in the tab "users", so they show the user icon
55
    tab = 'users'
1294.1.1 by William Grant
Add UserEditView, a non-AJAX partial replacement of UserSettingsView.
56
    permission = 'edit'
57
1681 by William Grant
Refactor UserEditView to use BaseFormView.
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
1294.1.1 by William Grant
Add UserEditView, a non-AJAX partial replacement of UserSettingsView.
72
73
    def populate(self, req, ctx):
1681 by William Grant
Refactor UserEditView to use BaseFormView.
74
        super(UserEditView, self).populate(req, ctx)
1294.1.7 by William Grant
Display account/password expiry times on +edit.
75
        ctx['format_datetime'] = ivle.date.make_date_nice
76
        ctx['format_datetime_short'] = ivle.date.format_datetime_for_paragraph
77
1294.1.1 by William Grant
Add UserEditView, a non-AJAX partial replacement of UserSettingsView.
78
1294.1.9 by William Grant
Add a UserAdminView, to set fullname/studentid/admin.
79
class UserAdminSchema(formencode.Schema):
80
    admin = formencode.validators.StringBoolean(if_missing=False)
1503 by David Coles
Admin: Allow enabling and disabling of users in admin UI
81
    disabled = formencode.validators.StringBoolean(if_missing=False)
1294.1.9 by William Grant
Add a UserAdminView, to set fullname/studentid/admin.
82
    fullname = formencode.validators.UnicodeString(not_empty=True)
83
    studentid = formencode.validators.UnicodeString(not_empty=False,
84
                                                    if_missing=None
85
                                                    )
86
1680 by William Grant
Refactor UserAdminView to use BaseFormView.
87
class UserAdminView(BaseFormView):
1294.1.9 by William Grant
Add a UserAdminView, to set fullname/studentid/admin.
88
    """A form for admins to change more of a user's details."""
89
    template = 'templates/user-admin.html'
1498 by Matt Giuca
user.py: All user pages are now in the tab "users", so they show the user icon
90
    tab = 'users'
1294.1.9 by William Grant
Add a UserAdminView, to set fullname/studentid/admin.
91
92
    def authorize(self, req):
93
        """Only allow access if the requesting user is an admin."""
1504 by Matt Giuca
ivle/webapp/admin/user.py: Fixed crash when visiting admin-only user pages while logged out (None dereference).
94
        return req.user and req.user.admin
1294.1.9 by William Grant
Add a UserAdminView, to set fullname/studentid/admin.
95
1680 by William Grant
Refactor UserAdminView to use BaseFormView.
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
122
1294.1.9 by William Grant
Add a UserAdminView, to set fullname/studentid/admin.
123
    def populate(self, req, ctx):
1680 by William Grant
Refactor UserAdminView to use BaseFormView.
124
        super(UserAdminView, self).populate(req, ctx)
125
126
        # Disable the admin checkbox if editing oneself
1501 by Matt Giuca
User administration page: Do not let an admin user change their own admin checkbox (disable and don't let it change). This would be bad.
127
        ctx['disable_admin'] = self.context is req.user
1294.1.9 by William Grant
Add a UserAdminView, to set fullname/studentid/admin.
128
1294.1.2 by William Grant
Add a non-AJAX password change view.
129
class PasswordChangeView(XHTMLView):
1294.1.5 by William Grant
Add a view for admins to reset other users' passwords.
130
    """A form to change a user's password, with knowledge of the old one."""
1294.1.2 by William Grant
Add a non-AJAX password change view.
131
    template = 'templates/user-password-change.html'
1498 by Matt Giuca
user.py: All user pages are now in the tab "users", so they show the user icon
132
    tab = 'users'
1294.1.2 by William Grant
Add a non-AJAX password change view.
133
    permission = 'edit'
134
1294.1.4 by William Grant
Forbid access to +changepassword if there is no passhash.
135
    def authorize(self, req):
136
        """Only allow access if the requesting user holds the permission,
137
           and the target user has a password set. Otherwise we might be
138
           clobbering external authn.
139
        """
140
        return super(PasswordChangeView, self).authorize(req) and \
141
               self.context.passhash is not None
142
1294.1.2 by William Grant
Add a non-AJAX password change view.
143
    def populate(self, req, ctx):
144
        error = None
145
        if req.method == 'POST':
146
            data = dict(req.get_fieldstorage())
147
            if data.get('old_password') is None or \
148
               not self.context.authenticate(data.get('old_password')):
149
                error = 'Incorrect password.'
150
            elif data.get('new_password') != data.get('new_password_again'):
151
                error = 'New passwords do not match.'
152
            elif not data.get('new_password'):
153
                error = 'New password cannot be empty.'
154
            else:
155
                self.context.password = data['new_password']
156
                req.store.commit()
157
                req.throw_redirect(req.uri)
158
1294.1.5 by William Grant
Add a view for admins to reset other users' passwords.
159
        ctx['req'] = req
160
        ctx['user'] = self.context
161
        ctx['error'] = error
162
163
class PasswordResetView(XHTMLView):
164
    """A form to reset a user's password, without knowledge of the old one."""
165
    template = 'templates/user-password-reset.html'
1498 by Matt Giuca
user.py: All user pages are now in the tab "users", so they show the user icon
166
    tab = 'users'
1294.1.5 by William Grant
Add a view for admins to reset other users' passwords.
167
168
    def authorize(self, req):
169
        """Only allow access if the requesting user is an admin."""
1504 by Matt Giuca
ivle/webapp/admin/user.py: Fixed crash when visiting admin-only user pages while logged out (None dereference).
170
        return req.user and req.user.admin
1294.1.5 by William Grant
Add a view for admins to reset other users' passwords.
171
172
    def populate(self, req, ctx):
173
        error = None
174
        if req.method == 'POST':
175
            data = dict(req.get_fieldstorage())
176
            if data.get('new_password') != data.get('new_password_again'):
177
                error = 'New passwords do not match.'
178
            elif not data.get('new_password'):
179
                error = 'New password cannot be empty.'
180
            else:
181
                self.context.password = data['new_password']
182
                req.store.commit()
183
                req.throw_redirect(req.uri)
184
1294.1.2 by William Grant
Add a non-AJAX password change view.
185
        ctx['user'] = self.context
186
        ctx['error'] = error
187
1099.1.99 by William Grant
Require that plugins providing media subclass MediaPlugin.
188
class Plugin(ViewPlugin, MediaPlugin):
1099.1.1 by Matt Giuca
Began implementing new dispatch framework (with Will Grant and Nick Chadwick).
189
    """
190
    The Plugin class for the user plugin.
191
    """
1294.2.19 by William Grant
Port ivle.webapp.admin.user's views to the new dispatch system.
192
1294.2.70 by William Grant
Split out ivle.webapp.admin's routes into annotated functions in ivle.webapp.traversal.
193
    forward_routes = (root_to_user,)
194
    reverse_routes = (user_url,)
1375 by William Grant
Add a user list -- as yet unlinked.
195
    views = [(ApplicationRoot, 'users', UsersView),
1679 by William Grant
Remove unused UserRESTView and associated infrastructure.
196
             (User, '+index', UserEditView),
197
             (User, '+admin', UserAdminView),
198
             (User, '+changepassword', PasswordChangeView),
199
             (User, '+resetpassword', PasswordResetView),
1294.2.19 by William Grant
Port ivle.webapp.admin.user's views to the new dispatch system.
200
             ]
1099.1.61 by William Grant
Port ivle.webapp.admin.user's media to the new framework.
201
1497 by Matt Giuca
Added Users tab to drop-down menu, for admins only.
202
    tabs = [
203
        ('users', 'Users', 'Display and edit all users',
1507 by William Grant
Shift the Users link to between Subjects and Help.
204
         'users.png', 'users', 90, True)
1497 by Matt Giuca
Added Users tab to drop-down menu, for admins only.
205
    ]
206
1294.2.138 by William Grant
Publish users in public mode.
207
    public_forward_routes = forward_routes
208
    public_reverse_routes = reverse_routes
209
1099.1.61 by William Grant
Port ivle.webapp.admin.user's media to the new framework.
210
    media = 'user-media'