mirror of https://github.com/jumpserver/jumpserver
chore: relove conflict
commit
873afd239e
|
@ -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'},
|
||||||
|
),
|
||||||
|
]
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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):
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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):
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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()
|
||||||
|
|
|
@ -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"]
|
||||||
|
|
|
@ -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"))
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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',
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
|
@ -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'),
|
||||||
|
),
|
||||||
|
]
|
|
@ -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),
|
||||||
|
|
Loading…
Reference in New Issue