Use enum interfaces for RollbackStrategy and SkipOrStopStrategy
This commit is contained in:
parent
620c9e84bb
commit
387abc30f8
6 changed files with 51 additions and 92 deletions
|
@ -5,8 +5,8 @@ import org.keycloak.component.ComponentModel;
|
|||
import org.keycloak.models.KeycloakSession;
|
||||
import sh.libre.scim.core.exceptions.ScimExceptionHandler;
|
||||
import sh.libre.scim.core.exceptions.ScimPropagationException;
|
||||
import sh.libre.scim.core.exceptions.SkipOrStopApproach;
|
||||
import sh.libre.scim.core.exceptions.SkipOrStopStrategy;
|
||||
import sh.libre.scim.core.exceptions.SkipOrStopStrategyFactory;
|
||||
import sh.libre.scim.storage.ScimEndpointConfigurationStorageProviderFactory;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
@ -34,9 +34,7 @@ public class ScimDispatcher {
|
|||
this.session = session;
|
||||
this.exceptionHandler = new ScimExceptionHandler(session);
|
||||
// By default, use a permissive Skip or Stop strategy
|
||||
this.skipOrStopStrategy = SkipOrStopStrategyFactory.create(
|
||||
SkipOrStopStrategyFactory.SkipOrStopApproach.ALWAYS_SKIP_AND_CONTINUE
|
||||
);
|
||||
this.skipOrStopStrategy = SkipOrStopApproach.ALWAYS_SKIP_AND_CONTINUE;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -0,0 +1,44 @@
|
|||
package sh.libre.scim.core.exceptions;
|
||||
|
||||
import sh.libre.scim.core.ScrimEndPointConfiguration;
|
||||
|
||||
|
||||
public enum RollbackApproach implements RollbackStrategy {
|
||||
ALWAYS_ROLLBACK {
|
||||
@Override
|
||||
public boolean shouldRollback(ScrimEndPointConfiguration configuration, ScimPropagationException e) {
|
||||
return true;
|
||||
}
|
||||
},
|
||||
NEVER_ROLLBACK {
|
||||
@Override
|
||||
public boolean shouldRollback(ScrimEndPointConfiguration configuration, ScimPropagationException e) {
|
||||
return false;
|
||||
}
|
||||
},
|
||||
CRITICAL_ONLY_ROLLBACK {
|
||||
@Override
|
||||
public boolean shouldRollback(ScrimEndPointConfiguration configuration, ScimPropagationException e) {
|
||||
if (e instanceof InconsistentScimMappingException) {
|
||||
// Occurs when mapping between a SCIM resource and a keycloak user failed (missing, ambiguous..)
|
||||
// Log can be sufficient here, no rollback required
|
||||
return false;
|
||||
}
|
||||
if (e instanceof UnexpectedScimDataException) {
|
||||
// Occurs when a SCIM endpoint sends invalid date (e.g. group with empty name, user without ids...)
|
||||
// No rollback required : we cannot recover. This needs to be fixed in the SCIM endpoint data
|
||||
return false;
|
||||
}
|
||||
if (e instanceof InvalidResponseFromScimEndpointException invalidResponseFromScimEndpointException) {
|
||||
return shouldRollbackBecauseOfResponse(invalidResponseFromScimEndpointException);
|
||||
}
|
||||
// Should not occur
|
||||
throw new IllegalStateException("Unkown ScimPropagationException", e);
|
||||
}
|
||||
|
||||
private boolean shouldRollbackBecauseOfResponse(InvalidResponseFromScimEndpointException e) {
|
||||
int httpStatus = e.getResponse().getHttpStatus();
|
||||
return httpStatus == 500;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,32 +0,0 @@
|
|||
package sh.libre.scim.core.exceptions;
|
||||
|
||||
import sh.libre.scim.core.ScrimEndPointConfiguration;
|
||||
|
||||
public class RollbackOnlyForCriticalErrorsStrategy implements RollbackStrategy {
|
||||
|
||||
private boolean shouldRollback(InvalidResponseFromScimEndpointException e) {
|
||||
int httpStatus = e.getResponse().getHttpStatus();
|
||||
return httpStatus == 500;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldRollback(ScrimEndPointConfiguration configuration, ScimPropagationException e) {
|
||||
if (e instanceof InvalidResponseFromScimEndpointException invalidResponseFromScimEndpointException) {
|
||||
return shouldRollback(invalidResponseFromScimEndpointException);
|
||||
}
|
||||
if (e instanceof InconsistentScimMappingException) {
|
||||
// Occurs when mapping between a SCIM resource and a keycloak user failed (missing, ambiguous..)
|
||||
// Log can be sufficient here, no rollback required
|
||||
return false;
|
||||
}
|
||||
if (e instanceof UnexpectedScimDataException) {
|
||||
// Occurs when a SCIM endpoint sends invalid date (e.g. group with empty name, user without ids...)
|
||||
// No rollback required : we cannot recover. This needs to be fixed in the SCIM endpoint data
|
||||
return false;
|
||||
}
|
||||
// Should not occur
|
||||
throw new IllegalStateException("Unkown ScimPropagationException", e);
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -1,36 +0,0 @@
|
|||
package sh.libre.scim.core.exceptions;
|
||||
|
||||
import sh.libre.scim.core.ScrimEndPointConfiguration;
|
||||
|
||||
public class RollbackStrategyFactory {
|
||||
|
||||
public static RollbackStrategy create(RollbackApproach approach) {
|
||||
// We could imagine more fine-grained rollback strategies (e.g. based on each Scim endpoint configuration)
|
||||
return switch (approach) {
|
||||
case ALWAYS_ROLLBACK -> new AlwaysRollbackStrategy();
|
||||
case NEVER_ROLLBACK -> new NeverRollbackStrategy();
|
||||
case CRITICAL_ONLY_ROLLBACK -> new RollbackOnlyForCriticalErrorsStrategy();
|
||||
};
|
||||
}
|
||||
|
||||
public enum RollbackApproach {
|
||||
ALWAYS_ROLLBACK, NEVER_ROLLBACK, CRITICAL_ONLY_ROLLBACK
|
||||
}
|
||||
|
||||
|
||||
private static final class AlwaysRollbackStrategy implements RollbackStrategy {
|
||||
|
||||
@Override
|
||||
public boolean shouldRollback(ScrimEndPointConfiguration configuration, ScimPropagationException e) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
private static final class NeverRollbackStrategy implements RollbackStrategy {
|
||||
|
||||
@Override
|
||||
public boolean shouldRollback(ScrimEndPointConfiguration configuration, ScimPropagationException e) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -17,7 +17,7 @@ public class ScimExceptionHandler {
|
|||
private final RollbackStrategy rollbackStrategy;
|
||||
|
||||
public ScimExceptionHandler(KeycloakSession session) {
|
||||
this(session, RollbackStrategyFactory.create(RollbackStrategyFactory.RollbackApproach.CRITICAL_ONLY_ROLLBACK));
|
||||
this(session, RollbackApproach.CRITICAL_ONLY_ROLLBACK);
|
||||
}
|
||||
|
||||
public ScimExceptionHandler(KeycloakSession session, RollbackStrategy rollbackStrategy) {
|
||||
|
|
|
@ -2,22 +2,9 @@ package sh.libre.scim.core.exceptions;
|
|||
|
||||
import sh.libre.scim.core.ScrimEndPointConfiguration;
|
||||
|
||||
public class SkipOrStopStrategyFactory {
|
||||
|
||||
public static SkipOrStopStrategy create(SkipOrStopApproach approach) {
|
||||
// We could imagine more fine-grained strategies (e.g. based on each Scim endpoint configuration)
|
||||
return switch (approach) {
|
||||
case ALWAYS_STOP -> new AlwaysStopStrategy();
|
||||
case ALWAYS_SKIP_AND_CONTINUE -> new AlwaysSkipAndContinueStrategy();
|
||||
};
|
||||
}
|
||||
|
||||
public enum SkipOrStopApproach {
|
||||
ALWAYS_SKIP_AND_CONTINUE, ALWAYS_STOP
|
||||
}
|
||||
|
||||
private static final class AlwaysStopStrategy implements SkipOrStopStrategy {
|
||||
|
||||
public enum SkipOrStopApproach implements SkipOrStopStrategy {
|
||||
ALWAYS_SKIP_AND_CONTINUE {
|
||||
@Override
|
||||
public boolean allowPartialSynchronizationWhenPushingToScim(ScrimEndPointConfiguration configuration) {
|
||||
return false;
|
||||
|
@ -42,10 +29,8 @@ public class SkipOrStopStrategyFactory {
|
|||
public boolean skipInvalidDataFromScimEndpoint(ScrimEndPointConfiguration configuration) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private static final class AlwaysSkipAndContinueStrategy implements SkipOrStopStrategy {
|
||||
|
||||
},
|
||||
ALWAYS_STOP {
|
||||
@Override
|
||||
public boolean allowPartialSynchronizationWhenPushingToScim(ScrimEndPointConfiguration configuration) {
|
||||
return true;
|
Loading…
Reference in a new issue