Пример #1
0
 def test_sign_unicode(self):
     client = Client('client_key', nonce='abc', timestamp='abc')
     _, h, b = client.sign('http://i.b/path', http_method='POST',
             body='status=%E5%95%A6%E5%95%A6',
             headers={'Content-Type': 'application/x-www-form-urlencoded'})
     self.assertEqual(b, 'status=%E5%95%A6%E5%95%A6')
     self.assertIn('oauth_signature="yrtSqp88m%2Fc5UDaucI8BXK4oEtk%3D"', h['Authorization'])
     _, h, b = client.sign('http://i.b/path', http_method='POST',
             body='status=%C3%A6%C3%A5%C3%B8',
             headers={'Content-Type': 'application/x-www-form-urlencoded'})
     self.assertEqual(b, 'status=%C3%A6%C3%A5%C3%B8')
     self.assertIn('oauth_signature="oG5t3Eg%2FXO5FfQgUUlTtUeeZzvk%3D"', h['Authorization'])
Пример #2
0
 def test_client_realm_sign_with_additional_realm(self):
     client = Client("client-key", realm="moo-realm")
     uri, header, body = client.sign("http://example-uri", realm="baa-realm")
     self.assertTrue(
         header["Authorization"].startswith('OAuth realm="baa-realm",'))
     # make sure sign() does not override the default realm
     self.assertEqual(client.realm, "moo-realm")
Пример #3
0
def get_access_token(request_token, request_token_secret, 
                     access_token_url, access_token_method,
                     public_key, secret_key,
                     verifier):
    """
    Returns access token and access token secret
    """
    c = Client(public_key,
        secret_key,
        resource_owner_key=request_token,
        resource_owner_secret=request_token_secret,
        signature_type=SIGNATURE_TYPE_QUERY,
        verifier=verifier
    )

    uri, headers, body =  c.sign(uri=access_token_url, http_method=access_token_method)
    http = httplib2.Http()

    response, content = httplib2.Http.request(http, uri, method=access_token_method, body=body,
        headers=headers)

    if response.get('status') != '200':
        raise Exception("Invalid access token response: %s." % content)

    tokens = dict(urlparse.parse_qsl(content))
    access_token = tokens.get('oauth_token')
    access_token_secret = tokens.get('oauth_token_secret')
    return access_token, access_token_secret
Пример #4
0
 def test_can_load_consumer_secret_from_settings(self):
     lti = Client(
         client_key=OTHER_LTI_CONSUMER_KEY,
         client_secret=OTHER_LTI_CONSUMER_SECRET,
         signature_type=SIGNATURE_TYPE_BODY,
     )
     (uri, _headers, body) = lti.sign(
         uri=self.url_prefix + LTI_TPA_LOGIN_URL, http_method='POST',
         headers={'Content-Type': FORM_ENCODED},
         body={
             'user_id': LTI_USER_ID,
             'custom_tpa_next': '/account/finish_auth/?course_id=my_course_id&enrollment_action=enroll',
         }
     )
     with self.settings(SOCIAL_AUTH_LTI_CONSUMER_SECRETS={OTHER_LTI_CONSUMER_KEY: OTHER_LTI_CONSUMER_SECRET}):
         login_response = self.client.post(path=uri, content_type=FORM_ENCODED, data=body)
         # The user should be redirected to the registration form
         self.assertEqual(login_response.status_code, 302)
         self.assertTrue(login_response['Location'].endswith(reverse('signin_user')))
         register_response = self.client.get(login_response['Location'])
         self.assertEqual(register_response.status_code, 200)
         self.assertIn(
             '"currentProvider": "Tool Consumer with Secret in Settings"',
             register_response.content
         )
         self.assertIn('"errorMessage": null', register_response.content)
Пример #5
0
class OAuth1(AuthBase):
    """Signs the request using OAuth 1 (RFC5849)"""
    def __init__(self, client_key,
            client_secret=None,
            resource_owner_key=None,
            resource_owner_secret=None,
            callback_uri=None,
            signature_method=SIGNATURE_HMAC,
            signature_type=SIGNATURE_TYPE_AUTH_HEADER,
            rsa_key=None, verifier=None):

        try:
            signature_type = signature_type.upper()
        except AttributeError:
            pass

        self.client = Client(client_key, client_secret, resource_owner_key,
            resource_owner_secret, callback_uri, signature_method,
            signature_type, rsa_key, verifier)

    def __call__(self, r):
        contenttype = r.headers.get('Content-Type', None)
        decoded_body = extract_params(r.data)
        if contenttype == None and decoded_body != None:
            r.headers['Content-Type'] = 'application/x-www-form-urlencoded'

        r.url, r.headers, r.data = self.client.sign(
            unicode(r.url), unicode(r.method), r.data, r.headers)
        return r
Пример #6
0
 def test_check_redirect_uri(self):
     client = Client('foo')
     uri, headers, _ = client.sign(self.uri)
     h, b, s = self.endpoint.create_request_token_response(
             uri, headers=headers)
     self.assertEqual(s, 400)
     self.assertIn('invalid_request', b)
Пример #7
0
def get_request_token(public_key, secret_key, url, method=u'POST'):
    '''
    
    :param public_key:
    :param secret_key:
    :param url:
    :param method:
    '''
    c = Client(
            unicode(public_key),
            unicode(secret_key), 
            signature_type=SIGNATURE_TYPE_QUERY
    )
    uri, headers, body = c.sign(
            uri=url, 
            http_method=method)
    http = httplib2.Http()

    response, content = httplib2.Http.request(http, uri, 
            method=method, 
            body=body,
            headers=headers
    )

    if response.get('status') != '200':
        raise Exception("Invalid request token response: %s." % content)

    tokens = dict(urlparse.parse_qsl(content))
    token = tokens.get('oauth_token')
    token_secret = tokens.get('oauth_token_secret')
    return unicode(token), unicode(token_secret)
