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

« back to all changes in this revision

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

  • Committer: Bazaar Package Importer
  • Author(s): Matthias Klose
  • Date: 2007-01-17 14:52:35 UTC
  • mto: (2.2.3 sid)
  • mto: This revision was merged to the branch mainline in revision 15.
  • Revision ID: james.westby@ubuntu.com-20070117145235-7gaj253qxi5wiq16
Tags: upstream-2.5.0
ImportĀ upstreamĀ versionĀ 2.5.0

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)