Пример #1
0
def extractRequestURL(request):
    # I am not sure why there isn't a thing that gets me the original
    # URI in the HTTP header and has to reconstruct all of this from
    # broken up pieces.

    actual_url = request.get('ACTUAL_URL', None)
    query_string = request.get('QUERY_STRING', None)
    
    if actual_url:
        result = actual_url
        if query_string:
            # XXX this is _seriously_ a pita.  For some reason in some
            # circumstances we are not getting back the original encoded
            # values that we used to sign the request.  This rectifies
            # that.
            try:
                urldecode(query_string)
            except ValueError:
                query_string = quote_plus(query_string, safe='=&;%+~')
            result += '?' + query_string
    else:
        # fallback.
        result = request.getURL()

    return result
Пример #2
0
    def refresh_token(self, token_url, refresh_token=None, body='', auth=None,
                      timeout=None, headers=None, verify=True, proxies=None, post_params=None, **kwargs):
        """Fetch a new access token using a refresh token.

        :param token_url: The token endpoint, must be HTTPS.
        :param refresh_token: The refresh_token to use.
        :param body: Optional application/x-www-form-urlencoded body to add the
                     include in the token request. Prefer kwargs over body.
        :param auth: An auth tuple or method as accepted by requests.
        :param timeout: Timeout of the request in seconds.
        :param verify: Verify SSL certificate.
        :param kwargs: Extra parameters to include in the token request.
        :param post_params: If True, sends body as url query string.
        :return: A token dict
        """
        if not token_url:
            raise ValueError('No token endpoint set for auto_refresh.')

        if not is_secure_transport(token_url):
            raise InsecureTransportError()

        refresh_token = refresh_token or self.token.get('refresh_token')

        log.debug('Adding auto refresh key word arguments %s.',
                  self.auto_refresh_kwargs)
        kwargs.update(self.auto_refresh_kwargs)
        body = self._client.prepare_refresh_body(body=body,
                refresh_token=refresh_token, scope=self.scope, **kwargs)
        log.debug('Prepared refresh token request body %s', body)

        if headers is None:
            headers = {
                'Accept': 'application/json',
                'Content-Type': (
                    'application/x-www-form-urlencoded;charset=UTF-8'
                ),
            }
        if not post_params:
            r = self.post(token_url, data=dict(urldecode(body)), auth=auth,
            timeout=timeout, headers=headers, verify=verify, withhold_token=True, proxies=proxies)
        else:
            r = self.post(token_url, data=params(urldecode(body)), auth=auth,
            timeout=timeout, headers=headers, verify=verify, withhold_token=True, proxies=proxies)
        log.debug('Request to refresh token completed with status %s.',
                  r.status_code)
        log.debug('Response headers were %s and content %s.',
                  r.headers, r.text)
        log.debug('Invoking %d token response hooks.',
                  len(self.compliance_hook['refresh_token_response']))
        for hook in self.compliance_hook['refresh_token_response']:
            log.debug('Invoking hook %s.', hook)
            r = hook(r)

        self.token = self._client.parse_request_body_response(r.text, scope=self.scope)
        if not 'refresh_token' in self.token:
            log.debug('No new refresh token given. Re-using old.')
            self.token['refresh_token'] = refresh_token
        return self.token
Пример #3
0
def callback():
    """Retrieving an access token.
    After you've redirected from our provider to your callback URL,
    you'll have access to the auth code in the redirect URL, which
    we'll be using to get an access token.
    """

    client = WebApplicationClient(client_id=CLIENT_ID)
    # Parse the response URI after the callback, with the same state we initially sent
    client.parse_request_uri_response(request.url,
                                      state=session["oauth_state"])
    # Now we've access to the auth code
    code = client.code

    # Prepare request body to get the access token
    body = client.prepare_request_body(
        code=code,
        redirect_uri=REDIRECT_URI,
        include_client_id=False,
        scope=scope,
    )

    # Basic HTTP auth by providing your client credentials
    auth = requests.auth.HTTPBasicAuth(CLIENT_ID, CLIENT_SECRET)

    # Making a post request to the TOKEN_URL endpoint
    r = requests.post(TOKEN_URL, data=dict(urldecode(body)), auth=auth)

    # Parse the response to get the token and store it in session
    token = client.parse_request_body_response(r.text, scope=scope)
    session["access_token"] = token

    return redirect("/home")
Пример #4
0
    def __call__(self, response):
        """Hook is required to be callable"""

        req_params = {k: v for k, v in urldecode(response.request.body)}
        code = req_params["code"]  # this is the unique param
        self.mapping[code] = response.json()
        return response
Пример #5
0
    def parse_authorization_response(self, url: str) -> Dict[str, str]:
        token = dict(urldecode(urlparse(url).query))

        self.oauth_client.resource_owner_key = token['oauth_token']
        self.oauth_client.verifier = token['oauth_verifier']

        return token
Пример #6
0
    async def fetch_access_token(self, verifier: Optional[str] = None) -> Dict[str, str]:
        if verifier:
            self.oauth_client.verifier = verifier
        if not getattr(self.oauth_client, 'verifier', None):
            raise ValueError('No client verifier set.')  # TODO: implement own exceptions

        log.debug(f'Fetching access token...')
        _, signed_headers, _ = self.oauth_client.sign(self.access_token_url, 'POST')
        log.debug(f'Signed headers: {signed_headers}')

        resp = await self.session.post(self.access_token_url, headers=signed_headers)
        log.debug(f'Response: {resp.status} {resp.reason}')
        log.debug(f'To: {resp.method} {resp.real_url.human_repr()}')
        log.debug(f'Requested as: {resp.request_info.method} {resp.request_info.real_url.human_repr()}')
        log.debug(f'Request headers: {resp.request_info.headers}')

        token_raw = await resp.text()
        log.debug(f'Token response: {token_raw}')
        token = dict(urldecode(token_raw))

        self.oauth_client.resource_owner_key = token['oauth_token']
        self.oauth_client.resource_owner_secret = token['oauth_token_secret']

        # Unset verifier
        self.oauth_client.verifier = None

        return token
Пример #7
0
    def refresh_token(self, token_url, refresh_token=None, body='', **kwargs):
        """Fetch a new access token using a refresh token.

        :param token_url: The token endpoint, must be HTTPS.
        :param refresh_token: The refresh_token to use.
        :param body: Optional application/x-www-form-urlencoded body to add the
                     include in the token request. Prefer kwargs over body.
        :param kwargs: Extra parameters to include in the token request.
        :return: A token dict
        """
        if not token_url:
            raise ValueError('No token endpoint set for auto_refresh.')

        if not token_url.startswith('https://'):
            raise InsecureTransportError()

        # Need to nullify token to prevent it from being added to the request
        refresh_token = refresh_token or self.token.get('refresh_token')
        self.token = {}

        kwargs.update(self.auto_refresh_kwargs)
        body = self._client.prepare_refresh_body(body=body,
                refresh_token=refresh_token, scope=self.scope, **kwargs)
        r = self.post(token_url, data=dict(urldecode(body)))
        self.token = self._client.parse_request_body_response(r.text, scope=self.scope)
        if not 'refresh_token' in self.token:
            self.token['refresh_token'] = refresh_token
        return self.token
Пример #8
0
    def fetch_token(self, token_url, code=None, authorization_response=None,
            body='', username=None, password=None, **kwargs):
        """Generic method for fetching an access token from the token endpoint.

        If you are using the MobileApplicationClient you will want to use
        token_from_fragment instead of fetch_token.

        :param token_url: Token endpoint URL, must use HTTPS.
        :param code: Authorization code (used by WebApplicationClients).
        :param authorization_response: Authorization response URL, the callback
                                       URL of the request back to you. Used by
                                       WebApplicationClients instead of code.
        :param body: Optional application/x-www-form-urlencoded body to add the
                     include in the token request. Prefer kwargs over body.
        :param username: Username used by LegacyApplicationClients.
        :param password: Password used by LegacyApplicationClients.
        :param kwargs: Extra parameters to include in the token request.
        :return: A token dict
        """
        if not token_url.startswith('https://'):
            raise InsecureTransportError()

        if not code and authorization_response:
            self._client.parse_request_uri_response(authorization_response,
                    state=self.state)
            code = self._client.code
        body = self._client.prepare_request_body(code=code, body=body,
                redirect_uri=self.redirect_uri, username=username,
                password=password, **kwargs)
        # (ib-lundgren) All known, to me, token requests use POST.
        r = self.post(token_url, data=dict(urldecode(body)),
            headers={'Accept': 'application/json'})
        self._client.parse_request_body_response(r.text, scope=self.scope)
        self.token = self._client.token
        return self.token
Пример #9
0
    def refresh_token(self, token_url, refresh_token=None, body='', **kwargs):
        """Fetch a new access token using a refresh token.

        :param token_url: The token endpoint, must be HTTPS.
        :param refresh_token: The refresh_token to use.
        :param body: Optional application/x-www-form-urlencoded body to add the
                     include in the token request. Prefer kwargs over body.
        :param kwargs: Extra parameters to include in the token request.
        :return: A token dict
        """
        if not token_url:
            raise ValueError('No token endpoint set for auto_refresh.')

        if not token_url.startswith('https://'):
            raise InsecureTransportError()

        # Need to nullify token to prevent it from being added to the request
        refresh_token = refresh_token or self.token.get('refresh_token')
        self.token = {}

        kwargs.update(self.auto_refresh_kwargs)
        body = self._client.prepare_refresh_body(body=body,
                                                 refresh_token=refresh_token,
                                                 scope=self.scope,
                                                 **kwargs)
        r = self.post(token_url, data=dict(urldecode(body)))
        self.token = self._client.parse_request_body_response(r.text,
                                                              scope=self.scope)
        if not 'refresh_token' in self.token:
            self.token['refresh_token'] = refresh_token
        return self.token
