Merge pull request #10655 from jumpserver/pr@dev@fix_login_acl_uniq

perf: 优化 LoginACL 迁移,避免 uniq error
pull/10657/head
老广 2023-06-08 18:35:23 +08:00 committed by GitHub
commit 8f8e781376
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 18 additions and 10 deletions

View File

@ -1,4 +1,5 @@
# Generated by Django 3.2.17 on 2023-06-06 10:57
from collections import defaultdict
from django.db import migrations, models
@ -7,7 +8,13 @@ import common.db.fields
def migrate_users_login_acls(apps, schema_editor):
login_acl_model = apps.get_model('acls', 'LoginACL')
name_used = defaultdict(int)
for login_acl in login_acl_model.objects.all():
name = login_acl.name
if name_used[name] > 0:
login_acl.name += "_{}".format(name_used[name])
name_used[name] += 1
login_acl.users = {
"type": "ids", "ids": [str(login_acl.user_id)]
}
@ -25,6 +32,7 @@ class Migration(migrations.Migration):
name='users',
field=common.db.fields.JSONManyToManyField(default=dict, to='users.User', verbose_name='Users'),
),
migrations.RunPython(migrate_users_login_acls),
migrations.RemoveField(
model_name='loginacl',
name='user',

View File

@ -90,7 +90,7 @@ class UserBaseACL(BaseACL):
queryset = cls.objects.all()
q = cls.users.get_filter_q(user)
queryset = queryset.filter(q)
return queryset.valid().distinct()
return queryset.filter(is_active=True).distinct()
class UserAssetAccountBaseACL(OrgModelMixin, UserBaseACL):
@ -125,4 +125,4 @@ class UserAssetAccountBaseACL(OrgModelMixin, UserBaseACL):
kwargs['org_id'] = org_id
if kwargs:
queryset = queryset.filter(**kwargs)
return queryset.valid().distinct().order_by('priority', 'date_created')
return queryset.filter(is_active=True).distinct().order_by('priority', 'date_created')

View File

@ -20,22 +20,18 @@ class LoginACL(UserBaseACL):
def is_action(self, action):
return self.action == action
@classmethod
def filter_acl(cls, user):
return user.login_acls.all().valid().distinct()
def create_confirm_ticket(self, request):
from tickets import const
from tickets.models import ApplyLoginTicket
from orgs.models import Organization
title = _('Login confirm') + ' {}'.format(self.user)
title = _('Login confirm') + ' {}'.format(request.user)
login_ip = get_request_ip(request) if request else ''
login_ip = login_ip or '0.0.0.0'
login_city = get_ip_city(login_ip)
login_datetime = local_now_display()
data = {
'title': title,
'applicant': self.user,
'applicant': request.user,
'apply_login_ip': login_ip,
'org_id': Organization.ROOT_ID,
'apply_login_city': login_city,

View File

@ -369,7 +369,7 @@ class AuthACLMixin:
logger.debug('Login confirm acl id: {}'.format(acl_id))
if not acl_id:
return
acl = LoginACL.filter_acl(user).filter(id=acl_id).first()
acl = LoginACL.get_user_acls(user).filter(id=acl_id).first()
if not acl:
return
if not acl.is_action(acl.ActionChoices.review):

View File

@ -10,7 +10,7 @@ from django.apps import apps
from django.core.exceptions import ValidationError
from django.core.validators import MinValueValidator, MaxValueValidator
from django.db import models
from django.db.models import Q, Manager
from django.db.models import Q, Manager, QuerySet
from django.utils.encoding import force_text
from django.utils.translation import ugettext_lazy as _
from rest_framework.utils.encoders import JSONEncoder
@ -486,6 +486,10 @@ class JSONManyToManyDescriptor:
elif rule['match'] == 'm2m':
if isinstance(value, Manager):
value = value.values_list('id', flat=True)
elif isinstance(value, QuerySet):
value = value.values_list('id', flat=True)
elif isinstance(value, models.Model):
value = [value.id]
value = set(map(str, value))
rule_value = set(map(str, rule_value))
res &= rule_value.issubset(value)