// 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.adaptor.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);
  }
}
