chore: relove conflict

pull/9158/head
ibuler 2022-12-05 13:41:28 +08:00
commit 873afd239e
15 changed files with 85 additions and 48 deletions

View File

@ -0,0 +1,25 @@
# Generated by Django 3.2.14 on 2022-12-05 03:22
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('acls', '0009_auto_20221204_0001'),
]
operations = [
migrations.AlterModelOptions(
name='commandfilteracl',
options={'ordering': ('priority', 'name'), 'verbose_name': 'Command acl'},
),
migrations.AlterModelOptions(
name='loginacl',
options={'ordering': ('priority', 'name'), 'verbose_name': 'Login acl'},
),
migrations.AlterModelOptions(
name='loginassetacl',
options={'ordering': ('priority', 'name'), 'verbose_name': 'Login asset acl'},
),
]

View File

@ -83,6 +83,7 @@ class BaseACL(CommonModelMixin):
objects = ACLManager.from_queryset(BaseACLQuerySet)() objects = ACLManager.from_queryset(BaseACLQuerySet)()
class Meta: class Meta:
ordering = ('priority', 'name')
abstract = True abstract = True
@ -96,7 +97,8 @@ class UserAssetAccountBaseACL(BaseACL, OrgModelMixin):
objects = ACLManager.from_queryset(UserAssetAccountACLQuerySet)() objects = ACLManager.from_queryset(UserAssetAccountACLQuerySet)()
class Meta: class Meta(BaseACL.Meta):
unique_together = ('name', 'org_id')
abstract = True abstract = True
@classmethod @classmethod
@ -118,4 +120,3 @@ class UserAssetAccountBaseACL(BaseACL, OrgModelMixin):
if kwargs: if kwargs:
queryset = queryset.filter(**kwargs) queryset = queryset.filter(**kwargs)
return queryset return queryset

View File

@ -8,7 +8,7 @@ from django.utils.translation import ugettext_lazy as _
from common.utils import lazyproperty, get_logger from common.utils import lazyproperty, get_logger
from orgs.mixins.models import JMSOrgBaseModel from orgs.mixins.models import JMSOrgBaseModel
from .base import UserAssetAccountBaseACL, UserAssetAccountACLQuerySet, ACLManager from .base import UserAssetAccountBaseACL
logger = get_logger(__file__) logger = get_logger(__file__)
@ -94,23 +94,11 @@ class CommandGroup(JMSOrgBaseModel):
return '{} % {}'.format(self.name, self.type) return '{} % {}'.format(self.name, self.type)
class CommandFilterACLQuerySet(UserAssetAccountACLQuerySet):
def get_command_groups(self):
ids = self.values_list('id', flat=True)
queryset = CommandFilterACL.command_groups.through.objects.filter(commandfilteracl_id__in=ids)
cmd_group_ids = queryset.values_list('commandgroup_id', flat=True)
command_groups = CommandGroup.objects.filter(id__in=cmd_group_ids)
return command_groups
class CommandFilterACL(UserAssetAccountBaseACL): class CommandFilterACL(UserAssetAccountBaseACL):
command_groups = models.ManyToManyField(CommandGroup, verbose_name=_('Commands')) command_groups = models.ManyToManyField(CommandGroup, verbose_name=_('Commands'))
objects = ACLManager.from_queryset(CommandFilterACLQuerySet)() class Meta(UserAssetAccountBaseACL.Meta):
abstract = False
class Meta:
unique_together = ('name', 'org_id')
ordering = ('priority', '-date_updated', 'name')
verbose_name = _('Command acl') verbose_name = _('Command acl')
def __str__(self): def __str__(self):

View File

@ -15,9 +15,9 @@ class LoginACL(BaseACL):
# 规则, ip_group, time_period # 规则, ip_group, time_period
rules = models.JSONField(default=dict, verbose_name=_('Rule')) rules = models.JSONField(default=dict, verbose_name=_('Rule'))
class Meta: class Meta(BaseACL.Meta):
ordering = ('priority', '-date_updated', 'name')
verbose_name = _('Login acl') verbose_name = _('Login acl')
abstract = False
def __str__(self): def __str__(self):
return self.name return self.name

View File

@ -6,10 +6,9 @@ from .base import UserAssetAccountBaseACL
class LoginAssetACL(UserAssetAccountBaseACL): class LoginAssetACL(UserAssetAccountBaseACL):
class Meta: class Meta(UserAssetAccountBaseACL.Meta):
unique_together = ('name', 'org_id')
ordering = ('priority', '-date_updated', 'name')
verbose_name = _('Login asset acl') verbose_name = _('Login asset acl')
abstract = False
def __str__(self): def __str__(self):
return self.name return self.name

