def verify_oauth_body_sign(self,
                               request,
                               content_type='application/x-www-form-urlencoded'
                               ):
        """
        Verify grade request from LTI provider using OAuth body signing.

        Uses http://oauth.googlecode.com/svn/spec/ext/body_hash/1.0/oauth-bodyhash.html::

            This specification extends the OAuth signature to include integrity checks on HTTP request bodies
            with content types other than application/x-www-form-urlencoded.

        Arguments:
            request: DjangoWebobRequest.

        Raises:
            LTIError if request is incorrect.
        """

        client_key, client_secret = self.get_client_key_secret()
        headers = {
            'Authorization':
            six.text_type(request.headers.get('Authorization')),
            'Content-Type': content_type,
        }

        sha1 = hashlib.sha1()
        sha1.update(request.body)
        oauth_body_hash = base64.b64encode(sha1.digest())
        oauth_params = signature.collect_parameters(
            headers=headers, exclude_oauth_signature=False)
        oauth_headers = dict(oauth_params)
        oauth_signature = oauth_headers.pop('oauth_signature')
        mock_request_lti_1 = mock.Mock(uri=six.text_type(
            six.moves.urllib.parse.unquote(self.get_outcome_service_url())),
                                       http_method=six.text_type(
                                           request.method),
                                       params=list(oauth_headers.items()),
                                       signature=oauth_signature)
        mock_request_lti_2 = mock.Mock(
            uri=six.text_type(six.moves.urllib.parse.unquote(request.url)),
            http_method=six.text_type(request.method),
            params=list(oauth_headers.items()),
            signature=oauth_signature)
        if oauth_body_hash != oauth_headers.get('oauth_body_hash'):
            log.error("OAuth body hash verification failed, provided: {}, "
                      "calculated: {}, for url: {}, body is: {}".format(
                          oauth_headers.get('oauth_body_hash'),
                          oauth_body_hash, self.get_outcome_service_url(),
                          request.body))
            raise LTIError("OAuth body hash verification is failed.")

        if (not signature.verify_hmac_sha1(mock_request_lti_1, client_secret)
                and not signature.verify_hmac_sha1(mock_request_lti_2,
                                                   client_secret)):
            log.error("OAuth signature verification failed, for "
                      "headers:{} url:{} method:{}".format(
                          oauth_headers, self.get_outcome_service_url(),
                          six.text_type(request.method)))
            raise LTIError("OAuth signature verification has failed.")
Exemple #2
0
    def verify_oauth_body_sign(self, request, content_type="application/x-www-form-urlencoded"):
        """
        Verify grade request from LTI provider using OAuth body signing.

        Uses http://oauth.googlecode.com/svn/spec/ext/body_hash/1.0/oauth-bodyhash.html::

            This specification extends the OAuth signature to include integrity checks on HTTP request bodies
            with content types other than application/x-www-form-urlencoded.

        Arguments:
            request: DjangoWebobRequest.

        Raises:
            LTIError if request is incorrect.
        """

        client_key, client_secret = self.get_client_key_secret()
        headers = {"Authorization": unicode(request.headers.get("Authorization")), "Content-Type": content_type}

        sha1 = hashlib.sha1()
        sha1.update(request.body)
        oauth_body_hash = base64.b64encode(sha1.digest())
        oauth_params = signature.collect_parameters(headers=headers, exclude_oauth_signature=False)
        oauth_headers = dict(oauth_params)
        oauth_signature = oauth_headers.pop("oauth_signature")
        mock_request_lti_1 = mock.Mock(
            uri=unicode(urllib.unquote(self.get_outcome_service_url())),
            http_method=unicode(request.method),
            params=oauth_headers.items(),
            signature=oauth_signature,
        )
        mock_request_lti_2 = mock.Mock(
            uri=unicode(urllib.unquote(request.url)),
            http_method=unicode(request.method),
            params=oauth_headers.items(),
            signature=oauth_signature,
        )
        if oauth_body_hash != oauth_headers.get("oauth_body_hash"):
            log.error(
                "OAuth body hash verification failed, provided: {}, "
                "calculated: {}, for url: {}, body is: {}".format(
                    oauth_headers.get("oauth_body_hash"), oauth_body_hash, self.get_outcome_service_url(), request.body
                )
            )
            raise LTIError("OAuth body hash verification is failed.")

        if not signature.verify_hmac_sha1(mock_request_lti_1, client_secret) and not signature.verify_hmac_sha1(
            mock_request_lti_2, client_secret
        ):
            log.error(
                "OAuth signature verification failed, for "
                "headers:{} url:{} method:{}".format(
                    oauth_headers, self.get_outcome_service_url(), unicode(request.method)
                )
            )
            raise LTIError("OAuth signature verification has failed.")
