mirror of
https://github.com/jumpserver/jumpserver.git
synced 2025-09-16 23:38:36 +00:00
perf: add delete account action (#15059)
This commit is contained in:
@@ -30,7 +30,6 @@ __all__ = [
|
||||
]
|
||||
|
||||
from ...filters import NodeFilterBackend
|
||||
|
||||
from ...risk_handlers import RiskHandler
|
||||
|
||||
|
||||
@@ -130,11 +129,13 @@ class AccountRiskViewSet(OrgBulkModelViewSet):
|
||||
s.validated_data, ("asset", "username", "action", "risk")
|
||||
)
|
||||
handler = RiskHandler(asset=asset, username=username, request=self.request)
|
||||
data = handler.handle(act, risk)
|
||||
if not data:
|
||||
return Response(data={"message": "Success"})
|
||||
s = serializers.AccountRiskSerializer(instance=data)
|
||||
return Response(data=s.data)
|
||||
|
||||
try:
|
||||
risk = handler.handle(act, risk)
|
||||
s = serializers.AccountRiskSerializer(instance=risk)
|
||||
return Response(data=s.data)
|
||||
except Exception as e:
|
||||
return Response(status=400, data=str(e))
|
||||
|
||||
|
||||
class CheckAccountEngineViewSet(JMSModelViewSet):
|
||||
|
@@ -155,6 +155,19 @@ class AnalyseAccountRisk:
|
||||
def _update_risk(self, account):
|
||||
return account
|
||||
|
||||
def lost_accounts(self, asset, lost_users):
|
||||
if not self.check_risk:
|
||||
return
|
||||
for user in lost_users:
|
||||
self._create_risk(
|
||||
dict(
|
||||
asset_id=str(asset.id),
|
||||
username=user,
|
||||
risk=RiskChoice.account_deleted,
|
||||
details=[{"datetime": self.now.isoformat()}],
|
||||
)
|
||||
)
|
||||
|
||||
def analyse_risk(self, asset, ga, d, sys_found):
|
||||
if not self.check_risk:
|
||||
return
|
||||
@@ -289,6 +302,8 @@ class GatherAccountsManager(AccountBasePlaybookManager):
|
||||
"username": username,
|
||||
}
|
||||
)
|
||||
risk_analyser = AnalyseAccountRisk(self.check_risk)
|
||||
risk_analyser.lost_accounts(asset, lost_users)
|
||||
|
||||
# 收集的账号 比 账号列表多的, 有可能是账号中删掉了, 但这时候状态已经是 confirm 了
|
||||
# 标识状态为 待处理, 让管理员去确认
|
||||
|
@@ -139,6 +139,7 @@ class Migration(migrations.Migration):
|
||||
choices=[
|
||||
("long_time_no_login", "Long time no login"),
|
||||
("new_found", "New found"),
|
||||
("account_deleted", "Account deleted"),
|
||||
("groups_changed", "Groups change"),
|
||||
("sudoers_changed", "Sudo changed"),
|
||||
("authorized_keys_changed", "Authorized keys changed"),
|
||||
|
@@ -1,8 +1,9 @@
|
||||
from itertools import islice
|
||||
|
||||
from django.db import models
|
||||
from django.db.models import TextChoices
|
||||
from django.utils import timezone
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
from itertools import islice
|
||||
|
||||
from common.const import ConfirmOrIgnore
|
||||
from common.db.models import JMSBaseModel
|
||||
@@ -41,6 +42,7 @@ class RiskChoice(TextChoices):
|
||||
# 依赖自动发现的
|
||||
long_time_no_login = 'long_time_no_login', _('Long time no login') # 好久没登录的账号, 禁用、删除
|
||||
new_found = 'new_found', _('New found') # 未被纳管的账号, 纳管, 删除, 禁用
|
||||
account_deleted = 'account_deleted', _('Account deleted') # 账号被删除, 纳管, 删除, 禁用
|
||||
group_changed = 'groups_changed', _('Groups change') # 组变更, 确认
|
||||
sudo_changed = 'sudoers_changed', _('Sudo changed') # sudo 变更, 确认
|
||||
authorized_keys_changed = 'authorized_keys_changed', _('Authorized keys changed') # authorized_keys 变更, 确认
|
||||
|
@@ -8,7 +8,7 @@ from accounts.models import (
|
||||
AccountRisk,
|
||||
SecretType,
|
||||
AutomationExecution,
|
||||
RiskChoice
|
||||
RiskChoice, Account
|
||||
)
|
||||
from common.const import ConfirmOrIgnore
|
||||
from common.utils import random_string
|
||||
@@ -19,10 +19,11 @@ TYPE_CHOICES = [
|
||||
("close", _("Close")),
|
||||
("disable_remote", _("Disable remote")),
|
||||
("delete_remote", _("Delete remote")),
|
||||
("delete_account", _("Delete account")),
|
||||
("delete_both", _("Delete remote")),
|
||||
("add_account", _("Add account")),
|
||||
("change_password_add", _("Change password and Add")),
|
||||
("change_password", _("Change password"))
|
||||
("change_password", _("Change password")),
|
||||
]
|
||||
|
||||
|
||||
@@ -73,6 +74,10 @@ class RiskHandler:
|
||||
def handle_reopen(self):
|
||||
pass
|
||||
|
||||
def handle_delete_account(self):
|
||||
Account.objects.filter(asset=self.asset, username=self.username).delete()
|
||||
GatheredAccount.objects.filter(asset=self.asset, username=self.username).delete()
|
||||
|
||||
def handle_close(self):
|
||||
pass
|
||||
|
||||
@@ -102,7 +107,7 @@ class RiskHandler:
|
||||
present=True, status=ConfirmOrIgnore.confirmed
|
||||
)
|
||||
self.risk = RiskChoice.new_found
|
||||
|
||||
|
||||
risk = self.get_risk()
|
||||
risk.account = account
|
||||
risk.save()
|
||||
@@ -113,6 +118,15 @@ class RiskHandler:
|
||||
def handle_delete_remote(self):
|
||||
self._handle_delete(delete="remote")
|
||||
|
||||
@staticmethod
|
||||
def start_execution(execution):
|
||||
execution.save()
|
||||
execution.start()
|
||||
|
||||
if execution.status != "success":
|
||||
msg = _("Execution failed: {}").format(execution.status)
|
||||
raise ValidationError(msg)
|
||||
|
||||
def _handle_delete(self, delete="both"):
|
||||
asset = self.asset
|
||||
execution = AutomationExecution()
|
||||
@@ -124,9 +138,7 @@ class RiskHandler:
|
||||
"delete": delete,
|
||||
"risk": self.risk
|
||||
}
|
||||
execution.save()
|
||||
execution.start()
|
||||
return execution.summary
|
||||
self.start_execution(execution)
|
||||
|
||||
def handle_delete_both(self):
|
||||
self._handle_delete(delete="both")
|
||||
@@ -134,7 +146,11 @@ class RiskHandler:
|
||||
def handle_change_password(self):
|
||||
asset = self.asset
|
||||
execution = AutomationExecution()
|
||||
account = self.asset.accounts.get(username=self.username)
|
||||
account = self.asset.accounts.filter(username=self.username, secret_type=SecretType.PASSWORD).first()
|
||||
|
||||
if not account:
|
||||
raise ValidationError("Account not found")
|
||||
|
||||
execution.snapshot = {
|
||||
"assets": [str(asset.id)],
|
||||
"accounts": [str(account.id)],
|
||||
@@ -143,9 +159,7 @@ class RiskHandler:
|
||||
"secret_strategy": "random",
|
||||
"name": "Change account password: {}@{}".format(self.username, asset.name),
|
||||
}
|
||||
execution.save()
|
||||
execution.start()
|
||||
return execution.summary
|
||||
self.start_execution(execution)
|
||||
|
||||
def handle_change_password_add(self):
|
||||
asset = self.asset
|
||||
@@ -174,10 +188,10 @@ class RiskHandler:
|
||||
'check_conn_after_change': True,
|
||||
"name": "Push account password: {}@{}".format(self.username, asset.name),
|
||||
}
|
||||
execution.save()
|
||||
execution.start()
|
||||
self.start_execution(execution)
|
||||
|
||||
GatheredAccount.objects.filter(asset=self.asset, username=self.username).update(
|
||||
present=True
|
||||
(
|
||||
GatheredAccount.objects
|
||||
.filter(asset=self.asset, username=self.username)
|
||||
.update(present=True)
|
||||
)
|
||||
return execution.summary
|
||||
|
Reference in New Issue
Block a user