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

package com.google.enterprise.adaptor;

import static com.google.enterprise.adaptor.secmgr.saml.OpenSamlUtil.makeAssertion;
import static com.google.enterprise.adaptor.secmgr.saml.OpenSamlUtil.makeAttribute;
import static com.google.enterprise.adaptor.secmgr.saml.OpenSamlUtil.makeAttributeStatement;
import static com.google.enterprise.adaptor.secmgr.saml.OpenSamlUtil.makeAttributeValue;

import static com.google.enterprise.adaptor.secmgr.saml.OpenSamlUtil.makeAudienceRestriction;
import static com.google.enterprise.adaptor.secmgr.saml.OpenSamlUtil.makeAuthnStatement;
import static com.google.enterprise.adaptor.secmgr.saml.OpenSamlUtil.makeConditions;
import static com.google.enterprise.adaptor.secmgr.saml.OpenSamlUtil.makeResponse;
import static com.google.enterprise.adaptor.secmgr.saml.OpenSamlUtil.makeStatus;
import static com.google.enterprise.adaptor.secmgr.saml.OpenSamlUtil.makeStatusCode;
import static com.google.enterprise.adaptor.secmgr.saml.OpenSamlUtil.makeStatusMessage;
import static com.google.enterprise.adaptor.secmgr.saml.OpenSamlUtil.makeSubject;
import static com.google.enterprise.adaptor.secmgr.saml.OpenSamlUtil.makeSubjectConfirmation;
import static com.google.enterprise.adaptor.secmgr.saml.OpenSamlUtil.makeSubjectConfirmationData;
import static com.google.enterprise.adaptor.secmgr.saml.OpenSamlUtil.makeSuccessfulStatus;

import com.google.enterprise.adaptor.secmgr.saml.OpenSamlUtil;

import com.sun.net.httpserver.HttpExchange;
import com.sun.net.httpserver.HttpHandler;

import org.apache.velocity.app.VelocityEngine;
import org.apache.velocity.runtime.log.JdkLogChute;
import org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader;
import org.joda.time.DateTime;
import org.opensaml.common.binding.SAMLMessageContext;
import org.opensaml.common.xml.SAMLConstants;
import org.opensaml.saml2.binding.AuthnResponseEndpointSelector;
import org.opensaml.saml2.binding.decoding.HTTPRedirectDeflateDecoder;
import org.opensaml.saml2.binding.encoding.HTTPPostEncoder;
import org.opensaml.saml2.core.Attribute;
import org.opensaml.saml2.core.AuthnContext;
import org.opensaml.saml2.core.AuthnRequest;
import org.opensaml.saml2.core.NameID;
import org.opensaml.saml2.core.Response;
import org.opensaml.saml2.core.StatusCode;
import org.opensaml.saml2.metadata.AssertionConsumerService;
import org.opensaml.saml2.metadata.Endpoint;
import org.opensaml.saml2.metadata.EntityDescriptor;
import org.opensaml.saml2.metadata.IDPSSODescriptor;
import org.opensaml.saml2.metadata.RoleDescriptor;
import org.opensaml.saml2.metadata.SPSSODescriptor;
import org.opensaml.ws.message.decoder.MessageDecodingException;
import org.opensaml.ws.message.encoder.MessageEncodingException;
import org.opensaml.xml.security.SecurityException;
import org.opensaml.xml.security.SecurityHelper;
import org.opensaml.xml.security.credential.Credential;

import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.URI;
import java.net.URISyntaxException;
import java.security.KeyPair;
import java.util.List;
import java.util.Collections;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 * Provides ability to recieve and respond to SAML authn requests.
 *
 * <p>This functions as the Identity Provider (IdP) role in SAML. An IdP
 * authenticates users when requested by a Service Provider (SP) and sends the
 * results to the SP.
 */
class SamlIdentityProvider {
  private static final Logger log
      = Logger.getLogger(SamlIdentityProvider.class.getName());
  private static final VelocityEngine velocityEngine;

  static {
    velocityEngine = new VelocityEngine();
    velocityEngine.addProperty("resource.loader", "classloader");
    velocityEngine.addProperty("classloader.resource.loader.class",
        ClasspathResourceLoader.class.getName());
    velocityEngine.addProperty("runtime.log.logsystem.class",
        JdkLogChute.class.getName());
    try {
      velocityEngine.init();
    } catch (Exception ex) {
      throw new RuntimeException(ex);
    }
  }

