Merge branch 'RED-6686' into 'master'

RED-6686 Extract Tenant and user-management code into a separate service.

See merge request redactmanager/persistence-service!4
This commit is contained in:
Timo Bejan 2023-06-26 22:44:52 +02:00
commit 5a62786367
322 changed files with 2390 additions and 7854 deletions

View File

@ -1,121 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>persistence-service-v1</artifactId>
<groupId>com.iqser.red.service</groupId>
<version>2.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>keycloak-commons</artifactId>
<dependencies>
<dependency>
<groupId>com.iqser.red.commons</groupId>
<artifactId>spring-commons</artifactId>
</dependency>
<dependency>
<groupId>com.iqser.red.commons</groupId>
<artifactId>logging-commons</artifactId>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.9</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-compress</artifactId>
<version>1.21</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-collections4</artifactId>
<version>4.4</version>
</dependency>
<dependency>
<groupId>com.iqser.red.commons</groupId>
<artifactId>metric-commons</artifactId>
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-spring-boot-adapter-core</artifactId>
<version>${keycloak.version}</version>
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-spring-security-adapter</artifactId>
<version>${keycloak.version}</version>
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-admin-client</artifactId>
<version>${keycloak.version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.dataformat</groupId>
<artifactId>jackson-dataformat-xml</artifactId>
<version>2.13.4</version>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
</dependency>
<!-- spring -->
<dependency>
<groupId>io.github.openfeign</groupId>
<artifactId>feign-core</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>com.iqser.red.commons</groupId>
<artifactId>jackson-commons</artifactId>
</dependency>
<!-- test -->
<dependency>
<groupId>com.iqser.red.commons</groupId>
<artifactId>test-commons</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.retry</groupId>
<artifactId>spring-retry</artifactId>
</dependency>
</dependencies>
</project>

View File

@ -1,24 +0,0 @@
package com.iqser.red.keycloak.commons;
import java.time.Duration;
import org.springframework.boot.autoconfigure.cache.RedisCacheManagerBuilderCustomizer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.cache.RedisCacheConfiguration;
@Configuration
@ComponentScan
public class DefaultKeyCloakCommonsConfiguration {
public static final String USERS_CACHE = "users";
@Bean
public RedisCacheManagerBuilderCustomizer redisUserCacheManagerBuilderCustomizer() {
return (builder) -> builder.withCacheConfiguration(USERS_CACHE, RedisCacheConfiguration.defaultCacheConfig().entryTtl(Duration.ofSeconds(10)));
}
}

View File

@ -1,41 +0,0 @@
package com.iqser.red.keycloak.commons;
import java.util.concurrent.TimeUnit;
import org.jboss.resteasy.client.jaxrs.ResteasyClientBuilder;
import org.jboss.resteasy.client.jaxrs.internal.ResteasyClientBuilderImpl;
import org.keycloak.OAuth2Constants;
import org.keycloak.admin.client.Keycloak;
import org.keycloak.admin.client.KeycloakBuilder;
import org.springframework.stereotype.Service;
@Service
public class KeyCloakAdminClientService {
private final Keycloak adminClient;
public KeyCloakAdminClientService(KeyCloakSettings settings) {
adminClient = KeycloakBuilder.builder()
.serverUrl(settings.getServerUrl())
.realm(settings.getRealm())
.clientId(settings.getClientId())
.clientSecret(settings.getClientSecret())
.grantType(OAuth2Constants.CLIENT_CREDENTIALS)
.resteasyClient(new ResteasyClientBuilderImpl().connectionTTL(2, TimeUnit.SECONDS)
.hostnameVerification(ResteasyClientBuilder.HostnameVerificationPolicy.ANY)
.connectionPoolSize(settings.getConnectionPoolSize())
.disableTrustManager()
.build())
.build();
}
public Keycloak getAdminClient() {
return adminClient;
}
}

View File

@ -1,21 +0,0 @@
package com.iqser.red.keycloak.commons;
import org.springframework.boot.context.properties.ConfigurationProperties;
import lombok.Data;
@Data
@ConfigurationProperties("commons.keycloak")
public class KeyCloakSettings {
private String serverUrl;
private String realm;
private String applicationClientId;
private String clientId;
private String clientSecret;
private String issuer;
private String rolePrefix = "RED_";
private int connectionPoolSize = 10;
private boolean scmEnabled;
}

View File

@ -1,56 +0,0 @@
package com.iqser.red.keycloak.commons;
import java.util.Optional;
import java.util.function.Function;
import org.keycloak.adapters.springsecurity.token.KeycloakAuthenticationToken;
import org.keycloak.representations.AccessToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import lombok.experimental.UtilityClass;
import lombok.extern.slf4j.Slf4j;
/**
* Collection of helpful functions to easily access information about an authenticated user.
*/
@Slf4j
@UtilityClass
public class KeycloakSecurity {
/**
* Determines the unique identifier for the currently logged in user.
*
* @return The unique user identifier. Never {@code null}.
*/
public String getUserId() {
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
if (auth == null) {
return "anonymousUser";
}
return auth.getName();
}
public Optional<String> getRealm(){
return getToken(t -> {
String issuer = t.getIssuer();
String realm = issuer.substring(issuer.lastIndexOf('/') + 1);
log.info(realm);
return realm;
});
}
public <R> Optional<R> getToken(Function<AccessToken, R> function) {
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
if (!(auth instanceof KeycloakAuthenticationToken)) {
return Optional.empty();
}
KeycloakAuthenticationToken keycloakAuth = (KeycloakAuthenticationToken) auth;
return Optional.ofNullable(function.apply(keycloakAuth.getAccount().getKeycloakSecurityContext().getToken()));
}
}

View File

@ -1,18 +0,0 @@
package com.iqser.red.keycloak.commons;
import org.springframework.stereotype.Service;
@Service
public class KeycloakSecurityService {
/**
* Determines the unique identifier for the currently logged in user.
*
* @return The unique user identifier. Never {@code null}.
*/
public String getUserId() {
return KeycloakSecurity.getUserId();
}
}

View File

@ -1,21 +0,0 @@
package com.iqser.red.keycloak.commons;
import org.keycloak.admin.client.resource.RealmResource;
import org.springframework.stereotype.Service;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
@Service
@RequiredArgsConstructor
@Slf4j
public class RealmService {
private final KeyCloakAdminClientService keycloak;
public RealmResource realm(String tenantId) {
return keycloak.getAdminClient().realm(tenantId);
}
}

View File

@ -1,101 +0,0 @@
package com.iqser.red.keycloak.commons;
import static com.iqser.red.keycloak.commons.DefaultKeyCloakCommonsConfiguration.USERS_CACHE;
import static com.iqser.red.keycloak.commons.roles.ApplicationRoles.RED_ADMIN_ROLE;
import static com.iqser.red.keycloak.commons.roles.ApplicationRoles.RED_MANAGER_ROLE;
import static com.iqser.red.keycloak.commons.roles.ApplicationRoles.RED_USER_ADMIN_ROLE;
import static com.iqser.red.keycloak.commons.roles.ApplicationRoles.RED_USER_ROLE;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
import org.keycloak.representations.idm.UserRepresentation;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.retry.support.RetryTemplate;
import org.springframework.stereotype.Service;
import com.iqser.red.keycloak.commons.model.User;
import com.iqser.red.keycloak.commons.roles.ApplicationRoles;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
@Slf4j
@Service
@RequiredArgsConstructor
public class UserListingService {
private final RealmService realmService;
private final RetryTemplate retryTemplate = RetryTemplate.builder().maxAttempts(3).exponentialBackoff(1000, 2, 5000).build();
@Cacheable(value = USERS_CACHE, key = "#tenantId")
public List<User> getAllUsers(String tenantId) {
return retryTemplate.execute(context -> {
var realm = realmService.realm(tenantId);
List<UserRepresentation> allUsers = realm.users().search(null, 0, 500);
Map<String, Set<String>> usersByRole = new HashMap<>();
if(!allUsers.isEmpty()) {
var realmRoles = realm.roles().list().stream().map(r -> r.getName().toUpperCase()).collect(Collectors.toSet());
for (var role : ApplicationRoles.ROLE_DATA.keySet()) {
if(realmRoles.contains(role)) {
Set<UserRepresentation> users = realm.roles().get(role).getRoleUserMembers(0, 500);
usersByRole.put(role, users.stream().map(UserRepresentation::getId).collect(Collectors.toSet()));
}
}
}
return compactUsers(allUsers, usersByRole);
});
}
private List<User> compactUsers(List<UserRepresentation> allUsers, Map<String, Set<String>> usersByRole) {
List<User> users = new ArrayList<>();
for (var userRepresentation : allUsers) {
var user = convertBasicUser(userRepresentation);
for (var entry : usersByRole.entrySet()) {
if (entry.getValue().contains(user.getUserId())) {
user.getRoles().add(entry.getKey());
}
}
users.add(user);
}
users.forEach(user -> {
if (user.getRoles().contains(RED_MANAGER_ROLE)) {
user.getRoles().add(RED_USER_ROLE);
}
if (user.getRoles().contains(RED_ADMIN_ROLE)) {
user.getRoles().add(RED_USER_ADMIN_ROLE);
}
});
return users;
}
public User convertBasicUser(UserRepresentation userRepresentation) {
return User.builder()
.email(userRepresentation.getEmail())
.username(userRepresentation.getUsername())
.firstName(userRepresentation.getFirstName())
.lastName(userRepresentation.getLastName())
.userId(userRepresentation.getId())
.isActive(userRepresentation.isEnabled())
.build();
}
}

View File

@ -1,259 +0,0 @@
package com.iqser.red.keycloak.commons.roles;
import static com.iqser.red.keycloak.commons.roles.ActionRoles.ADD_COMMENT;
import static com.iqser.red.keycloak.commons.roles.ActionRoles.ADD_DICTIONARY_ENTRY;
import static com.iqser.red.keycloak.commons.roles.ActionRoles.ADD_DOSSIER_DICTIONARY_ENTRY;
import static com.iqser.red.keycloak.commons.roles.ActionRoles.ADD_UPDATE_DICTIONARY_TYPE;
import static com.iqser.red.keycloak.commons.roles.ActionRoles.ADD_UPDATE_DOSSIER;
import static com.iqser.red.keycloak.commons.roles.ActionRoles.ADD_UPDATE_DOSSIER_DICTIONARY_TYPE;
import static com.iqser.red.keycloak.commons.roles.ActionRoles.ARCHIVE_DOSSIER;
import static com.iqser.red.keycloak.commons.roles.ActionRoles.CONVERT_HIGHLIGHTS;
import static com.iqser.red.keycloak.commons.roles.ActionRoles.CREATE_TENANT;
import static com.iqser.red.keycloak.commons.roles.ActionRoles.DELETE_COMMENT;
import static com.iqser.red.keycloak.commons.roles.ActionRoles.DELETE_DICTIONARY_ENTRY;
import static com.iqser.red.keycloak.commons.roles.ActionRoles.DELETE_DICTIONARY_TYPE;
import static com.iqser.red.keycloak.commons.roles.ActionRoles.DELETE_DOSSIER;
import static com.iqser.red.keycloak.commons.roles.ActionRoles.DELETE_DOSSIER_DICTIONARY_ENTRY;
import static com.iqser.red.keycloak.commons.roles.ActionRoles.DELETE_DOSSIER_DICTIONARY_TYPE;
import static com.iqser.red.keycloak.commons.roles.ActionRoles.DELETE_FILE;
import static com.iqser.red.keycloak.commons.roles.ActionRoles.DELETE_HIGHLIGHTS;
import static com.iqser.red.keycloak.commons.roles.ActionRoles.DELETE_IMPORTED_REDACTIONS;
import static com.iqser.red.keycloak.commons.roles.ActionRoles.DELETE_MANUAL_REDACTION;
import static com.iqser.red.keycloak.commons.roles.ActionRoles.DELETE_REPORT_TEMPLATE;
import static com.iqser.red.keycloak.commons.roles.ActionRoles.DEPLOYMENT_INFO;
import static com.iqser.red.keycloak.commons.roles.ActionRoles.DOWNLOAD_ANNOTATED_FILE;
import static com.iqser.red.keycloak.commons.roles.ActionRoles.DOWNLOAD_ORIGINAL_FILE;
import static com.iqser.red.keycloak.commons.roles.ActionRoles.DOWNLOAD_REDACTED_FILE;
import static com.iqser.red.keycloak.commons.roles.ActionRoles.DOWNLOAD_REDACTION_PREVIEW_FILE;
import static com.iqser.red.keycloak.commons.roles.ActionRoles.DOWNLOAD_REPORT_TEMPLATE;
import static com.iqser.red.keycloak.commons.roles.ActionRoles.DO_MANUAL_REDACTION;
import static com.iqser.red.keycloak.commons.roles.ActionRoles.EXCLUDE_INCLUDE_FILE;
import static com.iqser.red.keycloak.commons.roles.ActionRoles.EXCLUDE_INCLUDE_PAGES;
import static com.iqser.red.keycloak.commons.roles.ActionRoles.GET_HIGHLIGHTS;
import static com.iqser.red.keycloak.commons.roles.ActionRoles.GET_REPORT_TEMPLATES;
import static com.iqser.red.keycloak.commons.roles.ActionRoles.GET_RSS;
import static com.iqser.red.keycloak.commons.roles.ActionRoles.GET_TENANTS;
import static com.iqser.red.keycloak.commons.roles.ActionRoles.MANAGE_ACL_PERMISSIONS;
import static com.iqser.red.keycloak.commons.roles.ActionRoles.MANAGE_USER_PREFERENCES;
import static com.iqser.red.keycloak.commons.roles.ActionRoles.MANAGE_VIEWED_PAGES;
import static com.iqser.red.keycloak.commons.roles.ActionRoles.PROCESS_DOWNLOAD;
import static com.iqser.red.keycloak.commons.roles.ActionRoles.PROCESS_MANUAL_REDACTION_REQUEST;
import static com.iqser.red.keycloak.commons.roles.ActionRoles.PROCESS_TEXT_HIGHLIGHTS;
import static com.iqser.red.keycloak.commons.roles.ActionRoles.READ_ALL_USERS;
import static com.iqser.red.keycloak.commons.roles.ActionRoles.READ_APP_CONFIG;
import static com.iqser.red.keycloak.commons.roles.ActionRoles.READ_COLORS;
import static com.iqser.red.keycloak.commons.roles.ActionRoles.READ_DICTIONARY_TYPES;
import static com.iqser.red.keycloak.commons.roles.ActionRoles.READ_DIGITAL_SIGNATURE;
import static com.iqser.red.keycloak.commons.roles.ActionRoles.READ_DOSSIER;
import static com.iqser.red.keycloak.commons.roles.ActionRoles.READ_DOSSIER_ATTRIBUTES;
import static com.iqser.red.keycloak.commons.roles.ActionRoles.READ_DOSSIER_ATTRIBUTES_CONFIG;
import static com.iqser.red.keycloak.commons.roles.ActionRoles.READ_DOSSIER_STATUS;
import static com.iqser.red.keycloak.commons.roles.ActionRoles.READ_DOSSIER_TEMPLATES;
import static com.iqser.red.keycloak.commons.roles.ActionRoles.READ_DOWNLOAD_STATUS;
import static com.iqser.red.keycloak.commons.roles.ActionRoles.READ_FILE_ATTRIBUTES_CONFIG;
import static com.iqser.red.keycloak.commons.roles.ActionRoles.READ_FILE_STATUS;
import static com.iqser.red.keycloak.commons.roles.ActionRoles.READ_GENERAL_CONFIGURATION;
import static com.iqser.red.keycloak.commons.roles.ActionRoles.READ_LEGAL_BASIS;
import static com.iqser.red.keycloak.commons.roles.ActionRoles.READ_LICENSE;
import static com.iqser.red.keycloak.commons.roles.ActionRoles.READ_LICENSE_REPORT;
import static com.iqser.red.keycloak.commons.roles.ActionRoles.READ_MANUAL_REDACTIONS;
import static com.iqser.red.keycloak.commons.roles.ActionRoles.READ_NOTIFICATIONS;
import static com.iqser.red.keycloak.commons.roles.ActionRoles.READ_REDACTION_LOG;
import static com.iqser.red.keycloak.commons.roles.ActionRoles.READ_RULES;
import static com.iqser.red.keycloak.commons.roles.ActionRoles.READ_SMTP_CONFIGURATION;
import static com.iqser.red.keycloak.commons.roles.ActionRoles.READ_USERS;
import static com.iqser.red.keycloak.commons.roles.ActionRoles.READ_VERSIONS;
import static com.iqser.red.keycloak.commons.roles.ActionRoles.READ_WATERMARK;
import static com.iqser.red.keycloak.commons.roles.ActionRoles.REANALYZE_DOSSIER;
import static com.iqser.red.keycloak.commons.roles.ActionRoles.REANALYZE_FILE;
import static com.iqser.red.keycloak.commons.roles.ActionRoles.REINDEX;
import static com.iqser.red.keycloak.commons.roles.ActionRoles.REQUEST_MANUAL_REDACTION;
import static com.iqser.red.keycloak.commons.roles.ActionRoles.ROTATE_PAGE;
import static com.iqser.red.keycloak.commons.roles.ActionRoles.SEARCH;
import static com.iqser.red.keycloak.commons.roles.ActionRoles.SEARCH_AUDIT_LOG;
import static com.iqser.red.keycloak.commons.roles.ActionRoles.SET_REVIEWER;
import static com.iqser.red.keycloak.commons.roles.ActionRoles.SET_STATUS_APPROVED;
import static com.iqser.red.keycloak.commons.roles.ActionRoles.SET_STATUS_UNDER_APPROVAL;
import static com.iqser.red.keycloak.commons.roles.ActionRoles.UNARCHIVE_DOSSIER;
import static com.iqser.red.keycloak.commons.roles.ActionRoles.UPDATE_LICENSE;
import static com.iqser.red.keycloak.commons.roles.ActionRoles.UPDATE_MY_PROFILE;
import static com.iqser.red.keycloak.commons.roles.ActionRoles.UPDATE_NOTIFICATIONS;
import static com.iqser.red.keycloak.commons.roles.ActionRoles.UPLOAD_FILE;
import static com.iqser.red.keycloak.commons.roles.ActionRoles.UPLOAD_REPORT_TEMPLATE;
import static com.iqser.red.keycloak.commons.roles.ActionRoles.WRITE_APP_CONFIG;
import static com.iqser.red.keycloak.commons.roles.ActionRoles.WRITE_COLORS;
import static com.iqser.red.keycloak.commons.roles.ActionRoles.WRITE_DIGITAL_SIGNATURE;
import static com.iqser.red.keycloak.commons.roles.ActionRoles.WRITE_DOSSIER_ATTRIBUTES;
import static com.iqser.red.keycloak.commons.roles.ActionRoles.WRITE_DOSSIER_ATTRIBUTES_CONFIG;
import static com.iqser.red.keycloak.commons.roles.ActionRoles.WRITE_DOSSIER_STATUS;
import static com.iqser.red.keycloak.commons.roles.ActionRoles.WRITE_DOSSIER_TEMPLATES;
import static com.iqser.red.keycloak.commons.roles.ActionRoles.WRITE_FILE_ATTRIBUTES;
import static com.iqser.red.keycloak.commons.roles.ActionRoles.WRITE_FILE_ATTRIBUTES_CONFIG;
import static com.iqser.red.keycloak.commons.roles.ActionRoles.WRITE_GENERAL_CONFIGURATION;
import static com.iqser.red.keycloak.commons.roles.ActionRoles.WRITE_LEGAL_BASIS;
import static com.iqser.red.keycloak.commons.roles.ActionRoles.WRITE_RULES;
import static com.iqser.red.keycloak.commons.roles.ActionRoles.WRITE_SMTP_CONFIGURATION;
import static com.iqser.red.keycloak.commons.roles.ActionRoles.WRITE_USERS;
import static com.iqser.red.keycloak.commons.roles.ActionRoles.WRITE_WATERMARK;
import java.util.Collection;
import java.util.Map;
import java.util.Set;
import com.google.common.collect.Sets;
public final class ApplicationRoles {
public static final String RED_USER_ROLE = "RED_USER";
public static final String RED_MANAGER_ROLE = "RED_MANAGER";
public static final String RED_ADMIN_ROLE = "RED_ADMIN";
public static final String RED_USER_ADMIN_ROLE = "RED_USER_ADMIN";
public static final Set<String> RED_ROLES = Sets.newHashSet(RED_USER_ROLE, RED_MANAGER_ROLE, RED_ADMIN_ROLE, RED_USER_ADMIN_ROLE);
public static final Set<String> UNMAPPED_ACTION_ROLES = Sets.newHashSet(UNARCHIVE_DOSSIER, UPDATE_LICENSE, GET_RSS);
public static final Set<String> RED_USER_ACTION_ROLES = Sets.newHashSet(ADD_COMMENT,
READ_LICENSE,
READ_APP_CONFIG,
READ_DOSSIER_STATUS,
ADD_DOSSIER_DICTIONARY_ENTRY,
DO_MANUAL_REDACTION,
ADD_UPDATE_DOSSIER_DICTIONARY_TYPE,
DELETE_COMMENT,
DELETE_DOSSIER_DICTIONARY_ENTRY,
DELETE_DOSSIER_DICTIONARY_TYPE,
DELETE_FILE,
DELETE_MANUAL_REDACTION,
DOWNLOAD_ANNOTATED_FILE,
DOWNLOAD_ORIGINAL_FILE,
DOWNLOAD_REDACTED_FILE,
DOWNLOAD_REDACTION_PREVIEW_FILE,
DOWNLOAD_REPORT_TEMPLATE,
EXCLUDE_INCLUDE_FILE,
EXCLUDE_INCLUDE_PAGES,
GET_REPORT_TEMPLATES,
MANAGE_USER_PREFERENCES,
MANAGE_VIEWED_PAGES,
PROCESS_DOWNLOAD,
PROCESS_MANUAL_REDACTION_REQUEST,
READ_COLORS,
READ_DICTIONARY_TYPES,
READ_DIGITAL_SIGNATURE,
READ_DOSSIER,
READ_DOSSIER_ATTRIBUTES,
READ_DOSSIER_ATTRIBUTES_CONFIG,
READ_DOSSIER_TEMPLATES,
READ_DOWNLOAD_STATUS,
READ_FILE_ATTRIBUTES_CONFIG,
READ_FILE_STATUS,
READ_GENERAL_CONFIGURATION,
READ_LEGAL_BASIS,
READ_MANUAL_REDACTIONS,
READ_NOTIFICATIONS,
READ_REDACTION_LOG,
READ_RULES,
READ_USERS,
READ_VERSIONS,
READ_WATERMARK,
REANALYZE_DOSSIER,
REANALYZE_FILE,
REQUEST_MANUAL_REDACTION,
ROTATE_PAGE,
SEARCH,
SEARCH_AUDIT_LOG,
SET_REVIEWER,
SET_STATUS_APPROVED,
SET_STATUS_UNDER_APPROVAL,
UPDATE_MY_PROFILE,
UPDATE_NOTIFICATIONS,
UPLOAD_FILE,
WRITE_FILE_ATTRIBUTES,
PROCESS_TEXT_HIGHLIGHTS,
GET_HIGHLIGHTS,
CONVERT_HIGHLIGHTS,
DELETE_HIGHLIGHTS,
DELETE_IMPORTED_REDACTIONS);
public static final Set<String> RED_ADMIN_ACTION_ROLES = Sets.newHashSet(ADD_DICTIONARY_ENTRY,
ADD_UPDATE_DICTIONARY_TYPE,
WRITE_DOSSIER_STATUS,
READ_DOSSIER_STATUS,
DELETE_DICTIONARY_ENTRY,
DELETE_DICTIONARY_TYPE,
DELETE_REPORT_TEMPLATE,
DOWNLOAD_REPORT_TEMPLATE,
GET_REPORT_TEMPLATES,
MANAGE_USER_PREFERENCES,
READ_COLORS,
READ_DICTIONARY_TYPES,
READ_DIGITAL_SIGNATURE,
READ_DOSSIER_ATTRIBUTES,
READ_DOSSIER_ATTRIBUTES_CONFIG,
READ_DOSSIER_TEMPLATES,
READ_FILE_ATTRIBUTES_CONFIG,
READ_LEGAL_BASIS,
READ_LICENSE_REPORT,
READ_NOTIFICATIONS,
READ_RULES,
READ_SMTP_CONFIGURATION,
READ_VERSIONS,
READ_WATERMARK,
REINDEX,
SEARCH_AUDIT_LOG,
UPDATE_NOTIFICATIONS,
UPLOAD_REPORT_TEMPLATE,
WRITE_COLORS,
WRITE_DIGITAL_SIGNATURE,
WRITE_DOSSIER_ATTRIBUTES_CONFIG,
WRITE_DOSSIER_TEMPLATES,
WRITE_FILE_ATTRIBUTES_CONFIG,
WRITE_GENERAL_CONFIGURATION,
WRITE_LEGAL_BASIS,
WRITE_RULES,
WRITE_SMTP_CONFIGURATION,
WRITE_WATERMARK,
WRITE_APP_CONFIG,
MANAGE_ACL_PERMISSIONS,
CREATE_TENANT,
GET_TENANTS,
DEPLOYMENT_INFO);
public static final Set<String> RED_MANAGER_ACTION_ROLES = Sets.newHashSet(ADD_UPDATE_DOSSIER, ARCHIVE_DOSSIER, DELETE_DOSSIER, WRITE_DOSSIER_ATTRIBUTES);
public static final Set<String> RED_USER_ADMIN_ACTION_ROLES = Sets.newHashSet(MANAGE_USER_PREFERENCES,
READ_ALL_USERS,
READ_DOSSIER,
READ_APP_CONFIG,
READ_GENERAL_CONFIGURATION,
READ_GENERAL_CONFIGURATION,
READ_NOTIFICATIONS,
READ_USERS,
UPDATE_MY_PROFILE,
UPDATE_NOTIFICATIONS,
WRITE_USERS,
READ_LICENSE);
public static final Map<String, Set<String>> ROLE_DATA = Map.of(RED_USER_ROLE,
RED_USER_ACTION_ROLES,
RED_MANAGER_ROLE,
RED_MANAGER_ACTION_ROLES,
RED_ADMIN_ROLE,
RED_ADMIN_ACTION_ROLES,
RED_USER_ADMIN_ROLE,
RED_USER_ADMIN_ACTION_ROLES);
private ApplicationRoles() {}
public static void validateRoles(Collection<String> roles) {
for (String role : roles) {
if (!ROLE_DATA.containsKey(role)) {
throw new IllegalArgumentException("Invalid Role: " + role);
}
}
}
}

View File

@ -1,91 +0,0 @@
package com.iqser.red.keycloak.commons.security;
import javax.security.cert.X509Certificate;
import org.keycloak.adapters.BearerTokenRequestAuthenticator;
import org.keycloak.adapters.KeycloakDeployment;
import org.keycloak.adapters.OIDCAuthenticationError;
import org.keycloak.adapters.spi.AuthOutcome;
import org.keycloak.adapters.spi.HttpFacade;
import org.keycloak.common.VerificationException;
import org.keycloak.jose.jws.JWSInput;
import org.keycloak.jose.jws.JWSInputException;
public class RedBearerTokenRequestAuthenticator extends BearerTokenRequestAuthenticator {
private final String issuerUrl;
public RedBearerTokenRequestAuthenticator(KeycloakDeployment deployment, String issuerUrl) {
super(deployment);
this.issuerUrl = issuerUrl;
}
// This is the exact method copied from BearerTokenRequestAuthenticator but with a custom Token Verifier.
@Override
protected AuthOutcome authenticateToken(HttpFacade exchange, String tokenString) {
this.log.debug("Verifying access_token");
if (this.log.isTraceEnabled()) {
try {
JWSInput jwsInput = new JWSInput(tokenString);
String wireString = jwsInput.getWireString();
this.log.tracef("\taccess_token: %s", wireString.substring(0, wireString.lastIndexOf(".")) + ".signature");
} catch (JWSInputException var8) {
this.log.debugf(var8, "Failed to parse access_token: %s", tokenString);
}
}
try {
this.token = RedTokenVerifier.verifyToken(tokenString, this.deployment, issuerUrl);
} catch (VerificationException var7) {
this.log.debug("Failed to verify token");
this.challenge = this.challengeResponse(exchange, OIDCAuthenticationError.Reason.INVALID_TOKEN, "invalid_token", var7.getMessage());
return AuthOutcome.FAILED;
}
if (this.token.getIssuedAt() < this.deployment.getNotBefore()) {
this.log.debug("Stale token");
this.challenge = this.challengeResponse(exchange, OIDCAuthenticationError.Reason.STALE_TOKEN, "invalid_token", "Stale token");
return AuthOutcome.FAILED;
} else {
boolean verifyCaller = false;
if (this.deployment.isUseResourceRoleMappings()) {
verifyCaller = this.token.isVerifyCaller(this.deployment.getResourceName());
} else {
verifyCaller = this.token.isVerifyCaller();
}
this.surrogate = null;
if (verifyCaller) {
if (this.token.getTrustedCertificates() == null || this.token.getTrustedCertificates().isEmpty()) {
this.log.warn("No trusted certificates in token");
this.challenge = this.clientCertChallenge();
return AuthOutcome.FAILED;
}
X509Certificate[] chain = new X509Certificate[0];
try {
chain = exchange.getCertificateChain();
} catch (Exception var6) {
log.debug(var6);
}
if (chain == null || chain.length == 0) {
this.log.warn("No certificates provided by undertow to verify the caller");
this.challenge = this.clientCertChallenge();
return AuthOutcome.FAILED;
}
this.surrogate = chain[0].getSubjectDN().getName();
}
this.log.debug("successful authorized");
return AuthOutcome.AUTHENTICATED;
}
}
}

View File

@ -1,91 +0,0 @@
package com.iqser.red.keycloak.commons.security;
import javax.security.cert.X509Certificate;
import org.keycloak.adapters.KeycloakDeployment;
import org.keycloak.adapters.OIDCAuthenticationError;
import org.keycloak.adapters.QueryParameterTokenRequestAuthenticator;
import org.keycloak.adapters.spi.AuthOutcome;
import org.keycloak.adapters.spi.HttpFacade;
import org.keycloak.common.VerificationException;
import org.keycloak.jose.jws.JWSInput;
import org.keycloak.jose.jws.JWSInputException;
public class RedQueryParameterTokenRequestAuthenticator extends QueryParameterTokenRequestAuthenticator {
private final String issuerUrl;
public RedQueryParameterTokenRequestAuthenticator(KeycloakDeployment deployment, String issuerUrl) {
super(deployment);
this.issuerUrl = issuerUrl;
}
// This is the exact method copied from BearerTokenRequestAuthenticator but with a custom Token Verifier.
@Override
protected AuthOutcome authenticateToken(HttpFacade exchange, String tokenString) {
this.log.debug("Verifying access_token");
if (this.log.isTraceEnabled()) {
try {
JWSInput jwsInput = new JWSInput(tokenString);
String wireString = jwsInput.getWireString();
this.log.tracef("\taccess_token: %s", wireString.substring(0, wireString.lastIndexOf(".")) + ".signature");
} catch (JWSInputException var8) {
this.log.debugf(var8, "Failed to parse access_token: %s", tokenString);
}
}
try {
this.token = RedTokenVerifier.verifyToken(tokenString, this.deployment, issuerUrl);
} catch (VerificationException var7) {
this.log.debug("Failed to verify token");
this.challenge = this.challengeResponse(exchange, OIDCAuthenticationError.Reason.INVALID_TOKEN, "invalid_token", var7.getMessage());
return AuthOutcome.FAILED;
}
if (this.token.getIssuedAt() < this.deployment.getNotBefore()) {
this.log.debug("Stale token");
this.challenge = this.challengeResponse(exchange, OIDCAuthenticationError.Reason.STALE_TOKEN, "invalid_token", "Stale token");
return AuthOutcome.FAILED;
} else {
boolean verifyCaller = false;
if (this.deployment.isUseResourceRoleMappings()) {
verifyCaller = this.token.isVerifyCaller(this.deployment.getResourceName());
} else {
verifyCaller = this.token.isVerifyCaller();
}
this.surrogate = null;
if (verifyCaller) {
if (this.token.getTrustedCertificates() == null || this.token.getTrustedCertificates().isEmpty()) {
this.log.warn("No trusted certificates in token");
this.challenge = this.clientCertChallenge();
return AuthOutcome.FAILED;
}
X509Certificate[] chain = new X509Certificate[0];
try {
chain = exchange.getCertificateChain();
} catch (Exception var6) {
log.debug(var6);
}
if (chain == null || chain.length == 0) {
this.log.warn("No certificates provided by undertow to verify the caller");
this.challenge = this.clientCertChallenge();
return AuthOutcome.FAILED;
}
this.surrogate = chain[0].getSubjectDN().getName();
}
this.log.debug("successful authorized");
return AuthOutcome.AUTHENTICATED;
}
}
}

View File

@ -1,87 +0,0 @@
package com.iqser.red.keycloak.commons.security;
import static org.keycloak.TokenVerifier.IS_ACTIVE;
import static org.keycloak.TokenVerifier.SUBJECT_EXISTS_CHECK;
import java.security.PublicKey;
import org.apache.commons.lang3.StringUtils;
import org.keycloak.TokenVerifier;
import org.keycloak.adapters.KeycloakDeployment;
import org.keycloak.adapters.rotation.PublicKeyLocator;
import org.keycloak.common.VerificationException;
import org.keycloak.representations.AccessToken;
import lombok.experimental.UtilityClass;
import lombok.extern.slf4j.Slf4j;
@Slf4j
@UtilityClass
public class RedTokenVerifier {
public AccessToken verifyToken(String tokenString, KeycloakDeployment deployment, String issuerUrl) throws VerificationException {
TokenVerifier<AccessToken> tokenVerifier = createVerifier(tokenString, deployment, issuerUrl);
if (deployment.isVerifyTokenAudience()) {
tokenVerifier.audience(deployment.getResourceName());
}
return tokenVerifier.verify().getToken();
}
private TokenVerifier<AccessToken> createVerifier(String tokenString, KeycloakDeployment deployment, String issuerUrl) throws VerificationException {
TokenVerifier<AccessToken> tokenVerifier = TokenVerifier.create(tokenString, AccessToken.class)
.withChecks(SUBJECT_EXISTS_CHECK, IS_ACTIVE, new TokenVerifier.TokenTypeCheck("bearer"), new IssuerCheck(issuerUrl));
String kid = tokenVerifier.getHeader().getKeyId();
PublicKey publicKey = getPublicKey(kid, deployment);
tokenVerifier.publicKey(publicKey);
return tokenVerifier;
}
private PublicKey getPublicKey(String kid, KeycloakDeployment deployment) throws VerificationException {
PublicKeyLocator pkLocator = deployment.getPublicKeyLocator();
PublicKey publicKey = pkLocator.getPublicKey(kid, deployment);
if (publicKey == null) {
log.debug("Didn't find publicKey for kid: {}", kid);
throw new VerificationException("Didn't find publicKey for specified kid");
} else {
return publicKey;
}
}
@Slf4j
public static class IssuerCheck implements TokenVerifier.Predicate<AccessToken> {
private final String issuerUrl;
public IssuerCheck(String issuerUrl) {
this.issuerUrl = issuerUrl;
}
public boolean test(AccessToken t) throws VerificationException {
if (StringUtils.isEmpty(this.issuerUrl)) {
log.debug("Issuer Not Set, skipping verification");
return true;
} else if (!this.issuerUrl.equalsIgnoreCase(t.getIssuer())) {
var message = "Invalid token issuer. Expected '" + this.issuerUrl + "', but was '" + t.getIssuer() + "'";
log.debug(message);
throw new VerificationException(message);
} else {
log.debug("Issuer Verification Successful");
return true;
}
}
}
}

View File

@ -1,150 +0,0 @@
package com.iqser.red.keycloak.commons.security;
import javax.servlet.http.HttpServletRequest;
import org.keycloak.adapters.AdapterTokenStore;
import org.keycloak.adapters.BearerTokenRequestAuthenticator;
import org.keycloak.adapters.KeycloakDeployment;
import org.keycloak.adapters.QueryParameterTokenRequestAuthenticator;
import org.keycloak.adapters.RequestAuthenticator;
import org.keycloak.adapters.spi.HttpFacade;
import org.keycloak.adapters.springboot.KeycloakBaseSpringBootConfiguration;
import org.keycloak.adapters.springboot.KeycloakSpringBootConfigResolver;
import org.keycloak.adapters.springsecurity.KeycloakConfiguration;
import org.keycloak.adapters.springsecurity.authentication.KeycloakAuthenticationProvider;
import org.keycloak.adapters.springsecurity.authentication.SpringSecurityRequestAuthenticator;
import org.keycloak.adapters.springsecurity.authentication.SpringSecurityRequestAuthenticatorFactory;
import org.keycloak.adapters.springsecurity.config.KeycloakWebSecurityConfigurerAdapter;
import org.keycloak.adapters.springsecurity.filter.KeycloakAuthenticationProcessingFilter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Import;
import org.springframework.context.annotation.Primary;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.core.authority.mapping.SimpleAuthorityMapper;
import org.springframework.security.web.authentication.HttpStatusEntryPoint;
import org.springframework.security.web.authentication.session.NullAuthenticatedSessionStrategy;
import org.springframework.security.web.authentication.session.SessionAuthenticationStrategy;
import com.iqser.red.keycloak.commons.KeyCloakSettings;
import lombok.RequiredArgsConstructor;
@ConditionalOnProperty(value = "keycloak.enabled", havingValue = "true")
@RequiredArgsConstructor
@KeycloakConfiguration
@EnableConfigurationProperties(KeyCloakSettings.class)
@Import(KeycloakSpringBootConfigResolver.class)
public class SecuredKeyCloakConfiguration extends KeycloakWebSecurityConfigurerAdapter {
private final KeyCloakSettings keyCloakSettings;
@Bean
public KeycloakBaseSpringBootConfiguration keycloakBaseSpringBootConfiguration() {
return new KeycloakBaseSpringBootConfiguration();
}
// Submits the KeycloakAuthenticationProvider to the AuthenticationManager
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) {
KeycloakAuthenticationProvider keycloakAuthenticationProvider = keycloakAuthenticationProvider();
SimpleAuthorityMapper simpleAuthorityMapper = new SimpleAuthorityMapper();
simpleAuthorityMapper.setPrefix("");
keycloakAuthenticationProvider.setGrantedAuthoritiesMapper(simpleAuthorityMapper);
auth.authenticationProvider(keycloakAuthenticationProvider);
}
@Override
public void configure(WebSecurity web) {
web.ignoring()
.antMatchers("/actuator/health/**",
"/redaction-gateway-v1/async/download/with-ott/**",
"/redaction-gateway-v1/docs/**",
"/redaction-gateway-v1/docs",
"/redaction-gateway-v1/tenants/simple",
"/redaction-gateway-v1",
"/internal-api/**");
web.ignoring().antMatchers(HttpMethod.OPTIONS, "/**");
}
@Bean
@Primary
@Override
protected KeycloakAuthenticationProcessingFilter keycloakAuthenticationProcessingFilter() throws Exception {
KeycloakAuthenticationProcessingFilter filter = new KeycloakAuthenticationProcessingFilter(authenticationManagerBean());
filter.setSessionAuthenticationStrategy(sessionAuthenticationStrategy());
filter.setRequestAuthenticatorFactory(new SpringSecurityRequestAuthenticatorFactory() {
@Override
public RequestAuthenticator createRequestAuthenticator(HttpFacade facade,
HttpServletRequest request,
KeycloakDeployment deployment,
AdapterTokenStore tokenStore,
int sslRedirectPort) {
return new SpringSecurityRequestAuthenticator(facade, request, deployment, tokenStore, sslRedirectPort) {
@Override
protected BearerTokenRequestAuthenticator createBearerTokenAuthenticator() {
return new RedBearerTokenRequestAuthenticator(deployment, keyCloakSettings.getIssuer());
}
@Override
protected QueryParameterTokenRequestAuthenticator createQueryParameterTokenRequestAuthenticator() {
return new RedQueryParameterTokenRequestAuthenticator(deployment, keyCloakSettings.getIssuer());
}
};
}
});
return filter;
}
// Specifies the session authentication strategy
@Bean
@Override
protected SessionAuthenticationStrategy sessionAuthenticationStrategy() {
return new NullAuthenticatedSessionStrategy();
}
@Override
protected void configure(HttpSecurity http) throws Exception {
super.configure(http);
http.anonymous().disable();
http.authorizeRequests().anyRequest().authenticated();
http.csrf().disable();
http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
http.exceptionHandling().authenticationEntryPoint(new HttpStatusEntryPoint(HttpStatus.UNAUTHORIZED));
}
}