Пример #8
0
 def test_rsa_method(self):
     private_key = (
         "-----BEGIN RSA PRIVATE KEY-----\nMIICXgIBAAKBgQDk1/bxy"
         "S8Q8jiheHeYYp/4rEKJopeQRRKKpZI4s5i+UPwVpupG\nAlwXWfzXw"
         "SMaKPAoKJNdu7tqKRniqst5uoHXw98gj0x7zamu0Ck1LtQ4c7pFMVa"
         "h\n5IYGhBi2E9ycNS329W27nJPWNCbESTu7snVlG8V8mfvGGg3xNjT"
         "MO7IdrwIDAQAB\nAoGBAOQ2KuH8S5+OrsL4K+wfjoCi6MfxCUyqVU9"
         "GxocdM1m30WyWRFMEz2nKJ8fR\np3vTD4w8yplTOhcoXdQZl0kRoaD"
         "zrcYkm2VvJtQRrX7dKFT8dR8D/Tr7dNQLOXfC\nDY6xveQczE7qt7V"
         "k7lp4FqmxBsaaEuokt78pOOjywZoInjZhAkEA9wz3zoZNT0/i\nrf6"
         "qv2qTIeieUB035N3dyw6f1BGSWYaXSuerDCD/J1qZbAPKKhyHZbVaw"
         "Ft3UMhe\n542UftBaxQJBAO0iJy1I8GQjGnS7B3yvyH3CcLYGy296+"
         "XO/2xKp/d/ty1OIeovx\nC60pLNwuFNF3z9d2GVQAdoQ89hUkOtjZL"
         "eMCQQD0JO6oPHUeUjYT+T7ImAv7UKVT\nSuy30sKjLzqoGw1kR+wv7"
         "C5PeDRvscs4wa4CW9s6mjSrMDkDrmCLuJDtmf55AkEA\nkmaMg2PNr"
         "jUR51F0zOEFycaaqXbGcFwe1/xx9zLmHzMDXd4bsnwt9kk+fe0hQzV"
         "S\nJzatanQit3+feev1PN3QewJAWv4RZeavEUhKv+kLe95Yd0su7lT"
         "LVduVgh4v5yLT\nGa6FHdjGPcfajt+nrpB1n8UQBEH9ZxniokR/IPv"
         "dMlxqXA==\n-----END RSA PRIVATE KEY-----"
     )
     client = Client('client_key', signature_method=SIGNATURE_RSA,
         rsa_key=private_key, timestamp='1234567890', nonce='abc')
     u, h, b = client.sign('http://example.com')
     correct = ('OAuth oauth_nonce="abc", oauth_timestamp="1234567890", '
                'oauth_version="1.0", oauth_signature_method="RSA-SHA1", '
                'oauth_consumer_key="client_key", '
                'oauth_signature="ktvzkUhtrIawBcq21DRJrAyysTc3E1Zq5GdGu8EzH'
                'OtbeaCmOBDLGHAcqlm92mj7xp5E1Z6i2vbExPimYAJL7FzkLnkRE5YEJR4'
                'rNtIgAf1OZbYsIUmmBO%2BCLuStuu5Lg3tAluwC7XkkgoXCBaRKT1mUXzP'
                'HJILzZ8iFOvS6w5E%3D"')
     self.assertEqual(h['Authorization'], correct)
Пример #9
0
 def test_uri_provided_realm(self):
     client = Client("foo", callback_uri="https://c.b/cb", client_secret="bar")
     uri = self.uri + "?realm=foo"
     _, headers, _ = client.sign(uri)
     u, h, b, s = self.endpoint.create_request_token_response(uri, headers=headers)
     self.assertEqual(s, 200)
     self.assertIn("oauth_token", b)
Пример #10
0
 def test_hmac_sha1_method(self):
     client = Client('client_key', timestamp='1234567890', nonce='abc')
     u, h, b = client.sign('http://example.com')
     correct = ('OAuth oauth_nonce="abc", oauth_timestamp="1234567890", '
                'oauth_version="1.0", oauth_signature_method="HMAC-SHA1", '
                'oauth_consumer_key="client_key", '
                'oauth_signature="hH5BWYVqo7QI4EmPBUUe9owRUUQ%3D"')
     self.assertEqual(h['Authorization'], correct)
Пример #11
0
 def test_validate_signature(self):
     client = Client('foo',
             resource_owner_key='token',
             resource_owner_secret='secret')
     _, headers, _ = client.sign(self.uri + '/extra')
     v, r = self.endpoint.validate_protected_resource_request(
             self.uri, headers=headers)
     self.assertFalse(v)
Пример #12
0
 def test_hmac_sha256_method(self):
     client = Client('client_key', signature_method=SIGNATURE_HMAC_SHA256,
                     timestamp='1234567890', nonce='abc')
     u, h, b = client.sign('http://example.com')
     correct = ('OAuth oauth_nonce="abc", oauth_timestamp="1234567890", '
                'oauth_version="1.0", oauth_signature_method="HMAC-SHA256", '
                'oauth_consumer_key="client_key", '
                'oauth_signature="JzgJWBxX664OiMW3WE4MEjtYwOjI%2FpaUWHqtdHe68Es%3D"')
     self.assertEqual(h['Authorization'], correct)