  private final AuthnAuthority adaptor;
  /** Credentials to use to sign messages. */
  private final Credential cred;
  private final SamlMetadata metadata;
  private final SsoHandler ssoHandler = new SsoHandler();

  public SamlIdentityProvider(AuthnAuthority adaptor, SamlMetadata metadata,
      KeyPair key) {
    if (adaptor == null || metadata == null) {
      throw new NullPointerException();
    }
    this.adaptor = adaptor;
    this.metadata = metadata;
    this.cred = (key == null) ? null
        : SecurityHelper.getSimpleCredential(key.getPublic(), key.getPrivate());
  }

  public void respond(HttpExchange ex,
      SAMLMessageContext<AuthnRequest, Response, NameID> context,
      AuthnIdentity identity) throws IOException {
    Response samlResponse = createResponse(context, identity);

    context.setOutboundSAMLMessage(samlResponse);
    context.setOutboundMessageTransport(
        new HttpExchangeOutTransportAdapter(ex));

    String responseBinding = context.getPeerEntityEndpoint().getBinding();
    if (!SAMLConstants.SAML2_POST_BINDING_URI.equals(responseBinding)) {
      throw new IllegalStateException("Unknown SAML binding: "
          + responseBinding);
    }
    try {
      new HTTPPostEncoder(velocityEngine, "/templates/saml2-post-binding.vm")
          .encode(context);
    } catch (MessageEncodingException e) {
      throw new IOException("Failed to encode SAML response", e);
    }
    ex.getResponseBody().flush();
    ex.getResponseBody().close();
    ex.close();
  }

  private Response createResponse(
      SAMLMessageContext<AuthnRequest, Response, NameID> context,
      AuthnIdentity identity) {
    String recipient = context.getPeerEntityEndpoint().getLocation();
    String audience = context.getInboundMessageIssuer();
    String inResponseTo = context.getInboundSAMLMessage().getID();
    String issuer = context.getLocalEntityId();
    DateTime now = new DateTime();
    // Expiration time is 30 seconds in the future.
    DateTime expirationTime = now.plusMillis(30 * 1000);

    if (identity == null) {
      return makeResponse(issuer, now,
          makeStatus(
              makeStatusCode(StatusCode.RESPONDER_URI),
              makeStatusMessage("Could not authenticate user")),
          inResponseTo);
    }

    Attribute groupsAttribute = makeAttribute("member-of");
    Iterable<GroupPrincipal> groups = identity.getGroups();
    if (groups == null) {
      groups = Collections.emptySet();
    }
    for (GroupPrincipal group : groups) {
      String name = group.getName();
      groupsAttribute.getAttributeValues().add(makeAttributeValue(name));
    }

    return makeResponse(issuer, now, makeSuccessfulStatus(), inResponseTo,
        makeAssertion(issuer, now,
          makeSubject(identity.getUser().getName(),
            makeSubjectConfirmation(OpenSamlUtil.BEARER_METHOD,
              makeSubjectConfirmationData(recipient, expirationTime,
                inResponseTo))),
          makeConditions(now, expirationTime,
            makeAudienceRestriction(audience)),
          makeAuthnStatement(now, AuthnContext.IP_PASSWORD_AUTHN_CTX),
          makeAttributeStatement(groupsAttribute)));
  }

  public HttpHandler getSingleSignOnHandler() {
    return ssoHandler;
  }

