package org.keycloak.authorization.policy.provider.drools; import java.util.Collections; import java.util.HashMap; import java.util.Map; import org.keycloak.Config; import org.keycloak.authorization.AuthorizationProvider; import org.keycloak.authorization.model.Policy; import org.keycloak.authorization.model.ResourceServer; import org.keycloak.authorization.policy.provider.PolicyProvider; import org.keycloak.authorization.policy.provider.PolicyProviderAdminService; import org.keycloak.authorization.policy.provider.PolicyProviderFactory; import org.keycloak.models.KeycloakSession; import org.keycloak.models.KeycloakSessionFactory; import org.keycloak.representations.idm.authorization.PolicyRepresentation; import org.keycloak.representations.idm.authorization.RulePolicyRepresentation; import org.kie.api.KieServices; import org.kie.api.KieServices.Factory; import org.kie.api.runtime.KieContainer; /** * @author <a href="mailto:psilva@redhat.com">Pedro Igor</a> */ public class DroolsPolicyProviderFactory implements PolicyProviderFactory<RulePolicyRepresentation> { private KieServices ks; private final Map<String, DroolsPolicy> containers = Collections.synchronizedMap(new HashMap<>()); private DroolsPolicyProvider provider = new DroolsPolicyProvider(policy -> { if (!containers.containsKey(policy.getId())) { synchronized (containers) { update(policy); } } return containers.get(policy.getId()); }); @Override public String getName() { return "Rules"; } @Override public String getGroup() { return "Rule Based"; } @Override public PolicyProvider create(AuthorizationProvider authorization) { return provider; } @Override public PolicyProviderAdminService getAdminResource(ResourceServer resourceServer, AuthorizationProvider authorization) { return new DroolsPolicyAdminResource(this); } @Override public PolicyProvider create(KeycloakSession session) { return null; } @Override public void onCreate(Policy policy, RulePolicyRepresentation representation, AuthorizationProvider authorization) { updateConfig(policy, representation); update(policy); } @Override public void onUpdate(Policy policy, RulePolicyRepresentation representation, AuthorizationProvider authorization) { updateConfig(policy, representation); update(policy); } @Override public void onImport(Policy policy, PolicyRepresentation representation, AuthorizationProvider authorization) { update(policy); } @Override public void onRemove(Policy policy, AuthorizationProvider authorization) { remove(policy); } @Override public RulePolicyRepresentation toRepresentation(Policy policy, RulePolicyRepresentation representation) { representation.setArtifactGroupId(policy.getConfig().get("mavenArtifactGroupId")); representation.setArtifactId(policy.getConfig().get("mavenArtifactId")); representation.setArtifactVersion(policy.getConfig().get("mavenArtifactVersion")); representation.setScannerPeriod(policy.getConfig().get("scannerPeriod")); representation.setScannerPeriodUnit(policy.getConfig().get("scannerPeriodUnit")); representation.setSessionName(policy.getConfig().get("sessionName")); representation.setModuleName(policy.getConfig().get("moduleName")); return representation; } @Override public Class<RulePolicyRepresentation> getRepresentationType() { return RulePolicyRepresentation.class; } @Override public void init(Config.Scope config) { this.ks = Factory.get(); } @Override public void postInit(KeycloakSessionFactory factory) { } @Override public void close() { this.containers.values().forEach(DroolsPolicy::dispose); this.containers.clear(); } @Override public String getId() { return "rules"; } private void updateConfig(Policy policy, RulePolicyRepresentation representation) { policy.putConfig("mavenArtifactGroupId", representation.getArtifactGroupId()); policy.putConfig("mavenArtifactId", representation.getArtifactId()); policy.putConfig("mavenArtifactVersion", representation.getArtifactVersion()); policy.putConfig("scannerPeriod", representation.getScannerPeriod()); policy.putConfig("scannerPeriodUnit", representation.getScannerPeriodUnit()); policy.putConfig("sessionName", representation.getSessionName()); policy.putConfig("moduleName", representation.getModuleName()); } void update(Policy policy) { remove(policy); this.containers.put(policy.getId(), new DroolsPolicy(this.ks, policy)); } void remove(Policy policy) { DroolsPolicy holder = this.containers.remove(policy.getId()); if (holder != null) { holder.dispose(); } } KieContainer getKieContainer(String groupId, String artifactId, String version) { return this.ks.newKieContainer(this.ks.newReleaseId(groupId, artifactId, version)); } }