perf: 修改 acl

pull/9150/head
ibuler 2 years ago
parent 10e3100d3c
commit a18f544cf8

@ -5,7 +5,6 @@ from django.db import migrations, models
class Migration(migrations.Migration): class Migration(migrations.Migration):
dependencies = [ dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL), migrations.swappable_dependency(settings.AUTH_USER_MODEL),
('acls', '0004_auto_20220831_1658'), ('acls', '0004_auto_20220831_1658'),
@ -15,7 +14,7 @@ class Migration(migrations.Migration):
migrations.AlterField( migrations.AlterField(
model_name='loginacl', model_name='loginacl',
name='action', name='action',
field=models.CharField(choices=[('reject', 'Reject'), ('allow', 'Allow'), ('confirm', 'Confirm')], default='reject', max_length=64, verbose_name='Action'), field=models.CharField(default='reject', max_length=64, verbose_name='Action'),
), ),
migrations.AlterField( migrations.AlterField(
model_name='loginacl', model_name='loginacl',
@ -25,7 +24,7 @@ class Migration(migrations.Migration):
migrations.AlterField( migrations.AlterField(
model_name='loginassetacl', model_name='loginassetacl',
name='action', name='action',
field=models.CharField(choices=[('reject', 'Reject'), ('allow', 'Allow'), ('confirm', 'Confirm')], default='reject', max_length=64, verbose_name='Action'), field=models.CharField(default='reject', max_length=64, verbose_name='Action'),
), ),
migrations.AlterField( migrations.AlterField(
model_name='loginassetacl', model_name='loginassetacl',

@ -1,13 +1,13 @@
# Generated by Django 3.2.14 on 2022-12-01 11:39 # Generated by Django 3.2.14 on 2022-12-01 11:39
from django.conf import settings import uuid
import django.core.validators import django.core.validators
from django.conf import settings
from django.db import migrations, models from django.db import migrations, models
import uuid
class Migration(migrations.Migration): class Migration(migrations.Migration):
dependencies = [ dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL), migrations.swappable_dependency(settings.AUTH_USER_MODEL),
('acls', '0005_auto_20221201_1846'), ('acls', '0005_auto_20221201_1846'),
@ -22,9 +22,11 @@ class Migration(migrations.Migration):
('date_created', models.DateTimeField(auto_now_add=True, null=True, verbose_name='Date created')), ('date_created', models.DateTimeField(auto_now_add=True, null=True, verbose_name='Date created')),
('date_updated', models.DateTimeField(auto_now=True, verbose_name='Date updated')), ('date_updated', models.DateTimeField(auto_now=True, verbose_name='Date updated')),
('id', models.UUIDField(default=uuid.uuid4, primary_key=True, serialize=False)), ('id', models.UUIDField(default=uuid.uuid4, primary_key=True, serialize=False)),
('org_id', models.CharField(blank=True, db_index=True, default='', max_length=36, verbose_name='Organization')), ('org_id',
models.CharField(blank=True, db_index=True, default='', max_length=36, verbose_name='Organization')),
('name', models.CharField(max_length=128, verbose_name='Name')), ('name', models.CharField(max_length=128, verbose_name='Name')),
('type', models.CharField(choices=[('command', 'Command'), ('regex', 'Regex')], default='command', max_length=16, verbose_name='Type')), ('type', models.CharField(choices=[('command', 'Command'), ('regex', 'Regex')], default='command',
max_length=16, verbose_name='Type')),
('content', models.TextField(help_text='One line one command', verbose_name='Content')), ('content', models.TextField(help_text='One line one command', verbose_name='Content')),
('ignore_case', models.BooleanField(default=True, verbose_name='Ignore case')), ('ignore_case', models.BooleanField(default=True, verbose_name='Ignore case')),
], ],
@ -36,21 +38,26 @@ class Migration(migrations.Migration):
migrations.CreateModel( migrations.CreateModel(
name='CommandFilterACL', name='CommandFilterACL',
fields=[ fields=[
('org_id', models.CharField(blank=True, db_index=True, default='', max_length=36, verbose_name='Organization')), ('org_id',
models.CharField(blank=True, db_index=True, default='', max_length=36, verbose_name='Organization')),
('id', models.UUIDField(default=uuid.uuid4, primary_key=True, serialize=False)), ('id', models.UUIDField(default=uuid.uuid4, primary_key=True, serialize=False)),
('created_by', models.CharField(blank=True, max_length=32, null=True, verbose_name='Created by')), ('created_by', models.CharField(blank=True, max_length=32, null=True, verbose_name='Created by')),
('date_created', models.DateTimeField(auto_now_add=True, null=True, verbose_name='Date created')), ('date_created', models.DateTimeField(auto_now_add=True, null=True, verbose_name='Date created')),
('date_updated', models.DateTimeField(auto_now=True, verbose_name='Date updated')), ('date_updated', models.DateTimeField(auto_now=True, verbose_name='Date updated')),
('name', models.CharField(max_length=128, verbose_name='Name')), ('name', models.CharField(max_length=128, verbose_name='Name')),
('priority', models.IntegerField(default=50, help_text='1-100, the lower the value will be match first', validators=[django.core.validators.MinValueValidator(1), django.core.validators.MaxValueValidator(100)], verbose_name='Priority')), ('priority', models.IntegerField(default=50, help_text='1-100, the lower the value will be match first',
('action', models.CharField(choices=[('reject', 'Reject'), ('allow', 'Allow'), ('confirm', 'Confirm')], default='reject', max_length=64, verbose_name='Action')), validators=[django.core.validators.MinValueValidator(1),
django.core.validators.MaxValueValidator(100)],
verbose_name='Priority')),
('action', models.CharField(default='reject', max_length=64, verbose_name='Action')),
('is_active', models.BooleanField(default=True, verbose_name='Active')), ('is_active', models.BooleanField(default=True, verbose_name='Active')),
('comment', models.TextField(blank=True, default='', verbose_name='Comment')), ('comment', models.TextField(blank=True, default='', verbose_name='Comment')),
('users', models.JSONField(verbose_name='User')), ('users', models.JSONField(verbose_name='User')),
('accounts', models.JSONField(verbose_name='Account')), ('accounts', models.JSONField(verbose_name='Account')),
('assets', models.JSONField(verbose_name='Asset')), ('assets', models.JSONField(verbose_name='Asset')),
('commands', models.ManyToManyField(to='acls.CommandGroup', verbose_name='Commands')), ('commands', models.ManyToManyField(to='acls.CommandGroup', verbose_name='Commands')),
('reviewers', models.ManyToManyField(blank=True, to=settings.AUTH_USER_MODEL, verbose_name='Reviewers')), (
'reviewers', models.ManyToManyField(blank=True, to=settings.AUTH_USER_MODEL, verbose_name='Reviewers')),
], ],
options={ options={
'verbose_name': 'Command acl', 'verbose_name': 'Command acl',

@ -0,0 +1,21 @@
# Generated by Django 3.2.14 on 2022-12-02 02:48
from django.db import migrations
def migrate_login_type(apps, schema_editor):
login_asset_model = apps.get_model('acls', 'LoginAssetACL')
login_asset_model.objects.filter(action='login_confirm').update(action='review')
login_system_model = apps.get_model('acls', 'LoginACL')
login_system_model.objects.filter(action='confirm').update(action='review')
class Migration(migrations.Migration):
dependencies = [
('acls', '0006_commandfilteracl_commandgroup'),
]
operations = [
migrations.RunPython(migrate_login_type),
]

@ -1,16 +1,18 @@
from django.core.validators import MinValueValidator, MaxValueValidator
from django.db import models from django.db import models
from django.db.models import Q
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _
from django.core.validators import MinValueValidator, MaxValueValidator
from common.mixins import CommonModelMixin
from common.mixins import CommonModelMixin
from common.utils import contains_ip
__all__ = ['BaseACL', 'BaseACLQuerySet', 'ACLManager'] __all__ = ['BaseACL', 'BaseACLQuerySet', 'ACLManager', 'AssetAccountUserACLQuerySet']
class ActionChoices(models.TextChoices): class ActionChoices(models.TextChoices):
reject = 'reject', _('Reject') reject = 'reject', _('Reject')
allow = 'allow', _('Allow') accept = 'allow', _('Allow')
confirm = 'confirm', _('Confirm') review = 'review', _('Review')
class BaseACLQuerySet(models.QuerySet): class BaseACLQuerySet(models.QuerySet):
@ -27,6 +29,32 @@ class BaseACLQuerySet(models.QuerySet):
return self.inactive() return self.inactive()
class AssetAccountUserACLQuerySet(BaseACLQuerySet):
def filter_user(self, user):
return self.filter(
Q(users__username_group__contains=user.username) |
Q(users__username_group__contains='*')
)
def filter_asset(self, asset):
queryset = self.filter(
Q(assets__name_group__contains=asset.name) |
Q(assets__name_group__contains='*')
)
ids = [
q.id for q in queryset
if contains_ip(asset.address, q.assets.get('address_group', []))
]
queryset = self.filter(id__in=ids)
return queryset
def filter_account(self, account_username):
return self.filter(
Q(accounts__username_group__contains=account_username) |
Q(accounts__username_group__contains='*')
)
class ACLManager(models.Manager): class ACLManager(models.Manager):
def valid(self): def valid(self):
return self.get_queryset().valid() return self.get_queryset().valid()
@ -39,10 +67,7 @@ class BaseACL(CommonModelMixin):
help_text=_("1-100, the lower the value will be match first"), help_text=_("1-100, the lower the value will be match first"),
validators=[MinValueValidator(1), MaxValueValidator(100)] validators=[MinValueValidator(1), MaxValueValidator(100)]
) )
action = models.CharField( action = models.CharField(max_length=64, default=ActionChoices.reject, verbose_name=_('Action'))
max_length=64, verbose_name=_('Action'),
choices=ActionChoices.choices, default=ActionChoices.reject
)
reviewers = models.ManyToManyField('users.User', blank=True, verbose_name=_("Reviewers")) reviewers = models.ManyToManyField('users.User', blank=True, verbose_name=_("Reviewers"))
is_active = models.BooleanField(default=True, verbose_name=_("Active")) is_active = models.BooleanField(default=True, verbose_name=_("Active"))
comment = models.TextField(default='', blank=True, verbose_name=_('Comment')) comment = models.TextField(default='', blank=True, verbose_name=_('Comment'))

@ -6,11 +6,11 @@ from django.db import models
from django.db.models import Q from django.db.models import Q
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _
from users.models import User, UserGroup
from orgs.mixins.models import JMSOrgBaseModel
from common.utils import lazyproperty, get_logger, get_object_or_none from common.utils import lazyproperty, get_logger, get_object_or_none
from orgs.mixins.models import JMSOrgBaseModel
from orgs.mixins.models import OrgModelMixin from orgs.mixins.models import OrgModelMixin
from .base import BaseACL from users.models import User, UserGroup
from .base import BaseACL, AssetAccountUserACLQuerySet, ACLManager
logger = get_logger(__file__) logger = get_logger(__file__)
@ -50,7 +50,6 @@ class CommandGroup(JMSOrgBaseModel):
if ' ' in _cmd: if ' ' in _cmd:
regex.append(cmd) regex.append(cmd)
continue continue
if not cmd: if not cmd:
continue continue
@ -89,6 +88,19 @@ class CommandGroup(JMSOrgBaseModel):
def __str__(self): def __str__(self):
return '{} % {}'.format(self.type, self.content) return '{} % {}'.format(self.type, self.content)
class CommandFilterACL(OrgModelMixin, BaseACL):
users = models.JSONField(verbose_name=_('User'))
assets = models.JSONField(verbose_name=_('Asset'))
accounts = models.JSONField(verbose_name=_('Account'))
commands = models.ManyToManyField(CommandGroup, verbose_name=_('Commands'))
objects = ACLManager.from_queryset(AssetAccountUserACLQuerySet)()
class Meta:
unique_together = ('name', 'org_id')
ordering = ('priority', '-date_updated', 'name')
verbose_name = _('Command acl')
def create_command_confirm_ticket(self, run_command, session, cmd_filter_rule, org_id): def create_command_confirm_ticket(self, run_command, session, cmd_filter_rule, org_id):
from tickets.const import TicketType from tickets.const import TicketType
from tickets.models import ApplyCommandTicket from tickets.models import ApplyCommandTicket
@ -147,16 +159,3 @@ class CommandGroup(JMSOrgBaseModel):
else: else:
rules = cls.objects.none() rules = cls.objects.none()
return rules return rules
class CommandFilterACL(OrgModelMixin, BaseACL):
# 条件
users = models.JSONField(verbose_name=_('User'))
accounts = models.JSONField(verbose_name=_('Account'))
assets = models.JSONField(verbose_name=_('Asset'))
commands = models.ManyToManyField(CommandGroup, verbose_name=_('Commands'))
class Meta:
unique_together = ('name', 'org_id')
ordering = ('priority', '-date_updated', 'name')
verbose_name = _('Command acl')

@ -1,35 +1,8 @@
from django.db import models from django.db import models
from django.db.models import Q
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _
from orgs.mixins.models import OrgModelMixin, OrgManager
from .base import BaseACL, BaseACLQuerySet, ACLManager
from common.utils.ip import contains_ip
from orgs.mixins.models import OrgModelMixin
class ACLQuerySet(BaseACLQuerySet): from .base import BaseACL, ACLManager, AssetAccountUserACLQuerySet
def filter_user(self, user):
return self.filter(
Q(users__username_group__contains=user.username) |
Q(users__username_group__contains='*')
)
def filter_asset(self, asset):
queryset = self.filter(
Q(assets__name_group__contains=asset.name) |
Q(assets__name_group__contains='*')
)
ids = [
q.id for q in queryset
if contains_ip(asset.address, q.assets.get('address_group', []))
]
queryset = LoginAssetACL.objects.filter(id__in=ids)
return queryset
def filter_account(self, account_username):
return self.filter(
Q(accounts__username_group__contains=account_username) |
Q(accounts__username_group__contains='*')
)
class LoginAssetACL(BaseACL, OrgModelMixin): class LoginAssetACL(BaseACL, OrgModelMixin):
@ -38,7 +11,7 @@ class LoginAssetACL(BaseACL, OrgModelMixin):
accounts = models.JSONField(verbose_name=_('Account')) accounts = models.JSONField(verbose_name=_('Account'))
assets = models.JSONField(verbose_name=_('Asset')) assets = models.JSONField(verbose_name=_('Asset'))
objects = ACLManager.from_queryset(ACLQuerySet)() objects = ACLManager.from_queryset(AssetAccountUserACLQuerySet)()
class Meta: class Meta:
unique_together = ('name', 'org_id') unique_together = ('name', 'org_id')
@ -65,4 +38,3 @@ class LoginAssetACL(BaseACL, OrgModelMixin):
ticket = ApplyLoginAssetTicket.objects.create(**data) ticket = ApplyLoginAssetTicket.objects.create(**data)
ticket.open_by_system(assignees) ticket.open_by_system(assignees)
return ticket return ticket

@ -0,0 +1,94 @@
from django.utils.translation import ugettext_lazy as _
from rest_framework import serializers
from acls.models.base import ActionChoices
from common.drf.fields import LabeledChoiceField, ObjectRelatedField
from orgs.models import Organization
from users.models import User
common_help_text = _(
"Format for comma-delimited string, with * indicating a match all. "
)
class ACLUsersSerializer(serializers.Serializer):
username_group = serializers.ListField(
default=["*"],
child=serializers.CharField(max_length=128),
label=_("Username"),
help_text=common_help_text,
)
class ACLAssestsSerializer(serializers.Serializer):
address_group_help_text = _(
"Format for comma-delimited string, with * indicating a match all. "
"Such as: "
"192.168.10.1, 192.168.1.0/24, 10.1.1.1-10.1.1.20, 2001:db8:2de::e13, 2001:db8:1a:1110::/64"
" (Domain name support)"
)
name_group = serializers.ListField(
default=["*"],
child=serializers.CharField(max_length=128),
label=_("Name"),
help_text=common_help_text,
)
address_group = serializers.ListField(
default=["*"],
child=serializers.CharField(max_length=1024),
label=_("IP/Host"),
help_text=address_group_help_text,
)
class ACLAccountsSerializer(serializers.Serializer):
username_group = serializers.ListField(
default=["*"],
child=serializers.CharField(max_length=128),
label=_("Username"),
help_text=common_help_text,
)
class BaseUserAssetAccountACLSerializerMixin(serializers.Serializer):
users = ACLUsersSerializer()
assets = ACLAssestsSerializer()
accounts = ACLAccountsSerializer()
reviewers = ObjectRelatedField(
queryset=User.objects, many=True, required=False, label=_('Reviewers')
)
reviewers_amount = serializers.IntegerField(read_only=True, source="reviewers.count")
action = LabeledChoiceField(
choices=ActionChoices.choices, label=_("Action")
)
class Meta:
fields_mini = ["id", "name"]
fields_small = fields_mini + [
"users", "accounts", "assets", "is_active",
"date_created", "date_updated", "priority",
"action", "comment", "created_by", "org_id",
]
fields_m2m = ["reviewers", "reviewers_amount"]
fields = fields_small + fields_m2m
extra_kwargs = {
"reviewers": {"allow_null": False, "required": True},
"priority": {"default": 50},
"is_active": {"default": True},
}
def validate_reviewers(self, reviewers):
org_id = self.fields["org_id"].default()
org = Organization.get_instance(org_id)
if not org:
error = _("The organization `{}` does not exist".format(org_id))
raise serializers.ValidationError(error)
users = org.get_members()
valid_reviewers = list(set(reviewers) & set(users))
if not valid_reviewers:
error = _(
"None of the reviewers belong to Organization `{}`".format(org.name)
)
raise serializers.ValidationError(error)
return valid_reviewers

@ -0,0 +1,16 @@
from django.utils.translation import ugettext_lazy as _
from acls.models import CommandGroup, CommandFilterACL
from common.drf.fields import ObjectRelatedField
from orgs.mixins.serializers import BulkOrgResourceModelSerializer
from .base import BaseUserAssetAccountACLSerializerMixin
__all__ = ["CommandFilterACLSerializer"]
class CommandFilterACLSerializer(BaseUserAssetAccountACLSerializerMixin, BulkOrgResourceModelSerializer):
commands = ObjectRelatedField(queryset=CommandGroup.objects, many=True, required=False, label=_('Commands'))
class Meta(BaseUserAssetAccountACLSerializerMixin.Meta):
model = CommandFilterACL
fields = BaseUserAssetAccountACLSerializerMixin.Meta.fields + ['commands']

@ -1,109 +1,11 @@
from rest_framework import serializers
from django.utils.translation import ugettext_lazy as _
from common.drf.fields import LabeledChoiceField
from common.drf.fields import ObjectRelatedField
from orgs.mixins.serializers import BulkOrgResourceModelSerializer from orgs.mixins.serializers import BulkOrgResourceModelSerializer
from orgs.models import Organization
from users.models import User
from acls import models
from .base import BaseUserAssetAccountACLSerializerMixin
from ..models import LoginAssetACL
__all__ = ["LoginAssetACLSerializer"] __all__ = ["LoginAssetACLSerializer"]
common_help_text = _( class LoginAssetACLSerializer(BaseUserAssetAccountACLSerializerMixin, BulkOrgResourceModelSerializer):
"Format for comma-delimited string, with * indicating a match all. " class Meta(BaseUserAssetAccountACLSerializerMixin.Meta):
) model = LoginAssetACL
class LoginAssetACLUsersSerializer(serializers.Serializer):
username_group = serializers.ListField(
default=["*"],
child=serializers.CharField(max_length=128),
label=_("Username"),
help_text=common_help_text,
)
class LoginAssetACLAssestsSerializer(serializers.Serializer):
address_group_help_text = _(
"Format for comma-delimited string, with * indicating a match all. "
"Such as: "
"192.168.10.1, 192.168.1.0/24, 10.1.1.1-10.1.1.20, 2001:db8:2de::e13, 2001:db8:1a:1110::/64"
" (Domain name support)"
)
name_group = serializers.ListField(
default=["*"],
child=serializers.CharField(max_length=128),
label=_("Name"),
help_text=common_help_text,
)
address_group = serializers.ListField(
default=["*"],
child=serializers.CharField(max_length=1024),
label=_("IP/Host"),
help_text=address_group_help_text,
)
class LoginAssetACLAccountsSerializer(serializers.Serializer):
username_group = serializers.ListField(
default=["*"],
child=serializers.CharField(max_length=128),
label=_("Username"),
help_text=common_help_text,
)
class LoginAssetACLSerializer(BulkOrgResourceModelSerializer):
users = LoginAssetACLUsersSerializer()
assets = LoginAssetACLAssestsSerializer()
accounts = LoginAssetACLAccountsSerializer()
reviewers = ObjectRelatedField(
queryset=User.objects, many=True, required=False, label=_('Reviewers')
)
reviewers_amount = serializers.IntegerField(read_only=True, source="reviewers.count")
action = LabeledChoiceField(
choices=models.LoginAssetACL.ActionChoices.choices, label=_("Action")
)
class Meta:
model = models.LoginAssetACL
fields_mini = ["id", "name"]
fields_small = fields_mini + [
"users",
"accounts",
"assets",
"is_active",
"date_created",
"date_updated",
"priority",
"action",
"comment",
"created_by",
"org_id",
]
fields_m2m = ["reviewers", "reviewers_amount"]
fields = fields_small + fields_m2m
extra_kwargs = {
"reviewers": {"allow_null": False, "required": True},
"priority": {"default": 50},
"is_active": {"default": True},
}
def validate_reviewers(self, reviewers):
org_id = self.fields["org_id"].default()
org = Organization.get_instance(org_id)
if not org:
error = _("The organization `{}` does not exist".format(org_id))
raise serializers.ValidationError(error)
users = org.get_members()
valid_reviewers = list(set(reviewers) & set(users))
if not valid_reviewers:
error = _(
"None of the reviewers belong to Organization `{}`".format(org.name)
)
raise serializers.ValidationError(error)
return valid_reviewers

@ -1,17 +1,13 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# #
import re
import uuid import uuid
from django.db import models
from django.db.models import Q
from django.core.validators import MinValueValidator, MaxValueValidator from django.core.validators import MinValueValidator, MaxValueValidator
from django.db import models
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _
from users.models import User, UserGroup from common.utils import get_logger
from orgs.mixins.models import OrgModelMixin from orgs.mixins.models import OrgModelMixin
from common.utils import lazyproperty, get_logger, get_object_or_none
from ..models import Asset, Account
logger = get_logger(__file__) logger = get_logger(__file__)
@ -93,125 +89,3 @@ class CommandFilterRule(OrgModelMixin):
class Meta: class Meta:
ordering = ('priority', 'action') ordering = ('priority', 'action')
verbose_name = _("Command filter rule") verbose_name = _("Command filter rule")
@lazyproperty
def pattern(self):
if self.type == 'command':
s = self.construct_command_regex(content=self.content)
else:
s = r'{0}'.format(self.content)
return s
@classmethod
def construct_command_regex(cls, content):
regex = []
content = content.replace('\r\n', '\n')
for _cmd in content.split('\n'):
cmd = re.sub(r'\s+', ' ', _cmd)
cmd = re.escape(cmd)
cmd = cmd.replace('\\ ', '\s+')
# 有空格就不能 铆钉单词了
if ' ' in _cmd:
regex.append(cmd)
continue
if not cmd:
continue
# 如果是单个字符
if cmd[-1].isalpha():
regex.append(r'\b{0}\b'.format(cmd))
else:
regex.append(r'\b{0}'.format(cmd))
s = r'{}'.format('|'.join(regex))
return s
@staticmethod
def compile_regex(regex, ignore_case):
try:
if ignore_case:
pattern = re.compile(regex, re.IGNORECASE)
else:
pattern = re.compile(regex)
except Exception as e:
error = _('The generated regular expression is incorrect: {}').format(str(e))
logger.error(error)
return False, error, None
return True, '', pattern
def match(self, data):
succeed, error, pattern = self.compile_regex(self.pattern, self.ignore_case)
if not succeed:
return self.ACTION_UNKNOWN, ''
found = pattern.search(data)
if not found:
return self.ACTION_UNKNOWN, ''
if self.action == self.ActionChoices.allow:
return self.ActionChoices.allow, found.group()
else:
return self.ActionChoices.deny, found.group()
def __str__(self):
return '{} % {}'.format(self.type, self.content)
def create_command_confirm_ticket(self, run_command, session, cmd_filter_rule, org_id):
from tickets.const import TicketType
from tickets.models import ApplyCommandTicket
data = {
'title': _('Command confirm') + ' ({})'.format(session.user),
'type': TicketType.command_confirm,
'applicant': session.user_obj,
'apply_run_user_id': session.user_id,
'apply_run_asset': str(session.asset),
'apply_run_account': str(session.account),
'apply_run_command': run_command[:4090],
'apply_from_session_id': str(session.id),
'apply_from_cmd_filter_rule_id': str(cmd_filter_rule.id),
'apply_from_cmd_filter_id': str(cmd_filter_rule.filter.id),
'org_id': org_id,
}
ticket = ApplyCommandTicket.objects.create(**data)
assignees = self.reviewers.all()
ticket.open_by_system(assignees)
return ticket
@classmethod
def get_queryset(
cls, user_id=None, user_group_id=None, account=None,
asset_id=None, org_id=None
):
from assets.models import Account
user_groups = []
user = get_object_or_none(User, pk=user_id)
if user:
user_groups.extend(list(user.groups.all()))
user_group = get_object_or_none(UserGroup, pk=user_group_id)
if user_group:
org_id = user_group.org_id
user_groups.append(user_group)
asset = get_object_or_none(Asset, pk=asset_id)
q = Q()
if user:
q |= Q(users=user)
if user_groups:
q |= Q(user_groups__in=set(user_groups))
if account:
org_id = account.org_id
q |= Q(accounts__contains=account.username) | \
Q(accounts__contains=Account.AliasAccount.ALL)
if asset:
org_id = asset.org_id
q |= Q(assets=asset)
if q:
cmd_filters = CommandFilter.objects.filter(q).filter(is_active=True)
if org_id:
cmd_filters = cmd_filters.filter(org_id=org_id)
rule_ids = cmd_filters.values_list('rules', flat=True)
rules = cls.objects.filter(id__in=rule_ids)
else:
rules = cls.objects.none()
return rules

@ -1,25 +1,25 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# #
import inspect import inspect
from functools import partial
import time import time
from functools import partial
from typing import Callable from typing import Callable
from django.utils.http import urlencode
from django.core.cache import cache
from django.conf import settings from django.conf import settings
from django.contrib import auth from django.contrib import auth
from django.utils.translation import ugettext as _
from rest_framework.request import Request
from django.contrib.auth import ( from django.contrib.auth import (
BACKEND_SESSION_KEY, load_backend, BACKEND_SESSION_KEY, load_backend,
PermissionDenied, user_login_failed, _clean_credentials, PermissionDenied, user_login_failed, _clean_credentials,
) )
from django.core.cache import cache
from django.core.exceptions import ImproperlyConfigured from django.core.exceptions import ImproperlyConfigured
from django.shortcuts import reverse, redirect, get_object_or_404 from django.shortcuts import reverse, redirect, get_object_or_404
from django.utils.http import urlencode
from django.utils.translation import ugettext as _
from rest_framework.request import Request
from common.utils import get_request_ip, get_logger, bulk_get, FlashMessageUtil
from acls.models import LoginACL from acls.models import LoginACL
from common.utils import get_request_ip, get_logger, bulk_get, FlashMessageUtil
from users.models import User from users.models import User
from users.utils import LoginBlockUtil, MFABlockUtils, LoginIpBlockUtil from users.utils import LoginBlockUtil, MFABlockUtils, LoginIpBlockUtil
from . import errors from . import errors

Loading…
Cancel
Save