2023-04-20 06:43:40 +00:00
|
|
|
from django.db.transaction import atomic
|
2023-04-19 02:18:13 +00:00
|
|
|
from django.db.utils import IntegrityError
|
|
|
|
|
2023-04-12 09:59:13 +00:00
|
|
|
from accounts.models import AccountTemplate, Account
|
|
|
|
from assets.models import Asset
|
2023-01-16 11:02:09 +00:00
|
|
|
from common.serializers import SecretReadableMixin
|
2022-09-23 10:59:19 +00:00
|
|
|
from .base import BaseAccountSerializer
|
2022-08-24 08:36:42 +00:00
|
|
|
|
|
|
|
|
2022-09-23 10:59:19 +00:00
|
|
|
class AccountTemplateSerializer(BaseAccountSerializer):
|
|
|
|
class Meta(BaseAccountSerializer.Meta):
|
2022-08-24 08:36:42 +00:00
|
|
|
model = AccountTemplate
|
|
|
|
|
2023-04-12 09:59:13 +00:00
|
|
|
@staticmethod
|
2023-04-19 02:18:13 +00:00
|
|
|
def account_save(data, account):
|
|
|
|
for field, value in data.items():
|
|
|
|
setattr(account, field, value)
|
|
|
|
try:
|
|
|
|
account.save(update_fields=list(data.keys()))
|
|
|
|
except IntegrityError:
|
|
|
|
pass
|
|
|
|
|
|
|
|
# TODO 数据库访问的太多了 后期优化
|
2023-04-20 06:43:40 +00:00
|
|
|
@atomic()
|
2023-04-19 02:18:13 +00:00
|
|
|
def bulk_update_accounts(self, instance, diff):
|
2023-04-12 09:59:13 +00:00
|
|
|
accounts = Account.objects.filter(source_id=instance.id)
|
|
|
|
if not accounts:
|
|
|
|
return
|
|
|
|
|
|
|
|
diff.pop('secret', None)
|
2023-04-19 02:18:13 +00:00
|
|
|
name = diff.pop('name', None)
|
|
|
|
username = diff.pop('username', None)
|
|
|
|
secret_type = diff.pop('secret_type', None)
|
2023-04-12 09:59:13 +00:00
|
|
|
update_accounts = []
|
|
|
|
for account in accounts:
|
|
|
|
for field, value in diff.items():
|
|
|
|
setattr(account, field, value)
|
|
|
|
update_accounts.append(account)
|
2023-04-19 02:18:13 +00:00
|
|
|
|
2023-04-12 09:59:13 +00:00
|
|
|
if update_accounts:
|
|
|
|
Account.objects.bulk_update(update_accounts, diff.keys())
|
|
|
|
|
2023-04-19 02:18:13 +00:00
|
|
|
if name:
|
|
|
|
for account in accounts:
|
|
|
|
data = {'name': name}
|
|
|
|
self.account_save(data, account)
|
2023-04-12 09:59:13 +00:00
|
|
|
|
2023-04-19 02:18:13 +00:00
|
|
|
if secret_type and username:
|
|
|
|
asset_ids_supports = self.get_asset_ids_supports(accounts, secret_type)
|
|
|
|
for account in accounts:
|
|
|
|
asset_id = account.asset_id
|
|
|
|
if asset_id not in asset_ids_supports:
|
|
|
|
data = {'username': username}
|
|
|
|
self.account_save(data, account)
|
|
|
|
continue
|
|
|
|
data = {'username': username, 'secret_type': secret_type, 'secret': instance.secret}
|
|
|
|
self.account_save(data, account)
|
|
|
|
elif secret_type:
|
|
|
|
asset_ids_supports = self.get_asset_ids_supports(accounts, secret_type)
|
|
|
|
for account in accounts:
|
|
|
|
asset_id = account.asset_id
|
|
|
|
if asset_id not in asset_ids_supports:
|
|
|
|
continue
|
|
|
|
data = {'secret_type': secret_type, 'secret': instance.secret}
|
|
|
|
self.account_save(data, account)
|
|
|
|
elif username:
|
|
|
|
for account in accounts:
|
|
|
|
data = {'username': username}
|
|
|
|
self.account_save(data, account)
|
|
|
|
|
|
|
|
@staticmethod
|
|
|
|
def get_asset_ids_supports(accounts, secret_type):
|
2023-04-12 09:59:13 +00:00
|
|
|
asset_ids = accounts.values_list('asset_id', flat=True)
|
|
|
|
secret_type_supports = Asset.get_secret_type_assets(asset_ids, secret_type)
|
2023-04-19 02:18:13 +00:00
|
|
|
return [asset.id for asset in secret_type_supports]
|
2023-04-12 09:59:13 +00:00
|
|
|
|
|
|
|
def update(self, instance, validated_data):
|
|
|
|
diff = {
|
|
|
|
k: v for k, v in validated_data.items()
|
|
|
|
if getattr(instance, k) != v
|
|
|
|
}
|
|
|
|
instance = super().update(instance, validated_data)
|
|
|
|
self.bulk_update_accounts(instance, diff)
|
|
|
|
return instance
|
2022-11-28 07:54:16 +00:00
|
|
|
|
|
|
|
|
|
|
|
class AccountTemplateSecretSerializer(SecretReadableMixin, AccountTemplateSerializer):
|
|
|
|
class Meta(AccountTemplateSerializer.Meta):
|
|
|
|
extra_kwargs = {
|
|
|
|
'secret': {'write_only': False},
|
|
|
|
}
|