diff --git a/admin/src/main/scala/com/neu/model/SystemConfig.scala b/admin/src/main/scala/com/neu/model/SystemConfig.scala
index 2e9b4c026..da8b78194 100644
--- a/admin/src/main/scala/com/neu/model/SystemConfig.scala
+++ b/admin/src/main/scala/com/neu/model/SystemConfig.scala
@@ -16,6 +16,17 @@ case class RegistryHttpsProxyCfg(
password: Option[String]
)
case class Webhook(
+ name: String,
+ url: String,
+ enable: Boolean,
+ use_proxy: Boolean,
+ `type`: String,
+ cfg_type: String,
+ username: Option[String] = None,
+ password: Option[String] = None
+)
+
+case class MaskedWebhook(
name: String,
url: String,
enable: Boolean,
@@ -23,6 +34,7 @@ case class Webhook(
`type`: String,
cfg_type: String
)
+
case class RemoteRepository(
nickname: String,
provider: String,
@@ -186,6 +198,10 @@ case class WebhookConfigWrap(
config: Webhook
)
+case class MaskedWebhookConfigWrap(
+ config: MaskedWebhook
+)
+
case class SystemConfig4DashboardWrap(
config: SystemConfig4Dashboard,
error: Option[Error]
diff --git a/admin/src/main/scala/com/neu/model/SystemConfigJsonProtocol.scala b/admin/src/main/scala/com/neu/model/SystemConfigJsonProtocol.scala
index 4ddc4b59d..b89f61b41 100644
--- a/admin/src/main/scala/com/neu/model/SystemConfigJsonProtocol.scala
+++ b/admin/src/main/scala/com/neu/model/SystemConfigJsonProtocol.scala
@@ -25,7 +25,7 @@ object SystemConfigJsonProtocol extends DefaultJsonProtocol {
given azureDevopsConfigurationFormat: RootJsonFormat[AzureDevopsConfiguration] = jsonFormat5(
AzureDevopsConfiguration.apply
)
- given webhookFormat: RootJsonFormat[Webhook] = jsonFormat6(Webhook.apply)
+ given webhookFormat: RootJsonFormat[Webhook] = jsonFormat8(Webhook.apply)
given remoteRepoFormat: RootJsonFormat[RemoteRepository] = jsonFormat6(RemoteRepository.apply)
given remoteRepositoryWrapFormat: RootJsonFormat[RemoteRepositoryWrap] = jsonFormat1(
RemoteRepositoryWrap.apply
@@ -52,6 +52,11 @@ object SystemConfigJsonProtocol extends DefaultJsonProtocol {
WebhookConfigWrap.apply
)
+ given MaskedWebhookFormat: RootJsonFormat[MaskedWebhook] = jsonFormat6(MaskedWebhook.apply)
+ given MaskedWebhookConfigWrapFormat: RootJsonFormat[MaskedWebhookConfigWrap] = jsonFormat1(
+ MaskedWebhookConfigWrap.apply
+ )
+
given systemConfigSvcCfgV2Format: RootJsonFormat[SystemConfigSvcCfgV2] = jsonFormat3(
SystemConfigSvcCfgV2.apply
)
@@ -104,6 +109,9 @@ object SystemConfigJsonProtocol extends DefaultJsonProtocol {
def webhookConfigWrapToJson(webhookConfigWrap: WebhookConfigWrap): String =
webhookConfigWrap.toJson.compactPrint
+ def maskedWebhookConfigWrapToJson(maskedWebhookConfigWrap: MaskedWebhookConfigWrap): String =
+ maskedWebhookConfigWrap.toJson.compactPrint
+
def remoteRepositoryToJson(remoteRepository: RemoteRepository): String =
remoteRepository.toJson.compactPrint
diff --git a/admin/src/main/scala/com/neu/service/device/DeviceService.scala b/admin/src/main/scala/com/neu/service/device/DeviceService.scala
index 8f1b0ba8a..7852559b7 100644
--- a/admin/src/main/scala/com/neu/service/device/DeviceService.scala
+++ b/admin/src/main/scala/com/neu/service/device/DeviceService.scala
@@ -127,8 +127,21 @@ class DeviceService extends Directives with DefaultJsonFormats with LazyLogging
}
def updateWebhook(tokenId: String, webhook: Webhook, scope: Option[String]): Route = complete {
+ val printedPayload = maskedWebhookConfigWrapToJson(
+ MaskedWebhookConfigWrap(
+ MaskedWebhook(
+ name = webhook.name,
+ url = webhook.url,
+ enable = webhook.enable,
+ use_proxy = webhook.use_proxy,
+ `type` = webhook.`type`,
+ cfg_type = webhook.cfg_type
+ )
+ )
+ )
+ logger.info("Update config: {}", printedPayload)
+
val payload = webhookConfigWrapToJson(WebhookConfigWrap(webhook))
- logger.info("Update config: {}", payload)
RestClient.httpRequestWithHeader(
scope.fold(
diff --git a/admin/webapp/websrc/app/common/neuvector-formly/select/select.component.html b/admin/webapp/websrc/app/common/neuvector-formly/select/select.component.html
index 15f87355f..dd476cac0 100644
--- a/admin/webapp/websrc/app/common/neuvector-formly/select/select.component.html
+++ b/admin/webapp/websrc/app/common/neuvector-formly/select/select.component.html
@@ -1,17 +1,20 @@
-
- {{ field.templateOptions?.label ?? '' | translate }}
-
-
- {{ item.viewValue | translate }}
-
-
-
+
+
+ {{ field.templateOptions?.label ?? '' | translate }}
+
+
+ {{ item.viewValue | translate }}
+
+
+
+
diff --git a/admin/webapp/websrc/app/common/types/settings/config.ts b/admin/webapp/websrc/app/common/types/settings/config.ts
index 74d055179..f11421045 100644
--- a/admin/webapp/websrc/app/common/types/settings/config.ts
+++ b/admin/webapp/websrc/app/common/types/settings/config.ts
@@ -151,6 +151,8 @@ export interface Webhook {
use_proxy: boolean;
type: string;
cfg_type: string;
+ username: string;
+ password: string | null;
isEditable?: boolean;
}
diff --git a/admin/webapp/websrc/app/routes/components/federated-policy-configuration/federated-config-form/types/constants/webhook-constants.ts b/admin/webapp/websrc/app/routes/components/federated-policy-configuration/federated-config-form/types/constants/webhook-constants.ts
index 03f56c081..5d4223d0f 100644
--- a/admin/webapp/websrc/app/routes/components/federated-policy-configuration/federated-config-form/types/constants/webhook-constants.ts
+++ b/admin/webapp/websrc/app/routes/components/federated-policy-configuration/federated-config-form/types/constants/webhook-constants.ts
@@ -110,6 +110,42 @@ export const WebhookTableField = {
},
},
},
+ {
+ key: 'username',
+ wrappers: [FormlyComponents.READONLY_WRAPPER],
+ type: FormlyComponents.ICON_INPUT,
+ templateOptions: {
+ viewValue: 'login.USERNAME',
+ placeholder: 'login.USERNAME',
+ isCell: true,
+ required: false,
+ hideRequiredMarker: true,
+ maxLength: 1000,
+ },
+ validators: {
+ validation: [FormlyValidators.ObjName],
+ },
+ expressionProperties: {
+ 'templateOptions.disabled': model => {
+ return !model.isEditable;
+ },
+ },
+ },
+ {
+ key: 'password',
+ type: FormlyComponents.ICON_INPUT,
+ templateOptions: {
+ viewValue: 'login.PASSWORD',
+ isCell: true,
+ maxLength: 1000,
+ type: 'password',
+ },
+ expressionProperties: {
+ 'templateOptions.disabled': model => {
+ return !model.isEditable;
+ },
+ },
+ },
{
key: 'use_proxy',
type: FormlyComponents.CHECKBOX,
diff --git a/admin/webapp/websrc/app/routes/settings/configuration/config-form/config-form-config/constants/webhook-constants.ts b/admin/webapp/websrc/app/routes/settings/configuration/config-form/config-form-config/constants/webhook-constants.ts
index a5d6bda53..6304f9d24 100644
--- a/admin/webapp/websrc/app/routes/settings/configuration/config-form/config-form-config/constants/webhook-constants.ts
+++ b/admin/webapp/websrc/app/routes/settings/configuration/config-form/config-form-config/constants/webhook-constants.ts
@@ -73,6 +73,7 @@ export const WebhookTableField = {
templateOptions: {
viewValue: 'setting.webhook.WH_TYPE',
placeholder: 'setting.webhook.WH_TYPE',
+ isCell: true,
items: WebhookTypes,
required: true,
hideRequiredMarker: true,
@@ -112,6 +113,48 @@ export const WebhookTableField = {
},
},
},
+ {
+ key: 'username',
+ wrappers: [FormlyComponents.READONLY_WRAPPER],
+ type: FormlyComponents.ICON_INPUT,
+ templateOptions: {
+ viewValue: 'login.USERNAME',
+ placeholder: 'login.USERNAME',
+ isCell: true,
+ required: false,
+ hideRequiredMarker: true,
+ maxLength: 1000,
+ },
+ validators: {
+ validation: [FormlyValidators.ObjName],
+ },
+ expressionProperties: {
+ 'templateOptions.disabled': (model, formState) => {
+ return (
+ !formState.permissions.isWebhookAuthorized ||
+ model.cfg_type === GlobalConstant.CFG_TYPE.FED
+ );
+ },
+ },
+ },
+ {
+ key: 'password',
+ type: FormlyComponents.ICON_INPUT,
+ templateOptions: {
+ viewValue: 'login.PASSWORD',
+ isCell: true,
+ maxLength: 1000,
+ type: 'password',
+ },
+ expressionProperties: {
+ 'templateOptions.disabled': (model, formState) => {
+ return (
+ !formState.permissions.isWebhookAuthorized ||
+ model.cfg_type === GlobalConstant.CFG_TYPE.FED
+ );
+ },
+ },
+ },
{
key: 'use_proxy',
type: FormlyComponents.CHECKBOX,
diff --git a/admin/webapp/websrc/app/routes/settings/configuration/config-form/config-form.component.ts b/admin/webapp/websrc/app/routes/settings/configuration/config-form/config-form.component.ts
index f0101ad27..a194b31f6 100644
--- a/admin/webapp/websrc/app/routes/settings/configuration/config-form/config-form.component.ts
+++ b/admin/webapp/websrc/app/routes/settings/configuration/config-form/config-form.component.ts
@@ -216,6 +216,9 @@ export class ConfigFormComponent implements OnInit, OnDestroy {
this.updateWebhookValueChanges();
this.notificationService.open(this.tr.instant('setting.SUBMIT_OK'));
+ this._config.webhooks.forEach(webhook => {
+ webhook.password = '';
+ });
this.configOptions.resetModel?.(this._config);
setTimeout(() => this.configOptions.resetModel?.(this._config));
},
diff --git a/admin/webapp/websrc/app/routes/settings/configuration/remote-repository-form/remote-repository-form-config/index.ts b/admin/webapp/websrc/app/routes/settings/configuration/remote-repository-form/remote-repository-form-config/index.ts
index 80065fb6a..9c025b0f8 100644
--- a/admin/webapp/websrc/app/routes/settings/configuration/remote-repository-form/remote-repository-form-config/index.ts
+++ b/admin/webapp/websrc/app/routes/settings/configuration/remote-repository-form/remote-repository-form-config/index.ts
@@ -8,7 +8,7 @@ export const RemoteRepoFormConfig: FormlyFieldConfig[] = [
fieldGroupClassName: 'row',
fieldGroup: [
{
- className: 'col-12 col-md-6 mt-2',
+ className: 'col-12 col-md-6',
...ProviderField,
},
{