// Copyright 2008 Google Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package com.google.enterprise.secmgr.saml;

import static org.opensaml.common.xml.SAMLConstants.SAML20P_NS;

import com.google.common.collect.Lists;

import org.joda.time.DateTime;
import org.opensaml.Configuration;
import org.opensaml.DefaultBootstrap;
import org.opensaml.common.IdentifierGenerator;
import org.opensaml.common.SAMLObject;
import org.opensaml.common.SAMLObjectBuilder;
import org.opensaml.common.SAMLVersion;
import org.opensaml.common.binding.BasicEndpointSelector;
import org.opensaml.common.binding.BasicSAMLMessageContext;
import org.opensaml.common.binding.SAMLMessageContext;
import org.opensaml.common.binding.artifact.BasicSAMLArtifactMap;
import org.opensaml.common.binding.artifact.SAMLArtifactMap;
import org.opensaml.common.binding.artifact.SAMLArtifactMap.SAMLArtifactMapEntry;
import org.opensaml.common.impl.SecureRandomIdentifierGenerator;
import org.opensaml.saml2.core.Action;
import org.opensaml.saml2.core.Artifact;
import org.opensaml.saml2.core.ArtifactResolve;
import org.opensaml.saml2.core.ArtifactResponse;
import org.opensaml.saml2.core.Assertion;
import org.opensaml.saml2.core.Attribute;
import org.opensaml.saml2.core.AttributeStatement;
import org.opensaml.saml2.core.Audience;
import org.opensaml.saml2.core.AudienceRestriction;
import org.opensaml.saml2.core.AuthnContext;
import org.opensaml.saml2.core.AuthnContextClassRef;
import org.opensaml.saml2.core.AuthnRequest;
import org.opensaml.saml2.core.AuthnStatement;
import org.opensaml.saml2.core.AuthzDecisionQuery;
import org.opensaml.saml2.core.AuthzDecisionStatement;
import org.opensaml.saml2.core.Conditions;
import org.opensaml.saml2.core.DecisionTypeEnumeration;
import org.opensaml.saml2.core.Issuer;
import org.opensaml.saml2.core.NameID;
import org.opensaml.saml2.core.RequestAbstractType;
import org.opensaml.saml2.core.Response;
import org.opensaml.saml2.core.Statement;
import org.opensaml.saml2.core.Status;
import org.opensaml.saml2.core.StatusCode;
import org.opensaml.saml2.core.StatusMessage;
import org.opensaml.saml2.core.StatusResponseType;
import org.opensaml.saml2.core.Subject;
import org.opensaml.saml2.core.SubjectConfirmation;
import org.opensaml.saml2.core.SubjectConfirmationData;
import org.opensaml.saml2.metadata.EntityDescriptor;
import org.opensaml.saml2.metadata.KeyDescriptor;
import org.opensaml.saml2.metadata.AssertionConsumerService;
import org.opensaml.saml2.metadata.RoleDescriptor;
import org.opensaml.saml2.metadata.SingleSignOnService;
import org.opensaml.saml2.metadata.provider.FilesystemMetadataProvider;
import org.opensaml.saml2.metadata.provider.MetadataProviderException;
import org.opensaml.saml2.metadata.provider.ObservableMetadataProvider;
import org.opensaml.security.MetadataCredentialResolver;
import org.opensaml.util.storage.MapBasedStorageService;
import org.opensaml.ws.message.MessageContext;
import org.opensaml.ws.message.decoder.MessageDecoder;
import org.opensaml.ws.message.decoder.MessageDecodingException;
import org.opensaml.ws.message.encoder.MessageEncoder;
import org.opensaml.ws.message.encoder.MessageEncodingException;
import org.opensaml.ws.security.SecurityPolicy;
import org.opensaml.ws.security.SecurityPolicyResolver;
import org.opensaml.ws.security.SecurityPolicyRule;
import org.opensaml.ws.security.provider.BasicSecurityPolicy;
import org.opensaml.ws.security.provider.StaticSecurityPolicyResolver;
import org.opensaml.xml.ConfigurationException;
import org.opensaml.xml.XMLObject;
import org.opensaml.xml.XMLObjectBuilderFactory;
import org.opensaml.xml.io.MarshallingException;
import org.opensaml.xml.io.UnmarshallingException;
import org.opensaml.xml.parse.BasicParserPool;
import org.opensaml.xml.security.CriteriaSet;
import org.opensaml.xml.security.SecurityException;
import org.opensaml.xml.security.SecurityHelper;
import org.opensaml.xml.security.credential.Credential;
import org.opensaml.xml.security.credential.CredentialResolver;
import org.opensaml.xml.security.credential.UsageType;
import org.opensaml.xml.security.keyinfo.BasicProviderKeyInfoCredentialResolver;
import org.opensaml.xml.security.keyinfo.KeyInfoCredentialResolver;
import org.opensaml.xml.security.keyinfo.KeyInfoCriteria;
import org.opensaml.xml.security.keyinfo.KeyInfoProvider;
import org.opensaml.xml.security.keyinfo.provider.DSAKeyValueProvider;
import org.opensaml.xml.security.keyinfo.provider.InlineX509DataProvider;
import org.opensaml.xml.security.keyinfo.provider.RSAKeyValueProvider;
import org.opensaml.xml.security.trust.TrustEngine;
import org.opensaml.xml.signature.KeyInfo;
import org.w3c.dom.Element;