View File

@ -1,16 +0,0 @@
package com.iqser.red.keycloak.commons;
import static org.assertj.core.api.Assertions.assertThat;
import org.junit.jupiter.api.Test;
public class IdentityTest {
@Test
public void mockTest() {
int i = 1;
assertThat(i).isEqualTo(1);
}
}

View File

@ -24,10 +24,6 @@
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-ui</artifactId>
</dependency>
</dependencies>
</project>

View File

@ -1,27 +1,11 @@
package com.iqser.red.persistence.service.v1.external.api.impl;
import org.keycloak.adapters.KeycloakConfigResolver;
import org.keycloak.adapters.springboot.KeycloakSpringBootProperties;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.iqser.red.persistence.service.v1.external.api.impl.multitenacy.HeaderBasedKeycloakRealmResolver;
@Configuration
@ComponentScan
public class PersistenceServiceExternalApiConfiguration {
@Bean
public KeycloakConfigResolver keycloakConfigResolver(ObjectMapper objectMapper) {
return new HeaderBasedKeycloakRealmResolver(objectMapper);
}
@Autowired
public void setKeycloakSpringBootProperties(final KeycloakSpringBootProperties keycloakProperties) {
HeaderBasedKeycloakRealmResolver.setAdapterConfig(keycloakProperties);
}
}

