perf: update service to application

pull/14586/head
ibuler 2024-12-04 18:32:49 +08:00
parent 707a83ec19
commit fb8c27a025
23 changed files with 197 additions and 67 deletions

View File

@ -2,4 +2,4 @@ from .account import *
from .task import *
from .template import *
from .virtual import *
from .service import *
from .application import *

View File

@ -7,8 +7,8 @@ from rest_framework.decorators import action
from rest_framework.response import Response
from accounts import serializers
from accounts.models import ServiceIntegration
from audits.models import ServiceAccessLog
from accounts.models import IntegrationApplication
from audits.models import IntegrationApplicationLog
from authentication.permissions import UserConfirmation, ConfirmType
from common.exceptions import JMSException
from common.permissions import IsValidUser
@ -17,16 +17,16 @@ from orgs.mixins.api import OrgBulkModelViewSet
from rbac.permissions import RBACPermission
class ServiceIntegrationViewSet(OrgBulkModelViewSet):
model = ServiceIntegration
class IntegrationApplicationViewSet(OrgBulkModelViewSet):
model = IntegrationApplication
search_fields = ('name', 'comment')
serializer_classes = {
'default': serializers.ServiceIntegrationSerializer,
'get_account_secret': serializers.ServiceAccountSecretSerializer
'default': serializers.IntegrationApplicationSerializer,
'get_account_secret': serializers.IntegrationAccountSecretSerializer
}
rbac_perms = {
'get_once_secret': 'accounts.change_serviceintegration',
'get_account_secret': 'accounts.view_serviceintegration',
'get_once_secret': 'accounts.change_integrationapplication',
'get_account_secret': 'view_integrationapplication',
}
@action(
@ -66,7 +66,7 @@ class ServiceIntegrationViewSet(OrgBulkModelViewSet):
msg = _('Account not found')
raise JMSException(code='Not found', detail='%s' % msg)
asset = account.asset
ServiceAccessLog.objects.create(
IntegrationApplicationLog.objects.create(
remote_addr=get_request_ip(request), service=service.name, service_id=service.id,
account=f'{account.name}({account.username})', asset=f'{asset.name}({asset.address})',
)

View File

@ -34,7 +34,7 @@ class Migration(migrations.Migration):
('is_active', models.BooleanField(default=True, verbose_name='Active')),
],
options={
'verbose_name': 'Service integration',
'verbose_name': 'Application integration',
'unique_together': {('name', 'org_id')},
},
),

View File

@ -0,0 +1,108 @@
# Generated by Django 4.1.13 on 2024-12-04 08:27
import common.db.fields
import common.db.utils
from django.db import migrations, models
import private_storage.fields
import private_storage.storage.files
import uuid
class Migration(migrations.Migration):
dependencies = [
("accounts", "0018_changesecretrecord_ignore_fail_and_more"),
]
operations = [
migrations.CreateModel(
name="IntegrationApplication",
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",
),
),
("name", models.CharField(max_length=128, verbose_name="Name")),
(
"logo",
private_storage.fields.PrivateImageField(
max_length=128,
storage=private_storage.storage.files.PrivateFileSystemStorage(),
upload_to="integration-apps",
verbose_name="Logo",
),
),
(
"secret",
common.db.fields.EncryptTextField(
default="", verbose_name="Secret"
),
),
(
"accounts",
common.db.fields.JSONManyToManyField(
default=dict, to="accounts.Account", verbose_name="Accounts"
),
),
(
"ip_group",
models.JSONField(
default=common.db.utils.default_ip_group,
verbose_name="IP group",
),
),
(
"date_last_used",
models.DateTimeField(
blank=True, null=True, verbose_name="Date last used"
),
),
("is_active", models.BooleanField(default=True, verbose_name="Active")),
],
options={
"verbose_name": "Integration App",
"unique_together": {("name", "org_id")},
},
),
migrations.DeleteModel(
name="ServiceIntegration",
),
]

View File

@ -3,4 +3,4 @@ from .base import * # noqa
from .automations import * # noqa
from .template import * # noqa
from .virtual import * # noqa
from .service import * # noqa
from .application import * # noqa

View File

