perf: 添加 histories

pull/8991/head
ibuler 2022-10-20 16:39:11 +08:00
parent 1a2193d091
commit c55d3c0b6c
14 changed files with 59 additions and 85 deletions

View File

@ -1,4 +1,3 @@
from .account import *
from .backup import *
from .history import *
from .template import *

View File

@ -47,10 +47,18 @@ class AccountSecretsViewSet(RecordViewLogMixin, AccountViewSet):
# Todo: 记得打开
# permission_classes = [RBACPermission, UserConfirmation.require(ConfirmType.MFA)]
rbac_perms = {
'list': 'assets.view_assetaccountsecret',
'retrieve': 'assets.view_assetaccountsecret',
'list': 'assets.view_accountsecret',
'retrieve': 'assets.view_accountsecret',
'histories': ['assets.view_accountsecret'],
}
@action(methods=['get'], detail=True, url_path='histories', serializer_class=serializers.AccountHistorySerializer)
def histories(self, request, *args, **kwargs):
account = self.get_object()
histories = account.history.all()
serializer = serializers.AccountHistorySerializer(histories, many=True)
return Response(serializer.data)
class AccountTaskCreateAPI(CreateAPIView):
serializer_class = serializers.AccountTaskSerializer

View File

@ -1,38 +0,0 @@
from assets import serializers
from assets.models import Account
from assets.filters import AccountFilterSet
from common.mixins import RecordViewLogMixin
from .account import AccountViewSet, AccountSecretsViewSet
__all__ = ['AccountHistoryViewSet', 'AccountHistorySecretsViewSet']
class AccountHistoryFilterSet(AccountFilterSet):
class Meta:
model = Account.history.model
fields = ['id', 'secret_type']
class AccountHistoryViewSet(AccountViewSet):
model = Account.history.model
filterset_class = AccountHistoryFilterSet
serializer_classes = {
'default': serializers.AccountHistorySerializer,
}
rbac_perms = {
'list': 'assets.view_assethistoryaccount',
'retrieve': 'assets.view_assethistoryaccount',
}
http_method_names = ['get', 'options']
class AccountHistorySecretsViewSet(RecordViewLogMixin, AccountHistoryViewSet):
serializer_classes = {
'default': serializers.AccountHistorySecretSerializer
}
http_method_names = ['get']
permission_classes = AccountSecretsViewSet.permission_classes
rbac_perms = {
'list': 'assets.view_assethistoryaccountsecret',
'retrieve': 'assets.view_assethistoryaccountsecret',
}

View File

@ -92,7 +92,7 @@ class Migration(migrations.Migration):
name='Web',
fields=[
('asset_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='assets.asset')),
('autofill', models.CharField(default='basic', max_length=16)),
('autofill', models.CharField(choices=[('no', 'Disabled'), ('basic', 'Basic'), ('script', 'Script')], default='basic', max_length=16, verbose_name='Autofill')),
('password_selector', models.CharField(blank=True, default='', max_length=128, verbose_name='Password selector')),
('submit_selector', models.CharField(blank=True, default='', max_length=128, verbose_name='Submit selector')),
('username_selector', models.CharField(blank=True, default='', max_length=128, verbose_name='Username selector')),

View File

@ -28,7 +28,7 @@ class Migration(migrations.Migration):
('trigger', models.CharField(choices=[('manual', 'Manual trigger'), ('timing', 'Timing trigger')], default='manual', max_length=128, verbose_name='Trigger mode')),
],
options={
'verbose_name': 'Automation strategy execution',
'verbose_name': 'Automation task execution',
},
),
migrations.CreateModel(
@ -52,7 +52,7 @@ class Migration(migrations.Migration):
('nodes', models.ManyToManyField(blank=True, to='assets.Node', verbose_name='Nodes')),
],
options={
'verbose_name': 'Automation plan',
'verbose_name': 'Automation task',
'unique_together': {('org_id', 'name')},
},
),
@ -122,7 +122,7 @@ class Migration(migrations.Migration):
('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': 'Verify secret automation',
'verbose_name': 'Verify account automation',
},
bases=('assets.baseautomation',),
),
@ -150,7 +150,7 @@ class Migration(migrations.Migration):
migrations.AddField(
model_name='automationexecution',
name='automation',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='executions', to='assets.baseautomation', verbose_name='Automation strategy'),
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='executions', to='assets.baseautomation', verbose_name='Automation task'),
),
migrations.CreateModel(
name='ChangeSecretAutomation',

View File

@ -0,0 +1,24 @@
# Generated by Django 3.2.14 on 2022-10-19 12:40
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('assets', '0107_auto_20221019_1115'),
]
operations = [
migrations.AddField(
model_name='web',
name='script',
field=models.JSONField(blank=True, default=list, verbose_name='Script'),
),
migrations.AddField(
model_name='historicalaccount',
name='version',
field=models.IntegerField(default=0, verbose_name='Version'),
),
]

View File