Пример #10
0
    def refresh_token(self):
        refresh_token = self.token.get('refresh_token')

        body = self.oauth_client.prepare_refresh_body(
            body='',
            refresh_token=refresh_token,
            scope=self.scope,
            client_id=self.client_id,
            client_secret=self.client_secret)

        response = self.request(
            'POST',
            self.token_url,
            headers={
                'Accept': 'application/json',
                'Content-Type':
                'application/x-www-form-urlencoded;charset=UTF-8',
            },
            data=dict(urldecode(body)),
            auth=httpx.BasicAuth(self.client_id, self.client_secret),
            withhold_token=True)

        self.token = self.oauth_client.parse_request_body_response(
            response.text, scope=self.scope)
        if 'refresh_token' not in self.token:
            self.token['refresh_token'] = refresh_token

        return self.token
Пример #11
0
    def refresh_token(self, token_url, refresh_token=None, body='', auth=None,
                      timeout=None, headers=None, verify=True, **kwargs):
        """Fetch a new access token using a refresh token.

        :param token_url: The token endpoint, must be HTTPS.
        :param refresh_token: The refresh_token to use.
        :param body: Optional application/x-www-form-urlencoded body to add the
                     include in the token request. Prefer kwargs over body.
        :param auth: An auth tuple or method as accepted by requests.
        :param timeout: Timeout of the request in seconds.
        :param verify: Verify SSL certificate.
        :param kwargs: Extra parameters to include in the token request.
        :return: A token dict
        """
        if not token_url:
            raise ValueError('No token endpoint set for auto_refresh.')

        if not is_secure_transport(token_url):
            raise InsecureTransportError()

        # Need to nullify token to prevent it from being added to the request
        refresh_token = refresh_token or self.token.get('refresh_token')
        self.token = {}

        log.debug('Adding auto refresh key word arguments %s.',
                  self.auto_refresh_kwargs)
        kwargs.update(self.auto_refresh_kwargs)
        body = self._client.prepare_refresh_body(body=body,
                refresh_token=refresh_token, scope=self.scope, **kwargs)
        log.debug('Prepared refresh token request body %s', body)

        if headers is None:
            headers = {
                'Accept': 'application/json',
                'Content-Type': (
                    'application/x-www-form-urlencoded;charset=UTF-8'
                ),
            }

        r = self.post(token_url, data=dict(urldecode(body)), auth=auth,
                      timeout=timeout, headers=headers, verify=verify)
        log.debug('Request to refresh token completed with status %s.',
                  r.status_code)
        log.debug('Response headers were %s and content %s.',
                  r.headers, r.text)
        log.debug('Invoking %d token response hooks.',
                  len(self.compliance_hook['refresh_token_response']))

        r.raise_for_status()

        for hook in self.compliance_hook['refresh_token_response']:
            log.debug('Invoking hook %s.', hook)
            r = hook(r)

        self.token = self._client.parse_request_body_response(r.text, scope=self.scope)
        if not 'refresh_token' in self.token:
            log.debug('No new refresh token given. Re-using old.')
            self.token['refresh_token'] = refresh_token
        return self.token
Пример #12
0
 def _compliance_fix(r):
     token = dict(urldecode(r.text))
     expires = token.get('expires')
     if expires is not None:
         token['expires_in'] = expires
     token['token_type'] = 'Bearer'
     r._content = dumps(token)
     return r
Пример #13
0
 def _compliance_fix(r):
     token = dict(urldecode(r.text))
     expires = token.get('expires')
     if expires is not None:
         token['expires_in'] = expires
     token['token_type'] = 'Bearer'
     r._content = dumps(token)
     return r
Пример #14
0
    def _fetch_token(self, url):
        request = self.get(url)
        if(not(isinstance(request,dict) and request.has_key('error'))):
            token = dict(urldecode(request))
            self._populate_attributes(token)
            return token

        return request
Пример #15
0
 def _compliance_fix(r):
     token = dict(urldecode(r.text))
     expires = token.get("expires")
     if expires is not None:
         token["expires_in"] = expires
     token["token_type"] = "Bearer"
     r._content = dumps(token)
     return r
Пример #16
0
    def fetch_token(
        self,
        token_url,
        code=None,
        authorization_response=None,
        body="",
        auth=None,
        username=None,
        password=None,
        **kwargs
    ):
        """Generic method for fetching an access token from the token endpoint.

        If you are using the MobileApplicationClient you will want to use
        token_from_fragment instead of fetch_token.

        :param token_url: Token endpoint URL, must use HTTPS.
        :param code: Authorization code (used by WebApplicationClients).
        :param authorization_response: Authorization response URL, the callback
                                       URL of the request back to you. Used by
                                       WebApplicationClients instead of code.
        :param body: Optional application/x-www-form-urlencoded body to add the
                     include in the token request. Prefer kwargs over body.
        :param auth: An auth tuple or method as accepted by requests.
        :param username: Username used by LegacyApplicationClients.
        :param password: Password used by LegacyApplicationClients.
        :param kwargs: Extra parameters to include in the token request.
        :return: A token dict
        """
        if not is_secure_transport(token_url):
            raise InsecureTransportError()

        if not code and authorization_response:
            self._client.parse_request_uri_response(authorization_response, state=self._state)
            code = self._client.code
        elif not code and isinstance(self._client, WebApplicationClient):
            code = self._client.code
            if not code:
                raise ValueError("Please supply either code or " "authorization_code parameters.")

        body = self._client.prepare_request_body(
            code=code, body=body, redirect_uri=self.redirect_uri, username=username, password=password, **kwargs
        )
        # (ib-lundgren) All known, to me, token requests use POST.
        r = self.post(token_url, data=dict(urldecode(body)), headers={"Accept": "application/json"}, auth=auth)
        log.debug("Prepared fetch token request body %s", body)
        log.debug("Request to fetch token completed with status %s.", r.status_code)
        log.debug("Response headers were %s and content %s.", r.headers, r.text)
        log.debug("Invoking %d token response hooks.", len(self.compliance_hook["access_token_response"]))
        for hook in self.compliance_hook["access_token_response"]:
            log.debug("Invoking hook %s.", hook)
            r = hook(r)

        self._client.parse_request_body_response(r.text, scope=self.scope)
        self.token = self._client.token
        log.debug("Obtained token %s.", self.token)
        return self.token
Пример #17
0
 def test_urldecode(self):
     self.assertItemsEqual(urldecode(''), [])
     self.assertItemsEqual(urldecode('='), [('', '')])
     self.assertItemsEqual(urldecode('%20'), [(' ', '')])
     self.assertItemsEqual(urldecode('+'), [(' ', '')])
     self.assertItemsEqual(urldecode('c2'), [('c2', '')])
     self.assertItemsEqual(urldecode('c2='), [('c2', '')])
     self.assertItemsEqual(urldecode('foo=bar'), [('foo', 'bar')])
     self.assertItemsEqual(urldecode('foo_%20~=.bar-'),
                           [('foo_ ~', '.bar-')])
     self.assertItemsEqual(urldecode('foo=1,2,3'), [('foo', '1,2,3')])
     self.assertItemsEqual(urldecode('foo=bar.*'), [('foo', 'bar.*')])
     self.assertRaises(ValueError, urldecode, 'foo bar')
     self.assertRaises(ValueError, urldecode, '?')
     self.assertRaises(ValueError, urldecode, '%R')
     self.assertRaises(ValueError, urldecode, '%RA')
     self.assertRaises(ValueError, urldecode, '%AR')
     self.assertRaises(ValueError, urldecode, '%RR')
Пример #18
0
    def get_access_token(self, callback_uri, request_token):
        """
        Returns access token

        Third and last step of OAuth1

        """
        verifier = dict(urldecode(urlparse.urlparse(callback_uri).query))
        self.client.verifier = verifier.get('oauth_verifier')
        self.client.resource_owner_key = request_token.get('oauth_token')
        self.client.resource_owner_secret = request_token.get('oauth_token_secret')
        uri, headers, body = self.client.sign(self.access_token_url)
        response = requests.request(self.token_method, uri, headers=headers, data=body)
        self.client.verifier = None
        response.raise_for_status()
        token = dict(urldecode(response.text))
        self.set_token(token)
        return self.normalize_token_data(token)
Пример #19
0
 def test_urldecode(self):
     self.assertItemsEqual(urldecode(''), [])
     self.assertItemsEqual(urldecode('='), [('', '')])
     self.assertItemsEqual(urldecode('%20'), [(' ', '')])
     self.assertItemsEqual(urldecode('+'), [(' ', '')])
     self.assertItemsEqual(urldecode('c2'), [('c2', '')])
     self.assertItemsEqual(urldecode('c2='), [('c2', '')])
     self.assertItemsEqual(urldecode('foo=bar'), [('foo', 'bar')])
     self.assertItemsEqual(urldecode('foo_%20~=.bar-'),
                           [('foo_ ~', '.bar-')])
     self.assertItemsEqual(urldecode('foo=1,2,3'), [('foo', '1,2,3')])
     self.assertItemsEqual(urldecode('foo=bar.*'), [('foo', 'bar.*')])
     self.assertRaises(ValueError, urldecode, 'foo bar')
     self.assertRaises(ValueError, urldecode, '?')
     self.assertRaises(ValueError, urldecode, '%R')
     self.assertRaises(ValueError, urldecode, '%RA')
     self.assertRaises(ValueError, urldecode, '%AR')
     self.assertRaises(ValueError, urldecode, '%RR')
