Ejemplo n.º 1
0
 def _base_create(self, validated_data, object_name, object_class):
     created_by = validated_data.pop('created_by')
     if created_by.is_user_within_scope(validated_data['user']):
         perms_allowed_to_assign = validated_data[
             object_name].get_permissions(created_by)
         for perm in perms_allowed_to_assign:
             if not perms_allowed_to_assign[perm] and int(
                     validated_data[perm]):
                 raise serializers.ValidationError(
                     "May not assign permissions that you don't have yourself"
                 )
         new_staff_membership = object_class.objects.create(
             **validated_data)
         message = EmailMessageMaker.create_staff_member_addition_email(
             new_staff_membership)
         entity_name = new_staff_membership.object.__class__.__name__
         determiner = 'an' if entity_name[0] in 'aeiouAEIOU' else 'a'
         new_staff_membership.user.email_user(
             subject='You have been added to {} {}'.format(
                 determiner, entity_name),
             html_message=message)
         logger.event(
             badgrlog.PermissionCreatedEvent(
                 staff_instance=new_staff_membership,
                 request=self.context['request']))
         return new_staff_membership
     else:
         raise serializers.ValidationError(
             "You may not administrate this user.")
Ejemplo n.º 2
0
 def post(self, request, **kwargs):
     for field in ['badgeclass_slug', 'edu_id']:
         if field not in request.data:
             return Response(data='field missing', status=401)
     badge_class = get_object_or_404(
         BadgeClass, entity_id=request.data['badgeclass_slug'])
     # consent given when enrolling
     defaults = {
         'date_consent_given': timezone.now(),
         'first_name': request.data.get('first_name', ''),
         'last_name': request.data.get('last_name', '')
     }
     if request.user.may_enroll(badge_class):
         enrollment = StudentsEnrolled.objects.create(
             edu_id=request.data['edu_id'],
             badge_class_id=badge_class.pk,
             email=request.data['email'],
             **defaults)
         message = EmailMessageMaker.create_student_badge_request_email(
             badge_class)
         request.user.email_user(
             subject='You have successfully requested a badge',
             message=message)
         return Response(data='enrolled', status=200)
     return Response({'error': 'Cannot enroll'}, status=400)
Ejemplo n.º 3
0
 def notify_recipient(self):
     html_message = EmailMessageMaker.create_direct_award_student_mail(self)
     if settings.LOCAL_DEVELOPMENT_MODE:
         open_mail_in_browser(html_message)
     try:
         EmailBlacklist.objects.get(email=self.recipient_email)
     except EmailBlacklist.DoesNotExist:
         # Allow sending, as this email is not blacklisted.
         plain_text = strip_tags(html_message)
         send_mail(subject='Congratulations, you earned an edubadge!',
                   message=plain_text, html_message=html_message, recipient_list=[self.recipient_email])
Ejemplo n.º 4
0
 def put(self, request, **kwargs):
     enrollment = self.get_object(request, **kwargs)
     if not self.has_object_permissions(request, enrollment):
         raise BadgrApiException400("You do not have permission", 210)
     if enrollment.denied:
         raise BadgrApiException400("Enrollment already denied", 211)
     if enrollment.badge_instance:
         raise BadgrApiException400("Awarded enrollments cannot be denied",
                                    212)
     enrollment.denied = True
     enrollment.save()
     html_message = EmailMessageMaker.create_enrollment_denied_email(
         enrollment)
     subject = 'Your request for the badgeclass {} has been denied by the issuer.'.format(
         enrollment.badge_class.name)
     enrollment.user.email_user(subject=subject, html_message=html_message)
     return Response(data='Succesfully denied enrollment',
                     status=HTTP_200_OK)
