Ejemplo n.º 1
0
    def test_validate_endorsement_as_input(self):
        set_up_context_mock()
        self.set_up_resources()

        for resource in [self.assertion, self.badgeclass, self.issuer, self.endorsement, self.endorsement_issuer]:
            responses.add(responses.GET, resource['id'], json=resource)
        set_up_image_mock(self.badgeclass['image'])

        results = verify(self.endorsement['id'])
        self.assertTrue(results['report']['valid'])
        self.assertTrue(len(results['graph']), 2)
Ejemplo n.º 2
0
    def test_validate_linked_endorsement(self):
        set_up_context_mock()
        self.set_up_resources()

        for resource in [self.assertion, self.badgeclass, self.issuer, self.endorsement, self.endorsement_issuer]:
            responses.add(responses.GET, resource['id'], json=resource)
        set_up_image_mock(self.badgeclass['image'])

        results = verify(self.assertion['id'])
        self.assertTrue(results['report']['valid'])
        self.assertEqual(len(results['graph']), 5, "The graph now contains all five resources.")
Ejemplo n.º 3
0
    def get_or_create_assertion(cls, url=None, imagefile=None, assertion=None, created_by=None):

        # distill 3 optional arguments into one query argument
        query = (url, imagefile, assertion)
        query = filter(lambda v: v is not None, query)
        if len(query) != 1:
            raise ValueError("Must provide only 1 of: url, imagefile or assertion_obo")
        query = query[0]

        if created_by:
            badgecheck_recipient_profile = {
                'email': created_by.all_recipient_identifiers
            }
        else:
            badgecheck_recipient_profile = None

        try:
            response = openbadges.verify(query, recipient_profile=badgecheck_recipient_profile, **cls.badgecheck_options())
        except ValueError as e:
            raise ValidationError([{'name': "INVALID_BADGE", 'description': str(e)}])

        report = response.get('report', {})
        is_valid = report.get('valid')

        if not is_valid:
            if report.get('errorCount', 0) > 0:
                errors = list(cls.translate_errors(report.get('messages', [])))
            else:
                errors = [{'name': "UNABLE_TO_VERIFY", 'description': "Unable to verify the assertion"}]
            raise ValidationError(errors)

        graph = response.get('graph', [])

        assertion_obo = first_node_match(graph, dict(type="Assertion"))
        if not assertion_obo:
            raise ValidationError([{'name': "ASSERTION_NOT_FOUND", 'description': "Unable to find an assertion"}])

        badgeclass_obo = first_node_match(graph, dict(id=assertion_obo.get('badge', None)))
        if not badgeclass_obo:
            raise ValidationError([{'name': "ASSERTION_NOT_FOUND", 'description': "Unable to find a badgeclass"}])

        issuer_obo = first_node_match(graph, dict(id=badgeclass_obo.get('issuer', None)))
        if not issuer_obo:
            raise ValidationError([{'name': "ASSERTION_NOT_FOUND", 'description': "Unable to find an issuer"}])

        original_json = response.get('input').get('original_json', {})

        recipient_identifier = report.get('recipientProfile', {}).get('email', None)

        with transaction.atomic():
            issuer, issuer_created = Issuer.objects.get_or_create_from_ob2(issuer_obo, original_json=original_json.get(issuer_obo.get('id')))
            badgeclass, badgeclass_created = BadgeClass.objects.get_or_create_from_ob2(issuer, badgeclass_obo, original_json=original_json.get(badgeclass_obo.get('id')))
            return BadgeInstance.objects.get_or_create_from_ob2(badgeclass, assertion_obo, recipient_identifier=recipient_identifier, original_json=original_json.get(assertion_obo.get('id')))
Ejemplo n.º 4
0
    def get_assertion_obo(cls, badge_instance):
        try:
            response = openbadges.verify(badge_instance.source_url, recipient_profile=None, **cls.badgecheck_options())
        except ValueError as e:
            return None

        report = response.get('report', {})
        is_valid = report.get('valid')

        if is_valid:
            graph = response.get('graph', [])

            assertion_obo = first_node_match(graph, dict(type="Assertion"))
            if assertion_obo:
                return assertion_obo
