// Copyright 2011 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 org.junit.Assert.assertEquals;

import org.junit.BeforeClass;
import org.junit.Test;

import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.nio.charset.Charset;
import java.util.Collection;
import java.util.Collections;
import java.util.Map;

/**
 * Test cases for {@link SamlBatchAuthzHandler}.
 */
public class SamlBatchAuthzHandlerTest {
  private static final String SOAP_HEADER
      = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
      + "<soap11:Envelope "
      +   "xmlns:soap11=\"http://schemas.xmlsoap.org/soap/envelope/\">"
      +   "<soap11:Body>";
  private static final String SOAP_FOOTER
      =   "</soap11:Body>"
      + "</soap11:Envelope>";

  private AuthzAuthority adaptor = new MockAdaptor();
  private SamlMetadata samlMetadata = new SamlMetadata("localhost", 80,
      "localhost", "http://google.com/enterprise/gsa/security-manager",
      "http://google.com/enterprise/gsa/adaptor");
  private SamlBatchAuthzHandler handler = new SamlBatchAuthzHandler(
      adaptor, new MockDocIdCodec(), samlMetadata);
  private MockHttpExchange ex = new MockHttpExchange("POST", "/",
      new MockHttpContext(handler, "/"));
  private Charset charset = Charset.forName("UTF-8");

  @BeforeClass
  public static void initSaml() {
    GsaCommunicationHandler.bootstrapOpenSaml();
  }

  @Test
  public void testGet() throws Exception {
    MockHttpExchange ex = new MockHttpExchange("GET", "/",
        new MockHttpContext(handler, "/"));
    handler.handle(ex);
    assertEquals(405, ex.getResponseCode());
  }

  @Test
  public void testWrongPath() throws Exception {
    MockHttpExchange ex = new MockHttpExchange("POST", "/wrong",
        new MockHttpContext(handler, "/"));
    handler.handle(ex);
    assertEquals(404, ex.getResponseCode());
  }

  @Test
  public void testPermitAuthz() throws Exception {
    String request
        = SOAP_HEADER
        + generateAuthzDecisionQuery("http://localhost/doc/1234",
                                     "aoeuaoeu")
        + SOAP_FOOTER;
    String goldenResponse
        = SOAP_HEADER
        + generateGoldenResponse("http://localhost/doc/1234",
                                 "aoeuaoeu",
                                 "Permit")
        + SOAP_FOOTER;
    ex.setRequestBody(stringToStream(request));
    handler.handle(ex);
    assertEquals(200, ex.getResponseCode());
    String response = new String(ex.getResponseBytes(), charset);
    response = massageResponse(response);
    assertEquals(goldenResponse, response);
  }

  @Test
  public void testDenyAuthz() throws Exception {
    SamlBatchAuthzHandler handler = new SamlBatchAuthzHandler(
        new PrivateMockAdaptor(), new MockDocIdCodec(), samlMetadata);
    MockHttpExchange ex = new MockHttpExchange("POST", "/",
        new MockHttpContext(handler, "/"));
    String request
        = SOAP_HEADER
        + generateAuthzDecisionQuery("http://localhost/doc/1234",
                                     "aoeuaoeu")
        + SOAP_FOOTER;
    String goldenResponse
        = SOAP_HEADER
        + generateGoldenResponse("http://localhost/doc/1234",
                                 "aoeuaoeu",
                                 "Deny")
        + SOAP_FOOTER;
    ex.setRequestBody(stringToStream(request));
    handler.handle(ex);
    assertEquals(200, ex.getResponseCode());
    String response = new String(ex.getResponseBytes(), charset);
    response = massageResponse(response);
    assertEquals(goldenResponse, response);
  }