View File

@ -1,9 +1,8 @@
package com.iqser.red.persistence.service.v1.external.api.impl.controller;
import static com.iqser.red.keycloak.commons.roles.ActionRoles.READ_APP_CONFIG;
import static com.iqser.red.keycloak.commons.roles.ActionRoles.WRITE_APP_CONFIG;
import static com.iqser.red.service.persistence.management.v1.processor.roles.ActionRoles.READ_APP_CONFIG;
import static com.iqser.red.service.persistence.management.v1.processor.roles.ActionRoles.WRITE_APP_CONFIG;
import javax.validation.Valid;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.RequestBody;
@ -15,6 +14,7 @@ import com.iqser.red.service.persistence.management.v1.processor.utils.MagicConv
import com.iqser.red.service.persistence.service.v1.api.external.resource.ApplicationConfigurationResource;
import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.configuration.ApplicationConfig;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;

View File

@ -1,6 +1,6 @@
package com.iqser.red.persistence.service.v1.external.api.impl.controller;
import static com.iqser.red.keycloak.commons.roles.ActionRoles.SEARCH_AUDIT_LOG;
import static com.iqser.red.service.persistence.management.v1.processor.roles.ActionRoles.SEARCH_AUDIT_LOG;
import static com.iqser.red.service.persistence.management.v1.processor.utils.MagicConverter.convert;
import java.util.List;
@ -9,7 +9,7 @@ import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import com.iqser.red.keycloak.commons.KeycloakSecurity;
import com.knecon.fforesight.keycloakcommons.security.KeycloakSecurity;
import com.iqser.red.service.persistence.management.v1.processor.service.persistence.AuditPersistenceService;
import com.iqser.red.service.persistence.service.v1.api.external.resource.AuditResource;
import com.iqser.red.service.persistence.service.v1.api.shared.model.AuditCategory;

View File

@ -1,6 +1,6 @@
package com.iqser.red.persistence.service.v1.external.api.impl.controller;
import static com.iqser.red.keycloak.commons.roles.ActionRoles.MANAGE_ACL_PERMISSIONS;
import static com.iqser.red.service.persistence.management.v1.processor.roles.ActionRoles.MANAGE_ACL_PERMISSIONS;
import java.util.List;
import java.util.Set;

View File

@ -10,7 +10,6 @@ import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import javax.validation.Valid;
import org.springframework.core.io.InputStreamResource;
import org.springframework.http.HttpHeaders;
@ -24,7 +23,7 @@ import org.springframework.web.bind.annotation.RequestPart;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import com.iqser.red.keycloak.commons.KeycloakSecurity;
import com.knecon.fforesight.keycloakcommons.security.KeycloakSecurity;
import com.iqser.red.service.persistence.management.v1.processor.exception.BadRequestException;
import com.iqser.red.service.persistence.management.v1.processor.service.DictionaryService;
import com.iqser.red.service.persistence.management.v1.processor.service.persistence.AuditPersistenceService;
@ -44,6 +43,7 @@ import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemp
import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.type.Type;
import feign.FeignException;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;

View File

@ -1,7 +1,7 @@
package com.iqser.red.persistence.service.v1.external.api.impl.controller;
import static com.iqser.red.keycloak.commons.roles.ActionRoles.READ_DIGITAL_SIGNATURE;
import static com.iqser.red.keycloak.commons.roles.ActionRoles.WRITE_DIGITAL_SIGNATURE;
import static com.iqser.red.service.persistence.management.v1.processor.roles.ActionRoles.READ_DIGITAL_SIGNATURE;
import static com.iqser.red.service.persistence.management.v1.processor.roles.ActionRoles.WRITE_DIGITAL_SIGNATURE;
import java.nio.charset.StandardCharsets;
@ -10,7 +10,7 @@ import org.springframework.util.Base64Utils;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import com.iqser.red.keycloak.commons.KeycloakSecurity;
import com.knecon.fforesight.keycloakcommons.security.KeycloakSecurity;
import com.iqser.red.service.persistence.management.v1.processor.entity.configuration.DigitalSignatureEntity;
import com.iqser.red.service.persistence.management.v1.processor.entity.configuration.DigitalSignatureKmsEntity;
import com.iqser.red.service.persistence.management.v1.processor.service.DigitalSignatureKmsService;

View File

@ -1,10 +1,10 @@
package com.iqser.red.persistence.service.v1.external.api.impl.controller;
import static com.iqser.red.keycloak.commons.roles.ActionRoles.READ_DOSSIER_ATTRIBUTES;
import static com.iqser.red.keycloak.commons.roles.ActionRoles.READ_DOSSIER_ATTRIBUTES_CONFIG;
import static com.iqser.red.keycloak.commons.roles.ActionRoles.WRITE_DOSSIER_ATTRIBUTES;
import static com.iqser.red.keycloak.commons.roles.ActionRoles.WRITE_DOSSIER_ATTRIBUTES_CONFIG;
import static com.iqser.red.keycloak.commons.roles.ActionRoles.WRITE_FILE_ATTRIBUTES;
import static com.iqser.red.service.persistence.management.v1.processor.roles.ActionRoles.READ_DOSSIER_ATTRIBUTES;
import static com.iqser.red.service.persistence.management.v1.processor.roles.ActionRoles.READ_DOSSIER_ATTRIBUTES_CONFIG;
import static com.iqser.red.service.persistence.management.v1.processor.roles.ActionRoles.WRITE_DOSSIER_ATTRIBUTES;
import static com.iqser.red.service.persistence.management.v1.processor.roles.ActionRoles.WRITE_DOSSIER_ATTRIBUTES_CONFIG;
import static com.iqser.red.service.persistence.management.v1.processor.roles.ActionRoles.WRITE_FILE_ATTRIBUTES;
import java.util.List;
import java.util.Map;
@ -15,7 +15,7 @@ import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import com.iqser.red.keycloak.commons.KeycloakSecurity;
import com.knecon.fforesight.keycloakcommons.security.KeycloakSecurity;
import com.iqser.red.service.persistence.management.v1.processor.entity.dossier.DossierAttributeConfigEntity;
import com.iqser.red.service.persistence.management.v1.processor.service.AccessControlService;
import com.iqser.red.service.persistence.management.v1.processor.service.DossierAttributesManagementService;

View File

@ -1,10 +1,10 @@
package com.iqser.red.persistence.service.v1.external.api.impl.controller;
import static com.iqser.red.keycloak.commons.roles.ActionRoles.ADD_UPDATE_DOSSIER;
import static com.iqser.red.keycloak.commons.roles.ActionRoles.ARCHIVE_DOSSIER;
import static com.iqser.red.keycloak.commons.roles.ActionRoles.DELETE_DOSSIER;
import static com.iqser.red.keycloak.commons.roles.ActionRoles.READ_DOSSIER;
import static com.iqser.red.keycloak.commons.roles.ActionRoles.UNARCHIVE_DOSSIER;
import static com.iqser.red.service.persistence.management.v1.processor.roles.ActionRoles.ADD_UPDATE_DOSSIER;
import static com.iqser.red.service.persistence.management.v1.processor.roles.ActionRoles.ARCHIVE_DOSSIER;
import static com.iqser.red.service.persistence.management.v1.processor.roles.ActionRoles.DELETE_DOSSIER;
import static com.iqser.red.service.persistence.management.v1.processor.roles.ActionRoles.READ_DOSSIER;
import static com.iqser.red.service.persistence.management.v1.processor.roles.ActionRoles.UNARCHIVE_DOSSIER;
import java.time.OffsetDateTime;
import java.util.ArrayList;
@ -33,15 +33,15 @@ import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import com.google.common.collect.Lists;
import com.iqser.red.keycloak.commons.KeycloakSecurity;
import com.iqser.red.keycloak.commons.model.User;
import com.iqser.red.keycloak.commons.roles.ApplicationRoles;
import com.iqser.red.service.persistence.management.v1.processor.service.users.model.User;
import com.knecon.fforesight.keycloakcommons.security.KeycloakSecurity;
import com.iqser.red.service.persistence.management.v1.processor.roles.ApplicationRoles;
import com.iqser.red.service.persistence.management.v1.processor.acl.custom.dossier.DossierACLService;
import com.iqser.red.service.persistence.management.v1.processor.exception.BadRequestException;
import com.iqser.red.service.persistence.management.v1.processor.service.AccessControlService;
import com.iqser.red.service.persistence.management.v1.processor.service.DossierManagementService;
import com.iqser.red.service.persistence.management.v1.processor.service.FileStatusManagementService;
import com.iqser.red.service.persistence.management.v1.processor.service.UserService;
import com.iqser.red.service.persistence.management.v1.processor.service.users.UserService;
import com.iqser.red.service.persistence.management.v1.processor.service.persistence.AuditPersistenceService;
import com.iqser.red.service.persistence.management.v1.processor.service.persistence.NotificationPersistenceService;
import com.iqser.red.service.persistence.service.v1.api.external.resource.DossierResource;

View File

@ -1,6 +1,6 @@
package com.iqser.red.persistence.service.v1.external.api.impl.controller;
import static com.iqser.red.keycloak.commons.roles.ActionRoles.READ_DOSSIER;
import static com.iqser.red.service.persistence.management.v1.processor.roles.ActionRoles.READ_DOSSIER;
import java.util.List;
import java.util.Set;

View File

@ -1,12 +1,12 @@
package com.iqser.red.persistence.service.v1.external.api.impl.controller;
import static com.iqser.red.keycloak.commons.roles.ActionRoles.READ_DOSSIER_STATUS;
import static com.iqser.red.keycloak.commons.roles.ActionRoles.WRITE_DOSSIER_STATUS;
import static com.iqser.red.service.persistence.management.v1.processor.roles.ActionRoles.READ_DOSSIER_STATUS;
import static com.iqser.red.service.persistence.management.v1.processor.roles.ActionRoles.WRITE_DOSSIER_STATUS;
import java.util.List;
import java.util.stream.Collectors;
import javax.transaction.Transactional;
import jakarta.transaction.Transactional;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.PathVariable;

View File

