diff --git a/auth-center/auth-center-biz/src/main/java/com/jmsoftware/maf/authcenter/permission/service/PermissionService.java b/auth-center/auth-center-biz/src/main/java/com/jmsoftware/maf/authcenter/permission/service/PermissionService.kt similarity index 54% rename from auth-center/auth-center-biz/src/main/java/com/jmsoftware/maf/authcenter/permission/service/PermissionService.java rename to auth-center/auth-center-biz/src/main/java/com/jmsoftware/maf/authcenter/permission/service/PermissionService.kt index 61f09145..06c76944 100644 --- a/auth-center/auth-center-biz/src/main/java/com/jmsoftware/maf/authcenter/permission/service/PermissionService.java +++ b/auth-center/auth-center-biz/src/main/java/com/jmsoftware/maf/authcenter/permission/service/PermissionService.kt @@ -1,12 +1,11 @@ -package com.jmsoftware.maf.authcenter.permission.service; +package com.jmsoftware.maf.authcenter.permission.service -import com.jmsoftware.maf.authcenter.permission.response.GetServicesInfoResponse; -import com.jmsoftware.maf.common.domain.authcenter.permission.GetPermissionListByRoleIdListPayload; -import com.jmsoftware.maf.common.domain.authcenter.permission.GetPermissionListByRoleIdListResponse; -import org.springframework.validation.annotation.Validated; - -import javax.validation.Valid; -import javax.validation.constraints.NotNull; +import com.jmsoftware.maf.authcenter.permission.response.GetServicesInfoResponse +import com.jmsoftware.maf.common.domain.authcenter.permission.GetPermissionListByRoleIdListPayload +import com.jmsoftware.maf.common.domain.authcenter.permission.GetPermissionListByRoleIdListResponse +import org.springframework.validation.annotation.Validated +import javax.validation.Valid +import javax.validation.constraints.NotNull /** * Description: PermissionServiceImpl, change description here. @@ -14,19 +13,21 @@ * @author Johnny Miller (鍾俊), e-mail: johnnysviva@outlook.com, date: 2/18/2022 11:22 PM **/ @Validated -public interface PermissionService { +interface PermissionService { /** * Gets permission list by role id list. * * @param payload the payload * @return the permission list by role id list */ - GetPermissionListByRoleIdListResponse getPermissionListByRoleIdList(@Valid @NotNull GetPermissionListByRoleIdListPayload payload); + fun getPermissionListByRoleIdList( + payload: @Valid @NotNull GetPermissionListByRoleIdListPayload + ): GetPermissionListByRoleIdListResponse /** * Gets services info. * * @return the services info */ - GetServicesInfoResponse getServicesInfo(); + fun getServicesInfo(): GetServicesInfoResponse } diff --git a/auth-center/auth-center-biz/src/main/java/com/jmsoftware/maf/authcenter/permission/service/impl/PermissionServiceImpl.java b/auth-center/auth-center-biz/src/main/java/com/jmsoftware/maf/authcenter/permission/service/impl/PermissionServiceImpl.java deleted file mode 100644 index 1073f85a..00000000 --- a/auth-center/auth-center-biz/src/main/java/com/jmsoftware/maf/authcenter/permission/service/impl/PermissionServiceImpl.java +++ /dev/null @@ -1,108 +0,0 @@ -package com.jmsoftware.maf.authcenter.permission.service.impl; - -import cn.hutool.core.collection.CollUtil; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.google.common.collect.Lists; -import com.jmsoftware.maf.authcenter.permission.configuration.PermissionConfiguration; -import com.jmsoftware.maf.authcenter.permission.converter.PermissionMapStructMapper; -import com.jmsoftware.maf.authcenter.permission.response.GetServicesInfoResponse; -import com.jmsoftware.maf.authcenter.permission.service.PermissionDomainService; -import com.jmsoftware.maf.authcenter.permission.service.PermissionService; -import com.jmsoftware.maf.authcenter.role.service.RoleDomainService; -import com.jmsoftware.maf.common.bean.ResponseBodyBean; -import com.jmsoftware.maf.common.domain.authcenter.permission.GetPermissionListByRoleIdListPayload; -import com.jmsoftware.maf.common.domain.authcenter.permission.GetPermissionListByRoleIdListResponse; -import com.jmsoftware.maf.common.domain.authcenter.permission.PermissionType; -import com.jmsoftware.maf.common.domain.springbootstarter.HttpApiResourcesResponse; -import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; -import lombok.val; -import org.springframework.cloud.client.discovery.DiscoveryClient; -import org.springframework.stereotype.Service; -import org.springframework.web.client.RestTemplate; - -import javax.validation.Valid; -import javax.validation.constraints.NotNull; - -import static cn.hutool.core.text.CharSequenceUtil.format; -import static com.jmsoftware.maf.springcloudstarter.function.Slf4j.lazyDebug; -import static java.util.Objects.requireNonNull; - -/** - * Description: PermissionServiceImpl, change description here. - * - * @author Johnny Miller (鍾俊), e-mail: johnnysviva@outlook.com, date: 2/18/2022 11:37 PM - **/ -@Slf4j -@Service -@RequiredArgsConstructor -public class PermissionServiceImpl implements PermissionService { - private final PermissionDomainService permissionDomainService; - private final RoleDomainService roleDomainService; - private final DiscoveryClient discoveryClient; - private final RestTemplate restTemplate; - private final PermissionConfiguration permissionConfiguration; - private final ObjectMapper objectMapper; - - @Override - public GetPermissionListByRoleIdListResponse getPermissionListByRoleIdList( - @Valid @NotNull GetPermissionListByRoleIdListPayload payload - ) { - val adminRole = this.roleDomainService.checkAdmin(payload.getRoleIdList()); - val response = new GetPermissionListByRoleIdListResponse(); - response.setPermissionList(Lists.newArrayList()); - if (adminRole) { - log.warn("Admin role checked. The role can access any resources"); - val permission = new GetPermissionListByRoleIdListResponse.Permission(); - permission.setUrl("/**"); - permission.setType(PermissionType.BUTTON.getType()); - permission.setPermissionExpression("admin-permission"); - permission.setMethod("*"); - response.getPermissionList().add(permission); - return response; - } - val permissionList = - this.permissionDomainService.getPermissionListByRoleIdList( - payload.getRoleIdList(), payload.getPermissionTypeList()); - response.setPermissionList( - permissionList - .stream() - .map(PermissionMapStructMapper.INSTANCE::of) - .toList() - ); - return response; - } - - @Override - public GetServicesInfoResponse getServicesInfo() { - val serviceIdList = this.discoveryClient.getServices(); - log.info("Getting service info from Service ID list: {}", serviceIdList); - val response = new GetServicesInfoResponse(); - log.info("Ignored service ID: {}", this.permissionConfiguration.getIgnoredServiceIds()); - response.setList( - serviceIdList.stream() - .filter(serviceId -> !CollUtil.contains( - this.permissionConfiguration.getIgnoredServiceIds(), - serviceId - )) - .parallel() - .map(serviceId -> { - val responseBodyBean = this.restTemplate.getForObject( - format("http://{}/http-api-resources", serviceId), ResponseBodyBean.class); - val httpApiResourcesResponse = this.objectMapper.convertValue( - requireNonNull(responseBodyBean).getData(), - HttpApiResourcesResponse.class - ); - val serviceInfo = new GetServicesInfoResponse.ServiceInfo(); - serviceInfo.setServiceId(serviceId); - serviceInfo.setHttpApiResources(httpApiResourcesResponse); - lazyDebug(log, () -> format("Added serviceInfo: {}", serviceInfo)); - return serviceInfo; - }).toList() - ); - if (CollUtil.isEmpty(response.getList())) { - log.warn("Got am empty ServiceInfo list"); - } - return response; - } -} diff --git a/auth-center/auth-center-biz/src/main/java/com/jmsoftware/maf/authcenter/permission/service/impl/PermissionServiceImpl.kt b/auth-center/auth-center-biz/src/main/java/com/jmsoftware/maf/authcenter/permission/service/impl/PermissionServiceImpl.kt new file mode 100644 index 00000000..71b87c37 --- /dev/null +++ b/auth-center/auth-center-biz/src/main/java/com/jmsoftware/maf/authcenter/permission/service/impl/PermissionServiceImpl.kt @@ -0,0 +1,108 @@ +@file:Suppress("HttpUrlsUsage") + +package com.jmsoftware.maf.authcenter.permission.service.impl + +import cn.hutool.core.collection.CollUtil +import cn.hutool.core.text.CharSequenceUtil.format +import com.fasterxml.jackson.databind.ObjectMapper +import com.google.common.collect.Lists +import com.jmsoftware.maf.authcenter.permission.configuration.PermissionConfiguration +import com.jmsoftware.maf.authcenter.permission.converter.PermissionMapStructMapper +import com.jmsoftware.maf.authcenter.permission.persistence.Permission +import com.jmsoftware.maf.authcenter.permission.response.GetServicesInfoResponse +import com.jmsoftware.maf.authcenter.permission.response.GetServicesInfoResponse.ServiceInfo +import com.jmsoftware.maf.authcenter.permission.service.PermissionDomainService +import com.jmsoftware.maf.authcenter.permission.service.PermissionService +import com.jmsoftware.maf.authcenter.role.service.RoleDomainService +import com.jmsoftware.maf.common.bean.ResponseBodyBean +import com.jmsoftware.maf.common.domain.authcenter.permission.GetPermissionListByRoleIdListPayload +import com.jmsoftware.maf.common.domain.authcenter.permission.GetPermissionListByRoleIdListResponse +import com.jmsoftware.maf.common.domain.authcenter.permission.PermissionType +import com.jmsoftware.maf.common.domain.springbootstarter.HttpApiResourcesResponse +import com.jmsoftware.maf.springcloudstarter.function.Slf4j.lazyDebug +import org.slf4j.LoggerFactory +import org.springframework.cloud.client.discovery.DiscoveryClient +import org.springframework.stereotype.Service +import org.springframework.web.client.RestTemplate +import java.util.* +import javax.validation.Valid +import javax.validation.constraints.NotNull + +/** + * # PermissionServiceImpl + * + * Change description here. + * + * @author Johnny Miller (鍾俊), e-mail: johnnysviva@outlook.com, date: 2/18/2022 11:37 PM + */ +@Service +class PermissionServiceImpl( + private val permissionDomainService: PermissionDomainService, + private val roleDomainService: RoleDomainService, + private val discoveryClient: DiscoveryClient, + private val restTemplate: RestTemplate, + private val permissionConfiguration: PermissionConfiguration, + private val objectMapper: ObjectMapper, +) : PermissionService { + companion object { + private val log = LoggerFactory.getLogger(this::class.java) + } + + override fun getPermissionListByRoleIdList( + payload: @Valid @NotNull GetPermissionListByRoleIdListPayload + ): GetPermissionListByRoleIdListResponse { + val adminRole = roleDomainService.checkAdmin(payload.roleIdList) + val response = GetPermissionListByRoleIdListResponse() + response.permissionList = Lists.newArrayList() + if (adminRole) { + log.warn("Admin role checked. The role can access any resources") + val permission = GetPermissionListByRoleIdListResponse.Permission() + permission.url = "/**" + permission.type = PermissionType.BUTTON.type + permission.permissionExpression = "admin-permission" + permission.method = "*" + response.permissionList.add(permission) + return response + } + val permissionList = permissionDomainService.getPermissionListByRoleIdList( + payload.roleIdList, payload.permissionTypeList) + response.permissionList = permissionList + .stream() + .map { permission: Permission -> PermissionMapStructMapper.INSTANCE.of(permission) } + .toList() + return response + } + + override fun getServicesInfo(): GetServicesInfoResponse { + val serviceIdList = discoveryClient.services + log.info("Getting service info from Service ID list: {}", serviceIdList) + val response = GetServicesInfoResponse() + log.info("Ignored service ID: {}", permissionConfiguration.ignoredServiceIds) + response.list = serviceIdList.stream() + .filter { serviceId: String -> + !CollUtil.contains( + permissionConfiguration.ignoredServiceIds, + serviceId + ) + } + .parallel() + .map { serviceId: String -> + val responseBodyBean = restTemplate.getForObject( + format("http://{}/http-api-resources", serviceId), ResponseBodyBean::class.java, + )!! + val httpApiResourcesResponse = objectMapper.convertValue( + Objects.requireNonNull(responseBodyBean).data, + HttpApiResourcesResponse::class.java + ) + val serviceInfo = ServiceInfo() + serviceInfo.serviceId = serviceId + serviceInfo.httpApiResources = httpApiResourcesResponse + lazyDebug(log) { format("Added serviceInfo: {}", serviceInfo) } + serviceInfo + }.toList() + if (CollUtil.isEmpty(response.list)) { + log.warn("Got am empty ServiceInfo list") + } + return response + } +} diff --git a/auth-center/auth-center-biz/src/test/java/com/jmsoftware/maf/authcenter/permission/service/impl/PermissionServiceImplTest.java b/auth-center/auth-center-biz/src/test/java/com/jmsoftware/maf/authcenter/permission/service/impl/PermissionServiceImplTest.java deleted file mode 100644 index 81ee5caf..00000000 --- a/auth-center/auth-center-biz/src/test/java/com/jmsoftware/maf/authcenter/permission/service/impl/PermissionServiceImplTest.java +++ /dev/null @@ -1,118 +0,0 @@ -package com.jmsoftware.maf.authcenter.permission.service.impl; - -import cn.hutool.core.util.StrUtil; -import com.google.common.collect.Lists; -import com.google.common.collect.Sets; -import com.jmsoftware.maf.authcenter.permission.configuration.PermissionConfiguration; -import com.jmsoftware.maf.authcenter.permission.service.PermissionDomainService; -import com.jmsoftware.maf.authcenter.role.service.RoleDomainService; -import com.jmsoftware.maf.common.bean.ResponseBodyBean; -import com.jmsoftware.maf.common.domain.authcenter.permission.GetPermissionListByRoleIdListPayload; -import com.jmsoftware.maf.common.domain.springbootstarter.HttpApiResourcesResponse; -import lombok.extern.slf4j.Slf4j; -import lombok.val; -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.junit.jupiter.api.parallel.Execution; -import org.junit.jupiter.api.parallel.ExecutionMode; -import org.mockito.InjectMocks; -import org.mockito.Mock; -import org.mockito.junit.jupiter.MockitoExtension; -import org.springframework.cloud.client.discovery.DiscoveryClient; -import org.springframework.web.client.RestTemplate; - -import static org.junit.jupiter.api.Assertions.*; -import static org.mockito.ArgumentMatchers.*; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -/** - *

PermissionServiceImplTest

- * Description: PermissionServiceImplTest, change description here. - *

- *

Mockito JUnit 5 Extension

- *

There is also a Mockito extension for JUnit 5 that will make the initialization even simpler.

- *

Pros:

- * - *

Cons:

- * - * - * @author Johnny Miller (鍾俊), e-mail: johnnysviva@outlook.com, date: 4/3/22 10:19 PM - * @see Using Mockito With JUnit 5 - * @see YouTube - Using Mockito With JUnit 5 - **/ -@Slf4j -@ExtendWith(MockitoExtension.class) -@Execution(ExecutionMode.CONCURRENT) -class PermissionServiceImplTest { - @InjectMocks - private PermissionServiceImpl permissionService; - @Mock - private PermissionDomainService permissionDomainService; - @Mock - private RoleDomainService roleDomainService; - @Mock - private DiscoveryClient discoveryClient; - @Mock - private RestTemplate restTemplate; - @Mock - private PermissionConfiguration permissionConfiguration; - - @BeforeEach - void setUp() { - log.info("{} setUp", this.getClass().getSimpleName()); - } - - @AfterEach - void tearDown() { - log.info("{} tearDown", this.getClass().getSimpleName()); - } - - @Test - void getPermissionListByRoleIdList() { - when(this.roleDomainService.checkAdmin(anyList())).thenReturn(false); - when(this.permissionDomainService.getPermissionListByRoleIdList(anyList(), anyList())) - .thenReturn(Lists.newArrayList()); - - val payload = new GetPermissionListByRoleIdListPayload(); - payload.setRoleIdList(Lists.newArrayList()); - payload.setPermissionTypeList(Lists.newArrayList()); - val response = this.permissionService.getPermissionListByRoleIdList(payload); - log.info("Permission list response: {}", response); - verify(this.roleDomainService).checkAdmin(anyList()); - verify(this.permissionDomainService).getPermissionListByRoleIdList(anyList(), anyList()); - assertEquals(0, response.getPermissionList().size()); - } - - @Test - void getServicesInfo() { - when(this.discoveryClient.getServices()) - .thenReturn(Lists.newArrayList( - "auth-center", "oss-center", "maf-mis", "api-gateway", "spring-boot-admin")); - when(this.permissionConfiguration.getIgnoredServiceIds()) - .thenReturn(Sets.newHashSet("api-gateway", "spring-boot-admin")); - when(this.restTemplate.getForObject(anyString(), any())) - .thenReturn(ResponseBodyBean.ofSuccess(new HttpApiResourcesResponse())); - - val servicesInfo = this.permissionService.getServicesInfo(); - log.info("Services info: {}", servicesInfo); - verify(this.discoveryClient).getServices(); - assertNotEquals(0, servicesInfo.getList().size()); - assertTrue( - servicesInfo.getList() - .stream() - .anyMatch(service -> StrUtil.equalsAnyIgnoreCase(service.getServiceId(), "auth-center")) - ); - } -} diff --git a/auth-center/auth-center-biz/src/test/java/com/jmsoftware/maf/authcenter/permission/service/impl/PermissionServiceImplTest.kt b/auth-center/auth-center-biz/src/test/java/com/jmsoftware/maf/authcenter/permission/service/impl/PermissionServiceImplTest.kt new file mode 100644 index 00000000..872451ef --- /dev/null +++ b/auth-center/auth-center-biz/src/test/java/com/jmsoftware/maf/authcenter/permission/service/impl/PermissionServiceImplTest.kt @@ -0,0 +1,131 @@ +@file:Suppress("unused") + +package com.jmsoftware.maf.authcenter.permission.service.impl + +import cn.hutool.core.util.StrUtil +import com.fasterxml.jackson.databind.ObjectMapper +import com.google.common.collect.Lists +import com.jmsoftware.maf.authcenter.permission.configuration.PermissionConfiguration +import com.jmsoftware.maf.authcenter.permission.response.GetServicesInfoResponse.ServiceInfo +import com.jmsoftware.maf.authcenter.permission.service.PermissionDomainService +import com.jmsoftware.maf.authcenter.role.service.RoleDomainService +import com.jmsoftware.maf.common.bean.ResponseBodyBean +import com.jmsoftware.maf.common.domain.authcenter.permission.GetPermissionListByRoleIdListPayload +import com.jmsoftware.maf.common.domain.springbootstarter.HttpApiResourcesResponse +import org.junit.jupiter.api.AfterEach +import org.junit.jupiter.api.Assertions.* +import org.junit.jupiter.api.BeforeEach +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.extension.ExtendWith +import org.junit.jupiter.api.parallel.Execution +import org.junit.jupiter.api.parallel.ExecutionMode +import org.mockito.ArgumentMatchers.* +import org.mockito.InjectMocks +import org.mockito.Mock +import org.mockito.Mockito.`when` +import org.mockito.Mockito.verify +import org.mockito.junit.jupiter.MockitoExtension +import org.slf4j.LoggerFactory +import org.springframework.cloud.client.discovery.DiscoveryClient +import org.springframework.web.client.RestTemplate + +/** + * # PermissionServiceImplTest + * + * Description: PermissionServiceImplTest, change description here. + * + * ## Mockito JUnit 5 Extension + * + * There is also a Mockito extension for JUnit 5 that will make the initialization even simpler. + * + * **Pros:** + * + * * No need to call `MockitoAnnotations.openMocks()` + * * Validates framework usage and detects incorrect stubbing + * * Easy to create mocks + * * Very readable + * + * **Cons:** + * + * * Need an extra dependency on `org.mockito:mockito-junit-jupiter`, which has been included by Spring. + * So we don't have to worry about this. + * + * + * @author Johnny Miller (鍾俊), e-mail: johnnysviva@outlook.com, date: 4/3/22 10:19 PM + * @see [Using Mockito With JUnit 5](https://www.arhohuttunen.com/junit-5-mockito/) + * @see [YouTube - Using Mockito With JUnit 5](https://www.youtube.com/watch?v=p7_cTAF39A8/) + */ +@ExtendWith(MockitoExtension::class) +@Execution(ExecutionMode.CONCURRENT) +internal class PermissionServiceImplTest { + companion object { + private val log = LoggerFactory.getLogger(this::class.java) + } + + @InjectMocks + lateinit var permissionService: PermissionServiceImpl + + @Mock + lateinit var permissionDomainService: PermissionDomainService + + @Mock + lateinit var roleDomainService: RoleDomainService + + @Mock + lateinit var discoveryClient: DiscoveryClient + + @Mock + lateinit var restTemplate: RestTemplate + + @Mock + lateinit var permissionConfiguration: PermissionConfiguration + + @Mock + lateinit var objectMapper: ObjectMapper + + @BeforeEach + fun setUp() { + log.info("{} setUp", this.javaClass.simpleName) + } + + @AfterEach + fun tearDown() { + log.info("{} tearDown", this.javaClass.simpleName) + } + + @Test + fun getPermissionListByRoleIdList() { + `when`(roleDomainService.checkAdmin(anyList())).thenReturn(false) + `when`(permissionDomainService.getPermissionListByRoleIdList(anyList(), anyList())) + .thenReturn(Lists.newArrayList()) + val payload = GetPermissionListByRoleIdListPayload() + payload.roleIdList = Lists.newArrayList() + payload.permissionTypeList = Lists.newArrayList() + val response = permissionService.getPermissionListByRoleIdList(payload) + log.info("Permission list response: {}", response) + verify(roleDomainService).checkAdmin(anyList()) + verify(permissionDomainService).getPermissionListByRoleIdList(anyList(), anyList()) + assertEquals(0, response.permissionList.size) + } + + @Test + fun getServicesInfo() { + `when`(discoveryClient.services) + .thenReturn(listOf("auth-center", "oss-center", "maf-mis", "api-gateway", "spring-boot-admin")) + `when`(permissionConfiguration.ignoredServiceIds) + .thenReturn(setOf("api-gateway", "spring-boot-admin")) + `when`(restTemplate.getForObject(anyString(), any>())) + .thenReturn(ResponseBodyBean.ofSuccess(HttpApiResourcesResponse())) + val servicesInfo = permissionService.getServicesInfo() + log.info("Services info: {}", servicesInfo) + verify(discoveryClient).services + assertNotEquals(0, servicesInfo.list.size) + assertTrue( + servicesInfo.list + .stream() + .anyMatch { service: ServiceInfo -> + StrUtil.equalsAnyIgnoreCase(service.serviceId, "auth-center") + } + ) + } +} diff --git a/pom.xml b/pom.xml index 59425ee4..373e67a6 100644 --- a/pom.xml +++ b/pom.xml @@ -338,6 +338,31 @@ + + + org.jetbrains.kotlin + kotlin-maven-plugin + + + spring + + + -Xjsr305=strict + + + + + org.jetbrains.kotlin + kotlin-maven-noarg + ${kotlin.version} + + + org.jetbrains.kotlin + kotlin-maven-allopen + ${kotlin.version} + + + @@ -386,6 +411,20 @@ + + + org.jetbrains.kotlin + kotlin-reflect + + + org.jetbrains.kotlin + kotlin-stdlib-jdk8 + + + com.fasterxml.jackson.module + jackson-module-kotlin + + org.projectlombok