class GuestLoginRequestSerializer(serializers.Serializer):
    page = serializers.PrimaryKeyRelatedField(
        queryset=Page.objects.all(),
        many=False
    )
    email = serializers.EmailField()

    def save(self, **kwargs):
        email = self.validated_data['email']
        page = self.validated_data['page']
        group = page.group

        try:
            user = User.objects.get(username=email)
            if group.is_guest(user):
                generate_user_magic_link.delay(user_id=str(user.id), page_id=str(page.id))
            return True
        except Exception:
            # ToDo: Probably add some sort of instrumentation here
            return True

    class Meta:
        model = User
        fields = (
            'name',
            'group'
        )
class TicketSerializer(serializers.ModelSerializer):
    id = serializers.CharField()
    activation_link = serializers.SerializerMethodField()
    scanned = serializers.BooleanField(read_only=True)
    included_serializers = {
        'offline_lecture': OfflineLectureSerializer,
    }
    customer_email = serializers.EmailField(source='customer.email')
    offline_lecture_id = serializers.CharField(source='offline_lecture.id')
    offline_lecture = serializers.ResourceRelatedField(read_only=True)

    class Meta:
        model = Ticket
        fields = [
            'id',
            'customer_email',
            'activation_link',
            'offline_lecture',
            'scanned',
            'offline_lecture_id',
        ]

    def get_activation_link(self, obj):
        if obj.get_qr_code():
            return f"{settings.SITE_URL}/api/tickets/activate/{obj.qrcode.code}"
        return ""

    def create(self, validated_data):
        customer = validated_data.get('customer')
        offline_lecture = validated_data.get('offline_lecture')
        customer = User.objects.get(email=customer.get('email'))
        offline_lecture = OfflineLecture.objects.get(
            id=offline_lecture.get('id'))
        return Ticket.objects.create(customer=customer,
                                     offline_lecture=offline_lecture)
示例#3
0
class UserSerializer(serializers.HyperlinkedModelSerializer):
    basicprofile = ResourceRelatedField(read_only=True)

    email = serializers.EmailField()

    class Meta:
        model = User
        fields = ('url', 'username', 'email', 'is_staff', 'basicprofile')
示例#4
0
class EmploymentSummarySerializer(BaseModelSerializer):
    class Meta:
        model = Employment
        fields = ['id', 'url', 'created', 'updated', 'name', 'email', 'role']
        create_only_fields = ['email']

    name = serializers.CharField(source='user.get_full_name', read_only=True)
    email = serializers.EmailField(source='user.email')
示例#5
0
class PermissionLinkCreateSerializer(PermissionLinkSerializer):
    emails = serializers.ListField(child=serializers.EmailField(),
                                   min_length=0,
                                   required=False)

    class Meta:
        model = PermissionLink
        fields = ('name', 'expiration_date', 'emails')
        read_only = ('shipment', )
示例#6
0
class NotifySerializer(serializers.Serializer):

    from_email = serializers.EmailField(max_length=200, required=True)
    subject = serializers.CharField(max_length=500, required=True)
    message = serializers.CharField(max_length=1000, required=True)
    is_consent = serializers.BooleanField(default=False, required=False)

    def create(self, validated_data):
        """Create an RT ticket.
        If this is a consent approval then the procedure is:
        - create ticket in ENA-MG queue
        otherwise:
        - create ticket in EMG queue
        """
        import requests
        n = ena_models.Notify(**validated_data)

        emg_queue = settings.RT["emg_queue"]
        ena_queue = settings.RT["ena_queue"]

        ticket = {
            "id": "ticket/new",
            "Requestor": n.from_email,
            "Priority": "4",
            "Subject": n.subject,
            "Text": n.message.replace("\n", ';')
        }

        if n.is_consent:
            ticket["Queue"] = ena_queue
        else:
            ticket["Queue"] = emg_queue

        logger.info("Ticket %r" % ticket)

        content = [
            "{key}: {value}".format(
                key=key, value=value) for key, value in ticket.items()
        ]

        payload = {
            'user': settings.RT['user'],
            'pass': settings.RT['pass'],
            'content': "\n".join(content),
        }

        headers = {
            'Content-Type': 'application/x-www-form-urlencoded'
        }

        r = requests.post(settings.RT['url'], data=payload, headers=headers)
        return r.status_code

    class Meta:
        model = ena_models.Notify
        fields = '__all__'
