def request(self, method, url, header_auth=False, realm='', **req_kwargs): ''' A loose wrapper around Requests' :class:`~requests.sessions.Session` which injects OAuth 1.0/a parameters. :param method: A string representation of the HTTP method to be used. :type method: str :param url: The resource to be requested. :type url: str :param header_auth: Authentication via header, defaults to `False.` :type header_auth: bool :param realm: The auth header realm, defaults to ``""``. :type realm: str :param \*\*req_kwargs: Keyworded args to be passed down to Requests. :type \*\*req_kwargs: dict ''' req_kwargs.setdefault('headers', {}) req_kwargs['headers'] = CaseInsensitiveDict(req_kwargs['headers']) url = self._set_url(url) entity_method = method.upper() in ENTITY_METHODS if entity_method: req_kwargs['headers'].setdefault('Content-Type', FORM_URLENCODED) form_urlencoded = \ req_kwargs['headers'].get('Content-Type') == FORM_URLENCODED # inline string conversion if is_basestring(req_kwargs.get('params')): req_kwargs['params'] = dict(parse_qsl(req_kwargs['params'])) if is_basestring(req_kwargs.get('data')) and form_urlencoded: req_kwargs['data'] = dict(parse_qsl(req_kwargs['data'])) req_kwargs.setdefault('timeout', OAUTH1_DEFAULT_TIMEOUT) oauth_params = self._get_oauth_params(req_kwargs) # ensure we always create new instances of dictionary elements for key, value in req_kwargs.items(): if isinstance(value, dict): req_kwargs[key] = deepcopy(value) # sign the request oauth_params['oauth_signature'] = \ self.signature.sign(self.consumer_secret, self.access_token_secret, method, url, oauth_params, req_kwargs) if header_auth and not 'oauth_signature' in \ req_kwargs['headers'].get('Authorization', ''): header = self._get_auth_header(oauth_params, realm) req_kwargs['headers'].update({'Authorization': header}) elif entity_method and not 'oauth_signature' in \ (req_kwargs.get('data') or {}): req_kwargs['data'] = req_kwargs.get('data') or {} # If we have a urlencoded entity-body we should pass the OAuth # parameters on this body. However, if we do not, then we need to # pass these over the request URI, i.e. on params. # # See: # # http://tools.ietf.org/html/rfc5849#section-3.5.2 # # and: # # http://tools.ietf.org/html/rfc5849#section-3.5.3 if form_urlencoded: req_kwargs['data'].update(oauth_params) else: req_kwargs.setdefault('params', {}) req_kwargs['params'].update(oauth_params) elif not 'oauth_signature' in url: req_kwargs.setdefault('params', {}) req_kwargs['params'].update(oauth_params) return super(OAuth1Session, self).request(method, url, **req_kwargs)
def test_rauth_case_insensitive_dict(self): d = CaseInsensitiveDict() d.setdefault('Content-Type', 'foo') d.update({'content-type': 'bar'}) self.assertEqual(1, len(d.keys())) self.assertIn('content-type', d.keys()) self.assertEqual({'content-type': 'bar'}, d) d.update({'CONTENT-TYPE': 'baz'}) self.assertEqual(1, len(d.keys())) self.assertIn('content-type', d.keys()) self.assertEqual({'content-type': 'baz'}, d)
def test_rauth_case_insensitive_dict_list_of_tuples(self): d = CaseInsensitiveDict([('Content-Type', 'foo')]) self.assertEqual(d, {'content-type': 'foo'})
def fake_request(self, method, url, mock_request, mock_random, mock_time, mock_sig, header_auth=False, realm='', **kwargs): fake_random = 1 fake_time = 1 fake_sig = 'foo' fake_sig_meth = 'HMAC-SHA1' fake_nonce = sha1(str(fake_random)).hexdigest() mock_request.return_value = self.response mock_random.return_value = fake_random mock_time.return_value = fake_time mock_sig.return_value = fake_sig method = method url = self.session._set_url(url) service = OAuth1Service(self.consumer_key, self.consumer_secret, name='service', request_token_url=self.request_token_url, access_token_url=self.access_token_url, authorize_url=self.authorize_url, base_url=self.base_url) session = service.get_session( (self.access_token, self.access_token_secret)) r = session.request(method, url, header_auth=header_auth, realm=realm, **deepcopy(kwargs)) kwargs.setdefault('headers', {}) kwargs['headers'] = CaseInsensitiveDict(kwargs['headers']) entity_method = method.upper() in ENTITY_METHODS if entity_method: kwargs['headers'].setdefault('Content-Type', FORM_URLENCODED) form_urlencoded = \ kwargs['headers'].get('Content-Type') == FORM_URLENCODED if isinstance(kwargs.get('params'), basestring): kwargs['params'] = dict(parse_qsl(kwargs['params'])) if isinstance(kwargs.get('data'), basestring) and form_urlencoded: kwargs['data'] = dict(parse_qsl(kwargs['data'])) oauth_params = { 'oauth_consumer_key': session.consumer_key, 'oauth_nonce': fake_nonce, 'oauth_signature_method': fake_sig_meth, 'oauth_timestamp': fake_time, 'oauth_token': self.access_token, 'oauth_version': session.VERSION, 'oauth_signature': fake_sig } if header_auth: headers = { 'Authorization': self.fake_get_auth_header(oauth_params, realm=realm) } kwargs['headers'].update(headers) elif entity_method: kwargs['data'] = kwargs.get('data') or {} if form_urlencoded: kwargs['data'].update(oauth_params) else: kwargs.setdefault('params', {}) kwargs['params'].update(oauth_params) else: kwargs.setdefault('params', {}) kwargs['params'].update(**oauth_params) mock_request.assert_called_with(method, url, timeout=OAUTH1_DEFAULT_TIMEOUT, **kwargs) return r