import java.io.File;
import java.io.IOException;
import java.security.KeyException;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.util.Arrays;
import java.util.List;
import java.util.logging.Logger;

import javax.annotation.concurrent.Immutable;
import javax.xml.namespace.QName;

/**
 * A collection of utilities to support OpenSAML programming.  The majority of the
 * definitions here are static factory methods for SAML objects.
 * <p>
 * <strong>Notes on security policies and credential resolution:</strong>
 * <p>
 * OpenSAML has a very complicated mechanism for dealing with credentials and trust, of
 * which we use only a small part.  Here are the basic components:
 *
 * <dl>
 * <dt>{@link Credential}
 * <dd>Some information that can be used for signing or encryption.
 *
 * <dt>{@link CredentialResolver}
 * <dd>Selects one or more credentials based on a set of criteria.  We currently use only
 * {@link MetadataCredentialResolver}, which gets credentials from metadata using criteria
 * like entity ID and role.
 *
 * <dt>{@link KeyInfoCredentialResolver}
 * <dd>Extracts one or more credentials from a {@link KeyInfo} element; it's allowed to
 * choose between different credentials based on internal criteria.  We currently use a
 * KeyInfoCredentialResolver that selects only X.509 certificate credentials.
 *
 * <dt>{@link TrustEngine}
 * <dd>Evaluates the trustworthiness and validity of a given object against some given
 * criteria.  It is used as an element of some policy rules.
 *
 * <dt>{@link SecurityPolicy}
 * <dd>A collection of policy rules, evaluated against a message context, that determines
 * if a message is well-formed, valid, and otherwise okay to process.
 *
 * <dt>{@link SecurityPolicyRule}
 * <dd>A component of a security policy, also evaluated against a message context.
 *
 * <dt>{@link SecurityPolicyResolver}
 * <dd>Uses a given set of criteria to select a security policy.  We currently use only a
 * static policy resolver, which always returns the same policy.
 * </dl>
 *
 * <p>
 * The programmer simply attaches a security-policy resolver to the SAML message context
 * and OpenSAML will automatically enforce the security policy as appropriate.
 */
@Immutable
public final class OpenSamlUtil {
  private static final Logger LOGGER = Logger.getLogger(OpenSamlUtil.class.getName());

  /**
   * The human-readable name of the (GSA) service provider.
   */
  public static final String GOOGLE_PROVIDER_NAME = "Google Search Appliance";

  /**
   * The human-readable name of the (Security Manager) service provider.
   */
  public static final String SM_PROVIDER_NAME = "Google Security Manager";

  /**
   * The SAML "bearer" method, normally used in SubjectConfirmation.
   */
  public static final String BEARER_METHOD = "urn:oasis:names:tc:SAML:2.0:cm:bearer";

  public static final String SAML_EXTENSIONS_TAG = "Extensions";

  public static final String GSA_SESSION_ID_TAG = "GsaSessionId";

  public static final String GSA_FLAG_FAST_AUTHZ_TAG = "EnableFastAuthz";
  public static final String GSA_FAST_AUTHZ_FAST = "FAST";
  public static final String GSA_FAST_AUTHZ_ALL = "ALL";

  public static final String GOOGLE_NS_URI = "http://www.google.com/";
  public static final String GOOGLE_NS_PREFIX = "google:";
  public static final String GOOGLE_NS_PREFIX_NOCOLON = "google";
  /*public static final Namespace GOOGLE_NS =
      Namespace.getNamespace(GOOGLE_NS_PREFIX_NOCOLON, GOOGLE_NS_URI);*/

  static {
    try {
      DefaultBootstrap.bootstrap();
    } catch (ConfigurationException e) {
      throw new IllegalStateException(e);
    }

    // This is required in order to patch around missing code in OpenSAML.
    Configuration.registerObjectProvider(
        AttributeValue.DEFAULT_ELEMENT_NAME,
        new AttributeValueBuilder(),
        new AttributeValueMarshaller(),
        new AttributeValueUnmarshaller());
  }

  private static final XMLObjectBuilderFactory objectBuilderFactory =
      Configuration.getBuilderFactory();

  // TODO(cph): @SuppressWarnings is needed because objectBuilderFactory.getBuilder() returns a
  // supertype of the actual type.
  @SuppressWarnings("unchecked")
  private static <T extends SAMLObject> SAMLObjectBuilder<T> makeSamlObjectBuilder(QName name) {
    return (SAMLObjectBuilder<T>) objectBuilderFactory.getBuilder(name);
  }