Пример #13
0
 def test_uri_provided_realm(self):
     client = Client('foo', callback_uri='https://c.b/cb',
             client_secret='bar')
     uri = self.uri + '?realm=foo'
     _, headers, _ = client.sign(uri)
     h, b, s = self.endpoint.create_request_token_response(
             uri, headers=headers)
     self.assertEqual(s, 200)
     self.assertIn('oauth_token', b)
Пример #14
0
 def test_validate_signature(self):
     client = Client('foo',
             resource_owner_key='token',
             resource_owner_secret='secret',
             verifier='verfier')
     _, headers, _ = client.sign(self.uri + '/extra')
     h, b, s = self.endpoint.create_access_token_response(
             self.uri, headers=headers)
     self.assertEqual(s, 401)
Пример #15
0
 def test_decoding(self):
     client = Client('client_key', decoding='utf-8')
     uri, headers, body = client.sign('http://a.b/path?query', body='a=b',
             headers={'Content-Type': 'application/x-www-form-urlencoded'})
     self.assertIsInstance(uri, bytes_type)
     self.assertIsInstance(body, bytes_type)
     for k, v in headers.items():
         self.assertIsInstance(k, bytes_type)
         self.assertIsInstance(v, bytes_type)
Пример #16
0
 def test_sign_unicode(self):
     client = Client("client_key", nonce="abc", timestamp="abc")
     _, h, b = client.sign(
         "http://i.b/path",
         http_method="POST",
         body="status=%E5%95%A6%E5%95%A6",
         headers={"Content-Type": "application/x-www-form-urlencoded"},
     )
     self.assertEqual(b, "status=%E5%95%A6%E5%95%A6")
     self.assertIn('oauth_signature="yrtSqp88m%2Fc5UDaucI8BXK4oEtk%3D"', h["Authorization"])
     _, h, b = client.sign(
         "http://i.b/path",
         http_method="POST",
         body="status=%C3%A6%C3%A5%C3%B8",
         headers={"Content-Type": "application/x-www-form-urlencoded"},
     )
     self.assertEqual(b, "status=%C3%A6%C3%A5%C3%B8")
     self.assertIn('oauth_signature="oG5t3Eg%2FXO5FfQgUUlTtUeeZzvk%3D"', h["Authorization"])
Пример #17
0
 def test_sign_body(self):
     client = Client("client_key")
     _, h, b = client.sign(
         "http://i.b/path",
         http_method="POST",
         body="",
         headers={"Content-Type": "application/x-www-form-urlencoded"},
     )
     self.assertEqual(h["Content-Type"], "application/x-www-form-urlencoded")
Пример #18
0
 def test_params_in_query(self):
     client = Client('client_key', signature_type=SIGNATURE_TYPE_QUERY,
             timestamp='1378988215', nonce='14205877133089081931378988215')
     u, _, _ = client.sign('http://i.b/path', http_method='POST')
     correct = ('http://i.b/path?oauth_nonce=14205877133089081931378988215&'
                'oauth_timestamp=1378988215&'
                'oauth_version=1.0&'
                'oauth_signature_method=HMAC-SHA1&'
                'oauth_consumer_key=client_key&'
                'oauth_signature=08G5Snvw%2BgDAzBF%2BCmT5KqlrPKo%3D')
     self.assertEqual(u, correct)
Пример #19
0
    def test_case_insensitive_headers(self):
        client = Client('client_key')
        # Uppercase
        _, h, _ = client.sign('http://i.b/path', http_method='POST', body='',
                headers={'Content-Type': 'application/x-www-form-urlencoded'})
        self.assertEqual(h['Content-Type'], 'application/x-www-form-urlencoded')

        # Lowercase
        _, h, _ = client.sign('http://i.b/path', http_method='POST', body='',
                headers={'content-type': 'application/x-www-form-urlencoded'})
        self.assertEqual(h['content-type'], 'application/x-www-form-urlencoded')

        # Capitalized
        _, h, _ = client.sign('http://i.b/path', http_method='POST', body='',
                headers={'Content-type': 'application/x-www-form-urlencoded'})
        self.assertEqual(h['Content-type'], 'application/x-www-form-urlencoded')

        # Random
        _, h, _ = client.sign('http://i.b/path', http_method='POST', body='',
                headers={'conTent-tYpe': 'application/x-www-form-urlencoded'})
        self.assertEqual(h['conTent-tYpe'], 'application/x-www-form-urlencoded')
Пример #20
0
 def test_decoding(self):
     client = Client("client_key", decoding="utf-8")
     uri, headers, body = client.sign(
         "http://a.b/path?query",
         http_method="POST",
         body="a=b",
         headers={"Content-Type": "application/x-www-form-urlencoded"},
     )
     self.assertIsInstance(uri, bytes_type)
     self.assertIsInstance(body, bytes_type)
     for k, v in headers.items():
         self.assertIsInstance(k, bytes_type)
         self.assertIsInstance(v, bytes_type)
Пример #21
0
 def test_validate_signature(self):
     client = Client('foo',
             resource_owner_key='token',
             resource_owner_secret='secret')
     _, headers, _ = client.sign(self.uri + '/extra')
     v, r = self.endpoint.validate_protected_resource_request(
             self.uri, headers=headers)
     self.assertFalse(v)
     # the validator log should have `False` values
     self.assertTrue(r.validator_log['client'])
     self.assertTrue(r.validator_log['realm'])
     self.assertTrue(r.validator_log['resource_owner'])
     self.assertFalse(r.validator_log['signature'])
