Example #1
0
    def request(self, method, url, bearer_auth=True, **req_kwargs):
        """
        A loose wrapper around Requests' :class:`~requests.sessions.Session`
        which injects OAuth 2.0 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 bearer_auth: Whether to use Bearer Authentication or not,
            defaults to `True`.
        :type bearer_auth: bool
        :param \*\*req_kwargs: Keyworded args to be passed down to Requests.
        :type \*\*req_kwargs: dict
        """
        req_kwargs.setdefault("params", {})

        url = self._set_url(url)

        if is_basestring(req_kwargs["params"]):
            req_kwargs["params"] = dict(parse_qsl(req_kwargs["params"]))

        if bearer_auth and self.access_token is not None:
            bearer_token = "Bearer {token}".format(token=self.access_token)
            bearer_header = {"Authorization": bearer_token}
            req_kwargs.setdefault("headers", {})
            req_kwargs["headers"].update(bearer_header)
        else:
            req_kwargs["params"].update({self.access_token_key: self.access_token})

        req_kwargs.setdefault("timeout", OAUTH2_DEFAULT_TIMEOUT)

        return super(OAuth2Session, self).request(method, url, **req_kwargs)
Example #2
0
 def _get_lowered_d(self, d):
     lowered_d = {}
     for key in d:
         if is_basestring(key):
             lowered_d[key.lower()] = d[key]
         else:  # pragma: no cover
             lowered_d[key] = d[key]
     return lowered_d
Example #3
0
    def sign(self,
             consumer_secret,
             access_token_secret,
             method,
             url,
             oauth_params,
             req_kwargs):
        '''Sign request parameters.

        :param consumer_secret: RSA private key.
        :type consumer_secret: str or RSA._RSAobj
        :param access_token_secret: Unused.
        :type access_token_secret: str
        :param method: The method of this particular request.
        :type method: str
        :param url: The URL of this particular request.
        :type url: str
        :param oauth_params: OAuth parameters.
        :type oauth_params: dict
        :param req_kwargs: Keyworded args that will be sent to the request
            method.
        :type req_kwargs: dict
        '''
        url = self._remove_qs(url)

        oauth_params = \
            self._normalize_request_parameters(oauth_params, req_kwargs)
        parameters = map(self._escape, [method, url, oauth_params])

        # build a Signature Base String
        signature_base_string = b'&'.join(parameters)

        # resolve the key
        if is_basestring(consumer_secret):
            consumer_secret = self.RSA.importKey(consumer_secret)
        if not isinstance(consumer_secret, self.RSA._RSAobj):
            raise ValueError("invalid consumer_secret")

        # hash the string with RSA-SHA1
        s = self.PKCS1_v1_5.new(consumer_secret)
        # PyCrypto SHA.new requires an encoded byte string
        h = self.SHA.new(signature_base_string)
        hashed = s.sign(h)

        # return the signature
        return base64.b64encode(hashed)
Example #4
0
    def request(self, method, url, user_id=None, hash_meth="sha1", **req_kwargs):
        """
        A loose wrapper around Requests' :class:`~requests.sessions.Session`
        which injects Ofly 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 hash_meth: The hash method to use for signing, defaults to
            "sha1".
        :type hash_meth: str
        :param user_id: The oflyUserid, defaults to `None`.
        :type user_id: str
        :param \*\*req_kwargs: Keyworded args to be passed down to Requests.
        :type \*\*req_kwargs: dict
        """
        req_kwargs.setdefault("params", {})
        req_kwargs.setdefault("timeout", OFLY_DEFAULT_TIMEOUT)

        url = self._set_url(url)

        user_id = user_id or self.user_id
        assert user_id is not None, "An oflyUserid must be provided as `user_id`."

        if is_basestring(req_kwargs["params"]):
            req_kwargs["params"] = dict(parse_qsl(req_kwargs["params"]))

        req_kwargs["params"].update({"oflyUserid": user_id})

        params = OflySession.sign(url, self.app_id, self.app_secret, hash_meth=hash_meth, **req_kwargs["params"])

        # NOTE: Requests can't seem to handle unicode objects, instead we can
        # encode a string here.
        req_kwargs["params"] = params
        if not isinstance(req_kwargs["params"], bytes):
            req_kwargs["params"] = req_kwargs["params"].encode("utf-8")

        return super(OflySession, self).request(method, url, **req_kwargs)
Example #5
0
    def setdefault(self, key, default):
        if is_basestring(key):
            key = key.lower()

        super(CaseInsensitiveDict, self).setdefault(key, default)
Example #6
0
    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)