/*
 *  Licensed to the Apache Software Foundation (ASF) under one
 *  or more contributor license agreements.  See the NOTICE file
 *  distributed with this work for additional information
 *  regarding copyright ownership.  The ASF licenses this file
 *  to you 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.apache.directory.server;


import org.apache.directory.server.core.entry.DefaultServerEntry;
import org.apache.directory.server.core.entry.ServerEntry;
import org.apache.directory.server.core.interceptor.Interceptor;
import org.apache.directory.server.core.kerberos.PasswordPolicyInterceptor;
import org.apache.directory.server.core.partition.Partition;
import org.apache.directory.server.core.partition.impl.btree.Index;
import org.apache.directory.server.core.partition.impl.btree.jdbm.JdbmIndex;
import org.apache.directory.server.core.partition.impl.btree.jdbm.JdbmPartition;
import org.apache.directory.server.unit.AbstractServerTest;
import org.apache.directory.shared.ldap.message.AttributeImpl;
import org.apache.directory.shared.ldap.message.AttributesImpl;
import org.apache.directory.shared.ldap.name.LdapDN;

import javax.naming.NamingException;
import javax.naming.directory.Attribute;
import javax.naming.directory.Attributes;
import javax.naming.directory.DirContext;
import javax.naming.directory.InitialDirContext;
import java.util.HashSet;
import java.util.Hashtable;
import java.util.List;
import java.util.Set;


/**
 * An {@link AbstractServerTest} testing the (@link {@link PasswordPolicyInterceptor}.
 * 
 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
 * @version $Rev$, $Date$
 */
public class PasswordPolicyServiceITest extends AbstractServerTest
{
    private DirContext ctx;
    private DirContext users;


    /**
     * Set up a partition for EXAMPLE.COM, add the {@link PasswordPolicyInterceptor}
     * interceptor, and create a users subcontext.
     */
    public void setUp() throws Exception
    {
        super.setUp();
        setAllowAnonymousAccess( false );

        Attributes attrs;


        Hashtable<String, String> env = new Hashtable<String, String>();
        env.put( "java.naming.factory.initial", "com.sun.jndi.ldap.LdapCtxFactory" );
        env.put( "java.naming.provider.url", "ldap://localhost:" + port + "/dc=example,dc=com" );
        env.put( "java.naming.security.principal", "uid=admin,ou=system" );
        env.put( "java.naming.security.credentials", "secret" );
        env.put( "java.naming.security.authentication", "simple" );
        ctx = new InitialDirContext( env );

        attrs = getOrgUnitAttributes( "users" );
        users = ctx.createSubcontext( "ou=users", attrs );
    }

    protected void configureDirectoryService() throws NamingException
    {
        Set<Partition> partitions = new HashSet<Partition>();

        // Add partition 'example'
        JdbmPartition partition = new JdbmPartition();
        partition.setId( "example" );
        partition.setSuffix( "dc=example,dc=com" );

        Set<Index> indexedAttrs = new HashSet<Index>();
        indexedAttrs.add( new JdbmIndex( "ou" ) );
        indexedAttrs.add( new JdbmIndex( "dc" ) );
        indexedAttrs.add( new JdbmIndex( "objectClass" ) );
        partition.setIndexedAttributes( indexedAttrs );

        LdapDN exampleDn = new LdapDN( "dc=example,dc=com" );
        ServerEntry serverEntry = new DefaultServerEntry( directoryService.getRegistries(), exampleDn );
        serverEntry.put( "objectClass", "top", "domain" );
        serverEntry.put( "dc", "example" );
        
        partition.setContextEntry( serverEntry );

        partitions.add( partition );
        directoryService.setPartitions( partitions );

        List<Interceptor> list = directoryService.getInterceptors();

        list.add( new PasswordPolicyInterceptor() );
        directoryService.setInterceptors( list );
    }


    /**
     * Tests that passwords that are too short are properly rejected. 
     */
    public void testLength()
    {
        Attributes attrs = getPersonAttributes( "Nelson", "Horatio Nelson", "hnelson", "HN1" );
        try
        {
            users.createSubcontext( "uid=hnelson", attrs );
            fail( "Shouldn't have gotten here." );
        }
        catch ( NamingException ne )
        {
            assertTrue( ne.getMessage().contains( "length too short" ) );
            assertFalse( ne.getMessage().contains( "insufficient character mix" ) );
            assertFalse( ne.getMessage().contains( "contains portions of username" ) );
        }
    }


    /**
     * Tests that passwords with insufficient character mix are properly rejected. 
     */
    public void testCharacterMix()
    {
        Attributes attrs = getPersonAttributes( "Nelson", "Horatio Nelson", "hnelson", "secret" );
        try
        {
            users.createSubcontext( "uid=hnelson", attrs );
            fail( "Shouldn't have gotten here." );
        }
        catch ( NamingException ne )
        {
            assertFalse( ne.getMessage().contains( "length too short" ) );
            assertTrue( ne.getMessage().contains( "insufficient character mix" ) );
            assertFalse( ne.getMessage().contains( "contains portions of username" ) );
        }
    }


