Example #1
0
    def get_oauth_params(self, request):
        """Get the basic OAuth parameters to be used in generating a signature.
        """
        nonce = (generate_nonce()
                 if self.nonce is None else self.nonce)
        timestamp = (generate_timestamp()
                     if self.timestamp is None else self.timestamp)
        params = [
            ('oauth_nonce', nonce),
            ('oauth_timestamp', timestamp),
            ('oauth_version', '1.0'),
            ('oauth_signature_method', self.signature_method),
            ('oauth_consumer_key', self.client_key),
        ]
        if self.resource_owner_key:
            params.append(('oauth_token', self.resource_owner_key))
        if self.callback_uri:
            params.append(('oauth_callback', self.callback_uri))
        if self.verifier:
            params.append(('oauth_verifier', self.verifier))

        # providing body hash for requests other than x-www-form-urlencoded
        # as described in https://tools.ietf.org/html/draft-eaton-oauth-bodyhash-00#section-4.1.1
        # 4.1.1. When to include the body hash
        #    *  [...] MUST NOT include an oauth_body_hash parameter on requests with form-encoded request bodies
        #    *  [...] SHOULD include the oauth_body_hash parameter on all other requests.
        # Note that SHA-1 is vulnerable. The spec acknowledges that in https://tools.ietf.org/html/draft-eaton-oauth-bodyhash-00#section-6.2
        # At this time, no further effort has been made to replace SHA-1 for the OAuth Request Body Hash extension.
        content_type = request.headers.get('Content-Type', None)
        content_type_eligible = content_type and content_type.find('application/x-www-form-urlencoded') < 0
        if request.body is not None and content_type_eligible:
            params.append(('oauth_body_hash', base64.b64encode(hashlib.sha1(request.body.encode('utf-8')).digest()).decode('utf-8')))

        return params
Example #2
0
    def get_oauth_params(self, request):
        """Get the basic OAuth parameters to be used in generating a signature.
        """
        nonce = (generate_nonce() if self.nonce is None else self.nonce)
        timestamp = (generate_timestamp()
                     if self.timestamp is None else self.timestamp)
        params = [
            ('oauth_nonce', nonce),
            ('oauth_timestamp', timestamp),
            ('oauth_version', '1.0'),
            ('oauth_signature_method', self.signature_method),
            ('oauth_consumer_key', self.client_key),
        ]
        if self.resource_owner_key:
            params.append(('oauth_token', self.resource_owner_key))
        if self.callback_uri:
            params.append(('oauth_callback', self.callback_uri))
        if self.verifier:
            params.append(('oauth_verifier', self.verifier))

        # providing body hash for requests other than x-www-form-urlencoded
        # as described in http://oauth.googlecode.com/svn/spec/ext/body_hash/1.0/oauth-bodyhash.html
        # 4.1.1. When to include the body hash
        #    *  [...] MUST NOT include an oauth_body_hash parameter on requests with form-encoded request bodies
        #    *  [...] SHOULD include the oauth_body_hash parameter on all other requests.
        content_type = request.headers.get('Content-Type', None)
        content_type_eligible = content_type and content_type.find(
            'application/x-www-form-urlencoded') < 0
        if request.body is not None and content_type_eligible:
            params.append(('oauth_body_hash',
                           base64.b64encode(
                               hashlib.sha1(request.body.encode(
                                   'utf-8')).digest()).decode('utf-8')))

        return params
Example #3
0
    def get_oauth_params(self, request):
        """Get the basic OAuth parameters to be used in generating a signature.
        """
        nonce = (generate_nonce()
                 if self.nonce is None else self.nonce)
        timestamp = (generate_timestamp()
                     if self.timestamp is None else self.timestamp)
        params = [
            ('oauth_nonce', nonce),
            ('oauth_timestamp', timestamp),
            ('oauth_version', '1.0'),
            ('oauth_signature_method', self.signature_method),
            ('oauth_consumer_key', self.client_key),
        ]
        if self.resource_owner_key:
            params.append(('oauth_token', self.resource_owner_key))
        if self.callback_uri:
            params.append(('oauth_callback', self.callback_uri))
        if self.verifier:
            params.append(('oauth_verifier', self.verifier))

        # providing body hash for requests other than x-www-form-urlencoded
        # as described in http://oauth.googlecode.com/svn/spec/ext/body_hash/1.0/oauth-bodyhash.html
        # 4.1.1. When to include the body hash
        #    *  [...] MUST NOT include an oauth_body_hash parameter on requests with form-encoded request bodies
        #    *  [...] SHOULD include the oauth_body_hash parameter on all other requests.
        content_type = request.headers.get('Content-Type', None)
        content_type_eligible = content_type and content_type.find('application/x-www-form-urlencoded') < 0
        if request.body is not None and content_type_eligible:
            params.append(('oauth_body_hash', base64.b64encode(hashlib.sha1(request.body.encode('utf-8')).digest()).decode('utf-8')))

        return params
