~certify-web-dev/twisted/certify-trunk

« back to all changes in this revision

Viewing changes to twisted/web/guard.py

  • Committer: Bazaar Package Importer
  • Author(s): Moshe Zadka
  • Date: 2002-03-08 07:14:16 UTC
  • Revision ID: james.westby@ubuntu.com-20020308071416-oxvuw76tpcpi5v1q
Tags: upstream-0.15.5
ImportĀ upstreamĀ versionĀ 0.15.5

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
 
 
2
# Twisted, the Framework of Your Internet
 
3
# Copyright (C) 2001 Matthew W. Lefkowitz
 
4
 
5
# This library is free software; you can redistribute it and/or
 
6
# modify it under the terms of version 2.1 of the GNU Lesser General Public
 
7
# License as published by the Free Software Foundation.
 
8
 
9
# This library 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 GNU
 
12
# Lesser General Public License for more details.
 
13
 
14
# You should have received a copy of the GNU Lesser General Public
 
15
# License along with this library; if not, write to the Free Software
 
16
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
17
 
 
18
# System Imports
 
19
import string, traceback
 
20
from cStringIO import StringIO
 
21
 
 
22
# Sibling Imports
 
23
import error
 
24
import html
 
25
import resource
 
26
import widgets
 
27
from server import NOT_DONE_YET
 
28
 
 
29
 
 
30
class _Detacher:
 
31
    """Detach a web session from an attached perspective.
 
32
 
 
33
    This will happen when the session expires.
 
34
    """
 
35
    
 
36
    def __init__(self, session, identity, perspective):
 
37
        self.session = session
 
38
        self.identity = identity
 
39
        self.perspective = perspective
 
40
        session.notifyOnExpire(self.detach)
 
41
    
 
42
    def detach(self):
 
43
        self.perspective.detached(self.session, self.identity)
 
44
        del self.session
 
45
        del self.identity
 
46
        del self.perspective
 
47
 
 
48
 
 
49
class AuthForm(widgets.Form):
 
50
    formFields = [
 
51
        ['string','Identity','username',''],
 
52
        ['password','Password','password',''],
 
53
        ['string','Perspective','perspective','']
 
54
        ]
 
55
 
 
56
    def __init__(self, reqauth, sessionIdentity=None, sessionPerspective=None):
 
57
        """Initialize, specifying various options.
 
58
        
 
59
        Arguments:
 
60
 
 
61
            * reqauth: a web.resource.Resource instance, indicating which
 
62
              resource a user will be logging into with this form; this must
 
63
              specify a serviceName attribute which indicates the name of the
 
64
              service from which perspectives will be requested.
 
65
 
 
66
            * [sessionIdentity]: if specified, the name of the attribute on
 
67
              the user's session to set for the identity they get from logging
 
68
              in to this form.
 
69
            
 
70
            * [sessionPerspective]: if specified, the name of the attribute on
 
71
              the user's session to set for the perspective they get from
 
72
              logging in to this form.
 
73
        """
 
74
        self.reqauth = reqauth
 
75
        self.sessionPerspective = sessionPerspective
 
76
        self.sessionIdentity = sessionIdentity
 
77
 
 
78
    def gotPerspective(self, perspective, request, ident):
 
79
        # TODO: fix this...
 
80
        resKey = string.join(['AUTH',self.reqauth.service.serviceName], '_')
 
81
        sess = request.getSession()
 
82
        setattr(sess, resKey, perspective)
 
83
        if self.sessionPerspective:
 
84
            setattr(sess, self.sessionPerspective, perspective)
 
85
            if self.sessionIdentity:
 
86
                setattr(sess, self.sessionIdentity, ident)
 
87
            p = perspective.attached(sess, ident)
 
88
            _Detacher(sess, ident, p)
 
89
        return self.reqauth.reallyRender(request)
 
90
    
 
91
    def didntGetPerspective(self, error, request):
 
92
        print 'Password not verified! Error:', error
 
93
        io = StringIO()
 
94
        io.write(self.formatError("Login incorrect."))
 
95
        self.format(self.getFormFields(request), io.write, request)
 
96
        return [io.getvalue()]
 