Ejemplo n.º 5
0
    def post(self, request, **kwargs):
        entity_id = request.data.get('entity_id')
        badge_instance = self.get_object(entity_id)

        #only do badgecheck verify if not a local badge
        if (badge_instance.source_url):
            recipient_profile = {
                badge_instance.recipient_type: badge_instance.recipient_identifier
            }

            badge_check_options = {
                'include_original_json': True,
                'use_cache': True,
            }

            try:
                response = openbadges.verify(badge_instance.jsonld_id, recipient_profile=recipient_profile, **badge_check_options)
            except ValueError as e:
                raise ValidationError([{'name': "INVALID_BADGE", 'description': str(e)}])

            graph = response.get('graph', [])

            revoked_obo = first_node_match(graph, dict(revoked=True))

            if bool(revoked_obo):
                instance = BadgeInstance.objects.get(source_url=revoked_obo['id'])
                instance.revoke(revoked_obo.get('revocationReason', 'Badge is revoked'))

            else:
                report = response.get('report', {})
                is_valid = report.get('valid')

                if not is_valid:
                    if report.get('errorCount', 0) > 0:
                        errors = [{'name': 'UNABLE_TO_VERIFY', 'description': 'Unable to verify the assertion'}]
                    raise ValidationError(errors)

                validation_subject = report.get('validationSubject')

                badge_instance_obo = first_node_match(graph, dict(id=validation_subject))
                if not badge_instance_obo:
                    raise ValidationError([{'name': 'ASSERTION_NOT_FOUND', 'description': 'Unable to find an badge instance'}])

                badgeclass_obo = first_node_match(graph, dict(id=badge_instance_obo.get('badge', None)))
                if not badgeclass_obo:
                    raise ValidationError([{'name': 'ASSERTION_NOT_FOUND', 'description': 'Unable to find a badgeclass'}])

                issuer_obo = first_node_match(graph, dict(id=badgeclass_obo.get('issuer', None)))
                if not issuer_obo:
                    raise ValidationError([{'name': 'ASSERTION_NOT_FOUND', 'description': 'Unable to find an issuer'}])

                original_json = response.get('input').get('original_json', {})

                BadgeInstance.objects.update_from_ob2(
                    badge_instance.badgeclass,
                    badge_instance_obo,
                    badge_instance.recipient_identifier,
                    badge_instance.recipient_type,
                    original_json.get(badge_instance_obo.get('id', ''), None)
                )

                badge_instance.rebake(save=True)

                BadgeClass.objects.update_from_ob2(
                    badge_instance.issuer,
                    badgeclass_obo,
                    original_json.get(badgeclass_obo.get('id', ''), None)
                )

                Issuer.objects.update_from_ob2(
                    issuer_obo,
                    original_json.get(issuer_obo.get('id', ''), None)
                )
        result = self.get_object(entity_id).get_json(expand_badgeclass=True, expand_issuer=True)

        return Response(BaseSerializerV2.response_envelope([result], True, 'OK'), status=status.HTTP_200_OK)
Ejemplo n.º 6
0
    def get_or_create_assertion(cls,
                                url=None,
                                imagefile=None,
                                assertion=None,
                                created_by=None):

        # distill 3 optional arguments into one query argument
        query = (url, imagefile, assertion)
        query = filter(lambda v: v is not None, query)
        if len(query) != 1:
            raise ValueError(
                "Must provide only 1 of: url, imagefile or assertion_obo")
        query = query[0]

        if created_by:
            emails = [d.email for d in created_by.email_items.all()]
            badgecheck_recipient_profile = {
                'email':
                emails + [v.email for v in created_by.cached_email_variants()],
                'telephone':
                created_by.cached_verified_phone_numbers(),
                'url':
                created_by.cached_verified_urls()
            }
        else:
            badgecheck_recipient_profile = None

        try:
            if type(query) is dict:
                try:
                    query = json.dumps(query)
                except (TypeError, ValueError):
                    raise ValidationError("Could not parse dict to json")
            response = openbadges.verify(
                query,
                recipient_profile=badgecheck_recipient_profile,
                **cls.badgecheck_options())
        except ValueError as e:
            raise ValidationError([{
                'name': "INVALID_BADGE",
                'description': str(e)
            }])

        report = response.get('report', {})
        is_valid = report.get('valid')

        if not is_valid:
            if report.get('errorCount', 0) > 0:
                errors = list(cls.translate_errors(report.get('messages', [])))
            else:
                errors = [{
                    'name': "UNABLE_TO_VERIFY",
                    'description': "Unable to verify the assertion"
                }]
            raise ValidationError(errors)

        graph = response.get('graph', [])

        assertion_obo = first_node_match(graph, dict(type="Assertion"))
        if not assertion_obo:
            raise ValidationError([{
                'name': "ASSERTION_NOT_FOUND",
                'description': "Unable to find an assertion"
            }])

        badgeclass_obo = first_node_match(
            graph, dict(id=assertion_obo.get('badge', None)))
        if not badgeclass_obo:
            raise ValidationError([{
                'name': "ASSERTION_NOT_FOUND",
                'description': "Unable to find a badgeclass"
            }])

        issuer_obo = first_node_match(
            graph, dict(id=badgeclass_obo.get('issuer', None)))
        if not issuer_obo:
            raise ValidationError([{
                'name': "ASSERTION_NOT_FOUND",
                'description': "Unable to find an issuer"
            }])

        original_json = response.get('input').get('original_json', {})

        recipient_profile = report.get('recipientProfile', {})
        recipient_type, recipient_identifier = recipient_profile.items()[0]

        def commit_new_badge():
            with transaction.atomic():
                issuer, issuer_created = Issuer.objects.get_or_create_from_ob2(
                    issuer_obo,
                    original_json=original_json.get(issuer_obo.get('id')))
                badgeclass, badgeclass_created = BadgeClass.objects.get_or_create_from_ob2(
                    issuer,
                    badgeclass_obo,
                    original_json=original_json.get(badgeclass_obo.get('id')))
                if badgeclass_created and (getattr(
                        settings, 'BADGERANK_NOTIFY_ON_BADGECLASS_CREATE',
                        True) or getattr(
                            settings, 'BADGERANK_NOTIFY_ON_FIRST_ASSERTION',
                            True)):
                    from issuer.tasks import notify_badgerank_of_badgeclass
                    notify_badgerank_of_badgeclass.delay(
                        badgeclass_pk=badgeclass.pk)
                return BadgeInstance.objects.get_or_create_from_ob2(
                    badgeclass,
                    assertion_obo,
                    recipient_identifier=recipient_identifier,
                    recipient_type=recipient_type,
                    original_json=original_json.get(assertion_obo.get('id')))

        try:
            return commit_new_badge()
        except IntegrityError:
            logger.error(
                "Race condition caught when saving new assertion: {}".format(
                    query))
            return commit_new_badge()