@ -1,9 +1,7 @@
package com.iqser.red.persistence.service.v1.external.api.impl.controller;
import static com.iqser.red.keycloak.commons.roles.ActionRoles.READ_DOSSIER_TEMPLATES;
import static com.iqser.red.keycloak.commons.roles.ActionRoles.WRITE_DOSSIER_TEMPLATES;
import static com.iqser.red.keycloak.commons.roles.ApplicationRoles.RED_MANAGER_ROLE;
import static com.iqser.red.keycloak.commons.roles.ApplicationRoles.RED_USER_ROLE;
import static com.iqser.red.service.persistence.management.v1.processor.roles.ActionRoles.READ_DOSSIER_TEMPLATES;
import static com.iqser.red.service.persistence.management.v1.processor.roles.ActionRoles.WRITE_DOSSIER_TEMPLATES;
import static com.iqser.red.service.persistence.management.v1.processor.service.FeignExceptionHandler.processFeignException;
import java.io.IOException;
@ -14,10 +12,7 @@ import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
import javax.annotation.PostConstruct;
import org.apache.commons.lang3.StringUtils;
import org.keycloak.representations.idm.RoleRepresentation;
import org.springframework.beans.BeanUtils;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.PathVariable;
@ -27,15 +22,14 @@ import org.springframework.web.bind.annotation.RequestPart;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import com.iqser.red.keycloak.commons.KeycloakSecurity;
import com.iqser.red.service.persistence.management.v1.processor.acl.custom.dossier.DossierACLService;
import com.iqser.red.service.persistence.management.v1.processor.exception.BadRequestException;
import com.iqser.red.service.persistence.management.v1.processor.exception.ConflictException;
import com.iqser.red.service.persistence.management.v1.processor.service.DossierManagementService;
import com.iqser.red.service.persistence.management.v1.processor.service.DossierTemplateManagementService;
import com.iqser.red.service.persistence.management.v1.processor.service.DossierTemplateStatsService;
import com.iqser.red.service.persistence.management.v1.processor.service.UserService;
import com.iqser.red.service.persistence.management.v1.processor.service.persistence.AuditPersistenceService;
import com.iqser.red.service.persistence.management.v1.processor.service.users.UserService;
import com.iqser.red.service.persistence.service.v1.api.external.resource.DossierTemplateResource;
import com.iqser.red.service.persistence.service.v1.api.shared.model.AuditCategory;
import com.iqser.red.service.persistence.service.v1.api.shared.model.DossierTemplateModel;
@ -49,6 +43,7 @@ import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemp
import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.dossier.Dossier;
import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.importexport.ExportDownloadRequest;
import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.importexport.ImportDossierTemplateRequest;
import com.knecon.fforesight.keycloakcommons.security.KeycloakSecurity;
import feign.FeignException;
import io.micrometer.core.annotation.Timed;
@ -115,26 +110,23 @@ public class DossierTemplateController implements DossierTemplateResource {
@Override
@PreAuthorize("hasAuthority('" + READ_DOSSIER_TEMPLATES + "')")
@PreAuthorize("hasAuthority('" + WRITE_DOSSIER_TEMPLATES + "')")
public void deleteDossierTemplate(@PathVariable(DOSSIER_TEMPLATE_ID) String dossierTemplateId) {
String userId = KeycloakSecurity.getUserId();
if (!userService.checkUserHasAdminRole(userId)) {
throw new BadRequestException("Only admin user can delete the dossier template");
}
List<Dossier> dossiers = dossierManagementService.getAllDossiers(true, false);
if (dossiers != null && dossiers.stream().anyMatch(dossier -> dossier.getDossierTemplateId().equals(dossierTemplateId))) {
throw new ConflictException("Can not delete dossier template because there are dossiers based on it");
}
if (dossiers != null && dossiers.stream().anyMatch(dossier -> dossier.getDossierTemplateId().equals(dossierTemplateId))) {
throw new ConflictException("Can not delete dossier template because there are dossiers based on it");
}
dossierTemplateManagementService.deleteDossierTemplate(dossierTemplateId, userId);
auditPersistenceService.audit(AuditRequest.builder()
.userId(KeycloakSecurity.getUserId())
.objectId(dossierTemplateId)
.category(AuditCategory.DOSSIER_TEMPLATE.name())
.message("Dossier Template has been deleted")
.build());
dossierTemplateManagementService.deleteDossierTemplate(dossierTemplateId, userId);
auditPersistenceService.audit(AuditRequest.builder()
.userId(KeycloakSecurity.getUserId())
.objectId(dossierTemplateId)
.category(AuditCategory.DOSSIER_TEMPLATE.name())
.message("Dossier Template has been deleted")
.build());
}

View File

@ -1,6 +1,6 @@
package com.iqser.red.persistence.service.v1.external.api.impl.controller;
import static com.iqser.red.keycloak.commons.roles.ActionRoles.READ_DOSSIER_TEMPLATES;
import static com.iqser.red.service.persistence.management.v1.processor.roles.ActionRoles.READ_DOSSIER_TEMPLATES;
import java.util.List;
import java.util.Set;

View File

@ -1,7 +1,7 @@
package com.iqser.red.persistence.service.v1.external.api.impl.controller;
import static com.iqser.red.keycloak.commons.roles.ActionRoles.PROCESS_DOWNLOAD;
import static com.iqser.red.keycloak.commons.roles.ActionRoles.READ_DOWNLOAD_STATUS;
import static com.iqser.red.service.persistence.management.v1.processor.roles.ActionRoles.PROCESS_DOWNLOAD;
import static com.iqser.red.service.persistence.management.v1.processor.roles.ActionRoles.READ_DOWNLOAD_STATUS;
import static com.iqser.red.service.persistence.management.v1.processor.utils.DownloadBufferUtils.fileProxyStreamForDownload;
import java.util.List;
@ -24,7 +24,7 @@ import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import com.iqser.red.keycloak.commons.KeycloakSecurity;
import com.knecon.fforesight.keycloakcommons.security.KeycloakSecurity;
import com.iqser.red.persistence.service.v1.external.api.impl.service.OneTimeTokenService;
import com.iqser.red.service.persistence.management.v1.processor.exception.BadRequestException;
import com.iqser.red.service.persistence.management.v1.processor.exception.NotFoundException;
@ -34,7 +34,6 @@ import com.iqser.red.service.persistence.management.v1.processor.service.Downloa
import com.iqser.red.service.persistence.management.v1.processor.service.FileStatusService;
import com.iqser.red.service.persistence.management.v1.processor.service.persistence.AuditPersistenceService;
import com.iqser.red.service.persistence.management.v1.processor.utils.StringEncodingUtils;
import com.iqser.red.service.persistence.management.v1.processor.utils.multitenancy.TenantContext;
import com.iqser.red.service.persistence.service.v1.api.external.resource.DownloadResource;
import com.iqser.red.service.persistence.service.v1.api.shared.model.AuditCategory;
import com.iqser.red.service.persistence.service.v1.api.shared.model.DownloadResponse;
@ -51,6 +50,7 @@ import com.iqser.red.service.persistence.service.v1.api.shared.model.download.Do
import com.iqser.red.service.persistence.service.v1.api.shared.model.download.DownloadStatus;
import com.iqser.red.service.persistence.service.v1.api.shared.model.download.DownloadWithOptionRequest;
import com.iqser.red.storage.commons.service.StorageService;
import com.knecon.fforesight.tenantcommons.TenantContext;
import lombok.RequiredArgsConstructor;
import lombok.SneakyThrows;

View File

@ -30,9 +30,7 @@ import com.iqser.red.service.persistence.management.v1.processor.exception.BadRe
import com.iqser.red.service.persistence.management.v1.processor.exception.ConflictException;
import com.iqser.red.service.persistence.management.v1.processor.exception.NotAllowedException;
import com.iqser.red.service.persistence.management.v1.processor.exception.NotFoundException;
import com.iqser.red.service.persistence.management.v1.processor.service.job.AutomaticAnalysisJob;
import com.iqser.red.service.persistence.management.v1.processor.service.job.SyncUserPermissionsJob;
import com.iqser.red.service.persistence.management.v1.processor.utils.multitenancy.TenantContext;
import com.knecon.fforesight.tenantcommons.TenantContext;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;

View File

@ -1,8 +1,8 @@
package com.iqser.red.persistence.service.v1.external.api.impl.controller;
import static com.iqser.red.keycloak.commons.roles.ActionRoles.READ_FILE_ATTRIBUTES_CONFIG;
import static com.iqser.red.keycloak.commons.roles.ActionRoles.WRITE_FILE_ATTRIBUTES;
import static com.iqser.red.keycloak.commons.roles.ActionRoles.WRITE_FILE_ATTRIBUTES_CONFIG;
import static com.iqser.red.service.persistence.management.v1.processor.roles.ActionRoles.READ_FILE_ATTRIBUTES_CONFIG;
import static com.iqser.red.service.persistence.management.v1.processor.roles.ActionRoles.WRITE_FILE_ATTRIBUTES;
import static com.iqser.red.service.persistence.management.v1.processor.roles.ActionRoles.WRITE_FILE_ATTRIBUTES_CONFIG;
import java.util.List;
import java.util.Map;
@ -13,7 +13,7 @@ import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import com.iqser.red.keycloak.commons.KeycloakSecurity;
import com.knecon.fforesight.keycloakcommons.security.KeycloakSecurity;
import com.iqser.red.service.persistence.management.v1.processor.entity.configuration.FileAttributesGeneralConfigurationEntity;
import com.iqser.red.service.persistence.management.v1.processor.entity.dossier.FileAttributeConfigEntity;
import com.iqser.red.service.persistence.management.v1.processor.exception.BadRequestException;

View File

@ -1,8 +1,8 @@
package com.iqser.red.persistence.service.v1.external.api.impl.controller;
import static com.iqser.red.keycloak.commons.roles.ActionRoles.DELETE_FILE;
import static com.iqser.red.keycloak.commons.roles.ActionRoles.DOWNLOAD_ORIGINAL_FILE;
import static com.iqser.red.keycloak.commons.roles.ActionRoles.ROTATE_PAGE;
import static com.iqser.red.service.persistence.management.v1.processor.roles.ActionRoles.DELETE_FILE;
import static com.iqser.red.service.persistence.management.v1.processor.roles.ActionRoles.DOWNLOAD_ORIGINAL_FILE;
import static com.iqser.red.service.persistence.management.v1.processor.roles.ActionRoles.ROTATE_PAGE;
import static com.iqser.red.service.persistence.management.v1.processor.service.FeignExceptionHandler.processFeignException;
import static com.iqser.red.service.persistence.management.v1.processor.utils.DownloadBufferUtils.fileProxyStreamForDownload;
@ -24,7 +24,7 @@ import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import com.google.common.collect.Sets;
import com.iqser.red.keycloak.commons.KeycloakSecurity;
import com.knecon.fforesight.keycloakcommons.security.KeycloakSecurity;
import com.iqser.red.service.persistence.management.v1.processor.client.pdftronredactionservice.PDFTronClient;
import com.iqser.red.service.persistence.management.v1.processor.exception.BadRequestException;
import com.iqser.red.service.persistence.management.v1.processor.exception.NotAllowedException;
@ -35,7 +35,6 @@ import com.iqser.red.service.persistence.management.v1.processor.service.Reanaly
import com.iqser.red.service.persistence.management.v1.processor.service.persistence.AuditPersistenceService;
import com.iqser.red.service.persistence.management.v1.processor.utils.StorageIdUtils;
import com.iqser.red.service.persistence.management.v1.processor.utils.StringEncodingUtils;
import com.iqser.red.service.persistence.management.v1.processor.utils.multitenancy.TenantContext;
import com.iqser.red.service.persistence.service.v1.api.external.resource.FileManagementResource;
import com.iqser.red.service.persistence.service.v1.api.shared.model.AuditCategory;
import com.iqser.red.service.persistence.service.v1.api.shared.model.RotatePagesRequest;
@ -43,6 +42,7 @@ import com.iqser.red.service.persistence.service.v1.api.shared.model.audit.Audit
import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.dossier.file.FileModel;
import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.dossier.file.FileType;
import com.iqser.red.storage.commons.service.StorageService;
import com.knecon.fforesight.tenantcommons.TenantContext;
import feign.FeignException;
import io.micrometer.core.annotation.Timed;

View File

@ -1,40 +0,0 @@
package com.iqser.red.persistence.service.v1.external.api.impl.controller;
import static com.iqser.red.keycloak.commons.roles.ActionRoles.READ_GENERAL_CONFIGURATION;
import static com.iqser.red.keycloak.commons.roles.ActionRoles.WRITE_GENERAL_CONFIGURATION;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import com.iqser.red.service.persistence.management.v1.processor.service.GeneralConfigurationService;
import com.iqser.red.service.persistence.service.v1.api.external.resource.GeneralSettingsResource;
import com.iqser.red.service.persistence.service.v1.api.shared.model.GeneralConfigurationModel;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
@Slf4j
@RestController
@RequiredArgsConstructor
public class GeneralSettingsController implements GeneralSettingsResource {
private final GeneralConfigurationService generalConfigurationService;
@Override
@PreAuthorize("hasAuthority('" + READ_GENERAL_CONFIGURATION + "')")
public GeneralConfigurationModel getGeneralConfigurations() {
return generalConfigurationService.getGeneralConfigurations();
}
@Override
@PreAuthorize("hasAuthority('" + WRITE_GENERAL_CONFIGURATION + "')")
public void updateGeneralConfigurations(@RequestBody GeneralConfigurationModel generalConfigurationModel) {
generalConfigurationService.updateGeneralConfigurations(generalConfigurationModel);
}
}

View File

@ -1,9 +1,9 @@
package com.iqser.red.persistence.service.v1.external.api.impl.controller;
import static com.iqser.red.keycloak.commons.roles.ActionRoles.CONVERT_HIGHLIGHTS;
import static com.iqser.red.keycloak.commons.roles.ActionRoles.DELETE_HIGHLIGHTS;
import static com.iqser.red.keycloak.commons.roles.ActionRoles.DELETE_IMPORTED_REDACTIONS;
import static com.iqser.red.keycloak.commons.roles.ActionRoles.GET_HIGHLIGHTS;
import static com.iqser.red.service.persistence.management.v1.processor.roles.ActionRoles.CONVERT_HIGHLIGHTS;
import static com.iqser.red.service.persistence.management.v1.processor.roles.ActionRoles.DELETE_HIGHLIGHTS;
import static com.iqser.red.service.persistence.management.v1.processor.roles.ActionRoles.DELETE_IMPORTED_REDACTIONS;
import static com.iqser.red.service.persistence.management.v1.processor.roles.ActionRoles.GET_HIGHLIGHTS;
import static com.iqser.red.service.persistence.management.v1.processor.service.FeignExceptionHandler.processFeignException;
import static com.iqser.red.service.persistence.management.v1.processor.utils.StorageIdUtils.getStorageId;
@ -19,12 +19,12 @@ import com.iqser.red.service.pdftron.redaction.v1.api.model.highlights.TextHighl
import com.iqser.red.service.persistence.management.v1.processor.service.AccessControlService;
import com.iqser.red.service.persistence.management.v1.processor.service.FileStatusService;
import com.iqser.red.service.persistence.management.v1.processor.service.ReanalysisService;
import com.iqser.red.service.persistence.management.v1.processor.utils.multitenancy.TenantContext;
import com.iqser.red.service.persistence.service.v1.api.external.resource.HighlightsResource;
import com.iqser.red.service.persistence.service.v1.api.shared.model.AnnotationIds;
import com.iqser.red.service.persistence.service.v1.api.shared.model.annotations.DeleteImportedRedactionsRequest;
import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.dossier.file.FileType;
import com.iqser.red.storage.commons.service.StorageService;
import com.knecon.fforesight.tenantcommons.TenantContext;
import feign.FeignException;
import lombok.RequiredArgsConstructor;

View File

@ -1,18 +1,18 @@
package com.iqser.red.persistence.service.v1.external.api.impl.controller;
import static com.iqser.red.keycloak.commons.roles.ActionRoles.READ_LEGAL_BASIS;
import static com.iqser.red.keycloak.commons.roles.ActionRoles.WRITE_LEGAL_BASIS;
import static com.iqser.red.service.persistence.management.v1.processor.roles.ActionRoles.READ_LEGAL_BASIS;
import static com.iqser.red.service.persistence.management.v1.processor.roles.ActionRoles.WRITE_LEGAL_BASIS;
import java.util.List;
import javax.transaction.Transactional;
import jakarta.transaction.Transactional;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import com.iqser.red.keycloak.commons.KeycloakSecurity;
import com.knecon.fforesight.keycloakcommons.security.KeycloakSecurity;
import com.iqser.red.service.persistence.management.v1.processor.service.persistence.AuditPersistenceService;
import com.iqser.red.service.persistence.management.v1.processor.service.persistence.LegalBasisMappingPersistenceService;
import com.iqser.red.service.persistence.management.v1.processor.utils.MagicConverter;

View File

@ -1,7 +1,7 @@
package com.iqser.red.persistence.service.v1.external.api.impl.controller;
import static com.iqser.red.keycloak.commons.roles.ActionRoles.READ_LICENSE;
import static com.iqser.red.keycloak.commons.roles.ActionRoles.UPDATE_LICENSE;
import static com.iqser.red.service.persistence.management.v1.processor.roles.ActionRoles.READ_LICENSE;
import static com.iqser.red.service.persistence.management.v1.processor.roles.ActionRoles.UPDATE_LICENSE;
import java.time.OffsetDateTime;
import java.time.temporal.ChronoUnit;
@ -11,13 +11,13 @@ import org.springframework.core.env.Environment;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.RestController;
import com.iqser.red.service.persistence.management.v1.processor.utils.multitenancy.TenantContext;
import com.iqser.red.service.persistence.service.v1.api.external.resource.LicenseResource;
import com.iqser.red.service.persistence.service.v1.api.shared.model.license.Feature;
import com.iqser.red.service.persistence.service.v1.api.shared.model.license.FeatureType;
import com.iqser.red.service.persistence.service.v1.api.shared.model.license.License;
import com.iqser.red.service.persistence.service.v1.api.shared.model.license.RedactionLicenseModel;
import com.iqser.red.storage.commons.service.StorageService;
import com.knecon.fforesight.tenantcommons.TenantContext;
import lombok.RequiredArgsConstructor;
import lombok.SneakyThrows;

View File

@ -1,12 +1,12 @@
package com.iqser.red.persistence.service.v1.external.api.impl.controller;
import static com.iqser.red.keycloak.commons.roles.ActionRoles.READ_LICENSE_REPORT;
import static com.iqser.red.service.persistence.management.v1.processor.roles.ActionRoles.READ_LICENSE_REPORT;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import com.iqser.red.keycloak.commons.KeycloakSecurity;
import com.knecon.fforesight.keycloakcommons.security.KeycloakSecurity;
import com.iqser.red.service.persistence.management.v1.processor.service.LicenseReportService;
import com.iqser.red.service.persistence.management.v1.processor.service.persistence.AuditPersistenceService;
import com.iqser.red.service.persistence.service.v1.api.external.resource.LicenseReportResource;

View File

@ -1,12 +1,6 @@
package com.iqser.red.persistence.service.v1.external.api.impl.controller;
import static com.iqser.red.keycloak.commons.roles.ActionRoles.ADD_COMMENT;
import static com.iqser.red.keycloak.commons.roles.ActionRoles.DELETE_COMMENT;
import static com.iqser.red.keycloak.commons.roles.ActionRoles.DELETE_MANUAL_REDACTION;
import static com.iqser.red.keycloak.commons.roles.ActionRoles.DO_MANUAL_REDACTION;
import static com.iqser.red.keycloak.commons.roles.ActionRoles.PROCESS_MANUAL_REDACTION_REQUEST;
import static com.iqser.red.keycloak.commons.roles.ActionRoles.READ_MANUAL_REDACTIONS;
import static com.iqser.red.keycloak.commons.roles.ActionRoles.REQUEST_MANUAL_REDACTION;
import static com.iqser.red.service.persistence.management.v1.processor.roles.ActionRoles.*;
import static com.iqser.red.service.persistence.management.v1.processor.utils.TypeIdUtils.toTypeId;
import java.util.ArrayList;
@ -22,7 +16,6 @@ import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import com.iqser.red.keycloak.commons.KeycloakSecurity;
import com.iqser.red.service.persistence.management.v1.processor.exception.NotFoundException;
import com.iqser.red.service.persistence.management.v1.processor.service.AccessControlService;
import com.iqser.red.service.persistence.management.v1.processor.service.DossierManagementService;
@ -51,6 +44,7 @@ import com.iqser.red.service.persistence.service.v1.api.shared.model.manual.Lega
import com.iqser.red.service.persistence.service.v1.api.shared.model.manual.ManualRedactionWrapper;
import com.iqser.red.service.persistence.service.v1.api.shared.model.manual.RemoveRedactionRequest;
import com.iqser.red.service.persistence.service.v1.api.shared.model.manual.ResizeRedactionRequest;
import com.knecon.fforesight.keycloakcommons.security.KeycloakSecurity;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;

View File

@ -1,7 +1,7 @@
package com.iqser.red.persistence.service.v1.external.api.impl.controller;
import static com.iqser.red.keycloak.commons.roles.ActionRoles.READ_NOTIFICATIONS;
import static com.iqser.red.keycloak.commons.roles.ActionRoles.UPDATE_NOTIFICATIONS;
import static com.iqser.red.service.persistence.management.v1.processor.roles.ActionRoles.READ_NOTIFICATIONS;
import static com.iqser.red.service.persistence.management.v1.processor.roles.ActionRoles.UPDATE_NOTIFICATIONS;
import java.time.OffsetDateTime;
import java.util.List;
@ -11,7 +11,7 @@ import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import com.iqser.red.keycloak.commons.KeycloakSecurity;
import com.knecon.fforesight.keycloakcommons.security.KeycloakSecurity;
import com.iqser.red.service.persistence.management.v1.processor.service.persistence.NotificationPersistenceService;
import com.iqser.red.service.persistence.management.v1.processor.utils.MagicConverter;
import com.iqser.red.service.persistence.service.v1.api.external.resource.NotificationResource;

View File

@ -1,7 +1,7 @@
package com.iqser.red.persistence.service.v1.external.api.impl.controller;
import static com.iqser.red.keycloak.commons.roles.ActionRoles.READ_NOTIFICATIONS;
import static com.iqser.red.keycloak.commons.roles.ActionRoles.UPDATE_NOTIFICATIONS;
import static com.iqser.red.service.persistence.management.v1.processor.roles.ActionRoles.READ_NOTIFICATIONS;
import static com.iqser.red.service.persistence.management.v1.processor.roles.ActionRoles.UPDATE_NOTIFICATIONS;
import org.springframework.security.access.prepost.PreAuthorize;
@ -9,7 +9,7 @@ import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import com.iqser.red.keycloak.commons.KeycloakSecurity;
import com.knecon.fforesight.keycloakcommons.security.KeycloakSecurity;
import com.iqser.red.service.persistence.management.v1.processor.service.persistence.NotificationPreferencesPersistenceService;
import com.iqser.red.service.persistence.management.v1.processor.utils.MagicConverter;
import com.iqser.red.service.persistence.service.v1.api.external.resource.NotificationPreferencesResource;

View File

@ -1,6 +1,6 @@
package com.iqser.red.persistence.service.v1.external.api.impl.controller;
import static com.iqser.red.keycloak.commons.roles.ActionRoles.GET_RSS;
import static com.iqser.red.service.persistence.management.v1.processor.roles.ActionRoles.GET_RSS;
import java.util.Map;
import java.util.stream.Collectors;
@ -11,7 +11,7 @@ import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import com.iqser.red.keycloak.commons.KeycloakSecurity;
import com.knecon.fforesight.keycloakcommons.security.KeycloakSecurity;
import com.iqser.red.service.persistence.management.v1.processor.client.redactionreportservice.RssReportClient;
import com.iqser.red.service.persistence.management.v1.processor.service.ComponentOverrideService;
import com.iqser.red.service.persistence.management.v1.processor.service.persistence.AuditPersistenceService;

View File

@ -1,6 +1,6 @@
package com.iqser.red.persistence.service.v1.external.api.impl.controller;
import static com.iqser.red.keycloak.commons.roles.ActionRoles.*;
import static com.iqser.red.service.persistence.management.v1.processor.roles.ActionRoles.*;
import java.util.ArrayList;
import java.util.HashSet;
@ -16,7 +16,7 @@ import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import com.google.common.collect.Sets;
import com.iqser.red.keycloak.commons.KeycloakSecurity;
import com.knecon.fforesight.keycloakcommons.security.KeycloakSecurity;
import com.iqser.red.service.persistence.management.v1.processor.exception.BadRequestException;
import com.iqser.red.service.persistence.management.v1.processor.exception.NotFoundException;
import com.iqser.red.service.persistence.management.v1.processor.service.AccessControlService;

View File

@ -1,6 +1,6 @@
package com.iqser.red.persistence.service.v1.external.api.impl.controller;
import static com.iqser.red.keycloak.commons.roles.ActionRoles.READ_REDACTION_LOG;
import static com.iqser.red.service.persistence.management.v1.processor.roles.ActionRoles.READ_REDACTION_LOG;
import static com.iqser.red.service.persistence.management.v1.processor.service.FeignExceptionHandler.processFeignException;
import java.io.ByteArrayOutputStream;
@ -22,7 +22,6 @@ import org.springframework.web.bind.annotation.RestController;
import com.iqser.red.service.persistence.management.v1.processor.service.FileStatusService;
import com.iqser.red.service.persistence.management.v1.processor.service.RedactionLogService;
import com.iqser.red.service.persistence.management.v1.processor.utils.StringEncodingUtils;
import com.iqser.red.service.persistence.management.v1.processor.utils.multitenancy.TenantContext;
import com.iqser.red.service.persistence.service.v1.api.external.resource.RedactionLogResource;
import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.dossier.file.FileType;
import com.iqser.red.service.persistence.service.v1.api.shared.model.redactionlog.FilteredRedactionLogRequest;
@ -30,6 +29,7 @@ import com.iqser.red.service.persistence.service.v1.api.shared.model.redactionlo
import com.iqser.red.service.persistence.service.v1.api.shared.model.redactionlog.section.SectionGrid;
import com.iqser.red.storage.commons.exception.StorageObjectDoesNotExist;
import com.iqser.red.storage.commons.service.StorageService;
import com.knecon.fforesight.tenantcommons.TenantContext;
import feign.FeignException;
import lombok.RequiredArgsConstructor;

View File

@ -1,9 +1,9 @@
package com.iqser.red.persistence.service.v1.external.api.impl.controller;
import static com.iqser.red.keycloak.commons.roles.ActionRoles.DELETE_REPORT_TEMPLATE;
import static com.iqser.red.keycloak.commons.roles.ActionRoles.DOWNLOAD_REPORT_TEMPLATE;
import static com.iqser.red.keycloak.commons.roles.ActionRoles.GET_REPORT_TEMPLATES;
import static com.iqser.red.keycloak.commons.roles.ActionRoles.UPLOAD_REPORT_TEMPLATE;
import static com.iqser.red.service.persistence.management.v1.processor.roles.ActionRoles.DELETE_REPORT_TEMPLATE;
import static com.iqser.red.service.persistence.management.v1.processor.roles.ActionRoles.DOWNLOAD_REPORT_TEMPLATE;
import static com.iqser.red.service.persistence.management.v1.processor.roles.ActionRoles.GET_REPORT_TEMPLATES;
import static com.iqser.red.service.persistence.management.v1.processor.roles.ActionRoles.UPLOAD_REPORT_TEMPLATE;
import static com.iqser.red.service.persistence.management.v1.processor.service.FeignExceptionHandler.processFeignException;
import java.io.ByteArrayInputStream;
@ -27,7 +27,7 @@ import org.springframework.web.bind.annotation.RequestPart;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import com.iqser.red.keycloak.commons.KeycloakSecurity;
import com.knecon.fforesight.keycloakcommons.security.KeycloakSecurity;
import com.iqser.red.service.persistence.management.v1.processor.client.redactionreportservice.PlaceholderClient;
import com.iqser.red.service.persistence.management.v1.processor.client.redactionreportservice.ReportTemplatePlaceholderClient;
import com.iqser.red.service.persistence.management.v1.processor.exception.BadRequestException;
@ -39,7 +39,6 @@ import com.iqser.red.service.persistence.management.v1.processor.service.persist
import com.iqser.red.service.persistence.management.v1.processor.service.persistence.ReportTemplatePersistenceService;
import com.iqser.red.service.persistence.management.v1.processor.utils.MagicConverter;
import com.iqser.red.service.persistence.management.v1.processor.utils.StringEncodingUtils;
import com.iqser.red.service.persistence.management.v1.processor.utils.multitenancy.TenantContext;
import com.iqser.red.service.persistence.service.v1.api.external.resource.ReportTemplateResource;
import com.iqser.red.service.persistence.service.v1.api.shared.model.AuditCategory;
import com.iqser.red.service.persistence.service.v1.api.shared.model.PlaceholdersResponse;
@ -50,6 +49,7 @@ import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemp
import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.ReportTemplateUploadRequest;
import com.iqser.red.storage.commons.exception.StorageObjectDoesNotExist;
import com.iqser.red.storage.commons.service.StorageService;
import com.knecon.fforesight.tenantcommons.TenantContext;
import feign.FeignException;
import lombok.RequiredArgsConstructor;

View File

@ -1,7 +1,7 @@
package com.iqser.red.persistence.service.v1.external.api.impl.controller;
import static com.iqser.red.keycloak.commons.roles.ActionRoles.READ_RULES;
import static com.iqser.red.keycloak.commons.roles.ActionRoles.WRITE_RULES;
import static com.iqser.red.service.persistence.management.v1.processor.roles.ActionRoles.READ_RULES;
import static com.iqser.red.service.persistence.management.v1.processor.roles.ActionRoles.WRITE_RULES;
import static com.iqser.red.service.persistence.management.v1.processor.service.FeignExceptionHandler.processFeignException;
import java.io.ByteArrayInputStream;
@ -21,7 +21,6 @@ import org.springframework.web.bind.annotation.RequestPart;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import com.iqser.red.keycloak.commons.KeycloakSecurity;
import com.iqser.red.service.persistence.management.v1.processor.client.redactionservice.RedactionClient;
import com.iqser.red.service.persistence.management.v1.processor.exception.FileUploadException;
import com.iqser.red.service.persistence.management.v1.processor.exception.InvalidRulesException;
@ -31,6 +30,7 @@ import com.iqser.red.service.persistence.service.v1.api.external.resource.RulesR
import com.iqser.red.service.persistence.service.v1.api.shared.model.AuditCategory;
import com.iqser.red.service.persistence.service.v1.api.shared.model.Rules;
import com.iqser.red.service.persistence.service.v1.api.shared.model.audit.AuditRequest;
import com.knecon.fforesight.keycloakcommons.security.KeycloakSecurity;
import feign.FeignException;
import lombok.RequiredArgsConstructor;

View File

@ -1,100 +0,0 @@
package com.iqser.red.persistence.service.v1.external.api.impl.controller;
import static com.iqser.red.keycloak.commons.roles.ActionRoles.READ_SMTP_CONFIGURATION;
import static com.iqser.red.keycloak.commons.roles.ActionRoles.WRITE_SMTP_CONFIGURATION;
import java.util.HashMap;
import java.util.Map;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.iqser.red.keycloak.commons.KeycloakSecurity;
import com.iqser.red.keycloak.commons.RealmService;
import com.iqser.red.service.persistence.management.v1.processor.service.persistence.SMTPConfigurationService;
import com.iqser.red.service.persistence.management.v1.processor.utils.multitenancy.TenantContext;
import com.iqser.red.service.persistence.service.v1.api.external.resource.SMTPConfigurationResource;
import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.configuration.SMTPConfiguration;
import lombok.RequiredArgsConstructor;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
@Slf4j
@RestController
@RequiredArgsConstructor
public class SMTPConfigurationController implements SMTPConfigurationResource {
private final RealmService realmService;
private final SMTPConfigurationService smtpConfigurationService;
private final ObjectMapper objectMapper;
@Override
@PreAuthorize("hasAuthority('" + READ_SMTP_CONFIGURATION + "')")
public SMTPConfiguration getCurrentSMTPConfiguration() {
return smtpConfigurationService.getCurrentSMTPConfiguration(true);
}
@Override
@PreAuthorize("hasAuthority('" + WRITE_SMTP_CONFIGURATION + "')")
public void updateSMTPConfiguration(@RequestBody SMTPConfiguration smtpConfigurationModel) {
smtpConfigurationService.updateSMTPConfiguration(smtpConfigurationModel);
// also update in KC
var realmRepresentation = realmService.realm(TenantContext.getTenantId()).toRepresentation();
var propertiesMap = convertSMTPConfigurationModelToMap(smtpConfigurationModel);
realmRepresentation.setSmtpServer(propertiesMap);
realmService.realm(TenantContext.getTenantId()).update(realmRepresentation);
}
private Map<String, String> convertSMTPConfigurationModelToMap(SMTPConfiguration smtpConfigurationModel) {
Map<String, Object> propertiesMap = objectMapper.convertValue(smtpConfigurationModel, Map.class);
Map<String, String> stringPropertiesMap = new HashMap<>();
propertiesMap.forEach((key, value) -> {
if (value != null) {
stringPropertiesMap.put(key, value.toString());
} else {
stringPropertiesMap.put(key, "");
}
});
return stringPropertiesMap;
}
@SneakyThrows
@Override
@PreAuthorize("hasAuthority('" + WRITE_SMTP_CONFIGURATION + "')")
public void testSMTPConfiguration(@RequestBody SMTPConfiguration smtpConfigurationModel) {
var currentUserEmail = realmService.realm(TenantContext.getTenantId()).users().get(KeycloakSecurity.getUserId()).toRepresentation().getEmail();
smtpConfigurationService.testSMTPConfiguration(currentUserEmail, smtpConfigurationModel);
}
@Override
@PreAuthorize("hasAuthority('" + WRITE_SMTP_CONFIGURATION + "')")
public void clearSMTPConfiguration() {
smtpConfigurationService.deleteConfiguration();
// also update in KC
var realmRepresentation = realmService.realm(TenantContext.getTenantId()).toRepresentation();
realmRepresentation.setSmtpServer(new HashMap<>());
realmService.realm(TenantContext.getTenantId()).update(realmRepresentation);
}
}

View File

@ -1,6 +1,6 @@
package com.iqser.red.persistence.service.v1.external.api.impl.controller;
import static com.iqser.red.keycloak.commons.roles.ActionRoles.SEARCH;
import static com.iqser.red.service.persistence.management.v1.processor.roles.ActionRoles.SEARCH;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.RequestBody;

View File

@ -1,6 +1,6 @@
package com.iqser.red.persistence.service.v1.external.api.impl.controller;
import static com.iqser.red.keycloak.commons.roles.ActionRoles.*;
import static com.iqser.red.service.persistence.management.v1.processor.roles.ActionRoles.*;
import java.time.OffsetDateTime;
import java.util.ArrayList;
@ -11,7 +11,7 @@ import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
import javax.transaction.Transactional;
import jakarta.transaction.Transactional;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.access.prepost.PreAuthorize;
@ -20,15 +20,14 @@ import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import com.iqser.red.keycloak.commons.KeycloakSecurity;
import com.iqser.red.keycloak.commons.roles.ApplicationRoles;
import com.iqser.red.service.persistence.management.v1.processor.roles.ApplicationRoles;
import com.iqser.red.service.persistence.management.v1.processor.acl.custom.dossier.DossierACLService;
import com.iqser.red.service.persistence.management.v1.processor.exception.BadRequestException;
import com.iqser.red.service.persistence.management.v1.processor.exception.NotAllowedException;
import com.iqser.red.service.persistence.management.v1.processor.service.AccessControlService;
import com.iqser.red.service.persistence.management.v1.processor.service.DossierManagementService;
import com.iqser.red.service.persistence.management.v1.processor.service.FileStatusManagementService;
import com.iqser.red.service.persistence.management.v1.processor.service.UserService;
import com.iqser.red.service.persistence.management.v1.processor.service.users.UserService;
import com.iqser.red.service.persistence.management.v1.processor.service.persistence.AuditPersistenceService;
import com.iqser.red.service.persistence.management.v1.processor.service.persistence.NotificationPersistenceService;
import com.iqser.red.service.persistence.service.v1.api.external.resource.StatusResource;
@ -42,6 +41,7 @@ import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemp
import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.dossier.file.ProcessingStatus;
import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.dossier.file.WorkflowStatus;
import com.iqser.red.service.persistence.service.v1.api.shared.model.notification.NotificationType;
import com.knecon.fforesight.keycloakcommons.security.KeycloakSecurity;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;

View File

@ -1,7 +1,7 @@
package com.iqser.red.persistence.service.v1.external.api.impl.controller;
import static com.iqser.red.keycloak.commons.roles.ActionRoles.READ_DOSSIER;
import static com.iqser.red.service.persistence.management.v1.processor.roles.ActionRoles.READ_DOSSIER;
import static com.iqser.red.service.persistence.management.v1.processor.service.FeignExceptionHandler.processFeignException;
import java.io.ByteArrayInputStream;

View File

@ -1,63 +0,0 @@
package com.iqser.red.persistence.service.v1.external.api.impl.controller;
import static com.iqser.red.keycloak.commons.roles.ActionRoles.*;
import java.util.List;
import javax.validation.Valid;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import com.iqser.red.service.persistence.management.v1.processor.exception.BadRequestException;
import com.iqser.red.service.persistence.management.v1.processor.service.DeploymentKeyService;
import com.iqser.red.service.persistence.management.v1.processor.service.TenantManagementService;
import com.iqser.red.service.persistence.management.v1.processor.utils.MagicConverter;
import com.iqser.red.service.persistence.service.v1.api.external.resource.TenantsResource;
import com.iqser.red.service.persistence.service.v1.api.shared.model.common.JSONPrimitive;
import com.iqser.red.service.persistence.service.v1.api.shared.model.multitenancy.SimpleTenantResponse;
import com.iqser.red.service.persistence.service.v1.api.shared.model.multitenancy.TenantRequest;
import com.iqser.red.service.persistence.service.v1.api.shared.model.multitenancy.TenantResponse;
import lombok.RequiredArgsConstructor;
@RestController
@RequiredArgsConstructor
public class TenantsController implements TenantsResource {
private final TenantManagementService tenantManagementService;
private final DeploymentKeyService deploymentKeyService;
@PreAuthorize("hasAuthority('" + CREATE_TENANT + "')")
public void createTenant(@Valid @RequestBody TenantRequest tenantRequest) {
try {
tenantManagementService.createTenant(tenantRequest);
} catch (IllegalArgumentException e) {
throw new BadRequestException(e.getMessage(), e);
}
}
@PreAuthorize("hasAuthority('" + GET_TENANTS + "')")
public List<TenantResponse> getTenants() {
return tenantManagementService.getTenants();
}
@PreAuthorize("hasAuthority('" + DEPLOYMENT_INFO + "')")
public JSONPrimitive<String> getDeploymentKey(@PathVariable(TENANT_ID_PARAM) String tenantId) {
return JSONPrimitive.of(deploymentKeyService.getDeploymentKey(tenantId));
}
public List<SimpleTenantResponse> getSimpleTenants() {
return MagicConverter.convert(tenantManagementService.getTenants(), SimpleTenantResponse.class);
}
}

View File

@ -21,7 +21,7 @@ import org.springframework.web.bind.annotation.RequestPart;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import com.iqser.red.keycloak.commons.KeycloakSecurity;
import com.knecon.fforesight.keycloakcommons.security.KeycloakSecurity;
import com.iqser.red.service.pdftron.redaction.v1.api.model.ByteContentDocument;
import com.iqser.red.service.persistence.management.v1.processor.exception.BadRequestException;
import com.iqser.red.service.persistence.management.v1.processor.service.AccessControlService;

View File

@ -1,147 +0,0 @@
package com.iqser.red.persistence.service.v1.external.api.impl.controller;
import static com.iqser.red.keycloak.commons.roles.ActionRoles.*;
import java.util.List;
import java.util.stream.Collectors;
import javax.validation.Valid;
import org.apache.commons.lang3.StringUtils;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import com.iqser.red.keycloak.commons.KeyCloakSettings;
import com.iqser.red.keycloak.commons.model.User;
import com.iqser.red.service.persistence.management.v1.processor.exception.AuthenticationFailedException;
import com.iqser.red.service.persistence.management.v1.processor.exception.BadRequestException;
import com.iqser.red.service.persistence.management.v1.processor.exception.NotFoundException;
import com.iqser.red.service.persistence.management.v1.processor.service.UserService;
import com.iqser.red.service.persistence.service.v1.api.external.resource.UserResource;
import com.iqser.red.service.persistence.service.v1.api.shared.model.CreateUserRequest;
import com.iqser.red.service.persistence.service.v1.api.shared.model.ResetPasswordRequest;
import com.iqser.red.service.persistence.service.v1.api.shared.model.UpdateMyProfileRequest;
import com.iqser.red.service.persistence.service.v1.api.shared.model.UpdateProfileRequest;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
@Slf4j
@RestController
@RequiredArgsConstructor
public class UserController implements UserResource {
private final UserService userService;
private final KeyCloakSettings keyCloakSettings;
@Override
@PreAuthorize("hasAuthority('" + READ_USERS + "')")
public List<User> getAllRedUsers(@RequestParam(name = REFRESH_CACHE_PARAM, defaultValue = "false", required = false) boolean bypassCache) {
if (bypassCache) {
userService.evictUserCache();
}
return userService.getAllUsers()
.stream()
.filter(user -> user.getRoles().stream().anyMatch(r -> r.startsWith(keyCloakSettings.getRolePrefix())))
.collect(Collectors.toList());
}
@Override
@PreAuthorize("hasAuthority('" + READ_ALL_USERS + "')")
public List<User> getAllUsers(@RequestParam(name = REFRESH_CACHE_PARAM, defaultValue = "false", required = false) boolean bypassCache) {
if (bypassCache) {
userService.evictUserCache();
}
return userService.getAllUsers();
}
@Override
@PreAuthorize("hasAuthority('" + WRITE_USERS + "')")
public void updateProfile(@PathVariable(USER_ID) String userId, @RequestBody UpdateProfileRequest updateProfileRequest) {
this.userService.updateProfile(userId, updateProfileRequest);
}
@Override
@PreAuthorize("hasAuthority('" + UPDATE_MY_PROFILE + "')")
public void updateMyProfile(@Valid @RequestBody UpdateMyProfileRequest updateProfileRequest) {
try {
this.userService.updateMyProfile(updateProfileRequest);
} catch (AuthenticationFailedException e) {
throw new BadRequestException(e.getMessage(), e);
}
}
@Override
@PreAuthorize("hasAuthority('" + WRITE_USERS + "')")
public void deleteUsers(@RequestParam(USER_ID) List<String> userIds) {
userIds.forEach(this::deleteUser);
}
@Override
@PreAuthorize("hasAuthority('" + WRITE_USERS + "')")
public void deleteUser(@PathVariable(USER_ID) String userId) {
userService.deleteUser(userId);
}
@Override
@PreAuthorize("hasAuthority('" + WRITE_USERS + "')")
public User createUser(@RequestBody CreateUserRequest user) {
return this.userService.createUser(user);
}
@Override
@PreAuthorize("hasAuthority('" + READ_USERS + "')")
public User getUserById(@PathVariable(USER_ID) String userId) {
if (StringUtils.isEmpty(userId)) {
throw new BadRequestException("The userId should not be empty.");
}
return userService.getUserById(userId).orElseThrow(() -> new NotFoundException("User not found"));
}
@Override
@PreAuthorize("hasAuthority('" + WRITE_USERS + "')")
public void setRoles(@PathVariable(USER_ID) String userId, @RequestBody List<String> roles) {
userService.setRoles(userId, roles);
}
@Override
@PreAuthorize("hasAuthority('" + WRITE_USERS + "')")
public void resetPassword(@PathVariable(USER_ID) String userId, @RequestBody ResetPasswordRequest resetPasswordRequest) {
this.userService.resetPassword(userId, resetPasswordRequest);
}
@Override
@PreAuthorize("hasAuthority('" + WRITE_USERS + "')")
public User activateProfile(@PathVariable(USER_ID) String userId, @RequestParam(IS_ACTIVE_PARAM) boolean isActive) {
return this.userService.activateProfile(userId, isActive);
}
}

View File

@ -1,78 +0,0 @@
package com.iqser.red.persistence.service.v1.external.api.impl.controller;
import static com.iqser.red.keycloak.commons.roles.ActionRoles.MANAGE_USER_PREFERENCES;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
import com.iqser.red.keycloak.commons.KeycloakSecurity;
import com.iqser.red.service.persistence.management.v1.processor.service.UserService;
import com.iqser.red.service.persistence.service.v1.api.external.resource.UserPreferenceResource;
import lombok.RequiredArgsConstructor;
@RestController
@RequiredArgsConstructor
public class UserPreferenceController implements UserPreferenceResource {
private final UserService userService;
@Override
@PreAuthorize("hasAuthority('" + MANAGE_USER_PREFERENCES + "')")
public Map<String, List<String>> getAllUserAttributes() {
String userId = KeycloakSecurity.getUserId();
var userResource = userService.getUserResource(userId);
var userRepresentation = userResource.toRepresentation();
var attributes = userRepresentation.getAttributes();
return attributes != null ? attributes : new HashMap<>();
}
@Override
@PreAuthorize("hasAuthority('" + MANAGE_USER_PREFERENCES + "')")
public void setAttribute(@PathVariable(KEY_PARAMETER_NAME) String key, List<String> values) {
String userId = KeycloakSecurity.getUserId();
var userResource = userService.getUserResource(userId);
var userRepresentation = userResource.toRepresentation();
var attributes = userRepresentation.getAttributes();
if (attributes == null) {
attributes = new HashMap<>();
}
attributes.put(key, values);
userRepresentation.setAttributes(attributes);
userResource.update(userRepresentation);
}
@Override
@PreAuthorize("hasAuthority('" + MANAGE_USER_PREFERENCES + "')")
public void deleteAttribute(@PathVariable(KEY_PARAMETER_NAME) String key) {
String userId = KeycloakSecurity.getUserId();
var userResource = userService.getUserResource(userId);
var userRepresentation = userResource.toRepresentation();
if (userRepresentation.getAttributes() != null) {
userRepresentation.getAttributes().remove(key);
}
userResource.update(userRepresentation);
}
}

View File

@ -1,6 +1,6 @@
package com.iqser.red.persistence.service.v1.external.api.impl.controller;
import static com.iqser.red.keycloak.commons.roles.ActionRoles.READ_VERSIONS;
import static com.iqser.red.service.persistence.management.v1.processor.roles.ActionRoles.READ_VERSIONS;
import java.util.HashMap;
import java.util.List;

View File

@ -1,6 +1,6 @@
package com.iqser.red.persistence.service.v1.external.api.impl.controller;
import static com.iqser.red.keycloak.commons.roles.ActionRoles.MANAGE_VIEWED_PAGES;
import static com.iqser.red.service.persistence.management.v1.processor.roles.ActionRoles.MANAGE_VIEWED_PAGES;
import static com.iqser.red.service.persistence.management.v1.processor.service.FeignExceptionHandler.processFeignException;
import java.util.HashSet;
@ -10,7 +10,6 @@ import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import com.iqser.red.keycloak.commons.KeycloakSecurity;
import com.iqser.red.service.persistence.management.v1.processor.service.AccessControlService;
import com.iqser.red.service.persistence.management.v1.processor.service.AnalysisFlagsCalculationService;
import com.iqser.red.service.persistence.management.v1.processor.service.FileStatusService;
@ -20,6 +19,7 @@ import com.iqser.red.service.persistence.service.v1.api.external.resource.Viewed
import com.iqser.red.service.persistence.service.v1.api.shared.model.ViewedPages;
import com.iqser.red.service.persistence.service.v1.api.shared.model.ViewedPagesRequest;
import com.iqser.red.service.persistence.service.v1.api.shared.model.annotations.ViewedPage;
import com.knecon.fforesight.keycloakcommons.security.KeycloakSecurity;
import feign.FeignException;
import lombok.RequiredArgsConstructor;

View File

@ -1,7 +1,7 @@
package com.iqser.red.persistence.service.v1.external.api.impl.controller;
import static com.iqser.red.keycloak.commons.roles.ActionRoles.READ_WATERMARK;
import static com.iqser.red.keycloak.commons.roles.ActionRoles.WRITE_WATERMARK;
import static com.iqser.red.service.persistence.management.v1.processor.roles.ActionRoles.READ_WATERMARK;
import static com.iqser.red.service.persistence.management.v1.processor.roles.ActionRoles.WRITE_WATERMARK;
import java.util.List;
@ -11,7 +11,7 @@ import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import com.iqser.red.keycloak.commons.KeycloakSecurity;
import com.knecon.fforesight.keycloakcommons.security.KeycloakSecurity;
import com.iqser.red.service.persistence.management.v1.processor.service.WatermarkService;
import com.iqser.red.service.persistence.management.v1.processor.service.persistence.AuditPersistenceService;
import com.iqser.red.service.persistence.management.v1.processor.utils.MagicConverter;

View File

@ -4,12 +4,11 @@ import static com.iqser.red.service.persistence.management.v1.processor.utils.Do
import java.io.File;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
@Component

View File

@ -1,101 +0,0 @@
package com.iqser.red.persistence.service.v1.external.api.impl.multitenacy;
import static com.iqser.red.service.persistence.management.v1.processor.multitenancy.TenantInterceptor.TENANT_HEADER_NAME;
import java.util.Base64;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import org.keycloak.adapters.KeycloakConfigResolver;
import org.keycloak.adapters.KeycloakDeployment;
import org.keycloak.adapters.KeycloakDeploymentBuilder;
import org.keycloak.adapters.OIDCHttpFacade;
import org.keycloak.adapters.spi.HttpFacade;
import org.keycloak.representations.adapters.config.AdapterConfig;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.iqser.red.service.persistence.management.v1.processor.utils.MagicConverter;
import lombok.RequiredArgsConstructor;
import lombok.Setter;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
@Slf4j
@RequiredArgsConstructor
public class HeaderBasedKeycloakRealmResolver implements KeycloakConfigResolver {
private final Map<String, KeycloakDeployment> cache = new ConcurrentHashMap<>();
@Setter
private static AdapterConfig adapterConfig;
private KeycloakDeployment defaultDeployment;
private final ObjectMapper objectMapper;
@Override
public KeycloakDeployment resolve(OIDCHttpFacade.Request request) {
String tenant = getHeader(request, TENANT_HEADER_NAME);
if (tenant == null) {
// TODO always send as header and remove this.
tenant = getTenantFromBearerToken(request);
}
if (tenant == null) {
if (defaultDeployment == null) {
defaultDeployment = KeycloakDeploymentBuilder.build(adapterConfig);
}
return defaultDeployment;
}
return cache.computeIfAbsent(tenant, this::createKeyCloakDeployment);
}
// PMD marks this as unused, although it is clearly used.
// This seems to be a bug in PMD.
@SuppressWarnings("PMD.UnusedPrivateMethod")
@SneakyThrows
private String getTenantFromBearerToken(HttpFacade.Request request) {
String authHeader = request.getHeader("Authorization");
if (authHeader == null) {
return null;
}
String[] chunks = authHeader.split(" ")[1].split("\\.");
Base64.Decoder decoder = Base64.getUrlDecoder();
String payload = new String(decoder.decode(chunks[1]));
JsonNode actualObj = objectMapper.readTree(payload);
String issuer = actualObj.get("iss").asText();
return issuer.substring(issuer.lastIndexOf('/') + 1);
}
private KeycloakDeployment createKeyCloakDeployment(String tenant) {
var config = MagicConverter.convert(adapterConfig, AdapterConfig.class);
config.setRealm(tenant);
return KeycloakDeploymentBuilder.build(config);
}
// PMD marks this as unused, although it is clearly used.
// This seems to be a bug in PMD.
@SuppressWarnings("PMD.UnusedPrivateMethod")
private String getHeader(HttpFacade.Request request, String headerName) {
List<String> values = request.getHeaders(headerName);
if (values == null || values.isEmpty()) {
return null;
}
return values.get(values.size() - 1);
}
}

View File

@ -1,129 +0,0 @@
package com.iqser.red.persistence.service.v1.external.api.impl.swagger;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import org.springframework.boot.actuate.autoconfigure.endpoint.web.CorsEndpointProperties;
import org.springframework.boot.actuate.autoconfigure.endpoint.web.WebEndpointProperties;
import org.springframework.boot.actuate.autoconfigure.web.server.ManagementPortType;
import org.springframework.boot.actuate.endpoint.ExposableEndpoint;
import org.springframework.boot.actuate.endpoint.web.EndpointLinksResolver;
import org.springframework.boot.actuate.endpoint.web.EndpointMapping;
import org.springframework.boot.actuate.endpoint.web.EndpointMediaTypes;
import org.springframework.boot.actuate.endpoint.web.ExposableWebEndpoint;
import org.springframework.boot.actuate.endpoint.web.WebEndpointsSupplier;
import org.springframework.boot.actuate.endpoint.web.annotation.ControllerEndpointsSupplier;
import org.springframework.boot.actuate.endpoint.web.annotation.ServletEndpointsSupplier;
import org.springframework.boot.actuate.endpoint.web.servlet.WebMvcEndpointHandlerMapping;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;
import org.springframework.util.StringUtils;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.CorsConfigurationSource;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import io.swagger.v3.oas.annotations.OpenAPIDefinition;
import io.swagger.v3.oas.models.Components;
import io.swagger.v3.oas.models.OpenAPI;
import io.swagger.v3.oas.models.info.Info;
import io.swagger.v3.oas.models.security.OAuthFlow;
import io.swagger.v3.oas.models.security.OAuthFlows;
import io.swagger.v3.oas.models.security.SecurityRequirement;
import io.swagger.v3.oas.models.security.SecurityScheme;
@OpenAPIDefinition
@Configuration
@EnableWebMvc
@EnableConfigurationProperties(SwaggerProperties.class)
@ConditionalOnProperty(value = "swagger.enabled", havingValue = "true")
public class SwaggerAutoConfiguration {
private static final String TITLE = "API Documentation for Redaction Gateway";
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/<tenantId>/protocol/openid-connect";
@Bean
public WebMvcEndpointHandlerMapping webEndpointServletHandlerMapping(WebEndpointsSupplier webEndpointsSupplier,
ServletEndpointsSupplier servletEndpointsSupplier,
ControllerEndpointsSupplier controllerEndpointsSupplier,
EndpointMediaTypes endpointMediaTypes,
CorsEndpointProperties corsProperties,
WebEndpointProperties webEndpointProperties,
Environment environment) {
List<ExposableEndpoint<?>> allEndpoints = new ArrayList<>();
Collection<ExposableWebEndpoint> webEndpoints = webEndpointsSupplier.getEndpoints();
allEndpoints.addAll(webEndpoints);
allEndpoints.addAll(servletEndpointsSupplier.getEndpoints());
allEndpoints.addAll(controllerEndpointsSupplier.getEndpoints());
String basePath = webEndpointProperties.getBasePath();
EndpointMapping endpointMapping = new EndpointMapping(basePath);
boolean shouldRegisterLinksMapping = this.shouldRegisterLinksMapping(webEndpointProperties, environment, basePath);
return new WebMvcEndpointHandlerMapping(endpointMapping,
webEndpoints,
endpointMediaTypes,
corsProperties.toCorsConfiguration(),
new EndpointLinksResolver(allEndpoints, basePath),
shouldRegisterLinksMapping,
null);
}
private boolean shouldRegisterLinksMapping(WebEndpointProperties webEndpointProperties, Environment environment, String basePath) {
return webEndpointProperties.getDiscovery().isEnabled() && (StringUtils.hasText(basePath) || ManagementPortType.get(environment).equals(ManagementPortType.DIFFERENT));
}
@Bean
public CorsConfigurationSource corsConfigurationSource() {
CorsConfiguration configuration = new CorsConfiguration();
configuration.setAllowedMethods(Arrays.asList("GET", "POST", "PUT", "DELETE", "HEAD"));
configuration.applyPermitDefaultValues();
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", configuration);
return source;
}
@Bean
public OpenAPI customOpenApi() {
return new OpenAPI().info(new Info().title(TITLE).version(VERSION).description(DESCRIPTION))
.components(new Components().addSecuritySchemes(OAUTH_NAME, createOAuthScheme()))
.addSecurityItem(new SecurityRequirement().addList(OAUTH_NAME));
}
private SecurityScheme createOAuthScheme() {
OAuthFlows flows = createOAuthFlows();
return new SecurityScheme().type(SecurityScheme.Type.OAUTH2).flows(flows);
}
private OAuthFlows createOAuthFlows() {
OAuthFlow flow = createAuthorizationCodeFlow();
return new OAuthFlows().authorizationCode(flow);
}
private OAuthFlow createAuthorizationCodeFlow() {
return new OAuthFlow().authorizationUrl(PROTOCOL_URL_FORMAT + "/auth").tokenUrl(PROTOCOL_URL_FORMAT + "/token");
}
}

View File

@ -1,53 +0,0 @@
package com.iqser.red.persistence.service.v1.external.api.impl.swagger;
import java.util.Locale;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import org.springdoc.webmvc.api.OpenApiWebMvcResource;
import org.springdoc.webmvc.ui.SwaggerConfigResource;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import com.iqser.red.service.persistence.service.v1.api.external.resource.ExternalApi;
import io.swagger.v3.oas.annotations.Operation;
import lombok.RequiredArgsConstructor;
import lombok.SneakyThrows;
@RestController
@RequiredArgsConstructor
public class SwaggerCustomDocsController {
private final OpenApiWebMvcResource openApiWebMvcResource;
private final SwaggerConfigResource swaggerConfigResource;
@Value("${springdoc.api-docs.path:#{T(org.springdoc.core.Constants).DEFAULT_API_DOCS_URL}}")
private String apiDocsUrl;
@SneakyThrows
@Operation(hidden = true)
@GetMapping(ExternalApi.BASE_PATH + "/docs/tenant")
public String getDocs(HttpServletRequest request, @RequestParam(value = "tenantId", required = false, defaultValue = "redaction") String tenantId) {
var response = openApiWebMvcResource.openapiJson(request, ExternalApi.BASE_PATH + "/docs/tenant", Locale.getDefault());
return response.replace("<tenantId>", tenantId);
}
@Operation(hidden = true)
@GetMapping(value = "/redaction-gateway-v1/docs/swagger-config", produces = MediaType.APPLICATION_JSON_VALUE)
public Map<String, Object> getSwaggerUiConfig(HttpServletRequest request) {
var map = swaggerConfigResource.openapiJson(request);
map.put("url", apiDocsUrl);
return map;
}
}

View File

@ -1,31 +0,0 @@
package com.iqser.red.persistence.service.v1.external.api.impl.swagger;
import java.io.IOException;
import javax.annotation.PostConstruct;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import lombok.extern.slf4j.Slf4j;
@Slf4j
@Controller
@ConditionalOnProperty(value = "swagger.enabled", havingValue = "true")
public class SwaggerHomeController {
@Value("${server.servlet.context-path:}")
private String contextPath;
@GetMapping({"/redaction-gateway-v1", "/","redaction-gateway-v1/docs"})
public void home(HttpServletRequest request, HttpServletResponse response) throws IOException {
response.sendRedirect(contextPath + "/redaction-gateway-v1/docs/swagger-ui");
}
}

View File

@ -1,19 +0,0 @@
package com.iqser.red.persistence.service.v1.external.api.impl.swagger;
import org.springframework.boot.context.properties.ConfigurationProperties;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
@Data
@ConfigurationProperties("swagger")
public class SwaggerProperties {
@JsonProperty("auth-server-url")
protected String authServerUrl = "";
private boolean enabled;
private boolean securityEnabled;
private String defaultClientId;
}

View File

@ -1,47 +0,0 @@
package com.iqser.red.persistence.service.v1.external.api.impl.swagger;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import com.iqser.red.service.persistence.service.v1.api.external.resource.ExternalApi;
@Configuration
@EnableWebMvc
public class SwaggerTenantMvcConfigurer implements WebMvcConfigurer {
@Value("${springdoc.api-docs.path:#{T(org.springdoc.core.Constants).DEFAULT_API_DOCS_URL}}")
private String path;
@Override
public void addInterceptors(InterceptorRegistry registry) {
var cleanedUpPath = path.contains("?") ? path.substring(0, path.indexOf("?")) : path;
registry.addInterceptor(new DocsInterceptor()).addPathPatterns(cleanedUpPath);
}
public static class DocsInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
var query = "";
if (!StringUtils.isBlank(request.getQueryString())) {
query = "?" + request.getQueryString();
}
response.sendRedirect(ExternalApi.BASE_PATH + "/docs/tenant" + query);
return false;
}
}
}