  private static final SAMLObjectBuilder<Action> actionBuilder =
      makeSamlObjectBuilder(Action.DEFAULT_ELEMENT_NAME);
  private static final SAMLObjectBuilder<Artifact> artifactBuilder =
      makeSamlObjectBuilder(Artifact.DEFAULT_ELEMENT_NAME);
  private static final SAMLObjectBuilder<ArtifactResolve> artifactResolveBuilder =
      makeSamlObjectBuilder(ArtifactResolve.DEFAULT_ELEMENT_NAME);
  private static final SAMLObjectBuilder<ArtifactResponse> artifactResponseBuilder =
      makeSamlObjectBuilder(ArtifactResponse.DEFAULT_ELEMENT_NAME);
  private static final SAMLObjectBuilder<Assertion> assertionBuilder =
      makeSamlObjectBuilder(Assertion.DEFAULT_ELEMENT_NAME);
  private static final SAMLObjectBuilder<AssertionConsumerService> assertionConsumerServiceBuilder =
      makeSamlObjectBuilder(AssertionConsumerService.DEFAULT_ELEMENT_NAME);
  private static final SAMLObjectBuilder<Attribute> attributeBuilder =
      makeSamlObjectBuilder(Attribute.DEFAULT_ELEMENT_NAME);
  private static final SAMLObjectBuilder<AttributeStatement> attributeStatementBuilder =
      makeSamlObjectBuilder(AttributeStatement.DEFAULT_ELEMENT_NAME);
  private static final SAMLObjectBuilder<AttributeValue> attributeValueBuilder =
      makeSamlObjectBuilder(AttributeValue.DEFAULT_ELEMENT_NAME);
  private static final SAMLObjectBuilder<Audience> audienceBuilder =
      makeSamlObjectBuilder(Audience.DEFAULT_ELEMENT_NAME);
  private static final SAMLObjectBuilder<AudienceRestriction> audienceRestrictionBuilder =
      makeSamlObjectBuilder(AudienceRestriction.DEFAULT_ELEMENT_NAME);
  private static final SAMLObjectBuilder<AuthnContext> authnContextBuilder =
      makeSamlObjectBuilder(AuthnContext.DEFAULT_ELEMENT_NAME);
  private static final SAMLObjectBuilder<AuthnContextClassRef> authnContextClassRefBuilder =
      makeSamlObjectBuilder(AuthnContextClassRef.DEFAULT_ELEMENT_NAME);
  private static final SAMLObjectBuilder<AuthnRequest> authnRequestBuilder =
      makeSamlObjectBuilder(AuthnRequest.DEFAULT_ELEMENT_NAME);
  private static final SAMLObjectBuilder<AuthnStatement> authnStatementBuilder =
      makeSamlObjectBuilder(AuthnStatement.DEFAULT_ELEMENT_NAME);
  private static final SAMLObjectBuilder<AuthzDecisionQuery> authzDecisionQueryBuilder =
      makeSamlObjectBuilder(AuthzDecisionQuery.DEFAULT_ELEMENT_NAME);
  private static final SAMLObjectBuilder<AuthzDecisionStatement> authzDecisionStatementBuilder =
      makeSamlObjectBuilder(AuthzDecisionStatement.DEFAULT_ELEMENT_NAME);
  private static final SAMLObjectBuilder<Conditions> conditionsBuilder =
      makeSamlObjectBuilder(Conditions.DEFAULT_ELEMENT_NAME);
  private static final SAMLObjectBuilder<Issuer> issuerBuilder =
      makeSamlObjectBuilder(Issuer.DEFAULT_ELEMENT_NAME);
  private static final SAMLObjectBuilder<NameID> nameIDBuilder =
      makeSamlObjectBuilder(NameID.DEFAULT_ELEMENT_NAME);
  private static final SAMLObjectBuilder<Response> responseBuilder =
      makeSamlObjectBuilder(Response.DEFAULT_ELEMENT_NAME);
  private static final SAMLObjectBuilder<Status> statusBuilder =
      makeSamlObjectBuilder(Status.DEFAULT_ELEMENT_NAME);
  private static final SAMLObjectBuilder<StatusCode> statusCodeBuilder =
      makeSamlObjectBuilder(StatusCode.DEFAULT_ELEMENT_NAME);
  private static final SAMLObjectBuilder<StatusMessage> statusMessageBuilder =
      makeSamlObjectBuilder(StatusMessage.DEFAULT_ELEMENT_NAME);
  private static final SAMLObjectBuilder<Subject> subjectBuilder =
      makeSamlObjectBuilder(Subject.DEFAULT_ELEMENT_NAME);
  private static final SAMLObjectBuilder<SubjectConfirmation> subjectConfirmationBuilder =
      makeSamlObjectBuilder(SubjectConfirmation.DEFAULT_ELEMENT_NAME);
  private static final SAMLObjectBuilder<SubjectConfirmationData> subjectConfirmationDataBuilder =
      makeSamlObjectBuilder(SubjectConfirmationData.DEFAULT_ELEMENT_NAME);

  // Metadata builders

  private static final SAMLObjectBuilder<SingleSignOnService> singleSignOnServiceBuilder =
      makeSamlObjectBuilder(SingleSignOnService.DEFAULT_ELEMENT_NAME);

  // Identifier generator

  private static final IdentifierGenerator idGenerator;
  static {
    try {
      idGenerator = new SecureRandomIdentifierGenerator();
    } catch (NoSuchAlgorithmException e) {
      throw new IllegalStateException(e);
    }
  }

  // Non-instantiable class.
  private OpenSamlUtil() {
  }

  private static void initializeRequest(RequestAbstractType request, String issuer,
      DateTime issueInstant) {
    request.setID(generateIdentifier());
    request.setVersion(SAMLVersion.VERSION_20);
    request.setIssuer(makeIssuer(issuer));
    request.setIssueInstant(issueInstant);
  }

  private static void initializeResponse(StatusResponseType response, String issuer,
      DateTime issueInstant, Status status, String inResponseTo) {
    response.setID(generateIdentifier());
    response.setVersion(SAMLVersion.VERSION_20);
    response.setIssuer(makeIssuer(issuer));
    response.setIssueInstant(issueInstant);
    response.setStatus(status);
    response.setInResponseTo(inResponseTo);
  }