class UserSerializer(serializers.Serializer):
    id = serializers.CharField(read_only=True)
    username = serializers.CharField()
    email = serializers.EmailField()

    class Meta:
        model = User

    class JSONAPIMeta:
        resource_name = 'users'

    def create(self, validated_data):
        return User.objects.create_user(password='******', **validated_data)
示例#8
0
class EmailSerializer(serializers.Serializer):

    from_email = serializers.EmailField(required=True)
    subject = serializers.CharField(required=True)
    message = serializers.CharField(required=True)

    def create(self, validated_data):
        validated_data['recipient_list'] = (settings.EMAIL_HELPDESK,)
        logger.info("Email %r" % validated_data)
        send_mail(**validated_data)

    class Meta:
        model = ena_models.Notify
        fields = '__all__'
class GuestUserCreateSerializer(serializers.Serializer):
    """
    TODO: Matt rewrite with gin
    """
    organization = serializers.PrimaryKeyRelatedField(
        queryset=Organization.objects.get_queryset(),
        many=False
    )

    email = serializers.EmailField()
    name = serializers.CharField()

    # I don't know why, but setting this to be a pk related field errors...
    page = serializers.PrimaryKeyRelatedField(
        queryset=Page.objects.all(),
        many=False
    )

    def save(self, **kwargs):
        email = self.validated_data['email']
        user, created = User.objects.get_or_create(username=email)
        if created:
            user.name = self.validated_data['name']

        organization = self.validated_data['organization']
        org_user, _ = organization.get_or_add_user(user)
        org_user.is_guest = True
        org_user.is_admin = False

        user.save()
        org_user.save()
        page = self.validated_data['page']
        page.viewers.add(user)
        page.save()
        return user

    class Meta:
        model = User
        fields = (
            'name',
            'group'
        )
class ResetPasswordRequestSerializer(serializers.Serializer):
    """
    Request a new password. Sends an email.
    """
    email = serializers.EmailField()

    def save(self, **kwargs):
        # We don't want to expose that a user may or may not exist
        # Using the password reset form. So we load the user during save
        # and fail silently if we can't find it.
        try:
            user = User.objects.get(username=self.validated_data['email'])
        except User.DoesNotExist:
            return True

        #
        # Again, don't tell the requestor anything about the
        # permissions of the user.
        if user.is_staff or user.is_superuser:
            return True

        # Check to make sure the user isn't _only_ a guest and actually belongs to an org
        orgs = Organization.objects.filter(organization_users=user)
        org_count = orgs.count()
        if org_count < 1:
            return True

        # This is pretty confusing. but if the user is only a guest user, we don't allow them to reset their password.
        is_not_guest = False
        for org in orgs:
            if not org.is_guest(user):
                is_not_guest = True

        if not is_not_guest:
            return True
        token = token_encode(user, action='reset_password')
        email_user_password_reset_request(user.username, token=token)
        return True

    class Meta:
        model = User
示例#11
0
class CartOrderItemSerializer(serializers.ModelSerializer):
    item_type = serializers.CharField()
    object_id = serializers.IntegerField()
    customer_email = serializers.EmailField()

    class Meta:
        model = OrderItem
        fields = ['item_type', 'object_id', 'customer_email']

    def create(self, validated_data):
        content_type = ContentType.objects.get(
            model=validated_data['item_type'])

        user = User.objects.get(email=validated_data['customer_email'])

        order_item = OrderItem.objects.create(
            customer=user,
            content_type=content_type,
            object_id=validated_data['object_id'])

        return order_item
示例#12
0
class UserSerializer(serializers.ModelSerializer):
    email = serializers.EmailField(required=True,
                                   allow_blank=False,
                                   allow_null=False)

    class Meta:
        model = User
        fields = ('id', 'first_name', 'last_name', 'email', 'create_at',
                  'update_at')

    def create(self, validated_data):
        user = super().create(validated_data)
        user.set_password(validated_data['password'])
        user.save()
        return user

    def validate_email(self, email):
        if email:
            if User.objects.filter(email=email).exists():
                raise serializers.ValidationError('Email already used.')

            return email
