class FileserverRevokeDownloadSerializer(serializers.Serializer):

    file_transfer_id = UUIDField(required=True)
    ticket = serializers.CharField(required=True)
    ticket_nonce = serializers.CharField(required=True)
    ip_address = serializers.CharField(required=True)

    def validate(self, attrs: dict) -> dict:

        file_transfer_id = attrs.get('file_transfer_id')
        ticket_encrypted = attrs.get('ticket')
        ticket_nonce = attrs.get('ticket_nonce')
        ip_address = attrs.get('ip_address')

        try:
            file_transfer = File_Transfer.objects.select_related('user').\
                only('chunk_count', 'size', 'chunk_count_transferred', 'size_transferred', 'file_id', 'shard_id', 'secret_key', 'user__is_active', 'user_id').\
                get(pk=file_transfer_id, type='download')
        except File_Transfer.DoesNotExist:
            msg = _('Filetransfer does not exist.')
            raise exceptions.ValidationError(msg)

        if not file_transfer.user.is_active:
            msg = _('User inactive.')
            raise exceptions.ValidationError(msg)

        try:
            ticket_json = decrypt(file_transfer.secret_key, ticket_encrypted,
                                  ticket_nonce)
        except:
            msg = _('Malformed ticket. Decryption failed.')
            raise exceptions.ValidationError(msg)

        ticket = json.loads(ticket_json)

        if 'hash_checksum' not in ticket:
            msg = _('Malformed ticket. Blake2b hash missing.')
            raise exceptions.ValidationError(msg)

        hash_checksum = ticket['hash_checksum'].lower()

        count_cmsl = Fileserver_Cluster_Member_Shard_Link.objects.select_related('member')\
            .filter(member__valid_till__gt=timezone.now() - timedelta(seconds=settings.FILESERVER_ALIVE_TIMEOUT),
                 shard__active=True, member=self.context['request'].user, shard_id=file_transfer.shard_id).count()

        if count_cmsl != 1:
            msg = _('Permission denied.')
            raise exceptions.ValidationError(msg)

        try:
            file_chunk = File_Chunk.objects.get(hash_checksum=hash_checksum)
        except File_Chunk.DoesNotExist:
            msg = "NO_PERMISSION_OR_NOT_EXIST"
            raise exceptions.ValidationError(msg)

        attrs['file_transfer'] = file_transfer
        attrs['file_chunk'] = file_chunk

        return attrs
Exemple #2
0
class UpdateUserSerializer(serializers.Serializer):
    user_id = UUIDField(required=True)
    is_active = BooleanField(required=False)
    is_email_active = BooleanField(required=False)
    is_superuser = BooleanField(required=False)
    email = serializers.EmailField(required=False, error_messages={ 'invalid': 'INVALID_EMAIL_FORMAT' })


    def validate(self, attrs: dict) -> dict:

        user_id = attrs.get('user_id')
        is_active = attrs.get('is_active', None)
        is_email_active = attrs.get('is_email_active', None)
        is_superuser = attrs.get('is_superuser', None)
        email = attrs.get('email')

        try:
            user = User.objects.get(pk=user_id)
        except User.DoesNotExist:
            msg = "NO_PERMISSION_OR_NOT_EXIST"
            raise exceptions.ValidationError(msg)

        if email is not None:

            email = email.lower().strip()

            if len(settings.REGISTRATION_EMAIL_FILTER) > 0:
                email_prefix, domain = email.split("@")
                if domain not in settings.REGISTRATION_EMAIL_FILTER:
                    msg = _('E-Mail not allowed to register.')
                    raise exceptions.ValidationError(msg)

            # generate bcrypt with static salt.
            # I know its bad to use static salts, but its the best solution I could come up with,
            # if you want to store emails encrypted while not having to decrypt all emails for duplicate email hunt
            # Im aware that this allows attackers with this fix salt to "mass" attack all emails.
            # if you have a better solution, please let me know.
            email_bcrypt_full = bcrypt.hashpw(email.encode(), settings.EMAIL_SECRET_SALT.encode())
            email_bcrypt = email_bcrypt_full.decode().replace(settings.EMAIL_SECRET_SALT, '', 1)

            if User.objects.filter(email_bcrypt=email_bcrypt).exclude(pk=user_id).exists():
                msg = _('E-Mail already exists.')
                raise exceptions.ValidationError(msg)

            attrs['email_bcrypt'] = email_bcrypt

            # normally encrypt emails, so they are not stored in plaintext with a random nonce
            email = encrypt_with_db_secret(email)


        attrs['user'] = user
        attrs['email'] = email
        attrs['is_active'] = is_active
        attrs['is_email_active'] = is_email_active
        attrs['is_superuser'] = is_superuser

        return attrs