Example #4
0
    def get_oauth_params(self, request):
        """Get the basic OAuth parameters to be used in generating a signature.
        """
        nonce = (generate_nonce()
                 if self.nonce is None else self.nonce)
        timestamp = (generate_timestamp()
                     if self.timestamp is None else self.timestamp)
        params = [
            ('oauth_nonce', nonce),
            ('oauth_timestamp', timestamp),
            ('oauth_version', '1.0'),
            ('oauth_signature_method', self.signature_method),
            ('oauth_consumer_key', self.client_key),
        ]
        if self.resource_owner_key:
            params.append(('oauth_token', self.resource_owner_key))
        if self.callback_uri:
            params.append(('oauth_callback', self.callback_uri))
        if self.verifier:
            params.append(('oauth_verifier', self.verifier))

        # providing body hash for requests other than x-www-form-urlencoded
        # as described in https://tools.ietf.org/html/draft-eaton-oauth-bodyhash-00#section-4.1.1
        # 4.1.1. When to include the body hash
        #    *  [...] MUST NOT include an oauth_body_hash parameter on requests with form-encoded request bodies
        #    *  [...] SHOULD include the oauth_body_hash parameter on all other requests.
        # Note that SHA-1 is vulnerable. The spec acknowledges that in https://tools.ietf.org/html/draft-eaton-oauth-bodyhash-00#section-6.2
        # At this time, no further effort has been made to replace SHA-1 for the OAuth Request Body Hash extension.
        content_type = request.headers.get('Content-Type', None)
        content_type_eligible = content_type and content_type.find('application/x-www-form-urlencoded') < 0
        if request.body is not None and content_type_eligible:
            params.append(('oauth_body_hash', base64.b64encode(hashlib.sha1(request.body.encode('utf-8')).digest()).decode('utf-8')))

        return params
Example #5
0
    def get_context_data(self, **kwargs):
        role = self.request.GET.get('role', '')
        campus = self.request.GET.get('campus', '')

        lti_parameters = [
            ("roles", self._lti_role[role]),
            ("ext_roles", self._lti_ext_role[role]),
            ("custom_canvas_account_sis_id",
             'uwcourse:{}:arts-&-sciences:psych:psych'.format(campus)),
            ("oauth_timestamp", generate_timestamp()),
            ("oauth_nonce", generate_nonce()),
            ("resource_link_title",
             "UW LTI Development ({})".format(self.lti_app())),
        ]

        lti_parameters += self._static_lti_parameters

        # sign payload
        lti_app_uri = self.lti_app_uri()
        sbs = signature_base_string('POST', base_string_uri(lti_app_uri + '/'),
                                    normalize_parameters(lti_parameters))
        client_key = self._client_key
        client = Client(client_key,
                        client_secret=self._client_secrets[client_key])
        signature = sign_hmac_sha1_with_client(sbs, client)
        lti_parameters.append(("oauth_signature", signature))

        context = super().get_context_data(**kwargs)
        context['uri'] = lti_app_uri
        context['campus'] = campus
        context['role_name'] = role
        context['lti_parameters'] = lti_parameters
        return context