  /**
   * Static factory for SAML {@link Action} objects.
   *
   * @param name A URI identifying the represented action.
   * @param namespace A URI identifying the class of names being specified.
   * @return A new <code>Action</code> object.
   */
  public static Action makeAction(String name, String namespace) {
    Action action = actionBuilder.buildObject();
    action.setAction(name);
    action.setNamespace(namespace);
    return action;
  }

  /**
   * Static factory for SAML {@link Artifact} objects.
   *
   * @param value The artifact string.
   * @return A new <code>Artifact</code> object.
   */
  private static Artifact makeArtifact(String value) {
    Artifact element = artifactBuilder.buildObject();
    element.setArtifact(value);
    return element;
  }

  /**
   * Static factory for SAML {@link ArtifactResolve} objects.
   *
   * @param issuer The entity issuing this request.
   * @param issueInstant The time of issue for this statement.
   * @param value The artifact string to be resolved.
   * @return A new <code>ArtifactResolve</code> object.
   */
  public static ArtifactResolve makeArtifactResolve(String issuer, DateTime issueInstant,
      String value) {
    ArtifactResolve request = artifactResolveBuilder.buildObject();
    initializeRequest(request, issuer, issueInstant);
    request.setArtifact(makeArtifact(value));
    return request;
  }

  /**
   * Static factory for SAML {@link ArtifactResponse} objects.
   *
   * @param issuer The entity issuing this response.
   * @param issueInstant The time of issue for this statement.
   * @param status The <code>Status</code> object indicating the success of the resolution.
   * @param inResponseTo The message ID of the request this is a response to.
   * @param message The embedded message.
   * @return A new <code>ArtifactResponse</code> object.
   */
  public static ArtifactResponse makeArtifactResponse(String issuer, DateTime issueInstant,
      Status status, String inResponseTo, SAMLObject message) {
    ArtifactResponse response = artifactResponseBuilder.buildObject();
    initializeResponse(response, issuer, issueInstant, status, inResponseTo);
    if (message != null) {
      response.setMessage(message);
    }
    return response;
  }

  /**
   * Static factory for SAML {@link Assertion} objects.
   *
   * @param issuer The entity issuing this assertion.
   * @param issueInstant The time of issue for this statement.
   * @param subject The subject of the assertion.
   * @param conditions The conditions under which this assertion is valid.
   * @param statements Statements being made by this assertion.
   * @return A new <code>Assertion</code> object.
   */
  public static Assertion makeAssertion(String issuer, DateTime issueInstant, Subject subject,
      Conditions conditions, Statement... statements) {
    Assertion assertion = assertionBuilder.buildObject();
    assertion.setID(generateIdentifier());
    assertion.setVersion(SAMLVersion.VERSION_20);
    assertion.setIssuer(makeIssuer(issuer));
    assertion.setIssueInstant(issueInstant);
    assertion.setSubject(subject);
    if (conditions != null) {
      assertion.setConditions(conditions);
    }
    for (Statement statement : statements) {
      if (statement instanceof AuthnStatement) {
        assertion.getAuthnStatements().add((AuthnStatement) statement);
      } else if (statement instanceof AuthzDecisionStatement) {
        assertion.getAuthzDecisionStatements().add((AuthzDecisionStatement) statement);
      } else if (statement instanceof AttributeStatement) {
        assertion.getAttributeStatements().add((AttributeStatement) statement);
      } else {
        throw new IllegalArgumentException("Unknown statement type: " + statement);
      }
    }
    return assertion;
  }

  /**
   * Static factory for SAML {@link AssertionConsumerService} objects.
   *
   * @param location A URL for this service.
   * @param binding A SAML binding used to communicate with the service.
   * @return A new {@code AssertionConsumerService} object.
   */
  public static AssertionConsumerService makeAssertionConsumerService(String location,
      String binding) {
    AssertionConsumerService endpoint = assertionConsumerServiceBuilder.buildObject();
    endpoint.setLocation(location);
    endpoint.setBinding(binding);
    endpoint.setIndex(0);
    endpoint.setIsDefault(true);
    return endpoint;
  }

  /**
   * Static factory for SAML {@link Attribute} objects.
   *
   * @param name The attribute name.
   * @return A new <code>Attribute</code> object.
   */
  public static Attribute makeAttribute(String name) {
    Attribute attribute = attributeBuilder.buildObject();
    attribute.setName(name);
    return attribute;
  }

  /**
   * Static factory for SAML {@link AttributeStatement} objects.
   *
   * @param attributes The attributes to include in the statement.
   * @return A new <code>AttributeStatement</code> object.
   */
  public static AttributeStatement makeAttributeStatement(Attribute... attributes) {
    AttributeStatement statement = attributeStatementBuilder.buildObject();
    for (Attribute attribute : attributes) {
      if (attribute != null) {
        statement.getAttributes().add(attribute);
      }
    }
    return statement;
  }

  /**
   * Static factory for SAML {@link AttributeValue} objects.
   *
   * @return A new <code>AttributeValue</code> object.
   */
  public static AttributeValue makeAttributeValue(String value) {
    AttributeValue attrValue = attributeValueBuilder.buildObject();
    attrValue.setValue(value);
    return attrValue;
  }