class DeleteYubikeySerializer(serializers.Serializer):
    yubikey_otp_id = UUIDField(required=True)

    def validate(self, attrs: dict) -> dict:

        yubikey_otp_id = attrs.get('yubikey_otp_id')

        try:
            yubikey_otp = Yubikey_OTP.objects.get(pk=yubikey_otp_id)
        except Yubikey_OTP.DoesNotExist:
            msg = "NO_PERMISSION_OR_NOT_EXIST"
            raise exceptions.ValidationError(msg)

        attrs['yubikey_otp'] = yubikey_otp

        return attrs
class DeleteEmergencyCodeSerializer(serializers.Serializer):
    emergency_code_id = UUIDField(required=True)

    def validate(self, attrs: dict) -> dict:

        emergency_code_id = attrs.get('emergency_code_id')

        try:
            emergency_code = Emergency_Code.objects.get(pk=emergency_code_id)
        except Emergency_Code.DoesNotExist:
            msg = _("NO_PERMISSION_OR_NOT_EXIST")
            raise exceptions.ValidationError(msg)

        attrs['emergency_code'] = emergency_code

        return attrs
Exemple #5
0
class DeleteDuoSerializer(serializers.Serializer):
    duo_id = UUIDField(required=True)

    def validate(self, attrs: dict) -> dict:

        duo_id = attrs.get('duo_id')

        try:
            duo = Duo.objects.get(pk=duo_id)
        except Duo.DoesNotExist:
            msg = "NO_PERMISSION_OR_NOT_EXIST"
            raise exceptions.ValidationError(msg)

        attrs['duo'] = duo

        return attrs
class DeleteSessionSerializer(serializers.Serializer):
    session_id = UUIDField(required=True)

    def validate(self, attrs: dict) -> dict:

        session_id = attrs.get('session_id')

        try:
            token = Token.objects.get(id=session_id)
        except Token.DoesNotExist:
            msg = _("NO_PERMISSION_OR_NOT_EXIST")
            raise exceptions.ValidationError(msg)

        attrs['token'] = token

        return attrs
Exemple #7
0
class DeleteGASerializer(serializers.Serializer):
    google_authenticator_id = UUIDField(required=True)

    def validate(self, attrs: dict) -> dict:

        google_authenticator_id = attrs.get('google_authenticator_id')

        try:
            google_authenticator = Google_Authenticator.objects.get(pk=google_authenticator_id)
        except Google_Authenticator.DoesNotExist:
            msg = _("NO_PERMISSION_OR_NOT_EXIST")
            raise exceptions.ValidationError(msg)

        attrs['google_authenticator'] = google_authenticator

        return attrs
Exemple #8
0
class DeleteUserSerializer(serializers.Serializer):
    user_id = UUIDField(required=True)

    def validate(self, attrs: dict) -> dict:

        user_id = attrs.get('user_id')

        try:
            user = User.objects.get(pk=user_id)
        except User.DoesNotExist:
            msg = "NO_PERMISSION_OR_NOT_EXIST"
            raise exceptions.ValidationError(msg)

        attrs['user'] = user

        return attrs
class DeleteMembershipSerializer(serializers.Serializer):
    membership_id = UUIDField(required=True)

    def validate(self, attrs: dict) -> dict:

        membership_id = attrs.get('membership_id')

        try:
            membership = User_Group_Membership.objects.get(id=membership_id)
        except User_Group_Membership.DoesNotExist:
            msg = "NO_PERMISSION_OR_NOT_EXIST"
            raise exceptions.ValidationError(msg)

        attrs['membership'] = membership

        return attrs