Exemple #3
0
    def _check_oauth_signature(self, params, client_signature):
        """
        Checks oauth signature from client.

        `params` are params from post request except signature,
        `client_signature` is signature from request.

        Builds mocked request and verifies hmac-sha1 signing::
            1. builds string to sign from `params`, `url` and `http_method`.
            2. signs it with `client_secret` which comes from server settings.
            3. obtains signature after sign and then compares it with request.signature
            (request signature comes form client in request)

        Returns `True` if signatures are correct, otherwise `False`.

        """
        client_secret = str(self.server.config.get('client_secret', self.DEFAULT_CLIENT_SECRET))
        host = os.environ.get('BOK_CHOY_HOSTNAME', '127.0.0.1')
        port = self.server.server_address[1]
        lti_base = self.DEFAULT_LTI_ADDRESS.format(host=host, port=port)
        lti_endpoint = self.server.config.get('lti_endpoint', self.DEFAULT_LTI_ENDPOINT)
        url = lti_base + lti_endpoint
        request = mock.Mock()
        request.params = [(str(k), str(v)) for k, v in params.items()]
        request.uri = str(url)
        request.http_method = 'POST'
        request.signature = str(client_signature)
        return signature.verify_hmac_sha1(request, client_secret)
Exemple #4
0
def validate_2legged_oauth(oauth, uri, method, auth_header):
    """
    "Two-legged" OAuth authorization isn't standard and so not
    supported by current versions of oauthlib. The implementation
    here is sufficient for simple developer tools and testing. Real
    usage of OAuth will always require directing the user to the
    authorization page so that a resource-owner token can be
    generated.
    """
    req = Request(uri, method, "", auth_header)
    typ, params, oauth_params = oauth._get_signature_type_and_params(req)
    oauth_params = dict(oauth_params)
    req.params = filter(lambda x: x[0] not in ("oauth_signature", "realm"), params)
    req.signature = oauth_params.get("oauth_signature")
    req.client_key = oauth_params.get("oauth_consumer_key")
    req.nonce = oauth_params.get("oauth_nonce")
    req.timestamp = oauth_params.get("oauth_timestamp")
    if oauth_params.get("oauth_signature_method").lower() != "hmac-sha1":
        raise TwoLeggedOAuthError(u"unsupported signature method " + oauth_params.get("oauth_signature_method"))
    secret = validator.get_client_secret(req.client_key, req)
    valid_signature = signature.verify_hmac_sha1(req, secret, None)
    if valid_signature:
        return req.client_key
    else:
        raise TwoLeggedOAuthError(u"Cannot find APIAccess token with that key: %s" % req.client_key)
    def check_oauth_signature(self, params, client_signature):
        '''
        Checks oauth signature from client.

        `params` are params from post request except signature,
        `client_signature` is signature from request.

        Builds mocked request and verifies hmac-sha1 signing::
            1. builds string to sign from `params`, `url` and `http_method`.
            2. signs it with `client_secret` which comes from server settings.
            3. obtains signature after sign and then compares it with request.signature
            (request signature comes form client in request)

        Returns `True` if signatures are correct, otherwise `False`.

        '''
        client_secret = unicode(self.oauth_settings['client_secret'])
        url = self.oauth_settings['lti_base'] + self.oauth_settings[
            'lti_endpoint']

        request = mock.Mock()

        request.params = [(unicode(k), unicode(v)) for k, v in params.items()]
        request.uri = unicode(url)
        request.http_method = u'POST'
        request.signature = unicode(client_signature)
        return signature.verify_hmac_sha1(request, client_secret)
