Pull request #673: RED-3800 fix permissions
Merge in RED/persistence-service from RED-3800-fix-permissions to master * commit '4b941397df3d4de38923569ac983f0c35d9276dd': RED-3800 - sync custom permissions and KC users based on CRON and do it more often
This commit is contained in:
commit
534efa138d
@ -1,8 +1,15 @@
|
||||
package com.iqser.red.persistence.service.v1.external.api.impl.controller;
|
||||
|
||||
import java.time.OffsetDateTime;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.quartz.JobDataMap;
|
||||
import org.quartz.JobKey;
|
||||
import org.quartz.Scheduler;
|
||||
import org.quartz.SchedulerException;
|
||||
import org.quartz.Trigger;
|
||||
import org.quartz.TriggerBuilder;
|
||||
import org.springframework.core.Ordered;
|
||||
import org.springframework.core.annotation.Order;
|
||||
import org.springframework.http.HttpStatus;
|
||||
@ -23,11 +30,22 @@ import com.iqser.red.service.persistence.management.v1.processor.exception.BadRe
|
||||
import com.iqser.red.service.persistence.management.v1.processor.exception.ConflictException;
|
||||
import com.iqser.red.service.persistence.management.v1.processor.exception.NotAllowedException;
|
||||
import com.iqser.red.service.persistence.management.v1.processor.exception.NotFoundException;
|
||||
import com.iqser.red.service.persistence.management.v1.processor.service.job.AutomaticAnalysisJob;
|
||||
import com.iqser.red.service.persistence.management.v1.processor.service.job.SyncUserPermissionsJob;
|
||||
import com.iqser.red.service.persistence.management.v1.processor.utils.multitenancy.TenantContext;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
@Slf4j
|
||||
@RequiredArgsConstructor
|
||||
@RestControllerAdvice
|
||||
@Order(Ordered.HIGHEST_PRECEDENCE)
|
||||
public class ExternalControllerAdvice {
|
||||
|
||||
private final Scheduler scheduler;
|
||||
|
||||
|
||||
@ResponseBody
|
||||
@ResponseStatus(value = HttpStatus.NOT_FOUND)
|
||||
@ExceptionHandler(value = NotFoundException.class)
|
||||
@ -76,6 +94,22 @@ public class ExternalControllerAdvice {
|
||||
}
|
||||
|
||||
|
||||
@ResponseBody
|
||||
@ResponseStatus(value = HttpStatus.INTERNAL_SERVER_ERROR)
|
||||
@ExceptionHandler({org.springframework.security.acls.model.NotFoundException.class})
|
||||
public ErrorMessage handleACLNotFound(org.springframework.security.acls.model.NotFoundException e) {
|
||||
|
||||
// in case this error occurs on a rest request / force trigger the sync job
|
||||
try {
|
||||
scheduler.triggerJob(new JobKey("SyncUserPermissionsJob"), new JobDataMap(Map.of("tenantId", TenantContext.getTenantId())));
|
||||
} catch (SchedulerException ex) {
|
||||
log.debug("Failed to force trigger SyncUserPermissionsJob", ex);
|
||||
}
|
||||
|
||||
return new ErrorMessage(OffsetDateTime.now(), e.getMessage());
|
||||
}
|
||||
|
||||
|
||||
@ResponseBody
|
||||
@ResponseStatus(value = HttpStatus.BAD_REQUEST)
|
||||
@ExceptionHandler({MethodArgumentNotValidException.class})
|
||||
|
||||
@ -14,7 +14,9 @@ import org.springframework.context.annotation.Configuration;
|
||||
import com.iqser.red.service.persistence.management.v1.processor.service.job.AutomaticAnalysisJob;
|
||||
import com.iqser.red.service.persistence.management.v1.processor.service.job.DeletedFilesCleanupJob;
|
||||
import com.iqser.red.service.persistence.management.v1.processor.service.job.DownloadCleanupJob;
|
||||
import com.iqser.red.service.persistence.management.v1.processor.service.job.KeyCloakUserSyncJob;
|
||||
import com.iqser.red.service.persistence.management.v1.processor.service.job.SendNotificationEmailJob;
|
||||
import com.iqser.red.service.persistence.management.v1.processor.service.job.SyncUserPermissionsJob;
|
||||
|
||||
@Configuration
|
||||
public class CreateJobsConfiguration {
|
||||
@ -91,6 +93,54 @@ public class CreateJobsConfiguration {
|
||||
}
|
||||
|
||||
|
||||
@Bean
|
||||
public Trigger keyCloakUserSyncJobTrigger() throws ParseException {
|
||||
|
||||
return TriggerBuilder.newTrigger()
|
||||
.forJob(keyCloakUserSyncJobDetail())
|
||||
.withIdentity("KeyCloakUserSyncJobTrigger")
|
||||
.withDescription("Triggers KeyCloakUserSyncJob every 2 minutes")
|
||||
.withSchedule(CronScheduleBuilder.cronSchedule(new CronExpression("0 */2 * * * ?")))
|
||||
.build();
|
||||
}
|
||||
|
||||
|
||||
@Bean
|
||||
public JobDetail keyCloakUserSyncJobDetail() {
|
||||
|
||||
return JobBuilder.newJob()
|
||||
.ofType(KeyCloakUserSyncJob.class)
|
||||
.storeDurably()
|
||||
.withIdentity("KeyCloakUserSyncJob")
|
||||
.withDescription("Sync KC Users in case of deletions in KC")
|
||||
.build();
|
||||
}
|
||||
|
||||
|
||||
@Bean
|
||||
public Trigger syncUserPermissionsJobTrigger() throws ParseException {
|
||||
|
||||
return TriggerBuilder.newTrigger()
|
||||
.forJob(syncUserPermissionsJobDetail())
|
||||
.withIdentity("SyncUserPermissionsJobTrigger")
|
||||
.withDescription("Triggers SyncUserPermissionsJob every 2 minutes")
|
||||
.withSchedule(CronScheduleBuilder.cronSchedule(new CronExpression("0 */2 * * * ?")))
|
||||
.build();
|
||||
}
|
||||
|
||||
|
||||
@Bean
|
||||
public JobDetail syncUserPermissionsJobDetail() {
|
||||
|
||||
return JobBuilder.newJob()
|
||||
.ofType(SyncUserPermissionsJob.class)
|
||||
.storeDurably()
|
||||
.withIdentity("SyncUserPermissionsJob")
|
||||
.withDescription("Sync custom permissions for ACL")
|
||||
.build();
|
||||
}
|
||||
|
||||
|
||||
@Bean
|
||||
public Trigger downloadCleanupJobTrigger() throws ParseException {
|
||||
|
||||
|
||||
@ -1,21 +1,26 @@
|
||||
package com.iqser.red.service.persistence.management.v1.processor.job;
|
||||
package com.iqser.red.service.persistence.management.v1.processor.service.job;
|
||||
|
||||
import org.quartz.Job;
|
||||
import org.quartz.JobExecutionContext;
|
||||
import org.quartz.JobExecutionException;
|
||||
import org.springframework.scheduling.annotation.Scheduled;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import com.iqser.red.service.persistence.management.v1.processor.job.KeyCloakUserSyncService;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
@Slf4j
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class KeyCloakUserSyncJob {
|
||||
public class KeyCloakUserSyncJob implements Job {
|
||||
|
||||
private final KeyCloakUserSyncService keyCloakUserSyncService;
|
||||
|
||||
|
||||
@Scheduled(fixedRate = 1000 * 60, initialDelay = 1000 * 60)
|
||||
public void syncCustomPermissions() {
|
||||
@Override
|
||||
public void execute(JobExecutionContext context) throws JobExecutionException {
|
||||
|
||||
keyCloakUserSyncService.syncUsersWithKC();
|
||||
}
|
||||
@ -1,5 +1,8 @@
|
||||
package com.iqser.red.service.persistence.management.v1.processor.acl.custom.job;
|
||||
package com.iqser.red.service.persistence.management.v1.processor.service.job;
|
||||
|
||||
import org.quartz.Job;
|
||||
import org.quartz.JobExecutionContext;
|
||||
import org.quartz.JobExecutionException;
|
||||
import org.springframework.scheduling.annotation.Scheduled;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@ -13,18 +16,24 @@ import lombok.extern.slf4j.Slf4j;
|
||||
@Slf4j
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class SyncUserPermissionsJob {
|
||||
public class SyncUserPermissionsJob implements Job {
|
||||
|
||||
private final CustomPermissionService customPermissionService;
|
||||
|
||||
private final TenantManagementService tenantManagementService;
|
||||
|
||||
|
||||
@Scheduled(fixedRate = 1000 * 60 * 10, initialDelay = 1000 * 60)
|
||||
public void syncCustomPermissions() {
|
||||
@Override
|
||||
public void execute(JobExecutionContext context) throws JobExecutionException {
|
||||
|
||||
var singleTenant = context.getJobDetail().getJobDataMap() != null ? context.getJobDetail().getJobDataMap().get("tenantId") : null;
|
||||
tenantManagementService.getTenants().forEach(tenant -> {
|
||||
TenantContext.setTenantId(tenant.getTenantId());
|
||||
customPermissionService.syncAllCustomPermissions();
|
||||
// if it's for a single tenant run only for that one, else run it for all tenants
|
||||
if (tenant.getTenantId().equals(singleTenant) || singleTenant == null) {
|
||||
TenantContext.setTenantId(tenant.getTenantId());
|
||||
customPermissionService.syncAllCustomPermissions();
|
||||
TenantContext.clear();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@ -97,8 +97,8 @@ multitenancy:
|
||||
password: ${PSQL_PASSWORD:redaction}
|
||||
platform: org.hibernate.dialect.PostgreSQL95Dialect
|
||||
hikari:
|
||||
maximumPoolSize: 5
|
||||
minimum-idle: 5
|
||||
maximumPoolSize: 2
|
||||
minimum-idle: 2
|
||||
data-source-properties:
|
||||
cachePrepStmts: true
|
||||
prepStmtCacheSize: 1000
|
||||
@ -109,7 +109,7 @@ multitenancy:
|
||||
datasource:
|
||||
driverClassName: org.postgresql.Driver
|
||||
hikari:
|
||||
maximumPoolSize: 5
|
||||
maximumPoolSize: 8
|
||||
minimum-idle: 5
|
||||
data-source-properties:
|
||||
cachePrepStmts: true
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user