Example #6
0
    def get_oauth_params(self):
        """Get the basic OAuth parameters to be used in generating a signature.
        """
        params = [
            ('oauth_nonce', generate_nonce()),
            ('oauth_timestamp', generate_timestamp()),
            ('oauth_version', '1.0'),
            ('oauth_signature_method', self.signature_method),
            ('oauth_consumer_key', self.client_key),
        ]
        if self.resource_owner_key:
            params.append(('oauth_token', self.resource_owner_key))
        if self.callback_uri:
            params.append(('oauth_callback', self.callback_uri))
        if self.verifier:
            params.append(('oauth_verifier', self.verifier))

        return params
    def get_oauth_params(self):
        """Get the basic OAuth parameters to be used in generating a signature.
        """
        params = [
            (u"oauth_nonce", generate_nonce()),
            (u"oauth_timestamp", generate_timestamp()),
            (u"oauth_version", u"1.0"),
            (u"oauth_signature_method", self.signature_method),
            (u"oauth_consumer_key", self.client_key),
        ]
        if self.resource_owner_key:
            params.append((u"oauth_token", self.resource_owner_key))
        if self.callback_uri:
            params.append((u"oauth_callback", self.callback_uri))
        if self.verifier:
            params.append((u"oauth_verifier", self.verifier))

        return params
Example #8
0
    def get_oauth_params(self):
        """Get the basic OAuth parameters to be used in generating a signature.
        """
        params = [
            ('oauth_nonce', generate_nonce()),
            ('oauth_timestamp', generate_timestamp()),
            ('oauth_version', '1.0'),
            ('oauth_signature_method', self.signature_method),
            ('oauth_consumer_key', self.client_key),
        ]
        if self.resource_owner_key:
            params.append(('oauth_token', self.resource_owner_key))
        if self.callback_uri:
            params.append(('oauth_callback', self.callback_uri))
        if self.verifier:
            params.append(('oauth_verifier', self.verifier))

        return params
Example #9
0
    def get_oauth_params(self, request):
        """Get the basic OAuth parameters to be used in generating a signature.
        """
        nonce = generate_nonce() if self.nonce is None else self.nonce
        timestamp = generate_timestamp() if self.timestamp is None else self.timestamp
        params = [
            ("oauth_nonce", nonce),
            ("oauth_timestamp", timestamp),
            ("oauth_version", "1.0"),
            ("oauth_signature_method", self.signature_method),
            ("oauth_consumer_key", self.client_key),
        ]
        if self.resource_owner_key:
            params.append(("oauth_token", self.resource_owner_key))
        if self.callback_uri:
            params.append(("oauth_callback", self.callback_uri))
        if self.verifier:
            params.append(("oauth_verifier", self.verifier))

        return params
Example #10
0
 def sign(self, url, method=u'POST', signature_method=u'HMAC-SHA1'):
     """
     Use this method to create a signature over the authorization header, and the url query parameters
     :param url: request url
     :param method: request method (i.e. POST, GET)
     :param signature_method: method of signature. Only supports (HMAC-SHA1, PLAINTEXT)
     Note: that HMAC-SHA1 is required by Yahoo API queries since they are sent insecurely
     """
     # could change this to support additional methods
     # for now only support HMAC-SHA1 and PLAINTEXT (Yahoo only supports these)
     self.add_param(u'oauth_signature_method', signature_method)
     self.add_param(u'oauth_nonce', generate_nonce())
     self.add_param(u'oauth_timestamp', generate_timestamp())
     if signature_method == u'HMAC-SHA1':
         base_string = construct_base_string(unicode(method),
                                             normalize_base_string_uri(unicode(url)),
                                             normalize_parameters(self.params))
         signature = sign_hmac_sha1(base_string, self.client_secret, self.oauth_token_secret)
     else:
         signature = quote(self.client_secret + u'&' + self.oauth_token_secret)
     self.add_param(u'oauth_signature', signature)