Пример #20
0
 def sign_post_parameters(self, url=None):
     client = Client(self.service.consumer_key,
         client_secret=self.service.consumer_secret,
         signature_method=SIGNATURE_HMAC,
         signature_type=SIGNATURE_TYPE_BODY)
     uri, headers, body = client.sign(url or self.service.url,
         http_method="POST",
         body=self.parameters,
         headers={"Content-Type": "application/x-www-form-urlencoded"})
     return urldecode(body)
Пример #21
0
 def sign_post_parameters(self, url=None):
     client = Client(self.service.consumer_key,
         client_secret=self.service.consumer_secret,
         signature_method=SIGNATURE_HMAC,
         signature_type=SIGNATURE_TYPE_BODY)
     uri, headers, body = client.sign(self._get_url(url),
         http_method="POST",
         body=self.parameters,
         headers={"Content-Type": "application/x-www-form-urlencoded"})
     return urldecode(body)
    def refresh_token(
        self, token_url, refresh_token=None, body="", auth=None, timeout=None, headers=None, verify=True, **kwargs
    ):
        """Fetch a new access token using a refresh token.

        :param token_url: The token endpoint, must be HTTPS.
        :param refresh_token: The refresh_token to use.
        :param body: Optional application/x-www-form-urlencoded body to add the
                     include in the token request. Prefer kwargs over body.
        :param auth: An auth tuple or method as accepted by requests.
        :param timeout: Timeout of the request in seconds.
        :param verify: Verify SSL certificate.
        :param kwargs: Extra parameters to include in the token request.
        :return: A token dict
        """
        if not token_url:
            raise ValueError("No token endpoint set for auto_refresh.")

        if not is_secure_transport(token_url):
            raise InsecureTransportError()

        refresh_token = refresh_token or self.token.get("refresh_token")

        log.debug("Adding auto refresh key word arguments %s.", self.auto_refresh_kwargs)
        kwargs.update(self.auto_refresh_kwargs)
        body = self._client.prepare_refresh_body(body=body, refresh_token=refresh_token, scope=self.scope, **kwargs)
        log.debug("Prepared refresh token request body %s", body)

        if headers is None:
            headers = {
                "Accept": "application/json",
                "Content-Type": ("application/x-www-form-urlencoded;charset=UTF-8"),
            }

        r = self.post(
            token_url,
            data=dict(urldecode(body)),
            auth=auth,
            timeout=timeout,
            headers=headers,
            verify=verify,
            withhold_token=True,
        )
        log.debug("Request to refresh token completed with status %s.", r.status_code)
        log.debug("Response headers were %s and content %s.", r.headers, r.text)
        log.debug("Invoking %d token response hooks.", len(self.compliance_hook["refresh_token_response"]))
        for hook in self.compliance_hook["refresh_token_response"]:
            log.debug("Invoking hook %s.", hook)
            r = hook(r)

        self.token = self._client.parse_request_body_response(r.text, scope=self.scope)
        if not "refresh_token" in self.token:
            log.debug("No new refresh token given. Re-using old.")
            self.token["refresh_token"] = refresh_token
        return self.token
Пример #23
0
    def fetch_token(self, token_url, code=None, authorization_response=None,
            body='', auth=None, username=None, password=None, **kwargs):
        """Generic method for fetching an access token from the token endpoint.

        If you are using the MobileApplicationClient you will want to use
        token_from_fragment instead of fetch_token.

        :param token_url: Token endpoint URL, must use HTTPS.
        :param code: Authorization code (used by WebApplicationClients).
        :param authorization_response: Authorization response URL, the callback
                                       URL of the request back to you. Used by
                                       WebApplicationClients instead of code.
        :param body: Optional application/x-www-form-urlencoded body to add the
                     include in the token request. Prefer kwargs over body.
        :param auth: An auth tuple or method as accepted by requests.
        :param username: Username used by LegacyApplicationClients.
        :param password: Password used by LegacyApplicationClients.
        :param kwargs: Extra parameters to include in the token request.
        :return: A token dict
        """
        if not is_secure_transport(token_url):
            raise InsecureTransportError()

        if not code and authorization_response:
            self._client.parse_request_uri_response(authorization_response,
                    state=self._state)
            code = self._client.code
        elif not code and isinstance(self._client, WebApplicationClient):
            code = self._client.code
            if not code:
                raise ValueError('Please supply either code or '
                                 'authorization_code parameters.')


        body = self._client.prepare_request_body(code=code, body=body,
                redirect_uri=self.redirect_uri, username=username,
                password=password, **kwargs)
        # (ib-lundgren) All known, to me, token requests use POST.
        r = self.post(token_url, data=dict(urldecode(body)),
            headers={'Accept': 'application/json'}, auth=auth)
        log.debug('Prepared fetch token request body %s', body)
        log.debug('Request to fetch token completed with status %s.',
                  r.status_code)
        log.debug('Response headers were %s and content %s.',
                  r.headers, r.text)
        log.debug('Invoking %d token response hooks.',
                  len(self.compliance_hook['access_token_response']))
        for hook in self.compliance_hook['access_token_response']:
            log.debug('Invoking hook %s.', hook)
            r = hook(r)

        self._client.parse_request_body_response(r.text, scope=self.scope)
        self.token = self._client.token
        log.debug('Obtained token %s.', self.token)
        return self.token
Пример #24
0
    def _fetch_token(self, url):
        self.writeLog("Function: ---> fetch_token")
        self.writeLog("URL: " + url)
        self.writeLog("METHOD: GET")
        request = self.get(url)
        if(not(isinstance(request,dict) and request.has_key('error'))):
            token = dict(urldecode(request))
            self._populate_attributes(token)
            return token

        return request
Пример #25
0
    def _fetch_token(self, url):
        self.writeLog("Function: ---> fetch_token")
        self.writeLog("URL: " + url)
        self.writeLog("METHOD: GET")
        request = self.get(url)
        if (not (isinstance(request, dict) and request.has_key('error'))):
            token = dict(urldecode(request))
            self._populate_attributes(token)
            return token

        return request
Пример #26
0
    def get_request_token(self, redirect_uri):
        """
        Retrieve oauth token and token secret

        First step of OAuth1

        """
        self.client.callback_uri = redirect_uri
        uri, headers, body = self.client.sign(self.request_token_url)
        response = requests.request(self.token_method, uri, headers=headers, data=body)
        response.raise_for_status()
        return dict(urldecode(response.text))
Пример #27
0
    def _fetch_token(self, url, oauth_session, **request_kwargs):
        r = oauth_session.get(url, **request_kwargs)
        if r.status_code >= 400:
            error = 'Token request failed with code %s, response was \'%s\'.'
            raise TokenRequestDenied(error % (r.status_code, r.text), r)
        try:
            token = dict(urldecode(r.text.strip()))
        except ValueError as e:
            raise ValueError('Unable to decode token from token response. This is commonly caused by an unsuccessful request where a non urlencoded error message is returned. The decoding error was %s' % e)

        oauth_session._populate_attributes(token)
        return token
Пример #28
0
 def _raise_on_bad_post_request(self, request):
     """Raise if invalid POST request received
     """
     if request.http_method.upper() == 'POST':
         query_params = CaseInsensitiveDict(
             dict(urldecode(request.uri_query)))
         for key in query_params:
             if key not in OAUTHLIB_ALLOWED_POST_QUERY_PARAMS:
                 raise InvalidRequestError(
                     request=request,
                     description=(
                         'URL query parameters are not allowed for key {key}'
                         .format(key=key)))
Пример #29
0
    def refresh_token(self,
                      token_url,
                      refresh_token=None,
                      body='',
                      auth=None,
                      **kwargs):
        """Fetch a new access token using a refresh token.

        :param token_url: The token endpoint, must be HTTPS.
        :param refresh_token: The refresh_token to use.
        :param body: Optional application/x-www-form-urlencoded body to add the
                     include in the token request. Prefer kwargs over body.
        :param auth: An auth tuple or method as accepted by requests.
        :param kwargs: Extra parameters to include in the token request.
        :return: A token dict
        """
        if not token_url:
            raise ValueError('No token endpoint set for auto_refresh.')

        if not is_secure_transport(token_url):
            raise InsecureTransportError()

        # Need to nullify token to prevent it from being added to the request
        refresh_token = refresh_token or self.token.get('refresh_token')
        self.token = {}

        log.debug('Adding auto refresh key word arguments %s.',
                  self.auto_refresh_kwargs)
        kwargs.update(self.auto_refresh_kwargs)
        body = self._client.prepare_refresh_body(body=body,
                                                 refresh_token=refresh_token,
                                                 scope=self.scope,
                                                 **kwargs)
        log.debug('Prepared refresh token request body %s', body)
        r = self.post(token_url, data=dict(urldecode(body)), auth=auth)
        log.debug('Request to refresh token completed with status %s.',
                  r.status_code)
        log.debug('Response headers were %s and content %s.', r.headers,
                  r.text)
        log.debug('Invoking %d token response hooks.',
                  len(self.compliance_hook['refresh_token_response']))
        for hook in self.compliance_hook['refresh_token_response']:
            log.debug('Invoking hook %s.', hook)
            r = hook(r)

        self.token = self._client.parse_request_body_response(r.text,
                                                              scope=self.scope)
        if not 'refresh_token' in self.token:
            log.debug('No new refresh token given. Re-using old.')
            self.token['refresh_token'] = refresh_token
        return self.token
        def fake_refresh_check_body_and_connection_params(r, **kwargs):
            if "/refresh" in r.url:
                self.assertEqual('proxy.b', kwargs['proxies']['https'])
                data = dict(urldecode(r.body))
                self.assertDictEqual(
                    {
                        'grant_type': 'refresh_token',
                        'refresh_token': 'sldvafkjw34509s8dfsdf',
                        'extra': 'spam'
                    }, data)

            resp = mock.MagicMock()
            resp.text = json.dumps(self.token)
            return resp