Пример #22
0
 def test_plaintext_method(self):
     client = Client('client_key',
                     signature_method=SIGNATURE_PLAINTEXT,
                     timestamp='1234567890',
                     nonce='abc',
                     client_secret='foo',
                     resource_owner_secret='bar')
     u, h, b = client.sign('http://example.com')
     correct = ('OAuth oauth_nonce="abc", oauth_timestamp="1234567890", '
                'oauth_version="1.0", oauth_signature_method="PLAINTEXT", '
                'oauth_consumer_key="client_key", '
                'oauth_signature="foo%26bar"')
     self.assertEqual(h['Authorization'], correct)
Пример #23
0
 def test_params_in_body(self):
     client = Client('client_key', signature_type=SIGNATURE_TYPE_BODY,
             timestamp='1378988215', nonce='14205877133089081931378988215')
     _, h, b = client.sign('http://i.b/path', http_method='POST', body='a=b',
             headers={'Content-Type': 'application/x-www-form-urlencoded'})
     self.assertEqual(h['Content-Type'], 'application/x-www-form-urlencoded')
     correct = ('a=b&oauth_nonce=14205877133089081931378988215&'
                'oauth_timestamp=1378988215&'
                'oauth_version=1.0&'
                'oauth_signature_method=HMAC-SHA1&'
                'oauth_consumer_key=client_key&'
                'oauth_signature=2JAQomgbShqoscqKWBiYQZwWq94%3D')
     self.assertEqual(b, correct)
Пример #24
0
    def test_case_insensitive_headers(self):
        client = Client("client_key")
        # Uppercase
        _, h, _ = client.sign(
            "http://i.b/path",
            http_method="POST",
            body="",
            headers={"Content-Type": "application/x-www-form-urlencoded"},
        )
        self.assertEqual(h["Content-Type"], "application/x-www-form-urlencoded")

        # Lowercase
        _, h, _ = client.sign(
            "http://i.b/path",
            http_method="POST",
            body="",
            headers={"content-type": "application/x-www-form-urlencoded"},
        )
        self.assertEqual(h["content-type"], "application/x-www-form-urlencoded")

        # Capitalized
        _, h, _ = client.sign(
            "http://i.b/path",
            http_method="POST",
            body="",
            headers={"Content-type": "application/x-www-form-urlencoded"},
        )
        self.assertEqual(h["Content-type"], "application/x-www-form-urlencoded")

        # Random
        _, h, _ = client.sign(
            "http://i.b/path",
            http_method="POST",
            body="",
            headers={"conTent-tYpe": "application/x-www-form-urlencoded"},
        )
        self.assertEqual(h["conTent-tYpe"], "application/x-www-form-urlencoded")
Пример #25
0
 def test_plaintext_method(self):
     client = Client(
         "client_key",
         signature_method=SIGNATURE_PLAINTEXT,
         timestamp="1234567890",
         nonce="abc",
         client_secret="foo",
         resource_owner_secret="bar",
     )
     u, h, b = client.sign("http://example.com")
     correct = (
         'OAuth oauth_nonce="abc", oauth_timestamp="1234567890", '
         'oauth_version="1.0", oauth_signature_method="PLAINTEXT", '
         'oauth_consumer_key="client_key", '
         'oauth_signature="foo%26bar"'
     )
     self.assertEqual(h["Authorization"], correct)
Пример #26
0
    def test_register_method(self):
        Client.register_signature_method('PIZZA',
            lambda base_string, client: 'PIZZA')

        self.assertTrue('PIZZA' in Client.SIGNATURE_METHODS)

        client = Client('client_key', signature_method='PIZZA',
            timestamp='1234567890', nonce='abc')

        u, h, b = client.sign('http://example.com')

        self.assertEqual(h['Authorization'], (
            'OAuth oauth_nonce="abc", oauth_timestamp="1234567890", '
            'oauth_version="1.0", oauth_signature_method="PIZZA", '
            'oauth_consumer_key="client_key", '
            'oauth_signature="PIZZA"'
        ))
Пример #27
0
 def test_params_in_query(self):
     client = Client(
         "client_key",
         signature_type=SIGNATURE_TYPE_QUERY,
         timestamp="1378988215",
         nonce="14205877133089081931378988215",
     )
     u, _, _ = client.sign("http://i.b/path", http_method="POST")
     correct = (
         "http://i.b/path?oauth_nonce=14205877133089081931378988215&"
         "oauth_timestamp=1378988215&"
         "oauth_version=1.0&"
         "oauth_signature_method=HMAC-SHA1&"
         "oauth_consumer_key=client_key&"
         "oauth_signature=08G5Snvw%2BgDAzBF%2BCmT5KqlrPKo%3D"
     )
     self.assertEqual(u, correct)
Пример #28
0
    def test_register_method(self):
        Client.register_signature_method("PIZZA", lambda base_string, client: "PIZZA")

        self.assertTrue("PIZZA" in Client.SIGNATURE_METHODS)

        client = Client("client_key", signature_method="PIZZA", timestamp="1234567890", nonce="abc")

        u, h, b = client.sign("http://example.com")

        self.assertEquals(
            h["Authorization"],
            (
                'OAuth oauth_nonce="abc", oauth_timestamp="1234567890", '
                'oauth_version="1.0", oauth_signature_method="PIZZA", '
                'oauth_consumer_key="client_key", '
                'oauth_signature="PIZZA"'
            ),
        )