  /**
   * Static factory for SAML {@link Audience} objects.
   *
   * @param uri The audience URI.
   * @return A new <code>Audience</code> object.
   */
  private static Audience makeAudience(String uri) {
    Audience audience = audienceBuilder.buildObject();
    audience.setAudienceURI(uri);
    return audience;
  }

  /**
   * Static factory for SAML {@link AudienceRestriction} objects.
   *
   * @param uris The audience URIs.
   * @return A new <code>AudienceRestriction</code> object.
   */
  public static AudienceRestriction makeAudienceRestriction(String... uris) {
    AudienceRestriction restriction = audienceRestrictionBuilder.buildObject();
    for (String uri : uris) {
      restriction.getAudiences().add(makeAudience(uri));
    }
    return restriction;
  }

  /**
   * Static factory for SAML {@link AuthnContext} objects.
   *
   * @param classRef An <code>AuthnContextClassRef</code> identifying an authentication context
   * class.
   * @return A new <code>AuthnContext</code> object.
   */
  private static AuthnContext makeAuthnContext(AuthnContextClassRef classRef) {
    AuthnContext context = authnContextBuilder.buildObject();
    context.setAuthnContextClassRef(classRef);
    return context;
  }

  /**
   * Static factory for SAML {@link AuthnContext} objects.
   *
   * A convenience method that wraps the given URI in an {@link AuthnContextClassRef} object.
   *
   * @param uri A URI identifying an authentication context class.
   * @return A new <code>AuthnContext</code> object.
   */
  private static AuthnContext makeAuthnContext(String uri) {
    return makeAuthnContext(makeAuthnContextClassRef(uri));
  }

  /**
   * Static factory for SAML {@link AuthnContextClassRef} objects.
   *
   * @param uri A URI identifying an authentication context class.
   * @return A new <code>AuthnContextClassRef</code> object.
   */
  private static AuthnContextClassRef makeAuthnContextClassRef(String uri) {
    AuthnContextClassRef classRef = authnContextClassRefBuilder.buildObject();
    classRef.setAuthnContextClassRef(uri);
    return classRef;
  }

  /**
   * Static factory for SAML {@link AuthnRequest} objects.
   *
   * @param issuer The entity issuing this request.
   * @param issueInstant The time of issue for this statement.
   * @return A new <code>AuthnRequest</code> object.
   */
  public static AuthnRequest makeAuthnRequest(String issuer, DateTime issueInstant) {
    AuthnRequest request = authnRequestBuilder.buildObject();
    initializeRequest(request, issuer, issueInstant);
    return request;
  }

  /**
   * Static factory for SAML {@link AuthnStatement} objects.
   *
   * @param issueInstant The time of issue for this statement.
   * @param uri A URI identifying an authentication context class.
   * @return A new <code>AuthnStatement</code> object.
   */
  public static AuthnStatement makeAuthnStatement(DateTime issueInstant, String uri) {
    AuthnStatement statement = authnStatementBuilder.buildObject();
    statement.setAuthnInstant(issueInstant);
    statement.setAuthnContext(makeAuthnContext(uri));
    return statement;
  }

  /**
   * Static factory for SAML {@link AuthzDecisionQuery} objects.
   *
   * @param issuer The entity issuing this query.
   * @param issueInstant The time of issue for this query.
   * @param subject The subject requesting access to a resource.
   * @param resource The resource for which access is being requested.
   * @param action The action on the resource for which access is being requested.
   * @return A new <code>AuthzDecisionQuery</code> object.
   */
  public static AuthzDecisionQuery makeAuthzDecisionQuery(String issuer, DateTime issueInstant,
      Subject subject, String resource, Action action) {
    AuthzDecisionQuery query = authzDecisionQueryBuilder.buildObject();
    initializeRequest(query, issuer, issueInstant);
    query.setSubject(subject);
    query.setResource(resource);
    query.getActions().add(action);
    return query;
  }

  /**
   * Static factory for SAML {@link AuthzDecisionStatement} objects.
   *
   * @param resource The resource referred to by this access decision.
   * @param decision The access decision made by the authorization service.
   * @param actions The actions authorized to perform on the stated resource.
   * @return A new <code>AuthzDecisionStatement</code> object.
   */
  public static AuthzDecisionStatement makeAuthzDecisionStatement(String resource,
      DecisionTypeEnumeration decision, Action... actions) {
    AuthzDecisionStatement statement = authzDecisionStatementBuilder.buildObject();
    statement.setResource(resource);
    statement.setDecision(decision);
    statement.getActions().addAll(Arrays.asList(actions));
    return statement;
  }

  /**
   * Static factory for SAML {@link Conditions} objects.
   *
   * @param notBefore Earliest time at which assertion is valid.
   * @param notOnOrAfter Latest time at which assertion is valid.
   * @param restriction The audience restriction that must be satisfied.
   * @return A new <code>Conditions</code> object.
   */
  public static Conditions makeConditions(DateTime notBefore, DateTime notOnOrAfter,
      AudienceRestriction restriction) {
    Conditions conditions = conditionsBuilder.buildObject();
    conditions.setNotBefore(notBefore);
    conditions.setNotOnOrAfter(notOnOrAfter);
    conditions.getAudienceRestrictions().add(restriction);
    return conditions;
  }

