summaryrefslogtreecommitdiff
path: root/clients/XMLRPCAuth.py
blob: 40fd3254da1698b1c81bfd32215dc4d8ab9dc354 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
#
#	XMLRPC Client Basic HTTP Authentication Transport
#	by Troy Melhase <troy at gci.net>
#	as per http://mail.python.org/pipermail/python-list/2003-June/208575.html
#
#	Changes and additions by Smári McCarthy <smari@fabfolk.com>
#
#	Usage:
#>>> srv = XMLRPCAuthenticatedServer("http://host/xmlrpc/path", username="joe", password="secretpassword")
#
#	Traditional usage example:
#>>> auth_tran = BasicHTTPAuthTransport()
#>>> auth_tran.credentials = ("joe", "secretpassword")
#>>> srv = xmlrpclib.Server("http://host/xmlrpc/path", transport=auth_tran)
#
#

import base64
import xmlrpclib


class XMLRPCAuthenticatedServer(xmlrpclib.Server):
	def __init__(self, path, username=None, password=None, encoding=None, verbose=0, allow_none=0, use_datetime=0):
		self.auth_tran = BasicHTTPAuthTransport()
		self.auth_tran.credentials = (username, password)
		xmlrpclib.Server.__init__(self, path, transport=self.auth_tran, encoding=encoding, verbose=verbose, allow_none=allow_none, use_datetime=use_datetime)



class BasicHTTPAuthTransport(xmlrpclib.Transport):
    """ xmlrpclib.Transport subtype that sends Basic HTTP Authorization

        This subclass recognizes xmlrpclib versions '1.0.0' and '0.9.8' and
        adjusts accordingly during class definition.  Using any other
        version of xmlrpclib will raise an exception.
    """
    user_agent = '*py*'
    credentials = ()

    def send_basic_auth(self, connection):
        """ Include HTTP Basic Authorization data in a header """
        auth = base64.encodestring('%s:%s' % self.credentials).strip()
        auth = 'Basic %s' % (auth, )
        connection.putheader('Authorization', auth)

    if xmlrpclib.__version__ in ('1.0.0', '1.0.1'):
        ## override the send_host hook to also send basic auth
        def send_host(self, connection, host):
            xmlrpclib.Transport.send_host(self, connection, host)
            self.send_basic_auth(connection)

    elif xmlrpclib.__version__ == '0.9.8':
        ## override the request method to send all 
        ## the normal and plus basic auth
        def request(self, host, handler, request_body):
            import httplib
            h = httplib.HTTP(host)
            h.putrequest("POST", handler)
            h.putheader("Host", host)
            h.putheader("User-Agent", self.user_agent)
            h.putheader("Content-Type", "text/xml")
            h.putheader("Content-Length", str(len(request_body)))
            self.send_basic_auth(h)
            h.endheaders()

            if request_body:
                h.send(request_body)
            errcode, errmsg, headers = h.getreply()
            if errcode != 200:
                raise xmlrpclib.ProtocolError(host + handler, errcode, \
                    errmsg, headers)
            return self.parse_response(h.getfile())

    else:
        ## don't know what to redefine
        raise TypeError("Unrecognized xmlrpclib version: %s" % \
             (xmlrpclib.__version__, ))