Пример #29
0
class SignatureOnlyEndpointTest(TestCase):

    def setUp(self):
        self.validator = MagicMock(wraps=RequestValidator())
        self.validator.check_client_key.return_value = True
        self.validator.allowed_signature_methods = ['HMAC-SHA1']
        self.validator.get_client_secret.return_value = 'bar'
        self.validator.timestamp_lifetime = 600
        self.validator.validate_client_key.return_value = True
        self.validator.validate_timestamp_and_nonce.return_value = True
        self.validator.dummy_client = 'dummy'
        self.validator.dummy_secret = 'dummy'
        self.endpoint = SignatureOnlyEndpoint(self.validator)
        self.client = Client('foo', client_secret='bar')
        self.uri, self.headers, self.body = self.client.sign(
                'https://i.b/protected_resource')

    def test_missing_parameters(self):
        v, r = self.endpoint.validate_request(
                self.uri)
        self.assertFalse(v)

    def test_validate_client_key(self):
        self.validator.validate_client_key.return_value = False
        v, r = self.endpoint.validate_request(
                self.uri, headers=self.headers)
        self.assertFalse(v)

    def test_validate_signature(self):
        client = Client('foo')
        _, headers, _ = client.sign(self.uri + '/extra')
        v, r = self.endpoint.validate_request(
                self.uri, headers=headers)
        self.assertFalse(v)

    def test_valid_request(self):
        v, r = self.endpoint.validate_request(
                self.uri, headers=self.headers)
        self.assertTrue(v)
        self.validator.validate_timestamp_and_nonce.assert_called_once_with(
             self.client.client_key, ANY, ANY, ANY)
Пример #30
0
 def test_params_in_body(self):
     client = Client(
         "client_key",
         signature_type=SIGNATURE_TYPE_BODY,
         timestamp="1378988215",
         nonce="14205877133089081931378988215",
     )
     _, h, b = client.sign(
         "http://i.b/path",
         http_method="POST",
         body="a=b",
         headers={"Content-Type": "application/x-www-form-urlencoded"},
     )
     self.assertEqual(h["Content-Type"], "application/x-www-form-urlencoded")
     correct = (
         "a=b&oauth_nonce=14205877133089081931378988215&"
         "oauth_timestamp=1378988215&"
         "oauth_version=1.0&"
         "oauth_signature_method=HMAC-SHA1&"
         "oauth_consumer_key=client_key&"
         "oauth_signature=2JAQomgbShqoscqKWBiYQZwWq94%3D"
     )
     self.assertEqual(b, correct)
Пример #31
0
 def test_sign_body(self):
     client = Client('client_key')
     _, h, b = client.sign('http://i.b/path', http_method='POST', body='',
             headers={'Content-Type': 'application/x-www-form-urlencoded'})
     self.assertEqual(h['Content-Type'], 'application/x-www-form-urlencoded')
Пример #32
0
class ResourceEndpointTest(TestCase):
    def setUp(self):
        self.validator = MagicMock(wraps=RequestValidator())
        self.validator.check_client_key.return_value = True
        self.validator.check_access_token.return_value = True
        self.validator.allowed_signature_methods = ['HMAC-SHA1']
        self.validator.get_client_secret.return_value = 'bar'
        self.validator.get_access_token_secret.return_value = 'secret'
        self.validator.timestamp_lifetime = 600
        self.validator.validate_client_key.return_value = True
        self.validator.validate_access_token.return_value = True
        self.validator.validate_timestamp_and_nonce.return_value = True
        self.validator.validate_realms.return_value = True
        self.validator.dummy_client = 'dummy'
        self.validator.dummy_secret = 'dummy'
        self.validator.dummy_access_token = 'dummy'
        self.endpoint = ResourceEndpoint(self.validator)
        self.client = Client('foo',
                             client_secret='bar',
                             resource_owner_key='token',
                             resource_owner_secret='secret')
        self.uri, self.headers, self.body = self.client.sign(
            'https://i.b/protected_resource')

    def test_missing_parameters(self):
        self.validator.check_access_token.return_value = False
        v, r = self.endpoint.validate_protected_resource_request(self.uri)
        self.assertFalse(v)

    def test_check_access_token(self):
        self.validator.check_access_token.return_value = False
        v, r = self.endpoint.validate_protected_resource_request(
            self.uri, headers=self.headers)
        self.assertFalse(v)

    def test_validate_client_key(self):
        self.validator.validate_client_key.return_value = False
        v, r = self.endpoint.validate_protected_resource_request(
            self.uri, headers=self.headers)
        self.assertFalse(v)
        # the validator log should have `False` values
        self.assertFalse(r.validator_log['client'])
        self.assertTrue(r.validator_log['realm'])
        self.assertTrue(r.validator_log['resource_owner'])
        self.assertTrue(r.validator_log['signature'])

    def test_validate_access_token(self):
        self.validator.validate_access_token.return_value = False
        v, r = self.endpoint.validate_protected_resource_request(
            self.uri, headers=self.headers)
        self.assertFalse(v)
        # the validator log should have `False` values
        self.assertTrue(r.validator_log['client'])
        self.assertTrue(r.validator_log['realm'])
        self.assertFalse(r.validator_log['resource_owner'])
        self.assertTrue(r.validator_log['signature'])

    def test_validate_realms(self):
        self.validator.validate_realms.return_value = False
        v, r = self.endpoint.validate_protected_resource_request(
            self.uri, headers=self.headers)
        self.assertFalse(v)
        # the validator log should have `False` values
        self.assertTrue(r.validator_log['client'])
        self.assertFalse(r.validator_log['realm'])
        self.assertTrue(r.validator_log['resource_owner'])
        self.assertTrue(r.validator_log['signature'])

    def test_validate_signature(self):
        client = Client('foo',
                        resource_owner_key='token',
                        resource_owner_secret='secret')
        _, headers, _ = client.sign(self.uri + '/extra')
        v, r = self.endpoint.validate_protected_resource_request(
            self.uri, headers=headers)
        self.assertFalse(v)
        # the validator log should have `False` values
        self.assertTrue(r.validator_log['client'])
        self.assertTrue(r.validator_log['realm'])
        self.assertTrue(r.validator_log['resource_owner'])
        self.assertFalse(r.validator_log['signature'])

    def test_valid_request(self):
        v, r = self.endpoint.validate_protected_resource_request(
            self.uri, headers=self.headers)
        self.assertTrue(v)
        self.validator.validate_timestamp_and_nonce.assert_called_once_with(
            self.client.client_key,
            ANY,
            ANY,
            ANY,
            access_token=self.client.resource_owner_key)
        # everything in the validator_log should be `True`
        self.assertTrue(all(r.validator_log.items()))