Exemple #10
0
class DeleteGroupSerializer(serializers.Serializer):
    group_id = UUIDField(required=True)

    def validate(self, attrs: dict) -> dict:

        group_id = attrs.get('group_id')

        try:
            group = Group.objects.get(id=group_id)
        except Group.DoesNotExist:
            msg = "NO_PERMISSION_OR_NOT_EXIST"
            raise exceptions.ValidationError(msg)

        attrs['group'] = group

        return attrs
Exemple #11
0
class DeleteRecoveryCodeSerializer(serializers.Serializer):
    recovery_code_id = UUIDField(required=True)

    def validate(self, attrs: dict) -> dict:

        recovery_code_id = attrs.get('recovery_code_id')

        try:
            recovery_code = Recovery_Code.objects.get(pk=recovery_code_id)
        except Recovery_Code.DoesNotExist:
            msg = "NO_PERMISSION_OR_NOT_EXIST"
            raise exceptions.ValidationError(msg)

        attrs['recovery_code'] = recovery_code

        return attrs
Exemple #12
0
class DeleteUserSerializer(serializers.Serializer):
    user_id = UUIDField(required=True)

    def validate(self, attrs: dict) -> dict:

        user_id = attrs.get('user_id')

        try:
            user = User.objects.get(pk=user_id)
        except User.DoesNotExist:
            msg = _(
                "You don't have permission to access or it does not exist.")
            raise exceptions.ValidationError(msg)

        attrs['user'] = user

        return attrs
class DeleteYubikeySerializer(serializers.Serializer):
    yubikey_otp_id = UUIDField(required=True)

    def validate(self, attrs: dict) -> dict:

        yubikey_otp_id = attrs.get('yubikey_otp_id')

        try:
            yubikey_otp = Yubikey_OTP.objects.get(pk=yubikey_otp_id)
        except Yubikey_OTP.DoesNotExist:
            msg = _(
                "You don't have permission to access or it does not exist.")
            raise exceptions.ValidationError(msg)

        attrs['yubikey_otp'] = yubikey_otp

        return attrs
Exemple #14
0
class DeleteSessionSerializer(serializers.Serializer):
    session_id = UUIDField(required=True)

    def validate(self, attrs: dict) -> dict:

        session_id = attrs.get('session_id')

        try:
            token = Token.objects.get(id=session_id)
        except Token.DoesNotExist:
            msg = _(
                "You don't have permission to access or it does not exist.")
            raise exceptions.ValidationError(msg)

        attrs['token'] = token

        return attrs
class DeleteRecoveryCodeSerializer(serializers.Serializer):
    recovery_code_id = UUIDField(required=True)

    def validate(self, attrs: dict) -> dict:

        recovery_code_id = attrs.get('recovery_code_id')

        try:
            recovery_code = Recovery_Code.objects.get(pk=recovery_code_id)
        except Recovery_Code.DoesNotExist:
            msg = _(
                "You don't have permission to access or it does not exist.")
            raise exceptions.ValidationError(msg)

        attrs['recovery_code'] = recovery_code

        return attrs
Exemple #16
0
class DeleteDuoSerializer(serializers.Serializer):
    duo_id = UUIDField(required=True)

    def validate(self, attrs: dict) -> dict:

        duo_id = attrs.get('duo_id')

        try:
            duo = Duo.objects.get(pk=duo_id)
        except Duo.DoesNotExist:
            msg = _(
                "You don't have permission to access or it does not exist.")
            raise exceptions.ValidationError(msg)

        attrs['duo'] = duo

        return attrs
class DeleteGroupSerializer(serializers.Serializer):
    group_id = UUIDField(required=True)

    def validate(self, attrs: dict) -> dict:

        group_id = attrs.get('group_id')

        try:
            group = Group.objects.get(id=group_id)
        except Group.DoesNotExist:
            msg = _(
                "You don't have permission to access or it does not exist.")
            raise exceptions.ValidationError(msg)

        attrs['group'] = group

        return attrs
Exemple #18
0
class DeleteMembershipSerializer(serializers.Serializer):
    membership_id = UUIDField(required=True)

    def validate(self, attrs: dict) -> dict:

        membership_id = attrs.get('membership_id')

        try:
            membership = User_Group_Membership.objects.get(id=membership_id)
        except User_Group_Membership.DoesNotExist:
            msg = _(
                "You don't have permission to access or it does not exist.")
            raise exceptions.ValidationError(msg)

        attrs['membership'] = membership

        return attrs
