Pull request #620: RED-6162 - fixed swagger url

Merge in RED/persistence-service from RED-6162 to master

* commit 'cf6af4ba916b2666df6aab21730fc16fa69e2585':
  RED-5255 - ported to merged version - pmd fix
  RED-5255 - ported to merged version
  RED-6162 - fixed swagger url
This commit is contained in:
Timo Bejan 2023-03-10 13:22:42 +01:00
commit e26fba1c63
21 changed files with 156 additions and 41 deletions

View File

@ -76,11 +76,9 @@ public class SecuredKeyCloakConfiguration extends KeycloakWebSecurityConfigurerA
web.ignoring().antMatchers("/actuator/health/**",
"/redaction-gateway-v1/async/download/with-ott/**",
"/api/async/download/with-ott/**",
"/api/docs",
"/api/docs/**",
"/",
"/api",
"/redaction-gateway-v1/docs/**",
"/redaction-gateway-v1/docs",
"/redaction-gateway-v1",
"/internal-api/**");
web.ignoring().antMatchers(HttpMethod.OPTIONS, "/**");

View File

@ -38,7 +38,7 @@ public class GeneralConfigurationService {
return GeneralConfigurationModel.builder()
.auxiliaryName(auxiliaryName)
.displayName(realm.getDisplayNameHtml())
.forgotPasswordFunctionEnabled(realm.isResetPasswordAllowed())
.forgotPasswordFunctionEnabled(realm.isResetPasswordAllowed() != null && realm.isResetPasswordAllowed())
.build();
}

View File

@ -50,7 +50,6 @@ public class SwaggerAutoConfiguration {
private static final String DESCRIPTION = "Description for redaction";
private static final String VERSION = "1.0";
private static final String OAUTH_NAME = "RED-OAUTH";
private static final String PROTOCOL_URL_FORMAT = "/auth/realms/%s/protocol/openid-connect";
@Autowired

View File

@ -29,10 +29,10 @@ public class SwaggerHomeController {
}
@GetMapping({"/api", "/"})
@GetMapping({"/redaction-gateway-v1", "/","redaction-gateway-v1/docs"})
public void home(HttpServletRequest request, HttpServletResponse response) throws IOException {
response.sendRedirect(contextPath + "/api/docs/swagger-ui");
response.sendRedirect(contextPath + "/redaction-gateway-v1/docs/swagger-ui");
}
}

View File

@ -1,7 +1,5 @@
package com.iqser.red.service.persistence.management.v1.processor.acl;
import javax.sql.DataSource;
import org.springframework.cache.CacheManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

View File