Пример #31
0
    def _compliance_fix(r):
        # Facebook returns urlencoded token, or json on error. Skip
        # compliance fix if we can't urldecode.
        try:
            token = dict(urldecode(r.text))
        except ValueError:
            return r

        expires = token.get('expires')
        if expires is not None:
            token['expires_in'] = expires
        token['token_type'] = 'Bearer'
        r._content = dumps(token)
        return r
Пример #32
0
def get_token():
    # imaginary API call to get token
    flickr = "https://www.flickr.com/services"
    REQUEST_TOKEN_URL = "https://www.flickr.com/services/oauth/request_token"
    AUTHORIZE_URL = "https://www.flickr.com/services/oauth/authorize"
    ACCESS_TOKEN_URL = "https://www.flickr.com/services/oauth/access_token"
    SET_LICENSE_URL = "https://www.flickr.com/services/rest/?method=flickr.photos.licenses.setLicense"

    # Get a request token
    oauth = OAuth1(config.API_KEY, config.SECRET)

    fetch_response = requests.post(REQUEST_TOKEN_URL,
                                   data={'oauth_callback': 'oob'},
                                   auth=oauth)
    token = dict(urldecode(fetch_response.text.strip()))

    # Open a browser at the authentication URL
    authorize_url = "%s?oauth_token=%s&perms=%s" % (
        AUTHORIZE_URL, token['oauth_token'], 'write')
    webbrowser.open_new_tab(authorize_url)

    # Get the verifier code from the user
    verifier = str(input('Verifier code: '))

    # Trade the request token for an access token
    oauth = OAuth1(config.API_KEY,
                   config.API_SECRET,
                   resource_owner_key=token['oauth_token'],
                   resource_owner_secret=token['oauth_token_secret'],
                   verifier=verifier)

    fetch_response = requests.post(url=ACCESS_TOKEN_URL, auth=oauth)
    resp = dict(urldecode(fetch_response.text.strip()))

    save_token_to_file(resp['oauth_token'], resp['oauth_token_secret'])
    return (resp['oauth_token'], resp['oauth_token_secret'])
Пример #33
0
    def fetch_token(self,
                    token_url,
                    code=None,
                    authorization_response=None,
                    body='',
                    username=None,
                    password=None,
                    **kwargs):
        """Generic method for fetching an access token from the token endpoint.

        If you are using the MobileApplicationClient you will want to use
        token_from_fragment instead of fetch_token.

        :param token_url: Token endpoint URL, must use HTTPS.
        :param code: Authorization code (used by WebApplicationClients).
        :param authorization_response: Authorization response URL, the callback
                                       URL of the request back to you. Used by
                                       WebApplicationClients instead of code.
        :param body: Optional application/x-www-form-urlencoded body to add the
                     include in the token request. Prefer kwargs over body.
        :param username: Username used by LegacyApplicationClients.
        :param password: Password used by LegacyApplicationClients.
        :param kwargs: Extra parameters to include in the token request.
        :return: A token dict
        """
        if not token_url.startswith('https://'):
            raise InsecureTransportError()

        if not code and authorization_response:
            self._client.parse_request_uri_response(authorization_response,
                                                    state=self.state)
            code = self._client.code
        body = self._client.prepare_request_body(
            code=code,
            body=body,
            redirect_uri=self.redirect_uri,
            username=username,
            password=password,
            **kwargs)
        # (ib-lundgren) All known, to me, token requests use POST.
        r = self.post(token_url,
                      data=dict(urldecode(body)),
                      headers={'Accept': 'application/json'})
        self._client.parse_request_body_response(r.text, scope=self.scope)
        self.token = self._client.token
        return self.token
Пример #34
0
 def test_access_token_query_params(self):
     client = oauth1.Client(CLIENT_KEY,
                            client_secret=CLIENT_SECRET,
                            signature_type=SIGNATURE_TYPE_QUERY,
                            signature_method=SIGNATURE_PLAINTEXT,
                            resource_owner_key='V7jictT3VGpSG7IAkiY2F9naaQ0bRe',
                            resource_owner_secret='h4x6lTb5UIgCFt0UOy1VJ0uQgcY68h',
                            verifier='69qjCUfvYp3LjmgBJfz0FN9EMVOp6m')
     url = BASE_URL + ACCESS_TOKEN_ENDPOINT
     uri, headers, _ = client.sign(url,
                                   http_method='GET')
     req = urllib2.Request(str(uri), headers=headers)
     resp = urllib2.urlopen(req)
     data = resp.read()
     decoded_data = urldecode(data)
     oauth_response = dict(decoded_data)
     assert 'oauth_token' in oauth_response and 'oauth_token_secret' in oauth_response
Пример #35
0
    def __test_request_token_headers_params(self):
        client = oauth1.Client(CLIENT_KEY,
                               client_secret=CLIENT_SECRET,
                               signature_type=SIGNATURE_TYPE_AUTH_HEADER,
                               signature_method=SIGNATURE_PLAINTEXT,
                               callback_uri='http://localhost/callback')
        url = BASE_URL + REQUEST_TOKEN_ENDPOINT
        uri, headers, _ = client.sign(url,
                                      http_method='GET')
        r = requests.get(uri, headers=headers)

        if r.status_code != 200:
            assert False

        decoded_data = urldecode(r.text)
        oauth_response = dict(decoded_data)
        assert 'oauth_token' in oauth_response and 'oauth_token_secret' in oauth_response
Пример #36
0
  def refresh_token(self):
      """Step 3: obtains a new access_token from the the refresh token 
      obtained in step 2.	
      the token is internally saved
      """
      ##the method in oauth does not allow a custom header (issue created #182)
      ## in the mean time here is a request from the ground up
      #out  = self.oauth.refresh_token(self.refresh_token_url,
      #refresh_token=self.token['refresh_token'],
      #kwarg=self.auth_header)
 
      auth = OAuth2Session(self.client_id)
      body = auth._client.prepare_refresh_body(refresh_token=self.token['refresh_token'])
      r = auth.post(self.refresh_token_url, data=dict(urldecode(body)), verify=True,headers=self.auth_header)
      auth._client.parse_request_body_response(r.text, scope=self.oauth.scope)
      self.oauth.token = auth._client.token
      self.token = auth._client.token
      return(self.token)
Пример #37
0
    def refresh_token(self):
        """Step 3: obtains a new access_token from the the refresh token
        obtained in step 2.
        the token is internally saved
        """
        ##the method in oauth does not allow a custom header (issue created #182)
        ## in the mean time here is a request from the ground up
        #out  = self.oauth.refresh_token(self.refresh_token_url,
        #refresh_token=self.token['refresh_token'],
        #kwarg=self.auth_header)

        auth = OAuth2Session(self.client_id)
        body = auth._client.prepare_refresh_body(refresh_token=self.token['refresh_token'])
        r = auth.post(self.refresh_token_url, data=dict(urldecode(body)), verify=True,headers=self.auth_header)
        auth._client.parse_request_body_response(r.text, scope=self.oauth.scope)
        self.oauth.token = auth._client.token
        self.token = auth._client.token
        return(self.token)
    def parse_authorization_response(self, url):
        """Extract parameters from the post authorization redirect response URL.

        :param url: The full URL that resulted from the user being redirected
                    back from the OAuth provider to you, the client.
        :returns: A dict of parameters extracted from the URL.

        >>> redirect_response = 'https://127.0.0.1/callback?oauth_token=kjerht2309uf&oauth_token_secret=lsdajfh923874&oauth_verifier=w34o8967345'
        >>> oauth_session = OAuth1Session('client-key', client_secret='secret')
        >>> oauth_session.parse_authorization_response(redirect_response)
        {
            'oauth_token: 'kjerht2309u',
            'oauth_token_secret: 'lsdajfh923874',
            'oauth_verifier: 'w34o8967345',
        }
        """
        token = dict(urldecode(urlparse(url).query))
        self._populate_attributes(token)
        return token
Пример #39
0
    def parse_authorization_response(self, url):
        """Extract parameters from the post authorization redirect response URL.

        :param url: The full URL that resulted from the user being redirected
                    back from the OAuth provider to you, the client.
        :returns: A dict of parameters extracted from the URL.

        >>> redirect_response = 'https://127.0.0.1/callback?oauth_token=kjerht2309uf&oauth_token_secret=lsdajfh923874&oauth_verifier=w34o8967345'
        >>> oauth_session = OAuth1Session('client-key', client_secret='secret')
        >>> oauth_session.parse_authorization_response(redirect_response)
        {
            'oauth_token: 'kjerht2309u',
            'oauth_token_secret: 'lsdajfh923874',
            'oauth_verifier: 'w34o8967345',
        }
        """
        token = dict(urldecode(urlparse(url).query))
        self._populate_attributes(token)
        return token
