All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.jboss.as.domain.management.parsing.ManagementXml Maven / Gradle / Ivy

There is a newer version: 8.2.1.Final
Show newest version
/*
 * JBoss, Home of Professional Open Source.
 * Copyright 2011, Red Hat, Inc., and individual contributors
 * as indicated by the @author tags. See the copyright.txt file in the
 * distribution for a full listing of individual contributors.
 *
 * This is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as
 * published by the Free Software Foundation; either version 2.1 of
 * the License, or (at your option) any later version.
 *
 * This software is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this software; if not, write to the Free
 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
 */

package org.jboss.as.domain.management.parsing;

import static javax.xml.stream.XMLStreamConstants.END_ELEMENT;
import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.ACCESS;
import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.ADD;
import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.APPLICATION_CLASSIFICATION;
import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.AUDIT;
import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.AUTHENTICATION;
import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.AUTHORIZATION;
import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.CLASSIFICATION;
import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.CONSTRAINT;
import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.CORE_SERVICE;
import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.EXCLUDE;
import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.GROUP;
import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.HOST_SCOPED_ROLE;
import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.HOST_SCOPED_ROLES;
import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.HTTP_INTERFACE;
import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.INCLUDE;
import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.JAAS;
import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.LDAP;
import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.LDAP_CONNECTION;
import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.MANAGEMENT;
import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.MANAGEMENT_INTERFACE;
import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.NAME;
import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.NATIVE_INTERFACE;
import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.NATIVE_REMOTING_INTERFACE;
import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.OP;
import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.OP_ADDR;
import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.PLAIN_TEXT;
import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.PROPERTIES;
import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.ROLE_MAPPING;
import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.SECRET;
import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.SECURITY_REALM;
import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.SENSITIVITY_CLASSIFICATION;
import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.SERVER_GROUP_SCOPED_ROLE;
import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.SERVER_IDENTITY;
import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.SSL;
import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.TRUSTSTORE;
import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.TYPE;
import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.USER;
import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.USERS;
import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.VAULT_EXPRESSION;
import static org.jboss.as.controller.parsing.ParseUtils.isNoNamespaceAttribute;
import static org.jboss.as.controller.parsing.ParseUtils.missingOneOf;
import static org.jboss.as.controller.parsing.ParseUtils.missingRequired;
import static org.jboss.as.controller.parsing.ParseUtils.missingRequiredElement;
import static org.jboss.as.controller.parsing.ParseUtils.readStringAttributeElement;
import static org.jboss.as.controller.parsing.ParseUtils.requireNamespace;
import static org.jboss.as.controller.parsing.ParseUtils.requireNoContent;
import static org.jboss.as.controller.parsing.ParseUtils.requireSingleAttribute;
import static org.jboss.as.controller.parsing.ParseUtils.unexpectedAttribute;
import static org.jboss.as.controller.parsing.ParseUtils.unexpectedElement;
import static org.jboss.as.domain.management.DomainManagementLogger.ROOT_LOGGER;
import static org.jboss.as.domain.management.ModelDescriptionConstants.DEFAULT_DEFAULT_USER;
import static org.jboss.as.domain.management.ModelDescriptionConstants.DEFAULT_USER;
import static org.jboss.as.domain.management.ModelDescriptionConstants.LOCAL;
import static org.jboss.as.domain.management.ModelDescriptionConstants.PLUG_IN;
import static org.jboss.as.domain.management.ModelDescriptionConstants.PROPERTY;

import java.util.Collections;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
import java.util.TreeSet;

import javax.xml.stream.XMLStreamException;

import org.jboss.as.controller.ListAttributeDefinition;
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.Attribute;
import org.jboss.as.controller.parsing.Element;
import org.jboss.as.controller.parsing.Namespace;
import org.jboss.as.controller.parsing.ParseUtils;
import org.jboss.as.domain.management.access.AccessAuthorizationResourceDefinition;
import org.jboss.as.domain.management.access.ApplicationClassificationConfigResourceDefinition;
import org.jboss.as.domain.management.access.ApplicationClassificationTypeResourceDefinition;
import org.jboss.as.domain.management.access.HostScopedRolesResourceDefinition;
import org.jboss.as.domain.management.access.PrincipalResourceDefinition;
import org.jboss.as.domain.management.access.SensitivityClassificationTypeResourceDefinition;
import org.jboss.as.domain.management.access.SensitivityResourceDefinition;
import org.jboss.as.domain.management.access.ServerGroupScopedRoleResourceDefinition;
import org.jboss.as.domain.management.connections.ldap.LdapConnectionResourceDefinition;
import org.jboss.as.domain.management.security.AbstractPlugInAuthResourceDefinition;
import org.jboss.as.domain.management.security.JaasAuthenticationResourceDefinition;
import org.jboss.as.domain.management.security.KeystoreAttributes;
import org.jboss.as.domain.management.security.LdapAuthenticationResourceDefinition;
import org.jboss.as.domain.management.security.LocalAuthenticationResourceDefinition;
import org.jboss.as.domain.management.security.PlugInAuthenticationResourceDefinition;
import org.jboss.as.domain.management.security.PropertiesAuthenticationResourceDefinition;
import org.jboss.as.domain.management.security.PropertiesAuthorizationResourceDefinition;
import org.jboss.as.domain.management.security.PropertyResourceDefinition;
import org.jboss.as.domain.management.security.SSLServerIdentityResourceDefinition;
import org.jboss.as.domain.management.security.SecretServerIdentityResourceDefinition;
import org.jboss.as.domain.management.security.SecurityRealmResourceDefinition;
import org.jboss.as.domain.management.security.UserResourceDefinition;
import org.jboss.dmr.ModelNode;
import org.jboss.dmr.Property;
import org.jboss.staxmapper.XMLExtendedStreamReader;
import org.jboss.staxmapper.XMLExtendedStreamWriter;

/**
 * Bits of parsing and marshaling logic that are related to {@code } elements in domain.xml, host.xml
 * and standalone.xml.
 *
 * @author Darran Lofthouse
 * @author Brian Stansberry (c) 2011 Red Hat Inc.
 */
public class ManagementXml {

    /** Handles config-file specific aspects of parsing and marshalling {@code } elements */
    public abstract static class Delegate {