Exemple #6
0
    def _check_oauth_signature(self, params, client_signature):
        """
        Checks oauth signature from client.

        `params` are params from post request except signature,
        `client_signature` is signature from request.

        Builds mocked request and verifies hmac-sha1 signing::
            1. builds string to sign from `params`, `url` and `http_method`.
            2. signs it with `client_secret` which comes from server settings.
            3. obtains signature after sign and then compares it with request.signature
            (request signature comes form client in request)

        Returns `True` if signatures are correct, otherwise `False`.

        """
        client_secret = unicode(self.server.config.get('client_secret', self.DEFAULT_CLIENT_SECRET))

        port = self.server.server_address[1]
        lti_base = self.DEFAULT_LTI_ADDRESS.format(port=port)
        lti_endpoint = self.server.config.get('lti_endpoint', self.DEFAULT_LTI_ENDPOINT)
        url = lti_base + lti_endpoint

        request = mock.Mock()
        request.params = [(unicode(k), unicode(v)) for k, v in params.items()]
        request.uri = unicode(url)
        request.http_method = u'POST'
        request.signature = unicode(client_signature)
        return signature.verify_hmac_sha1(request, client_secret)
    def check_oauth_signature(self, params, client_signature):
        '''
        Checks oauth signature from client.

        `params` are params from post request except signature,
        `client_signature` is signature from request.

        Builds mocked request and verifies hmac-sha1 signing::
            1. builds string to sign from `params`, `url` and `http_method`.
            2. signs it with `client_secret` which comes from server settings.
            3. obtains signature after sign and then compares it with request.signature
            (request signature comes form client in request)

        Returns `True` if signatures are correct, otherwise `False`.

        '''
        client_secret = unicode(self.oauth_settings['client_secret'])
        url = self.oauth_settings['lti_base'] + self.oauth_settings['lti_endpoint']

        request = mock.Mock()

        request.params = [(unicode(k), unicode(v)) for k, v in params.items()]
        request.uri = unicode(url)
        request.http_method = u'POST'
        request.signature = unicode(client_signature)
        return signature.verify_hmac_sha1(request, client_secret)
Exemple #8
0
def validate_2legged_oauth(oauth, uri, method, auth_header):
    """
    "Two-legged" OAuth authorization isn't standard and so not
    supported by current versions of oauthlib. The implementation
    here is sufficient for simple developer tools and testing. Real
    usage of OAuth will always require directing the user to the
    authorization page so that a resource-owner token can be
    generated.
    """
    req = Request(uri, method, '', auth_header)
    typ, params, oauth_params = oauth._get_signature_type_and_params(req)
    oauth_params = dict(oauth_params)
    req.params = filter(lambda x: x[0] not in ("oauth_signature", "realm"),
                        params)
    req.signature = oauth_params.get('oauth_signature')
    req.client_key = oauth_params.get('oauth_consumer_key')
    req.nonce = oauth_params.get('oauth_nonce')
    req.timestamp = oauth_params.get('oauth_timestamp')
    if oauth_params.get('oauth_signature_method').lower() != 'hmac-sha1':
        raise TwoLeggedOAuthError(u'unsupported signature method ' +
                                  oauth_params.get('oauth_signature_method'))
    secret = validator.get_client_secret(req.client_key, req)
    valid_signature = signature.verify_hmac_sha1(req, secret, None)
    if valid_signature:
        return req.client_key
    else:
        raise TwoLeggedOAuthError(
            u'Cannot find APIAccess token with that key: %s' % req.client_key)
Exemple #9
0
    def check_oauth(self):
        """
        Checks whether the request passes Oauth signature check
        :return valid_oauth
        """
        resp = dict(self.__httprequest.POST.dict())
        orderedresp = OrderedDict(sorted(resp.items(), key=lambda t: t[0]))
        query_string = urllib.urlencode(orderedresp)
        oauth_headers = dict(
            signature.collect_parameters(query_string,
                                         exclude_oauth_signature=False))
        sig = oauth_headers.pop('oauth_signature')
        consumer_secret = self.get_oauthsecret_for_key(
            orderedresp.get('oauth_consumer_key'))

        oauthrequest = Oauthrequest()
        oauthrequest.params = oauth_headers.items()
        oauthrequest.uri = unicode(
            urllib.unquote(self.__httprequest.build_absolute_uri()))
        oauthrequest.http_method = unicode('POST')
        oauthrequest.signature = sig
        if signature.verify_hmac_sha1(request=oauthrequest,
                                      client_secret=unicode(consumer_secret)):
            return True
        return False
Exemple #10
0
 def test_sign_hmac_sha1_with_client(self):
     """
     Test sign and verify with HMAC-SHA1.
     """
     self.assertEqual(
         self.expected_signature_hmac_sha1,
         sign_hmac_sha1_with_client(self.eg_signature_base_string,
                                    self.hmac_client))
     self.assertTrue(verify_hmac_sha1(
         MockRequest('POST',
                     'http://example.com/request',
                     self.eg_params,
                     self.expected_signature_hmac_sha1),
         self.hmac_client.client_secret,
         self.hmac_client.resource_owner_secret))
