Example #1
0
    def test_stmt_post_no_scope(self):
        stmt = json.dumps({"actor":{"objectType": "Agent", "mbox":"*****@*****.**", "name":"bob"},
            "verb":{"id": "http://adlnet.gov/expapi/verbs/passed","display": {"en-US":"passed"}},
            "object": {"id":"test_post"}})

        oauth_header_resource_params, access_token = self.perform_oauth_handshake(scope=False)

        oauth_request = OAuthRequest.from_token_and_callback(access_token, http_method='POST',
            http_url='http://testserver/XAPI/statements/', parameters=oauth_header_resource_params)
        signature_method = OAuthSignatureMethod_HMAC_SHA1()
        signature = signature_method.build_signature(oauth_request, self.consumer, access_token)
        oauth_header_resource_params['oauth_signature'] = signature
        
        resp = self.client.post('/XAPI/statements/', data=stmt, content_type="application/json",
            Authorization=oauth_header_resource_params, X_Experience_API_Version="0.95")
        self.assertEqual(resp.status_code, 200)
Example #2
0
    def test_stmt_complex_get(self):
        stmt = Statement.Statement(json.dumps({"actor":{"objectType": "Agent", "mbox":"*****@*****.**", "name":"bob"},
            "verb":{"id": "http://adlnet.gov/expapi/verbs/passed","display": {"en-US":"passed"}},
            "object": {"id":"test_complex_get"}}))
        param = {"object":{"objectType": "Activity", "id":"test_complex_get"}}
        path = "%s?%s" % ('http://testserver/XAPI/statements', urllib.urlencode(param))

        oauth_header_resource_params, access_token = self.perform_oauth_handshake()

        oauth_request = OAuthRequest.from_token_and_callback(access_token, http_method='GET',
            http_url=path, parameters=oauth_header_resource_params)
        signature_method = OAuthSignatureMethod_HMAC_SHA1()
        signature = signature_method.build_signature(oauth_request, self.consumer, access_token)
        oauth_header_resource_params['oauth_signature'] = signature

        resp = self.client.get(path,Authorization=oauth_header_resource_params, X_Experience_API_Version="0.95")        
        self.assertEqual(resp.status_code, 200)
Example #3
0
 def test_stmt_put(self):
     put_guid = str(uuid.uuid4())
     stmt = json.dumps({"actor":{"objectType": "Agent", "mbox":"*****@*****.**", "name":"bill"},
         "verb":{"id": "http://adlnet.gov/expapi/verbs/accessed","display": {"en-US":"accessed"}},
         "object": {"id":"test_put"}})
     param = {"statementId":put_guid}
     path = "%s?%s" % ('http://testserver/XAPI/statements', urllib.urlencode(param))
     
     oauth_header_resource_params, access_token = self.perform_oauth_handshake()
     
     oauth_request = OAuthRequest.from_token_and_callback(access_token, http_method='PUT',
         http_url=path, parameters=oauth_header_resource_params)
     signature_method = OAuthSignatureMethod_HMAC_SHA1()
     signature = signature_method.build_signature(oauth_request, self.consumer, access_token)
     oauth_header_resource_params['oauth_signature'] = signature
     
     # Put statements
     resp = self.client.put(path, data=stmt, content_type="application/json",
         Authorization=oauth_header_resource_params, X_Experience_API_Version="0.95")
     self.assertEqual(resp.status_code, 204)