@ -10,15 +10,15 @@ import lombok.Getter;
public class RedPermission extends AbstractPermission implements Permission {
public static final RedPermission VIEW_OBJECT = new RedPermission("VIEW_OBJECT", 1 << 0, 'V', 100); // 1
public static final RedPermission VIEW_OBJECT = new RedPermission("VIEW_OBJECT", 1 << 0, 'V', 100, false); // 1
public static final RedPermission ACCESS_OBJECT = new RedPermission("ACCESS_OBJECT", 1 << 1, 'A', 200); // 2
public static final RedPermission ACCESS_OBJECT = new RedPermission("ACCESS_OBJECT", 1 << 1, 'A', 200, false); // 2
public static final RedPermission REVIEW = new RedPermission("REVIEW", 1 << 2, 'W', 30); // 4
public static final RedPermission REVIEW = new RedPermission("REVIEW", 1 << 2, 'W', 30, true); // 4
public static final RedPermission APPROVE = new RedPermission("APPROVE", 1 << 3, 'A', 20); // 8
public static final RedPermission APPROVE = new RedPermission("APPROVE", 1 << 3, 'A', 20, true); // 8
public static final RedPermission OWNER = new RedPermission("OWNER", 1 << 4, 'O', 10); // 16
public static final RedPermission OWNER = new RedPermission("OWNER", 1 << 4, 'O', 10, false); // 16
private static final List<RedPermission> ALL_PERMISSIONS = List.of(VIEW_OBJECT, ACCESS_OBJECT, REVIEW, APPROVE, OWNER);
@ -28,12 +28,16 @@ public class RedPermission extends AbstractPermission implements Permission {
@Getter
private final int sort;
@Getter
private final boolean isChangeable;
protected RedPermission(String name, int mask, char code, int sort) {
protected RedPermission(String name, int mask, char code, int sort, boolean isChangeable) {
super(mask, code);
this.name = name;
this.sort = sort;
this.isChangeable = isChangeable;
}

View File

@ -4,8 +4,7 @@ import com.iqser.red.service.persistence.service.v1.api.shared.model.permission.
public final class CustomPermissionConstants {
public static final CustomPermissionModel EVERYONE_ELSE = new CustomPermissionModel(-1, "EVERYONE_ELSE", 100_000);
public static final CustomPermissionModel EVERYONE_ELSE = new CustomPermissionModel(-1, "EVERYONE_ELSE", 100_000, true);
private CustomPermissionConstants() {}

View File

@ -25,28 +25,30 @@ public class CustomDossierPermissionsACLInitializer implements IACLInitializer {
private static final String TARGET_OBJECT = "Dossier";
private final CustomPermissionService customPermissionService;
public void initialize() {
if (customPermissionService.getCustomPermissionMappings(TARGET_OBJECT).isEmpty()) {
log.info("No custom permissions seeded. Adding defaults!");
if (customPermissionService.getCustomPermissionMappings(TARGET_OBJECT).isEmpty()) {
List<CustomPermissionMappingModel> mappingModels = new ArrayList<>();
log.info("No custom permissions seeded. Adding defaults!");
var viewObjectPermission = convert(RedPermission.VIEW_OBJECT);
var viewObjectMappedPermissions = List.of(convert(RedPermission.OWNER), convert(RedPermission.APPROVE), convert(RedPermission.REVIEW), EVERYONE_ELSE);
List<CustomPermissionMappingModel> mappingModels = new ArrayList<>();
mappingModels.add(new CustomPermissionMappingModel(viewObjectPermission, viewObjectMappedPermissions));
var viewObjectPermission = convert(RedPermission.VIEW_OBJECT);
var viewObjectMappedPermissions = List.of(convert(RedPermission.OWNER), convert(RedPermission.APPROVE), convert(RedPermission.REVIEW), EVERYONE_ELSE);
var accessObjectPermission = convert(RedPermission.ACCESS_OBJECT);
var accessObjectMappedPermissions = List.of(convert(RedPermission.OWNER), convert(RedPermission.APPROVE), convert(RedPermission.REVIEW), EVERYONE_ELSE);
mappingModels.add(new CustomPermissionMappingModel(viewObjectPermission, viewObjectMappedPermissions));
mappingModels.add(new CustomPermissionMappingModel(accessObjectPermission, accessObjectMappedPermissions));
var accessObjectPermission = convert(RedPermission.ACCESS_OBJECT);
var accessObjectMappedPermissions = List.of(convert(RedPermission.OWNER), convert(RedPermission.APPROVE), convert(RedPermission.REVIEW), EVERYONE_ELSE);
customPermissionService.saveCustomPermissionMappings(TARGET_OBJECT, mappingModels);
mappingModels.add(new CustomPermissionMappingModel(accessObjectPermission, accessObjectMappedPermissions));
}
customPermissionService.saveCustomPermissionMappings(TARGET_OBJECT, mappingModels);
customPermissionService.syncAllCustomPermissions();
}
customPermissionService.syncAllCustomPermissions();
}
@ -59,7 +61,7 @@ public class CustomDossierPermissionsACLInitializer implements IACLInitializer {
private CustomPermissionModel convert(RedPermission redPermission) {
return new CustomPermissionModel(redPermission.getMask(), redPermission.getName(), redPermission.getSort());
return new CustomPermissionModel(redPermission.getMask(), redPermission.getName(), redPermission.getSort(), redPermission.isChangeable());
}
}

View File

@ -9,6 +9,7 @@ import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;
@ -98,7 +99,7 @@ public class CustomPermissionService {
private CustomPermissionModel fromPermission(RedPermission redPermission) {
return new CustomPermissionModel(redPermission.getMask(), redPermission.getName(), redPermission.getSort());
return new CustomPermissionModel(redPermission.getMask(), redPermission.getName(), redPermission.getSort(), redPermission.isChangeable());
}
@ -169,12 +170,29 @@ public class CustomPermissionService {
public void saveCustomPermissionMappings(String targetObject, List<CustomPermissionMappingModel> customPermissionMappingModel) {
List<CustomPermissionEntity> entities = new ArrayList<>();
// retrieve the defined configuration of permissions
List<CustomPermissionMappingModel> existingPermissionDefined = getExistingPermissions(targetObject);
customPermissionMappingModel.forEach(c -> c.getMappedPermissions().forEach(value -> {
CustomPermissionEntity entity = new CustomPermissionEntity(targetObject, c.getTargetPermission().getMask(), value.getMask());
entities.add(entity);
}));
for (CustomPermissionMappingModel permissionMappingModel : existingPermissionDefined) {
CustomPermissionModel targetPermission = permissionMappingModel.getTargetPermission();
List<CustomPermissionModel> mappedPermissionsDefined = permissionMappingModel.getMappedPermissions();
//retrieve the permissions which can be changeable in order to add them
List<Integer> mappedPermissionMasksNotChangeable = mappedPermissionsDefined.stream().filter(p -> !p.isChangeable()).map(CustomPermissionModel::getMask).toList();
for (Integer mappedMask : mappedPermissionMasksNotChangeable) {
Optional<CustomPermissionEntity> existingPermissionEntity = entities.stream()
.filter(e -> e.getTargetPermissionMask() == targetPermission.getMask() && e.getExistingPermissionMask() == mappedMask)
.findAny();
if (existingPermissionEntity.isEmpty()) { //the required permission was disabled but it is not allowed
entities.add(new CustomPermissionEntity(targetObject, targetPermission.getMask(), mappedMask));
}
}
}
customPermissionRepository.deleteByTargetObject(targetObject);
customPermissionRepository.saveAll(entities);

View File

@ -66,6 +66,9 @@ public class DossierTemplateEntity {
@Column(name = "soft_delete_time")
private OffsetDateTime softDeleteTime;
@Column(name = "keep_image_metadata")
private boolean keepImageMetadata;
@Builder.Default
@Column(columnDefinition = "text", name = "download_file_types")
@Convert(converter = JSONDownloadFileTypeConverter.class)
@ -104,4 +107,6 @@ public class DossierTemplateEntity {
@Transient
private DossierTemplateStatus dossierTemplateStatus;
}

View File

@ -22,11 +22,13 @@ import com.iqser.red.service.pdftron.redaction.v1.api.model.RedactionResultMessa
import com.iqser.red.service.pdftron.redaction.v1.api.model.RedactionType;
import com.iqser.red.service.persistence.management.v1.processor.configuration.MessagingConfiguration;
import com.iqser.red.service.persistence.management.v1.processor.entity.dossier.DossierEntity;
import com.iqser.red.service.persistence.management.v1.processor.entity.dossier.DossierTemplateEntity;
import com.iqser.red.service.persistence.management.v1.processor.entity.dossier.FileEntity;
import com.iqser.red.service.persistence.management.v1.processor.entity.dossier.ReportTemplateEntity;
import com.iqser.red.service.persistence.management.v1.processor.entity.download.DownloadStatusEntity;
import com.iqser.red.service.persistence.management.v1.processor.service.ColorsService;
import com.iqser.red.service.persistence.management.v1.processor.service.FileManagementStorageService;
import com.iqser.red.service.persistence.management.v1.processor.service.persistence.DossierTemplatePersistenceService;
import com.iqser.red.service.persistence.management.v1.processor.service.persistence.DownloadStatusPersistenceService;
import com.iqser.red.service.persistence.management.v1.processor.service.persistence.FileStatusPersistenceService;
import com.iqser.red.service.persistence.management.v1.processor.service.persistence.NotificationPersistenceService;
@ -65,16 +67,16 @@ public class DownloadPreparationService {
DownloadReportCleanupService downloadReportCleanupService;
ColorsService colorsService;
FileManagementServiceSettings settings;
DossierTemplatePersistenceService dossierTemplatePersistenceService;
@Transactional
public void createDownload(ReportResultMessage reportResultMessage) throws JsonProcessingException {
DownloadStatusEntity downloadStatus = downloadStatusPersistenceService.getStatus(reportResultMessage.getDownloadId());
DossierEntity dossier = downloadStatus.getDossier();
String storedPreviewColor = downloadStatus.getRedactionPreviewColor();
var downloadStatus = downloadStatusPersistenceService.getStatus(reportResultMessage.getDownloadId());
var dossier = downloadStatus.getDossier();
var storedPreviewColor = downloadStatus.getRedactionPreviewColor();
// var dossierTemplate = dossierTemplatePersistenceService.getDossierTemplate(dossier.getDossierTemplateId());
final String previewColor;
if (storedPreviewColor == null || storedPreviewColor.isBlank()) {
@ -96,6 +98,7 @@ public class DownloadPreparationService {
.map(FileEntity::getId)
.collect(Collectors.toSet()))
.redactionPreviewColor(previewColor)
// .keepImageMetaData(dossierTemplate.isKeepImageMetadata())
.appliedRedactionColor(appliedRedactionColor)
.build();

View File

@ -121,3 +121,5 @@ databaseChangeLog:
file: db/changelog/tenant/sql/201-acl-duplicate-cleanup.sql
- include:
file: db/changelog/tenant/sql/202-acl-duplicate-cleanup.sql
- include:
file: db/changelog/tenant/sql/46-add-keep_image_metadata.sql

View File

@ -0,0 +1,2 @@
-- add new column
alter table dossier_template add column keep_image_metadata BOOLEAN NOT NULL DEFAULT FALSE;

View File

@ -56,6 +56,12 @@
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.testcontainers</groupId>
<artifactId>postgresql</artifactId>

View File

@ -61,7 +61,7 @@ commons:
keycloak:
applicationClientId: redaction
clientId: redaction-system
clientSecret: NSQmQWTBAPH4HwJXIFQQdazigWP8EHgg
clientSecret: G5E1qLU8ZNdDv7HY5BNLPdt5nXdeF7cU
realm: redaction
serverUrl: http://localhost:8080
issuer: ''

View File

@ -154,11 +154,11 @@ commons:
springdoc:
swagger-ui:
path: /api/docs/swagger-ui
path: /redaction-gateway-v1/docs/swagger-ui
operations-sorter: alpha
tags-sorter: alpha
api-docs:
path: /api/docs
path: /redaction-gateway-v1/docs
pre-loading-enabled: true
packages-to-scan: ['com.iqser.red.persistence.service.v1.external.api']

View File

@ -0,0 +1,11 @@
package com.iqser.red.service.peristence.v1.server.integration.client;
import org.springframework.cloud.openfeign.FeignClient;
import com.iqser.red.service.persistence.service.v1.api.external.resource.CustomPermissionMappingResource;
import com.iqser.red.service.persistence.service.v1.api.external.resource.ViewedPagesResource;
@FeignClient(name = "CustomPermissionClient", url = "http://localhost:${server.port}")
public interface CustomPermissionClient extends CustomPermissionMappingResource {
}

View File

@ -0,0 +1,63 @@
package com.iqser.red.service.peristence.v1.server.integration.tests;
import static com.iqser.red.keycloak.commons.roles.ActionRoles.MANAGE_ACL_PERMISSIONS;
import static com.iqser.red.service.persistence.service.v1.api.external.resource.CustomPermissionMappingResource.PERMISSION_REST_PATH;
import static com.iqser.red.service.persistence.service.v1.api.external.resource.CustomPermissionMappingResource.TARGET_OBJECT_VARIABLE;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import java.util.ArrayList;
import java.util.List;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.security.test.context.support.WithMockUser;
import org.springframework.test.web.servlet.request.MockHttpServletRequestBuilder;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import com.iqser.red.service.peristence.v1.server.integration.client.CustomPermissionClient;
import com.iqser.red.service.peristence.v1.server.integration.utils.AbstractPersistenceServerServiceTest;
import com.iqser.red.service.persistence.management.v1.processor.acl.RedPermission;
import com.iqser.red.service.persistence.management.v1.processor.acl.custom.constants.CustomPermissionConstants;
import com.iqser.red.service.persistence.service.v1.api.shared.model.permission.CustomPermissionMappingModel;
import com.iqser.red.service.persistence.service.v1.api.shared.model.permission.CustomPermissionModel;
public class CustomPermissionTest extends AbstractPersistenceServerServiceTest {
@Autowired
private CustomPermissionClient customPermissionClient;
@Test
public void testSaveCustomPermissions() {
CustomPermissionModel targetViewPermission = new CustomPermissionModel(RedPermission.VIEW_OBJECT.getMask(),
RedPermission.VIEW_OBJECT.getName(),
RedPermission.VIEW_OBJECT.getSort(),
false);
List<CustomPermissionModel> mappedViewPermissions = new ArrayList<>();
mappedViewPermissions.add(new CustomPermissionModel(RedPermission.APPROVE.getMask(), RedPermission.APPROVE.getName(), RedPermission.APPROVE.getSort(), true));
mappedViewPermissions.add(new CustomPermissionModel(RedPermission.REVIEW.getMask(), RedPermission.REVIEW.getName(), RedPermission.REVIEW.getSort(), true));
CustomPermissionModel targetAccessPermission = new CustomPermissionModel(RedPermission.ACCESS_OBJECT.getMask(),
RedPermission.ACCESS_OBJECT.getName(),
RedPermission.ACCESS_OBJECT.getSort(),
false);
List<CustomPermissionModel> mappedAccessPermissions = new ArrayList<>();
mappedAccessPermissions.add(new CustomPermissionModel(RedPermission.APPROVE.getMask(), RedPermission.APPROVE.getName(), RedPermission.APPROVE.getSort(), true));
mappedAccessPermissions.add(new CustomPermissionModel(RedPermission.REVIEW.getMask(), RedPermission.REVIEW.getName(), RedPermission.REVIEW.getSort(), true));
mappedAccessPermissions.add(new CustomPermissionModel(CustomPermissionConstants.EVERYONE_ELSE.getMask(),
CustomPermissionConstants.EVERYONE_ELSE.getName(),
CustomPermissionConstants.EVERYONE_ELSE.getSort(),
true));
List<CustomPermissionMappingModel> customPermissionMappingModels = new ArrayList<>();
customPermissionMappingModels.add(new CustomPermissionMappingModel(targetViewPermission, mappedViewPermissions));
customPermissionMappingModels.add(new CustomPermissionMappingModel(targetAccessPermission, mappedAccessPermissions));
customPermissionClient.saveCustomPermissionMappings("Dossier", customPermissionMappingModels);
}
}

View File

@ -53,6 +53,9 @@ public class DossierTemplateModel {
@Schema(description = "Status of dossier template.")
private DossierTemplateStatus dossierTemplateStatus;
@Schema(description = "Representing the setting if the metadata of images in pdfs should get kept or removed")
private boolean keepImageMetadata;
public String getId(){
return dossierTemplateId;
}

View File

@ -30,5 +30,6 @@ public class DossierTemplate {
private boolean deleted;
private Set<DownloadFileType> downloadFileTypes = new HashSet<>();
private DossierTemplateStatus dossierTemplateStatus;
private boolean keepImageMetadata;
}

View File

@ -12,5 +12,6 @@ public class CustomPermissionModel {
private final Integer mask;
private final String name;
private final int sort;
private final boolean isChangeable;
}