1
2
3
4
5
6 import base64
7 import os
8 import re
9 import urlparse
10 try:
11 from urlparse import parse_qsl
12 except ImportError:
13 from cgi import parse_qsl
14 from urlparse import urlunparse
15
16 from . import __version__
17 from .errors import ProxyError
18 from .http import Request, Unreader
19 from .oauth2 import Consumer, Request, SignatureMethod_HMAC_SHA1,\
20 Token
21 from .sock import send
22 from .util import parse_netloc
23
24
26
29
31 if not hasattr(obj, "on_request") and not hasattr(obj, "on_response"):
32 raise TypeError("%s is not a filter object." % obj.__class__.__name__)
33
34 self.filters.append(obj)
35
37 for i, f in enumerate(self.filters):
38 if obj == f: del self.filters[i]
39
40 - def apply(self, kind, *args):
41 for f in self.filters:
42 try:
43 func = getattr(f, kind)
44 except AttributeError:
45 continue
46 func(*args)
47
49 """ Simple filter to manage basic authentification"""
50
52 self.credentials = (username, password)
53
57
58
59
61 """ Simple proxy filter.
62 This filter find proxy from environment and if it exists it
63 connect to the proxy and modify connection headers.
64 """
65
67 proxy = os.environ.get('https_proxy')
68 if proxy:
69 proxy_uri = urlparse.urlparse(proxy)
70 proxy_auth = _get_proxy_auth()
71 if proxy_auth:
72 proxy_auth = 'Proxy-authorization: %s' % proxy_auth
73 proxy_connect = 'CONNECT %s:%s HTTP/1.0\r\n' % parse_netloc(proxy_uri)
74
75 user_agent = "User-Agent: restkit/%s\r\n" % __version__
76 proxy_pieces = '%s%s%s\r\n' % (proxy_connect, proxy_auth,
77 user_agent)
78
79 send(sck, proxy_pieces)
80 unreader = http.Unreader(sck)
81 resp = http.Request(unreader)
82 body = resp.body.read()
83 if resp.status_int != 200:
84 raise ProxyError("Tunnel connection failed: %d %s" %
85 (resp.status_int, body))
86
87
89 proxy_username = os.environ.get('proxy-username')
90 if not proxy_username:
91 proxy_username = os.environ.get('proxy_username')
92 proxy_password = os.environ.get('proxy-password')
93 if not proxy_password:
94 proxy_password = os.environ.get('proxy_password')
95 if proxy_username:
96 user_auth = base64.encodestring('%s:%s' % (proxy_username,
97 proxy_password))
98 return 'Basic %s\r\n' % (user_auth.strip())
99 else:
100 return ''
101
103 """ validate a consumer agains oauth2.Consumer object """
104 if not hasattr(consumer, "key"):
105 raise ValueError("Invalid consumer.")
106 return consumer
107
109 """ validate a token agains oauth2.Token object """
110 if token is not None and not hasattr(token, "key"):
111 raise ValueError("Invalid token.")
112 return token
113
114
116 """ oauth filter """
117
118 - def __init__(self, path, consumer, token=None, method=None):
119 """ Init OAuthFilter
120
121 :param path: path or regexp. * mean all path on wicth oauth can be
122 applied.
123 :param consumer: oauth consumer, instance of oauth2.Consumer
124 :param token: oauth token, instance of oauth2.Token
125 :param method: oauth signature method
126
127 token and method signature are optionnals. Consumer should be an
128 instance of `oauth2.Consumer`, token an instance of `oauth2.Toke`
129 signature method an instance of `oauth2.SignatureMethod`.
130
131 """
132
133 if path.endswith('*'):
134 self.match = re.compile("%s.*" % path.rsplit('*', 1)[0])
135 else:
136 self.match = re.compile("%s$" % path)
137 self.consumer = validate_consumer(consumer)
138 self.token = validate_token(token)
139 self.method = method or SignatureMethod_HMAC_SHA1()
140
144
146 if not self.on_path(client):
147 return
148
149 params = {}
150 form = False
151 parsed_url = client.parsed_url
152
153 if client.body and client.body is not None:
154 ctype = client.headers.iget('content-ype')
155 if ctype is not None and \
156 ctype.startswith('application/x-www-form-urlencoded'):
157
158 form = True
159 params = dict(parse_qsl(client.body))
160
161
162 params.update(parse_qsl(parsed_url.query))
163
164 raw_url = urlunparse((parsed_url.scheme, parsed_url.netloc,
165 parsed_url.path, '', '', ''))
166
167 oauth_req = Request.from_consumer_and_token(self.consumer,
168 token=self.token, http_method=client.method,
169 http_url=raw_url, parameters=params)
170
171 oauth_req.sign_request(self.method, self.consumer, self.token)
172
173 if form:
174 client.body = oauth_req.to_postdata()
175 client.headers['Content-Length'] = len(client.body)
176 elif client.method in ('GET', 'HEAD'):
177 client.original_url = client.url
178 client.url = oauth_req.to_url()
179 else:
180 oauth_headers = oauth_req.to_header()
181 client.headers.update(oauth_headers)
182