From 9c846830720d9bde4891c80cff86b338b6de93e2 Mon Sep 17 00:00:00 2001 From: weizhile <348358584@qq.com> Date: Thu, 2 Nov 2023 01:42:19 +0800 Subject: [PATCH 1/8] Fix serious appendDataInfluence bug in AuditSpanAspect. Add patch of dealing with collection-type arg when AOP capturing input parameter for "AnyMatched". --- .../apollo/audit/aop/ApolloAuditSpanAspect.java | 16 +++++++++++++--- .../component/ApolloAuditLogApiJpaImpl.java | 2 +- .../component/ApolloAuditLogApiJpaImplTest.java | 2 +- 3 files changed, 15 insertions(+), 5 deletions(-) diff --git a/apollo-audit/apollo-audit-impl/src/main/java/com/ctrip/framework/apollo/audit/aop/ApolloAuditSpanAspect.java b/apollo-audit/apollo-audit-impl/src/main/java/com/ctrip/framework/apollo/audit/aop/ApolloAuditSpanAspect.java index 535a07dfda6..d8e1b80c72e 100644 --- a/apollo-audit/apollo-audit-impl/src/main/java/com/ctrip/framework/apollo/audit/aop/ApolloAuditSpanAspect.java +++ b/apollo-audit/apollo-audit-impl/src/main/java/com/ctrip/framework/apollo/audit/aop/ApolloAuditSpanAspect.java @@ -24,7 +24,8 @@ import java.lang.annotation.Annotation; import java.lang.reflect.Method; import java.util.Arrays; -import java.util.Objects; +import java.util.Collection; +import java.util.Iterator; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; @@ -72,8 +73,17 @@ public Object around(ProceedingJoinPoint pjp, ApolloAuditLog auditLog) throws Th } } if (entityName != null && fieldName != null) { - String matchedValue = String.valueOf(arg); - api.appendDataInfluence("AnyMatched", entityName, fieldName, matchedValue); + // if arg is a collection + if (arg instanceof Collection) { + for (Object o : ((Collection) arg).toArray()) { + String matchedValue = String.valueOf(o); + api.appendDataInfluence(entityName, "AnyMatched", fieldName, matchedValue); + } + } + else { + String matchedValue = String.valueOf(arg); + api.appendDataInfluence(entityName, "AnyMatched", fieldName, matchedValue); + } } } } diff --git a/apollo-audit/apollo-audit-impl/src/main/java/com/ctrip/framework/apollo/audit/component/ApolloAuditLogApiJpaImpl.java b/apollo-audit/apollo-audit-impl/src/main/java/com/ctrip/framework/apollo/audit/component/ApolloAuditLogApiJpaImpl.java index d7c1baab2a4..7bb3f95cc70 100644 --- a/apollo-audit/apollo-audit-impl/src/main/java/com/ctrip/framework/apollo/audit/component/ApolloAuditLogApiJpaImpl.java +++ b/apollo-audit/apollo-audit-impl/src/main/java/com/ctrip/framework/apollo/audit/component/ApolloAuditLogApiJpaImpl.java @@ -106,7 +106,7 @@ public void appendDataInfluences(List entities, Class beanDefinition) f.setAccessible(true); String val = String.valueOf(f.get(e)); String fieldName = f.getAnnotation(ApolloAuditLogDataInfluenceTableField.class).fieldName(); - appendDataInfluence(tableId, tableName, fieldName, val); + appendDataInfluence(tableName, tableId, fieldName, val); } } catch (IllegalAccessException ex) { throw new IllegalArgumentException("failed append data influence, " diff --git a/apollo-audit/apollo-audit-impl/src/test/java/com/ctrip/framework/apollo/audit/component/ApolloAuditLogApiJpaImplTest.java b/apollo-audit/apollo-audit-impl/src/test/java/com/ctrip/framework/apollo/audit/component/ApolloAuditLogApiJpaImplTest.java index f1ddd8e8f30..728b9689712 100644 --- a/apollo-audit/apollo-audit-impl/src/test/java/com/ctrip/framework/apollo/audit/component/ApolloAuditLogApiJpaImplTest.java +++ b/apollo-audit/apollo-audit-impl/src/test/java/com/ctrip/framework/apollo/audit/component/ApolloAuditLogApiJpaImplTest.java @@ -185,7 +185,7 @@ public void testAppendDataInfluences() { api.appendDataInfluences(entities, MockDataInfluenceEntity.class); Mockito.verify(api, Mockito.times(entityNum)) - .appendDataInfluence(Mockito.anyString(), Mockito.eq("MockTableName"), Mockito.eq("MarkedAttribute"), + .appendDataInfluence(Mockito.eq("MockTableName"), Mockito.any(), Mockito.eq("MarkedAttribute"), Mockito.any()); } From 783df07a4b58c7dbe0f0b50870d27321d0b7bdf0 Mon Sep 17 00:00:00 2001 From: weizhile <348358584@qq.com> Date: Thu, 2 Nov 2023 08:39:51 +0800 Subject: [PATCH 2/8] Fix front-end bugs. --- .../static/audit_log_trace_detail.html | 18 +++++++++--------- .../AuditLogTraceDetailController.js | 13 ++++++++++--- 2 files changed, 19 insertions(+), 12 deletions(-) diff --git a/apollo-portal/src/main/resources/static/audit_log_trace_detail.html b/apollo-portal/src/main/resources/static/audit_log_trace_detail.html index f66bc60b213..3721dff8ebb 100644 --- a/apollo-portal/src/main/resources/static/audit_log_trace_detail.html +++ b/apollo-portal/src/main/resources/static/audit_log_trace_detail.html @@ -99,31 +99,31 @@

- {{'ApolloAuditLog.DataInfluence.EntityName' | translate}}: {{dataInfluenceEntity[0].name}} + {{'ApolloAuditLog.DataInfluence.EntityName' | translate}}: {{dataInfluenceEntity[1].name}}
-
- {{'ApolloAuditLog.DataInfluence.EntityId' | translate}}: {{dataInfluenceEntity[0].id}} +
+ {{'ApolloAuditLog.DataInfluence.EntityId' | translate}}: {{dataInfluenceEntity[1].id}}
-
+
{{'ApolloAuditLog.DataInfluence.AnyMatchedEntityId' | translate}}

-
+
{{'ApolloAuditLog.DataInfluence.Fields' | translate}}:
-
+
{{'ApolloAuditLog.DataInfluence.MatchedFields' | translate}}:
-
+ ng-show="dataInfluenceEntity[1].id != 'AnyMatched'"> {{dataInfluence.fieldName}} ==> {{dataInfluence.fieldNewValue}}
+ ng-show="dataInfluenceEntity[1].id == 'AnyMatched'"> {{dataInfluence.fieldName}} <== {{showingDetail.logDTO.opType == 'DELETE' ? dataInfluence.fieldOldValue : dataInfluence.fieldNewValue}}
diff --git a/apollo-portal/src/main/resources/static/scripts/controller/AuditLogTraceDetailController.js b/apollo-portal/src/main/resources/static/scripts/controller/AuditLogTraceDetailController.js index 43b56f196a1..ad8e71fa4c4 100644 --- a/apollo-portal/src/main/resources/static/scripts/controller/AuditLogTraceDetailController.js +++ b/apollo-portal/src/main/resources/static/scripts/controller/AuditLogTraceDetailController.js @@ -136,12 +136,19 @@ function auditLogTraceDetailController($scope, $location, $window, $translate, t name: dto.influenceEntityName, id: dto.influenceEntityId }; - if (!entityMap.has(key)) { - entityMap.set(key, []); + var keyString = JSON.stringify(key); + var value = { + name: dto.influenceEntityName, + id: dto.influenceEntityId, + dtoList: [] + }; + if (!entityMap.has(keyString)) { + entityMap.set(keyString, value); } - entityMap.get(key).push(dto); + entityMap.get(keyString).dtoList.push(dto); }); $scope.dataInfluenceEntities = Array.from(entityMap); + console.log($scope.dataInfluenceEntities); } function showText(text) { From e82ddd834458866c731d502ad15331fa06974268 Mon Sep 17 00:00:00 2001 From: weizhile <348358584@qq.com> Date: Thu, 2 Nov 2023 21:04:05 +0800 Subject: [PATCH 3/8] Fix front-end bugs and Enhance front-end styles. --- .../apollo/audit/component/ApolloAuditLogApiJpaImpl.java | 3 +++ .../src/main/resources/static/audit_log_trace_detail.html | 8 ++++++-- .../scripts/controller/AuditLogTraceDetailController.js | 1 - 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/apollo-audit/apollo-audit-impl/src/main/java/com/ctrip/framework/apollo/audit/component/ApolloAuditLogApiJpaImpl.java b/apollo-audit/apollo-audit-impl/src/main/java/com/ctrip/framework/apollo/audit/component/ApolloAuditLogApiJpaImpl.java index 7bb3f95cc70..742fe593222 100644 --- a/apollo-audit/apollo-audit-impl/src/main/java/com/ctrip/framework/apollo/audit/component/ApolloAuditLogApiJpaImpl.java +++ b/apollo-audit/apollo-audit-impl/src/main/java/com/ctrip/framework/apollo/audit/component/ApolloAuditLogApiJpaImpl.java @@ -78,6 +78,9 @@ public void appendDataInfluence(String entityName, String entityId, String field OpType type = traceContext.tracer().getActiveSpan().getOpType(); ApolloAuditLogDataInfluence.Builder builder = ApolloAuditLogDataInfluence.builder().spanId(spanId) .entityName(entityName).entityId(entityId).fieldName(fieldName); + if (type == null) { + return; + } switch (type) { case CREATE: case UPDATE: diff --git a/apollo-portal/src/main/resources/static/audit_log_trace_detail.html b/apollo-portal/src/main/resources/static/audit_log_trace_detail.html index 3721dff8ebb..2fd446b479f 100644 --- a/apollo-portal/src/main/resources/static/audit_log_trace_detail.html +++ b/apollo-portal/src/main/resources/static/audit_log_trace_detail.html @@ -119,9 +119,13 @@

class="cursor-pointer" ng-click="showRelatedDataInfluence(dataInfluence.influenceEntityName,dataInfluence.influenceEntityId,dataInfluence.fieldName)">
+ ng-show="dataInfluenceEntity[1].id != 'AnyMatched' && dataInfluence.fieldNewValue"> {{dataInfluence.fieldName}} ==> {{dataInfluence.fieldNewValue}}
+
+ {{dataInfluence.fieldName}} : {{dataInfluence.fieldOldValue}} ==> (deleted) +
{{dataInfluence.fieldName}} <== @@ -158,7 +162,7 @@

- {{ di.fieldNewValue }} + {{ di.fieldNewValue ? di.fieldNewValue : '(deleted)' }} {{ di.happenedTime | date: 'yyyy-MM-dd HH:mm:ss' }} diff --git a/apollo-portal/src/main/resources/static/scripts/controller/AuditLogTraceDetailController.js b/apollo-portal/src/main/resources/static/scripts/controller/AuditLogTraceDetailController.js index ad8e71fa4c4..b2887964bce 100644 --- a/apollo-portal/src/main/resources/static/scripts/controller/AuditLogTraceDetailController.js +++ b/apollo-portal/src/main/resources/static/scripts/controller/AuditLogTraceDetailController.js @@ -148,7 +148,6 @@ function auditLogTraceDetailController($scope, $location, $window, $translate, t entityMap.get(keyString).dtoList.push(dto); }); $scope.dataInfluenceEntities = Array.from(entityMap); - console.log($scope.dataInfluenceEntities); } function showText(text) { From 4d7d6d680cf88ac8a0ff88ced61632f2d502d144 Mon Sep 17 00:00:00 2001 From: weizhile <348358584@qq.com> Date: Thu, 2 Nov 2023 21:49:08 +0800 Subject: [PATCH 4/8] rawly implement basic needs in issue --- .../apollo/audit/aop/ApolloAuditSpanAspect.java | 1 - .../apollo/biz/service/AppNamespaceService.java | 3 +++ .../apollo/portal/api/AdminServiceAPI.java | 8 +++++++- .../apollo/portal/controller/AppController.java | 5 +++-- .../portal/controller/ClusterController.java | 4 ++++ .../portal/controller/NamespaceController.java | 7 +++++++ .../portal/controller/PermissionController.java | 13 +++++++++++++ .../framework/apollo/portal/entity/po/Role.java | 4 ++++ .../apollo/portal/entity/po/UserRole.java | 5 +++++ .../DefaultRoleInitializationService.java | 8 ++++++++ .../defaultimpl/DefaultRolePermissionService.java | 15 ++++++++++++++- 11 files changed, 68 insertions(+), 5 deletions(-) diff --git a/apollo-audit/apollo-audit-impl/src/main/java/com/ctrip/framework/apollo/audit/aop/ApolloAuditSpanAspect.java b/apollo-audit/apollo-audit-impl/src/main/java/com/ctrip/framework/apollo/audit/aop/ApolloAuditSpanAspect.java index d8e1b80c72e..04ecc223bfe 100644 --- a/apollo-audit/apollo-audit-impl/src/main/java/com/ctrip/framework/apollo/audit/aop/ApolloAuditSpanAspect.java +++ b/apollo-audit/apollo-audit-impl/src/main/java/com/ctrip/framework/apollo/audit/aop/ApolloAuditSpanAspect.java @@ -25,7 +25,6 @@ import java.lang.reflect.Method; import java.util.Arrays; import java.util.Collection; -import java.util.Iterator; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; diff --git a/apollo-biz/src/main/java/com/ctrip/framework/apollo/biz/service/AppNamespaceService.java b/apollo-biz/src/main/java/com/ctrip/framework/apollo/biz/service/AppNamespaceService.java index 66d7bb63b08..27a16ed326d 100644 --- a/apollo-biz/src/main/java/com/ctrip/framework/apollo/biz/service/AppNamespaceService.java +++ b/apollo-biz/src/main/java/com/ctrip/framework/apollo/biz/service/AppNamespaceService.java @@ -16,6 +16,8 @@ */ package com.ctrip.framework.apollo.biz.service; +import com.ctrip.framework.apollo.audit.annotation.ApolloAuditLog; +import com.ctrip.framework.apollo.audit.annotation.OpType; import com.ctrip.framework.apollo.biz.entity.Audit; import com.ctrip.framework.apollo.biz.entity.Cluster; import com.ctrip.framework.apollo.biz.entity.Namespace; @@ -102,6 +104,7 @@ public List findByAppIdAndNamespaces(String appId, Set nam } @Transactional + @ApolloAuditLog(type = OpType.CREATE, name = "AppNamespace.createDefault") public void createDefaultAppNamespace(String appId, String createBy) { if (!isAppNamespaceNameUnique(appId, ConfigConsts.NAMESPACE_APPLICATION)) { throw new ServiceException("appnamespace not unique"); diff --git a/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/api/AdminServiceAPI.java b/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/api/AdminServiceAPI.java index fcd46a32fa1..5e192284a1b 100644 --- a/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/api/AdminServiceAPI.java +++ b/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/api/AdminServiceAPI.java @@ -118,17 +118,20 @@ public NamespaceDTO findPublicNamespaceForAssociatedNamespace(Env env, String ap NamespaceDTO.class, appId, clusterName, namespaceName); } + @ApolloAuditLog(type = OpType.RPC, name = "Namespace.createInRemote") public NamespaceDTO createNamespace(Env env, NamespaceDTO namespace) { return restTemplate .post(env, "apps/{appId}/clusters/{clusterName}/namespaces", namespace, NamespaceDTO.class, namespace.getAppId(), namespace.getClusterName()); } + @ApolloAuditLog(type = OpType.RPC, name = "AppNamespace.createInRemote") public AppNamespaceDTO createAppNamespace(Env env, AppNamespaceDTO appNamespace) { return restTemplate .post(env, "apps/{appId}/appnamespaces", appNamespace, AppNamespaceDTO.class, appNamespace.getAppId()); } + @ApolloAuditLog(type = OpType.RPC, name = "AppNamespace.createMissingAppNamespaceInRemote") public AppNamespaceDTO createMissingAppNamespace(Env env, AppNamespaceDTO appNamespace) { return restTemplate .post(env, "apps/{appId}/appnamespaces?silentCreation=true", appNamespace, AppNamespaceDTO.class, @@ -140,6 +143,7 @@ public List getAppNamespaces(String appId, Env env) { return Arrays.asList(appNamespaceDTOs); } + @ApolloAuditLog(type = OpType.RPC, name = "Namespace.deleteInRemote") public void deleteNamespace(Env env, String appId, String clusterName, String namespaceName, String operator) { restTemplate .delete(env, "apps/{appId}/clusters/{clusterName}/namespaces/{namespaceName}?operator={operator}", appId, @@ -167,6 +171,7 @@ public int countPublicAppNamespaceAssociatedNamespaces(Env env, String publicNam return count == null ? 0 : count; } + @ApolloAuditLog(type = OpType.RPC, name = "AppNamespace.deleteInRemote") public void deleteAppNamespace(Env env, String appId, String namespaceName, String operator) { restTemplate.delete(env, "/apps/{appId}/appnamespaces/{namespaceName}?operator={operator}", appId, namespaceName, operator); @@ -266,12 +271,13 @@ public boolean isClusterUnique(String appId, Env env, String clusterName) { } + @ApolloAuditLog(type = OpType.RPC, name = "Cluster.createInRemote") public ClusterDTO create(Env env, ClusterDTO cluster) { return restTemplate.post(env, "apps/{appId}/clusters", cluster, ClusterDTO.class, cluster.getAppId()); } - + @ApolloAuditLog(type = OpType.RPC, name = "Cluster.deleteInRemote") public void delete(Env env, String appId, String clusterName, String operator) { restTemplate.delete(env, "apps/{appId}/clusters/{clusterName}?operator={operator}", appId, clusterName, operator); } diff --git a/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/controller/AppController.java b/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/controller/AppController.java index 1a171b5bb50..7e96c9923cf 100644 --- a/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/controller/AppController.java +++ b/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/controller/AppController.java @@ -121,7 +121,7 @@ public List findAppsByOwner(@RequestParam("owner") String owner, Pageable p @PreAuthorize(value = "@permissionValidator.hasCreateApplicationPermission()") @PostMapping - @ApolloAuditLog(type = OpType.CREATE) + @ApolloAuditLog(type = OpType.CREATE, name = "App.create.request") public App create(@Valid @RequestBody AppModel appModel) { App app = transformToApp(appModel); @@ -130,7 +130,7 @@ public App create(@Valid @RequestBody AppModel appModel) { @PreAuthorize(value = "@permissionValidator.isAppAdmin(#appId)") @PutMapping("/{appId:.+}") - @ApolloAuditLog(type = OpType.UPDATE) + @ApolloAuditLog(type = OpType.UPDATE, name = "App.update.request") public void update(@PathVariable String appId, @Valid @RequestBody AppModel appModel) { if (!Objects.equals(appId, appModel.getAppId())) { throw new BadRequestException("The App Id of path variable and request body is different"); @@ -161,6 +161,7 @@ public MultiResponseEntity nav(@PathVariable String appId) { } @PostMapping(value = "/envs/{env}", consumes = {"application/json"}) + @ApolloAuditLog(type = OpType.CREATE, name = "App.create.forEnv") public ResponseEntity create(@PathVariable String env, @Valid @RequestBody App app) { appService.createAppInRemote(Env.valueOf(env), app); diff --git a/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/controller/ClusterController.java b/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/controller/ClusterController.java index 27c2306509b..9e8e1ab178f 100644 --- a/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/controller/ClusterController.java +++ b/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/controller/ClusterController.java @@ -16,6 +16,8 @@ */ package com.ctrip.framework.apollo.portal.controller; +import com.ctrip.framework.apollo.audit.annotation.ApolloAuditLog; +import com.ctrip.framework.apollo.audit.annotation.OpType; import com.ctrip.framework.apollo.common.dto.ClusterDTO; import com.ctrip.framework.apollo.portal.environment.Env; import com.ctrip.framework.apollo.portal.service.ClusterService; @@ -44,6 +46,7 @@ public ClusterController(final ClusterService clusterService, final UserInfoHold @PreAuthorize(value = "@permissionValidator.hasCreateClusterPermission(#appId)") @PostMapping(value = "apps/{appId}/envs/{env}/clusters") + @ApolloAuditLog(type = OpType.CREATE, name = "Cluster.create.request") public ClusterDTO createCluster(@PathVariable String appId, @PathVariable String env, @Valid @RequestBody ClusterDTO cluster) { String operator = userInfoHolder.getUser().getUserId(); @@ -55,6 +58,7 @@ public ClusterDTO createCluster(@PathVariable String appId, @PathVariable String @PreAuthorize(value = "@permissionValidator.isSuperAdmin()") @DeleteMapping(value = "apps/{appId}/envs/{env}/clusters/{clusterName:.+}") + @ApolloAuditLog(type = OpType.DELETE, name = "Cluster.delete.request") public ResponseEntity deleteCluster(@PathVariable String appId, @PathVariable String env, @PathVariable String clusterName){ clusterService.deleteCluster(Env.valueOf(env), appId, clusterName); diff --git a/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/controller/NamespaceController.java b/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/controller/NamespaceController.java index c3bbbcadad8..6a29a2f5f0d 100644 --- a/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/controller/NamespaceController.java +++ b/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/controller/NamespaceController.java @@ -16,6 +16,8 @@ */ package com.ctrip.framework.apollo.portal.controller; +import com.ctrip.framework.apollo.audit.annotation.ApolloAuditLog; +import com.ctrip.framework.apollo.audit.annotation.OpType; import com.ctrip.framework.apollo.common.dto.AppNamespaceDTO; import com.ctrip.framework.apollo.common.dto.NamespaceDTO; import com.ctrip.framework.apollo.common.entity.AppNamespace; @@ -141,6 +143,7 @@ public NamespaceBO findPublicNamespaceForAssociatedNamespace(@PathVariable Strin @PreAuthorize(value = "@permissionValidator.hasCreateNamespacePermission(#appId)") @PostMapping("/apps/{appId}/namespaces") + @ApolloAuditLog(type = OpType.CREATE, name = "Namespace.create") public ResponseEntity createNamespace(@PathVariable String appId, @RequestBody List models) { @@ -171,6 +174,7 @@ public ResponseEntity createNamespace(@PathVariable String appId, @PreAuthorize(value = "@permissionValidator.hasDeleteNamespacePermission(#appId)") @DeleteMapping("/apps/{appId}/envs/{env}/clusters/{clusterName}/linked-namespaces/{namespaceName:.+}") + @ApolloAuditLog(type = OpType.DELETE, name = "Namespace.deleteLinkedNamespace") public ResponseEntity deleteLinkedNamespace(@PathVariable String appId, @PathVariable String env, @PathVariable String clusterName, @PathVariable String namespaceName) { @@ -193,6 +197,7 @@ public List findNamespaceUsage(@PathVariable String appId, @Path @PreAuthorize(value = "@permissionValidator.hasDeleteNamespacePermission(#appId)") @DeleteMapping("/apps/{appId}/appnamespaces/{namespaceName:.+}") + @ApolloAuditLog(type = OpType.DELETE, name = "AppNamespace.delete") public ResponseEntity deleteAppNamespace(@PathVariable String appId, @PathVariable String namespaceName) { AppNamespace appNamespace = appNamespaceService.deleteAppNamespace(appId, namespaceName); @@ -215,6 +220,7 @@ public AppNamespaceDTO findAppNamespace(@PathVariable String appId, @PathVariabl @PreAuthorize(value = "@permissionValidator.hasCreateAppNamespacePermission(#appId, #appNamespace)") @PostMapping("/apps/{appId}/appnamespaces") + @ApolloAuditLog(type = OpType.CREATE, name = "AppNamespace.create") public AppNamespace createAppNamespace(@PathVariable String appId, @RequestParam(defaultValue = "true") boolean appendNamespacePrefix, @Valid @RequestBody AppNamespace appNamespace) { @@ -272,6 +278,7 @@ public MultiResponseEntity findMissingNamespaces(@PathVariable String ap } @PostMapping("/apps/{appId}/envs/{env}/clusters/{clusterName}/missing-namespaces") + @ApolloAuditLog(type = OpType.CREATE, name = "Namespace.createMissingNamespaces") public ResponseEntity createMissingNamespaces(@PathVariable String appId, @PathVariable String env, @PathVariable String clusterName) { Set missingNamespaces = findMissingNamespaceNames(appId, env, clusterName); diff --git a/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/controller/PermissionController.java b/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/controller/PermissionController.java index 9cb4eb54ca8..bdcc2932ae7 100644 --- a/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/controller/PermissionController.java +++ b/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/controller/PermissionController.java @@ -16,6 +16,8 @@ */ package com.ctrip.framework.apollo.portal.controller; +import com.ctrip.framework.apollo.audit.annotation.ApolloAuditLog; +import com.ctrip.framework.apollo.audit.annotation.OpType; import com.ctrip.framework.apollo.common.exception.BadRequestException; import com.ctrip.framework.apollo.common.utils.RequestPrecondition; import com.ctrip.framework.apollo.portal.component.PermissionValidator; @@ -73,6 +75,7 @@ public PermissionController( } @PostMapping("/apps/{appId}/initPermission") + @ApolloAuditLog(type = OpType.CREATE, name = "Auth.initAppPermission") public ResponseEntity initAppPermission(@PathVariable String appId, @RequestBody String namespaceName) { roleInitializationService.initNamespaceEnvRoles(appId, namespaceName, userInfoHolder.getUser().getUserId()); return ResponseEntity.ok().build(); @@ -148,6 +151,7 @@ public NamespaceEnvRolesAssignedUsers getNamespaceEnvRoles(@PathVariable String @PreAuthorize(value = "@permissionValidator.hasAssignRolePermission(#appId)") @PostMapping("/apps/{appId}/envs/{env}/namespaces/{namespaceName}/roles/{roleType}") + @ApolloAuditLog(type = OpType.CREATE, name = "Auth.assignNamespaceEnvRoleToUser") public ResponseEntity assignNamespaceEnvRoleToUser(@PathVariable String appId, @PathVariable String env, @PathVariable String namespaceName, @PathVariable String roleType, @RequestBody String user) { checkUserExists(user); @@ -172,6 +176,7 @@ public ResponseEntity assignNamespaceEnvRoleToUser(@PathVariable String ap @PreAuthorize(value = "@permissionValidator.hasAssignRolePermission(#appId)") @DeleteMapping("/apps/{appId}/envs/{env}/namespaces/{namespaceName}/roles/{roleType}") + @ApolloAuditLog(type = OpType.DELETE, name = "Auth.removeNamespaceEnvRoleFromUser") public ResponseEntity removeNamespaceEnvRoleFromUser(@PathVariable String appId, @PathVariable String env, @PathVariable String namespaceName, @PathVariable String roleType, @RequestParam String user) { RequestPrecondition.checkArgumentsNotEmpty(user); @@ -208,6 +213,7 @@ public NamespaceRolesAssignedUsers getNamespaceRoles(@PathVariable String appId, @PreAuthorize(value = "@permissionValidator.hasAssignRolePermission(#appId)") @PostMapping("/apps/{appId}/namespaces/{namespaceName}/roles/{roleType}") + @ApolloAuditLog(type = OpType.CREATE, name = "Auth.assignNamespaceRoleToUser") public ResponseEntity assignNamespaceRoleToUser(@PathVariable String appId, @PathVariable String namespaceName, @PathVariable String roleType, @RequestBody String user) { checkUserExists(user); @@ -227,6 +233,7 @@ public ResponseEntity assignNamespaceRoleToUser(@PathVariable String appId @PreAuthorize(value = "@permissionValidator.hasAssignRolePermission(#appId)") @DeleteMapping("/apps/{appId}/namespaces/{namespaceName}/roles/{roleType}") + @ApolloAuditLog(type = OpType.DELETE, name = "Auth.removeNamespaceRoleFromUser") public ResponseEntity removeNamespaceRoleFromUser(@PathVariable String appId, @PathVariable String namespaceName, @PathVariable String roleType, @RequestParam String user) { RequestPrecondition.checkArgumentsNotEmpty(user); @@ -252,6 +259,7 @@ public AppRolesAssignedUsers getAppRoles(@PathVariable String appId) { @PreAuthorize(value = "@permissionValidator.hasManageAppMasterPermission(#appId)") @PostMapping("/apps/{appId}/roles/{roleType}") + @ApolloAuditLog(type = OpType.CREATE, name = "Auth.assignAppRoleToUser") public ResponseEntity assignAppRoleToUser(@PathVariable String appId, @PathVariable String roleType, @RequestBody String user) { checkUserExists(user); @@ -271,6 +279,7 @@ public ResponseEntity assignAppRoleToUser(@PathVariable String appId, @Pat @PreAuthorize(value = "@permissionValidator.hasManageAppMasterPermission(#appId)") @DeleteMapping("/apps/{appId}/roles/{roleType}") + @ApolloAuditLog(type = OpType.DELETE, name = "Auth.removeAppRoleFromUser") public ResponseEntity removeAppRoleFromUser(@PathVariable String appId, @PathVariable String roleType, @RequestParam String user) { RequestPrecondition.checkArgumentsNotEmpty(user); @@ -291,6 +300,7 @@ private void checkUserExists(String userId) { @PreAuthorize(value = "@permissionValidator.isSuperAdmin()") @PostMapping("/system/role/createApplication") + @ApolloAuditLog(type = OpType.CREATE, name = "Auth.addCreateApplicationRoleToUser") public ResponseEntity addCreateApplicationRoleToUser(@RequestBody List userIds) { userIds.forEach(this::checkUserExists); @@ -302,6 +312,7 @@ public ResponseEntity addCreateApplicationRoleToUser(@RequestBody List deleteCreateApplicationRoleFromUser(@PathVariable("userId") String userId) { checkUserExists(userId); Set userIds = new HashSet<>(); @@ -327,6 +338,7 @@ public JsonObject hasCreateApplicationPermission(@PathVariable String userId) { @PreAuthorize(value = "@permissionValidator.isSuperAdmin()") @PostMapping("/apps/{appId}/system/master/{userId}") + @ApolloAuditLog(type = OpType.CREATE, name = "Auth.addManageAppMasterRoleToUser") public ResponseEntity addManageAppMasterRoleToUser(@PathVariable String appId, @PathVariable String userId) { checkUserExists(userId); roleInitializationService.initManageAppMasterRole(appId, userInfoHolder.getUser().getUserId()); @@ -339,6 +351,7 @@ public ResponseEntity addManageAppMasterRoleToUser(@PathVariable String ap @PreAuthorize(value = "@permissionValidator.isSuperAdmin()") @DeleteMapping("/apps/{appId}/system/master/{userId}") + @ApolloAuditLog(type = OpType.DELETE, name = "Auth.forbidManageAppMaster") public ResponseEntity forbidManageAppMaster(@PathVariable String appId, @PathVariable String userId) { checkUserExists(userId); roleInitializationService.initManageAppMasterRole(appId, userInfoHolder.getUser().getUserId()); diff --git a/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/entity/po/Role.java b/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/entity/po/Role.java index 6c2bb2cd687..29a0b1b542e 100644 --- a/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/entity/po/Role.java +++ b/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/entity/po/Role.java @@ -16,6 +16,8 @@ */ package com.ctrip.framework.apollo.portal.entity.po; +import com.ctrip.framework.apollo.audit.annotation.ApolloAuditLogDataInfluenceTable; +import com.ctrip.framework.apollo.audit.annotation.ApolloAuditLogDataInfluenceTableField; import com.ctrip.framework.apollo.common.entity.BaseEntity; import org.hibernate.annotations.SQLDelete; @@ -32,7 +34,9 @@ @Table(name = "`Role`") @SQLDelete(sql = "Update Role set IsDeleted = true, DeletedAt = ROUND(UNIX_TIMESTAMP(NOW(4))*1000) where Id = ?") @Where(clause = "`IsDeleted` = false") +@ApolloAuditLogDataInfluenceTable(tableName = "Role") public class Role extends BaseEntity { + @ApolloAuditLogDataInfluenceTableField(fieldName = "RoleName") @Column(name = "`RoleName`", nullable = false) private String roleName; diff --git a/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/entity/po/UserRole.java b/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/entity/po/UserRole.java index aa6ab8b28cb..222804e29ac 100644 --- a/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/entity/po/UserRole.java +++ b/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/entity/po/UserRole.java @@ -16,6 +16,8 @@ */ package com.ctrip.framework.apollo.portal.entity.po; +import com.ctrip.framework.apollo.audit.annotation.ApolloAuditLogDataInfluenceTable; +import com.ctrip.framework.apollo.audit.annotation.ApolloAuditLogDataInfluenceTableField; import com.ctrip.framework.apollo.common.entity.BaseEntity; import org.hibernate.annotations.SQLDelete; @@ -32,10 +34,13 @@ @Table(name = "`UserRole`") @SQLDelete(sql = "Update UserRole set IsDeleted = true, DeletedAt = ROUND(UNIX_TIMESTAMP(NOW(4))*1000) where Id = ?") @Where(clause = "`IsDeleted` = false") +@ApolloAuditLogDataInfluenceTable(tableName = "UserRole") public class UserRole extends BaseEntity { + @ApolloAuditLogDataInfluenceTableField(fieldName = "UserId") @Column(name = "`UserId`", nullable = false) private String userId; + @ApolloAuditLogDataInfluenceTableField(fieldName = "RoleId") @Column(name = "`RoleId`", nullable = false) private long roleId; diff --git a/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/spi/defaultimpl/DefaultRoleInitializationService.java b/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/spi/defaultimpl/DefaultRoleInitializationService.java index ddb78400741..07ca0474a5d 100644 --- a/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/spi/defaultimpl/DefaultRoleInitializationService.java +++ b/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/spi/defaultimpl/DefaultRoleInitializationService.java @@ -16,6 +16,8 @@ */ package com.ctrip.framework.apollo.portal.spi.defaultimpl; +import com.ctrip.framework.apollo.audit.annotation.ApolloAuditLog; +import com.ctrip.framework.apollo.audit.annotation.OpType; import com.ctrip.framework.apollo.common.entity.App; import com.ctrip.framework.apollo.common.entity.BaseEntity; import com.ctrip.framework.apollo.core.ConfigConsts; @@ -57,6 +59,7 @@ public DefaultRoleInitializationService(final RolePermissionService rolePermissi } @Transactional + @ApolloAuditLog(type = OpType.CREATE, name = "Auth.initAppRoles") public void initAppRoles(App app) { String appId = app.getAppId(); @@ -91,6 +94,7 @@ public void initAppRoles(App app) { } @Transactional + @ApolloAuditLog(type = OpType.CREATE, name = "Auth.initNamespaceRoles") public void initNamespaceRoles(String appId, String namespaceName, String operator) { String modifyNamespaceRoleName = RoleUtils.buildModifyNamespaceRoleName(appId, namespaceName); @@ -107,6 +111,7 @@ public void initNamespaceRoles(String appId, String namespaceName, String operat } @Transactional + @ApolloAuditLog(type = OpType.CREATE, name = "Auth.initNamespaceEnvRoles") public void initNamespaceEnvRoles(String appId, String namespaceName, String operator) { List portalEnvs = portalConfig.portalSupportedEnvs(); @@ -116,6 +121,7 @@ public void initNamespaceEnvRoles(String appId, String namespaceName, String ope } @Transactional + @ApolloAuditLog(type = OpType.CREATE, name = "Auth.initNamespaceSpecificEnvRoles") public void initNamespaceSpecificEnvRoles(String appId, String namespaceName, String env, String operator) { String modifyNamespaceEnvRoleName = RoleUtils.buildModifyNamespaceRoleName(appId, namespaceName, env); if (rolePermissionService.findRoleByRoleName(modifyNamespaceEnvRoleName) == null) { @@ -131,6 +137,7 @@ public void initNamespaceSpecificEnvRoles(String appId, String namespaceName, St } @Transactional + @ApolloAuditLog(type = OpType.CREATE, name = "Auth.initCreateAppRole") public void initCreateAppRole() { if (rolePermissionService.findRoleByRoleName(SystemRoleManagerService.CREATE_APPLICATION_ROLE_NAME) != null) { return; @@ -158,6 +165,7 @@ public void createManageAppMasterRole(String appId, String operator) { // fix historical data @Transactional + @ApolloAuditLog(type = OpType.CREATE, name = "Auth.initManageAppMasterRole") public void initManageAppMasterRole(String appId, String operator) { String manageAppMasterRoleName = RoleUtils.buildAppRoleName(appId, PermissionType.MANAGE_APP_MASTER); if (rolePermissionService.findRoleByRoleName(manageAppMasterRoleName) != null) { diff --git a/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/spi/defaultimpl/DefaultRolePermissionService.java b/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/spi/defaultimpl/DefaultRolePermissionService.java index ef48d436fc0..d7697650b08 100644 --- a/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/spi/defaultimpl/DefaultRolePermissionService.java +++ b/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/spi/defaultimpl/DefaultRolePermissionService.java @@ -16,6 +16,11 @@ */ package com.ctrip.framework.apollo.portal.spi.defaultimpl; +import com.ctrip.framework.apollo.audit.annotation.ApolloAuditLog; +import com.ctrip.framework.apollo.audit.annotation.ApolloAuditLogDataInfluence; +import com.ctrip.framework.apollo.audit.annotation.ApolloAuditLogDataInfluenceTable; +import com.ctrip.framework.apollo.audit.annotation.ApolloAuditLogDataInfluenceTableField; +import com.ctrip.framework.apollo.audit.annotation.OpType; import com.ctrip.framework.apollo.openapi.repository.ConsumerRoleRepository; import com.ctrip.framework.apollo.portal.component.config.PortalConfig; import com.ctrip.framework.apollo.portal.entity.bo.UserInfo; @@ -107,6 +112,7 @@ public Role createRoleWithPermissions(Role role, Set permissionIds) { * @return the users assigned roles */ @Transactional + @ApolloAuditLog(type = OpType.CREATE, name = "Auth.assignRoleToUsers") public Set assignRoleToUsers(String roleName, Set userIds, String operatorUserId) { Role role = findRoleByRoleName(roleName); @@ -136,7 +142,14 @@ public Set assignRoleToUsers(String roleName, Set userIds, * Remove role from users */ @Transactional - public void removeRoleFromUsers(String roleName, Set userIds, String operatorUserId) { + @ApolloAuditLog(type = OpType.DELETE, name = "Auth.removeRoleFromUsers") + public void removeRoleFromUsers( + @ApolloAuditLogDataInfluence + @ApolloAuditLogDataInfluenceTable(tableName = "UserRole") + @ApolloAuditLogDataInfluenceTableField(fieldName = "RoleName") String roleName, + @ApolloAuditLogDataInfluence + @ApolloAuditLogDataInfluenceTable(tableName = "UserRole") + @ApolloAuditLogDataInfluenceTableField(fieldName = "UserId") Set userIds, String operatorUserId) { Role role = findRoleByRoleName(roleName); Preconditions.checkState(role != null, "Role %s doesn't exist!", roleName); From 7f9ebbf7f8a3e4c8ac01c5eee15ce65bbdc4ec47 Mon Sep 17 00:00:00 2001 From: weizhile <348358584@qq.com> Date: Sun, 5 Nov 2023 21:39:52 +0800 Subject: [PATCH 5/8] implement basic needs in issue --- .../framework/apollo/portal/api/AdminServiceAPI.java | 8 ++++++++ .../apollo/portal/controller/AccessKeyController.java | 6 ++++++ .../framework/apollo/portal/controller/AppController.java | 6 +++--- .../apollo/portal/controller/ClusterController.java | 4 ++-- .../portal/controller/NamespaceBranchController.java | 6 ++++++ .../apollo/portal/controller/PermissionController.java | 1 - .../apollo/portal/controller/ServerConfigController.java | 4 ++++ .../framework/apollo/portal/entity/po/ServerConfig.java | 5 +++++ .../spi/defaultimpl/DefaultRoleInitializationService.java | 6 ------ 9 files changed, 34 insertions(+), 12 deletions(-) diff --git a/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/api/AdminServiceAPI.java b/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/api/AdminServiceAPI.java index 5e192284a1b..aecc4fe07a8 100644 --- a/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/api/AdminServiceAPI.java +++ b/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/api/AdminServiceAPI.java @@ -286,6 +286,7 @@ public void delete(Env env, String appId, String clusterName, String operator) { @Service public static class AccessKeyAPI extends API { + @ApolloAuditLog(type = OpType.RPC, name = "AccessKey.createInRemote") public AccessKeyDTO create(Env env, AccessKeyDTO accessKey) { return restTemplate.post(env, "apps/{appId}/accesskeys", accessKey, AccessKeyDTO.class, accessKey.getAppId()); @@ -297,16 +298,19 @@ public List findByAppId(Env env, String appId) { return Arrays.asList(accessKeys); } + @ApolloAuditLog(type = OpType.RPC, name = "AccessKey.deleteInRemote") public void delete(Env env, String appId, long id, String operator) { restTemplate.delete(env, "apps/{appId}/accesskeys/{id}?operator={operator}", appId, id, operator); } + @ApolloAuditLog(type = OpType.RPC, name = "AccessKey.enableInRemote") public void enable(Env env, String appId, long id, String operator) { restTemplate.put(env, "apps/{appId}/accesskeys/{id}/enable?operator={operator}", null, appId, id, operator); } + @ApolloAuditLog(type = OpType.RPC, name = "AccessKey.disableInRemote") public void disable(Env env, String appId, long id, String operator) { restTemplate.put(env, "apps/{appId}/accesskeys/{id}/disable?operator={operator}", null, appId, id, operator); @@ -519,6 +523,7 @@ public int getInstanceCountByNamespace(String appId, Env env, String clusterName @Service public static class NamespaceBranchAPI extends API { + @ApolloAuditLog(type = OpType.RPC, name = "NamespaceBranch.createInRemote") public NamespaceDTO createBranch(String appId, Env env, String clusterName, String namespaceName, String operator) { return restTemplate @@ -540,6 +545,7 @@ public GrayReleaseRuleDTO findBranchGrayRules(String appId, Env env, String clus } + @ApolloAuditLog(type = OpType.RPC, name = "NamespaceBranch.updateInRemote") public void updateBranchGrayRules(String appId, Env env, String clusterName, String namespaceName, String branchName, GrayReleaseRuleDTO rules) { restTemplate @@ -548,6 +554,7 @@ public void updateBranchGrayRules(String appId, Env env, String clusterName, } + @ApolloAuditLog(type = OpType.RPC, name = "NamespaceBranch.deleteInRemote") public void deleteBranch(String appId, Env env, String clusterName, String namespaceName, String branchName, String operator) { restTemplate.delete(env, @@ -593,6 +600,7 @@ public List findAllConfigDBConfig(Env env){ }).getBody(); } + @ApolloAuditLog(type = OpType.RPC, name = "ServerConfig.createOrUpdateConfigDBConfigInRemote") public ServerConfig createOrUpdateConfigDBConfig(Env env, ServerConfig serverConfig){ return restTemplate.post(env, "/server/config", serverConfig, ServerConfig.class); } diff --git a/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/controller/AccessKeyController.java b/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/controller/AccessKeyController.java index 127cd063f82..1e764b3b353 100644 --- a/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/controller/AccessKeyController.java +++ b/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/controller/AccessKeyController.java @@ -16,6 +16,8 @@ */ package com.ctrip.framework.apollo.portal.controller; +import com.ctrip.framework.apollo.audit.annotation.ApolloAuditLog; +import com.ctrip.framework.apollo.audit.annotation.OpType; import com.ctrip.framework.apollo.common.dto.AccessKeyDTO; import com.ctrip.framework.apollo.portal.environment.Env; import com.ctrip.framework.apollo.portal.service.AccessKeyService; @@ -44,6 +46,7 @@ public AccessKeyController( @PreAuthorize(value = "@permissionValidator.isAppAdmin(#appId)") @PostMapping(value = "/apps/{appId}/envs/{env}/accesskeys") + @ApolloAuditLog(type = OpType.CREATE, name = "AccessKey.create") public AccessKeyDTO save(@PathVariable String appId, @PathVariable String env, @RequestBody AccessKeyDTO accessKeyDTO) { String secret = UUID.randomUUID().toString().replaceAll("-", ""); @@ -61,6 +64,7 @@ public List findByAppId(@PathVariable String appId, @PreAuthorize(value = "@permissionValidator.isAppAdmin(#appId)") @DeleteMapping(value = "/apps/{appId}/envs/{env}/accesskeys/{id}") + @ApolloAuditLog(type = OpType.DELETE, name = "AccessKey.delete") public void delete(@PathVariable String appId, @PathVariable String env, @PathVariable long id) { @@ -70,6 +74,7 @@ public void delete(@PathVariable String appId, @PreAuthorize(value = "@permissionValidator.isAppAdmin(#appId)") @PutMapping(value = "/apps/{appId}/envs/{env}/accesskeys/{id}/enable") + @ApolloAuditLog(type = OpType.UPDATE, name = "AccessKey.enable") public void enable(@PathVariable String appId, @PathVariable String env, @PathVariable long id) { @@ -79,6 +84,7 @@ public void enable(@PathVariable String appId, @PreAuthorize(value = "@permissionValidator.isAppAdmin(#appId)") @PutMapping(value = "/apps/{appId}/envs/{env}/accesskeys/{id}/disable") + @ApolloAuditLog(type = OpType.UPDATE, name = "AccessKey.disable") public void disable(@PathVariable String appId, @PathVariable String env, @PathVariable long id) { diff --git a/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/controller/AppController.java b/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/controller/AppController.java index 7e96c9923cf..4005f011acb 100644 --- a/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/controller/AppController.java +++ b/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/controller/AppController.java @@ -121,7 +121,7 @@ public List findAppsByOwner(@RequestParam("owner") String owner, Pageable p @PreAuthorize(value = "@permissionValidator.hasCreateApplicationPermission()") @PostMapping - @ApolloAuditLog(type = OpType.CREATE, name = "App.create.request") + @ApolloAuditLog(type = OpType.CREATE, name = "App.create") public App create(@Valid @RequestBody AppModel appModel) { App app = transformToApp(appModel); @@ -130,7 +130,7 @@ public App create(@Valid @RequestBody AppModel appModel) { @PreAuthorize(value = "@permissionValidator.isAppAdmin(#appId)") @PutMapping("/{appId:.+}") - @ApolloAuditLog(type = OpType.UPDATE, name = "App.update.request") + @ApolloAuditLog(type = OpType.UPDATE, name = "App.update") public void update(@PathVariable String appId, @Valid @RequestBody AppModel appModel) { if (!Objects.equals(appId, appModel.getAppId())) { throw new BadRequestException("The App Id of path variable and request body is different"); @@ -183,7 +183,7 @@ public AppDTO load(@PathVariable String appId) { @PreAuthorize(value = "@permissionValidator.isSuperAdmin()") @DeleteMapping("/{appId:.+}") - @ApolloAuditLog(type = OpType.RPC, name = "App.delete.request") + @ApolloAuditLog(type = OpType.RPC, name = "App.delete") public void deleteApp(@PathVariable String appId) { App app = appService.deleteAppInLocal(appId); diff --git a/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/controller/ClusterController.java b/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/controller/ClusterController.java index 9e8e1ab178f..cc670ff49b0 100644 --- a/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/controller/ClusterController.java +++ b/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/controller/ClusterController.java @@ -46,7 +46,7 @@ public ClusterController(final ClusterService clusterService, final UserInfoHold @PreAuthorize(value = "@permissionValidator.hasCreateClusterPermission(#appId)") @PostMapping(value = "apps/{appId}/envs/{env}/clusters") - @ApolloAuditLog(type = OpType.CREATE, name = "Cluster.create.request") + @ApolloAuditLog(type = OpType.CREATE, name = "Cluster.create") public ClusterDTO createCluster(@PathVariable String appId, @PathVariable String env, @Valid @RequestBody ClusterDTO cluster) { String operator = userInfoHolder.getUser().getUserId(); @@ -58,7 +58,7 @@ public ClusterDTO createCluster(@PathVariable String appId, @PathVariable String @PreAuthorize(value = "@permissionValidator.isSuperAdmin()") @DeleteMapping(value = "apps/{appId}/envs/{env}/clusters/{clusterName:.+}") - @ApolloAuditLog(type = OpType.DELETE, name = "Cluster.delete.request") + @ApolloAuditLog(type = OpType.DELETE, name = "Cluster.delete") public ResponseEntity deleteCluster(@PathVariable String appId, @PathVariable String env, @PathVariable String clusterName){ clusterService.deleteCluster(Env.valueOf(env), appId, clusterName); diff --git a/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/controller/NamespaceBranchController.java b/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/controller/NamespaceBranchController.java index 75adb257466..4afd9920b09 100644 --- a/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/controller/NamespaceBranchController.java +++ b/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/controller/NamespaceBranchController.java @@ -16,6 +16,8 @@ */ package com.ctrip.framework.apollo.portal.controller; +import com.ctrip.framework.apollo.audit.annotation.ApolloAuditLog; +import com.ctrip.framework.apollo.audit.annotation.OpType; import com.ctrip.framework.apollo.common.dto.GrayReleaseRuleDTO; import com.ctrip.framework.apollo.common.dto.NamespaceDTO; import com.ctrip.framework.apollo.common.dto.ReleaseDTO; @@ -78,6 +80,7 @@ public NamespaceBO findBranch(@PathVariable String appId, @PreAuthorize(value = "@permissionValidator.hasModifyNamespacePermission(#appId, #namespaceName, #env)") @PostMapping(value = "/apps/{appId}/envs/{env}/clusters/{clusterName}/namespaces/{namespaceName}/branches") + @ApolloAuditLog(type = OpType.CREATE, name = "NamespaceBranch.create") public NamespaceDTO createBranch(@PathVariable String appId, @PathVariable String env, @PathVariable String clusterName, @@ -87,6 +90,7 @@ public NamespaceDTO createBranch(@PathVariable String appId, } @DeleteMapping(value = "/apps/{appId}/envs/{env}/clusters/{clusterName}/namespaces/{namespaceName}/branches/{branchName}") + @ApolloAuditLog(type = OpType.DELETE, name = "NamespaceBranch.delete") public void deleteBranch(@PathVariable String appId, @PathVariable String env, @PathVariable String clusterName, @@ -113,6 +117,7 @@ public void deleteBranch(@PathVariable String appId, @PreAuthorize(value = "@permissionValidator.hasReleaseNamespacePermission(#appId, #namespaceName, #env)") @PostMapping(value = "/apps/{appId}/envs/{env}/clusters/{clusterName}/namespaces/{namespaceName}/branches/{branchName}/merge") + @ApolloAuditLog(type = OpType.UPDATE, name = "NamespaceBranch.merge") public ReleaseDTO merge(@PathVariable String appId, @PathVariable String env, @PathVariable String clusterName, @PathVariable String namespaceName, @PathVariable String branchName, @RequestParam(value = "deleteBranch", defaultValue = "true") boolean deleteBranch, @@ -152,6 +157,7 @@ public GrayReleaseRuleDTO getBranchGrayRules(@PathVariable String appId, @PathVa @PreAuthorize(value = "@permissionValidator.hasOperateNamespacePermission(#appId, #namespaceName, #env)") @PutMapping(value = "/apps/{appId}/envs/{env}/clusters/{clusterName}/namespaces/{namespaceName}/branches/{branchName}/rules") + @ApolloAuditLog(type = OpType.UPDATE, name = "NamespaceBranch.updateBranchRules") public void updateBranchRules(@PathVariable String appId, @PathVariable String env, @PathVariable String clusterName, @PathVariable String namespaceName, @PathVariable String branchName, @RequestBody GrayReleaseRuleDTO rules) { diff --git a/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/controller/PermissionController.java b/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/controller/PermissionController.java index bdcc2932ae7..6ba5f5080af 100644 --- a/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/controller/PermissionController.java +++ b/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/controller/PermissionController.java @@ -75,7 +75,6 @@ public PermissionController( } @PostMapping("/apps/{appId}/initPermission") - @ApolloAuditLog(type = OpType.CREATE, name = "Auth.initAppPermission") public ResponseEntity initAppPermission(@PathVariable String appId, @RequestBody String namespaceName) { roleInitializationService.initNamespaceEnvRoles(appId, namespaceName, userInfoHolder.getUser().getUserId()); return ResponseEntity.ok().build(); diff --git a/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/controller/ServerConfigController.java b/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/controller/ServerConfigController.java index bf2a65857f4..99f5941d37f 100644 --- a/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/controller/ServerConfigController.java +++ b/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/controller/ServerConfigController.java @@ -17,6 +17,8 @@ package com.ctrip.framework.apollo.portal.controller; +import com.ctrip.framework.apollo.audit.annotation.ApolloAuditLog; +import com.ctrip.framework.apollo.audit.annotation.OpType; import com.ctrip.framework.apollo.portal.entity.po.ServerConfig; import com.ctrip.framework.apollo.portal.environment.Env; import com.ctrip.framework.apollo.portal.service.ServerConfigService; @@ -42,12 +44,14 @@ public ServerConfigController(final ServerConfigService serverConfigService) { @PreAuthorize(value = "@permissionValidator.isSuperAdmin()") @PostMapping("/server/portal-db/config") + @ApolloAuditLog(type = OpType.CREATE, name = "ServerConfig.createOrUpdatePortalDBConfig") public ServerConfig createOrUpdatePortalDBConfig(@Valid @RequestBody ServerConfig serverConfig) { return serverConfigService.createOrUpdatePortalDBConfig(serverConfig); } @PreAuthorize(value = "@permissionValidator.isSuperAdmin()") @PostMapping("/server/envs/{env}/config-db/config") + @ApolloAuditLog(type = OpType.CREATE, name = "ServerConfig.createOrUpdateConfigDBConfig") public ServerConfig createOrUpdateConfigDBConfig(@Valid @RequestBody ServerConfig serverConfig, @PathVariable String env) { return serverConfigService.createOrUpdateConfigDBConfig(Env.transformEnv(env), serverConfig); } diff --git a/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/entity/po/ServerConfig.java b/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/entity/po/ServerConfig.java index 3363a2a9683..690c9a749d6 100644 --- a/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/entity/po/ServerConfig.java +++ b/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/entity/po/ServerConfig.java @@ -16,6 +16,8 @@ */ package com.ctrip.framework.apollo.portal.entity.po; +import com.ctrip.framework.apollo.audit.annotation.ApolloAuditLogDataInfluenceTable; +import com.ctrip.framework.apollo.audit.annotation.ApolloAuditLogDataInfluenceTableField; import com.ctrip.framework.apollo.common.entity.BaseEntity; import javax.validation.constraints.NotBlank; @@ -33,13 +35,16 @@ @Table(name = "`ServerConfig`") @SQLDelete(sql = "Update ServerConfig set IsDeleted = true, DeletedAt = ROUND(UNIX_TIMESTAMP(NOW(4))*1000) where Id = ?") @Where(clause = "`IsDeleted` = false") +@ApolloAuditLogDataInfluenceTable(tableName = "ServerConfig") public class ServerConfig extends BaseEntity { @NotBlank(message = "ServerConfig.Key cannot be blank") @Column(name = "`Key`", nullable = false) + @ApolloAuditLogDataInfluenceTableField(fieldName = "Key") private String key; @NotBlank(message = "ServerConfig.Value cannot be blank") @Column(name = "`Value`", nullable = false) + @ApolloAuditLogDataInfluenceTableField(fieldName = "Value") private String value; @Column(name = "`Comment`", nullable = false) diff --git a/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/spi/defaultimpl/DefaultRoleInitializationService.java b/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/spi/defaultimpl/DefaultRoleInitializationService.java index 07ca0474a5d..0e63d7a0f71 100644 --- a/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/spi/defaultimpl/DefaultRoleInitializationService.java +++ b/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/spi/defaultimpl/DefaultRoleInitializationService.java @@ -59,7 +59,6 @@ public DefaultRoleInitializationService(final RolePermissionService rolePermissi } @Transactional - @ApolloAuditLog(type = OpType.CREATE, name = "Auth.initAppRoles") public void initAppRoles(App app) { String appId = app.getAppId(); @@ -94,7 +93,6 @@ public void initAppRoles(App app) { } @Transactional - @ApolloAuditLog(type = OpType.CREATE, name = "Auth.initNamespaceRoles") public void initNamespaceRoles(String appId, String namespaceName, String operator) { String modifyNamespaceRoleName = RoleUtils.buildModifyNamespaceRoleName(appId, namespaceName); @@ -111,7 +109,6 @@ public void initNamespaceRoles(String appId, String namespaceName, String operat } @Transactional - @ApolloAuditLog(type = OpType.CREATE, name = "Auth.initNamespaceEnvRoles") public void initNamespaceEnvRoles(String appId, String namespaceName, String operator) { List portalEnvs = portalConfig.portalSupportedEnvs(); @@ -121,7 +118,6 @@ public void initNamespaceEnvRoles(String appId, String namespaceName, String ope } @Transactional - @ApolloAuditLog(type = OpType.CREATE, name = "Auth.initNamespaceSpecificEnvRoles") public void initNamespaceSpecificEnvRoles(String appId, String namespaceName, String env, String operator) { String modifyNamespaceEnvRoleName = RoleUtils.buildModifyNamespaceRoleName(appId, namespaceName, env); if (rolePermissionService.findRoleByRoleName(modifyNamespaceEnvRoleName) == null) { @@ -137,7 +133,6 @@ public void initNamespaceSpecificEnvRoles(String appId, String namespaceName, St } @Transactional - @ApolloAuditLog(type = OpType.CREATE, name = "Auth.initCreateAppRole") public void initCreateAppRole() { if (rolePermissionService.findRoleByRoleName(SystemRoleManagerService.CREATE_APPLICATION_ROLE_NAME) != null) { return; @@ -165,7 +160,6 @@ public void createManageAppMasterRole(String appId, String operator) { // fix historical data @Transactional - @ApolloAuditLog(type = OpType.CREATE, name = "Auth.initManageAppMasterRole") public void initManageAppMasterRole(String appId, String operator) { String manageAppMasterRoleName = RoleUtils.buildAppRoleName(appId, PermissionType.MANAGE_APP_MASTER); if (rolePermissionService.findRoleByRoleName(manageAppMasterRoleName) != null) { From 9818139dea17c087295e4edc4b57d7cc2d75d3d4 Mon Sep 17 00:00:00 2001 From: weizhile <348358584@qq.com> Date: Fri, 10 Nov 2023 03:00:33 +0800 Subject: [PATCH 6/8] Optimize code structure and add unit test for ApolloAuditSpanAspect. --- .../audit/aop/ApolloAuditSpanAspect.java | 93 +++++++----- .../audit/constants/ApolloAuditConstants.java | 2 + .../audit/aop/ApolloAuditSpanAspectTest.java | 143 ++++++++++++++++++ .../DefaultRoleInitializationService.java | 2 - 4 files changed, 199 insertions(+), 41 deletions(-) create mode 100644 apollo-audit/apollo-audit-impl/src/test/java/com/ctrip/framework/apollo/audit/aop/ApolloAuditSpanAspectTest.java diff --git a/apollo-audit/apollo-audit-impl/src/main/java/com/ctrip/framework/apollo/audit/aop/ApolloAuditSpanAspect.java b/apollo-audit/apollo-audit-impl/src/main/java/com/ctrip/framework/apollo/audit/aop/ApolloAuditSpanAspect.java index 04ecc223bfe..533e2172ad3 100644 --- a/apollo-audit/apollo-audit-impl/src/main/java/com/ctrip/framework/apollo/audit/aop/ApolloAuditSpanAspect.java +++ b/apollo-audit/apollo-audit-impl/src/main/java/com/ctrip/framework/apollo/audit/aop/ApolloAuditSpanAspect.java @@ -21,16 +21,16 @@ import com.ctrip.framework.apollo.audit.annotation.ApolloAuditLogDataInfluenceTable; import com.ctrip.framework.apollo.audit.annotation.ApolloAuditLogDataInfluenceTableField; import com.ctrip.framework.apollo.audit.api.ApolloAuditLogApi; +import com.ctrip.framework.apollo.audit.constants.ApolloAuditConstants; import java.lang.annotation.Annotation; import java.lang.reflect.Method; -import java.util.Arrays; +import java.util.ArrayList; import java.util.Collection; +import java.util.Collections; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Pointcut; -import org.springframework.web.context.request.RequestContextHolder; -import org.springframework.web.context.request.ServletRequestAttributes; @Aspect public class ApolloAuditSpanAspect { @@ -48,49 +48,45 @@ public void setAuditSpan(ApolloAuditLog auditLog) { @Around(value = "setAuditSpan(auditLog)") public Object around(ProceedingJoinPoint pjp, ApolloAuditLog auditLog) throws Throwable { String opName = auditLog.name(); - if (opName.equals("") && RequestContextHolder.getRequestAttributes() != null) { - ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes(); - opName = servletRequestAttributes.getRequest().getRequestURI(); - } - try (AutoCloseable scope = api.appendAuditLog(auditLog.type(), opName, auditLog.description())) { - Object[] args = pjp.getArgs(); - Method method = findMethod(pjp.getTarget().getClass(), pjp.getSignature().getName()); - for (int i = 0; i < args.length; i++) { - Object arg = args[i]; - Annotation[] annotations = method.getParameterAnnotations()[i]; - if (Arrays.stream(annotations).anyMatch(anno -> anno instanceof ApolloAuditLogDataInfluence)) { - String entityName = null; - String fieldName = null; - for(int j = 0; j < annotations.length; j++) { - if(annotations[j] instanceof ApolloAuditLogDataInfluenceTable) { - entityName = ((ApolloAuditLogDataInfluenceTable) annotations[j]).tableName(); - } - if(annotations[j] instanceof ApolloAuditLogDataInfluenceTableField) { - fieldName = ((ApolloAuditLogDataInfluenceTableField) annotations[j]).fieldName(); - } - } - if (entityName != null && fieldName != null) { - // if arg is a collection - if (arg instanceof Collection) { - for (Object o : ((Collection) arg).toArray()) { - String matchedValue = String.valueOf(o); - api.appendDataInfluence(entityName, "AnyMatched", fieldName, matchedValue); - } - } - else { - String matchedValue = String.valueOf(arg); - api.appendDataInfluence(entityName, "AnyMatched", fieldName, matchedValue); - } - } + auditDataInfluenceArg(pjp); + return pjp.proceed(); + } + } + + void auditDataInfluenceArg(ProceedingJoinPoint pjp) { + Method method = findMethod(pjp); + Object[] args = pjp.getArgs(); + for (int i = 0; i < args.length; i++) { + Object arg = args[i]; + Annotation[] annotations = method.getParameterAnnotations()[i]; + + boolean needAudit = false; + String entityName = null; + String fieldName = null; + + for (Annotation annotation : annotations) { + if (annotation instanceof ApolloAuditLogDataInfluence) { + needAudit = true; + } + if (annotation instanceof ApolloAuditLogDataInfluenceTable) { + entityName = ((ApolloAuditLogDataInfluenceTable) annotation).tableName(); + } + if (annotation instanceof ApolloAuditLogDataInfluenceTableField) { + fieldName = ((ApolloAuditLogDataInfluenceTableField) annotation).fieldName(); } } - return pjp.proceed(); + + if (needAudit) { + parseArgAndAppend(entityName, fieldName, arg); + } } } - Method findMethod(Class clazz, String methodName) { + Method findMethod(ProceedingJoinPoint pjp) { + Class clazz = pjp.getTarget().getClass(); + String methodName = pjp.getSignature().getName(); for (Method method : clazz.getDeclaredMethods()) { if (method.getName().equals(methodName)) { return method; @@ -99,4 +95,23 @@ Method findMethod(Class clazz, String methodName) { return null; } + void parseArgAndAppend(String entityName, String fieldName, Object arg) { + if (entityName == null || fieldName == null) { + return; + } + + Collection parsedList = new ArrayList<>(Collections.emptyList()); + if (arg instanceof Collection) { + /* if arg is a collection */ + parsedList.addAll((Collection) arg); + } else { + parsedList.add(arg); + } + + for (Object o : parsedList) { + String matchedValue = String.valueOf(o); + api.appendDataInfluence(entityName, ApolloAuditConstants.ANY_MATCHED_ID, fieldName, + matchedValue); + } + } } diff --git a/apollo-audit/apollo-audit-impl/src/main/java/com/ctrip/framework/apollo/audit/constants/ApolloAuditConstants.java b/apollo-audit/apollo-audit-impl/src/main/java/com/ctrip/framework/apollo/audit/constants/ApolloAuditConstants.java index 602dbd1bff1..1c0b0c75ec4 100644 --- a/apollo-audit/apollo-audit-impl/src/main/java/com/ctrip/framework/apollo/audit/constants/ApolloAuditConstants.java +++ b/apollo-audit/apollo-audit-impl/src/main/java/com/ctrip/framework/apollo/audit/constants/ApolloAuditConstants.java @@ -24,4 +24,6 @@ public interface ApolloAuditConstants { String FOLLOWS_FROM_ID = "Apollo-Audit-FollowsFromId"; String TRACER = "Apollo-Audit-Tracer"; + + String ANY_MATCHED_ID = "AnyMatched"; } diff --git a/apollo-audit/apollo-audit-impl/src/test/java/com/ctrip/framework/apollo/audit/aop/ApolloAuditSpanAspectTest.java b/apollo-audit/apollo-audit-impl/src/test/java/com/ctrip/framework/apollo/audit/aop/ApolloAuditSpanAspectTest.java new file mode 100644 index 00000000000..18612191c0a --- /dev/null +++ b/apollo-audit/apollo-audit-impl/src/test/java/com/ctrip/framework/apollo/audit/aop/ApolloAuditSpanAspectTest.java @@ -0,0 +1,143 @@ +package com.ctrip.framework.apollo.audit.aop; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.doNothing; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.eq; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import com.ctrip.framework.apollo.audit.annotation.ApolloAuditLog; +import com.ctrip.framework.apollo.audit.annotation.ApolloAuditLogDataInfluence; +import com.ctrip.framework.apollo.audit.annotation.ApolloAuditLogDataInfluenceTable; +import com.ctrip.framework.apollo.audit.annotation.ApolloAuditLogDataInfluenceTableField; +import com.ctrip.framework.apollo.audit.annotation.OpType; +import com.ctrip.framework.apollo.audit.api.ApolloAuditLogApi; +import com.ctrip.framework.apollo.audit.constants.ApolloAuditConstants; +import java.lang.reflect.Method; +import java.util.Arrays; +import java.util.List; +import org.aspectj.lang.ProceedingJoinPoint; +import org.aspectj.lang.Signature; +import org.junit.jupiter.api.Test; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.boot.test.mock.mockito.SpyBean; +import org.springframework.test.context.ContextConfiguration; + +@SpringBootTest +@ContextConfiguration(classes = ApolloAuditSpanAspect.class) +public class ApolloAuditSpanAspectTest { + + @SpyBean + ApolloAuditSpanAspect aspect; + + @MockBean + ApolloAuditLogApi api; + + @Test + public void testAround() throws Throwable { + final OpType opType = OpType.CREATE; + final String opName = "App.create"; + final String description = "no description"; + + ProceedingJoinPoint mockPJP = mock(ProceedingJoinPoint.class); + ApolloAuditLog mockAnnotation = mock(ApolloAuditLog.class); + AutoCloseable mockScope = mock(AutoCloseable.class); + { + when(mockAnnotation.type()).thenReturn(opType); + when(mockAnnotation.name()).thenReturn(opName); + when(mockAnnotation.description()).thenReturn(description); + when(api.appendAuditLog(eq(opType), eq(opName), eq(description))) + .thenReturn(mockScope); + doNothing().when(aspect).auditDataInfluenceArg(mockPJP); + } + + aspect.around(mockPJP, mockAnnotation); + verify(api, times(1)) + .appendAuditLog(eq(opType), eq(opName), eq(description)); + verify(mockScope, times(1)) + .close(); + verify(aspect, times(1)) + .auditDataInfluenceArg(eq(mockPJP)); + } + + @Test + public void testAuditDataInfluenceArg() throws NoSuchMethodException { + ProceedingJoinPoint mockPJP = mock(ProceedingJoinPoint.class); + Object[] args = new Object[]{new Object(), new Object()}; + Method method = MockAuditClass.class.getMethod("mockAuditMethod", Object.class, Object.class); + { + doReturn(method).when(aspect).findMethod(any()); + when(mockPJP.getArgs()).thenReturn(args); + } + aspect.auditDataInfluenceArg(mockPJP); + verify(aspect, times(1)) + .parseArgAndAppend(eq("App"), eq("Name"), eq(args[0])); + } + + @Test + public void testFindMethod() throws NoSuchMethodException { + ProceedingJoinPoint mockPJP = mock(ProceedingJoinPoint.class); + MockAuditClass mockAuditClass = new MockAuditClass(); + Signature signature = mock(Signature.class); + Method method = MockAuditClass.class.getMethod("mockAuditMethod", Object.class, Object.class); + { + when(mockPJP.getTarget()).thenReturn(mockAuditClass); + when(mockPJP.getSignature()).thenReturn(signature); + when(signature.getName()).thenReturn("mockAuditMethod"); + } + Method methodFounded = aspect.findMethod(mockPJP); + + assertEquals(method, methodFounded); + } + + @Test + public void testParseArgAndAppendCaseNullName() { + Object somewhat = new Object(); + aspect.parseArgAndAppend(null, null, somewhat); + verify(api, times(0)) + .appendDataInfluence(any(), any(), any(), any()); + } + + @Test + public void testParseArgAndAppendCaseCollectionTypeArg() { + final String entityName = "App"; + final String fieldName = "Name"; + List list = Arrays.asList(new Object(), new Object(), new Object()); + + { + doNothing().when(api).appendDataInfluence(any(), any(), any(), any()); + } + aspect.parseArgAndAppend(entityName, fieldName, list); + verify(api, times(list.size())).appendDataInfluence(eq(entityName), + eq(ApolloAuditConstants.ANY_MATCHED_ID), eq(fieldName), any()); + } + + @Test + public void testParseArgAndAppendCaseNormalTypeArg() { + final String entityName = "App"; + final String fieldName = "Name"; + Object arg = new Object(); + + { + doNothing().when(api).appendDataInfluence(any(), any(), any(), any()); + } + aspect.parseArgAndAppend(entityName, fieldName, arg); + verify(api, times(1)).appendDataInfluence(eq(entityName), + eq(ApolloAuditConstants.ANY_MATCHED_ID), eq(fieldName), any()); + } + + public class MockAuditClass { + + public void mockAuditMethod( + @ApolloAuditLogDataInfluence + @ApolloAuditLogDataInfluenceTable(tableName = "App") + @ApolloAuditLogDataInfluenceTableField(fieldName = "Name") Object val1, + Object val2) { + } + } +} diff --git a/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/spi/defaultimpl/DefaultRoleInitializationService.java b/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/spi/defaultimpl/DefaultRoleInitializationService.java index 0e63d7a0f71..ddb78400741 100644 --- a/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/spi/defaultimpl/DefaultRoleInitializationService.java +++ b/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/spi/defaultimpl/DefaultRoleInitializationService.java @@ -16,8 +16,6 @@ */ package com.ctrip.framework.apollo.portal.spi.defaultimpl; -import com.ctrip.framework.apollo.audit.annotation.ApolloAuditLog; -import com.ctrip.framework.apollo.audit.annotation.OpType; import com.ctrip.framework.apollo.common.entity.App; import com.ctrip.framework.apollo.common.entity.BaseEntity; import com.ctrip.framework.apollo.core.ConfigConsts; From fd708f57c295dfa592da78d61f0eea71da304a2e Mon Sep 17 00:00:00 2001 From: weizhile <348358584@qq.com> Date: Fri, 10 Nov 2023 03:03:03 +0800 Subject: [PATCH 7/8] add license --- .../audit/aop/ApolloAuditSpanAspectTest.java | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/apollo-audit/apollo-audit-impl/src/test/java/com/ctrip/framework/apollo/audit/aop/ApolloAuditSpanAspectTest.java b/apollo-audit/apollo-audit-impl/src/test/java/com/ctrip/framework/apollo/audit/aop/ApolloAuditSpanAspectTest.java index 18612191c0a..303a4f07df3 100644 --- a/apollo-audit/apollo-audit-impl/src/test/java/com/ctrip/framework/apollo/audit/aop/ApolloAuditSpanAspectTest.java +++ b/apollo-audit/apollo-audit-impl/src/test/java/com/ctrip/framework/apollo/audit/aop/ApolloAuditSpanAspectTest.java @@ -1,3 +1,19 @@ +/* + * Copyright 2023 Apollo Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ package com.ctrip.framework.apollo.audit.aop; import static org.junit.jupiter.api.Assertions.assertEquals; From ef839f260a34595dd3c60a9f58ba0d02b20e45d3 Mon Sep 17 00:00:00 2001 From: weizhile <348358584@qq.com> Date: Fri, 10 Nov 2023 21:02:41 +0800 Subject: [PATCH 8/8] update ApolloAuditSpanAspect --- .../audit/aop/ApolloAuditSpanAspect.java | 21 ++++++++----------- 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/apollo-audit/apollo-audit-impl/src/main/java/com/ctrip/framework/apollo/audit/aop/ApolloAuditSpanAspect.java b/apollo-audit/apollo-audit-impl/src/main/java/com/ctrip/framework/apollo/audit/aop/ApolloAuditSpanAspect.java index 533e2172ad3..054d637139b 100644 --- a/apollo-audit/apollo-audit-impl/src/main/java/com/ctrip/framework/apollo/audit/aop/ApolloAuditSpanAspect.java +++ b/apollo-audit/apollo-audit-impl/src/main/java/com/ctrip/framework/apollo/audit/aop/ApolloAuditSpanAspect.java @@ -50,8 +50,9 @@ public Object around(ProceedingJoinPoint pjp, ApolloAuditLog auditLog) throws Th String opName = auditLog.name(); try (AutoCloseable scope = api.appendAuditLog(auditLog.type(), opName, auditLog.description())) { + Object proceed = pjp.proceed(); auditDataInfluenceArg(pjp); - return pjp.proceed(); + return proceed; } } @@ -96,22 +97,18 @@ Method findMethod(ProceedingJoinPoint pjp) { } void parseArgAndAppend(String entityName, String fieldName, Object arg) { - if (entityName == null || fieldName == null) { + if (entityName == null || fieldName == null || arg == null) { return; } - Collection parsedList = new ArrayList<>(Collections.emptyList()); if (arg instanceof Collection) { - /* if arg is a collection */ - parsedList.addAll((Collection) arg); + for (Object o : (Collection) arg) { + String matchedValue = String.valueOf(o); + api.appendDataInfluence(entityName, ApolloAuditConstants.ANY_MATCHED_ID, fieldName, matchedValue); + } } else { - parsedList.add(arg); - } - - for (Object o : parsedList) { - String matchedValue = String.valueOf(o); - api.appendDataInfluence(entityName, ApolloAuditConstants.ANY_MATCHED_ID, fieldName, - matchedValue); + String matchedValue = String.valueOf(arg); + api.appendDataInfluence(entityName, ApolloAuditConstants.ANY_MATCHED_ID, fieldName, matchedValue); } } }