diff --git a/.dev/tenant-user-management-service/docker-compose.yaml b/.dev/tenant-user-management-service/docker-compose.yaml index d1d919d..20a5aa5 100644 --- a/.dev/tenant-user-management-service/docker-compose.yaml +++ b/.dev/tenant-user-management-service/docker-compose.yaml @@ -31,6 +31,8 @@ services: ports: - 5672:5672 - 15672:15672 + - 5671:5671 + - 4369:4369 minio: mem_limit: 1000m image: minio/minio diff --git a/build.gradle.kts b/build.gradle.kts index 9a889fa..6641606 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -78,14 +78,16 @@ dependencies { implementation("commons-validator:commons-validator:1.7") implementation("org.springframework.boot:spring-boot-configuration-processor") testImplementation("org.springframework.boot:spring-boot-starter-test") - + testImplementation("org.springframework.cloud:spring-cloud-starter-openfeign") + testImplementation("org.projectlombok:lombok") compileOnly("org.projectlombok:lombok") developmentOnly("org.springframework.boot:spring-boot-devtools") annotationProcessor("org.springframework.boot:spring-boot-configuration-processor") annotationProcessor("org.projectlombok:lombok") testImplementation("org.springframework.boot:spring-boot-starter-test") testImplementation("org.springframework.amqp:spring-rabbit-test") - testImplementation("org.testcontainers:elasticsearch:1.17.6") + testImplementation("org.testcontainers:postgresql:1.18.3") + testImplementation("com.github.dasniko:testcontainers-keycloak:2.5.0") testAnnotationProcessor("org.projectlombok:lombok") } diff --git a/src/main/java/com/knecon/fforesight/tenantusermanagement/api/external/GeneralSettingsResource.java b/src/main/java/com/knecon/fforesight/tenantusermanagement/api/external/GeneralSettingsResource.java index e283ebf..a970183 100644 --- a/src/main/java/com/knecon/fforesight/tenantusermanagement/api/external/GeneralSettingsResource.java +++ b/src/main/java/com/knecon/fforesight/tenantusermanagement/api/external/GeneralSettingsResource.java @@ -15,8 +15,6 @@ import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.responses.ApiResponse; import io.swagger.v3.oas.annotations.responses.ApiResponses; -@RequestMapping("${fforesight.tenant-user-management.base-path:}") - public interface GeneralSettingsResource { String API_PATH = "/configuration/general"; diff --git a/src/main/java/com/knecon/fforesight/tenantusermanagement/api/external/PublicResource.java b/src/main/java/com/knecon/fforesight/tenantusermanagement/api/external/PublicResource.java new file mode 100644 index 0000000..9ed32fd --- /dev/null +++ b/src/main/java/com/knecon/fforesight/tenantusermanagement/api/external/PublicResource.java @@ -0,0 +1,8 @@ +package com.knecon.fforesight.tenantusermanagement.api.external; + +import org.springframework.web.bind.annotation.RequestMapping; + +@RequestMapping("${fforesight.tenant-user-management.base-path:}") +public interface PublicResource { + +} diff --git a/src/main/java/com/knecon/fforesight/tenantusermanagement/api/external/SMTPConfigurationResource.java b/src/main/java/com/knecon/fforesight/tenantusermanagement/api/external/SMTPConfigurationResource.java index 264a705..6667002 100644 --- a/src/main/java/com/knecon/fforesight/tenantusermanagement/api/external/SMTPConfigurationResource.java +++ b/src/main/java/com/knecon/fforesight/tenantusermanagement/api/external/SMTPConfigurationResource.java @@ -16,8 +16,6 @@ import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.responses.ApiResponse; import io.swagger.v3.oas.annotations.responses.ApiResponses; -@RequestMapping("${fforesight.tenant-user-management.base-path:}") - public interface SMTPConfigurationResource { String SMTP_PATH = "/configuration/smtp"; diff --git a/src/main/java/com/knecon/fforesight/tenantusermanagement/api/external/TenantsResource.java b/src/main/java/com/knecon/fforesight/tenantusermanagement/api/external/TenantsResource.java index 78e7749..89f593c 100644 --- a/src/main/java/com/knecon/fforesight/tenantusermanagement/api/external/TenantsResource.java +++ b/src/main/java/com/knecon/fforesight/tenantusermanagement/api/external/TenantsResource.java @@ -21,7 +21,6 @@ import io.swagger.v3.oas.annotations.responses.ApiResponse; import io.swagger.v3.oas.annotations.responses.ApiResponses; @ResponseStatus(value = HttpStatus.OK) -@RequestMapping("${fforesight.tenant-user-management.base-path:}") public interface TenantsResource { String TENANT_ID_PARAM = "tenantId"; diff --git a/src/main/java/com/knecon/fforesight/tenantusermanagement/api/external/UserPreferenceResource.java b/src/main/java/com/knecon/fforesight/tenantusermanagement/api/external/UserPreferenceResource.java index 7805122..4a9b04e 100644 --- a/src/main/java/com/knecon/fforesight/tenantusermanagement/api/external/UserPreferenceResource.java +++ b/src/main/java/com/knecon/fforesight/tenantusermanagement/api/external/UserPreferenceResource.java @@ -18,8 +18,6 @@ import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.responses.ApiResponse; import io.swagger.v3.oas.annotations.responses.ApiResponses; -@RequestMapping("${fforesight.tenant-user-management.base-path:}") - public interface UserPreferenceResource { String PREFERENCES_PATH = "/attributes"; diff --git a/src/main/java/com/knecon/fforesight/tenantusermanagement/api/external/UserResource.java b/src/main/java/com/knecon/fforesight/tenantusermanagement/api/external/UserResource.java index bc679a9..84ddea6 100644 --- a/src/main/java/com/knecon/fforesight/tenantusermanagement/api/external/UserResource.java +++ b/src/main/java/com/knecon/fforesight/tenantusermanagement/api/external/UserResource.java @@ -26,8 +26,6 @@ import io.swagger.v3.oas.annotations.responses.ApiResponse; import io.swagger.v3.oas.annotations.responses.ApiResponses; @ResponseStatus(value = HttpStatus.OK) -@RequestMapping("${fforesight.tenant-user-management.base-path:}") - public interface UserResource { String USER_REST_PATH = "/user"; @@ -61,19 +59,19 @@ public interface UserResource { @ResponseBody - @ResponseStatus(value = HttpStatus.NO_CONTENT) + @ResponseStatus(value = HttpStatus.OK) @Operation(summary = "Update your own user-profile.", description = "None") @ApiResponses(value = {@ApiResponse(responseCode = "204", description = "OK"), @ApiResponse(responseCode = "400", description = "Failed to update profile, e-mail cannot be empty")}) - @PostMapping(value = UPDATE_USER_PROFILE_PATH + USER_ID_PATH_VARIABLE, consumes = MediaType.APPLICATION_JSON_VALUE) - void updateProfile(@PathVariable(USER_ID) String userId, @RequestBody UpdateProfileRequest updateProfileRequest); + @PostMapping(value = UPDATE_USER_PROFILE_PATH + USER_ID_PATH_VARIABLE, consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE) + User updateProfile(@PathVariable(USER_ID) String userId, @RequestBody UpdateProfileRequest updateProfileRequest); @ResponseBody - @ResponseStatus(value = HttpStatus.NO_CONTENT) + @ResponseStatus(value = HttpStatus.OK) @Operation(summary = "Update your own user-profile.", description = "None") @ApiResponses(value = {@ApiResponse(responseCode = "204", description = "OK"), @ApiResponse(responseCode = "400", description = "Failed to update profile, e-mail cannot be empty")}) - @PostMapping(value = UPDATE_MY_USER_PROFILE_PATH, consumes = MediaType.APPLICATION_JSON_VALUE) - void updateMyProfile(@RequestBody UpdateMyProfileRequest updateProfileRequest); + @PostMapping(value = UPDATE_MY_USER_PROFILE_PATH, consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE) + User updateMyProfile(@RequestBody UpdateMyProfileRequest updateProfileRequest); @ResponseBody @@ -106,11 +104,11 @@ public interface UserResource { User getUserById(@PathVariable(USER_ID) String userId); - @ResponseStatus(value = HttpStatus.NO_CONTENT) + @ResponseStatus(value = HttpStatus.OK) @Operation(summary = "Add a role to users", description = "None") @ApiResponses(value = {@ApiResponse(responseCode = "204", description = "No Content"), @ApiResponse(responseCode = "404", description = "The provided userId can not be found."), @ApiResponse(responseCode = "400", description = "One ore more roles are not valid.")}) - @PostMapping(value = USER_ROLE_REST_PATH, consumes = MediaType.APPLICATION_JSON_VALUE) - void setRoles(@PathVariable(USER_ID) String userId, @RequestBody Set roles); + @PostMapping(value = USER_ROLE_REST_PATH, consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE) + User setRoles(@PathVariable(USER_ID) String userId, @RequestBody Set roles); @ResponseStatus(value = HttpStatus.NO_CONTENT) diff --git a/src/main/java/com/knecon/fforesight/tenantusermanagement/api/internal/InternalResource.java b/src/main/java/com/knecon/fforesight/tenantusermanagement/api/internal/InternalResource.java new file mode 100644 index 0000000..81c26fb --- /dev/null +++ b/src/main/java/com/knecon/fforesight/tenantusermanagement/api/internal/InternalResource.java @@ -0,0 +1,8 @@ +package com.knecon.fforesight.tenantusermanagement.api.internal; + +import org.springframework.web.bind.annotation.RequestMapping; + +@RequestMapping("/internal") +public interface InternalResource { + +} diff --git a/src/main/java/com/knecon/fforesight/tenantusermanagement/api/internal/InternalTenantsResource.java b/src/main/java/com/knecon/fforesight/tenantusermanagement/api/internal/InternalTenantsResource.java index 1dc3084..31e5f9b 100644 --- a/src/main/java/com/knecon/fforesight/tenantusermanagement/api/internal/InternalTenantsResource.java +++ b/src/main/java/com/knecon/fforesight/tenantusermanagement/api/internal/InternalTenantsResource.java @@ -22,7 +22,6 @@ import io.swagger.v3.oas.annotations.responses.ApiResponse; import io.swagger.v3.oas.annotations.responses.ApiResponses; @ResponseStatus(value = HttpStatus.OK) -@RequestMapping("/internal") public interface InternalTenantsResource { String TENANT_ID_PARAM = "tenantId"; diff --git a/src/main/java/com/knecon/fforesight/tenantusermanagement/api/internal/InternalUserResource.java b/src/main/java/com/knecon/fforesight/tenantusermanagement/api/internal/InternalUserResource.java index 202a8dd..7d584e1 100644 --- a/src/main/java/com/knecon/fforesight/tenantusermanagement/api/internal/InternalUserResource.java +++ b/src/main/java/com/knecon/fforesight/tenantusermanagement/api/internal/InternalUserResource.java @@ -17,7 +17,6 @@ import io.swagger.v3.oas.annotations.responses.ApiResponse; import io.swagger.v3.oas.annotations.responses.ApiResponses; @ResponseStatus(value = HttpStatus.OK) -@RequestMapping("/internal") public interface InternalUserResource { String USER_REST_PATH = "/user"; diff --git a/src/main/java/com/knecon/fforesight/tenantusermanagement/controller/external/GeneralSettingsController.java b/src/main/java/com/knecon/fforesight/tenantusermanagement/controller/external/GeneralSettingsController.java index 46b988b..8d59875 100644 --- a/src/main/java/com/knecon/fforesight/tenantusermanagement/controller/external/GeneralSettingsController.java +++ b/src/main/java/com/knecon/fforesight/tenantusermanagement/controller/external/GeneralSettingsController.java @@ -8,6 +8,7 @@ import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RestController; import com.knecon.fforesight.tenantusermanagement.api.external.GeneralSettingsResource; +import com.knecon.fforesight.tenantusermanagement.api.external.PublicResource; import com.knecon.fforesight.tenantusermanagement.model.GeneralConfigurationModel; import com.knecon.fforesight.tenantusermanagement.service.GeneralConfigurationService; @@ -17,7 +18,7 @@ import lombok.extern.slf4j.Slf4j; @Slf4j @RestController @RequiredArgsConstructor -public class GeneralSettingsController implements GeneralSettingsResource { +public class GeneralSettingsController implements GeneralSettingsResource, PublicResource { private final GeneralConfigurationService generalConfigurationService; diff --git a/src/main/java/com/knecon/fforesight/tenantusermanagement/controller/external/SMTPConfigurationController.java b/src/main/java/com/knecon/fforesight/tenantusermanagement/controller/external/SMTPConfigurationController.java index 9007a4c..47a4df0 100644 --- a/src/main/java/com/knecon/fforesight/tenantusermanagement/controller/external/SMTPConfigurationController.java +++ b/src/main/java/com/knecon/fforesight/tenantusermanagement/controller/external/SMTPConfigurationController.java @@ -13,6 +13,7 @@ import org.springframework.web.bind.annotation.RestController; import com.fasterxml.jackson.databind.ObjectMapper; import com.knecon.fforesight.tenantcommons.EncryptionDecryptionService; import com.knecon.fforesight.tenantcommons.TenantContext; +import com.knecon.fforesight.tenantusermanagement.api.external.PublicResource; import com.knecon.fforesight.tenantusermanagement.api.external.SMTPConfigurationResource; import com.knecon.fforesight.tenantusermanagement.model.SMTPConfiguration; import com.knecon.fforesight.tenantusermanagement.service.RealmService; @@ -24,9 +25,8 @@ import lombok.extern.slf4j.Slf4j; @Slf4j @RestController @RequiredArgsConstructor -public class SMTPConfigurationController implements SMTPConfigurationResource { +public class SMTPConfigurationController implements SMTPConfigurationResource, PublicResource { - private final static String DEFAULT_PASSWORD = "********"; private final static String SMTP_PASSWORD_KEY = "FFORESIGHT_SMTP_PASSWORD"; private final RealmService realmService; private final ObjectMapper objectMapper; @@ -51,7 +51,7 @@ public class SMTPConfigurationController implements SMTPConfigurationResource { var propertiesMap = convertSMTPConfigurationModelToMap(smtpConfigurationModel); realmRepresentation.setSmtpServer(propertiesMap); - if (!smtpConfigurationModel.getPassword().equalsIgnoreCase(DEFAULT_PASSWORD)) { + if (!smtpConfigurationModel.getPassword().matches("\\**")) { realmRepresentation.getAttributesOrEmpty().put(SMTP_PASSWORD_KEY, encryptionDecryptionService.encrypt(smtpConfigurationModel.getPassword())); } diff --git a/src/main/java/com/knecon/fforesight/tenantusermanagement/controller/external/TenantsController.java b/src/main/java/com/knecon/fforesight/tenantusermanagement/controller/external/TenantsController.java index 0f9a9b5..6e91034 100644 --- a/src/main/java/com/knecon/fforesight/tenantusermanagement/controller/external/TenantsController.java +++ b/src/main/java/com/knecon/fforesight/tenantusermanagement/controller/external/TenantsController.java @@ -14,6 +14,7 @@ import org.springframework.web.bind.annotation.RestController; import org.springframework.web.server.ResponseStatusException; import com.knecon.fforesight.tenantcommons.model.TenantResponse; +import com.knecon.fforesight.tenantusermanagement.api.external.PublicResource; import com.knecon.fforesight.tenantusermanagement.api.external.TenantsResource; import com.knecon.fforesight.tenantusermanagement.model.DeploymentKeyResponse; import com.knecon.fforesight.tenantusermanagement.model.SimpleTenantResponse; @@ -26,7 +27,7 @@ import lombok.RequiredArgsConstructor; @RestController @RequiredArgsConstructor -public class TenantsController implements TenantsResource { +public class TenantsController implements TenantsResource, PublicResource { private final TenantManagementService tenantManagementService; private final DeploymentKeyService deploymentKeyService; diff --git a/src/main/java/com/knecon/fforesight/tenantusermanagement/controller/external/UserController.java b/src/main/java/com/knecon/fforesight/tenantusermanagement/controller/external/UserController.java index 49e2252..2a4f31c 100644 --- a/src/main/java/com/knecon/fforesight/tenantusermanagement/controller/external/UserController.java +++ b/src/main/java/com/knecon/fforesight/tenantusermanagement/controller/external/UserController.java @@ -18,6 +18,7 @@ import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.server.ResponseStatusException; +import com.knecon.fforesight.tenantusermanagement.api.external.PublicResource; import com.knecon.fforesight.tenantusermanagement.api.external.UserResource; import com.knecon.fforesight.tenantusermanagement.model.CreateUserRequest; import com.knecon.fforesight.tenantusermanagement.model.ResetPasswordRequest; @@ -34,7 +35,7 @@ import lombok.extern.slf4j.Slf4j; @Slf4j @RestController @RequiredArgsConstructor -public class UserController implements UserResource { +public class UserController implements UserResource, PublicResource { private final UserService userService; private final TenantUserManagementProperties tenantUserManagementProperties; @@ -67,17 +68,17 @@ public class UserController implements UserResource { @Override @PreAuthorize("hasAuthority('" + WRITE_USERS + "')") - public void updateProfile(@PathVariable(USER_ID) String userId, @RequestBody UpdateProfileRequest updateProfileRequest) { + public User updateProfile(@PathVariable(USER_ID) String userId, @RequestBody UpdateProfileRequest updateProfileRequest) { - this.userService.updateProfile(userId, updateProfileRequest); + return this.userService.updateProfile(userId, updateProfileRequest); } @Override @PreAuthorize("hasAuthority('" + UPDATE_MY_PROFILE + "')") - public void updateMyProfile(@Valid @RequestBody UpdateMyProfileRequest updateProfileRequest) { + public User updateMyProfile(@Valid @RequestBody UpdateMyProfileRequest updateProfileRequest) { - this.userService.updateMyProfile(updateProfileRequest); + return this.userService.updateMyProfile(updateProfileRequest); } @@ -118,9 +119,9 @@ public class UserController implements UserResource { @Override @PreAuthorize("hasAuthority('" + WRITE_USERS + "')") - public void setRoles(@PathVariable(USER_ID) String userId, @RequestBody Set roles) { + public User setRoles(@PathVariable(USER_ID) String userId, @RequestBody Set roles) { - userService.setRoles(userId, roles); + return userService.setRoles(userId, roles); } diff --git a/src/main/java/com/knecon/fforesight/tenantusermanagement/controller/external/UserPreferenceController.java b/src/main/java/com/knecon/fforesight/tenantusermanagement/controller/external/UserPreferenceController.java index 99e8770..455647f 100644 --- a/src/main/java/com/knecon/fforesight/tenantusermanagement/controller/external/UserPreferenceController.java +++ b/src/main/java/com/knecon/fforesight/tenantusermanagement/controller/external/UserPreferenceController.java @@ -9,6 +9,7 @@ import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RestController; import com.knecon.fforesight.keycloakcommons.security.KeycloakSecurity; +import com.knecon.fforesight.tenantusermanagement.api.external.PublicResource; import com.knecon.fforesight.tenantusermanagement.api.external.UserPreferenceResource; import com.knecon.fforesight.tenantusermanagement.permissions.UserManagementPermissions; import com.knecon.fforesight.tenantusermanagement.service.UserService; @@ -17,7 +18,7 @@ import lombok.RequiredArgsConstructor; @RestController @RequiredArgsConstructor -public class UserPreferenceController implements UserPreferenceResource { +public class UserPreferenceController implements UserPreferenceResource, PublicResource { private final UserService userService; diff --git a/src/main/java/com/knecon/fforesight/tenantusermanagement/controller/internal/InternalTenantsController.java b/src/main/java/com/knecon/fforesight/tenantusermanagement/controller/internal/InternalTenantsController.java index fe9fd7d..e3453e7 100644 --- a/src/main/java/com/knecon/fforesight/tenantusermanagement/controller/internal/InternalTenantsController.java +++ b/src/main/java/com/knecon/fforesight/tenantusermanagement/controller/internal/InternalTenantsController.java @@ -10,6 +10,8 @@ import org.springframework.web.server.ResponseStatusException; import com.knecon.fforesight.tenantcommons.model.TenantResponse; import com.knecon.fforesight.tenantcommons.model.UpdateDetailsRequest; +import com.knecon.fforesight.tenantusermanagement.api.external.PublicResource; +import com.knecon.fforesight.tenantusermanagement.api.internal.InternalResource; import com.knecon.fforesight.tenantusermanagement.api.internal.InternalTenantsResource; import com.knecon.fforesight.tenantusermanagement.model.DeploymentKeyResponse; import com.knecon.fforesight.tenantusermanagement.model.SimpleTenantResponse; @@ -22,7 +24,7 @@ import lombok.RequiredArgsConstructor; @RestController @RequiredArgsConstructor -public class InternalTenantsController implements InternalTenantsResource { +public class InternalTenantsController implements InternalTenantsResource, InternalResource { private final TenantManagementService tenantManagementService; private final DeploymentKeyService deploymentKeyService; diff --git a/src/main/java/com/knecon/fforesight/tenantusermanagement/controller/internal/InternalUserController.java b/src/main/java/com/knecon/fforesight/tenantusermanagement/controller/internal/InternalUserController.java index 0b1a4ee..f1f6e19 100644 --- a/src/main/java/com/knecon/fforesight/tenantusermanagement/controller/internal/InternalUserController.java +++ b/src/main/java/com/knecon/fforesight/tenantusermanagement/controller/internal/InternalUserController.java @@ -5,6 +5,7 @@ import java.util.List; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; +import com.knecon.fforesight.tenantusermanagement.api.internal.InternalResource; import com.knecon.fforesight.tenantusermanagement.api.internal.InternalUserResource; import com.knecon.fforesight.tenantusermanagement.model.User; import com.knecon.fforesight.tenantusermanagement.service.UserService; @@ -15,7 +16,7 @@ import lombok.extern.slf4j.Slf4j; @Slf4j @RestController @RequiredArgsConstructor -public class InternalUserController implements InternalUserResource { +public class InternalUserController implements InternalUserResource, InternalResource { private final UserService userService; diff --git a/src/main/java/com/knecon/fforesight/tenantusermanagement/dev/DevApplicationRunner.java b/src/main/java/com/knecon/fforesight/tenantusermanagement/dev/DevApplicationRunner.java new file mode 100644 index 0000000..3e075af --- /dev/null +++ b/src/main/java/com/knecon/fforesight/tenantusermanagement/dev/DevApplicationRunner.java @@ -0,0 +1,26 @@ +package com.knecon.fforesight.tenantusermanagement.dev; + +import org.springframework.boot.ApplicationArguments; +import org.springframework.boot.ApplicationRunner; +import org.springframework.context.annotation.Profile; +import org.springframework.stereotype.Service; + +import lombok.RequiredArgsConstructor; +import lombok.SneakyThrows; + +@Service +@Profile("dev") +@RequiredArgsConstructor +public class DevApplicationRunner implements ApplicationRunner { + + private final DevTestTenantService devTestTenantService; + + + @Override + @SneakyThrows + public void run(ApplicationArguments args) { + + devTestTenantService.createTestTenant("sampleTenant"); + } + +} diff --git a/src/main/java/com/knecon/fforesight/tenantusermanagement/DevConfiguration.java b/src/main/java/com/knecon/fforesight/tenantusermanagement/dev/DevTestTenantService.java similarity index 58% rename from src/main/java/com/knecon/fforesight/tenantusermanagement/DevConfiguration.java rename to src/main/java/com/knecon/fforesight/tenantusermanagement/dev/DevTestTenantService.java index 44267d6..9dbadad 100644 --- a/src/main/java/com/knecon/fforesight/tenantusermanagement/DevConfiguration.java +++ b/src/main/java/com/knecon/fforesight/tenantusermanagement/dev/DevTestTenantService.java @@ -1,108 +1,79 @@ -package com.knecon.fforesight.tenantusermanagement; +package com.knecon.fforesight.tenantusermanagement.dev; -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.File; -import java.io.FileOutputStream; -import java.io.IOException; -import java.nio.charset.StandardCharsets; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; import java.sql.Connection; import java.sql.DriverManager; -import java.util.ArrayList; import java.util.Set; import java.util.UUID; -import java.util.stream.Stream; -import java.util.zip.ZipEntry; -import java.util.zip.ZipOutputStream; import javax.annotation.PostConstruct; import javax.sql.DataSource; -import org.apache.commons.io.IOUtils; -import org.checkerframework.checker.units.qual.A; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; -import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Profile; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.core.StatementCallback; import org.springframework.jdbc.datasource.SingleConnectionDataSource; +import org.springframework.stereotype.Service; -import com.fasterxml.jackson.databind.ObjectMapper; import com.knecon.fforesight.tenantcommons.model.DatabaseConnection; import com.knecon.fforesight.tenantcommons.model.S3StorageConnection; import com.knecon.fforesight.tenantcommons.model.SearchConnection; import com.knecon.fforesight.tenantusermanagement.model.TenantRequest; -import com.knecon.fforesight.tenantusermanagement.model.TenantUser; -import com.knecon.fforesight.tenantusermanagement.model.User; -import com.knecon.fforesight.tenantusermanagement.properties.TenantUserManagementProperties; -import com.knecon.fforesight.tenantusermanagement.service.KeyCloakRoleManagerService; -import com.knecon.fforesight.tenantusermanagement.service.RealmService; import com.knecon.fforesight.tenantusermanagement.service.TenantManagementService; +import lombok.RequiredArgsConstructor; import lombok.SneakyThrows; import lombok.extern.slf4j.Slf4j; @Slf4j @Profile("dev") -@Configuration -public class DevConfiguration { +@Service +@RequiredArgsConstructor +public class DevTestTenantService { - @Autowired - private TenantManagementService tenantManagementService; - @Autowired - private KeyCloakRoleManagerService keyCloakRoleManagerService; - @Autowired - private DataSource dataSource; + private final TenantManagementService tenantManagementService; + private final DataSource dataSource; @Value("${spring.datasource.url:}") private String masterJDBCURL; - @Autowired - private TenantUserManagementProperties tenantUserManagementProperties; - @Autowired - private RealmService realmService; + + @PostConstruct @SneakyThrows - public void postConstruct() { + public void createTestTenantIfNotExists(String tenantId) { - - var tenant = 99; try { - tenantManagementService.getTenant("tenant" + tenant); + tenantManagementService.getTenant(tenantId); } catch (Exception e) { - createDefaultTenant(tenant); + createTestTenant(tenantId); } } @SneakyThrows - public void createDefaultTenant(int number) { + public void createTestTenant(String tenantId) { String tenantsDBName = "tenants"; String tenantsDBPassword = "tenants"; - String tenantName = "tenant" + number; - log.info("Creating Tenant {} ", tenantName); + log.info("Creating Tenant {} ", tenantId); - var jdbcUrl = masterJDBCURL.substring(0, masterJDBCURL.lastIndexOf('/') + 1) + tenantsDBName + "?currentSchema=" + tenantName; + var jdbcUrl = masterJDBCURL.substring(0, masterJDBCURL.lastIndexOf('/') + 1) + tenantsDBName + "?currentSchema=" + tenantId; createDatabase(tenantsDBName, tenantsDBPassword); - createSchema(jdbcUrl, tenantName, tenantsDBName, tenantsDBPassword); + createSchema(jdbcUrl, tenantId, tenantsDBName, tenantsDBPassword); var tenantRequest = TenantRequest.builder() - .tenantId(tenantName) - .displayName(tenantName) + .tenantId(tenantId) + .displayName(tenantId) .guid(UUID.randomUUID().toString()) .databaseConnection(DatabaseConnection.builder() .driver("postgresql") .host("localhost") .port("5432") .database(tenantsDBName) - .schema(tenantName) + .schema(tenantId) .username(tenantsDBName) .password(tenantsDBPassword) .build()) @@ -156,28 +127,5 @@ public class DevConfiguration { } - public byte[] pack(String sourceDirPath) throws IOException { - - var bos = new ByteArrayOutputStream(); - var p = Paths.get(sourceDirPath); - try (ZipOutputStream zs = new ZipOutputStream(bos)) { - Stream paths = Files.walk(p); - { - paths.filter(path -> !Files.isDirectory(path)).forEach(path -> { - ZipEntry zipEntry = new ZipEntry(p.relativize(path).toString()); - try { - zs.putNextEntry(zipEntry); - Files.copy(path, zs); - zs.closeEntry(); - } catch (IOException e) { - System.err.println(e); - } - }); - } - } - - return bos.toByteArray(); - - } } diff --git a/src/main/java/com/knecon/fforesight/tenantusermanagement/model/GeneralConfigurationModel.java b/src/main/java/com/knecon/fforesight/tenantusermanagement/model/GeneralConfigurationModel.java index 3c62411..2ebb91f 100644 --- a/src/main/java/com/knecon/fforesight/tenantusermanagement/model/GeneralConfigurationModel.java +++ b/src/main/java/com/knecon/fforesight/tenantusermanagement/model/GeneralConfigurationModel.java @@ -3,12 +3,14 @@ package com.knecon.fforesight.tenantusermanagement.model; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; +import lombok.EqualsAndHashCode; import lombok.NoArgsConstructor; @Data @NoArgsConstructor @AllArgsConstructor @Builder +@EqualsAndHashCode public class GeneralConfigurationModel { private boolean forgotPasswordFunctionEnabled; diff --git a/src/main/java/com/knecon/fforesight/tenantusermanagement/model/UpdateMyProfileRequest.java b/src/main/java/com/knecon/fforesight/tenantusermanagement/model/UpdateMyProfileRequest.java index 9e002cf..f059874 100644 --- a/src/main/java/com/knecon/fforesight/tenantusermanagement/model/UpdateMyProfileRequest.java +++ b/src/main/java/com/knecon/fforesight/tenantusermanagement/model/UpdateMyProfileRequest.java @@ -3,9 +3,15 @@ package com.knecon.fforesight.tenantusermanagement.model; import io.swagger.v3.oas.annotations.media.Schema; import jakarta.validation.constraints.Email; import jakarta.validation.constraints.NotEmpty; +import lombok.AllArgsConstructor; +import lombok.Builder; import lombok.Data; +import lombok.NoArgsConstructor; @Data +@Builder +@NoArgsConstructor +@AllArgsConstructor public class UpdateMyProfileRequest { @Schema(description = "Email of user.") diff --git a/src/main/java/com/knecon/fforesight/tenantusermanagement/model/UpdateProfileRequest.java b/src/main/java/com/knecon/fforesight/tenantusermanagement/model/UpdateProfileRequest.java index d66393a..da80652 100644 --- a/src/main/java/com/knecon/fforesight/tenantusermanagement/model/UpdateProfileRequest.java +++ b/src/main/java/com/knecon/fforesight/tenantusermanagement/model/UpdateProfileRequest.java @@ -4,9 +4,15 @@ import java.util.HashSet; import java.util.Set; import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; +import lombok.Builder; import lombok.Data; +import lombok.NoArgsConstructor; @Data +@NoArgsConstructor +@AllArgsConstructor +@Builder public class UpdateProfileRequest { @Schema(description = "Email of user.") @@ -18,6 +24,7 @@ public class UpdateProfileRequest { @Schema(description = "Last name of user.") private String lastName; + @Builder.Default @Schema(description = "Roles.") private Set roles = new HashSet<>(); diff --git a/src/main/java/com/knecon/fforesight/tenantusermanagement/model/User.java b/src/main/java/com/knecon/fforesight/tenantusermanagement/model/User.java index 712fa7f..1d68f29 100644 --- a/src/main/java/com/knecon/fforesight/tenantusermanagement/model/User.java +++ b/src/main/java/com/knecon/fforesight/tenantusermanagement/model/User.java @@ -7,12 +7,14 @@ import java.util.TreeSet; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; +import lombok.EqualsAndHashCode; import lombok.NoArgsConstructor; @Data @Builder @NoArgsConstructor @AllArgsConstructor +@EqualsAndHashCode(of = "userId") public class User implements Serializable { private String userId; diff --git a/src/main/java/com/knecon/fforesight/tenantusermanagement/properties/TenantUserManagementProperties.java b/src/main/java/com/knecon/fforesight/tenantusermanagement/properties/TenantUserManagementProperties.java index 7c7e5ac..6492dc0 100644 --- a/src/main/java/com/knecon/fforesight/tenantusermanagement/properties/TenantUserManagementProperties.java +++ b/src/main/java/com/knecon/fforesight/tenantusermanagement/properties/TenantUserManagementProperties.java @@ -17,6 +17,8 @@ public class TenantUserManagementProperties { private String publicServerUrl; private String realm; private String applicationClientId; + private String swaggerClientId ="swagger-ui-client"; + private String swaggerClientSecret; private String clientId; private String clientSecret; private String basePath = "/"; diff --git a/src/main/java/com/knecon/fforesight/tenantusermanagement/service/DeploymentKeyService.java b/src/main/java/com/knecon/fforesight/tenantusermanagement/service/DeploymentKeyService.java index a6452d5..3f9a74c 100644 --- a/src/main/java/com/knecon/fforesight/tenantusermanagement/service/DeploymentKeyService.java +++ b/src/main/java/com/knecon/fforesight/tenantusermanagement/service/DeploymentKeyService.java @@ -19,7 +19,8 @@ public class DeploymentKeyService { private final HashFunction hashFunction = Hashing.farmHashFingerprint64(); private final String hardcodedKey = "89274365-160c-49f2-ab8b-ad83fc43c2e1"; - @Value("${redaction.kubernetes.id:someValue}") + + @Value("${fforesight.kubernetes.id:someValue}") private String redactionKubernetesId; diff --git a/src/main/java/com/knecon/fforesight/tenantusermanagement/service/TenantManagementService.java b/src/main/java/com/knecon/fforesight/tenantusermanagement/service/TenantManagementService.java index 0a0f211..ee6c1c6 100644 --- a/src/main/java/com/knecon/fforesight/tenantusermanagement/service/TenantManagementService.java +++ b/src/main/java/com/knecon/fforesight/tenantusermanagement/service/TenantManagementService.java @@ -261,8 +261,9 @@ public class TenantManagementService implements TenantProvider { var swaggerClient = new ClientRepresentation(); swaggerClient.setEnabled(true); - swaggerClient.setName("swagger-ui-client"); - swaggerClient.setClientId("swagger-ui-client"); + swaggerClient.setName(tenantUserManagementProperties.getSwaggerClientId()); + swaggerClient.setClientId(tenantUserManagementProperties.getSwaggerClientId()); + swaggerClient.setSecret(tenantUserManagementProperties.getSwaggerClientSecret()); swaggerClient.setStandardFlowEnabled(true); swaggerClient.setImplicitFlowEnabled(false); swaggerClient.setDirectAccessGrantsEnabled(false); diff --git a/src/main/java/com/knecon/fforesight/tenantusermanagement/service/UserService.java b/src/main/java/com/knecon/fforesight/tenantusermanagement/service/UserService.java index 1a7fc86..2b8d3c9 100644 --- a/src/main/java/com/knecon/fforesight/tenantusermanagement/service/UserService.java +++ b/src/main/java/com/knecon/fforesight/tenantusermanagement/service/UserService.java @@ -138,7 +138,7 @@ public class UserService { @CacheEvict(value = "${commons.keycloak.userCache}", allEntries = true, beforeInvocation = true) - public void setRoles(String userId, Set newRoles, Set currentUserRoles) { + public User setRoles(String userId, Set newRoles, Set currentUserRoles) { var allRoles = tenantUserManagementProperties.getKcRoleMapping().getAllRoles(); newRoles.forEach(role -> { @@ -180,22 +180,23 @@ public class UserService { userResource.roles().realmLevel().remove(currentRolesAsRoleRepresentation); userResource.roles().realmLevel().add(newMappedRoles); - this.rabbitTemplate.convertAndSend(userExchangeName, - "user.rolesUpdated", - (new UserRolesUpdatedEvent(getUserByUsername(userResource.toRepresentation().getUsername()), userRoles, newRoles, KeycloakSecurity.getUserId()))); + var userWithNewRoles = getUserByUsername(userResource.toRepresentation().getUsername()); + this.rabbitTemplate.convertAndSend(userExchangeName, "user.rolesUpdated", (new UserRolesUpdatedEvent(userWithNewRoles, userRoles, newRoles, KeycloakSecurity.getUserId()))); + return userWithNewRoles; } @CacheEvict(value = "${commons.keycloak.userCache}", allEntries = true, beforeInvocation = true) - public void setRoles(String userId, Set roles) { + public User setRoles(String userId, Set roles) { var currentUserResource = getUserResource(KeycloakSecurity.getUserId()); var currentUserRoles = currentUserResource.roles().realmLevel().listEffective().stream().map(RoleRepresentation::getName).collect(Collectors.toSet()); currentUserRoles = currentUserRoles.stream().filter(r -> tenantUserManagementProperties.getKcRoleMapping().isValidRole(r)).collect(Collectors.toSet()); - setRoles(userId, roles, currentUserRoles); + var userWithNewRoles = setRoles(userId, roles, currentUserRoles); + return userWithNewRoles; } @@ -225,7 +226,7 @@ public class UserService { @CacheEvict(value = "${commons.keycloak.userCache}", allEntries = true, beforeInvocation = true) - public void updateMyProfile(UpdateMyProfileRequest updateProfileRequest) { + public User updateMyProfile(UpdateMyProfileRequest updateProfileRequest) { var user = this.getUserResource(KeycloakSecurity.getUserId()); var userRepresentation = user.toRepresentation(); @@ -257,6 +258,7 @@ public class UserService { this.rabbitTemplate.convertAndSend(userExchangeName, "user.ownProfileUpdated", (new UserUpdatedOwnProfileEvent(updatedProfile))); + return updatedProfile; } @@ -285,8 +287,7 @@ public class UserService { .realm(TenantContext.getTenantId()) .username(username) .password(password) - .clientId(tenantUserManagementProperties.getClientId()) - .clientSecret(tenantUserManagementProperties.getClientSecret()) + .clientId(tenantUserManagementProperties.getApplicationClientId()) .grantType(OAuth2Constants.PASSWORD) .resteasyClient(new ResteasyClientBuilderImpl().connectionTTL(2, TimeUnit.SECONDS) .hostnameVerification(ResteasyClientBuilder.HostnameVerificationPolicy.ANY) @@ -388,7 +389,7 @@ public class UserService { @CacheEvict(value = "${commons.keycloak.userCache}", allEntries = true, beforeInvocation = true) - public void updateProfile(String userId, UpdateProfileRequest updateProfileRequest) { + public User updateProfile(String userId, UpdateProfileRequest updateProfileRequest) { var user = this.getUserResource(userId); var userRepresentation = user.toRepresentation(); @@ -415,6 +416,7 @@ public class UserService { this.rabbitTemplate.convertAndSend(userExchangeName, "user.updated", (new UserUpdatedEvent(updatedUser, KeycloakSecurity.getUserId()))); + return updatedUser; } diff --git a/src/main/resources/application-dev.yaml b/src/main/resources/application-dev.yaml index af4d76a..5d34eb1 100644 --- a/src/main/resources/application-dev.yaml +++ b/src/main/resources/application-dev.yaml @@ -7,6 +7,7 @@ fforesight: server-url: http://localhost:8080 client-secret: WJ4CIR2t65r55caWFBg4LWhdW2kOMjeC client-id: manager + realm: master kc-role-mapping: roles: - name: SUPER_USER diff --git a/src/main/resources/application.yaml b/src/main/resources/application.yaml index 340174b..00ceee3 100644 --- a/src/main/resources/application.yaml +++ b/src/main/resources/application.yaml @@ -92,13 +92,6 @@ fforesight: auth-server-url: '/auth' enabled: true default-client-id: 'swagger-ui-client' - jobs: - datasource: - url: jdbc:postgresql://${PSQL_HOST:localhost}:${PSQL_PORT:5432}/${PSQL_DATABASE:master}?cachePrepStmts=true&useServerPrepStmts=true&rewriteBatchedStatements=true - driverClassName: org.postgresql.Driver - username: ${PSQL_USERNAME:fforesight} - password: ${PSQL_PASSWORD:fforesight} - platform: org.hibernate.dialect.PostgreSQL95Dialect tenant-user-management: base-path: '/tenant-user-management' tenant-exchange: diff --git a/src/test/java/com/knecon/fforesight/AbstractTenantUserManagementIntegrationTest.java b/src/test/java/com/knecon/fforesight/AbstractTenantUserManagementIntegrationTest.java new file mode 100644 index 0000000..836ea8a --- /dev/null +++ b/src/test/java/com/knecon/fforesight/AbstractTenantUserManagementIntegrationTest.java @@ -0,0 +1,88 @@ +package com.knecon.fforesight; + +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.extension.ExtendWith; +import org.springframework.amqp.rabbit.core.RabbitTemplate; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.autoconfigure.amqp.RabbitAutoConfiguration; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.boot.test.util.TestPropertyValues; +import org.springframework.cloud.openfeign.EnableFeignClients; +import org.springframework.context.ApplicationContextInitializer; +import org.springframework.context.ConfigurableApplicationContext; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Import; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit.jupiter.SpringExtension; + +import com.knecon.fforesight.feigntestclients.external.TenantsClient; +import com.knecon.fforesight.feigntestclients.internal.InternalTenantsClient; +import com.knecon.fforesight.tenantusermanagement.TenantUserManagementServiceApplication; +import com.knecon.fforesight.testcontainers.KeyCloakTestContainer; +import com.knecon.fforesight.testcontainers.RedisTestContainer; +import com.knecon.fforesight.testcontainers.SpringPostgreSQLTestContainer; +import com.knecon.fforesight.utils.TestTenantService; + +import lombok.extern.slf4j.Slf4j; + +@ExtendWith(SpringExtension.class) +@EnableFeignClients(basePackageClasses = {TenantsClient.class, InternalTenantsClient.class}) +@Import(AbstractTenantUserManagementIntegrationTest.TestConfiguration.class) +@ContextConfiguration(initializers = {AbstractTenantUserManagementIntegrationTest.Initializer.class}) +@SpringBootTest(classes = TenantUserManagementServiceApplication.class, webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT) +public class AbstractTenantUserManagementIntegrationTest { + + @MockBean + protected RabbitTemplate rabbitTemplate; + + @Autowired + protected TestTenantService testTenantService; + + public final static String TEST_TENANT_ID = "test_tenant_fforesight"; + + @BeforeEach + public void createTestTenant(){ + testTenantService.createTestTenantIfNotExists(TEST_TENANT_ID); + } + + @Slf4j + static class Initializer implements ApplicationContextInitializer { + + public void initialize(ConfigurableApplicationContext configurableApplicationContext) { + + var postgreSQLContainerMaster = SpringPostgreSQLTestContainer.getInstance().withDatabaseName("integration-tests-db-master").withUsername("sa").withPassword("sa"); + + postgreSQLContainerMaster.start(); + + var redisContainer = RedisTestContainer.getInstance(); + redisContainer.start(); + + var connectionStringDetails = "?serverTimezone=UTC&cachePrepStmts=true&useServerPrepStmts=true&rewriteBatchedStatements=true"; + + var kcInstance = KeyCloakTestContainer.getInstance(); + + TestPropertyValues.of("spring.datasource.url=" + postgreSQLContainerMaster.getJdbcUrl() + connectionStringDetails, + "spring.datasource.username=" + postgreSQLContainerMaster.getUsername(), + "spring.datasource.password=" + postgreSQLContainerMaster.getPassword(), + "fforesight.tenant-user-management.serverUrl=" + kcInstance.getAuthServerUrl(), + "REDIS_PORT=" + redisContainer.getFirstMappedPort(), + "REDIS_HOST=" + redisContainer.getHost(), + "fforesight.jobs.enabled=false", + "fforesight.keycloak.enabled=true").applyTo(configurableApplicationContext.getEnvironment()); + + } + + } + + @Configuration + @ComponentScan + @EnableAutoConfiguration(exclude = {RabbitAutoConfiguration.class}) + public static class TestConfiguration { + + } + +} diff --git a/src/test/java/com/knecon/fforesight/feigntestclients/external/GeneralSettingsClient.java b/src/test/java/com/knecon/fforesight/feigntestclients/external/GeneralSettingsClient.java new file mode 100644 index 0000000..8e86ee5 --- /dev/null +++ b/src/test/java/com/knecon/fforesight/feigntestclients/external/GeneralSettingsClient.java @@ -0,0 +1,10 @@ +package com.knecon.fforesight.feigntestclients.external; + +import org.springframework.cloud.openfeign.FeignClient; + +import com.knecon.fforesight.tenantusermanagement.api.external.GeneralSettingsResource; + +@FeignClient(name = "GeneralSettingsClient", url = "http://localhost:${server.port}" ,path = "${fforesight.tenant-user-management.base-path:}") +public interface GeneralSettingsClient extends GeneralSettingsResource { + +} diff --git a/src/test/java/com/knecon/fforesight/feigntestclients/external/SMTPConfigurationClient.java b/src/test/java/com/knecon/fforesight/feigntestclients/external/SMTPConfigurationClient.java new file mode 100644 index 0000000..e950fe4 --- /dev/null +++ b/src/test/java/com/knecon/fforesight/feigntestclients/external/SMTPConfigurationClient.java @@ -0,0 +1,10 @@ +package com.knecon.fforesight.feigntestclients.external; + +import org.springframework.cloud.openfeign.FeignClient; + +import com.knecon.fforesight.tenantusermanagement.api.external.SMTPConfigurationResource; + +@FeignClient(name = "SMTPConfigurationClient", url = "http://localhost:${server.port}",path = "${fforesight.tenant-user-management.base-path:}") +public interface SMTPConfigurationClient extends SMTPConfigurationResource { + +} diff --git a/src/test/java/com/knecon/fforesight/feigntestclients/external/TenantsClient.java b/src/test/java/com/knecon/fforesight/feigntestclients/external/TenantsClient.java new file mode 100644 index 0000000..72bf207 --- /dev/null +++ b/src/test/java/com/knecon/fforesight/feigntestclients/external/TenantsClient.java @@ -0,0 +1,10 @@ +package com.knecon.fforesight.feigntestclients.external; + +import org.springframework.cloud.openfeign.FeignClient; + +import com.knecon.fforesight.tenantusermanagement.api.external.TenantsResource; + +@FeignClient(name = "TenantsClient", url = "http://localhost:${server.port}",path = "${fforesight.tenant-user-management.base-path:}") +public interface TenantsClient extends TenantsResource { + +} diff --git a/src/test/java/com/knecon/fforesight/feigntestclients/external/UserClient.java b/src/test/java/com/knecon/fforesight/feigntestclients/external/UserClient.java new file mode 100644 index 0000000..8f3b617 --- /dev/null +++ b/src/test/java/com/knecon/fforesight/feigntestclients/external/UserClient.java @@ -0,0 +1,10 @@ +package com.knecon.fforesight.feigntestclients.external; + +import org.springframework.cloud.openfeign.FeignClient; + +import com.knecon.fforesight.tenantusermanagement.api.external.UserResource; + +@FeignClient(name = "UserClient", url = "http://localhost:${server.port}",path = "${fforesight.tenant-user-management.base-path:}") +public interface UserClient extends UserResource { + +} diff --git a/src/test/java/com/knecon/fforesight/feigntestclients/external/UserPreferenceClient.java b/src/test/java/com/knecon/fforesight/feigntestclients/external/UserPreferenceClient.java new file mode 100644 index 0000000..85e958e --- /dev/null +++ b/src/test/java/com/knecon/fforesight/feigntestclients/external/UserPreferenceClient.java @@ -0,0 +1,10 @@ +package com.knecon.fforesight.feigntestclients.external; + +import org.springframework.cloud.openfeign.FeignClient; + +import com.knecon.fforesight.tenantusermanagement.api.external.UserPreferenceResource; + +@FeignClient(name = "UserPreferenceClient", url = "http://localhost:${server.port}", path = "${fforesight.tenant-user-management.base-path:}") +public interface UserPreferenceClient extends UserPreferenceResource { + +} diff --git a/src/test/java/com/knecon/fforesight/feigntestclients/internal/InternalTenantsClient.java b/src/test/java/com/knecon/fforesight/feigntestclients/internal/InternalTenantsClient.java new file mode 100644 index 0000000..cceb7ba --- /dev/null +++ b/src/test/java/com/knecon/fforesight/feigntestclients/internal/InternalTenantsClient.java @@ -0,0 +1,10 @@ +package com.knecon.fforesight.feigntestclients.internal; + +import org.springframework.cloud.openfeign.FeignClient; + +import com.knecon.fforesight.tenantusermanagement.api.internal.InternalTenantsResource; + +@FeignClient(name = "InternalTenantsClient", url = "http://localhost:${server.port}", path = "/internal") +public interface InternalTenantsClient extends InternalTenantsResource { + +} diff --git a/src/test/java/com/knecon/fforesight/testcontainers/KeyCloakTestContainer.java b/src/test/java/com/knecon/fforesight/testcontainers/KeyCloakTestContainer.java new file mode 100644 index 0000000..f8b8f63 --- /dev/null +++ b/src/test/java/com/knecon/fforesight/testcontainers/KeyCloakTestContainer.java @@ -0,0 +1,66 @@ +package com.knecon.fforesight.testcontainers; + +import java.util.ArrayList; +import java.util.List; + +import org.keycloak.admin.client.resource.RealmResource; +import org.keycloak.admin.client.resource.UserResource; +import org.keycloak.representations.idm.ClientRepresentation; +import org.keycloak.representations.idm.RoleRepresentation; + +import dasniko.testcontainers.keycloak.KeycloakContainer; + +public class KeyCloakTestContainer { + + private static final String IMAGE_VERSION = "quay.io/keycloak/keycloak:21.0.0"; + private static KeycloakContainer keycloak = null; + + + private KeyCloakTestContainer() { + + } + + + public static KeycloakContainer getInstance() { + + if (keycloak == null) { + keycloak = new KeycloakContainer(IMAGE_VERSION).withAdminUsername("admin").withAdminPassword("admin"); + + keycloak.start(); + + var keycloakAdminClient = keycloak.getKeycloakAdminClient(); + var masterRealm = keycloakAdminClient.realm("master"); + + var adminClient = new ClientRepresentation(); + + adminClient.setId("adminClient"); + adminClient.setEnabled(true); + adminClient.setName("adminClient"); + adminClient.setSecret("adminClientSecret"); + adminClient.setServiceAccountsEnabled(true); + adminClient.setDirectAccessGrantsEnabled(true); + adminClient.setStandardFlowEnabled(true); + adminClient.setImplicitFlowEnabled(true); + adminClient.setDirectAccessGrantsEnabled(true); + masterRealm.clients().create(adminClient); + + RealmResource myRealm = keycloakAdminClient.realm("master"); + String userId = myRealm.clients().get("adminClient").getServiceAccountUser().getId(); + UserResource serviceAccountUser = myRealm.users().get(userId); + + ClientRepresentation clientThatOwnsRole = myRealm.clients().findByClientId("master-realm").get(0); + + String clientIdOfRoleOwner = clientThatOwnsRole.getId(); + + List roles = new ArrayList<>(); + roles.addAll(myRealm.clients().get(clientIdOfRoleOwner).roles().list()); + serviceAccountUser.roles().clientLevel(clientIdOfRoleOwner).add(roles); + serviceAccountUser.roles().realmLevel().add(List.of(myRealm.roles().get("create-realm").toRepresentation())); + + } + + return keycloak; + + } + +} diff --git a/src/test/java/com/knecon/fforesight/testcontainers/RedisTestContainer.java b/src/test/java/com/knecon/fforesight/testcontainers/RedisTestContainer.java new file mode 100644 index 0000000..38afa4c --- /dev/null +++ b/src/test/java/com/knecon/fforesight/testcontainers/RedisTestContainer.java @@ -0,0 +1,26 @@ +package com.knecon.fforesight.testcontainers; + +import org.testcontainers.containers.GenericContainer; +import org.testcontainers.utility.DockerImageName; + +public class RedisTestContainer extends GenericContainer { + + private static final String IMAGE_VERSION = "redis:6.2.6"; + private static RedisTestContainer container; + + + private RedisTestContainer() { + + super(DockerImageName.parse(IMAGE_VERSION)); + } + + + public static RedisTestContainer getInstance() { + + if (container == null) { + container = new RedisTestContainer().withExposedPorts(6379); + } + return container; + } + +} diff --git a/src/test/java/com/knecon/fforesight/testcontainers/SpringPostgreSQLTestContainer.java b/src/test/java/com/knecon/fforesight/testcontainers/SpringPostgreSQLTestContainer.java new file mode 100644 index 0000000..0d80a02 --- /dev/null +++ b/src/test/java/com/knecon/fforesight/testcontainers/SpringPostgreSQLTestContainer.java @@ -0,0 +1,25 @@ +package com.knecon.fforesight.testcontainers; + +import org.testcontainers.containers.PostgreSQLContainer; + +public class SpringPostgreSQLTestContainer extends PostgreSQLContainer { + + private static final String IMAGE_VERSION = "postgres:15.2"; + private static SpringPostgreSQLTestContainer container; + + + private SpringPostgreSQLTestContainer() { + + super(IMAGE_VERSION); + } + + + public static SpringPostgreSQLTestContainer getInstance() { + + if (container == null) { + container = new SpringPostgreSQLTestContainer(); + } + return container; + } + +} diff --git a/src/test/java/com/knecon/fforesight/tests/GeneralSettingsTest.java b/src/test/java/com/knecon/fforesight/tests/GeneralSettingsTest.java new file mode 100644 index 0000000..0717a84 --- /dev/null +++ b/src/test/java/com/knecon/fforesight/tests/GeneralSettingsTest.java @@ -0,0 +1,42 @@ +package com.knecon.fforesight.tests; + +import static org.assertj.core.api.Assertions.assertThat; + +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; + +import com.knecon.fforesight.AbstractTenantUserManagementIntegrationTest; +import com.knecon.fforesight.feigntestclients.external.GeneralSettingsClient; +import com.knecon.fforesight.tenantcommons.TenantContext; +import com.knecon.fforesight.tenantusermanagement.model.GeneralConfigurationModel; + +public class GeneralSettingsTest extends AbstractTenantUserManagementIntegrationTest { + + @Autowired + private GeneralSettingsClient generalSettingsClient; + + + @Test + public void testGeneralSettings() { + + TenantContext.setTenantId(AbstractTenantUserManagementIntegrationTest.TEST_TENANT_ID); + + var generalConfig = generalSettingsClient.getGeneralConfigurations(); + assertThat(generalConfig).isNotNull(); + + var updatedConfig = new GeneralConfigurationModel(); + updatedConfig.setAuxiliaryName("Test"); + updatedConfig.setDisplayName("Test"); + updatedConfig.setForgotPasswordFunctionEnabled(true); + generalSettingsClient.updateGeneralConfigurations(updatedConfig); + + generalConfig = generalSettingsClient.getGeneralConfigurations(); + assertThat(generalConfig.getAuxiliaryName()).isEqualTo(updatedConfig.getAuxiliaryName()); + assertThat(generalConfig.isForgotPasswordFunctionEnabled()).isEqualTo(updatedConfig.isForgotPasswordFunctionEnabled()); + assertThat(generalConfig.getDisplayName()).contains(updatedConfig.getDisplayName()); + + TenantContext.clear(); + + } + +} diff --git a/src/test/java/com/knecon/fforesight/IdentityTest.java b/src/test/java/com/knecon/fforesight/tests/IdentityTest.java similarity index 84% rename from src/test/java/com/knecon/fforesight/IdentityTest.java rename to src/test/java/com/knecon/fforesight/tests/IdentityTest.java index 3d8aed8..db216a5 100644 --- a/src/test/java/com/knecon/fforesight/IdentityTest.java +++ b/src/test/java/com/knecon/fforesight/tests/IdentityTest.java @@ -1,4 +1,4 @@ -package com.knecon.fforesight; +package com.knecon.fforesight.tests; import static org.junit.jupiter.api.Assumptions.assumeTrue; diff --git a/src/test/java/com/knecon/fforesight/tests/SMTPConfigurationTest.java b/src/test/java/com/knecon/fforesight/tests/SMTPConfigurationTest.java new file mode 100644 index 0000000..1cf095f --- /dev/null +++ b/src/test/java/com/knecon/fforesight/tests/SMTPConfigurationTest.java @@ -0,0 +1,53 @@ +package com.knecon.fforesight.tests; + +import static org.assertj.core.api.Assertions.assertThat; + +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; + +import com.knecon.fforesight.AbstractTenantUserManagementIntegrationTest; +import com.knecon.fforesight.feigntestclients.external.SMTPConfigurationClient; +import com.knecon.fforesight.tenantcommons.TenantContext; +import com.knecon.fforesight.tenantusermanagement.model.SMTPConfiguration; + +public class SMTPConfigurationTest extends AbstractTenantUserManagementIntegrationTest { + + @Autowired + private SMTPConfigurationClient smtpConfigurationClient; + + + @Test + public void testSMTPConfiguration() { + + TenantContext.setTenantId(AbstractTenantUserManagementIntegrationTest.TEST_TENANT_ID); + + try { + var currentSMTPConfiguration = smtpConfigurationClient.getCurrentSMTPConfiguration(); + } catch (Exception e) { + System.out.println(e.getMessage()); + } + + SMTPConfiguration newConfig = new SMTPConfiguration(); + newConfig.setAuth(true); + newConfig.setFrom("from@knecon.com"); + newConfig.setHost("test.knecon.com"); + newConfig.setPassword("secret"); + newConfig.setUser("user"); + newConfig.setStarttls(true); + newConfig.setSsl(false); + smtpConfigurationClient.updateSMTPConfiguration(newConfig); + + var currentSMTPConfiguration = smtpConfigurationClient.getCurrentSMTPConfiguration(); + assertThat(currentSMTPConfiguration.getPassword()).matches("\\**"); + assertThat(currentSMTPConfiguration.getUser()).isEqualTo("user"); + assertThat(currentSMTPConfiguration.getHost()).isEqualTo("test.knecon.com"); + assertThat(currentSMTPConfiguration.isSsl()).isFalse(); + assertThat(currentSMTPConfiguration.isStarttls()).isTrue(); + assertThat(currentSMTPConfiguration.isAuth()).isTrue(); + assertThat(currentSMTPConfiguration.getFrom()).isEqualTo("from@knecon.com"); + + TenantContext.clear(); + + } + +} diff --git a/src/test/java/com/knecon/fforesight/tests/StartupTest.java b/src/test/java/com/knecon/fforesight/tests/StartupTest.java new file mode 100644 index 0000000..7981de0 --- /dev/null +++ b/src/test/java/com/knecon/fforesight/tests/StartupTest.java @@ -0,0 +1,25 @@ +package com.knecon.fforesight.tests; + +import static org.assertj.core.api.Assertions.assertThat; + +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; + +import com.knecon.fforesight.AbstractTenantUserManagementIntegrationTest; +import com.knecon.fforesight.feigntestclients.internal.InternalTenantsClient; + +public class StartupTest extends AbstractTenantUserManagementIntegrationTest { + + @Autowired + private InternalTenantsClient internalTenantsClient; + + + @Test + public void testStartup() { + + var simpleTenants = internalTenantsClient.getSimpleTenants(); + assertThat(simpleTenants).isNotEmpty(); + + } + +} diff --git a/src/test/java/com/knecon/fforesight/tests/TenantsTest.java b/src/test/java/com/knecon/fforesight/tests/TenantsTest.java new file mode 100644 index 0000000..d02dac2 --- /dev/null +++ b/src/test/java/com/knecon/fforesight/tests/TenantsTest.java @@ -0,0 +1,40 @@ +package com.knecon.fforesight.tests; + +import static org.assertj.core.api.Assertions.assertThat; + +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; + +import com.knecon.fforesight.AbstractTenantUserManagementIntegrationTest; +import com.knecon.fforesight.feigntestclients.external.TenantsClient; +import com.knecon.fforesight.tenantcommons.TenantContext; +import com.knecon.fforesight.tenantusermanagement.api.external.TenantsResource; +import com.knecon.fforesight.utils.TestTenantService; + +public class TenantsTest extends AbstractTenantUserManagementIntegrationTest { + + @Autowired + private TenantsClient tenantsClient; + + @Autowired + private TestTenantService testTenantService; + + + @Test + public void testCreateNewTenant() { + + testTenantService.createTestTenantIfNotExists("new_tenant"); + + TenantContext.setTenantId("new_tenant"); + + var deploymentKey = tenantsClient.getDeploymentKey("new_tenant"); + assertThat(deploymentKey.getValue()).isNotBlank(); + + var tenant = tenantsClient.getTenant("new_tenant"); + assertThat(tenant.getGuid()).isNotBlank(); + + assertThat(tenantsClient.getTenants().stream().anyMatch(t -> t.getTenantId().equals("new_tenant"))).isTrue(); + TenantContext.clear(); + } + +} diff --git a/src/test/java/com/knecon/fforesight/tests/UserPreferenceTest.java b/src/test/java/com/knecon/fforesight/tests/UserPreferenceTest.java new file mode 100644 index 0000000..85d770b --- /dev/null +++ b/src/test/java/com/knecon/fforesight/tests/UserPreferenceTest.java @@ -0,0 +1,39 @@ +package com.knecon.fforesight.tests; + +import static org.assertj.core.api.Assertions.assertThat; + +import java.util.List; + +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; + +import com.knecon.fforesight.AbstractTenantUserManagementIntegrationTest; +import com.knecon.fforesight.feigntestclients.external.UserPreferenceClient; +import com.knecon.fforesight.tenantcommons.TenantContext; + +public class UserPreferenceTest extends AbstractTenantUserManagementIntegrationTest { + + @Autowired + private UserPreferenceClient userPreferenceClient; + + @Test + public void testUserPreferences(){ + + TenantContext.setTenantId(AbstractTenantUserManagementIntegrationTest.TEST_TENANT_ID); + + var allMyAttributes = userPreferenceClient.getAllUserAttributes(); + assertThat(allMyAttributes).isEmpty(); + + userPreferenceClient.setAttribute("test", List.of("1","2","3")); + allMyAttributes = userPreferenceClient.getAllUserAttributes(); + assertThat(allMyAttributes).hasEntrySatisfying("test", k -> assertThat(k).containsExactly("1","2","3")); + + userPreferenceClient.deleteAttribute("test"); + + allMyAttributes = userPreferenceClient.getAllUserAttributes(); + assertThat(allMyAttributes).isEmpty(); + + TenantContext.clear(); + } + +} diff --git a/src/test/java/com/knecon/fforesight/tests/UserTest.java b/src/test/java/com/knecon/fforesight/tests/UserTest.java new file mode 100644 index 0000000..48319e7 --- /dev/null +++ b/src/test/java/com/knecon/fforesight/tests/UserTest.java @@ -0,0 +1,81 @@ +package com.knecon.fforesight.tests; + +import static org.assertj.core.api.Assertions.assertThat; + +import java.util.HashSet; +import java.util.List; + +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; + +import com.knecon.fforesight.AbstractTenantUserManagementIntegrationTest; +import com.knecon.fforesight.feigntestclients.external.UserClient; +import com.knecon.fforesight.tenantcommons.TenantContext; +import com.knecon.fforesight.tenantusermanagement.model.CreateUserRequest; +import com.knecon.fforesight.tenantusermanagement.model.UpdateMyProfileRequest; +import com.knecon.fforesight.tenantusermanagement.model.UpdateProfileRequest; +import com.knecon.fforesight.tenantusermanagement.properties.TenantUserManagementProperties; + +public class UserTest extends AbstractTenantUserManagementIntegrationTest { + + @Autowired + private UserClient userClient; + + @Autowired + private TenantUserManagementProperties tenantUserManagementProperties; + + + @Test + public void testUsers() { + + TenantContext.setTenantId(AbstractTenantUserManagementIntegrationTest.TEST_TENANT_ID); + + var allUsers = userClient.getAllUsers(true); + var testUserFound = allUsers.stream().anyMatch(u -> u.getEmail().equalsIgnoreCase("test@fforesight.com")); + assertThat(allUsers).isNotEmpty(); + assertThat(testUserFound).isTrue(); + + allUsers = userClient.getApplicationSpecificUsers(true); + testUserFound = allUsers.stream().anyMatch(u -> u.getEmail().equalsIgnoreCase("test@fforesight.com")); + assertThat(allUsers).isNotEmpty(); + assertThat(testUserFound).isTrue(); + + var testUserId = allUsers.iterator().next().getUserId(); + var testUser = userClient.getUserById(testUserId); + assertThat(testUser).isNotNull(); + + testUser = userClient.updateMyProfile(UpdateMyProfileRequest.builder().email("test@fforesight.com").firstName("updateTestFirstName").lastName("updateTestLastName").build()); + assertThat(testUser.getLastName()).isEqualTo("updateTestLastName"); + assertThat(testUser.getFirstName()).isEqualTo("updateTestFirstName"); + + CreateUserRequest createUserRequest = new CreateUserRequest(); + createUserRequest.setEmail("test.new.user@knecon.com"); + createUserRequest.setFirstName("Test"); + createUserRequest.setLastName("New User"); + createUserRequest.setUsername(createUserRequest.getEmail()); + createUserRequest.setRoles(tenantUserManagementProperties.getKcRoleMapping().getAllRoles()); + var createdUser = userClient.createUser(createUserRequest); + + allUsers = userClient.getAllUsers(true); + assertThat(allUsers).hasSize(2); + + createdUser = userClient.activateProfile(createdUser.getUserId(), true); + assertThat(createdUser.isActive()).isTrue(); + + createdUser = userClient.activateProfile(createdUser.getUserId(), false); + assertThat(createdUser.isActive()).isFalse(); + + createdUser = userClient.setRoles(createdUser.getUserId(), new HashSet<>()); + assertThat(createdUser.getRoles()).isEmpty(); + + createdUser = userClient.updateProfile(createdUser.getUserId(), + UpdateProfileRequest.builder().email("test.new.user@knecon.com").firstName("update test").lastName("update test").roles(tenantUserManagementProperties.getKcRoleMapping().getAllRoles()).build()); + assertThat(createdUser.getRoles()).containsExactly(tenantUserManagementProperties.getKcRoleMapping().getAllRoles().toArray(new String[0])); + + userClient.deleteUsers(List.of(createdUser.getUserId())); + + allUsers = userClient.getAllUsers(true); + assertThat(allUsers).hasSize(1); + } + +} diff --git a/src/test/java/com/knecon/fforesight/utils/FeignRequestInterceptor.java b/src/test/java/com/knecon/fforesight/utils/FeignRequestInterceptor.java new file mode 100644 index 0000000..8a487d2 --- /dev/null +++ b/src/test/java/com/knecon/fforesight/utils/FeignRequestInterceptor.java @@ -0,0 +1,25 @@ +package com.knecon.fforesight.utils; + +import org.springframework.stereotype.Component; + +import feign.RequestInterceptor; +import feign.RequestTemplate; +import lombok.RequiredArgsConstructor; + +@Component +@RequiredArgsConstructor +public class FeignRequestInterceptor implements RequestInterceptor { + + private final TokenService tokenService; + + + @Override + public void apply(RequestTemplate requestTemplate) { + + if (!requestTemplate.path().startsWith("/internal") || requestTemplate.feignTarget().url().endsWith("/internal")) { + var token = tokenService.getToken(); + requestTemplate.header("Authorization", "bearer " + token); + } + } + +} diff --git a/src/test/java/com/knecon/fforesight/utils/TestTenantService.java b/src/test/java/com/knecon/fforesight/utils/TestTenantService.java new file mode 100644 index 0000000..0d72fa9 --- /dev/null +++ b/src/test/java/com/knecon/fforesight/utils/TestTenantService.java @@ -0,0 +1,71 @@ +package com.knecon.fforesight.utils; + +import static org.assertj.core.api.Assertions.assertThat; + +import java.util.List; +import java.util.Set; +import java.util.UUID; + +import org.springframework.stereotype.Service; + +import com.knecon.fforesight.feigntestclients.external.TenantsClient; +import com.knecon.fforesight.tenantcommons.TenantContext; +import com.knecon.fforesight.tenantcommons.model.DatabaseConnection; +import com.knecon.fforesight.tenantcommons.model.S3StorageConnection; +import com.knecon.fforesight.tenantcommons.model.SearchConnection; +import com.knecon.fforesight.tenantusermanagement.api.internal.InternalTenantsResource; +import com.knecon.fforesight.tenantusermanagement.model.TenantRequest; +import com.knecon.fforesight.tenantusermanagement.model.TenantUser; +import com.knecon.fforesight.testcontainers.SpringPostgreSQLTestContainer; + +import lombok.RequiredArgsConstructor; + +@Service +@RequiredArgsConstructor +public class TestTenantService { + + private final InternalTenantsResource internalTenantsResource; + private final TenantsClient tenantsClient; + + private final TokenService tokenService; + + public void createTestTenantIfNotExists(String testTenantId) { + + try { + var tenantExists = internalTenantsResource.getTenant(testTenantId); + assertThat(tenantExists.getGuid()).isNotBlank(); + + }catch (Exception e) { + // not found + var tenantRequest = TenantRequest.builder() + .tenantId(testTenantId) + .displayName(testTenantId) + .guid(UUID.randomUUID().toString()) + .defaultUsers(List.of(TenantUser.builder().roles(Set.of("SUPER_USER")).username("test@fforesight.com").password("secret").email("test@fforesight.com").build())) + .databaseConnection(DatabaseConnection.builder() + .driver("postgresql") + .host(SpringPostgreSQLTestContainer.getInstance().getHost()) + .port(String.valueOf(SpringPostgreSQLTestContainer.getInstance().getFirstMappedPort())) + .database(SpringPostgreSQLTestContainer.getInstance().getDatabaseName()) + .schema(testTenantId) + .username(SpringPostgreSQLTestContainer.getInstance().getUsername()) + .password(SpringPostgreSQLTestContainer.getInstance().getPassword()) + .build()) + .searchConnection(SearchConnection.builder().hosts(Set.of("localhost")).port(9200).scheme("http").numberOfShards("1").numberOfReplicas("5").build()) + .s3StorageConnection(S3StorageConnection.builder().key("minioadmin").secret("minioadmin").bucketName("redaction").endpoint("http://localhost:9000").build()) + .build(); + + var response = internalTenantsResource.createTenant(tenantRequest); + + assertThat(response.getGuid()).isNotBlank(); + + TenantContext.setTenantId(testTenantId); + tokenService.setUser("test@fforesight.com", "secret"); + + var tenant = tenantsClient.getTenant(testTenantId); + assertThat(tenant.getGuid()).isNotBlank(); + } + + } + +} diff --git a/src/test/java/com/knecon/fforesight/utils/TokenService.java b/src/test/java/com/knecon/fforesight/utils/TokenService.java new file mode 100644 index 0000000..5875d90 --- /dev/null +++ b/src/test/java/com/knecon/fforesight/utils/TokenService.java @@ -0,0 +1,81 @@ +package com.knecon.fforesight.utils; + +import java.io.InputStream; +import java.io.InputStreamReader; +import java.util.concurrent.TimeUnit; + +import javax.ws.rs.BadRequestException; + +import org.apache.commons.io.IOUtils; +import org.jboss.resteasy.client.jaxrs.ResteasyClientBuilder; +import org.jboss.resteasy.client.jaxrs.internal.ResteasyClientBuilderImpl; +import org.keycloak.OAuth2Constants; +import org.keycloak.admin.client.KeycloakBuilder; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import com.knecon.fforesight.tenantcommons.TenantContext; +import com.knecon.fforesight.tenantusermanagement.properties.TenantUserManagementProperties; + +import lombok.SneakyThrows; +import lombok.extern.slf4j.Slf4j; + +@Slf4j +@Service +public class TokenService { + + @Autowired + private TenantUserManagementProperties tenantUserManagementProperties; + private String username; + private String password; + + private String accessToken = null; + + + public void setUser(String username, String password) { + + this.username = username; + this.password = password; + this.accessToken = null; + } + + + @SneakyThrows + public String getToken() { + + if(TenantContext.getTenantId() == null){ + return null; + } + + if (accessToken != null) { + return accessToken; + } + + var tokenClient = KeycloakBuilder.builder() + .serverUrl(tenantUserManagementProperties.getServerUrl()) + .realm(TenantContext.getTenantId()) + .username(username) + .password(password) + .clientId(tenantUserManagementProperties.getApplicationClientId()) + .grantType(OAuth2Constants.PASSWORD) + .resteasyClient(new ResteasyClientBuilderImpl().connectionTTL(2, TimeUnit.SECONDS) + .hostnameVerification(ResteasyClientBuilder.HostnameVerificationPolicy.ANY) + .connectionPoolSize(tenantUserManagementProperties.getConnectionPoolSize()) + .disableTrustManager() + .build()) + .build(); + + try { + accessToken = tokenClient.tokenManager().getAccessTokenString(); + return accessToken; + }catch (BadRequestException e){ + var response = IOUtils.toString(new InputStreamReader((InputStream) e.getResponse().getEntity())); + log.warn("Exception getting token: {}",response, e); + throw e; + } finally { + tokenClient.close(); + } + + } + +} diff --git a/src/test/resources/application.yaml b/src/test/resources/application.yaml new file mode 100644 index 0000000..8455b38 --- /dev/null +++ b/src/test/resources/application.yaml @@ -0,0 +1,131 @@ +server: + port: 28181 + +management: + endpoint: + metrics.enabled: ${monitoring.enabled:false} + prometheus.enabled: ${monitoring.enabled:false} + health.enabled: true + endpoints.web.exposure.include: prometheus, health, metrics + metrics.export.prometheus.enabled: ${monitoring.enabled:false} + +info: + description: Tenant User Management Service + + +spring: + datasource: + url: jdbc:postgresql://${PSQL_HOST:localhost}:${PSQL_PORT:5432}/${PSQL_DATABASE:master}?cachePrepStmts=true&useServerPrepStmts=true&rewriteBatchedStatements=true + driverClassName: org.postgresql.Driver + username: ${PSQL_USERNAME:fforesight} + password: ${PSQL_PASSWORD:fforesight} + platform: org.hibernate.dialect.PostgreSQL95Dialect + hikari: + maximumPoolSize: 2 + minimum-idle: 2 + data-source-properties: + cachePrepStmts: true + prepStmtCacheSize: 1000 + prepStmtCacheSqlLimit: 2048 + jackson: + serialization: + write-dates-as-timestamps: false + deserialization: + accept-single-value-as-array: true + main: + allow-bean-definition-overriding: true + allow-circular-references: true + jpa: + open-in-view: true + database-platform: org.hibernate.dialect.PostgreSQL95Dialect + hibernate: + ddl-auto: none + naming-strategy: org.hibernate.cfg.ImprovedNamingStrategy + properties: + hibernate: + jdbc: + batch_size: 1000 + order_inserts: true + order_updates: true + cache: + type: redis + mvc: + pathmatch: + matching-strategy: ant-path-matcher + redis: + host: ${REDIS_HOST:localhost} + port: ${REDIS_PORT:6379} + password: ${REDIS_PASSWORD:} + + + rabbitmq: + host: ${RABBITMQ_HOST:localhost} + port: ${RABBITMQ_PORT:5672} + username: ${RABBITMQ_USERNAME:user} + password: ${RABBITMQ_PASSWORD:rabbitmq} + listener: + simple: + acknowledge-mode: AUTO + concurrency: 5 + retry: + enabled: true + max-attempts: 3 + max-interval: 15000 + prefetch: 1 + + liquibase: + change-log: classpath:/db/changelog/db.changelog-master.yaml + enabled: true + application: + name: tenant-user-management + data: + redis: + host: ${REDIS_HOST:localhost} + port: ${REDIS_PORT:6379} + password: ${REDIS_PASSWORD:} +fforesight: + keycloak: + ignored-endpoints: [ '/actuator/health', '/tenant-user-management','/internal/**','/tenant-user-management/docs/**','/tenant-user-management/docs','/tenant-user-management/tenants/simple' ] + enabled: true + springdoc: + base-path: '/tenant-user-management' + auth-server-url: '/auth' + enabled: true + default-client-id: 'swagger-ui-client' + default-tenant: 'fforesight' + tenant-exchange: + name: 'tenants-exchange' + user-exchange: + name: 'users-exchange' + tenant-user-management: + base-path: '/tenant-user-management' + realm: master + server-url: http://localhost:28181 + client-secret: adminClientSecret + client-id: adminClient + kc-role-mapping: + roles: + - name: SUPER_USER + set-by-default: true + rank: 100 + permissions: + - 'fforesight-read-general-configuration' + - 'fforesight-write-general-configuration' + - 'fforesight-manage-user-preferences' + - 'fforesight-read-users' + - 'fforesight-read-all-users' + - 'fforesight-write-users' + - 'fforesight-update-my-profile' + - 'fforesight-create-tenant' + - 'fforesight-get-tenants' + - 'fforesight-deployment-info' + - 'fforesight-read-smtp-configuration' + - 'fforesight-write-smtp-configuration' + access-token-life-span: 86400 + application-name: tenant-user-management + application-client-id: tenant-user-management + swagger-client-secret: 'testSecret123!' + +cors.enabled: true +springdoc: + packages-to-scan: [ 'com.knecon.fforesight.tenantusermanagement.controller.external' ]