diff --git a/integration/pom.xml b/integration/pom.xml
index 4f5369dd53e..5c1f1328c8b 100755
--- a/integration/pom.xml
+++ b/integration/pom.xml
@@ -22,10 +22,7 @@
as7-eap6/adapterjettyundertow
- wildfly-adapter
- wildfly-extensions
- wildfly-server-subsystem
- wildfly-adapter-subsystem
+ wildflykeycloak-as7-subsystemjsinstalled
diff --git a/integration/wildfly/pom.xml b/integration/wildfly/pom.xml
new file mode 100644
index 00000000000..25df76d2611
--- /dev/null
+++ b/integration/wildfly/pom.xml
@@ -0,0 +1,22 @@
+
+
+ keycloak-parent
+ org.keycloak
+ 1.3.0.Beta1-SNAPSHOT
+ ../../pom.xml
+
+ Keycloak WildFly Integration
+
+ 4.0.0
+
+ keycloak-wildfly-integration-pom
+ pom
+
+
+ wildfly-adapter
+ wildfly-extensions
+ wildfly-server-subsystem
+ wildfly-adapter-subsystem
+
+
\ No newline at end of file
diff --git a/integration/wildfly/wildfly-adapter-subsystem/pom.xml b/integration/wildfly/wildfly-adapter-subsystem/pom.xml
new file mode 100755
index 00000000000..0a28a652e32
--- /dev/null
+++ b/integration/wildfly/wildfly-adapter-subsystem/pom.xml
@@ -0,0 +1,105 @@
+
+
+
+ 4.0.0
+
+
+ org.keycloak
+ keycloak-parent
+ 1.3.0.Beta1-SNAPSHOT
+ ../../../pom.xml
+
+
+ keycloak-wildfly-adapter-subsystem
+ Keycloak Adapter Subsystem
+
+ jar
+
+
+
+
+ org.apache.maven.plugins
+ maven-surefire-plugin
+
+ false
+ true
+
+
+ jboss.home
+ ${jboss.home}
+
+
+
+ **/*TestCase.java
+
+
+
+
+
+
+
+
+ org.wildfly.core
+ wildfly-controller
+ provided
+
+
+ org.wildfly.core
+ wildfly-server
+ provided
+
+
+ org.wildfly
+ wildfly-web-common
+ provided
+
+
+ org.jboss.logging
+ jboss-logging-annotations
+ ${jboss-logging-tools.version}
+
+ provided
+ true
+
+
+
+ org.jboss.logging
+ jboss-logging-processor
+
+ provided
+ true
+
+
+
+ org.wildfly.core
+ wildfly-subsystem-test-framework
+ test
+
+
+ junit
+ junit
+ test
+
+
+ org.keycloak
+ keycloak-wildfly-adapter
+ ${project.version}
+
+
+
diff --git a/integration/wildfly/wildfly-adapter-subsystem/src/main/java/org/keycloak/subsystem/adapter/extension/CredentialAddHandler.java b/integration/wildfly/wildfly-adapter-subsystem/src/main/java/org/keycloak/subsystem/adapter/extension/CredentialAddHandler.java
new file mode 100755
index 00000000000..2b9852c32e0
--- /dev/null
+++ b/integration/wildfly/wildfly-adapter-subsystem/src/main/java/org/keycloak/subsystem/adapter/extension/CredentialAddHandler.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2014 Red Hat Inc. and/or its affiliates and other contributors
+ * as indicated by the @author tags. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package org.keycloak.subsystem.adapter.extension;
+
+import org.jboss.as.controller.AbstractAddStepHandler;
+import org.jboss.as.controller.AttributeDefinition;
+import org.jboss.as.controller.OperationContext;
+import org.jboss.as.controller.OperationFailedException;
+import org.jboss.dmr.ModelNode;
+
+/**
+ * Add a credential to a deployment.
+ *
+ * @author Stan Silvert ssilvert@redhat.com (C) 2014 Red Hat Inc.
+ */
+public class CredentialAddHandler extends AbstractAddStepHandler {
+
+ public CredentialAddHandler(AttributeDefinition... attributes) {
+ super(attributes);
+ }
+
+ @Override
+ protected void performRuntime(OperationContext context, ModelNode operation, ModelNode model) throws OperationFailedException {
+ KeycloakAdapterConfigService ckService = KeycloakAdapterConfigService.getInstance();
+ ckService.addCredential(operation, context.resolveExpressions(model));
+ }
+
+}
diff --git a/integration/wildfly/wildfly-adapter-subsystem/src/main/java/org/keycloak/subsystem/adapter/extension/CredentialDefinition.java b/integration/wildfly/wildfly-adapter-subsystem/src/main/java/org/keycloak/subsystem/adapter/extension/CredentialDefinition.java
new file mode 100755
index 00000000000..77dfd9db225
--- /dev/null
+++ b/integration/wildfly/wildfly-adapter-subsystem/src/main/java/org/keycloak/subsystem/adapter/extension/CredentialDefinition.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright 2013 Red Hat Inc. and/or its affiliates and other contributors
+ * as indicated by the @author tags. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package org.keycloak.subsystem.adapter.extension;
+
+import org.jboss.as.controller.AttributeDefinition;
+import org.jboss.as.controller.PathElement;
+import org.jboss.as.controller.SimpleAttributeDefinitionBuilder;
+import org.jboss.as.controller.SimpleResourceDefinition;
+import org.jboss.as.controller.operations.common.GenericSubsystemDescribeHandler;
+import org.jboss.as.controller.operations.validation.StringLengthValidator;
+import org.jboss.as.controller.registry.ManagementResourceRegistration;
+import org.jboss.dmr.ModelType;
+
+/**
+ * Defines attributes and operations for a credential.
+ *
+ * @author Stan Silvert ssilvert@redhat.com (C) 2013 Red Hat Inc.
+ */
+public class CredentialDefinition extends SimpleResourceDefinition {
+
+ public static final String TAG_NAME = "credential";
+
+ protected static final AttributeDefinition VALUE =
+ new SimpleAttributeDefinitionBuilder("value", ModelType.STRING, false)
+ .setAllowExpression(true)
+ .setValidator(new StringLengthValidator(1, Integer.MAX_VALUE, false, true))
+ .build();
+
+ public CredentialDefinition() {
+ super(PathElement.pathElement(TAG_NAME),
+ KeycloakExtension.getResourceDescriptionResolver(TAG_NAME),
+ new CredentialAddHandler(VALUE),
+ CredentialRemoveHandler.INSTANCE);
+ }
+
+ @Override
+ public void registerOperations(ManagementResourceRegistration resourceRegistration) {
+ super.registerOperations(resourceRegistration);
+ resourceRegistration.registerOperationHandler(GenericSubsystemDescribeHandler.DEFINITION, GenericSubsystemDescribeHandler.INSTANCE);
+ }
+
+ @Override
+ public void registerAttributes(ManagementResourceRegistration resourceRegistration) {
+ super.registerAttributes(resourceRegistration);
+ resourceRegistration.registerReadWriteAttribute(VALUE, null, new CredentialReadWriteAttributeHandler());
+ }
+}
diff --git a/integration/wildfly/wildfly-adapter-subsystem/src/main/java/org/keycloak/subsystem/adapter/extension/CredentialReadWriteAttributeHandler.java b/integration/wildfly/wildfly-adapter-subsystem/src/main/java/org/keycloak/subsystem/adapter/extension/CredentialReadWriteAttributeHandler.java
new file mode 100644
index 00000000000..7aff17f1712
--- /dev/null
+++ b/integration/wildfly/wildfly-adapter-subsystem/src/main/java/org/keycloak/subsystem/adapter/extension/CredentialReadWriteAttributeHandler.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2014 Red Hat Inc. and/or its affiliates and other contributors
+ * as indicated by the @author tags. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package org.keycloak.subsystem.adapter.extension;
+
+import org.jboss.as.controller.AbstractWriteAttributeHandler;
+import org.jboss.as.controller.OperationContext;
+import org.jboss.as.controller.OperationFailedException;
+import org.jboss.dmr.ModelNode;
+
+/**
+ * Update a credential value.
+ *
+ * @author Stan Silvert ssilvert@redhat.com (C) 2014 Red Hat Inc.
+ */
+public class CredentialReadWriteAttributeHandler extends AbstractWriteAttributeHandler {
+
+ @Override
+ protected boolean applyUpdateToRuntime(OperationContext context, ModelNode operation, String attributeName,
+ ModelNode resolvedValue, ModelNode currentValue, AbstractWriteAttributeHandler.HandbackHolder hh) throws OperationFailedException {
+
+ KeycloakAdapterConfigService ckService = KeycloakAdapterConfigService.getInstance();
+ ckService.updateCredential(operation, attributeName, resolvedValue);
+
+ hh.setHandback(ckService);
+
+ return false;
+ }
+
+ @Override
+ protected void revertUpdateToRuntime(OperationContext context, ModelNode operation, String attributeName,
+ ModelNode valueToRestore, ModelNode valueToRevert, KeycloakAdapterConfigService ckService) throws OperationFailedException {
+ ckService.updateCredential(operation, attributeName, valueToRestore);
+ }
+
+}
diff --git a/integration/wildfly/wildfly-adapter-subsystem/src/main/java/org/keycloak/subsystem/adapter/extension/CredentialRemoveHandler.java b/integration/wildfly/wildfly-adapter-subsystem/src/main/java/org/keycloak/subsystem/adapter/extension/CredentialRemoveHandler.java
new file mode 100644
index 00000000000..36923f08dfd
--- /dev/null
+++ b/integration/wildfly/wildfly-adapter-subsystem/src/main/java/org/keycloak/subsystem/adapter/extension/CredentialRemoveHandler.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2014 Red Hat Inc. and/or its affiliates and other contributors
+ * as indicated by the @author tags. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package org.keycloak.subsystem.adapter.extension;
+
+import org.jboss.as.controller.AbstractRemoveStepHandler;
+import org.jboss.as.controller.OperationContext;
+import org.jboss.as.controller.OperationFailedException;
+import org.jboss.dmr.ModelNode;
+
+/**
+ * Remove a credential from a deployment.
+ *
+ * @author Stan Silvert ssilvert@redhat.com (C) 2014 Red Hat Inc.
+ */
+public final class CredentialRemoveHandler extends AbstractRemoveStepHandler {
+
+ public static CredentialRemoveHandler INSTANCE = new CredentialRemoveHandler();
+
+ private CredentialRemoveHandler() {}
+
+ @Override
+ protected void performRuntime(OperationContext context, ModelNode operation, ModelNode model) throws OperationFailedException {
+ KeycloakAdapterConfigService ckService = KeycloakAdapterConfigService.getInstance();
+ ckService.removeCredential(operation);
+ }
+
+}
diff --git a/integration/wildfly/wildfly-adapter-subsystem/src/main/java/org/keycloak/subsystem/adapter/extension/KeycloakAdapterConfigDeploymentProcessor.java b/integration/wildfly/wildfly-adapter-subsystem/src/main/java/org/keycloak/subsystem/adapter/extension/KeycloakAdapterConfigDeploymentProcessor.java
new file mode 100755
index 00000000000..f6246273e2f
--- /dev/null
+++ b/integration/wildfly/wildfly-adapter-subsystem/src/main/java/org/keycloak/subsystem/adapter/extension/KeycloakAdapterConfigDeploymentProcessor.java
@@ -0,0 +1,131 @@
+/*
+ * Copyright 2014 Red Hat Inc. and/or its affiliates and other contributors
+ * as indicated by the @author tags. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package org.keycloak.subsystem.adapter.extension;
+
+import org.jboss.as.server.deployment.DeploymentPhaseContext;
+import org.jboss.as.server.deployment.DeploymentUnit;
+import org.jboss.as.server.deployment.DeploymentUnitProcessingException;
+import org.jboss.as.server.deployment.DeploymentUnitProcessor;
+import org.jboss.as.web.common.WarMetaData;
+import org.jboss.logging.Logger;
+import org.jboss.metadata.javaee.spec.ParamValueMetaData;
+import org.jboss.metadata.web.jboss.JBossWebMetaData;
+import org.jboss.metadata.web.spec.LoginConfigMetaData;
+import org.keycloak.subsystem.adapter.logging.KeycloakLogger;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Pass authentication data (keycloak.json) as a servlet context param so it can be read by the KeycloakServletExtension.
+ *
+ * @author Stan Silvert ssilvert@redhat.com (C) 2014 Red Hat Inc.
+ */
+public class KeycloakAdapterConfigDeploymentProcessor implements DeploymentUnitProcessor {
+ protected Logger log = Logger.getLogger(KeycloakAdapterConfigDeploymentProcessor.class);
+
+ // This param name is defined again in Keycloak Undertow Integration class
+ // org.keycloak.adapters.undertow.KeycloakServletExtension. We have this value in
+ // two places to avoid dependency between Keycloak Subsystem and Keyclaok Undertow Integration.
+ public static final String AUTH_DATA_PARAM_NAME = "org.keycloak.json.adapterConfig";
+
+ // not sure if we need this yet, keeping here just in case
+ protected void addSecurityDomain(DeploymentUnit deploymentUnit, KeycloakAdapterConfigService service) {
+ String deploymentName = deploymentUnit.getName();
+ if (!service.isSecureDeployment(deploymentName)) {
+ return;
+ }
+ WarMetaData warMetaData = deploymentUnit.getAttachment(WarMetaData.ATTACHMENT_KEY);
+ if (warMetaData == null) return;
+ JBossWebMetaData webMetaData = warMetaData.getMergedJBossWebMetaData();
+ if (webMetaData == null) return;
+
+ LoginConfigMetaData loginConfig = webMetaData.getLoginConfig();
+ if (loginConfig == null || !loginConfig.getAuthMethod().equalsIgnoreCase("KEYCLOAK")) {
+ return;
+ }
+
+ webMetaData.setSecurityDomain("keycloak");
+ }
+
+ @Override
+ public void deploy(DeploymentPhaseContext phaseContext) throws DeploymentUnitProcessingException {
+ DeploymentUnit deploymentUnit = phaseContext.getDeploymentUnit();
+
+ String deploymentName = deploymentUnit.getName();
+ KeycloakAdapterConfigService service = KeycloakAdapterConfigService.getInstance();
+ if (service.isSecureDeployment(deploymentName)) {
+ addKeycloakAuthData(phaseContext, deploymentName, service);
+ }
+
+ // FYI, Undertow Extension will find deployments that have auth-method set to KEYCLOAK
+
+ // todo notsure if we need this
+ // addSecurityDomain(deploymentUnit, service);
+ }
+
+ private void addKeycloakAuthData(DeploymentPhaseContext phaseContext, String deploymentName, KeycloakAdapterConfigService service) throws DeploymentUnitProcessingException {
+ DeploymentUnit deploymentUnit = phaseContext.getDeploymentUnit();
+ WarMetaData warMetaData = deploymentUnit.getAttachment(WarMetaData.ATTACHMENT_KEY);
+ if (warMetaData == null) {
+ throw new DeploymentUnitProcessingException("WarMetaData not found for " + deploymentName + ". Make sure you have specified a WAR as your secure-deployment in the Keycloak subsystem.");
+ }
+
+ addJSONData(service.getJSON(deploymentName), warMetaData);
+ JBossWebMetaData webMetaData = warMetaData.getMergedJBossWebMetaData();
+ if (webMetaData == null) {
+ webMetaData = new JBossWebMetaData();
+ warMetaData.setMergedJBossWebMetaData(webMetaData);
+ }
+
+ LoginConfigMetaData loginConfig = webMetaData.getLoginConfig();
+ if (loginConfig == null) {
+ loginConfig = new LoginConfigMetaData();
+ webMetaData.setLoginConfig(loginConfig);
+ }
+ loginConfig.setAuthMethod("KEYCLOAK");
+ loginConfig.setRealmName(service.getRealmName(deploymentName));
+ KeycloakLogger.ROOT_LOGGER.deploymentSecured(deploymentName);
+ }
+
+ private void addJSONData(String json, WarMetaData warMetaData) {
+ JBossWebMetaData webMetaData = warMetaData.getMergedJBossWebMetaData();
+ if (webMetaData == null) {
+ webMetaData = new JBossWebMetaData();
+ warMetaData.setMergedJBossWebMetaData(webMetaData);
+ }
+
+ List contextParams = webMetaData.getContextParams();
+ if (contextParams == null) {
+ contextParams = new ArrayList();
+ }
+
+ ParamValueMetaData param = new ParamValueMetaData();
+ param.setParamName(AUTH_DATA_PARAM_NAME);
+ param.setParamValue(json);
+ contextParams.add(param);
+
+ webMetaData.setContextParams(contextParams);
+ }
+
+ @Override
+ public void undeploy(DeploymentUnit du) {
+
+ }
+
+}
diff --git a/integration/wildfly/wildfly-adapter-subsystem/src/main/java/org/keycloak/subsystem/adapter/extension/KeycloakAdapterConfigService.java b/integration/wildfly/wildfly-adapter-subsystem/src/main/java/org/keycloak/subsystem/adapter/extension/KeycloakAdapterConfigService.java
new file mode 100755
index 00000000000..c6f616adce0
--- /dev/null
+++ b/integration/wildfly/wildfly-adapter-subsystem/src/main/java/org/keycloak/subsystem/adapter/extension/KeycloakAdapterConfigService.java
@@ -0,0 +1,179 @@
+/*
+ * Copyright 2013 Red Hat Inc. and/or its affiliates and other contributors
+ * as indicated by the @author tags. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package org.keycloak.subsystem.adapter.extension;
+
+import org.jboss.dmr.ModelNode;
+import org.jboss.dmr.Property;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.ADDRESS;
+
+/**
+ * This service keeps track of the entire Keycloak management model so as to provide
+ * adapter configuration to each deployment at deploy time.
+ *
+ * @author Stan Silvert ssilvert@redhat.com (C) 2013 Red Hat Inc.
+ */
+public final class KeycloakAdapterConfigService {
+
+ private static final String CREDENTIALS_JSON_NAME = "credentials";
+
+ private static final KeycloakAdapterConfigService INSTANCE = new KeycloakAdapterConfigService();
+
+ public static KeycloakAdapterConfigService getInstance() {
+ return INSTANCE;
+ }
+
+ private final Map realms = new HashMap();
+
+ // keycloak-secured deployments
+ private final Map secureDeployments = new HashMap();
+
+
+ private KeycloakAdapterConfigService() {
+ }
+
+ public void addRealm(ModelNode operation, ModelNode model) {
+ this.realms.put(realmNameFromOp(operation), model.clone());
+ }
+
+ public void updateRealm(ModelNode operation, String attrName, ModelNode resolvedValue) {
+ ModelNode realm = this.realms.get(realmNameFromOp(operation));
+ realm.get(attrName).set(resolvedValue);
+ }
+
+ public void removeRealm(ModelNode operation) {
+ this.realms.remove(realmNameFromOp(operation));
+ }
+
+ public void addSecureDeployment(ModelNode operation, ModelNode model) {
+ ModelNode deployment = model.clone();
+ this.secureDeployments.put(deploymentNameFromOp(operation), deployment);
+ }
+
+ public void updateSecureDeployment(ModelNode operation, String attrName, ModelNode resolvedValue) {
+ ModelNode deployment = this.secureDeployments.get(deploymentNameFromOp(operation));
+ deployment.get(attrName).set(resolvedValue);
+ }
+
+ public void removeSecureDeployment(ModelNode operation) {
+ this.secureDeployments.remove(deploymentNameFromOp(operation));
+ }
+
+ public void addCredential(ModelNode operation, ModelNode model) {
+ ModelNode credentials = credentialsFromOp(operation);
+ if (!credentials.isDefined()) {
+ credentials = new ModelNode();
+ }
+
+ String credentialName = credentialNameFromOp(operation);
+ credentials.get(credentialName).set(model.get("value").asString());
+
+ ModelNode deployment = this.secureDeployments.get(deploymentNameFromOp(operation));
+ deployment.get(CREDENTIALS_JSON_NAME).set(credentials);
+ }
+
+ public void removeCredential(ModelNode operation) {
+ ModelNode credentials = credentialsFromOp(operation);
+ if (!credentials.isDefined()) {
+ throw new RuntimeException("Can not remove credential. No credential defined for deployment in op " + operation.toString());
+ }
+
+ String credentialName = credentialNameFromOp(operation);
+ credentials.remove(credentialName);
+ }
+
+ public void updateCredential(ModelNode operation, String attrName, ModelNode resolvedValue) {
+ ModelNode credentials = credentialsFromOp(operation);
+ if (!credentials.isDefined()) {
+ throw new RuntimeException("Can not update credential. No credential defined for deployment in op " + operation.toString());
+ }
+
+ String credentialName = credentialNameFromOp(operation);
+ credentials.get(credentialName).set(resolvedValue);
+ }
+
+ private ModelNode credentialsFromOp(ModelNode operation) {
+ ModelNode deployment = this.secureDeployments.get(deploymentNameFromOp(operation));
+ return deployment.get(CREDENTIALS_JSON_NAME);
+ }
+
+ private String realmNameFromOp(ModelNode operation) {
+ return valueFromOpAddress(RealmDefinition.TAG_NAME, operation);
+ }
+
+ private String deploymentNameFromOp(ModelNode operation) {
+ return valueFromOpAddress(SecureDeploymentDefinition.TAG_NAME, operation);
+ }
+
+ private String credentialNameFromOp(ModelNode operation) {
+ return valueFromOpAddress(CredentialDefinition.TAG_NAME, operation);
+ }
+
+ private String valueFromOpAddress(String addrElement, ModelNode operation) {
+ String deploymentName = getValueOfAddrElement(operation.get(ADDRESS), addrElement);
+ if (deploymentName == null) throw new RuntimeException("Can't find '" + addrElement + "' in address " + operation.toString());
+ return deploymentName;
+ }
+
+ private String getValueOfAddrElement(ModelNode address, String elementName) {
+ for (ModelNode element : address.asList()) {
+ if (element.has(elementName)) return element.get(elementName).asString();
+ }
+
+ return null;
+ }
+
+ public String getRealmName(String deploymentName) {
+ ModelNode deployment = this.secureDeployments.get(deploymentName);
+ return deployment.get(RealmDefinition.TAG_NAME).asString();
+
+ }
+
+ public String getJSON(String deploymentName) {
+ ModelNode deployment = this.secureDeployments.get(deploymentName);
+ String realmName = deployment.get(RealmDefinition.TAG_NAME).asString();
+ ModelNode realm = this.realms.get(realmName);
+
+ ModelNode json = new ModelNode();
+ json.get(RealmDefinition.TAG_NAME).set(realmName);
+
+ // Realm values set first. Some can be overridden by deployment values.
+ if (realm != null) setJSONValues(json, realm);
+ setJSONValues(json, deployment);
+ return json.toJSONString(true);
+ }
+
+ private void setJSONValues(ModelNode json, ModelNode values) {
+ for (Property prop : values.asPropertyList()) {
+ String name = prop.getName();
+ ModelNode value = prop.getValue();
+ if (value.isDefined()) {
+ json.get(name).set(value);
+ }
+ }
+ }
+
+ public boolean isSecureDeployment(String deploymentName) {
+ //log.info("********* CHECK KEYCLOAK DEPLOYMENT: deployments.size()" + deployments.size());
+
+ return this.secureDeployments.containsKey(deploymentName);
+ }
+}
diff --git a/integration/wildfly/wildfly-adapter-subsystem/src/main/java/org/keycloak/subsystem/adapter/extension/KeycloakDependencyProcessor.java b/integration/wildfly/wildfly-adapter-subsystem/src/main/java/org/keycloak/subsystem/adapter/extension/KeycloakDependencyProcessor.java
new file mode 100755
index 00000000000..3e968b4af63
--- /dev/null
+++ b/integration/wildfly/wildfly-adapter-subsystem/src/main/java/org/keycloak/subsystem/adapter/extension/KeycloakDependencyProcessor.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright 2013 Red Hat Inc. and/or its affiliates and other contributors
+ * as indicated by the @author tags. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package org.keycloak.subsystem.adapter.extension;
+
+import org.jboss.as.server.deployment.Attachments;
+import org.jboss.as.server.deployment.DeploymentPhaseContext;
+import org.jboss.as.server.deployment.DeploymentUnit;
+import org.jboss.as.server.deployment.DeploymentUnitProcessingException;
+import org.jboss.as.server.deployment.DeploymentUnitProcessor;
+import org.jboss.as.server.deployment.module.ModuleDependency;
+import org.jboss.as.server.deployment.module.ModuleSpecification;
+import org.jboss.modules.Module;
+import org.jboss.modules.ModuleIdentifier;
+import org.jboss.modules.ModuleLoader;
+
+/**
+ *
+ * @author Stan Silvert ssilvert@redhat.com (C) 2013 Red Hat Inc.
+ */
+public abstract class KeycloakDependencyProcessor implements DeploymentUnitProcessor {
+
+ private static final ModuleIdentifier KEYCLOAK_JBOSS_CORE_ADAPTER = ModuleIdentifier.create("org.keycloak.keycloak-jboss-adapter-core");
+ private static final ModuleIdentifier KEYCLOAK_CORE_ADAPTER = ModuleIdentifier.create("org.keycloak.keycloak-adapter-core");
+ private static final ModuleIdentifier KEYCLOAK_CORE = ModuleIdentifier.create("org.keycloak.keycloak-core");
+
+ @Override
+ public void deploy(DeploymentPhaseContext phaseContext) throws DeploymentUnitProcessingException {
+ final DeploymentUnit deploymentUnit = phaseContext.getDeploymentUnit();
+
+ // Next phase, need to detect if this is a Keycloak deployment. If not, don't add the modules.
+
+ final ModuleSpecification moduleSpecification = deploymentUnit.getAttachment(Attachments.MODULE_SPECIFICATION);
+ final ModuleLoader moduleLoader = Module.getBootModuleLoader();
+ addCommonModules(moduleSpecification, moduleLoader);
+ addPlatformSpecificModules(moduleSpecification, moduleLoader);
+ }
+
+ private void addCommonModules(ModuleSpecification moduleSpecification, ModuleLoader moduleLoader) {
+ // ModuleDependency(ModuleLoader moduleLoader, ModuleIdentifier identifier, boolean optional, boolean export, boolean importServices, boolean userSpecified)
+ moduleSpecification.addSystemDependency(new ModuleDependency(moduleLoader, KEYCLOAK_JBOSS_CORE_ADAPTER, false, false, false, false));
+ moduleSpecification.addSystemDependency(new ModuleDependency(moduleLoader, KEYCLOAK_CORE_ADAPTER, false, false, false, false));
+ moduleSpecification.addSystemDependency(new ModuleDependency(moduleLoader, KEYCLOAK_CORE, false, false, false, false));
+ }
+
+ abstract protected void addPlatformSpecificModules(ModuleSpecification moduleSpecification, ModuleLoader moduleLoader);
+
+ @Override
+ public void undeploy(DeploymentUnit du) {
+
+ }
+
+}
diff --git a/integration/wildfly/wildfly-adapter-subsystem/src/main/java/org/keycloak/subsystem/adapter/extension/KeycloakDependencyProcessorWildFly.java b/integration/wildfly/wildfly-adapter-subsystem/src/main/java/org/keycloak/subsystem/adapter/extension/KeycloakDependencyProcessorWildFly.java
new file mode 100755
index 00000000000..a11bd01d683
--- /dev/null
+++ b/integration/wildfly/wildfly-adapter-subsystem/src/main/java/org/keycloak/subsystem/adapter/extension/KeycloakDependencyProcessorWildFly.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2013 Red Hat Inc. and/or its affiliates and other contributors
+ * as indicated by the @author tags. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package org.keycloak.subsystem.adapter.extension;
+
+import org.jboss.as.server.deployment.module.ModuleDependency;
+import org.jboss.as.server.deployment.module.ModuleSpecification;
+import org.jboss.modules.ModuleIdentifier;
+import org.jboss.modules.ModuleLoader;
+
+/**
+ * Add platform-specific modules for WildFly.
+ *
+ * @author Stan Silvert ssilvert@redhat.com (C) 2014 Red Hat Inc.
+ */
+public class KeycloakDependencyProcessorWildFly extends KeycloakDependencyProcessor {
+
+ private static final ModuleIdentifier KEYCLOAK_WILDFLY_ADAPTER = ModuleIdentifier.create("org.keycloak.keycloak-wildfly-adapter");
+ private static final ModuleIdentifier KEYCLOAK_UNDERTOW_ADAPTER = ModuleIdentifier.create("org.keycloak.keycloak-undertow-adapter");
+
+ @Override
+ protected void addPlatformSpecificModules(ModuleSpecification moduleSpecification, ModuleLoader moduleLoader) {
+ // ModuleDependency(ModuleLoader moduleLoader, ModuleIdentifier identifier, boolean optional, boolean export, boolean importServices, boolean userSpecified)
+ moduleSpecification.addSystemDependency(new ModuleDependency(moduleLoader, KEYCLOAK_WILDFLY_ADAPTER, false, false, true, false));
+ moduleSpecification.addSystemDependency(new ModuleDependency(moduleLoader, KEYCLOAK_UNDERTOW_ADAPTER, false, false, false, false));
+ }
+}
diff --git a/integration/wildfly/wildfly-adapter-subsystem/src/main/java/org/keycloak/subsystem/adapter/extension/KeycloakExtension.java b/integration/wildfly/wildfly-adapter-subsystem/src/main/java/org/keycloak/subsystem/adapter/extension/KeycloakExtension.java
new file mode 100755
index 00000000000..31f69572e2d
--- /dev/null
+++ b/integration/wildfly/wildfly-adapter-subsystem/src/main/java/org/keycloak/subsystem/adapter/extension/KeycloakExtension.java
@@ -0,0 +1,83 @@
+/*
+ * Copyright 2013 Red Hat Inc. and/or its affiliates and other contributors
+ * as indicated by the @author tags. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package org.keycloak.subsystem.adapter.extension;
+
+import org.jboss.as.controller.Extension;
+import org.jboss.as.controller.ExtensionContext;
+import org.jboss.as.controller.ModelVersion;
+import org.jboss.as.controller.PathElement;
+import org.jboss.as.controller.ResourceDefinition;
+import org.jboss.as.controller.SubsystemRegistration;
+import org.jboss.as.controller.descriptions.StandardResourceDescriptionResolver;
+import org.jboss.as.controller.parsing.ExtensionParsingContext;
+import org.jboss.as.controller.registry.ManagementResourceRegistration;
+import org.keycloak.subsystem.adapter.logging.KeycloakLogger;
+
+import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.SUBSYSTEM;
+
+
+/**
+ * Main Extension class for the subsystem.
+ *
+ * @author Stan Silvert ssilvert@redhat.com (C) 2013 Red Hat Inc.
+ */
+public class KeycloakExtension implements Extension {
+
+ public static final String SUBSYSTEM_NAME = "keycloak";
+ public static final String NAMESPACE = "urn:jboss:domain:keycloak:1.1";
+ private static final KeycloakSubsystemParser PARSER = new KeycloakSubsystemParser();
+ static final PathElement PATH_SUBSYSTEM = PathElement.pathElement(SUBSYSTEM, SUBSYSTEM_NAME);
+ private static final String RESOURCE_NAME = KeycloakExtension.class.getPackage().getName() + ".LocalDescriptions";
+ private static final ModelVersion MGMT_API_VERSION = ModelVersion.create(1,1,0);
+ static final PathElement SUBSYSTEM_PATH = PathElement.pathElement(SUBSYSTEM, SUBSYSTEM_NAME);
+ private static final ResourceDefinition KEYCLOAK_SUBSYSTEM_RESOURCE = new KeycloakSubsystemDefinition();
+ static final RealmDefinition REALM_DEFINITION = new RealmDefinition();
+ static final SecureDeploymentDefinition SECURE_DEPLOYMENT_DEFINITION = new SecureDeploymentDefinition();
+ static final CredentialDefinition CREDENTIAL_DEFINITION = new CredentialDefinition();
+
+ public static StandardResourceDescriptionResolver getResourceDescriptionResolver(final String... keyPrefix) {
+ StringBuilder prefix = new StringBuilder(SUBSYSTEM_NAME);
+ for (String kp : keyPrefix) {
+ prefix.append('.').append(kp);
+ }
+ return new StandardResourceDescriptionResolver(prefix.toString(), RESOURCE_NAME, KeycloakExtension.class.getClassLoader(), true, false);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void initializeParsers(final ExtensionParsingContext context) {
+ context.setSubsystemXmlMapping(SUBSYSTEM_NAME, KeycloakExtension.NAMESPACE, PARSER);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void initialize(final ExtensionContext context) {
+ KeycloakLogger.ROOT_LOGGER.debug("Activating Keycloak Extension");
+ final SubsystemRegistration subsystem = context.registerSubsystem(SUBSYSTEM_NAME, MGMT_API_VERSION);
+
+ ManagementResourceRegistration registration = subsystem.registerSubsystemModel(KEYCLOAK_SUBSYSTEM_RESOURCE);
+ registration.registerSubModel(REALM_DEFINITION);
+ ManagementResourceRegistration secureDeploymentRegistration = registration.registerSubModel(SECURE_DEPLOYMENT_DEFINITION);
+ secureDeploymentRegistration.registerSubModel(CREDENTIAL_DEFINITION);
+
+ subsystem.registerXMLElementWriter(PARSER);
+ }
+}
diff --git a/integration/wildfly/wildfly-adapter-subsystem/src/main/java/org/keycloak/subsystem/adapter/extension/KeycloakSubsystemAdd.java b/integration/wildfly/wildfly-adapter-subsystem/src/main/java/org/keycloak/subsystem/adapter/extension/KeycloakSubsystemAdd.java
new file mode 100755
index 00000000000..81ad1ce5db3
--- /dev/null
+++ b/integration/wildfly/wildfly-adapter-subsystem/src/main/java/org/keycloak/subsystem/adapter/extension/KeycloakSubsystemAdd.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright 2013 Red Hat Inc. and/or its affiliates and other contributors
+ * as indicated by the @author tags. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package org.keycloak.subsystem.adapter.extension;
+
+
+import org.jboss.as.controller.AbstractBoottimeAddStepHandler;
+import org.jboss.as.controller.OperationContext;
+import org.jboss.as.server.AbstractDeploymentChainStep;
+import org.jboss.as.server.DeploymentProcessorTarget;
+import org.jboss.as.server.deployment.Phase;
+import org.jboss.dmr.ModelNode;
+
+import org.jboss.as.server.deployment.DeploymentUnitProcessor;
+
+/**
+ * The Keycloak subsystem add update handler.
+ *
+ * @author Stan Silvert ssilvert@redhat.com (C) 2013 Red Hat Inc.
+ */
+class KeycloakSubsystemAdd extends AbstractBoottimeAddStepHandler {
+
+ static final KeycloakSubsystemAdd INSTANCE = new KeycloakSubsystemAdd();
+
+ @Override
+ protected void performBoottime(final OperationContext context, ModelNode operation, final ModelNode model) {
+ context.addStep(new AbstractDeploymentChainStep() {
+ @Override
+ protected void execute(DeploymentProcessorTarget processorTarget) {
+ processorTarget.addDeploymentProcessor(KeycloakExtension.SUBSYSTEM_NAME, Phase.DEPENDENCIES, 0, chooseDependencyProcessor());
+ processorTarget.addDeploymentProcessor(KeycloakExtension.SUBSYSTEM_NAME,
+ Phase.POST_MODULE, // PHASE
+ Phase.POST_MODULE_VALIDATOR_FACTORY - 1, // PRIORITY
+ chooseConfigDeploymentProcessor());
+ }
+ }, OperationContext.Stage.RUNTIME);
+ }
+
+ private DeploymentUnitProcessor chooseDependencyProcessor() {
+ return new KeycloakDependencyProcessorWildFly();
+ }
+
+ private DeploymentUnitProcessor chooseConfigDeploymentProcessor() {
+ return new KeycloakAdapterConfigDeploymentProcessor();
+ }
+}
diff --git a/integration/wildfly/wildfly-adapter-subsystem/src/main/java/org/keycloak/subsystem/adapter/extension/KeycloakSubsystemDefinition.java b/integration/wildfly/wildfly-adapter-subsystem/src/main/java/org/keycloak/subsystem/adapter/extension/KeycloakSubsystemDefinition.java
new file mode 100644
index 00000000000..975fc6c503c
--- /dev/null
+++ b/integration/wildfly/wildfly-adapter-subsystem/src/main/java/org/keycloak/subsystem/adapter/extension/KeycloakSubsystemDefinition.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2014 Red Hat Inc. and/or its affiliates and other contributors
+ * as indicated by the @author tags. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package org.keycloak.subsystem.adapter.extension;
+
+import org.jboss.as.controller.ReloadRequiredRemoveStepHandler;
+import org.jboss.as.controller.SimpleResourceDefinition;
+import org.jboss.as.controller.operations.common.GenericSubsystemDescribeHandler;
+import org.jboss.as.controller.registry.ManagementResourceRegistration;
+
+/**
+ * Definition of subsystem=keycloak.
+ *
+ * @author Stan Silvert ssilvert@redhat.com (C) 2013 Red Hat Inc.
+ */
+public class KeycloakSubsystemDefinition extends SimpleResourceDefinition {
+ protected KeycloakSubsystemDefinition() {
+ super(KeycloakExtension.SUBSYSTEM_PATH,
+ KeycloakExtension.getResourceDescriptionResolver("subsystem"),
+ KeycloakSubsystemAdd.INSTANCE,
+ ReloadRequiredRemoveStepHandler.INSTANCE
+ );
+ }
+
+ @Override
+ public void registerOperations(ManagementResourceRegistration resourceRegistration) {
+ super.registerOperations(resourceRegistration);
+ resourceRegistration.registerOperationHandler(GenericSubsystemDescribeHandler.DEFINITION, GenericSubsystemDescribeHandler.INSTANCE);
+ }
+
+}
diff --git a/integration/wildfly/wildfly-adapter-subsystem/src/main/java/org/keycloak/subsystem/adapter/extension/KeycloakSubsystemParser.java b/integration/wildfly/wildfly-adapter-subsystem/src/main/java/org/keycloak/subsystem/adapter/extension/KeycloakSubsystemParser.java
new file mode 100755
index 00000000000..3c63f7e8323
--- /dev/null
+++ b/integration/wildfly/wildfly-adapter-subsystem/src/main/java/org/keycloak/subsystem/adapter/extension/KeycloakSubsystemParser.java
@@ -0,0 +1,224 @@
+/*
+ * Copyright 2014 Red Hat Inc. and/or its affiliates and other contributors
+ * as indicated by the @author tags. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package org.keycloak.subsystem.adapter.extension;
+
+import org.jboss.as.controller.AttributeDefinition;
+import org.jboss.as.controller.PathAddress;
+import org.jboss.as.controller.PathElement;
+import org.jboss.as.controller.SimpleAttributeDefinition;
+import org.jboss.as.controller.descriptions.ModelDescriptionConstants;
+import org.jboss.as.controller.operations.common.Util;
+import org.jboss.as.controller.parsing.ParseUtils;
+import org.jboss.as.controller.persistence.SubsystemMarshallingContext;
+import org.jboss.dmr.ModelNode;
+import org.jboss.dmr.Property;
+import org.jboss.staxmapper.XMLElementReader;
+import org.jboss.staxmapper.XMLElementWriter;
+import org.jboss.staxmapper.XMLExtendedStreamReader;
+import org.jboss.staxmapper.XMLExtendedStreamWriter;
+
+import javax.xml.stream.XMLStreamConstants;
+import javax.xml.stream.XMLStreamException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * The subsystem parser, which uses stax to read and write to and from xml
+ */
+class KeycloakSubsystemParser implements XMLStreamConstants, XMLElementReader>, XMLElementWriter {
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void readElement(final XMLExtendedStreamReader reader, final List list) throws XMLStreamException {
+ // Require no attributes
+ ParseUtils.requireNoAttributes(reader);
+ ModelNode addKeycloakSub = Util.createAddOperation(PathAddress.pathAddress(KeycloakExtension.PATH_SUBSYSTEM));
+ list.add(addKeycloakSub);
+
+ while (reader.hasNext() && nextTag(reader) != END_ELEMENT) {
+ if (reader.getLocalName().equals(RealmDefinition.TAG_NAME)) {
+ readRealm(reader, list);
+ }
+ else if (reader.getLocalName().equals(SecureDeploymentDefinition.TAG_NAME)) {
+ readDeployment(reader, list);
+ }
+ }
+ }
+
+ // used for debugging
+ private int nextTag(XMLExtendedStreamReader reader) throws XMLStreamException {
+ return reader.nextTag();
+ }
+
+ private void readRealm(XMLExtendedStreamReader reader, List list) throws XMLStreamException {
+ String realmName = readNameAttribute(reader);
+ ModelNode addRealm = new ModelNode();
+ addRealm.get(ModelDescriptionConstants.OP).set(ModelDescriptionConstants.ADD);
+ PathAddress addr = PathAddress.pathAddress(PathElement.pathElement(ModelDescriptionConstants.SUBSYSTEM, KeycloakExtension.SUBSYSTEM_NAME),
+ PathElement.pathElement(RealmDefinition.TAG_NAME, realmName));
+ addRealm.get(ModelDescriptionConstants.OP_ADDR).set(addr.toModelNode());
+
+ while (reader.hasNext() && nextTag(reader) != END_ELEMENT) {
+ String tagName = reader.getLocalName();
+ SimpleAttributeDefinition def = RealmDefinition.lookup(tagName);
+ if (def == null) throw new XMLStreamException("Unknown realm tag " + tagName);
+ def.parseAndSetParameter(reader.getElementText(), addRealm, reader);
+ }
+
+ if (!SharedAttributeDefinitons.validateTruststoreSetIfRequired(addRealm)) {
+ //TODO: externalize the message
+ throw new XMLStreamException("truststore and truststore-password must be set if ssl-required is not none and disable-trust-maanger is false.");
+ }
+
+ list.add(addRealm);
+ }
+
+ private void readDeployment(XMLExtendedStreamReader reader, List resourcesToAdd) throws XMLStreamException {
+ String name = readNameAttribute(reader);
+ ModelNode addSecureDeployment = new ModelNode();
+ addSecureDeployment.get(ModelDescriptionConstants.OP).set(ModelDescriptionConstants.ADD);
+ PathAddress addr = PathAddress.pathAddress(PathElement.pathElement(ModelDescriptionConstants.SUBSYSTEM, KeycloakExtension.SUBSYSTEM_NAME),
+ PathElement.pathElement(SecureDeploymentDefinition.TAG_NAME, name));
+ addSecureDeployment.get(ModelDescriptionConstants.OP_ADDR).set(addr.toModelNode());
+ List credentialsToAdd = new ArrayList();
+ while (reader.hasNext() && nextTag(reader) != END_ELEMENT) {
+ String tagName = reader.getLocalName();
+ if (tagName.equals(CredentialDefinition.TAG_NAME)) {
+ readCredential(reader, addr, credentialsToAdd);
+ continue;
+ }
+
+ SimpleAttributeDefinition def = SecureDeploymentDefinition.lookup(tagName);
+ if (def == null) throw new XMLStreamException("Unknown secure-deployment tag " + tagName);
+ def.parseAndSetParameter(reader.getElementText(), addSecureDeployment, reader);
+ }
+
+
+ /**
+ * TODO need to check realm-ref first.
+ if (!SharedAttributeDefinitons.validateTruststoreSetIfRequired(addSecureDeployment)) {
+ //TODO: externalize the message
+ throw new XMLStreamException("truststore and truststore-password must be set if ssl-required is not none and disable-trust-maanger is false.");
+ }
+ */
+
+ // Must add credentials after the deployment is added.
+ resourcesToAdd.add(addSecureDeployment);
+ resourcesToAdd.addAll(credentialsToAdd);
+ }
+
+ public void readCredential(XMLExtendedStreamReader reader, PathAddress parent, List credentialsToAdd) throws XMLStreamException {
+ String name = readNameAttribute(reader);
+ ModelNode addCredential = new ModelNode();
+ addCredential.get(ModelDescriptionConstants.OP).set(ModelDescriptionConstants.ADD);
+ PathAddress addr = PathAddress.pathAddress(parent, PathElement.pathElement(CredentialDefinition.TAG_NAME, name));
+ addCredential.get(ModelDescriptionConstants.OP_ADDR).set(addr.toModelNode());
+ addCredential.get(CredentialDefinition.VALUE.getName()).set(reader.getElementText());
+ credentialsToAdd.add(addCredential);
+ }
+
+ // expects that the current tag will have one single attribute called "name"
+ private String readNameAttribute(XMLExtendedStreamReader reader) throws XMLStreamException {
+ String name = null;
+ for (int i = 0; i < reader.getAttributeCount(); i++) {
+ String attr = reader.getAttributeLocalName(i);
+ if (attr.equals("name")) {
+ name = reader.getAttributeValue(i);
+ continue;
+ }
+ throw ParseUtils.unexpectedAttribute(reader, i);
+ }
+ if (name == null) {
+ throw ParseUtils.missingRequired(reader, Collections.singleton("name"));
+ }
+ return name;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void writeContent(final XMLExtendedStreamWriter writer, final SubsystemMarshallingContext context) throws XMLStreamException {
+ context.startSubsystemElement(KeycloakExtension.NAMESPACE, false);
+ writeRealms(writer, context);
+ writeSecureDeployments(writer, context);
+ writer.writeEndElement();
+ }
+
+ private void writeRealms(XMLExtendedStreamWriter writer, SubsystemMarshallingContext context) throws XMLStreamException {
+ if (!context.getModelNode().get(RealmDefinition.TAG_NAME).isDefined()) {
+ return;
+ }
+ for (Property realm : context.getModelNode().get(RealmDefinition.TAG_NAME).asPropertyList()) {
+ writer.writeStartElement(RealmDefinition.TAG_NAME);
+ writer.writeAttribute("name", realm.getName());
+ ModelNode realmElements = realm.getValue();
+ for (AttributeDefinition element : RealmDefinition.ALL_ATTRIBUTES) {
+ element.marshallAsElement(realmElements, writer);
+ }
+
+ writer.writeEndElement();
+ }
+ }
+
+ private void writeSecureDeployments(XMLExtendedStreamWriter writer, SubsystemMarshallingContext context) throws XMLStreamException {
+ if (!context.getModelNode().get(SecureDeploymentDefinition.TAG_NAME).isDefined()) {
+ return;
+ }
+ for (Property deployment : context.getModelNode().get(SecureDeploymentDefinition.TAG_NAME).asPropertyList()) {
+ writer.writeStartElement(SecureDeploymentDefinition.TAG_NAME);
+ writer.writeAttribute("name", deployment.getName());
+ ModelNode deploymentElements = deployment.getValue();
+ for (AttributeDefinition element : SecureDeploymentDefinition.ALL_ATTRIBUTES) {
+ element.marshallAsElement(deploymentElements, writer);
+ }
+
+ ModelNode credentials = deploymentElements.get(CredentialDefinition.TAG_NAME);
+ if (credentials.isDefined()) {
+ writeCredentials(writer, credentials);
+ }
+
+ writer.writeEndElement();
+ }
+ }
+
+ private void writeCredentials(XMLExtendedStreamWriter writer, ModelNode credentials) throws XMLStreamException {
+ for (Property credential : credentials.asPropertyList()) {
+ writer.writeStartElement(CredentialDefinition.TAG_NAME);
+ writer.writeAttribute("name", credential.getName());
+ String credentialValue = credential.getValue().get(CredentialDefinition.VALUE.getName()).asString();
+ writeCharacters(writer, credentialValue);
+ writer.writeEndElement();
+ }
+ }
+
+ // code taken from org.jboss.as.controller.AttributeMarshaller
+ private void writeCharacters(XMLExtendedStreamWriter writer, String content) throws XMLStreamException {
+ if (content.indexOf('\n') > -1) {
+ // Multiline content. Use the overloaded variant that staxmapper will format
+ writer.writeCharacters(content);
+ } else {
+ // Staxmapper will just output the chars without adding newlines if this is used
+ char[] chars = content.toCharArray();
+ writer.writeCharacters(chars, 0, chars.length);
+ }
+ }
+
+}
diff --git a/integration/wildfly/wildfly-adapter-subsystem/src/main/java/org/keycloak/subsystem/adapter/extension/RealmAddHandler.java b/integration/wildfly/wildfly-adapter-subsystem/src/main/java/org/keycloak/subsystem/adapter/extension/RealmAddHandler.java
new file mode 100755
index 00000000000..1651ddf6513
--- /dev/null
+++ b/integration/wildfly/wildfly-adapter-subsystem/src/main/java/org/keycloak/subsystem/adapter/extension/RealmAddHandler.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright 2013 Red Hat Inc. and/or its affiliates and other contributors
+ * as indicated by the @author tags. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package org.keycloak.subsystem.adapter.extension;
+
+import org.jboss.as.controller.AbstractAddStepHandler;
+import org.jboss.as.controller.AttributeDefinition;
+import org.jboss.as.controller.OperationContext;
+import org.jboss.as.controller.OperationFailedException;
+import org.jboss.dmr.ModelNode;
+
+import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.ADD;
+import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.OP;
+
+/**
+ * Add a new realm.
+ *
+ * @author Stan Silvert ssilvert@redhat.com (C) 2013 Red Hat Inc.
+ */
+public final class RealmAddHandler extends AbstractAddStepHandler {
+
+ public static RealmAddHandler INSTANCE = new RealmAddHandler();
+
+ private RealmAddHandler() {}
+
+ @Override
+ protected void populateModel(ModelNode operation, ModelNode model) throws OperationFailedException {
+ // TODO: localize exception. get id number
+ if (!operation.get(OP).asString().equals(ADD)) {
+ throw new OperationFailedException("Unexpected operation for add realm. operation=" + operation.toString());
+ }
+
+ for (AttributeDefinition attrib : RealmDefinition.ALL_ATTRIBUTES) {
+ attrib.validateAndSet(operation, model);
+ }
+
+ if (!SharedAttributeDefinitons.validateTruststoreSetIfRequired(model.clone())) {
+ //TODO: externalize message
+ throw new OperationFailedException("truststore and truststore-password must be set if ssl-required is not none and disable-trust-maanger is false.");
+ }
+ }
+
+ @Override
+ protected void performRuntime(OperationContext context, ModelNode operation, ModelNode model) throws OperationFailedException {
+ KeycloakAdapterConfigService ckService = KeycloakAdapterConfigService.getInstance();
+ ckService.addRealm(operation, context.resolveExpressions(model));
+ }
+}
diff --git a/integration/wildfly/wildfly-adapter-subsystem/src/main/java/org/keycloak/subsystem/adapter/extension/RealmDefinition.java b/integration/wildfly/wildfly-adapter-subsystem/src/main/java/org/keycloak/subsystem/adapter/extension/RealmDefinition.java
new file mode 100755
index 00000000000..160a6eb2020
--- /dev/null
+++ b/integration/wildfly/wildfly-adapter-subsystem/src/main/java/org/keycloak/subsystem/adapter/extension/RealmDefinition.java
@@ -0,0 +1,87 @@
+/*
+ * Copyright 2013 Red Hat Inc. and/or its affiliates and other contributors
+ * as indicated by the @author tags. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package org.keycloak.subsystem.adapter.extension;
+
+import org.jboss.as.controller.AttributeDefinition;
+import org.jboss.as.controller.PathElement;
+import org.jboss.as.controller.SimpleAttributeDefinition;
+import org.jboss.as.controller.SimpleResourceDefinition;
+import org.jboss.as.controller.operations.common.GenericSubsystemDescribeHandler;
+import org.jboss.as.controller.registry.ManagementResourceRegistration;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Defines attributes and operations for the Realm
+ *
+ * @author Stan Silvert ssilvert@redhat.com (C) 2013 Red Hat Inc.
+ */
+public class RealmDefinition extends SimpleResourceDefinition {
+
+ public static final String TAG_NAME = "realm";
+
+
+ protected static final List REALM_ONLY_ATTRIBUTES = new ArrayList();
+ static {
+ }
+
+ protected static final List ALL_ATTRIBUTES = new ArrayList();
+ static {
+ ALL_ATTRIBUTES.addAll(REALM_ONLY_ATTRIBUTES);
+ ALL_ATTRIBUTES.addAll(SharedAttributeDefinitons.ATTRIBUTES);
+ }
+
+ private static final Map DEFINITION_LOOKUP = new HashMap();
+ static {
+ for (SimpleAttributeDefinition def : ALL_ATTRIBUTES) {
+ DEFINITION_LOOKUP.put(def.getXmlName(), def);
+ }
+ }
+
+ private static final RealmWriteAttributeHandler realmAttrHandler = new RealmWriteAttributeHandler(ALL_ATTRIBUTES.toArray(new SimpleAttributeDefinition[0]));
+
+ public RealmDefinition() {
+ super(PathElement.pathElement("realm"),
+ KeycloakExtension.getResourceDescriptionResolver("realm"),
+ RealmAddHandler.INSTANCE,
+ RealmRemoveHandler.INSTANCE);
+ }
+
+ @Override
+ public void registerOperations(ManagementResourceRegistration resourceRegistration) {
+ super.registerOperations(resourceRegistration);
+ resourceRegistration.registerOperationHandler(GenericSubsystemDescribeHandler.DEFINITION, GenericSubsystemDescribeHandler.INSTANCE);
+ }
+
+ @Override
+ public void registerAttributes(ManagementResourceRegistration resourceRegistration) {
+ super.registerAttributes(resourceRegistration);
+
+ for (AttributeDefinition attrDef : ALL_ATTRIBUTES) {
+ //TODO: use subclass of realmAttrHandler that can call RealmDefinition.validateTruststoreSetIfRequired
+ resourceRegistration.registerReadWriteAttribute(attrDef, null, realmAttrHandler);
+ }
+ }
+
+
+ public static SimpleAttributeDefinition lookup(String name) {
+ return DEFINITION_LOOKUP.get(name);
+ }
+}
diff --git a/integration/wildfly/wildfly-adapter-subsystem/src/main/java/org/keycloak/subsystem/adapter/extension/RealmRemoveHandler.java b/integration/wildfly/wildfly-adapter-subsystem/src/main/java/org/keycloak/subsystem/adapter/extension/RealmRemoveHandler.java
new file mode 100644
index 00000000000..16e43618ab6
--- /dev/null
+++ b/integration/wildfly/wildfly-adapter-subsystem/src/main/java/org/keycloak/subsystem/adapter/extension/RealmRemoveHandler.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2013 Red Hat Inc. and/or its affiliates and other contributors
+ * as indicated by the @author tags. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package org.keycloak.subsystem.adapter.extension;
+
+import org.jboss.as.controller.AbstractRemoveStepHandler;
+import org.jboss.as.controller.OperationContext;
+import org.jboss.as.controller.OperationFailedException;
+import org.jboss.dmr.ModelNode;
+
+/**
+ * Remove a realm.
+ *
+ * @author Stan Silvert ssilvert@redhat.com (C) 2013 Red Hat Inc.
+ */
+public final class RealmRemoveHandler extends AbstractRemoveStepHandler {
+
+ public static RealmRemoveHandler INSTANCE = new RealmRemoveHandler();
+
+ private RealmRemoveHandler() {}
+
+ @Override
+ protected void performRuntime(OperationContext context, ModelNode operation, ModelNode model) throws OperationFailedException {
+ KeycloakAdapterConfigService ckService = KeycloakAdapterConfigService.getInstance();
+ ckService.removeRealm(operation);
+ }
+}
diff --git a/integration/wildfly/wildfly-adapter-subsystem/src/main/java/org/keycloak/subsystem/adapter/extension/RealmWriteAttributeHandler.java b/integration/wildfly/wildfly-adapter-subsystem/src/main/java/org/keycloak/subsystem/adapter/extension/RealmWriteAttributeHandler.java
new file mode 100755
index 00000000000..f8f5e41b105
--- /dev/null
+++ b/integration/wildfly/wildfly-adapter-subsystem/src/main/java/org/keycloak/subsystem/adapter/extension/RealmWriteAttributeHandler.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright 2013 Red Hat Inc. and/or its affiliates and other contributors
+ * as indicated by the @author tags. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package org.keycloak.subsystem.adapter.extension;
+
+import org.jboss.as.controller.AbstractWriteAttributeHandler;
+import org.jboss.as.controller.AttributeDefinition;
+import org.jboss.as.controller.OperationContext;
+import org.jboss.as.controller.OperationFailedException;
+import org.jboss.dmr.ModelNode;
+
+/**
+ * Update an attribute on a realm.
+ *
+ * @author Stan Silvert ssilvert@redhat.com (C) 2013 Red Hat Inc.
+ */
+public class RealmWriteAttributeHandler extends AbstractWriteAttributeHandler {
+
+ public RealmWriteAttributeHandler(AttributeDefinition... definitions) {
+ super(definitions);
+ }
+
+ @Override
+ protected boolean applyUpdateToRuntime(OperationContext context, ModelNode operation, String attributeName,
+ ModelNode resolvedValue, ModelNode currentValue, HandbackHolder hh) throws OperationFailedException {
+ KeycloakAdapterConfigService ckService = KeycloakAdapterConfigService.getInstance();
+ ckService.updateRealm(operation, attributeName, resolvedValue);
+
+ hh.setHandback(ckService);
+
+ return false;
+ }
+
+ @Override
+ protected void revertUpdateToRuntime(OperationContext context, ModelNode operation, String attributeName,
+ ModelNode valueToRestore, ModelNode valueToRevert, KeycloakAdapterConfigService ckService) throws OperationFailedException {
+ ckService.updateRealm(operation, attributeName, valueToRestore);
+ }
+
+}
diff --git a/integration/wildfly/wildfly-adapter-subsystem/src/main/java/org/keycloak/subsystem/adapter/extension/SecureDeploymentAddHandler.java b/integration/wildfly/wildfly-adapter-subsystem/src/main/java/org/keycloak/subsystem/adapter/extension/SecureDeploymentAddHandler.java
new file mode 100755
index 00000000000..8bf263df2e8
--- /dev/null
+++ b/integration/wildfly/wildfly-adapter-subsystem/src/main/java/org/keycloak/subsystem/adapter/extension/SecureDeploymentAddHandler.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright 2013 Red Hat Inc. and/or its affiliates and other contributors
+ * as indicated by the @author tags. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package org.keycloak.subsystem.adapter.extension;
+
+import org.jboss.as.controller.AbstractAddStepHandler;
+import org.jboss.as.controller.AttributeDefinition;
+import org.jboss.as.controller.OperationContext;
+import org.jboss.as.controller.OperationFailedException;
+import org.jboss.dmr.ModelNode;
+
+import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.ADD;
+import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.OP;
+
+/**
+ * Add a deployment to a realm.
+ *
+ * @author Stan Silvert ssilvert@redhat.com (C) 2013 Red Hat Inc.
+ */
+public final class SecureDeploymentAddHandler extends AbstractAddStepHandler {
+
+ public static SecureDeploymentAddHandler INSTANCE = new SecureDeploymentAddHandler();
+
+ private SecureDeploymentAddHandler() {}
+
+ @Override
+ protected void populateModel(ModelNode operation, ModelNode model) throws OperationFailedException {
+ // TODO: localize exception. get id number
+ if (!operation.get(OP).asString().equals(ADD)) {
+ throw new OperationFailedException("Unexpected operation for add secure deployment. operation=" + operation.toString());
+ }
+
+ for (AttributeDefinition attr : SecureDeploymentDefinition.ALL_ATTRIBUTES) {
+ attr.validateAndSet(operation, model);
+ }
+ }
+
+ @Override
+ protected void performRuntime(OperationContext context, ModelNode operation, ModelNode model) throws OperationFailedException {
+ KeycloakAdapterConfigService ckService = KeycloakAdapterConfigService.getInstance();
+ ckService.addSecureDeployment(operation, context.resolveExpressions(model));
+ }
+}
diff --git a/integration/wildfly/wildfly-adapter-subsystem/src/main/java/org/keycloak/subsystem/adapter/extension/SecureDeploymentDefinition.java b/integration/wildfly/wildfly-adapter-subsystem/src/main/java/org/keycloak/subsystem/adapter/extension/SecureDeploymentDefinition.java
new file mode 100755
index 00000000000..1932cc8e8e2
--- /dev/null
+++ b/integration/wildfly/wildfly-adapter-subsystem/src/main/java/org/keycloak/subsystem/adapter/extension/SecureDeploymentDefinition.java
@@ -0,0 +1,130 @@
+/*
+ * Copyright 2013 Red Hat Inc. and/or its affiliates and other contributors
+ * as indicated by the @author tags. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package org.keycloak.subsystem.adapter.extension;
+
+import org.jboss.as.controller.AttributeDefinition;
+import org.jboss.as.controller.PathElement;
+import org.jboss.as.controller.SimpleAttributeDefinition;
+import org.jboss.as.controller.SimpleAttributeDefinitionBuilder;
+import org.jboss.as.controller.SimpleResourceDefinition;
+import org.jboss.as.controller.operations.common.GenericSubsystemDescribeHandler;
+import org.jboss.as.controller.operations.validation.StringLengthValidator;
+import org.jboss.as.controller.registry.ManagementResourceRegistration;
+import org.jboss.dmr.ModelNode;
+import org.jboss.dmr.ModelType;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Defines attributes and operations for a secure-deployment.
+ *
+ * @author Stan Silvert ssilvert@redhat.com (C) 2013 Red Hat Inc.
+ */
+public class SecureDeploymentDefinition extends SimpleResourceDefinition {
+
+ public static final String TAG_NAME = "secure-deployment";
+
+ protected static final SimpleAttributeDefinition REALM =
+ new SimpleAttributeDefinitionBuilder("realm", ModelType.STRING, true)
+ .setXmlName("realm")
+ .setAllowExpression(true)
+ .setValidator(new StringLengthValidator(1, Integer.MAX_VALUE, true, true))
+ .build();
+ protected static final SimpleAttributeDefinition RESOURCE =
+ new SimpleAttributeDefinitionBuilder("resource", ModelType.STRING, true)
+ .setXmlName("resource")
+ .setAllowExpression(true)
+ .setValidator(new StringLengthValidator(1, Integer.MAX_VALUE, true, true))
+ .build();
+ protected static final SimpleAttributeDefinition USE_RESOURCE_ROLE_MAPPINGS =
+ new SimpleAttributeDefinitionBuilder("use-resource-role-mappings", ModelType.BOOLEAN, true)
+ .setXmlName("use-resource-role-mappings")
+ .setAllowExpression(true)
+ .setDefaultValue(new ModelNode(false))
+ .build();
+ protected static final SimpleAttributeDefinition BEARER_ONLY =
+ new SimpleAttributeDefinitionBuilder("bearer-only", ModelType.BOOLEAN, true)
+ .setXmlName("bearer-only")
+ .setAllowExpression(true)
+ .setDefaultValue(new ModelNode(false))
+ .build();
+ protected static final SimpleAttributeDefinition ENABLE_BASIC_AUTH =
+ new SimpleAttributeDefinitionBuilder("enable-basic-auth", ModelType.BOOLEAN, true)
+ .setXmlName("enable-basic-auth")
+ .setAllowExpression(true)
+ .setDefaultValue(new ModelNode(false))
+ .build();
+ protected static final SimpleAttributeDefinition PUBLIC_CLIENT =
+ new SimpleAttributeDefinitionBuilder("public-client", ModelType.BOOLEAN, true)
+ .setXmlName("public-client")
+ .setAllowExpression(true)
+ .setDefaultValue(new ModelNode(false))
+ .build();
+
+ protected static final List DEPLOYMENT_ONLY_ATTRIBUTES = new ArrayList();
+ static {
+ DEPLOYMENT_ONLY_ATTRIBUTES.add(REALM);
+ DEPLOYMENT_ONLY_ATTRIBUTES.add(RESOURCE);
+ DEPLOYMENT_ONLY_ATTRIBUTES.add(USE_RESOURCE_ROLE_MAPPINGS);
+ DEPLOYMENT_ONLY_ATTRIBUTES.add(BEARER_ONLY);
+ DEPLOYMENT_ONLY_ATTRIBUTES.add(ENABLE_BASIC_AUTH);
+ DEPLOYMENT_ONLY_ATTRIBUTES.add(PUBLIC_CLIENT);
+ }
+
+ protected static final List ALL_ATTRIBUTES = new ArrayList();
+ static {
+ ALL_ATTRIBUTES.addAll(DEPLOYMENT_ONLY_ATTRIBUTES);
+ ALL_ATTRIBUTES.addAll(SharedAttributeDefinitons.ATTRIBUTES);
+ }
+
+ private static final Map DEFINITION_LOOKUP = new HashMap();
+ static {
+ for (SimpleAttributeDefinition def : ALL_ATTRIBUTES) {
+ DEFINITION_LOOKUP.put(def.getXmlName(), def);
+ }
+ }
+
+ private static SecureDeploymentWriteAttributeHandler attrHandler = new SecureDeploymentWriteAttributeHandler(ALL_ATTRIBUTES);
+
+ public SecureDeploymentDefinition() {
+ super(PathElement.pathElement(TAG_NAME),
+ KeycloakExtension.getResourceDescriptionResolver(TAG_NAME),
+ SecureDeploymentAddHandler.INSTANCE,
+ SecureDeploymentRemoveHandler.INSTANCE);
+ }
+
+ @Override
+ public void registerOperations(ManagementResourceRegistration resourceRegistration) {
+ super.registerOperations(resourceRegistration);
+ resourceRegistration.registerOperationHandler(GenericSubsystemDescribeHandler.DEFINITION, GenericSubsystemDescribeHandler.INSTANCE);
+ }
+
+ @Override
+ public void registerAttributes(ManagementResourceRegistration resourceRegistration) {
+ super.registerAttributes(resourceRegistration);
+ for (AttributeDefinition attrDef : ALL_ATTRIBUTES) {
+ resourceRegistration.registerReadWriteAttribute(attrDef, null, attrHandler);
+ }
+ }
+
+ public static SimpleAttributeDefinition lookup(String name) {
+ return DEFINITION_LOOKUP.get(name);
+ }
+}
diff --git a/integration/wildfly/wildfly-adapter-subsystem/src/main/java/org/keycloak/subsystem/adapter/extension/SecureDeploymentRemoveHandler.java b/integration/wildfly/wildfly-adapter-subsystem/src/main/java/org/keycloak/subsystem/adapter/extension/SecureDeploymentRemoveHandler.java
new file mode 100644
index 00000000000..6e2aefc1ef6
--- /dev/null
+++ b/integration/wildfly/wildfly-adapter-subsystem/src/main/java/org/keycloak/subsystem/adapter/extension/SecureDeploymentRemoveHandler.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2013 Red Hat Inc. and/or its affiliates and other contributors
+ * as indicated by the @author tags. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package org.keycloak.subsystem.adapter.extension;
+
+import org.jboss.as.controller.AbstractRemoveStepHandler;
+import org.jboss.as.controller.OperationContext;
+import org.jboss.as.controller.OperationFailedException;
+import org.jboss.dmr.ModelNode;
+
+/**
+ * Remove a secure-deployment from a realm.
+ *
+ * @author Stan Silvert ssilvert@redhat.com (C) 2013 Red Hat Inc.
+ */
+public final class SecureDeploymentRemoveHandler extends AbstractRemoveStepHandler {
+
+ public static SecureDeploymentRemoveHandler INSTANCE = new SecureDeploymentRemoveHandler();
+
+ private SecureDeploymentRemoveHandler() {}
+
+ @Override
+ protected void performRuntime(OperationContext context, ModelNode operation, ModelNode model) throws OperationFailedException {
+ KeycloakAdapterConfigService ckService = KeycloakAdapterConfigService.getInstance();
+ ckService.removeSecureDeployment(operation);
+ }
+}
diff --git a/integration/wildfly/wildfly-adapter-subsystem/src/main/java/org/keycloak/subsystem/adapter/extension/SecureDeploymentWriteAttributeHandler.java b/integration/wildfly/wildfly-adapter-subsystem/src/main/java/org/keycloak/subsystem/adapter/extension/SecureDeploymentWriteAttributeHandler.java
new file mode 100755
index 00000000000..6ed9d55b422
--- /dev/null
+++ b/integration/wildfly/wildfly-adapter-subsystem/src/main/java/org/keycloak/subsystem/adapter/extension/SecureDeploymentWriteAttributeHandler.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright 2013 Red Hat Inc. and/or its affiliates and other contributors
+ * as indicated by the @author tags. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package org.keycloak.subsystem.adapter.extension;
+
+import org.jboss.as.controller.AbstractWriteAttributeHandler;
+import org.jboss.as.controller.AttributeDefinition;
+import org.jboss.as.controller.OperationContext;
+import org.jboss.as.controller.OperationFailedException;
+import org.jboss.as.controller.SimpleAttributeDefinition;
+import org.jboss.dmr.ModelNode;
+
+import java.util.List;
+
+/**
+ * Update an attribute on a secure-deployment.
+ *
+ * @author Stan Silvert ssilvert@redhat.com (C) 2013 Red Hat Inc.
+ */
+public class SecureDeploymentWriteAttributeHandler extends AbstractWriteAttributeHandler {
+
+ public SecureDeploymentWriteAttributeHandler(List definitions) {
+ this(definitions.toArray(new AttributeDefinition[definitions.size()]));
+ }
+
+ public SecureDeploymentWriteAttributeHandler(AttributeDefinition... definitions) {
+ super(definitions);
+ }
+
+ @Override
+ protected boolean applyUpdateToRuntime(OperationContext context, ModelNode operation, String attributeName,
+ ModelNode resolvedValue, ModelNode currentValue, HandbackHolder hh) throws OperationFailedException {
+ KeycloakAdapterConfigService ckService = KeycloakAdapterConfigService.getInstance();
+ hh.setHandback(ckService);
+ ckService.updateSecureDeployment(operation, attributeName, resolvedValue);
+ return false;
+ }
+
+ @Override
+ protected void revertUpdateToRuntime(OperationContext context, ModelNode operation, String attributeName,
+ ModelNode valueToRestore, ModelNode valueToRevert, KeycloakAdapterConfigService ckService) throws OperationFailedException {
+ ckService.updateSecureDeployment(operation, attributeName, valueToRestore);
+ }
+
+}
diff --git a/integration/wildfly/wildfly-adapter-subsystem/src/main/java/org/keycloak/subsystem/adapter/extension/SharedAttributeDefinitons.java b/integration/wildfly/wildfly-adapter-subsystem/src/main/java/org/keycloak/subsystem/adapter/extension/SharedAttributeDefinitons.java
new file mode 100755
index 00000000000..f7abc0485a2
--- /dev/null
+++ b/integration/wildfly/wildfly-adapter-subsystem/src/main/java/org/keycloak/subsystem/adapter/extension/SharedAttributeDefinitons.java
@@ -0,0 +1,228 @@
+/*
+ * Copyright 2013 Red Hat Inc. and/or its affiliates and other contributors
+ * as indicated by the @author tags. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package org.keycloak.subsystem.adapter.extension;
+
+import org.jboss.as.controller.SimpleAttributeDefinition;
+import org.jboss.as.controller.SimpleAttributeDefinitionBuilder;
+import org.jboss.as.controller.operations.validation.IntRangeValidator;
+import org.jboss.as.controller.operations.validation.StringLengthValidator;
+import org.jboss.dmr.ModelNode;
+import org.jboss.dmr.ModelType;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Defines attributes that can be present in both a realm and an application (secure-deployment).
+ *
+ * @author Stan Silvert ssilvert@redhat.com (C) 2013 Red Hat Inc.
+ */
+public class SharedAttributeDefinitons {
+
+ protected static final SimpleAttributeDefinition REALM_PUBLIC_KEY =
+ new SimpleAttributeDefinitionBuilder("realm-public-key", ModelType.STRING, true)
+ .setXmlName("realm-public-key")
+ .setAllowExpression(true)
+ .setValidator(new StringLengthValidator(1, Integer.MAX_VALUE, true, true))
+ .build();
+ protected static final SimpleAttributeDefinition AUTH_SERVER_URL =
+ new SimpleAttributeDefinitionBuilder("auth-server-url", ModelType.STRING, true)
+ .setXmlName("auth-server-url")
+ .setAllowExpression(true)
+ .setValidator(new StringLengthValidator(1, Integer.MAX_VALUE, true, true))
+ .build();
+ protected static final SimpleAttributeDefinition SSL_REQUIRED =
+ new SimpleAttributeDefinitionBuilder("ssl-required", ModelType.STRING, true)
+ .setXmlName("ssl-required")
+ .setAllowExpression(true)
+ .setDefaultValue(new ModelNode("external"))
+ .build();
+ protected static final SimpleAttributeDefinition ALLOW_ANY_HOSTNAME =
+ new SimpleAttributeDefinitionBuilder("allow-any-hostname", ModelType.BOOLEAN, true)
+ .setXmlName("allow-any-hostname")
+ .setAllowExpression(true)
+ .setDefaultValue(new ModelNode(false))
+ .build();
+ protected static final SimpleAttributeDefinition DISABLE_TRUST_MANAGER =
+ new SimpleAttributeDefinitionBuilder("disable-trust-manager", ModelType.BOOLEAN, true)
+ .setXmlName("disable-trust-manager")
+ .setAllowExpression(true)
+ .setDefaultValue(new ModelNode(false))
+ .build();
+ protected static final SimpleAttributeDefinition TRUSTSTORE =
+ new SimpleAttributeDefinitionBuilder("truststore", ModelType.STRING, true)
+ .setXmlName("truststore")
+ .setAllowExpression(true)
+ .setValidator(new StringLengthValidator(1, Integer.MAX_VALUE, true, true))
+ .build();
+ protected static final SimpleAttributeDefinition TRUSTSTORE_PASSWORD =
+ new SimpleAttributeDefinitionBuilder("truststore-password", ModelType.STRING, true)
+ .setXmlName("truststore-password")
+ .setAllowExpression(true)
+ .setValidator(new StringLengthValidator(1, Integer.MAX_VALUE, true, true))
+ .build();
+ protected static final SimpleAttributeDefinition CONNECTION_POOL_SIZE =
+ new SimpleAttributeDefinitionBuilder("connection-pool-size", ModelType.INT, true)
+ .setXmlName("connection-pool-size")
+ .setAllowExpression(true)
+ .setValidator(new IntRangeValidator(0, true))
+ .build();
+
+ protected static final SimpleAttributeDefinition ENABLE_CORS =
+ new SimpleAttributeDefinitionBuilder("enable-cors", ModelType.BOOLEAN, true)
+ .setXmlName("enable-cors")
+ .setAllowExpression(true)
+ .setDefaultValue(new ModelNode(false))
+ .build();
+ protected static final SimpleAttributeDefinition CLIENT_KEYSTORE =
+ new SimpleAttributeDefinitionBuilder("client-keystore", ModelType.STRING, true)
+ .setXmlName("client-keystore")
+ .setAllowExpression(true)
+ .setValidator(new StringLengthValidator(1, Integer.MAX_VALUE, true, true))
+ .build();
+ protected static final SimpleAttributeDefinition CLIENT_KEYSTORE_PASSWORD =
+ new SimpleAttributeDefinitionBuilder("client-keystore-password", ModelType.STRING, true)
+ .setXmlName("client-keystore-password")
+ .setAllowExpression(true)
+ .setValidator(new StringLengthValidator(1, Integer.MAX_VALUE, true, true))
+ .build();
+ protected static final SimpleAttributeDefinition CLIENT_KEY_PASSWORD =
+ new SimpleAttributeDefinitionBuilder("client-key-password", ModelType.STRING, true)
+ .setXmlName("client-key-password")
+ .setAllowExpression(true)
+ .setValidator(new StringLengthValidator(1, Integer.MAX_VALUE, true, true))
+ .build();
+ protected static final SimpleAttributeDefinition CORS_MAX_AGE =
+ new SimpleAttributeDefinitionBuilder("cors-max-age", ModelType.INT, true)
+ .setXmlName("cors-max-age")
+ .setAllowExpression(true)
+ .setValidator(new IntRangeValidator(-1, true))
+ .build();
+ protected static final SimpleAttributeDefinition CORS_ALLOWED_HEADERS =
+ new SimpleAttributeDefinitionBuilder("cors-allowed-headers", ModelType.STRING, true)
+ .setXmlName("cors-allowed-headers")
+ .setAllowExpression(true)
+ .setValidator(new StringLengthValidator(1, Integer.MAX_VALUE, true, true))
+ .build();
+ protected static final SimpleAttributeDefinition CORS_ALLOWED_METHODS =
+ new SimpleAttributeDefinitionBuilder("cors-allowed-methods", ModelType.STRING, true)
+ .setXmlName("cors-allowed-methods")
+ .setAllowExpression(true)
+ .setValidator(new StringLengthValidator(1, Integer.MAX_VALUE, true, true))
+ .build();
+ protected static final SimpleAttributeDefinition EXPOSE_TOKEN =
+ new SimpleAttributeDefinitionBuilder("expose-token", ModelType.BOOLEAN, true)
+ .setXmlName("expose-token")
+ .setAllowExpression(true)
+ .setDefaultValue(new ModelNode(false))
+ .build();
+ protected static final SimpleAttributeDefinition AUTH_SERVER_URL_FOR_BACKEND_REQUESTS =
+ new SimpleAttributeDefinitionBuilder("auth-server-url-for-backend-requests", ModelType.STRING, true)
+ .setXmlName("auth-server-url-for-backend-requests")
+ .setAllowExpression(true)
+ .setValidator(new StringLengthValidator(1, Integer.MAX_VALUE, true, true))
+ .build();
+ protected static final SimpleAttributeDefinition ALWAYS_REFRESH_TOKEN =
+ new SimpleAttributeDefinitionBuilder("always-refresh-token", ModelType.BOOLEAN, true)
+ .setXmlName("always-refresh-token")
+ .setAllowExpression(true)
+ .setDefaultValue(new ModelNode(false))
+ .build();
+ protected static final SimpleAttributeDefinition REGISTER_NODE_AT_STARTUP =
+ new SimpleAttributeDefinitionBuilder("register-node-at-startup", ModelType.BOOLEAN, true)
+ .setXmlName("register-node-at-startup")
+ .setAllowExpression(true)
+ .setDefaultValue(new ModelNode(false))
+ .build();
+ protected static final SimpleAttributeDefinition REGISTER_NODE_PERIOD =
+ new SimpleAttributeDefinitionBuilder("register-node-period", ModelType.INT, true)
+ .setXmlName("register-node-period")
+ .setAllowExpression(true)
+ .setValidator(new IntRangeValidator(-1, true))
+ .build();
+ protected static final SimpleAttributeDefinition TOKEN_STORE =
+ new SimpleAttributeDefinitionBuilder("token-store", ModelType.STRING, true)
+ .setXmlName("token-store")
+ .setAllowExpression(true)
+ .setValidator(new StringLengthValidator(1, Integer.MAX_VALUE, true, true))
+ .build();
+ protected static final SimpleAttributeDefinition PRINCIPAL_ATTRIBUTE =
+ new SimpleAttributeDefinitionBuilder("principal-attribute", ModelType.STRING, true)
+ .setXmlName("principal-attribute")
+ .setAllowExpression(true)
+ .setValidator(new StringLengthValidator(1, Integer.MAX_VALUE, true, true))
+ .build();
+
+
+
+ protected static final List ATTRIBUTES = new ArrayList();
+ static {
+ ATTRIBUTES.add(REALM_PUBLIC_KEY);
+ ATTRIBUTES.add(AUTH_SERVER_URL);
+ ATTRIBUTES.add(TRUSTSTORE);
+ ATTRIBUTES.add(TRUSTSTORE_PASSWORD);
+ ATTRIBUTES.add(SSL_REQUIRED);
+ ATTRIBUTES.add(ALLOW_ANY_HOSTNAME);
+ ATTRIBUTES.add(DISABLE_TRUST_MANAGER);
+ ATTRIBUTES.add(CONNECTION_POOL_SIZE);
+ ATTRIBUTES.add(ENABLE_CORS);
+ ATTRIBUTES.add(CLIENT_KEYSTORE);
+ ATTRIBUTES.add(CLIENT_KEYSTORE_PASSWORD);
+ ATTRIBUTES.add(CLIENT_KEY_PASSWORD);
+ ATTRIBUTES.add(CORS_MAX_AGE);
+ ATTRIBUTES.add(CORS_ALLOWED_HEADERS);
+ ATTRIBUTES.add(CORS_ALLOWED_METHODS);
+ ATTRIBUTES.add(EXPOSE_TOKEN);
+ ATTRIBUTES.add(AUTH_SERVER_URL_FOR_BACKEND_REQUESTS);
+ ATTRIBUTES.add(ALWAYS_REFRESH_TOKEN);
+ ATTRIBUTES.add(REGISTER_NODE_AT_STARTUP);
+ ATTRIBUTES.add(REGISTER_NODE_PERIOD);
+ ATTRIBUTES.add(TOKEN_STORE);
+ ATTRIBUTES.add(PRINCIPAL_ATTRIBUTE);
+ }
+
+ /**
+ * truststore and truststore-password must be set if ssl-required is not none and disable-trust-manager is false.
+ *
+ * @param attributes The full set of attributes.
+ *
+ * @return true if the attributes are valid, false otherwise.
+ */
+ public static boolean validateTruststoreSetIfRequired(ModelNode attributes) {
+ if (isSet(attributes, DISABLE_TRUST_MANAGER)) {
+ return true;
+ }
+
+ if (isSet(attributes, SSL_REQUIRED) && attributes.get(SSL_REQUIRED.getName()).asString().equals("none")) {
+ return true;
+ }
+
+ return isSet(attributes, TRUSTSTORE) && isSet(attributes, TRUSTSTORE_PASSWORD);
+ }
+
+ private static boolean isSet(ModelNode attributes, SimpleAttributeDefinition def) {
+ ModelNode attribute = attributes.get(def.getName());
+
+ if (def.getType() == ModelType.BOOLEAN) {
+ return attribute.isDefined() && attribute.asBoolean();
+ }
+
+ return attribute.isDefined() && !attribute.asString().isEmpty();
+ }
+
+
+}
diff --git a/integration/wildfly/wildfly-adapter-subsystem/src/main/java/org/keycloak/subsystem/adapter/logging/KeycloakLogger.java b/integration/wildfly/wildfly-adapter-subsystem/src/main/java/org/keycloak/subsystem/adapter/logging/KeycloakLogger.java
new file mode 100755
index 00000000000..de0bb4b9cba
--- /dev/null
+++ b/integration/wildfly/wildfly-adapter-subsystem/src/main/java/org/keycloak/subsystem/adapter/logging/KeycloakLogger.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2013 Red Hat Inc. and/or its affiliates and other contributors
+ * as indicated by the @author tags. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package org.keycloak.subsystem.adapter.logging;
+
+import org.jboss.logging.BasicLogger;
+import org.jboss.logging.Logger;
+import org.jboss.logging.annotations.LogMessage;
+import org.jboss.logging.annotations.Message;
+import org.jboss.logging.annotations.MessageLogger;
+
+import static org.jboss.logging.Logger.Level.INFO;
+
+/**
+ * This interface to be fleshed out later when error messages are fully externalized.
+ *
+ * @author Stan Silvert ssilvert@redhat.com (C) 2013 Red Hat Inc.
+ */
+@MessageLogger(projectCode = "KEYCLOAK")
+public interface KeycloakLogger extends BasicLogger {
+
+ /**
+ * A logger with a category of the package name.
+ */
+ KeycloakLogger ROOT_LOGGER = Logger.getMessageLogger(KeycloakLogger.class, "org.jboss.keycloak");
+
+ @LogMessage(level = INFO)
+ @Message(value = "Keycloak subsystem override for deployment %s")
+ void deploymentSecured(String deployment);
+
+
+}
diff --git a/integration/wildfly/wildfly-adapter-subsystem/src/main/java/org/keycloak/subsystem/adapter/logging/KeycloakMessages.java b/integration/wildfly/wildfly-adapter-subsystem/src/main/java/org/keycloak/subsystem/adapter/logging/KeycloakMessages.java
new file mode 100755
index 00000000000..a45b0b82a9f
--- /dev/null
+++ b/integration/wildfly/wildfly-adapter-subsystem/src/main/java/org/keycloak/subsystem/adapter/logging/KeycloakMessages.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2013 Red Hat Inc. and/or its affiliates and other contributors
+ * as indicated by the @author tags. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package org.keycloak.subsystem.adapter.logging;
+
+import org.jboss.logging.Messages;
+import org.jboss.logging.annotations.MessageBundle;
+
+/**
+ * This interface to be fleshed out later when error messages are fully externalized.
+ *
+ * @author Stan Silvert ssilvert@redhat.com (C) 2012 Red Hat Inc.
+ */
+@MessageBundle(projectCode = "KEYCLOAK")
+public interface KeycloakMessages {
+
+ /**
+ * The messages
+ */
+ KeycloakMessages MESSAGES = Messages.getBundle(KeycloakMessages.class);
+}
diff --git a/integration/wildfly/wildfly-adapter-subsystem/src/main/resources/META-INF/services/org.jboss.as.controller.Extension b/integration/wildfly/wildfly-adapter-subsystem/src/main/resources/META-INF/services/org.jboss.as.controller.Extension
new file mode 100644
index 00000000000..b759b38f86f
--- /dev/null
+++ b/integration/wildfly/wildfly-adapter-subsystem/src/main/resources/META-INF/services/org.jboss.as.controller.Extension
@@ -0,0 +1 @@
+org.keycloak.subsystem.adapter.extension.KeycloakExtension
diff --git a/integration/wildfly/wildfly-adapter-subsystem/src/main/resources/org/keycloak/subsystem/adapter/extension/LocalDescriptions.properties b/integration/wildfly/wildfly-adapter-subsystem/src/main/resources/org/keycloak/subsystem/adapter/extension/LocalDescriptions.properties
new file mode 100755
index 00000000000..c00bd8d2274
--- /dev/null
+++ b/integration/wildfly/wildfly-adapter-subsystem/src/main/resources/org/keycloak/subsystem/adapter/extension/LocalDescriptions.properties
@@ -0,0 +1,72 @@
+keycloak.subsystem=Keycloak adapter subsystem
+keycloak.subsystem.add=Operation Adds Keycloak adapter subsystem
+keycloak.subsystem.remove=Operation removes Keycloak adapter subsystem
+keycloak.subsystem.realm=A Keycloak realm.
+keycloak.subsystem.secure-deployment=A deployment secured by Keycloak.
+
+keycloak.realm=A Keycloak realm.
+keycloak.realm.add=Add a realm definition to the subsystem.
+keycloak.realm.remove=Remove a realm from the subsystem.
+keycloak.realm.realm-public-key=Public key of the realm
+keycloak.realm.auth-server-url=Base URL of the Realm Auth Server
+keycloak.realm.disable-trust-manager=Adapter will not use a trust manager when making adapter HTTPS requests
+keycloak.realm.ssl-required=Specify if SSL is required (valid values are all, external and none)
+keycloak.realm.allow-any-hostname=SSL Setting
+keycloak.realm.truststore=Truststore used for adapter client HTTPS requests
+keycloak.realm.truststore-password=Password of the Truststore
+keycloak.realm.connection-pool-size=Connection pool size for the client used by the adapter
+keycloak.realm.enable-cors=Enable Keycloak CORS support
+keycloak.realm.client-keystore=n/a
+keycloak.realm.client-keystore-password=n/a
+keycloak.realm.client-key-password=n/a
+keycloak.realm.cors-max-age=CORS max-age header
+keycloak.realm.cors-allowed-headers=CORS allowed headers
+keycloak.realm.cors-allowed-methods=CORS allowed methods
+keycloak.realm.expose-token=Enable secure URL that exposes access token
+keycloak.realm.auth-server-url-for-backend-requests=URL to use to make background calls to auth server
+keycloak.realm.always-refresh-token=Refresh token on every single web request
+keycloak.realm.register-node-at-startup=Cluster setting
+keycloak.realm.register-node-period=how often to re-register node
+keycloak.realm.token-store=cookie or session storage for auth session data
+keycloak.realm.principal-attribute=token attribute to use to set Principal name
+
+
+keycloak.secure-deployment=A deployment secured by Keycloak
+keycloak.secure-deployment.add=Add a deployment to be secured by Keycloak
+keycloak.secure-deployment.realm=Keycloak realm
+keycloak.secure-deployment.remove=Remove a deployment to be secured by Keycloak
+keycloak.secure-deployment.realm-public-key=Public key of the realm
+keycloak.secure-deployment.auth-server-url=Base URL of the Realm Auth Server
+keycloak.secure-deployment.disable-trust-manager=Adapter will not use a trust manager when making adapter HTTPS requests
+keycloak.secure-deployment.ssl-required=Specify if SSL is required (valid values are all, external and none)
+keycloak.secure-deployment.allow-any-hostname=SSL Setting
+keycloak.secure-deployment.truststore=Truststore used for adapter client HTTPS requests
+keycloak.secure-deployment.truststore-password=Password of the Truststore
+keycloak.secure-deployment.connection-pool-size=Connection pool size for the client used by the adapter
+keycloak.secure-deployment.resource=Application name
+keycloak.secure-deployment.use-resource-role-mappings=Use resource level permissions from token
+keycloak.secure-deployment.credentials=Adapter credentials
+keycloak.secure-deployment.bearer-only=Bearer Token Auth only
+keycloak.secure-deployment.enable-basic-auth=Enable Basic Authentication
+keycloak.secure-deployment.public-client=Public client
+keycloak.secure-deployment.enable-cors=Enable Keycloak CORS support
+keycloak.secure-deployment.client-keystore=n/a
+keycloak.secure-deployment.client-keystore-password=n/a
+keycloak.secure-deployment.client-key-password=n/a
+keycloak.secure-deployment.cors-max-age=CORS max-age header
+keycloak.secure-deployment.cors-allowed-headers=CORS allowed headers
+keycloak.secure-deployment.cors-allowed-methods=CORS allowed methods
+keycloak.secure-deployment.expose-token=Enable secure URL that exposes access token
+keycloak.secure-deployment.auth-server-url-for-backend-requests=URL to use to make background calls to auth server
+keycloak.secure-deployment.always-refresh-token=Refresh token on every single web request
+keycloak.secure-deployment.register-node-at-startup=Cluster setting
+keycloak.secure-deployment.register-node-period=how often to re-register node
+keycloak.secure-deployment.token-store=cookie or session storage for auth session data
+keycloak.secure-deployment.principal-attribute=token attribute to use to set Principal name
+
+keycloak.secure-deployment.credential=Credential value
+
+keycloak.credential=Credential
+keycloak.credential.value=Credential value
+keycloak.credential.add=Credential add
+keycloak.credential.remove=Credential remove
\ No newline at end of file
diff --git a/integration/wildfly/wildfly-adapter-subsystem/src/main/resources/schema/wildfly-keycloak_1_1.xsd b/integration/wildfly/wildfly-adapter-subsystem/src/main/resources/schema/wildfly-keycloak_1_1.xsd
new file mode 100755
index 00000000000..269b3232dd0
--- /dev/null
+++ b/integration/wildfly/wildfly-adapter-subsystem/src/main/resources/schema/wildfly-keycloak_1_1.xsd
@@ -0,0 +1,105 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ The name of the realm.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ The name of the realm.
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/integration/wildfly/wildfly-adapter-subsystem/src/main/resources/subsystem-templates/keycloak-adapter.xml b/integration/wildfly/wildfly-adapter-subsystem/src/main/resources/subsystem-templates/keycloak-adapter.xml
new file mode 100644
index 00000000000..a2187f6e1f5
--- /dev/null
+++ b/integration/wildfly/wildfly-adapter-subsystem/src/main/resources/subsystem-templates/keycloak-adapter.xml
@@ -0,0 +1,7 @@
+
+
+
+ org.keycloak.keycloak-adapter-subsystem
+
+
+
diff --git a/integration/wildfly/wildfly-adapter-subsystem/src/test/java/org/keycloak/subsystem/adapter/extension/RealmDefinitionTestCase.java b/integration/wildfly/wildfly-adapter-subsystem/src/test/java/org/keycloak/subsystem/adapter/extension/RealmDefinitionTestCase.java
new file mode 100755
index 00000000000..92a1958a59d
--- /dev/null
+++ b/integration/wildfly/wildfly-adapter-subsystem/src/test/java/org/keycloak/subsystem/adapter/extension/RealmDefinitionTestCase.java
@@ -0,0 +1,86 @@
+/*
+ * Copyright 2013 Red Hat Inc. and/or its affiliates and other contributors
+ * as indicated by the @author tags. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package org.keycloak.subsystem.adapter.extension;
+
+import org.jboss.dmr.ModelNode;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ *
+ * @author Stan Silvert ssilvert@redhat.com (C) 2013 Red Hat Inc.
+ */
+public class RealmDefinitionTestCase {
+
+ private ModelNode model;
+
+ @Before
+ public void setUp() {
+ model = new ModelNode();
+ model.get("realm").set("demo");
+ model.get("resource").set("customer-portal");
+ model.get("realm-public-key").set("MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCrVrCuTtArbgaZzL1hvh0xtL5mc7o0NqPVnYXkLvgcwiC3BjLGw1tGEGoJaXDuSaRllobm53JBhjx33UNv+5z/UMG4kytBWxheNVKnL6GgqlNabMaFfPLPCF8kAgKnsi79NMo+n6KnSY8YeUmec/p2vjO2NjsSAVcWEQMVhJ31LwIDAQAB");
+ model.get("auth-url").set("http://localhost:8080/auth-server/rest/realms/demo/protocol/openid-connect/login");
+ model.get("code-url").set("http://localhost:8080/auth-server/rest/realms/demo/protocol/openid-connect/access/codes");
+ model.get("expose-token").set(true);
+ ModelNode credential = new ModelNode();
+ credential.get("password").set("password");
+ model.get("credentials").set(credential);
+ }
+
+ @Test
+ public void testIsTruststoreSetIfRequired() throws Exception {
+ model.get("ssl-required").set("none");
+ model.get("disable-trust-manager").set(true);
+ Assert.assertTrue(SharedAttributeDefinitons.validateTruststoreSetIfRequired(model));
+
+ model.get("ssl-required").set("none");
+ model.get("disable-trust-manager").set(false);
+ Assert.assertTrue(SharedAttributeDefinitons.validateTruststoreSetIfRequired(model));
+
+ model.get("ssl-required").set("all");
+ model.get("disable-trust-manager").set(true);
+ Assert.assertTrue(SharedAttributeDefinitons.validateTruststoreSetIfRequired(model));
+
+ model.get("ssl-required").set("all");
+ model.get("disable-trust-manager").set(false);
+ Assert.assertFalse(SharedAttributeDefinitons.validateTruststoreSetIfRequired(model));
+
+ model.get("ssl-required").set("external");
+ model.get("disable-trust-manager").set(false);
+ Assert.assertFalse(SharedAttributeDefinitons.validateTruststoreSetIfRequired(model));
+
+ model.get("ssl-required").set("all");
+ model.get("disable-trust-manager").set(false);
+ model.get("truststore").set("foo");
+ Assert.assertFalse(SharedAttributeDefinitons.validateTruststoreSetIfRequired(model));
+
+ model.get("ssl-required").set("all");
+ model.get("disable-trust-manager").set(false);
+ model.get("truststore").set("foo");
+ model.get("truststore-password").set("password");
+ Assert.assertTrue(SharedAttributeDefinitons.validateTruststoreSetIfRequired(model));
+
+ model.get("ssl-required").set("external");
+ model.get("disable-trust-manager").set(false);
+ model.get("truststore").set("foo");
+ model.get("truststore-password").set("password");
+ Assert.assertTrue(SharedAttributeDefinitons.validateTruststoreSetIfRequired(model));
+ }
+
+}
diff --git a/integration/wildfly/wildfly-adapter-subsystem/src/test/java/org/keycloak/subsystem/adapter/extension/SubsystemParsingTestCase.java b/integration/wildfly/wildfly-adapter-subsystem/src/test/java/org/keycloak/subsystem/adapter/extension/SubsystemParsingTestCase.java
new file mode 100755
index 00000000000..baa131b09d7
--- /dev/null
+++ b/integration/wildfly/wildfly-adapter-subsystem/src/test/java/org/keycloak/subsystem/adapter/extension/SubsystemParsingTestCase.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright 2013 Red Hat Inc. and/or its affiliates and other contributors
+ * as indicated by the @author tags. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package org.keycloak.subsystem.adapter.extension;
+
+import org.jboss.as.subsystem.test.AbstractSubsystemBaseTest;
+import org.jboss.dmr.ModelNode;
+import org.junit.Test;
+
+import java.io.IOException;
+
+
+/**
+ * Tests all management expects for subsystem, parsing, marshaling, model definition and other
+ * Here is an example that allows you a fine grained controller over what is tested and how. So it can give you ideas what can be done and tested.
+ * If you have no need for advanced testing of subsystem you look at {@link SubsystemBaseParsingTestCase} that testes same stuff but most of the code
+ * is hidden inside of test harness
+ *
+ * @author Kabir Khan
+ * @author Tomaz Cerar
+ * @author Marko Strukelj
+ */
+public class SubsystemParsingTestCase extends AbstractSubsystemBaseTest {
+
+ public SubsystemParsingTestCase() {
+ super(KeycloakExtension.SUBSYSTEM_NAME, new KeycloakExtension());
+ }
+
+ @Test
+ public void testJson() throws Exception {
+ ModelNode node = new ModelNode();
+ node.get("realm").set("demo");
+ node.get("resource").set("customer-portal");
+ node.get("realm-public-key").set("MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCrVrCuTtArbgaZzL1hvh0xtL5mc7o0NqPVnYXkLvgcwiC3BjLGw1tGEGoJaXDuSaRllobm53JBhjx33UNv+5z/UMG4kytBWxheNVKnL6GgqlNabMaFfPLPCF8kAgKnsi79NMo+n6KnSY8YeUmec/p2vjO2NjsSAVcWEQMVhJ31LwIDAQAB");
+ node.get("auth-url").set("http://localhost:8080/auth-server/rest/realms/demo/protocol/openid-connect/login");
+ node.get("code-url").set("http://localhost:8080/auth-server/rest/realms/demo/protocol/openid-connect/access/codes");
+ node.get("ssl-required").set("external");
+ node.get("expose-token").set(true);
+ ModelNode credential = new ModelNode();
+ credential.get("password").set("password");
+ node.get("credentials").set(credential);
+
+ System.out.println("json=" + node.toJSONString(false));
+ }
+
+ @Override
+ protected String getSubsystemXml() throws IOException {
+ return readResource("keycloak-1.1.xml");
+ }
+
+ @Override
+ protected String getSubsystemXsdPath() throws Exception {
+ return "schema/wildfly-keycloak_1_1.xsd";
+ }
+
+ @Override
+ protected String[] getSubsystemTemplatePaths() throws IOException {
+ return new String[]{
+ "/subsystem-templates/keycloak-adapter.xml"
+ };
+ }
+}
diff --git a/integration/wildfly/wildfly-adapter-subsystem/src/test/resources/org/keycloak/subsystem/adapter/extension/keycloak-1.1.xml b/integration/wildfly/wildfly-adapter-subsystem/src/test/resources/org/keycloak/subsystem/adapter/extension/keycloak-1.1.xml
new file mode 100644
index 00000000000..2d12d88576f
--- /dev/null
+++ b/integration/wildfly/wildfly-adapter-subsystem/src/test/resources/org/keycloak/subsystem/adapter/extension/keycloak-1.1.xml
@@ -0,0 +1,24 @@
+
+
+ master
+ web-console
+ true
+
+ MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC4siLKUew0WYxdtq6/rwk4Uj/4amGFFnE/yzIxQVU0PUqz3QBRVkUWpDj0K6ZnS5nzJV/y6DHLEy7hjZTdRDphyF1sq09aDOYnVpzu8o2sIlMM8q5RnUyEfIyUZqwo8pSZDJ90fS0s+IDUJNCSIrAKO3w1lqZDHL6E/YFHXyzkvQIDAQAB
+
+ http://localhost:8080/auth
+ EXTERNAL
+ 0aa31d98-e0aa-404c-b6e0-e771dba1e798
+
+
+ master
+ http-endpoint
+ true
+
+ MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC4siLKUew0WYxdtq6/rwk4Uj/4amGFFnE/yzIxQVU0PUqz3QBRVkUWpDj0K6ZnS5nzJV/y6DHLEy7hjZTdRDphyF1sq09aDOYnVpzu8o2sIlMM8q5RnUyEfIyUZqwo8pSZDJ90fS0s+IDUJNCSIrAKO3w1lqZDHL6E/YFHXyzkvQIDAQAB
+
+ http://localhost:8080/auth
+ EXTERNAL
+ 2769a4a2-5be0-454f-838f-f33b7755b667
+
+
\ No newline at end of file
diff --git a/integration/wildfly-adapter/pom.xml b/integration/wildfly/wildfly-adapter/pom.xml
similarity index 95%
rename from integration/wildfly-adapter/pom.xml
rename to integration/wildfly/wildfly-adapter/pom.xml
index ee4568b6475..bd61b440531 100755
--- a/integration/wildfly-adapter/pom.xml
+++ b/integration/wildfly/wildfly-adapter/pom.xml
@@ -1,104 +1,104 @@
-
-
-
- keycloak-parent
- org.keycloak
- 1.3.0.Beta1-SNAPSHOT
- ../../pom.xml
-
- 4.0.0
-
- keycloak-wildfly-adapter
- Keycloak Wildfly Integration
-
-
-
-
- org.jboss.logging
- jboss-logging
- ${jboss.logging.version}
- provided
-
-
- org.keycloak
- keycloak-core
-
-
- org.keycloak
- keycloak-adapter-core
-
-
- org.keycloak
- keycloak-undertow-adapter
-
-
- org.keycloak
- keycloak-jboss-adapter-core
-
-
- org.apache.httpcomponents
- httpclient
-
-
- net.iharder
- base64
-
-
- org.bouncycastle
- bcprov-jdk15on
-
-
- org.codehaus.jackson
- jackson-core-asl
-
-
- org.codehaus.jackson
- jackson-mapper-asl
-
-
- org.codehaus.jackson
- jackson-xc
-
-
- org.picketbox
- picketbox
- 4.0.20.Final
- provided
-
-
- org.jboss.spec.javax.servlet
- jboss-servlet-api_3.0_spec
- provided
-
-
-
- io.undertow
- undertow-servlet
- provided
-
-
- io.undertow
- undertow-core
- provided
-
-
- junit
- junit
- test
-
-
-
-
-
- org.apache.maven.plugins
- maven-compiler-plugin
-
- ${maven.compiler.source}
- ${maven.compiler.target}
-
-
-
-
-
-
+
+
+
+ keycloak-parent
+ org.keycloak
+ 1.3.0.Beta1-SNAPSHOT
+ ../../../pom.xml
+
+ 4.0.0
+
+ keycloak-wildfly-adapter
+ Keycloak Wildfly Integration
+
+
+
+
+ org.jboss.logging
+ jboss-logging
+ ${jboss.logging.version}
+ provided
+
+
+ org.keycloak
+ keycloak-core
+
+
+ org.keycloak
+ keycloak-adapter-core
+
+
+ org.keycloak
+ keycloak-undertow-adapter
+
+
+ org.keycloak
+ keycloak-jboss-adapter-core
+
+
+ org.apache.httpcomponents
+ httpclient
+
+
+ net.iharder
+ base64
+
+
+ org.bouncycastle
+ bcprov-jdk15on
+
+
+ org.codehaus.jackson
+ jackson-core-asl
+
+
+ org.codehaus.jackson
+ jackson-mapper-asl
+
+
+ org.codehaus.jackson
+ jackson-xc
+
+
+ org.picketbox
+ picketbox
+ 4.0.20.Final
+ provided
+
+
+ org.jboss.spec.javax.servlet
+ jboss-servlet-api_3.0_spec
+ provided
+
+
+
+ io.undertow
+ undertow-servlet
+ provided
+
+
+ io.undertow
+ undertow-core
+ provided
+
+
+ junit
+ junit
+ test
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+
+ ${maven.compiler.source}
+ ${maven.compiler.target}
+
+
+
+
+
+
\ No newline at end of file
diff --git a/integration/wildfly-adapter/src/main/java/org/keycloak/adapters/wildfly/SecurityInfoHelper.java b/integration/wildfly/wildfly-adapter/src/main/java/org/keycloak/adapters/wildfly/SecurityInfoHelper.java
similarity index 97%
rename from integration/wildfly-adapter/src/main/java/org/keycloak/adapters/wildfly/SecurityInfoHelper.java
rename to integration/wildfly/wildfly-adapter/src/main/java/org/keycloak/adapters/wildfly/SecurityInfoHelper.java
index 9838772b129..5f13cd67697 100755
--- a/integration/wildfly-adapter/src/main/java/org/keycloak/adapters/wildfly/SecurityInfoHelper.java
+++ b/integration/wildfly/wildfly-adapter/src/main/java/org/keycloak/adapters/wildfly/SecurityInfoHelper.java
@@ -1,116 +1,116 @@
-package org.keycloak.adapters.wildfly;
-
-import org.jboss.security.NestableGroup;
-import org.jboss.security.SecurityConstants;
-import org.jboss.security.SecurityContextAssociation;
-import org.jboss.security.SimpleGroup;
-import org.jboss.security.SimplePrincipal;
-import org.keycloak.adapters.KeycloakAccount;
-
-import javax.security.auth.Subject;
-import java.security.Principal;
-import java.security.acl.Group;
-import java.util.Collection;
-import java.util.Enumeration;
-import java.util.Iterator;
-import java.util.Set;
-
-/**
- * @author Bill Burke
- * @version $Revision: 1 $
- */
-public class SecurityInfoHelper {
- public static void propagateSessionInfo(KeycloakAccount account) {
- Subject subject = new Subject();
- Set principals = subject.getPrincipals();
- principals.add(account.getPrincipal());
- Group[] roleSets = getRoleSets(account.getRoles());
- for (int g = 0; g < roleSets.length; g++) {
- Group group = roleSets[g];
- String name = group.getName();
- Group subjectGroup = createGroup(name, principals);
- if (subjectGroup instanceof NestableGroup) {
- /* A NestableGroup only allows Groups to be added to it so we
- need to add a SimpleGroup to subjectRoles to contain the roles
- */
- SimpleGroup tmp = new SimpleGroup("Roles");
- subjectGroup.addMember(tmp);
- subjectGroup = tmp;
- }
- // Copy the group members to the Subject group
- Enumeration extends Principal> members = group.members();
- while (members.hasMoreElements()) {
- Principal role = (Principal) members.nextElement();
- subjectGroup.addMember(role);
- }
- }
- // add the CallerPrincipal group if none has been added in getRoleSets
- Group callerGroup = new SimpleGroup(SecurityConstants.CALLER_PRINCIPAL_GROUP);
- callerGroup.addMember(account.getPrincipal());
- principals.add(callerGroup);
- org.jboss.security.SecurityContext sc = SecurityContextAssociation.getSecurityContext();
- Principal userPrincipal = getPrincipal(subject);
- sc.getUtil().createSubjectInfo(userPrincipal, account, subject);
- }
-
- /**
- * Get the Principal given the authenticated Subject. Currently the first subject that is not of type {@code Group} is
- * considered or the single subject inside the CallerPrincipal group.
- *
- * @param subject
- * @return the authenticated subject
- */
- protected static Principal getPrincipal(Subject subject) {
- Principal principal = null;
- Principal callerPrincipal = null;
- if (subject != null) {
- Set principals = subject.getPrincipals();
- if (principals != null && !principals.isEmpty()) {
- for (Principal p : principals) {
- if (!(p instanceof Group) && principal == null) {
- principal = p;
- }
- if (p instanceof Group) {
- Group g = Group.class.cast(p);
- if (g.getName().equals(SecurityConstants.CALLER_PRINCIPAL_GROUP) && callerPrincipal == null) {
- Enumeration extends Principal> e = g.members();
- if (e.hasMoreElements())
- callerPrincipal = e.nextElement();
- }
- }
- }
- }
- }
- return callerPrincipal == null ? principal : callerPrincipal;
- }
-
- protected static Group createGroup(String name, Set principals) {
- Group roles = null;
- Iterator iter = principals.iterator();
- while (iter.hasNext()) {
- Object next = iter.next();
- if ((next instanceof Group) == false)
- continue;
- Group grp = (Group) next;
- if (grp.getName().equals(name)) {
- roles = grp;
- break;
- }
- }
- // If we did not find a group create one
- if (roles == null) {
- roles = new SimpleGroup(name);
- principals.add(roles);
- }
- return roles;
- }
-
- protected static Group[] getRoleSets(Collection roleSet) {
- SimpleGroup roles = new SimpleGroup("Roles");
- Group[] roleSets = {roles};
- for (String role : roleSet) {
- roles.addMember(new SimplePrincipal(role));
- }
- return roleSets;
- }
-}
+package org.keycloak.adapters.wildfly;
+
+import org.jboss.security.NestableGroup;
+import org.jboss.security.SecurityConstants;
+import org.jboss.security.SecurityContextAssociation;
+import org.jboss.security.SimpleGroup;
+import org.jboss.security.SimplePrincipal;
+import org.keycloak.adapters.KeycloakAccount;
+
+import javax.security.auth.Subject;
+import java.security.Principal;
+import java.security.acl.Group;
+import java.util.Collection;
+import java.util.Enumeration;
+import java.util.Iterator;
+import java.util.Set;
+
+/**
+ * @author Bill Burke
+ * @version $Revision: 1 $
+ */
+public class SecurityInfoHelper {
+ public static void propagateSessionInfo(KeycloakAccount account) {
+ Subject subject = new Subject();
+ Set principals = subject.getPrincipals();
+ principals.add(account.getPrincipal());
+ Group[] roleSets = getRoleSets(account.getRoles());
+ for (int g = 0; g < roleSets.length; g++) {
+ Group group = roleSets[g];
+ String name = group.getName();
+ Group subjectGroup = createGroup(name, principals);
+ if (subjectGroup instanceof NestableGroup) {
+ /* A NestableGroup only allows Groups to be added to it so we
+ need to add a SimpleGroup to subjectRoles to contain the roles
+ */
+ SimpleGroup tmp = new SimpleGroup("Roles");
+ subjectGroup.addMember(tmp);
+ subjectGroup = tmp;
+ }
+ // Copy the group members to the Subject group
+ Enumeration extends Principal> members = group.members();
+ while (members.hasMoreElements()) {
+ Principal role = (Principal) members.nextElement();
+ subjectGroup.addMember(role);
+ }
+ }
+ // add the CallerPrincipal group if none has been added in getRoleSets
+ Group callerGroup = new SimpleGroup(SecurityConstants.CALLER_PRINCIPAL_GROUP);
+ callerGroup.addMember(account.getPrincipal());
+ principals.add(callerGroup);
+ org.jboss.security.SecurityContext sc = SecurityContextAssociation.getSecurityContext();
+ Principal userPrincipal = getPrincipal(subject);
+ sc.getUtil().createSubjectInfo(userPrincipal, account, subject);
+ }
+
+ /**
+ * Get the Principal given the authenticated Subject. Currently the first subject that is not of type {@code Group} is
+ * considered or the single subject inside the CallerPrincipal group.
+ *
+ * @param subject
+ * @return the authenticated subject
+ */
+ protected static Principal getPrincipal(Subject subject) {
+ Principal principal = null;
+ Principal callerPrincipal = null;
+ if (subject != null) {
+ Set principals = subject.getPrincipals();
+ if (principals != null && !principals.isEmpty()) {
+ for (Principal p : principals) {
+ if (!(p instanceof Group) && principal == null) {
+ principal = p;
+ }
+ if (p instanceof Group) {
+ Group g = Group.class.cast(p);
+ if (g.getName().equals(SecurityConstants.CALLER_PRINCIPAL_GROUP) && callerPrincipal == null) {
+ Enumeration extends Principal> e = g.members();
+ if (e.hasMoreElements())
+ callerPrincipal = e.nextElement();
+ }
+ }
+ }
+ }
+ }
+ return callerPrincipal == null ? principal : callerPrincipal;
+ }
+
+ protected static Group createGroup(String name, Set principals) {
+ Group roles = null;
+ Iterator iter = principals.iterator();
+ while (iter.hasNext()) {
+ Object next = iter.next();
+ if ((next instanceof Group) == false)
+ continue;
+ Group grp = (Group) next;
+ if (grp.getName().equals(name)) {
+ roles = grp;
+ break;
+ }
+ }
+ // If we did not find a group create one
+ if (roles == null) {
+ roles = new SimpleGroup(name);
+ principals.add(roles);
+ }
+ return roles;
+ }
+
+ protected static Group[] getRoleSets(Collection roleSet) {
+ SimpleGroup roles = new SimpleGroup("Roles");
+ Group[] roleSets = {roles};
+ for (String role : roleSet) {
+ roles.addMember(new SimplePrincipal(role));
+ }
+ return roleSets;
+ }
+}
diff --git a/integration/wildfly-adapter/src/main/java/org/keycloak/adapters/wildfly/WildflyAuthenticationMechanism.java b/integration/wildfly/wildfly-adapter/src/main/java/org/keycloak/adapters/wildfly/WildflyAuthenticationMechanism.java
similarity index 98%
rename from integration/wildfly-adapter/src/main/java/org/keycloak/adapters/wildfly/WildflyAuthenticationMechanism.java
rename to integration/wildfly/wildfly-adapter/src/main/java/org/keycloak/adapters/wildfly/WildflyAuthenticationMechanism.java
index 85f8bd318df..53d8e0c02c2 100755
--- a/integration/wildfly-adapter/src/main/java/org/keycloak/adapters/wildfly/WildflyAuthenticationMechanism.java
+++ b/integration/wildfly/wildfly-adapter/src/main/java/org/keycloak/adapters/wildfly/WildflyAuthenticationMechanism.java
@@ -1,35 +1,35 @@
-package org.keycloak.adapters.wildfly;
-
-import io.undertow.security.api.SecurityContext;
-import io.undertow.server.HttpServerExchange;
-import io.undertow.servlet.api.ConfidentialPortManager;
-import org.keycloak.adapters.AdapterDeploymentContext;
-import org.keycloak.adapters.AdapterTokenStore;
-import org.keycloak.adapters.KeycloakDeployment;
-import org.keycloak.adapters.NodesRegistrationManagement;
-import org.keycloak.adapters.undertow.ServletKeycloakAuthMech;
-import org.keycloak.adapters.undertow.ServletRequestAuthenticator;
-import org.keycloak.adapters.undertow.UndertowHttpFacade;
-import org.keycloak.adapters.undertow.UndertowUserSessionManagement;
-
-/**
- * @author Bill Burke
- * @version $Revision: 1 $
- */
-public class WildflyAuthenticationMechanism extends ServletKeycloakAuthMech {
-
- public WildflyAuthenticationMechanism(AdapterDeploymentContext deploymentContext,
- UndertowUserSessionManagement userSessionManagement,
- NodesRegistrationManagement nodesRegistrationManagement,
- ConfidentialPortManager portManager, String errorPage) {
- super(deploymentContext, userSessionManagement, nodesRegistrationManagement, portManager, errorPage);
- }
-
- @Override
- protected ServletRequestAuthenticator createRequestAuthenticator(KeycloakDeployment deployment, HttpServerExchange exchange, SecurityContext securityContext, UndertowHttpFacade facade) {
- int confidentialPort = getConfidentilPort(exchange);
- AdapterTokenStore tokenStore = getTokenStore(exchange, facade, deployment, securityContext);
- return new WildflyRequestAuthenticator(facade, deployment,
- confidentialPort, securityContext, exchange, tokenStore);
- }
-}
+package org.keycloak.adapters.wildfly;
+
+import io.undertow.security.api.SecurityContext;
+import io.undertow.server.HttpServerExchange;
+import io.undertow.servlet.api.ConfidentialPortManager;
+import org.keycloak.adapters.AdapterDeploymentContext;
+import org.keycloak.adapters.AdapterTokenStore;
+import org.keycloak.adapters.KeycloakDeployment;
+import org.keycloak.adapters.NodesRegistrationManagement;
+import org.keycloak.adapters.undertow.ServletKeycloakAuthMech;
+import org.keycloak.adapters.undertow.ServletRequestAuthenticator;
+import org.keycloak.adapters.undertow.UndertowHttpFacade;
+import org.keycloak.adapters.undertow.UndertowUserSessionManagement;
+
+/**
+ * @author Bill Burke
+ * @version $Revision: 1 $
+ */
+public class WildflyAuthenticationMechanism extends ServletKeycloakAuthMech {
+
+ public WildflyAuthenticationMechanism(AdapterDeploymentContext deploymentContext,
+ UndertowUserSessionManagement userSessionManagement,
+ NodesRegistrationManagement nodesRegistrationManagement,
+ ConfidentialPortManager portManager, String errorPage) {
+ super(deploymentContext, userSessionManagement, nodesRegistrationManagement, portManager, errorPage);
+ }
+
+ @Override
+ protected ServletRequestAuthenticator createRequestAuthenticator(KeycloakDeployment deployment, HttpServerExchange exchange, SecurityContext securityContext, UndertowHttpFacade facade) {
+ int confidentialPort = getConfidentilPort(exchange);
+ AdapterTokenStore tokenStore = getTokenStore(exchange, facade, deployment, securityContext);
+ return new WildflyRequestAuthenticator(facade, deployment,
+ confidentialPort, securityContext, exchange, tokenStore);
+ }
+}
diff --git a/integration/wildfly-adapter/src/main/java/org/keycloak/adapters/wildfly/WildflyKeycloakServletExtension.java b/integration/wildfly/wildfly-adapter/src/main/java/org/keycloak/adapters/wildfly/WildflyKeycloakServletExtension.java
similarity index 98%
rename from integration/wildfly-adapter/src/main/java/org/keycloak/adapters/wildfly/WildflyKeycloakServletExtension.java
rename to integration/wildfly/wildfly-adapter/src/main/java/org/keycloak/adapters/wildfly/WildflyKeycloakServletExtension.java
index 2e432857cd5..4735deb03b7 100755
--- a/integration/wildfly-adapter/src/main/java/org/keycloak/adapters/wildfly/WildflyKeycloakServletExtension.java
+++ b/integration/wildfly/wildfly-adapter/src/main/java/org/keycloak/adapters/wildfly/WildflyKeycloakServletExtension.java
@@ -1,25 +1,25 @@
-package org.keycloak.adapters.wildfly;
-
-import io.undertow.servlet.api.DeploymentInfo;
-import org.jboss.logging.Logger;
-import org.keycloak.adapters.AdapterDeploymentContext;
-import org.keycloak.adapters.NodesRegistrationManagement;
-import org.keycloak.adapters.undertow.KeycloakServletExtension;
-import org.keycloak.adapters.undertow.ServletKeycloakAuthMech;
-import org.keycloak.adapters.undertow.UndertowUserSessionManagement;
-
-/**
- * @author Bill Burke
- * @version $Revision: 1 $
- */
-public class WildflyKeycloakServletExtension extends KeycloakServletExtension {
- protected static Logger log = Logger.getLogger(WildflyKeycloakServletExtension.class);
-
- @Override
- protected ServletKeycloakAuthMech createAuthenticationMechanism(DeploymentInfo deploymentInfo, AdapterDeploymentContext deploymentContext,
- UndertowUserSessionManagement userSessionManagement, NodesRegistrationManagement nodesRegistrationManagement) {
- log.debug("creating WildflyAuthenticationMechanism");
- return new WildflyAuthenticationMechanism(deploymentContext, userSessionManagement, nodesRegistrationManagement, deploymentInfo.getConfidentialPortManager(), getErrorPage(deploymentInfo));
-
- }
-}
+package org.keycloak.adapters.wildfly;
+
+import io.undertow.servlet.api.DeploymentInfo;
+import org.jboss.logging.Logger;
+import org.keycloak.adapters.AdapterDeploymentContext;
+import org.keycloak.adapters.NodesRegistrationManagement;
+import org.keycloak.adapters.undertow.KeycloakServletExtension;
+import org.keycloak.adapters.undertow.ServletKeycloakAuthMech;
+import org.keycloak.adapters.undertow.UndertowUserSessionManagement;
+
+/**
+ * @author Bill Burke
+ * @version $Revision: 1 $
+ */
+public class WildflyKeycloakServletExtension extends KeycloakServletExtension {
+ protected static Logger log = Logger.getLogger(WildflyKeycloakServletExtension.class);
+
+ @Override
+ protected ServletKeycloakAuthMech createAuthenticationMechanism(DeploymentInfo deploymentInfo, AdapterDeploymentContext deploymentContext,
+ UndertowUserSessionManagement userSessionManagement, NodesRegistrationManagement nodesRegistrationManagement) {
+ log.debug("creating WildflyAuthenticationMechanism");
+ return new WildflyAuthenticationMechanism(deploymentContext, userSessionManagement, nodesRegistrationManagement, deploymentInfo.getConfidentialPortManager(), getErrorPage(deploymentInfo));
+
+ }
+}
diff --git a/integration/wildfly-adapter/src/main/java/org/keycloak/adapters/wildfly/WildflyRequestAuthenticator.java b/integration/wildfly/wildfly-adapter/src/main/java/org/keycloak/adapters/wildfly/WildflyRequestAuthenticator.java
similarity index 97%
rename from integration/wildfly-adapter/src/main/java/org/keycloak/adapters/wildfly/WildflyRequestAuthenticator.java
rename to integration/wildfly/wildfly-adapter/src/main/java/org/keycloak/adapters/wildfly/WildflyRequestAuthenticator.java
index 84074d67f01..7930d953176 100755
--- a/integration/wildfly-adapter/src/main/java/org/keycloak/adapters/wildfly/WildflyRequestAuthenticator.java
+++ b/integration/wildfly/wildfly-adapter/src/main/java/org/keycloak/adapters/wildfly/WildflyRequestAuthenticator.java
@@ -1,137 +1,137 @@
-package org.keycloak.adapters.wildfly;
-
-import io.undertow.security.api.SecurityContext;
-import io.undertow.server.HttpServerExchange;
-import org.jboss.logging.Logger;
-import org.jboss.security.NestableGroup;
-import org.jboss.security.SecurityConstants;
-import org.jboss.security.SecurityContextAssociation;
-import org.jboss.security.SimpleGroup;
-import org.jboss.security.SimplePrincipal;
-import org.keycloak.adapters.AdapterTokenStore;
-import org.keycloak.adapters.HttpFacade;
-import org.keycloak.adapters.KeycloakDeployment;
-import org.keycloak.adapters.undertow.KeycloakUndertowAccount;
-import org.keycloak.adapters.undertow.ServletRequestAuthenticator;
-import org.keycloak.adapters.undertow.UndertowUserSessionManagement;
-
-import javax.security.auth.Subject;
-import java.security.Principal;
-import java.security.acl.Group;
-import java.util.Collection;
-import java.util.Enumeration;
-import java.util.Iterator;
-import java.util.Set;
-
-/**
- * @author Bill Burke
- * @version $Revision: 1 $
- */
-public class WildflyRequestAuthenticator extends ServletRequestAuthenticator {
- protected static Logger log = Logger.getLogger(WildflyRequestAuthenticator.class);
-
- public WildflyRequestAuthenticator(HttpFacade facade, KeycloakDeployment deployment, int sslRedirectPort,
- SecurityContext securityContext, HttpServerExchange exchange,
- AdapterTokenStore tokenStore) {
- super(facade, deployment, sslRedirectPort, securityContext, exchange, tokenStore);
- }
-
- @Override
- protected void propagateKeycloakContext(KeycloakUndertowAccount account) {
- super.propagateKeycloakContext(account);
- SecurityInfoHelper.propagateSessionInfo(account);
- log.debug("propagate security context to wildfly");
- Subject subject = new Subject();
- Set principals = subject.getPrincipals();
- principals.add(account.getPrincipal());
- Group[] roleSets = getRoleSets(account.getRoles());
- for (int g = 0; g < roleSets.length; g++) {
- Group group = roleSets[g];
- String name = group.getName();
- Group subjectGroup = createGroup(name, principals);
- if (subjectGroup instanceof NestableGroup) {
- /* A NestableGroup only allows Groups to be added to it so we
- need to add a SimpleGroup to subjectRoles to contain the roles
- */
- SimpleGroup tmp = new SimpleGroup("Roles");
- subjectGroup.addMember(tmp);
- subjectGroup = tmp;
- }
- // Copy the group members to the Subject group
- Enumeration extends Principal> members = group.members();
- while (members.hasMoreElements()) {
- Principal role = (Principal) members.nextElement();
- subjectGroup.addMember(role);
- }
- }
- // add the CallerPrincipal group if none has been added in getRoleSets
- Group callerGroup = new SimpleGroup(SecurityConstants.CALLER_PRINCIPAL_GROUP);
- callerGroup.addMember(account.getPrincipal());
- principals.add(callerGroup);
- org.jboss.security.SecurityContext sc = SecurityContextAssociation.getSecurityContext();
- Principal userPrincipal = getPrincipal(subject);
- sc.getUtil().createSubjectInfo(userPrincipal, account, subject);
- }
-
- /**
- * Get the Principal given the authenticated Subject. Currently the first subject that is not of type {@code Group} is
- * considered or the single subject inside the CallerPrincipal group.
- *
- * @param subject
- * @return the authenticated subject
- */
- protected Principal getPrincipal(Subject subject) {
- Principal principal = null;
- Principal callerPrincipal = null;
- if (subject != null) {
- Set principals = subject.getPrincipals();
- if (principals != null && !principals.isEmpty()) {
- for (Principal p : principals) {
- if (!(p instanceof Group) && principal == null) {
- principal = p;
- }
- if (p instanceof Group) {
- Group g = Group.class.cast(p);
- if (g.getName().equals(SecurityConstants.CALLER_PRINCIPAL_GROUP) && callerPrincipal == null) {
- Enumeration extends Principal> e = g.members();
- if (e.hasMoreElements())
- callerPrincipal = e.nextElement();
- }
- }
- }
- }
- }
- return callerPrincipal == null ? principal : callerPrincipal;
- }
-
- protected Group createGroup(String name, Set principals) {
- Group roles = null;
- Iterator iter = principals.iterator();
- while (iter.hasNext()) {
- Object next = iter.next();
- if ((next instanceof Group) == false)
- continue;
- Group grp = (Group) next;
- if (grp.getName().equals(name)) {
- roles = grp;
- break;
- }
- }
- // If we did not find a group create one
- if (roles == null) {
- roles = new SimpleGroup(name);
- principals.add(roles);
- }
- return roles;
- }
-
- protected Group[] getRoleSets(Collection roleSet) {
- SimpleGroup roles = new SimpleGroup("Roles");
- Group[] roleSets = {roles};
- for (String role : roleSet) {
- roles.addMember(new SimplePrincipal(role));
- }
- return roleSets;
- }
-
-}
+package org.keycloak.adapters.wildfly;
+
+import io.undertow.security.api.SecurityContext;
+import io.undertow.server.HttpServerExchange;
+import org.jboss.logging.Logger;
+import org.jboss.security.NestableGroup;
+import org.jboss.security.SecurityConstants;
+import org.jboss.security.SecurityContextAssociation;
+import org.jboss.security.SimpleGroup;
+import org.jboss.security.SimplePrincipal;
+import org.keycloak.adapters.AdapterTokenStore;
+import org.keycloak.adapters.HttpFacade;
+import org.keycloak.adapters.KeycloakDeployment;
+import org.keycloak.adapters.undertow.KeycloakUndertowAccount;
+import org.keycloak.adapters.undertow.ServletRequestAuthenticator;
+import org.keycloak.adapters.undertow.UndertowUserSessionManagement;
+
+import javax.security.auth.Subject;
+import java.security.Principal;
+import java.security.acl.Group;
+import java.util.Collection;
+import java.util.Enumeration;
+import java.util.Iterator;
+import java.util.Set;
+
+/**
+ * @author Bill Burke
+ * @version $Revision: 1 $
+ */
+public class WildflyRequestAuthenticator extends ServletRequestAuthenticator {
+ protected static Logger log = Logger.getLogger(WildflyRequestAuthenticator.class);
+
+ public WildflyRequestAuthenticator(HttpFacade facade, KeycloakDeployment deployment, int sslRedirectPort,
+ SecurityContext securityContext, HttpServerExchange exchange,
+ AdapterTokenStore tokenStore) {
+ super(facade, deployment, sslRedirectPort, securityContext, exchange, tokenStore);
+ }
+
+ @Override
+ protected void propagateKeycloakContext(KeycloakUndertowAccount account) {
+ super.propagateKeycloakContext(account);
+ SecurityInfoHelper.propagateSessionInfo(account);
+ log.debug("propagate security context to wildfly");
+ Subject subject = new Subject();
+ Set principals = subject.getPrincipals();
+ principals.add(account.getPrincipal());
+ Group[] roleSets = getRoleSets(account.getRoles());
+ for (int g = 0; g < roleSets.length; g++) {
+ Group group = roleSets[g];
+ String name = group.getName();
+ Group subjectGroup = createGroup(name, principals);
+ if (subjectGroup instanceof NestableGroup) {
+ /* A NestableGroup only allows Groups to be added to it so we
+ need to add a SimpleGroup to subjectRoles to contain the roles
+ */
+ SimpleGroup tmp = new SimpleGroup("Roles");
+ subjectGroup.addMember(tmp);
+ subjectGroup = tmp;
+ }
+ // Copy the group members to the Subject group
+ Enumeration extends Principal> members = group.members();
+ while (members.hasMoreElements()) {
+ Principal role = (Principal) members.nextElement();
+ subjectGroup.addMember(role);
+ }
+ }
+ // add the CallerPrincipal group if none has been added in getRoleSets
+ Group callerGroup = new SimpleGroup(SecurityConstants.CALLER_PRINCIPAL_GROUP);
+ callerGroup.addMember(account.getPrincipal());
+ principals.add(callerGroup);
+ org.jboss.security.SecurityContext sc = SecurityContextAssociation.getSecurityContext();
+ Principal userPrincipal = getPrincipal(subject);
+ sc.getUtil().createSubjectInfo(userPrincipal, account, subject);
+ }
+
+ /**
+ * Get the Principal given the authenticated Subject. Currently the first subject that is not of type {@code Group} is
+ * considered or the single subject inside the CallerPrincipal group.
+ *
+ * @param subject
+ * @return the authenticated subject
+ */
+ protected Principal getPrincipal(Subject subject) {
+ Principal principal = null;
+ Principal callerPrincipal = null;
+ if (subject != null) {
+ Set principals = subject.getPrincipals();
+ if (principals != null && !principals.isEmpty()) {
+ for (Principal p : principals) {
+ if (!(p instanceof Group) && principal == null) {
+ principal = p;
+ }
+ if (p instanceof Group) {
+ Group g = Group.class.cast(p);
+ if (g.getName().equals(SecurityConstants.CALLER_PRINCIPAL_GROUP) && callerPrincipal == null) {
+ Enumeration extends Principal> e = g.members();
+ if (e.hasMoreElements())
+ callerPrincipal = e.nextElement();
+ }
+ }
+ }
+ }
+ }
+ return callerPrincipal == null ? principal : callerPrincipal;
+ }
+
+ protected Group createGroup(String name, Set principals) {
+ Group roles = null;
+ Iterator iter = principals.iterator();
+ while (iter.hasNext()) {
+ Object next = iter.next();
+ if ((next instanceof Group) == false)
+ continue;
+ Group grp = (Group) next;
+ if (grp.getName().equals(name)) {
+ roles = grp;
+ break;
+ }
+ }
+ // If we did not find a group create one
+ if (roles == null) {
+ roles = new SimpleGroup(name);
+ principals.add(roles);
+ }
+ return roles;
+ }
+
+ protected Group[] getRoleSets(Collection roleSet) {
+ SimpleGroup roles = new SimpleGroup("Roles");
+ Group[] roleSets = {roles};
+ for (String role : roleSet) {
+ roles.addMember(new SimplePrincipal(role));
+ }
+ return roleSets;
+ }
+
+}
diff --git a/integration/wildfly-adapter/src/main/resources/META-INF/services/io.undertow.servlet.ServletExtension b/integration/wildfly/wildfly-adapter/src/main/resources/META-INF/services/io.undertow.servlet.ServletExtension
similarity index 100%
rename from integration/wildfly-adapter/src/main/resources/META-INF/services/io.undertow.servlet.ServletExtension
rename to integration/wildfly/wildfly-adapter/src/main/resources/META-INF/services/io.undertow.servlet.ServletExtension
diff --git a/integration/wildfly-extensions/pom.xml b/integration/wildfly/wildfly-extensions/pom.xml
similarity index 97%
rename from integration/wildfly-extensions/pom.xml
rename to integration/wildfly/wildfly-extensions/pom.xml
index 16594e6ebfe..5bdf23fe49b 100755
--- a/integration/wildfly-extensions/pom.xml
+++ b/integration/wildfly/wildfly-extensions/pom.xml
@@ -21,7 +21,7 @@
org.keycloakkeycloak-parent1.3.0.Beta1-SNAPSHOT
- ../../pom.xml
+ ../../../pom.xmlkeycloak-wildfly-extensions
diff --git a/integration/wildfly-extensions/src/main/java/org/keycloak/provider/wildfly/ModuleProviderLoaderFactory.java b/integration/wildfly/wildfly-extensions/src/main/java/org/keycloak/provider/wildfly/ModuleProviderLoaderFactory.java
similarity index 100%
rename from integration/wildfly-extensions/src/main/java/org/keycloak/provider/wildfly/ModuleProviderLoaderFactory.java
rename to integration/wildfly/wildfly-extensions/src/main/java/org/keycloak/provider/wildfly/ModuleProviderLoaderFactory.java
diff --git a/integration/wildfly-extensions/src/main/java/org/keycloak/provider/wildfly/ModuleThemeProviderFactory.java b/integration/wildfly/wildfly-extensions/src/main/java/org/keycloak/provider/wildfly/ModuleThemeProviderFactory.java
similarity index 100%
rename from integration/wildfly-extensions/src/main/java/org/keycloak/provider/wildfly/ModuleThemeProviderFactory.java
rename to integration/wildfly/wildfly-extensions/src/main/java/org/keycloak/provider/wildfly/ModuleThemeProviderFactory.java
diff --git a/integration/wildfly-extensions/src/main/resources/META-INF/services/org.keycloak.freemarker.ThemeProviderFactory b/integration/wildfly/wildfly-extensions/src/main/resources/META-INF/services/org.keycloak.freemarker.ThemeProviderFactory
similarity index 100%
rename from integration/wildfly-extensions/src/main/resources/META-INF/services/org.keycloak.freemarker.ThemeProviderFactory
rename to integration/wildfly/wildfly-extensions/src/main/resources/META-INF/services/org.keycloak.freemarker.ThemeProviderFactory
diff --git a/integration/wildfly-extensions/src/main/resources/META-INF/services/org.keycloak.provider.ProviderLoaderFactory b/integration/wildfly/wildfly-extensions/src/main/resources/META-INF/services/org.keycloak.provider.ProviderLoaderFactory
similarity index 100%
rename from integration/wildfly-extensions/src/main/resources/META-INF/services/org.keycloak.provider.ProviderLoaderFactory
rename to integration/wildfly/wildfly-extensions/src/main/resources/META-INF/services/org.keycloak.provider.ProviderLoaderFactory
diff --git a/integration/wildfly-server-subsystem/pom.xml b/integration/wildfly/wildfly-server-subsystem/pom.xml
similarity index 97%
rename from integration/wildfly-server-subsystem/pom.xml
rename to integration/wildfly/wildfly-server-subsystem/pom.xml
index c4a6519bb9d..71bb0fd66e5 100755
--- a/integration/wildfly-server-subsystem/pom.xml
+++ b/integration/wildfly/wildfly-server-subsystem/pom.xml
@@ -20,8 +20,8 @@
org.keycloakkeycloak-parent
- 1.2.0.RC1-SNAPSHOT
- ../../pom.xml
+ 1.3.0.Beta1-SNAPSHOT
+ ../../../pom.xmlkeycloak-wildfly-server-subsystem
diff --git a/integration/wildfly-server-subsystem/src/main/java/org/keycloak/subsystem/server/extension/KeycloakAdapterConfigService.java b/integration/wildfly/wildfly-server-subsystem/src/main/java/org/keycloak/subsystem/server/extension/KeycloakAdapterConfigService.java
similarity index 100%
rename from integration/wildfly-server-subsystem/src/main/java/org/keycloak/subsystem/server/extension/KeycloakAdapterConfigService.java
rename to integration/wildfly/wildfly-server-subsystem/src/main/java/org/keycloak/subsystem/server/extension/KeycloakAdapterConfigService.java
diff --git a/integration/wildfly-server-subsystem/src/main/java/org/keycloak/subsystem/server/extension/KeycloakDependencyProcessor.java b/integration/wildfly/wildfly-server-subsystem/src/main/java/org/keycloak/subsystem/server/extension/KeycloakDependencyProcessor.java
similarity index 100%
rename from integration/wildfly-server-subsystem/src/main/java/org/keycloak/subsystem/server/extension/KeycloakDependencyProcessor.java
rename to integration/wildfly/wildfly-server-subsystem/src/main/java/org/keycloak/subsystem/server/extension/KeycloakDependencyProcessor.java
diff --git a/integration/wildfly-server-subsystem/src/main/java/org/keycloak/subsystem/server/extension/KeycloakDependencyProcessorWildFly.java b/integration/wildfly/wildfly-server-subsystem/src/main/java/org/keycloak/subsystem/server/extension/KeycloakDependencyProcessorWildFly.java
similarity index 100%
rename from integration/wildfly-server-subsystem/src/main/java/org/keycloak/subsystem/server/extension/KeycloakDependencyProcessorWildFly.java
rename to integration/wildfly/wildfly-server-subsystem/src/main/java/org/keycloak/subsystem/server/extension/KeycloakDependencyProcessorWildFly.java
diff --git a/integration/wildfly-server-subsystem/src/main/java/org/keycloak/subsystem/server/extension/KeycloakExtension.java b/integration/wildfly/wildfly-server-subsystem/src/main/java/org/keycloak/subsystem/server/extension/KeycloakExtension.java
similarity index 100%
rename from integration/wildfly-server-subsystem/src/main/java/org/keycloak/subsystem/server/extension/KeycloakExtension.java
rename to integration/wildfly/wildfly-server-subsystem/src/main/java/org/keycloak/subsystem/server/extension/KeycloakExtension.java
diff --git a/integration/wildfly-server-subsystem/src/main/java/org/keycloak/subsystem/server/extension/KeycloakSubsystemAdd.java b/integration/wildfly/wildfly-server-subsystem/src/main/java/org/keycloak/subsystem/server/extension/KeycloakSubsystemAdd.java
similarity index 100%
rename from integration/wildfly-server-subsystem/src/main/java/org/keycloak/subsystem/server/extension/KeycloakSubsystemAdd.java
rename to integration/wildfly/wildfly-server-subsystem/src/main/java/org/keycloak/subsystem/server/extension/KeycloakSubsystemAdd.java
diff --git a/integration/wildfly-server-subsystem/src/main/java/org/keycloak/subsystem/server/extension/KeycloakSubsystemDefinition.java b/integration/wildfly/wildfly-server-subsystem/src/main/java/org/keycloak/subsystem/server/extension/KeycloakSubsystemDefinition.java
similarity index 100%
rename from integration/wildfly-server-subsystem/src/main/java/org/keycloak/subsystem/server/extension/KeycloakSubsystemDefinition.java
rename to integration/wildfly/wildfly-server-subsystem/src/main/java/org/keycloak/subsystem/server/extension/KeycloakSubsystemDefinition.java
diff --git a/integration/wildfly-server-subsystem/src/main/java/org/keycloak/subsystem/server/extension/KeycloakSubsystemParser.java b/integration/wildfly/wildfly-server-subsystem/src/main/java/org/keycloak/subsystem/server/extension/KeycloakSubsystemParser.java
similarity index 100%
rename from integration/wildfly-server-subsystem/src/main/java/org/keycloak/subsystem/server/extension/KeycloakSubsystemParser.java
rename to integration/wildfly/wildfly-server-subsystem/src/main/java/org/keycloak/subsystem/server/extension/KeycloakSubsystemParser.java
diff --git a/integration/wildfly-server-subsystem/src/main/java/org/keycloak/subsystem/server/extension/authserver/AbstractAddOverlayHandler.java b/integration/wildfly/wildfly-server-subsystem/src/main/java/org/keycloak/subsystem/server/extension/authserver/AbstractAddOverlayHandler.java
similarity index 100%
rename from integration/wildfly-server-subsystem/src/main/java/org/keycloak/subsystem/server/extension/authserver/AbstractAddOverlayHandler.java
rename to integration/wildfly/wildfly-server-subsystem/src/main/java/org/keycloak/subsystem/server/extension/authserver/AbstractAddOverlayHandler.java
diff --git a/integration/wildfly-server-subsystem/src/main/java/org/keycloak/subsystem/server/extension/authserver/AddProviderHandler.java b/integration/wildfly/wildfly-server-subsystem/src/main/java/org/keycloak/subsystem/server/extension/authserver/AddProviderHandler.java
similarity index 100%
rename from integration/wildfly-server-subsystem/src/main/java/org/keycloak/subsystem/server/extension/authserver/AddProviderHandler.java
rename to integration/wildfly/wildfly-server-subsystem/src/main/java/org/keycloak/subsystem/server/extension/authserver/AddProviderHandler.java
diff --git a/integration/wildfly-server-subsystem/src/main/java/org/keycloak/subsystem/server/extension/authserver/AuthServerAddHandler.java b/integration/wildfly/wildfly-server-subsystem/src/main/java/org/keycloak/subsystem/server/extension/authserver/AuthServerAddHandler.java
similarity index 100%
rename from integration/wildfly-server-subsystem/src/main/java/org/keycloak/subsystem/server/extension/authserver/AuthServerAddHandler.java
rename to integration/wildfly/wildfly-server-subsystem/src/main/java/org/keycloak/subsystem/server/extension/authserver/AuthServerAddHandler.java
diff --git a/integration/wildfly-server-subsystem/src/main/java/org/keycloak/subsystem/server/extension/authserver/AuthServerDefinition.java b/integration/wildfly/wildfly-server-subsystem/src/main/java/org/keycloak/subsystem/server/extension/authserver/AuthServerDefinition.java
similarity index 100%
rename from integration/wildfly-server-subsystem/src/main/java/org/keycloak/subsystem/server/extension/authserver/AuthServerDefinition.java
rename to integration/wildfly/wildfly-server-subsystem/src/main/java/org/keycloak/subsystem/server/extension/authserver/AuthServerDefinition.java
diff --git a/integration/wildfly-server-subsystem/src/main/java/org/keycloak/subsystem/server/extension/authserver/AuthServerRemoveHandler.java b/integration/wildfly/wildfly-server-subsystem/src/main/java/org/keycloak/subsystem/server/extension/authserver/AuthServerRemoveHandler.java
similarity index 100%
rename from integration/wildfly-server-subsystem/src/main/java/org/keycloak/subsystem/server/extension/authserver/AuthServerRemoveHandler.java
rename to integration/wildfly/wildfly-server-subsystem/src/main/java/org/keycloak/subsystem/server/extension/authserver/AuthServerRemoveHandler.java
diff --git a/integration/wildfly-server-subsystem/src/main/java/org/keycloak/subsystem/server/extension/authserver/AuthServerUtil.java b/integration/wildfly/wildfly-server-subsystem/src/main/java/org/keycloak/subsystem/server/extension/authserver/AuthServerUtil.java
similarity index 100%
rename from integration/wildfly-server-subsystem/src/main/java/org/keycloak/subsystem/server/extension/authserver/AuthServerUtil.java
rename to integration/wildfly/wildfly-server-subsystem/src/main/java/org/keycloak/subsystem/server/extension/authserver/AuthServerUtil.java
diff --git a/integration/wildfly-server-subsystem/src/main/java/org/keycloak/subsystem/server/extension/authserver/AuthServerWriteAttributeHandler.java b/integration/wildfly/wildfly-server-subsystem/src/main/java/org/keycloak/subsystem/server/extension/authserver/AuthServerWriteAttributeHandler.java
similarity index 100%
rename from integration/wildfly-server-subsystem/src/main/java/org/keycloak/subsystem/server/extension/authserver/AuthServerWriteAttributeHandler.java
rename to integration/wildfly/wildfly-server-subsystem/src/main/java/org/keycloak/subsystem/server/extension/authserver/AuthServerWriteAttributeHandler.java
diff --git a/integration/wildfly-server-subsystem/src/main/java/org/keycloak/subsystem/server/extension/authserver/KeycloakServerDeploymentProcessor.java b/integration/wildfly/wildfly-server-subsystem/src/main/java/org/keycloak/subsystem/server/extension/authserver/KeycloakServerDeploymentProcessor.java
similarity index 100%
rename from integration/wildfly-server-subsystem/src/main/java/org/keycloak/subsystem/server/extension/authserver/KeycloakServerDeploymentProcessor.java
rename to integration/wildfly/wildfly-server-subsystem/src/main/java/org/keycloak/subsystem/server/extension/authserver/KeycloakServerDeploymentProcessor.java
diff --git a/integration/wildfly-server-subsystem/src/main/java/org/keycloak/subsystem/server/extension/authserver/ListOverlaysHandler.java b/integration/wildfly/wildfly-server-subsystem/src/main/java/org/keycloak/subsystem/server/extension/authserver/ListOverlaysHandler.java
similarity index 100%
rename from integration/wildfly-server-subsystem/src/main/java/org/keycloak/subsystem/server/extension/authserver/ListOverlaysHandler.java
rename to integration/wildfly/wildfly-server-subsystem/src/main/java/org/keycloak/subsystem/server/extension/authserver/ListOverlaysHandler.java
diff --git a/integration/wildfly-server-subsystem/src/main/java/org/keycloak/subsystem/server/extension/authserver/OverlayKeycloakServerJsonHandler.java b/integration/wildfly/wildfly-server-subsystem/src/main/java/org/keycloak/subsystem/server/extension/authserver/OverlayKeycloakServerJsonHandler.java
similarity index 100%
rename from integration/wildfly-server-subsystem/src/main/java/org/keycloak/subsystem/server/extension/authserver/OverlayKeycloakServerJsonHandler.java
rename to integration/wildfly/wildfly-server-subsystem/src/main/java/org/keycloak/subsystem/server/extension/authserver/OverlayKeycloakServerJsonHandler.java
diff --git a/integration/wildfly-server-subsystem/src/main/java/org/keycloak/subsystem/server/extension/authserver/RemoveOverlayHandler.java b/integration/wildfly/wildfly-server-subsystem/src/main/java/org/keycloak/subsystem/server/extension/authserver/RemoveOverlayHandler.java
similarity index 100%
rename from integration/wildfly-server-subsystem/src/main/java/org/keycloak/subsystem/server/extension/authserver/RemoveOverlayHandler.java
rename to integration/wildfly/wildfly-server-subsystem/src/main/java/org/keycloak/subsystem/server/extension/authserver/RemoveOverlayHandler.java
diff --git a/integration/wildfly-server-subsystem/src/main/java/org/keycloak/subsystem/server/logging/KeycloakLogger.java b/integration/wildfly/wildfly-server-subsystem/src/main/java/org/keycloak/subsystem/server/logging/KeycloakLogger.java
similarity index 100%
rename from integration/wildfly-server-subsystem/src/main/java/org/keycloak/subsystem/server/logging/KeycloakLogger.java
rename to integration/wildfly/wildfly-server-subsystem/src/main/java/org/keycloak/subsystem/server/logging/KeycloakLogger.java
diff --git a/integration/wildfly-server-subsystem/src/main/java/org/keycloak/subsystem/server/logging/KeycloakMessages.java b/integration/wildfly/wildfly-server-subsystem/src/main/java/org/keycloak/subsystem/server/logging/KeycloakMessages.java
similarity index 100%
rename from integration/wildfly-server-subsystem/src/main/java/org/keycloak/subsystem/server/logging/KeycloakMessages.java
rename to integration/wildfly/wildfly-server-subsystem/src/main/java/org/keycloak/subsystem/server/logging/KeycloakMessages.java
diff --git a/integration/wildfly-server-subsystem/src/main/resources/META-INF/services/org.jboss.as.controller.Extension b/integration/wildfly/wildfly-server-subsystem/src/main/resources/META-INF/services/org.jboss.as.controller.Extension
similarity index 100%
rename from integration/wildfly-server-subsystem/src/main/resources/META-INF/services/org.jboss.as.controller.Extension
rename to integration/wildfly/wildfly-server-subsystem/src/main/resources/META-INF/services/org.jboss.as.controller.Extension
diff --git a/integration/wildfly-server-subsystem/src/main/resources/org/keycloak/subsystem/server/extension/LocalDescriptions.properties b/integration/wildfly/wildfly-server-subsystem/src/main/resources/org/keycloak/subsystem/server/extension/LocalDescriptions.properties
similarity index 100%
rename from integration/wildfly-server-subsystem/src/main/resources/org/keycloak/subsystem/server/extension/LocalDescriptions.properties
rename to integration/wildfly/wildfly-server-subsystem/src/main/resources/org/keycloak/subsystem/server/extension/LocalDescriptions.properties
diff --git a/integration/wildfly-server-subsystem/src/main/resources/schema/wildfly-keycloak-server_1_1.xsd b/integration/wildfly/wildfly-server-subsystem/src/main/resources/schema/wildfly-keycloak-server_1_1.xsd
similarity index 100%
rename from integration/wildfly-server-subsystem/src/main/resources/schema/wildfly-keycloak-server_1_1.xsd
rename to integration/wildfly/wildfly-server-subsystem/src/main/resources/schema/wildfly-keycloak-server_1_1.xsd
diff --git a/integration/wildfly-server-subsystem/src/main/resources/subsystem-templates/keycloak-datasources.xml b/integration/wildfly/wildfly-server-subsystem/src/main/resources/subsystem-templates/keycloak-datasources.xml
similarity index 100%
rename from integration/wildfly-server-subsystem/src/main/resources/subsystem-templates/keycloak-datasources.xml
rename to integration/wildfly/wildfly-server-subsystem/src/main/resources/subsystem-templates/keycloak-datasources.xml
diff --git a/integration/wildfly-server-subsystem/src/main/resources/subsystem-templates/keycloak-server.xml b/integration/wildfly/wildfly-server-subsystem/src/main/resources/subsystem-templates/keycloak-server.xml
similarity index 100%
rename from integration/wildfly-server-subsystem/src/main/resources/subsystem-templates/keycloak-server.xml
rename to integration/wildfly/wildfly-server-subsystem/src/main/resources/subsystem-templates/keycloak-server.xml
diff --git a/integration/wildfly-server-subsystem/src/test/java/org/keycloak/subsystem/server/extension/SubsystemParsingTestCase.java b/integration/wildfly/wildfly-server-subsystem/src/test/java/org/keycloak/subsystem/server/extension/SubsystemParsingTestCase.java
similarity index 100%
rename from integration/wildfly-server-subsystem/src/test/java/org/keycloak/subsystem/server/extension/SubsystemParsingTestCase.java
rename to integration/wildfly/wildfly-server-subsystem/src/test/java/org/keycloak/subsystem/server/extension/SubsystemParsingTestCase.java
diff --git a/integration/wildfly-server-subsystem/src/test/resources/org/keycloak/subsystem/server/extension/keycloak-server-1.1.xml b/integration/wildfly/wildfly-server-subsystem/src/test/resources/org/keycloak/subsystem/server/extension/keycloak-server-1.1.xml
similarity index 100%
rename from integration/wildfly-server-subsystem/src/test/resources/org/keycloak/subsystem/server/extension/keycloak-server-1.1.xml
rename to integration/wildfly/wildfly-server-subsystem/src/test/resources/org/keycloak/subsystem/server/extension/keycloak-server-1.1.xml