Exemple #19
0
class DeleteGASerializer(serializers.Serializer):
    google_authenticator_id = UUIDField(required=True)

    def validate(self, attrs: dict) -> dict:

        google_authenticator_id = attrs.get('google_authenticator_id')

        try:
            google_authenticator = Google_Authenticator.objects.get(
                pk=google_authenticator_id)
        except Google_Authenticator.DoesNotExist:
            msg = _(
                "You don't have permission to access or it does not exist.")
            raise exceptions.ValidationError(msg)

        attrs['google_authenticator'] = google_authenticator

        return attrs
class FileserverAuthorizeUploadSerializer(serializers.Serializer):

    file_transfer_id = UUIDField(required=True)
    ticket = serializers.CharField(required=True)
    ticket_nonce = serializers.CharField(required=True)
    chunk_size = serializers.IntegerField(required=True)
    hash_checksum = serializers.CharField(required=True)
    ip_address = serializers.CharField(required=True)

    def validate(self, attrs: dict) -> dict:

        file_transfer_id = attrs.get('file_transfer_id')
        ticket_encrypted = attrs.get('ticket')
        ticket_nonce = attrs.get('ticket_nonce')
        chunk_size = attrs.get('chunk_size', 0)
        hash_checksum = attrs.get('hash_checksum', '').lower()
        ip_address = attrs.get('ip_address')

        try:
            file_transfer = File_Transfer.objects.select_related('user').\
                only('chunk_count', 'size', 'chunk_count_transferred', 'size_transferred', 'file_id', 'shard_id', 'secret_key', 'user__is_active', 'user_id').\
                get(pk=file_transfer_id, type='upload')
        except File_Transfer.DoesNotExist:
            msg = _('Filetransfer does not exist.')
            raise exceptions.ValidationError(msg)

        if not file_transfer.user.is_active:
            msg = _('User inactive.')
            raise exceptions.ValidationError(msg)

        try:
            ticket_json = decrypt(file_transfer.secret_key, ticket_encrypted,
                                  ticket_nonce)
        except:
            msg = _('Malformed ticket. Decryption failed.')
            raise exceptions.ValidationError(msg)

        ticket = json.loads(ticket_json)

        if 'chunk_position' not in ticket:
            msg = _('Malformed ticket. Chunk Position missing.')
            raise exceptions.ValidationError(msg)

        if 'hash_checksum' not in ticket:
            msg = _('Malformed ticket. Blake2b hash missing.')
            raise exceptions.ValidationError(msg)

        chunk_size_limit = 128 * 1024 * 1024 + 40
        if chunk_size > chunk_size_limit:
            msg = _("Chunk size exceeds limit.")
            raise exceptions.ValidationError(msg)
        if chunk_size < 40:
            msg = _("Chunk size too small.")
            raise exceptions.ValidationError(msg)

        chunk_position = ticket['chunk_position']
        hash_checksum_ticket = ticket['hash_checksum'].lower()

        if hash_checksum_ticket != hash_checksum:
            msg = _('Chunk corrupted.')
            raise exceptions.ValidationError(msg)

        count_cmsl = Fileserver_Cluster_Member_Shard_Link.objects.select_related('member')\
            .filter(member__valid_till__gt=timezone.now() - timedelta(seconds=settings.FILESERVER_ALIVE_TIMEOUT),
                 shard__active=True, member=self.context['request'].user, shard_id=file_transfer.shard_id).count()

        if count_cmsl != 1:
            msg = _('Permission denied.')
            raise exceptions.ValidationError(msg)

        if file_transfer.chunk_count_transferred + 1 > file_transfer.chunk_count:
            msg = _('Chunk count exceeded.')
            raise exceptions.ValidationError(msg)

        if file_transfer.size_transferred + chunk_size > file_transfer.size:
            msg = _('Chunk size exceeded.')
            raise exceptions.ValidationError(msg)

        attrs['file_transfer'] = file_transfer
        attrs['user_id'] = file_transfer.user_id
        attrs['chunk_position'] = chunk_position
        attrs['chunk_size'] = chunk_size
        attrs['hash_checksum'] = hash_checksum

        return attrs