    /**
     * Tests that passwords that contain substrings of the username are properly rejected. 
     */
    public void testContainsUsername()
    {
        Attributes attrs = getPersonAttributes( "Nelson", "Horatio Nelson", "hnelson", "A1nelson" );
        try
        {
            users.createSubcontext( "uid=hnelson", attrs );
            fail( "Shouldn't have gotten here." );
        }
        catch ( NamingException ne )
        {
            assertFalse( ne.getMessage().contains( "length too short" ) );
            assertFalse( ne.getMessage().contains( "insufficient character mix" ) );
            assertTrue( ne.getMessage().contains( "contains portions of username" ) );
        }
    }


    /**
     * Tests that passwords with insufficient character mix and that are too
     * short are properly rejected. 
     */
    public void testCharacterMixAndLength()
    {
        Attributes attrs = getPersonAttributes( "Nelson", "Horatio Nelson", "hnelson", "hi" );
        try
        {
            users.createSubcontext( "uid=hnelson", attrs );
            fail( "Shouldn't have gotten here." );
        }
        catch ( NamingException ne )
        {
            assertTrue( ne.getMessage().contains( "length too short" ) );
            assertTrue( ne.getMessage().contains( "insufficient character mix" ) );
            assertFalse( ne.getMessage().contains( "contains portions of username" ) );
        }
    }


    /**
     * Tests that passwords that are too short and that contain substrings of
     * the username are properly rejected.
     */
    public void testLengthAndContainsUsername()
    {
        Attributes attrs = getPersonAttributes( "Bush", "William Bush", "wbush", "bush1" );
        try
        {
            users.createSubcontext( "uid=wbush", attrs );
            fail( "Shouldn't have gotten here." );
        }
        catch ( NamingException ne )
        {
            assertTrue( ne.getMessage().contains( "length too short" ) );
            assertFalse( ne.getMessage().contains( "insufficient character mix" ) );
            assertTrue( ne.getMessage().contains( "contains portions of username" ) );
        }
    }


    /**
     * Tests that passwords with insufficient character mix and that contain substrings of
     * the username are properly rejected.
     */
    public void testCharacterMixAndContainsUsername()
    {
        Attributes attrs = getPersonAttributes( "Nelson", "Horatio Nelson", "hnelson", "hnelson" );
        try
        {
            users.createSubcontext( "uid=hnelson", attrs );
            fail( "Shouldn't have gotten here." );
        }
        catch ( NamingException ne )
        {
            assertFalse( ne.getMessage().contains( "length too short" ) );
            assertTrue( ne.getMessage().contains( "insufficient character mix" ) );
            assertTrue( ne.getMessage().contains( "contains portions of username" ) );
        }
    }


    /**
     * Tests that passwords with insufficient character mix and that are too
     * short and that contain substrings of the username are properly rejected.
     */
    public void testCharacterMixAndLengthAndContainsUsername()
    {
        Attributes attrs = getPersonAttributes( "Bush", "William Bush", "wbush", "bush" );
        try
        {
            users.createSubcontext( "uid=wbush", attrs );
            fail( "Shouldn't have gotten here." );
        }
        catch ( NamingException ne )
        {
            assertTrue( ne.getMessage().contains( "length too short" ) );
            assertTrue( ne.getMessage().contains( "insufficient character mix" ) );
            assertTrue( ne.getMessage().contains( "contains portions of username" ) );
        }
    }


    /**
     * Tear down.
     */
    public void tearDown() throws Exception
    {
        ctx.close();
        ctx = null;
        super.tearDown();
    }


    /**
     * Convenience method for creating a person.
     */
    protected Attributes getPersonAttributes( String sn, String cn, String uid, String userPassword )
    {
        Attributes attrs = new AttributesImpl();
        Attribute ocls = new AttributeImpl( "objectClass" );
        ocls.add( "top" );
        ocls.add( "person" ); // sn $ cn
        ocls.add( "inetOrgPerson" ); // uid
        attrs.put( ocls );
        attrs.put( "cn", cn );
        attrs.put( "sn", sn );
        attrs.put( "uid", uid );
        attrs.put( "userPassword", userPassword );

        return attrs;
    }


    /**
     * Convenience method for creating an organizational unit.
     */
    protected Attributes getOrgUnitAttributes( String ou )
    {
        Attributes attrs = new AttributesImpl();
        Attribute ocls = new AttributeImpl( "objectClass" );
        ocls.add( "top" );
        ocls.add( "organizationalUnit" );
        attrs.put( ocls );
        attrs.put( "ou", ou );

        return attrs;
    }
}