  private class SsoHandler implements HttpHandler {
    @Override
    public void handle(HttpExchange ex) throws IOException {
      if (!"GET".equals(ex.getRequestMethod())) {
        HttpExchanges.cannedRespond(ex, HttpURLConnection.HTTP_BAD_METHOD,
            Translation.HTTP_BAD_METHOD);
        return;
      }
      if (!ex.getRequestURI().getPath().equals(ex.getHttpContext().getPath())) {
        HttpExchanges.cannedRespond(ex, HttpURLConnection.HTTP_NOT_FOUND,
            Translation.HTTP_NOT_FOUND);
        return;
      }
      // Setup SAML context.
      SAMLMessageContext<AuthnRequest, Response, NameID> context
          = OpenSamlUtil.makeSamlMessageContext();
      context.setLocalEntityId(metadata.getLocalEntity().getEntityID());
      context.setLocalEntityMetadata(metadata.getLocalEntity());
      context.setLocalEntityRole(IDPSSODescriptor.DEFAULT_ELEMENT_NAME);
      context.setLocalEntityRoleMetadata(
          getFirst(metadata.getLocalEntity().getRoleDescriptors(
              IDPSSODescriptor.DEFAULT_ELEMENT_NAME)));
      context.setOutboundMessageIssuer(metadata.getLocalEntity().getEntityID());
      context.setOutboundSAMLMessageSigningCredential(cred);

      context.setInboundMessageTransport(
          new HttpExchangeInTransportAdapter(ex));
      // Decode request.
      try {
        new RequestUriRedirectDeflateDecoder(HttpExchanges.getRequestUri(ex))
            .decode(context);
      } catch (MessageDecodingException e) {
        log.log(Level.INFO, "Error decoding message", e);
        HttpExchanges.cannedRespond(ex, HttpURLConnection.HTTP_BAD_REQUEST,
            Translation.HTTP_BAD_REQUEST_ERROR_DECODING);
        return;
      } catch (SecurityException e) {
        log.log(Level.WARNING, "Security error while decoding message", e);
        HttpExchanges.cannedRespond(ex, HttpURLConnection.HTTP_BAD_REQUEST,
            Translation.HTTP_BAD_REQUEST_SECURITY_ERROR);
        return;
      }

      Endpoint peerEndpoint = selectEndpoint(context);
      if (peerEndpoint == null) {
        log.log(Level.INFO,
            "Error decoding message: could not determine peerEndpoint");
        HttpExchanges.cannedRespond(ex, HttpURLConnection.HTTP_BAD_REQUEST,
            Translation.HTTP_BAD_REQUEST_ERROR_DECODING);
        return;
      }
      context.setPeerEntityEndpoint(peerEndpoint);

      adaptor.authenticateUser(ex, new AuthnCallback(context));
    }

    private Endpoint selectEndpoint(
        SAMLMessageContext<AuthnRequest, ?, ?> context) {
      AuthnResponseEndpointSelector selector
          = new AuthnResponseEndpointSelector();
      selector.setEndpointType(
          AssertionConsumerService.DEFAULT_ELEMENT_NAME);
      selector.getSupportedIssuerBindings()
          .add(SAMLConstants.SAML2_POST_BINDING_URI);

      String peerEntityId = context.getInboundMessageIssuer();
      EntityDescriptor entityDescriptor = null;
      RoleDescriptor roleDescriptor = null;
      // TODO(ejona): Support additional peer entities other than a single GSA.
      if (peerEntityId != null
          && peerEntityId.equals(metadata.getPeerEntity().getEntityID())) {
        entityDescriptor = metadata.getPeerEntity();
        roleDescriptor = getFirst(entityDescriptor.getRoleDescriptors(
            SPSSODescriptor.DEFAULT_ELEMENT_NAME));
      } else {
        log.log(Level.INFO, "Unknown Peer Entity Id: {0}", peerEntityId);
      }

      selector.setSamlRequest(context.getInboundSAMLMessage());
      selector.setEntityMetadata(entityDescriptor);
      selector.setEntityRoleMetadata(roleDescriptor);

      return selector.selectEndpoint();
    }

    private <V> V getFirst(List<V> list) {
      return list.isEmpty() ? null : list.get(0);
    }
  }

  private class AuthnCallback implements AuthnAuthority.Callback {
    private final SAMLMessageContext<AuthnRequest, Response, NameID> context;

    public AuthnCallback(
        SAMLMessageContext<AuthnRequest, Response, NameID> context) {
      this.context = context;
    }

    @Override
    public void userAuthenticated(HttpExchange ex, AuthnIdentity identity)
        throws IOException {
      respond(ex, context, identity);
    }
  }

  private static class RequestUriRedirectDeflateDecoder
      extends HTTPRedirectDeflateDecoder {
    private final String requestUri;

    /**
     * @param requestUri the URI the client used to make the request
     */
    public RequestUriRedirectDeflateDecoder(URI requestUri) {
      try {
        // Remove query parameters from URI.
        requestUri = new URI(requestUri.getScheme(), requestUri.getAuthority(),
            requestUri.getPath(), null, null);
      } catch (URISyntaxException e) {
        throw new IllegalStateException(e);
      }
      this.requestUri = requestUri.toASCIIString();
    }

    @Override
    protected String getActualReceiverEndpointURI(
        SAMLMessageContext messageContext) {
      // This method in HTTPRedirectDeflateDecoder is hard-coded for use with
      // HttpServletRequestAdapter only, which we aren't using.
      return requestUri;
    }
  }
}