View File

@ -136,12 +136,6 @@
<version>${project.version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>com.iqser.red.service</groupId>
<artifactId>keycloak-commons</artifactId>
<version>${project.version}</version>
<scope>compile</scope>
</dependency>
</dependencies>
</project>

View File

@ -1,6 +1,5 @@
package com.iqser.red.service.persistence.service.v1.api.external.resource;
import javax.validation.Valid;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
@ -15,6 +14,7 @@ import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemp
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.responses.ApiResponses;
import jakarta.validation.Valid;
public interface ApplicationConfigurationResource {

View File

@ -1,36 +0,0 @@
package com.iqser.red.service.persistence.service.v1.api.external.resource;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;
import com.iqser.red.service.persistence.service.v1.api.shared.model.GeneralConfigurationModel;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.responses.ApiResponses;
public interface GeneralSettingsResource {
String SMTP_PATH = ExternalApi.BASE_PATH + "/configuration/general";
@ResponseBody
@ResponseStatus(value = HttpStatus.OK)
@GetMapping(value = SMTP_PATH, produces = MediaType.APPLICATION_JSON_VALUE)
@Operation(summary = "Returns the current general Configuration.")
@ApiResponses(value = {@ApiResponse(responseCode = "200", description = "OK.")})
GeneralConfigurationModel getGeneralConfigurations();
@ResponseStatus(value = HttpStatus.NO_CONTENT)
@PostMapping(value = SMTP_PATH, consumes = MediaType.APPLICATION_JSON_VALUE)
@Operation(summary = "Write General Configurations to KeyCloak")
@ApiResponses(value = {@ApiResponse(responseCode = "204", description = "General Configuration updated successful."), @ApiResponse(responseCode = "400", description = "General Configuration update failed.")})
void updateGeneralConfigurations(@RequestBody GeneralConfigurationModel generalConfigurationModel);
}

View File

@ -1,53 +0,0 @@
package com.iqser.red.service.persistence.service.v1.api.external.resource;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;
import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.configuration.SMTPConfiguration;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.responses.ApiResponses;
public interface SMTPConfigurationResource {
String SMTP_PATH = ExternalApi.BASE_PATH + "/configuration/smtp";
String TEST_PATH = "/test";
@ResponseBody
@ResponseStatus(value = HttpStatus.OK)
@GetMapping(value = SMTP_PATH, produces = MediaType.APPLICATION_JSON_VALUE)
@Operation(summary = "Returns the current SMTP Configuration.")
@ApiResponses(value = {@ApiResponse(responseCode = "200", description = "OK."), @ApiResponse(responseCode = "404", description = "SMTP not configured.")})
SMTPConfiguration getCurrentSMTPConfiguration();
@ResponseStatus(value = HttpStatus.NO_CONTENT)
@PostMapping(value = SMTP_PATH, consumes = MediaType.APPLICATION_JSON_VALUE)
@Operation(summary = "Write SMTP Settings to KeyCloak")
@ApiResponses(value = {@ApiResponse(responseCode = "204", description = "SMTP Configuration updated successful."), @ApiResponse(responseCode = "400", description = "SMTP update failed.")})
void updateSMTPConfiguration(@RequestBody SMTPConfiguration smtpConfigurationModel);
@ResponseStatus(value = HttpStatus.OK)
@PostMapping(value = SMTP_PATH + TEST_PATH, consumes = MediaType.APPLICATION_JSON_VALUE)
@Operation(summary = "Test SMTP Settings to KeyCloak")
@ApiResponses(value = {@ApiResponse(responseCode = "200", description = "SMTP Configuration is valid."), @ApiResponse(responseCode = "400", description = "SMTP test failed.")})
void testSMTPConfiguration(@RequestBody SMTPConfiguration smtpConfigurationModel);
@ResponseStatus(value = HttpStatus.NO_CONTENT)
@DeleteMapping(value = SMTP_PATH)
@Operation(summary = "Clear SMTP Settings to KeyCloak")
@ApiResponses(value = {@ApiResponse(responseCode = "200", description = "SMTP Configuration has been cleared."), @ApiResponse(responseCode = "400", description = "Failed to clear SMTP Configuration.")})
void clearSMTPConfiguration();
}

View File

@ -1,51 +0,0 @@
package com.iqser.red.service.persistence.service.v1.api.external.resource;
import java.util.List;
import org.springframework.http.HttpStatus;
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.RequestBody;
import org.springframework.web.bind.annotation.ResponseStatus;
import com.iqser.red.service.persistence.service.v1.api.shared.model.common.JSONPrimitive;
import com.iqser.red.service.persistence.service.v1.api.shared.model.multitenancy.SimpleTenantResponse;
import com.iqser.red.service.persistence.service.v1.api.shared.model.multitenancy.TenantRequest;
import com.iqser.red.service.persistence.service.v1.api.shared.model.multitenancy.TenantResponse;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.responses.ApiResponses;
@ResponseStatus(value = HttpStatus.OK)
public interface TenantsResource {
String TENANT_ID_PARAM = "tenantId";
String TENANT_ID_PATH_PARAM = "/{" + TENANT_ID_PARAM + "}";
@PostMapping(value = ExternalApi.BASE_PATH + "/tenants", consumes = MediaType.APPLICATION_JSON_VALUE)
@Operation(summary = "Creates a new Tenant", description = "None")
@ApiResponses(value = {@ApiResponse(responseCode = "200", description = "OK")})
void createTenant(@RequestBody TenantRequest tenant);
@GetMapping(value = ExternalApi.BASE_PATH + "/tenants", produces = MediaType.APPLICATION_JSON_VALUE)
@Operation(summary = "Gets all existing tenant", description = "None")
@ApiResponses(value = {@ApiResponse(responseCode = "200", description = "OK")})
List<TenantResponse> getTenants();
@GetMapping(value = ExternalApi.BASE_PATH + "/tenants/simple", produces = MediaType.APPLICATION_JSON_VALUE)
@Operation(summary = "Gets all existing tenant in a simplified format", description = "None")
@ApiResponses(value = {@ApiResponse(responseCode = "200", description = "OK")})
List<SimpleTenantResponse> getSimpleTenants();
@GetMapping(value = ExternalApi.BASE_PATH + "/deploymentKey" + TENANT_ID_PATH_PARAM, produces = MediaType.APPLICATION_JSON_VALUE)
@Operation(summary = "Returns the deployment key for a tenant", description = "None")
@ApiResponses(value = {@ApiResponse(responseCode = "200", description = "OK")})
JSONPrimitive<String> getDeploymentKey(@PathVariable(TENANT_ID_PARAM) String tenantId);
}

View File

@ -1,49 +0,0 @@
package com.iqser.red.service.persistence.service.v1.api.external.resource;
import java.util.List;
import java.util.Map;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.responses.ApiResponses;
public interface UserPreferenceResource {
String PREFERENCES_PATH = ExternalApi.BASE_PATH + "/attributes";
String KEY_PARAMETER_NAME = "key";
String KEY_PATH_VARIABLE = "/{" + KEY_PARAMETER_NAME + "}";
@ResponseBody
@ResponseStatus(value = HttpStatus.OK)
@GetMapping(value = PREFERENCES_PATH, produces = MediaType.APPLICATION_JSON_VALUE)
@Operation(summary = "Get User Attributes.", description = "None")
@ApiResponses(value = {@ApiResponse(responseCode = "200", description = "OK")})
Map<String, List<String>> getAllUserAttributes();
@ResponseStatus(HttpStatus.NO_CONTENT)
@PutMapping(value = PREFERENCES_PATH + KEY_PATH_VARIABLE, consumes = MediaType.APPLICATION_JSON_VALUE)
@Operation(summary = "Store User Attribute by key.", description = "None")
@ApiResponses(value = {@ApiResponse(responseCode = "204", description = "OK")})
void setAttribute(@PathVariable(KEY_PARAMETER_NAME) String key, @RequestBody List<String> values);
@ResponseBody
@ResponseStatus(value = HttpStatus.NO_CONTENT)
@DeleteMapping(value = PREFERENCES_PATH + KEY_PATH_VARIABLE)
@Operation(summary = "Delete User Preferences by key.", description = "None")
@ApiResponses(value = {@ApiResponse(responseCode = "204", description = "OK")})
void deleteAttribute(@PathVariable(KEY_PARAMETER_NAME) String key);
}

View File

@ -1,125 +0,0 @@
package com.iqser.red.service.persistence.service.v1.api.external.resource;
import java.util.List;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.DeleteMapping;
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.RequestBody;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;
import com.iqser.red.keycloak.commons.model.User;
import com.iqser.red.service.persistence.service.v1.api.shared.model.CreateUserRequest;
import com.iqser.red.service.persistence.service.v1.api.shared.model.ResetPasswordRequest;
import com.iqser.red.service.persistence.service.v1.api.shared.model.UpdateMyProfileRequest;
import com.iqser.red.service.persistence.service.v1.api.shared.model.UpdateProfileRequest;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.responses.ApiResponses;
@ResponseStatus(value = HttpStatus.OK)
public interface UserResource {
String USER_REST_PATH = ExternalApi.BASE_PATH + "/user";
String RED_USER_REST_PATH = USER_REST_PATH + "/red";
String UPDATE_USER_PROFILE_PATH = USER_REST_PATH + "/profile";
String ACTIVATE_USER_PROFILE_PATH = UPDATE_USER_PROFILE_PATH + "/activate";
String UPDATE_MY_USER_PROFILE_PATH = USER_REST_PATH + "/my-profile";
String USER_ID = "userId";
String USER_ID_PATH_VARIABLE = "/{" + USER_ID + "}";
String USER_ROLE_REST_PATH = USER_REST_PATH + USER_ID_PATH_VARIABLE + "/role";
String RESET_PASSWORD_PATH = USER_REST_PATH + USER_ID_PATH_VARIABLE + "/reset-password";
String REFRESH_CACHE_PARAM = "refreshCache";
String IS_ACTIVE_PARAM = "isActive";
@ResponseBody
@Operation(summary = "Gets the users who contain redaction roles.", description = "None")
@ApiResponses(value = {@ApiResponse(responseCode = "200", description = "OK"), @ApiResponse(responseCode = "400", description = "Invalid " + "offset or limit specified.")})
@GetMapping(value = RED_USER_REST_PATH, produces = MediaType.APPLICATION_JSON_VALUE)
List<User> getAllRedUsers(@RequestParam(name = REFRESH_CACHE_PARAM, defaultValue = "false", required = false) boolean bypassCache);
@ResponseBody
@Operation(summary = "Gets all the users in realm with information of roles.", description = "None")
@ApiResponses(value = {@ApiResponse(responseCode = "200", description = "OK"), @ApiResponse(responseCode = "400", description = "Invalid " + "offset or limit specified.")})
@GetMapping(value = USER_REST_PATH, produces = MediaType.APPLICATION_JSON_VALUE)
List<User> getAllUsers(@RequestParam(name = REFRESH_CACHE_PARAM, defaultValue = "false", required = false) boolean bypassCache);
@ResponseBody
@ResponseStatus(value = HttpStatus.NO_CONTENT)
@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);
@ResponseBody
@ResponseStatus(value = HttpStatus.NO_CONTENT)
@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);
@ResponseBody
@ResponseStatus(value = HttpStatus.NO_CONTENT)
@Operation(summary = "Deletes given user", description = "None")
@ApiResponses(value = {@ApiResponse(responseCode = "204", description = "OK"), @ApiResponse(responseCode = "405", description = "Operation is not allowed."), @ApiResponse(responseCode = "409", description = "Conflict while deleting user.")})
@DeleteMapping(value = USER_REST_PATH + USER_ID_PATH_VARIABLE)
void deleteUser(@PathVariable(USER_ID) String userId);
@ResponseBody
@ResponseStatus(value = HttpStatus.NO_CONTENT)
@Operation(summary = "Deletes given users", description = "None")
@ApiResponses(value = {@ApiResponse(responseCode = "204", description = "OK"), @ApiResponse(responseCode = "405", description = "Operation is not allowed."), @ApiResponse(responseCode = "409", description = "Conflict while deleting user.")})
@DeleteMapping(value = USER_REST_PATH)
void deleteUsers(@RequestParam(USER_ID) List<String> userIds);
@ResponseBody
@Operation(summary = "Create a new user.", description = "None")
@ApiResponses(value = {@ApiResponse(responseCode = "200", description = "OK"), @ApiResponse(responseCode = "400", description = "Invalid Data."), @ApiResponse(responseCode = "409", description = "User already exists.")})
@PostMapping(value = USER_REST_PATH, consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
User createUser(@RequestBody CreateUserRequest user);
@ResponseBody
@Operation(summary = "Gets the user in realm with information of roles.", description = "None")
@ApiResponses(value = {@ApiResponse(responseCode = "200", description = "OK"), @ApiResponse(responseCode = "404", description = "The " + "userId can not be found."), @ApiResponse(responseCode = "400", description = "The provided user id is empty or " + "null.")})
@GetMapping(value = USER_REST_PATH + USER_ID_PATH_VARIABLE, produces = MediaType.APPLICATION_JSON_VALUE)
User getUserById(@PathVariable(USER_ID) String userId);
@ResponseStatus(value = HttpStatus.NO_CONTENT)
@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 List<String> roles);
@ResponseStatus(value = HttpStatus.NO_CONTENT)
@Operation(summary = "Reset a user's password", description = "None")
@ApiResponses(value = {@ApiResponse(responseCode = "204", description = "No Content"), @ApiResponse(responseCode = "404", description = "The provided userId can not be found.")})
@PostMapping(value = RESET_PASSWORD_PATH, consumes = MediaType.APPLICATION_JSON_VALUE)
void resetPassword(@PathVariable(USER_ID) String userId, @RequestBody ResetPasswordRequest resetPasswordRequest);
@ResponseBody
@Operation(summary = "Activate/ deactivate a user-profile.", description = "None")
@ApiResponses(value = {@ApiResponse(responseCode = "200", description = "OK"), @ApiResponse(responseCode = "400", description = "Failed to activate/deactivate profile")})
@PostMapping(value = ACTIVATE_USER_PROFILE_PATH + USER_ID_PATH_VARIABLE, produces = MediaType.APPLICATION_JSON_VALUE)
User activateProfile(@PathVariable(USER_ID) String userId, @RequestParam(IS_ACTIVE_PARAM) boolean isActive);
}