Пример #40
0
    def __test_request_token_body_params(self):
        client = oauth1.Client(CLIENT_KEY,
                               client_secret=CLIENT_SECRET,
                               signature_type=SIGNATURE_TYPE_BODY,
                               signature_method=SIGNATURE_PLAINTEXT,
                               callback_uri='oob')
        headers = {'Content-Type': 'application/x-www-form-urlencoded'}
        url = BASE_URL + REQUEST_TOKEN_ENDPOINT
        uri, headers, body = client.sign(url,
                                         headers=headers,
                                         http_method='POST',
                                         body='')
        r = requests.post(uri, body, headers=headers)

        if r.status_code != 200:
            assert False

        decoded_data = urldecode(r.text)
        oauth_response = dict(decoded_data)
        assert 'oauth_token' in oauth_response and 'oauth_token_secret' in oauth_response
Пример #41
0
    def test_access_token_query_params(self):
        client = oauth1.Client(CLIENT_KEY,
                               client_secret=CLIENT_SECRET,
                               signature_type=SIGNATURE_TYPE_QUERY,
                               signature_method=SIGNATURE_PLAINTEXT,
                               resource_owner_key='HJUCE34yYlRToKKu7fXq90bmRmZm1j',
                               resource_owner_secret='4VVbhBQXcAdJhw42lTvGk0qN1F1Moe',
                               verifier='cXqtvQxfP6EReq7A6ulLKbOrXeflTk')
        url = BASE_URL + ACCESS_TOKEN_ENDPOINT
        uri, headers, _ = client.sign(url,
                                      http_method='GET')

        headers['StackSync-API'] = "v2"
        r = requests.get(uri, headers=headers)

        if 200 < r.status_code >= 300:
            assert False

        decoded_data = urldecode(r.text)
        oauth_response = dict(decoded_data)
        assert 'oauth_token' in oauth_response and 'oauth_token_secret' in oauth_response
Пример #42
0
    def _fetch_token(self, url):
        log.debug('Fetching token from %s using client %s', url, self._client.client)
        r = self.post(url)

        if r.status_code >= 400:
            error = "Token request failed with code %s, response was '%s'."
            raise TokenRequestDenied(error % (r.status_code, r.text), r.status_code)

        log.debug('Decoding token from response "%s"', r.text)
        try:
            token = dict(urldecode(r.text))
        except ValueError as e:
            error = ("Unable to decode token from token response. "
                     "This is commonly caused by an unsuccessful request where"
                     " a non urlencoded error message is returned. "
                     "The decoding error was %s""" % e)
            raise ValueError(error)

        log.debug('Obtained token %s', token)
        log.debug('Updating internal client attributes from token data.')
        self._populate_attributes(token)
        return token
Пример #43
0
    async def fetch_request_token(self) -> Dict[str, str]:
        log.debug(f'Fetching request token...')
        _, signed_headers, _ = self.oauth_client.sign(self.request_token_url, 'POST')
        log.debug(f'Signed headers: {signed_headers}')

        resp = await self.session.post(self.request_token_url, headers=signed_headers)
        log.debug(f'Response: {resp.status} {resp.reason}')
        log.debug(f'To: {resp.method} {resp.real_url.human_repr()}')
        log.debug(f'Requested as: {resp.request_info.method} {resp.request_info.real_url.human_repr()}')
        log.debug(f'Request headers: {resp.request_info.headers}')

        token_raw = await resp.text()
        log.debug(f'Token response: {token_raw}')
        token = dict(urldecode(token_raw))

        self.oauth_client.resource_owner_key = token['oauth_token']
        self.oauth_client.resource_owner_secret = token['oauth_token_secret']

        # Set callback to None for future signing calls
        self.oauth_client.callback_uri = None

        return token
Пример #44
0
    def is_refresh_token_valid(refresh_token):
        client_id = settings.EVEOAUTH['CONSUMER_KEY']
        client_secret = settings.EVEOAUTH['CONSUMER_SECRET']
        headers = {
            'Accept': 'application/json',
            'Content-Type':
            ('application/x-www-form-urlencoded;charset=UTF-8'),
        }
        body = "grant_type=refresh_token&client_secret=%s&client_id=%s&refresh_token=%s" % (
            client_secret, client_id, refresh_token)
        token_url = settings.EVEOAUTH['BASE_URL'] + settings.EVEOAUTH[
            'TOKEN_URL']
        session = requests.Session()

        r = session.post(token_url,
                         data=dict(urldecode(body)),
                         headers=headers)
        logger.debug('Request to fetch token completed with status %s.',
                     r.status_code)
        logger.debug('Request headers were %s', r.request.headers)
        logger.debug('Request body was %s', r.request.body)
        logger.debug('Response headers were %s and content %s.', r.headers,
                     r.text)

        #breadcrumbs.record('Request to fetch token completed with status %s.',r.status_code)
        #breadcrumbs.record('Request headers were %s', r.request.headers)
        #breadcrumbs.record('Request body was %s', r.request.body)
        #breadcrumbs.record('Response headers were %s and content %s.',r.headers, r.text)

        if r.text:
            try:
                content = json.loads(r.text)
                if "error" in content:
                    if content["error"] == "invalid_token":
                        return False
            # any exceptions here are purely the fault of CCP oauth, and cannot be used to indicate token validity
            except ValueError:
                return True
        return True
Пример #45
0
    def fetch_token(self, code):
        body = self.oauth_client.prepare_request_body(
            code=code,
            body='',
            redirect_uri=self.redirect_uri,
            include_client_id=None)

        response = self.request(
            'POST',
            self.token_url,
            headers={
                'Accept': 'application/json',
                'Content-Type':
                'application/x-www-form-urlencoded;charset=UTF-8',
            },
            data=dict(urldecode(body)),
            auth=httpx.BasicAuth(self.client_id, self.client_secret))

        self.token = self.oauth_client.parse_request_body_response(
            response.text, scope=self.scope)

        return self.token
Пример #46
0
    def refresh_token(self, token_url, refresh_token=None, body='', auth=None,
                      **kwargs):
        """Fetch a new access token using a refresh token.

        :param token_url: The token endpoint, must be HTTPS.
        :param refresh_token: The refresh_token to use.
        :param body: Optional application/x-www-form-urlencoded body to add the
                     include in the token request. Prefer kwargs over body.
        :param auth: An auth tuple or method as accepted by requests.
        :param kwargs: Extra parameters to include in the token request.
        :return: A token dict
        """
        if not token_url:
            raise ValueError('No token endpoint set for auto_refresh.')

        if not is_secure_transport(token_url):
            raise InsecureTransportError()

        # Need to nullify token to prevent it from being added to the request
        refresh_token = refresh_token or self.token.get('refresh_token')
        self.token = {}

        log.debug('Adding auto refresh key word arguments %s.',
                  self.auto_refresh_kwargs)
        kwargs.update(self.auto_refresh_kwargs)
        body = self._client.prepare_refresh_body(body=body,
                refresh_token=refresh_token, scope=self.scope, **kwargs)
        log.debug('Prepared refresh token request body %s', body)
        r = self.post(token_url, data=dict(urldecode(body)), auth=auth)
        log.debug('Request to refresh token completed with status %s.',
                  r.status_code)
        log.debug('Response headers were %s and content %s.',
                  r.headers, r.text)
        self.token = self._client.parse_request_body_response(r.text, scope=self.scope)
        if not 'refresh_token' in self.token:
            log.debug('No new refresh token given. Re-using old.')
            self.token['refresh_token'] = refresh_token
        return self.token
Пример #47
0
def params_from_uri(uri):
    params = dict(urldecode(urlparse(uri).query))
    if 'scope' in params:
        params['scope'] = scope_to_list(params['scope'])
    return params
