Пример #1
0
 def post(self, request, **kwargs):
     context = self.get_context_data(**kwargs)
     response = []
     if not request.data:
         raise BadgrApiException400('No provisionments sent', 0)
     for provisionment in request.data:
         serializer = self.v1_serializer_class(data=provisionment,
                                               context=context)
         try:
             serializer.is_valid(raise_exception=True)
             serializer.save(created_by=request.user)
             message = {'status': 'success', 'message': serializer.data}
         except ValidationError as e:
             if not isinstance(
                     e, BadgrValidationError) and 'email' in e.detail:
                 # Consistency with other BadgrValidationErrors
                 e = BadgrValidationError("Enter a valid email address",
                                          509)
             # check if email address was a duplicate
             duplicate_with_success = [
                 x for x in response if x['status'] == 'success'
                 and x['email'] == provisionment['email']
             ]
             if duplicate_with_success:
                 e = BadgrValidationError(
                     'You entered this email address multiple times.', 510)
             message = {'status': 'failure', 'message': e.detail}
         message['email'] = provisionment['email']
         response.append(message)
     return Response(response, status=status.HTTP_201_CREATED)
Пример #2
0
    def award(self, recipient):
        """Accept the direct award and make an assertion out of it"""
        from issuer.models import BadgeInstance
        if self.eppn not in recipient.eppns:
            raise BadgrValidationError('Cannot award, eppn does not match', 999)

        institution = self.badgeclass.institution
        identifiers = [inst.identifier for inst in self.badgeclass.award_allowed_institutions.all()] + [
            institution.identifier]
        schac_homes = recipient.schac_homes
        if self.badgeclass.formal:
            allowed = institution.identifier in schac_homes
        else:
            allowed = any(identifier in schac_homes for identifier in identifiers)
        if not allowed:
            raise BadgrValidationError('Cannot award, you are not a member of the institution of the badgeclass', 999)
        assertion = self.badgeclass.issue(recipient=recipient,
                                     created_by=self.created_by,
                                     acceptance=BadgeInstance.ACCEPTANCE_ACCEPTED,
                                     recipient_type=BadgeInstance.RECIPIENT_TYPE_EDUID,
                                     send_email=False,
                                     award_type=BadgeInstance.AWARD_TYPE_DIRECT_AWARD,
                                     direct_award_bundle=self.bundle)
        # delete any pending enrollments for this badgeclass and user
        recipient.cached_pending_enrollments().filter(badge_class=self.badgeclass).delete()
        recipient.remove_cached_data(['cached_pending_enrollments'])
        return assertion
Пример #3
0
 def create(self, validated_data, **kwargs):
     user_permissions = validated_data['issuer'].get_permissions(
         validated_data['created_by'])
     if user_permissions['may_create']:
         if validated_data['formal'] and not validated_data[
                 'issuer'].faculty.institution.grondslag_formeel:
             raise BadgrValidationError(
                 "Cannot create a formal badgeclass for an institution without the judicial basis for formal badges",
                 215)
         if not validated_data['formal'] and not validated_data[
                 'issuer'].faculty.institution.grondslag_informeel:
             raise BadgrValidationError(
                 "Cannot create an informal badgeclass for an institution without the judicial basis for informal badges",
                 216)
         try:
             new_badgeclass = BadgeClass.objects.create(**validated_data)
         except IntegrityError:
             raise BadgrValidationFieldError(
                 'name',
                 "There is already a Badgeclass with this name inside this Issuer",
                 911)
         return new_badgeclass
     else:
         raise BadgrValidationError(
             "You don't have the necessary permissions", 100)
Пример #4
0
 def update(self, instance, validated_data):
     if instance.rejected:
         raise BadgrValidationError('You cannot edit an invitation that has been rejected.', 508)
     if not instance.entity.has_permissions(self.context['request'].user, ['may_administrate_users']):
         raise BadgrValidationError('You do not have permission to invite user for this entity.', 507)
     [setattr(instance, attr, validated_data.get(attr)) for attr in validated_data]
     instance.save()
     return instance
Пример #5
0
 def revoke(self, revocation_reason):
     if self.status == DirectAward.STATUS_REVOKED:
         raise BadgrValidationError("DirectAward is already revoked", 999)
     if not revocation_reason:
         raise BadgrValidationError("revocation_reason is required", 999)
     self.status = DirectAward.STATUS_REVOKED
     self.revocation_reason = revocation_reason
     self.save()