@ -10,12 +10,12 @@ from common.utils import random_string
from orgs.mixins.models import JMSOrgBaseModel
class ServiceIntegration(JMSOrgBaseModel):
class IntegrationApplication(JMSOrgBaseModel):
is_anonymous = False
name = models.CharField(max_length=128, unique=False, verbose_name=_('Name'))
logo_image = PrivateImageField(
upload_to='service-integration', max_length=128, verbose_name=_('Logo')
logo = PrivateImageField(
upload_to='integration-apps', max_length=128, verbose_name=_('Logo')
)
secret = fields.EncryptTextField(default='', verbose_name=_('Secret'))
accounts = JSONManyToManyField('accounts.Account', default=dict, verbose_name=_('Accounts'))
@ -25,7 +25,7 @@ class ServiceIntegration(JMSOrgBaseModel):
class Meta:
unique_together = [('name', 'org_id')]
verbose_name = _('Service integration')
verbose_name = _('Integration App')
@property
def accounts_amount(self):
@ -43,7 +43,7 @@ class ServiceIntegration(JMSOrgBaseModel):
@staticmethod
def has_perms(perms):
support_perms = ['accounts.view_serviceintegration']
support_perms = ['accounts.view_integrationapplication']
return all([perm in support_perms for perm in perms])
def get_secret(self):

View File

@ -1,12 +1,12 @@
from django.utils.translation import gettext_lazy as _
from rest_framework import serializers
from accounts.models import ServiceIntegration
from accounts.models import IntegrationApplication
from acls.serializers.rules import ip_group_child_validator, ip_group_help_text
from common.serializers.fields import JSONManyToManyField
class ServiceIntegrationSerializer(serializers.ModelSerializer):
class IntegrationApplicationSerializer(serializers.ModelSerializer):
accounts = JSONManyToManyField(label=_('Account'))
ip_group = serializers.ListField(
default=['*'], label=_('Access IP'), help_text=ip_group_help_text,
@ -14,9 +14,9 @@ class ServiceIntegrationSerializer(serializers.ModelSerializer):
)
class Meta:
model = ServiceIntegration
model = IntegrationApplication
fields_mini = ['id', 'name']
fields_small = fields_mini + ['logo_image', 'accounts']
fields_small = fields_mini + ['logo', 'accounts']
fields = fields_small + [
'date_last_used', 'date_created', 'date_updated',
'ip_group', 'accounts_amount', 'comment', 'is_active'
@ -31,10 +31,10 @@ class ServiceIntegrationSerializer(serializers.ModelSerializer):
super().__init__(*args, **kwargs)
request_method = self.context.get('request').method
if request_method == 'PUT':
self.fields['logo_image'].required = False
self.fields['logo'].required = False
class ServiceAccountSecretSerializer(serializers.Serializer):
class IntegrationAccountSecretSerializer(serializers.Serializer):
asset = serializers.CharField(required=False, allow_blank=True)
asset_id = serializers.UUIDField(required=False, allow_null=True)
account = serializers.CharField(required=False, allow_blank=True)

View File

@ -9,7 +9,6 @@ app_name = 'accounts'
router = BulkRouter()
router.register(r'accounts', api.AccountViewSet, 'account')
router.register(r'service-integrations', api.ServiceIntegrationViewSet, 'service-integration')
router.register(r'virtual-accounts', api.VirtualAccountViewSet, 'virtual-account')
router.register(r'gathered-accounts', api.GatheredAccountViewSet, 'gathered-account')
router.register(r'account-secrets', api.AccountSecretsViewSet, 'account-secret')
@ -29,6 +28,8 @@ router.register(r'check-account-automations', api.CheckAccountAutomationViewSet,
router.register(r'check-account-executions', api.CheckAccountExecutionViewSet, 'check-account-execution')
router.register(r'account-check-engines', api.CheckAccountEngineViewSet, 'account-check-engine')
router.register(r'account-risks', api.AccountRiskViewSet, 'account-risks')
router.register(r'integration-applications', api.IntegrationApplicationViewSet, 'integration-apps')
urlpatterns = [
path('accounts/bulk/', api.AssetAccountBulkCreateApi.as_view(), name='account-bulk-create'),

View File

@ -33,7 +33,7 @@ from .const import ActivityChoices
from .filters import UserSessionFilterSet, OperateLogFilterSet
from .models import (
FTPLog, UserLoginLog, OperateLog, PasswordChangeLog,
ActivityLog, JobLog, UserSession, ServiceAccessLog
ActivityLog, JobLog, UserSession, IntegrationApplicationLog
)
from .serializers import (
FTPLogSerializer, UserLoginLogSerializer, JobLogSerializer,
@ -293,7 +293,7 @@ class UserSessionViewSet(CommonApiMixin, viewsets.ModelViewSet):
class ServiceAccessLogViewSet(OrgReadonlyModelViewSet):
model = ServiceAccessLog
model = IntegrationApplicationLog
serializer_class = ServiceAccessLogSerializer
extra_filter_backends = [DatetimeRangeFilterBackend]
date_range_filter_fields = [

View File

@ -16,8 +16,8 @@ class Migration(migrations.Migration):
fields=[
('id', models.UUIDField(default=uuid.uuid4, primary_key=True, serialize=False)),
('remote_addr', models.GenericIPAddressField(verbose_name='Remote addr')),
('service', models.CharField(max_length=128, verbose_name='Service')),
('service_id', models.UUIDField(verbose_name='Service ID')),
('service', models.CharField(max_length=128, verbose_name='Application')),
('service_id', models.UUIDField(verbose_name='Application ID')),
('asset', models.CharField(max_length=128, verbose_name='Asset')),
('account', models.CharField(max_length=128, verbose_name='Account')),
('datetime', models.DateTimeField(auto_now=True, verbose_name='Datetime')),

View File

@ -0,0 +1,17 @@
# Generated by Django 4.1.13 on 2024-12-04 09:11
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
("audits", "0004_serviceaccesslog"),
]
operations = [
migrations.RenameModel(
old_name="ServiceAccessLog",
new_name="IntegrationApplicationLog",
),
]

View File

@ -27,14 +27,14 @@ from .const import (
)
__all__ = [
"JobLog",
"FTPLog",
"OperateLog",
"ActivityLog",
"PasswordChangeLog",
"UserLoginLog",
"JobLog",
"UserSession",
"ServiceAccessLog",
"ActivityLog",
"UserLoginLog",
"PasswordChangeLog",
"IntegrationApplicationLog",
]
@ -304,11 +304,11 @@ class UserSession(models.Model):
]
class ServiceAccessLog(models.Model):
class IntegrationApplicationLog(models.Model):
id = models.UUIDField(default=uuid.uuid4, primary_key=True)
remote_addr = models.GenericIPAddressField(verbose_name=_("Remote addr"))
service = models.CharField(max_length=128, verbose_name=_("Service"))
service_id = models.UUIDField(verbose_name=_("Service ID"))
service = models.CharField(max_length=128, verbose_name=_("Application"))
service_id = models.UUIDField(verbose_name=_("Application ID"))
asset = models.CharField(max_length=128, verbose_name=_("Asset"))
account = models.CharField(max_length=128, verbose_name=_("Account"))
datetime = models.DateTimeField(auto_now=True, verbose_name=_("Datetime"))

View File

@ -193,7 +193,7 @@ class UserSessionSerializer(serializers.ModelSerializer):
class ServiceAccessLogSerializer(serializers.ModelSerializer):
class Meta:
model = models.ServiceAccessLog
model = models.IntegrationApplicationLog
fields_mini = ['id']
fields_small = fields_mini + [
'remote_addr', 'service', 'service_id', 'asset', 'account', 'datetime'

View File

@ -7,7 +7,7 @@ from django.utils import timezone
from django.utils.translation import gettext as _
from rest_framework import authentication, exceptions
from accounts.models import ServiceIntegration
from accounts.models import IntegrationApplication
from common.auth import signature
from common.decorators import merge_delay_run
from common.utils import get_object_or_none, get_request_ip_or_data, contains_ip, get_request_ip
@ -36,7 +36,7 @@ def update_user_last_used(users=()):
@merge_delay_run(ttl=60)
def update_service_integration_last_used(service_integrations=()):
ServiceIntegration.objects.filter(
IntegrationApplication.objects.filter(
id__in=service_integrations
).update(date_last_used=timezone.now())
@ -162,7 +162,7 @@ class ServiceAuthentication(signature.SignatureAuthentication):
def get_object(self, key_id):
if not self.__instance:
self.__instance = ServiceIntegration.objects.filter(
self.__instance = IntegrationApplication.objects.filter(
id=key_id, is_active=True,
).first()
return self.__instance

View File

@ -6326,7 +6326,7 @@ msgid "Logo"
msgstr ""
#: settings/serializers/auth/oauth2.py:28
msgid "Service provider"
msgid "Application provider"
msgstr ""
#: settings/serializers/auth/oauth2.py:31
@ -6539,7 +6539,7 @@ msgid ""
msgstr ""
#: settings/serializers/auth/sms.py:18
msgid "Enable Short Message Service (SMS)"
msgid "Enable Short Message Application (SMS)"
msgstr ""
#: settings/serializers/auth/sms.py:21 xpack/plugins/cloud/models.py:36
@ -6547,7 +6547,7 @@ msgid "Provider"
msgstr ""
#: settings/serializers/auth/sms.py:22
msgid "Short Message Service (SMS) provider or protocol"
msgid "Short Message Application (SMS) provider or protocol"
msgstr ""
#: settings/serializers/auth/sms.py:25
@ -10486,7 +10486,7 @@ msgid "Key File"
msgstr ""
#: xpack/plugins/cloud/serializers/account_attrs.py:144
msgid "Service account key"
msgid "Application account key"
msgstr ""
#: xpack/plugins/cloud/serializers/account_attrs.py:145

View File

@ -6566,7 +6566,7 @@ msgid "Logo"
msgstr "アイコン"
#: settings/serializers/auth/oauth2.py:28
msgid "Service provider"
msgid "Application provider"
msgstr "サービスプロバイダー"
#: settings/serializers/auth/oauth2.py:31
@ -6794,7 +6794,7 @@ msgstr ""
"`value` は Slack サービスのユーザー属性名です"
#: settings/serializers/auth/sms.py:18
msgid "Enable Short Message Service (SMS)"
msgid "Enable Short Message Application (SMS)"
msgstr "短信サービスSMSを有効にする"
#: settings/serializers/auth/sms.py:21 xpack/plugins/cloud/models.py:36
@ -6802,7 +6802,7 @@ msgid "Provider"
msgstr "プロバイダー"
#: settings/serializers/auth/sms.py:22
msgid "Short Message Service (SMS) provider or protocol"
msgid "Short Message Application (SMS) provider or protocol"
msgstr "短信サービスSMSのプロバイダーまたはプロトコル"
#: settings/serializers/auth/sms.py:25
@ -6851,7 +6851,7 @@ msgstr "元の番号(Src id)"
#: settings/serializers/auth/sms.py:81
msgid "Business type"
msgstr "ビジネス・タイプ(Service id)"
msgstr "ビジネス・タイプ(Application id)"
#: settings/serializers/auth/sms.py:85
#, python-brace-format
@ -10936,7 +10936,7 @@ msgid "Key File"
msgstr "キーファイル"
#: xpack/plugins/cloud/serializers/account_attrs.py:144
msgid "Service account key"
msgid "Application account key"
msgstr "サービスアカウントキー"
#: xpack/plugins/cloud/serializers/account_attrs.py:145

View File

@ -6519,7 +6519,7 @@ msgid "Logo"
msgstr "图标"
#: settings/serializers/auth/oauth2.py:28
msgid "Service provider"
msgid "Application provider"
msgstr "服务提供商"
#: settings/serializers/auth/oauth2.py:31
@ -6743,7 +6743,7 @@ msgstr ""
"户属性名称"
#: settings/serializers/auth/sms.py:18
msgid "Enable Short Message Service (SMS)"
msgid "Enable Short Message Application (SMS)"
msgstr "启用短信服务 (SMS)"
#: settings/serializers/auth/sms.py:21 xpack/plugins/cloud/models.py:36
@ -6751,7 +6751,7 @@ msgid "Provider"
msgstr "云服务商"
#: settings/serializers/auth/sms.py:22
msgid "Short Message Service (SMS) provider or protocol"
msgid "Short Message Application (SMS) provider or protocol"
msgstr "短信服务 (SMS) 提供商或协议"
#: settings/serializers/auth/sms.py:25
@ -6800,7 +6800,7 @@ msgstr "原始号码(Src id)"
#: settings/serializers/auth/sms.py:81
msgid "Business type"
msgstr "业务类型(Service id)"
msgstr "业务类型(Application id)"
#: settings/serializers/auth/sms.py:85
#, python-brace-format
@ -10820,7 +10820,7 @@ msgid "Key File"
msgstr "密钥文件"
#: xpack/plugins/cloud/serializers/account_attrs.py:144
msgid "Service account key"
msgid "Application account key"
msgstr "服务账号密钥"
#: xpack/plugins/cloud/serializers/account_attrs.py:145

View File

@ -6480,7 +6480,7 @@ msgid "Logo"
msgstr "圖示"
#: settings/serializers/auth/oauth2.py:28
msgid "Service provider"
msgid "Application provider"
msgstr "服務提供商"
#: settings/serializers/auth/oauth2.py:31
@ -6632,7 +6632,7 @@ msgstr "只有 SSL 域名可以使用 Passkey(通行金鑰)認證"
#: settings/serializers/auth/passkey.py:15
msgid "FIDO Server ID"
msgstr "Passkey Service Domain"
msgstr "Passkey Application Domain"
#: settings/serializers/auth/passkey.py:17
msgid ""
@ -6644,7 +6644,7 @@ msgstr ""
#: settings/serializers/auth/passkey.py:22
msgid "FIDO Server name"
msgstr "Passkey Service Name"
msgstr "Passkey Application Name"
#: settings/serializers/auth/radius.py:14
#: settings/serializers/auth/radius.py:16
@ -6704,7 +6704,7 @@ msgstr ""
"務使用者屬性名稱"
#: settings/serializers/auth/sms.py:18
msgid "Enable Short Message Service (SMS)"
msgid "Enable Short Message Application (SMS)"
msgstr "啟用簡訊服務 (SMS)"
#: settings/serializers/auth/sms.py:21 xpack/plugins/cloud/models.py:36
@ -6712,7 +6712,7 @@ msgid "Provider"
msgstr "雲服務商"
#: settings/serializers/auth/sms.py:22
msgid "Short Message Service (SMS) provider or protocol"
msgid "Short Message Application (SMS) provider or protocol"
msgstr "簡訊服務 (SMS) 供應商或協議"
#: settings/serializers/auth/sms.py:25
@ -6761,7 +6761,7 @@ msgstr "原始號碼(Src id)"
#: settings/serializers/auth/sms.py:81
msgid "Business type"
msgstr "業務型態(Service id)"
msgstr "業務型態(Application id)"
#: settings/serializers/auth/sms.py:85
#, python-brace-format
@ -10759,7 +10759,7 @@ msgid "Key File"
msgstr "金鑰文件"
#: xpack/plugins/cloud/serializers/account_attrs.py:144
msgid "Service account key"
msgid "Application account key"
msgstr "服務帳號金鑰"
#: xpack/plugins/cloud/serializers/account_attrs.py:145

View File

@ -9,6 +9,8 @@
"AccessKey": "Access key",
"Account": "Account",
"AccountAmount": "Account amount",
"AccountSessions": "Sessions",
"AccountActivity": "Activity",
"AccountBackup": "Backup accounts",
"AccountBackupCreate": "Create account backup",
"AccountBackupDetail": "Backup account details",
@ -103,7 +105,7 @@
"AppletHosts": "RemoteApp machine",
"Applets": "RemoteApp",
"Applicant": "Applicant",
"Applications": "Assets",
"Applications": "Applications",
"ApplyAsset": "Apply for assets",
"ApplyFromCMDFilterRule": "Command filter rules",
"ApplyFromSession": "Session",
@ -253,6 +255,7 @@
"Certificate": "Certificate",
"CertificateKey": "Client key",
"ChangeCredentials": "Change account secrets",
"ChangeSecret": "Change secrets",
"ChangeCredentialsHelpText": "The secret is the password or key used to connect to the asset. when the secret is changed, the asset will be updated with the new secret",
"ChangeField": "Change field",
"ChangeOrganization": "Change organization",
@ -1086,7 +1089,6 @@
"ServerAccountKey": "Service account key",
"ServerError": "Server error",
"ServerTime": "Server time",
"ServiceIntegration": "Service integration",
"Session": "Session",
"SessionCommands": "Session commands",
"SessionConnectTrend": "Session connection trends",
@ -1216,6 +1218,10 @@
"Task": "Task",
"TaskDetail": "Task details",
"TaskDone": "Task finished",
"RiskDetection": "Risk detection",
"DetectTasks": "Detect tasks",
"DetectResults": "Detect results",
"DetectEngines": "Detect engines",
"TaskID": "Task id",
"TaskList": "Tasks",
"TaskMonitor": "Monitoring",

View File

@ -1121,7 +1121,6 @@
"ServerAccountKey": "サービスアカウントキー",
"ServerError": "サーバーエラー",
"ServerTime": "サーバータイム",
"ServiceIntegration": "サービス統合",
"Session": "コンバセーション",
"SessionCommands": "セッションアクション",
"SessionConnectTrend": "セッションの接続トレンド",

View File

@ -1089,7 +1089,7 @@
"ServerAccountKey": "服务账号密钥",
"ServerError": "服务器错误",
"ServerTime": "服务器时间",
"ServiceIntegration": "服务对接",
"IntegrationApplication": "服务对接",
"Session": "会话",
"SessionCommands": "会话命令",
"SessionConnectTrend": "会话连接趋势",

View File

@ -1439,7 +1439,6 @@
"ServerAccountKey": "服務帳號金鑰",
"ServerError": "伺服器錯誤",
"ServerTime": "伺服器時間",
"ServiceIntegration": "服務對接",
"ServiceRatio": "組件負載統計",
"Session": "會話",
"SessionCommands": "會話指令",

View File

@ -14,7 +14,7 @@ class ComponentI18nApi(RetrieveAPIView):
lang_data = {}
def get_component_translations(self, name):
if name in self.lang_data:
if not settings.DEBUG and name in self.lang_data:
return self.lang_data[name]
component_dir = safe_join(settings.APPS_DIR, 'i18n', name)