// 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 org.junit.Assert.*;

import com.sun.net.httpserver.HttpExchange;

import org.junit.*;
import org.junit.rules.ExpectedException;

import java.io.IOException;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.xml.bind.DatatypeConverter;

/**
 * Test cases for {@link SamlIdentityProvider}.
 */
public class SamlIdentityProviderTest {
  @Rule
  public ExpectedException thrown = ExpectedException.none();

  private SamlMetadata metadata = new SamlMetadata(
      "bruteforce.mtv.corp.google.com", 5678,
      "entyo36.hot.corp.google.com",
      "http://google.com/enterprise/gsa/security-manager",
      "http://google.com/enterprise/gsa/adaptor");
  private UserPrincipal user = new UserPrincipal("user1");
  private Set<GroupPrincipal> groups = GroupPrincipal.makeSet(Arrays.asList(
      "group1", "group2"));
  private AuthnAuthority adaptor = new AuthnAuthorityImpl();
  private SamlIdentityProvider identityProvider = new SamlIdentityProvider(
      adaptor, metadata, null);
  private MockHttpContext httpContext = new MockHttpsContext(null, "/samlip");

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

  @Test
  public void testNullAdaptor() {
    thrown.expect(NullPointerException.class);
    new SamlIdentityProvider(null, metadata, null);
  }

  @Test
  public void testNullMetadata() {
    thrown.expect(NullPointerException.class);
    new SamlIdentityProvider(adaptor, null, null);
  }

  @Test
  public void testNormalFlow() throws Exception {
    MockHttpExchange ex = new MockHttpExchange("GET", "/samlip?"
        + "SAMLRequest=fZJdb5swFIbv%2Byss3wPGGSGxAlW2rh9Su0UN3cVuJsc5IZbApj4GNf"
          + "%2B%2BBJIq26Te2dbx8x6fx4vrt7oiHTjU1mQ0DhklYJTdalNm9KW4DWb0Or9aoKwr"
          + "3ohl6%2FfmGV5bQE%2BWiOB8f%2B%2BbNdjW4NbgOq3g5fkxo3vvGxRRBMYf7GQa7q"
          + "0PlXVNWFpbVtCv6whBtU77Q1BLI0tw0TFFnqnqRKXkpk%2FTRvqhxTN441oPO%2BsU"
          + "hLXv%2FmWLZJrOBp5uKHm4yegfmG%2BTlCXzSTqFhM3TL0pylc53G57GkM52fRmu%2"
          + "BnTdQUZ3skI4nmALDwa9ND6jnMWTgMUBTwrGRMwFY%2BF0xn9TsnLWW2Wrr9qMk2ud"
          + "EVaiRmFkDSi8Euvl06PgIRObsQjFfVGsgtXPdTEAOr0F96Ovzujd8A7y3XhwjdMIZH"
          + "0aFXkaR0XJr7MzfnTWWzQoRkufpzenVmk%2BShXDG90l4XPAhyCaH130Ki6UwkfLUY"
          + "nyP8OL6DIzP23%2F%2Flf5Ow%3D%3D", httpContext);
    ex.getRequestHeaders().set("Host", "bruteforce.mtv.corp.google.com:5678");
    identityProvider.getSingleSignOnHandler().handle(ex);
    assertEquals(200, ex.getResponseCode());
    String response = new String(ex.getResponseBytes(), "UTF-8");
    assertTrue(response.contains("action=\"https://entyo36.hot.corp.google.com/"
        + "security-manager/samlassertionconsumer\""));
    assertTrue(response.contains("SAMLResponse"));
    Matcher m = Pattern.compile(" name=\"SAMLResponse\" value=\"([^\"]*)\"")
        .matcher(response);
    assertTrue(m.find());
    String samlResponse = new String(
        DatatypeConverter.parseBase64Binary(m.group(1)), "UTF-8");
    assertTrue(samlResponse.contains("https://entyo36.hot.corp.google.com/"
        + "security-manager/samlassertionconsumer"));
    assertTrue(samlResponse.contains("user1"));
    assertTrue(samlResponse.contains(
        "<saml2:AttributeStatement><saml2:Attribute Name=\"member-of\">"
        + "<saml2:AttributeValue>group1</saml2:AttributeValue>"
        + "<saml2:AttributeValue>group2</saml2:AttributeValue>"
        + "</saml2:Attribute></saml2:AttributeStatement>"));
  }

  @Test
  public void testWrongMethod() throws Exception {
    MockHttpExchange ex = new MockHttpExchange("POST", "/samlip",
        httpContext);
    identityProvider.getSingleSignOnHandler().handle(ex);
    assertEquals(405, ex.getResponseCode());
  }

  @Test
  public void testWrongPath() throws Exception {
    MockHttpExchange ex = new MockHttpExchange("GET", "/samlipMORE",
        httpContext);
    identityProvider.getSingleSignOnHandler().handle(ex);
    assertEquals(404, ex.getResponseCode());
  }

  private class AuthnAuthorityImpl implements AuthnAuthority {
    @Override
    public void authenticateUser(HttpExchange ex, Callback callback)
        throws IOException {
      callback.userAuthenticated(ex, new AuthnIdentityImpl());
    }
  }

  private class AuthnIdentityImpl implements AuthnIdentity {
    @Override
    public UserPrincipal getUser() {
      return user;
    }

    @Override
    public Set<GroupPrincipal> getGroups() {
      return groups;
    }

    @Override
    public String getPassword() {
      return null;
    }
  }
}