  @Test
  public void testBrokenAdaptor() throws Exception {
    AuthzAuthority adaptor = new AuthzAuthority() {
      @Override
      public Map<DocId, AuthzStatus> isUserAuthorized(AuthnIdentity identity,
          Collection<DocId> ids) {
        return null;
      }
    };
    SamlBatchAuthzHandler handler = new SamlBatchAuthzHandler(
        adaptor, new MockDocIdCodec(), samlMetadata);
    MockHttpExchange ex = new MockHttpExchange("POST", "/",
        new MockHttpContext(handler, "/"));
    String request
        = SOAP_HEADER
        + generateAuthzDecisionQuery("http://localhost/doc/1234",
                                     "aoeuaoeu")
        + SOAP_FOOTER;
    String goldenResponse
        = SOAP_HEADER
        + generateGoldenResponse("http://localhost/doc/1234",
                                 "aoeuaoeu",
                                 "Deny")
        + SOAP_FOOTER;
    ex.setRequestBody(stringToStream(request));
    handler.handle(ex);
    assertEquals(200, ex.getResponseCode());
    String response = new String(ex.getResponseBytes(), charset);
    response = massageResponse(response);
    assertEquals(goldenResponse, response);
  }

  @Test
  public void testIndeterminateAdaptor() throws Exception {
    AuthzAuthority adaptor = new AuthzAuthority() {
      @Override
      public Map<DocId, AuthzStatus> isUserAuthorized(AuthnIdentity identity,
          Collection<DocId> ids) {
        assertEquals(1, ids.size());
        DocId docId = (DocId) ids.toArray()[0];
        return Collections.singletonMap(docId, AuthzStatus.INDETERMINATE);
      }
    };
    SamlBatchAuthzHandler handler = new SamlBatchAuthzHandler(
        adaptor, new MockDocIdCodec(), samlMetadata);
    MockHttpExchange ex = new MockHttpExchange("POST", "/",
        new MockHttpContext(handler, "/"));
    String request
        = SOAP_HEADER
        + generateAuthzDecisionQuery("http://localhost/doc/1234",
                                     "aoeuaoeu")
        + SOAP_FOOTER;
    String goldenResponse
        = SOAP_HEADER
        + generateGoldenResponse("http://localhost/doc/1234",
                                 "aoeuaoeu",
                                 "Deny")
        + SOAP_FOOTER;
    ex.setRequestBody(stringToStream(request));
    handler.handle(ex);
    assertEquals(200, ex.getResponseCode());
    String response = new String(ex.getResponseBytes(), charset);
    response = massageResponse(response);
    assertEquals(goldenResponse, response);
  }

  @Test
  public void testErroringAdaptor() throws Exception {
    AuthzAuthority adaptor = new AuthzAuthority() {
      @Override
      public Map<DocId, AuthzStatus> isUserAuthorized(AuthnIdentity identity,
          Collection<DocId> ids) {
        throw new RuntimeException("something happened");
      }
    };
    SamlBatchAuthzHandler handler = new SamlBatchAuthzHandler(
        adaptor, new MockDocIdCodec(), samlMetadata);
    MockHttpExchange ex = new MockHttpExchange("POST", "/",
        new MockHttpContext(handler, "/"));
    String request
        = SOAP_HEADER
        + generateAuthzDecisionQuery("http://localhost/doc/1234",
                                     "aoeuaoeu")
        + SOAP_FOOTER;
    String goldenResponse
        = SOAP_HEADER
        + generateGoldenResponse("http://localhost/doc/1234",
                                 "aoeuaoeu",
                                 "Deny")
        + SOAP_FOOTER;
    ex.setRequestBody(stringToStream(request));
    handler.handle(ex);
    assertEquals(200, ex.getResponseCode());
    String response = new String(ex.getResponseBytes(), charset);
    response = massageResponse(response);
    assertEquals(goldenResponse, response);
  }

  @Test
  public void testUnknownResourceHost() throws Exception {
    String request
        = SOAP_HEADER
        + generateAuthzDecisionQuery("http://wronghost/doc/1234",
                                     "aoeuaoeu")
        + SOAP_FOOTER;
    String goldenResponse
        = SOAP_HEADER
        + generateGoldenResponse("http://wronghost/doc/1234",
                                 "aoeuaoeu",
                                 "Indeterminate")
        + SOAP_FOOTER;
    ex.setRequestBody(stringToStream(request));
    handler.handle(ex);
    assertEquals(200, ex.getResponseCode());
    String response = new String(ex.getResponseBytes(), charset);
    response = massageResponse(response);
    assertEquals(goldenResponse, response);
  }