Ejemplo n.º 5
0
    def handle(self, *args, **options):
        command_frequency = 24  # hours
        new_enrollments = StudentsEnrolled.objects\
            .filter(date_created__gte=timezone.now()-timedelta(hours=command_frequency))\
            .filter(date_awarded=None)\
            .filter(denied=False)
        staff = StudentsEnrolled.objects.none()  # create empty queryset
        badge_classes = {}
        for enrollment in new_enrollments:
            badge_class = enrollment.badge_class
            try:
                badge_classes[badge_class] += 1
            except KeyError:
                badge_classes[badge_class] = 1
            staff |= badge_class.issuer.staff.all()
        staff = staff.distinct()

        old_unprocessed_enrollments = StudentsEnrolled.objects \
            .filter(date_created__lt=timezone.now() - timedelta(hours=command_frequency)) \
            .filter(date_awarded=None)\
            .filter(denied=False)
        old_badge_classes = {}
        for enrollment in old_unprocessed_enrollments:
            badge_class = enrollment.badge_class
            try:
                old_badge_classes[badge_class] += 1
            except KeyError:
                old_badge_classes[badge_class] = 1

        # filter the results per staff member
        for user in staff:
            badge_classes_new_enrollments = dict(
                (badge_class, counter)
                for badge_class, counter in badge_classes.iteritems()
                if user in badge_class.issuer.staff.all())
            badge_classes_old_enrollments = dict(
                (badge_class, counter)
                for badge_class, counter in old_badge_classes.iteritems()
                if user in badge_class.issuer.staff.all())
            message = EmailMessageMaker.create_issuer_staff_badge_request_email(
                badge_classes_new_enrollments, badge_classes_old_enrollments)
            user.email_user(subject='You have badge requests waiting for you.',
                            message=message)
Ejemplo n.º 6
0
 def send_email(self):
     """Send the invitation email to the recipient"""
     try:
         EmailBlacklist.objects.get(email=self.email)
     except EmailBlacklist.DoesNotExist:
         login_link = BadgrApp.objects.get(pk=1).email_confirmation_redirect
         html_message = EmailMessageMaker.create_user_invited_email(
             provisionment=self, login_link=login_link)
         subject = 'You have been invited to accept a new role for the {entity_type} {entity_name}'.format(
             entity_type=self.entity.__class__.__name__.lower(),
             entity_name=self.entity.name)
         if not self.user:
             plain_text = strip_tags(html_message)
             send_mail(subject,
                       message=plain_text,
                       recipient_list=[self.email],
                       html_message=html_message)
         else:
             self.user.email_user(subject=subject,
                                  html_message=html_message)
Ejemplo n.º 7
0
 def update(self, instance, validated_data):
     original_perms = instance.permissions
     for permission in original_perms.keys():
         new_value = bool(int(validated_data[permission]))
         original_value = original_perms[permission]
         if original_value != new_value:  # this permission is changed
             setattr(instance, permission,
                     new_value)  # update the permission
     instance.save()
     logger.event(
         badgrlog.PermissionChangedEvent(
             staff_instance=instance,
             previous_permissions=original_perms,
             request=self.context['request']))
     html_message = EmailMessageMaker.create_staff_rights_changed_email(
         instance)
     subject = 'You role has changed for you staff membership for the {entity_type} {entity_name}'.format(
         entity_type=instance.object.__class__.__name__.lower(),
         entity_name=instance.object.name)
     instance.user.email_user(subject=subject, html_message=html_message)
     return instance
Ejemplo n.º 8
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)
Ejemplo n.º 9
0
 def notify_awarder(self):
     html_message = EmailMessageMaker.create_direct_award_bundle_mail(self)
     plain_text = strip_tags(html_message)
     send_mail(subject='You have awarded Edubadges!',
               message=plain_text, html_message=html_message, recipient_list=[self.created_by.email])
Ejemplo n.º 10
0
 def notify_recipients(self):
     html_message = EmailMessageMaker.create_direct_award_student_mail(self)
     plain_text = strip_tags(html_message)
     send_mail(subject='Congratulations, you earned an edubadge!',
               message=plain_text, html_message=html_message, bcc=self.recipient_emails)