Пример #48
0
 def _fetch_token(self, url):
     token = dict(urldecode(self.post(url).text))
     self._populate_attributes(token)
     return token
    def fetch_token(
        self,
        token_url,
        code=None,
        authorization_response=None,
        body="",
        auth=None,
        username=None,
        password=None,
        method="POST",
        timeout=None,
        headers=None,
        verify=True,
        proxies=None,
        include_client_id=None,
        client_secret=None,
        **kwargs
    ):
        """Generic method for fetching an access token from the token endpoint.

        If you are using the MobileApplicationClient you will want to use
        `token_from_fragment` instead of `fetch_token`.

        The current implementation enforces the RFC guidelines.

        :param token_url: Token endpoint URL, must use HTTPS.
        :param code: Authorization code (used by WebApplicationClients).
        :param authorization_response: Authorization response URL, the callback
                                       URL of the request back to you. Used by
                                       WebApplicationClients instead of code.
        :param body: Optional application/x-www-form-urlencoded body to add the
                     include in the token request. Prefer kwargs over body.
        :param auth: An auth tuple or method as accepted by `requests`.
        :param username: Username required by LegacyApplicationClients to appear
                         in the request body.
        :param password: Password required by LegacyApplicationClients to appear
                         in the request body.
        :param method: The HTTP method used to make the request. Defaults
                       to POST, but may also be GET. Other methods should
                       be added as needed.
        :param timeout: Timeout of the request in seconds.
        :param headers: Dict to default request headers with.
        :param verify: Verify SSL certificate.
        :param proxies: The `proxies` argument is passed onto `requests`.
        :param include_client_id: Should the request body include the
                                  `client_id` parameter. Default is `None`,
                                  which will attempt to autodetect. This can be
                                  forced to always include (True) or never
                                  include (False).
        :param client_secret: The `client_secret` paired to the `client_id`.
                              This is generally required unless provided in the
                              `auth` tuple. If the value is `None`, it will be
                              omitted from the request, however if the value is
                              an empty string, an empty string will be sent.
        :param kwargs: Extra parameters to include in the token request.
        :return: A token dict
        """
        if not is_secure_transport(token_url):
            raise InsecureTransportError()

        if not code and authorization_response:
            self._client.parse_request_uri_response(
                authorization_response, state=self._state
            )
            code = self._client.code
        elif not code and isinstance(self._client, WebApplicationClient):
            code = self._client.code
            if not code:
                raise ValueError(
                    "Please supply either code or " "authorization_response parameters."
                )

        # Earlier versions of this library build an HTTPBasicAuth header out of
        # `username` and `password`. The RFC states, however these attributes
        # must be in the request body and not the header.
        # If an upstream server is not spec compliant and requires them to
        # appear as an Authorization header, supply an explicit `auth` header
        # to this function.
        # This check will allow for empty strings, but not `None`.
        #
        # Refernences
        # 4.3.2 - Resource Owner Password Credentials Grant
        #         https://tools.ietf.org/html/rfc6749#section-4.3.2

        if isinstance(self._client, LegacyApplicationClient):
            if username is None:
                raise ValueError(
                    "`LegacyApplicationClient` requires both the "
                    "`username` and `password` parameters."
                )
            if password is None:
                raise ValueError(
                    "The required paramter `username` was supplied, "
                    "but `password` was not."
                )

        # merge username and password into kwargs for `prepare_request_body`
        if username is not None:
            kwargs["username"] = username
        if password is not None:
            kwargs["password"] = password

        # is an auth explicitly supplied?
        if auth is not None:
            # if we're dealing with the default of `include_client_id` (None):
            # we will assume the `auth` argument is for an RFC compliant server
            # and we should not send the `client_id` in the body.
            # This approach allows us to still force the client_id by submitting
            # `include_client_id=True` along with an `auth` object.
            if include_client_id is None:
                include_client_id = False

        # otherwise we may need to create an auth header
        else:
            # since we don't have an auth header, we MAY need to create one
            # it is possible that we want to send the `client_id` in the body
            # if so, `include_client_id` should be set to True
            # otherwise, we will generate an auth header
            if include_client_id is not True:
                client_id = self.client_id
                if client_id:
                    log.debug(
                        'Encoding `client_id` "%s" with `client_secret` '
                        "as Basic auth credentials.",
                        client_id,
                    )
                    client_secret = client_secret if client_secret is not None else ""
                    auth = requests.auth.HTTPBasicAuth(client_id, client_secret)

        if include_client_id:
            # this was pulled out of the params
            # it needs to be passed into prepare_request_body
            if client_secret is not None:
                kwargs["client_secret"] = client_secret

        body = self._client.prepare_request_body(
            code=code,
            body=body,
            redirect_uri=self.redirect_uri,
            include_client_id=include_client_id,
            **kwargs
        )

        headers = headers or {
            "Accept": "application/json",
            "Content-Type": "application/x-www-form-urlencoded;charset=UTF-8",
        }
        self.token = {}
        if method.upper() == "POST":
            r = self.post(
                token_url,
                data=dict(urldecode(body)),
                timeout=timeout,
                headers=headers,
                auth=auth,
                verify=verify,
                proxies=proxies,
            )
            log.debug("Prepared fetch token request body %s", body)
        elif method.upper() == "GET":
            # if method is not 'POST', switch body to querystring and GET
            r = self.get(
                token_url,
                params=dict(urldecode(body)),
                timeout=timeout,
                headers=headers,
                auth=auth,
                verify=verify,
                proxies=proxies,
            )
            log.debug("Prepared fetch token request querystring %s", body)
        else:
            raise ValueError("The method kwarg must be POST or GET.")

        log.debug("Request to fetch token completed with status %s.", r.status_code)
        log.debug("Request headers were %s", r.request.headers)
        log.debug("Request body was %s", r.request.body)
        log.debug("Response headers were %s and content %s.", r.headers, r.text)
        log.debug(
            "Invoking %d token response hooks.",
            len(self.compliance_hook["access_token_response"]),
        )
        for hook in self.compliance_hook["access_token_response"]:
            log.debug("Invoking hook %s.", hook)
            r = hook(r)

        self._client.parse_request_body_response(r.text, scope=self.scope)
        self.token = self._client.token
        log.debug("Obtained token %s.", self.token)
        return self.token
Пример #50
0
    def fetch_token(self, token_url, code=None, authorization_response=None,
            body='', auth=None, username=None, password=None, method='POST',
            timeout=None, headers=None, verify=True, **kwargs):
        """Generic method for fetching an access token from the token endpoint.

        If you are using the MobileApplicationClient you will want to use
        token_from_fragment instead of fetch_token.

        :param token_url: Token endpoint URL, must use HTTPS.
        :param code: Authorization code (used by WebApplicationClients).
        :param authorization_response: Authorization response URL, the callback
                                       URL of the request back to you. Used by
                                       WebApplicationClients instead of code.
        :param body: Optional application/x-www-form-urlencoded body to add the
                     include in the token request. Prefer kwargs over body.
        :param auth: An auth tuple or method as accepted by requests.
        :param username: Username used by LegacyApplicationClients.
        :param password: Password used by LegacyApplicationClients.
        :param method: The HTTP method used to make the request. Defaults
                       to POST, but may also be GET. Other methods should
                       be added as needed.
        :param headers: Dict to default request headers with.
        :param timeout: Timeout of the request in seconds.
        :param verify: Verify SSL certificate.
        :param kwargs: Extra parameters to include in the token request.
        :return: A token dict
        """
        if not is_secure_transport(token_url):
            raise InsecureTransportError()

        if not code and authorization_response:
            self._client.parse_request_uri_response(authorization_response,
                    state=self._state)
            code = self._client.code
        elif not code and isinstance(self._client, WebApplicationClient):
            code = self._client.code
            if not code:
                raise ValueError('Please supply either code or '
                                 'authorization_code parameters.')


        body = self._client.prepare_request_body(code=code, body=body,
                redirect_uri=self.redirect_uri, username=username,
                password=password, **kwargs)

        headers = headers or {
            'Accept': 'application/json',
            'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8',
        }
        if method.upper() == 'POST':
            r = self.post(token_url, data=dict(urldecode(body)),
                timeout=timeout, headers=headers, auth=auth,
                verify=verify)
            log.debug('Prepared fetch token request body %s', body)
        elif method.upper() == 'GET':
            # if method is not 'POST', switch body to querystring and GET
            r = self.get(token_url, params=dict(urldecode(body)),
                timeout=timeout, headers=headers, auth=auth,
                verify=verify)
            log.debug('Prepared fetch token request querystring %s', body)
        else:
            raise ValueError('The method kwarg must be POST or GET.')

        log.debug('Request to fetch token completed with status %s.',
                  r.status_code)
        log.debug('Request headers were %s', r.request.headers)
        log.debug('Request body was %s', r.request.body)
        log.debug('Response headers were %s and content %s.',
                  r.headers, r.text)
        log.debug('Invoking %d token response hooks.',
                  len(self.compliance_hook['access_token_response']))
        for hook in self.compliance_hook['access_token_response']:
            log.debug('Invoking hook %s.', hook)
            r = hook(r)

        r.raise_for_status()

        self._client.parse_request_body_response(r.text, scope=self.scope)
        self.token = self._client.token
        log.debug('Obtained token %s.', self.token)
        return self.token
 def _fetch_token(self, url):
     token = dict(urldecode(self.post(url).text))
     self._populate_attributes(token)
     return token
Пример #52
0
 def _compliance_fix(r):
     token = dict(urldecode(r.text))
     token['expires_in'] = token['expires']
     token['token_type'] = 'Bearer'
     r._content = dumps(token)
     return r
Пример #53
0
def params_from_uri(uri):
    params = dict(urldecode(urlparse(uri).query))
    if 'scope' in params:
        params['scope'] = scope_to_list(params['scope'])
    return params
Пример #54
0
    def get_common_objects(self):
        super().get_common_objects()
        user = self.request.user

        # Determine user ID.
        student_id = "aplusuid%d" % (user.pk)
        if self.profile.student_id:
            student_id = self.profile.student_id

        # MD5 the user id so that the real student id and names or emails
        # are not linked in external services.
        student_id = hashlib.md5(student_id.encode('utf-8')).hexdigest()

        # Determine user role.
        role = "Student"
        if self.is_teacher:
            role = "Instructor"
        elif self.is_assistant:
            role = "TA,TeachingAssistant"

        parameters = {

            "lti_version": "LTI-1p0",
            "lti_message_type": "basic-lti-launch-request",

            "resource_link_id": "aplus%d" % (self.service.pk),
            "resource_link_title": self.menu_item.label,

            # User session.
            "user_id": student_id,
            "roles": role,
            "lis_person_name_full": "%s %s" % (user.first_name, user.last_name),
            "lis_person_name_given": user.first_name,
            "lis_person_name_family": user.last_name,
            "lis_person_contact_email_primary": user.email,

            # Selected course.
            "context_id": self.request.get_host() \
                + self.instance.get_absolute_url(),
            "context_title": self.course.name,
            "context_label": self.course.code,

            "launch_presentation_locale": get_language(),

            "tool_consumer_instance_guid": self.request.get_host() + "/aplus",
            "tool_consumer_instance_name": "A+ LMS",
        }
        headers = {
            "Content-Type": "application/x-www-form-urlencoded",
        }

        # Sign the request using OAuth.
        client = Client(self.service.consumer_key,
            client_secret=self.service.consumer_secret,
            signature_method=SIGNATURE_HMAC,
            signature_type=SIGNATURE_TYPE_BODY)
        uri, headers, body = client.sign(self.service.url,
            http_method="POST",
            body=parameters,
            headers=headers)
        self.url = uri
        self.parameters = urldecode(body)
        self.note("url", "parameters")