  @Test
  public void testUnknownResourcePort() throws Exception {
    String request
        = SOAP_HEADER
        + generateAuthzDecisionQuery("http://localhost:81/doc/1234",
                                     "aoeuaoeu")
        + SOAP_FOOTER;
    String goldenResponse
        = SOAP_HEADER
        + generateGoldenResponse("http://localhost:81/doc/1234",
                                 "aoeuaoeu",
                                 "Indeterminate")
        + SOAP_FOOTER;
    ex.setRequestBody(stringToStream(request));
    handler.handle(ex);
    assertEquals(200, ex.getResponseCode());
    String response = new String(ex.getResponseBytes(), charset);
    response = massageResponse(response);
    assertEquals(goldenResponse, response);
  }

  @Test
  public void testUnknownResourceScheme() throws Exception {
    String request
        = SOAP_HEADER
        + generateAuthzDecisionQuery("https://localhost/doc/1234",
                                     "aoeuaoeu")
        + SOAP_FOOTER;
    String goldenResponse
        = SOAP_HEADER
        + generateGoldenResponse("https://localhost/doc/1234",
                                 "aoeuaoeu",
                                 "Indeterminate")
        + SOAP_FOOTER;
    ex.setRequestBody(stringToStream(request));
    handler.handle(ex);
    assertEquals(200, ex.getResponseCode());
    String response = new String(ex.getResponseBytes(), charset);
    response = massageResponse(response);
    assertEquals(goldenResponse, response);
  }

  @Test
  public void testMultiRequest() throws Exception {
    String request
        = SOAP_HEADER
        + generateAuthzDecisionQuery("http://localhost/doc/1234",
                                     "aoeuaoeu1")
        + generateAuthzDecisionQuery("http://localhost/doc/1235",
                                     "aoeuaoeu2")
        + generateAuthzDecisionQuery("http://localhost/doc/1236",
                                     "aoeuaoeu3")
        + SOAP_FOOTER;
    String goldenResponse
        = SOAP_HEADER
        + generateGoldenResponse("http://localhost/doc/1234",
                                 "aoeuaoeu1",
                                 "Permit")
        + generateGoldenResponse("http://localhost/doc/1235",
                                 "aoeuaoeu2",
                                 "Permit")
        + generateGoldenResponse("http://localhost/doc/1236",
                                 "aoeuaoeu3",
                                 "Permit")
        + SOAP_FOOTER;
    ex.setRequestBody(stringToStream(request));
    handler.handle(ex);
    assertEquals(200, ex.getResponseCode());
    String response = new String(ex.getResponseBytes(), charset);
    response = massageResponse(response);
    assertEquals(goldenResponse, response);
  }

  @Test
  public void testMultiRequestWithDifferentSubjects() throws Exception {
    String request
        = SOAP_HEADER
        + "<samlp:AuthzDecisionQuery "
        +   "ID=\"aoeuaoeu1\" "
        +   "IssueInstant=\"2009-10-20T17:52:29Z\" "
        +   "Version=\"2.0\" "
        +   "Resource=\"http://localhost/doc/1234\" "
        +   "xmlns:saml=\"urn:oasis:names:tc:SAML:2.0:assertion\" "
        +   "xmlns:samlp=\"urn:oasis:names:tc:SAML:2.0:protocol\">"
        +   "<saml:Subject>"
        +     "<saml:NameID>Polly Hedra</saml:NameID>"
        +   "</saml:Subject>"
        +   "<saml:Action "
        +     "Namespace=\"urn:oasis:names:tc:SAML:1.0:action:ghpp\">"
        +     "GET"
        +   "</saml:Action>"
        + "</samlp:AuthzDecisionQuery>"
        + "<samlp:AuthzDecisionQuery "
        +   "ID=\"aoeuaoeu2\" "
        +   "IssueInstant=\"2009-10-20T17:52:29Z\" "
        +   "Version=\"2.0\" "
        +   "Resource=\"http://localhost/doc/1234\" "
        +   "xmlns:saml=\"urn:oasis:names:tc:SAML:2.0:assertion\" "
        +   "xmlns:samlp=\"urn:oasis:names:tc:SAML:2.0:protocol\">"
        +   "<saml:Subject>"
        +     "<saml:NameID>Some Other Polly Hedra</saml:NameID>"
        +   "</saml:Subject>"
        +   "<saml:Action "
        +     "Namespace=\"urn:oasis:names:tc:SAML:1.0:action:ghpp\">"
        +     "GET"
        +   "</saml:Action>"
        + "</samlp:AuthzDecisionQuery>"
        + SOAP_FOOTER;
    ex.setRequestBody(stringToStream(request));
    handler.handle(ex);
    assertEquals(400, ex.getResponseCode());
  }