  /**
   * Static factory for SAML {@link Issuer} objects.
   *
   * @param name The issuer of a response object.  In the absence of a specific format, this is a
   *     URI identifying the issuer.
   * @return A new <code>Issuer</code> object.
   */
  private static Issuer makeIssuer(String name) {
    Issuer issuer = issuerBuilder.buildObject();
    issuer.setValue(name);
    return issuer;
  }

  /**
   * Static factory for SAML {@link NameID} objects.
   *
   * @param name The name represented by this object.
   * @return A new <code>NameID</code> object.
   */
  private static NameID makeNameId(String name) {
    NameID id = nameIDBuilder.buildObject();
    id.setValue(name);
    return id;
  }

  /**
   * Static factory for SAML {@link Response} objects.
   *
   * @param issuer The entity issuing this response.
   * @param issueInstant The time of issue for this statement.
   * @param status The <code>Status</code> object indicating the success of requested action.
   * @param request The request that this is a response to.
   * @param assertions The assertions carried by this response.
   * @return A new <code>Response</code> object.
   */
  public static Response makeResponse(String issuer, DateTime issueInstant,
      Status status, RequestAbstractType request, Assertion... assertions) {
    return makeResponse(issuer, issueInstant, status, request.getID(), assertions);
  }

  /**
   * Static factory for SAML {@link Response} objects.
   *
   * @param issuer The entity issuing this response.
   * @param issueInstant The time of issue for this statement.
   * @param status The <code>Status</code> object indicating the success of requested action.
   * @param inResponseTo The message ID of the request this is a response to.
   * @param assertions The assertions carried by this response.
   * @return A new <code>Response</code> object.
   */
  public static Response makeResponse(String issuer, DateTime issueInstant, Status status,
      String inResponseTo, Assertion... assertions) {
    Response response = responseBuilder.buildObject();
    initializeResponse(response, issuer, issueInstant, status, inResponseTo);
    response.getAssertions().addAll(Arrays.asList(assertions));
    return response;
  }

  /**
   * Static factory for SAML {@link Status} objects.
   *
   * @param value A URI specifying one of the standard SAML status codes.
   * @return A new <code>Status</code> object.
   */
  public static Status makeStatus(String value) {
    Status status = statusBuilder.buildObject();
    status.setStatusCode(makeStatusCode(value));
    return status;
  }

  /**
   * Static factory for SAML {@link Status} objects.
   *
   * A convenience method that generates a status object with a message.
   *
   * @param value A URI specifying one of the standard SAML status codes.
   * @param message A string describing the status.
   * @return A new <code>Status</code> object.
   */
  public static Status makeStatus(String value, String message) {
    Status status = makeStatus(value);
    status.setStatusMessage(makeStatusMessage(message));
    return status;
  }

  /**
   * Static factory for SAML {@link Status} objects.
   *
   * @param statusCode A status code indicating result status of a request.
   * @param statusMessage An optional message providing human-readable detail of the status.
   * @return A new {@link Status} object.
   */
  public static Status makeStatus(StatusCode statusCode, StatusMessage statusMessage) {
    Status status = statusBuilder.buildObject();
    status.setStatusCode(statusCode);
    if (statusMessage != null) {
      status.setStatusMessage(statusMessage);
    }
    return status;
  }

  /**
   * Static factory for a successful SAML status element.
   *
   * @return A successful {@link Status} element.
   */
  public static Status makeSuccessfulStatus() {
    return makeStatus(makeStatusCode(StatusCode.SUCCESS_URI), null);
  }

  /**
   * Static factory for SAML {@link StatusCode} objects.
   *
   * @param value A URI specifying one of the standard SAML status codes.
   * @return A new <code>StatusCode</code> object.
   */
  public static StatusCode makeStatusCode(String value) {
    StatusCode code = statusCodeBuilder.buildObject();
    code.setValue(value);
    return code;
  }

  /**
   * Static factory for SAML {@link StatusMessage} objects.
   *
   * @param value A status message string.
   * @return A new <code>StatusMessage</code> object.
   */
  public static StatusMessage makeStatusMessage(String value) {
    StatusMessage message = statusMessageBuilder.buildObject();
    message.setMessage(value);
    return message;
  }

  /**
   * Static factory for SAML {@link Subject} objects.
   *
   * @param name The name identifying the subject.
   * @param confirmations The confirmations for this subject.
   * @return A new <code>Subject</code> object.
   */
  public static Subject makeSubject(String name, SubjectConfirmation... confirmations) {
    Subject samlSubject = subjectBuilder.buildObject();
    samlSubject.setNameID(makeNameId(name));
    if (confirmations != null) {
      samlSubject.getSubjectConfirmations().addAll(Arrays.asList(confirmations));
    }
    return samlSubject;
  }

  /**
   * Static factory for SAML {@link SubjectConfirmation} objects.
   *
   * @param method The method used to confirm the subject.
   * @param data The data about the confirmation.
   * @return A new <code>SubjectConfirmation</code> object.
   */
  public static SubjectConfirmation makeSubjectConfirmation(String method,
      SubjectConfirmationData data) {
    SubjectConfirmation confirmation = subjectConfirmationBuilder.buildObject();
    confirmation.setMethod(method);
    confirmation.setSubjectConfirmationData(data);
    return confirmation;
  }