Ejemplo n.º 7
0
    def get_or_create_assertion(cls,
                                url=None,
                                imagefile=None,
                                assertion=None,
                                created_by=None):

        # distill 3 optional arguments into one query argument
        query = (url, imagefile, assertion)
        query = filter(lambda v: v is not None, query)
        if len(query) != 1:
            raise ValueError(
                "Must provide only 1 of: url, imagefile or assertion_obo")
        query = query[0]

        if created_by:
            recipient_id = created_by.get_recipient_identifier(),
            badgecheck_recipient_profile = {
                'id': created_by.get_recipient_identifier(),
                'email': [email.email for email in created_by.verified_emails]
            }
        else:
            badgecheck_recipient_profile = None

        try:
            response = openbadges.verify(
                query,
                recipient_profile=badgecheck_recipient_profile,
                **cls.badgecheck_options())
        except ValueError as e:
            raise ValidationError([{
                'name': "INVALID_BADGE",
                'description': str(e)
            }])

        report = response.get('report', {})
        # override VALIDATE_PROPERTY for id, until IMS accepts EduID iri format

        if report['errorCount'] > 0:
            index_of_uri_format_failure = None
            uri_format_message_found = False
            for index, message in enumerate(report['messages']):
                if 'not valid in unknown type node' in message['result']:
                    index_of_uri_format_failure = index
                    uri_format_message_found = True
            if uri_format_message_found:
                report['errorCount'] -= 1
                report['messages'].pop(index_of_uri_format_failure)
                if report['errorCount'] == 0:
                    report['valid'] = True

        is_valid = report.get('valid')

        if not is_valid:
            if report.get('errorCount', 0) > 0:
                errors = list(cls.translate_errors(report.get('messages', [])))
            else:
                errors = [{
                    'name': "UNABLE_TO_VERIFY",
                    'description': "Unable to verify the assertion"
                }]
            raise ValidationError(errors)

        graph = response.get('graph', [])

        assertion_obo = first_node_match(graph, dict(type="Assertion"))
        if not assertion_obo:
            raise ValidationError([{
                'name': "ASSERTION_NOT_FOUND",
                'description': "Unable to find an assertion"
            }])

        badgeclass_obo = first_node_match(
            graph, dict(id=assertion_obo.get('badge', None)))
        if not badgeclass_obo:
            raise ValidationError([{
                'name': "ASSERTION_NOT_FOUND",
                'description': "Unable to find a badgeclass"
            }])

        issuer_obo = first_node_match(
            graph, dict(id=badgeclass_obo.get('issuer', None)))
        if not issuer_obo:
            raise ValidationError([{
                'name': "ASSERTION_NOT_FOUND",
                'description': "Unable to find an issuer"
            }])

        original_json = response.get('input').get('original_json', {})

        recipient_identifier = report.get('recipientProfile', {}).get(
            'id', None)  # first use 'id' as the recipient_identifier type
        if not recipient_identifier:  # the assertion might instead have the 'email' recipient_identifier type
            recipient_identifier = report.get('recipientProfile',
                                              {}).get('email', None)

        with transaction.atomic():
            issuer, issuer_created = Issuer.objects.get_or_create_from_ob2(
                issuer_obo,
                original_json=original_json.get(issuer_obo.get('id')))
            badgeclass, badgeclass_created = BadgeClass.objects.get_or_create_from_ob2(
                issuer,
                badgeclass_obo,
                original_json=original_json.get(badgeclass_obo.get('id')))
            return BadgeInstance.objects.get_or_create_from_ob2(
                badgeclass,
                assertion_obo,
                recipient_identifier=recipient_identifier,
                original_json=original_json.get(assertion_obo.get('id')))