View File

@ -2,7 +2,7 @@ package com.iqser.red.service.persistence.v1.internal.api.controller;
import java.util.List;
import javax.transaction.Transactional;
import jakarta.transaction.Transactional;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestParam;

View File

@ -4,7 +4,7 @@ import static com.iqser.red.service.persistence.management.v1.processor.utils.Ma
import java.util.List;
import javax.transaction.Transactional;
import jakarta.transaction.Transactional;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;

View File

@ -1,56 +0,0 @@
package com.iqser.red.service.persistence.v1.internal.api.controller;
import java.util.List;
import javax.validation.Valid;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import com.iqser.red.service.persistence.management.v1.processor.exception.BadRequestException;
import com.iqser.red.service.persistence.management.v1.processor.service.DeploymentKeyService;
import com.iqser.red.service.persistence.management.v1.processor.service.TenantManagementService;
import com.iqser.red.service.persistence.service.v1.api.internal.resources.TenantsResource;
import com.iqser.red.service.persistence.service.v1.api.shared.model.common.JSONPrimitive;
import com.iqser.red.service.persistence.service.v1.api.shared.model.multitenancy.TenantRequest;
import com.iqser.red.service.persistence.service.v1.api.shared.model.multitenancy.TenantResponse;
import lombok.RequiredArgsConstructor;
@RestController
@RequiredArgsConstructor
public class TenantsInternalController implements TenantsResource {
private final TenantManagementService tenantManagementService;
private final DeploymentKeyService deploymentKeyService;
public void createTenant(@Valid @RequestBody TenantRequest tenantRequest) {
try {
tenantManagementService.createTenant(tenantRequest);
} catch (IllegalArgumentException e) {
throw new BadRequestException(e.getMessage(), e);
}
}
public List<TenantResponse> getTenants() {
return tenantManagementService.getTenants();
}
public TenantResponse getTenant(@PathVariable(TENANT_ID_PARAM) String tenantId) {
return tenantManagementService.getTenant(tenantId);
}
public JSONPrimitive<String> getDeploymentKey(@PathVariable(TENANT_ID_PARAM) String tenantId) {
return JSONPrimitive.of(deploymentKeyService.getDeploymentKey(tenantId));
}
}