  /**
   * Static factory for SAML {@link SubjectConfirmationData} objects.
   *
   * @param recipient The entity ID of the intended recipient.
   * @param expirationTime The expiration time for this subject.
   * @param inResponseTo The message ID of the AuthnRequest this is a response to.
   * @return A new <code>SubjectConfirmationData</code> object.
   */
  public static SubjectConfirmationData makeSubjectConfirmationData(String recipient,
      DateTime expirationTime, String inResponseTo) {
    SubjectConfirmationData data = subjectConfirmationDataBuilder.buildObject();
    data.setRecipient(recipient);
    data.setNotOnOrAfter(expirationTime);
    data.setInResponseTo(inResponseTo);
    return data;
  }

  /*
   * Metadata descriptions.
   */

  /**
   * Static factory for SAML {@link SingleSignOnService} objects.
   *
   * @param binding The SAML binding implemented by this service.
   * @param location The URL that the service listens to.
   * @return A new <code>SingleSignOnService</code> object.
   */
  public static SingleSignOnService makeSingleSignOnService(String binding, String location) {
    SingleSignOnService service = singleSignOnServiceBuilder.buildObject();
    service.setBinding(binding);
    service.setLocation(location);
    return service;
  }

  /*
   * Endpoint selection
   */

  public static void initializeLocalEntity(
      SAMLMessageContext<? extends SAMLObject, ? extends SAMLObject, ? extends SAMLObject> context,
      EntityDescriptor entity, RoleDescriptor role) {
    initializeLocalEntity(context, entity);
    context.setLocalEntityRole(role.getElementQName());
    context.setLocalEntityRoleMetadata(role);
  }

  public static void initializeLocalEntity(
      SAMLMessageContext<? extends SAMLObject, ? extends SAMLObject, ? extends SAMLObject> context,
      EntityDescriptor entity) {
    context.setLocalEntityId(entity.getEntityID());
    context.setLocalEntityMetadata(entity);
    context.setOutboundMessageIssuer(entity.getEntityID());
  }

  public static void initializePeerEntity(
      SAMLMessageContext<? extends SAMLObject, ? extends SAMLObject, ? extends SAMLObject> context,
      EntityDescriptor entity, RoleDescriptor role, QName endpointType, String binding) {
    context.setPeerEntityId(entity.getEntityID());
    context.setPeerEntityMetadata(entity);
    context.setPeerEntityRole(role.getElementQName());
    context.setPeerEntityRoleMetadata(role);
    {
      BasicEndpointSelector selector = new BasicEndpointSelector();
      selector.setEntityMetadata(entity);
      selector.setEndpointType(endpointType);
      selector.setEntityRoleMetadata(role);
      selector.getSupportedIssuerBindings().add(binding);
      context.setPeerEntityEndpoint(selector.selectEndpoint());
    }
  }

  /*
   * Identifiers
   */

  /**
   * Generate a random identifier.
   *
   * @return A new identifier string.
   */
  public static String generateIdentifier() {
    return idGenerator.generateIdentifier();
  }

  /*
   * Context and codecs
   */

  /**
   * Static factory for OpenSAML message-context objects.
   *
   * @param <TI> The type of the request object.
   * @param <TO> The type of the response object.
   * @param <TN> The type of the name identifier used for subjects.
   * @return A new message-context object.
   */
  public static <TI extends SAMLObject, TO extends SAMLObject, TN extends SAMLObject>
        SAMLMessageContext<TI, TO, TN> makeSamlMessageContext() {
    SAMLMessageContext<TI, TO, TN> context = new BasicSAMLMessageContext<TI, TO, TN>();
    context.setInboundSAMLProtocol(SAML20P_NS);  // we only use SAML 2.0
    context.setOutboundSAMLProtocol(SAML20P_NS);
    return context;
  }

  /**
   * Run a message encoder.
   *
   * @param encoder The message encoder to run.
   * @param context The message context to pass to the encoder.
   * @throws IOException if unable to encode message.
   */
  public static void runEncoder(MessageEncoder encoder, MessageContext context)
      throws IOException {
    try {
      encoder.encode(context);
    } catch (MessageEncodingException e) {
      throw new IOException(e);
    }
  }

  /**
   * Run a message decoder.
   *
   * @param decoder The message decoder to run.
   * @param context The message context to pass to the decoder.
   * @throws IOException if unable to decode message.
   */
  public static void runDecoder(MessageDecoder decoder, MessageContext context)
      throws IOException {
    try {
      decoder.decode(context);
    } catch (MessageDecodingException e) {
      throw new IOException(e);
    } catch (SecurityException e) {
      throw new IOException(e);
    }
  }

  /**
   * Get a string for the current date/time, in the correct format for SAML.
   *
   * @return The corresponding string.
   */
  public static String samlDateString() {
    return samlDateString(new DateTime());
  }

  /**
   * Get a string for a given date/time, in the correct format for SAML.
   *
   * @param date The date/time to convert.
   * @return The corresponding string.
   */
  public static String samlDateString(DateTime date) {
    synchronized (samlDateStringLock) {
      return Configuration.getSAMLDateFormatter().print(date);
    }
  }

  private static final Object samlDateStringLock = new Object();

  /**
   * Get a SAML metadata provider that reads from a specified file.  The provider adjusts
   * its output as the file is changed.
   *
   * @param file The file containing the metadata.
   * @return A metadata provider for the given file.
   * @throws MetadataProviderException if there are problems reading the file.
   */
  public static ObservableMetadataProvider getMetadataFromFile(File file)
      throws MetadataProviderException {
    FilesystemMetadataProvider provider = new FilesystemMetadataProvider(file);
    provider.setParserPool(new BasicParserPool());
    // Causes null-pointer errors in OpenSAML code:
    //provider.setRequireValidMetadata(true);
    return provider;
  }

