Merge branch 'RED-7006' into 'main'

Red 7006 - add endpoint to update tenant

See merge request fforesight/tenant-user-management-service!1
This commit is contained in:
Timo Bejan 2023-07-13 11:16:10 +02:00
commit 5f3418ad3b
12 changed files with 167 additions and 10 deletions

View File

@ -7,8 +7,8 @@ import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseStatus;
import com.knecon.fforesight.tenantcommons.model.TenantResponse;
@ -44,6 +44,10 @@ public interface TenantsResource {
@ApiResponses(value = {@ApiResponse(responseCode = "200", description = "OK")})
TenantResponse getTenant(@PathVariable("tenantId") String tenantId);
@PutMapping(value = "/tenants/{tenantId}", consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
@Operation(summary = "Update existing tenant", description = "None")
@ApiResponses(value = {@ApiResponse(responseCode = "200", description = "OK")})
TenantResponse updateTenant(@PathVariable("tenantId") String tenantId, @RequestBody TenantRequest tenantRequest);
@GetMapping(value = "/tenants/simple", produces = MediaType.APPLICATION_JSON_VALUE)
@Operation(summary = "Gets all existing tenant in a simplified format", description = "None")

View File

@ -7,8 +7,8 @@ import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseStatus;
import com.knecon.fforesight.tenantcommons.model.TenantResponse;
@ -51,6 +51,11 @@ public interface InternalTenantsResource {
@ApiResponses(value = {@ApiResponse(responseCode = "200", description = "OK")})
TenantResponse getTenant(@PathVariable("tenantId") String tenantId);
@PutMapping(value = "/tenants/{tenantId}", consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
@Operation(summary = "Update existing tenant", description = "None")
@ApiResponses(value = {@ApiResponse(responseCode = "200", description = "OK")})
TenantResponse updateTenant(@PathVariable("tenantId") String tenantId, @RequestBody TenantRequest tenantRequest);
@GetMapping(value = "/tenants/simple", produces = MediaType.APPLICATION_JSON_VALUE)
@Operation(summary = "Gets all existing tenant in a simplified format", description = "None")

View File

@ -3,6 +3,7 @@ package com.knecon.fforesight.tenantusermanagement.controller.external;
import static com.knecon.fforesight.tenantusermanagement.permissions.UserManagementPermissions.CREATE_TENANT;
import static com.knecon.fforesight.tenantusermanagement.permissions.UserManagementPermissions.DEPLOYMENT_INFO;
import static com.knecon.fforesight.tenantusermanagement.permissions.UserManagementPermissions.GET_TENANTS;
import static com.knecon.fforesight.tenantusermanagement.permissions.UserManagementPermissions.UPDATE_TENANT;
import java.util.List;
@ -63,6 +64,13 @@ public class TenantsController implements TenantsResource, PublicResource {
return tenantManagementService.getTenants().stream().map(t -> new SimpleTenantResponse(t.getTenantId(), t.getDisplayName(), t.getGuid())).toList();
}
@PreAuthorize("hasAuthority('" + UPDATE_TENANT + "')")
public TenantResponse updateTenant(String tenantId,
@RequestBody TenantRequest tenantRequest) {
return tenantManagementService.updateTenant(tenantId, tenantRequest);
}
@PreAuthorize("hasAuthority('" + DEPLOYMENT_INFO + "')")
public DeploymentKeyResponse getDeploymentKey(@PathVariable(TENANT_ID_PARAM) String tenantId) {

View File

@ -10,7 +10,6 @@ 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;
@ -59,6 +58,13 @@ public class InternalTenantsController implements InternalTenantsResource, Inter
}
@Override
public TenantResponse updateTenant(String tenantId, TenantRequest tenantRequest) {
return tenantManagementService.updateTenant(tenantId, tenantRequest);
}
public List<SimpleTenantResponse> getSimpleTenants() {
return tenantManagementService.getTenants().stream().map(t -> new SimpleTenantResponse(t.getTenantId(), t.getDisplayName(), t.getGuid())).toList();

View File

@ -18,6 +18,7 @@ public class UserManagementPermissions {
// Multitenancy
public static final String CREATE_TENANT = "fforesight-create-tenant";
public static final String GET_TENANTS = "fforesight-get-tenants";
public static final String UPDATE_TENANT = "fforesight-update-tenant";
public static final String DEPLOYMENT_INFO = "fforesight-deployment-info";
// SMTP

View File

@ -82,7 +82,7 @@ public class TenantManagementService implements TenantProvider {
@SneakyThrows
public TenantResponse createTenant(TenantRequest tenantRequest) {
log.info("Tenants are: {}", tenantRepository.findAll().stream().map(t -> t.getTenantId()).collect(Collectors.toList()));
log.info("Tenants are: {}", tenantRepository.findAll().stream().map(TenantEntity::getTenantId).collect(Collectors.toList()));
log.info("Requested to create tenant for: {}", tenantRequest.getTenantId());
try {
@ -352,6 +352,69 @@ public class TenantManagementService implements TenantProvider {
return tenantRepository.findById(tenantId).map(this::convert).orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND, "Tenant does not exist"));
}
public TenantResponse updateTenant(String tenantId, TenantRequest tenantRequest) {
var tenant = tenantRepository.findById(tenantId);
if (tenant.isPresent()) {
var tenantEntity = tenant.get();
tenantEntity.setDisplayName(tenantRequest.getDisplayName());
var databaseConnection = tenantRequest.getDatabaseConnection();
if (databaseConnection != null) {
tenantEntity.setDatabaseConnection(DatabaseConnectionEntity.builder()
.driver(databaseConnection.getDriver())
.host(databaseConnection.getHost())
.port(databaseConnection.getPort())
.database(databaseConnection.getDatabase())
.schema(databaseConnection.getSchema())
.username(databaseConnection.getUsername())
.password(encryptionService.encrypt(databaseConnection.getPassword()))
.params(databaseConnection.getParams())
.build());
}
var searchConnection = tenantRequest.getSearchConnection();
if (searchConnection != null) {
tenantEntity.setSearchConnection(SearchConnectionEntity.builder()
.hosts(searchConnection.getHosts())
.port(searchConnection.getPort())
.scheme(searchConnection.getScheme())
.username(searchConnection.getUsername())
.password(encryptionService.encrypt(searchConnection.getPassword()))
.numberOfShards(searchConnection.getNumberOfShards())
.numberOfReplicas(searchConnection.getNumberOfReplicas())
.build());
}
var azureStorageConnection = tenantRequest.getAzureStorageConnection();
if (azureStorageConnection != null) {
tenantEntity
.setAzureStorageConnection(AzureStorageConnectionEntity.builder()
.connectionString(encryptionService.encrypt(azureStorageConnection.getConnectionString()))
.containerName(azureStorageConnection.getContainerName())
.build());
}
var s3StorageConnection = tenantRequest.getS3StorageConnection();
if (s3StorageConnection != null) {
tenantEntity
.setS3StorageConnection(S3StorageConnectionEntity.builder()
.key(s3StorageConnection.getKey())
.secret(encryptionService.encrypt(s3StorageConnection.getSecret()))
.signerType(s3StorageConnection.getSignerType())
.bucketName(s3StorageConnection.getBucketName())
.region(s3StorageConnection.getRegion())
.endpoint(s3StorageConnection.getEndpoint())
.build());
}
return convert(tenantRepository.save(tenantEntity));
} else {
throw new ResponseStatusException(HttpStatus.NOT_FOUND, "Tenant does not exist");
}
}
public List<TenantResponse> getTenants() {

View File

@ -23,6 +23,7 @@ fforesight:
- 'fforesight-update-my-profile'
- 'fforesight-create-tenant'
- 'fforesight-get-tenants'
- 'fforesight-update-tenant'
- 'fforesight-deployment-info'
- 'fforesight-read-smtp-configuration'
- 'fforesight-write-smtp-configuration'

View File

@ -13,7 +13,7 @@ fforesight:
default-theme: 'scm'
valid-redirect-uris: [ '/redaction-gateway-v1/*','/tenant-user-management/*','http://localhost:4200/*','/ui/*' ,'/auth/*' ]
kc-role-mapping:
unmappedPermissions: [ "red-unarchive-dossier", "red-update-license", "fforesight-create-tenant" ]
unmappedPermissions: [ "red-unarchive-dossier", "red-update-license", "fforesight-create-tenant", "fforesight-update-tenant" ]
compositeRoles:
- name: RED_MANAGER
composites:
@ -45,7 +45,7 @@ fforesight:
"red-read-legal-basis", "red-read-license-report", "red-read-notification", "red-read-rules", "fforesight-read-smtp-configuration", "red-read-versions", "red-read-watermark",
"red-reindex", "red-search-audit-log", "red-update-notification", "red-upload-report-template", "red-write-colors", "red-write-digital-signature", "red-write-dossier-attributes-config",
"red-write-dossier-templates", "red-write-file-attributes-config", "fforesight-write-general-configuration", "red-write-legal-basis", "red-write-rules", "fforesight-write-smtp-configuration",
"red-write-watermark", "red-write-app-configuration", "red-manage-acl-permissions", "fforesight-create-tenant", "fforesight-get-tenants", "fforesight-deployment-info" ]
"red-write-watermark", "red-write-app-configuration", "red-manage-acl-permissions", "fforesight-create-tenant", "fforesight-get-tenants", "fforesight-update-tenant", "fforesight-deployment-info" ]
- name: RED_MANAGER
set-by-default: false
rank: 200

View File

@ -8,7 +8,7 @@ fforesight:
default-theme: 'redaction'
valid-redirect-uris: [ '/redaction-gateway-v1/*','/tenant-user-management/*','http://localhost:4200/*','/ui/*' ,'/auth/*']
kc-role-mapping:
unmappedPermissions: [ "red-unarchive-dossier", "red-update-license", "red-get-rss","fforesight-create-tenant" ]
unmappedPermissions: [ "red-unarchive-dossier", "red-update-license", "red-get-rss","fforesight-create-tenant", "fforesight-update-tenant" ]
compositeRoles:
- name: RED_MANAGER
composites:
@ -40,7 +40,7 @@ fforesight:
"red-read-legal-basis", "red-read-license-report", "red-read-notification", "red-read-rules", "fforesight-read-smtp-configuration", "red-read-versions", "red-read-watermark",
"red-reindex", "red-search-audit-log", "red-update-notification", "red-upload-report-template", "red-write-colors", "red-write-digital-signature", "red-write-dossier-attributes-config",
"red-write-dossier-templates", "red-write-file-attributes-config", "fforesight-write-general-configuration", "red-write-legal-basis", "red-write-rules", "fforesight-write-smtp-configuration",
"red-write-watermark", "red-write-app-configuration", "red-manage-acl-permissions", "fforesight-create-tenant", "fforesight-get-tenants", "fforesight-deployment-info" ]
"red-write-watermark", "red-write-app-configuration", "red-manage-acl-permissions", "fforesight-create-tenant", "fforesight-get-tenants", "fforesight-update-tenant", "fforesight-deployment-info" ]
- name: RED_MANAGER
set-by-default: false
rank: 200

View File

@ -2,13 +2,21 @@ package com.knecon.fforesight.tests;
import static org.assertj.core.api.Assertions.assertThat;
import java.util.Map;
import java.util.Set;
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.EncryptionDecryptionService;
import com.knecon.fforesight.tenantcommons.TenantContext;
import com.knecon.fforesight.tenantusermanagement.api.external.TenantsResource;
import com.knecon.fforesight.tenantcommons.model.AzureStorageConnection;
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.utils.TestTenantService;
public class TenantsTest extends AbstractTenantUserManagementIntegrationTest {
@ -19,6 +27,9 @@ public class TenantsTest extends AbstractTenantUserManagementIntegrationTest {
@Autowired
private TestTenantService testTenantService;
@Autowired
private EncryptionDecryptionService encryptionService;
@Test
public void testCreateNewTenant() {
@ -37,4 +48,62 @@ public class TenantsTest extends AbstractTenantUserManagementIntegrationTest {
TenantContext.clear();
}
@Test
public void testUpdateTenant() {
testTenantService.createTestTenantIfNotExists("new_tenant");
TenantContext.setTenantId("new_tenant");
var tenantRequest = TenantRequest.builder()
.tenantId("new_tenant")
.displayName("updated_display_name")
.searchConnection(SearchConnection.builder()
.numberOfReplicas("1")
.hosts(Set.of("updated_host"))
.numberOfShards("2")
.password("updated_pwd")
.port(123)
.username("updated_username")
.scheme("updated_scheme")
.build())
.databaseConnection(DatabaseConnection.builder()
.database("updated_db")
.driver("updated_driver")
.host("updated_host")
.port("123")
.schema("updated_schema")
.params(Map.of("key", "value"))
.password("updated_pwd")
.username("updated_username")
.build())
.s3StorageConnection(S3StorageConnection.builder()
.key("updated_key")
.bucketName("updated_bucket")
.endpoint("updated_endpoint")
.region("updated_region")
.secret("updated_secret")
.signerType("updated_signer")
.build())
.azureStorageConnection(AzureStorageConnection.builder()
.connectionString("updated_connection")
.containerName("updated_container")
.build())
.build();
var tenantEntity = tenantsClient.updateTenant("new_tenant", tenantRequest);
tenantRequest.getS3StorageConnection().setSecret(encryptionService.encrypt("updated_secret"));
tenantRequest.getAzureStorageConnection().setConnectionString(encryptionService.encrypt("updated_connection"));
tenantRequest.getSearchConnection().setPassword(encryptionService.encrypt("updated_pwd"));
tenantRequest.getDatabaseConnection().setPassword(encryptionService.encrypt("updated_pwd"));
assertThat(tenantEntity.getDisplayName()).isEqualTo(tenantRequest.getDisplayName());
assertThat(tenantEntity.getS3StorageConnection()).isEqualTo(tenantRequest.getS3StorageConnection());
assertThat(tenantEntity.getAzureStorageConnection()).isEqualTo(tenantRequest.getAzureStorageConnection());
assertThat(tenantEntity.getSearchConnection()).isEqualTo(tenantRequest.getSearchConnection());
assertThat(tenantEntity.getDatabaseConnection()).isEqualTo(tenantRequest.getDatabaseConnection());
TenantContext.clear();
}
}

View File

@ -30,7 +30,6 @@ public class TokenService {
private String password;
private String accessToken;
@SuppressWarnings("PMD")
public void setUser(String username, String password) {

View File

@ -118,6 +118,7 @@ fforesight:
- 'fforesight-update-my-profile'
- 'fforesight-create-tenant'
- 'fforesight-get-tenants'
- 'fforesight-update-tenant'
- 'fforesight-deployment-info'
- 'fforesight-read-smtp-configuration'
- 'fforesight-write-smtp-configuration'