jumpserver/apps/common/fields.py

77 lines
2.4 KiB
Python
Raw Normal View History

2018-01-12 07:43:26 +00:00
# -*- coding: utf-8 -*-
#
import json
2018-04-18 04:46:25 +00:00
from django.db import models
2018-01-12 07:43:26 +00:00
from django import forms
from django.utils import six
from django.core.exceptions import ValidationError
2018-01-22 09:21:03 +00:00
from django.utils.translation import ugettext as _
2018-02-01 09:14:15 +00:00
from rest_framework import serializers
2018-04-18 04:46:25 +00:00
from .utils import get_signer
signer = get_signer()
2018-01-12 07:43:26 +00:00
class DictField(forms.Field):
widget = forms.Textarea
def to_python(self, value):
"""Returns a Python boolean object."""
# Explicitly check for the string 'False', which is what a hidden field
# will submit for False. Also check for '0', since this is what
# RadioSelect will provide. Because bool("True") == bool('1') == True,
# we don't need to handle that explicitly.
if isinstance(value, six.string_types):
try:
value = json.loads(value)
return value
except json.JSONDecodeError:
2018-01-22 09:21:03 +00:00
return ValidationError(_("Not a valid json"))
else:
return ValidationError(_("Not a string type"))
2018-01-12 07:43:26 +00:00
def validate(self, value):
2018-01-22 09:21:03 +00:00
if isinstance(value, ValidationError):
raise value
2018-01-12 07:43:26 +00:00
if not value and self.required:
raise ValidationError(self.error_messages['required'], code='required')
def has_changed(self, initial, data):
# Sometimes data or initial may be a string equivalent of a boolean
# so we should run it through to_python first to get a boolean value
return self.to_python(initial) != self.to_python(data)
2018-02-01 09:14:15 +00:00
class StringIDField(serializers.Field):
def to_representation(self, value):
return {"pk": value.pk, "name": value.__str__()}
2018-04-10 12:29:06 +00:00
class StringManyToManyField(serializers.RelatedField):
def to_representation(self, value):
2018-04-18 04:46:25 +00:00
return value.__str__()
class EncryptMixin:
def from_db_value(self, value, expression, connection, context):
if value is not None:
return signer.unsign(value)
return super().from_db_value(self, value, expression, connection, context)
def get_prep_value(self, value):
if value is None:
return value
return signer.sign(value).decode('utf-8')
class EncryptTextField(EncryptMixin, models.TextField):
description = _("Encrypt field using Secret Key")
class EncryptCharField(EncryptMixin, models.CharField):
def __init__(self, *args, **kwargs):
kwargs['max_length'] = 2048
super().__init__(*args, **kwargs)