perf: Display account history in combination with password change records

pull/14732/head
feng 2024-12-25 11:19:39 +08:00 committed by feng626
parent 8420c0b22b
commit 95ff9a3cdb
3 changed files with 96 additions and 8 deletions

View File

@ -5,14 +5,16 @@ from rest_framework.response import Response
from rest_framework.status import HTTP_200_OK
from accounts import serializers
from accounts.const import ChangeSecretRecordStatusChoice
from accounts.filters import AccountFilterSet
from accounts.mixins import AccountRecordViewLogMixin
from accounts.models import Account
from accounts.models import Account, ChangeSecretRecord
from assets.models import Asset, Node
from authentication.permissions import UserConfirmation, ConfirmType
from common.api.mixin import ExtraFilterFieldsMixin
from common.drf.filters import AttrRulesFilterBackend
from common.permissions import IsValidUser
from common.utils import lazyproperty
from orgs.mixins.api import OrgBulkModelViewSet
from rbac.permissions import RBACPermission
@ -127,17 +129,31 @@ class AccountHistoriesSecretAPI(ExtraFilterFieldsMixin, AccountRecordViewLogMixi
'GET': 'accounts.view_accountsecret',
}
def get_object(self):
@lazyproperty
def account(self) -> Account:
return get_object_or_404(Account, pk=self.kwargs.get('pk'))
def get_object(self):
return self.account
@lazyproperty
def latest_history(self):
return self.account.history.first()
@property
def latest_change_secret_record(self) -> ChangeSecretRecord:
return self.account.change_secret_records.filter(
status=ChangeSecretRecordStatusChoice.pending
).order_by('-date_created').first()
@staticmethod
def filter_spm_queryset(resource_ids, queryset):
return queryset.filter(history_id__in=resource_ids)
def get_queryset(self):
account = self.get_object()
account = self.account
histories = account.history.all()
latest_history = account.history.first()
latest_history = self.latest_history
if not latest_history:
return histories
if account.secret != latest_history.secret:
@ -146,3 +162,25 @@ class AccountHistoriesSecretAPI(ExtraFilterFieldsMixin, AccountRecordViewLogMixi
return histories
histories = histories.exclude(history_id=latest_history.history_id)
return histories
def filter_queryset(self, queryset):
queryset = super().filter_queryset(queryset)
queryset = list(queryset)
latest_history = self.latest_history
if not latest_history:
return queryset
latest_change_secret_record = self.latest_change_secret_record
if not latest_change_secret_record:
return queryset
if latest_change_secret_record.date_created > latest_history.history_date:
temp_history = self.model(
secret=latest_change_secret_record.new_secret,
secret_type=self.account.secret_type,
version=latest_history.version,
history_date=latest_change_secret_record.date_created,
)
queryset = [temp_history] + queryset
return queryset

View File

@ -0,0 +1,42 @@
# Generated by Django 4.1.13 on 2024-12-24 05:27
import django.db.models.deletion
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('assets', '0011_auto_20241204_1516'),
('accounts', '0023_alter_changesecretrecord_options'),
]
operations = [
migrations.RemoveField(
model_name='changesecretrecord',
name='date_started',
),
migrations.AlterField(
model_name='changesecretrecord',
name='account',
field=models.ForeignKey(
null=True, on_delete=django.db.models.deletion.SET_NULL,
related_name='change_secret_records', to='accounts.account'
),
),
migrations.AlterField(
model_name='changesecretrecord',
name='asset',
field=models.ForeignKey(
null=True, on_delete=django.db.models.deletion.SET_NULL,
related_name='asset_change_secret_records', to='assets.asset'
),
),
migrations.AlterField(
model_name='changesecretrecord',
name='execution',
field=models.ForeignKey(
null=True, on_delete=django.db.models.deletion.SET_NULL,
related_name='execution_change_secret_records', to='accounts.automationexecution'
),
),
]

View File

@ -31,12 +31,20 @@ class ChangeSecretAutomation(ChangeSecretMixin, AccountBaseAutomation):
class ChangeSecretRecord(JMSBaseModel):
execution = models.ForeignKey('accounts.AutomationExecution', on_delete=models.SET_NULL, null=True)
asset = models.ForeignKey('assets.Asset', on_delete=models.SET_NULL, null=True)
account = models.ForeignKey('accounts.Account', on_delete=models.SET_NULL, null=True)
account = models.ForeignKey(
'accounts.Account', on_delete=models.SET_NULL,
null=True, related_name='change_secret_records'
)
asset = models.ForeignKey(
'assets.Asset', on_delete=models.SET_NULL,
null=True, related_name='asset_change_secret_records'
)
execution = models.ForeignKey(
'accounts.AutomationExecution', on_delete=models.SET_NULL,
null=True, related_name='execution_change_secret_records',
)
old_secret = fields.EncryptTextField(blank=True, null=True, verbose_name=_('Old secret'))
new_secret = fields.EncryptTextField(blank=True, null=True, verbose_name=_('New secret'))
date_started = models.DateTimeField(blank=True, null=True, verbose_name=_('Date started'))
date_finished = models.DateTimeField(blank=True, null=True, verbose_name=_('Date finished'), db_index=True)
ignore_fail = models.BooleanField(default=False, verbose_name=_('Ignore fail'))
status = models.CharField(