1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 import base64
22 import time, random
23 import urlparse
24 import hmac
25 import hashlib
26 from scapi.util import escape
27 import logging
28
29
30 USE_DOUBLE_ESCAPE_HACK = True
31 """
32 There seems to be an uncertainty on the way
33 parameters are to be escaped. For now, this
34 variable switches between two escaping mechanisms.
35
36 If True, the passed parameters - GET or POST - are
37 escaped *twice*.
38 """
39
40 logger = logging.getLogger(__name__)
41
43
44 FORBIDDEN = ['realm', 'oauth_signature']
45
48
49 - def build_signature(self, request, parameters, consumer_secret, token_secret, oauth_parameters):
50 if logger.level == logging.DEBUG:
51 logger.debug("request: %r", request)
52 logger.debug("parameters: %r", parameters)
53 logger.debug("consumer_secret: %r", consumer_secret)
54 logger.debug("token_secret: %r", token_secret)
55 logger.debug("oauth_parameters: %r", oauth_parameters)
56
57
58 temp = {}
59 temp.update(oauth_parameters)
60 for p in self.FORBIDDEN:
61 if p in temp:
62 del temp[p]
63 if parameters is not None:
64 temp.update(parameters)
65 sig = (
66 escape(self.get_normalized_http_method(request)),
67 escape(self.get_normalized_http_url(request)),
68 self.get_normalized_parameters(temp),
69 )
70
71 key = '%s&' % consumer_secret
72 if token_secret is not None:
73 key += token_secret
74 raw = '&'.join(sig)
75 logger.debug("raw basestring: %s", raw)
76 logger.debug("key: %s", key)
77
78 hashed = hmac.new(key, raw, hashlib.sha1)
79
80 signature = escape(base64.b64encode(hashed.digest()))
81 return signature
82
83
85 return request.get_method().upper()
86
87
88
90 url = request.get_full_url()
91 parts = urlparse.urlparse(url)
92 url_string = '%s://%s%s' % (parts.scheme, parts.netloc, parts.path)
93 return url_string
94
95
97 if params is None:
98 params = {}
99 try:
100
101 del params['oauth_signature']
102 except:
103 pass
104 key_values = []
105
106 for key, values in params.iteritems():
107 if isinstance(values, file):
108 continue
109 if isinstance(values, (int, long, float)):
110 values = str(values)
111 if isinstance(values, (list, tuple)):
112 values = [str(v) for v in values]
113 if isinstance(values, basestring):
114 values = [values]
115 if USE_DOUBLE_ESCAPE_HACK and not key.startswith("ouath"):
116 key = escape(key)
117 for v in values:
118 v = v.encode("utf-8")
119 key = key.encode("utf-8")
120 if USE_DOUBLE_ESCAPE_HACK and not key.startswith("oauth"):
121
122
123
124 v = escape(v)
125 key_values.append(escape("%s=%s" % (key, v)))
126
127 key_values.sort()
128
129 return escape('&').join(key_values)
130
131
133 OAUTH_API_VERSION = '1.0'
134 AUTHORIZATION_HEADER = "Authorization"
135
137 self._consumer, self._token, self._secret = consumer, token, secret
138 self._consumer_secret = consumer_secret
139 self._signature_method = signature_method
140 random.seed()
141
142
143 - def augment_request(self, req, parameters, use_multipart=False, oauth_callback=None, oauth_verifier=None):
144 oauth_parameters = {
145 'oauth_consumer_key': self._consumer,
146 'oauth_timestamp': self.generate_timestamp(),
147 'oauth_nonce': self.generate_nonce(),
148 'oauth_version': self.OAUTH_API_VERSION,
149 'oauth_signature_method' : self._signature_method.get_name(),
150
151 }
152 if self._token is not None:
153 oauth_parameters['oauth_token'] = self._token
154
155 if oauth_callback is not None:
156 oauth_parameters['oauth_callback'] = oauth_callback
157
158 if oauth_verifier is not None:
159 oauth_parameters['oauth_verifier'] = oauth_verifier
160
161
162
163 if use_multipart:
164 parameters = None
165
166 oauth_parameters['oauth_signature'] = self._signature_method.build_signature(req,
167 parameters,
168 self._consumer_secret,
169 self._secret,
170 oauth_parameters)
171 def to_header(d):
172 return ",".join('%s="%s"' % (key, value) for key, value in sorted(oauth_parameters.items()))
173
174 req.add_header(self.AUTHORIZATION_HEADER, "OAuth %s" % to_header(oauth_parameters))
175
177 return int(time.time())
178
180 return ''.join(str(random.randint(0, 9)) for i in range(length))
181
182
184
185 - def __init__(self, user, password, consumer, consumer_secret):
186 self._base64string = base64.encodestring("%s:%s" % (user, password))[:-1]
187 self._x_auth_header = 'OAuth oauth_consumer_key="%s" oauth_consumer_secret="%s"' % (consumer, consumer_secret)
188
190 req.add_header("Authorization", "Basic %s" % self._base64string)
191 req.add_header("X-Authorization", self._x_auth_header)
192