示例#13
0
class LoginBackOfficeSerializer(serializers.Serializer):

    email = serializers.EmailField(required=True)

    password = serializers.CharField(max_length=20, required=True)

    def validate(self, validate_data):
        try:
            user = User.objects.get(email=validate_data["email"])
        except User.DoesNotExist:
            raise AuthenticationFailed()

        if not user.check_password(validate_data["password"]):
            raise AuthenticationFailed()

        return validate_data

    def get_user(self, data):
        """
        return user object
        """
        return User.objects.get(email__exact=data.get('email'))
class UserSerializer(BaseInternalModelSerializer):
    """
    Model: User

    """
    organizations = ResourceRelatedField(
        many=True,
        read_only=True,
        source='organizations_organization'
    )

    username = serializers.EmailField(
        validators=[
            UniqueValidator(
                queryset=User.objects.all(),
                message="Email address is already in use",
            )]
    )
    avatar = RemoteFileField(required=False)
    organization_role = serializers.SerializerMethodField()

    def get_organization_role(self, obj):
        request = self.context.get('request')
        if not request:
            return None

        if not hasattr(request, 'organization'):
            return None

        organization = request.organization

        if not organization:
            return None

        if organization.is_owner(obj):
            return "Owner"

        if organization.is_admin(obj):
            return "Admin"

        if organization.is_guest(obj):
            return "Guest"

        if organization.organization_users.filter(user=obj):
            return "Member"

        return None

    class Meta:
        model = User
        fields = (
            'id',
            'created',
            'modified',
            'name',
            'username',
            'is_staff',
            'is_active',
            'is_superuser',
            'organizations',
            'date_joined',
            'avatar',
            'metadata',
            'organization_role',
            'features',
            'notification_preferences'
        )
        read_only_fields = (
            'id',
            'is_staff',
            'is_superuser',
            'organizations',
            'date_joined',
        )
        lookup_field = 'id'
class RegistrationSerializer(serializers.Serializer):
    """
    User registration serializer. Creates a user and an org.
    """

    # User Fields
    name = serializers.CharField()
    username = serializers.EmailField(
        validators=[
            UniqueValidator(
                queryset=User.objects.all(),
                message="Email address is already in use",
            )]
    )
    confirm_password = serializers.CharField()
    password = serializers.CharField()

    # Organization Fields
    organization_name = serializers.CharField()

    def validate(self, data):
        """
        TODO: We're currently passing org data into the user serializer model.
        This might cause conflicts. Consider doing something smarter.
        :param data:
        :return:
        """
        #
        # User Validation

        # Perform server side validation
        if data['password'] != data['confirm_password']:
            raise serializers.ValidationError(
                'Password and Confirm Password should be the same'
            )

        user_serializer = UserSerializer(data=data)
        user_serializer.is_valid(raise_exception=True)

        organization_data = {
            'name': data['organization_name']
        }

        organization_serializer = OrganizationSerializer(data=organization_data)
        organization_serializer.is_valid(raise_exception=True)

        data['user_serializer'] = user_serializer
        data['organization_serializer'] = organization_serializer

        return data

    def save(self, **kwargs):
        user_serializer = self.validated_data['user_serializer']
        organization_serializer = self.validated_data['organization_serializer']

        #
        # Make the user first
        user_serializer.save()
        user = user_serializer.instance
        user.set_password(self.validated_data['password'])
        user.save()

        #
        # Do organization things
        organization_serializer.save()
        organization = organization_serializer.instance
        organization.add_user(user)

        #
        # Holy shit this is real frustrating that I can't do this any other way...
        # Lets see here...
        # 1) Can't just let the normal celery tasks handle this because
        #    We save the org so many times we get duplicate tasks trying to create
        #    Multiple resources
        #
        # 2) Can't use kwargs.created in a signal because the owner hasn't been added
        #    to the organization at that point (until we run organization.add_user
        #    and we can't do that until we create, because we need an organization id.

        # Intercom
        IntercomOrganizationSync().execute(organization, "create_or_update")

        # Stripe
        StripeOrganizationSync().execute(organization, "create_or_update")

        return True

    class Meta:
        model = User