Пример #6
0
 def match_user(self, user):
     '''Sets given user as the matched user'''
     try:
         entity_institution = self.entity.institution
     except AttributeError:
         entity_institution = self.entity
     if user.institution != entity_institution:
         raise BadgrValidationError(
             'May not invite user from other institution', 504)
     if user.is_teacher and not self.for_teacher:
         raise BadgrValidationError('This invite is for a student', 505)
     if not user.is_teacher and self.for_teacher:
         raise BadgrValidationError('This invite is for a teacher', 506)
     self.user = user
     self.save()
Пример #7
0
 def _validate_staff_collision(self):
     """validate to see if there is a existing staff membership that conflicts for the entity of this invite"""
     if self.user and self.entity.get_all_staff_memberships_in_current_branch(
             self.user):
         raise BadgrValidationError(
             'Cannot invite user for this entity. There is a conflicting staff membership.',
             502)
Пример #8
0
def validate_errors(serializer):
    serializer.is_valid()
    errors = serializer.errors
    if errors:
        fields = {}
        for attr, field_errors in errors.items():
            fields[attr] = []
            for error in field_errors:
                try:
                    fields[attr].append({
                        'error_code':
                        get_form_error_code(vars(error)['code']),
                        'error_message':
                        error
                    })
                except TypeError as e:  # TODO: make this recursive for endless depth
                    sub_fields = {}
                    for sub_attr, sub_errors in error.items():
                        sub_fields[sub_attr] = []
                        for sub_error in sub_errors:
                            sub_fields[sub_attr].append({
                                'error_code':
                                get_form_error_code(vars(sub_error)['code']),
                                'error_message':
                                sub_error
                            })
                    fields[attr].append(sub_fields)
        raise BadgrValidationError(error_message=fields, error_code=999)
Пример #9
0
 def validate(self, attrs):
     validated_data = super(UserProvisionmentSerializer, self).validate(attrs)
     entity = validated_data['content_type'].get_object_for_this_type(entity_id=validated_data['object_id'])
     if not entity.has_permissions(self.context['request'].user, ['may_administrate_users']):
         raise BadgrValidationError('You do not have permission to invite user for this entity.', 507)
     validated_data['object_id'] = entity.id
     return attrs
Пример #10
0
 def _validate_unique(self, exclude=None):
     """Custom uniqueness validation of the provisionment, used before save"""
     if UserProvisionment.objects.filter(
             type=self.type,
             rejected=False,
             for_teacher=self.for_teacher,
             email=self.email).exclude(pk=self.pk).exists():
         raise BadgrValidationError(
             'There may be only one invite per email address.', 501)
     return super(UserProvisionment, self).validate_unique(exclude=exclude)
Пример #11
0
 def validate_extensions(self, extensions):
     if extensions:
         for ext in extensions.values():
             if "@context" in ext and not ext['@context'].startswith(
                     settings.EXTENSIONS_ROOT_URL):
                 raise BadgrValidationError(
                     error_code=999,
                     error_message=
                     f"extensions @context invalid {ext['@context']}")
     return extensions
Пример #12
0
 def _validate_invite_collision(self):
     """validate to see if the there is another invite that collides with this one
      (i.e. if both are created the staff memberships will collide"""
     all_entities_in_same_branch = self.entity.get_all_entities_in_branch()
     all_invites_for_same_user = UserProvisionment.objects.filter(
         email=self.email)
     for invite in all_invites_for_same_user:
         if invite != self and invite.entity in all_entities_in_same_branch:
             raise BadgrValidationError(
                 'Cannot invite user for this entity. There is a conflicting invite.',
                 503)
Пример #13
0
 def create(self, validated_data):
     terms = Terms.objects.get(entity_id=validated_data['terms_entity_id'])
     if terms.institution:
         if not terms.institution.identifier in self.context[
                 'request'].user.get_all_associated_institutions_identifiers(
                 ):
             raise BadgrValidationError(
                 'You cannot accept terms that are not from your institution',
                 0)
     if validated_data['accepted']:
         return terms.accept(self.context['request'].user)
