// 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.assertEquals;
import static org.junit.Assert.assertTrue;

import com.sun.net.httpserver.HttpExchange;

import org.junit.BeforeClass;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;

import java.io.IOException;
import java.util.Arrays;
import java.util.Set;
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;
    }
  }
}