@ -41,7 +41,7 @@ class Account(BaseAccount):
)
version = models.IntegerField(default=0, verbose_name=_('Version'))
history = AccountHistoricalRecords(
included_fields=['id', 'secret_type', 'secret']
included_fields=['id', 'secret_type', 'secret', 'version']
)
class Meta:

View File

@ -5,7 +5,13 @@ from .common import Asset
class Web(Asset):
autofill = models.CharField(max_length=16, default='basic')
class FillType(models.TextChoices):
no = 'no', _('Disabled')
basic = 'basic', _('Basic')
script = 'script', _('Script')
autofill = models.CharField(max_length=16, choices=FillType.choices, default='basic', verbose_name=_("Autofill"))
username_selector = models.CharField(max_length=128, blank=True, default='', verbose_name=_("Username selector"))
password_selector = models.CharField(max_length=128, blank=True, default='', verbose_name=_("Password selector"))
submit_selector = models.CharField(max_length=128, blank=True, default='', verbose_name=_("Submit selector"))
script = models.JSONField(blank=True, default=list, verbose_name=_("Script"))

View File

@ -1,3 +1,2 @@
from .account import *
from .history import *
from .template import *

View File

@ -60,8 +60,8 @@ class AccountSerializer(AccountSerializerCreateMixin, BaseAccountSerializer):
class Meta(BaseAccountSerializer.Meta):
model = Account
fields = BaseAccountSerializer.Meta.fields \
+ ['su_from', 'version', 'asset'] \
+ ['template', 'push_now']
+ ['su_from', 'version', 'asset'] \
+ ['template', 'push_now']
extra_kwargs = {
**BaseAccountSerializer.Meta.extra_kwargs,
'name': {'required': False, 'allow_null': True},
@ -89,6 +89,13 @@ class AccountSecretSerializer(SecretReadableMixin, AccountSerializer):
}
class AccountHistorySerializer(serializers.ModelSerializer):
class Meta:
model = Account.history.model
fields = ['id', 'secret', 'secret_type', 'version', 'history_date', 'history_user']
read_only_fields = fields
class AccountTaskSerializer(serializers.Serializer):
ACTION_CHOICES = (
('test', 'test'),

View File

@ -1,26 +0,0 @@
from assets.models import Account
from common.drf.serializers import SecretReadableMixin
from .base import BaseAccountSerializer
from .account import AccountSerializer, AccountSecretSerializer
class AccountHistorySerializer(AccountSerializer):
class Meta:
model = Account.history.model
fields = BaseAccountSerializer.Meta.fields_mini
read_only_fields = fields
ref_name = 'AccountHistorySerializer'
def get_field_names(self, declared_fields, info):
fields = super().get_field_names(declared_fields, info)
fields = list(set(fields) - {'org_name'})
return fields
def to_representation(self, instance):
return super(AccountSerializer, self).to_representation(instance)
class AccountHistorySecretSerializer(SecretReadableMixin, AccountHistorySerializer):
class Meta(AccountHistorySerializer.Meta):
extra_kwargs = AccountSecretSerializer.Meta.extra_kwargs

View File

@ -10,7 +10,8 @@ class WebSerializer(AssetSerializer):
model = Web
fields = AssetSerializer.Meta.fields + [
'autofill', 'username_selector',
'password_selector', 'submit_selector'
'password_selector', 'submit_selector',
'script'
]
extra_kwargs = {
**AssetSerializer.Meta.extra_kwargs,
@ -25,5 +26,5 @@ class WebSerializer(AssetSerializer):
},
'submit_selector': {
'default': 'button[type=submit]',
}
},
}

View File

@ -17,8 +17,6 @@ router.register(r'clouds', api.CloudViewSet, 'cloud')
router.register(r'accounts', api.AccountViewSet, 'account')
router.register(r'account-templates', api.AccountTemplateViewSet, 'account-template')
router.register(r'account-secrets', api.AccountSecretsViewSet, 'account-secret')
router.register(r'accounts-history', api.AccountHistoryViewSet, 'account-history')
router.register(r'account-history-secrets', api.AccountHistorySecretsViewSet, 'account-history-secret')
router.register(r'platforms', api.AssetPlatformViewSet, 'platform')
router.register(r'labels', api.LabelViewSet, 'label')
router.register(r'nodes', api.NodeViewSet, 'node')

View File

@ -39,10 +39,6 @@ exclude_permissions = (
('assets', 'assetuser', '*', '*'),
('assets', 'gathereduser', 'add,delete,change', 'gathereduser'),
('assets', 'accountbackupplanexecution', 'delete,change', 'accountbackupplanexecution'),
('assets', 'account', 'change', 'account'),
# TODO 暂时去掉历史账号的权限
('assets', 'account', '*', 'assethistoryaccount'),
('assets', 'account', '*', 'assethistoryaccountsecret'),
('perms', 'userassetgrantedtreenoderelation', '*', '*'),
('perms', 'usergrantedmappingnode', '*', '*'),