mirror of
https://github.com/jumpserver/jumpserver.git
synced 2025-12-16 09:02:49 +00:00
Compare commits
9 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
34c3147264 | ||
|
|
1cf57c822d | ||
|
|
edfac357b9 | ||
|
|
2e5dfd8bab | ||
|
|
53da79ae46 | ||
|
|
e258772242 | ||
|
|
0a5bf9cf03 | ||
|
|
ac7c865b67 | ||
|
|
ff6a8fa4d7 |
@@ -3,6 +3,7 @@ from rest_framework import serializers
|
|||||||
|
|
||||||
from acls.models.base import ActionChoices
|
from acls.models.base import ActionChoices
|
||||||
from common.serializers.fields import LabeledChoiceField, ObjectRelatedField
|
from common.serializers.fields import LabeledChoiceField, ObjectRelatedField
|
||||||
|
from jumpserver.utils import has_valid_xpack_license
|
||||||
from orgs.models import Organization
|
from orgs.models import Organization
|
||||||
from users.models import User
|
from users.models import User
|
||||||
|
|
||||||
@@ -51,7 +52,26 @@ class ACLAccountsSerializer(serializers.Serializer):
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
class BaseUserAssetAccountACLSerializerMixin(serializers.Serializer):
|
class ActionAclSerializer(serializers.Serializer):
|
||||||
|
action = LabeledChoiceField(
|
||||||
|
choices=ActionChoices.choices, default=ActionChoices.reject, label=_("Action")
|
||||||
|
)
|
||||||
|
|
||||||
|
def __init__(self, *args, **kwargs):
|
||||||
|
super().__init__(*args, **kwargs)
|
||||||
|
self.set_action_choices()
|
||||||
|
|
||||||
|
def set_action_choices(self):
|
||||||
|
action = self.fields.get("action")
|
||||||
|
if not action:
|
||||||
|
return
|
||||||
|
choices = action.choices
|
||||||
|
if not has_valid_xpack_license():
|
||||||
|
choices.pop(ActionChoices.review, None)
|
||||||
|
action._choices = choices
|
||||||
|
|
||||||
|
|
||||||
|
class BaseUserAssetAccountACLSerializerMixin(ActionAclSerializer, serializers.Serializer):
|
||||||
users = ACLUsersSerializer(label=_('User'))
|
users = ACLUsersSerializer(label=_('User'))
|
||||||
assets = ACLAssestsSerializer(label=_('Asset'))
|
assets = ACLAssestsSerializer(label=_('Asset'))
|
||||||
accounts = ACLAccountsSerializer(label=_('Account'))
|
accounts = ACLAccountsSerializer(label=_('Account'))
|
||||||
@@ -77,9 +97,6 @@ class BaseUserAssetAccountACLSerializerMixin(serializers.Serializer):
|
|||||||
reviewers_amount = serializers.IntegerField(
|
reviewers_amount = serializers.IntegerField(
|
||||||
read_only=True, source="reviewers.count", label=_('Reviewers amount')
|
read_only=True, source="reviewers.count", label=_('Reviewers amount')
|
||||||
)
|
)
|
||||||
action = LabeledChoiceField(
|
|
||||||
choices=ActionChoices.choices, default=ActionChoices.reject, label=_("Action")
|
|
||||||
)
|
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
fields_mini = ["id", "name"]
|
fields_mini = ["id", "name"]
|
||||||
|
|||||||
@@ -2,12 +2,11 @@ from django.utils.translation import ugettext as _
|
|||||||
from rest_framework import serializers
|
from rest_framework import serializers
|
||||||
|
|
||||||
from common.serializers import BulkModelSerializer, MethodSerializer
|
from common.serializers import BulkModelSerializer, MethodSerializer
|
||||||
from common.serializers.fields import ObjectRelatedField, LabeledChoiceField
|
from common.serializers.fields import ObjectRelatedField
|
||||||
from jumpserver.utils import has_valid_xpack_license
|
|
||||||
from users.models import User
|
from users.models import User
|
||||||
|
from .base import ActionAclSerializer
|
||||||
from .rules import RuleSerializer
|
from .rules import RuleSerializer
|
||||||
from ..models import LoginACL
|
from ..models import LoginACL
|
||||||
from ..models.base import ActionChoices
|
|
||||||
|
|
||||||
__all__ = [
|
__all__ = [
|
||||||
"LoginACLSerializer",
|
"LoginACLSerializer",
|
||||||
@@ -18,12 +17,11 @@ common_help_text = _(
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
class LoginACLSerializer(BulkModelSerializer):
|
class LoginACLSerializer(ActionAclSerializer, BulkModelSerializer):
|
||||||
user = ObjectRelatedField(queryset=User.objects, label=_("User"))
|
user = ObjectRelatedField(queryset=User.objects, label=_("User"))
|
||||||
reviewers = ObjectRelatedField(
|
reviewers = ObjectRelatedField(
|
||||||
queryset=User.objects, label=_("Reviewers"), many=True, required=False
|
queryset=User.objects, label=_("Reviewers"), many=True, required=False
|
||||||
)
|
)
|
||||||
action = LabeledChoiceField(choices=ActionChoices.choices, label=_('Action'))
|
|
||||||
reviewers_amount = serializers.IntegerField(
|
reviewers_amount = serializers.IntegerField(
|
||||||
read_only=True, source="reviewers.count", label=_("Reviewers amount")
|
read_only=True, source="reviewers.count", label=_("Reviewers amount")
|
||||||
)
|
)
|
||||||
@@ -45,18 +43,5 @@ class LoginACLSerializer(BulkModelSerializer):
|
|||||||
"is_active": {"default": True},
|
"is_active": {"default": True},
|
||||||
}
|
}
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
|
||||||
super().__init__(*args, **kwargs)
|
|
||||||
self.set_action_choices()
|
|
||||||
|
|
||||||
def set_action_choices(self):
|
|
||||||
action = self.fields.get("action")
|
|
||||||
if not action:
|
|
||||||
return
|
|
||||||
choices = action.choices
|
|
||||||
if not has_valid_xpack_license():
|
|
||||||
choices.pop(LoginACL.ActionChoices.review, None)
|
|
||||||
action._choices = choices
|
|
||||||
|
|
||||||
def get_rules_serializer(self):
|
def get_rules_serializer(self):
|
||||||
return RuleSerializer()
|
return RuleSerializer()
|
||||||
|
|||||||
@@ -163,8 +163,10 @@ class CategoryTreeApi(SerializeToTreeNodeMixin, generics.ListAPIView):
|
|||||||
# 资源数量统计可选项 (asset, account)
|
# 资源数量统计可选项 (asset, account)
|
||||||
count_resource = self.request.query_params.get('count_resource', 'asset')
|
count_resource = self.request.query_params.get('count_resource', 'asset')
|
||||||
|
|
||||||
if include_asset and self.request.query_params.get('key'):
|
if not self.request.query_params.get('key'):
|
||||||
|
nodes = AllTypes.to_tree_nodes(include_asset, count_resource=count_resource)
|
||||||
|
elif include_asset:
|
||||||
nodes = self.get_assets()
|
nodes = self.get_assets()
|
||||||
else:
|
else:
|
||||||
nodes = AllTypes.to_tree_nodes(include_asset, count_resource=count_resource)
|
nodes = []
|
||||||
return Response(data=nodes)
|
return Response(data=nodes)
|
||||||
|
|||||||
@@ -20,12 +20,13 @@ def get_prop_name_id(apps, app, category):
|
|||||||
|
|
||||||
|
|
||||||
def migrate_database_to_asset(apps, *args):
|
def migrate_database_to_asset(apps, *args):
|
||||||
|
node_model = apps.get_model('assets', 'Node')
|
||||||
app_model = apps.get_model('applications', 'Application')
|
app_model = apps.get_model('applications', 'Application')
|
||||||
db_model = apps.get_model('assets', 'Database')
|
db_model = apps.get_model('assets', 'Database')
|
||||||
platform_model = apps.get_model('assets', 'Platform')
|
platform_model = apps.get_model('assets', 'Platform')
|
||||||
|
|
||||||
applications = app_model.objects.filter(category='db')
|
applications = app_model.objects.filter(category='db')
|
||||||
platforms = platform_model.objects.all().filter(internal=True)
|
platforms = platform_model.objects.all().filter(internal=True).exclude(name='Redis6+')
|
||||||
platforms_map = {p.type: p for p in platforms}
|
platforms_map = {p.type: p for p in platforms}
|
||||||
print()
|
print()
|
||||||
|
|
||||||
@@ -84,11 +85,18 @@ def create_app_nodes(apps, org_id):
|
|||||||
node_keys = node_model.objects.filter(org_id=org_id) \
|
node_keys = node_model.objects.filter(org_id=org_id) \
|
||||||
.filter(key__regex=child_pattern) \
|
.filter(key__regex=child_pattern) \
|
||||||
.values_list('key', flat=True)
|
.values_list('key', flat=True)
|
||||||
if not node_keys:
|
if node_keys:
|
||||||
return
|
node_key_split = [key.split(':') for key in node_keys]
|
||||||
node_key_split = [key.split(':') for key in node_keys]
|
next_value = max([int(k[1]) for k in node_key_split]) + 1
|
||||||
next_value = max([int(k[1]) for k in node_key_split]) + 1
|
parent_key = node_key_split[0][0]
|
||||||
parent_key = node_key_split[0][0]
|
else:
|
||||||
|
root_node = node_model.objects.filter(org_id=org_id)\
|
||||||
|
.filter(parent_key='', key__regex=r'^[0-9]+$').exclude(key__startswith='-').first()
|
||||||
|
if not root_node:
|
||||||
|
return
|
||||||
|
parent_key = root_node.key
|
||||||
|
next_value = 0
|
||||||
|
|
||||||
next_key = '{}:{}'.format(parent_key, next_value)
|
next_key = '{}:{}'.format(parent_key, next_value)
|
||||||
name = 'Apps'
|
name = 'Apps'
|
||||||
parent = node_model.objects.get(key=parent_key)
|
parent = node_model.objects.get(key=parent_key)
|
||||||
|
|||||||
@@ -161,11 +161,12 @@ def migrate_db_accounts(apps, schema_editor):
|
|||||||
name = f'{username}(token)'
|
name = f'{username}(token)'
|
||||||
else:
|
else:
|
||||||
secret_type = attr
|
secret_type = attr
|
||||||
name = username
|
name = username or f'{username}(password)'
|
||||||
auth_infos.append((name, secret_type, secret))
|
auth_infos.append((name, secret_type, secret))
|
||||||
|
|
||||||
if not auth_infos:
|
if not auth_infos:
|
||||||
auth_infos.append((username, 'password', ''))
|
name = username or f'{username}(password)'
|
||||||
|
auth_infos.append((name, 'password', ''))
|
||||||
|
|
||||||
for name, secret_type, secret in auth_infos:
|
for name, secret_type, secret in auth_infos:
|
||||||
values['name'] = name
|
values['name'] = name
|
||||||
|
|||||||
@@ -175,6 +175,8 @@ def _parse_ssh_private_key(text, password=None):
|
|||||||
dsa.DSAPrivateKey,
|
dsa.DSAPrivateKey,
|
||||||
ed25519.Ed25519PrivateKey,
|
ed25519.Ed25519PrivateKey,
|
||||||
"""
|
"""
|
||||||
|
if not bool(password):
|
||||||
|
password = None
|
||||||
if isinstance(text, str):
|
if isinstance(text, str):
|
||||||
try:
|
try:
|
||||||
text = text.encode("utf-8")
|
text = text.encode("utf-8")
|
||||||
|
|||||||
@@ -80,7 +80,7 @@ def on_org_create_or_update(sender, instance, **kwargs):
|
|||||||
|
|
||||||
|
|
||||||
@receiver(pre_delete, sender=Organization)
|
@receiver(pre_delete, sender=Organization)
|
||||||
def on_org_delete(sender, instance, **kwargs):
|
def delete_org_root_node_on_org_delete(sender, instance, **kwargs):
|
||||||
expire_orgs_mapping_for_memory(instance.id)
|
expire_orgs_mapping_for_memory(instance.id)
|
||||||
|
|
||||||
# 删除该组织下所有 节点
|
# 删除该组织下所有 节点
|
||||||
@@ -91,7 +91,7 @@ def on_org_delete(sender, instance, **kwargs):
|
|||||||
|
|
||||||
|
|
||||||
@receiver(post_delete, sender=Organization)
|
@receiver(post_delete, sender=Organization)
|
||||||
def on_org_delete(sender, instance, **kwargs):
|
def expire_user_orgs_on_org_delete(sender, instance, **kwargs):
|
||||||
expire_user_orgs()
|
expire_user_orgs()
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -140,7 +140,7 @@ class ComponentsPrometheusMetricsUtil(TypedComponentsStatusMetricsUtil):
|
|||||||
for component in self.components:
|
for component in self.components:
|
||||||
if not component.is_alive:
|
if not component.is_alive:
|
||||||
continue
|
continue
|
||||||
component_stat = component.latest_stat
|
component_stat = component.last_stat
|
||||||
if not component_stat:
|
if not component_stat:
|
||||||
continue
|
continue
|
||||||
metric_text = state_metric_text % (
|
metric_text = state_metric_text % (
|
||||||
|
|||||||
Reference in New Issue
Block a user