Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
io.quarkus.keycloak.pep.runtime.KeycloakPolicyEnforcerTenantConfigBuilder Maven / Gradle / Ivy
Go to download
Policy enforcer using Keycloak-managed permissions to control access to protected resources
package io.quarkus.keycloak.pep.runtime;
import static org.keycloak.representations.adapters.config.PolicyEnforcerConfig.EnforcementMode.ENFORCING;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.Set;
import java.util.function.BiConsumer;
import java.util.function.Function;
import java.util.random.RandomGenerator;
import org.keycloak.representations.adapters.config.PolicyEnforcerConfig.EnforcementMode;
import org.keycloak.representations.adapters.config.PolicyEnforcerConfig.ScopeEnforcementMode;
import io.quarkus.keycloak.pep.runtime.KeycloakPolicyEnforcerTenantConfig.KeycloakConfigPolicyEnforcer;
import io.quarkus.keycloak.pep.runtime.KeycloakPolicyEnforcerTenantConfig.KeycloakConfigPolicyEnforcer.ClaimInformationPointConfig;
import io.quarkus.keycloak.pep.runtime.KeycloakPolicyEnforcerTenantConfig.KeycloakConfigPolicyEnforcer.MethodConfig;
import io.quarkus.keycloak.pep.runtime.KeycloakPolicyEnforcerTenantConfig.KeycloakConfigPolicyEnforcer.PathCacheConfig;
import io.quarkus.keycloak.pep.runtime.KeycloakPolicyEnforcerTenantConfig.KeycloakConfigPolicyEnforcer.PathConfig;
import io.quarkus.runtime.util.StringUtil;
public final class KeycloakPolicyEnforcerTenantConfigBuilder {
private record KeycloakPolicyEnforcerTenantConfigImpl(int connectionPoolSize,
KeycloakConfigPolicyEnforcer policyEnforcer) implements KeycloakPolicyEnforcerTenantConfig {
}
private record KeycloakConfigPolicyEnforcerImpl(Map paths, EnforcementMode enforcementMode,
boolean lazyLoadPaths, boolean httpMethodAsScope, ClaimInformationPointConfig claimInformationPoint,
PathCacheConfig pathCache) implements KeycloakConfigPolicyEnforcer {
}
private record PathCacheConfigImpl(long lifespan, int maxEntries) implements PathCacheConfig {
}
private record ClaimInformationPointConfigImpl(Map> simpleConfig,
Map>> complexConfig) implements ClaimInformationPointConfig {
}
private record MethodConfigImpl(String method, List scopes,
ScopeEnforcementMode scopesEnforcementMode) implements MethodConfig {
}
private record PathConfigImpl(Optional name, Optional path, Optional> paths,
Map methods, EnforcementMode enforcementMode,
ClaimInformationPointConfig claimInformationPoint) implements PathConfig {
}
private final Map paths = new HashMap<>();
private int connectionPoolSize;
private EnforcementMode enforcementMode;
private boolean lazyLoadPaths;
private boolean httpMethodAsScope;
private ClaimInformationPointConfig claimInformationPoint;
private PathCacheConfig pathCache;
KeycloakPolicyEnforcerTenantConfigBuilder(KeycloakPolicyEnforcerTenantConfig originalConfig) {
connectionPoolSize = originalConfig.connectionPoolSize();
var policyEnforcer = originalConfig.policyEnforcer();
enforcementMode = policyEnforcer.enforcementMode();
lazyLoadPaths = policyEnforcer.lazyLoadPaths();
httpMethodAsScope = policyEnforcer.httpMethodAsScope();
claimInformationPoint = policyEnforcer.claimInformationPoint();
pathCache = policyEnforcer.pathCache();
policyEnforcer.paths().forEach(new BiConsumer() {
@Override
public void accept(String name, PathConfig pathConfig) {
paths.put(name, new PathConfigBuilderImpl(KeycloakPolicyEnforcerTenantConfigBuilder.this, pathConfig));
}
});
}
/**
* Creates immutable {@link KeycloakPolicyEnforcerTenantConfig}.
* Original builder can be safely re-used. The builder itself is not a thread-safe.
*
* @return KeycloakPolicyEnforcerTenantConfig
*/
public KeycloakPolicyEnforcerTenantConfig build() {
var pathConfigs = new HashMap();
paths.forEach(new BiConsumer() {
@Override
public void accept(String name, PathConfigBuilderImpl pathConfigBuilder) {
var pathConfig = new PathConfigImpl(Optional.ofNullable(pathConfigBuilder.name), Optional.empty(),
Optional.of(List.copyOf(pathConfigBuilder.paths)), Map.copyOf(pathConfigBuilder.methods),
pathConfigBuilder.enforcementMode, pathConfigBuilder.claimInformationPointConfig);
pathConfigs.put(name, pathConfig);
}
});
return new KeycloakPolicyEnforcerTenantConfigImpl(connectionPoolSize, new KeycloakConfigPolicyEnforcerImpl(
Map.copyOf(pathConfigs), enforcementMode, lazyLoadPaths, httpMethodAsScope, claimInformationPoint, pathCache));
}
public KeycloakPolicyEnforcerTenantConfigBuilder connectionPoolSize(int connectionPoolSize) {
this.connectionPoolSize = connectionPoolSize;
return this;
}
public KeycloakPolicyEnforcerTenantConfigBuilder enforcementMode(EnforcementMode enforcementMode) {
Objects.requireNonNull(enforcementMode);
this.enforcementMode = enforcementMode;
return this;
}
public KeycloakPolicyEnforcerTenantConfigBuilder lazyLoadPaths(boolean lazyLoadPaths) {
this.lazyLoadPaths = lazyLoadPaths;
return this;
}
public KeycloakPolicyEnforcerTenantConfigBuilder httpMethodAsScope(boolean httpMethodAsScope) {
this.httpMethodAsScope = httpMethodAsScope;
return this;
}
public KeycloakPolicyEnforcerTenantConfigBuilder pathCache(long lifespan) {
pathCache = new PathCacheConfigImpl(lifespan, pathCache == null ? 0 : pathCache.maxEntries());
return this;
}
public KeycloakPolicyEnforcerTenantConfigBuilder pathCache(int maxEntries) {
pathCache = new PathCacheConfigImpl(pathCache == null ? 0L : pathCache.lifespan(), maxEntries);
return this;
}
public KeycloakPolicyEnforcerTenantConfigBuilder pathCache(int maxEntries, long lifespan) {
pathCache = new PathCacheConfigImpl(lifespan, maxEntries);
return this;
}
public PathCacheConfigBuilder pathCache() {
return new PathCacheConfigBuilder(this);
}
public KeycloakPolicyEnforcerTenantConfigBuilder claimInformationPoint(Map> simpleConfig) {
claimInformationPoint = new ClaimInformationPointConfigImpl(simpleConfig == null ? Map.of() : Map.copyOf(simpleConfig),
claimInformationPoint == null ? Map.of() : claimInformationPoint.complexConfig());
return this;
}
public KeycloakPolicyEnforcerTenantConfigBuilder claimInformationPoint(Map> simpleConfig,
Map>> complexConfig) {
claimInformationPoint = new ClaimInformationPointConfigImpl(simpleConfig == null ? Map.of() : Map.copyOf(simpleConfig),
complexConfig == null ? Map.of() : Map.copyOf(complexConfig));
return this;
}
public ClaimInformationPointConfigBuilder claimInformationPoint() {
return new ClaimInformationPointConfigBuilder<>() {
@Override
public KeycloakPolicyEnforcerTenantConfigBuilder build() {
if (simpleConfig != null || complexConfig != null) {
return KeycloakPolicyEnforcerTenantConfigBuilder.this.claimInformationPoint(simpleConfig, complexConfig);
}
return KeycloakPolicyEnforcerTenantConfigBuilder.this;
}
};
}
/**
* Adds path with {@param name).
*
* @param name refers to the 'path1' from the 'quarkus.keycloak.policy-enforcer.paths."path1".*' config properties
* @param paths refers to the 'quarkus.keycloak.policy-enforcer.paths."paths".paths' configuration property
* @param enforcementMode enforcement mode
* @return PathConfigBuilder
*/
public PathConfigBuilder namedPaths(String name, EnforcementMode enforcementMode, String... paths) {
var pathConfigBuilder = namedPaths(name, paths);
pathConfigBuilder.enforcementMode(enforcementMode);
return pathConfigBuilder;
}
/**
* Adds path with {@param name).
*
* @param name refers to the 'path1' from the 'quarkus.keycloak.policy-enforcer.paths."path1".*' config properties
* @param paths refers to the 'quarkus.keycloak.policy-enforcer.paths."paths".paths' configuration property
* @return PathConfigBuilder
*/
public PathConfigBuilder namedPaths(String name, String... paths) {
Objects.requireNonNull(name);
final PathConfigBuilderImpl pathConfigBuilder = this.paths.computeIfAbsent(name,
new Function() {
@Override
public PathConfigBuilderImpl apply(String ignored) {
return new PathConfigBuilderImpl(KeycloakPolicyEnforcerTenantConfigBuilder.this, null);
}
});
if (paths != null && paths.length > 0) {
pathConfigBuilder.paths.addAll(Set.of(paths));
}
return pathConfigBuilder;
}
/**
* Adds paths with generated name.
*
* @param paths refers to the 'quarkus.keycloak.policy-enforcer.paths."paths".paths' configuration property
* @param enforcementMode enforcement mode
* @return PathConfigBuilder
*/
public PathConfigBuilder paths(EnforcementMode enforcementMode, String... paths) {
var pathConfigBuilder = paths(paths);
pathConfigBuilder.enforcementMode(enforcementMode);
return pathConfigBuilder;
}
/**
* Adds paths with generated name.
*
* @param paths refers to the 'quarkus.keycloak.policy-enforcer.paths."paths".paths' configuration property
* @return PathConfigBuilder
*/
public PathConfigBuilder paths(String... paths) {
final String name;
if (paths == null || paths.length == 0) {
name = getRandomPathName();
} else {
name = StringUtil.hyphenate(String.join("-", paths));
}
return namedPaths(name, paths);
}
private String getRandomPathName() {
String name;
do {
name = "path" + RandomGenerator.getDefault().nextInt();
} while (paths.containsKey(name));
return name;
}
public sealed interface PathConfigBuilder permits PathConfigBuilderImpl {
KeycloakPolicyEnforcerTenantConfigBuilder claimInformationPoint(Map> simpleConfig);
KeycloakPolicyEnforcerTenantConfigBuilder claimInformationPoint(Map> simpleConfig,
Map>> complexConfig);
ClaimInformationPointConfigBuilder claimInformationPoint();
KeycloakPolicyEnforcerTenantConfigBuilder enforcementMode(EnforcementMode enforcementMode);
/**
* Makes this path specific for a POST method only.
*
* @param scopes optional scopes
* @return KeycloakPolicyEnforcerTenantConfigBuilder
*/
KeycloakPolicyEnforcerTenantConfigBuilder post(String... scopes);
/**
* Makes this path specific for a POST method only.
*
* @param scopes optional scopes
* @param scopeEnforcementMode refers to the
* 'quarkus.keycloak.policy-enforcer.paths."paths".methods."methods".scopes-enforcement-mode' config property
* @return KeycloakPolicyEnforcerTenantConfigBuilder
*/
KeycloakPolicyEnforcerTenantConfigBuilder post(ScopeEnforcementMode scopeEnforcementMode, String... scopes);
/**
* Makes this path specific for a HEAD method only.
*
* @param scopes optional scopes
* @return KeycloakPolicyEnforcerTenantConfigBuilder
*/
KeycloakPolicyEnforcerTenantConfigBuilder head(String... scopes);
/**
* Makes this path specific for a HEAD method only.
*
* @param scopes optional scopes
* @param scopeEnforcementMode refers to the
* 'quarkus.keycloak.policy-enforcer.paths."paths".methods."methods".scopes-enforcement-mode' config property
* @return KeycloakPolicyEnforcerTenantConfigBuilder
*/
KeycloakPolicyEnforcerTenantConfigBuilder head(ScopeEnforcementMode scopeEnforcementMode, String... scopes);
/**
* Makes this path specific for a GET method only.
*
* @param scopes optional scopes
* @return KeycloakPolicyEnforcerTenantConfigBuilder
*/
KeycloakPolicyEnforcerTenantConfigBuilder get(String... scopes);
/**
* Makes this path specific for a GET method only.
*
* @param scopes optional scopes
* @param scopeEnforcementMode refers to the
* 'quarkus.keycloak.policy-enforcer.paths."paths".methods."methods".scopes-enforcement-mode' config property
* @return KeycloakPolicyEnforcerTenantConfigBuilder
*/
KeycloakPolicyEnforcerTenantConfigBuilder get(ScopeEnforcementMode scopeEnforcementMode, String... scopes);
/**
* Makes this path specific for a PUT method only.
*
* @param scopes optional scopes
* @return KeycloakPolicyEnforcerTenantConfigBuilder
*/
KeycloakPolicyEnforcerTenantConfigBuilder put(String... scopes);
/**
* Makes this path specific for a PUT method only.
*
* @param scopes optional scopes
* @param scopeEnforcementMode refers to the
* 'quarkus.keycloak.policy-enforcer.paths."paths".methods."methods".scopes-enforcement-mode' config property
* @return KeycloakPolicyEnforcerTenantConfigBuilder
*/
KeycloakPolicyEnforcerTenantConfigBuilder put(ScopeEnforcementMode scopeEnforcementMode, String... scopes);
/**
* Makes this path specific for a PATCH method only.
*
* @param scopes optional scopes
* @return KeycloakPolicyEnforcerTenantConfigBuilder
*/
KeycloakPolicyEnforcerTenantConfigBuilder patch(String... scopes);
/**
* Makes this path specific for a PATCH method only.
*
* @param scopes optional scopes
* @param scopeEnforcementMode refers to the
* 'quarkus.keycloak.policy-enforcer.paths."paths".methods."methods".scopes-enforcement-mode' config property
* @return KeycloakPolicyEnforcerTenantConfigBuilder
*/
KeycloakPolicyEnforcerTenantConfigBuilder patch(ScopeEnforcementMode scopeEnforcementMode, String... scopes);
/**
* Make this path specific for the HTTP {@code method} only.
*
* @param method refers to the 'quarkus.keycloak.policy-enforcer.paths."paths".methods."methods".method' config property
* @param scopeEnforcementMode refers to the
* 'quarkus.keycloak.policy-enforcer.paths."paths".methods."methods".scopes-enforcement-mode' config property
* @param scopes refers to the 'quarkus.keycloak.policy-enforcer.paths."paths".methods."methods".scopes' config property
* @return KeycloakPolicyEnforcerTenantConfigBuilder
*/
KeycloakPolicyEnforcerTenantConfigBuilder method(String method, ScopeEnforcementMode scopeEnforcementMode,
String... scopes);
/**
* Creates builder for a path method.
* Corresponds to configuration properties 'quarkus.keycloak.policy-enforcer.paths."paths".methods.*'.
*
* @return method builder
*/
MethodConfigBuilder method();
/**
* @param name permission name, as set by the 'quarkus.keycloak.policy-enforcer.paths."paths".name' config property
* @return PathConfigBuilder
*/
PathConfigBuilder permissionName(String name);
/**
* Returns parent {@link KeycloakPolicyEnforcerTenantConfigBuilder}.
* Calling this method is purely optional.
*
* @return parent builder
*/
KeycloakPolicyEnforcerTenantConfigBuilder parent();
}
private static final class PathConfigBuilderImpl implements PathConfigBuilder {
private final KeycloakPolicyEnforcerTenantConfigBuilder builder;
private final Map methods = new HashMap<>();
private final Set paths = new HashSet<>();
private ClaimInformationPointConfig claimInformationPointConfig = new ClaimInformationPointConfigImpl(Map.of(),
Map.of());
private EnforcementMode enforcementMode = ENFORCING;
private String name = null;
private PathConfigBuilderImpl(KeycloakPolicyEnforcerTenantConfigBuilder builder, PathConfig pathConfig) {
this.builder = builder;
if (pathConfig != null) {
this.methods.putAll(pathConfig.methods());
this.claimInformationPointConfig = pathConfig.claimInformationPoint();
this.paths.addAll(pathConfig.paths().orElse(List.of()));
if (pathConfig.path().isPresent()) {
this.paths.add(pathConfig.path().get());
}
this.enforcementMode = pathConfig.enforcementMode();
}
}
@Override
public KeycloakPolicyEnforcerTenantConfigBuilder claimInformationPoint(
Map> simpleConfig) {
claimInformationPointConfig = new ClaimInformationPointConfigImpl(
simpleConfig == null ? Map.of() : Map.copyOf(simpleConfig),
claimInformationPointConfig == null ? Map.of() : claimInformationPointConfig.complexConfig());
return builder;
}
@Override
public KeycloakPolicyEnforcerTenantConfigBuilder claimInformationPoint(Map> simpleConfig,
Map>> complexConfig) {
claimInformationPointConfig = new ClaimInformationPointConfigImpl(
simpleConfig == null ? Map.of() : Map.copyOf(simpleConfig),
complexConfig == null ? Map.of() : Map.copyOf(complexConfig));
return builder;
}
@Override
public ClaimInformationPointConfigBuilder claimInformationPoint() {
return new ClaimInformationPointConfigBuilder<>() {
@Override
public PathConfigBuilder build() {
if (simpleConfig != null || complexConfig != null) {
PathConfigBuilderImpl.this.claimInformationPoint(simpleConfig, complexConfig);
}
return PathConfigBuilderImpl.this;
}
};
}
@Override
public PathConfigBuilder permissionName(String name) {
this.name = name;
return this;
}
@Override
public KeycloakPolicyEnforcerTenantConfigBuilder enforcementMode(EnforcementMode enforcementMode) {
Objects.requireNonNull(enforcementMode);
this.enforcementMode = enforcementMode;
return builder;
}
@Override
public KeycloakPolicyEnforcerTenantConfigBuilder post(String... scopes) {
return post(null, scopes);
}
@Override
public KeycloakPolicyEnforcerTenantConfigBuilder post(ScopeEnforcementMode scopeEnforcementMode, String... scopes) {
return method("POST", scopeEnforcementMode, scopes);
}
@Override
public KeycloakPolicyEnforcerTenantConfigBuilder head(String... scopes) {
return head(null, scopes);
}
@Override
public KeycloakPolicyEnforcerTenantConfigBuilder head(ScopeEnforcementMode scopeEnforcementMode, String... scopes) {
return method("HEAD", scopeEnforcementMode, scopes);
}
@Override
public KeycloakPolicyEnforcerTenantConfigBuilder get(String... scopes) {
return get(null, scopes);
}
@Override
public KeycloakPolicyEnforcerTenantConfigBuilder get(ScopeEnforcementMode scopeEnforcementMode, String... scopes) {
return method("GET", scopeEnforcementMode, scopes);
}
@Override
public KeycloakPolicyEnforcerTenantConfigBuilder put(String... scopes) {
return put(null, scopes);
}
@Override
public KeycloakPolicyEnforcerTenantConfigBuilder put(ScopeEnforcementMode scopeEnforcementMode, String... scopes) {
return method("PUT", scopeEnforcementMode, scopes);
}
@Override
public KeycloakPolicyEnforcerTenantConfigBuilder patch(String... scopes) {
return patch(null, scopes);
}
@Override
public KeycloakPolicyEnforcerTenantConfigBuilder patch(ScopeEnforcementMode scopeEnforcementMode, String... scopes) {
return method("PATCH", scopeEnforcementMode, scopes);
}
@Override
public KeycloakPolicyEnforcerTenantConfigBuilder method(String method, ScopeEnforcementMode scopeEnforcementMode,
String... scopes) {
Objects.requireNonNull(method);
if (scopeEnforcementMode == null) {
// default enforcement scope is ALL
scopeEnforcementMode = ScopeEnforcementMode.ALL;
}
methods.put(method.toLowerCase(), new MethodConfigImpl(method, List.of(scopes), scopeEnforcementMode));
return builder;
}
@Override
public MethodConfigBuilder method() {
return new MethodConfigBuilder(this);
}
@Override
public KeycloakPolicyEnforcerTenantConfigBuilder parent() {
return builder;
}
}
public static final class PathCacheConfigBuilder {
private final KeycloakPolicyEnforcerTenantConfigBuilder parent;
Integer maxEntries = null;
Long lifespan = null;
private PathCacheConfigBuilder(KeycloakPolicyEnforcerTenantConfigBuilder parent) {
this.parent = parent;
}
public PathCacheConfigBuilder lifespan(long lifespan) {
this.lifespan = lifespan;
return this;
}
public PathCacheConfigBuilder maxEntries(int maxEntries) {
this.maxEntries = maxEntries;
return this;
}
public KeycloakPolicyEnforcerTenantConfigBuilder build() {
if (maxEntries == null && lifespan == null) {
return parent;
}
if (maxEntries == null) {
return parent.pathCache(lifespan);
}
if (lifespan == null) {
return parent.pathCache(maxEntries);
}
return parent.pathCache(maxEntries, lifespan);
}
}
public static abstract class ClaimInformationPointConfigBuilder {
protected Map> simpleConfig = null;
protected Map>> complexConfig = null;
private ClaimInformationPointConfigBuilder() {
}
public ClaimInformationPointConfigBuilder simpleConfig(Map> simpleConfig) {
this.simpleConfig = simpleConfig;
return this;
}
public ClaimInformationPointConfigBuilder complexConfig(
Map>> complexConfig) {
this.complexConfig = complexConfig;
return this;
}
public abstract T build();
}
public static final class MethodConfigBuilder {
private final PathConfigBuilder builder;
private String method;
private String[] scopes;
private ScopeEnforcementMode scopesEnforcementMode;
private MethodConfigBuilder(PathConfigBuilder builder) {
this.builder = builder;
}
public MethodConfigBuilder method(String method) {
this.method = method;
return this;
}
public MethodConfigBuilder scopes(String... scopes) {
this.scopes = scopes;
return this;
}
public MethodConfigBuilder scopesEnforcementMode(ScopeEnforcementMode scopesEnforcementMode) {
this.scopesEnforcementMode = scopesEnforcementMode;
return this;
}
public PathConfigBuilder build() {
Objects.requireNonNull(method);
builder.method(method, scopesEnforcementMode, scopes == null ? new String[] {} : scopes);
return builder;
}
}
}