View File

@ -1,40 +0,0 @@
package com.iqser.red.service.persistence.service.v1.api.internal.resources;
import java.util.List;
import org.springframework.http.HttpStatus;
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.RequestBody;
import org.springframework.web.bind.annotation.ResponseStatus;
import com.iqser.red.service.persistence.service.v1.api.shared.model.common.JSONPrimitive;
import com.iqser.red.service.persistence.service.v1.api.shared.model.multitenancy.TenantRequest;
import com.iqser.red.service.persistence.service.v1.api.shared.model.multitenancy.TenantResponse;
@ResponseStatus(value = HttpStatus.OK)
public interface TenantsResource {
String TENANT_PATH = "/tenants";
String TENANT_ID_PARAM = "tenantId";
String TENANT_ID_PATH_PARAM = "/{" + TENANT_ID_PARAM + "}";
@PostMapping(value = InternalApi.BASE_PATH + TENANT_PATH, consumes = MediaType.APPLICATION_JSON_VALUE)
void createTenant(@RequestBody TenantRequest tenantRequest);
@GetMapping(value = InternalApi.BASE_PATH + TENANT_PATH, produces = MediaType.APPLICATION_JSON_VALUE)
List<TenantResponse> getTenants();
@GetMapping(value = InternalApi.BASE_PATH + TENANT_PATH + TENANT_ID_PATH_PARAM, produces = MediaType.APPLICATION_JSON_VALUE)
TenantResponse getTenant(@PathVariable(TENANT_ID_PARAM) String tenantId);
@GetMapping(value = InternalApi.BASE_PATH + "/deploymentKey" + TENANT_ID_PATH_PARAM, produces = MediaType.APPLICATION_JSON_VALUE)
JSONPrimitive<String> getDeploymentKey(@PathVariable(TENANT_ID_PARAM) String tenantId);
}

View File

@ -16,12 +16,30 @@
<properties>
<bucket4j.version>6.4.1</bucket4j.version>
<bucket4j.spring.version>0.4.0</bucket4j.spring.version>
<swagger-commons.version>0.5.0</swagger-commons.version>
<keycloak-commons.version>0.14.0</keycloak-commons.version>
<jobs-commons.version>0.6.0</jobs-commons.version>
</properties>
<dependencies>
<dependency>
<groupId>com.knecon.fforesight</groupId>
<artifactId>jobs-commons</artifactId>
<version>${jobs-commons.version}</version>
</dependency>
<dependency>
<groupId>com.knecon.fforesight</groupId>
<artifactId>keycloak-commons</artifactId>
<version>${keycloak-commons.version}</version>
</dependency>
<dependency>
<groupId>com.knecon.fforesight</groupId>
<artifactId>swagger-commons</artifactId>
<version>${swagger-commons.version}</version>
</dependency>
<dependency>
<groupId>com.iqser.red.service</groupId>
<artifactId>pdftron-redaction-service-api-v1</artifactId>
@ -146,11 +164,6 @@
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>com.iqser.red.service</groupId>
<artifactId>keycloak-commons</artifactId>
<version>${project.version}</version>
</dependency>
<!-- commons -->
<dependency>
<groupId>com.iqser.red.commons</groupId>
@ -216,11 +229,6 @@
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-quartz</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-amqp</artifactId>
@ -249,11 +257,6 @@
<artifactId>log4j-slf4j-impl</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.liquibase</groupId>
<artifactId>liquibase-core</artifactId>
<version>4.3.1</version>
</dependency>
<dependency>
<groupId>com.yannbriancon</groupId>
<artifactId>spring-hibernate-query-utils</artifactId>
@ -283,7 +286,6 @@
<configuration>
<annotationProcessors>
<annotationProcessor>lombok.launch.AnnotationProcessorHider$AnnotationProcessor</annotationProcessor>
<annotationProcessor>com.dslplatform.json.processor.CompiledJsonAnnotationProcessor</annotationProcessor>
</annotationProcessors>
</configuration>
</plugin>

View File

