Esempio n. 1
0
    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')
Esempio n. 2
0
    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)
Esempio n. 3
0
    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)
Esempio n. 4
0
    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": "*****@*****.**"
                }]
            })