Example #11
0
    def get_oauth_params(self, request):
        """Get the basic OAuth parameters to be used in generating a signature.
        """
        nonce = (generate_nonce() if self.nonce is None else self.nonce)
        timestamp = (generate_timestamp()
                     if self.timestamp is None else self.timestamp)
        params = [
            ('oauth_nonce', nonce),
            ('oauth_timestamp', timestamp),
            ('oauth_version', self.version),
            ('oauth_signature_method', self.signature_method),
            ('oauth_consumer_key', self.client_key),
        ]
        if self.resource_owner_key:
            params.append(('oauth_token', self.resource_owner_key))
        if self.callback_uri:
            params.append(('oauth_callback', self.callback_uri))
        if self.verifier:
            params.append(('oauth_verifier', self.verifier))

        return params
    def get_oauth_params(self, request):
        __doc__ = Client.get_oauth_params.__doc__
        nonce = (generate_nonce()
                 if self.nonce is None else self.nonce)
        timestamp = (generate_timestamp()
                     if self.timestamp is None else self.timestamp)
        params = [
            ('oauth_nonce', nonce),
            ('oauth_timestamp', timestamp),
            ('oauth_version', '1.0'),
            ('oauth_signature_method', self.signature_method),
            ('oauth_consumer_key', self.client_key),
            ]
        if self.resource_owner_key:
            params.append(('oauth_token', self.resource_owner_key))
        else:
            params.append(('oauth_body_hash', self.hash_body(request)))
        if self.callback_uri:
            params.append(('oauth_callback', self.callback_uri))
        if self.verifier:
            params.append(('oauth_verifier', self.verifier))

        return params
Example #13
0
def prepare_mac_header(token, uri, key, http_method, nonce=None, headers=None,
        body=None, ext='', hash_algorithm='hmac-sha-1', issue_time=None,
        draft=0):
    """Add an `MAC Access Authentication`_ signature to headers.

    Unlike OAuth 1, this HMAC signature does not require inclusion of the request
    payload/body, neither does it use a combination of client_secret and
    token_secret but rather a mac_key provided together with the access token.

    Currently two algorithms are supported, "hmac-sha-1" and "hmac-sha-256",
    `extension algorithms`_ are not supported.

    Example MAC Authorization header, linebreaks added for clarity

    Authorization: MAC id="h480djs93hd8",
                       nonce="1336363200:dj83hs9s",
                       mac="bhCQXTVyfj5cmA9uKkPFx1zeOXM="

    .. _`MAC Access Authentication`: http://tools.ietf.org/html/draft-ietf-oauth-v2-http-mac-01
    .. _`extension algorithms`: http://tools.ietf.org/html/draft-ietf-oauth-v2-http-mac-01#section-7.1

    :param uri: Request URI.
    :param headers: Request headers as a dictionary.
    :param http_method: HTTP Request method.
    :param key: MAC given provided by token endpoint.
    :param hash_algorithm: HMAC algorithm provided by token endpoint.
    :param issue_time: Time when the MAC credentials were issues as a datetime object.
    :param draft: MAC authentication specification version.
    :return: headers dictionary with the authorization field added.
    """
    http_method = http_method.upper()
    host, port = utils.host_from_uri(uri)

    if hash_algorithm.lower() == 'hmac-sha-1':
        h = hashlib.sha1
    elif hash_algorithm.lower() == 'hmac-sha-256':
        h = hashlib.sha256
    else:
        raise ValueError('unknown hash algorithm')

    if draft == 0:
        nonce = nonce or '{0}:{1}'.format(utils.generate_age(issue_time),
                                          common.generate_nonce())
    else:
        ts = common.generate_timestamp()
        nonce = common.generate_nonce()

    sch, net, path, par, query, fra = urlparse(uri)

    if query:
        request_uri = path + '?' + query
    else:
        request_uri = path

    # Hash the body/payload
    if body is not None and draft == 0:
        bodyhash = b2a_base64(h(body.encode('utf-8')).digest())[:-1].decode('utf-8')
    else:
        bodyhash = ''

    # Create the normalized base string
    base = []
    if draft == 0:
        base.append(nonce)
    else:
        base.append(ts)
        base.append(nonce)
    base.append(http_method.upper())
    base.append(request_uri)
    base.append(host)
    base.append(port)
    if draft == 0:
        base.append(bodyhash)
    base.append(ext or '')
    base_string = '\n'.join(base) + '\n'

    # hmac struggles with unicode strings - http://bugs.python.org/issue5285
    if isinstance(key, unicode_type):
        key = key.encode('utf-8')
    sign = hmac.new(key, base_string.encode('utf-8'), h)
    sign = b2a_base64(sign.digest())[:-1].decode('utf-8')

    header = []
    header.append('MAC id="%s"' % token)
    if draft != 0:
        header.append('ts="%s"' % ts)
    header.append('nonce="%s"' % nonce)
    if bodyhash:
        header.append('bodyhash="%s"' % bodyhash)
    if ext:
        header.append('ext="%s"' % ext)
    header.append('mac="%s"' % sign)

    headers = headers or {}
    headers['Authorization'] = ', '.join(header)
    return headers