Пример #14
0
 def post(self, request, **kwargs):
     directaward = self.get_object(request, **kwargs)
     if not self.has_object_permissions(request, directaward):
         return Response(status=status.HTTP_404_NOT_FOUND)
     if request.data.get('accept', False):  # has accepted it
         if not directaward.badgeclass.terms_accepted(request.user):
             raise BadgrValidationError(
                 "Cannot accept direct award, must accept badgeclass terms first",
                 999)
         assertion = directaward.award(recipient=request.user)
         directaward.badgeclass.remove_cached_data(['cached_direct_awards'])
         directaward.delete()
         return Response({'entity_id': assertion.entity_id},
                         status=status.HTTP_201_CREATED)
     elif not request.data.get('accept', True):  # has rejected it
         directaward.status = DirectAward.STATUS_REJECTED  # reject it
         directaward.save()
         directaward.badgeclass.remove_cached_data(['cached_direct_awards'])
         return Response({'rejected': True}, status=status.HTTP_200_OK)
     raise BadgrValidationError(
         'Neither accepted or rejected the direct award', 999)
Пример #15
0
 def update(self, instance, validated_data):
     if instance.assertions and instance.name_english and instance.name_english != validated_data[
             "name_english"]:
         raise BadgrValidationError(
             "Cannot change the name, assertions have already been issued within this entity",
             214)
     if instance.assertions and instance.name_dutch and instance.name_dutch != validated_data[
             "name_dutch"]:
         raise BadgrValidationError(
             "Cannot change the name, assertions have already been issued within this entity",
             214)
     [
         setattr(instance, attr, validated_data.get(attr))
         for attr in validated_data
     ]
     self.save_extensions(validated_data, instance)
     if not instance.badgrapp_id:
         instance.badgrapp = BadgrApp.objects.get_current(
             self.context.get('request', None))
     instance.save()
     return instance
Пример #16
0
 def create(self, validated_data):
     terms = Terms.objects.get(entity_id=validated_data['terms_entity_id'])
     institution = terms.institution
     if institution:
         identifiers = [inst.identifier for inst in institution.award_allowed_institutions.all()] + [
             institution.identifier]
         schac_homes = self.context['request'].user.schac_homes
         allowed = any(identifier in schac_homes for identifier in identifiers) or institution.award_allow_all_institutions
         if not allowed:
             raise BadgrValidationError('You cannot accept terms that are not allowed by your institution', 0)
     if validated_data['accepted']:
         return terms.accept(self.context['request'].user)
Пример #17
0
    def validate(self, data):
        badgeclass = self.context['request'].data.get('badgeclass')
        if badgeclass.narrative_required and not data.get('narrative'):
            raise BadgrValidationError(error_code=999,
                                       error_message="Narrative is required")
        if badgeclass.evidence_required and not data.get("evidence_items"):
            raise BadgrValidationError(error_code=999,
                                       error_message="Eviidence is required")
        if data.get('email') and not data.get('recipient_identifier'):
            data['recipient_identifier'] = data.get('email')

        hashed = data.get('hashed', None)
        if hashed is None:
            recipient_type = data.get('recipient_type')
            if recipient_type in (BadgeInstance.RECIPIENT_TYPE_URL,
                                  BadgeInstance.RECIPIENT_TYPE_ID):
                data['hashed'] = False
            else:
                data['hashed'] = True

        return data
Пример #18
0
 def get_general_terms(cls, user):
     if user.is_student:
         return list(
             Terms.objects.filter(
                 terms_type__in=(Terms.TYPE_SERVICE_AGREEMENT_STUDENT,
                                 Terms.TYPE_TERMS_OF_SERVICE)))
     elif user.is_teacher:
         return list(
             Terms.objects.filter(
                 terms_type__in=(Terms.TYPE_SERVICE_AGREEMENT_EMPLOYEE,
                                 Terms.TYPE_TERMS_OF_SERVICE)))
     raise BadgrValidationError(
         'Cannot get general terms user is neither teacher nor student', 0)
Пример #19
0
 def create(self, validated_data, **kwargs):
     user_permissions = validated_data['faculty'].get_permissions(
         validated_data['created_by'])
     if user_permissions['may_create']:
         new_issuer = Issuer(**validated_data)
         # set badgrapp
         new_issuer.badgrapp = BadgrApp.objects.get_current(
             self.context.get('request', None))
         new_issuer.save()
         return new_issuer
     else:
         raise BadgrValidationError(
             "You don't have the necessary permissions", 100)