  @Test
  public void testBadXml() throws Exception {
    String request
        = SOAP_HEADER;
    ex.setRequestBody(stringToStream(request));
    handler.handle(ex);
    assertEquals(400, ex.getResponseCode());
  }

  @Test
  public void testNoQueries() throws Exception {
    String request
        = SOAP_HEADER + SOAP_FOOTER;
    ex.setRequestBody(stringToStream(request));
    handler.handle(ex);
    assertEquals(400, ex.getResponseCode());
  }

  @Test
  public void testNoResource() throws Exception {
    String request
        = SOAP_HEADER
        + "<samlp:AuthzDecisionQuery "
        +   "ID=\"aoeuaoeu\" "
        +   "IssueInstant=\"2009-10-20T17:52:29Z\" "
        +   "Version=\"2.0\" "
        +   "xmlns:saml=\"urn:oasis:names:tc:SAML:2.0:assertion\" "
        +   "xmlns:samlp=\"urn:oasis:names:tc:SAML:2.0:protocol\">"
        +   "<saml:Subject>"
        +     "<saml:NameID>Polly Hedra</saml:NameID>"
        +   "</saml:Subject>"
        +   "<saml:Action "
        +     "Namespace=\"urn:oasis:names:tc:SAML:1.0:action:ghpp\">"
        +     "GET"
        +   "</saml:Action>"
        + "</samlp:AuthzDecisionQuery>"
        + SOAP_FOOTER;
    ex.setRequestBody(stringToStream(request));
    handler.handle(ex);
    System.out.println(new String(ex.getResponseBytes(), charset));
    assertEquals(400, ex.getResponseCode());
  }

  @Test
  public void testNoSubject() throws Exception {
    String request
        = SOAP_HEADER
        + "<samlp:AuthzDecisionQuery "
        +   "ID=\"aoeuaoeu\" "
        +   "IssueInstant=\"2009-10-20T17:52:29Z\" "
        +   "Version=\"2.0\" "
        +   "Resource=\"http://localhost/doc/1234\" "
        +   "xmlns:saml=\"urn:oasis:names:tc:SAML:2.0:assertion\" "
        +   "xmlns:samlp=\"urn:oasis:names:tc:SAML:2.0:protocol\">"
        +   "<saml:Action "
        +     "Namespace=\"urn:oasis:names:tc:SAML:1.0:action:ghpp\">"
        +     "GET"
        +   "</saml:Action>"
        + "</samlp:AuthzDecisionQuery>"
        + SOAP_FOOTER;
    ex.setRequestBody(stringToStream(request));
    handler.handle(ex);
    System.out.println(new String(ex.getResponseBytes(), charset));
    assertEquals(400, ex.getResponseCode());
  }

  @Test
  public void testNoSubjectNameId() throws Exception {
    String request
        = SOAP_HEADER
        + "<samlp:AuthzDecisionQuery "
        +   "ID=\"aoeuaoeu\" "
        +   "IssueInstant=\"2009-10-20T17:52:29Z\" "
        +   "Version=\"2.0\" "
        +   "Resource=\"http://localhost/doc/1234\" "
        +   "xmlns:saml=\"urn:oasis:names:tc:SAML:2.0:assertion\" "
        +   "xmlns:samlp=\"urn:oasis:names:tc:SAML:2.0:protocol\">"
        +   "<saml:Subject/>"
        +   "<saml:Action "
        +     "Namespace=\"urn:oasis:names:tc:SAML:1.0:action:ghpp\">"
        +     "GET"
        +   "</saml:Action>"
        + "</samlp:AuthzDecisionQuery>"
        + SOAP_FOOTER;
    ex.setRequestBody(stringToStream(request));
    handler.handle(ex);
    System.out.println(new String(ex.getResponseBytes(), charset));
    assertEquals(400, ex.getResponseCode());
  }

