/*
 * Copyright 2005-2010 the original author or authors.
 *
 * 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 org.springframework.ldap.core.support;

import java.util.Hashtable;

import javax.naming.NamingException;
import javax.naming.directory.DirContext;

import org.springframework.ldap.core.AuthenticationSource;
import org.springframework.ldap.core.ContextSource;

/**
 * A strategy to use when authenticating LDAP connections on creation. When
 * authenticating LDAP connections different strategies are needed depending on
 * the authentication mechanism used. Furthermore, depending on the mechanism
 * the work to be done needs to be applied at different stages of the
 * <code>DirContext</code> creation process. A
 * DirContextAuthenticationStrategy contains the logic to perform a particular
 * type of authentication mechanism and will be called by its
 * {@link ContextSource} at appropriate stages of the process.
 * 
 * @author Mattias Hellborg Arthursson
 */
public interface DirContextAuthenticationStrategy {

	/**
	 * This method is responsible for preparing the environment to be used when
	 * creating the <code>DirContext</code> instance. The base environment
	 * (including URL, <code>ContextFactory</code> etc. will already be set,
	 * and this method is called just before the actual Context is to be
	 * created.
	 * 
	 * @param env The <code>Hashtable</code> to be sent to the
	 * <code>DirContext</code> instance on initialization. Pre-configured with
	 * the basic settings; the implementation of this method is responsible for
	 * manipulating the environment as appropriate for the particular
	 * authentication mechanism.
	 * @param userDn the user DN to authenticate, as received from the
	 * {@link AuthenticationSource} of the {@link ContextSource}.
	 * @param password the password to authenticate with, as received from the
	 * {@link AuthenticationSource} of the {@link ContextSource}.
	 * @throws NamingException if anything goes wrong. This will cause the
	 * <code>DirContext</code> creation to be aborted and the exception to be
	 * translated and rethrown.
	 */
	public void setupEnvironment(Hashtable env, String userDn, String password) throws NamingException;

	/**
	 * This method is responsible for post-processing the
	 * <code>DirContext</code> instance after it has been created. It will be
	 * called immediately after the instance has been created. Some
	 * authentication mechanisms, e.g. TLS, require particular stuff to happen
	 * before the actual target Context is closed. This method provides the
	 * possibility to replace or wrap the actual DirContext with a proxy so that
	 * any calls on it may be intercepted.
	 * 
	 * @param ctx the freshly created <code>DirContext</code> instance. The
	 * actual implementation class (e.g. <code>InitialLdapContext</code>)
	 * depends on the {@link ContextSource} implementation.
	 * @param userDn the user DN to authenticate, as received from the
	 * {@link AuthenticationSource} of the {@link ContextSource}.
	 * @param password the password to authenticate with, as received from the
	 * {@link AuthenticationSource} of the {@link ContextSource}.
	 * @return the DirContext, possibly modified, replaced or wrapped.
	 * @throws NamingException if anything goes wrong. This will cause the
	 * <code>DirContext</code> creation to be aborted and the exception to be
	 * translated and rethrown.
	 */
	public DirContext processContextAfterCreation(DirContext ctx, String userDn, String password)
			throws NamingException;

}