@ -2,7 +2,9 @@ package com.iqser.red.service.persistence.management.v1.processor;
import javax.sql.DataSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.openfeign.EnableFeignClients;
import org.springframework.cloud.openfeign.support.PageJacksonModule;
import org.springframework.cloud.openfeign.support.SortJacksonModule;
@ -11,6 +13,7 @@ import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.DependsOn;
import org.springframework.context.annotation.Primary;
import org.springframework.core.env.Environment;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.retry.backoff.ExponentialBackOffPolicy;
import org.springframework.retry.policy.SimpleRetryPolicy;
@ -20,11 +23,16 @@ import com.iqser.red.service.persistence.management.v1.processor.client.pdftronr
import com.iqser.red.service.persistence.management.v1.processor.client.redactionreportservice.StatusReportClient;
import com.iqser.red.service.persistence.management.v1.processor.client.redactionservice.RedactionClient;
import com.iqser.red.service.persistence.management.v1.processor.client.searchservice.SearchClient;
import com.iqser.red.service.persistence.management.v1.processor.client.tenantusermanagementservice.UsersClient;
import com.iqser.red.service.persistence.management.v1.processor.settings.FileManagementServiceSettings;
import jakarta.annotation.PostConstruct;
import lombok.extern.slf4j.Slf4j;
@Slf4j
@Configuration
@ComponentScan
@EnableFeignClients(basePackageClasses = {PDFTronClient.class, StatusReportClient.class, SearchClient.class, RedactionClient.class})
@EnableFeignClients(basePackageClasses = {PDFTronClient.class, StatusReportClient.class, SearchClient.class, RedactionClient.class, UsersClient.class})
public class PersistenceServiceProcessorConfiguration {
public static final String TENANT_DATA_SOURCE_QUALIFIER = "multiTenantDataSource";

View File

@ -14,23 +14,22 @@ import org.springframework.security.acls.model.MutableAcl;
import org.springframework.security.acls.model.MutableAclService;
import org.springframework.transaction.annotation.Transactional;
import com.iqser.red.keycloak.commons.UserListingService;
import com.iqser.red.keycloak.commons.model.User;
import com.iqser.red.service.persistence.management.v1.processor.acl.AbstractACLService;
import com.iqser.red.service.persistence.management.v1.processor.acl.RedPermission;
import com.iqser.red.service.persistence.management.v1.processor.utils.multitenancy.TenantContext;
import com.iqser.red.service.persistence.management.v1.processor.client.tenantusermanagementservice.UsersClient;
import com.iqser.red.service.persistence.management.v1.processor.service.users.model.User;
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 abstract class ICustomPermissionService<T, ID extends Serializable> extends AbstractACLService<ID> {
protected final UserListingService userListingService;
protected final UsersClient usersClient;
protected ICustomPermissionService(UserListingService userListingService, MutableAclService mutableAclService) {
protected ICustomPermissionService(UsersClient usersClient, MutableAclService mutableAclService) {
super(mutableAclService);
this.userListingService = userListingService;
this.usersClient = usersClient;
}
@ -109,7 +108,7 @@ public abstract class ICustomPermissionService<T, ID extends Serializable> exten
private Set<String> getUserIds() {
return userListingService.getAllUsers(TenantContext.getTenantId()).stream().map(User::getUserId).collect(Collectors.toSet());
return usersClient.getAllUsers(true).stream().map(User::getUserId).collect(Collectors.toSet());
}

View File

@ -1,18 +1,15 @@
package com.iqser.red.service.persistence.management.v1.processor.acl.custom.dossier;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Set;
import java.util.stream.Collectors;
import org.springframework.security.acls.model.MutableAclService;
import org.springframework.stereotype.Service;
import com.iqser.red.keycloak.commons.UserListingService;
import com.iqser.red.service.persistence.management.v1.processor.acl.RedPermission;
import com.iqser.red.service.persistence.management.v1.processor.acl.custom.api.ICustomPermissionService;
import com.iqser.red.service.persistence.management.v1.processor.client.tenantusermanagementservice.UsersClient;
import com.iqser.red.service.persistence.management.v1.processor.service.DossierManagementService;
import com.iqser.red.service.persistence.management.v1.processor.service.TenantManagementService;
import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.dossier.Dossier;
@Service
@ -20,11 +17,11 @@ public class AccessObjectDossierObjectPermissionService extends ICustomPermissio
private final DossierManagementService dossierManagementService;
public AccessObjectDossierObjectPermissionService(UserListingService userService,
public AccessObjectDossierObjectPermissionService(UsersClient usersClient,
MutableAclService mutableAclService,
DossierManagementService dossierManagementService) {
super(userService, mutableAclService);
super(usersClient, mutableAclService);
this.dossierManagementService = dossierManagementService;
}

View File

@ -8,11 +8,10 @@ import java.util.stream.Collectors;
import org.springframework.security.acls.model.MutableAclService;
import org.springframework.stereotype.Service;
import com.iqser.red.keycloak.commons.UserListingService;
import com.iqser.red.service.persistence.management.v1.processor.acl.RedPermission;
import com.iqser.red.service.persistence.management.v1.processor.acl.custom.api.ICustomPermissionService;
import com.iqser.red.service.persistence.management.v1.processor.client.tenantusermanagementservice.UsersClient;
import com.iqser.red.service.persistence.management.v1.processor.service.DossierManagementService;
import com.iqser.red.service.persistence.management.v1.processor.service.TenantManagementService;
import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.dossier.Dossier;
@Service
@ -21,9 +20,9 @@ public class ViewObjectDossierObjectPermissionService extends ICustomPermissionS
private final DossierManagementService dossierManagementService;
public ViewObjectDossierObjectPermissionService(UserListingService userService, MutableAclService mutableAclService, DossierManagementService dossierManagementService) {
public ViewObjectDossierObjectPermissionService(UsersClient usersClient, MutableAclService mutableAclService, DossierManagementService dossierManagementService) {
super(userService, mutableAclService);
super(usersClient, mutableAclService);
this.dossierManagementService = dossierManagementService;
}

View File

@ -3,11 +3,8 @@ package com.iqser.red.service.persistence.management.v1.processor.acl.custom.ini
import java.util.Comparator;
import java.util.List;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.stereotype.Service;
import com.iqser.red.service.persistence.management.v1.processor.utils.multitenancy.TenantContext;
import lombok.RequiredArgsConstructor;

View File

@ -9,8 +9,6 @@ import org.springframework.stereotype.Service;
import com.iqser.red.service.persistence.management.v1.processor.acl.RedPermission;
import com.iqser.red.service.persistence.management.v1.processor.acl.custom.service.CustomPermissionService;
import com.iqser.red.service.persistence.management.v1.processor.service.TenantManagementService;
import com.iqser.red.service.persistence.management.v1.processor.utils.multitenancy.TenantContext;
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;

View File

@ -0,0 +1,24 @@
package com.iqser.red.service.persistence.management.v1.processor.client.tenantusermanagementservice;
import java.util.List;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import com.iqser.red.service.persistence.management.v1.processor.service.users.model.User;
@FeignClient(name = "UsersClient", url = "${tenant-user-management-service.url}")
public interface UsersClient {
String REFRESH_CACHE_PARAM = "refreshCache";
String USER_REST_PATH = "/user";
@ResponseBody
@GetMapping(value = USER_REST_PATH, produces = MediaType.APPLICATION_JSON_VALUE)
List<User> getAllUsers(@RequestParam(name = REFRESH_CACHE_PARAM, defaultValue = "false", required = false) boolean bypassCache);
}

View File

@ -1,30 +0,0 @@
package com.iqser.red.service.persistence.management.v1.processor.configuration;
import java.util.concurrent.Executor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
@Slf4j
@Configuration
@EnableScheduling
@RequiredArgsConstructor
public class CleanupDownloadSchedulerConfiguration {
@Bean
public Executor taskExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(1);
executor.setMaxPoolSize(1);
executor.setThreadNamePrefix("CleanupDownloadScheduler-");
executor.initialize();
return executor;
}
}

View File

@ -0,0 +1,50 @@
package com.iqser.red.service.persistence.management.v1.processor.configuration;
import org.springframework.amqp.core.Binding;
import org.springframework.amqp.core.BindingBuilder;
import org.springframework.amqp.core.FanoutExchange;
import org.springframework.amqp.core.Queue;
import org.springframework.amqp.core.QueueBuilder;
import org.springframework.amqp.core.TopicExchange;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import lombok.RequiredArgsConstructor;
@Configuration
@RequiredArgsConstructor
public class TenantMessagingConfiguration {
public static final String PERSISTENCE_SERVICE_TENANT_EVENTS_DQL = "persistence-service-tenant-events-dql";
public static final String PERSISTENCE_SERVICE_TENANT_CREATED_QUEUE = "persistence-service-tenant-created-queue";
@Bean("persistenceServiceTenantCreatedQueue")
public Queue persistenceServiceTenantCreatedQueue() {
return QueueBuilder.durable(PERSISTENCE_SERVICE_TENANT_CREATED_QUEUE)
.withArgument("x-dead-letter-exchange", "").withArgument("x-dead-letter-routing-key", PERSISTENCE_SERVICE_TENANT_EVENTS_DQL).build();
}
@Bean
public Queue persistenceServiceTenantDLQ() {
return QueueBuilder.durable(PERSISTENCE_SERVICE_TENANT_EVENTS_DQL).build();
}
@Bean
public Binding tenantExchangeBinding(@Qualifier("persistenceServiceTenantCreatedQueue") Queue persistenceServiceTenantCreatedQueue,
@Qualifier("tenantExchange") TopicExchange tenantExchange) {
return BindingBuilder.bind(persistenceServiceTenantCreatedQueue).to(tenantExchange).with("tenant.created");
}
@Bean(name = "tenantExchange")
TopicExchange tenantExchange(@Value("${fforesight.tenant-exchange.name}") String tenantExchangeName) {
return new TopicExchange(tenantExchangeName);
}
}

View File

@ -0,0 +1,149 @@
package com.iqser.red.service.persistence.management.v1.processor.configuration;
import org.springframework.amqp.core.Binding;
import org.springframework.amqp.core.BindingBuilder;
import org.springframework.amqp.core.Queue;
import org.springframework.amqp.core.QueueBuilder;
import org.springframework.amqp.core.TopicExchange;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import lombok.RequiredArgsConstructor;
@Configuration
@RequiredArgsConstructor
public class UserMessagingConfiguration {
public static final String PERSISTENCE_SERVICE_USER_CREATED_QUEUE = "persistence-service-user-created-queue";
public static final String PERSISTENCE_SERVICE_USER_DELETED_QUEUE = "persistence-service-user-deleted-queue";
public static final String PERSISTENCE_SERVICE_USER_UPDATED_QUEUE = "persistence-service-user-updated-queue";
public static final String PERSISTENCE_SERVICE_USER_STATUS_CHANGED_QUEUE = "persistence-service-user-status-changed-queue";
public static final String PERSISTENCE_SERVICE_USER_ROLES_UPDATED_QUEUE = "persistence-service-user-roles-updated-queue";
public static final String PERSISTENCE_SERVICE_USER_OWN_PROFILE_UPDATED_QUEUE = "persistence-service-user-own-profile-updated-queue";
public static final String PERSISTENCE_SERVICE_USER_EVENTS_DQL = "persistence-service-user-events-dql";
@Bean("persistenceServiceUserRolesUpdatedQueue")
public Queue persistenceServiceUserRolesUpdatedQueue() {
return QueueBuilder.durable(PERSISTENCE_SERVICE_USER_ROLES_UPDATED_QUEUE)
.withArgument("x-dead-letter-exchange", "")
.withArgument("x-dead-letter-routing-key", PERSISTENCE_SERVICE_USER_EVENTS_DQL)
.build();
}
@Bean
public Binding userRolesUpdatedBinding(@Qualifier("persistenceServiceUserRolesUpdatedQueue") Queue persistenceServiceUserRolesUpdatedQueue,
@Qualifier("userExchange") TopicExchange userExchange) {
return BindingBuilder.bind(persistenceServiceUserRolesUpdatedQueue).to(userExchange).with("user.rolesUpdated");
}
@Bean("persistenceServiceUserStatusChangedQueue")
public Queue persistenceServiceUserStatusChangedQueue() {
return QueueBuilder.durable(PERSISTENCE_SERVICE_USER_STATUS_CHANGED_QUEUE)
.withArgument("x-dead-letter-exchange", "")
.withArgument("x-dead-letter-routing-key", PERSISTENCE_SERVICE_USER_EVENTS_DQL)
.build();
}
@Bean
public Binding userStatusChangedBinding(@Qualifier("persistenceServiceUserStatusChangedQueue") Queue persistenceServiceUserStatusChangedQueue,
@Qualifier("userExchange") TopicExchange userExchange) {
return BindingBuilder.bind(persistenceServiceUserStatusChangedQueue).to(userExchange).with("user.statusChanged");
}
@Bean("persistenceServiceUserUpdatedQueue")
public Queue persistenceServiceUserUpdatedQueue() {
return QueueBuilder.durable(PERSISTENCE_SERVICE_USER_UPDATED_QUEUE)
.withArgument("x-dead-letter-exchange", "")
.withArgument("x-dead-letter-routing-key", PERSISTENCE_SERVICE_USER_EVENTS_DQL)
.build();
}
@Bean
public Binding userUpdatedBinding(@Qualifier("persistenceServiceUserUpdatedQueue") Queue persistenceServiceUserUpdatedQueue,
@Qualifier("userExchange") TopicExchange userExchange) {
return BindingBuilder.bind(persistenceServiceUserUpdatedQueue).to(userExchange).with("user.updated");
}
@Bean("persistenceServiceUserDeletedQueue")
public Queue persistenceServiceUserDeletedQueue() {
return QueueBuilder.durable(PERSISTENCE_SERVICE_USER_DELETED_QUEUE)
.withArgument("x-dead-letter-exchange", "")
.withArgument("x-dead-letter-routing-key", PERSISTENCE_SERVICE_USER_EVENTS_DQL)
.build();
}
@Bean
public Binding userDeletedBinding(@Qualifier("persistenceServiceUserDeletedQueue") Queue persistenceServiceUserDeletedQueue,
@Qualifier("userExchange") TopicExchange userExchange) {
return BindingBuilder.bind(persistenceServiceUserDeletedQueue).to(userExchange).with("user.deleted");
}
@Bean("persistenceServiceUserOwnProfileUpdatedQueue")
public Queue persistenceServiceUserOwnProfileUpdatedQueue() {
return QueueBuilder.durable(PERSISTENCE_SERVICE_USER_OWN_PROFILE_UPDATED_QUEUE)
.withArgument("x-dead-letter-exchange", "")
.withArgument("x-dead-letter-routing-key", PERSISTENCE_SERVICE_USER_EVENTS_DQL)
.build();
}
@Bean
public Binding userProfileUpdatedBinding(@Qualifier("persistenceServiceUserOwnProfileUpdatedQueue") Queue persistenceServiceUserOwnProfileUpdatedQueue,
@Qualifier("userExchange") TopicExchange userExchange) {
return BindingBuilder.bind(persistenceServiceUserOwnProfileUpdatedQueue).to(userExchange).with("user.ownProfileUpdated");
}
@Bean("persistenceServiceUserCreatedQueue")
public Queue persistenceServiceUserCreatedQueue() {
return QueueBuilder.durable(PERSISTENCE_SERVICE_USER_CREATED_QUEUE)
.withArgument("x-dead-letter-exchange", "")
.withArgument("x-dead-letter-routing-key", PERSISTENCE_SERVICE_USER_EVENTS_DQL)
.build();
}
@Bean
public Binding userCreatedBinding(@Qualifier("persistenceServiceUserCreatedQueue") Queue persistenceServiceUserCreatedQueue,
@Qualifier("userExchange") TopicExchange userExchange) {
return BindingBuilder.bind(persistenceServiceUserCreatedQueue).to(userExchange).with("user.created");
}
@Bean
public Queue persistenceServiceUserEventsDLQ() {
return QueueBuilder.durable(PERSISTENCE_SERVICE_USER_EVENTS_DQL).build();
}
@Bean(name = "userExchange")
TopicExchange tenantExchange(@Value("${fforesight.user-exchange.name}") String userExchange) {
return new TopicExchange(userExchange);
}
}

View File

@ -2,8 +2,8 @@ package com.iqser.red.service.persistence.management.v1.processor.entity.annotat
import java.io.Serializable;
import javax.persistence.Column;
import javax.persistence.Embeddable;
import jakarta.persistence.Column;
import jakarta.persistence.Embeddable;
import lombok.AllArgsConstructor;
import lombok.Builder;

View File

@ -2,12 +2,13 @@ package com.iqser.red.service.persistence.management.v1.processor.entity.annotat
import java.time.OffsetDateTime;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.ManyToOne;
import jakarta.persistence.Table;
import com.iqser.red.service.persistence.management.v1.processor.entity.dossier.FileEntity;
@ -25,7 +26,7 @@ import lombok.NoArgsConstructor;
public class CommentEntity {
@Id
@GeneratedValue
@GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;
@Column

View File

@ -4,14 +4,14 @@ import java.time.OffsetDateTime;
import java.util.HashSet;
import java.util.Set;
import javax.persistence.Column;
import javax.persistence.ElementCollection;
import javax.persistence.EmbeddedId;
import javax.persistence.Entity;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
import jakarta.persistence.Column;
import jakarta.persistence.ElementCollection;
import jakarta.persistence.EmbeddedId;
import jakarta.persistence.Entity;
import jakarta.persistence.EnumType;
import jakarta.persistence.Enumerated;
import jakarta.persistence.ManyToOne;
import jakarta.persistence.Table;
import org.hibernate.annotations.Fetch;
import org.hibernate.annotations.FetchMode;

View File

@ -2,13 +2,13 @@ package com.iqser.red.service.persistence.management.v1.processor.entity.annotat
import java.time.OffsetDateTime;
import javax.persistence.Column;
import javax.persistence.EmbeddedId;
import javax.persistence.Entity;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
import jakarta.persistence.Column;
import jakarta.persistence.EmbeddedId;
import jakarta.persistence.Entity;
import jakarta.persistence.EnumType;
import jakarta.persistence.Enumerated;
import jakarta.persistence.ManyToOne;
import jakarta.persistence.Table;
import com.iqser.red.service.persistence.management.v1.processor.entity.dossier.FileEntity;
import com.iqser.red.service.persistence.service.v1.api.shared.model.annotations.AnnotationStatus;

View File

@ -2,13 +2,13 @@ package com.iqser.red.service.persistence.management.v1.processor.entity.annotat
import java.time.OffsetDateTime;
import javax.persistence.Column;
import javax.persistence.EmbeddedId;
import javax.persistence.Entity;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
import jakarta.persistence.Column;
import jakarta.persistence.EmbeddedId;
import jakarta.persistence.Entity;
import jakarta.persistence.EnumType;
import jakarta.persistence.Enumerated;
import jakarta.persistence.ManyToOne;
import jakarta.persistence.Table;
import com.iqser.red.service.persistence.management.v1.processor.entity.dossier.FileEntity;
import com.iqser.red.service.persistence.service.v1.api.shared.model.annotations.AnnotationStatus;

View File

@ -2,13 +2,13 @@ package com.iqser.red.service.persistence.management.v1.processor.entity.annotat
import java.time.OffsetDateTime;
import javax.persistence.Column;
import javax.persistence.EmbeddedId;
import javax.persistence.Entity;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
import jakarta.persistence.Column;
import jakarta.persistence.EmbeddedId;
import jakarta.persistence.Entity;
import jakarta.persistence.EnumType;
import jakarta.persistence.Enumerated;
import jakarta.persistence.ManyToOne;
import jakarta.persistence.Table;
import com.iqser.red.service.persistence.management.v1.processor.entity.dossier.FileEntity;
import com.iqser.red.service.persistence.service.v1.api.shared.model.annotations.AnnotationStatus;

View File

@ -6,15 +6,15 @@ import java.util.HashSet;
import java.util.List;
import java.util.Set;
import javax.persistence.Column;
import javax.persistence.ElementCollection;
import javax.persistence.EmbeddedId;
import javax.persistence.Entity;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;
import javax.persistence.FetchType;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
import jakarta.persistence.Column;
import jakarta.persistence.ElementCollection;
import jakarta.persistence.EmbeddedId;
import jakarta.persistence.Entity;
import jakarta.persistence.EnumType;
import jakarta.persistence.Enumerated;
import jakarta.persistence.FetchType;
import jakarta.persistence.ManyToOne;
import jakarta.persistence.Table;
import org.hibernate.annotations.Fetch;
import org.hibernate.annotations.FetchMode;

View File

@ -4,15 +4,15 @@ import java.time.OffsetDateTime;
import java.util.ArrayList;
import java.util.List;
import javax.persistence.Column;
import javax.persistence.ElementCollection;
import javax.persistence.EmbeddedId;
import javax.persistence.Entity;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;
import javax.persistence.FetchType;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
import jakarta.persistence.Column;
import jakarta.persistence.ElementCollection;
import jakarta.persistence.EmbeddedId;
import jakarta.persistence.Entity;
import jakarta.persistence.EnumType;
import jakarta.persistence.Enumerated;
import jakarta.persistence.FetchType;
import jakarta.persistence.ManyToOne;
import jakarta.persistence.Table;
import org.hibernate.annotations.Fetch;
import org.hibernate.annotations.FetchMode;

View File

@ -1,6 +1,6 @@
package com.iqser.red.service.persistence.management.v1.processor.entity.annotations;
import javax.persistence.Embeddable;
import jakarta.persistence.Embeddable;
import lombok.AllArgsConstructor;
import lombok.Builder;

View File

@ -3,14 +3,14 @@ package com.iqser.red.service.persistence.management.v1.processor.entity.annotat
import java.io.Serializable;
import java.time.OffsetDateTime;
import javax.persistence.Column;
import javax.persistence.Embeddable;
import javax.persistence.EmbeddedId;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.ManyToOne;
import javax.persistence.MapsId;
import javax.persistence.Table;
import jakarta.persistence.Column;
import jakarta.persistence.Embeddable;
import jakarta.persistence.EmbeddedId;
import jakarta.persistence.Entity;
import jakarta.persistence.FetchType;
import jakarta.persistence.ManyToOne;
import jakarta.persistence.MapsId;
import jakarta.persistence.Table;
import com.iqser.red.service.persistence.management.v1.processor.entity.dossier.FileEntity;

View File

@ -4,14 +4,15 @@ import java.time.OffsetDateTime;
import java.util.HashMap;
import java.util.Map;
import javax.persistence.Basic;
import javax.persistence.Column;
import javax.persistence.Convert;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;
import jakarta.persistence.Basic;
import jakarta.persistence.Column;
import jakarta.persistence.Convert;
import jakarta.persistence.Entity;
import jakarta.persistence.FetchType;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.Table;
import com.iqser.red.service.persistence.management.v1.processor.utils.JSONMapConverter;
@ -29,7 +30,7 @@ import lombok.NoArgsConstructor;
public class AuditEntity {
@Id
@GeneratedValue
@GeneratedValue(strategy = GenerationType.IDENTITY)
private long recordId;
@Column

View File

@ -1,9 +1,9 @@
package com.iqser.red.service.persistence.management.v1.processor.entity.configuration;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.Id;
import jakarta.persistence.Table;
import lombok.AllArgsConstructor;
import lombok.Builder;

View File

@ -1,11 +1,11 @@
package com.iqser.red.service.persistence.management.v1.processor.entity.configuration;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.PrePersist;
import javax.persistence.PreUpdate;
import javax.persistence.Table;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.Id;
import jakarta.persistence.PrePersist;
import jakarta.persistence.PreUpdate;
import jakarta.persistence.Table;
import lombok.AllArgsConstructor;
import lombok.Builder;

View File

@ -1,11 +1,11 @@
package com.iqser.red.service.persistence.management.v1.processor.entity.configuration;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.Table;
import lombok.AllArgsConstructor;
import lombok.Builder;

View File

@ -1,12 +1,12 @@
package com.iqser.red.service.persistence.management.v1.processor.entity.configuration;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.Table;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;

View File

@ -1,11 +1,11 @@
package com.iqser.red.service.persistence.management.v1.processor.entity.configuration;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.Table;
import lombok.AllArgsConstructor;
import lombok.Builder;

Some files were not shown because too many files have changed in this diff Show More