~landscape/zope3/newer-from-ztk

« back to all changes in this revision

Viewing changes to src/twisted/web2/auth/wrapper.py

  • Committer: Thomas Hervé
  • Date: 2009-07-08 13:52:04 UTC
  • Revision ID: thomas@canonical.com-20090708135204-df5eesrthifpylf8
Remove twisted copy

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# -*- test-case-name: twisted.web2.test.test_httpauth -*-
2
 
 
3
 
"""
4
 
Wrapper Resources for rfc2617 HTTP Auth.
5
 
"""
6
 
from zope.interface import implements
7
 
from twisted.cred import error
8
 
 
9
 
from twisted.web2 import resource
10
 
from twisted.web2 import responsecode
11
 
from twisted.web2 import http
12
 
from twisted.web2 import iweb
13
 
 
14
 
class UnauthorizedResponse(http.StatusResponse):
15
 
    """A specialized response class for generating www-authenticate headers
16
 
    from the given L{CredentialFactory} instances
17
 
    """
18
 
 
19
 
    def __init__(self, factories, remoteAddr=None):
20
 
        super(UnauthorizedResponse, self).__init__(
21
 
            responsecode.UNAUTHORIZED,
22
 
            "You are not authorized to access this resource.")
23
 
        
24
 
        authHeaders = []
25
 
        for factory in factories.itervalues():
26
 
            authHeaders.append((factory.scheme,
27
 
                                factory.getChallenge(remoteAddr)))
28
 
 
29
 
        self.headers.setHeader('www-authenticate', authHeaders)
30
 
 
31
 
 
32
 
class UnauthorizedResource(resource.LeafResource):
33
 
    """Returned by locateChild or render to generate an http Unauthorized
34
 
       response.
35
 
    """
36
 
 
37
 
    def __init__(self, factories):
38
 
        """
39
 
        @param factories: sequence of ICredentialFactory implementations 
40
 
                          for which to generate a WWW-Authenticate header.
41
 
        """
42
 
        self.factories = factories
43
 
        
44
 
    def render(self, req):
45
 
        return UnauthorizedResponse(self.factories, req.remoteAddr)
46
 
 
47
 
 
48
 
class HTTPAuthResource(object):
49
 
    """I wrap a resource to prevent it being accessed unless the authentication
50
 
       can be completed using the credential factory, portal, and interfaces
51
 
       specified.
52
 
    """
53
 
 
54
 
    implements(iweb.IResource)
55
 
 
56
 
    def __init__(self, wrappedResource, credentialFactories,
57
 
                 portal, interfaces):
58
 
        """
59
 
        @param wrappedResource: A L{twisted.web2.iweb.IResource} to be returned 
60
 
                                from locateChild and render upon successful
61
 
                                authentication.
62
 
 
63
 
        @param credentialFactories: A list of instances that implement 
64
 
                                    L{ICredentialFactory}.
65
 
        @type credentialFactories: L{list}
66
 
 
67
 
        @param portal: Portal to handle logins for this resource.
68
 
        @type portal: L{twisted.cred.portal.Portal}
69
 
        
70
 
        @param interfaces: the interfaces that are allowed to log in via the 
71
 
                           given portal
72
 
        @type interfaces: L{tuple}
73
 
        """
74
 
 
75
 
        self.wrappedResource = wrappedResource
76
 
 
77
 
        self.credentialFactories = dict([(factory.scheme, factory) 
78
 
                                         for factory in credentialFactories])
79
 
        self.portal = portal
80
 
        self.interfaces = interfaces
81
 
 
82
 
    def login(self, factory, response, req):
83
 
        def _loginSucceeded(res):
84
 
            return self.wrappedResource
85
 
 
86
 
        def _loginFailed(res):
87
 
            return UnauthorizedResource(self.credentialFactories)
88
 
 
89
 
        try:
90
 
            creds = factory.decode(response, req)
91
 
        except error.LoginFailed:
92
 
            return UnauthorizedResource(self.credentialFactories)
93
 
 
94
 
        return self.portal.login(creds, None, *self.interfaces
95
 
                                ).addCallbacks(_loginSucceeded,
96
 
                                               _loginFailed)
97
 
 
98
 
    def authenticate(self, req):
99
 
        authHeader = req.headers.getHeader('authorization')
100
 
 
101
 
        if authHeader is None or authHeader[0] not in self.credentialFactories:
102
 
            return UnauthorizedResource(self.credentialFactories)
103
 
        else:
104
 
            return self.login(self.credentialFactories[authHeader[0]],
105
 
                              authHeader[1], req)
106
 
 
107
 
    def locateChild(self, req, seg):
108
 
        return self.authenticate(req), seg[1:]
109
 
 
110
 
    def renderHTTP(self, req):
111
 
        return self.authenticate(req)