From 06de6c35750768cbfd73c283b2cf3f42fd421b1f Mon Sep 17 00:00:00 2001 From: Michael Bai Date: Fri, 22 Oct 2021 14:27:54 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E8=B5=84=E4=BA=A7?= =?UTF-8?q?=E7=B3=BB=E7=BB=9F=E7=94=A8=E6=88=B7auth-info=E8=8E=B7=E5=8F=96?= =?UTF-8?q?=E6=B5=81=E7=A8=8B=E5=8F=8A=E5=88=9B=E5=BB=BA=E6=97=B6=E6=89=8B?= =?UTF-8?q?=E5=8A=A8=E7=99=BB=E5=BD=95=E6=96=B9=E5=BC=8F=E7=9A=84=E6=A0=A1?= =?UTF-8?q?=E9=AA=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/assets/api/admin_user.py | 2 + apps/assets/api/asset.py | 1 + apps/assets/api/domain.py | 2 + apps/assets/api/system_user.py | 4 +- apps/assets/models/user.py | 56 ++++++++----------- apps/assets/serializers/system_user.py | 49 ++++++++++------ apps/orgs/api.py | 2 + .../api/application/application_permission.py | 2 + apps/perms/api/asset/asset_permission.py | 2 + apps/terminal/api/task.py | 1 + apps/tickets/api/ticket.py | 2 + apps/users/api/group.py | 2 + apps/users/api/user.py | 2 + 13 files changed, 77 insertions(+), 50 deletions(-) diff --git a/apps/assets/api/admin_user.py b/apps/assets/api/admin_user.py index 043a30a1b..e7f1598cd 100644 --- a/apps/assets/api/admin_user.py +++ b/apps/assets/api/admin_user.py @@ -21,6 +21,8 @@ class AdminUserViewSet(OrgBulkModelViewSet): search_fields = filterset_fields serializer_class = serializers.AdminUserSerializer permission_classes = (IsOrgAdmin,) + ordering_fields = ('name',) + ordering = ('name', ) def get_queryset(self): queryset = super().get_queryset().filter(type=SystemUser.Type.admin) diff --git a/apps/assets/api/asset.py b/apps/assets/api/asset.py index 410020d39..321fa5af7 100644 --- a/apps/assets/api/asset.py +++ b/apps/assets/api/asset.py @@ -50,6 +50,7 @@ class AssetViewSet(SuggestionMixin, FilterAssetByNodeMixin, OrgBulkModelViewSet) } search_fields = ("hostname", "ip") ordering_fields = ("hostname", "ip", "port", "cpu_cores") + ordering = ('hostname', ) serializer_classes = { 'default': serializers.AssetSerializer, 'suggestion': serializers.MiniAssetSerializer diff --git a/apps/assets/api/domain.py b/apps/assets/api/domain.py index dbf7fa277..fe3255103 100644 --- a/apps/assets/api/domain.py +++ b/apps/assets/api/domain.py @@ -22,6 +22,8 @@ class DomainViewSet(OrgBulkModelViewSet): search_fields = filterset_fields permission_classes = (IsOrgAdminOrAppUser,) serializer_class = serializers.DomainSerializer + ordering_fields = ('name',) + ordering = ('name', ) def get_serializer_class(self): if self.request.query_params.get('gateway'): diff --git a/apps/assets/api/system_user.py b/apps/assets/api/system_user.py index f03f2e7d4..01baf000b 100644 --- a/apps/assets/api/system_user.py +++ b/apps/assets/api/system_user.py @@ -41,6 +41,8 @@ class SystemUserViewSet(SuggestionMixin, OrgBulkModelViewSet): 'default': serializers.SystemUserSerializer, 'suggestion': serializers.MiniSystemUserSerializer } + ordering_fields = ('name', 'protocol') + ordering = ('name', ) permission_classes = (IsOrgAdminOrAppUser,) @@ -73,7 +75,7 @@ class SystemUserTempAuthInfoApi(generics.CreateAPIView): with tmp_to_root_org(): instance = get_object_or_404(SystemUser, pk=pk) - instance.set_temp_auth(instance_id, user, data) + instance.set_temp_auth(instance_id, user.id, data) return Response(serializer.data, status=201) diff --git a/apps/assets/models/user.py b/apps/assets/models/user.py index 3677144c2..52e3c2af8 100644 --- a/apps/assets/models/user.py +++ b/apps/assets/models/user.py @@ -103,16 +103,23 @@ class AuthMixin: password = cache.get(key) return password - def load_tmp_auth_if_has(self, asset_or_app_id, user): - if not asset_or_app_id or not user: - return + def _clean_auth_info_if_manual_login_mode(self): + if self.login_mode == self.LOGIN_MANUAL: + self.password = '' + self.private_key = '' + self.public_key = '' + def _load_tmp_auth_if_has(self, asset_or_app_id, user_id): if self.login_mode != self.LOGIN_MANUAL: return - auth = self.get_temp_auth(asset_or_app_id, user) + if not asset_or_app_id or not user_id: + return + + auth = self.get_temp_auth(asset_or_app_id, user_id) if not auth: return + username = auth.get('username') password = auth.get('password') @@ -122,17 +129,11 @@ class AuthMixin: self.password = password def load_app_more_auth(self, app_id=None, user_id=None): - from users.models import User - + self._clean_auth_info_if_manual_login_mode() + # 加载临时认证信息 if self.login_mode == self.LOGIN_MANUAL: - self.password = '' - self.private_key = '' - if not user_id: + self._load_tmp_auth_if_has(app_id, user_id) return - user = get_object_or_none(User, pk=user_id) - if not user: - return - self.load_tmp_auth_if_has(app_id, user) def load_asset_special_auth(self, asset, username=''): """ @@ -152,34 +153,25 @@ class AuthMixin: def load_asset_more_auth(self, asset_id=None, username=None, user_id=None): from users.models import User - + self._clean_auth_info_if_manual_login_mode() + # 加载临时认证信息 if self.login_mode == self.LOGIN_MANUAL: - self.password = '' - self.private_key = '' - - asset = None - if asset_id: - asset = get_object_or_none(Asset, pk=asset_id) - # 没有资产就没有必要继续了 - if not asset: - logger.debug('Asset not found, pass') + self._load_tmp_auth_if_has(asset_id, user_id) return - - user = None - if user_id: - user = get_object_or_none(User, pk=user_id) - - _username = self.username + # 更新用户名 + user = get_object_or_none(User, pk=user_id) if user_id else None if self.username_same_with_user: if user and not username: _username = user.username else: _username = username self.username = _username - # 加载某个资产的特殊配置认证信息 - self.load_asset_special_auth(asset, _username) - self.load_tmp_auth_if_has(asset_id, user) + asset = get_object_or_none(Asset, pk=asset_id) if asset_id else None + if not asset: + logger.debug('Asset not found, pass') + return + self.load_asset_special_auth(asset, self.username) class SystemUser(ProtocolMixin, AuthMixin, BaseUser): diff --git a/apps/assets/serializers/system_user.py b/apps/assets/serializers/system_user.py index 16cf9451c..a380c3831 100644 --- a/apps/assets/serializers/system_user.py +++ b/apps/assets/serializers/system_user.py @@ -123,7 +123,8 @@ class SystemUserSerializer(AuthSerializerMixin, BulkOrgResourceModelSerializer): return '' return home - def validate_sftp_root(self, value): + @staticmethod + def validate_sftp_root(value): if value in ['home', 'tmp']: return value if not value.startswith('/'): @@ -131,19 +132,6 @@ class SystemUserSerializer(AuthSerializerMixin, BulkOrgResourceModelSerializer): raise serializers.ValidationError(error) return value - def validate_admin_user(self, attrs): - if self.instance: - tp = self.instance.type - else: - tp = attrs.get('type') - if tp != SystemUser.Type.admin: - return attrs - attrs['protocol'] = SystemUser.Protocol.ssh - attrs['login_mode'] = SystemUser.LOGIN_AUTO - attrs['username_same_with_user'] = False - attrs['auto_push'] = False - return attrs - def validate_password(self, password): super().validate_password(password) auto_gen_key = self.get_initial_value("auto_generate_key", False) @@ -155,7 +143,20 @@ class SystemUserSerializer(AuthSerializerMixin, BulkOrgResourceModelSerializer): raise serializers.ValidationError(_("Password or private key required")) return password - def validate_gen_key(self, attrs): + def _validate_admin_user(self, attrs): + if self.instance: + tp = self.instance.type + else: + tp = attrs.get('type') + if tp != SystemUser.Type.admin: + return attrs + attrs['protocol'] = SystemUser.Protocol.ssh + attrs['login_mode'] = SystemUser.LOGIN_AUTO + attrs['username_same_with_user'] = False + attrs['auto_push'] = False + return attrs + + def _validate_gen_key(self, attrs): username = attrs.get("username", "manual") auto_gen_key = attrs.pop("auto_generate_key", False) protocol = attrs.get("protocol") @@ -179,9 +180,23 @@ class SystemUserSerializer(AuthSerializerMixin, BulkOrgResourceModelSerializer): attrs["public_key"] = public_key return attrs + def _validate_login_mode(self, attrs): + if 'login_mode' in attrs: + login_mode = attrs['login_mode'] + else: + login_mode = self.instance.login_mode if self.instance else SystemUser.LOGIN_AUTO + + if login_mode == SystemUser.LOGIN_MANUAL: + attrs['password'] = '' + attrs['private_key'] = '' + attrs['public_key'] = '' + + return attrs + def validate(self, attrs): - attrs = self.validate_admin_user(attrs) - attrs = self.validate_gen_key(attrs) + attrs = self._validate_admin_user(attrs) + attrs = self._validate_gen_key(attrs) + attrs = self._validate_login_mode(attrs) return attrs @classmethod diff --git a/apps/orgs/api.py b/apps/orgs/api.py index bc07a6833..283e71469 100644 --- a/apps/orgs/api.py +++ b/apps/orgs/api.py @@ -48,6 +48,8 @@ class OrgViewSet(BulkModelViewSet): queryset = Organization.objects.all() serializer_class = OrgSerializer permission_classes = (IsSuperUserOrAppUser,) + ordering_fields = ('name',) + ordering = ('name', ) def get_serializer_class(self): mapper = { diff --git a/apps/perms/api/application/application_permission.py b/apps/perms/api/application/application_permission.py index 9c3eb18b4..798455053 100644 --- a/apps/perms/api/application/application_permission.py +++ b/apps/perms/api/application/application_permission.py @@ -22,6 +22,8 @@ class ApplicationPermissionViewSet(BasePermissionViewSet): custom_filter_fields = BasePermissionViewSet.custom_filter_fields + [ 'application_id', 'application', 'app', 'app_name' ] + ordering_fields = ('name',) + ordering = ('name', ) def get_queryset(self): queryset = super().get_queryset().prefetch_related( diff --git a/apps/perms/api/asset/asset_permission.py b/apps/perms/api/asset/asset_permission.py index ff4de7d9f..7b3be59c1 100644 --- a/apps/perms/api/asset/asset_permission.py +++ b/apps/perms/api/asset/asset_permission.py @@ -21,3 +21,5 @@ class AssetPermissionViewSet(OrgBulkModelViewSet): serializer_class = serializers.AssetPermissionSerializer filterset_class = AssetPermissionFilter search_fields = ('name',) + ordering_fields = ('name',) + ordering = ('name', ) diff --git a/apps/terminal/api/task.py b/apps/terminal/api/task.py index 474cab65f..137b8481b 100644 --- a/apps/terminal/api/task.py +++ b/apps/terminal/api/task.py @@ -17,6 +17,7 @@ logger = logging.getLogger(__file__) class TaskViewSet(BulkModelViewSet): queryset = Task.objects.all() serializer_class = serializers.TaskSerializer + filterset_fields = ('is_finished',) permission_classes = (IsOrgAdminOrAppUser,) diff --git a/apps/tickets/api/ticket.py b/apps/tickets/api/ticket.py index cbbe72151..86d06f062 100644 --- a/apps/tickets/api/ticket.py +++ b/apps/tickets/api/ticket.py @@ -29,6 +29,8 @@ class TicketViewSet(CommonApiMixin, viewsets.ModelViewSet): search_fields = [ 'title', 'action', 'type', 'status', 'applicant_display' ] + ordering_fields = ('title',) + ordering = ('title', ) def create(self, request, *args, **kwargs): raise MethodNotAllowed(self.action) diff --git a/apps/users/api/group.py b/apps/users/api/group.py index 27196c2f3..db8c4109c 100644 --- a/apps/users/api/group.py +++ b/apps/users/api/group.py @@ -16,3 +16,5 @@ class UserGroupViewSet(OrgBulkModelViewSet): search_fields = filterset_fields permission_classes = (IsOrgAdmin,) serializer_class = UserGroupSerializer + ordering_fields = ('name', ) + ordering = ('name', ) diff --git a/apps/users/api/user.py b/apps/users/api/user.py index a1b808a22..2499e7b78 100644 --- a/apps/users/api/user.py +++ b/apps/users/api/user.py @@ -42,6 +42,8 @@ class UserViewSet(CommonApiMixin, UserQuerysetMixin, BulkModelViewSet): 'invite': InviteSerializer, } extra_filter_backends = [OrgRoleUserFilterBackend] + ordering_fields = ('name',) + ordering = ('name', ) def get_queryset(self): queryset = super().get_queryset().prefetch_related(