Example #14
0
def prepare_mac_header(token,
                       uri,
                       key,
                       http_method,
                       nonce=None,
                       headers=None,
                       body=None,
                       ext='',
                       hash_algorithm='hmac-sha-1',
                       issue_time=None,
                       draft=0):
    """Add an `MAC Access Authentication`_ signature to headers.

    Unlike OAuth 1, this HMAC signature does not require inclusion of the
    request payload/body, neither does it use a combination of client_secret
    and token_secret but rather a mac_key provided together with the access
    token.

    Currently two algorithms are supported, "hmac-sha-1" and "hmac-sha-256",
    `extension algorithms`_ are not supported.

    Example MAC Authorization header, linebreaks added for clarity

    Authorization: MAC id="h480djs93hd8",
                       nonce="1336363200:dj83hs9s",
                       mac="bhCQXTVyfj5cmA9uKkPFx1zeOXM="

    .. _`MAC Access Authentication`: http://tools.ietf.org/html/draft-ietf-oauth-v2-http-mac-01
    .. _`extension algorithms`: http://tools.ietf.org/html/draft-ietf-oauth-v2-http-mac-01#section-7.1

    :param uri: Request URI.
    :param headers: Request headers as a dictionary.
    :param http_method: HTTP Request method.
    :param key: MAC given provided by token endpoint.
    :param hash_algorithm: HMAC algorithm provided by token endpoint.
    :param issue_time: Time when the MAC credentials were issued (datetime).
    :param draft: MAC authentication specification version.
    :return: headers dictionary with the authorization field added.
    """
    http_method = http_method.upper()
    host, port = utils.host_from_uri(uri)

    if hash_algorithm.lower() == 'hmac-sha-1':
        h = hashlib.sha1
    elif hash_algorithm.lower() == 'hmac-sha-256':
        h = hashlib.sha256
    else:
        raise ValueError('unknown hash algorithm')

    if draft == 0:
        nonce = nonce or '{0}:{1}'.format(utils.generate_age(issue_time),
                                          common.generate_nonce())
    else:
        ts = common.generate_timestamp()
        nonce = common.generate_nonce()

    sch, net, path, par, query, fra = urlparse(uri)

    if query:
        request_uri = path + '?' + query
    else:
        request_uri = path

    # Hash the body/payload
    if body is not None and draft == 0:
        body = body.encode('utf-8')
        bodyhash = b2a_base64(h(body).digest())[:-1].decode('utf-8')
    else:
        bodyhash = ''

    # Create the normalized base string
    base = []
    if draft == 0:
        base.append(nonce)
    else:
        base.append(ts)
        base.append(nonce)
    base.append(http_method.upper())
    base.append(request_uri)
    base.append(host)
    base.append(port)
    if draft == 0:
        base.append(bodyhash)
    base.append(ext or '')
    base_string = '\n'.join(base) + '\n'

    # hmac struggles with unicode strings - http://bugs.python.org/issue5285
    if isinstance(key, unicode_type):
        key = key.encode('utf-8')
    sign = hmac.new(key, base_string.encode('utf-8'), h)
    sign = b2a_base64(sign.digest())[:-1].decode('utf-8')

    header = []
    header.append('MAC id="%s"' % token)
    if draft != 0:
        header.append('ts="%s"' % ts)
    header.append('nonce="%s"' % nonce)
    if bodyhash:
        header.append('bodyhash="%s"' % bodyhash)
    if ext:
        header.append('ext="%s"' % ext)
    header.append('mac="%s"' % sign)

    headers = headers or {}
    headers['Authorization'] = ', '.join(header)
    return headers
Example #15
0
 def test_generate_timestamp(self):
     timestamp = generate_timestamp()
     self.assertIsInstance(timestamp, unicode_type)
     self.assertTrue(int(timestamp))
     self.assertGreater(int(timestamp), 1331672335)
Example #16
0
 def test_generate_timestamp(self):
     timestamp = generate_timestamp()
     self.assertIsInstance(timestamp, unicode_type)
     self.assertTrue(int(timestamp))
     self.assertGreater(int(timestamp), 1331672335)