Пример #55
0
def collect_parameters(uri_query="", body=[], headers=None, exclude_oauth_signature=True, with_realm=False):
    """**Parameter Sources**

    Parameters starting with `oauth_` will be unescaped.

    Body parameters must be supplied as a dict, a list of 2-tuples, or a
    formencoded query string.

    Headers must be supplied as a dict.

    Per `section 3.4.1.3.1`_ of the spec.

    For example, the HTTP request::

        POST /request?b5=%3D%253D&a3=a&c%40=&a2=r%20b HTTP/1.1
        Host: example.com
        Content-Type: application/x-www-form-urlencoded
        Authorization: OAuth realm="Example",
            oauth_consumer_key="9djdj82h48djs9d2",
            oauth_token="kkk9d7dh3k39sjv7",
            oauth_signature_method="HMAC-SHA1",
            oauth_timestamp="137131201",
            oauth_nonce="7d8f3e4a",
            oauth_signature="djosJKDKJSD8743243%2Fjdk33klY%3D"

        c2&a3=2+q

    contains the following (fully decoded) parameters used in the
    signature base sting::

        +------------------------+------------------+
        |          Name          |       Value      |
        +------------------------+------------------+
        |           b5           |       =%3D       |
        |           a3           |         a        |
        |           c@           |                  |
        |           a2           |        r b       |
        |   oauth_consumer_key   | 9djdj82h48djs9d2 |
        |       oauth_token      | kkk9d7dh3k39sjv7 |
        | oauth_signature_method |     HMAC-SHA1    |
        |     oauth_timestamp    |     137131201    |
        |       oauth_nonce      |     7d8f3e4a     |
        |           c2           |                  |
        |           a3           |        2 q       |
        +------------------------+------------------+

    Note that the value of "b5" is "=%3D" and not "==".  Both "c@" and
    "c2" have empty values.  While the encoding rules specified in this
    specification for the purpose of constructing the signature base
    string exclude the use of a "+" character (ASCII code 43) to
    represent an encoded space character (ASCII code 32), this practice
    is widely used in "application/x-www-form-urlencoded" encoded values,
    and MUST be properly decoded, as demonstrated by one of the "a3"
    parameter instances (the "a3" parameter is used twice in this
    request).

    .. _`section 3.4.1.3.1`: http://tools.ietf.org/html/rfc5849#section-3.4.1.3.1
    """
    headers = headers or {}
    params = []

    # The parameters from the following sources are collected into a single
    # list of name/value pairs:

    # *  The query component of the HTTP request URI as defined by
    #    `RFC3986, Section 3.4`_.  The query component is parsed into a list
    #    of name/value pairs by treating it as an
    #    "application/x-www-form-urlencoded" string, separating the names
    #    and values and decoding them as defined by
    #    `W3C.REC-html40-19980424`_, Section 17.13.4.
    #
    # .. _`RFC3986, Section 3.4`: http://tools.ietf.org/html/rfc3986#section-3.4
    # .. _`W3C.REC-html40-19980424`: http://tools.ietf.org/html/rfc5849#ref-W3C.REC-html40-19980424
    if uri_query:
        params.extend(urldecode(uri_query))

    # *  The OAuth HTTP "Authorization" header field (`Section 3.5.1`_) if
    #    present.  The header's content is parsed into a list of name/value
    #    pairs excluding the "realm" parameter if present.  The parameter
    #    values are decoded as defined by `Section 3.5.1`_.
    #
    # .. _`Section 3.5.1`: http://tools.ietf.org/html/rfc5849#section-3.5.1
    if headers:
        headers_lower = dict((k.lower(), v) for k, v in headers.items())
        authorization_header = headers_lower.get("authorization")
        if authorization_header is not None:
            params.extend(
                [i for i in utils.parse_authorization_header(authorization_header) if with_realm or i[0] != "realm"]
            )

    # *  The HTTP request entity-body, but only if all of the following
    #    conditions are met:
    #     *  The entity-body is single-part.
    #
    #     *  The entity-body follows the encoding requirements of the
    #        "application/x-www-form-urlencoded" content-type as defined by
    #        `W3C.REC-html40-19980424`_.

    #     *  The HTTP request entity-header includes the "Content-Type"
    #        header field set to "application/x-www-form-urlencoded".
    #
    # .._`W3C.REC-html40-19980424`: http://tools.ietf.org/html/rfc5849#ref-W3C.REC-html40-19980424

    # TODO: enforce header param inclusion conditions
    bodyparams = extract_params(body) or []
    params.extend(bodyparams)

    # ensure all oauth params are unescaped
    unescaped_params = []
    for k, v in params:
        if k.startswith("oauth_"):
            v = utils.unescape(v)
        unescaped_params.append((k, v))

    # The "oauth_signature" parameter MUST be excluded from the signature
    # base string if present.
    if exclude_oauth_signature:
        unescaped_params = list(filter(lambda i: i[0] != "oauth_signature", unescaped_params))

    return unescaped_params
resource_owner_secret = ''

if client_key == '' or client_secret == '':
    print "Please change your client key and secret in connectXAuth.py header"
    sys.exit(0)

if username == 'USER_NAME' or password == 'USER_PASSWORD':
    print "Please change username and password in connectXAuth.py header"
    sys.exit(0)

client = Client(client_key, client_secret=client_secret, signature_type=SIGNATURE_TYPE_BODY)
headers = {"Content-Type": CONTENT_TYPE_FORM_URLENCODED}
body = 'x_auth_mode=client_auth&x_auth_username='******'&x_auth_password='******'oauth_token')
resource_owner_secret = oauth_tokens.get('oauth_token_secret')

cred = {"client_key": client_key, "client_secret": client_secret,
        "resource_owner_key": resource_owner_key,
        "resource_owner_secret": resource_owner_secret}

import json
with open('credentials.json', 'w') as outfile:
    json.dump(cred, outfile)
Пример #57
0
    async def refresh_token(self,
                            token_url,
                            refresh_token=None,
                            body="",
                            auth=None,
                            timeout=None,
                            headers=None,
                            verify_ssl=True,
                            proxies=None,
                            **kwargs):
        """Fetch a new access token using a refresh token.

        :param token_url: The token endpoint, must be HTTPS.
        :param refresh_token: The refresh_token to use.
        :param body: Optional application/x-www-form-urlencoded body to add the
                     include in the token request. Prefer kwargs over body.
        :param auth: An auth tuple or method as accepted by `requests`.
        :param timeout: Timeout of the request in seconds.
        :param headers: A dict of headers to be used by `requests`.
        :param verify: Verify SSL certificate.
        :param proxies: The `proxies` argument will be passed to `requests`.
        :param kwargs: Extra parameters to include in the token request.
        :return: A token dict
        """
        if not token_url:
            raise ValueError("No token endpoint set for auto_refresh.")

        if not is_secure_transport(token_url):
            raise InsecureTransportError()

        refresh_token = refresh_token or self.token.get("refresh_token")

        log.debug("Adding auto refresh key word arguments %s.",
                  self.auto_refresh_kwargs)

        kwargs.update(self.auto_refresh_kwargs)
        body = self._client.prepare_refresh_body(body=body,
                                                 refresh_token=refresh_token,
                                                 scope=self.scope,
                                                 **kwargs)
        log.debug("Prepared refresh token request body %s", body)

        if headers is None:
            headers = {
                "Accept":
                "application/json",
                "Content-Type":
                ("application/x-www-form-urlencoded;charset=UTF-8"),
            }

        async with self.post(
                token_url,
                data=dict(urldecode(body)),
                auth=auth,
                timeout=timeout,
                headers=headers,
                verify_ssl=verify_ssl,
                withhold_token=True,
                # proxy=proxies,
        ) as resp:
            log.debug("Request to refresh token completed with status %s.",
                      resp.status)
            text = await resp.text()
            log.debug("Response headers were %s and content %s.", resp.headers,
                      text)
            (resp, ) = self._invoke_hooks("refresh_token_response", resp)

        self.token = self._client.parse_request_body_response(text,
                                                              scope=self.scope)
        if "refresh_token" not in self.token:
            log.debug("No new refresh token given. Re-using old.")
            self.token["refresh_token"] = refresh_token
        return self.token