Пример #20
0
    def create(self, validated_data):
        """
        Requires self.context to include request (with authenticated request.user)
        and badgeclass: issuer.models.BadgeClass.
        """
        badgeclass = self.context['request'].data.get('badgeclass')
        enrollment = StudentsEnrolled.objects.get(
            entity_id=validated_data.get('enrollment_entity_id'))
        expires_at = None
        if badgeclass.expiration_period:
            expires_at = datetime.datetime.now().replace(
                microsecond=0, second=0, minute=0,
                hour=0) + badgeclass.expiration_period
        if enrollment.badge_instance:
            raise BadgrValidationError(
                "Can't award enrollment, it has already been awarded", 213)
        if self.context['request'].data.get('issue_signed', False):
            assertion = badgeclass.issue_signed(
                recipient=enrollment.user,
                created_by=self.context.get('request').user,
                allow_uppercase=validated_data.get('allow_uppercase'),
                recipient_type=validated_data.get(
                    'recipient_type', BadgeInstance.RECIPIENT_TYPE_EDUID),
                expires_at=expires_at,
                extensions=validated_data.get('extension_items', None),
                identifier=uuid.uuid4().urn,
                signer=validated_data.get('created_by'),
                # evidence=validated_data.get('evidence_items', None)  # Dont forget this one when you re-implement signing
                # narrative=validated_data.get('narrative', None)  # idem
            )
        else:
            assertion = badgeclass.issue(
                recipient=enrollment.user,
                created_by=self.context.get('request').user,
                allow_uppercase=validated_data.get('allow_uppercase'),
                recipient_type=validated_data.get(
                    'recipient_type', BadgeInstance.RECIPIENT_TYPE_EDUID),
                expires_at=expires_at,
                extensions=validated_data.get('extension_items', None),
                evidence=validated_data.get('evidence_items', None),
                narrative=validated_data.get('narrative', None))

        enrollment.date_awarded = timezone.now()
        enrollment.badge_instance = assertion
        enrollment.save()
        enrollment.user.remove_cached_data(['cached_pending_enrollments'])
        # delete the pending direct awards for this badgeclass and this user
        badgeclass.cached_pending_direct_awards().filter(
            eppn__in=enrollment.user.eppns).delete()
        return assertion
Пример #21
0
    def create(self, validated_data):
        badgeclass = validated_data['badgeclass']
        batch_mode = validated_data.pop('batch_mode')
        notify_recipients = validated_data.pop('notify_recipients')
        direct_awards = validated_data.pop('direct_awards')
        user_permissions = badgeclass.get_permissions(
            validated_data['created_by'])
        if user_permissions['may_award']:
            successfull_direct_awards = []
            try:
                with transaction.atomic():
                    direct_award_bundle = DirectAwardBundle.objects.create(
                        initial_total=direct_awards.__len__(),
                        **validated_data)
                    for direct_award in direct_awards:
                        successfull_direct_awards.append(
                            DirectAward.objects.create(
                                bundle=direct_award_bundle,
                                badgeclass=badgeclass,
                                **direct_award))
            except IntegrityError:
                raise BadgrValidationError(
                    "A direct award already exists with this eppn for this badgeclass",
                    999)
            if notify_recipients:
                for da in successfull_direct_awards:
                    da.notify_recipient()
            if batch_mode:
                direct_award_bundle.notify_awarder()
            direct_award_bundle.badgeclass.remove_cached_data(
                ['cached_direct_awards'])
            direct_award_bundle.badgeclass.remove_cached_data(
                ['cached_direct_award_bundles'])

            return direct_award_bundle
        raise BadgrValidationError("You don't have the necessary permissions",
                                   100)
Пример #22
0
 def validate_extensions(self, extensions):
     is_formal = False
     if extensions:
         for ext_name, ext in extensions.items():
             if "@context" in ext and not ext['@context'].startswith(
                     settings.EXTENSIONS_ROOT_URL):
                 raise BadgrValidationError(
                     error_code=999,
                     error_message=
                     f"extensions @context invalid {ext['@context']}")
             if ext_name.endswith('ECTSExtension') or ext_name.endswith(
                     'StudyLoadExtension'):
                 is_formal = True
     self.formal = is_formal
     return extensions
Пример #23
0
 def create(self, validated_data, **kwargs):
     user_institution = self.context['request'].user.institution
     user_permissions = user_institution.get_permissions(
         validated_data['created_by'])
     if user_permissions['may_create']:
         validated_data['institution'] = user_institution
         del validated_data['created_by']
         new_faculty = Faculty(**validated_data)
         try:
             new_faculty.save()
         except IntegrityError as e:
             raise serializers.ValidationError(
                 "Faculty name already exists")
         return new_faculty
     else:
         BadgrValidationError("You don't have the necessary permissions",
                              100)