Example #4
0
    def test_all_error_flows(self):
        # Test request_token without appropriate headers
        resp = self.client.get("/XAPI/OAuth/initiate/", X_Experience_API_Version="0.95")
        self.assertEqual(resp.status_code, 401)
        self.assertIn('WWW-Authenticate', resp._headers['www-authenticate'])
        self.assertIn('OAuth realm="http://localhost:8000/XAPI"', resp._headers['www-authenticate'])
        self.assertEqual(resp.content, 'Invalid request parameters.')

        # TEST REQUEST TOKEN
        oauth_header_request_params = {
            'oauth_consumer_key': self.consumer.key,
            'oauth_signature_method': 'PLAINTEXT',
            'oauth_signature':'%s&' % self.consumer.secret,
            'oauth_timestamp': str(int(time.time())),
            'oauth_nonce': 'requestnonce',
            'oauth_version': '1.0',
            'oauth_callback':'http://example.com/request_token_ready'
        }
        # Test passing scope as form param
        form_data = {
            'scope':'all',
        }               
        request_resp = self.client.get("/XAPI/OAuth/initiate/", Authorization=oauth_header_request_params, data=form_data, X_Experience_API_Version="0.95")
        self.assertEqual(request_resp.status_code, 200)
        self.assertIn('oauth_token_secret=', request_resp.content)
        self.assertIn('oauth_token=', request_resp.content)
        self.assertIn('&oauth_callback_confirmed=true', request_resp.content)
        token = list(models.Token.objects.all())[-1]
        self.assertIn(token.key, request_resp.content)
        self.assertIn(token.secret, request_resp.content)
        self.assertEqual(token.callback, 'http://example.com/request_token_ready')
        self.assertEqual(token.callback_confirmed, True)

        # Test wrong scope
        form_data['scope'] = 'videos'
        scope_resp = self.client.get("/XAPI/OAuth/initiate/", Authorization=oauth_header_request_params, data=form_data, X_Experience_API_Version="0.95")
        self.assertEqual(scope_resp.status_code, 401)
        self.assertEqual(scope_resp.content, 'Resource videos does not exist.')
        form_data['scope'] = 'statements'

        # Test wrong callback
        oauth_header_request_params['oauth_callback'] = 'wrongcallback'
        call_resp = self.client.get("/XAPI/OAuth/initiate/", Authorization=oauth_header_request_params, data=form_data, X_Experience_API_Version="0.95")
        self.assertEqual(call_resp.status_code, 401)
        self.assertEqual(call_resp.content, 'Invalid callback URL.')

        # Test AUTHORIZE
        oauth_auth_params = {'oauth_token': token.key}
        auth_resp = self.client.get("/XAPI/OAuth/authorize/", oauth_auth_params, X_Experience_API_Version="0.95")
        self.assertEqual(auth_resp.status_code, 302)
        self.assertIn('http://testserver/accounts/login/?next=/XAPI/OAuth/authorize/%3F', auth_resp['Location'])
        self.assertIn(token.key, auth_resp['Location'])
        self.client.login(username='******', password='******')
        self.assertEqual(token.is_approved, False)
        auth_resp = self.client.get("/XAPI/OAuth/authorize/", oauth_auth_params, X_Experience_API_Version="0.95")
        self.assertEqual(auth_resp.status_code, 200) # Show return/display OAuth authorized view
        oauth_auth_params['authorize_access'] = 1
        auth_post = self.client.post("/XAPI/OAuth/authorize/", oauth_auth_params, X_Experience_API_Version="0.95")
        self.assertEqual(auth_post.status_code, 302)
        self.assertIn('http://example.com/request_token_ready?oauth_verifier=', auth_post['Location'])
        token = list(models.Token.objects.all())[-1]
        self.assertIn(token.key, auth_post['Location'])
        self.assertEqual(token.is_approved, True)

        # Test without session param (previous POST removed it)
        auth_post = self.client.post("/XAPI/OAuth/authorize/", oauth_auth_params, X_Experience_API_Version="0.95")
        self.assertEqual(auth_post.status_code, 401)
        self.assertEqual(auth_post.content, 'Action not allowed.')

        # Test fake access
        auth_resp = self.client.get("/XAPI/OAuth/authorize/", oauth_auth_params, X_Experience_API_Version="0.95")
        oauth_auth_params['authorize_access'] = 0
        auth_resp = self.client.post("/XAPI/OAuth/authorize/", oauth_auth_params, X_Experience_API_Version="0.95")
        self.assertEqual(auth_resp.status_code, 302)
        self.assertEqual(auth_resp['Location'], 'http://example.com/request_token_ready?error=Access%20not%20granted%20by%20user.')
        self.client.logout()

        # Test ACCESS TOKEN
        oauth_header_access_params = {
            'oauth_consumer_key': self.consumer.key,
            'oauth_token': token.key,
            'oauth_signature_method': 'PLAINTEXT',
            'oauth_signature':'%s&%s' % (self.consumer.secret, token.secret),
            'oauth_timestamp': str(int(time.time())),
            'oauth_nonce': 'accessnonce',
            'oauth_version': '1.0',
            'oauth_verifier': token.verifier
        }
        access_resp = self.client.get("/XAPI/OAuth/token/", Authorization=oauth_header_access_params, X_Experience_API_Version="0.95")
        self.assertEqual(access_resp.status_code, 200)
        access_token = list(models.Token.objects.filter(token_type=models.Token.ACCESS))[-1]
        self.assertIn(access_token.key, access_resp.content)
        self.assertEqual(access_token.user.username, u'jane')

        # Test same Nonce
        access_resp = self.client.get("/XAPI/OAuth/token/", Authorization=oauth_header_access_params, X_Experience_API_Version="0.95")
        self.assertEqual(access_resp.status_code, 401)
        self.assertEqual(access_resp.content, 'Nonce already used: accessnonce')

        # Test missing/invalid verifier
        oauth_header_access_params['oauth_nonce'] = 'yetanotheraccessnonce'
        oauth_header_access_params['oauth_verifier'] = 'invalidverifier'
        access_resp = self.client.get("/XAPI/OAuth/token/", Authorization=oauth_header_access_params, X_Experience_API_Version="0.95")
        self.assertEqual(access_resp.status_code, 401)
        self.assertEqual(access_resp.content, 'Consumer key or token key does not match. Make sure your request token is approved. Check your verifier too if you use OAuth 1.0a.')     
        oauth_header_access_params['oauth_verifier'] = token.verifier

        # Test token not approved
        oauth_header_access_params['oauth_nonce'] = 'anotheraccessnonce'
        token.is_approved = False
        token.save()
        access_resp = self.client.get("/XAPI/OAuth/token/", Authorization=oauth_header_access_params, X_Experience_API_Version="0.95")
        self.assertEqual(access_resp.status_code, 401)
        self.assertEqual(access_resp.content, 'Consumer key or token key does not match. Make sure your request token is approved. Check your verifier too if you use OAuth 1.0a.')

        # Test ACCESS RESOURCE
        oauth_header_resource_params = {
            'oauth_consumer_key': self.consumer.key,
            'oauth_token': access_token.key,
            'oauth_signature_method': 'HMAC-SHA1',
            'oauth_timestamp': str(int(time.time())),
            'oauth_nonce': 'accessresourcenonce',
            'oauth_version': '1.0'
        }
        oauth_request = OAuthRequest.from_token_and_callback(access_token,
            http_url='http://testserver/XAPI/statements/', parameters=oauth_header_resource_params)
        signature_method = OAuthSignatureMethod_HMAC_SHA1()
        signature = signature_method.build_signature(oauth_request, self.consumer, access_token)
        oauth_header_resource_params['oauth_signature'] = signature
        resp = self.client.get("/XAPI/statements/", Authorization=oauth_header_resource_params, X_Experience_API_Version="0.95")
        self.assertEqual(resp.status_code, 200)
        self.assertEqual(resp.content, '{"statements": [], "more": ""}')

        # Test wrong signature
        oauth_header_resource_params['oauth_signature'] = 'wrongsignature'
        oauth_header_resource_params['oauth_nonce'] = 'anotheraccessresourcenonce'
        resp = self.client.get("/XAPI/statements/", Authorization=oauth_header_resource_params, X_Experience_API_Version="0.95")
        self.assertEqual(resp.status_code, 401)
        self.assertIn('Invalid signature.', resp.content)

        # Test wrong params - will not return 'Invalid request parameters.' like oauth example states
        # because there is no Authorization header. With no auth header the lrs reads as no auth supplied at all
        resp = self.client.get("/XAPI/statements/", X_Experience_API_Version="0.95")
        self.assertEqual(resp.status_code, 401)
        self.assertEqual(resp.content, 'Auth is enabled but no authentication was sent with the request.')

        # Test revoke access
        access_token.delete()
        oauth_header_resource_params['oauth_signature'] = signature
        oauth_header_resource_params['oauth_nonce'] = 'yetanotheraccessresourcenonce'
        resp = self.client.get("/XAPI/statements/", Authorization=oauth_header_resource_params, X_Experience_API_Version="0.95")
        self.assertEqual(resp.status_code, 401)
        self.assertIn('Invalid access token', resp.content)