Пример #33
0
 def test_client_realm_sign_with_default_realm(self):
     client = Client("client-key", realm="moo-realm")
     self.assertEqual(client.realm, "moo-realm")
     uri, header, body = client.sign("http://example-uri")
     self.assertTrue(
         header["Authorization"].startswith('OAuth realm="moo-realm",'))
Пример #34
0
class OAuth1(AuthBase):
    """Signs the request using OAuth 1 (RFC5849)"""
    def __init__(self,
                 client_key,
                 client_secret=None,
                 resource_owner_key=None,
                 resource_owner_secret=None,
                 callback_uri=None,
                 signature_method=SIGNATURE_HMAC,
                 signature_type=SIGNATURE_TYPE_AUTH_HEADER,
                 rsa_key=None,
                 verifier=None):

        try:
            signature_type = signature_type.upper()
        except AttributeError:
            pass

        self.client = Client(client_key, client_secret, resource_owner_key,
                             resource_owner_secret, callback_uri,
                             signature_method, signature_type, rsa_key,
                             verifier)

    def __call__(self, r):
        """Add OAuth parameters to the request.

        Parameters may be included from the body if the content-type is
        urlencoded, if no content type is set an educated guess is made.
        """
        contenttype = r.headers.get('Content-Type', None)
        # extract_params will not give params unless the body is a properly
        # formatted string, a dictionary or a list of 2-tuples.
        decoded_body = extract_params(r.data)
        if contenttype == None and decoded_body != None:
            # extract_params can only check the present r.data and does not know
            # of r.files, thus an extra check is performed. We know that
            # if files are present the request will not have
            # Content-type: x-www-form-urlencoded. We guess it will have
            # a mimetype of multipart/form-encoded and if this is not the case
            # we assume the correct header will be set later.
            if r.files:
                # Omit body data in the signing and since it will always
                # be empty (cant add paras to body if multipart) and we wish
                # to preserve body.
                r.headers['Content-Type'] = 'multipart/form-encoded'
                r.url, r.headers, _ = self.client.sign(unicode(r.url),
                                                       unicode(r.method), None,
                                                       r.headers)
            else:
                # Normal signing
                r.headers['Content-Type'] = 'application/x-www-form-urlencoded'
                r.url, r.headers, r.data = self.client.sign(
                    unicode(r.url), unicode(r.method), r.data, r.headers)

            # Having the authorization header, key or value, in unicode will
            # result in UnicodeDecodeErrors when the request is concatenated
            # by httplib. This can easily be seen when attaching files.
            # Note that simply encoding the value is not enough since Python
            # saves the type of first key set. Thus we remove and re-add.
            # >>> d = {u'a':u'foo'}
            # >>> d['a'] = 'foo'
            # >>> d
            # { u'a' : 'foo' }
            u_header = unicode('Authorization')
            if u_header in r.headers:
                auth_header = r.headers[u_header].encode('utf-8')
                del r.headers[u_header]
                r.headers['Authorization'] = auth_header

            return r
Пример #35
0
 def test_validate_signature(self):
     client = Client('foo', callback_uri='https://c.b/cb')
     _, headers, _ = client.sign(self.uri + '/extra')
     u, h, b, s = self.endpoint.create_request_token_response(
         self.uri, headers=headers)
     self.assertEqual(s, 401)
Пример #36
0
class RequestTokenEndpointTest(TestCase):
    def setUp(self):
        self.validator = MagicMock(wraps=RequestValidator())
        self.validator.check_client_key.return_value = True
        self.validator.allowed_signature_methods = ['HMAC-SHA1']
        self.validator.get_client_secret.return_value = 'bar'
        self.validator.get_default_realms.return_value = ['foo']
        self.validator.timestamp_lifetime = 600
        self.validator.check_realms.return_value = True
        self.validator.validate_client_key.return_value = True
        self.validator.validate_requested_realms.return_value = True
        self.validator.validate_redirect_uri.return_value = True
        self.validator.validate_timestamp_and_nonce.return_value = True
        self.validator.dummy_client = 'dummy'
        self.validator.dummy_secret = 'dummy'
        self.validator.save_request_token = MagicMock()
        self.endpoint = RequestTokenEndpoint(self.validator)
        self.client = Client('foo',
                             client_secret='bar',
                             realm='foo',
                             callback_uri='https://c.b/cb')
        self.uri, self.headers, self.body = self.client.sign(
            'https://i.b/request_token')

    def test_check_redirect_uri(self):
        client = Client('foo')
        uri, headers, _ = client.sign(self.uri)
        u, h, b, s = self.endpoint.create_request_token_response(
            uri, headers=headers)
        self.assertEqual(s, 400)
        self.assertIn('invalid_request', b)

    def test_check_realms(self):
        self.validator.check_realms.return_value = False
        u, h, b, s = self.endpoint.create_request_token_response(
            self.uri, headers=self.headers)
        self.assertEqual(s, 400)
        self.assertIn('invalid_request', b)

    def test_validate_client_key(self):
        self.validator.validate_client_key.return_value = False
        u, h, b, s = self.endpoint.create_request_token_response(
            self.uri, headers=self.headers)
        self.assertEqual(s, 401)

    def test_validate_realms(self):
        self.validator.validate_requested_realms.return_value = False
        u, h, b, s = self.endpoint.create_request_token_response(
            self.uri, headers=self.headers)
        self.assertEqual(s, 401)

    def test_validate_redirect_uri(self):
        self.validator.validate_redirect_uri.return_value = False
        u, h, b, s = self.endpoint.create_request_token_response(
            self.uri, headers=self.headers)
        self.assertEqual(s, 401)

    def test_validate_signature(self):
        client = Client('foo', callback_uri='https://c.b/cb')
        _, headers, _ = client.sign(self.uri + '/extra')
        u, h, b, s = self.endpoint.create_request_token_response(
            self.uri, headers=headers)
        self.assertEqual(s, 401)

    def test_valid_request(self):
        u, h, b, s = self.endpoint.create_request_token_response(
            self.uri, headers=self.headers)
        self.assertEqual(s, 200)
        self.assertIn('oauth_token', b)

    def test_uri_provided_realm(self):
        client = Client('foo',
                        callback_uri='https://c.b/cb',
                        client_secret='bar')
        uri = self.uri + '?realm=foo'
        _, headers, _ = client.sign(uri)
        u, h, b, s = self.endpoint.create_request_token_response(
            uri, headers=headers)
        self.assertEqual(s, 200)
        self.assertIn('oauth_token', b)