Пример #58
0
    async def fetch_token(self,
                          token_url,
                          code=None,
                          authorization_response=None,
                          body="",
                          auth=None,
                          username=None,
                          password=None,
                          method="POST",
                          force_querystring=False,
                          timeout=None,
                          headers=None,
                          verify_ssl=True,
                          proxies=None,
                          include_client_id=None,
                          client_id=None,
                          client_secret=None,
                          **kwargs):
        """Generic method for fetching an access token from the token endpoint.

        If you are using the MobileApplicationClient you will want to use
        `token_from_fragment` instead of `fetch_token`.

        The current implementation enforces the RFC guidelines.

        :param token_url: Token endpoint URL, must use HTTPS.
        :param code: Authorization code (used by WebApplicationClients).
        :param authorization_response: Authorization response URL, the callback
                                       URL of the request back to you. Used by
                                       WebApplicationClients instead of code.
        :param body: Optional application/x-www-form-urlencoded body to add the
                     include in the token request. Prefer kwargs over body.
        :param auth: An auth tuple or method as accepted by `requests`.
        :param username: Username required by LegacyApplicationClients to appear
                         in the request body.
        :param password: Password required by LegacyApplicationClients to appear
                         in the request body.
        :param method: The HTTP method used to make the request. Defaults
                       to POST, but may also be GET. Other methods should
                       be added as needed.
        :param force_querystring: If True, force the request body to be sent
            in the querystring instead.
        :param timeout: Timeout of the request in seconds.
        :param headers: Dict to default request headers with.
        :param verify: Verify SSL certificate.
        :param proxies: The `proxies` argument is passed onto `requests`.
        :param include_client_id: Should the request body include the
                                  `client_id` parameter. Default is `None`,
                                  which will attempt to autodetect. This can be
                                  forced to always include (True) or never
                                  include (False).
        :param client_secret: The `client_secret` paired to the `client_id`.
                              This is generally required unless provided in the
                              `auth` tuple. If the value is `None`, it will be
                              omitted from the request, however if the value is
                              an empty string, an empty string will be sent.
        :param kwargs: Extra parameters to include in the token request.
        :return: A token dict
        """
        if not is_secure_transport(token_url):
            raise InsecureTransportError()

        if not code and authorization_response:
            log.debug('-- response %s', authorization_response)
            self._client.parse_request_uri_response(
                str(authorization_response), state=self._state)
            code = self._client.code
            log.debug('--code %s', code)
        elif not code and isinstance(self._client, WebApplicationClient):
            code = self._client.code
            if not code:
                raise ValueError("Please supply either code or "
                                 "authorization_response parameters.")

        # Earlier versions of this library build an HTTPBasicAuth header out of
        # `username` and `password`. The RFC states, however these attributes
        # must be in the request body and not the header.
        # If an upstream server is not spec compliant and requires them to
        # appear as an Authorization header, supply an explicit `auth` header
        # to this function.
        # This check will allow for empty strings, but not `None`.
        #
        # Refernences
        # 4.3.2 - Resource Owner Password Credentials Grant
        #         https://tools.ietf.org/html/rfc6749#section-4.3.2

        if isinstance(self._client, LegacyApplicationClient):
            if username is None:
                raise ValueError("`LegacyApplicationClient` requires both the "
                                 "`username` and `password` parameters.")
            if password is None:
                raise ValueError(
                    "The required paramter `username` was supplied, "
                    "but `password` was not.")

        # merge username and password into kwargs for `prepare_request_body`
        if username is not None:
            kwargs["username"] = username
        if password is not None:
            kwargs["password"] = password

        # is an auth explicitly supplied?
        if auth is not None:
            # if we're dealing with the default of `include_client_id` (None):
            # we will assume the `auth` argument is for an RFC compliant server
            # and we should not send the `client_id` in the body.
            # This approach allows us to still force the client_id by submitting
            # `include_client_id=True` along with an `auth` object.
            if include_client_id is None:
                include_client_id = False

        # otherwise we may need to create an auth header
        else:
            # since we don't have an auth header, we MAY need to create one
            # it is possible that we want to send the `client_id` in the body
            # if so, `include_client_id` should be set to True
            # otherwise, we will generate an auth header
            if include_client_id is not True:
                client_id = self.client_id
            if client_id:
                log.debug(
                    'Encoding `client_id` "%s" with `client_secret` '
                    "as Basic auth credentials.",
                    client_id,
                )
                client_secret = client_secret if client_secret is not None else ""
                auth = aiohttp.BasicAuth(login=client_id,
                                         password=client_secret)

        if include_client_id:
            # this was pulled out of the params
            # it needs to be passed into prepare_request_body
            if client_secret is not None:
                kwargs["client_secret"] = client_secret

        body = self._client.prepare_request_body(
            code=code,
            body=body,
            redirect_uri=self.redirect_uri,
            include_client_id=include_client_id,
            **kwargs)

        headers = headers or {
            "Accept": "application/json",
            "Content-Type": "application/x-www-form-urlencoded;charset=UTF-8",
        }
        self.token = {}
        request_kwargs = {}
        if method.upper() == "POST":
            request_kwargs["params" if force_querystring else "data"] = dict(
                urldecode(body))
        elif method.upper() == "GET":
            request_kwargs["params"] = dict(urldecode(body))
        else:
            raise ValueError("The method kwarg must be POST or GET.")

        async with self.request(method=method,
                                url=token_url,
                                timeout=timeout,
                                headers=headers,
                                auth=auth,
                                verify_ssl=verify_ssl,
                                proxy=proxies,
                                **request_kwargs) as resp:
            log.debug("Request to fetch token completed with status %s.",
                      resp.status)
            log.debug("Request headers were %s", headers)
            log.debug("Request body was %s", body)
            text = await resp.text()

            log.debug("Response headers were %s and content %s.", resp.headers,
                      text)
            (resp, ) = self._invoke_hooks("access_token_response", resp)

        self._client.parse_request_body_response(text, scope=self.scope)
        self.token = self._client.token
        log.debug("Obtained token %s.", self.token)
        return self.token
Пример #59
0
    def fetch_token(self, token_url, code=None, authorization_response=None,
            body='', auth=None, username=None, password=None, method='POST',
            timeout=None, headers=None, verify=True, proxies=None, **kwargs):
        """Generic method for fetching an access token from the token endpoint.

        If you are using the MobileApplicationClient you will want to use
        token_from_fragment instead of fetch_token.

        :param token_url: Token endpoint URL, must use HTTPS.
        :param code: Authorization code (used by WebApplicationClients).
        :param authorization_response: Authorization response URL, the callback
                                       URL of the request back to you. Used by
                                       WebApplicationClients instead of code.
        :param body: Optional application/x-www-form-urlencoded body to add the
                     include in the token request. Prefer kwargs over body.
        :param auth: An auth tuple or method as accepted by requests.
        :param username: Username used by LegacyApplicationClients.
        :param password: Password used by LegacyApplicationClients.
        :param method: The HTTP method used to make the request. Defaults
                       to POST, but may also be GET. Other methods should
                       be added as needed.
        :param headers: Dict to default request headers with.
        :param timeout: Timeout of the request in seconds.
        :param verify: Verify SSL certificate.
        :param kwargs: Extra parameters to include in the token request.
        :return: A token dict
        """
        if not is_secure_transport(token_url):
            raise InsecureTransportError()

        if not code and authorization_response:
            self._client.parse_request_uri_response(authorization_response,
                    state=self._state)
            code = self._client.code
        elif not code and isinstance(self._client, WebApplicationClient):
            code = self._client.code
            if not code:
                raise ValueError('Please supply either code or '
                                 'authorization_response parameters.')


        body = self._client.prepare_request_body(code=code, body=body,
                redirect_uri=self.redirect_uri, username=username,
                password=password, **kwargs)

        client_id = kwargs.get('client_id', '')
        if auth is None:
            if client_id:
                log.debug('Encoding client_id "%s" with client_secret as Basic auth credentials.', client_id)
                client_secret = kwargs.get('client_secret', '')
                client_secret = client_secret if client_secret is not None else ''
                auth = requests.auth.HTTPBasicAuth(client_id, client_secret)
            elif username:
                if password is None:
                    raise ValueError('Username was supplied, but not password.')
                log.debug('Encoding username, password as Basic auth credentials.')
                auth = requests.auth.HTTPBasicAuth(username, password)

        headers = headers or {
            'Accept': 'application/json',
            'Content-Type': 'application/json',
        }
        self.token = {}
        if method.upper() == 'POST':
            r = self.post(token_url, json=dict(urldecode(body)),
                timeout=timeout, headers=headers, auth=auth,
                verify=verify, proxies=proxies)
            log.debug('Prepared fetch token request body %s', body)
        elif method.upper() == 'GET':
            # if method is not 'POST', switch body to querystring and GET
            r = self.get(token_url, params=dict(urldecode(body)),
                timeout=timeout, headers=headers, auth=auth,
                verify=verify, proxies=proxies)
            log.debug('Prepared fetch token request querystring %s', body)
        else:
            raise ValueError('The method kwarg must be POST or GET.')

        log.debug('Request to fetch token completed with status %s.',
                  r.status_code)
        log.debug('Request headers were %s', r.request.headers)
        log.debug('Request body was %s', r.request.body)
        log.debug('Response headers were %s and content %s.',
                  r.headers, r.text)
        log.debug('Invoking %d token response hooks.',
                  len(self.compliance_hook['access_token_response']))
        for hook in self.compliance_hook['access_token_response']:
            log.debug('Invoking hook %s.', hook)
            r = hook(r)

        self._client.parse_request_body_response(r.text, scope=self.scope)
        self.token = self._client.token
        log.debug('Obtained token %s.', self.token)
        return self.token