View File

@ -156,15 +156,15 @@ class ConnectionToken(OrgModelMixin, JMSBaseModel):
return self.domain.random_gateway() return self.domain.random_gateway()
@lazyproperty @lazyproperty
def acl_command_groups(self): def command_filter_acls(self):
from acls.models import CommandFilterACL from acls.models import CommandFilterACL
kwargs = { kwargs = {
'user': self.user, 'user': self.user,
'asset': self.asset, 'asset': self.asset,
'account': self.account, 'account': self.account,
} }
command_groups = CommandFilterACL.filter_queryset(**kwargs).get_command_groups() acls = CommandFilterACL.filter_queryset(**kwargs).valid()
return command_groups return acls
class SuperConnectionToken(ConnectionToken): class SuperConnectionToken(ConnectionToken):

View File

@ -26,7 +26,7 @@ __all__ = ['CommandViewSet', 'InsecureCommandAlertAPI']
class CommandQueryMixin: class CommandQueryMixin:
command_store = get_command_storage() command_store = get_command_storage()
filterset_fields = [ filterset_fields = [
"asset", "system_user", "user", "session", "asset", "account", "user", "session",
"risk_level", "input" "risk_level", "input"
] ]
default_days_ago = 5 default_days_ago = 5
@ -56,7 +56,7 @@ class CommandQueryMixin:
multi_command_storage = get_multi_command_storage() multi_command_storage = get_multi_command_storage()
queryset = multi_command_storage.filter( queryset = multi_command_storage.filter(
date_from=date_from, date_to=date_to, date_from=date_from, date_to=date_to,
user=q.get("user"), asset=q.get("asset"), system_user=q.get("system_user"), user=q.get("user"), asset=q.get("asset"), account=q.get("account"),
input=q.get("input"), session=q.get("session_id", q.get('session')), input=q.get("input"), session=q.get("session_id", q.get('session')),
risk_level=self.get_query_risk_level(), org_id=self.get_org_id(), risk_level=self.get_query_risk_level(), org_id=self.get_org_id(),
) )
@ -91,7 +91,7 @@ class CommandViewSet(JMSBulkModelViewSet):
{ {
"user": "admin", "user": "admin",
"asset": "localhost", "asset": "localhost",
"system_user": "web", "account": "web",
"session": "xxxxxx", "session": "xxxxxx",
"input": "whoami", "input": "whoami",
"output": "d2hvbWFp", # base64.b64encode(s) "output": "d2hvbWFp", # base64.b64encode(s)

View File

@ -15,13 +15,13 @@ class CommandBase(object):
@abc.abstractmethod @abc.abstractmethod
def filter(self, date_from=None, date_to=None, def filter(self, date_from=None, date_to=None,
user=None, asset=None, system_user=None, user=None, asset=None, account=None,
input=None, session=None, risk_level=None, org_id=None): input=None, session=None, risk_level=None, org_id=None):
pass pass
@abc.abstractmethod @abc.abstractmethod
def count(self, date_from=None, date_to=None, def count(self, date_from=None, date_to=None,
user=None, asset=None, system_user=None, user=None, asset=None, account=None,
input=None, session=None): input=None, session=None):
pass pass

View File

@ -21,7 +21,7 @@ class CommandStore(CommandBase):
""" """
self.model.objects.create( self.model.objects.create(
user=command["user"], asset=command["asset"], user=command["user"], asset=command["asset"],
system_user=command["system_user"], input=command["input"], account=command["account"], input=command["input"],
output=command["output"], session=command["session"], output=command["output"], session=command["session"],
risk_level=command.get("risk_level", 0), org_id=command["org_id"], risk_level=command.get("risk_level", 0), org_id=command["org_id"],
timestamp=command["timestamp"] timestamp=command["timestamp"]
@ -36,7 +36,7 @@ class CommandStore(CommandBase):
cmd_input = pretty_string(c['input']) cmd_input = pretty_string(c['input'])
cmd_output = pretty_string(c['output'], max_length=1024) cmd_output = pretty_string(c['output'], max_length=1024)
_commands.append(self.model( _commands.append(self.model(
user=c["user"], asset=c["asset"], system_user=c["system_user"], user=c["user"], asset=c["asset"], account=c["account"],
input=cmd_input, output=cmd_output, session=c["session"], input=cmd_input, output=cmd_output, session=c["session"],
risk_level=c.get("risk_level", 0), org_id=c["org_id"], risk_level=c.get("risk_level", 0), org_id=c["org_id"],
timestamp=c["timestamp"] timestamp=c["timestamp"]
@ -64,7 +64,7 @@ class CommandStore(CommandBase):
@staticmethod @staticmethod
def make_filter_kwargs( def make_filter_kwargs(
date_from=None, date_to=None, date_from=None, date_to=None,
user=None, asset=None, system_user=None, user=None, asset=None, account=None,
input=None, session=None, risk_level=None, org_id=None): input=None, session=None, risk_level=None, org_id=None):
filter_kwargs = {} filter_kwargs = {}
date_from_default = timezone.now() - datetime.timedelta(days=7) date_from_default = timezone.now() - datetime.timedelta(days=7)
@ -87,8 +87,8 @@ class CommandStore(CommandBase):
filter_kwargs["user__startswith"] = user filter_kwargs["user__startswith"] = user
if asset: if asset:
filter_kwargs['asset'] = asset filter_kwargs['asset'] = asset
if system_user: if account:
filter_kwargs['system_user'] = system_user filter_kwargs['account'] = account
if input: if input:
filter_kwargs['input__icontains'] = input filter_kwargs['input__icontains'] = input
if session: if session:
@ -100,22 +100,22 @@ class CommandStore(CommandBase):
return filter_kwargs return filter_kwargs
def filter(self, date_from=None, date_to=None, def filter(self, date_from=None, date_to=None,
user=None, asset=None, system_user=None, user=None, asset=None, account=None,
input=None, session=None, risk_level=None, org_id=None): input=None, session=None, risk_level=None, org_id=None):
filter_kwargs = self.make_filter_kwargs( filter_kwargs = self.make_filter_kwargs(
date_from=date_from, date_to=date_to, user=user, date_from=date_from, date_to=date_to, user=user,
asset=asset, system_user=system_user, input=input, asset=asset, account=account, input=input,
session=session, risk_level=risk_level, org_id=org_id, session=session, risk_level=risk_level, org_id=org_id,
) )
queryset = self.model.objects.filter(**filter_kwargs) queryset = self.model.objects.filter(**filter_kwargs)
return queryset return queryset
def count(self, date_from=None, date_to=None, def count(self, date_from=None, date_to=None,
user=None, asset=None, system_user=None, user=None, asset=None, account=None,
input=None, session=None): input=None, session=None):
filter_kwargs = self.make_filter_kwargs( filter_kwargs = self.make_filter_kwargs(
date_from=date_from, date_to=date_to, user=user, date_from=date_from, date_to=date_to, user=user,
asset=asset, system_user=system_user, input=input, asset=asset, account=account, input=input,
session=session, session=session,
) )
count = self.model.objects.filter(**filter_kwargs).count() count = self.model.objects.filter(**filter_kwargs).count()

View File

@ -49,7 +49,7 @@ class CommandStore(object):
self.es = Elasticsearch(hosts=hosts, max_retries=0, **kwargs) self.es = Elasticsearch(hosts=hosts, max_retries=0, **kwargs)
self.exact_fields = set() self.exact_fields = set()
self.match_fields = {'input', 'risk_level', 'user', 'asset', 'system_user'} self.match_fields = {'input', 'risk_level', 'user', 'asset', 'account'}
may_exact_fields = {'session', 'org_id'} may_exact_fields = {'session', 'org_id'}
if self.is_new_index_type(): if self.is_new_index_type():
@ -142,7 +142,7 @@ class CommandStore(object):
def make_data(command): def make_data(command):
data = dict( data = dict(
user=command["user"], asset=command["asset"], user=command["user"], asset=command["asset"],
system_user=command["system_user"], input=command["input"], account=command["account"], input=command["input"],
output=command["output"], risk_level=command["risk_level"], output=command["output"], risk_level=command["risk_level"],
session=command["session"], timestamp=command["timestamp"], session=command["session"], timestamp=command["timestamp"],
org_id=command["org_id"] org_id=command["org_id"]

View File

@ -19,7 +19,7 @@ class AbstractSessionCommand(OrgModelMixin):
id = models.UUIDField(default=uuid.uuid4, primary_key=True) id = models.UUIDField(default=uuid.uuid4, primary_key=True)
user = models.CharField(max_length=64, db_index=True, verbose_name=_("User")) user = models.CharField(max_length=64, db_index=True, verbose_name=_("User"))
asset = models.CharField(max_length=128, db_index=True, verbose_name=_("Asset")) asset = models.CharField(max_length=128, db_index=True, verbose_name=_("Asset"))
system_user = models.CharField(max_length=64, db_index=True, verbose_name=_("System user")) account = models.CharField(max_length=64, db_index=True, verbose_name=_("Account"))
input = models.CharField(max_length=128, db_index=True, verbose_name=_("Input")) input = models.CharField(max_length=128, db_index=True, verbose_name=_("Input"))
output = models.CharField(max_length=1024, blank=True, verbose_name=_("Output")) output = models.CharField(max_length=1024, blank=True, verbose_name=_("Output"))
session = models.CharField(max_length=36, db_index=True, verbose_name=_("Session")) session = models.CharField(max_length=36, db_index=True, verbose_name=_("Session"))

View File

@ -33,7 +33,8 @@ class SessionCommandSerializer(SimpleSessionCommandSerializer):
"""使用这个类作为基础Command Log Serializer类, 用来序列化""" """使用这个类作为基础Command Log Serializer类, 用来序列化"""
id = serializers.UUIDField(read_only=True) id = serializers.UUIDField(read_only=True)
system_user = serializers.CharField(label=_("System user")) # 限制 64 字符,不能直接迁移成 128 字符,命令表数据量会比较大 # 限制 64 字符,不能直接迁移成 128 字符,命令表数据量会比较大
account = serializers.CharField(label=_("Account "))
output = serializers.CharField(max_length=2048, allow_blank=True, label=_("Output")) output = serializers.CharField(max_length=2048, allow_blank=True, label=_("Output"))
risk_level_display = serializers.SerializerMethodField(label=_('Risk level display')) risk_level_display = serializers.SerializerMethodField(label=_('Risk level display'))
timestamp = serializers.IntegerField(label=_('Timestamp')) timestamp = serializers.IntegerField(label=_('Timestamp'))
@ -45,7 +46,7 @@ class SessionCommandSerializer(SimpleSessionCommandSerializer):
risk_mapper = dict(AbstractSessionCommand.RISK_LEVEL_CHOICES) risk_mapper = dict(AbstractSessionCommand.RISK_LEVEL_CHOICES)
return risk_mapper.get(obj.risk_level) return risk_mapper.get(obj.risk_level)
def validate_system_user(self, value): def validate_account(self, value):
if len(value) > 64: if len(value) > 64:
value = pretty_string(value, 64) value = pretty_string(value, 64)
return value return value

View File

@ -16,7 +16,7 @@ class CommandFilter(filters.FilterSet):
class Meta: class Meta:
model = Command model = Command
fields = [ fields = [
'asset', 'system_user', 'user', 'session', 'risk_level', 'input', 'asset', 'account', 'user', 'session', 'risk_level', 'input',
'date_from', 'date_to', 'session_id', 'risk_level', 'command_storage_id', 'date_from', 'date_to', 'session_id', 'risk_level', 'command_storage_id',
] ]
@ -49,14 +49,14 @@ class CommandFilter(filters.FilterSet):
class CommandFilterForStorageTree(CommandFilter): class CommandFilterForStorageTree(CommandFilter):
asset = filters.CharFilter(method='do_nothing') asset = filters.CharFilter(method='do_nothing')
system_user = filters.CharFilter(method='do_nothing') account = filters.CharFilter(method='do_nothing')
session = filters.CharFilter(method='do_nothing') session = filters.CharFilter(method='do_nothing')
risk_level = filters.NumberFilter(method='do_nothing') risk_level = filters.NumberFilter(method='do_nothing')
class Meta: class Meta:
model = CommandStorage model = CommandStorage
fields = [ fields = [
'asset', 'system_user', 'user', 'session', 'risk_level', 'input', 'asset', 'account', 'user', 'session', 'risk_level', 'input',
'date_from', 'date_to', 'session_id', 'risk_level', 'command_storage_id', 'date_from', 'date_to', 'session_id', 'risk_level', 'command_storage_id',
] ]

View File

@ -0,0 +1,23 @@
# Generated by Django 3.2.14 on 2022-12-05 05:16
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('terminal', '0060_alter_applethostdeployment_options'),
]
operations = [
migrations.RenameField(
model_name='command',
old_name='system_user',
new_name='account',
),
migrations.AlterField(
model_name='command',
name='account',
field=models.CharField(db_index=True, max_length=64, verbose_name='Account'),
),
]

View File

@ -33,7 +33,7 @@ class Command(AbstractSessionCommand):
cls(**{ cls(**{
'user': random_string(6), 'user': random_string(6),
'asset': random_string(10), 'asset': random_string(10),
'system_user': random_string(6), 'account': random_string(6),
'session': str(uuid.uuid4()), 'session': str(uuid.uuid4()),
'input': random_string(16), 'input': random_string(16),
'output': random_string(64), 'output': random_string(64),