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

1076 by chadnickbok
Created a new app, logout, which when given a GET
1
# IVLE
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
1099.1.41 by William Grant
Port www/apps/logout to new framework (in ivle.webapp.security).
18
# Author: Will Grant, Nick Chadwick
19
1099.1.120 by William Grant
Move the login machinery to the new framework.
20
import urllib
21
import datetime
22
try:
23
    import mod_python.Cookie
24
except ImportError:
25
    # This needs to be importable from outside Apache.
26
    pass
27
1137 by William Grant
Attempt to use subject pulldown modules to enrol users whenever they log in.
28
import ivle.pulldown_subj
1099.1.161 by William Grant
Move ivle.dispatch.login.get_user_details() to ivle.webapp.security.
29
import ivle.webapp.security
1099.1.120 by William Grant
Move the login machinery to the new framework.
30
from ivle.auth import authenticate, AuthError
1099.1.41 by William Grant
Port www/apps/logout to new framework (in ivle.webapp.security).
31
from ivle.webapp.base.xhtml import XHTMLView
1099.1.120 by William Grant
Move the login machinery to the new framework.
32
from ivle.webapp.base.plugins import CookiePlugin
33
34
class LoginView(XHTMLView):
35
    '''A view to allow a user to log in.'''
36
    template = 'login.html'
1099.1.129 by William Grant
Allow XHTML views to specify that they cannot have overlays.
37
    allow_overlays = False
1099.1.120 by William Grant
Move the login machinery to the new framework.
38
39
    def authorize(self, req):
40
        return True
41
42
    def populate(self, req, ctx):
43
        fields = req.get_fieldstorage()
44
        nexturl = fields.getfirst('url')
45
1705 by Matt Giuca
Login page: Added a warning that Internet Explorer is unsupported at this time. This checks the UA string for 'MSIE' and a bit more magic. Fixes Launchpad bug #526822.
46
        # XXX Warning that Internet Explorer is unsupported
47
        # Test if the user is in Internet Explorer
48
        try:
49
            useragent = req.headers_in['User-Agent']
50
            # A bit of very basic UA string detection
51
            ctx['msie'] = ('MSIE' in useragent
52
                           and 'AppleWebKit' not in useragent
53
                           and 'Gecko' not in useragent
54
                           and 'Opera' not in useragent)
55
        except KeyError:
56
            ctx['msie'] = False
57
1099.1.120 by William Grant
Move the login machinery to the new framework.
58
        if nexturl is None:
59
            nexturl = '/'
60
1154 by William Grant
Only redirect +login for logged in users if the method is not POST. We do this
61
        # We are already logged in. If it is a POST, they might be trying to
62
        # clobber their session with some new credentials. That's their own
63
        # business, so we let them do it. Otherwise, we don't bother prompting
64
        # and just redirect to the destination.
1099.1.125 by William Grant
Move the pending/no_agreement handling into the new login machinery.
65
        # Note that req.user is None even if we are 'logged in', if the user is
1154 by William Grant
Only redirect +login for logged in users if the method is not POST. We do this
66
        # invalid (state != enabled, or expired).
67
        if req.method != "POST" and req.user is not None:
1099.1.120 by William Grant
Move the login machinery to the new framework.
68
            req.throw_redirect(nexturl)
69
1099.1.209 by William Grant
Don't escape / in paths when they are in +login/+tos URLs.
70
        # Don't give any URL if we want /.
71
        if nexturl == '/':
72
            query_string = ''
73
        else:
74
            query_string = '?url=' + urllib.quote(nexturl, safe="/~")
75
1210 by William Grant
Use Request.make_path everywhere.
76
        ctx['path'] = req.make_path('+login') + query_string
1099.1.120 by William Grant
Move the login machinery to the new framework.
77
1099.1.125 by William Grant
Move the pending/no_agreement handling into the new login machinery.
78
        # If this succeeds, the user is invalid.
1099.1.161 by William Grant
Move ivle.dispatch.login.get_user_details() to ivle.webapp.security.
79
        user = ivle.webapp.security.get_user_details(req)
1099.1.125 by William Grant
Move the pending/no_agreement handling into the new login machinery.
80
        if user is not None:
81
            if user.state == "no_agreement":
82
                # Authenticated, but need to accept the ToS. Send them there.
83
                # IMPORTANT NOTE FOR HACKERS: You can't simply disable this
84
                # if you are not planning to display a ToS page - the ToS
85
                # acceptance process actually calls usrmgt to create the user
86
                # jails and related stuff.
1210 by William Grant
Use Request.make_path everywhere.
87
                req.throw_redirect(req.make_path('+tos') + query_string)
1099.1.125 by William Grant
Move the pending/no_agreement handling into the new login machinery.
88
            elif user.state == "pending":
89
                # FIXME: this isn't quite the right answer, but it
90
                # should be more robust in the short term.
91
                session = req.get_session()
92
                session.invalidate()
93
                session.delete()