Пример #37
0
 def test_client_no_realm(self):
     client = Client("client-key")
     uri, header, body = client.sign("http://example-uri")
     self.assertTrue(
         header["Authorization"].startswith('OAuth oauth_nonce='))
Пример #38
0
 def test_validate_signature(self):
     client = Client('foo')
     _, headers, _ = client.sign(self.uri + '/extra')
     v, r = self.endpoint.validate_request(self.uri, headers=headers)
     self.assertFalse(v)
Пример #39
0
class AccessTokenEndpointTest(TestCase):
    def setUp(self):
        self.validator = MagicMock(wraps=RequestValidator())
        self.validator.check_client_key.return_value = True
        self.validator.check_request_token.return_value = True
        self.validator.check_verifier.return_value = True
        self.validator.allowed_signature_methods = ['HMAC-SHA1']
        self.validator.get_client_secret.return_value = 'bar'
        self.validator.get_request_token_secret.return_value = 'secret'
        self.validator.get_realms.return_value = ['foo']
        self.validator.timestamp_lifetime = 600
        self.validator.validate_client_key.return_value = True
        self.validator.validate_request_token.return_value = True
        self.validator.validate_verifier.return_value = True
        self.validator.validate_timestamp_and_nonce.return_value = True
        self.validator.invalidate_request_token.return_value = True
        self.validator.dummy_client = 'dummy'
        self.validator.dummy_secret = 'dummy'
        self.validator.dummy_request_token = 'dummy'
        self.validator.save_access_token = MagicMock()
        self.endpoint = AccessTokenEndpoint(self.validator)
        self.client = Client('foo',
                             client_secret='bar',
                             resource_owner_key='token',
                             resource_owner_secret='secret',
                             verifier='verfier')
        self.uri, self.headers, self.body = self.client.sign(
            'https://i.b/access_token')

    def test_check_request_token(self):
        self.validator.check_request_token.return_value = False
        h, b, s = self.endpoint.create_access_token_response(
            self.uri, headers=self.headers)
        self.assertEqual(s, 400)
        self.assertIn('invalid_request', b)

    def test_check_verifier(self):
        self.validator.check_verifier.return_value = False
        h, b, s = self.endpoint.create_access_token_response(
            self.uri, headers=self.headers)
        self.assertEqual(s, 400)
        self.assertIn('invalid_request', b)

    def test_validate_client_key(self):
        self.validator.validate_client_key.return_value = False
        h, b, s = self.endpoint.create_access_token_response(
            self.uri, headers=self.headers)
        self.assertEqual(s, 401)

    def test_validate_request_token(self):
        self.validator.validate_request_token.return_value = False
        h, b, s = self.endpoint.create_access_token_response(
            self.uri, headers=self.headers)
        self.assertEqual(s, 401)

    def test_validate_verifier(self):
        self.validator.validate_verifier.return_value = False
        h, b, s = self.endpoint.create_access_token_response(
            self.uri, headers=self.headers)
        self.assertEqual(s, 401)

    def test_validate_signature(self):
        client = Client('foo',
                        resource_owner_key='token',
                        resource_owner_secret='secret',
                        verifier='verfier')
        _, headers, _ = client.sign(self.uri + '/extra')
        h, b, s = self.endpoint.create_access_token_response(self.uri,
                                                             headers=headers)
        self.assertEqual(s, 401)

    def test_valid_request(self):
        h, b, s = self.endpoint.create_access_token_response(
            self.uri, headers=self.headers)
        self.assertEqual(s, 200)
        self.assertIn('oauth_token', b)
        self.validator.validate_timestamp_and_nonce.assert_called_once_with(
            self.client.client_key,
            ANY,
            ANY,
            ANY,
            request_token=self.client.resource_owner_key)
        self.validator.invalidate_request_token.assert_called_once_with(
            self.client.client_key, self.client.resource_owner_key, ANY)