Exemple #11
0
    def verify_oauth_body_sign(self, request):
        """
        Verify grade request from LTI provider using OAuth body signing.

        Uses http://oauth.googlecode.com/svn/spec/ext/body_hash/1.0/oauth-bodyhash.html::

            This specification extends the OAuth signature to include integrity checks on HTTP request bodies
            with content types other than application/x-www-form-urlencoded.

        Arguments:
            request: DjangoWebobRequest.

        Raises:
            LTIError if request is incorrect.
        """

        client_key, client_secret = self.get_client_key_secret()

        headers = {
            'Authorization':unicode(request.headers.get('Authorization')),
            'Content-Type': 'application/x-www-form-urlencoded',
        }

        sha1 = hashlib.sha1()
        sha1.update(request.body)
        oauth_body_hash = base64.b64encode(sha1.digest())

        oauth_params = signature.collect_parameters(headers=headers, exclude_oauth_signature=False)
        oauth_headers =dict(oauth_params)
        oauth_signature = oauth_headers.pop('oauth_signature')

        mock_request = mock.Mock(
            uri=unicode(urllib.unquote(request.url)),
            http_method=unicode(request.method),
            params=oauth_headers.items(),
            signature=oauth_signature
        )
        if oauth_body_hash != oauth_headers.get('oauth_body_hash'):
            log.debug("[LTI]: OAuth body hash verification is failed.")
            raise LTIError
        if not signature.verify_hmac_sha1(mock_request, client_secret):
            log.debug("[LTI]: OAuth signature verification is failed.")
            raise LTIError
Exemple #12
0
    def clean_oauth_signature(self):
        """
        Cleans and validates the 'oauth signature'. The signature is verified by calculating the hash (using the
        algorithm specified in 'oauth_signature_method') of the URL, METHOD and BODY. After the calculation the
        signature is compared with the 'oauth_signature' to check if they match. When the signatures match we can
        assure that the request is from a authorized entity.
        """
        oauth_request = Request(self.request.build_absolute_uri(),
                                self.request.method, self.request.POST)
        oauth_request.signature = self.cleaned_data["oauth_signature"]
        oauth_request.params = [(k, v) for k, v in self.request.POST.items()
                                if k != "oauth_signature"]

        if not oauth.verify_hmac_sha1(oauth_request, settings.LTI_SECRET):
            raise ValidationError(
                "Invalid signature, URL: {}, method: {}".format(
                    self.request.build_absolute_uri(), self.request.method))

        return self.cleaned_data["oauth_signature"]
Exemple #13
0
    def verify_oauth_body_sign(self,
                               request,
                               content_type='application/x-www-form-urlencoded'
                               ):
        """
        Verify grade request from LTI provider using OAuth body signing.

        Uses http://oauth.googlecode.com/svn/spec/ext/body_hash/1.0/oauth-bodyhash.html::

            This specification extends the OAuth signature to include integrity checks on HTTP request bodies
            with content types other than application/x-www-form-urlencoded.

        Arguments:
            request: DjangoWebobRequest.

        Raises:
            LTIError if request is incorrect.
        """

        client_key, client_secret = self.get_client_key_secret()
        headers = {
            'Authorization': unicode(request.headers.get('Authorization')),
            'Content-Type': content_type,
        }

        sha1 = hashlib.sha1()
        sha1.update(request.body)
        oauth_body_hash = base64.b64encode(sha1.digest())
        oauth_params = signature.collect_parameters(
            headers=headers, exclude_oauth_signature=False)
        oauth_headers = dict(oauth_params)
        oauth_signature = oauth_headers.pop('oauth_signature')
        mock_request = mock.Mock(uri=unicode(urllib.unquote(request.url)),
                                 http_method=unicode(request.method),
                                 params=oauth_headers.items(),
                                 signature=oauth_signature)

        if oauth_body_hash != oauth_headers.get('oauth_body_hash'):
            raise LTIError("OAuth body hash verification is failed.")

        if not signature.verify_hmac_sha1(mock_request, client_secret):
            raise LTIError("OAuth signature verification is failed.")
Exemple #14
0
    def check_oauth(self):
        """
        Checks whether the request passes Oauth signature check
        :return valid_oauth
        """
        resp = dict(self.__httprequest.POST.dict())
        orderedresp = OrderedDict(sorted(resp.items(), key=lambda t: t[0]))
        query_string = urllib.urlencode(orderedresp)
        oauth_headers = dict(signature.collect_parameters(query_string, exclude_oauth_signature=False))
        sig = oauth_headers.pop('oauth_signature')
        consumer_secret = self.get_oauthsecret_for_key(orderedresp.get('oauth_consumer_key'))

        oauthrequest = Oauthrequest()
        oauthrequest.params = oauth_headers.items()
        oauthrequest.uri = unicode(urllib.unquote(self.__httprequest.build_absolute_uri()))
        oauthrequest.http_method = unicode('POST')
        oauthrequest.signature = sig
        if signature.verify_hmac_sha1(request=oauthrequest, client_secret=unicode(consumer_secret)):
            return True
        return False