[Update] serializer mixin继承 (#2810)

* [Update] serializer mixin继承

* [Update] 修改system user更新serialzier

* [Update] 修改success message
pull/2817/head
老广 2019-06-19 16:45:14 +08:00 committed by GitHub
parent d6165e5975
commit 10616b8d9e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
20 changed files with 102 additions and 51 deletions

View File

@ -4,8 +4,8 @@
from rest_framework import serializers
from common.mixins import BulkSerializerMixin
from common.serializers import AdaptedBulkListSerializer
from orgs.mixins import BulkOrgResourceModelSerializer
from .. import const
from ..models import RemoteApp
@ -66,7 +66,7 @@ class RemoteAppParamsDictField(serializers.DictField):
return value
class RemoteAppSerializer(BulkSerializerMixin, serializers.ModelSerializer):
class RemoteAppSerializer(BulkOrgResourceModelSerializer):
params = RemoteAppParamsDictField()
class Meta:

View File

@ -8,11 +8,12 @@ from common.serializers import AdaptedBulkListSerializer
from ..models import Node, AdminUser
from ..const import ADMIN_USER_CONN_CACHE_KEY
from orgs.mixins import BulkOrgResourceModelSerializer
from .base import AuthSerializer
class AdminUserSerializer(serializers.ModelSerializer):
class AdminUserSerializer(BulkOrgResourceModelSerializer):
"""
管理用户
"""
@ -27,7 +28,7 @@ class AdminUserSerializer(serializers.ModelSerializer):
list_serializer_class = AdaptedBulkListSerializer
model = AdminUser
fields = [
'id', 'org_id', 'name', 'username', 'assets_amount',
'id', 'name', 'username', 'assets_amount',
'reachable_amount', 'unreachable_amount', 'password', 'comment',
'date_created', 'date_updated', 'become', 'become_method',
'become_user', 'created_by',

View File

@ -5,8 +5,7 @@ from rest_framework.validators import ValidationError
from django.utils.translation import ugettext_lazy as _
from orgs.mixins import OrgResourceSerializerMixin
from common.mixins import BulkSerializerMixin
from orgs.mixins import BulkOrgResourceModelSerializer
from common.serializers import AdaptedBulkListSerializer
from ..models import Asset, Protocol
from .system_user import AssetSystemUserSerializer
@ -23,8 +22,7 @@ class ProtocolSerializer(serializers.ModelSerializer):
fields = ["name", "port"]
class AssetSerializer(BulkSerializerMixin, OrgResourceSerializerMixin,
serializers.ModelSerializer):
class AssetSerializer(BulkOrgResourceModelSerializer):
protocols = ProtocolSerializer(many=True)
"""
@ -34,7 +32,7 @@ class AssetSerializer(BulkSerializerMixin, OrgResourceSerializerMixin,
model = Asset
list_serializer_class = AdaptedBulkListSerializer
fields = [
'id', 'org_id', 'org_name', 'ip', 'hostname', 'protocol', 'port',
'id', 'ip', 'hostname', 'protocol', 'port',
'protocols', 'platform', 'is_active', 'public_ip', 'domain',
'admin_user', 'nodes', 'labels', 'number', 'vendor', 'model', 'sn',
'cpu_model', 'cpu_count', 'cpu_cores', 'cpu_vcpus', 'memory',
@ -93,7 +91,7 @@ class AssetSerializer(BulkSerializerMixin, OrgResourceSerializerMixin,
return instance
def update(self, instance, validated_data):
protocols_data = validated_data.pop("protocols")
protocols_data = validated_data.pop("protocols", None)
# 兼容老的api
protocol = validated_data.get("protocol")
@ -104,12 +102,14 @@ class AssetSerializer(BulkSerializerMixin, OrgResourceSerializerMixin,
if not protocol and not port and protocols_data:
validated_data["protocol"] = protocols_data[0]["name"]
validated_data["port"] = protocols_data[0]["port"]
protocols = None
if protocols_data:
protocols_serializer = ProtocolSerializer(data=protocols_data, many=True)
protocols_serializer.is_valid(raise_exception=True)
protocols = protocols_serializer.save()
instance = super().update(instance, validated_data)
if protocols:
instance.protocols.all().delete()
instance.protocols.set(protocols)
return instance

View File

@ -9,6 +9,7 @@ from ..backends import AssetUserManager
from common.utils import validate_ssh_private_key
from common.mixins import BulkSerializerMixin
from common.serializers import AdaptedBulkListSerializer
from orgs.mixins import BulkOrgResourceModelSerializer
__all__ = [
@ -23,7 +24,7 @@ class BasicAssetSerializer(serializers.ModelSerializer):
fields = ['hostname', 'ip']
class AssetUserSerializer(BulkSerializerMixin, serializers.ModelSerializer):
class AssetUserSerializer(BulkOrgResourceModelSerializer):
hostname = serializers.CharField(read_only=True, label=_("Hostname"))
ip = serializers.CharField(read_only=True, label=_("IP"))
connectivity = serializers.CharField(read_only=True, label=_("Connectivity"))
@ -51,7 +52,7 @@ class AssetUserSerializer(BulkSerializerMixin, serializers.ModelSerializer):
)
fields = [
"id", "hostname", "ip", "username", "password", "asset", "version",
"is_latest", "connectivity", "backend", "org_id",
"is_latest", "connectivity", "backend",
"date_created", "date_updated", "private_key", "public_key",
]
extra_kwargs = {

View File

@ -5,9 +5,10 @@ from rest_framework import serializers
from common.fields import ChoiceDisplayField
from common.serializers import AdaptedBulkListSerializer
from ..models import CommandFilter, CommandFilterRule, SystemUser
from orgs.mixins import BulkOrgResourceModelSerializer
class CommandFilterSerializer(serializers.ModelSerializer):
class CommandFilterSerializer(BulkOrgResourceModelSerializer):
rules = serializers.PrimaryKeyRelatedField(queryset=CommandFilterRule.objects.all(), many=True)
system_users = serializers.PrimaryKeyRelatedField(queryset=SystemUser.objects.all(), many=True)
@ -17,7 +18,7 @@ class CommandFilterSerializer(serializers.ModelSerializer):
fields = '__all__'
class CommandFilterRuleSerializer(serializers.ModelSerializer):
class CommandFilterRuleSerializer(BulkOrgResourceModelSerializer):
serializer_choice_field = ChoiceDisplayField
class Meta:

View File

@ -3,11 +3,12 @@
from rest_framework import serializers
from common.serializers import AdaptedBulkListSerializer
from orgs.mixins import BulkOrgResourceModelSerializer
from ..models import Domain, Gateway
class DomainSerializer(serializers.ModelSerializer):
class DomainSerializer(BulkOrgResourceModelSerializer):
asset_count = serializers.SerializerMethodField()
gateway_count = serializers.SerializerMethodField()
@ -25,7 +26,7 @@ class DomainSerializer(serializers.ModelSerializer):
return obj.gateway_set.all().count()
class GatewaySerializer(serializers.ModelSerializer):
class GatewaySerializer(BulkOrgResourceModelSerializer):
class Meta:
model = Gateway
list_serializer_class = AdaptedBulkListSerializer
@ -45,7 +46,7 @@ class GatewayWithAuthSerializer(GatewaySerializer):
return fields
class DomainWithGatewaySerializer(serializers.ModelSerializer):
class DomainWithGatewaySerializer(BulkOrgResourceModelSerializer):
gateways = GatewayWithAuthSerializer(many=True, read_only=True)
class Meta:

View File

@ -3,11 +3,12 @@
from rest_framework import serializers
from common.serializers import AdaptedBulkListSerializer
from orgs.mixins import BulkOrgResourceModelSerializer
from ..models import Label
class LabelSerializer(serializers.ModelSerializer):
class LabelSerializer(BulkOrgResourceModelSerializer):
asset_count = serializers.SerializerMethodField()
class Meta:
@ -25,7 +26,7 @@ class LabelSerializer(serializers.ModelSerializer):
return fields
class LabelDistinctSerializer(serializers.ModelSerializer):
class LabelDistinctSerializer(BulkOrgResourceModelSerializer):
value = serializers.SerializerMethodField()
class Meta:

View File

@ -1,6 +1,7 @@
# -*- coding: utf-8 -*-
from rest_framework import serializers
from orgs.mixins import BulkOrgResourceModelSerializer
from ..models import Asset, Node
@ -10,7 +11,7 @@ __all__ = [
]
class NodeSerializer(serializers.ModelSerializer):
class NodeSerializer(BulkOrgResourceModelSerializer):
assets_amount = serializers.IntegerField(read_only=True)
class Meta:

View File

@ -3,12 +3,12 @@ from rest_framework import serializers
from django.utils.translation import ugettext_lazy as _
from common.serializers import AdaptedBulkListSerializer
from ..models import SystemUser, Asset
from orgs.mixins import BulkOrgResourceModelSerializer
from ..models import SystemUser
from .base import AuthSerializer
class SystemUserSerializer(serializers.ModelSerializer):
class SystemUserSerializer(BulkOrgResourceModelSerializer):
"""
系统用户
"""
@ -31,7 +31,7 @@ class SystemUserSerializer(serializers.ModelSerializer):
model = SystemUser
list_serializer_class = AdaptedBulkListSerializer
fields = [
'id', 'org_id', 'name', 'username', 'login_mode',
'id', 'name', 'username', 'login_mode', 'login_mode_display',
'login_mode_display', 'priority', 'protocol', 'auto_push',
'password', 'assets_amount', 'reachable_amount', 'reachable_assets',
'unreachable_amount', 'unreachable_assets', 'cmd_filters', 'sudo',
@ -39,17 +39,9 @@ class SystemUserSerializer(serializers.ModelSerializer):
]
extra_kwargs = {
'login_mode_display': {'label': _('Login mode display')},
'created_by': {'read_only': True}, 'nodes': {'read_only': True},
'assets': {'read_only': True}
'created_by': {'read_only': True},
}
def get_field_names(self, declared_fields, info):
fields = super(SystemUserSerializer, self).get_field_names(declared_fields, info)
fields.extend([
'login_mode_display',
])
return fields
@staticmethod
def get_unreachable_assets(obj):
return obj.assets_unreachable

View File

@ -65,6 +65,7 @@ def on_system_user_update(sender, instance=None, created=True, **kwargs):
@receiver(m2m_changed, sender=SystemUser.nodes.through)
def on_system_user_nodes_change(sender, instance=None, **kwargs):
if instance and kwargs["action"] == "post_add":
logger.info("System user `{}` nodes update signal received".format(instance))
assets = set()
nodes = kwargs['model'].objects.filter(pk__in=kwargs['pk_set'])
for node in nodes:

View File

@ -76,6 +76,7 @@ function initTable2() {
function onNodeSelected2(event, treeNode) {
var url = asset_table2.ajax.url();
url = setUrlParam(url, "node_id", treeNode.meta.node.id);
url = setUrlParam(url, "show_current_asset", "");
asset_table2.ajax.url(url);
asset_table2.ajax.reload();
}

View File

@ -20,7 +20,6 @@ from django.views.decorators.csrf import csrf_exempt
from django.utils.decorators import method_decorator
from django.core.cache import cache
from django.utils import timezone
from django.contrib.auth.mixins import LoginRequiredMixin
from django.shortcuts import redirect
from django.contrib.messages.views import SuccessMessageMixin
from django.forms.formsets import formset_factory

View File

@ -147,7 +147,23 @@ class PrivateTokenAuthentication(authentication.TokenAuthentication):
class SessionAuthentication(authentication.SessionAuthentication):
def enforce_csrf(self, request):
reason = CSRFCheck().process_view(request, None, (), {})
if reason:
raise exceptions.AuthenticationFailed(reason)
def authenticate(self, request):
"""
Returns a `User` if the request session currently has a logged in user.
Otherwise returns `None`.
"""
# Get the session-based user from the underlying HttpRequest object
user = getattr(request._request, 'user', None)
# Unauthenticated, CSRF validation not required
if not user or not user.is_active:
return None
try:
self.enforce_csrf(request)
except exceptions.AuthenticationFailed:
return None
# CSRF passed with authenticated user
return user, None

View File

@ -211,6 +211,8 @@ class ApiMessageMixin:
_action_map = {"create": _("create"), "update": _("update")}
def get_success_message(self, cleaned_data):
if not isinstance(cleaned_data, dict):
return ''
data = {k: v for k, v in cleaned_data.items()}
action = getattr(self, "action", "create")
data["action"] = self._action_map.get(action)

View File

@ -1,6 +1,7 @@
# -*- coding: utf-8 -*-
#
from .models import Organization
from .utils import get_org_from_request, set_current_org
@ -8,7 +9,21 @@ class OrgMiddleware:
def __init__(self, get_response):
self.get_response = get_response
@staticmethod
def set_permed_org_if_need(request):
if request.content_type != "text/plain":
return
if not (request.user.is_authenticated and request.user.is_org_admin):
return
org = get_org_from_request(request)
if org.can_admin_by(request.user):
return
admin_orgs = Organization.get_user_admin_orgs(request.user)
if admin_orgs:
request.session['oid'] = str(admin_orgs[0].id)
def __call__(self, request):
self.set_permed_org_if_need(request)
org = get_org_from_request(request)
request.current_org = org
set_current_org(org)

View File

@ -13,6 +13,7 @@ from rest_framework.validators import UniqueTogetherValidator
from common.utils import get_logger
from common.validators import ProjectUniqueValidator
from common.mixins import BulkSerializerMixin
from .utils import (
current_org, set_current_org, set_to_root_org, get_current_org_id
)
@ -25,6 +26,7 @@ __all__ = [
'OrgManager', 'OrgViewGenericMixin', 'OrgModelMixin', 'OrgModelForm',
'RootOrgViewMixin', 'OrgMembershipSerializerMixin',
'OrgMembershipModelViewSetMixin', 'OrgResourceSerializerMixin',
'BulkOrgResourceSerializerMixin', 'BulkOrgResourceModelSerializer',
]
@ -217,7 +219,7 @@ class OrgResourceSerializerMixin(serializers.Serializer):
由于HiddenField字段不可读API获取资产信息时获取不到org_id
但是coco需要资产的org_id字段所以修改为CharField类型
"""
org_id = serializers.CharField(default=get_current_org_id)
org_id = serializers.ReadOnlyField(default=get_current_org_id)
def get_validators(self):
_validators = super().get_validators()
@ -229,3 +231,16 @@ class OrgResourceSerializerMixin(serializers.Serializer):
v = ProjectUniqueValidator(v.queryset, v.fields)
validators.append(v)
return validators
def get_field_names(self, declared_fields, info):
fields = super().get_field_names(declared_fields, info)
fields.extend(["org_id", "org_name"])
return fields
class BulkOrgResourceSerializerMixin(BulkSerializerMixin, OrgResourceSerializerMixin):
pass
class BulkOrgResourceModelSerializer(BulkOrgResourceSerializerMixin, serializers.ModelSerializer):
pass

View File

@ -4,6 +4,7 @@
from rest_framework import serializers
from common.fields import StringManyToManyField
from orgs.mixins import BulkOrgResourceModelSerializer
from perms.models import AssetPermission, Action
from assets.models import Node
from assets.serializers import AssetGrantedSerializer
@ -22,13 +23,13 @@ class ActionSerializer(serializers.ModelSerializer):
fields = '__all__'
class AssetPermissionCreateUpdateSerializer(serializers.ModelSerializer):
class AssetPermissionCreateUpdateSerializer(BulkOrgResourceModelSerializer):
class Meta:
model = AssetPermission
exclude = ('created_by', 'date_created')
class AssetPermissionListSerializer(serializers.ModelSerializer):
class AssetPermissionListSerializer(BulkOrgResourceModelSerializer):
users = StringManyToManyField(many=True, read_only=True)
user_groups = StringManyToManyField(many=True, read_only=True)
assets = StringManyToManyField(many=True, read_only=True)

View File

@ -3,6 +3,8 @@
from rest_framework import serializers
from common.serializers import AdaptedBulkListSerializer
from orgs.mixins import BulkOrgResourceModelSerializer
from ..models import RemoteAppPermission
@ -13,13 +15,14 @@ __all__ = [
]
class RemoteAppPermissionSerializer(serializers.ModelSerializer):
class RemoteAppPermissionSerializer(BulkOrgResourceModelSerializer):
class Meta:
model = RemoteAppPermission
list_serializer_class = AdaptedBulkListSerializer
fields = [
'id', 'name', 'users', 'user_groups', 'remote_apps', 'comment',
'is_active', 'date_start', 'date_expired', 'is_valid',
'created_by', 'date_created', 'org_id'
'created_by', 'date_created',
]
read_only_fields = ['created_by', 'date_created']

View File

@ -2,7 +2,6 @@
#
from django.views.generic import ListView, UpdateView, DeleteView, \
DetailView, View
from django.contrib.auth.mixins import LoginRequiredMixin
from django.utils.translation import ugettext as _
from django.shortcuts import redirect
from django.urls import reverse_lazy, reverse

View File

@ -7,6 +7,7 @@ from rest_framework import serializers
from common.utils import get_signer, validate_ssh_public_key
from common.mixins import BulkSerializerMixin
from common.serializers import AdaptedBulkListSerializer
from orgs.mixins import BulkOrgResourceModelSerializer
from ..models import User, UserGroup
signer = get_signer()
@ -56,7 +57,7 @@ class UserUpdateGroupSerializer(serializers.ModelSerializer):
fields = ['id', 'groups']
class UserGroupSerializer(BulkSerializerMixin, serializers.ModelSerializer):
class UserGroupSerializer(BulkOrgResourceModelSerializer):
users = serializers.PrimaryKeyRelatedField(
required=False, many=True, queryset=User.objects.all(), label=_('User')
)