Compare commits
94 Commits
Author | SHA1 | Date |
---|---|---|
Diamantis Tziotzios | e8aef281d4 | |
Diamantis Tziotzios | 00c6978594 | |
Diamantis Tziotzios | 3adb518e61 | |
Konstantina Galouni | eb74ef86b9 | |
Diamantis Tziotzios | a1ee9c82bc | |
Diamantis Tziotzios | 5e5bd39313 | |
Diamantis Tziotzios | 5e99cef60e | |
Diamantis Tziotzios | cc7edc2f49 | |
Diamantis Tziotzios | a1849c64ca | |
Diamantis Tziotzios | 192220161b | |
George Kalampokis | 87758c3e9a | |
Diamantis Tziotzios | 83342f5afa | |
Diamantis Tziotzios | 65cdb3b6ea | |
Diamantis Tziotzios | 536ba9b900 | |
Alexandros Mandilaras | 6bd3302788 | |
Diamantis Tziotzios | 4970f5812f | |
Diamantis Tziotzios | 9fed92dbcb | |
Diamantis Tziotzios | 44dab9c19a | |
Alexandros Mandilaras | 54f911d826 | |
Diamantis Tziotzios | 9879050eab | |
Diamantis Tziotzios | 8a41a7dcd9 | |
Diamantis Tziotzios | d60cc144d5 | |
Georgios Kakaletris | 9c37e5a073 | |
Georgios Kakaletris | 444c1aacb1 | |
Diamantis Tziotzios | 59d7383947 | |
Diamantis Tziotzios | 6caa1af134 | |
George Kalampokis | 74a6019a72 | |
George Kalampokis | 5c903c0f48 | |
George Kalampokis | ec8f6a6d48 | |
Bernaldo Mihasi | ecd86f413a | |
Bernaldo Mihasi | c238615b50 | |
Bernaldo Mihasi | 10d0f1fb0e | |
Bernaldo Mihasi | 846405435c | |
Bernaldo Mihasi | dfc9e14003 | |
Bernaldo Mihasi | bc1894586b | |
Bernaldo Mihasi | 2bf0a857bc | |
Bernaldo Mihasi | 3d10e8ad28 | |
Bernaldo Mihasi | 53b61853e1 | |
Bernaldo Mihasi | d644b1dc91 | |
Diamantis Tziotzios | 50c96ef821 | |
Konstantina Galouni | 0adc7044ab | |
Konstantina Galouni | 13e62fd409 | |
Diamantis Tziotzios | 7185b5d117 | |
George Kalampokis | 5f131b9823 | |
Diamantis Tziotzios | 93320f7c94 | |
Diamantis Tziotzios | 876d99ce38 | |
George Kalampokis | 7a71110033 | |
Diamantis Tziotzios | 14c267c97e | |
Diamantis Tziotzios | b04b35d62b | |
Diamantis Tziotzios | 7a8375b988 | |
Diamantis Tziotzios | 895dbcf098 | |
Diamantis Tziotzios | bd15b1e2c7 | |
George Kalampokis | faabd343a9 | |
George Kalampokis | e5a929f259 | |
George Kalampokis | d1fc10854c | |
George Kalampokis | 2537923dc0 | |
George Kalampokis | c1adbe283a | |
George Kalampokis | 1c365a191e | |
Kristian Ntavidi | 82c5586067 | |
George Kalampokis | 04f230dff1 | |
George Kalampokis | 72d88d9db4 | |
George Kalampokis | 143a4c0214 | |
George Kalampokis | e7e5ed02b3 | |
George Kalampokis | b5fcc5971e | |
Diamantis Tziotzios | c16c35225f | |
Diamantis Tziotzios | f5d266554b | |
Diamantis Tziotzios | db31597fc0 | |
Diamantis Tziotzios | 9f5054668e | |
George Kalampokis | 38986ef67b | |
Diamantis Tziotzios | bff260b85b | |
George Kalampokis | 9519300dc4 | |
George Kalampokis | 9373d3e038 | |
dtziotzios | d971f02a94 | |
Georgios Kakaletris | d3915e26e7 | |
George Kalampokis | c028aad615 | |
Diamantis Tziotzios | 4ee39074a3 | |
Diamantis Tziotzios | 1b4952a909 | |
Diamantis Tziotzios | 3ada5a0d3d | |
Diamantis Tziotzios | 63ee865dd9 | |
Diamantis Tziotzios | 2a52138124 | |
Diamantis Tziotzios | 7cf64c18f2 | |
Diamantis Tziotzios | 71d317bab7 | |
Ioannis Kalyvas | cd8b3448f5 | |
Ioannis Kalyvas | c3d4cb6fdd | |
Ioannis Kalyvas | b0ccac191f | |
Ioannis Kalyvas | 3b1f37ef22 | |
Ioannis Kalyvas | b8e040ee94 | |
Ioannis Kalyvas | 50444a0b73 | |
Diamantis Tziotzios | 85bdb7fad1 | |
annabakouli | b2e49fbb8a | |
Diamantis Tziotzios | bfc6b63067 | |
Nikolaos Laskaris | 9941c96dc2 | |
Nikolaos Laskaris | 06272c79da | |
Nikolaos Laskaris | a00eec68d8 |
|
@ -46,9 +46,6 @@ ELK.Docker/shared/data-elk/
|
|||
.settings/
|
||||
bin/
|
||||
*.classpath
|
||||
.run
|
||||
openDMP/dmp-backend/uploads/
|
||||
openDMP/dmp-backend/tmp/
|
||||
logs/
|
||||
dmp-backend/web/src/main/resources/certificates/
|
||||
/storage/
|
||||
dmp-frontend/.angular/
|
||||
|
|
|
@ -1,3 +1,9 @@
|
|||
|
||||
**Important note: The deployment, troubleshooting, maintenance and operation of on-premises / self-served OpenDMP instances for development, testing or production use, shall be the sole responsibility of the adopter. No support is guaranteed by OpenDMP implentation team for issues that may be encountered during deployment, extension or operation of such installations.**
|
||||
|
||||
**Documentation is provided on a best-effort basis for the code and processes around the development, deployment and operation of OpenDMP. If you find any misalignment of the actual processes with the related documentation, please let us know so that the misalignment is addressed for the benefit of future adopters.**
|
||||
|
||||
|
||||
# Using Docker Compose with Argos
|
||||
|
||||
ARGOS is an open extensible service that simplifies the management, validation, monitoring and maintenance and of Data Management Plans. It allows actors (researchers, managers, supervisors etc) to create actionable DMPs that may be freely exchanged among infrastructures for carrying out specific aspects of the Data management process in accordance with the intentions and commitment of Data owners.
|
||||
|
|
|
@ -1,27 +0,0 @@
|
|||
####################################### Build stage #######################################
|
||||
FROM maven:3.9-eclipse-temurin-17-alpine AS build-stage
|
||||
|
||||
ARG CITE_MAVEN_ACCOUNT_USR
|
||||
ARG CITE_MAVEN_ACCOUNT_PSW
|
||||
|
||||
COPY pom.xml /build/
|
||||
COPY annotation /build/annotation/
|
||||
COPY annotation-web /build/annotation-web/
|
||||
COPY settings.xml /root/.m2/settings.xml
|
||||
RUN rm -f /build/annotation-web/src/main/resources/config/app.env
|
||||
RUN rm -f /build/annotation-web/src/main/resources/config/*-dev.yml
|
||||
RUN rm -f /build/annotation-web/src/main/resources/logging/*.xml
|
||||
RUN rm -f /build/annotation-web/src/main/resources/certificates/*.crt
|
||||
|
||||
WORKDIR /build/
|
||||
|
||||
RUN mvn -Dserver.username=${CITE_MAVEN_ACCOUNT_USR} -Dserver.password=${CITE_MAVEN_ACCOUNT_PSW} dependency:go-offline
|
||||
# Build project
|
||||
RUN mvn -Dserver.username=${CITE_MAVEN_ACCOUNT_USR} -Dserver.password=${CITE_MAVEN_ACCOUNT_PSW} clean package
|
||||
|
||||
######################################## Run Stage ########################################
|
||||
FROM eclipse-temurin:17-jre-ubi9-minimal
|
||||
|
||||
COPY --from=build-stage /build/annotation-web/target/sti-viewer-annotation-web.jar /app/sti-viewer-annotation-web.jar
|
||||
|
||||
ENTRYPOINT ["java","-Dspring.config.additional-location=file:/config/","-Dspring.profiles.active=${PROFILE}","-Djava.security.egd=file:/dev/./urandom","-jar","/app/sti-viewer-annotation-web.jar"]
|
|
@ -1,33 +0,0 @@
|
|||
HELP.md
|
||||
target/
|
||||
!.mvn/wrapper/maven-wrapper.jar
|
||||
!**/src/main/**/target/
|
||||
!**/src/test/**/target/
|
||||
|
||||
### STS ###
|
||||
.apt_generated
|
||||
.classpath
|
||||
.factorypath
|
||||
.project
|
||||
.settings
|
||||
.springBeans
|
||||
.sts4-cache
|
||||
|
||||
### IntelliJ IDEA ###
|
||||
.idea
|
||||
*.iws
|
||||
*.iml
|
||||
*.ipr
|
||||
|
||||
### NetBeans ###
|
||||
/nbproject/private/
|
||||
/nbbuild/
|
||||
/dist/
|
||||
/nbdist/
|
||||
/.nb-gradle/
|
||||
build/
|
||||
!**/src/main/**/build/
|
||||
!**/src/test/**/build/
|
||||
|
||||
### VS Code ###
|
||||
.vscode/
|
|
@ -1,90 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<parent>
|
||||
<groupId>gr.cite</groupId>
|
||||
<artifactId>annotation-service-parent</artifactId>
|
||||
<version>1.0.0</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
<artifactId>annotation-web</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<properties>
|
||||
<maven.compiler.release>21</maven.compiler.release>
|
||||
<maven.compiler.source>21</maven.compiler.source>
|
||||
<maven.compiler.target>21</maven.compiler.target>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-webflux</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-validation</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.postgresql</groupId>
|
||||
<artifactId>postgresql</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.hibernate.orm</groupId>
|
||||
<artifactId>hibernate-core</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-tomcat</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>gr.cite</groupId>
|
||||
<artifactId>annotation</artifactId>
|
||||
<version>1.0.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>gr.cite</groupId>
|
||||
<artifactId>oidc-authz</artifactId>
|
||||
<version>2.1.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>gr.cite</groupId>
|
||||
<artifactId>cache</artifactId>
|
||||
<version>2.1.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>gr.cite</groupId>
|
||||
<artifactId>exceptions-web</artifactId>
|
||||
<version>1.0.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>gr.cite</groupId>
|
||||
<artifactId>cors-web</artifactId>
|
||||
<version>1.0.0</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<finalName>argos-annotation-web</finalName>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
</project>
|
|
@ -1,26 +0,0 @@
|
|||
package gr.cite.annotation.web;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.boot.autoconfigure.domain.EntityScan;
|
||||
import org.springframework.scheduling.annotation.EnableAsync;
|
||||
|
||||
@SpringBootApplication(
|
||||
scanBasePackages = {
|
||||
"eu.eudat",
|
||||
"gr.cite",
|
||||
"gr.cite.queueoutbox",
|
||||
"gr.cite.queueinbox",
|
||||
"gr.cite.annotation.integrationevent",
|
||||
"gr.cite.tools",
|
||||
"gr.cite.commons"})
|
||||
@EntityScan({
|
||||
"gr.cite.annotation.data"})
|
||||
@EnableAsync
|
||||
public class AnnotationApplication {
|
||||
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(AnnotationApplication.class, args);
|
||||
}
|
||||
|
||||
}
|
|
@ -1,40 +0,0 @@
|
|||
package gr.cite.annotation.web;
|
||||
|
||||
import gr.cite.annotation.web.interceptors.UserInterceptor;
|
||||
import gr.cite.annotation.web.scope.tenant.TenantInterceptor;
|
||||
import gr.cite.annotation.web.scope.tenant.TenantScopeClaimInterceptor;
|
||||
import gr.cite.annotation.web.scope.tenant.TenantScopeHeaderInterceptor;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
|
||||
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
|
||||
|
||||
@Configuration
|
||||
public class WebConfiguration implements WebMvcConfigurer {
|
||||
private final TenantInterceptor tenantInterceptor;
|
||||
private final TenantScopeHeaderInterceptor scopeHeaderInterceptor;
|
||||
private final TenantScopeClaimInterceptor scopeClaimInterceptor;
|
||||
private final UserInterceptor userInterceptor;
|
||||
|
||||
@Autowired
|
||||
public WebConfiguration(
|
||||
TenantInterceptor tenantInterceptor,
|
||||
TenantScopeHeaderInterceptor scopeHeaderInterceptor,
|
||||
TenantScopeClaimInterceptor scopeClaimInterceptor,
|
||||
UserInterceptor userInterceptor
|
||||
) {
|
||||
this.tenantInterceptor = tenantInterceptor;
|
||||
this.scopeHeaderInterceptor = scopeHeaderInterceptor;
|
||||
this.scopeClaimInterceptor = scopeClaimInterceptor;
|
||||
this.userInterceptor = userInterceptor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addInterceptors(InterceptorRegistry registry) {
|
||||
int order = 1;
|
||||
registry.addWebRequestInterceptor(scopeHeaderInterceptor).order(order++);
|
||||
registry.addWebRequestInterceptor(scopeClaimInterceptor).order(order++);
|
||||
registry.addWebRequestInterceptor(userInterceptor).order(order++);
|
||||
registry.addWebRequestInterceptor(tenantInterceptor).order(order++);
|
||||
}
|
||||
}
|
|
@ -1,44 +0,0 @@
|
|||
package gr.cite.annotation.web.authorization;
|
||||
|
||||
import gr.cite.commons.web.authz.handler.AuthorizationHandler;
|
||||
import gr.cite.commons.web.authz.handler.AuthorizationHandlerContext;
|
||||
import gr.cite.commons.web.authz.policy.AuthorizationRequirement;
|
||||
import gr.cite.commons.web.oidc.principal.MyPrincipal;
|
||||
import gr.cite.annotation.authorization.OwnedAuthorizationRequirement;
|
||||
import gr.cite.annotation.authorization.OwnedResource;
|
||||
import gr.cite.annotation.common.scope.user.UserScope;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component("ownedAuthorizationHandler")
|
||||
public class OwnedAuthorizationHandler extends AuthorizationHandler<OwnedAuthorizationRequirement> {
|
||||
|
||||
private final UserScope userScope;
|
||||
|
||||
@Autowired
|
||||
public OwnedAuthorizationHandler(UserScope userScope) {
|
||||
this.userScope = userScope;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int handleRequirement(AuthorizationHandlerContext context, Object resource, AuthorizationRequirement requirement) {
|
||||
OwnedAuthorizationRequirement req = (OwnedAuthorizationRequirement) requirement;
|
||||
|
||||
OwnedResource rs = (OwnedResource) resource;
|
||||
|
||||
boolean isAuthenticated = ((MyPrincipal) context.getPrincipal()).isAuthenticated();
|
||||
if (!isAuthenticated) return ACCESS_NOT_DETERMINED;
|
||||
|
||||
if (this.userScope.getUserIdSafe() == null) return ACCESS_NOT_DETERMINED;
|
||||
|
||||
if (rs != null && rs.getUserIds() != null && rs.getUserIds().contains(this.userScope.getUserIdSafe())) return ACCESS_GRANTED;
|
||||
|
||||
return ACCESS_NOT_DETERMINED;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<? extends AuthorizationRequirement> supporting() {
|
||||
return OwnedAuthorizationRequirement.class;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,25 +0,0 @@
|
|||
package gr.cite.annotation.web.config;
|
||||
|
||||
import org.springframework.context.MessageSource;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.support.ReloadableResourceBundleMessageSource;
|
||||
import org.springframework.validation.beanvalidation.LocalValidatorFactoryBean;
|
||||
|
||||
@Configuration
|
||||
public class AppMessageSourceConfiguration {
|
||||
@Bean
|
||||
public MessageSource messageSource() {
|
||||
ReloadableResourceBundleMessageSource messageSource = new ReloadableResourceBundleMessageSource();
|
||||
messageSource.setBasename("classpath:messages/messages");
|
||||
messageSource.setDefaultEncoding("UTF-8");
|
||||
return messageSource;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public LocalValidatorFactoryBean getValidator() {
|
||||
LocalValidatorFactoryBean bean = new LocalValidatorFactoryBean();
|
||||
bean.setValidationMessageSource(messageSource());
|
||||
return bean;
|
||||
}
|
||||
}
|
|
@ -1,142 +0,0 @@
|
|||
package gr.cite.annotation.web.config;
|
||||
|
||||
import gr.cite.commons.web.authz.handler.AuthorizationHandler;
|
||||
import gr.cite.commons.web.authz.handler.PermissionClientAuthorizationHandler;
|
||||
import gr.cite.commons.web.authz.policy.AuthorizationRequirement;
|
||||
import gr.cite.commons.web.authz.policy.AuthorizationRequirementMapper;
|
||||
import gr.cite.commons.web.authz.policy.AuthorizationResource;
|
||||
import gr.cite.commons.web.authz.policy.resolver.AuthorizationPolicyConfigurer;
|
||||
import gr.cite.commons.web.authz.policy.resolver.AuthorizationPolicyResolverStrategy;
|
||||
import gr.cite.commons.web.oidc.configuration.WebSecurityProperties;
|
||||
import gr.cite.annotation.authorization.OwnedAuthorizationRequirement;
|
||||
import gr.cite.annotation.authorization.OwnedResource;
|
||||
import gr.cite.annotation.web.authorization.OwnedAuthorizationHandler;
|
||||
import jakarta.servlet.Filter;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.security.authentication.AuthenticationManagerResolver;
|
||||
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
||||
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
|
||||
import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;
|
||||
import org.springframework.security.config.annotation.web.configurers.HeadersConfigurer;
|
||||
import org.springframework.security.config.http.SessionCreationPolicy;
|
||||
import org.springframework.security.web.SecurityFilterChain;
|
||||
import org.springframework.security.web.authentication.preauth.AbstractPreAuthenticatedProcessingFilter;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
@Configuration
|
||||
@EnableWebSecurity
|
||||
public class SecurityConfiguration {
|
||||
|
||||
private final WebSecurityProperties webSecurityProperties;
|
||||
private final AuthenticationManagerResolver<HttpServletRequest> authenticationManagerResolver;
|
||||
private final Filter apiKeyFilter;
|
||||
private final OwnedAuthorizationHandler ownedAuthorizationHandler;
|
||||
|
||||
@Autowired
|
||||
public SecurityConfiguration(WebSecurityProperties webSecurityProperties,
|
||||
@Qualifier("tokenAuthenticationResolver") AuthenticationManagerResolver<HttpServletRequest> authenticationManagerResolver,
|
||||
@Qualifier("apiKeyFilter") Filter apiKeyFilter,
|
||||
@Qualifier("ownedAuthorizationHandler") OwnedAuthorizationHandler ownedAuthorizationHandler) {
|
||||
this.webSecurityProperties = webSecurityProperties;
|
||||
this.authenticationManagerResolver = authenticationManagerResolver;
|
||||
this.apiKeyFilter = apiKeyFilter;
|
||||
this.ownedAuthorizationHandler = ownedAuthorizationHandler;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
|
||||
HttpSecurity tempHttp = http
|
||||
.csrf(AbstractHttpConfigurer::disable)
|
||||
.cors(httpSecurityCorsConfigurer -> {})
|
||||
.headers(httpSecurityHeadersConfigurer -> httpSecurityHeadersConfigurer.frameOptions(HeadersConfigurer.FrameOptionsConfig::disable))
|
||||
.addFilterBefore(apiKeyFilter, AbstractPreAuthenticatedProcessingFilter.class)
|
||||
.authorizeHttpRequests(authRequest ->
|
||||
authRequest.requestMatchers(buildAntPatterns(webSecurityProperties.getAllowedEndpoints())).anonymous()
|
||||
.requestMatchers(buildAntPatterns(webSecurityProperties.getAuthorizedEndpoints())).authenticated())
|
||||
.sessionManagement( sessionManagementConfigurer-> sessionManagementConfigurer.sessionCreationPolicy(SessionCreationPolicy.NEVER))
|
||||
.oauth2ResourceServer(oauth2 -> oauth2.authenticationManagerResolver(authenticationManagerResolver));
|
||||
return tempHttp.build();
|
||||
}
|
||||
|
||||
@Bean
|
||||
AuthorizationPolicyConfigurer authorizationPolicyConfigurer() {
|
||||
return new AuthorizationPolicyConfigurer() {
|
||||
|
||||
@Override
|
||||
public AuthorizationPolicyResolverStrategy strategy() {
|
||||
return AuthorizationPolicyResolverStrategy.STRICT_CONSENSUS_BASED;
|
||||
}
|
||||
|
||||
//Here you can register your custom authorization handlers, which will get used as well as the existing ones
|
||||
//This is optional and can be omitted
|
||||
//If not set / set to null, only the default authorization handlers will be used
|
||||
@Override
|
||||
public List<AuthorizationHandler<? extends AuthorizationRequirement>> addCustomHandlers() {
|
||||
return List.of(ownedAuthorizationHandler);
|
||||
}
|
||||
|
||||
//Here you can register your custom authorization requirements (if any)
|
||||
//This is optional and can be omitted
|
||||
//If not set / set to null, only the default authorization requirements will be used
|
||||
@Override
|
||||
public List<? extends AuthorizationRequirement> extendRequirements() {
|
||||
return List.of(
|
||||
// new TimeOfDayAuthorizationRequirement(new TimeOfDay("08:00","16:00"), true)
|
||||
);
|
||||
}
|
||||
|
||||
//Here you can select handlers you want to disable by providing the classes they are implemented by
|
||||
//You can disable any handler (including any custom one)
|
||||
//This is optional and can be omitted
|
||||
//If not set / set to null, all the handlers will be invoked, based on their requirement support
|
||||
//In the example below, the default client handler will be ignored by the resolver
|
||||
@Override
|
||||
public List<Class<? extends AuthorizationHandler<? extends AuthorizationRequirement>>> disableHandlers() {
|
||||
return List.of(PermissionClientAuthorizationHandler.class);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Bean
|
||||
AuthorizationRequirementMapper authorizationRequirementMapper() {
|
||||
return new AuthorizationRequirementMapper() {
|
||||
@Override
|
||||
public AuthorizationRequirement map(AuthorizationResource resource, boolean matchAll, String[] permissions) {
|
||||
Class<?> type = resource.getClass();
|
||||
if (!AuthorizationResource.class.isAssignableFrom(type)) throw new IllegalArgumentException("resource");
|
||||
|
||||
if (OwnedResource.class.equals(type)) {
|
||||
return new OwnedAuthorizationRequirement();
|
||||
}
|
||||
throw new IllegalArgumentException("resource");
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private String[] buildAntPatterns(Set<String> endpoints) {
|
||||
if (endpoints == null) {
|
||||
return new String[0];
|
||||
}
|
||||
return endpoints.stream()
|
||||
.filter(endpoint -> endpoint != null && !endpoint.isBlank())
|
||||
.map(endpoint -> "/" + stripUnnecessaryCharacters(endpoint) + "/**")
|
||||
.toArray(String[]::new);
|
||||
}
|
||||
|
||||
private String stripUnnecessaryCharacters(String endpoint) {
|
||||
endpoint = endpoint.strip();
|
||||
if (endpoint.startsWith("/")) {
|
||||
endpoint = endpoint.substring(1);
|
||||
}
|
||||
if (endpoint.endsWith("/")) {
|
||||
endpoint = endpoint.substring(0, endpoint.length() - 1);
|
||||
}
|
||||
return endpoint;
|
||||
}
|
||||
}
|
|
@ -1,193 +0,0 @@
|
|||
package gr.cite.annotation.web.controllerhandler;
|
||||
|
||||
import gr.cite.annotation.common.JsonHandlingService;
|
||||
import gr.cite.tools.exception.*;
|
||||
import gr.cite.tools.logging.LoggerService;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.bind.annotation.ControllerAdvice;
|
||||
import org.springframework.web.bind.annotation.ExceptionHandler;
|
||||
import org.springframework.web.bind.annotation.RestControllerAdvice;
|
||||
import org.springframework.web.context.request.WebRequest;
|
||||
|
||||
import java.text.MessageFormat;
|
||||
import java.util.Map;
|
||||
|
||||
@RestControllerAdvice
|
||||
@ControllerAdvice
|
||||
public class GlobalExceptionHandler {
|
||||
private static final LoggerService logger = new LoggerService(LoggerFactory.getLogger(GlobalExceptionHandler.class));
|
||||
|
||||
private final JsonHandlingService jsonHandlingService;
|
||||
|
||||
public GlobalExceptionHandler(JsonHandlingService jsonHandlingService) {
|
||||
this.jsonHandlingService = jsonHandlingService;
|
||||
}
|
||||
|
||||
|
||||
@ExceptionHandler(Exception.class)
|
||||
public ResponseEntity<?> handleUnexpectedErrors(Exception exception, WebRequest request) throws Exception {
|
||||
HandledException handled = this.handleException(exception, request);
|
||||
this.log(handled.getLevel(), exception, MessageFormat.format("returning code {0} and payload {1}", handled.getStatusCode(), handled.getMessage()));
|
||||
return new ResponseEntity<>(handled.getMessage(), handled.getStatusCode());
|
||||
}
|
||||
|
||||
public void log(System.Logger.Level level, Exception e, String message) {
|
||||
if (level != null) {
|
||||
switch (level) {
|
||||
case TRACE:
|
||||
logger.trace(message, e);
|
||||
break;
|
||||
case DEBUG:
|
||||
logger.debug(message, e);
|
||||
break;
|
||||
case INFO:
|
||||
logger.info(message, e);
|
||||
break;
|
||||
case WARNING:
|
||||
logger.warn(message, e);
|
||||
break;
|
||||
case ERROR:
|
||||
logger.error(message, e);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public HandledException handleException(Exception exception, WebRequest request) throws Exception {
|
||||
HttpStatus statusCode;
|
||||
Map<String, Object> result;
|
||||
System.Logger.Level logLevel;
|
||||
|
||||
switch (exception){
|
||||
case MyNotFoundException myNotFoundException -> {
|
||||
logLevel = System.Logger.Level.DEBUG;
|
||||
statusCode = HttpStatus.NOT_FOUND;
|
||||
int code = myNotFoundException.getCode();
|
||||
if (code > 0) {
|
||||
result = Map.ofEntries(
|
||||
Map.entry("code", code),
|
||||
Map.entry("error", myNotFoundException.getMessage())
|
||||
);
|
||||
}
|
||||
else {
|
||||
result = Map.ofEntries(
|
||||
Map.entry("error", myNotFoundException.getMessage())
|
||||
);
|
||||
}
|
||||
}
|
||||
case MyUnauthorizedException myUnauthorizedException -> {
|
||||
logLevel = System.Logger.Level.DEBUG;
|
||||
statusCode = HttpStatus.UNAUTHORIZED;
|
||||
int code = myUnauthorizedException.getCode();
|
||||
if (code > 0) {
|
||||
result = Map.ofEntries(
|
||||
Map.entry("code", code),
|
||||
Map.entry("error", myUnauthorizedException.getMessage())
|
||||
);
|
||||
}
|
||||
else {
|
||||
result = Map.ofEntries(
|
||||
Map.entry("error", myUnauthorizedException.getMessage())
|
||||
);
|
||||
}
|
||||
}
|
||||
case MyForbiddenException myForbiddenException -> {
|
||||
logLevel = System.Logger.Level.DEBUG;
|
||||
statusCode = HttpStatus.FORBIDDEN;
|
||||
int code = myForbiddenException.getCode();
|
||||
if (code > 0) {
|
||||
result = Map.ofEntries(
|
||||
Map.entry("code", code),
|
||||
Map.entry("error", myForbiddenException.getMessage())
|
||||
);
|
||||
}
|
||||
else {
|
||||
result = Map.ofEntries(
|
||||
Map.entry("error", myForbiddenException.getMessage())
|
||||
);
|
||||
}
|
||||
}
|
||||
case MyValidationException myValidationException -> {
|
||||
logLevel = System.Logger.Level.DEBUG;
|
||||
statusCode = HttpStatus.BAD_REQUEST;
|
||||
int code = myValidationException.getCode();
|
||||
if (code > 0) {
|
||||
result = Map.ofEntries(
|
||||
Map.entry("code", code),
|
||||
Map.entry("error", myValidationException.getMessage()),
|
||||
Map.entry("message", myValidationException.getErrors())
|
||||
);
|
||||
}
|
||||
else {
|
||||
result = Map.ofEntries(
|
||||
Map.entry("error", myValidationException.getMessage()),
|
||||
Map.entry("message", myValidationException.getErrors())
|
||||
);
|
||||
}
|
||||
}
|
||||
case MyApplicationException myApplicationException -> {
|
||||
logLevel = System.Logger.Level.ERROR;
|
||||
statusCode = HttpStatus.INTERNAL_SERVER_ERROR;
|
||||
int code = myApplicationException.getCode();
|
||||
if (code > 0) {
|
||||
result = Map.ofEntries(
|
||||
Map.entry("code", code),
|
||||
Map.entry("error", myApplicationException.getMessage())
|
||||
);
|
||||
}
|
||||
else {
|
||||
result = Map.ofEntries(
|
||||
Map.entry("error", myApplicationException.getMessage())
|
||||
);
|
||||
}
|
||||
}
|
||||
default -> {
|
||||
logLevel = System.Logger.Level.ERROR;
|
||||
statusCode = HttpStatus.INTERNAL_SERVER_ERROR;
|
||||
result = Map.ofEntries(
|
||||
Map.entry("error", "System error")
|
||||
);
|
||||
}
|
||||
};
|
||||
String serialization = this.jsonHandlingService.toJsonSafe(result);
|
||||
return new HandledException(statusCode, serialization, logLevel);
|
||||
}
|
||||
|
||||
public static class HandledException{
|
||||
public HttpStatus statusCode;
|
||||
public String message;
|
||||
public System.Logger.Level level;
|
||||
|
||||
public HandledException(HttpStatus statusCode, String message, System.Logger.Level level) {
|
||||
this.statusCode = statusCode;
|
||||
this.message = message;
|
||||
this.level = level;
|
||||
}
|
||||
|
||||
public HttpStatus getStatusCode() {
|
||||
return statusCode;
|
||||
}
|
||||
|
||||
public void setStatusCode(HttpStatus statusCode) {
|
||||
this.statusCode = statusCode;
|
||||
}
|
||||
|
||||
public String getMessage() {
|
||||
return message;
|
||||
}
|
||||
|
||||
public void setMessage(String message) {
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
public System.Logger.Level getLevel() {
|
||||
return level;
|
||||
}
|
||||
|
||||
public void setLevel(System.Logger.Level level) {
|
||||
this.level = level;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,131 +0,0 @@
|
|||
package gr.cite.annotation.web.controllers;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import gr.cite.annotation.audit.AuditableAction;
|
||||
import gr.cite.annotation.data.AnnotationEntity;
|
||||
import gr.cite.annotation.model.Annotation;
|
||||
import gr.cite.annotation.model.builder.AnnotationBuilder;
|
||||
import gr.cite.annotation.model.censorship.AnnotationCensor;
|
||||
import gr.cite.annotation.model.persist.AnnotationPersist;
|
||||
import gr.cite.annotation.query.AnnotationQuery;
|
||||
import gr.cite.annotation.query.lookup.AnnotationLookup;
|
||||
import gr.cite.annotation.service.annotation.AnnotationService;
|
||||
import gr.cite.annotation.web.model.QueryResult;
|
||||
import gr.cite.tools.auditing.AuditService;
|
||||
import gr.cite.tools.data.builder.BuilderFactory;
|
||||
import gr.cite.tools.data.censor.CensorFactory;
|
||||
import gr.cite.tools.data.query.QueryFactory;
|
||||
import gr.cite.tools.exception.MyApplicationException;
|
||||
import gr.cite.tools.exception.MyForbiddenException;
|
||||
import gr.cite.tools.exception.MyNotFoundException;
|
||||
import gr.cite.tools.fieldset.FieldSet;
|
||||
import gr.cite.tools.logging.LoggerService;
|
||||
import gr.cite.tools.logging.MapLogEntry;
|
||||
import gr.cite.tools.validation.ValidationFilterAnnotation;
|
||||
import jakarta.transaction.Transactional;
|
||||
import jakarta.xml.bind.JAXBException;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.context.MessageSource;
|
||||
import org.springframework.context.i18n.LocaleContextHolder;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.management.InvalidApplicationException;
|
||||
import javax.xml.parsers.ParserConfigurationException;
|
||||
import javax.xml.transform.TransformerException;
|
||||
import java.util.AbstractMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
@RestController
|
||||
@RequestMapping(path = "api/annotation", produces = MediaType.APPLICATION_JSON_VALUE)
|
||||
public class AnnotationController {
|
||||
|
||||
private static final LoggerService logger = new LoggerService(LoggerFactory.getLogger(AnnotationController.class));
|
||||
|
||||
private final CensorFactory censorFactory;
|
||||
|
||||
private final QueryFactory queryFactory;
|
||||
|
||||
private final BuilderFactory builderFactory;
|
||||
|
||||
private final AuditService auditService;
|
||||
|
||||
private final MessageSource messageSource;
|
||||
|
||||
private final AnnotationService annotationService;
|
||||
|
||||
public AnnotationController(CensorFactory censorFactory, QueryFactory queryFactory, BuilderFactory builderFactory, AuditService auditService, MessageSource messageSource, AnnotationService annotationService) {
|
||||
this.censorFactory = censorFactory;
|
||||
this.queryFactory = queryFactory;
|
||||
this.builderFactory = builderFactory;
|
||||
this.auditService = auditService;
|
||||
this.messageSource = messageSource;
|
||||
this.annotationService = annotationService;
|
||||
}
|
||||
|
||||
@PostMapping("query")
|
||||
public QueryResult<Annotation> query(@RequestBody AnnotationLookup lookup) {
|
||||
logger.debug("querying {}", Annotation.class.getSimpleName());
|
||||
|
||||
this.censorFactory.censor(AnnotationCensor.class).censor(lookup.getProject(), null);
|
||||
|
||||
AnnotationQuery query = lookup.enrich(this.queryFactory);
|
||||
List<AnnotationEntity> data = query.collectAs(lookup.getProject());
|
||||
List<Annotation> models = this.builderFactory.builder(AnnotationBuilder.class).build(lookup.getProject(), data);
|
||||
long count = (lookup.getMetadata() != null && lookup.getMetadata().getCountAll()) ? query.count() : models.size();
|
||||
|
||||
this.auditService.track(AuditableAction.Annotation_Query, "lookup", lookup);
|
||||
|
||||
return new QueryResult<>(models, count);
|
||||
}
|
||||
|
||||
@GetMapping("{id}")
|
||||
public Annotation get(@PathVariable("id") UUID id, FieldSet fieldSet) throws MyApplicationException, MyForbiddenException, MyNotFoundException {
|
||||
logger.debug(new MapLogEntry("retrieving" + Annotation.class.getSimpleName()).And("id", id).And("fields", fieldSet));
|
||||
|
||||
this.censorFactory.censor(AnnotationCensor.class).censor(fieldSet, null);
|
||||
|
||||
AnnotationQuery query = this.queryFactory.query(AnnotationQuery.class).ids(id);
|
||||
Annotation model = this.builderFactory.builder(AnnotationBuilder.class).build(fieldSet, query.firstAs(fieldSet));
|
||||
if (model == null)
|
||||
throw new MyNotFoundException(messageSource.getMessage("General_ItemNotFound", new Object[]{id, Annotation.class.getSimpleName()}, LocaleContextHolder.getLocale()));
|
||||
|
||||
this.auditService.track(AuditableAction.Annotation_Lookup, Map.ofEntries(
|
||||
new AbstractMap.SimpleEntry<String, Object>("id", id),
|
||||
new AbstractMap.SimpleEntry<String, Object>("fields", fieldSet)
|
||||
));
|
||||
|
||||
return model;
|
||||
}
|
||||
|
||||
@PostMapping("persist")
|
||||
@Transactional
|
||||
@ValidationFilterAnnotation(validator = AnnotationPersist.AnnotationPersistValidator.ValidatorName, argumentName = "model")
|
||||
public Annotation persist(@RequestBody AnnotationPersist model, FieldSet fieldSet) throws MyApplicationException, MyForbiddenException, MyNotFoundException, InvalidApplicationException, JAXBException, ParserConfigurationException, JsonProcessingException, TransformerException {
|
||||
logger.debug(new MapLogEntry("persisting" + Annotation.class.getSimpleName()).And("model", model).And("fieldSet", fieldSet));
|
||||
|
||||
this.censorFactory.censor(AnnotationCensor.class).censor(fieldSet, null);
|
||||
|
||||
Annotation persisted = this.annotationService.persist(model, fieldSet);
|
||||
|
||||
this.auditService.track(AuditableAction.Annotation_Persist, Map.ofEntries(
|
||||
new AbstractMap.SimpleEntry<String, Object>("model", model),
|
||||
new AbstractMap.SimpleEntry<String, Object>("fields", fieldSet)
|
||||
));
|
||||
|
||||
return persisted;
|
||||
}
|
||||
|
||||
@DeleteMapping("{id}")
|
||||
@Transactional
|
||||
public void delete(@PathVariable("id") UUID id) throws MyForbiddenException, InvalidApplicationException {
|
||||
logger.debug(new MapLogEntry("retrieving" + Annotation.class.getSimpleName()).And("id", id));
|
||||
|
||||
this.annotationService.deleteAndSave(id);
|
||||
|
||||
this.auditService.track(AuditableAction.Annotation_Delete, "id", id);
|
||||
}
|
||||
|
||||
}
|
|
@ -1,91 +0,0 @@
|
|||
package gr.cite.annotation.web.controllers;
|
||||
|
||||
import gr.cite.commons.web.oidc.principal.CurrentPrincipalResolver;
|
||||
import gr.cite.commons.web.oidc.principal.MyPrincipal;
|
||||
import gr.cite.commons.web.oidc.principal.extractor.ClaimExtractor;
|
||||
import gr.cite.annotation.audit.AuditableAction;
|
||||
import gr.cite.annotation.common.scope.tenant.TenantScope;
|
||||
import gr.cite.annotation.web.model.Account;
|
||||
import gr.cite.annotation.web.model.AccountBuilder;
|
||||
import gr.cite.tools.auditing.AuditService;
|
||||
import gr.cite.tools.fieldset.BaseFieldSet;
|
||||
import gr.cite.tools.fieldset.FieldSet;
|
||||
import gr.cite.tools.logging.LoggerService;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@RestController
|
||||
@RequestMapping(path = "api/principal", produces = MediaType.APPLICATION_JSON_VALUE)
|
||||
public class PrincipalController {
|
||||
private static final LoggerService logger = new LoggerService(LoggerFactory.getLogger(PrincipalController.class));
|
||||
private final AuditService auditService;
|
||||
|
||||
private final CurrentPrincipalResolver currentPrincipalResolver;
|
||||
private final AccountBuilder accountBuilder;
|
||||
private final ClaimExtractor claimExtractor;
|
||||
|
||||
@Autowired
|
||||
public PrincipalController(
|
||||
CurrentPrincipalResolver currentPrincipalResolver,
|
||||
AccountBuilder accountBuilder,
|
||||
AuditService auditService,
|
||||
ClaimExtractor claimExtractor) {
|
||||
this.currentPrincipalResolver = currentPrincipalResolver;
|
||||
this.accountBuilder = accountBuilder;
|
||||
this.auditService = auditService;
|
||||
this.claimExtractor = claimExtractor;
|
||||
}
|
||||
|
||||
@GetMapping("me")
|
||||
public Account me(FieldSet fieldSet) {
|
||||
logger.debug("me");
|
||||
|
||||
|
||||
if (fieldSet == null || fieldSet.isEmpty()) {
|
||||
fieldSet = new BaseFieldSet(
|
||||
Account._isAuthenticated,
|
||||
BaseFieldSet.asIndexer(Account._principal, Account.PrincipalInfo._subject),
|
||||
BaseFieldSet.asIndexer(Account._principal, Account.PrincipalInfo._userId),
|
||||
BaseFieldSet.asIndexer(Account._principal, Account.PrincipalInfo._name),
|
||||
BaseFieldSet.asIndexer(Account._principal, Account.PrincipalInfo._scope),
|
||||
BaseFieldSet.asIndexer(Account._principal, Account.PrincipalInfo._client),
|
||||
BaseFieldSet.asIndexer(Account._principal, Account.PrincipalInfo._issuedAt),
|
||||
BaseFieldSet.asIndexer(Account._principal, Account.PrincipalInfo._notBefore),
|
||||
BaseFieldSet.asIndexer(Account._principal, Account.PrincipalInfo._authenticatedAt),
|
||||
BaseFieldSet.asIndexer(Account._principal, Account.PrincipalInfo._expiresAt),
|
||||
BaseFieldSet.asIndexer(Account._principal, Account.PrincipalInfo._more),
|
||||
Account._permissions);
|
||||
}
|
||||
|
||||
MyPrincipal principal = this.currentPrincipalResolver.currentPrincipal();
|
||||
|
||||
Account me = this.accountBuilder.build(fieldSet, principal);
|
||||
|
||||
this.auditService.track(AuditableAction.Principal_Lookup);
|
||||
//auditService.trackIdentity(AuditableAction.IdentityTracking_Action);
|
||||
|
||||
return me;
|
||||
|
||||
}
|
||||
|
||||
@GetMapping("my-tenants")
|
||||
public List<String> myTenants() {
|
||||
logger.debug("my-tenants");
|
||||
|
||||
MyPrincipal principal = this.currentPrincipalResolver.currentPrincipal();
|
||||
List<String> tenants = this.claimExtractor.asStrings(principal, TenantScope.TenantCodesClaimName);
|
||||
|
||||
this.auditService.track(AuditableAction.Tenants_Lookup);
|
||||
//auditService.trackIdentity(AuditableAction.IdentityTracking_Action);
|
||||
|
||||
return tenants == null ? null : tenants.stream().distinct().collect(Collectors.toList());
|
||||
}
|
||||
|
||||
}
|
|
@ -1,129 +0,0 @@
|
|||
package gr.cite.annotation.web.controllers;
|
||||
|
||||
import gr.cite.annotation.audit.AuditableAction;
|
||||
import gr.cite.annotation.authorization.AuthorizationFlags;
|
||||
import gr.cite.annotation.common.enums.TenantConfigurationType;
|
||||
import gr.cite.annotation.data.TenantConfigurationEntity;
|
||||
import gr.cite.annotation.model.TenantConfiguration;
|
||||
import gr.cite.annotation.model.builder.TenantConfigurationBuilder;
|
||||
import gr.cite.annotation.model.censorship.TenantConfigurationCensor;
|
||||
import gr.cite.annotation.model.persist.tenantconfiguration.TenantConfigurationEmailClientPersist;
|
||||
import gr.cite.annotation.query.TenantConfigurationQuery;
|
||||
import gr.cite.annotation.query.lookup.TenantConfigurationLookup;
|
||||
import gr.cite.annotation.service.tenantconfiguration.TenantConfigurationService;
|
||||
import gr.cite.annotation.web.model.QueryResult;
|
||||
import gr.cite.tools.auditing.AuditService;
|
||||
import gr.cite.tools.data.builder.BuilderFactory;
|
||||
import gr.cite.tools.data.censor.CensorFactory;
|
||||
import gr.cite.tools.data.query.QueryFactory;
|
||||
import gr.cite.tools.exception.MyApplicationException;
|
||||
import gr.cite.tools.exception.MyForbiddenException;
|
||||
import gr.cite.tools.exception.MyNotFoundException;
|
||||
import gr.cite.tools.fieldset.FieldSet;
|
||||
import gr.cite.tools.logging.LoggerService;
|
||||
import gr.cite.tools.logging.MapLogEntry;
|
||||
import gr.cite.tools.validation.ValidationFilterAnnotation;
|
||||
import jakarta.transaction.Transactional;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.MessageSource;
|
||||
import org.springframework.context.i18n.LocaleContextHolder;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.management.InvalidApplicationException;
|
||||
import java.util.*;
|
||||
|
||||
@RestController
|
||||
@RequestMapping(path = "api/notification/tenant-configuration")
|
||||
public class TenantConfigurationController {
|
||||
private static final LoggerService logger = new LoggerService(LoggerFactory.getLogger(TenantConfigurationController.class));
|
||||
|
||||
private final BuilderFactory builderFactory;
|
||||
private final AuditService auditService;
|
||||
private final TenantConfigurationService tenantConfigurationService;
|
||||
private final CensorFactory censorFactory;
|
||||
private final QueryFactory queryFactory;
|
||||
private final MessageSource messageSource;
|
||||
|
||||
@Autowired
|
||||
public TenantConfigurationController(BuilderFactory builderFactory,
|
||||
AuditService auditService,
|
||||
TenantConfigurationService tenantConfigurationService, CensorFactory censorFactory,
|
||||
QueryFactory queryFactory,
|
||||
MessageSource messageSource) {
|
||||
this.builderFactory = builderFactory;
|
||||
this.auditService = auditService;
|
||||
this.tenantConfigurationService = tenantConfigurationService;
|
||||
this.censorFactory = censorFactory;
|
||||
this.queryFactory = queryFactory;
|
||||
this.messageSource = messageSource;
|
||||
}
|
||||
|
||||
@PostMapping("query")
|
||||
public QueryResult<TenantConfiguration> query(@RequestBody TenantConfigurationLookup lookup) throws MyApplicationException, MyForbiddenException {
|
||||
logger.debug("querying {}", TenantConfiguration.class.getSimpleName());
|
||||
|
||||
this.censorFactory.censor(TenantConfigurationCensor.class).censor(lookup.getProject());
|
||||
|
||||
TenantConfigurationQuery query = lookup.enrich(this.queryFactory);
|
||||
List<TenantConfigurationEntity> data = query.collectAs(lookup.getProject());
|
||||
List<TenantConfiguration> models = this.builderFactory.builder(TenantConfigurationBuilder.class).authorize(AuthorizationFlags.OwnerOrPermission).build(lookup.getProject(), data);
|
||||
long count = (lookup.getMetadata() != null && lookup.getMetadata().getCountAll()) ? query.count() : models.size();
|
||||
|
||||
this.auditService.track(AuditableAction.Tenant_Configuration_Query, "lookup", lookup);
|
||||
|
||||
return new QueryResult<>(models, count);
|
||||
}
|
||||
|
||||
@GetMapping("{id}")
|
||||
@Transactional
|
||||
public TenantConfiguration get(@PathVariable UUID id, FieldSet fieldSet, Locale locale) throws MyApplicationException, MyForbiddenException, MyNotFoundException {
|
||||
logger.debug(new MapLogEntry("retrieving" + TenantConfiguration.class.getSimpleName()).And("id", id).And("fields", fieldSet));
|
||||
|
||||
this.censorFactory.censor(TenantConfigurationCensor.class).censor(fieldSet);
|
||||
|
||||
TenantConfigurationQuery query = this.queryFactory.query(TenantConfigurationQuery.class).ids(id);
|
||||
TenantConfiguration model = this.builderFactory.builder(TenantConfigurationBuilder.class).authorize(AuthorizationFlags.OwnerOrPermission).build(fieldSet, query.firstAs(fieldSet));
|
||||
if (model == null)
|
||||
throw new MyNotFoundException(messageSource.getMessage("General_ItemNotFound", new Object[]{id, TenantConfiguration.class.getSimpleName()}, LocaleContextHolder.getLocale()));
|
||||
|
||||
this.auditService.track(AuditableAction.Tenant_Configuration_Lookup, Map.ofEntries(
|
||||
new AbstractMap.SimpleEntry<String, Object>("id", id),
|
||||
new AbstractMap.SimpleEntry<String, Object>("fields", fieldSet)
|
||||
));
|
||||
//this.auditService.trackIdentity(AuditableAction.IdentityTracking_Action);
|
||||
|
||||
return model;
|
||||
}
|
||||
|
||||
@PostMapping("persist/email-client")
|
||||
@Transactional
|
||||
@ValidationFilterAnnotation(validator = TenantConfigurationEmailClientPersist.TenantConfigurationEmailClientPersistValidator.ValidatorName, argumentName = "model")
|
||||
public TenantConfiguration persist(@RequestBody TenantConfigurationEmailClientPersist model, FieldSet fieldSet)
|
||||
{
|
||||
logger.debug(new MapLogEntry("persisting").And("type", TenantConfigurationType.EMAIL_CLIENT_CONFIGURATION).And("model", model).And("fields", fieldSet));
|
||||
|
||||
TenantConfiguration persisted = this.tenantConfigurationService.persist(model, fieldSet);
|
||||
|
||||
this.auditService.track(AuditableAction.Tenant_Configuration_Persist, Map.of(
|
||||
"type", TenantConfigurationType.EMAIL_CLIENT_CONFIGURATION,
|
||||
"model", model,
|
||||
"fields", fieldSet
|
||||
));
|
||||
//this._auditService.TrackIdentity(AuditableAction.IdentityTracking_Action);
|
||||
|
||||
return persisted;
|
||||
}
|
||||
|
||||
@DeleteMapping("{id}")
|
||||
@Transactional
|
||||
public void delete(@PathVariable("id") UUID id) throws MyForbiddenException, InvalidApplicationException {
|
||||
logger.debug(new MapLogEntry("deleting" + TenantConfiguration.class.getSimpleName()).And("id", id));
|
||||
|
||||
this.tenantConfigurationService.deleteAndSave(id);
|
||||
|
||||
this.auditService.track(AuditableAction.Tenant_Configuration_Delete, "id", id);
|
||||
|
||||
//this.auditService.trackIdentity(AuditableAction.IdentityTracking_Action);
|
||||
}
|
||||
}
|
|
@ -1,17 +0,0 @@
|
|||
//package gr.cite.intelcomp.stiviewer.web.controllers.error;
|
||||
//
|
||||
//import gr.cite.tools.exception.MyValidationException;
|
||||
//import org.springframework.http.HttpStatus;
|
||||
//import org.springframework.http.ResponseEntity;
|
||||
//import org.springframework.web.bind.annotation.ControllerAdvice;
|
||||
//import org.springframework.web.bind.annotation.ExceptionHandler;
|
||||
//import org.springframework.web.context.request.WebRequest;
|
||||
//
|
||||
//@ControllerAdvice
|
||||
//public class GenericErrorHandler {
|
||||
//
|
||||
// @ExceptionHandler(MyValidationException.class)
|
||||
// public ResponseEntity<MyValidationException> handleValidationException(MyValidationException e, WebRequest webRequest) {
|
||||
// return ResponseEntity.status(HttpStatus.NOT_ACCEPTABLE).body(e);
|
||||
// }
|
||||
//}
|
|
@ -1,101 +0,0 @@
|
|||
package gr.cite.annotation.web.interceptors;
|
||||
|
||||
import gr.cite.commons.web.oidc.principal.CurrentPrincipalResolver;
|
||||
import gr.cite.commons.web.oidc.principal.extractor.ClaimExtractor;
|
||||
import gr.cite.annotation.common.JsonHandlingService;
|
||||
import gr.cite.annotation.common.lock.LockByKeyManager;
|
||||
import gr.cite.annotation.common.scope.user.UserScope;
|
||||
import gr.cite.annotation.data.UserCredentialEntity;
|
||||
import gr.cite.annotation.model.UserCredential;
|
||||
import gr.cite.annotation.query.UserCredentialQuery;
|
||||
import gr.cite.tools.data.query.QueryFactory;
|
||||
import gr.cite.tools.exception.MyForbiddenException;
|
||||
import gr.cite.tools.fieldset.BaseFieldSet;
|
||||
import gr.cite.tools.logging.LoggerService;
|
||||
import jakarta.persistence.EntityManager;
|
||||
import jakarta.persistence.PersistenceContext;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.lang.NonNull;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.transaction.PlatformTransactionManager;
|
||||
import org.springframework.ui.ModelMap;
|
||||
import org.springframework.web.context.request.WebRequest;
|
||||
import org.springframework.web.context.request.WebRequestInterceptor;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
@Component
|
||||
public class UserInterceptor implements WebRequestInterceptor {
|
||||
private static final LoggerService logger = new LoggerService(LoggerFactory.getLogger(UserInterceptor.class));
|
||||
private final UserScope userScope;
|
||||
private final ClaimExtractor claimExtractor;
|
||||
private final CurrentPrincipalResolver currentPrincipalResolver;
|
||||
private final PlatformTransactionManager transactionManager;
|
||||
private final UserInterceptorCacheService userInterceptorCacheService;
|
||||
private final JsonHandlingService jsonHandlingService;
|
||||
private final QueryFactory queryFactory;
|
||||
private final LockByKeyManager lockByKeyManager;
|
||||
@PersistenceContext
|
||||
public EntityManager entityManager;
|
||||
|
||||
@Autowired
|
||||
public UserInterceptor(
|
||||
UserScope userScope,
|
||||
ClaimExtractor claimExtractor,
|
||||
CurrentPrincipalResolver currentPrincipalResolver,
|
||||
PlatformTransactionManager transactionManager,
|
||||
UserInterceptorCacheService userInterceptorCacheService,
|
||||
JsonHandlingService jsonHandlingService,
|
||||
QueryFactory queryFactory,
|
||||
LockByKeyManager lockByKeyManager) {
|
||||
this.userScope = userScope;
|
||||
this.currentPrincipalResolver = currentPrincipalResolver;
|
||||
this.claimExtractor = claimExtractor;
|
||||
this.transactionManager = transactionManager;
|
||||
this.userInterceptorCacheService = userInterceptorCacheService;
|
||||
this.jsonHandlingService = jsonHandlingService;
|
||||
this.queryFactory = queryFactory;
|
||||
this.lockByKeyManager = lockByKeyManager;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void preHandle(WebRequest request) {
|
||||
UUID userId = null;
|
||||
if (this.currentPrincipalResolver.currentPrincipal().isAuthenticated()) {
|
||||
String subjectId = this.claimExtractor.subjectString(this.currentPrincipalResolver.currentPrincipal());
|
||||
if (subjectId == null || subjectId.isBlank()) throw new MyForbiddenException("Empty subjects not allowed");
|
||||
|
||||
UserInterceptorCacheService.UserInterceptorCacheValue cacheValue = this.userInterceptorCacheService.lookup(this.userInterceptorCacheService.buildKey(subjectId));
|
||||
if (cacheValue != null) {
|
||||
userId = cacheValue.getUserId();
|
||||
} else {
|
||||
userId = this.findExistingUserFromDbForce(subjectId);
|
||||
|
||||
cacheValue = new UserInterceptorCacheService.UserInterceptorCacheValue(subjectId, userId);
|
||||
|
||||
this.userInterceptorCacheService.put(cacheValue);
|
||||
}
|
||||
}
|
||||
this.userScope.setUserId(userId);
|
||||
}
|
||||
|
||||
private UUID findExistingUserFromDbForce(String subjectId){
|
||||
UserCredentialEntity userCredential = this.queryFactory.query(UserCredentialQuery.class).externalIds(subjectId).firstAs(new BaseFieldSet().ensure(UserCredential._user));
|
||||
if (userCredential != null) {
|
||||
return userCredential.getUserId();
|
||||
} else {
|
||||
throw new MyForbiddenException("User not created try again.");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void postHandle(@NonNull WebRequest request, ModelMap model) {
|
||||
this.userScope.setUserId(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterCompletion(@NonNull WebRequest request, Exception ex) {
|
||||
}
|
||||
}
|
||||
|
|
@ -1,10 +0,0 @@
|
|||
package gr.cite.annotation.web.interceptors;
|
||||
|
||||
import gr.cite.tools.cache.CacheOptions;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
@Configuration
|
||||
@ConfigurationProperties(prefix = "cache.user-by-subject-id")
|
||||
public class UserInterceptorCacheOptions extends CacheOptions {
|
||||
}
|
|
@ -1,66 +0,0 @@
|
|||
package gr.cite.annotation.web.interceptors;
|
||||
|
||||
import gr.cite.tools.cache.CacheService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.UUID;
|
||||
|
||||
@Service
|
||||
public class UserInterceptorCacheService extends CacheService<UserInterceptorCacheService.UserInterceptorCacheValue> {
|
||||
|
||||
public static class UserInterceptorCacheValue {
|
||||
|
||||
public UserInterceptorCacheValue() {
|
||||
}
|
||||
|
||||
public UserInterceptorCacheValue(String subjectId, UUID userId) {
|
||||
this.subjectId = subjectId;
|
||||
this.userId = userId;
|
||||
}
|
||||
|
||||
private String subjectId;
|
||||
|
||||
public String getSubjectId() {
|
||||
return subjectId;
|
||||
}
|
||||
|
||||
public void setSubjectId(String subjectId) {
|
||||
this.subjectId = subjectId;
|
||||
}
|
||||
|
||||
private UUID userId;
|
||||
public UUID getUserId() {
|
||||
return userId;
|
||||
}
|
||||
|
||||
public void setUserId(UUID userId) {
|
||||
this.userId = userId;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Autowired
|
||||
public UserInterceptorCacheService(UserInterceptorCacheOptions options) {
|
||||
super(options);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Class<UserInterceptorCacheValue> valueClass() {
|
||||
return UserInterceptorCacheValue.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String keyOf(UserInterceptorCacheValue value) {
|
||||
return this.buildKey(value.getSubjectId());
|
||||
}
|
||||
|
||||
|
||||
public String buildKey(String subject) {
|
||||
HashMap<String, String> keyParts = new HashMap<>();
|
||||
keyParts.put("$subject$", subject);
|
||||
return this.generateKey(keyParts);
|
||||
}
|
||||
}
|
|
@ -1,160 +0,0 @@
|
|||
package gr.cite.annotation.web.model;
|
||||
|
||||
import gr.cite.tools.logging.annotation.LogSensitive;
|
||||
|
||||
import java.time.Instant;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
public class Account {
|
||||
|
||||
public static class PrincipalInfo {
|
||||
|
||||
public static final String _userId = "userId";
|
||||
public UUID userId;
|
||||
|
||||
public UUID getUserId() {
|
||||
return userId;
|
||||
}
|
||||
|
||||
public void setUserId(UUID userId) {
|
||||
this.userId = userId;
|
||||
}
|
||||
|
||||
public static final String _subject = "subject";
|
||||
public UUID subject;
|
||||
|
||||
public UUID getSubject() {
|
||||
return subject;
|
||||
}
|
||||
|
||||
public void setSubject(UUID subject) {
|
||||
this.subject = subject;
|
||||
}
|
||||
|
||||
public static final String _name = "name";
|
||||
@LogSensitive
|
||||
public String name;
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public static final String _scope = "scope";
|
||||
public List<String> scope;
|
||||
|
||||
public List<String> getScope() {
|
||||
return scope;
|
||||
}
|
||||
|
||||
public void setScope(List<String> scope) {
|
||||
this.scope = scope;
|
||||
}
|
||||
|
||||
public static final String _client = "client";
|
||||
public String client;
|
||||
|
||||
public String getClient() {
|
||||
return client;
|
||||
}
|
||||
|
||||
public void setClient(String client) {
|
||||
this.client = client;
|
||||
}
|
||||
|
||||
public static final String _notBefore = "notBefore";
|
||||
public Instant notBefore;
|
||||
|
||||
public Instant getNotBefore() {
|
||||
return notBefore;
|
||||
}
|
||||
|
||||
public void setNotBefore(Instant notBefore) {
|
||||
this.notBefore = notBefore;
|
||||
}
|
||||
|
||||
public static final String _issuedAt = "issuedAt";
|
||||
public Instant issuedAt;
|
||||
|
||||
public Instant getIssuedAt() {
|
||||
return issuedAt;
|
||||
}
|
||||
|
||||
public void setIssuedAt(Instant issuedAt) {
|
||||
this.issuedAt = issuedAt;
|
||||
}
|
||||
|
||||
public static final String _authenticatedAt = "authenticatedAt";
|
||||
public Instant authenticatedAt;
|
||||
|
||||
public Instant getAuthenticatedAt() {
|
||||
return authenticatedAt;
|
||||
}
|
||||
|
||||
public void setAuthenticatedAt(Instant authenticatedAt) {
|
||||
this.authenticatedAt = authenticatedAt;
|
||||
}
|
||||
|
||||
public static final String _expiresAt = "expiresAt";
|
||||
public Instant expiresAt;
|
||||
|
||||
public Instant getExpiresAt() {
|
||||
return expiresAt;
|
||||
}
|
||||
|
||||
public void setExpiresAt(Instant expiresAt) {
|
||||
this.expiresAt = expiresAt;
|
||||
}
|
||||
|
||||
public static final String _more = "more";
|
||||
@LogSensitive
|
||||
public Map<String, List<String>> more;
|
||||
|
||||
public Map<String, List<String>> getMore() {
|
||||
return more;
|
||||
}
|
||||
|
||||
public void setMore(Map<String, List<String>> more) {
|
||||
this.more = more;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static final String _isAuthenticated = "isAuthenticated";
|
||||
private Boolean isAuthenticated;
|
||||
|
||||
public Boolean getIsAuthenticated() {
|
||||
return isAuthenticated;
|
||||
}
|
||||
|
||||
public void setIsAuthenticated(Boolean authenticated) {
|
||||
isAuthenticated = authenticated;
|
||||
}
|
||||
|
||||
public static final String _principal = "principal";
|
||||
private PrincipalInfo principal;
|
||||
|
||||
public PrincipalInfo getPrincipal() {
|
||||
return principal;
|
||||
}
|
||||
|
||||
public void setPrincipal(PrincipalInfo principal) {
|
||||
this.principal = principal;
|
||||
}
|
||||
|
||||
public static final String _permissions = "permissions";
|
||||
private List<String> permissions;
|
||||
|
||||
public List<String> getPermissions() {
|
||||
return permissions;
|
||||
}
|
||||
|
||||
public void setPermissions(List<String> permissions) {
|
||||
this.permissions = permissions;
|
||||
}
|
||||
}
|
|
@ -1,83 +0,0 @@
|
|||
package gr.cite.annotation.web.model;
|
||||
|
||||
import gr.cite.commons.web.authz.configuration.AuthorizationConfiguration;
|
||||
import gr.cite.commons.web.oidc.principal.CurrentPrincipalResolver;
|
||||
import gr.cite.commons.web.oidc.principal.MyPrincipal;
|
||||
import gr.cite.commons.web.oidc.principal.extractor.ClaimExtractor;
|
||||
import gr.cite.commons.web.oidc.principal.extractor.ClaimExtractorKeys;
|
||||
import gr.cite.annotation.common.scope.user.UserScope;
|
||||
import gr.cite.tools.fieldset.BaseFieldSet;
|
||||
import gr.cite.tools.fieldset.FieldSet;
|
||||
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
|
||||
import org.springframework.context.annotation.Scope;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
@Component
|
||||
@Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE)
|
||||
public class AccountBuilder {
|
||||
|
||||
private final ClaimExtractor claimExtractor;
|
||||
private final Set<String> excludeMoreClaim;
|
||||
private final AuthorizationConfiguration authorizationConfiguration;
|
||||
private final CurrentPrincipalResolver currentPrincipalResolver;
|
||||
private final UserScope userScope;
|
||||
|
||||
public AccountBuilder(ClaimExtractor claimExtractor, AuthorizationConfiguration authorizationConfiguration, CurrentPrincipalResolver currentPrincipalResolver, UserScope userScope) {
|
||||
this.claimExtractor = claimExtractor;
|
||||
this.authorizationConfiguration = authorizationConfiguration;
|
||||
this.currentPrincipalResolver = currentPrincipalResolver;
|
||||
this.userScope = userScope;
|
||||
this.excludeMoreClaim = Set.of(
|
||||
ClaimExtractorKeys.Subject,
|
||||
ClaimExtractorKeys.Name,
|
||||
ClaimExtractorKeys.Scope,
|
||||
ClaimExtractorKeys.Client,
|
||||
ClaimExtractorKeys.IssuedAt,
|
||||
ClaimExtractorKeys.NotBefore,
|
||||
ClaimExtractorKeys.AuthenticatedAt,
|
||||
ClaimExtractorKeys.ExpiresAt);
|
||||
}
|
||||
|
||||
public Account build(FieldSet fields, MyPrincipal principal) {
|
||||
Account model = new Account();
|
||||
if (principal == null || !principal.isAuthenticated()) {
|
||||
model.setIsAuthenticated(false);
|
||||
return model;
|
||||
}
|
||||
model.setIsAuthenticated(true);
|
||||
|
||||
FieldSet principalFields = fields.extractPrefixed(BaseFieldSet.asIndexerPrefix(Account._principal));
|
||||
if (!principalFields.isEmpty()) model.setPrincipal(new Account.PrincipalInfo());
|
||||
if (principalFields.hasField(Account.PrincipalInfo._subject)) model.getPrincipal().setSubject(this.claimExtractor.subjectUUID(principal));
|
||||
if (principalFields.hasField(Account.PrincipalInfo._userId)) model.getPrincipal().setUserId(this.userScope.getUserIdSafe());
|
||||
if (principalFields.hasField(Account.PrincipalInfo._name)) model.getPrincipal().setName(this.claimExtractor.name(principal));
|
||||
if (principalFields.hasField(Account.PrincipalInfo._scope)) model.getPrincipal().setScope(this.claimExtractor.scope(principal));
|
||||
if (principalFields.hasField(Account.PrincipalInfo._client)) model.getPrincipal().setClient(this.claimExtractor.client(principal));
|
||||
if (principalFields.hasField(Account.PrincipalInfo._issuedAt)) model.getPrincipal().setIssuedAt(this.claimExtractor.issuedAt(principal));
|
||||
if (principalFields.hasField(Account.PrincipalInfo._notBefore)) model.getPrincipal().setNotBefore(this.claimExtractor.notBefore(principal));
|
||||
if (principalFields.hasField(Account.PrincipalInfo._authenticatedAt)) model.getPrincipal().setAuthenticatedAt(this.claimExtractor.authenticatedAt(principal));
|
||||
if (principalFields.hasField(Account.PrincipalInfo._expiresAt)) model.getPrincipal().setExpiresAt(this.claimExtractor.expiresAt(principal));
|
||||
if (principalFields.hasField(Account.PrincipalInfo._more)) {
|
||||
model.getPrincipal().setMore(new HashMap<>());
|
||||
for (String key : this.claimExtractor.knownPublicKeys()) {
|
||||
if (this.excludeMoreClaim.contains(key)) continue;
|
||||
List<String> values = this.claimExtractor.asStrings(principal, key);
|
||||
if (values == null || values.size() == 0) continue;
|
||||
if (!model.getPrincipal().getMore().containsKey(key)) model.getPrincipal().getMore().put(key, new ArrayList<>());
|
||||
model.getPrincipal().getMore().get(key).addAll(values);
|
||||
}
|
||||
}
|
||||
|
||||
if (fields.hasField(Account._permissions)) {
|
||||
List<String> roles = claimExtractor.roles(currentPrincipalResolver.currentPrincipal());
|
||||
Set<String> permissions = authorizationConfiguration.permissionsOfRoles(roles);
|
||||
model.setPermissions(new ArrayList<>(permissions));
|
||||
}
|
||||
return model;
|
||||
}
|
||||
}
|
|
@ -1,37 +0,0 @@
|
|||
package gr.cite.annotation.web.model;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class QueryResult<M> {
|
||||
public QueryResult() { }
|
||||
public QueryResult(List<M> items, long count)
|
||||
{
|
||||
this.items = items;
|
||||
this.count = count;
|
||||
}
|
||||
|
||||
public List<M> items;
|
||||
public long count;
|
||||
|
||||
public List<M> getItems() {
|
||||
return items;
|
||||
}
|
||||
|
||||
public void setItems(List<M> items) {
|
||||
this.items = items;
|
||||
}
|
||||
|
||||
public long getCount() {
|
||||
return count;
|
||||
}
|
||||
|
||||
public void setCount(long count) {
|
||||
this.count = count;
|
||||
}
|
||||
|
||||
public static QueryResult<?> Empty()
|
||||
{
|
||||
return new QueryResult<>(new ArrayList<>(), 0L);
|
||||
}
|
||||
}
|
|
@ -1,10 +0,0 @@
|
|||
package gr.cite.annotation.web.scope.tenant;
|
||||
|
||||
import gr.cite.tools.cache.CacheOptions;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
@Configuration
|
||||
@ConfigurationProperties(prefix = "cache.tenant-by-code")
|
||||
public class TenantByCodeCacheOptions extends CacheOptions {
|
||||
}
|
|
@ -1,76 +0,0 @@
|
|||
package gr.cite.annotation.web.scope.tenant;
|
||||
|
||||
import gr.cite.annotation.convention.ConventionService;
|
||||
import gr.cite.annotation.event.TenantTouchedEvent;
|
||||
import gr.cite.tools.cache.CacheService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.event.EventListener;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.UUID;
|
||||
|
||||
@Service
|
||||
public class TenantByCodeCacheService extends CacheService<TenantByCodeCacheService.TenantByCodeCacheValue> {
|
||||
|
||||
public static class TenantByCodeCacheValue {
|
||||
|
||||
public TenantByCodeCacheValue() {
|
||||
}
|
||||
|
||||
public TenantByCodeCacheValue(String tenantCode, UUID tenantId) {
|
||||
this.tenantCode = tenantCode;
|
||||
this.tenantId = tenantId;
|
||||
}
|
||||
|
||||
private String tenantCode;
|
||||
|
||||
public String getTenantCode() {
|
||||
return tenantCode;
|
||||
}
|
||||
|
||||
public void setTenantCode(String tenantCode) {
|
||||
this.tenantCode = tenantCode;
|
||||
}
|
||||
|
||||
private UUID tenantId;
|
||||
|
||||
public UUID getTenantId() {
|
||||
return tenantId;
|
||||
}
|
||||
|
||||
public void setTenantId(UUID tenantId) {
|
||||
this.tenantId = tenantId;
|
||||
}
|
||||
}
|
||||
|
||||
private final ConventionService conventionService;
|
||||
|
||||
@Autowired
|
||||
public TenantByCodeCacheService(TenantByCodeCacheOptions options, ConventionService conventionService) {
|
||||
super(options);
|
||||
this.conventionService = conventionService;
|
||||
}
|
||||
|
||||
@EventListener
|
||||
public void handleTenantTouchedEvent(TenantTouchedEvent event) {
|
||||
if (!this.conventionService.isNullOrEmpty(event.getTenantCode())) this.evict(this.buildKey(event.getTenantCode()));
|
||||
if (!this.conventionService.isNullOrEmpty(event.getPreviousTenantCode())) this.evict(this.buildKey(event.getPreviousTenantCode()));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Class<TenantByCodeCacheValue> valueClass() {
|
||||
return TenantByCodeCacheValue.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String keyOf(TenantByCodeCacheValue value) {
|
||||
return this.buildKey(value.getTenantCode());
|
||||
}
|
||||
|
||||
public String buildKey(String code) {
|
||||
return this.generateKey(new HashMap<>() {{
|
||||
put("$code$", code);
|
||||
}});
|
||||
}
|
||||
}
|
|
@ -1,10 +0,0 @@
|
|||
package gr.cite.annotation.web.scope.tenant;
|
||||
|
||||
import gr.cite.tools.cache.CacheOptions;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
@Configuration
|
||||
@ConfigurationProperties(prefix = "cache.tenant-by-id")
|
||||
public class TenantByIdCacheOptions extends CacheOptions {
|
||||
}
|
|
@ -1,76 +0,0 @@
|
|||
package gr.cite.annotation.web.scope.tenant;
|
||||
|
||||
import gr.cite.annotation.convention.ConventionService;
|
||||
import gr.cite.annotation.event.TenantTouchedEvent;
|
||||
import gr.cite.tools.cache.CacheService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.event.EventListener;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Locale;
|
||||
import java.util.UUID;
|
||||
|
||||
@Service
|
||||
public class TenantByIdCacheService extends CacheService<TenantByIdCacheService.TenantByIdCacheValue> {
|
||||
|
||||
public static class TenantByIdCacheValue {
|
||||
|
||||
public TenantByIdCacheValue() {
|
||||
}
|
||||
|
||||
public TenantByIdCacheValue(String tenantCode, UUID tenantId) {
|
||||
this.tenantCode = tenantCode;
|
||||
this.tenantId = tenantId;
|
||||
}
|
||||
|
||||
private String tenantCode;
|
||||
|
||||
public String getTenantCode() {
|
||||
return tenantCode;
|
||||
}
|
||||
|
||||
public void setTenantCode(String tenantCode) {
|
||||
this.tenantCode = tenantCode;
|
||||
}
|
||||
|
||||
private UUID tenantId;
|
||||
|
||||
public UUID getTenantId() {
|
||||
return tenantId;
|
||||
}
|
||||
|
||||
public void setTenantId(UUID tenantId) {
|
||||
this.tenantId = tenantId;
|
||||
}
|
||||
}
|
||||
|
||||
private final ConventionService conventionService;
|
||||
|
||||
@Autowired
|
||||
public TenantByIdCacheService(TenantByIdCacheOptions options, ConventionService conventionService) {
|
||||
super(options);
|
||||
this.conventionService = conventionService;
|
||||
}
|
||||
|
||||
@EventListener
|
||||
public void handleTenantTouchedEvent(TenantTouchedEvent event) {
|
||||
if (!this.conventionService.isNullOrEmpty(event.getTenantCode())) this.evict(this.buildKey(event.getTenantId()));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Class<TenantByIdCacheValue> valueClass() {
|
||||
return TenantByIdCacheValue.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String keyOf(TenantByIdCacheValue value) {
|
||||
return this.buildKey(value.getTenantId());
|
||||
}
|
||||
|
||||
public String buildKey(UUID id) {
|
||||
return this.generateKey(new HashMap<>() {{
|
||||
put("$tenantId$", id.toString().toLowerCase(Locale.ROOT));
|
||||
}});
|
||||
}
|
||||
}
|
|
@ -1,166 +0,0 @@
|
|||
package gr.cite.annotation.web.scope.tenant;
|
||||
|
||||
import gr.cite.commons.web.authz.service.AuthorizationService;
|
||||
import gr.cite.commons.web.oidc.principal.CurrentPrincipalResolver;
|
||||
import gr.cite.commons.web.oidc.principal.extractor.ClaimExtractor;
|
||||
import gr.cite.annotation.authorization.Permission;
|
||||
import gr.cite.annotation.common.enums.IsActive;
|
||||
import gr.cite.annotation.common.scope.tenant.TenantScope;
|
||||
import gr.cite.annotation.common.scope.user.UserScope;
|
||||
import gr.cite.annotation.data.TenantUserEntity;
|
||||
import gr.cite.annotation.data.UserEntity;
|
||||
import gr.cite.annotation.data.tenant.TenantScopedBaseEntity;
|
||||
import gr.cite.annotation.errorcode.ErrorThesaurusProperties;
|
||||
import gr.cite.tools.exception.MyForbiddenException;
|
||||
import gr.cite.tools.logging.LoggerService;
|
||||
import jakarta.persistence.EntityManager;
|
||||
import jakarta.persistence.PersistenceContext;
|
||||
import jakarta.persistence.Tuple;
|
||||
import jakarta.persistence.criteria.CriteriaBuilder;
|
||||
import jakarta.persistence.criteria.CriteriaQuery;
|
||||
import jakarta.persistence.criteria.Root;
|
||||
import jakarta.persistence.criteria.Subquery;
|
||||
import org.hibernate.Session;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.lang.NonNull;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.ui.ModelMap;
|
||||
import org.springframework.web.context.request.ServletWebRequest;
|
||||
import org.springframework.web.context.request.WebRequest;
|
||||
import org.springframework.web.context.request.WebRequestInterceptor;
|
||||
|
||||
import javax.management.InvalidApplicationException;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
|
||||
@Component
|
||||
public class TenantInterceptor implements WebRequestInterceptor {
|
||||
|
||||
private static final LoggerService logger = new LoggerService(LoggerFactory.getLogger(TenantInterceptor.class));
|
||||
private final TenantScope tenantScope;
|
||||
private final UserScope userScope;
|
||||
private final CurrentPrincipalResolver currentPrincipalResolver;
|
||||
private final ClaimExtractor claimExtractor;
|
||||
private final ApplicationContext applicationContext;
|
||||
private final ErrorThesaurusProperties errorThesaurusProperties;
|
||||
private final TenantScopeProperties tenantScopeProperties;
|
||||
private final UserAllowedTenantCacheService userAllowedTenantCacheService;
|
||||
private final ErrorThesaurusProperties errors;
|
||||
|
||||
@PersistenceContext
|
||||
public EntityManager entityManager;
|
||||
|
||||
@Autowired
|
||||
public TenantInterceptor(
|
||||
TenantScope tenantScope,
|
||||
UserScope userScope,
|
||||
CurrentPrincipalResolver currentPrincipalResolver,
|
||||
ClaimExtractor claimExtractor,
|
||||
ApplicationContext applicationContext,
|
||||
ErrorThesaurusProperties errorThesaurusProperties,
|
||||
TenantScopeProperties tenantScopeProperties,
|
||||
UserAllowedTenantCacheService userAllowedTenantCacheService,
|
||||
ErrorThesaurusProperties errors) {
|
||||
this.tenantScope = tenantScope;
|
||||
this.userScope = userScope;
|
||||
this.currentPrincipalResolver = currentPrincipalResolver;
|
||||
this.claimExtractor = claimExtractor;
|
||||
this.applicationContext = applicationContext;
|
||||
this.errorThesaurusProperties = errorThesaurusProperties;
|
||||
this.tenantScopeProperties = tenantScopeProperties;
|
||||
this.userAllowedTenantCacheService = userAllowedTenantCacheService;
|
||||
this.errors = errors;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void preHandle(WebRequest request) throws InvalidApplicationException {
|
||||
if (!this.currentPrincipalResolver.currentPrincipal().isAuthenticated()) return;
|
||||
if (!this.tenantScope.isMultitenant()) return;
|
||||
|
||||
boolean isAllowedNoTenant = this.applicationContext.getBean(AuthorizationService.class).authorize(Permission.AllowNoTenant);
|
||||
if (tenantScope.isSet() && this.entityManager != null) {
|
||||
List<String> currentPrincipalTenantCodes = this.claimExtractor.asStrings(this.currentPrincipalResolver.currentPrincipal(), TenantScope.TenantCodesClaimName);
|
||||
if ((currentPrincipalTenantCodes == null || !currentPrincipalTenantCodes.contains(tenantScope.getTenantCode())) && !isAllowedNoTenant) {
|
||||
logger.warn("tenant not allowed {}", this.tenantScope.getTenant());
|
||||
//throw new MyForbiddenException(this.errors.getTenantNotAllowed().getCode(), this.errors.getTenantNotAllowed().getMessage());
|
||||
}
|
||||
|
||||
boolean isUserAllowedTenant = false;
|
||||
UserAllowedTenantCacheService.UserAllowedTenantCacheValue cacheValue = this.userAllowedTenantCacheService.lookup(this.userAllowedTenantCacheService.buildKey(this.userScope.getUserId(), this.tenantScope.getTenant()));
|
||||
if (cacheValue != null) {
|
||||
isUserAllowedTenant = cacheValue.isAllowed();
|
||||
} else {
|
||||
isUserAllowedTenant = this.isUserAllowedTenant();
|
||||
this.userAllowedTenantCacheService.put(new UserAllowedTenantCacheService.UserAllowedTenantCacheValue(this.userScope.getUserId(), this.tenantScope.getTenant(), isUserAllowedTenant));
|
||||
}
|
||||
|
||||
if (isUserAllowedTenant) {
|
||||
this.entityManager
|
||||
.unwrap(Session.class)
|
||||
.enableFilter(TenantScopedBaseEntity.tenantFilter).setParameter(TenantScopedBaseEntity.tenantFilterTenantParam, tenantScope.getTenant().toString());
|
||||
} else {
|
||||
if (isAllowedNoTenant || this.isWhiteListedEndpoint(request)) {
|
||||
tenantScope.setTenant(null, null);
|
||||
} else {
|
||||
logger.warn("tenant not allowed {}", this.tenantScope.getTenant());
|
||||
//throw new MyForbiddenException(this.errors.getTenantNotAllowed().getCode(), this.errors.getTenantNotAllowed().getMessage());
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (!isAllowedNoTenant) {
|
||||
if (!this.isWhiteListedEndpoint(request)) {
|
||||
logger.warn("tenant scope not provided");
|
||||
throw new MyForbiddenException(this.errorThesaurusProperties.getMissingTenant().getCode(), this.errorThesaurusProperties.getMissingTenant().getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isWhiteListedEndpoint(WebRequest request) {
|
||||
String servletPath = ((ServletWebRequest) request).getRequest().getServletPath();
|
||||
if (this.tenantScopeProperties.getWhiteListedEndpoints() != null) {
|
||||
for (String whiteListedEndpoint : this.tenantScopeProperties.getWhiteListedEndpoints()) {
|
||||
if (servletPath.toLowerCase(Locale.ROOT).startsWith(whiteListedEndpoint.toLowerCase(Locale.ROOT))) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean isUserAllowedTenant() throws InvalidApplicationException {
|
||||
if (userScope.isSet()) {
|
||||
CriteriaBuilder criteriaBuilder = this.entityManager.getCriteriaBuilder();
|
||||
CriteriaQuery<Tuple> query = criteriaBuilder.createQuery(Tuple.class);
|
||||
Root<UserEntity> root = query.from(UserEntity.class);
|
||||
Subquery<TenantUserEntity> subQuery = query.subquery(TenantUserEntity.class);
|
||||
Root<TenantUserEntity> subQueryRoot = subQuery.from(TenantUserEntity.class);
|
||||
query.where(criteriaBuilder.and(
|
||||
criteriaBuilder.equal(root.get(UserEntity._isActive), IsActive.Active),
|
||||
criteriaBuilder.in(root.get(UserEntity._id)).value(subQuery.where(
|
||||
criteriaBuilder.and(
|
||||
criteriaBuilder.equal(subQueryRoot.get(TenantUserEntity._tenantId), this.tenantScope.getTenant()),
|
||||
criteriaBuilder.equal(subQueryRoot.get(TenantUserEntity._userId), this.userScope.getUserId()),
|
||||
criteriaBuilder.equal(subQueryRoot.get(TenantUserEntity._isActive), IsActive.Active)
|
||||
)).select(subQueryRoot.get(TenantUserEntity._userId)).distinct(true)
|
||||
)
|
||||
));
|
||||
query.multiselect(root.get(UserEntity._id).alias(UserEntity._id));
|
||||
List<Tuple> results = this.entityManager.createQuery(query).getResultList();
|
||||
if (results.size() > 0) return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void postHandle(@NonNull WebRequest request, ModelMap model) {
|
||||
this.tenantScope.setTenant(null, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterCompletion(@NonNull WebRequest request, Exception ex) {
|
||||
}
|
||||
}
|
|
@ -1,196 +0,0 @@
|
|||
package gr.cite.annotation.web.scope.tenant;
|
||||
|
||||
import gr.cite.commons.web.oidc.principal.CurrentPrincipalResolver;
|
||||
import gr.cite.commons.web.oidc.principal.MyPrincipal;
|
||||
import gr.cite.commons.web.oidc.principal.extractor.ClaimExtractor;
|
||||
import gr.cite.commons.web.oidc.principal.extractor.ClaimExtractorContext;
|
||||
import gr.cite.annotation.common.enums.IsActive;
|
||||
import gr.cite.annotation.common.scope.tenant.TenantScope;
|
||||
import gr.cite.annotation.convention.ConventionService;
|
||||
import gr.cite.annotation.data.TenantEntity;
|
||||
import gr.cite.annotation.errorcode.ErrorThesaurusProperties;
|
||||
import gr.cite.tools.exception.MyForbiddenException;
|
||||
import gr.cite.tools.logging.LoggerService;
|
||||
import jakarta.persistence.EntityManager;
|
||||
import jakarta.persistence.PersistenceContext;
|
||||
import jakarta.persistence.Tuple;
|
||||
import jakarta.persistence.criteria.CriteriaBuilder;
|
||||
import jakarta.persistence.criteria.CriteriaQuery;
|
||||
import jakarta.persistence.criteria.Root;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.lang.NonNull;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.ui.ModelMap;
|
||||
import org.springframework.web.context.request.WebRequest;
|
||||
import org.springframework.web.context.request.WebRequestInterceptor;
|
||||
|
||||
import javax.management.InvalidApplicationException;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
@Component
|
||||
public class TenantScopeClaimInterceptor implements WebRequestInterceptor {
|
||||
private static final LoggerService logger = new LoggerService(LoggerFactory.getLogger(TenantScopeClaimInterceptor.class));
|
||||
private final TenantScope tenantScope;
|
||||
private final ConventionService conventionService;
|
||||
private final TenantScopeProperties tenantScopeProperties;
|
||||
private final ErrorThesaurusProperties errorThesaurusProperties;
|
||||
private final ClaimExtractor claimExtractor;
|
||||
private final CurrentPrincipalResolver currentPrincipalResolver;
|
||||
private final String clientTenantClaimName;
|
||||
private final ClaimExtractorContext claimExtractorContext;
|
||||
private final TenantByCodeCacheService tenantByCodeCacheService;
|
||||
private final TenantByIdCacheService tenantByIdCacheService;
|
||||
@PersistenceContext
|
||||
public EntityManager entityManager;
|
||||
|
||||
@Autowired
|
||||
public TenantScopeClaimInterceptor(
|
||||
TenantScope tenantScope,
|
||||
ConventionService conventionService,
|
||||
ClaimExtractor claimExtractor,
|
||||
CurrentPrincipalResolver currentPrincipalResolver,
|
||||
ErrorThesaurusProperties errorThesaurusProperties,
|
||||
TenantScopeProperties tenantScopeProperties,
|
||||
ClaimExtractorContext claimExtractorContext,
|
||||
TenantByCodeCacheService tenantByCodeCacheService,
|
||||
TenantByIdCacheService tenantByIdCacheService
|
||||
) {
|
||||
this.tenantScope = tenantScope;
|
||||
this.conventionService = conventionService;
|
||||
this.currentPrincipalResolver = currentPrincipalResolver;
|
||||
this.claimExtractor = claimExtractor;
|
||||
this.errorThesaurusProperties = errorThesaurusProperties;
|
||||
this.tenantScopeProperties = tenantScopeProperties;
|
||||
this.claimExtractorContext = claimExtractorContext;
|
||||
this.tenantByCodeCacheService = tenantByCodeCacheService;
|
||||
this.tenantByIdCacheService = tenantByIdCacheService;
|
||||
this.clientTenantClaimName = this.tenantScopeProperties.getClientClaimsPrefix() + TenantScope.TenantClaimName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void preHandle(@NotNull WebRequest request) throws InvalidApplicationException {
|
||||
if (!this.currentPrincipalResolver.currentPrincipal().isAuthenticated()) return;
|
||||
if (!this.tenantScope.isMultitenant()) return;
|
||||
|
||||
MyPrincipal principal = this.currentPrincipalResolver.currentPrincipal();
|
||||
if (principal != null && principal.isAuthenticated() /* principal.Claims.Any() */) {
|
||||
Boolean scoped = this.scopeByPrincipal(this.tenantScope, principal);
|
||||
if (!scoped) scoped = this.scopeByClient(this.tenantScope, principal);
|
||||
if (!scoped && this.tenantScope.isSet() && this.tenantScopeProperties.getEnforceTrustedTenant()) throw new MyForbiddenException(this.errorThesaurusProperties.getMissingTenant().getCode(), this.errorThesaurusProperties.getMissingTenant().getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
private Boolean scopeByPrincipal(TenantScope scope, MyPrincipal principal) {
|
||||
String tenantCode = this.claimExtractor.tenantString(principal);
|
||||
if (tenantCode == null || tenantCode.isBlank()) tenantCode = this.claimExtractor.asString(principal, this.clientTenantClaimName);
|
||||
|
||||
UUID tenantId = this.conventionService.parseUUIDSafe(tenantCode);
|
||||
if (tenantId == null && tenantCode == null) return false;
|
||||
if (tenantId == null) {
|
||||
TenantByCodeCacheService.TenantByCodeCacheValue cacheValue = this.tenantByCodeCacheService.lookup(this.tenantByCodeCacheService.buildKey(tenantCode));
|
||||
if (cacheValue != null) {
|
||||
tenantId = cacheValue.getTenantId();
|
||||
} else {
|
||||
tenantId = this.getTenantIdFromDatabase(tenantCode);
|
||||
this.tenantByCodeCacheService.put(new TenantByCodeCacheService.TenantByCodeCacheValue(tenantCode, tenantId));
|
||||
this.tenantByIdCacheService.put(new TenantByIdCacheService.TenantByIdCacheValue(tenantCode, tenantId));
|
||||
}
|
||||
} else {
|
||||
logger.debug("tenant claim was set to {}", tenantId);
|
||||
TenantByIdCacheService.TenantByIdCacheValue cacheValue = this.tenantByIdCacheService.lookup(this.tenantByIdCacheService.buildKey(tenantId));
|
||||
|
||||
if (cacheValue != null) {
|
||||
tenantCode = cacheValue.getTenantCode();
|
||||
} else {
|
||||
tenantCode = this.getTenantCodeFromDatabase(tenantId);
|
||||
this.tenantByCodeCacheService.put(new TenantByCodeCacheService.TenantByCodeCacheValue(tenantCode, tenantId));
|
||||
this.tenantByIdCacheService.put(new TenantByIdCacheService.TenantByIdCacheValue(tenantCode, tenantId));
|
||||
}
|
||||
}
|
||||
|
||||
if (tenantId != null && tenantCode != null && !tenantCode.isBlank()) {
|
||||
logger.debug("parsed tenant header and set tenant id to {}", tenantId);
|
||||
this.tenantScope.setTenant(tenantId, tenantCode);
|
||||
this.claimExtractorContext.putReplaceParameter(TenantScope.TenantReplaceParameter, tenantCode);
|
||||
}
|
||||
return tenantId != null;
|
||||
}
|
||||
|
||||
private Boolean scopeByClient(TenantScope scope, MyPrincipal principal) throws InvalidApplicationException {
|
||||
String client = this.claimExtractor.client(principal);
|
||||
|
||||
Boolean isWhiteListed = this.tenantScopeProperties.getWhiteListedClients() != null && !this.conventionService.isNullOrEmpty(client) && this.tenantScopeProperties.getWhiteListedClients().contains(client);
|
||||
logger.debug("client is whitelisted : {}, scope is set: {}, with value {}", isWhiteListed, scope.isSet(), (scope.isSet() ? scope.getTenant() : null));
|
||||
|
||||
return isWhiteListed && scope.isSet();
|
||||
}
|
||||
|
||||
private UUID getTenantIdFromDatabase(String tenantCode) {
|
||||
CriteriaBuilder criteriaBuilder = this.entityManager.getCriteriaBuilder();
|
||||
CriteriaQuery<Tuple> query = criteriaBuilder.createQuery(Tuple.class);
|
||||
Root<TenantEntity> root = query.from(TenantEntity.class);
|
||||
query = query.where(
|
||||
criteriaBuilder.and(
|
||||
criteriaBuilder.equal(root.get(TenantEntity._code), tenantCode),
|
||||
criteriaBuilder.equal(root.get(TenantEntity._isActive), IsActive.Active)
|
||||
)
|
||||
).multiselect(root.get(TenantEntity._id).alias(TenantEntity._id));
|
||||
List<Tuple> results = this.entityManager.createQuery(query).getResultList();
|
||||
if (results.size() == 1) {
|
||||
Object o;
|
||||
try {
|
||||
o = results.get(0).get(TenantEntity._id);
|
||||
} catch (IllegalArgumentException e) {
|
||||
return null;
|
||||
}
|
||||
if (o == null) return null;
|
||||
try {
|
||||
return (UUID) o;
|
||||
} catch (ClassCastException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private String getTenantCodeFromDatabase(UUID tenantId) {
|
||||
CriteriaBuilder criteriaBuilder = this.entityManager.getCriteriaBuilder();
|
||||
CriteriaQuery<Tuple> query = criteriaBuilder.createQuery(Tuple.class);
|
||||
Root<TenantEntity> root = query.from(TenantEntity.class);
|
||||
query = query.where(
|
||||
criteriaBuilder.and(
|
||||
criteriaBuilder.equal(root.get(TenantEntity._id), tenantId),
|
||||
criteriaBuilder.equal(root.get(TenantEntity._isActive), IsActive.Active)
|
||||
)
|
||||
).multiselect(root.get(TenantEntity._code).alias(TenantEntity._code));
|
||||
List<Tuple> results = this.entityManager.createQuery(query).getResultList();
|
||||
if (results.size() == 1) {
|
||||
Object o;
|
||||
try {
|
||||
o = results.get(0).get(TenantEntity._code);
|
||||
} catch (IllegalArgumentException e) {
|
||||
return null;
|
||||
}
|
||||
if (o == null) return null;
|
||||
try {
|
||||
return (String) o;
|
||||
} catch (ClassCastException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void postHandle(@NonNull WebRequest request, ModelMap model) {
|
||||
this.tenantScope.setTenant(null, null);
|
||||
this.claimExtractorContext.removeReplaceParameter(TenantScope.TenantReplaceParameter);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterCompletion(@NonNull WebRequest request, Exception ex) {
|
||||
}
|
||||
}
|
|
@ -1,9 +0,0 @@
|
|||
package gr.cite.annotation.web.scope.tenant;
|
||||
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
@Configuration
|
||||
@EnableConfigurationProperties(TenantScopeProperties.class)
|
||||
public class TenantScopeConfiguration {
|
||||
}
|
|
@ -1,161 +0,0 @@
|
|||
package gr.cite.annotation.web.scope.tenant;
|
||||
|
||||
import gr.cite.commons.web.oidc.principal.CurrentPrincipalResolver;
|
||||
import gr.cite.commons.web.oidc.principal.extractor.ClaimExtractorContext;
|
||||
import gr.cite.annotation.common.enums.IsActive;
|
||||
import gr.cite.annotation.common.scope.tenant.TenantScope;
|
||||
import gr.cite.annotation.convention.ConventionService;
|
||||
import gr.cite.annotation.data.TenantEntity;
|
||||
import gr.cite.tools.logging.LoggerService;
|
||||
import jakarta.persistence.EntityManager;
|
||||
import jakarta.persistence.PersistenceContext;
|
||||
import jakarta.persistence.Tuple;
|
||||
import jakarta.persistence.criteria.CriteriaBuilder;
|
||||
import jakarta.persistence.criteria.CriteriaQuery;
|
||||
import jakarta.persistence.criteria.Root;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.lang.NonNull;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.ui.ModelMap;
|
||||
import org.springframework.web.context.request.WebRequest;
|
||||
import org.springframework.web.context.request.WebRequestInterceptor;
|
||||
|
||||
import javax.management.InvalidApplicationException;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
@Component
|
||||
public class TenantScopeHeaderInterceptor implements WebRequestInterceptor {
|
||||
private static final LoggerService logger = new LoggerService(LoggerFactory.getLogger(TenantScopeHeaderInterceptor.class));
|
||||
private final TenantScope tenantScope;
|
||||
private final ConventionService conventionService;
|
||||
private final TenantByCodeCacheService tenantByCodeCacheService;
|
||||
private final TenantByIdCacheService tenantByIdCacheService;
|
||||
private final ClaimExtractorContext claimExtractorContext;
|
||||
private final CurrentPrincipalResolver currentPrincipalResolver;
|
||||
@PersistenceContext
|
||||
public EntityManager entityManager;
|
||||
|
||||
@Autowired
|
||||
public TenantScopeHeaderInterceptor(
|
||||
TenantScope tenantScope,
|
||||
ConventionService conventionService,
|
||||
TenantByCodeCacheService tenantByCodeCacheService,
|
||||
TenantByIdCacheService tenantByIdCacheService,
|
||||
ClaimExtractorContext claimExtractorContext,
|
||||
CurrentPrincipalResolver currentPrincipalResolver
|
||||
) {
|
||||
this.tenantScope = tenantScope;
|
||||
this.conventionService = conventionService;
|
||||
this.tenantByCodeCacheService = tenantByCodeCacheService;
|
||||
this.tenantByIdCacheService = tenantByIdCacheService;
|
||||
this.claimExtractorContext = claimExtractorContext;
|
||||
this.currentPrincipalResolver = currentPrincipalResolver;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void preHandle(WebRequest request) throws InvalidApplicationException {
|
||||
if (!this.currentPrincipalResolver.currentPrincipal().isAuthenticated()) return;
|
||||
if (!this.tenantScope.isMultitenant()) return;
|
||||
|
||||
String tenantCode = request.getHeader(TenantScope.TenantClaimName);
|
||||
logger.debug("retrieved request tenant header is: {header}", tenantCode);
|
||||
if (this.conventionService.isNullOrEmpty(tenantCode)) return;
|
||||
|
||||
UUID tenantId = this.conventionService.parseUUIDSafe(tenantCode);
|
||||
if (tenantId == null && tenantCode == null) return;
|
||||
if (tenantId == null) {
|
||||
TenantByCodeCacheService.TenantByCodeCacheValue cacheValue = this.tenantByCodeCacheService.lookup(this.tenantByCodeCacheService.buildKey(tenantCode));
|
||||
if (cacheValue != null) {
|
||||
tenantId = cacheValue.getTenantId();
|
||||
} else {
|
||||
tenantId = this.getTenantIdFromDatabase(tenantCode);
|
||||
this.tenantByCodeCacheService.put(new TenantByCodeCacheService.TenantByCodeCacheValue(tenantCode, tenantId));
|
||||
this.tenantByIdCacheService.put(new TenantByIdCacheService.TenantByIdCacheValue(tenantCode, tenantId));
|
||||
}
|
||||
} else {
|
||||
TenantByIdCacheService.TenantByIdCacheValue cacheValue = this.tenantByIdCacheService.lookup(this.tenantByIdCacheService.buildKey(tenantId));
|
||||
if (cacheValue != null) {
|
||||
tenantCode = cacheValue.getTenantCode();
|
||||
} else {
|
||||
tenantCode = this.getTenantCodeFromDatabase(tenantId);
|
||||
this.tenantByCodeCacheService.put(new TenantByCodeCacheService.TenantByCodeCacheValue(tenantCode, tenantId));
|
||||
this.tenantByIdCacheService.put(new TenantByIdCacheService.TenantByIdCacheValue(tenantCode, tenantId));
|
||||
}
|
||||
}
|
||||
|
||||
if (tenantId != null && tenantCode != null && !tenantCode.isBlank()) {
|
||||
logger.debug("parsed tenant header and set tenant id to {tenant}", tenantId);
|
||||
this.tenantScope.setTenant(tenantId, tenantCode);
|
||||
this.claimExtractorContext.putReplaceParameter(TenantScope.TenantReplaceParameter, tenantCode);
|
||||
}
|
||||
}
|
||||
|
||||
private UUID getTenantIdFromDatabase(String tenantCode) {
|
||||
CriteriaBuilder criteriaBuilder = this.entityManager.getCriteriaBuilder();
|
||||
CriteriaQuery<Tuple> query = criteriaBuilder.createQuery(Tuple.class);
|
||||
Root<TenantEntity> root = query.from(TenantEntity.class);
|
||||
query = query.where(
|
||||
criteriaBuilder.and(
|
||||
criteriaBuilder.equal(root.get(TenantEntity._code), tenantCode),
|
||||
criteriaBuilder.equal(root.get(TenantEntity._isActive), IsActive.Active)
|
||||
)
|
||||
).multiselect(root.get(TenantEntity._id).alias(TenantEntity._id));
|
||||
List<Tuple> results = this.entityManager.createQuery(query).getResultList();
|
||||
if (results.size() == 1) {
|
||||
Object o;
|
||||
try {
|
||||
o = results.get(0).get(TenantEntity._id);
|
||||
} catch (IllegalArgumentException e) {
|
||||
return null;
|
||||
}
|
||||
if (o == null) return null;
|
||||
try {
|
||||
return UUID.class.cast(o);
|
||||
} catch (ClassCastException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private String getTenantCodeFromDatabase(UUID tenantId) {
|
||||
CriteriaBuilder criteriaBuilder = this.entityManager.getCriteriaBuilder();
|
||||
CriteriaQuery<Tuple> query = criteriaBuilder.createQuery(Tuple.class);
|
||||
Root<TenantEntity> root = query.from(TenantEntity.class);
|
||||
query = query.where(
|
||||
criteriaBuilder.and(
|
||||
criteriaBuilder.equal(root.get(TenantEntity._id), tenantId),
|
||||
criteriaBuilder.equal(root.get(TenantEntity._isActive), IsActive.Active)
|
||||
)
|
||||
).multiselect(root.get(TenantEntity._code).alias(TenantEntity._code));
|
||||
List<Tuple> results = this.entityManager.createQuery(query).getResultList();
|
||||
if (results.size() == 1) {
|
||||
Object o;
|
||||
try {
|
||||
o = results.get(0).get(TenantEntity._code);
|
||||
} catch (IllegalArgumentException e) {
|
||||
return null;
|
||||
}
|
||||
if (o == null) return null;
|
||||
try {
|
||||
return String.class.cast(o);
|
||||
} catch (ClassCastException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void postHandle(@NonNull WebRequest request, ModelMap model) {
|
||||
|
||||
this.tenantScope.setTenant(null, null);
|
||||
this.claimExtractorContext.removeReplaceParameter(TenantScope.TenantReplaceParameter);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterCompletion(@NonNull WebRequest request, Exception ex) {
|
||||
}
|
||||
}
|
|
@ -1,43 +0,0 @@
|
|||
package gr.cite.annotation.web.scope.tenant;
|
||||
|
||||
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
|
||||
@ConfigurationProperties(prefix = "tenant.interceptor")
|
||||
public class TenantScopeProperties {
|
||||
|
||||
private String clientClaimsPrefix;
|
||||
public String getClientClaimsPrefix() {
|
||||
return clientClaimsPrefix;
|
||||
}
|
||||
public void setClientClaimsPrefix(String clientClaimsPrefix) {
|
||||
this.clientClaimsPrefix = clientClaimsPrefix;
|
||||
}
|
||||
|
||||
private HashSet<String> whiteListedClients;
|
||||
public HashSet<String> getWhiteListedClients() {
|
||||
return whiteListedClients;
|
||||
}
|
||||
public void setWhiteListedClients(HashSet<String> whiteListedClients) {
|
||||
this.whiteListedClients = whiteListedClients;
|
||||
}
|
||||
|
||||
private List<String> whiteListedEndpoints;
|
||||
public List<String> getWhiteListedEndpoints() {
|
||||
return whiteListedEndpoints;
|
||||
}
|
||||
public void setWhiteListedEndpoints(List<String> whiteListedEndpoints) {
|
||||
this.whiteListedEndpoints = whiteListedEndpoints;
|
||||
}
|
||||
|
||||
private Boolean enforceTrustedTenant;
|
||||
public Boolean getEnforceTrustedTenant() {
|
||||
return enforceTrustedTenant;
|
||||
}
|
||||
public void setEnforceTrustedTenant(Boolean enforceTrustedTenant) {
|
||||
this.enforceTrustedTenant = enforceTrustedTenant;
|
||||
}
|
||||
}
|
|
@ -1,10 +0,0 @@
|
|||
package gr.cite.annotation.web.scope.tenant;
|
||||
|
||||
import gr.cite.tools.cache.CacheOptions;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
@Configuration
|
||||
@ConfigurationProperties(prefix = "cache.user-allowed-tenant")
|
||||
public class UserAllowedTenantCacheOptions extends CacheOptions {
|
||||
}
|
|
@ -1,90 +0,0 @@
|
|||
package gr.cite.annotation.web.scope.tenant;
|
||||
|
||||
import gr.cite.annotation.event.UserAddedToTenantEvent;
|
||||
import gr.cite.annotation.event.UserRemovedFromTenantEvent;
|
||||
import gr.cite.tools.cache.CacheService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.event.EventListener;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Locale;
|
||||
import java.util.UUID;
|
||||
|
||||
@Service
|
||||
public class UserAllowedTenantCacheService extends CacheService<UserAllowedTenantCacheService.UserAllowedTenantCacheValue> {
|
||||
|
||||
public static class UserAllowedTenantCacheValue {
|
||||
|
||||
public UserAllowedTenantCacheValue() {
|
||||
}
|
||||
|
||||
public UserAllowedTenantCacheValue(UUID userId, UUID tenantId, boolean isAllowed) {
|
||||
this.userId = userId;
|
||||
this.tenantId = tenantId;
|
||||
this.isAllowed = isAllowed;
|
||||
}
|
||||
|
||||
private UUID userId;
|
||||
|
||||
public UUID getUserId() {
|
||||
return userId;
|
||||
}
|
||||
|
||||
public void setUserId(UUID userId) {
|
||||
this.userId = userId;
|
||||
}
|
||||
|
||||
private UUID tenantId;
|
||||
|
||||
public UUID getTenantId() {
|
||||
return tenantId;
|
||||
}
|
||||
|
||||
public void setTenantId(UUID tenantId) {
|
||||
this.tenantId = tenantId;
|
||||
}
|
||||
|
||||
private boolean isAllowed;
|
||||
|
||||
public boolean isAllowed() {
|
||||
return isAllowed;
|
||||
}
|
||||
|
||||
public void setAllowed(boolean allowed) {
|
||||
isAllowed = allowed;
|
||||
}
|
||||
}
|
||||
|
||||
@Autowired
|
||||
public UserAllowedTenantCacheService(UserAllowedTenantCacheOptions options) {
|
||||
super(options);
|
||||
}
|
||||
|
||||
@EventListener
|
||||
public void handleUserRemovedFromTenantEvent(UserRemovedFromTenantEvent event) {
|
||||
this.evict(this.buildKey(event.getUserId(), event.getTenantId()));
|
||||
}
|
||||
|
||||
@EventListener
|
||||
public void handleUserAddedToTenantEvent(UserAddedToTenantEvent event) {
|
||||
this.evict(this.buildKey(event.getUserId(), event.getTenantId()));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Class<UserAllowedTenantCacheValue> valueClass() {
|
||||
return UserAllowedTenantCacheValue.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String keyOf(UserAllowedTenantCacheValue value) {
|
||||
return this.buildKey(value.getUserId(), value.getTenantId());
|
||||
}
|
||||
|
||||
public String buildKey(UUID userId, UUID tenantId) {
|
||||
return this.generateKey(new HashMap<>() {{
|
||||
put("$user_id$", userId.toString().toLowerCase(Locale.ROOT));
|
||||
put("$tenant_id$", tenantId.toString().toLowerCase(Locale.ROOT));
|
||||
}});
|
||||
}
|
||||
}
|
|
@ -1,154 +0,0 @@
|
|||
//package gr.cite.notification.web.scope.user;
|
||||
//
|
||||
//
|
||||
//import gr.cite.commons.web.oidc.principal.CurrentPrincipalResolver;
|
||||
//import gr.cite.commons.web.oidc.principal.extractor.ClaimExtractor;
|
||||
//import gr.cite.notification.common.enums.IsActive;
|
||||
//import gr.cite.notification.common.scope.user.UserScope;
|
||||
//import gr.cite.notification.data.UserEntity;
|
||||
//import gr.cite.notification.locale.LocaleService;
|
||||
//import gr.cite.tools.logging.LoggerService;
|
||||
//import org.slf4j.LoggerFactory;
|
||||
//import org.springframework.beans.factory.annotation.Autowired;
|
||||
//import org.springframework.lang.NonNull;
|
||||
//import org.springframework.stereotype.Component;
|
||||
//import org.springframework.transaction.PlatformTransactionManager;
|
||||
//import org.springframework.transaction.TransactionDefinition;
|
||||
//import org.springframework.transaction.TransactionStatus;
|
||||
//import org.springframework.transaction.support.DefaultTransactionDefinition;
|
||||
//import org.springframework.ui.ModelMap;
|
||||
//import org.springframework.web.context.request.WebRequest;
|
||||
//import org.springframework.web.context.request.WebRequestInterceptor;
|
||||
//
|
||||
//import javax.management.InvalidApplicationException;
|
||||
//import jakarta.persistence.EntityManager;
|
||||
//import jakarta.persistence.PersistenceContext;
|
||||
//import jakarta.persistence.Tuple;
|
||||
//import jakarta.persistence.criteria.CriteriaBuilder;
|
||||
//import jakarta.persistence.criteria.CriteriaQuery;
|
||||
//import jakarta.persistence.criteria.Root;
|
||||
//import java.time.Instant;
|
||||
//import java.util.List;
|
||||
//import java.util.UUID;
|
||||
//
|
||||
//@Component
|
||||
//public class UserInterceptor implements WebRequestInterceptor {
|
||||
// private static final LoggerService logger = new LoggerService(LoggerFactory.getLogger(UserInterceptor.class));
|
||||
// private final UserScope userScope;
|
||||
// private final ClaimExtractor claimExtractor;
|
||||
// private final CurrentPrincipalResolver currentPrincipalResolver;
|
||||
// private final LocaleService localeService;
|
||||
// private final PlatformTransactionManager transactionManager;
|
||||
// private final UserInterceptorCacheService userInterceptorCacheService;
|
||||
// @PersistenceContext
|
||||
// public EntityManager entityManager;
|
||||
//
|
||||
// @Autowired
|
||||
// public UserInterceptor(
|
||||
// UserScope userScope,
|
||||
// LocaleService localeService,
|
||||
// ClaimExtractor claimExtractor,
|
||||
// CurrentPrincipalResolver currentPrincipalResolver,
|
||||
// PlatformTransactionManager transactionManager,
|
||||
// UserInterceptorCacheService userInterceptorCacheService
|
||||
// ) {
|
||||
// this.userScope = userScope;
|
||||
// this.localeService = localeService;
|
||||
// this.currentPrincipalResolver = currentPrincipalResolver;
|
||||
// this.claimExtractor = claimExtractor;
|
||||
// this.transactionManager = transactionManager;
|
||||
// this.userInterceptorCacheService = userInterceptorCacheService;
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public void preHandle(WebRequest request) throws InvalidApplicationException {
|
||||
// UUID userId = null;
|
||||
// if (this.currentPrincipalResolver.currentPrincipal().isAuthenticated()) {
|
||||
// String subjectId = this.claimExtractor.subjectString(this.currentPrincipalResolver.currentPrincipal());
|
||||
//
|
||||
// UserInterceptorCacheService.UserInterceptorCacheValue cacheValue = this.userInterceptorCacheService.lookup(this.userInterceptorCacheService.buildKey(subjectId));
|
||||
// if (cacheValue != null) {
|
||||
// userId = cacheValue.getUserId();
|
||||
// } else {
|
||||
// userId = this.getUserIdFromDatabase(subjectId);
|
||||
// if (userId == null) userId = this.createUser(subjectId);
|
||||
//
|
||||
// this.userInterceptorCacheService.put(new UserInterceptorCacheService.UserInterceptorCacheValue(subjectId, userId));
|
||||
// }
|
||||
// }
|
||||
// this.userScope.setUserId(userId);
|
||||
// }
|
||||
//
|
||||
// private UUID getUserIdFromDatabase(String subjectId) throws InvalidApplicationException {
|
||||
// CriteriaBuilder criteriaBuilder = this.entityManager.getCriteriaBuilder();
|
||||
// CriteriaQuery<Tuple> query = criteriaBuilder.createQuery(Tuple.class);
|
||||
// Root<UserEntity> root = query.from(UserEntity.class);
|
||||
// query.where(
|
||||
// criteriaBuilder.and(
|
||||
//// criteriaBuilder.equal(root.get(UserEntity._subjectId), subjectId),
|
||||
// criteriaBuilder.equal(root.get(UserEntity._isActive), IsActive.Active)
|
||||
// ));
|
||||
//
|
||||
// query.multiselect(root.get(UserEntity._id).alias(UserEntity._id));
|
||||
//
|
||||
// List<Tuple> results = this.entityManager.createQuery(query).getResultList();
|
||||
// if (results.size() == 1) {
|
||||
// Object o;
|
||||
// try {
|
||||
// o = results.get(0).get(UserEntity._id);
|
||||
// } catch (IllegalArgumentException e) {
|
||||
// return null;
|
||||
// }
|
||||
// if (o == null) return null;
|
||||
// try {
|
||||
// return UUID.class.cast(o);
|
||||
// } catch (ClassCastException e) {
|
||||
// return null;
|
||||
// }
|
||||
// }
|
||||
// return null;
|
||||
// }
|
||||
//
|
||||
// private UUID createUser(String subjectId) {
|
||||
// String name = this.claimExtractor.name(this.currentPrincipalResolver.currentPrincipal());
|
||||
// String familyName = this.claimExtractor.familyName(this.currentPrincipalResolver.currentPrincipal());
|
||||
// if (name == null) name = subjectId;
|
||||
// UserEntity user = new UserEntity();
|
||||
// user.setId(UUID.randomUUID());
|
||||
// user.setCreatedAt(Instant.now());
|
||||
// user.setUpdatedAt(Instant.now());
|
||||
// user.setName(name);
|
||||
//// user.setLastName(familyName == null ? name : familyName);
|
||||
// user.setIsActive(IsActive.Active);
|
||||
//// user.setSubjectId(subjectId);
|
||||
//// user.setCulture(this.localeService.cultureName());
|
||||
//// user.setTimezone(this.localeService.timezoneName());
|
||||
//// user.setLanguage(this.localeService.language());
|
||||
//
|
||||
// DefaultTransactionDefinition definition = new DefaultTransactionDefinition();
|
||||
// definition.setName(UUID.randomUUID().toString());
|
||||
// definition.setIsolationLevel(TransactionDefinition.ISOLATION_READ_COMMITTED);
|
||||
// definition.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
|
||||
// TransactionStatus status = null;
|
||||
// try {
|
||||
// status = transactionManager.getTransaction(definition);
|
||||
// this.entityManager.persist(user);
|
||||
//
|
||||
// this.entityManager.flush();
|
||||
// transactionManager.commit(status);
|
||||
// } catch (Exception ex) {
|
||||
// if (status != null) transactionManager.rollback(status);
|
||||
// throw ex;
|
||||
// }
|
||||
// return user.getId();
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public void postHandle(@NonNull WebRequest request, ModelMap model) {
|
||||
// this.userScope.setUserId(null);
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public void afterCompletion(@NonNull WebRequest request, Exception ex) {
|
||||
// }
|
||||
//}
|
|
@ -1,10 +0,0 @@
|
|||
//package gr.cite.notification.web.scope.user;
|
||||
//
|
||||
//import gr.cite.tools.cache.CacheOptions;
|
||||
//import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
//import org.springframework.context.annotation.Configuration;
|
||||
//
|
||||
//@Configuration
|
||||
//@ConfigurationProperties(prefix = "cache.user-by-subject-id")
|
||||
//public class UserInterceptorCacheOptions extends CacheOptions {
|
||||
//}
|
|
@ -1,77 +0,0 @@
|
|||
//package gr.cite.notification.web.scope.user;
|
||||
//
|
||||
//import gr.cite.notification.convention.ConventionService;
|
||||
//import gr.cite.notification.event.UserTouchedEvent;
|
||||
//import gr.cite.tools.cache.CacheService;
|
||||
//import org.springframework.beans.factory.annotation.Autowired;
|
||||
//import org.springframework.context.event.EventListener;
|
||||
//import org.springframework.stereotype.Service;
|
||||
//
|
||||
//import java.util.HashMap;
|
||||
//import java.util.UUID;
|
||||
//
|
||||
//@Service
|
||||
//public class UserInterceptorCacheService extends CacheService<UserInterceptorCacheService.UserInterceptorCacheValue> {
|
||||
//
|
||||
// public static class UserInterceptorCacheValue {
|
||||
//
|
||||
// public UserInterceptorCacheValue() {
|
||||
// }
|
||||
//
|
||||
// public UserInterceptorCacheValue(String subjectId, UUID userId) {
|
||||
// this.subjectId = subjectId;
|
||||
// this.userId = userId;
|
||||
// }
|
||||
//
|
||||
// private String subjectId;
|
||||
//
|
||||
// public String getSubjectId() {
|
||||
// return subjectId;
|
||||
// }
|
||||
//
|
||||
// public void setSubjectId(String subjectId) {
|
||||
// this.subjectId = subjectId;
|
||||
// }
|
||||
//
|
||||
// private UUID userId;
|
||||
//
|
||||
// public UUID getUserId() {
|
||||
// return userId;
|
||||
// }
|
||||
//
|
||||
// public void setUserId(UUID userId) {
|
||||
// this.userId = userId;
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// private final ConventionService conventionService;
|
||||
//
|
||||
// @Autowired
|
||||
// public UserInterceptorCacheService(UserInterceptorCacheOptions options, ConventionService conventionService) {
|
||||
// super(options);
|
||||
// this.conventionService = conventionService;
|
||||
// }
|
||||
//
|
||||
// @EventListener
|
||||
// public void handleUserTouchedEvent(UserTouchedEvent event) {
|
||||
// if (!this.conventionService.isNullOrEmpty(event.getSubjectId())) this.evict(this.buildKey(event.getSubjectId()));
|
||||
// if (!this.conventionService.isNullOrEmpty(event.getPreviousSubjectId())) this.evict(this.buildKey(event.getPreviousSubjectId()));
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// protected Class<UserInterceptorCacheValue> valueClass() {
|
||||
// return UserInterceptorCacheValue.class;
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public String keyOf(UserInterceptorCacheValue value) {
|
||||
// return this.buildKey(value.getSubjectId());
|
||||
// }
|
||||
//
|
||||
//
|
||||
// public String buildKey(String subject) {
|
||||
// return this.generateKey(new HashMap<>() {{
|
||||
// put("$subject$", subject);
|
||||
// }});
|
||||
// }
|
||||
//}
|
|
@ -1,20 +0,0 @@
|
|||
spring:
|
||||
jackson:
|
||||
default-property-inclusion: non_null
|
||||
config:
|
||||
import: optional:classpath:config/app.env[.properties], optional:file:../config/app.env[.properties],
|
||||
optional:classpath:config/db.yml[.yml], optional:classpath:config/db-${spring.profiles.active}.yml[.yml], optional:file:../config/db-${spring.profiles.active}.yml[.yml],
|
||||
optional:classpath:config/permissions.yml[.yml], optional:classpath:config/permissions-${spring.profiles.active}.yml[.yml], optional:file:../config/permissions-${spring.profiles.active}.yml[.yml],
|
||||
optional:classpath:config/errors.yml[.yml], optional:classpath:config/errors-${spring.profiles.active}.yml[.yml], optional:file:../config/errors-${spring.profiles.active}.yml[.yml],
|
||||
optional:classpath:config/security.yml[.yml], optional:classpath:config/security-${spring.profiles.active}.yml[.yml], optional:file:../config/security-${spring.profiles.active}.yml[.yml],
|
||||
optional:classpath:config/server.yml[.yml], optional:classpath:config/server-${spring.profiles.active}.yml[.yml], optional:file:../config/server-${spring.profiles.active}.yml[.yml],
|
||||
optional:classpath:config/logging.yml[.yml], optional:classpath:config/logging-${spring.profiles.active}.yml[.yml], optional:file:../config/logging-${spring.profiles.active}.yml[.yml],
|
||||
optional:classpath:config/idpclaims.yml[.yml], optional:classpath:config/idpclaims-${spring.profiles.active}.yml[.yml], optional:file:../config/idpclaims-${spring.profiles.active}.yml[.yml],
|
||||
optional:classpath:config/cache.yml[.yml], optional:classpath:config/cache-${spring.profiles.active}.yml[.yml], optional:file:../config/cache-${spring.profiles.active}.yml[.yml],
|
||||
optional:classpath:config/tenant.yml[.yml], optional:classpath:config/tenant-${spring.profiles.active}.yml[.yml], optional:file:../config/tenant-${spring.profiles.active}.yml[.yml],
|
||||
optional:classpath:config/locale.yml[.yml], optional:classpath:config/locale-${spring.profiles.active}.yml[.yml], optional:file:../config/locale-${spring.profiles.active}.yml[.yml],
|
||||
optional:classpath:config/cors.yml[.yml], optional:classpath:config/cors-${spring.profiles.active}.yml[.yml], optional:file:../config/cors-${spring.profiles.active}.yml[.yml],
|
||||
optional:classpath:config/email.yml[.yml], optional:classpath:config/email-${spring.profiles.active}.yml[.yml], optional:file:../config/email-${spring.profiles.active}.yml[.yml],
|
||||
optional:classpath:config/queue.yml[.yml], optional:classpath:config/queue-${spring.profiles.active}.yml[.yml], optional:file:../config/queue-${spring.profiles.active}.yml[.yml],
|
||||
optional:classpath:config/cipher.yml[.yml], optional:classpath:config/cipher-${spring.profiles.active}.yml[.yml], optional:file:../config/cipher-${spring.profiles.active}.yml[.yml],
|
||||
optional:classpath:config/formatting.yml[.yml], optional:classpath:config/formatting-${spring.profiles.active}.yml[.yml], optional:file:../config/formatting-${spring.profiles.active}.yml[.yml]
|
|
@ -1,77 +0,0 @@
|
|||
cache:
|
||||
manager:
|
||||
fallbackToNoOpCache: true
|
||||
caffeineCaches:
|
||||
- names: [ apikey ]
|
||||
allowNullValues: true
|
||||
initialCapacity: 100
|
||||
maximumSize: 500
|
||||
enableRecordStats: false
|
||||
expireAfterWriteMinutes: 10
|
||||
expireAfterAccessMinutes: 10
|
||||
refreshAfterWriteMinutes: 10
|
||||
- names: [ tenantByCode ]
|
||||
allowNullValues: true
|
||||
initialCapacity: 100
|
||||
maximumSize: 500
|
||||
enableRecordStats: false
|
||||
expireAfterWriteMinutes: 10
|
||||
expireAfterAccessMinutes: 10
|
||||
refreshAfterWriteMinutes: 10
|
||||
- names: [ tenantById ]
|
||||
allowNullValues: true
|
||||
initialCapacity: 100
|
||||
maximumSize: 500
|
||||
enableRecordStats: false
|
||||
expireAfterWriteMinutes: 10
|
||||
expireAfterAccessMinutes: 10
|
||||
refreshAfterWriteMinutes: 10
|
||||
- names: [ userBySubjectId ]
|
||||
allowNullValues: true
|
||||
initialCapacity: 100
|
||||
maximumSize: 500
|
||||
enableRecordStats: false
|
||||
expireAfterWriteMinutes: 5
|
||||
expireAfterAccessMinutes: 5
|
||||
refreshAfterWriteMinutes: 5
|
||||
- names: [ userAccessTenant ]
|
||||
allowNullValues: true
|
||||
initialCapacity: 100
|
||||
maximumSize: 500
|
||||
enableRecordStats: false
|
||||
expireAfterWriteMinutes: 5
|
||||
expireAfterAccessMinutes: 5
|
||||
refreshAfterWriteMinutes: 5
|
||||
- names: [ formattingUserProfile ]
|
||||
allowNullValues: true
|
||||
initialCapacity: 100
|
||||
maximumSize: 500
|
||||
enableRecordStats: false
|
||||
expireAfterWriteMinutes: 1
|
||||
expireAfterAccessMinutes: 1
|
||||
refreshAfterWriteMinutes: 1
|
||||
mapCaches:
|
||||
- names: [ cacheB ]
|
||||
allowNullValues: true
|
||||
storeByValue: true
|
||||
apiKey:
|
||||
name: apikey
|
||||
keyPattern: resolve_$keyhash$:v0
|
||||
userBySubjectId:
|
||||
name: userBySubjectId
|
||||
keyPattern: user_by_subject_$subject$:v0
|
||||
tenantByCode:
|
||||
name: tenantByCode
|
||||
keyPattern: tenant_by_code_$code$:v0
|
||||
tenantById:
|
||||
name: tenantById
|
||||
keyPattern: tenant_by_id_$tenantId$:v0
|
||||
userAllowedTenant:
|
||||
name: userAccessTenant
|
||||
keyPattern: user_access_tenant_$user_id$_$tenant_id$:v0
|
||||
formattingUserProfileCache:
|
||||
name: formattingUserProfile
|
||||
keyPattern: formatting_user_profile$user_id$:v0
|
||||
template:
|
||||
name: template
|
||||
key-pattern: ------
|
|
@ -1,35 +0,0 @@
|
|||
cipher-profiles:
|
||||
profile-map:
|
||||
configuration-profile-name: "configuration"
|
||||
queue-profile-name: "queue"
|
||||
notification-profile-name: "queue"
|
||||
|
||||
cipher:
|
||||
# salted-hash:
|
||||
# default-o: null
|
||||
# options: null
|
||||
symetric-encryption:
|
||||
default-o: null
|
||||
options:
|
||||
configuration:
|
||||
aes:
|
||||
key: ${CIPHER_SYMETRIC_ENCRYPTION_CONFIGURATION_AES_KEY:}
|
||||
iv: ${CIPHER_SYMETRIC_ENCRYPTION_CONFIGURATION_AES_IV:}
|
||||
queue:
|
||||
aes:
|
||||
key: ${CIPHER_SYMETRIC_ENCRYPTION_QUEUE_AES_KEY:}
|
||||
iv: ${CIPHER_SYMETRIC_ENCRYPTION_QUEUE_AES_IV:}
|
||||
masking:
|
||||
default: null
|
||||
options:
|
||||
configuration:
|
||||
character: "*"
|
||||
clear-begining: 2
|
||||
clear-ending: 4
|
||||
at-least-percentage: 70
|
||||
digital-signature:
|
||||
default: null
|
||||
options:
|
||||
configuration:
|
||||
certificate-path: null
|
||||
certificate-password: null
|
|
@ -1,3 +0,0 @@
|
|||
web:
|
||||
cors:
|
||||
allowed-origins: [ http://localhost, http://localhost:4200 ]
|
|
@ -1,7 +0,0 @@
|
|||
web:
|
||||
cors:
|
||||
enabled: true
|
||||
allowed-methods: [ HEAD, GET, POST, PUT, DELETE, PATCH ]
|
||||
allowed-headers: [ Authorization, Cache-Control, Content-Type, Content-Disposition, x-tenant ]
|
||||
exposed-headers: [ Authorization, Cache-Control, Content-Type, Content-Disposition ]
|
||||
allow-credentials: false
|
|
@ -1,7 +0,0 @@
|
|||
spring:
|
||||
jpa:
|
||||
show-sql: true
|
||||
properties:
|
||||
hibernate:
|
||||
show_sql: true
|
||||
format_sql: false
|
|
@ -1,24 +0,0 @@
|
|||
spring:
|
||||
jpa:
|
||||
properties:
|
||||
hibernate:
|
||||
ddl-auto: validate
|
||||
dialect: org.hibernate.dialect.PostgreSQLDialect
|
||||
hibernate:
|
||||
naming:
|
||||
physical-strategy: gr.cite.notification.config.db.PrefixPhysicalNamingStrategy
|
||||
implicit-strategy: org.springframework.boot.orm.jpa.hibernate.SpringImplicitNamingStrategy
|
||||
datasource:
|
||||
url: ${DB_CONNECTION_STRING}
|
||||
username: ${DB_USER}
|
||||
password: ${DB_PASSWORD}
|
||||
driver-class-name: org.postgresql.Driver
|
||||
hikari:
|
||||
connection-timeout: 30000
|
||||
minimum-idle: 3
|
||||
maximum-pool-size: 5
|
||||
idle-timeout: 600000
|
||||
max-lifetime: 1800000
|
||||
|
||||
naming-strategy:
|
||||
prefix: ant_
|
|
@ -1,14 +0,0 @@
|
|||
spring:
|
||||
mail:
|
||||
host: ${MAIL_HOST:}
|
||||
port: ${MAIL_PORT:}
|
||||
username: ${MAIL_USERNAME:}
|
||||
password: ${MAIL_PASSWORD:}
|
||||
properties:
|
||||
mail:
|
||||
smtp:
|
||||
auth: ${MAIL_AUTH:}
|
||||
starttls:
|
||||
enable: ${MAIL_TLS:}
|
||||
email:
|
||||
address: ${MAIL_ADDRESS:}
|
|
@ -1,43 +0,0 @@
|
|||
error-thesaurus:
|
||||
hash-conflict:
|
||||
code: 100
|
||||
message: there is a hash conflict for the item modified. please reload to get the latest changes
|
||||
forbidden:
|
||||
code: 101
|
||||
message: insufficient rights
|
||||
system-error:
|
||||
code: 102
|
||||
message: an unexpected system error occurred
|
||||
missing-tenant:
|
||||
code: 103
|
||||
message: tenant scope not provided
|
||||
invalid-api-key:
|
||||
code: 104
|
||||
message: provided APIKey not valid
|
||||
stale-api-key:
|
||||
code: 105
|
||||
message: there was a problem authorizing you with your API key. Please try again. Contact the system administrator if the problem persists
|
||||
model-validation:
|
||||
code: 106
|
||||
message: validation error
|
||||
sensitive-info:
|
||||
code: 107
|
||||
message: you are attempting to access sensitive information. please don't do that
|
||||
non-person-principal:
|
||||
code: 108
|
||||
message: the operation is available only to person users
|
||||
blocking-consent:
|
||||
code: 113
|
||||
message: user consents are not sufficient to complete the operation
|
||||
single-tenant-configuration-per-type-supported:
|
||||
code: 116
|
||||
message: a single tenant configuration entry per config type is supported
|
||||
incompatible-tenant-configuration-types:
|
||||
code: 117
|
||||
message: the provided tenant configuration type is incompatible
|
||||
missing-totp-token:
|
||||
code: 118
|
||||
message: totp token not provided
|
||||
overlapping-tenant-configuration-notifier-list:
|
||||
code: 119
|
||||
message: Overlapping Tenant Configuration Notifier List
|
|
@ -1,6 +0,0 @@
|
|||
formatting:
|
||||
options:
|
||||
integer-format: "%,d"
|
||||
decimal-digits-round: 2
|
||||
decimal-format: "#0.00"
|
||||
date-time-format: "YYYY-MM-dd'T'HH:mm:ss"
|
|
@ -1,39 +0,0 @@
|
|||
idpclient:
|
||||
claims:
|
||||
mapping:
|
||||
Subject:
|
||||
- type: sub
|
||||
Name:
|
||||
- type: name
|
||||
Client:
|
||||
- type: client_id
|
||||
AuthenticationMethod:
|
||||
- type: amr
|
||||
NotBefore:
|
||||
- type: nbf
|
||||
AuthenticatedAt:
|
||||
- type: auth_time
|
||||
ExpiresAt:
|
||||
- type: exp
|
||||
Email:
|
||||
- type: email
|
||||
Roles:
|
||||
- type: resource_access
|
||||
path: dmp_web.roles
|
||||
Scope:
|
||||
- type: scope
|
||||
AccessToken:
|
||||
- type: x-access-token
|
||||
visibility: SENSITIVE
|
||||
IssuedAt:
|
||||
- type: iat
|
||||
Issuer:
|
||||
- type: iss
|
||||
Audience:
|
||||
- type: aud
|
||||
TokenType:
|
||||
- type: typ
|
||||
AuthorizedParty:
|
||||
- type: azp
|
||||
Authorities:
|
||||
- type: authorities
|
|
@ -1,4 +0,0 @@
|
|||
locale:
|
||||
timezone: UTC
|
||||
language: en
|
||||
culture: en-US
|
|
@ -1,2 +0,0 @@
|
|||
logging:
|
||||
config: classpath:logging/logback-dev.xml
|
|
@ -1,35 +0,0 @@
|
|||
logging:
|
||||
context:
|
||||
request:
|
||||
requestIdKey: req.id
|
||||
requestRemoteHostKey: req.remoteHost
|
||||
requestUriKey: req.requestURI
|
||||
requestQueryStringKey: req.queryString
|
||||
requestUrlKey : req.requestURL
|
||||
requestMethodKey: req.method
|
||||
requestUserAgentKey: req.userAgent
|
||||
requestForwardedForKey: req.xForwardedFor
|
||||
requestSchemeKey: req.scheme
|
||||
requestRemoteAddressKey: req.remoteAddr
|
||||
requestRemotePortKey: req.remotePort
|
||||
requestRemoteUserKey: req.remoteUser
|
||||
principal:
|
||||
subjectKey: usr.subject
|
||||
nameKey: usr.name
|
||||
clientKey: usr.client
|
||||
audit:
|
||||
enable: true
|
||||
requestRemoteHostKey: req.remoteHost
|
||||
requestUriKey: req.requestURI
|
||||
requestQueryStringKey: req.queryString
|
||||
requestUrlKey : req.requestURL
|
||||
requestMethodKey: req.method
|
||||
requestUserAgentKey: req.userAgent
|
||||
requestForwardedForKey: req.xForwardedFor
|
||||
requestSchemeKey: req.scheme
|
||||
requestRemoteAddressKey: req.remoteAddr
|
||||
requestRemotePortKey: req.remotePort
|
||||
requestRemoteUserKey: req.remoteUser
|
||||
principalSubjectKey: usr.subject
|
||||
principalNameKey: usr.name
|
||||
principalClientKey: usr.client
|
|
@ -1,108 +0,0 @@
|
|||
permissions:
|
||||
extendedClaims: [ ]
|
||||
policies:
|
||||
|
||||
# Tenants
|
||||
BrowseTenant:
|
||||
roles:
|
||||
- ic-sti-superuser
|
||||
clients: [ ]
|
||||
allowAnonymous: false
|
||||
allowAuthenticated: false
|
||||
EditTenant:
|
||||
roles:
|
||||
- ic-sti-superuser
|
||||
clients: [ ]
|
||||
allowAnonymous: false
|
||||
allowAuthenticated: false
|
||||
DeleteTenant:
|
||||
roles:
|
||||
- ic-sti-superuser
|
||||
claims: [ ]
|
||||
clients: [ ]
|
||||
allowAnonymous: false
|
||||
allowAuthenticated: false
|
||||
AllowNoTenant:
|
||||
roles:
|
||||
- ic-sti-superuser
|
||||
claims: [ ]
|
||||
clients: [ ]
|
||||
allowAnonymous: false
|
||||
allowAuthenticated: false
|
||||
# Users
|
||||
BrowseUser:
|
||||
roles:
|
||||
- ic-sti-superuser
|
||||
- tenantadmin
|
||||
clients: [ ]
|
||||
allowAnonymous: true
|
||||
allowAuthenticated: false
|
||||
EditUser:
|
||||
roles:
|
||||
- admin
|
||||
- ic-sti-superuser
|
||||
clients: [ ]
|
||||
allowAnonymous: false
|
||||
allowAuthenticated: false
|
||||
DeleteUser:
|
||||
roles:
|
||||
- ic-sti-superuser
|
||||
claims: [ ]
|
||||
clients: [ ]
|
||||
allowAnonymous: false
|
||||
allowAuthenticated: false
|
||||
# UserContactInfo
|
||||
BrowseUserContactInfo:
|
||||
roles:
|
||||
- ic-sti-superuser
|
||||
clients: [ ]
|
||||
allowAnonymous: true
|
||||
allowAuthenticated: false
|
||||
EditUserContactInfo:
|
||||
roles:
|
||||
- ic-sti-superuser
|
||||
- user
|
||||
clients: [ ]
|
||||
allowAnonymous: false
|
||||
allowAuthenticated: false
|
||||
DeleteUserContactInfo:
|
||||
roles:
|
||||
- ic-sti-superuser
|
||||
claims: [ ]
|
||||
clients: [ ]
|
||||
allowAnonymous: false
|
||||
allowAuthenticated: false
|
||||
#Annotation
|
||||
BrowseAnnotation:
|
||||
roles:
|
||||
- Admin
|
||||
clients: [ ]
|
||||
allowAnonymous: true
|
||||
allowAuthenticated: false
|
||||
EditAnnotation:
|
||||
roles:
|
||||
- Admin
|
||||
clients: [ ]
|
||||
allowAnonymous: true
|
||||
allowAuthenticated: false
|
||||
DeleteAnnotation:
|
||||
roles:
|
||||
- Admin
|
||||
clients: [ ]
|
||||
allowAnonymous: false
|
||||
allowAuthenticated: false
|
||||
#Tenant Configuration
|
||||
BrowseTenantConfiguration:
|
||||
roles:
|
||||
- ic-sti-superuser
|
||||
clients: [ ]
|
||||
allowAnonymous: false
|
||||
allowAuthenticated: false
|
||||
EditTenantConfiguration:
|
||||
roles:
|
||||
- ic-sti-superuser
|
||||
clients: [ ]
|
||||
allowAnonymous: false
|
||||
allowAuthenticated: false
|
||||
|
||||
# ViewPage Permissions
|
|
@ -1,21 +0,0 @@
|
|||
queue:
|
||||
rabbitmq:
|
||||
enable: true
|
||||
durable: true
|
||||
queue: cite_dmp_devel_notification_inbox_queue
|
||||
exchange: cite_dmp_devel_queue
|
||||
listenerEnabled: true
|
||||
publisherEnabled: true
|
||||
task:
|
||||
publisher:
|
||||
enable: true
|
||||
options:
|
||||
exchange: cite_dmp_devel_queue
|
||||
rabbitmq:
|
||||
enable: true
|
||||
listener:
|
||||
enable: true
|
||||
options:
|
||||
exchange: cite_dmp_devel_queue
|
||||
rabbitmq:
|
||||
enable: true
|
|
@ -1,56 +0,0 @@
|
|||
spring:
|
||||
rabbitmq:
|
||||
host: ${RABBIT_HOST}
|
||||
port: ${RABBIT_PORT}
|
||||
username: ${RABBIT_USER}
|
||||
password: ${RABBIT_PASS}
|
||||
ssl:
|
||||
enabled: false
|
||||
queue:
|
||||
rabbitmq:
|
||||
enable: false
|
||||
app-id: ${QUEUE_APP_ID}
|
||||
durable: null
|
||||
queue: null
|
||||
exchange: null
|
||||
listenerEnabled: true
|
||||
publisherEnabled: true
|
||||
#TODO
|
||||
connection-recovery:
|
||||
enable: true
|
||||
network-recovery-interval: 5000
|
||||
unreachable-recovery-interval: 5000
|
||||
task:
|
||||
publisher:
|
||||
enable: false
|
||||
options:
|
||||
exchange: null
|
||||
forget-me-completed-topic: forgetme.completed
|
||||
what-you-know-about-me-completed-topic: whatyouknowaboutme.completed
|
||||
generate-file-topic: generate.file
|
||||
rabbitmq:
|
||||
enable: false
|
||||
interval-seconds: 30
|
||||
options:
|
||||
retry-threashold: 100
|
||||
retry-delay-step-seconds: 300
|
||||
max-retry-delay-seconds: 10800
|
||||
too-old-to-send-seconds: 604800
|
||||
confirm-timeout-seconds: 30
|
||||
listener:
|
||||
enable: false
|
||||
options:
|
||||
exchange: null
|
||||
notify-topic: notification.notify
|
||||
tenant-removal-topic: tenant.remove
|
||||
tenant-touched-topic: tenant.touch
|
||||
user-removal-topic: user.remove
|
||||
user-touched-topic: user.touch
|
||||
rabbitmq:
|
||||
enable: false
|
||||
interval-seconds: 30
|
||||
options:
|
||||
retry-threashold: 100
|
||||
retry-delay-step-seconds: 300
|
||||
max-retry-delay-seconds: 10800
|
||||
too-old-to-send-seconds: 604800
|
|
@ -1,20 +0,0 @@
|
|||
web:
|
||||
security:
|
||||
enabled: true
|
||||
authorized-endpoints: [ api ]
|
||||
allowed-endpoints: [ public, dataset, master-item, test ]
|
||||
idp:
|
||||
api-key:
|
||||
enabled: true
|
||||
authorization-header: Authorization
|
||||
client-id: ${IDP_APIKEY_CLIENT_ID}
|
||||
client-secret: ${IDP_APIKEY_CLIENT_SECRET}
|
||||
scope: ${IDP_APIKEY_SCOPE}
|
||||
resource:
|
||||
token-type: JWT
|
||||
opaque:
|
||||
client-id: ${IDP_OPAQUE_CLIENT_ID}
|
||||
client-secret: ${IDP_OPAQUE_CLIENT_SECRET}
|
||||
jwt:
|
||||
claims: [ role, x-role ]
|
||||
issuer-uri: ${IDP_ISSUER_URI:}
|
|
@ -1,2 +0,0 @@
|
|||
server:
|
||||
forward-headers-strategy: FRAMEWORK
|
|
@ -1,3 +0,0 @@
|
|||
server:
|
||||
port: ${WEB_PORT}
|
||||
forward-headers-strategy: NONE
|
|
@ -1,8 +0,0 @@
|
|||
tenant:
|
||||
multitenancy:
|
||||
is-multitenant: false
|
||||
interceptor:
|
||||
client-claims-prefix: client_
|
||||
white-listed-clients: [ ]
|
||||
enforce-trusted-tenant: false
|
||||
white-listed-endpoints: [ '/api/principal/my-tenants', '/api/principal/me','/api/user/user-settings', '/error', '/api/tenant-request' ]
|
|
@ -1,61 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<configuration debug="true">
|
||||
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
|
||||
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
|
||||
<Pattern>%date{ISO8601} [%thread] %-5level %logger{36} [%X{req.id}] - %message%n</Pattern>
|
||||
</encoder>
|
||||
</appender>
|
||||
|
||||
<appender name="TROUBLESHOOTING" class="ch.qos.logback.core.rolling.RollingFileAppender">
|
||||
<file>logs/logging.log</file>
|
||||
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
|
||||
<fileNamePattern>logs/logging.%d{yyyy-MM-dd}.%i.log</fileNamePattern>
|
||||
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
|
||||
<maxFileSize>100MB</maxFileSize>
|
||||
</timeBasedFileNamingAndTriggeringPolicy>
|
||||
<maxHistory>15</maxHistory>
|
||||
</rollingPolicy>
|
||||
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
|
||||
<Pattern>%date{ISO8601} [%thread] %-5level %logger{36} [%X{req.id}] - %message%n</Pattern>
|
||||
</encoder>
|
||||
</appender>
|
||||
|
||||
<appender name="AUDITING" class="ch.qos.logback.core.rolling.RollingFileAppender">
|
||||
<file>logs/auditing.log</file>
|
||||
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
|
||||
<fileNamePattern>logs/auditing.%d{yyyy-MM-dd}.%i.log</fileNamePattern>
|
||||
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
|
||||
<maxFileSize>100MB</maxFileSize>
|
||||
</timeBasedFileNamingAndTriggeringPolicy>
|
||||
<maxHistory>15</maxHistory>
|
||||
</rollingPolicy>
|
||||
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
|
||||
<Pattern>%date{ISO8601} - %X{req.id} - %message%n</Pattern>
|
||||
</encoder>
|
||||
</appender>
|
||||
|
||||
<logger name="org.springframework.web" level="INFO" additivity="false">
|
||||
<appender-ref ref="TROUBLESHOOTING"/>
|
||||
<appender-ref ref="STDOUT"/>
|
||||
</logger>
|
||||
<logger name="org.hibernate" level="INFO" additivity="false">
|
||||
<appender-ref ref="TROUBLESHOOTING"/>
|
||||
<appender-ref ref="STDOUT"/>
|
||||
</logger>
|
||||
<logger name="gr.cite" level="DEBUG" additivity="false">
|
||||
<appender-ref ref="TROUBLESHOOTING"/>
|
||||
<appender-ref ref="STDOUT"/>
|
||||
</logger>
|
||||
<logger name="org.springframework.data.elasticsearch.client.WIRE" level="TRACE" additivity="false">
|
||||
<appender-ref ref="TROUBLESHOOTING"/>
|
||||
<appender-ref ref="STDOUT"/>
|
||||
</logger>
|
||||
<logger name="audit" level="INFO" additivity="false">
|
||||
<appender-ref ref="AUDITING"/>
|
||||
<appender-ref ref="STDOUT"/>
|
||||
</logger>
|
||||
<root level="info">
|
||||
<appender-ref ref="TROUBLESHOOTING"/>
|
||||
<appender-ref ref="STDOUT"/>
|
||||
</root>
|
||||
</configuration>
|
|
@ -1,10 +0,0 @@
|
|||
validation.empty=Value cannot be empty
|
||||
validation.hashempty=Hash must be set
|
||||
validation.lowerthanmin=Value must be larger than {value}
|
||||
validation.largerthanmax=Value must be less than {value}
|
||||
validation.invalidid=Not valid id
|
||||
General_ItemNotFound=Item {0} of type {1} not found
|
||||
Validation_Required={0} is required
|
||||
Validation_OverPosting=Too much info
|
||||
Validation_MaxLength={0} too long
|
||||
Validation_UnexpectedValue=Unexpected value in field {0}
|
|
@ -1,6 +0,0 @@
|
|||
validation.empty=el-Value cannot be empty
|
||||
validation.hashempty=el-Hash must be set
|
||||
validation.lowerthanmin=el-Value must be larger than {value}
|
||||
validation.largerthanmax=el-Value must be less than {value}
|
||||
validation.invalidid=el-Not valid id
|
||||
General_ItemNotFound=el-Item {0} of type {1} not found
|
|
@ -1,33 +0,0 @@
|
|||
HELP.md
|
||||
target/
|
||||
!.mvn/wrapper/maven-wrapper.jar
|
||||
!**/src/main/**/target/
|
||||
!**/src/test/**/target/
|
||||
|
||||
### STS ###
|
||||
.apt_generated
|
||||
.classpath
|
||||
.factorypath
|
||||
.project
|
||||
.settings
|
||||
.springBeans
|
||||
.sts4-cache
|
||||
|
||||
### IntelliJ IDEA ###
|
||||
.idea
|
||||
*.iws
|
||||
*.iml
|
||||
*.ipr
|
||||
|
||||
### NetBeans ###
|
||||
/nbproject/private/
|
||||
/nbbuild/
|
||||
/dist/
|
||||
/nbdist/
|
||||
/.nb-gradle/
|
||||
build/
|
||||
!**/src/main/**/build/
|
||||
!**/src/test/**/build/
|
||||
|
||||
### VS Code ###
|
||||
.vscode/
|
|
@ -1,99 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<parent>
|
||||
<groupId>gr.cite</groupId>
|
||||
<artifactId>annotation-service-parent</artifactId>
|
||||
<version>1.0.0</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
<artifactId>annotation</artifactId>
|
||||
|
||||
<properties>
|
||||
<java.version>21</java.version>
|
||||
<maven.compiler.source>21</maven.compiler.source>
|
||||
<maven.compiler.target>21</maven.compiler.target>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-data-jpa</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-mail</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.poi</groupId>
|
||||
<artifactId>poi</artifactId>
|
||||
<version>5.2.2</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.poi</groupId>
|
||||
<artifactId>poi-ooxml</artifactId>
|
||||
<version>5.2.2</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>gr.cite</groupId>
|
||||
<artifactId>data-tools</artifactId>
|
||||
<version>2.1.2</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>gr.cite</groupId>
|
||||
<artifactId>field-set</artifactId>
|
||||
<version>2.1.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>gr.cite</groupId>
|
||||
<artifactId>oidc-authn</artifactId>
|
||||
<version>1.0.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>gr.cite</groupId>
|
||||
<artifactId>logging</artifactId>
|
||||
<version>1.0.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>gr.cite</groupId>
|
||||
<artifactId>oidc-authz</artifactId>
|
||||
<version>1.0.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>gr.cite</groupId>
|
||||
<artifactId>exceptions</artifactId>
|
||||
<version>1.0.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>gr.cite</groupId>
|
||||
<artifactId>validation</artifactId>
|
||||
<version>3.0.2</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.fasterxml.jackson.datatype</groupId>
|
||||
<artifactId>jackson-datatype-jsr310</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>gr.cite</groupId>
|
||||
<artifactId>cipher</artifactId>
|
||||
<version>1.0.0</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
|
@ -1,54 +0,0 @@
|
|||
package gr.cite.annotation.audit;
|
||||
|
||||
import gr.cite.tools.logging.EventId;
|
||||
|
||||
public class AuditableAction {
|
||||
// public static final EventId Tenant_Available_Notifiers_Query = new EventId(2006, "Tenant_Available_Notifiers_Query");
|
||||
public static final EventId Principal_Lookup = new EventId(6000, "Principal_Lookup");
|
||||
public static final EventId Tenants_Lookup = new EventId(6001, "Tenants_Lookup");
|
||||
|
||||
// public static final EventId User_Available_Notifiers_Query = new EventId(10004, "User_Available_Notifiers_Query");
|
||||
|
||||
public static final EventId User_Query = new EventId(11000, "User_Query");
|
||||
public static final EventId User_Lookup = new EventId(11001, "User_Lookup");
|
||||
public static final EventId User_Persist = new EventId(11002, "User_Persist");
|
||||
public static final EventId User_Delete = new EventId(11003, "User_Delete");
|
||||
|
||||
public static final EventId Tenant_Query = new EventId(12000, "Tenant_Query");
|
||||
public static final EventId Tenant_Lookup = new EventId(12001, "Tenant_Lookup");
|
||||
public static final EventId Tenant_Persist = new EventId(12002, "Tenant_Persist");
|
||||
public static final EventId Tenant_Delete = new EventId(12003, "Tenant_Delete");
|
||||
|
||||
// public static final EventId Notification_Query = new EventId(19000, "Notification_Query");
|
||||
// public static final EventId Notification_Lookup = new EventId(19001, "Notification_Lookup");
|
||||
// public static final EventId Notification_Persist = new EventId(19002, "Notification_Persist");
|
||||
// public static final EventId Notification_Delete = new EventId(19003, "Notification_Delete");
|
||||
|
||||
// public static final EventId InApp_Notification_Query = new EventId(20000, "InApp_Notification_Query");
|
||||
// public static final EventId InApp_Notification_Lookup = new EventId(20001, "InApp_Notification_Lookup");
|
||||
// public static final EventId InApp_Notification_Persist = new EventId(20002, "InApp_Notification_Persist");
|
||||
// public static final EventId InApp_Notification_Delete = new EventId(20003, "InApp_Notification_Delete");
|
||||
// public static final EventId InApp_Notification_Read = new EventId(20003, "InApp_Notification_Read");
|
||||
// public static final EventId InApp_Notification_Read_All = new EventId(20003, "InApp_Notification_Read_All");
|
||||
|
||||
public static final EventId Tenant_Configuration_Query = new EventId(21000, "Tenant_Configuration_Query");
|
||||
public static final EventId Tenant_Configuration_Lookup = new EventId(21001, "Tenant_Configuration_Lookup");
|
||||
public static final EventId Tenant_Configuration_Persist = new EventId(21002, "Tenant_Configuration_Persist");
|
||||
public static final EventId Tenant_Configuration_Delete = new EventId(21003, "Tenant_Configuration_Delete");
|
||||
|
||||
// public static final EventId User_Notification_Preference_Query = new EventId(22000, "User_Notification_Preference_Query");
|
||||
// public static final EventId User_Notification_Preference_Lookup = new EventId(22001, "User_Notification_Preference_Lookup");
|
||||
// public static final EventId User_Notification_Preference_Persist = new EventId(22002, "User_Notification_Preference_Persist");
|
||||
// public static final EventId User_Notification_Preference_Delete = new EventId(22003, "User_Notification_Preference_Delete");
|
||||
//
|
||||
// public static final EventId Notification_Template_Query = new EventId(23000, "Notification_Template_Query");
|
||||
// public static final EventId Notification_Template_Lookup = new EventId(23001, "Notification_Template_Lookup");
|
||||
// public static final EventId Notification_Template_Persist = new EventId(23002, "Notification_Template_Persist");
|
||||
// public static final EventId Notification_Template_Delete = new EventId(23003, "Notification_Template_Delete");
|
||||
|
||||
public static final EventId Annotation_Query = new EventId(24000, "Annotation_Query");
|
||||
public static final EventId Annotation_Lookup = new EventId(24001, "Annotation_Lookup");
|
||||
public static final EventId Annotation_Persist = new EventId(24002, "Annotation_Persist");
|
||||
public static final EventId Annotation_Delete = new EventId(24003, "Annotation_Delete");
|
||||
|
||||
}
|
|
@ -1,8 +0,0 @@
|
|||
package gr.cite.annotation.authorization;
|
||||
|
||||
import java.util.EnumSet;
|
||||
|
||||
public enum AuthorizationFlags {
|
||||
None, Permission, Owner;
|
||||
public static final EnumSet<AuthorizationFlags> OwnerOrPermission = EnumSet.of(Owner, Permission);
|
||||
}
|
|
@ -1,6 +0,0 @@
|
|||
package gr.cite.annotation.authorization;
|
||||
|
||||
import gr.cite.commons.web.authz.policy.AuthorizationRequirement;
|
||||
|
||||
public class OwnedAuthorizationRequirement implements AuthorizationRequirement {
|
||||
}
|
|
@ -1,26 +0,0 @@
|
|||
package gr.cite.annotation.authorization;
|
||||
|
||||
import gr.cite.commons.web.authz.policy.AuthorizationResource;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
public class OwnedResource extends AuthorizationResource {
|
||||
private List<UUID> userIds;
|
||||
|
||||
public OwnedResource(UUID userId) {
|
||||
this(List.of(userId));
|
||||
}
|
||||
|
||||
public OwnedResource(List<UUID> userIds) {
|
||||
this.userIds = userIds;
|
||||
}
|
||||
|
||||
public List<UUID> getUserIds() {
|
||||
return userIds;
|
||||
}
|
||||
|
||||
public void setUserIds(List<UUID> userIds) {
|
||||
this.userIds = userIds;
|
||||
}
|
||||
}
|
|
@ -1,31 +0,0 @@
|
|||
package gr.cite.annotation.authorization;
|
||||
|
||||
public final class Permission {
|
||||
//User
|
||||
public static String BrowseUser = "BrowseUser";
|
||||
public static String EditUser = "EditUser";
|
||||
public static String DeleteUser = "DeleteUser";
|
||||
|
||||
//UserContactInfo
|
||||
public static String BrowseUserContactInfo = "BrowseUserContactInfo";
|
||||
public static String EditUserContactInfo = "EditUserContactInfo";
|
||||
public static String DeleteUserContactInfo = "DeleteUserContactInfo";
|
||||
|
||||
//Tenant
|
||||
public static String BrowseTenant = "BrowseTenant";
|
||||
public static String EditTenant = "EditTenant";
|
||||
public static String DeleteTenant = "DeleteTenant";
|
||||
public static String AllowNoTenant = "AllowNoTenant";
|
||||
|
||||
//Annotation
|
||||
public static final String BrowseAnnotation = "BrowseAnnotation";
|
||||
public static String EditAnnotation = "EditAnnotation";
|
||||
public static String DeleteAnnotation = "DeleteAnnotation";
|
||||
|
||||
public static final String BrowseTenantConfiguration = "BrowseTenantConfiguration";
|
||||
public static final String EditTenantConfiguration = "EditTenantConfiguration";
|
||||
|
||||
// UI Pages
|
||||
public static String ViewTenantConfigurationPage = "ViewTenantConfigurationPage";
|
||||
|
||||
}
|
|
@ -1,93 +0,0 @@
|
|||
package gr.cite.annotation.cache;
|
||||
|
||||
import gr.cite.annotation.config.formatting.FormattingUserprofileCacheOptions;
|
||||
import gr.cite.annotation.event.UserTouchedEvent;
|
||||
import gr.cite.tools.cache.CacheService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.event.EventListener;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Locale;
|
||||
import java.util.UUID;
|
||||
|
||||
@Service
|
||||
public class FormattingUserprofileCacheCacheService extends CacheService<FormattingUserprofileCacheCacheService.UserFormattingProfileCacheValue> {
|
||||
|
||||
public static class UserFormattingProfileCacheValue {
|
||||
|
||||
public UserFormattingProfileCacheValue() {
|
||||
}
|
||||
|
||||
public UserFormattingProfileCacheValue(UUID userId, String zone, String culture, String language) {
|
||||
this.userId = userId;
|
||||
this.zone = zone;
|
||||
this.culture = culture;
|
||||
this.language = language;
|
||||
}
|
||||
|
||||
private UUID userId;
|
||||
private String zone;
|
||||
private String culture;
|
||||
private String language;
|
||||
|
||||
public String getZone() {
|
||||
return zone;
|
||||
}
|
||||
|
||||
public void setZone(String zone) {
|
||||
this.zone = zone;
|
||||
}
|
||||
|
||||
public String getCulture() {
|
||||
return culture;
|
||||
}
|
||||
|
||||
public void setCulture(String culture) {
|
||||
this.culture = culture;
|
||||
}
|
||||
|
||||
public String getLanguage() {
|
||||
return language;
|
||||
}
|
||||
|
||||
public void setLanguage(String language) {
|
||||
this.language = language;
|
||||
}
|
||||
|
||||
public UUID getUserId() {
|
||||
return userId;
|
||||
}
|
||||
|
||||
public void setUserId(UUID userId) {
|
||||
this.userId = userId;
|
||||
}
|
||||
}
|
||||
|
||||
@Autowired
|
||||
public FormattingUserprofileCacheCacheService(FormattingUserprofileCacheOptions options) {
|
||||
super(options);
|
||||
}
|
||||
|
||||
@EventListener
|
||||
public void handleUserTouchedEvent(UserTouchedEvent event) {
|
||||
if (event.getUserId() != null) this.evict(this.buildKey(event.getUserId()));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Class<UserFormattingProfileCacheValue> valueClass() {
|
||||
return UserFormattingProfileCacheValue.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String keyOf(UserFormattingProfileCacheValue value) {
|
||||
return this.buildKey(value.getUserId());
|
||||
}
|
||||
|
||||
|
||||
public String buildKey(UUID userId) {
|
||||
return this.generateKey(new HashMap<>() {{
|
||||
put("$user_id$", userId.toString().toLowerCase(Locale.ROOT));
|
||||
}});
|
||||
}
|
||||
}
|
|
@ -1,43 +0,0 @@
|
|||
package gr.cite.annotation.common;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import gr.cite.tools.logging.LoggerService;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
public class JsonHandlingService {
|
||||
private static final LoggerService logger = new LoggerService(LoggerFactory.getLogger(JsonHandlingService.class));
|
||||
private final ObjectMapper objectMapper = new ObjectMapper();
|
||||
|
||||
public String toJson(Object item) throws JsonProcessingException {
|
||||
if (item == null) return null;
|
||||
return objectMapper.writeValueAsString(item);
|
||||
}
|
||||
|
||||
public String toJsonSafe(Object item) {
|
||||
if (item == null) return null;
|
||||
try {
|
||||
return objectMapper.writeValueAsString(item);
|
||||
} catch (Exception ex) {
|
||||
logger.error("Json Parsing Error: " + ex.getLocalizedMessage(), ex);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public <T> T fromJson(Class<T> type, String json) throws JsonProcessingException {
|
||||
if (json == null) return null;
|
||||
return objectMapper.readValue(json, type);
|
||||
}
|
||||
|
||||
public <T> T fromJsonSafe(Class<T> type, String json) {
|
||||
if (json == null) return null;
|
||||
try {
|
||||
return objectMapper.readValue(json, type);
|
||||
} catch (Exception ex) {
|
||||
logger.error("Json Parsing Error: " + ex.getLocalizedMessage(), ex);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,8 +0,0 @@
|
|||
package gr.cite.annotation.common;
|
||||
|
||||
public class StringUtils {
|
||||
|
||||
public static Boolean isNullOrEmpty(String string) {
|
||||
return string == null || string.isEmpty();
|
||||
}
|
||||
}
|
|
@ -1,117 +0,0 @@
|
|||
package gr.cite.annotation.common;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import gr.cite.annotation.common.types.xml.XmlSerializable;
|
||||
import jakarta.xml.bind.JAXBContext;
|
||||
import jakarta.xml.bind.JAXBException;
|
||||
import jakarta.xml.bind.Marshaller;
|
||||
import jakarta.xml.bind.Unmarshaller;
|
||||
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
|
||||
import org.springframework.context.annotation.Scope;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.w3c.dom.Document;
|
||||
import org.xml.sax.InputSource;
|
||||
import org.xml.sax.SAXException;
|
||||
|
||||
import javax.management.InvalidApplicationException;
|
||||
import javax.xml.parsers.DocumentBuilder;
|
||||
import javax.xml.parsers.DocumentBuilderFactory;
|
||||
import javax.xml.parsers.ParserConfigurationException;
|
||||
import javax.xml.transform.OutputKeys;
|
||||
import javax.xml.transform.Transformer;
|
||||
import javax.xml.transform.TransformerException;
|
||||
import javax.xml.transform.TransformerFactory;
|
||||
import javax.xml.transform.dom.DOMSource;
|
||||
import javax.xml.transform.stream.StreamResult;
|
||||
import java.io.IOException;
|
||||
import java.io.StringReader;
|
||||
import java.io.StringWriter;
|
||||
|
||||
@Component
|
||||
@Scope(value = ConfigurableBeanFactory.SCOPE_SINGLETON)
|
||||
public class XmlHandlingService {
|
||||
|
||||
public String generateXml(Document doc) throws TransformerException {
|
||||
TransformerFactory tFact = TransformerFactory.newInstance();
|
||||
Transformer trans = tFact.newTransformer();
|
||||
StringWriter writer = new StringWriter();
|
||||
StreamResult result = new StreamResult(writer);
|
||||
DOMSource source = new DOMSource(doc);
|
||||
trans.setOutputProperty(OutputKeys.INDENT, "yes");
|
||||
trans.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2");
|
||||
trans.transform(source, result);
|
||||
return writer.toString();
|
||||
}
|
||||
|
||||
public String toXml(Object item) throws JsonProcessingException, JAXBException, ParserConfigurationException, InvalidApplicationException, TransformerException {
|
||||
if (XmlSerializable.class.isAssignableFrom(item.getClass())){
|
||||
Document document = this.getDocument();
|
||||
if (document == null) throw new InvalidApplicationException("Can not create document");
|
||||
document.appendChild(((XmlSerializable)item).toXml(document));
|
||||
return this.generateXml(document);
|
||||
}
|
||||
|
||||
JAXBContext context = JAXBContext.newInstance(item.getClass());
|
||||
Marshaller marshaller = context.createMarshaller();
|
||||
StringWriter out = new StringWriter();
|
||||
marshaller.marshal(item, out);
|
||||
return out.toString();
|
||||
}
|
||||
|
||||
public String toXmlSafe(Object item) {
|
||||
if (item == null) return null;
|
||||
try {
|
||||
return this.toXml(item);
|
||||
} catch (Exception ex) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public <T> T fromXml(Class<T> type, String xmlString) throws JAXBException, InstantiationException, IllegalAccessException, ParserConfigurationException, IOException, SAXException {
|
||||
if (XmlSerializable.class.isAssignableFrom(type)){
|
||||
XmlSerializable<T> object = (XmlSerializable<T>)type.newInstance();
|
||||
return (T) object.fromXml(this.getDocument(xmlString).getDocumentElement());
|
||||
} else {
|
||||
JAXBContext jaxbContext = JAXBContext.newInstance(type);
|
||||
Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller();
|
||||
|
||||
return (T) jaxbUnmarshaller.unmarshal(new StringReader(xmlString));
|
||||
}
|
||||
}
|
||||
|
||||
public <T> T fromXmlSafe(Class<T> type, String xmlString) {
|
||||
if (xmlString == null) return null;
|
||||
try {
|
||||
return this.fromXml(type, xmlString);
|
||||
} catch (Exception ex) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
// public <T extends XmlSerializable<T>> T xmlSerializableFromXml(Class<T> type, String xmlString) throws JAXBException, InstantiationException, IllegalAccessException, ParserConfigurationException, IOException, SAXException {
|
||||
// T object = type.newInstance();
|
||||
// return (T) object.fromXml(this.getDocument(xmlString).getDocumentElement());
|
||||
// }
|
||||
//
|
||||
// public <T extends XmlSerializable<T>> T xmlSerializableFromXmlSafe(Class<T> type, String xmlString) {
|
||||
// if (xmlString == null) return null;
|
||||
// try {
|
||||
// return this.xmlSerializableFromXml(type, xmlString);
|
||||
// } catch (Exception ex) {
|
||||
// return null;
|
||||
// }
|
||||
// }
|
||||
|
||||
public Document getDocument(String xml) throws ParserConfigurationException, IOException, SAXException {
|
||||
DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
|
||||
DocumentBuilder docBuilder = docFactory.newDocumentBuilder();
|
||||
InputSource inputStream = new InputSource(new StringReader(xml));
|
||||
return docBuilder.parse(inputStream);
|
||||
}
|
||||
|
||||
public Document getDocument() throws ParserConfigurationException {
|
||||
DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
|
||||
DocumentBuilder docBuilder = docFactory.newDocumentBuilder();
|
||||
return docBuilder.newDocument();
|
||||
}
|
||||
}
|
|
@ -1,29 +0,0 @@
|
|||
package gr.cite.annotation.common.enums;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonValue;
|
||||
import gr.cite.annotation.data.conventers.DatabaseEnum;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
public enum ContactInfoType implements DatabaseEnum<Short> {
|
||||
Email((short) 0),
|
||||
MobilePhone((short) 1),
|
||||
LandLinePhone((short) 2);
|
||||
private final Short value;
|
||||
|
||||
ContactInfoType(Short value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
@JsonValue
|
||||
public Short getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
private static final Map<Short, ContactInfoType> map = EnumUtils.getEnumValueMap(ContactInfoType.class);
|
||||
|
||||
public static ContactInfoType of(Short i) {
|
||||
return map.get(i);
|
||||
}
|
||||
}
|
|
@ -1,16 +0,0 @@
|
|||
package gr.cite.annotation.common.enums;
|
||||
|
||||
import gr.cite.annotation.data.conventers.DatabaseEnum;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class EnumUtils {
|
||||
public static <EnumType extends Enum<EnumType> & DatabaseEnum<EnumValue>, EnumValue> Map<EnumValue, EnumType> getEnumValueMap(Class<EnumType> enumType){
|
||||
HashMap<EnumValue, EnumType> map = new HashMap<>();
|
||||
for (EnumType v : enumType.getEnumConstants()) {
|
||||
map.put(v.getValue(), v);
|
||||
}
|
||||
return map;
|
||||
}
|
||||
}
|
|
@ -1,28 +0,0 @@
|
|||
package gr.cite.annotation.common.enums;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonValue;
|
||||
import gr.cite.annotation.data.conventers.DatabaseEnum;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
public enum IsActive implements DatabaseEnum<Short> {
|
||||
Inactive((short) 0),
|
||||
Active((short) 1);
|
||||
|
||||
private final Short value;
|
||||
|
||||
IsActive(Short value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
@JsonValue
|
||||
public Short getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
private static final Map<Short, IsActive> map = EnumUtils.getEnumValueMap(IsActive.class);
|
||||
|
||||
public static IsActive of(Short i) {
|
||||
return map.get(i);
|
||||
}
|
||||
}
|
|
@ -1,29 +0,0 @@
|
|||
package gr.cite.annotation.common.enums;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonValue;
|
||||
import gr.cite.annotation.data.conventers.DatabaseEnum;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
public enum TenantConfigurationType implements DatabaseEnum<Short> {
|
||||
EMAIL_CLIENT_CONFIGURATION((short)1),
|
||||
DEFAULT_USER_LOCALE((short)3),
|
||||
NOTIFIER_LIST((short)4);
|
||||
|
||||
private final Short value;
|
||||
|
||||
TenantConfigurationType(Short value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
@JsonValue
|
||||
public Short getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
private static final Map<Short, TenantConfigurationType> map = EnumUtils.getEnumValueMap(TenantConfigurationType.class);
|
||||
|
||||
public static TenantConfigurationType of(Short i) {
|
||||
return map.get(i);
|
||||
}
|
||||
}
|
|
@ -1,58 +0,0 @@
|
|||
package gr.cite.annotation.common.lock;
|
||||
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
|
||||
@Service
|
||||
public class LockByKeyManager {
|
||||
|
||||
private static class LockWrapper {
|
||||
private final ReentrantLock lock = new ReentrantLock();
|
||||
private final AtomicInteger numberOfThreadsInQueue = new AtomicInteger(1);
|
||||
|
||||
private LockWrapper addThreadInQueue() {
|
||||
numberOfThreadsInQueue.incrementAndGet();
|
||||
return this;
|
||||
}
|
||||
|
||||
private int removeThreadFromQueue() {
|
||||
return numberOfThreadsInQueue.decrementAndGet();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static ConcurrentHashMap<String, LockWrapper> locks = new ConcurrentHashMap<String, LockWrapper>();
|
||||
|
||||
public void lock(String key) {
|
||||
LockWrapper lockWrapper = locks.compute(key, (k, v) -> v == null ? new LockWrapper() : v.addThreadInQueue());
|
||||
lockWrapper.lock.lock();
|
||||
}
|
||||
|
||||
public boolean tryLock(String key, long timeout, TimeUnit unit) throws InterruptedException {
|
||||
LockWrapper lockWrapper = null;
|
||||
try {
|
||||
lockWrapper = locks.compute(key, (k, v) -> v == null ? new LockWrapper() : v.addThreadInQueue());
|
||||
return lockWrapper.lock.tryLock(timeout, unit);
|
||||
} catch (Exception ex){
|
||||
if (lockWrapper != null && lockWrapper.removeThreadFromQueue() == 0) {
|
||||
// NB : We pass in the specific value to remove to handle the case where another thread would queue right before the removal
|
||||
locks.remove(key, lockWrapper);
|
||||
}
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
|
||||
public void unlock(String key) {
|
||||
LockWrapper lockWrapper = locks.get(key);
|
||||
lockWrapper.lock.unlock();
|
||||
if (lockWrapper.removeThreadFromQueue() == 0) {
|
||||
// NB : We pass in the specific value to remove to handle the case where another thread would queue right before the removal
|
||||
locks.remove(key, lockWrapper);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -1,125 +0,0 @@
|
|||
package gr.cite.annotation.common.scope.fake;
|
||||
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.web.context.request.RequestAttributes;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class FakeRequestAttributes implements RequestAttributes {
|
||||
private Map<String, Object> requestAttributeMap = new HashMap<>();
|
||||
private final Map<String, Runnable> requestDestructionCallbacks = new LinkedHashMap<>(8);
|
||||
private volatile boolean requestActive = true;
|
||||
|
||||
@Override
|
||||
public Object getAttribute(String name, int scope) {
|
||||
if (scope == RequestAttributes.SCOPE_REQUEST) {
|
||||
if (!isRequestActive()) {
|
||||
throw new IllegalStateException("Cannot ask for request attribute - request is not active anymore!");
|
||||
}
|
||||
return this.requestAttributeMap.get(name);
|
||||
} else {
|
||||
throw new IllegalStateException("Only " + RequestAttributes.SCOPE_REQUEST + " allowed for " + FakeRequestAttributes.class.getSimpleName());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAttribute(String name, Object value, int scope) {
|
||||
if (scope == RequestAttributes.SCOPE_REQUEST) {
|
||||
if (!isRequestActive()) {
|
||||
throw new IllegalStateException("Cannot set request attribute - request is not active anymore!");
|
||||
}
|
||||
this.requestAttributeMap.put(name, value);
|
||||
} else {
|
||||
throw new IllegalStateException("Only " + RequestAttributes.SCOPE_REQUEST + " allowed for " + FakeRequestAttributes.class.getSimpleName());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeAttribute(String name, int scope) {
|
||||
if (scope == RequestAttributes.SCOPE_REQUEST) {
|
||||
if (isRequestActive()) {
|
||||
removeRequestDestructionCallback(name);
|
||||
this.requestAttributeMap.remove(name);
|
||||
}
|
||||
} else {
|
||||
throw new IllegalStateException("Only " + RequestAttributes.SCOPE_REQUEST + " allowed for " + FakeRequestAttributes.class.getSimpleName());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] getAttributeNames(int scope) {
|
||||
if (scope == RequestAttributes.SCOPE_REQUEST) {
|
||||
if (!isRequestActive()) {
|
||||
throw new IllegalStateException("Cannot ask for request attributes - request is not active anymore!");
|
||||
}
|
||||
return this.requestAttributeMap.keySet().toArray(new String[0]);
|
||||
} else {
|
||||
throw new IllegalStateException("Only " + RequestAttributes.SCOPE_REQUEST + " allowed for " + FakeRequestAttributes.class.getSimpleName());
|
||||
}
|
||||
//return new String[0];
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerDestructionCallback(String name, Runnable callback, int scope) {
|
||||
if (scope == SCOPE_REQUEST) {
|
||||
registerRequestDestructionCallback(name, callback);
|
||||
} else {
|
||||
throw new IllegalStateException("Only " + RequestAttributes.SCOPE_REQUEST + " allowed for " + FakeRequestAttributes.class.getSimpleName());
|
||||
}
|
||||
}
|
||||
|
||||
protected final void registerRequestDestructionCallback(String name, Runnable callback) {
|
||||
Assert.notNull(name, "Name must not be null");
|
||||
Assert.notNull(callback, "Callback must not be null");
|
||||
synchronized (this.requestDestructionCallbacks) {
|
||||
this.requestDestructionCallbacks.put(name, callback);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object resolveReference(String key) {
|
||||
// Not supported
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSessionId() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getSessionMutex() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public void requestCompleted() {
|
||||
executeRequestDestructionCallbacks();
|
||||
for (String name : getAttributeNames(RequestAttributes.SCOPE_REQUEST)) {
|
||||
this.removeAttribute(name, RequestAttributes.SCOPE_REQUEST);
|
||||
}
|
||||
this.requestActive = false;
|
||||
}
|
||||
|
||||
private final boolean isRequestActive() {
|
||||
return this.requestActive;
|
||||
}
|
||||
|
||||
|
||||
private final void removeRequestDestructionCallback(String name) {
|
||||
Assert.notNull(name, "Name must not be null");
|
||||
synchronized (this.requestDestructionCallbacks) {
|
||||
this.requestDestructionCallbacks.remove(name);
|
||||
}
|
||||
}
|
||||
|
||||
private void executeRequestDestructionCallbacks() {
|
||||
synchronized (this.requestDestructionCallbacks) {
|
||||
for (Runnable runnable : this.requestDestructionCallbacks.values()) {
|
||||
runnable.run();
|
||||
}
|
||||
this.requestDestructionCallbacks.clear();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,40 +0,0 @@
|
|||
package gr.cite.annotation.common.scope.fake;
|
||||
|
||||
import org.springframework.web.context.request.RequestAttributes;
|
||||
import org.springframework.web.context.request.RequestContextHolder;
|
||||
|
||||
import java.io.Closeable;
|
||||
|
||||
public class FakeRequestScope implements Closeable {
|
||||
private RequestAttributes initialRequestAttributes = null;
|
||||
private FakeRequestAttributes currentRequestAttributes = null;
|
||||
boolean isInUse = false;
|
||||
|
||||
public FakeRequestScope() {
|
||||
this.reset();
|
||||
}
|
||||
|
||||
public void reset() {
|
||||
this.close();
|
||||
this.isInUse = true;
|
||||
|
||||
this.initialRequestAttributes = RequestContextHolder.getRequestAttributes();
|
||||
this.currentRequestAttributes = new FakeRequestAttributes();
|
||||
RequestContextHolder.setRequestAttributes(this.currentRequestAttributes);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
if (!this.isInUse) return;
|
||||
this.isInUse = false;
|
||||
|
||||
if (initialRequestAttributes != null) RequestContextHolder.setRequestAttributes(initialRequestAttributes);
|
||||
else RequestContextHolder.resetRequestAttributes();
|
||||
|
||||
if (currentRequestAttributes != null) currentRequestAttributes.requestCompleted();
|
||||
|
||||
this.initialRequestAttributes = null;
|
||||
this.currentRequestAttributes = null;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,9 +0,0 @@
|
|||
package gr.cite.annotation.common.scope.tenant;
|
||||
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
@Configuration
|
||||
@EnableConfigurationProperties(MultitenancyProperties.class)
|
||||
public class MultitenancyConfiguration {
|
||||
}
|
|
@ -1,16 +0,0 @@
|
|||
package gr.cite.annotation.common.scope.tenant;
|
||||
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
|
||||
@ConfigurationProperties(prefix = "tenant.multitenancy")
|
||||
public class MultitenancyProperties {
|
||||
private boolean isMultitenant;
|
||||
|
||||
public boolean isMultitenant() {
|
||||
return isMultitenant;
|
||||
}
|
||||
|
||||
public void setIsMultitenant(boolean multitenant) {
|
||||
isMultitenant = multitenant;
|
||||
}
|
||||
}
|
|
@ -1,86 +0,0 @@
|
|||
package gr.cite.annotation.common.scope.tenant;
|
||||
|
||||
import gr.cite.annotation.data.tenant.TenantScopedBaseEntity;
|
||||
import gr.cite.tools.logging.LoggerService;
|
||||
import jakarta.persistence.EntityManager;
|
||||
import org.hibernate.Session;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.web.context.annotation.RequestScope;
|
||||
|
||||
import javax.management.InvalidApplicationException;
|
||||
import java.util.UUID;
|
||||
|
||||
@Component
|
||||
@RequestScope
|
||||
public class TenantScope {
|
||||
public static final String TenantReplaceParameter = "::TenantCode::";
|
||||
public static final String TenantCodesClaimName = "TenantCodes";
|
||||
public static final String TenantClaimName = "x-tenant";
|
||||
|
||||
private MultitenancyProperties multitenancy;
|
||||
private static final LoggerService logger = new LoggerService(LoggerFactory.getLogger(TenantScope.class));
|
||||
private UUID tenant = null;
|
||||
private String tenantCode = null;
|
||||
private UUID initialTenant = null;
|
||||
private String initialTenantCode = null;
|
||||
|
||||
@Autowired
|
||||
public TenantScope(MultitenancyProperties multitenancy) {
|
||||
this.multitenancy = multitenancy;
|
||||
}
|
||||
|
||||
public Boolean isMultitenant() {
|
||||
return multitenancy.isMultitenant();
|
||||
}
|
||||
|
||||
public Boolean isSet() {
|
||||
if (!this.isMultitenant()) return true;
|
||||
return this.tenant != null;
|
||||
}
|
||||
|
||||
public UUID getTenant() throws InvalidApplicationException {
|
||||
if (!this.isMultitenant()) return null;
|
||||
if (this.tenant == null) throw new InvalidApplicationException("tenant not set");
|
||||
return this.tenant;
|
||||
}
|
||||
|
||||
public String getTenantCode() throws InvalidApplicationException {
|
||||
if (!this.isMultitenant()) return null;
|
||||
if (this.tenant == null) throw new InvalidApplicationException("tenant not set");
|
||||
return this.tenantCode;
|
||||
}
|
||||
|
||||
public void setTempTenant(EntityManager entityManager, UUID tenant, String tenantCode) {
|
||||
this.tenant = tenant;
|
||||
|
||||
if(this.tenant != null) {
|
||||
entityManager
|
||||
.unwrap(Session.class)
|
||||
.enableFilter(TenantScopedBaseEntity.tenantFilter).setParameter(TenantScopedBaseEntity.tenantFilterTenantParam, this.tenant.toString());
|
||||
}
|
||||
}
|
||||
|
||||
public void removeTempTenant(EntityManager entityManager) {
|
||||
this.tenant = this.initialTenant;
|
||||
this.tenantCode = this.initialTenantCode;
|
||||
if(this.initialTenant != null) {
|
||||
entityManager
|
||||
.unwrap(Session.class)
|
||||
.enableFilter(TenantScopedBaseEntity.tenantFilter).setParameter(TenantScopedBaseEntity.tenantFilterTenantParam, this.initialTenant.toString());
|
||||
}
|
||||
}
|
||||
|
||||
public void setTenant(UUID tenant, String tenantCode) {
|
||||
if (this.isMultitenant()) {
|
||||
this.tenant = tenant;
|
||||
this.initialTenant = tenant;
|
||||
this.tenantCode = tenantCode;
|
||||
this.initialTenantCode = tenantCode;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -1,8 +0,0 @@
|
|||
package gr.cite.annotation.common.scope.tenant;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
public interface TenantScoped {
|
||||
void setTenantId(UUID tenantId);
|
||||
UUID getTenantId();
|
||||
}
|
|
@ -1,34 +0,0 @@
|
|||
package gr.cite.annotation.common.scope.user;
|
||||
|
||||
import gr.cite.tools.logging.LoggerService;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.web.context.annotation.RequestScope;
|
||||
|
||||
import javax.management.InvalidApplicationException;
|
||||
import java.util.UUID;
|
||||
|
||||
@Component
|
||||
@RequestScope
|
||||
public class UserScope {
|
||||
private static final LoggerService logger = new LoggerService(LoggerFactory.getLogger(UserScope.class));
|
||||
private UUID userId = null;
|
||||
|
||||
public Boolean isSet(){
|
||||
return this.userId != null;
|
||||
}
|
||||
|
||||
public UUID getUserId() throws InvalidApplicationException {
|
||||
if (this.userId == null) throw new InvalidApplicationException("user not set");
|
||||
return this.userId;
|
||||
}
|
||||
|
||||
public UUID getUserIdSafe() {
|
||||
return this.userId;
|
||||
}
|
||||
|
||||
public void setUserId(UUID userId) {
|
||||
this.userId = userId;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,35 +0,0 @@
|
|||
package gr.cite.annotation.common.types.tenant;
|
||||
|
||||
|
||||
import jakarta.xml.bind.annotation.XmlAccessType;
|
||||
import jakarta.xml.bind.annotation.XmlAccessorType;
|
||||
import jakarta.xml.bind.annotation.XmlElement;
|
||||
import jakarta.xml.bind.annotation.XmlRootElement;
|
||||
|
||||
@XmlRootElement(name = "config")
|
||||
@XmlAccessorType(XmlAccessType.FIELD)
|
||||
public class TenantConfigEntity {
|
||||
|
||||
@XmlElement(name = "deposit-configuration")
|
||||
private TenantDepositConfigEntity deposit;
|
||||
|
||||
@XmlElement(name = "file-transformers-configuration")
|
||||
private TenantFileTransformersConfigEntity fileTransformers;
|
||||
|
||||
public TenantDepositConfigEntity getDeposit() {
|
||||
return deposit;
|
||||
}
|
||||
|
||||
public void setDeposit(TenantDepositConfigEntity deposit) {
|
||||
this.deposit = deposit;
|
||||
}
|
||||
|
||||
public TenantFileTransformersConfigEntity getFileTransformers() {
|
||||
return fileTransformers;
|
||||
}
|
||||
|
||||
public void setFileTransformers(TenantFileTransformersConfigEntity fileTransformers) {
|
||||
this.fileTransformers = fileTransformers;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,25 +0,0 @@
|
|||
package gr.cite.annotation.common.types.tenant;
|
||||
|
||||
import jakarta.xml.bind.annotation.XmlAccessType;
|
||||
import jakarta.xml.bind.annotation.XmlAccessorType;
|
||||
import jakarta.xml.bind.annotation.XmlElement;
|
||||
import jakarta.xml.bind.annotation.XmlElementWrapper;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@XmlAccessorType(XmlAccessType.FIELD)
|
||||
public class TenantDepositConfigEntity {
|
||||
|
||||
@XmlElementWrapper(name = "sources")
|
||||
@XmlElement(name = "source")
|
||||
private List<TenantSourceEntity> sources;
|
||||
|
||||
|
||||
public List<TenantSourceEntity> getSources() {
|
||||
return sources;
|
||||
}
|
||||
|
||||
public void setSources(List<TenantSourceEntity> sources) {
|
||||
this.sources = sources;
|
||||
}
|
||||
}
|
|
@ -1,24 +0,0 @@
|
|||
package gr.cite.annotation.common.types.tenant;
|
||||
|
||||
import jakarta.xml.bind.annotation.XmlAccessType;
|
||||
import jakarta.xml.bind.annotation.XmlAccessorType;
|
||||
import jakarta.xml.bind.annotation.XmlElement;
|
||||
import jakarta.xml.bind.annotation.XmlElementWrapper;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@XmlAccessorType(XmlAccessType.FIELD)
|
||||
public class TenantFileTransformersConfigEntity {
|
||||
|
||||
@XmlElementWrapper(name = "sources")
|
||||
@XmlElement(name = "source")
|
||||
private List<TenantSourceEntity> sources;
|
||||
|
||||
public List<TenantSourceEntity> getSources() {
|
||||
return sources;
|
||||
}
|
||||
|
||||
public void setSources(List<TenantSourceEntity> sources) {
|
||||
this.sources = sources;
|
||||
}
|
||||
}
|
|
@ -1,79 +0,0 @@
|
|||
package gr.cite.annotation.common.types.tenant;
|
||||
|
||||
import jakarta.xml.bind.annotation.XmlAccessType;
|
||||
import jakarta.xml.bind.annotation.XmlAccessorType;
|
||||
import jakarta.xml.bind.annotation.XmlElement;
|
||||
import jakarta.xml.bind.annotation.XmlElementWrapper;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@XmlAccessorType(XmlAccessType.FIELD)
|
||||
public class TenantSourceEntity {
|
||||
|
||||
@XmlElement(name = "url")
|
||||
private String url;
|
||||
|
||||
@XmlElementWrapper(name = "codes")
|
||||
@XmlElement(name = "code")
|
||||
private List<String> codes;
|
||||
|
||||
@XmlElement(name = "issuer-url")
|
||||
private String issuerUrl;
|
||||
|
||||
@XmlElement(name = "client-id")
|
||||
private String clientId;
|
||||
|
||||
@XmlElement(name = "client-secret")
|
||||
private String clientSecret;
|
||||
|
||||
@XmlElement(name = "scope")
|
||||
private String scope;
|
||||
|
||||
public String getUrl() {
|
||||
return url;
|
||||
}
|
||||
|
||||
public void setUrl(String url) {
|
||||
this.url = url;
|
||||
}
|
||||
|
||||
public List<String> getCodes() {
|
||||
return codes;
|
||||
}
|
||||
|
||||
public void setCodes(List<String> codes) {
|
||||
this.codes = codes;
|
||||
}
|
||||
|
||||
public String getIssuerUrl() {
|
||||
return issuerUrl;
|
||||
}
|
||||
|
||||
public void setIssuerUrl(String issuerUrl) {
|
||||
this.issuerUrl = issuerUrl;
|
||||
}
|
||||
|
||||
public String getClientId() {
|
||||
return clientId;
|
||||
}
|
||||
|
||||
public void setClientId(String clientId) {
|
||||
this.clientId = clientId;
|
||||
}
|
||||
|
||||
public String getClientSecret() {
|
||||
return clientSecret;
|
||||
}
|
||||
|
||||
public void setClientSecret(String clientSecret) {
|
||||
this.clientSecret = clientSecret;
|
||||
}
|
||||
|
||||
public String getScope() {
|
||||
return scope;
|
||||
}
|
||||
|
||||
public void setScope(String scope) {
|
||||
this.scope = scope;
|
||||
}
|
||||
}
|
|
@ -1,37 +0,0 @@
|
|||
package gr.cite.annotation.common.types.tenantconfiguration;
|
||||
|
||||
public class DefaultUserLocaleConfigurationDataContainer {
|
||||
|
||||
public static class Field {
|
||||
public static final String LANGUAGE = "language";
|
||||
public static final String TIME_ZONE = "timeZone";
|
||||
public static final String CULTURE = "culture";
|
||||
}
|
||||
private String language;
|
||||
private String timeZone;
|
||||
private String culture;
|
||||
|
||||
public String getLanguage() {
|
||||
return language;
|
||||
}
|
||||
|
||||
public void setLanguage(String language) {
|
||||
this.language = language;
|
||||
}
|
||||
|
||||
public String getTimeZone() {
|
||||
return timeZone;
|
||||
}
|
||||
|
||||
public void setTimeZone(String timeZone) {
|
||||
this.timeZone = timeZone;
|
||||
}
|
||||
|
||||
public String getCulture() {
|
||||
return culture;
|
||||
}
|
||||
|
||||
public void setCulture(String culture) {
|
||||
this.culture = culture;
|
||||
}
|
||||
}
|
|
@ -1,87 +0,0 @@
|
|||
package gr.cite.annotation.common.types.tenantconfiguration;
|
||||
|
||||
public class EmailClientConfigurationDataContainer {
|
||||
|
||||
public static class Field {
|
||||
public static final String REQUIRE_CREDENTIALS = "requireCredentials";
|
||||
public static final String ENABLE_SSL = "enableSSL";
|
||||
public static final String CERTIFICATE_PATH = "certificatePath";
|
||||
public static final String HOST_SERVER = "hostServer";
|
||||
public static final String HOST_PORT_NO = "hostPortNo";
|
||||
public static final String EMAIL_ADDRESS = "emailAddress";
|
||||
public static final String EMAIL_USER_NAME = "emailUserName";
|
||||
public static final String EMAIL_PASSWORD = "emailPassword";
|
||||
}
|
||||
private Boolean requireCredentials;
|
||||
private Boolean enableSSL;
|
||||
private String certificatePath;
|
||||
private String hostServer;
|
||||
private Integer hostPortNo;
|
||||
private String emailAddress;
|
||||
private String emailUserName;
|
||||
private String emailPassword;
|
||||
|
||||
public Boolean getRequireCredentials() {
|
||||
return requireCredentials;
|
||||
}
|
||||
|
||||
public void setRequireCredentials(Boolean requireCredentials) {
|
||||
this.requireCredentials = requireCredentials;
|
||||
}
|
||||
|
||||
public Boolean getEnableSSL() {
|
||||
return enableSSL;
|
||||
}
|
||||
|
||||
public void setEnableSSL(Boolean enableSSL) {
|
||||
this.enableSSL = enableSSL;
|
||||
}
|
||||
|
||||
public String getCertificatePath() {
|
||||
return certificatePath;
|
||||
}
|
||||
|
||||
public void setCertificatePath(String certificatePath) {
|
||||
this.certificatePath = certificatePath;
|
||||
}
|
||||
|
||||
public String getHostServer() {
|
||||
return hostServer;
|
||||
}
|
||||
|
||||
public void setHostServer(String hostServer) {
|
||||
this.hostServer = hostServer;
|
||||
}
|
||||
|
||||
public Integer getHostPortNo() {
|
||||
return hostPortNo;
|
||||
}
|
||||
|
||||
public void setHostPortNo(Integer hostPortNo) {
|
||||
this.hostPortNo = hostPortNo;
|
||||
}
|
||||
|
||||
public String getEmailAddress() {
|
||||
return emailAddress;
|
||||
}
|
||||
|
||||
public void setEmailAddress(String emailAddress) {
|
||||
this.emailAddress = emailAddress;
|
||||
}
|
||||
|
||||
public String getEmailUserName() {
|
||||
return emailUserName;
|
||||
}
|
||||
|
||||
public void setEmailUserName(String emailUserName) {
|
||||
this.emailUserName = emailUserName;
|
||||
}
|
||||
|
||||
public String getEmailPassword() {
|
||||
return emailPassword;
|
||||
}
|
||||
|
||||
public void setEmailPassword(String emailPassword) {
|
||||
this.emailPassword = emailPassword;
|
||||
}
|
||||
}
|
|
@ -1,60 +0,0 @@
|
|||
package gr.cite.annotation.common.types.user;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
public class AdditionalInfoEntity {
|
||||
private String avatarUrl;
|
||||
private String timezone;
|
||||
private String culture;
|
||||
private String language;
|
||||
private String roleOrganization;
|
||||
private UUID organizationId;
|
||||
|
||||
public String getAvatarUrl() {
|
||||
return avatarUrl;
|
||||
}
|
||||
|
||||
public void setAvatarUrl(String avatarUrl) {
|
||||
this.avatarUrl = avatarUrl;
|
||||
}
|
||||
|
||||
public String getTimezone() {
|
||||
return timezone;
|
||||
}
|
||||
|
||||
public void setTimezone(String timezone) {
|
||||
this.timezone = timezone;
|
||||
}
|
||||
|
||||
public String getCulture() {
|
||||
return culture;
|
||||
}
|
||||
|
||||
public void setCulture(String culture) {
|
||||
this.culture = culture;
|
||||
}
|
||||
|
||||
public String getLanguage() {
|
||||
return language;
|
||||
}
|
||||
|
||||
public void setLanguage(String language) {
|
||||
this.language = language;
|
||||
}
|
||||
|
||||
public UUID getOrganizationId() {
|
||||
return organizationId;
|
||||
}
|
||||
|
||||
public void setOrganizationId(UUID organizationId) {
|
||||
this.organizationId = organizationId;
|
||||
}
|
||||
|
||||
public String getRoleOrganization() {
|
||||
return roleOrganization;
|
||||
}
|
||||
|
||||
public void setRoleOrganization(String roleOrganization) {
|
||||
this.roleOrganization = roleOrganization;
|
||||
}
|
||||
}
|
|
@ -1,87 +0,0 @@
|
|||
package gr.cite.annotation.common.types.xml;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.Element;
|
||||
import org.w3c.dom.Node;
|
||||
import org.w3c.dom.NodeList;
|
||||
import org.xml.sax.InputSource;
|
||||
import org.xml.sax.SAXException;
|
||||
|
||||
import javax.xml.parsers.DocumentBuilder;
|
||||
import javax.xml.parsers.DocumentBuilderFactory;
|
||||
import javax.xml.parsers.ParserConfigurationException;
|
||||
import javax.xml.transform.OutputKeys;
|
||||
import javax.xml.transform.Transformer;
|
||||
import javax.xml.transform.TransformerException;
|
||||
import javax.xml.transform.TransformerFactory;
|
||||
import javax.xml.transform.dom.DOMSource;
|
||||
import javax.xml.transform.stream.StreamResult;
|
||||
import java.io.IOException;
|
||||
import java.io.StringReader;
|
||||
import java.io.StringWriter;
|
||||
|
||||
|
||||
public class XmlBuilder {
|
||||
private static final Logger logger = LoggerFactory.getLogger(XmlBuilder.class);
|
||||
|
||||
public static Document getDocument() {
|
||||
DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
|
||||
DocumentBuilder docBuilder;
|
||||
try {
|
||||
docBuilder = docFactory.newDocumentBuilder();
|
||||
Document doc = docBuilder.newDocument();
|
||||
return doc;
|
||||
} catch (ParserConfigurationException e) {
|
||||
// TODO Auto-generated catch block
|
||||
logger.error(e.getMessage(), e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static String generateXml(Document doc) {
|
||||
TransformerFactory tFact = TransformerFactory.newInstance();
|
||||
Transformer trans;
|
||||
try {
|
||||
trans = tFact.newTransformer();
|
||||
StringWriter writer = new StringWriter();
|
||||
StreamResult result = new StreamResult(writer);
|
||||
DOMSource source = new DOMSource(doc);
|
||||
trans.setOutputProperty(OutputKeys.INDENT, "yes");
|
||||
trans.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2");
|
||||
trans.transform(source, result);
|
||||
return writer.toString();
|
||||
} catch (TransformerException e) {
|
||||
// TODO Auto-generated catch block
|
||||
logger.error(e.getMessage(), e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static Document fromXml(String xml) {
|
||||
DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
|
||||
DocumentBuilder docBuilder;
|
||||
try {
|
||||
docBuilder = docFactory.newDocumentBuilder();
|
||||
InputSource inputStream = new InputSource(new StringReader(xml));
|
||||
Document doc = docBuilder.parse(inputStream);
|
||||
return doc;
|
||||
} catch (ParserConfigurationException | SAXException | IOException e) {
|
||||
// TODO Auto-generated catch block
|
||||
logger.error(e.getMessage(), e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static Element getNodeFromListByTagName(NodeList list, String tagName) {
|
||||
for (int temp = 0; temp < list.getLength(); temp++) {
|
||||
Node element = list.item(temp);
|
||||
if (element.getNodeType() == Node.ELEMENT_NODE) {
|
||||
if (element.getNodeName().equals(tagName)) return (Element) element;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
|
@ -1,11 +0,0 @@
|
|||
package gr.cite.annotation.common.types.xml;
|
||||
|
||||
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.Element;
|
||||
|
||||
public interface XmlSerializable<T> {
|
||||
Element toXml(Document doc);
|
||||
|
||||
T fromXml(Element item);
|
||||
}
|
|
@ -1,63 +0,0 @@
|
|||
package gr.cite.annotation.common.validation;
|
||||
|
||||
import gr.cite.annotation.convention.ConventionService;
|
||||
import gr.cite.annotation.errorcode.ErrorThesaurusProperties;
|
||||
import gr.cite.tools.exception.MyValidationException;
|
||||
import gr.cite.tools.validation.AbstractValidator;
|
||||
import gr.cite.tools.validation.ValidationResult;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
public abstract class BaseValidator<T> extends AbstractValidator<T> {
|
||||
protected final ConventionService conventionService;
|
||||
protected final ErrorThesaurusProperties errors;
|
||||
|
||||
protected BaseValidator(ConventionService conventionService, ErrorThesaurusProperties errors) {
|
||||
this.conventionService = conventionService;
|
||||
this.errors = errors;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void validateForce(Object target) {
|
||||
this.validate(target);
|
||||
ValidationResult result = result();
|
||||
if (!result.isValid()) {
|
||||
List<Map.Entry<String, List<String>>> errorsMap = this.flattenValidationResult();
|
||||
throw new MyValidationException(this.errors.getModelValidation().getCode(), errorsMap);
|
||||
}
|
||||
}
|
||||
|
||||
protected Boolean isValidGuid(UUID guid) {
|
||||
return this.conventionService.isValidGuid(guid);
|
||||
}
|
||||
|
||||
protected Boolean isValidHash(String hash) {
|
||||
return this.conventionService.isValidHash(hash);
|
||||
}
|
||||
|
||||
protected Boolean isEmpty(String value) {
|
||||
return this.conventionService.isNullOrEmpty(value);
|
||||
}
|
||||
protected Boolean isListNullOrEmpty(List<?> value) {
|
||||
return this.conventionService.isListNullOrEmpty(value);
|
||||
}
|
||||
protected Boolean isNull(Object value) {
|
||||
return value == null;
|
||||
}
|
||||
|
||||
protected Boolean isNull(Collection<?> value) {
|
||||
return value == null;
|
||||
}
|
||||
|
||||
protected Boolean lessEqualLength(String value, int size) {
|
||||
return value.length() <= size;
|
||||
}
|
||||
|
||||
protected Boolean lessEqual(Integer value, int target) {
|
||||
return value <= target;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,20 +0,0 @@
|
|||
package gr.cite.annotation.config.db;
|
||||
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.boot.context.properties.bind.ConstructorBinding;
|
||||
|
||||
@ConfigurationProperties(prefix = "naming-strategy")
|
||||
public class NamingStrategyProperties {
|
||||
|
||||
private final String prefix;
|
||||
|
||||
@ConstructorBinding
|
||||
public NamingStrategyProperties(String prefix) {
|
||||
this.prefix = prefix;
|
||||
}
|
||||
|
||||
public String getPrefix() {
|
||||
return prefix;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,28 +0,0 @@
|
|||
package gr.cite.annotation.config.db;
|
||||
|
||||
import gr.cite.annotation.common.StringUtils;
|
||||
import org.hibernate.boot.model.naming.Identifier;
|
||||
import org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl;
|
||||
import org.hibernate.engine.jdbc.env.spi.JdbcEnvironment;
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
@EnableConfigurationProperties({NamingStrategyProperties.class})
|
||||
public class PrefixPhysicalNamingStrategy extends PhysicalNamingStrategyStandardImpl {
|
||||
|
||||
private final NamingStrategyProperties namingStrategyProperties;
|
||||
|
||||
public PrefixPhysicalNamingStrategy(NamingStrategyProperties namingStrategyProperties) {
|
||||
this.namingStrategyProperties = namingStrategyProperties;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Identifier toPhysicalTableName(Identifier logicalName, JdbcEnvironment context) {
|
||||
if (StringUtils.isNullOrEmpty(namingStrategyProperties.getPrefix()))
|
||||
return super.toPhysicalTableName(logicalName, context);
|
||||
Identifier identifier = new Identifier(namingStrategyProperties.getPrefix() + logicalName.getText(), logicalName.isQuoted());
|
||||
return super.toPhysicalTableName(identifier, context);
|
||||
}
|
||||
|
||||
}
|
|
@ -1,9 +0,0 @@
|
|||
package gr.cite.annotation.config.email;
|
||||
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
@Configuration
|
||||
@EnableConfigurationProperties(EmailProperties.class)
|
||||
public class EmailConfig {
|
||||
}
|
|
@ -1,17 +0,0 @@
|
|||
package gr.cite.annotation.config.email;
|
||||
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
|
||||
@ConfigurationProperties(prefix = "email")
|
||||
public class EmailProperties {
|
||||
|
||||
private final String address;
|
||||
|
||||
public EmailProperties(String address) {
|
||||
this.address = address;
|
||||
}
|
||||
|
||||
public String getAddress() {
|
||||
return address;
|
||||
}
|
||||
}
|
|
@ -1,9 +0,0 @@
|
|||
package gr.cite.annotation.config.formatting;
|
||||
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
@Configuration
|
||||
@EnableConfigurationProperties(FormattingServiceProperties.class)
|
||||
public class FormattingServiceConfiguration {
|
||||
}
|
|
@ -1,38 +0,0 @@
|
|||
package gr.cite.annotation.config.formatting;
|
||||
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
|
||||
@ConfigurationProperties(prefix = "formatting.options")
|
||||
public class FormattingServiceProperties {
|
||||
|
||||
private final String integerFormat;
|
||||
|
||||
private final String decimalFormat;
|
||||
|
||||
private final String dateTimeFormat;
|
||||
|
||||
private final Integer decimalDigitsRound;
|
||||
|
||||
public FormattingServiceProperties(String integerFormat, String decimalFormat, String dateTimeFormat, Integer decimalDigitsRound) {
|
||||
this.integerFormat = integerFormat;
|
||||
this.decimalFormat = decimalFormat;
|
||||
this.dateTimeFormat = dateTimeFormat;
|
||||
this.decimalDigitsRound = decimalDigitsRound;
|
||||
}
|
||||
|
||||
public String getIntegerFormat() {
|
||||
return integerFormat;
|
||||
}
|
||||
|
||||
public String getDecimalFormat() {
|
||||
return decimalFormat;
|
||||
}
|
||||
|
||||
public String getDateTimeFormat() {
|
||||
return dateTimeFormat;
|
||||
}
|
||||
|
||||
public Integer getDecimalDigitsRound() {
|
||||
return decimalDigitsRound;
|
||||
}
|
||||
}
|
|
@ -1,10 +0,0 @@
|
|||
package gr.cite.annotation.config.formatting;
|
||||
|
||||
import gr.cite.tools.cache.CacheOptions;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
@Configuration
|
||||
@ConfigurationProperties(prefix = "cache.formatting-user-profile-cache")
|
||||
public class FormattingUserprofileCacheOptions extends CacheOptions {
|
||||
}
|
|
@ -1,41 +0,0 @@
|
|||
package gr.cite.annotation.convention;
|
||||
|
||||
import gr.cite.tools.exception.MyApplicationException;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
import java.util.function.Function;
|
||||
|
||||
public interface ConventionService {
|
||||
Boolean isValidId(Integer id);
|
||||
|
||||
Boolean isValidGuid(UUID guid);
|
||||
|
||||
Boolean isValidUUID(String str);
|
||||
UUID parseUUIDSafe(String str);
|
||||
|
||||
Boolean isValidHash(String hash);
|
||||
|
||||
String hashValue(Object value) throws MyApplicationException;
|
||||
|
||||
String limit(String text, int maxLength);
|
||||
|
||||
String truncate(String text, int maxLength);
|
||||
|
||||
UUID getEmptyUUID();
|
||||
|
||||
boolean isNullOrEmpty(String value);
|
||||
|
||||
boolean isListNullOrEmpty(List value);
|
||||
|
||||
String stringEmpty();
|
||||
|
||||
String asPrefix(String name);
|
||||
|
||||
String asIndexerPrefix(String part);
|
||||
|
||||
String asIndexer(String... names);
|
||||
|
||||
<K, V> Map<K, List<V>> toDictionaryOfList(List<V> items, Function<V, K> keySelector);
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue