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

« back to all changes in this revision

Viewing changes to ivle/webapp/security/views.py

  • Committer: Matt Giuca
  • Date: 2010-07-28 06:09:00 UTC
  • Revision ID: matt.giuca@gmail.com-20100728060900-6a0lcuexcv1juh5r
ivle/webapp/submit/submit.html: Rewrote error message when an offering could not be found to submit to. This can have one of several causes, and the old error assumed it was because you weren't in a subject dir. Now enumerates the possible reasons. (LP: #526853)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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
 
 
18
# Author: Will Grant, Nick Chadwick
 
19
 
 
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
 
 
28
import ivle.pulldown_subj
 
29
import ivle.webapp.security
 
30
from ivle.auth import authenticate, AuthError
 
31
from ivle.webapp.base.xhtml import XHTMLView
 
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'
 
37
    allow_overlays = False
 
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
 
 
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
 
 
58
        if nexturl is None:
 
59
            nexturl = '/'
 
60
 
 
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.
 
65
        # Note that req.user is None even if we are 'logged in', if the user is
 
66
        # invalid (state != enabled, or expired).
 
67
        if req.method != "POST" and req.user is not None:
 
68
            req.throw_redirect(nexturl)
 
69
 
 
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
 
 
76
        ctx['path'] = req.make_path('+login') + query_string
 
77
 
 
78
        # If this succeeds, the user is invalid.
 
79
        user = ivle.webapp.security.get_user_details(req)
 
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.
 
87
                req.throw_redirect(req.make_path('+tos') + query_string)
 
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
 
 
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.
 
101
            user = ivle.webapp.security.get_user_details(req)
 
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:
 
116
                        # Username is case insensitive
 
117
                        user = authenticate.authenticate(req.config, req.store,
 
118
                                    username.value.lower(), password.value)
 
119
                    except AuthError, msg:
 
120
                        badlogin = msg
 
121
                    if user is None:
 
122
                        # Must have got an error. Do not authenticate.
 
123
                        # The except: above will have set a message.
 
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()
 
130
                        session.unlock()
 
131
                        user.last_login = datetime.datetime.now()
 
132
 
 
133
                        # Create cookies for plugins that might request them.
 
134
                        for plugin in req.config.plugin_index[CookiePlugin]:
 
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
 
 
142
                        # Add any new enrolments.
 
143
                        ivle.pulldown_subj.enrol_user(req.config, req.store, user)
 
144
                        req.store.commit()
 
145
 
 
146
                        req.throw_redirect(nexturl)
 
147
 
 
148
                # We didn't succeed.
 
149
                # Render the login form with the error message.
 
150
                ctx['error'] = badlogin
 
151
 
 
152
 
 
153
class LogoutView(XHTMLView):
 
154
    '''A view to log the current session out.'''
 
155
    template = 'logout.html'
 
156
    allow_overlays = False
 
157
 
 
158
    def authorize(self, req):
 
159
        # This can be used by any authenticated user, even if they haven't
 
160
        # accepted the ToS yet.
 
161
        return ivle.webapp.security.get_user_details(req) is not None
 
162
 
 
163
    def populate(self, req, ctx):
 
164
        if req.method == "POST":
 
165
            req.logout()
 
166
        else:
 
167
            ctx['path'] =  req.make_path('+logout')