94
                user.state = u'no_agreement'
95
                req.store.commit()
96
                req.throw_redirect(nexturl)
97
1099.1.120 by William Grant
Move the login machinery to the new framework.
98
        if req.method == "POST":
99
            # While req.user is normally set to get_user_details, it won't set
100
            # it if the account isn't valid. So we get it ourselves.
1099.1.161 by William Grant
Move ivle.dispatch.login.get_user_details() to ivle.webapp.security.
101
            user = ivle.webapp.security.get_user_details(req)
1099.1.120 by William Grant
Move the login machinery to the new framework.
102
103
            badlogin = None
104
105
            username = fields.getfirst('user')
106
            password = fields.getfirst('pass')
107
            if username is not None:
108
                # From this point onwards, we will be showing an error message
109
                # if unsuccessful.
110
                # Authenticate
111
                if password is None:
112
                    badlogin = "No password supplied."
113
                else:
114
                    user = None
115
                    try:
1317 by David Coles
Normalise usernames to lowercase so that they are case insensitive.
116
                        # Username is case insensitive
1278 by William Grant
No more ivle.conf in ivle.auth.
117
                        user = authenticate.authenticate(req.config, req.store,
1317 by David Coles
Normalise usernames to lowercase so that they are case insensitive.
118
                                    username.value.lower(), password.value)
1099.1.120 by William Grant
Move the login machinery to the new framework.
119
                    except AuthError, msg:
120
                        badlogin = msg
121
                    if user is None:
122
                        # Must have got an error. Do not authenticate.
1099.1.123 by William Grant
Don't crash when not authenticated, and display an error on password absence.
123
                        # The except: above will have set a message.
1099.1.120 by William Grant
Move the login machinery to the new framework.
124
                        pass
125
                    else:
126
                        # Success - Set the session and redirect to the URL.
127
                        session = req.get_session()
128
                        session['login'] = user.login
129
                        session.save()
1130 by William Grant
Unlock the session everywhere as soon as we are done with it, and add a warning
130
                        session.unlock()
1099.1.120 by William Grant
Move the login machinery to the new framework.
131
                        user.last_login = datetime.datetime.now()
132
133
                        # Create cookies for plugins that might request them.
1092.1.59 by William Grant
Move the plugin loading/indexing logic into ivle.config.Config.
134
                        for plugin in req.config.plugin_index[CookiePlugin]:
1099.1.120 by William Grant
Move the login machinery to the new framework.
135
                            for cookie in plugin.cookies:
136
                                # The function can be None if they just need to be
137
                                # deleted at logout.
138
                                if plugin.cookies[cookie] is not None:
139
                                    req.add_cookie(mod_python.Cookie.Cookie(cookie,
140
                                          plugin.cookies[cookie](user), path='/'))
141
1137 by William Grant
Attempt to use subject pulldown modules to enrol users whenever they log in.
142
                        # Add any new enrolments.
1279 by William Grant
Drop ivle.conf usage from ivle.pulldown_subj.
143
                        ivle.pulldown_subj.enrol_user(req.config, req.store, user)
1137 by William Grant
Attempt to use subject pulldown modules to enrol users whenever they log in.
144
                        req.store.commit()
145
1099.1.120 by William Grant
Move the login machinery to the new framework.
146
                        req.throw_redirect(nexturl)
147
1099.1.123 by William Grant
Don't crash when not authenticated, and display an error on password absence.
148
                # We didn't succeed.
149
                # Render the login form with the error message.
150
                ctx['error'] = badlogin
1099.1.120 by William Grant
Move the login machinery to the new framework.
151
1099.1.41 by William Grant
Port www/apps/logout to new framework (in ivle.webapp.security).
152
153
class LogoutView(XHTMLView):
154
    '''A view to log the current session out.'''
155
    template = 'logout.html'
1099.1.129 by William Grant
Allow XHTML views to specify that they cannot have overlays.
156
    allow_overlays = False
1099.1.41 by William Grant
Port www/apps/logout to new framework (in ivle.webapp.security).
157
1099.1.110 by William Grant
Implement an authorization system in the new framework. This breaks the REST
158
    def authorize(self, req):
1099.1.126 by William Grant
Allow any authenticated (even invalid) user to use the logout view.
159
        # This can be used by any authenticated user, even if they haven't
160
        # accepted the ToS yet.
1099.1.161 by William Grant
Move ivle.dispatch.login.get_user_details() to ivle.webapp.security.
161
        return ivle.webapp.security.get_user_details(req) is not None
1099.1.110 by William Grant
Implement an authorization system in the new framework. This breaks the REST
162
1099.1.41 by William Grant
Port www/apps/logout to new framework (in ivle.webapp.security).
163
    def populate(self, req, ctx):
164
        if req.method == "POST":
165
            req.logout()
166
        else:
1210 by William Grant
Use Request.make_path everywhere.
167
            ctx['path'] =  req.make_path('+logout')