        /**
         * Parse {@link Element#SECURITY_REALMS} content.
         * 

This default implementation does standard parsing; override to disable.

* @param reader the xml reader * @param address the address of the parent resource for any added resources * @param expectedNs the expected namespace for any children * @param operationsList list to which any operations should be added * @throws XMLStreamException */ protected void parseSecurityRealms(XMLExtendedStreamReader reader, ModelNode address, Namespace expectedNs, List operationsList) throws XMLStreamException { ManagementXml.parseSecurityRealms(reader, address, expectedNs, operationsList); } /** * Parse {@link Element#OUTBOUND_CONNECTIONS} content. *

This default implementation does standard parsing; override to disable.

* * @param reader the xml reader * @param address the address of the parent resource for any added resources * @param expectedNs the expected namespace for any children * @param operationsList list to which any operations should be added * @throws XMLStreamException */ protected void parseOutboundConnections(XMLExtendedStreamReader reader, ModelNode address, Namespace expectedNs, List operationsList) throws XMLStreamException { ManagementXml.parseOutboundConnections(reader, address, expectedNs, operationsList); } /** * Parse {@link Element#MANAGEMENT_INTERFACES} content. *

This default implementation throws {@code UnsupportedOperationException}; override to support.

* * @param reader the xml reader * @param address the address of the parent resource for any added resources * @param expectedNs the expected namespace for any children * @param operationsList list to which any operations should be added * @throws XMLStreamException */ protected void parseManagementInterfaces(XMLExtendedStreamReader reader, ModelNode address, Namespace expectedNs, List operationsList) throws XMLStreamException { throw new UnsupportedOperationException(); } /** * Parse {@link Element#ACCESS_CONTROL} content. *

This default implementation throws {@code UnsupportedOperationException}; override to support.

* * @param reader the xml reader * @param address the address of the parent resource for any added resources * @param expectedNs the expected namespace for any children * @param operationsList list to which any operations should be added * @throws XMLStreamException */ protected void parseAccessControl(final XMLExtendedStreamReader reader, final ModelNode address, final Namespace expectedNs, final List operationsList) throws XMLStreamException { // Must override if supported throw new UnsupportedOperationException(); } protected void parseAuditLog(final XMLExtendedStreamReader reader, final ModelNode address, final Namespace expectedNs, final List list) throws XMLStreamException { //Must override if supported throw new UnsupportedOperationException(); } /** * Write the {@link Element#NATIVE_INTERFACE} element. *

This default implementation does standard writing

* * @param writer the xml writer * @param accessAuthorization the access=authorization configuration * @throws XMLStreamException */ protected void writeAccessControl(XMLExtendedStreamWriter writer, ModelNode accessAuthorization) throws XMLStreamException { ManagementXml.writeAccessControl(writer, accessAuthorization); } /** * Write the {@link Element#NATIVE_INTERFACE} element. *

This default implementation throws {@code UnsupportedOperationException}; override to support.

* * @param writer the xml writer * @param protocol the interface configuration * @throws XMLStreamException */ protected void writeNativeManagementProtocol(XMLExtendedStreamWriter writer, ModelNode protocol) throws XMLStreamException { // Must override if supported throw new UnsupportedOperationException(); } /** * Write the {@link Element#HTTP_INTERFACE} element. *

This default implementation throws {@code UnsupportedOperationException}; override to support.

* * @param writer the xml writer * @param protocol the interface configuration * @throws XMLStreamException */ protected void writeHttpManagementProtocol(XMLExtendedStreamWriter writer, ModelNode protocol) throws XMLStreamException { // Must override if supported throw new UnsupportedOperationException(); } protected void writeAuditLog(XMLExtendedStreamWriter writer, ModelNode auditLog) throws XMLStreamException { // Must override if supported throw new UnsupportedOperationException(); } } private final Delegate delegate; public ManagementXml(Delegate delegate) { this.delegate = delegate; } public void parseManagement(final XMLExtendedStreamReader reader, final ModelNode address, final Namespace expectedNs, final List list, boolean requireNativeInterface) throws XMLStreamException { switch (expectedNs) { case DOMAIN_1_0: case DOMAIN_1_1: case DOMAIN_1_2: case DOMAIN_1_3: case DOMAIN_1_4: parseManagement_1_0(reader, address, expectedNs, list, requireNativeInterface); break; default: parseManagement_2_0(reader, address, expectedNs, list, requireNativeInterface); } } private void parseManagement_1_0(final XMLExtendedStreamReader reader, final ModelNode address, final Namespace expectedNs, final List list, boolean requireNativeInterface) throws XMLStreamException { int securityRealmsCount = 0; int connectionsCount = 0; int managementInterfacesCount = 0; final ModelNode managementAddress = address.clone().add(CORE_SERVICE, MANAGEMENT); while (reader.hasNext() && reader.nextTag() != END_ELEMENT) { requireNamespace(reader, expectedNs); final Element element = Element.forName(reader.getLocalName()); switch (element) { case SECURITY_REALMS: { if (++securityRealmsCount > 1) { throw unexpectedElement(reader); } delegate.parseSecurityRealms(reader, managementAddress, expectedNs, list); break; } case OUTBOUND_CONNECTIONS: { if (++connectionsCount > 1) { throw unexpectedElement(reader); } delegate.parseOutboundConnections(reader, managementAddress, expectedNs, list); break; } case MANAGEMENT_INTERFACES: { if (++managementInterfacesCount > 1) { throw unexpectedElement(reader); } delegate.parseManagementInterfaces(reader, managementAddress, expectedNs, list); break; } default: { throw unexpectedElement(reader); } } } if (requireNativeInterface && managementInterfacesCount < 1) { throw missingRequiredElement(reader, EnumSet.of(Element.MANAGEMENT_INTERFACES)); } } private void parseManagement_2_0(final XMLExtendedStreamReader reader, final ModelNode address, final Namespace expectedNs, final List list, boolean requireNativeInterface) throws XMLStreamException { int securityRealmsCount = 0; int connectionsCount = 0; int managementInterfacesCount = 0; final ModelNode managementAddress = address.clone().add(CORE_SERVICE, MANAGEMENT); while (reader.hasNext() && reader.nextTag() != END_ELEMENT) { requireNamespace(reader, expectedNs); final Element element = Element.forName(reader.getLocalName()); switch (element) { case SECURITY_REALMS: { if (++securityRealmsCount > 1) { throw unexpectedElement(reader); } delegate.parseSecurityRealms(reader, managementAddress, expectedNs, list); break; } case OUTBOUND_CONNECTIONS: { if (++connectionsCount > 1) { throw unexpectedElement(reader); } delegate.parseOutboundConnections(reader, managementAddress, expectedNs, list); break; } case MANAGEMENT_INTERFACES: { if (++managementInterfacesCount > 1) { throw unexpectedElement(reader); } delegate.parseManagementInterfaces(reader, managementAddress, expectedNs, list); break; } case AUDIT_LOG: { delegate.parseAuditLog(reader, managementAddress, expectedNs, list); break; } case ACCESS_CONTROL: { delegate.parseAccessControl(reader, managementAddress, expectedNs, list); break; } default: { throw unexpectedElement(reader); } } } if (requireNativeInterface && managementInterfacesCount < 1) { throw missingRequiredElement(reader, EnumSet.of(Element.MANAGEMENT_INTERFACES)); } } private static void parseOutboundConnections(final XMLExtendedStreamReader reader, final ModelNode address, final Namespace expectedNs, final List list) throws XMLStreamException { while (reader.hasNext() && reader.nextTag() != END_ELEMENT) { requireNamespace(reader, expectedNs); final Element element = Element.forName(reader.getLocalName()); switch (element) { case LDAP: { switch (expectedNs) { case DOMAIN_1_0: case DOMAIN_1_1: case DOMAIN_1_2: case DOMAIN_1_3: parseLdapConnection_1_0(reader, address, list); break; default: parseLdapConnection_1_4(reader, address, list); break; } break; } default: { throw unexpectedElement(reader); } } } } private static void parseLdapConnection_1_0(final XMLExtendedStreamReader reader, final ModelNode address, final List list) throws XMLStreamException { final ModelNode add = new ModelNode(); add.get(OP).set(ADD); list.add(add); Set required = EnumSet.of(Attribute.NAME, Attribute.URL, Attribute.SEARCH_DN, Attribute.SEARCH_CREDENTIAL); final int count = reader.getAttributeCount(); for (int i = 0; i < count; i++) { final String value = reader.getAttributeValue(i); if (!isNoNamespaceAttribute(reader, i)) { throw unexpectedAttribute(reader, i); } else { final Attribute attribute = Attribute.forName(reader.getAttributeLocalName(i)); required.remove(attribute); switch (attribute) { case NAME: { add.get(OP_ADDR).set(address).add(LDAP_CONNECTION, value); break; } case URL: { LdapConnectionResourceDefinition.URL.parseAndSetParameter(value, add, reader); break; } case SEARCH_DN: { LdapConnectionResourceDefinition.SEARCH_DN.parseAndSetParameter(value, add, reader); break; } case SEARCH_CREDENTIAL: { LdapConnectionResourceDefinition.SEARCH_CREDENTIAL.parseAndSetParameter(value, add, reader); break; } case INITIAL_CONTEXT_FACTORY: { LdapConnectionResourceDefinition.INITIAL_CONTEXT_FACTORY.parseAndSetParameter(value, add, reader); break; } default: { throw unexpectedAttribute(reader, i); } } } } if (required.size() > 0) { throw missingRequired(reader, required); } requireNoContent(reader); } private static void parseLdapConnection_1_4(final XMLExtendedStreamReader reader, final ModelNode address, final List list) throws XMLStreamException { final ModelNode add = new ModelNode(); add.get(OP).set(ADD); list.add(add); Set required = EnumSet.of(Attribute.NAME, Attribute.URL); final int count = reader.getAttributeCount(); for (int i = 0; i < count; i++) { final String value = reader.getAttributeValue(i); if (!isNoNamespaceAttribute(reader, i)) { throw unexpectedAttribute(reader, i); } else { final Attribute attribute = Attribute.forName(reader.getAttributeLocalName(i)); required.remove(attribute); switch (attribute) { case NAME: { add.get(OP_ADDR).set(address).add(LDAP_CONNECTION, value); break; } case URL: { LdapConnectionResourceDefinition.URL.parseAndSetParameter(value, add, reader); break; } case SEARCH_DN: { LdapConnectionResourceDefinition.SEARCH_DN.parseAndSetParameter(value, add, reader); break; } case SEARCH_CREDENTIAL: { LdapConnectionResourceDefinition.SEARCH_CREDENTIAL.parseAndSetParameter(value, add, reader); break; } case SECURITY_REALM: { LdapConnectionResourceDefinition.SECURITY_REALM.parseAndSetParameter(value, add, reader); break; } case INITIAL_CONTEXT_FACTORY: { LdapConnectionResourceDefinition.INITIAL_CONTEXT_FACTORY.parseAndSetParameter(value, add, reader); break; } default: { throw unexpectedAttribute(reader, i); } } } } if (required.size() > 0) { throw missingRequired(reader, required); } requireNoContent(reader); } private static void parseSecurityRealms(final XMLExtendedStreamReader reader, final ModelNode address, final Namespace expectedNs, final List list) throws XMLStreamException { while (reader.hasNext() && reader.nextTag() != END_ELEMENT) { requireNamespace(reader, expectedNs); final Element element = Element.forName(reader.getLocalName()); switch (element) { case SECURITY_REALM: { switch (expectedNs) { case DOMAIN_1_0: parseSecurityRealm_1_0(reader, address, expectedNs, list); break; case DOMAIN_1_1: case DOMAIN_1_2: parseSecurityRealm_1_1(reader, address, expectedNs, list); break; default: parseSecurityRealm_1_3(reader, address, expectedNs, list); break; } break; } default: { throw unexpectedElement(reader); } } } } private static void parseSecurityRealm_1_0(final XMLExtendedStreamReader reader, final ModelNode address, final Namespace expectedNs, final List list) throws XMLStreamException { requireSingleAttribute(reader, Attribute.NAME.getLocalName()); // After double checking the name of the only attribute we can retrieve it. final String realmName = reader.getAttributeValue(0); final ModelNode realmAddress = address.clone(); realmAddress.add(SECURITY_REALM, realmName); final ModelNode add = new ModelNode(); add.get(OP_ADDR).set(realmAddress); add.get(OP).set(ADD); list.add(add); while (reader.hasNext() && reader.nextTag() != END_ELEMENT) { requireNamespace(reader, expectedNs); final Element element = Element.forName(reader.getLocalName()); switch (element) { case SERVER_IDENTITIES: parseServerIdentities(reader, expectedNs, realmAddress, list); break; case AUTHENTICATION: { parseAuthentication_1_0(reader, expectedNs, realmAddress, list); break; } default: { throw unexpectedElement(reader); } } } } private static void parseSecurityRealm_1_1(final XMLExtendedStreamReader reader, final ModelNode address, final Namespace expectedNs, final List list) throws XMLStreamException { requireSingleAttribute(reader, Attribute.NAME.getLocalName()); // After double checking the name of the only attribute we can retrieve it. final String realmName = reader.getAttributeValue(0); final ModelNode realmAddress = address.clone(); realmAddress.add(SECURITY_REALM, realmName); final ModelNode add = new ModelNode(); add.get(OP_ADDR).set(realmAddress); add.get(OP).set(ADD); list.add(add); while (reader.hasNext() && reader.nextTag() != END_ELEMENT) { requireNamespace(reader, expectedNs); final Element element = Element.forName(reader.getLocalName()); switch (element) { case SERVER_IDENTITIES: parseServerIdentities(reader, expectedNs, realmAddress, list); break; case AUTHENTICATION: { parseAuthentication_1_1(reader, expectedNs, realmAddress, list); break; } case AUTHORIZATION: parseAuthorization_1_1(reader, expectedNs, add, list); break; default: { throw unexpectedElement(reader); } } } } private static void parseSecurityRealm_1_3(final XMLExtendedStreamReader reader, final ModelNode address, final Namespace expectedNs, final List list) throws XMLStreamException { requireSingleAttribute(reader, Attribute.NAME.getLocalName()); // After double checking the name of the only attribute we can retrieve it. final String realmName = reader.getAttributeValue(0); final ModelNode realmAddress = address.clone(); realmAddress.add(SECURITY_REALM, realmName); final ModelNode add = new ModelNode(); add.get(OP_ADDR).set(realmAddress); add.get(OP).set(ADD); list.add(add); while (reader.hasNext() && reader.nextTag() != END_ELEMENT) { requireNamespace(reader, expectedNs); final Element element = Element.forName(reader.getLocalName()); switch (element) { case PLUG_INS: parsePlugIns(reader, expectedNs, realmAddress, list); break; case SERVER_IDENTITIES: parseServerIdentities(reader, expectedNs, realmAddress, list); break; case AUTHENTICATION: { parseAuthentication_1_3(reader, expectedNs, realmAddress, list); break; } case AUTHORIZATION: switch (expectedNs) { case DOMAIN_1_3: case DOMAIN_1_4: parseAuthorization_1_3(reader, expectedNs, add, list); break; default: parseAuthorization_2_0(reader, expectedNs, add, list); } break; default: { throw unexpectedElement(reader); } } } } private static void parsePlugIns(final XMLExtendedStreamReader reader, final Namespace expectedNs, final ModelNode realmAddress, final List list) throws XMLStreamException { while (reader.hasNext() && reader.nextTag() != END_ELEMENT) { requireNamespace(reader, expectedNs); final Element element = Element.forName(reader.getLocalName()); switch (element) { case PLUG_IN: { ModelNode plugIn = new ModelNode(); plugIn.get(OP).set(ADD); String moduleValue = readStringAttributeElement(reader, Attribute.MODULE.getLocalName()); final ModelNode newAddress = realmAddress.clone(); newAddress.add(PLUG_IN, moduleValue); plugIn.get(OP_ADDR).set(newAddress); list.add(plugIn); break; } default: { throw unexpectedElement(reader); } } } } private static void parseServerIdentities(final XMLExtendedStreamReader reader, final Namespace expectedNs, final ModelNode realmAddress, final List list) throws XMLStreamException { while (reader.hasNext() && reader.nextTag() != END_ELEMENT) { requireNamespace(reader, expectedNs); final Element element = Element.forName(reader.getLocalName()); switch (element) { case SECRET: { parseSecret(reader, realmAddress, list); break; } case SSL: { parseSSL(reader, expectedNs, realmAddress, list); break; } default: { throw unexpectedElement(reader); } } } } private static void parseSecret(final XMLExtendedStreamReader reader, final ModelNode realmAddress, final List list) throws XMLStreamException { ModelNode secret = new ModelNode(); secret.get(OP).set(ADD); secret.get(OP_ADDR).set(realmAddress).add(SERVER_IDENTITY, SECRET); String secretValue = readStringAttributeElement(reader, Attribute.VALUE.getLocalName()); SecretServerIdentityResourceDefinition.VALUE.parseAndSetParameter(secretValue, secret, reader); list.add(secret); } private static void parseSSL(final XMLExtendedStreamReader reader, final Namespace expectedNs, final ModelNode realmAddress, final List list) throws XMLStreamException { ModelNode ssl = new ModelNode(); ssl.get(OP).set(ADD); ssl.get(OP_ADDR).set(realmAddress).add(SERVER_IDENTITY, SSL); list.add(ssl); final int count = reader.getAttributeCount(); for (int i = 0; i < count; i++) { final String value = reader.getAttributeValue(i); if (!isNoNamespaceAttribute(reader, i)) { throw unexpectedAttribute(reader, i); } else { final Attribute attribute = Attribute.forName(reader.getAttributeLocalName(i)); switch (attribute) { case PROTOCOL: { SSLServerIdentityResourceDefinition.PROTOCOL.parseAndSetParameter(value, ssl, reader); break; } default: { throw unexpectedAttribute(reader, i); } } } } while (reader.hasNext() && reader.nextTag() != END_ELEMENT) { requireNamespace(reader, expectedNs); final Element element = Element.forName(reader.getLocalName()); switch (element) { case KEYSTORE: { switch (expectedNs) { case DOMAIN_1_0: case DOMAIN_1_1: case DOMAIN_1_2: parseKeystore_1_0(reader, ssl); break; default: parseKeystore_1_3(reader, ssl, true); } break; } default: { throw unexpectedElement(reader); } } } } private static void parseKeystore_1_0(final XMLExtendedStreamReader reader, final ModelNode addOperation) throws XMLStreamException { Set required = EnumSet.of(Attribute.PATH, Attribute.PASSWORD); final int count = reader.getAttributeCount(); for (int i = 0; i < count; i++) { final String value = reader.getAttributeValue(i); if (!isNoNamespaceAttribute(reader, i)) { throw unexpectedAttribute(reader, i); } else { final Attribute attribute = Attribute.forName(reader.getAttributeLocalName(i)); required.remove(attribute); switch (attribute) { case PATH: KeystoreAttributes.KEYSTORE_PATH.parseAndSetParameter(value, addOperation, reader); break; case PASSWORD: { KeystoreAttributes.KEYSTORE_PASSWORD.parseAndSetParameter(value, addOperation, reader); break; } case RELATIVE_TO: { KeystoreAttributes.KEYSTORE_RELATIVE_TO.parseAndSetParameter(value, addOperation, reader); break; } default: { throw unexpectedAttribute(reader, i); } } } } if (required.size() > 0) { throw missingRequired(reader, required); } requireNoContent(reader); } private static void parseKeystore_1_3(final XMLExtendedStreamReader reader, final ModelNode addOperation, final boolean extended) throws XMLStreamException { Set required = EnumSet.of(Attribute.PATH, Attribute.KEYSTORE_PASSWORD); final int count = reader.getAttributeCount(); for (int i = 0; i < count; i++) { final String value = reader.getAttributeValue(i); if (!isNoNamespaceAttribute(reader, i)) { throw unexpectedAttribute(reader, i); } else { final Attribute attribute = Attribute.forName(reader.getAttributeLocalName(i)); required.remove(attribute); switch (attribute) { case PATH: KeystoreAttributes.KEYSTORE_PATH.parseAndSetParameter(value, addOperation, reader); break; case PASSWORD: { // TODO - Support for this attribute can later be removed, would suggest removing at the // start of AS 8 development. ROOT_LOGGER.passwordAttributeDeprecated(); required.remove(Attribute.KEYSTORE_PASSWORD); KeystoreAttributes.KEYSTORE_PASSWORD.parseAndSetParameter(value, addOperation, reader); break; } case KEYSTORE_PASSWORD: { KeystoreAttributes.KEYSTORE_PASSWORD.parseAndSetParameter(value, addOperation, reader); break; } case RELATIVE_TO: { KeystoreAttributes.KEYSTORE_RELATIVE_TO.parseAndSetParameter(value, addOperation, reader); break; } /* * The 'extended' attributes when a true keystore and not just a keystore acting as a truststore. */ case ALIAS: { if (extended) { KeystoreAttributes.ALIAS.parseAndSetParameter(value, addOperation, reader); } else { throw unexpectedAttribute(reader, i); } break; } case KEY_PASSWORD: { if (extended) { KeystoreAttributes.KEY_PASSWORD.parseAndSetParameter(value, addOperation, reader); } else { throw unexpectedAttribute(reader, i); } break; } default: { throw unexpectedAttribute(reader, i); } } } } if (required.size() > 0) { throw missingRequired(reader, required); } requireNoContent(reader); } private static void parseAuthentication_1_0(final XMLExtendedStreamReader reader, final Namespace expectedNs, final ModelNode realmAddress, final List list) throws XMLStreamException { int userCount = 0; while (reader.hasNext() && reader.nextTag() != END_ELEMENT) { requireNamespace(reader, expectedNs); final Element element = Element.forName(reader.getLocalName()); // Only a single user element within the authentication element is currently supported. if (++userCount > 1) { throw unexpectedElement(reader); } switch (element) { case LDAP: { parseLdapAuthentication_1_0(reader, realmAddress, list); break; } case PROPERTIES: { parsePropertiesAuthentication_1_0(reader, realmAddress, list); break; } case USERS: { parseUsersAuthentication(reader, expectedNs, realmAddress, list); break; } default: { throw unexpectedElement(reader); } } } addLegacyLocalAuthentication(realmAddress, list); } private static void parseAuthentication_1_1(final XMLExtendedStreamReader reader, final Namespace expectedNs, final ModelNode realmAddress, final List list) throws XMLStreamException { // Only one truststore can be defined. boolean trustStoreFound = false; // Only one of ldap, properties or users can be defined. boolean usernamePasswordFound = false; while (reader.hasNext() && reader.nextTag() != END_ELEMENT) { requireNamespace(reader, expectedNs); final Element element = Element.forName(reader.getLocalName()); switch (element) { case JAAS: { if (usernamePasswordFound) { throw unexpectedElement(reader); } parseJaasAuthentication(reader, realmAddress, list); usernamePasswordFound = true; break; } case LDAP: { if (usernamePasswordFound) { throw unexpectedElement(reader); } parseLdapAuthentication_1_1(reader, expectedNs, realmAddress, list); usernamePasswordFound = true; break; } case PROPERTIES: { if (usernamePasswordFound) { throw unexpectedElement(reader); } parsePropertiesAuthentication_1_1(reader, realmAddress, list); usernamePasswordFound = true; break; } case TRUSTSTORE: { if (trustStoreFound) { throw unexpectedElement(reader); } parseTruststore(reader, expectedNs, realmAddress, list); trustStoreFound = true; break; } case USERS: { if (usernamePasswordFound) { throw unexpectedElement(reader); } parseUsersAuthentication(reader, expectedNs, realmAddress, list); usernamePasswordFound = true; break; } default: { throw unexpectedElement(reader); } } } addLegacyLocalAuthentication(realmAddress, list); } private static void parseAuthentication_1_3(final XMLExtendedStreamReader reader, final Namespace expectedNs, final ModelNode realmAddress, final List list) throws XMLStreamException { // Only one truststore can be defined. boolean trustStoreFound = false; // Only one local can be defined. boolean localFound = false; // Only one of ldap, properties or users can be defined. boolean usernamePasswordFound = false; while (reader.hasNext() && reader.nextTag() != END_ELEMENT) { requireNamespace(reader, expectedNs); final Element element = Element.forName(reader.getLocalName()); switch (element) { case JAAS: { if (usernamePasswordFound) { throw unexpectedElement(reader); } parseJaasAuthentication(reader, realmAddress, list); usernamePasswordFound = true; break; } case LDAP: { if (usernamePasswordFound) { throw unexpectedElement(reader); } // This method is specific to version 1.3 of the schema and beyond - no need to // consider namespaces before this point. switch (expectedNs) { case DOMAIN_1_3: parseLdapAuthentication_1_1(reader, expectedNs, realmAddress, list); break; default: parseLdapAuthentication_1_4(reader, expectedNs, realmAddress, list); break; } usernamePasswordFound = true; break; } case PROPERTIES: { if (usernamePasswordFound) { throw unexpectedElement(reader); } parsePropertiesAuthentication_1_1(reader, realmAddress, list); usernamePasswordFound = true; break; } case TRUSTSTORE: { if (trustStoreFound) { throw unexpectedElement(reader); } parseTruststore(reader, expectedNs, realmAddress, list); trustStoreFound = true; break; } case USERS: { if (usernamePasswordFound) { throw unexpectedElement(reader); } parseUsersAuthentication(reader, expectedNs, realmAddress, list); usernamePasswordFound = true; break; } case PLUG_IN: { if (usernamePasswordFound) { throw unexpectedElement(reader); } ModelNode parentAddress = realmAddress.clone().add(AUTHENTICATION); parsePlugIn_Authentication(reader, expectedNs, parentAddress, list); usernamePasswordFound = true; break; } case LOCAL: { if (localFound) { throw unexpectedElement(reader); } parseLocalAuthentication(reader, expectedNs, realmAddress, list); localFound = true; break; } default: { throw unexpectedElement(reader); } } } } private static void parseJaasAuthentication(final XMLExtendedStreamReader reader, final ModelNode realmAddress, final List list) throws XMLStreamException { ModelNode addr = realmAddress.clone().add(AUTHENTICATION, JAAS); ModelNode jaas = Util.getEmptyOperation(ADD, addr); list.add(jaas); boolean nameFound = false; final int count = reader.getAttributeCount(); for (int i = 0; i < count; i++) { final String value = reader.getAttributeValue(i); if (!isNoNamespaceAttribute(reader, i)) { throw unexpectedAttribute(reader, i); } else { final Attribute attribute = Attribute.forName(reader.getAttributeLocalName(i)); switch (attribute) { case NAME: if (nameFound) { throw unexpectedAttribute(reader, i); } nameFound = true; JaasAuthenticationResourceDefinition.NAME.parseAndSetParameter(value, jaas, reader); break; default: { throw unexpectedAttribute(reader, i); } } } } if (nameFound == false) { throw missingRequired(reader, Collections.singleton(Attribute.NAME)); } requireNoContent(reader); } private static void parseLdapAuthentication_1_0(final XMLExtendedStreamReader reader, final ModelNode realmAddress, final List list) throws XMLStreamException { ModelNode addr = realmAddress.clone().add(AUTHENTICATION, LDAP); ModelNode ldapAuthentication = Util.getEmptyOperation(ADD, addr); list.add(ldapAuthentication); Set required = EnumSet.of(Attribute.CONNECTION, Attribute.BASE_DN, Attribute.USERNAME_ATTRIBUTE); final int count = reader.getAttributeCount(); for (int i = 0; i < count; i++) { final String value = reader.getAttributeValue(i); if (!isNoNamespaceAttribute(reader, i)) { throw unexpectedAttribute(reader, i); } else { final Attribute attribute = Attribute.forName(reader.getAttributeLocalName(i)); required.remove(attribute); switch (attribute) { case CONNECTION: { LdapAuthenticationResourceDefinition.CONNECTION.parseAndSetParameter(value, ldapAuthentication, reader); break; } case BASE_DN: { LdapAuthenticationResourceDefinition.BASE_DN.parseAndSetParameter(value, ldapAuthentication, reader); break; } case USERNAME_ATTRIBUTE: { LdapAuthenticationResourceDefinition.USERNAME_FILTER.parseAndSetParameter(value, ldapAuthentication, reader); break; } case RECURSIVE: { LdapAuthenticationResourceDefinition.RECURSIVE.parseAndSetParameter(value, ldapAuthentication, reader); break; } case USER_DN: { LdapAuthenticationResourceDefinition.USER_DN.parseAndSetParameter(value, ldapAuthentication, reader); break; } default: { throw unexpectedAttribute(reader, i); } } } } if (required.size() > 0) throw missingRequired(reader, required); requireNoContent(reader); } private static void parseLdapAuthentication_1_1(final XMLExtendedStreamReader reader, final Namespace expectedNs, final ModelNode realmAddress, final List list) throws XMLStreamException { ModelNode addr = realmAddress.clone().add(AUTHENTICATION, LDAP); ModelNode ldapAuthentication = Util.getEmptyOperation(ADD, addr); list.add(ldapAuthentication); Set required = EnumSet.of(Attribute.CONNECTION, Attribute.BASE_DN); final int count = reader.getAttributeCount(); for (int i = 0; i < count; i++) { final String value = reader.getAttributeValue(i); if (!isNoNamespaceAttribute(reader, i)) { throw unexpectedAttribute(reader, i); } else { final Attribute attribute = Attribute.forName(reader.getAttributeLocalName(i)); required.remove(attribute); switch (attribute) { case CONNECTION: { LdapAuthenticationResourceDefinition.CONNECTION.parseAndSetParameter(value, ldapAuthentication, reader); break; } case BASE_DN: { LdapAuthenticationResourceDefinition.BASE_DN.parseAndSetParameter(value, ldapAuthentication, reader); break; } case RECURSIVE: { LdapAuthenticationResourceDefinition.RECURSIVE.parseAndSetParameter(value, ldapAuthentication, reader); break; } case USER_DN: { LdapAuthenticationResourceDefinition.USER_DN.parseAndSetParameter(value, ldapAuthentication, reader); break; } default: { throw unexpectedAttribute(reader, i); } } } } if (required.size() > 0) { throw missingRequired(reader, required); } boolean choiceFound = false; while (reader.hasNext() && reader.nextTag() != END_ELEMENT) { if (choiceFound) { throw unexpectedElement(reader); } choiceFound = true; requireNamespace(reader, expectedNs); final Element element = Element.forName(reader.getLocalName()); switch (element) { case ADVANCED_FILTER: String filter = readStringAttributeElement(reader, Attribute.FILTER.getLocalName()); LdapAuthenticationResourceDefinition.ADVANCED_FILTER.parseAndSetParameter(filter, ldapAuthentication, reader); break; case USERNAME_FILTER: { String usernameAttr = readStringAttributeElement(reader, Attribute.ATTRIBUTE.getLocalName()); LdapAuthenticationResourceDefinition.USERNAME_FILTER.parseAndSetParameter(usernameAttr, ldapAuthentication, reader); break; } default: { throw unexpectedElement(reader); } } } if (!choiceFound) { throw missingOneOf(reader, EnumSet.of(Element.ADVANCED_FILTER, Element.USERNAME_FILTER)); } } private static void parseLdapAuthentication_1_4(final XMLExtendedStreamReader reader, final Namespace expectedNs, final ModelNode realmAddress, final List list) throws XMLStreamException { ModelNode addr = realmAddress.clone().add(AUTHENTICATION, LDAP); ModelNode ldapAuthentication = Util.getEmptyOperation(ADD, addr); list.add(ldapAuthentication); Set required = EnumSet.of(Attribute.CONNECTION, Attribute.BASE_DN); final int count = reader.getAttributeCount(); for (int i = 0; i < count; i++) { final String value = reader.getAttributeValue(i); if (!isNoNamespaceAttribute(reader, i)) { throw unexpectedAttribute(reader, i); } else { final Attribute attribute = Attribute.forName(reader.getAttributeLocalName(i)); required.remove(attribute); switch (attribute) { case CONNECTION: { LdapAuthenticationResourceDefinition.CONNECTION.parseAndSetParameter(value, ldapAuthentication, reader); break; } case BASE_DN: { LdapAuthenticationResourceDefinition.BASE_DN.parseAndSetParameter(value, ldapAuthentication, reader); break; } case RECURSIVE: { LdapAuthenticationResourceDefinition.RECURSIVE.parseAndSetParameter(value, ldapAuthentication, reader); break; } case USER_DN: { LdapAuthenticationResourceDefinition.USER_DN.parseAndSetParameter(value, ldapAuthentication, reader); break; } case ALLOW_EMPTY_PASSWORDS: { LdapAuthenticationResourceDefinition.ALLOW_EMPTY_PASSWORDS.parseAndSetParameter(value, ldapAuthentication, reader); break; } default: { throw unexpectedAttribute(reader, i); } } } } if (required.size() > 0) { throw missingRequired(reader, required); } boolean choiceFound = false; while (reader.hasNext() && reader.nextTag() != END_ELEMENT) { if (choiceFound) { throw unexpectedElement(reader); } choiceFound = true; requireNamespace(reader, expectedNs); final Element element = Element.forName(reader.getLocalName()); switch (element) { case ADVANCED_FILTER: String filter = readStringAttributeElement(reader, Attribute.FILTER.getLocalName()); LdapAuthenticationResourceDefinition.ADVANCED_FILTER.parseAndSetParameter(filter, ldapAuthentication, reader); break; case USERNAME_FILTER: { String usernameAttr = readStringAttributeElement(reader, Attribute.ATTRIBUTE.getLocalName()); LdapAuthenticationResourceDefinition.USERNAME_FILTER.parseAndSetParameter(usernameAttr, ldapAuthentication, reader); break; } default: { throw unexpectedElement(reader); } } } if (!choiceFound) { throw missingOneOf(reader, EnumSet.of(Element.ADVANCED_FILTER, Element.USERNAME_FILTER)); } } private static void addLegacyLocalAuthentication(final ModelNode realmAddress, final List list) { /* * Before version 1.3 of the domain schema there was no configuration for the local mechanism, however it was always * enabled - this adds an arbitrary add local op to recreate this behaviour in the older schema versions. */ ModelNode addr = realmAddress.clone().add(AUTHENTICATION, LOCAL); ModelNode local = Util.getEmptyOperation(ADD, addr); local.get(DEFAULT_USER).set(DEFAULT_DEFAULT_USER); list.add(local); } private static void parseLocalAuthentication(final XMLExtendedStreamReader reader, final Namespace expectedNs, final ModelNode realmAddress, final List list) throws XMLStreamException { ModelNode addr = realmAddress.clone().add(AUTHENTICATION, LOCAL); ModelNode local = Util.getEmptyOperation(ADD, addr); list.add(local); final int count = reader.getAttributeCount(); Set attributesFound = new HashSet(count); for (int i = 0; i < count; i++) { final String value = reader.getAttributeValue(i); if (!isNoNamespaceAttribute(reader, i)) { throw unexpectedAttribute(reader, i); } else { final Attribute attribute = Attribute.forName(reader.getAttributeLocalName(i)); if (attributesFound.contains(attribute)) { throw unexpectedAttribute(reader, i); } attributesFound.add(attribute); switch (attribute) { case DEFAULT_USER: LocalAuthenticationResourceDefinition.DEFAULT_USER.parseAndSetParameter(value, local, reader); break; case ALLOWED_USERS: LocalAuthenticationResourceDefinition.ALLOWED_USERS.parseAndSetParameter(value, local, reader); break; default: { throw unexpectedAttribute(reader, i); } } } } // All attributes are optional. requireNoContent(reader); } private static void parsePropertiesAuthentication_1_0(final XMLExtendedStreamReader reader, final ModelNode realmAddress, final List list) throws XMLStreamException { ModelNode addr = realmAddress.clone().add(AUTHENTICATION, PROPERTIES); ModelNode properties = Util.getEmptyOperation(ADD, addr); list.add(properties); String path = null; final int count = reader.getAttributeCount(); for (int i = 0; i < count; i++) { final String value = reader.getAttributeValue(i); if (!isNoNamespaceAttribute(reader, i)) { throw unexpectedAttribute(reader, i); } else { final Attribute attribute = Attribute.forName(reader.getAttributeLocalName(i)); switch (attribute) { case PATH: path = value; PropertiesAuthenticationResourceDefinition.PATH.parseAndSetParameter(value, properties, reader); break; case RELATIVE_TO: { PropertiesAuthenticationResourceDefinition.RELATIVE_TO.parseAndSetParameter(value, properties, reader); break; } default: { throw unexpectedAttribute(reader, i); } } } } if (path == null) throw missingRequired(reader, Collections.singleton(Attribute.PATH)); requireNoContent(reader); // This property was not supported in version 1.0 of the schema, however it is set to true here to ensure // the default behaviour if a document based on 1.0 of the schema is parsed, 1.1 now defaults this to false. properties.get(PLAIN_TEXT).set(true); } private static void parsePropertiesAuthentication_1_1(final XMLExtendedStreamReader reader, final ModelNode realmAddress, final List list) throws XMLStreamException { ModelNode addr = realmAddress.clone().add(AUTHENTICATION, PROPERTIES); ModelNode properties = Util.getEmptyOperation(ADD, addr); list.add(properties); String path = null; final int count = reader.getAttributeCount(); for (int i = 0; i < count; i++) { final String value = reader.getAttributeValue(i); if (!isNoNamespaceAttribute(reader, i)) { throw unexpectedAttribute(reader, i); } else { final Attribute attribute = Attribute.forName(reader.getAttributeLocalName(i)); switch (attribute) { case PATH: path = value; PropertiesAuthenticationResourceDefinition.PATH.parseAndSetParameter(value, properties, reader); break; case RELATIVE_TO: { PropertiesAuthenticationResourceDefinition.RELATIVE_TO.parseAndSetParameter(value, properties, reader); break; } case PLAIN_TEXT: { PropertiesAuthenticationResourceDefinition.PLAIN_TEXT.parseAndSetParameter(value, properties, reader); break; } default: { throw unexpectedAttribute(reader, i); } } } } if (path == null) throw missingRequired(reader, Collections.singleton(Attribute.PATH)); requireNoContent(reader); } // The users element defines users within the domain model, it is a simple authentication for some out of the box users. private static void parseUsersAuthentication(final XMLExtendedStreamReader reader, final Namespace expectedNs, final ModelNode realmAddress, final List list) throws XMLStreamException { final ModelNode usersAddress = realmAddress.clone().add(AUTHENTICATION, USERS); list.add(Util.getEmptyOperation(ADD, usersAddress)); while (reader.hasNext() && reader.nextTag() != END_ELEMENT) { requireNamespace(reader, expectedNs); final Element element = Element.forName(reader.getLocalName()); switch (element) { case USER: { parseUser(reader, expectedNs, usersAddress, list); break; } default: { throw unexpectedElement(reader); } } } } private static void parseUser(final XMLExtendedStreamReader reader, final Namespace expectedNs, final ModelNode usersAddress, final List list) throws XMLStreamException { requireSingleAttribute(reader, Attribute.USERNAME.getLocalName()); // After double checking the name of the only attribute we can retrieve it. final String userName = reader.getAttributeValue(0); final ModelNode userAddress = usersAddress.clone().add(USER, userName); ModelNode user = Util.getEmptyOperation(ADD, userAddress); list.add(user); String password = null; while (reader.hasNext() && reader.nextTag() != END_ELEMENT) { requireNamespace(reader, expectedNs); final Element element = Element.forName(reader.getLocalName()); switch (element) { case PASSWORD: { password = reader.getElementText(); UserResourceDefinition.PASSWORD.parseAndSetParameter(password, user, reader); break; } default: { throw unexpectedElement(reader); } } } if (password == null) { throw missingRequiredElement(reader, EnumSet.of(Element.PASSWORD)); } } private static void parseTruststore(final XMLExtendedStreamReader reader, final Namespace expectedNs, final ModelNode realmAddress, final List list) throws XMLStreamException { final ModelNode op = new ModelNode(); op.get(OP).set(ADD); op.get(OP_ADDR).set(realmAddress).add(ModelDescriptionConstants.AUTHENTICATION, ModelDescriptionConstants.TRUSTSTORE); switch (expectedNs) { case DOMAIN_1_0: case DOMAIN_1_1: case DOMAIN_1_2: parseKeystore_1_0(reader, op); break; default: parseKeystore_1_3(reader, op, true); } list.add(op); } private static void parseAuthorization_1_1(final XMLExtendedStreamReader reader, final Namespace expectedNs, final ModelNode realmAdd, final List list) throws XMLStreamException { ModelNode realmAddress = realmAdd.get(OP_ADDR); boolean authzFound = false; while (reader.hasNext() && reader.nextTag() != END_ELEMENT) { requireNamespace(reader, expectedNs); final Element element = Element.forName(reader.getLocalName()); // Only a single element within the authorization element is currently supported. if (authzFound) { throw unexpectedElement(reader); } switch (element) { case PROPERTIES: { parsePropertiesAuthorization(reader, realmAddress, list); authzFound = true; break; } default: { throw unexpectedElement(reader); } } } } private static void parseAuthorization_1_3(final XMLExtendedStreamReader reader, final Namespace expectedNs, final ModelNode realmAdd, final List list) throws XMLStreamException { ModelNode realmAddress = realmAdd.get(OP_ADDR); boolean authzFound = false; while (reader.hasNext() && reader.nextTag() != END_ELEMENT) { requireNamespace(reader, expectedNs); final Element element = Element.forName(reader.getLocalName()); // Only a single element within the authorization element is currently supported. if (authzFound) { throw unexpectedElement(reader); } switch (element) { case PROPERTIES: { parsePropertiesAuthorization(reader, realmAddress, list); authzFound = true; break; } case PLUG_IN: { ModelNode parentAddress = realmAddress.clone().add(AUTHORIZATION); parsePlugIn_Authorization(reader, expectedNs, parentAddress, list); authzFound = true; break; } default: { throw unexpectedElement(reader); } } } } private static void parseAuthorization_2_0(final XMLExtendedStreamReader reader, final Namespace expectedNs, final ModelNode realmAdd, final List list) throws XMLStreamException { ModelNode realmAddress = realmAdd.get(OP_ADDR); final int count = reader.getAttributeCount(); for (int i = 0; i < count; i++) { final String value = reader.getAttributeValue(i); if (!isNoNamespaceAttribute(reader, i)) { throw unexpectedAttribute(reader, i); } else { final Attribute attribute = Attribute.forName(reader.getAttributeLocalName(i)); switch (attribute) { case MAP_GROUPS_TO_ROLES: SecurityRealmResourceDefinition.MAP_GROUPS_TO_ROLES.parseAndSetParameter(value, realmAdd, reader); break; default: { throw unexpectedAttribute(reader, i); } } } } boolean authzFound = false; while (reader.hasNext() && reader.nextTag() != END_ELEMENT) { requireNamespace(reader, expectedNs); final Element element = Element.forName(reader.getLocalName()); // Only a single element within the authorization element is currently supported. if (authzFound) { throw unexpectedElement(reader); } switch (element) { case PROPERTIES: { parsePropertiesAuthorization(reader, realmAddress, list); authzFound = true; break; } case PLUG_IN: { ModelNode parentAddress = realmAddress.clone().add(AUTHORIZATION); parsePlugIn_Authorization(reader, expectedNs, parentAddress, list); authzFound = true; break; } default: { throw unexpectedElement(reader); } } } } private static void parsePropertiesAuthorization(final XMLExtendedStreamReader reader, final ModelNode realmAddress, final List list) throws XMLStreamException { ModelNode addr = realmAddress.clone().add(AUTHORIZATION, PROPERTIES); ModelNode properties = Util.getEmptyOperation(ADD, addr); list.add(properties); String path = null; final int count = reader.getAttributeCount(); for (int i = 0; i < count; i++) { final String value = reader.getAttributeValue(i); if (!isNoNamespaceAttribute(reader, i)) { throw unexpectedAttribute(reader, i); } else { final Attribute attribute = Attribute.forName(reader.getAttributeLocalName(i)); switch (attribute) { case PATH: path = value; PropertiesAuthorizationResourceDefinition.PATH.parseAndSetParameter(value, properties, reader); break; case RELATIVE_TO: { PropertiesAuthorizationResourceDefinition.RELATIVE_TO.parseAndSetParameter(value, properties, reader); break; } default: { throw unexpectedAttribute(reader, i); } } } } if (path == null) throw missingRequired(reader, Collections.singleton(Attribute.PATH)); requireNoContent(reader); } private static void parsePlugIn_Authentication(final XMLExtendedStreamReader reader, final Namespace expectedNs, final ModelNode parentAddress, final List list) throws XMLStreamException { ModelNode addr = parentAddress.clone().add(PLUG_IN); ModelNode plugIn = Util.getEmptyOperation(ADD, addr); list.add(plugIn); boolean nameFound = false; final int count = reader.getAttributeCount(); for (int i = 0; i < count; i++) { final String value = reader.getAttributeValue(i); if (!isNoNamespaceAttribute(reader, i)) { throw unexpectedAttribute(reader, i); } else { final Attribute attribute = Attribute.forName(reader.getAttributeLocalName(i)); switch (attribute) { case NAME: PlugInAuthenticationResourceDefinition.NAME.parseAndSetParameter(value, plugIn, reader); nameFound = true; break; case MECHANISM: { PlugInAuthenticationResourceDefinition.MECHANISM.parseAndSetParameter(value, plugIn, reader); break; } default: { throw unexpectedAttribute(reader, i); } } } } if (nameFound == false) { throw missingRequired(reader, Collections.singleton(Attribute.NAME)); } while (reader.hasNext() && reader.nextTag() != END_ELEMENT) { requireNamespace(reader, expectedNs); final Element element = Element.forName(reader.getLocalName()); switch (element) { case PROPERTIES: { while (reader.hasNext() && reader.nextTag() != END_ELEMENT) { requireNamespace(reader, expectedNs); final Element propertyElement = Element.forName(reader.getLocalName()); switch (propertyElement) { case PROPERTY: parseProperty(reader, addr, list); break; default: throw unexpectedElement(reader); } } break; } default: { throw unexpectedElement(reader); } } } } private static void parsePlugIn_Authorization(final XMLExtendedStreamReader reader, final Namespace expectedNs, final ModelNode parentAddress, final List list) throws XMLStreamException { ModelNode addr = parentAddress.clone().add(PLUG_IN); ModelNode plugIn = Util.getEmptyOperation(ADD, addr); list.add(plugIn); requireSingleAttribute(reader, Attribute.NAME.getLocalName()); // After double checking the name of the only attribute we can retrieve it. final String plugInName = reader.getAttributeValue(0); plugIn.get(NAME).set(plugInName); while (reader.hasNext() && reader.nextTag() != END_ELEMENT) { requireNamespace(reader, expectedNs); final Element element = Element.forName(reader.getLocalName()); switch (element) { case PROPERTIES: { while (reader.hasNext() && reader.nextTag() != END_ELEMENT) { requireNamespace(reader, expectedNs); final Element propertyElement = Element.forName(reader.getLocalName()); switch (propertyElement) { case PROPERTY: parseProperty(reader, addr, list); break; default: throw unexpectedElement(reader); } } break; } default: { throw unexpectedElement(reader); } } } } private static void parseProperty(final XMLExtendedStreamReader reader, final ModelNode parentAddress, final List list) throws XMLStreamException { final ModelNode add = new ModelNode(); add.get(OP).set(ADD); list.add(add); boolean addressFound = false; final int count = reader.getAttributeCount(); for (int i = 0; i < count; i++) { final String value = reader.getAttributeValue(i); if (!isNoNamespaceAttribute(reader, i)) { throw unexpectedAttribute(reader, i); } else { final Attribute attribute = Attribute.forName(reader.getAttributeLocalName(i)); switch (attribute) { case NAME: add.get(OP_ADDR).set(parentAddress).add(PROPERTY, value); addressFound = true; break; case VALUE: { PropertyResourceDefinition.VALUE.parseAndSetParameter(value, add, reader); break; } default: { throw unexpectedAttribute(reader, i); } } } } if (addressFound == false) throw missingRequired(reader, Collections.singleton(Attribute.NAME)); requireNoContent(reader); } public static void parseAccessControlRoleMapping(final XMLExtendedStreamReader reader, final ModelNode accContAddr, final Namespace expectedNs, final List list) throws XMLStreamException { int count = reader.getAttributeCount(); for (int i = 0; i < count; i++) { final String value = reader.getAttributeValue(i); if (!isNoNamespaceAttribute(reader, i)) { throw unexpectedAttribute(reader, i); } else { final Attribute attribute = Attribute.forName(reader.getAttributeLocalName(i)); switch (attribute) { case USE_REALM_ROLES: { ModelNode valNode = AccessAuthorizationResourceDefinition.USE_REALM_ROLES.parse(value, reader); list.add(Util.getWriteAttributeOperation(accContAddr, AccessAuthorizationResourceDefinition.USE_REALM_ROLES.getName(), valNode)); break; } default: { throw unexpectedAttribute(reader, i); } } } } while (reader.hasNext() && reader.nextTag() != END_ELEMENT) { requireNamespace(reader, expectedNs); final Element element = Element.forName(reader.getLocalName()); if (element == Element.ROLE) { parseRole(reader, accContAddr, expectedNs, list); } else { throw unexpectedElement(reader); } } } private static void parseRole(final XMLExtendedStreamReader reader, final ModelNode address, final Namespace expectedNs, final List list) throws XMLStreamException { ParseUtils.requireSingleAttribute(reader, NAME); String name = reader.getAttributeValue(0); ModelNode addr = address.clone().add(ROLE_MAPPING, name); final ModelNode add = new ModelNode(); add.get(OP_ADDR).set(addr); add.get(OP).set(ADD); list.add(add); while (reader.hasNext() && reader.nextTag() != END_ELEMENT) { requireNamespace(reader, expectedNs); final Element element = Element.forName(reader.getLocalName()); switch (element) { case INCLUDE: { ModelNode includeAddr = addr.clone().add(INCLUDE); parseIncludeExclude(reader, includeAddr, expectedNs, list); break; } case EXCLUDE: { ModelNode excludeAddr = addr.clone().add(EXCLUDE); parseIncludeExclude(reader, excludeAddr, expectedNs, list); break; } default: { throw unexpectedElement(reader); } } } } private static void parseIncludeExclude(final XMLExtendedStreamReader reader, final ModelNode address, final Namespace expectedNs, final List list) throws XMLStreamException { ParseUtils.requireNoAttributes(reader); while (reader.hasNext() && reader.nextTag() != END_ELEMENT) { requireNamespace(reader, expectedNs); final Element element = Element.forName(reader.getLocalName()); switch (element) { case GROUP: { parsePrincipal(reader, address, GROUP, expectedNs, list); break; } case USER: { parsePrincipal(reader, address, USER, expectedNs, list); break; } default: { throw unexpectedElement(reader); } } } } private static void parsePrincipal(final XMLExtendedStreamReader reader, final ModelNode address, final String type, final Namespace expectedNs, final List list) throws XMLStreamException { String realm = null; String name = null; ModelNode addOp = new ModelNode(); addOp.get(OP).set(ADD); addOp.get(TYPE).set(type); int count = reader.getAttributeCount(); for (int i = 0; i < count; i++) { final String value = reader.getAttributeValue(i); if (!isNoNamespaceAttribute(reader, i)) { throw unexpectedAttribute(reader, i); } else { final Attribute attribute = Attribute.forName(reader.getAttributeLocalName(i)); switch (attribute) { case NAME: { name = value; PrincipalResourceDefinition.NAME.parseAndSetParameter(value, addOp, reader); break; } case REALM: { realm = value; PrincipalResourceDefinition.REALM.parseAndSetParameter(value, addOp, reader); break; } default: { throw unexpectedAttribute(reader, i); } } } } if (name == null) { throw ParseUtils.missingRequired(reader, Collections.singleton(Attribute.NAME)); } String addrValue = type + "-" + name + (realm != null ? "@" + realm : ""); ModelNode addAddr = address.clone().add(addrValue); addOp.get(OP_ADDR).set(addAddr); list.add(addOp); ParseUtils.requireNoContent(reader); } public static void parseAccessControlConstraints(final XMLExtendedStreamReader reader, final ModelNode accAuthzAddr, final Namespace expectedNs, final List list) throws XMLStreamException { ParseUtils.requireNoAttributes(reader); while (reader.hasNext() && reader.nextTag() != END_ELEMENT) { requireNamespace(reader, expectedNs); final Element element = Element.forName(reader.getLocalName()); switch (element) { case VAULT_EXPRESSION_SENSITIVITY: { ModelNode vaultAddr = accAuthzAddr.clone().add(CONSTRAINT, VAULT_EXPRESSION); parseClassificationType(reader, vaultAddr, expectedNs, list, true); break; } case SENSITIVE_CLASSIFICATIONS: { ModelNode sensAddr = accAuthzAddr.clone().add(CONSTRAINT, SENSITIVITY_CLASSIFICATION); parseSensitiveClassifications(reader, sensAddr, expectedNs, list); break; } case APPLICATION_CLASSIFICATIONS: { ModelNode applAddr = accAuthzAddr.clone().add(CONSTRAINT, APPLICATION_CLASSIFICATION); parseApplicationClassifications(reader, applAddr, expectedNs, list); break; } default: { throw unexpectedElement(reader); } } } } private static void parseSensitiveClassifications(final XMLExtendedStreamReader reader, final ModelNode address, final Namespace expectedNs, final List list) throws XMLStreamException { ParseUtils.requireNoAttributes(reader); while (reader.hasNext() && reader.nextTag() != END_ELEMENT) { requireNamespace(reader, expectedNs); final Element element = Element.forName(reader.getLocalName()); switch (element) { case SENSITIVE_CLASSIFICATION: { parseSensitivityClassification(reader, address, expectedNs, list); break; } default: { throw unexpectedElement(reader); } } } } private static void parseSensitivityClassification(final XMLExtendedStreamReader reader, final ModelNode address, final Namespace expectedNs, final List list) throws XMLStreamException { parseClassificationType(reader, address, expectedNs, list, false); // String name = null; // final int count = reader.getAttributeCount(); // for (int i = 0; i < count; i++) { // final String value = reader.getAttributeValue(i); // if (!isNoNamespaceAttribute(reader, i)) { // throw unexpectedAttribute(reader, i); // } else { // final Attribute attribute = Attribute.forName(reader.getAttributeLocalName(i)); // switch (attribute) { // case NAME: // name = value; // break; // default: { // throw unexpectedAttribute(reader, i); // } // } // } // } // // if (name == null) { // throw ParseUtils.missingRequired(reader, Collections.singleton(NAME)); // } // // ModelNode newAddress = address.clone().add(SensitivityClassificationTypeResourceDefinition.PATH_ELEMENT.getKey(), name); // while (reader.hasNext() && reader.nextTag() != END_ELEMENT) { // requireNamespace(reader, expectedNs); // final Element element = Element.forName(reader.getLocalName()); // String name = null; // // switch (element) { // case TYPE: { // parseClassificationType(reader, newAddress, expectedNs, list, false); // break; // } // default: { // throw unexpectedElement(reader); // } // } // } } private static void parseClassificationType(final XMLExtendedStreamReader reader, final ModelNode address, final Namespace expectedNs, final List list, boolean vault) throws XMLStreamException { final int count = reader.getAttributeCount(); String name = null; String type = null; Map values = new HashMap(); for (int i = 0; i < count; i++) { final String value = reader.getAttributeValue(i); if (!isNoNamespaceAttribute(reader, i)) { throw unexpectedAttribute(reader, i); } else { final Attribute attribute = Attribute.forName(reader.getAttributeLocalName(i)); switch (attribute) { case NAME: { name = value; break; } case TYPE: { type = value; break; } case REQUIRES_ADDRESSABLE: { values.put(SensitivityResourceDefinition.CONFIGURED_REQUIRES_ADDRESSABLE.getName(), SensitivityResourceDefinition.CONFIGURED_REQUIRES_ADDRESSABLE.parse(value, reader)); break; } case REQUIRES_READ: { values.put(SensitivityResourceDefinition.CONFIGURED_REQUIRES_READ.getName(), SensitivityResourceDefinition.CONFIGURED_REQUIRES_READ.parse(value, reader)); break; } case REQUIRES_WRITE: { values.put(SensitivityResourceDefinition.CONFIGURED_REQUIRES_WRITE.getName(), SensitivityResourceDefinition.CONFIGURED_REQUIRES_WRITE.parse(value, reader)); break; } default: { throw unexpectedAttribute(reader, i); } } } } if (name == null && !vault) { throw ParseUtils.missingRequired(reader, Collections.singleton(Attribute.NAME)); } if (type == null && !vault) { throw ParseUtils.missingRequired(reader, Collections.singleton(Attribute.TYPE)); } final ModelNode newAddress = vault ? address : address.clone() .add(SensitivityClassificationTypeResourceDefinition.PATH_ELEMENT.getKey(), type) .add(SensitivityResourceDefinition.PATH_ELEMENT.getKey(), name); for (Map.Entry entry : values.entrySet()) { list.add(Util.getWriteAttributeOperation(newAddress, entry.getKey(), entry.getValue())); } ParseUtils.requireNoContent(reader); } private static void parseApplicationClassifications(final XMLExtendedStreamReader reader, final ModelNode address, final Namespace expectedNs, final List list) throws XMLStreamException { ParseUtils.requireNoAttributes(reader); while (reader.hasNext() && reader.nextTag() != END_ELEMENT) { requireNamespace(reader, expectedNs); final Element element = Element.forName(reader.getLocalName()); switch (element) { case APPLICATION_CLASSIFICATION: { parseApplicationClassification(reader, address, expectedNs, list); break; } default: { throw unexpectedElement(reader); } } } } private static void parseApplicationClassification(final XMLExtendedStreamReader reader, final ModelNode address, final Namespace expectedNs, final List list) throws XMLStreamException { String name = null; String type = null; Boolean applicationValue = null; final int count = reader.getAttributeCount(); for (int i = 0; i < count; i++) { final String value = reader.getAttributeValue(i); if (!isNoNamespaceAttribute(reader, i)) { throw unexpectedAttribute(reader, i); } else { final Attribute attribute = Attribute.forName(reader.getAttributeLocalName(i)); switch (attribute) { case NAME: name = value; break; case TYPE: type = value; break; case APPLICATION: applicationValue = Boolean.valueOf(value); break; default: { throw unexpectedAttribute(reader, i); } } } } if (name == null) { throw ParseUtils.missingRequired(reader, Collections.singleton(NAME)); } if (type == null) { throw ParseUtils.missingRequired(reader, Collections.singleton(Attribute.TYPE)); } if (applicationValue == null) { throw ParseUtils.missingRequired(reader, Collections.singleton(Attribute.APPLICATION)); } ModelNode newAddress = address.clone() .add(ApplicationClassificationTypeResourceDefinition.PATH_ELEMENT.getKey(), type) .add(ApplicationClassificationConfigResourceDefinition.PATH_ELEMENT.getKey(), name); list.add(Util.getWriteAttributeOperation(newAddress, ApplicationClassificationConfigResourceDefinition.CONFIGURED_APPLICATION.getName(), applicationValue.toString())); ParseUtils.requireNoContent(reader); } public static void parseServerGroupScopedRoles(final XMLExtendedStreamReader reader, final ModelNode address, final Namespace expectedNs, final List list) throws XMLStreamException { ParseUtils.requireNoAttributes(reader); String scopedRoleType = ServerGroupScopedRoleResourceDefinition.PATH_ELEMENT.getKey(); while (reader.hasNext() && reader.nextTag() != END_ELEMENT) { requireNamespace(reader, expectedNs); final Element element = Element.forName(reader.getLocalName()); switch (element) { case ROLE: { parseScopedRole(reader, address, expectedNs, list, scopedRoleType, Element.SERVER_GROUP, ServerGroupScopedRoleResourceDefinition.BASE_ROLE, ServerGroupScopedRoleResourceDefinition.SERVER_GROUPS, true); break; } default: { throw unexpectedElement(reader); } } } } public static void parseHostScopedRoles(final XMLExtendedStreamReader reader, final ModelNode address, final Namespace expectedNs, final List list) throws XMLStreamException { ParseUtils.requireNoAttributes(reader); String scopedRoleType = HostScopedRolesResourceDefinition.PATH_ELEMENT.getKey(); while (reader.hasNext() && reader.nextTag() != END_ELEMENT) { requireNamespace(reader, expectedNs); final Element element = Element.forName(reader.getLocalName()); switch (element) { case ROLE: { parseScopedRole(reader, address, expectedNs, list, scopedRoleType, Element.HOST, HostScopedRolesResourceDefinition.BASE_ROLE, HostScopedRolesResourceDefinition.HOSTS, false); break; } default: { throw unexpectedElement(reader); } } } } private static void parseScopedRole(XMLExtendedStreamReader reader, ModelNode address, Namespace expectedNs, List ops, String scopedRoleType, final Element listElement, SimpleAttributeDefinition baseRoleDefinition, ListAttributeDefinition listDefinition, boolean requireChildren) throws XMLStreamException { final ModelNode addOp = Util.createAddOperation(); ops.add(addOp); final ModelNode ourAddress = addOp.get(OP_ADDR).set(address); final Set required = EnumSet.of(Attribute.NAME, Attribute.BASE_ROLE); final int count = reader.getAttributeCount(); for (int i = 0; i < count; i++) { final String value = reader.getAttributeValue(i); if (!isNoNamespaceAttribute(reader, i)) { throw unexpectedAttribute(reader, i); } final Attribute attribute = Attribute.forName(reader.getAttributeLocalName(i)); required.remove(attribute); switch (attribute) { case NAME: ourAddress.add(scopedRoleType, value); break; case BASE_ROLE: baseRoleDefinition.parseAndSetParameter(value, addOp, reader); break; default: { throw unexpectedAttribute(reader, i); } } } if (!required.isEmpty()) { throw missingRequired(reader, required); } boolean missingChildren = requireChildren; while (reader.hasNext() && reader.nextTag() != END_ELEMENT) { boolean named = false; requireNamespace(reader, expectedNs); final Element element = Element.forName(reader.getLocalName()); if (element == listElement) { missingChildren = false; final int groupCount = reader.getAttributeCount(); for (int i = 0; i < groupCount; i++) { final String value = reader.getAttributeValue(i); if (!isNoNamespaceAttribute(reader, i)) { throw unexpectedAttribute(reader, i); } final Attribute attribute = Attribute.forName(reader.getAttributeLocalName(i)); required.remove(attribute); if (attribute == Attribute.NAME) { named = true; listDefinition.parseAndAddParameterElement(value, addOp, reader); } else { throw unexpectedAttribute(reader, i); } } } else { throw unexpectedElement(reader); } if (!named) { throw missingRequired(reader, EnumSet.of(Attribute.NAME)); } requireNoContent(reader); } if (missingChildren) { throw missingRequired(reader, EnumSet.of(listElement)); } } public void writeManagement(final XMLExtendedStreamWriter writer, final ModelNode management, boolean allowInterfaces) throws XMLStreamException { boolean hasSecurityRealm = management.hasDefined(SECURITY_REALM); boolean hasConnection = management.hasDefined(LDAP_CONNECTION); boolean hasInterface = allowInterfaces && management.hasDefined(MANAGEMENT_INTERFACE); // TODO - These checks are going to become a source of bugs in certain cases - what we really need is a way to allow writing to continue and // if an element is empty by the time it is closed then undo the write of that element. ModelNode accessAuthorization = management.hasDefined(ACCESS) ? management.get(ACCESS, AUTHORIZATION) : null; boolean accessAuthorizationDefined = accessAuthorization != null && accessAuthorization.isDefined(); boolean hasServerGroupRoles = accessAuthorizationDefined && accessAuthorization.hasDefined(SERVER_GROUP_SCOPED_ROLE); boolean hasHostRoles = accessAuthorizationDefined && (accessAuthorization.hasDefined(HOST_SCOPED_ROLE) || accessAuthorization.hasDefined(HOST_SCOPED_ROLES)); boolean hasRoleMapping = accessAuthorizationDefined && accessAuthorization.hasDefined(ROLE_MAPPING); Map>> configuredAccessConstraints = getConfiguredAccessConstraints(accessAuthorization); boolean hasUseRealmRoles = accessAuthorizationDefined && accessAuthorization.hasDefined(AccessAuthorizationResourceDefinition.USE_REALM_ROLES.getName()); boolean hasProvider = accessAuthorizationDefined && accessAuthorization.hasDefined(AccessAuthorizationResourceDefinition.PROVIDER.getName()); ModelNode auditLog = management.hasDefined(ACCESS) ? management.get(ACCESS, AUDIT) : new ModelNode(); if (!hasSecurityRealm && !hasConnection && !hasInterface && !hasServerGroupRoles && !hasHostRoles && !hasRoleMapping && configuredAccessConstraints.size() == 0 && !hasProvider && !hasUseRealmRoles && !auditLog.isDefined()) { return; } writer.writeStartElement(Element.MANAGEMENT.getLocalName()); if (hasSecurityRealm) { writeSecurityRealm(writer, management); } if (hasConnection) { writeOutboundConnections(writer, management); } if (auditLog.isDefined()) { delegate.writeAuditLog(writer, auditLog); } if (allowInterfaces && hasInterface) { writeManagementInterfaces(writer, management); } if (accessAuthorizationDefined) { delegate.writeAccessControl(writer, accessAuthorization); } writer.writeEndElement(); } private static void writeAccessControl(final XMLExtendedStreamWriter writer, final ModelNode accessAuthorization) throws XMLStreamException { if (accessAuthorization == null || accessAuthorization.isDefined()==false) { return; // All subsequent checks are based on this being defined. } boolean hasServerGroupRoles = accessAuthorization.hasDefined(SERVER_GROUP_SCOPED_ROLE); boolean hasHostRoles = accessAuthorization.hasDefined(HOST_SCOPED_ROLE) || accessAuthorization.hasDefined(HOST_SCOPED_ROLES); boolean hasRoleMapping = accessAuthorization.hasDefined(ROLE_MAPPING); Map>> configuredAccessConstraints = getConfiguredAccessConstraints(accessAuthorization); boolean hasUseRealmRoles = accessAuthorization.hasDefined(AccessAuthorizationResourceDefinition.USE_REALM_ROLES.getName()); boolean hasProvider = accessAuthorization.hasDefined(AccessAuthorizationResourceDefinition.PROVIDER.getName()); if (!hasProvider && !hasUseRealmRoles && !hasServerGroupRoles && !hasHostRoles && !hasRoleMapping && configuredAccessConstraints.size() == 0) { return; } writer.writeStartElement(Element.ACCESS_CONTROL.getLocalName()); AccessAuthorizationResourceDefinition.PROVIDER.marshallAsAttribute(accessAuthorization, writer); if (hasServerGroupRoles) { ModelNode serverGroupRoles = accessAuthorization.get(SERVER_GROUP_SCOPED_ROLE); if (serverGroupRoles.asInt() > 0) { writeServerGroupScopedRoles(writer, serverGroupRoles); } } if (hasHostRoles) { ModelNode serverGroupRoles = accessAuthorization.get(HOST_SCOPED_ROLE); if (serverGroupRoles.asInt() > 0) { writeHostScopedRoles(writer, serverGroupRoles); } } if (hasUseRealmRoles || hasRoleMapping) { writeRoleMapping(writer, accessAuthorization); } if (configuredAccessConstraints.size() > 0) { writeAccessConstraints(writer, accessAuthorization, configuredAccessConstraints); } writer.writeEndElement(); } private void writeSecurityRealm(XMLExtendedStreamWriter writer, ModelNode management) throws XMLStreamException { ModelNode securityRealms = management.get(SECURITY_REALM); writer.writeStartElement(Element.SECURITY_REALMS.getLocalName()); for (Property variable : securityRealms.asPropertyList()) { writer.writeStartElement(Element.SECURITY_REALM.getLocalName()); writeAttribute(writer, Attribute.NAME, variable.getName()); ModelNode realm = variable.getValue(); if (realm.hasDefined(PLUG_IN)) { writePlugIns(writer, realm.get(PLUG_IN)); } if (realm.hasDefined(SERVER_IDENTITY)) { writeServerIdentities(writer, realm); } if (realm.hasDefined(AUTHENTICATION)) { writeAuthentication(writer, realm); } if (realm.hasDefined(AUTHORIZATION)) { writeAuthorization(writer, realm); } writer.writeEndElement(); } writer.writeEndElement(); } private void writePlugIns(XMLExtendedStreamWriter writer, ModelNode plugIns) throws XMLStreamException { writer.writeStartElement(Element.PLUG_INS.getLocalName()); for (Property variable : plugIns.asPropertyList()) { writer.writeEmptyElement(Element.PLUG_IN.getLocalName()); writer.writeAttribute(Attribute.MODULE.getLocalName(), variable.getName()); } writer.writeEndElement(); } private void writeServerIdentities(XMLExtendedStreamWriter writer, ModelNode realm) throws XMLStreamException { writer.writeStartElement(Element.SERVER_IDENTITIES.getLocalName()); ModelNode serverIdentities = realm.get(SERVER_IDENTITY); if (serverIdentities.hasDefined(SSL)) { writer.writeStartElement(Element.SSL.getLocalName()); ModelNode ssl = serverIdentities.get(SSL); SSLServerIdentityResourceDefinition.PROTOCOL.marshallAsAttribute(ssl, writer); if (ssl.hasDefined(KeystoreAttributes.KEYSTORE_PATH.getName())) { writer.writeEmptyElement(Element.KEYSTORE.getLocalName()); KeystoreAttributes.KEYSTORE_PATH.marshallAsAttribute(ssl, writer); KeystoreAttributes.KEYSTORE_RELATIVE_TO.marshallAsAttribute(ssl, writer); KeystoreAttributes.KEYSTORE_PASSWORD.marshallAsAttribute(ssl, writer); KeystoreAttributes.ALIAS.marshallAsAttribute(ssl, writer); KeystoreAttributes.KEY_PASSWORD.marshallAsAttribute(ssl, writer); } writer.writeEndElement(); } if (serverIdentities.hasDefined(SECRET)) { ModelNode secret = serverIdentities.get(SECRET); writer.writeEmptyElement(Element.SECRET.getLocalName()); SecretServerIdentityResourceDefinition.VALUE.marshallAsAttribute(secret, writer); } writer.writeEndElement(); } private void writeAuthentication(XMLExtendedStreamWriter writer, ModelNode realm) throws XMLStreamException { writer.writeStartElement(Element.AUTHENTICATION.getLocalName()); ModelNode authentication = realm.require(AUTHENTICATION); if (authentication.hasDefined(TRUSTSTORE)) { ModelNode truststore = authentication.require(TRUSTSTORE); writer.writeEmptyElement(Element.TRUSTSTORE.getLocalName()); KeystoreAttributes.KEYSTORE_PATH.marshallAsAttribute(truststore, writer); KeystoreAttributes.KEYSTORE_RELATIVE_TO.marshallAsAttribute(truststore, writer); KeystoreAttributes.KEYSTORE_PASSWORD.marshallAsAttribute(truststore, writer); } if (authentication.hasDefined(LOCAL)) { ModelNode local = authentication.require(LOCAL); writer.writeStartElement(Element.LOCAL.getLocalName()); LocalAuthenticationResourceDefinition.DEFAULT_USER.marshallAsAttribute(local, writer); LocalAuthenticationResourceDefinition.ALLOWED_USERS.marshallAsAttribute(local, writer); writer.writeEndElement(); } if (authentication.hasDefined(JAAS)) { ModelNode jaas = authentication.get(JAAS); writer.writeStartElement(Element.JAAS.getLocalName()); JaasAuthenticationResourceDefinition.NAME.marshallAsAttribute(jaas, writer); writer.writeEndElement(); } else if (authentication.hasDefined(LDAP)) { ModelNode userLdap = authentication.get(LDAP); writer.writeStartElement(Element.LDAP.getLocalName()); LdapAuthenticationResourceDefinition.CONNECTION.marshallAsAttribute(userLdap, writer); LdapAuthenticationResourceDefinition.BASE_DN.marshallAsAttribute(userLdap, writer); LdapAuthenticationResourceDefinition.RECURSIVE.marshallAsAttribute(userLdap, writer); LdapAuthenticationResourceDefinition.USER_DN.marshallAsAttribute(userLdap, writer); LdapAuthenticationResourceDefinition.ALLOW_EMPTY_PASSWORDS.marshallAsAttribute(userLdap, writer); if (LdapAuthenticationResourceDefinition.USERNAME_FILTER.isMarshallable(userLdap)) { writer.writeEmptyElement(Element.USERNAME_FILTER.getLocalName()); LdapAuthenticationResourceDefinition.USERNAME_FILTER.marshallAsAttribute(userLdap, writer); } else if (LdapAuthenticationResourceDefinition.ADVANCED_FILTER.isMarshallable(userLdap)) { writer.writeEmptyElement(Element.ADVANCED_FILTER.getLocalName()); LdapAuthenticationResourceDefinition.ADVANCED_FILTER.marshallAsAttribute(userLdap, writer); } writer.writeEndElement(); } else if (authentication.hasDefined(PROPERTIES)) { ModelNode properties = authentication.require(PROPERTIES); writer.writeEmptyElement(Element.PROPERTIES.getLocalName()); PropertiesAuthenticationResourceDefinition.PATH.marshallAsAttribute(properties, writer); PropertiesAuthenticationResourceDefinition.RELATIVE_TO.marshallAsAttribute(properties, writer); PropertiesAuthenticationResourceDefinition.PLAIN_TEXT.marshallAsAttribute(properties, writer); } else if (authentication.hasDefined(USERS)) { ModelNode userDomain = authentication.get(USERS); ModelNode users = userDomain.hasDefined(USER) ? userDomain.require(USER) : new ModelNode().setEmptyObject(); writer.writeStartElement(Element.USERS.getLocalName()); for (Property userProps : users.asPropertyList()) { String userName = userProps.getName(); ModelNode currentUser = userProps.getValue(); writer.writeStartElement(Element.USER.getLocalName()); writer.writeAttribute(Attribute.USERNAME.getLocalName(), userName); UserResourceDefinition.PASSWORD.marshallAsElement(currentUser, writer); writer.writeEndElement(); } writer.writeEndElement(); } else if (authentication.hasDefined(PLUG_IN)) { writePlugIn_Authentication(writer, authentication.get(PLUG_IN)); } writer.writeEndElement(); } private void writePlugIn_Authentication(XMLExtendedStreamWriter writer, ModelNode plugIn) throws XMLStreamException { writer.writeStartElement(Element.PLUG_IN.getLocalName()); AbstractPlugInAuthResourceDefinition.NAME.marshallAsAttribute(plugIn, writer); PlugInAuthenticationResourceDefinition.MECHANISM.marshallAsAttribute(plugIn, writer); if (plugIn.hasDefined(PROPERTY)) { writer.writeStartElement(PROPERTIES); for (Property current : plugIn.get(PROPERTY).asPropertyList()) { writer.writeEmptyElement(PROPERTY); writer.writeAttribute(Attribute.NAME.getLocalName(), current.getName()); PropertyResourceDefinition.VALUE.marshallAsAttribute(current.getValue(), writer); } writer.writeEndElement(); } writer.writeEndElement(); } private void writeAuthorization(XMLExtendedStreamWriter writer, ModelNode realm) throws XMLStreamException { writer.writeStartElement(Element.AUTHORIZATION.getLocalName()); SecurityRealmResourceDefinition.MAP_GROUPS_TO_ROLES.marshallAsAttribute(realm, writer); ModelNode authorization = realm.require(AUTHORIZATION); if (authorization.hasDefined(PROPERTIES)) { ModelNode properties = authorization.require(PROPERTIES); writer.writeEmptyElement(Element.PROPERTIES.getLocalName()); PropertiesAuthorizationResourceDefinition.PATH.marshallAsAttribute(properties, writer); PropertiesAuthorizationResourceDefinition.RELATIVE_TO.marshallAsAttribute(properties, writer); } else if (authorization.hasDefined(PLUG_IN)) { writePlugIn_Authorization(writer, authorization.get(PLUG_IN)); } writer.writeEndElement(); } private void writePlugIn_Authorization(XMLExtendedStreamWriter writer, ModelNode plugIn) throws XMLStreamException { writer.writeStartElement(Element.PLUG_IN.getLocalName()); AbstractPlugInAuthResourceDefinition.NAME.marshallAsAttribute(plugIn, writer); if (plugIn.hasDefined(PROPERTY)) { writer.writeStartElement(PROPERTIES); for (Property current : plugIn.get(PROPERTY).asPropertyList()) { writer.writeEmptyElement(PROPERTY); writer.writeAttribute(Attribute.NAME.getLocalName(), current.getName()); PropertyResourceDefinition.VALUE.marshallAsAttribute(current.getValue(), writer); } writer.writeEndElement(); } writer.writeEndElement(); } private void writeOutboundConnections(XMLExtendedStreamWriter writer, ModelNode management) throws XMLStreamException { writer.writeStartElement(Element.OUTBOUND_CONNECTIONS.getLocalName()); for (Property variable : management.get(LDAP_CONNECTION).asPropertyList()) { ModelNode connection = variable.getValue(); writer.writeEmptyElement(Element.LDAP.getLocalName()); writer.writeAttribute(Attribute.NAME.getLocalName(), variable.getName()); LdapConnectionResourceDefinition.URL.marshallAsAttribute(connection, writer); LdapConnectionResourceDefinition.SEARCH_DN.marshallAsAttribute(connection, writer); LdapConnectionResourceDefinition.SEARCH_CREDENTIAL.marshallAsAttribute(connection, writer); LdapConnectionResourceDefinition.SECURITY_REALM.marshallAsAttribute(connection, writer); LdapConnectionResourceDefinition.INITIAL_CONTEXT_FACTORY.marshallAsAttribute(connection, writer); } writer.writeEndElement(); } private void writeManagementInterfaces(XMLExtendedStreamWriter writer, ModelNode management) throws XMLStreamException { writer.writeStartElement(Element.MANAGEMENT_INTERFACES.getLocalName()); ModelNode managementInterfaces = management.get(MANAGEMENT_INTERFACE); if (managementInterfaces.hasDefined(NATIVE_REMOTING_INTERFACE)) { writer.writeEmptyElement(Element.NATIVE_REMOTING_INTERFACE.getLocalName()); } if (managementInterfaces.hasDefined(NATIVE_INTERFACE)) { delegate.writeNativeManagementProtocol(writer, managementInterfaces.get(NATIVE_INTERFACE)); } if (managementInterfaces.hasDefined(HTTP_INTERFACE)) { delegate.writeHttpManagementProtocol(writer, managementInterfaces.get(HTTP_INTERFACE)); } writer.writeEndElement(); } private static Map>> getConfiguredAccessConstraints(ModelNode accessAuthorization) { Map>> configuredConstraints = new HashMap>>(); if (accessAuthorization != null && accessAuthorization.hasDefined(CONSTRAINT)) { ModelNode constraint = accessAuthorization.get(CONSTRAINT); configuredConstraints.putAll(getVaultConstraints(constraint)); configuredConstraints.putAll(getSensitivityClassificationConstraints(constraint)); configuredConstraints.putAll(getApplicationClassificationConstraints(constraint)); } return configuredConstraints; } private static Map>> getVaultConstraints(final ModelNode constraint) { Map>> configuredConstraints = new HashMap>>(); if (constraint.hasDefined(VAULT_EXPRESSION)) { ModelNode classification = constraint.require(VAULT_EXPRESSION); if (classification.hasDefined(SensitivityResourceDefinition.CONFIGURED_REQUIRES_ADDRESSABLE.getName()) || classification.hasDefined(SensitivityResourceDefinition.CONFIGURED_REQUIRES_WRITE.getName()) || classification.hasDefined(SensitivityResourceDefinition.CONFIGURED_REQUIRES_READ.getName())) { configuredConstraints.put(SensitivityResourceDefinition.VAULT_ELEMENT.getKey(), Collections.> emptyMap()); } } return configuredConstraints; } private static Map>> getSensitivityClassificationConstraints(final ModelNode constraint) { Map>> configuredConstraints = new HashMap>>(); if (constraint.hasDefined(SENSITIVITY_CLASSIFICATION)) { ModelNode sensitivityParent = constraint.require(SENSITIVITY_CLASSIFICATION); if (sensitivityParent.hasDefined(TYPE)) { for (Property typeProperty : sensitivityParent.get(TYPE).asPropertyList()) { if (typeProperty.getValue().hasDefined(CLASSIFICATION)) { for (Property sensitivityProperty : typeProperty.getValue().get(CLASSIFICATION).asPropertyList()) { ModelNode classification = sensitivityProperty.getValue(); if (classification.hasDefined(SensitivityResourceDefinition.CONFIGURED_REQUIRES_ADDRESSABLE.getName()) || classification.hasDefined(SensitivityResourceDefinition.CONFIGURED_REQUIRES_WRITE .getName()) || classification.hasDefined(SensitivityResourceDefinition.CONFIGURED_REQUIRES_READ .getName())) { Map> constraintMap = configuredConstraints.get(SENSITIVITY_CLASSIFICATION); if (constraintMap == null) { constraintMap = new TreeMap>(); configuredConstraints.put(SENSITIVITY_CLASSIFICATION, constraintMap); } Set types = constraintMap.get(typeProperty.getName()); if (types == null) { types = new TreeSet(); constraintMap.put(typeProperty.getName(), types); } types.add(sensitivityProperty.getName()); } } } } } } return configuredConstraints; } private static Map>> getApplicationClassificationConstraints(final ModelNode constraint) { Map>> configuredConstraints = new HashMap>>(); if (constraint.hasDefined(APPLICATION_CLASSIFICATION)) { ModelNode appTypeParent = constraint.require(APPLICATION_CLASSIFICATION); if (appTypeParent.hasDefined(TYPE)) { for (Property typeProperty : appTypeParent.get(TYPE).asPropertyList()) { if (typeProperty.getValue().hasDefined(CLASSIFICATION)) { for (Property applicationProperty : typeProperty.getValue().get(CLASSIFICATION).asPropertyList()) { ModelNode applicationType = applicationProperty.getValue(); if (applicationType.hasDefined(ApplicationClassificationConfigResourceDefinition.CONFIGURED_APPLICATION.getName())) { Map> constraintMap = configuredConstraints.get(APPLICATION_CLASSIFICATION); if (constraintMap == null) { constraintMap = new TreeMap>(); configuredConstraints.put(APPLICATION_CLASSIFICATION, constraintMap); } Set types = constraintMap.get(typeProperty.getName()); if (types == null) { types = new TreeSet(); constraintMap.put(typeProperty.getName(), types); } types.add(applicationProperty.getName()); } } } } } } return configuredConstraints; } private static void writeRoleMapping(XMLExtendedStreamWriter writer, ModelNode accessAuthorization) throws XMLStreamException { writer.writeStartElement(Element.ROLE_MAPPING.getLocalName()); AccessAuthorizationResourceDefinition.USE_REALM_ROLES.marshallAsAttribute(accessAuthorization, writer); if (accessAuthorization.hasDefined(ROLE_MAPPING)) { ModelNode roleMappings = accessAuthorization.get(ROLE_MAPPING); for (Property variable : roleMappings.asPropertyList()) { writer.writeStartElement(Element.ROLE.getLocalName()); writeAttribute(writer, Attribute.NAME, variable.getName()); ModelNode role = variable.getValue(); if (role.hasDefined(INCLUDE)) { writeIncludeExclude(writer, Element.INCLUDE.getLocalName(), role.get(INCLUDE)); } if (role.hasDefined(EXCLUDE)) { writeIncludeExclude(writer, Element.EXCLUDE.getLocalName(), role.get(EXCLUDE)); } writer.writeEndElement(); } } writer.writeEndElement(); } private static void writeIncludeExclude(XMLExtendedStreamWriter writer, String elementName, ModelNode includeExclude) throws XMLStreamException { List list = includeExclude.asPropertyList(); if (list.isEmpty()) { return; } writer.writeStartElement(elementName); for (Property current : list) { // The names where only arbitrary to allow unique referencing. writePrincipal(writer, current.getValue()); } writer.writeEndElement(); } private static void writePrincipal(XMLExtendedStreamWriter writer, ModelNode principal) throws XMLStreamException { String elementName = principal.require(TYPE).asString().equalsIgnoreCase(GROUP) ? Element.GROUP.getLocalName() : Element.USER.getLocalName(); writer.writeStartElement(elementName); PrincipalResourceDefinition.REALM.marshallAsAttribute(principal, writer); PrincipalResourceDefinition.NAME.marshallAsAttribute(principal, writer); writer.writeEndElement(); } private static void writeAccessConstraints(XMLExtendedStreamWriter writer, ModelNode accessAuthorization, Map>> configuredConstraints) throws XMLStreamException { writer.writeStartElement(Element.CONSTRAINTS.getLocalName()); if (configuredConstraints.containsKey(SensitivityResourceDefinition.VAULT_ELEMENT.getKey())){ writer.writeEmptyElement(Element.VAULT_EXPRESSION_SENSITIVITY.getLocalName()); ModelNode model = accessAuthorization.get(SensitivityResourceDefinition.VAULT_ELEMENT.getKey(), SensitivityResourceDefinition.VAULT_ELEMENT.getValue()); SensitivityResourceDefinition.CONFIGURED_REQUIRES_ADDRESSABLE.marshallAsAttribute(model, writer); SensitivityResourceDefinition.CONFIGURED_REQUIRES_READ.marshallAsAttribute(model, writer); SensitivityResourceDefinition.CONFIGURED_REQUIRES_WRITE.marshallAsAttribute(model, writer); } if (configuredConstraints.containsKey(SENSITIVITY_CLASSIFICATION)) { writer.writeStartElement(Element.SENSITIVE_CLASSIFICATIONS.getLocalName()); Map> constraints = configuredConstraints.get(SENSITIVITY_CLASSIFICATION); for (Map.Entry> entry : constraints.entrySet()) { for (String classification : entry.getValue()) { writer.writeEmptyElement(Element.SENSITIVE_CLASSIFICATION.getLocalName()); ModelNode model = accessAuthorization.get(CONSTRAINT, SENSITIVITY_CLASSIFICATION, TYPE, entry.getKey(), CLASSIFICATION, classification); writeAttribute(writer, Attribute.TYPE, entry.getKey()); writeAttribute(writer, Attribute.NAME, classification); SensitivityResourceDefinition.CONFIGURED_REQUIRES_ADDRESSABLE.marshallAsAttribute(model, writer); SensitivityResourceDefinition.CONFIGURED_REQUIRES_READ.marshallAsAttribute(model, writer); SensitivityResourceDefinition.CONFIGURED_REQUIRES_WRITE.marshallAsAttribute(model, writer); } } writer.writeEndElement(); } if (configuredConstraints.containsKey(APPLICATION_CLASSIFICATION)) { writer.writeStartElement(Element.APPLICATION_CLASSIFICATIONS.getLocalName()); Map> constraints = configuredConstraints.get(APPLICATION_CLASSIFICATION); for (Map.Entry> entry : constraints.entrySet()) { for (String classification : entry.getValue()) { writer.writeEmptyElement(Element.APPLICATION_CLASSIFICATION.getLocalName()); ModelNode model = accessAuthorization.get(CONSTRAINT, APPLICATION_CLASSIFICATION, TYPE, entry.getKey(), CLASSIFICATION, classification); writeAttribute(writer, Attribute.TYPE, entry.getKey()); writeAttribute(writer, Attribute.NAME, classification); ApplicationClassificationConfigResourceDefinition.CONFIGURED_APPLICATION.marshallAsAttribute(model, writer); } } writer.writeEndElement(); } writer.writeEndElement(); } private static void writeServerGroupScopedRoles(XMLExtendedStreamWriter writer, ModelNode scopedRoles) throws XMLStreamException { writer.writeStartElement(Element.SERVER_GROUP_SCOPED_ROLES.getLocalName()); for (Property property : scopedRoles.asPropertyList()) { writer.writeStartElement(Element.ROLE.getLocalName()); writer.writeAttribute(Attribute.NAME.getLocalName(), property.getName()); ModelNode value = property.getValue(); ServerGroupScopedRoleResourceDefinition.BASE_ROLE.marshallAsAttribute(value, writer); ServerGroupScopedRoleResourceDefinition.SERVER_GROUPS.marshallAsElement(value, writer); writer.writeEndElement(); } writer.writeEndElement(); } private static void writeHostScopedRoles(XMLExtendedStreamWriter writer, ModelNode scopedRoles) throws XMLStreamException { writer.writeStartElement(Element.HOST_SCOPED_ROLES.getLocalName()); for (Property property : scopedRoles.asPropertyList()) { writer.writeStartElement(Element.ROLE.getLocalName()); writer.writeAttribute(Attribute.NAME.getLocalName(), property.getName()); ModelNode value = property.getValue(); HostScopedRolesResourceDefinition.BASE_ROLE.marshallAsAttribute(value, writer); HostScopedRolesResourceDefinition.HOSTS.marshallAsElement(value, writer); writer.writeEndElement(); } writer.writeEndElement(); } private static void writeAttribute(XMLExtendedStreamWriter writer, Attribute attribute, String value) throws XMLStreamException { writer.writeAttribute(attribute.getLocalName(), value); } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy