def test_uploaded_badge_returns_coerced_json(self): setup_basic_1_0() setup_resources([ {'url': OPENBADGES_CONTEXT_V1_URI, 'filename': 'v1_context.json'}, {'url': OPENBADGES_CONTEXT_V2_URI, 'response_body': json.dumps(OPENBADGES_CONTEXT_V2_DICT)} ]) self.setup_user(email='*****@*****.**', authenticate=True) post_input = { 'url': 'http://a.com/instance' } with mock.patch('mainsite.blacklist.api_query_is_in_blacklist', new=lambda a, b: False): response = self.client.post( '/v1/earner/badges', post_input ) self.assertEqual(response.status_code, 201) uploaded_badge = response.data assertion_entityid = uploaded_badge.get('id') assertion_url = '/public/assertions/{}?v=2_0'.format(assertion_entityid) response = self.client.get(assertion_url) self.assertEqual(response.status_code, 200) coerced_assertion = response.data assertion = BadgeInstance.objects.get(entity_id=assertion_entityid) self.assertDictEqual(coerced_assertion, assertion.get_json(obi_version="2_0")) # We should not change the declared jsonld ID of the requested object self.assertEqual(coerced_assertion.get('id'), 'http://a.com/instance')
def test_pending_assertion_returns_404(self): setup_resources([ { 'url': 'http://a.com/assertion-embedded1', 'filename': '2_0_assertion_embedded_badgeclass.json' }, { 'url': OPENBADGES_CONTEXT_V2_URI, 'response_body': json.dumps(OPENBADGES_CONTEXT_V2_DICT) }, { 'url': 'http://a.com/badgeclass_image', 'filename': "unbaked_image.png", 'mode': 'rb' }, ]) unverified_email = '*****@*****.**' test_user = self.setup_user(email='*****@*****.**', authenticate=True) CachedEmailAddress.objects.add_email(test_user, unverified_email) post_input = {"url": "http://a.com/assertion-embedded1"} with mock.patch('mainsite.blacklist.api_query_is_in_blacklist', new=lambda a, b: False): post_resp = self.client.post('/v2/backpack/import', post_input, format='json') assertion = BadgeInstance.objects.first() self.client.logout() get_resp = self.client.get('/public/assertions/{}'.format( assertion.entity_id)) self.assertEqual(get_resp.status_code, 404)
def test_submit_badges_with_intragraph_references(self): setup_resources([ { 'url': 'http://a.com/assertion-embedded1', 'filename': '2_0_assertion_embedded_badgeclass.json' }, { 'url': OPENBADGES_CONTEXT_V2_URI, 'response_body': json.dumps(OPENBADGES_CONTEXT_V2_DICT) }, { 'url': 'http://a.com/badgeclass_image', 'filename': "unbaked_image.png", 'mode': 'rb' }, ]) self.setup_user(email='*****@*****.**', authenticate=True) assertion = { "@context": 'https://w3id.org/openbadges/v2', "id": 'http://a.com/assertion-embedded1', "type": "Assertion", } post_input = {'assertion': assertion} with mock.patch('mainsite.blacklist.api_query_is_in_blacklist', new=lambda a, b: False): response = self.client.post('/bcv1/assertions', post_input, format='json') self.assertEqual(response.status_code, 201)
def _perform_registration_and_authentication(self, **kwargs): requested_scopes = [ "https://purl.imsglobal.org/spec/ob/v2p1/scope/assertion.readonly", "https://purl.imsglobal.org/spec/ob/v2p1/scope/assertion.create", "https://purl.imsglobal.org/spec/ob/v2p1/scope/profile.readonly", ] registration_data = { "client_name": "Badge Issuer", "client_uri": "https://issuer.example.com", "logo_uri": "https://issuer.example.com/logo.png", "tos_uri": "https://issuer.example.com/terms-of-service", "policy_uri": "https://issuer.example.com/privacy-policy", "software_id": "13dcdc83-fc0d-4c8d-9159-6461da297388", "software_version": "54dfc83-fc0d-4c8d-9159-6461da297388", "redirect_uris": ["https://issuer.example.com/o/redirect"], "token_endpoint_auth_method": "client_secret_basic", "grant_types": ["authorization_code", "refresh_token"], "response_types": ["code"], "scope": ' '.join(requested_scopes) } user = self.setup_user(email='*****@*****.**', authenticate=True) response = self.client.post('/o/register', registration_data) client_id = response.data['client_id'] for required_property in [ 'client_id', 'client_secret', 'client_id_issued_at', 'client_secret_expires_at' ]: self.assertIn(required_property, response.data) # At this point the client would trigger the user's agent to make a GET request to the authorize UI endpooint # which would in turn make sure the user is authenticated and then trigger a post to the API to obtain a # success URL that includes a code. Then the user is redirected to that success URL so the client can continue. url = '/o/authorize' verifier = ''.join( random.choices(string.ascii_lowercase + string.digits, k=16)) data = { "allow": True, "response_type": "code", "client_id": response.data['client_id'], "redirect_uri": registration_data['redirect_uris'][0], "scopes": requested_scopes, "state": "", "code_challenge": base64.urlsafe_b64encode( hashlib.sha256( verifier.encode()).digest()).decode().rstrip('='), "code_challenge_method": 'S256' } response = self.client.post(url, data=data) self.assertEqual(response.status_code, 200) self.assertTrue(response.data['success_url'].startswith( registration_data['redirect_uris'][0])) url = parse.urlparse(response.data['success_url']) code = parse.parse_qs(url.query)['code'][0] # Now the client has retrieved the code and will attempt to exchange it for an access token. if kwargs.get('pkce_fail') is True: verifier = "swisscheese" data = { 'grant_type': 'authorization_code', 'code': code, 'client_id': client_id, 'redirect_uri': registration_data['redirect_uris'][0], 'scope': ' '.join(requested_scopes), 'code_verifier': verifier } response = self.client.post('/o/token', data=data) if kwargs.get('pkce_fail') is True: self.assertEqual(response.status_code, 400) return self.assertEqual(response.status_code, 200) self.client.logout() token_data = json.loads(response.content) self.assertTrue('refresh_token' in token_data) access_token = token_data['access_token'] test_issuer_user = self.setup_user(authenticate=False) test_issuer = self.setup_issuer(owner=test_issuer_user) test_badgeclass = self.setup_badgeclass(issuer=test_issuer) with mock.patch('mainsite.blacklist.api_query_is_in_blacklist', new=lambda a, b: False): assertion = test_badgeclass.issue(user.email, notify=False) # Get the assertion self.client.credentials( HTTP_AUTHORIZATION='Bearer {}'.format(access_token)) response = self.client.get('/bcv1/assertions') self.assertEqual(response.status_code, 200) REMOTE_BADGE_URI = 'http://a.com/assertion-embedded1' setup_resources([ { 'url': REMOTE_BADGE_URI, 'filename': '2_0_assertion_embedded_badgeclass.json' }, { 'url': OPENBADGES_CONTEXT_V2_URI, 'response_body': json.dumps(OPENBADGES_CONTEXT_V2_DICT) }, { 'url': 'http://a.com/badgeclass_image', 'filename': "unbaked_image.png", 'mode': 'rb' }, ]) # Post new external assertion assertion.save() expected_status = { "error": None, "statusCode": 200, "statusText": 'OK' } with mock.patch('mainsite.blacklist.api_query_is_in_blacklist', new=lambda a, b: False): response = self.client.post('/bcv1/assertions', data={'id': REMOTE_BADGE_URI}, format='json') self.assertEqual(response.status_code, 201) self.assertJSONEqual(force_text(response.content), {"status": expected_status}) response = self.client.get('/bcv1/assertions') self.assertEqual(response.status_code, 200) self.assertJSONEqual(force_text(json.dumps(response.data['status'])), expected_status) self.assertEqual(len(response.data['results']), 2) ids = [ response.data['results'][0]['id'], response.data['results'][1]['id'] ] self.assertTrue(assertion.jsonld_id in ids) self.assertTrue(REMOTE_BADGE_URI in ids) for result in response.data['results']: self.assertEqual(result['@context'], OPENBADGES_CONTEXT_V2_URI) self.assertEqual(result['type'], 'Assertion') response = self.client.get('/bcv1/profile') self.assertEqual(response.status_code, 200) self.assertJSONEqual( force_text(response.content), { "status": expected_status, "results": [{ "@context": "https://w3id.org/openbadges/v2", "name": "firsty lastington", "email": "*****@*****.**" }] })