mirror of https://github.com/jumpserver/jumpserver
perf: squash migrations
parent
78fa7438f7
commit
3164b13e6d
|
@ -1,5 +1,6 @@
|
||||||
from .backup import *
|
from .backup import *
|
||||||
from .base import *
|
from .base import *
|
||||||
from .change_secret import *
|
from .change_secret import *
|
||||||
|
from .check_account import *
|
||||||
from .gather_accounts import *
|
from .gather_accounts import *
|
||||||
from .push_account import *
|
from .push_account import *
|
||||||
|
|
|
@ -1,8 +1,5 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
#
|
#
|
||||||
from rest_framework import status
|
|
||||||
from rest_framework.decorators import action
|
|
||||||
from rest_framework.response import Response
|
|
||||||
|
|
||||||
from accounts import serializers
|
from accounts import serializers
|
||||||
from accounts.const import AutomationTypes
|
from accounts.const import AutomationTypes
|
||||||
|
@ -13,7 +10,7 @@ from .base import AutomationExecutionViewSet
|
||||||
|
|
||||||
__all__ = [
|
__all__ = [
|
||||||
'CheckAccountsAutomationViewSet', 'CheckAccountExecutionViewSet',
|
'CheckAccountsAutomationViewSet', 'CheckAccountExecutionViewSet',
|
||||||
'AccountRiskViewSet'
|
'AccountRiskViewSet', 'AccountCheckEngineViewSet',
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
@ -49,9 +46,26 @@ class AccountRiskViewSet(OrgBulkModelViewSet):
|
||||||
'sync_accounts': 'assets.add_AccountRisk',
|
'sync_accounts': 'assets.add_AccountRisk',
|
||||||
}
|
}
|
||||||
|
|
||||||
@action(methods=['post'], detail=False, url_path='sync-accounts')
|
|
||||||
def sync_accounts(self, request, *args, **kwargs):
|
class AccountCheckEngineViewSet(OrgBulkModelViewSet):
|
||||||
gathered_account_ids = request.data.get('gathered_account_ids')
|
search_fields = ('name',)
|
||||||
gathered_accounts = self.model.objects.filter(id__in=gathered_account_ids)
|
serializer_class = serializers.AccountCheckEngineSerializer
|
||||||
self.model.sync_accounts(gathered_accounts)
|
rbac_perms = {
|
||||||
return Response(status=status.HTTP_201_CREATED)
|
'list': 'assets.view_accountcheckautomation',
|
||||||
|
}
|
||||||
|
|
||||||
|
def get_queryset(self):
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
'id': 1,
|
||||||
|
'name': 'check_gathered_account',
|
||||||
|
'display_name': '检查发现的账号',
|
||||||
|
'description': '基于自动发现的账号结果进行检查分析 '
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'id': 2,
|
||||||
|
'name': 'check_account_secret',
|
||||||
|
'display_name': '检查账号密码强弱',
|
||||||
|
'description': '基于账号密码的安全性进行检查分析'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
|
@ -59,7 +59,7 @@ class GatherAccountsManager(AccountBasePlaybookManager):
|
||||||
for username, info in result.items():
|
for username, info in result.items():
|
||||||
self.asset_usernames_mapper[asset].add(username)
|
self.asset_usernames_mapper[asset].add(username)
|
||||||
|
|
||||||
d = {'asset': asset, 'username': username, 'present': True, **info}
|
d = {'asset': asset, 'username': username, 'remote_present': True, **info}
|
||||||
if len(d['address_last_login']) > 32:
|
if len(d['address_last_login']) > 32:
|
||||||
d['address_last_login'] = d['address_last_login'][:32]
|
d['address_last_login'] = d['address_last_login'][:32]
|
||||||
accounts.append(d)
|
accounts.append(d)
|
||||||
|
@ -112,11 +112,11 @@ class GatherAccountsManager(AccountBasePlaybookManager):
|
||||||
# 新增创建,不用处理状态
|
# 新增创建,不用处理状态
|
||||||
|
|
||||||
# 远端上 比 收集账号少的
|
# 远端上 比 收集账号少的
|
||||||
# 标识 present=False, 标记为待处理
|
# 标识 remote_present=False, 标记为待处理
|
||||||
# 远端资产上不存在的,标识为待处理,需要管理员介入
|
# 远端资产上不存在的,标识为待处理,需要管理员介入
|
||||||
lost_users = ori_ga_users - remote_users
|
lost_users = ori_ga_users - remote_users
|
||||||
if lost_users:
|
if lost_users:
|
||||||
queryset.filter(username__in=lost_users).update(status='', present=False)
|
queryset.filter(username__in=lost_users).update(status='', remote_present=False)
|
||||||
|
|
||||||
# 收集的账号 比 账号列表多的, 有可能是账号中删掉了, 但这时候状态已经是 confirm 了
|
# 收集的账号 比 账号列表多的, 有可能是账号中删掉了, 但这时候状态已经是 confirm 了
|
||||||
# 标识状态为 待处理, 让管理员去确认
|
# 标识状态为 待处理, 让管理员去确认
|
||||||
|
@ -128,19 +128,22 @@ class GatherAccountsManager(AccountBasePlaybookManager):
|
||||||
# 这个好像不不用对比,原始情况就这样
|
# 这个好像不不用对比,原始情况就这样
|
||||||
|
|
||||||
# 远端账号 比 账号列表少的
|
# 远端账号 比 账号列表少的
|
||||||
# 创建收集账号,标识 present=False, 状态待处理
|
# 创建收集账号,标识 remote_present=False, 状态待处理
|
||||||
|
|
||||||
# 远端账号 比 账号列表多的
|
# 远端账号 比 账号列表多的
|
||||||
# 正常情况, 不用处理,因为远端账号会创建到收集账号,收集账号再去对比
|
# 正常情况, 不用处理,因为远端账号会创建到收集账号,收集账号再去对比
|
||||||
|
|
||||||
# 远端存在的账号,标识为已存在
|
|
||||||
queryset.filter(username__in=remote_users, present=False).update(present=True)
|
|
||||||
|
|
||||||
# 不过这个好像也处理一下 status,因为已存在,这是状态应该是确认
|
# 不过这个好像也处理一下 status,因为已存在,这是状态应该是确认
|
||||||
(queryset.filter(username__in=ori_users)
|
(queryset.filter(username__in=ori_users)
|
||||||
.exclude(status=ConfirmOrIgnore.confirmed)
|
.exclude(status=ConfirmOrIgnore.confirmed)
|
||||||
.update(status=ConfirmOrIgnore.confirmed))
|
.update(status=ConfirmOrIgnore.confirmed))
|
||||||
|
|
||||||
|
# 远端存在的账号,标识为已存在
|
||||||
|
queryset.filter(username__in=remote_users, remote_present=False).update(remote_present=True)
|
||||||
|
|
||||||
|
# 资产上没有的,标识为为存在
|
||||||
|
queryset.exclude(username__in=ori_users).filter(present=False).update(present=True)
|
||||||
|
|
||||||
def batch_create_gathered_account(self, d, batch_size=20):
|
def batch_create_gathered_account(self, d, batch_size=20):
|
||||||
if d is None:
|
if d is None:
|
||||||
if self.pending_add_accounts:
|
if self.pending_add_accounts:
|
||||||
|
@ -222,7 +225,7 @@ class GatherAccountsManager(AccountBasePlaybookManager):
|
||||||
|
|
||||||
asset_ids = self.asset_usernames_mapper.keys()
|
asset_ids = self.asset_usernames_mapper.keys()
|
||||||
assets = Asset.objects.filter(id__in=asset_ids).prefetch_related('accounts')
|
assets = Asset.objects.filter(id__in=asset_ids).prefetch_related('accounts')
|
||||||
gather_accounts = GatheredAccount.objects.filter(asset_id__in=asset_ids, present=True)
|
gather_accounts = GatheredAccount.objects.filter(asset_id__in=asset_ids, remote_present=True)
|
||||||
|
|
||||||
asset_id_map = {str(asset.id): asset for asset in assets}
|
asset_id_map = {str(asset.id): asset for asset in assets}
|
||||||
asset_id_username = list(assets.values_list('id', 'accounts__username'))
|
asset_id_username = list(assets.values_list('id', 'accounts__username'))
|
||||||
|
|
|
@ -1,15 +1,69 @@
|
||||||
# Generated by Django 4.1.13 on 2024-10-12 03:20
|
# Generated by Django 4.1.13 on 2024-11-01 10:24
|
||||||
|
|
||||||
from django.db import migrations, models
|
from django.db import migrations, models
|
||||||
|
import django.db.models.deletion
|
||||||
|
import uuid
|
||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
("assets", "0006_baseautomation_start_time"),
|
||||||
("accounts", "0004_alter_changesecretrecord_account_and_more"),
|
("accounts", "0004_alter_changesecretrecord_account_and_more"),
|
||||||
]
|
]
|
||||||
|
|
||||||
operations = [
|
operations = [
|
||||||
|
migrations.CreateModel(
|
||||||
|
name="AccountCheckAutomation",
|
||||||
|
fields=[
|
||||||
|
(
|
||||||
|
"baseautomation_ptr",
|
||||||
|
models.OneToOneField(
|
||||||
|
auto_created=True,
|
||||||
|
on_delete=django.db.models.deletion.CASCADE,
|
||||||
|
parent_link=True,
|
||||||
|
primary_key=True,
|
||||||
|
serialize=False,
|
||||||
|
to="assets.baseautomation",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
options={
|
||||||
|
"verbose_name": "Gather account automation",
|
||||||
|
},
|
||||||
|
bases=("accounts.accountbaseautomation",),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name="account",
|
||||||
|
name="change_secret_status",
|
||||||
|
field=models.CharField(
|
||||||
|
blank=True,
|
||||||
|
max_length=16,
|
||||||
|
null=True,
|
||||||
|
verbose_name="Change secret status",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name="account",
|
||||||
|
name="date_change_secret",
|
||||||
|
field=models.DateTimeField(
|
||||||
|
blank=True, null=True, verbose_name="Date change secret"
|
||||||
|
),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name="account",
|
||||||
|
name="date_last_login",
|
||||||
|
field=models.DateTimeField(
|
||||||
|
blank=True, null=True, verbose_name="Date last access"
|
||||||
|
),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name="account",
|
||||||
|
name="login_by",
|
||||||
|
field=models.CharField(
|
||||||
|
blank=True, max_length=128, null=True, verbose_name="Access by"
|
||||||
|
),
|
||||||
|
),
|
||||||
migrations.AddField(
|
migrations.AddField(
|
||||||
model_name="account",
|
model_name="account",
|
||||||
name="secret_reset",
|
name="secret_reset",
|
||||||
|
@ -26,10 +80,165 @@ class Migration(migrations.Migration):
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
migrations.AddField(
|
migrations.AddField(
|
||||||
model_name="account",
|
model_name="gatheredaccount",
|
||||||
name="date_last_access",
|
name="authorized_keys",
|
||||||
field=models.DateTimeField(
|
field=models.TextField(
|
||||||
blank=True, null=True, verbose_name="Date last access"
|
blank=True, default="", verbose_name="Authorized keys"
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name="gatheredaccount",
|
||||||
|
name="groups",
|
||||||
|
field=models.TextField(blank=True, default="", verbose_name="Groups"),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name="gatheredaccount",
|
||||||
|
name="remote_present",
|
||||||
|
field=models.BooleanField(default=True, verbose_name="Remote present"),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name="gatheredaccount",
|
||||||
|
name="status",
|
||||||
|
field=models.CharField(
|
||||||
|
blank=True,
|
||||||
|
choices=[("confirmed", "Confirmed"), ("ignored", "Ignored")],
|
||||||
|
default="",
|
||||||
|
max_length=32,
|
||||||
|
verbose_name="Status",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name="gatheredaccount",
|
||||||
|
name="sudoers",
|
||||||
|
field=models.TextField(blank=True, default="", verbose_name="Sudoers"),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name="account",
|
||||||
|
name="connectivity",
|
||||||
|
field=models.CharField(
|
||||||
|
choices=[
|
||||||
|
("-", "Unknown"),
|
||||||
|
("na", "N/A"),
|
||||||
|
("ok", "OK"),
|
||||||
|
("err", "Error"),
|
||||||
|
],
|
||||||
|
default="-",
|
||||||
|
max_length=16,
|
||||||
|
verbose_name="Connectivity",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name="gatheredaccount",
|
||||||
|
name="present",
|
||||||
|
field=models.BooleanField(default=False, verbose_name="Present"),
|
||||||
|
),
|
||||||
|
migrations.CreateModel(
|
||||||
|
name="GatheredAccountDiff",
|
||||||
|
fields=[
|
||||||
|
(
|
||||||
|
"id",
|
||||||
|
models.BigAutoField(
|
||||||
|
auto_created=True,
|
||||||
|
primary_key=True,
|
||||||
|
serialize=False,
|
||||||
|
verbose_name="ID",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
("diff", models.TextField(default="", verbose_name="Diff")),
|
||||||
|
(
|
||||||
|
"item",
|
||||||
|
models.CharField(default="", max_length=32, verbose_name="Item"),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"date_created",
|
||||||
|
models.DateTimeField(
|
||||||
|
auto_now_add=True, verbose_name="Date created"
|
||||||
|
),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"account",
|
||||||
|
models.ForeignKey(
|
||||||
|
on_delete=django.db.models.deletion.CASCADE,
|
||||||
|
to="accounts.gatheredaccount",
|
||||||
|
verbose_name="Gathered account",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
migrations.CreateModel(
|
||||||
|
name="AccountRisk",
|
||||||
|
fields=[
|
||||||
|
(
|
||||||
|
"created_by",
|
||||||
|
models.CharField(
|
||||||
|
blank=True, max_length=128, null=True, verbose_name="Created by"
|
||||||
|
),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"updated_by",
|
||||||
|
models.CharField(
|
||||||
|
blank=True, max_length=128, null=True, verbose_name="Updated by"
|
||||||
|
),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"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"),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"comment",
|
||||||
|
models.TextField(blank=True, default="", verbose_name="Comment"),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"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",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"risk",
|
||||||
|
models.CharField(
|
||||||
|
choices=[
|
||||||
|
("zombie", "Zombie"),
|
||||||
|
("ghost", "Ghost"),
|
||||||
|
("weak_password", "Weak password"),
|
||||||
|
("long_time_no_change", "Long time no change"),
|
||||||
|
],
|
||||||
|
max_length=128,
|
||||||
|
verbose_name="Risk",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"confirmed",
|
||||||
|
models.BooleanField(default=False, verbose_name="Confirmed"),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"account",
|
||||||
|
models.ForeignKey(
|
||||||
|
on_delete=django.db.models.deletion.CASCADE,
|
||||||
|
related_name="risks",
|
||||||
|
to="accounts.account",
|
||||||
|
verbose_name="Account",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
options={
|
||||||
|
"verbose_name": "Account risk",
|
||||||
|
},
|
||||||
|
),
|
||||||
]
|
]
|
||||||
|
|
|
@ -1,112 +0,0 @@
|
||||||
# Generated by Django 4.1.13 on 2024-10-22 06:36
|
|
||||||
|
|
||||||
from django.db import migrations, models
|
|
||||||
import django.db.models.deletion
|
|
||||||
import uuid
|
|
||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
|
||||||
|
|
||||||
dependencies = [
|
|
||||||
("assets", "0006_baseautomation_start_time"),
|
|
||||||
("accounts", "0005_account_secret_reset"),
|
|
||||||
]
|
|
||||||
|
|
||||||
operations = [
|
|
||||||
migrations.CreateModel(
|
|
||||||
name="AccountCheckAutomation",
|
|
||||||
fields=[
|
|
||||||
(
|
|
||||||
"baseautomation_ptr",
|
|
||||||
models.OneToOneField(
|
|
||||||
auto_created=True,
|
|
||||||
on_delete=django.db.models.deletion.CASCADE,
|
|
||||||
parent_link=True,
|
|
||||||
primary_key=True,
|
|
||||||
serialize=False,
|
|
||||||
to="assets.baseautomation",
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
options={
|
|
||||||
"verbose_name": "Gather account automation",
|
|
||||||
},
|
|
||||||
bases=("accounts.accountbaseautomation",),
|
|
||||||
),
|
|
||||||
migrations.CreateModel(
|
|
||||||
name="AccountRisk",
|
|
||||||
fields=[
|
|
||||||
(
|
|
||||||
"created_by",
|
|
||||||
models.CharField(
|
|
||||||
blank=True, max_length=128, null=True, verbose_name="Created by"
|
|
||||||
),
|
|
||||||
),
|
|
||||||
(
|
|
||||||
"updated_by",
|
|
||||||
models.CharField(
|
|
||||||
blank=True, max_length=128, null=True, verbose_name="Updated by"
|
|
||||||
),
|
|
||||||
),
|
|
||||||
(
|
|
||||||
"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"),
|
|
||||||
),
|
|
||||||
(
|
|
||||||
"comment",
|
|
||||||
models.TextField(blank=True, default="", verbose_name="Comment"),
|
|
||||||
),
|
|
||||||
(
|
|
||||||
"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",
|
|
||||||
),
|
|
||||||
),
|
|
||||||
(
|
|
||||||
"risk",
|
|
||||||
models.CharField(
|
|
||||||
choices=[
|
|
||||||
("zombie", "Zombie"),
|
|
||||||
("ghost", "Ghost"),
|
|
||||||
("weak_password", "Weak password"),
|
|
||||||
("long_time_no_change", "Long time no change"),
|
|
||||||
],
|
|
||||||
max_length=128,
|
|
||||||
verbose_name="Risk",
|
|
||||||
),
|
|
||||||
),
|
|
||||||
(
|
|
||||||
"confirmed",
|
|
||||||
models.BooleanField(default=False, verbose_name="Confirmed"),
|
|
||||||
),
|
|
||||||
(
|
|
||||||
"account",
|
|
||||||
models.ForeignKey(
|
|
||||||
on_delete=django.db.models.deletion.CASCADE,
|
|
||||||
related_name="risks",
|
|
||||||
to="accounts.account",
|
|
||||||
verbose_name="Account",
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
options={
|
|
||||||
"abstract": False,
|
|
||||||
},
|
|
||||||
),
|
|
||||||
]
|
|
|
@ -1,42 +0,0 @@
|
||||||
# Generated by Django 4.1.13 on 2024-10-24 07:50
|
|
||||||
|
|
||||||
from django.db import migrations, models
|
|
||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
|
||||||
|
|
||||||
dependencies = [
|
|
||||||
("accounts", "0006_accountcheckautomation_accountrisk"),
|
|
||||||
]
|
|
||||||
|
|
||||||
operations = [
|
|
||||||
migrations.AddField(
|
|
||||||
model_name="account",
|
|
||||||
name="date_change_secret",
|
|
||||||
field=models.DateTimeField(
|
|
||||||
blank=True, null=True, verbose_name="Date change secret"
|
|
||||||
),
|
|
||||||
),
|
|
||||||
migrations.AddField(
|
|
||||||
model_name="account",
|
|
||||||
name="date_discovery",
|
|
||||||
field=models.DateTimeField(
|
|
||||||
blank=True, null=True, verbose_name="Date discovery"
|
|
||||||
),
|
|
||||||
),
|
|
||||||
migrations.AlterField(
|
|
||||||
model_name="account",
|
|
||||||
name="connectivity",
|
|
||||||
field=models.CharField(
|
|
||||||
choices=[
|
|
||||||
("-", "Unknown"),
|
|
||||||
("na", "N/A"),
|
|
||||||
("ok", "OK"),
|
|
||||||
("err", "Error"),
|
|
||||||
],
|
|
||||||
default="-",
|
|
||||||
max_length=16,
|
|
||||||
verbose_name="Connectivity",
|
|
||||||
),
|
|
||||||
),
|
|
||||||
]
|
|
|
@ -1,20 +0,0 @@
|
||||||
# Generated by Django 4.1.13 on 2024-10-24 08:15
|
|
||||||
|
|
||||||
from django.db import migrations, models
|
|
||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
|
||||||
|
|
||||||
dependencies = [
|
|
||||||
("accounts", "0007_account_date_change_secret_account_date_discovery_and_more"),
|
|
||||||
]
|
|
||||||
|
|
||||||
operations = [
|
|
||||||
migrations.AddField(
|
|
||||||
model_name="account",
|
|
||||||
name="access_by",
|
|
||||||
field=models.CharField(
|
|
||||||
blank=True, max_length=128, null=True, verbose_name="Access by"
|
|
||||||
),
|
|
||||||
),
|
|
||||||
]
|
|
|
@ -1,27 +0,0 @@
|
||||||
# Generated by Django 4.1.13 on 2024-10-24 08:51
|
|
||||||
|
|
||||||
from django.db import migrations, models
|
|
||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
|
||||||
|
|
||||||
dependencies = [
|
|
||||||
("accounts", "0008_account_access_by"),
|
|
||||||
]
|
|
||||||
|
|
||||||
operations = [
|
|
||||||
migrations.RemoveField(
|
|
||||||
model_name="account",
|
|
||||||
name="date_discovery",
|
|
||||||
),
|
|
||||||
migrations.AddField(
|
|
||||||
model_name="account",
|
|
||||||
name="change_secret_status",
|
|
||||||
field=models.CharField(
|
|
||||||
blank=True,
|
|
||||||
max_length=16,
|
|
||||||
null=True,
|
|
||||||
verbose_name="Change secret status",
|
|
||||||
),
|
|
||||||
),
|
|
||||||
]
|
|
|
@ -1,37 +0,0 @@
|
||||||
# Generated by Django 4.1.13 on 2024-10-28 08:05
|
|
||||||
|
|
||||||
from django.db import migrations, models
|
|
||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
|
||||||
|
|
||||||
dependencies = [
|
|
||||||
("accounts", "0009_remove_account_date_discovery_and_more"),
|
|
||||||
]
|
|
||||||
|
|
||||||
operations = [
|
|
||||||
migrations.AlterModelOptions(
|
|
||||||
name="accountrisk",
|
|
||||||
options={"verbose_name": "Account risk"},
|
|
||||||
),
|
|
||||||
migrations.RenameField(
|
|
||||||
model_name="account",
|
|
||||||
old_name="date_last_access",
|
|
||||||
new_name="date_last_login",
|
|
||||||
),
|
|
||||||
migrations.RenameField(
|
|
||||||
model_name="account",
|
|
||||||
old_name="access_by",
|
|
||||||
new_name="login_by",
|
|
||||||
),
|
|
||||||
migrations.AddField(
|
|
||||||
model_name="gatheredaccount",
|
|
||||||
name="status",
|
|
||||||
field=models.CharField(
|
|
||||||
choices=[("confirmed", "Confirmed"), ("ignored", "Ignored")],
|
|
||||||
default="",
|
|
||||||
max_length=32,
|
|
||||||
verbose_name="Status",
|
|
||||||
),
|
|
||||||
),
|
|
||||||
]
|
|
|
@ -1,64 +0,0 @@
|
||||||
# Generated by Django 4.1.13 on 2024-10-30 02:57
|
|
||||||
|
|
||||||
from django.db import migrations, models
|
|
||||||
import django.db.models.deletion
|
|
||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
|
||||||
|
|
||||||
dependencies = [
|
|
||||||
("accounts", "0010_alter_accountrisk_options_and_more"),
|
|
||||||
]
|
|
||||||
|
|
||||||
operations = [
|
|
||||||
migrations.AddField(
|
|
||||||
model_name="gatheredaccount",
|
|
||||||
name="authorized_keys",
|
|
||||||
field=models.TextField(
|
|
||||||
blank=True, default="", verbose_name="Authorized keys"
|
|
||||||
),
|
|
||||||
),
|
|
||||||
migrations.AddField(
|
|
||||||
model_name="gatheredaccount",
|
|
||||||
name="groups",
|
|
||||||
field=models.TextField(blank=True, default="", verbose_name="Groups"),
|
|
||||||
),
|
|
||||||
migrations.AddField(
|
|
||||||
model_name="gatheredaccount",
|
|
||||||
name="sudo",
|
|
||||||
field=models.TextField(default=False, verbose_name="Sudo"),
|
|
||||||
),
|
|
||||||
migrations.CreateModel(
|
|
||||||
name="GatheredAccountDiff",
|
|
||||||
fields=[
|
|
||||||
(
|
|
||||||
"id",
|
|
||||||
models.BigAutoField(
|
|
||||||
auto_created=True,
|
|
||||||
primary_key=True,
|
|
||||||
serialize=False,
|
|
||||||
verbose_name="ID",
|
|
||||||
),
|
|
||||||
),
|
|
||||||
("diff", models.TextField(default="", verbose_name="Diff")),
|
|
||||||
(
|
|
||||||
"item",
|
|
||||||
models.CharField(default="", max_length=32, verbose_name="Item"),
|
|
||||||
),
|
|
||||||
(
|
|
||||||
"date_created",
|
|
||||||
models.DateTimeField(
|
|
||||||
auto_now_add=True, verbose_name="Date created"
|
|
||||||
),
|
|
||||||
),
|
|
||||||
(
|
|
||||||
"account",
|
|
||||||
models.ForeignKey(
|
|
||||||
on_delete=django.db.models.deletion.CASCADE,
|
|
||||||
to="accounts.gatheredaccount",
|
|
||||||
verbose_name="Gathered account",
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
]
|
|
|
@ -1,24 +0,0 @@
|
||||||
# Generated by Django 4.1.13 on 2024-10-31 08:39
|
|
||||||
|
|
||||||
from django.db import migrations, models
|
|
||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
|
||||||
|
|
||||||
dependencies = [
|
|
||||||
("accounts", "0011_remove_gatheredaccount_action_and_more"),
|
|
||||||
]
|
|
||||||
|
|
||||||
operations = [
|
|
||||||
migrations.AlterField(
|
|
||||||
model_name="gatheredaccount",
|
|
||||||
name="status",
|
|
||||||
field=models.CharField(
|
|
||||||
blank=True,
|
|
||||||
choices=[("confirmed", "Confirmed"), ("ignored", "Ignored")],
|
|
||||||
default="",
|
|
||||||
max_length=32,
|
|
||||||
verbose_name="Status",
|
|
||||||
),
|
|
||||||
),
|
|
||||||
]
|
|
|
@ -1,22 +0,0 @@
|
||||||
# Generated by Django 4.1.13 on 2024-10-31 08:48
|
|
||||||
|
|
||||||
from django.db import migrations, models
|
|
||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
|
||||||
|
|
||||||
dependencies = [
|
|
||||||
("accounts", "0012_alter_gatheredaccount_status"),
|
|
||||||
]
|
|
||||||
|
|
||||||
operations = [
|
|
||||||
migrations.RemoveField(
|
|
||||||
model_name="gatheredaccount",
|
|
||||||
name="sudo",
|
|
||||||
),
|
|
||||||
migrations.AddField(
|
|
||||||
model_name="gatheredaccount",
|
|
||||||
name="sudoers",
|
|
||||||
field=models.TextField(default=False, verbose_name="Sudoers"),
|
|
||||||
),
|
|
||||||
]
|
|
|
@ -20,7 +20,8 @@ class GatheredAccountDiff(models.Model):
|
||||||
|
|
||||||
|
|
||||||
class GatheredAccount(JMSOrgBaseModel):
|
class GatheredAccount(JMSOrgBaseModel):
|
||||||
present = models.BooleanField(default=True, verbose_name=_("Remote present")) # 资产上是否还存在
|
remote_present = models.BooleanField(default=True, verbose_name=_("Remote present")) # 远端资产上是否还存在
|
||||||
|
present = models.BooleanField(default=False, verbose_name=_("Present")) # 系统资产上是否还存在
|
||||||
date_last_login = models.DateTimeField(null=True, verbose_name=_("Date login"))
|
date_last_login = models.DateTimeField(null=True, verbose_name=_("Date login"))
|
||||||
asset = models.ForeignKey('assets.Asset', on_delete=models.CASCADE, verbose_name=_("Asset"))
|
asset = models.ForeignKey('assets.Asset', on_delete=models.CASCADE, verbose_name=_("Asset"))
|
||||||
username = models.CharField(max_length=32, blank=True, db_index=True, verbose_name=_('Username'))
|
username = models.CharField(max_length=32, blank=True, db_index=True, verbose_name=_('Username'))
|
||||||
|
|
|
@ -22,9 +22,10 @@ class GatheredAccountSerializer(BulkOrgResourceModelSerializer):
|
||||||
class Meta(BaseAccountSerializer.Meta):
|
class Meta(BaseAccountSerializer.Meta):
|
||||||
model = GatheredAccount
|
model = GatheredAccount
|
||||||
fields = [
|
fields = [
|
||||||
'id', 'present', 'asset', 'username',
|
'id', 'asset', 'username',
|
||||||
'date_updated', 'address_last_login',
|
'date_updated', 'address_last_login',
|
||||||
'groups', 'sudoers', 'authorized_keys',
|
'groups', 'sudoers', 'authorized_keys',
|
||||||
|
'remote_present', 'present',
|
||||||
'date_last_login', 'status'
|
'date_last_login', 'status'
|
||||||
]
|
]
|
||||||
read_only_fields = fields
|
read_only_fields = fields
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
#
|
#
|
||||||
from rest_framework.serializers import ModelSerializer
|
from rest_framework import serializers
|
||||||
|
|
||||||
from accounts.const import AutomationTypes
|
from accounts.const import AutomationTypes
|
||||||
from accounts.models import AccountCheckAutomation, AccountRisk
|
from accounts.models import AccountCheckAutomation, AccountRisk
|
||||||
|
@ -11,11 +11,12 @@ logger = get_logger(__file__)
|
||||||
|
|
||||||
__all__ = [
|
__all__ = [
|
||||||
'CheckAccountsAutomationSerializer',
|
'CheckAccountsAutomationSerializer',
|
||||||
'AccountRiskSerializer'
|
'AccountRiskSerializer',
|
||||||
|
'AccountCheckEngineSerializer'
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
class AccountRiskSerializer(ModelSerializer):
|
class AccountRiskSerializer(serializers.ModelSerializer):
|
||||||
class Meta:
|
class Meta:
|
||||||
model = AccountRisk
|
model = AccountRisk
|
||||||
fields = '__all__'
|
fields = '__all__'
|
||||||
|
@ -32,3 +33,10 @@ class CheckAccountsAutomationSerializer(BaseAutomationSerializer):
|
||||||
@property
|
@property
|
||||||
def model_type(self):
|
def model_type(self):
|
||||||
return AutomationTypes.check_account
|
return AutomationTypes.check_account
|
||||||
|
|
||||||
|
|
||||||
|
class AccountCheckEngineSerializer(serializers.Serializer):
|
||||||
|
id = serializers.IntegerField(required=False)
|
||||||
|
name = serializers.CharField(max_length=128, required=True)
|
||||||
|
display_name = serializers.CharField(max_length=128, required=False)
|
||||||
|
description = serializers.CharField(required=False)
|
||||||
|
|
|
@ -24,6 +24,7 @@ router.register(r'gather-account-executions', api.GatherAccountsExecutionViewSet
|
||||||
router.register(r'push-account-automations', api.PushAccountAutomationViewSet, 'push-account-automation')
|
router.register(r'push-account-automations', api.PushAccountAutomationViewSet, 'push-account-automation')
|
||||||
router.register(r'push-account-executions', api.PushAccountExecutionViewSet, 'push-account-execution')
|
router.register(r'push-account-executions', api.PushAccountExecutionViewSet, 'push-account-execution')
|
||||||
router.register(r'push-account-records', api.PushAccountRecordViewSet, 'push-account-record')
|
router.register(r'push-account-records', api.PushAccountRecordViewSet, 'push-account-record')
|
||||||
|
router.register(r'account-check-engines', api.AccountCheckEngineViewSet, 'account-check-engine')
|
||||||
|
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
path('accounts/bulk/', api.AssetAccountBulkCreateApi.as_view(), name='account-bulk-create'),
|
path('accounts/bulk/', api.AssetAccountBulkCreateApi.as_view(), name='account-bulk-create'),
|
||||||
|
|
|
@ -52,7 +52,7 @@ class RBACPermission(permissions.DjangoModelPermissions):
|
||||||
return cls.format_perms(perm_tmpl, model_cls)
|
return cls.format_perms(perm_tmpl, model_cls)
|
||||||
|
|
||||||
def get_default_action_perms(self, model_cls):
|
def get_default_action_perms(self, model_cls):
|
||||||
if model_cls is None:
|
if model_cls is None or not hasattr(model_cls, '_meta'):
|
||||||
return {}
|
return {}
|
||||||
|
|
||||||
perms = {}
|
perms = {}
|
||||||
|
|
Loading…
Reference in New Issue