97
 
 
98
    def gotIdentity(self, ident, password, request, perspectiveName):
 
99
        if ident.verifyPlainPassword(password):
 
100
            ret = ident.requestPerspectiveForKey(self.reqauth.service.serviceName,
 
101
                                                  perspectiveName).addCallbacks(
 
102
                self.gotPerspective, self.didntGetPerspective,
 
103
                callbackArgs=(request,ident),
 
104
                errbackArgs=(request,))
 
105
            ret.needsHeader = 1
 
106
            return [ret]
 
107
        else:
 
108
            return self.didntGetPerspective("no such identity", request)
 
109
 
 
110
    def didntGetIdentity(self, unauth, request):
 
111
        io = StringIO()
 
112
        io.write(self.formatError("Login incorrect."))
 
113
        self.format(self.getFormFields(request), io.write, request)
 
114
        return io.getvalue()
 
115
 
 
116
    def process(self, write, request, submit, username, password, perspective):
 
117
        """Process the form results.
 
118
        """
 
119
        # must be done before page is displayed so cookie can get set!
 
120
        request.getSession()
 
121
        # this site must be tagged with an application.
 
122
        idrq = self.reqauth.service.application.authorizer.getIdentityRequest(username)
 
123
        idrq.needsHeader = 1
 
124
        idrq.addCallbacks(self.gotIdentity, self.didntGetIdentity,
 
125
                          callbackArgs=(password,request,perspective or username),
 
126
                          errbackArgs=(request,))
 
127
        return [idrq]
 
128
 
 
129
class AuthPage(widgets.Page):
 
130
    template = '''
 
131
    <html><head><title>Authorization Required</title></head>
 
132
    <body>
 
133
    <center>
 
134
    %%%%authForm%%%%
 
135
    </center>
 
136
    </body>
 
137
    </html>
 
138
    '''
 
139
    authForm = None
 
140
    def __init__(self, reqauth, sessionIdentity=None, sessionPerspective=None):
 
141
        widgets.Page.__init__(self)
 
142
        self.authForm = AuthForm(reqauth, sessionPerspective, sessionIdentity)
 
143
 
 
144
 
 
145
class WidgetGuard(widgets.Widget):
 
146
    
 
147
    def __init__(self, wid, service,
 
148
                 sessionIdentity=None,
 
149
                 sessionPerspective=None):
 
150
        self.wid = wid
 
151
        self.service = service
 
152
        self.sessionPerspective = sessionPerspective
 
153
        self.sessionIdentity = sessionIdentity
 
154
 
 
155
    def reallyRender(self, request):
 
156
        return widgets.possiblyDeferWidget(self.wid, request)
 
157
 
 
158
    def display(self, request):
 
159
        session = request.getSession()
 
160
        resKey = string.join(['AUTH',self.service.serviceName], '_')
 
161
        if hasattr(session, resKey):
 
162
            return self.wid.display(request)
 
163
        else:
 
164
            return AuthForm(self).display(request)
 
165
 
 
166
 
 
167
 
 
168
class ResourceGuard(resource.Resource):
 
169
    isLeaf = 1
 
170
    def __init__(self, res, service, sessionIdentity=None, sessionPerspective=None):
 
171
        self.res = res
 
172
        self.service = service
 
173
        self.sessionPerspective = sessionPerspective
 
174
        self.sessionIdentity = sessionIdentity
 
175
 
 
176
    def reallyRender(self, request):
 
177
        # it's authenticated already...
 
178
        res = self.res.getChildForRequest(request)
 
179
        val = res.render(request)
 
180
        if val != NOT_DONE_YET:
 
181
            request.write(val)
 
182
            request.finish()
 
183
        return widgets.FORGET_IT
 
184
 
 
185
    def render(self, request):
 
186
        session = request.getSession()
 
187
        resKey = string.join(['AUTH',self.service.serviceName], '_')
 
188
        if hasattr(session, resKey):
 
189
            self.reallyRender(request)
 
190
            return NOT_DONE_YET
 
191
        else:
 
192
            return AuthPage(self,
 
193
                            self.sessionPerspective,
 
194
                            self.sessionIdentity).render(request)
 
195