  /**
   * Make a static security-policy resolver that resolves to a given policy.
   *
   * @param policy The security policy to resolve to.
   * @return A security-policy resolver that resolves to the given policy.
   */
  public static SecurityPolicyResolver makeStaticSecurityPolicyResolver(SecurityPolicy policy) {
    return new StaticSecurityPolicyResolver(policy);
  }

  /**
   * Make a static security-policy resolver that resolves to a given policy.
   *
   * @param rules The policy rules that comprise the returned policy.
   * @return A security-policy resolver that resolves to the given policy.
   */
  public static SecurityPolicyResolver makeStaticSecurityPolicyResolver(
      SecurityPolicyRule... rules) {
    return makeStaticSecurityPolicyResolver(makeBasicSecurityPolicy(rules));
  }

  /**
   * Make a basic security policy, consisting of a set of rules that must all be satisfied.
   *
   * @param rules The rules comprising the policy.
   * @return A new security policy.
   */
  public static SecurityPolicy makeBasicSecurityPolicy(SecurityPolicyRule... rules) {
    BasicSecurityPolicy securityPolicy = new BasicSecurityPolicy();
    securityPolicy.getPolicyRules().addAll(Arrays.asList(rules));
    return securityPolicy;
  }

  private static KeyInfoCredentialResolver standardKeyInfoCredentialResolver = null;

  /**
   * Make a KeyInfoCredentialResolver that knows about some basic credential types.
   *
   * @return A new KeyInfoCredentialResolver.
   */
  public static synchronized KeyInfoCredentialResolver getStandardKeyInfoCredentialResolver() {
    if (standardKeyInfoCredentialResolver == null) {
      List<KeyInfoProvider> providers = Lists.newArrayList();
      providers.add(new DSAKeyValueProvider());
      providers.add(new RSAKeyValueProvider());
      providers.add(new InlineX509DataProvider());
      standardKeyInfoCredentialResolver = new BasicProviderKeyInfoCredentialResolver(providers);
    }
    return standardKeyInfoCredentialResolver;
  }

  /**
   * Return the standard credentials from a given KeyInfo object.
   *
   * @param keyInfo The KeyInfo object to examine.
   * @return The standard credentials found in the object.
   * @throws SecurityException
   */
  public static Iterable<Credential> resolveStandardKeyInfoCredentials(KeyInfo keyInfo)
      throws SecurityException {
    return getStandardKeyInfoCredentialResolver()
        .resolve(new CriteriaSet(new KeyInfoCriteria(keyInfo)));
  }

  /**
   * Does a given peer's metadata support verification of signed messages?
   *
   * @param context The SAML message context containing the peer's metadata.
   * @return True if the role supports verification of signed messages.
   */
  public static boolean peerSupportsSignatureVerification(
      SAMLMessageContext<? extends SAMLObject, ? extends SAMLObject, ? extends SAMLObject>
      context) {
    for (KeyDescriptor keyDescriptor : context.getPeerEntityRoleMetadata().getKeyDescriptors()) {
      if (keyDescriptor.getUse() == UsageType.SIGNING) {
        try {
          if (resolveStandardKeyInfoCredentials(keyDescriptor.getKeyInfo()).iterator().hasNext()) {
            return true;
          }
        } catch (SecurityException e) {
          throw new IllegalStateException("Got SecurityException while extracting credentials:", e);
        }
      }
    }
    return false;
  }

  /**
   * Read a PEM-encoded private-key file and return it as a {@link PrivateKey} object.
   *
   * @param file The file to read.
   * @return The private-key object, never null.
   * @throws IOException if there's some kind of error reading or converting the file.
   */
  public static PrivateKey readPrivateKeyFile(File file)
      throws IOException {
    try {
      return SecurityHelper.decodePrivateKey(file, new char[0]);
    } catch (KeyException e) {
      throw new IOException(e);
    }
  }

  /**
   * Convert an OpenSAML object to a DOM object.
   *
   * @param xmlObject The OpenSAML object to convert.
   * @return The corresponding DOM object.
   * @throws MarshallingException if unable to convert object.
   */
  public static Element marshallXmlObject(XMLObject xmlObject) throws MarshallingException {
    return Configuration.getMarshallerFactory().getMarshaller(xmlObject).marshall(xmlObject);
  }

  /**
   * Convert a DOM object to an OpenSAML object.
   *
   * @param element A DOM object representing a SAML element.
   * @return The corresponding OpenSAML object.
   * @throws UnmarshallingException if unable to convert object.
   */
  public static XMLObject unmarshallXmlObject(Element element) throws UnmarshallingException {
    return Configuration.getUnmarshallerFactory().getUnmarshaller(element).unmarshall(element);
  }

  /**
   * Make a new artifact map.
   *
   * @param artifactLifetime The lifetime of the map's artifacts, in milliseconds.
   * @return A new artifact map.
   */
  public static SAMLArtifactMap makeArtifactMap(int artifactLifetime) {
    return new BasicSAMLArtifactMap(
        new BasicParserPool(),
        new MapBasedStorageService<String, SAMLArtifactMapEntry>(),
        artifactLifetime);
  }
}