Пример #40
0
class IntegrationTestLTI(testutil.TestCase):
    """
    Integration tests for third_party_auth LTI auth providers
    """
    def setUp(self):
        super(IntegrationTestLTI, self).setUp()  # lint-amnesty, pylint: disable=super-with-arguments
        self.hostname = 'testserver'
        self.client.defaults['SERVER_NAME'] = self.hostname
        self.url_prefix = 'http://{}'.format(self.hostname)
        self.configure_lti_provider(
            name='Other Tool Consumer 1',
            enabled=True,
            lti_consumer_key='other1',
            lti_consumer_secret='secret1',
            lti_max_timestamp_age=10,
        )
        self.configure_lti_provider(
            name='LTI Test Tool Consumer',
            enabled=True,
            lti_consumer_key=LTI_CONSUMER_KEY,
            lti_consumer_secret=LTI_CONSUMER_SECRET,
            lti_max_timestamp_age=10,
        )
        self.configure_lti_provider(
            name='Tool Consumer with Secret in Settings',
            enabled=True,
            lti_consumer_key=OTHER_LTI_CONSUMER_KEY,
            lti_consumer_secret='',
            lti_max_timestamp_age=10,
        )
        self.lti = Client(
            client_key=LTI_CONSUMER_KEY,
            client_secret=LTI_CONSUMER_SECRET,
            signature_type=SIGNATURE_TYPE_BODY,
        )

    def test_lti_login(self):
        # The user initiates a login from an external site
        (uri, _headers, body) = self.lti.sign(
            uri=self.url_prefix + LTI_TPA_LOGIN_URL,
            http_method='POST',
            headers={'Content-Type': FORM_ENCODED},
            body={
                'user_id':
                LTI_USER_ID,
                'custom_tpa_next':
                '/account/finish_auth/?course_id=my_course_id&enrollment_action=enroll',
            })
        login_response = self.client.post(path=uri,
                                          content_type=FORM_ENCODED,
                                          data=body)
        # The user should be redirected to the registration form
        assert login_response.status_code == 302
        assert login_response['Location'].endswith(reverse('signin_user'))
        register_response = self.client.get(login_response['Location'])
        self.assertContains(register_response,
                            '"currentProvider": "LTI Test Tool Consumer"')
        self.assertContains(register_response, '"errorMessage": null')

        # Now complete the form:
        ajax_register_response = self.client.post(
            reverse('user_api_registration'), {
                'email': EMAIL,
                'name': 'Myself',
                'username': EDX_USER_ID,
                'honor_code': True,
            })
        assert ajax_register_response.status_code == 200
        continue_response = self.client.get(self.url_prefix +
                                            LTI_TPA_COMPLETE_URL)
        # The user should be redirected to the finish_auth view which will enroll them.
        # FinishAuthView.js reads the URL parameters directly from $.url
        assert continue_response.status_code == 302
        assert continue_response[
            'Location'] == '/account/finish_auth/?course_id=my_course_id&enrollment_action=enroll'

        # Now check that we can login again
        self.client.logout()
        self.verify_user_email(EMAIL)
        (uri, _headers,
         body) = self.lti.sign(uri=self.url_prefix + LTI_TPA_LOGIN_URL,
                               http_method='POST',
                               headers={'Content-Type': FORM_ENCODED},
                               body={'user_id': LTI_USER_ID})
        login_2_response = self.client.post(path=uri,
                                            content_type=FORM_ENCODED,
                                            data=body)
        # The user should be redirected to the dashboard
        assert login_2_response.status_code == 302
        assert login_2_response['Location'] == (LTI_TPA_COMPLETE_URL + '?')
        continue_2_response = self.client.get(login_2_response['Location'])
        assert continue_2_response.status_code == 302
        assert continue_2_response['Location'].endswith(reverse('dashboard'))

        # Check that the user was created correctly
        user = User.objects.get(email=EMAIL)
        assert user.username == EDX_USER_ID

    def test_reject_initiating_login(self):
        response = self.client.get(self.url_prefix + LTI_TPA_LOGIN_URL)
        assert response.status_code == 405
        # Not Allowed

    def test_reject_bad_login(self):
        login_response = self.client.post(
            path=self.url_prefix + LTI_TPA_LOGIN_URL,
            content_type=FORM_ENCODED,
            data="invalid=login",
        )
        # The user should be redirected to the login page with an error message
        # (auth_entry defaults to login for this provider)
        assert login_response.status_code == 302
        assert login_response['Location'].endswith(reverse('signin_user'))
        error_response = self.client.get(login_response['Location'])
        self.assertContains(
            error_response,
            'Authentication failed: LTI parameters could not be validated.',
        )

    def test_can_load_consumer_secret_from_settings(self):
        lti = Client(
            client_key=OTHER_LTI_CONSUMER_KEY,
            client_secret=OTHER_LTI_CONSUMER_SECRET,
            signature_type=SIGNATURE_TYPE_BODY,
        )
        (uri, _headers, body) = lti.sign(
            uri=self.url_prefix + LTI_TPA_LOGIN_URL,
            http_method='POST',
            headers={'Content-Type': FORM_ENCODED},
            body={
                'user_id':
                LTI_USER_ID,
                'custom_tpa_next':
                '/account/finish_auth/?course_id=my_course_id&enrollment_action=enroll',
            })
        with self.settings(SOCIAL_AUTH_LTI_CONSUMER_SECRETS={
                OTHER_LTI_CONSUMER_KEY: OTHER_LTI_CONSUMER_SECRET
        }):
            login_response = self.client.post(path=uri,
                                              content_type=FORM_ENCODED,
                                              data=body)
            # The user should be redirected to the registration form
            assert login_response.status_code == 302
            assert login_response['Location'].endswith(reverse('signin_user'))
            register_response = self.client.get(login_response['Location'])
            self.assertContains(
                register_response,
                '"currentProvider": "Tool Consumer with Secret in Settings"',
            )
            self.assertContains(register_response, '"errorMessage": null')