diff --git a/apps/assets/api/account/__init__.py b/apps/assets/api/account/__init__.py index 6e402a550..19f1af93d 100644 --- a/apps/assets/api/account/__init__.py +++ b/apps/assets/api/account/__init__.py @@ -1,4 +1,3 @@ from .account import * from .backup import * -from .history import * from .template import * diff --git a/apps/assets/api/account/account.py b/apps/assets/api/account/account.py index eaba34571..8e8e320bd 100644 --- a/apps/assets/api/account/account.py +++ b/apps/assets/api/account/account.py @@ -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 diff --git a/apps/assets/api/account/history.py b/apps/assets/api/account/history.py deleted file mode 100644 index cfcbfeb8e..000000000 --- a/apps/assets/api/account/history.py +++ /dev/null @@ -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', - } diff --git a/apps/assets/migrations/0092_add_host.py b/apps/assets/migrations/0092_add_host.py index 10a5c8367..72ad9f7d8 100644 --- a/apps/assets/migrations/0092_add_host.py +++ b/apps/assets/migrations/0092_add_host.py @@ -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')), diff --git a/apps/assets/migrations/0107_auto_20221019_1115.py b/apps/assets/migrations/0107_auto_20221019_1115.py index 0c0fb772f..6c812b708 100644 --- a/apps/assets/migrations/0107_auto_20221019_1115.py +++ b/apps/assets/migrations/0107_auto_20221019_1115.py @@ -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', diff --git a/apps/assets/migrations/0108_auto_20221019_2040.py b/apps/assets/migrations/0108_auto_20221019_2040.py new file mode 100644 index 000000000..c2f47fc2f --- /dev/null +++ b/apps/assets/migrations/0108_auto_20221019_2040.py @@ -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'), + ), + ] diff --git a/apps/assets/models/account.py b/apps/assets/models/account.py index 391a58e9b..8bb19bb39 100644 --- a/apps/assets/models/account.py +++ b/apps/assets/models/account.py @@ -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: diff --git a/apps/assets/models/asset/web.py b/apps/assets/models/asset/web.py index 1bcd3a766..15445b3d6 100644 --- a/apps/assets/models/asset/web.py +++ b/apps/assets/models/asset/web.py @@ -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")) diff --git a/apps/assets/serializers/account/__init__.py b/apps/assets/serializers/account/__init__.py index 70c013231..062b7064c 100644 --- a/apps/assets/serializers/account/__init__.py +++ b/apps/assets/serializers/account/__init__.py @@ -1,3 +1,2 @@ from .account import * -from .history import * from .template import * diff --git a/apps/assets/serializers/account/account.py b/apps/assets/serializers/account/account.py index 5ef2bfde3..6faf2c946 100644 --- a/apps/assets/serializers/account/account.py +++ b/apps/assets/serializers/account/account.py @@ -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'), diff --git a/apps/assets/serializers/account/history.py b/apps/assets/serializers/account/history.py deleted file mode 100644 index a49636334..000000000 --- a/apps/assets/serializers/account/history.py +++ /dev/null @@ -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 diff --git a/apps/assets/serializers/asset/web.py b/apps/assets/serializers/asset/web.py index a6bd89435..333795473 100644 --- a/apps/assets/serializers/asset/web.py +++ b/apps/assets/serializers/asset/web.py @@ -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]', - } + }, } diff --git a/apps/assets/urls/api_urls.py b/apps/assets/urls/api_urls.py index 491d83163..688319ef6 100644 --- a/apps/assets/urls/api_urls.py +++ b/apps/assets/urls/api_urls.py @@ -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') diff --git a/apps/rbac/const.py b/apps/rbac/const.py index 037358be0..bf79168a3 100644 --- a/apps/rbac/const.py +++ b/apps/rbac/const.py @@ -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', '*', '*'),