Ejemplo n.º 11
0
    def post(self, request, **kwargs):
        """
        ---
        parameters:
            - name: slug
              type: string
              paramType: path
              description: The slug of the issuer whose roles to modify.
              required: true
            - name: action
              type: string
              paramType: form
              description: The action to perform on the user. Must be one of 'add', 'modify', or 'remove'.
              required: true
            - name: username
              type: string
              paramType: form
              description: The username of the user to add or remove from this role.
              required: false
            - name: email
              type: string
              paramType: form
              description: A verified email address of the user to add or remove from this role.
              required: false
            - name: role
              type: string
              paramType: form
              description: Role to set user as. One of 'owner', 'editor', or 'staff'
              defaultValue: staff
              required: false
        """
        # validate POST data
        serializer = IssuerRoleActionSerializerV1(data=request.data)
        if not serializer.is_valid():
            return Response(serializer.errors,
                            status=status.HTTP_400_BAD_REQUEST)

        current_issuer = self.get_object(request, **kwargs)
        if not self.has_object_permissions(request, current_issuer):
            return Response(
                "Issuer not found. Authenticated user must be Issuer's owner to modify user permissions.",
                status=status.HTTP_404_NOT_FOUND)

        if not request.user.is_superuser and request.user not in current_issuer.owners:
            raise PermissionDenied(
                "Must be an owner of an issuer profile to modify permissions")

        try:
            if serializer.validated_data.get('username'):
                user_id = serializer.validated_data.get('username')
                user_to_modify = get_user_model().objects.get(username=user_id)
            else:
                user_id = serializer.validated_data.get('email')
                matching_email = [
                    email for email in CachedEmailAddress.objects.filter(
                        email=user_id, verified=True)
                    if email.user.has_surf_conext_social_account()
                ]
                if not matching_email:
                    raise CachedEmailAddress.DoesNotExist
                user_to_modify = matching_email[0].user
        except (
                get_user_model().DoesNotExist,
                CachedEmailAddress.DoesNotExist,
        ):
            error_text = "User not found. Email must be verified and correspond to an existing user with a teacher account."
            if user_id is None:
                error_text = 'User not found. Neither email address or username was provided.'
            return Response(error_text, status=status.HTTP_404_NOT_FOUND)

        if user_to_modify == request.user:
            return Response(
                "Cannot modify your own permissions on an issuer profile",
                status=status.HTTP_400_BAD_REQUEST)

        action = serializer.validated_data.get('action')
        if action == 'add':
            role = serializer.validated_data.get('role')
            if IssuerStaff.objects.filter(user=user_to_modify,
                                          issuer=current_issuer,
                                          role=role).exists():
                raise ValidationError(
                    "Could not add user to staff list. User already in staff list."
                )
            else:
                value = json_dumps({
                    'issuer_pk': current_issuer.pk,
                    'staff_pk': user_to_modify.pk,
                    'role': role
                })
                code = signing.dumps(obj=value,
                                     salt=getattr(settings, 'ACCOUNT_SALT',
                                                  'salty_stuff'))
                url = urljoin(
                    user_to_modify.get_badgr_app().public_pages_redirect,
                    '/accept-staff-membership/' + code)
                message = EmailMessageMaker.create_staff_member_addition_email(
                    url,
                    current_issuer,
                    role,
                    expiration=settings.STAFF_MEMBER_CONFIRMATION_EXPIRE_DAYS)
                user_to_modify.email_user(
                    subject='You have been added to an Issuer',
                    message=message)
                return Response(
                    "Succesfully invited user to become staff member.",
                    status=status.HTTP_200_OK)

        elif action == 'modify':
            role = serializer.validated_data.get('role')
            try:
                staff_instance = IssuerStaff.objects.get(user=user_to_modify,
                                                         issuer=current_issuer)
                staff_instance.role = role
                staff_instance.save(update_fields=('role', ))
            except IssuerStaff.DoesNotExist:
                raise ValidationError(
                    "Cannot modify staff record. Matching staff record does not exist."
                )

        elif action == 'remove':
            staff_instance = IssuerStaff.objects.get(user=user_to_modify,
                                                     issuer=current_issuer)
            if staff_instance.is_signer:
                raise ValidationError(
                    "Cannot remove staff member who is a signer.")
            staff_instance.delete()
            if not user_to_modify.staff_memberships():
                user_to_modify.loses_permission('view_issuer_tab', BadgeUser)
                user_to_modify.save()
            current_issuer.publish()
            user_to_modify.publish()
            return Response("User %s has been removed from %s staff." %
                            (user_to_modify.username, current_issuer.name),
                            status=status.HTTP_200_OK)

        # update cached issuers and badgeclasses for user
        user_to_modify.save()

        return Response(IssuerStaffSerializerV1(staff_instance).data)