diff --git a/apps/acls/api/connect_acl.py b/apps/acls/api/connect_acl.py deleted file mode 100644 index aeff03ea2..000000000 --- a/apps/acls/api/connect_acl.py +++ /dev/null @@ -1,52 +0,0 @@ -from rest_framework.views import APIView -from rest_framework import status -from django.http.response import JsonResponse -from django.utils.translation import ugettext_lazy as _ - -from common.drf.api import JMSBulkModelViewSet -from common.const.choices import ConnectMethodChoices -from ..models import ConnectACL -from .. import serializers - -__all__ = ['ConnectACLViewSet', 'ConnectMethodsAPI', 'ConnectMethodPermissionsAPI'] - - -class ConnectACLViewSet(JMSBulkModelViewSet): - queryset = ConnectACL.objects.all() - filterset_fields = ('name', ) - search_fields = ('name',) - serializer_class = serializers.ConnectACLSerializer - - -class ConnectMethodsAPI(APIView): - rbac_perms = { - 'GET': 'acls.view_connnectacl', - } - - @staticmethod - def get(request, *args, **kwargs): - data = [] - for m in ConnectMethodChoices.choices: - data.append({'label': m[1], 'value': m[0]}) - return JsonResponse(data, safe=False) - - -class ConnectMethodPermissionsAPI(APIView): - rbac_perms = { - 'GET': 'acls.view_connnectacl', - } - - @staticmethod - def get(request, *args, **kwargs): - login_type = request.query_params.get('login_type') - if not login_type: - rules = ConnectACL().all_rules(request.user) - return JsonResponse({'rules': rules}) - - acl = ConnectACL.match(request.user, login_type) - if acl: - err = _('The current user is not allowed to login in this way') - return JsonResponse({'error': err}) - else: - return JsonResponse({'msg': 'ok'}) - diff --git a/apps/acls/models/connect_acl.py b/apps/acls/models/connect_acl.py deleted file mode 100644 index a936f3cb4..000000000 --- a/apps/acls/models/connect_acl.py +++ /dev/null @@ -1,120 +0,0 @@ -from django.db import models -from django.core.cache import cache -from django.utils.translation import ugettext_lazy as _ - -from common.utils.connection import get_redis_client -from common.const.choices import ConnectMethodChoices -from orgs.mixins.models import OrgManager, OrgModelMixin -from .base import BaseACL, BaseACLQuerySet - - -class ACLManager(OrgManager): - - def valid(self): - return self.get_queryset().valid() - - -class ConnectACL(BaseACL, OrgModelMixin): - ConnectACLUserCacheKey = 'CONNECT_ACL_USER_{}' - ConnectACLUserCacheTTL = 600 - - class ActionChoices(models.TextChoices): - reject = 'reject', _('Reject') - - # 用户 - users = models.ManyToManyField( - 'users.User', related_name='connect_acls', blank=True, - verbose_name=_("User") - ) - user_groups = models.ManyToManyField( - 'users.UserGroup', related_name='connect_acls', blank=True, - verbose_name=_("User group"), - ) - rules = models.JSONField(default=list, verbose_name=_('Rule')) - # 动作 - action = models.CharField( - max_length=64, verbose_name=_('Action'), - choices=ActionChoices.choices, default=ActionChoices.reject - ) - - objects = ACLManager.from_queryset(BaseACLQuerySet)() - - class Meta: - ordering = ('priority', '-date_updated', 'name') - verbose_name = _('Connect acl') - - def __str__(self): - return self.name - - @property - def rules_display(self): - return ', '.join( - [ConnectMethodChoices.get_label(i) for i in self.rules] - ) - - def is_action(self, action): - return self.action == action - - @staticmethod - def match(user, connect_type): - if not user: - return - - user_acls = user.connect_acls.all().valid().distinct() - for acl in user_acls: - if connect_type in acl.rules: - return acl - - for user_group in user.groups.all(): - acls = user_group.connect_acls.all().valid().distinct() - for acl in acls: - if connect_type in acl.rules: - return acl - - def _get_all_rules_from_cache(self, user): - find = False - cache_key = self.ConnectACLUserCacheKey.format(user.id) - rules = cache.get(cache_key) - if rules is not None: - find = True - return rules, find - - @staticmethod - def _get_all_rules_from_db(user): - connect_rules = set() - user_acls = user.connect_acls.all().valid() - user_acl_rules = user_acls.values_list('id', 'rules') - for r_id, rule in user_acl_rules: - connect_rules.update(rule) - - for ug in user.groups.all(): - user_group_acls = ug.connect_acls.all().valid() - user_group_rules = user_group_acls.values_list('id', 'rules') - for r_id, rule in user_group_rules: - connect_rules.update(rule) - return list(connect_rules) - - def set_all_rules_to_cache(self, key, rules): - cache.set(key, rules, self.ConnectACLUserCacheTTL) - - def all_rules(self, user): - rules, find = self._get_all_rules_from_cache(user) - if not find: - rules = self._get_all_rules_from_db(user) - self.set_all_rules_to_cache( - self.ConnectACLUserCacheKey.format(user.id), rules - ) - return rules - - def clear_rules_cache(self): - cache.delete_pattern( - self.ConnectACLUserCacheKey.format('*') - ) - - def save(self, *args, **kwargs): - self.clear_rules_cache() - return super().save(*args, **kwargs) - - def delete(self, using=None, keep_parents=False): - self.clear_rules_cache() - return super().delete(using=using, keep_parents=keep_parents) diff --git a/apps/acls/serializers/connnect_acl.py b/apps/acls/serializers/connnect_acl.py deleted file mode 100644 index c4377491f..000000000 --- a/apps/acls/serializers/connnect_acl.py +++ /dev/null @@ -1,36 +0,0 @@ -from django.utils.translation import ugettext as _ -from rest_framework import serializers - -from common.drf.serializers import BulkModelSerializer -from common.const.choices import ConnectMethodChoices -from ..models import ConnectACL - - -__all__ = ['ConnectACLSerializer', ] - - -class ConnectACLSerializer(BulkModelSerializer): - action_display = serializers.ReadOnlyField(source='get_action_display', label=_('Action')) - - class Meta: - model = ConnectACL - fields_mini = ['id', 'name'] - fields_small = fields_mini + [ - 'priority', 'rules', 'rules_display', 'action', 'action_display', 'is_active', - 'date_created', 'date_updated', 'comment', 'created_by' - ] - fields_m2m = ['users', 'user_groups'] - fields = fields_small + fields_m2m - extra_kwargs = { - 'priority': {'default': 50}, - 'is_active': {'default': True} - } - - @staticmethod - def validate_rules(rules): - for r in rules: - label = ConnectMethodChoices.get_label(r) - if not label: - error = _('Invalid connection method: {}').format(r) - raise serializers.ValidationError(error) - return rules