mirror of https://github.com/jumpserver/jumpserver
fix: 删除掉连接方式控制半成品代码
parent
563b9f77a6
commit
faf1dedfe2
|
@ -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'})
|
|
||||||
|
|
|
@ -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)
|
|
|
@ -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
|
|
Loading…
Reference in New Issue