示例#16
0
class UserProfileSerializer(serializers.ModelSerializer):
    """
    Serializer class for UserProfile model
    """

    first_name = serializers.CharField(source="user.first_name")
    last_name = serializers.CharField(source="user.last_name")
    email = serializers.EmailField(source="user.email")
    password = serializers.CharField(
        source="user.password",
        allow_null=True,
        default=None,
        required=False,
        write_only=True,
    )
    last_login = serializers.DateTimeField(
        source="user.last_login", read_only=True)
    submission_count = serializers.SerializerMethodField()
    amount_earned = SerializableAmountField(read_only=True)
    avg_amount_earned = SerializableAvgAmountEarnedField(read_only=True)
    metadata = serializers.JSONField(read_only=True)

    class Meta:  # pylint:  disable=too-few-public-methods
        """
        class meta options
        """

        model = UserProfile
        fields = [
            "id",
            "created",
            "modified",
            "role_display",
            "gender_display",
            "expertise_display",
            "first_name",
            "last_name",
            "password",
            "email",
            "ona_pk",
            "ona_username",
            "payment_number",
            "approved_submissions",
            "rejected_submissions",
            "approval_rate",
            "amount_earned",
            "last_login",
            "avg_submissions",
            "avg_approved_submissions",
            "avg_rejected_submissions",
            "avg_approval_rate",
            "avg_amount_earned",
            "phone_number",
            "role",
            "expertise",
            "gender",
            "national_id",
            "submission_count",
            "address",
            "metadata",
        ]

    owner_only_fields = ("metadata", )

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)

        if self.instance and hasattr(self.Meta, "owner_only_fields"):
            request = self.context.get("request")
            is_permitted = (request and request.user
                            and request.user == self.instance.user)
            if isinstance(self.instance,
                          QuerySet) or not is_permitted or not request:
                for field in getattr(self.Meta, "owner_only_fields"):
                    self.fields.pop(field)

    def get_submission_count(self, obj):  # pylint: disable=no-self-use
        """
        Get the submission count
        """
        return obj.user.submission_set.count()

    def validate_password(self, value):
        """
        Custom validation for Password Field
        """
        if not self.instance:
            # On create of a new user Password shouldn't be none
            if value is None:
                raise serializers.ValidationError(NEED_PASSWORD_ON_CREATE)

        if value is not None:
            validate_password(value)

        return value

    def create(self, validated_data):
        """
        Custom create method to create User object then UserProfile object
        """
        user_data = validated_data.pop("user")
        user_data["username"] = validated_data.get("ona_username")
        first_name = user_data.get("first_name")
        last_name = user_data.get("last_name")
        email = user_data.get("email")
        password = user_data.get("password")

        created, data = create_ona_user(
            settings.ONA_BASE_URL,
            user_data["username"],
            first_name,
            last_name,
            email,
            password,
        )

        if not created:
            raise serializers.ValidationError(data)

        if not data:
            raise serializers.ValidationError(CANNOT_ACCESS_ONADATA)

        ona_pk = data.get("id")
        metadata = data.get("metadata")

        add_team_member(settings.ONA_BASE_URL, user_data["username"],
                        settings.ONA_MEMBERS_TEAM_ID)

        # make user an admin of organisation at ona
        if validated_data.get("role") == UserProfile.ADMIN:
            updated = change_user_role(
                settings.ONA_BASE_URL,
                settings.ONA_ORG_NAME,
                user_data["username"],
                settings.ONA_OWNER_ROLE,
            )
            if not updated:
                # default to contributor role incase admin fails
                validated_data["role"] = UserProfile.CONTRIBUTOR
        elif validated_data["role"] == UserProfile.CONTRIBUTOR:
            change_user_role(
                settings.ONA_BASE_URL,
                settings.ONA_ORG_NAME,
                user_data["username"],
                settings.ONA_CONTRIBUTER_ROLE,
            )

        # set an unusable password by not passing the password to the create
        # method.  Why, you ask?  Because we don't want to store passwords
        # on the Kaznet site.  Ona is the source of truth for this.
        try:
            del user_data["password"]
        except KeyError:
            pass

        # create the User object
        user = UserSerializer.create(
            UserSerializer(), validated_data=user_data)
        # populate the UserProfile object
        userprofile = user.userprofile
        userprofile.ona_pk = ona_pk
        userprofile.ona_username = user.username
        userprofile.payment_number = validated_data.get("payment_number")
        userprofile.phone_number = validated_data.get("phone_number")
        if validated_data.get("role"):
            userprofile.role = validated_data.get("role")
        userprofile.gender = validated_data.get("gender")
        if validated_data.get("national_id"):
            userprofile.national_id = validated_data.get("national_id")
        userprofile.expertise = validated_data.get("expertise")

        if metadata:
            userprofile.metadata["last_password_edit"] = metadata.get(
                settings.ONA_LAST_PASSWORD_EDIT_FIELD)
        userprofile.metadata["gravatar"] = data.get("gravatar")
        userprofile.save()

        return userprofile

    # pylint: disable=too-many-branches, too-many-statements
    def update(self, instance, validated_data):
        """
        Custom update method for UserProfiles
        """
        # deal with the user object
        user = instance.user
        user_data = validated_data.pop("user")
        username = user.username
        first_name = user_data.get("first_name")
        last_name = user_data.get("last_name")
        data = {}

        # you can't change username
        try:
            del user_data["username"]
        except KeyError:
            pass

        # you can't change email
        # this is because Onadata requires your current password when changing
        # the email.  And we cannot get the user's current password
        try:
            del user_data["email"]
        except KeyError:
            pass

        # you can't change password
        # this is because Onadata requires your current password when changing
        # the password.  And we cannot get the user's current password
        try:
            del user_data["password"]
        except KeyError:
            pass

        # only pick changed values significant to ona profile
        update_data = {}
        if first_name != instance.user.first_name:
            update_data["first_name"] = first_name
        if last_name != instance.user.last_name:
            update_data["last_name"] = last_name

        # update on ona only if there is are changes made significant to ona
        if any(update_data):
            updated, data = update_details(settings.ONA_BASE_URL, username,
                                           update_data)

            if not updated:
                raise serializers.ValidationError(data)

            if not data:
                raise serializers.ValidationError(CANNOT_ACCESS_ONADATA)

        # change role to admin if the user is not initially an admin
        if (validated_data.get("role") == UserProfile.ADMIN
                and instance.role != UserProfile.ADMIN):
            updated = change_user_role(
                settings.ONA_BASE_URL,
                settings.ONA_ORG_NAME,
                username,
                settings.ONA_OWNER_ROLE,
            )
            if not updated:
                # default to previous role incase change to admin fails
                validated_data["role"] = instance.role

        # change role to contributor if user was admin initially
        elif (validated_data.get("role") != UserProfile.ADMIN
              and instance.role == UserProfile.ADMIN):
            updated = change_user_role(
                settings.ONA_BASE_URL,
                settings.ONA_ORG_NAME,
                username,
                settings.ONA_CONTRIBUTER_ROLE,
            )
            if not updated:
                # default to previous role incase change to contributor fails
                validated_data["role"] = instance.role

        UserSerializer().update(instance=user, validated_data=user_data)

        # deal with the userprofile object
        instance.payment_number = validated_data.get("payment_number",
                                                     instance.payment_number)
        instance.phone_number = validated_data.get("phone_number",
                                                   instance.phone_number)
        instance.role = validated_data.get("role", instance.role)
        instance.gender = validated_data.get("gender", instance.gender)
        if instance.national_id:
            instance.national_id = validated_data.get("national_id",
                                                      instance.national_id)
        instance.expertise = validated_data.get("expertise",
                                                instance.expertise)

        if any(data):
            metadata = data.get("metadata")
            gravatar = data.get("gravatar")

            try:
                instance.metadata["last_password_edit"] = metadata.get(
                    settings.ONA_LAST_PASSWORD_EDIT_FIELD)
            except AttributeError:
                pass

            instance.metadata["gravatar"] = gravatar
        instance.save()

        return instance