  @Test
  public void testEmptySubjectNameId() throws Exception {
    String request
        = SOAP_HEADER
        + "<samlp:AuthzDecisionQuery "
        +   "ID=\"aoeuaoeu\" "
        +   "IssueInstant=\"2009-10-20T17:52:29Z\" "
        +   "Version=\"2.0\" "
        +   "Resource=\"http://localhost/doc/1234\" "
        +   "xmlns:saml=\"urn:oasis:names:tc:SAML:2.0:assertion\" "
        +   "xmlns:samlp=\"urn:oasis:names:tc:SAML:2.0:protocol\">"
        +   "<saml:Subject>"
        +     "<saml:NameID/>"
        +   "</saml:Subject>"
        +   "<saml:Action "
        +     "Namespace=\"urn:oasis:names:tc:SAML:1.0:action:ghpp\">"
        +     "GET"
        +   "</saml:Action>"
        + "</samlp:AuthzDecisionQuery>"
        + SOAP_FOOTER;
    ex.setRequestBody(stringToStream(request));
    handler.handle(ex);
    System.out.println(new String(ex.getResponseBytes(), charset));
    assertEquals(400, ex.getResponseCode());
  }

  private String massageResponse(String response) {
    return response.replaceAll("ID=\"[^\"]+\"", "ID=\"someid\"")
        .replaceAll("IssueInstant=\"[^\"]+\"", "IssueInstant=\"sometime\"");
  }

  private String generateAuthzDecisionQuery(String resource, String id) {
    return "<samlp:AuthzDecisionQuery "
        +     "ID=\"" + id + "\" "
        +     "IssueInstant=\"2009-10-20T17:52:29Z\" "
        +     "Version=\"2.0\" "
        +     "Resource=\"" + resource + "\" "
        +     "xmlns:saml=\"urn:oasis:names:tc:SAML:2.0:assertion\" "
        +     "xmlns:samlp=\"urn:oasis:names:tc:SAML:2.0:protocol\">"
        +     "<saml:Subject>"
        +       "<saml:NameID>Polly Hedra</saml:NameID>"
        +     "</saml:Subject>"
        +     "<saml:Action "
        +       "Namespace=\"urn:oasis:names:tc:SAML:1.0:action:ghpp\">"
        +       "GET"
        +     "</saml:Action>"
        +   "</samlp:AuthzDecisionQuery>";
  }

  private String generateGoldenResponse(String resource, String requestId,
                                        String decision) {
    return "<saml2p:Response "
        +    "ID=\"someid\" "
        +    "InResponseTo=\"" + requestId + "\" "
        +    "IssueInstant=\"sometime\" "
        +    "Version=\"2.0\" "
        +    "xmlns:saml2p=\"urn:oasis:names:tc:SAML:2.0:protocol\">"
        +    "<saml2:Issuer "
        +      "xmlns:saml2=\"urn:oasis:names:tc:SAML:2.0:assertion\">"
        +      "http://google.com/enterprise/gsa/adaptor"
        +    "</saml2:Issuer>"
        +    "<saml2p:Status>"
        +      "<saml2p:StatusCode "
        +        "Value=\"urn:oasis:names:tc:SAML:2.0:status:Success\"/>"
        +    "</saml2p:Status>"
        +    "<saml2:Assertion "
        +      "ID=\"someid\" "
        +      "IssueInstant=\"sometime\" "
        +      "Version=\"2.0\" "
        +      "xmlns:saml2=\"urn:oasis:names:tc:SAML:2.0:assertion\">"
        +      "<saml2:Issuer>"
        +        "http://google.com/enterprise/gsa/adaptor"
        +      "</saml2:Issuer>"
        +      "<saml2:Subject>"
        +        "<saml2:NameID>Polly Hedra</saml2:NameID>"
        +      "</saml2:Subject>"
        +      "<saml2:AuthzDecisionStatement "
        +        "Decision=\"" + decision + "\" "
        +        "Resource=\"" + resource + "\">"
        +        "<saml2:Action "
        +          "Namespace=\"urn:oasis:names:tc:SAML:1.0:action:ghpp\">"
        +          "GET"
        +        "</saml2:Action>"
        +      "</saml2:AuthzDecisionStatement>"
        +    "</saml2:Assertion>"
        +  "</saml2p:Response>";
  }

  private InputStream stringToStream(String str) {
    return new ByteArrayInputStream(str.getBytes(charset));
  }
}