Пример #24
0
 def update(self, instance, validated_data):
     if instance.assertions:
         raise BadgrValidationError(
             error_code=999,
             error_message=
             "Cannot change any value, assertions have already been issued")
     self.save_extensions(validated_data, instance)
     for key, value in validated_data.items():
         setattr(instance, key, value)
     try:
         instance.save()
     except IntegrityError:
         raise BadgrValidationFieldError(
             'name',
             "There is already a Badgeclass with this name inside this Issuer",
             909)
     return instance
Пример #25
0
 def create(self, validated_data, **kwargs):
     user_permissions = validated_data['faculty'].get_permissions(
         validated_data['created_by'])
     if user_permissions['may_create']:
         new_issuer = Issuer(**validated_data)
         # set badgrapp
         new_issuer.badgrapp = BadgrApp.objects.get_current(
             self.context.get('request', None))
         try:
             new_issuer.save()
         except IntegrityError:
             raise BadgrValidationFieldError(
                 'name',
                 "There is already an Issuer with this name inside this Issuer group",
                 908)
         return new_issuer
     else:
         raise BadgrValidationError(
             "You don't have the necessary permissions", 100)
Пример #26
0
 def update(self, instance, validated_data):
     if instance.assertions and instance.name != validated_data["name"]:
         raise BadgrValidationError(
             "Cannot change the name, assertions have already been issued within this entity",
             214)
     [
         setattr(instance, attr, validated_data.get(attr))
         for attr in validated_data
     ]
     self.save_extensions(validated_data, instance)
     if not instance.badgrapp_id:
         instance.badgrapp = BadgrApp.objects.get_current(
             self.context.get('request', None))
     try:
         instance.save()
     except IntegrityError:
         raise BadgrValidationFieldError(
             'name',
             "There is already an Issuer with this name inside this Issuer group",
             908)
     return instance
Пример #27
0
 def update(self, instance, validated_data):
     if instance.assertions and len(
         [ass for ass in instance.assertions if not ass.revoked]) > 0:
         raise BadgrValidationError(
             error_code=999,
             error_message=
             "Cannot change any value, assertions have already been issued")
     self.save_extensions(validated_data, instance)
     for key, value in validated_data.items():
         if key is not 'award_allowed_institutions':
             setattr(instance, key, value)
     instance.award_allowed_institutions.set(
         validated_data.get('award_allowed_institutions', []))
     try:
         instance.save()
     except IntegrityError:
         raise BadgrValidationFieldError(
             'name',
             "There is already a Badgeclass with this name inside this Issuer",
             911)
     return instance
Пример #28
0
 def post(self, request, **kwargs):
     if 'badgeclass_slug' not in request.data:
         raise BadgrApiException400("Missing badgeclass id", 208)
     badge_class = get_object_or_404(
         BadgeClass, entity_id=request.data['badgeclass_slug'])
     if not badge_class.terms_accepted(request.user):
         raise BadgrValidationError(
             "Cannot enroll, must accept terms first", 0)
     if request.user.may_enroll(badge_class, raise_exception=True):
         enrollment = StudentsEnrolled.objects.create(
             badge_class_id=badge_class.pk,
             user=request.user,
             date_consent_given=timezone.now())
         message = EmailMessageMaker.create_student_badge_request_email(
             request.user, badge_class)
         request.user.email_user(
             subject='You have successfully requested an edubadge',
             html_message=message)
         return Response(data={
             'status': 'enrolled',
             'entity_id': enrollment.entity_id
         },
                         status=201)
     raise BadgrApiException400('Cannot enroll', 209)
Пример #29
0
 def is_valid(self, raise_exception=False):
     try:
         return super(BadgrBaseModelSerializer,
                      self).is_valid(raise_exception)
     except ValidationError as e:
         raise BadgrValidationError(error_message=e.detail, error_code=999)
Пример #30
0
 def delete(self, *args, **kwargs):
     if self._is_last_staff_membership():
         raise BadgrValidationError(
             'Cannot remove the last staff membership of this institution.',
             500)
     return super(InstitutionStaff, self).delete(*args, **kwargs)