/*
 *   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.fortress.realm;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.security.Principal;
import java.util.NoSuchElementException;
import java.util.Set;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.directory.fortress.core.GlobalIds;
import org.apache.directory.fortress.core.ReviewMgr;
import org.apache.directory.fortress.core.ReviewMgrFactory;
import org.apache.directory.fortress.core.AccessMgr;
import org.apache.directory.fortress.core.AccessMgrFactory;
import org.apache.directory.fortress.core.SecurityException;
import org.apache.directory.fortress.core.GlobalErrIds;
import org.apache.directory.fortress.core.model.User;
import org.apache.directory.fortress.core.model.Role;
import org.apache.directory.fortress.core.model.Session;
import org.apache.directory.fortress.core.util.VUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * This class contains common functions for container managed security.  These APIs may be called by external programs as needed though the expected
 * practice for external app usage  is to call Apache Fortress Core APIs, e.g. {@link org.apache.directory.fortress.core.AccessMgr} and {@link org.apache.directory.fortress.core.ReviewMgr}.
 * This class is NOT thread safe if contextId is set.
 *
 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
 */
public class J2eePolicyMgrImpl implements J2eePolicyMgr
{
    private static final String CLS_NM = J2eePolicyMgrImpl.class.getName();
    private static final Logger LOG = LoggerFactory.getLogger( CLS_NM );
    private AccessMgr accessMgr;
    private ReviewMgr reviewMgr;
    private static final String SESSION = "session";
    private String contextId;

    J2eePolicyMgrImpl ()
    {
        try
        {
            accessMgr = AccessMgrFactory.createInstance( );
            reviewMgr = ReviewMgrFactory.createInstance( );
            LOG.info( "{} - constructed", CLS_NM );
        }
        catch ( SecurityException se )
        {
            LOG.error( "{} caught SecurityException={}", CLS_NM, se );
        }
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public boolean authenticate( String userId, String password ) throws SecurityException
    {
        boolean result = false;
        Session session = accessMgr.authenticate( userId, password );
        
        if ( session != null )
        {
            result = true;
            LOG.debug( "{}.authenticate userId [{}], successful", CLS_NM, userId );
        }
        else
        {
            LOG.debug( "{}.authenticate userId [{}], failed", CLS_NM, userId );
        }

        return result;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public TcPrincipal createSession( String userId, String password ) throws SecurityException
    {
        User user = new User( userId, new String ( password ) );
        
        return createSession( user );
    }

    /**
     * {@inheritDoc}
     */
    public TcPrincipal createSession( String userId, String password, List<String> roles ) throws SecurityException
    {
        User user = new User( userId, new String ( password ) );
        
        // Load the passed in role list into list of User requested roles:
        if ( CollectionUtils.isNotEmpty( roles ) )
        {
            for(String role : roles)
            {
                user.setRoleName( role );
            }
        }
        
        return createSession( user );
    }

    /**
     * {@inheritDoc}
     */
    private TcPrincipal createSession( User user ) throws SecurityException
    {
        Session session = accessMgr.createSession( user, false );
        LOG.debug( "{}.createSession userId [{}], successful", CLS_NM, user.getUserId() );
        HashMap<String, Object> context = new HashMap<String, Object>();
        context.put( SESSION, session );

        // now serialize the principal:
        String ser = serialize( session );

        // Store the serialized principal inside the context hashmap
        // which allows overriden toString to return it later, from within an application thread.
        // This facilitates assertion of rbac session from the tomcat realm into the web application session.
        context.put( TcPrincipal.SERIALIZED, ser );
        
        return new TcPrincipal( user.getUserId(), context );
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public Session createSession( User user, boolean isTrusted ) throws SecurityException
    {
        LOG.debug( "{}.createSession userId [{}], isTrusted [{}]", CLS_NM, user.getUserId(), isTrusted );
        
        return accessMgr.createSession( user, isTrusted );
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public boolean hasRole( Principal principal, String roleName ) throws SecurityException
    {
        String fullMethodName = CLS_NM + ".hasRole";
        LOG.debug( "{}.hasRole userId [{}], role [{}]", CLS_NM, principal.getName(), roleName );

        // Fail closed
        boolean result = false;

        // Principal must contain a HashMap that contains a Fortress session object.
        HashMap<String, Object> context = ( ( TcPrincipal ) principal ).getContext();
        VUtil.assertNotNull( context, GlobalErrIds.SESS_CTXT_NULL, fullMethodName );

        // This Map must contain a Fortress Session:
        Session session = (Session)context.get( SESSION );
        VUtil.assertNotNull( session, GlobalErrIds.USER_SESS_NULL, fullMethodName );

        Set<String> authZRoles = accessMgr.authorizedRoles( session );
        
        if ( ( authZRoles != null ) && ( authZRoles.size() > 0 ) )
        {
            // Does the set of authorized roles contain a name matched to the one passed in?
            if ( authZRoles.contains( roleName ) )
            {
                // Yes, we have a match.
                LOG.debug( "{} userId [{}], role [{}], successful", fullMethodName, principal.getName(), roleName );
                result = true;
            }
            else
            {
                // User is not authorized in their Session..
                LOG.debug( "{} userId [{}], is not authorized role [{}]", fullMethodName, principal.getName(), roleName );
            }
        }
        else
        {
            // User does not have any authorized Roles in their Session..
            LOG.info( "{} userId [{}], role [{}], has no authorized roles", fullMethodName, principal.getName(), roleName );
        }
        
        return result;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public Role readRole( String roleName ) throws SecurityException
    {
        return reviewMgr.readRole( new Role( roleName ) );
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public List<String> searchRoles(String searchString, int limit ) throws SecurityException
    {
        return reviewMgr.findRoles( searchString, limit );
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public User readUser( String userId ) throws SecurityException
    {
        return reviewMgr.readUser( new User( userId ) );
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public List<String> searchUsers(String searchString, int limit ) throws SecurityException
    {
        return reviewMgr.findUsers( new User( searchString ), limit );
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public List<String> assignedUsers( String roleName, int limit ) throws SecurityException
    {
        return reviewMgr.assignedUsers( new Role( roleName ), limit );
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public List<String> authorizedRoles( String userId ) throws SecurityException
    {
        List<String> list = null;
        // This will check temporal constraints on User and Roles.
        Session session = createSession( new User( userId ), true );
        // Get the Set of authorized Roles.
        Set<String> authZRoleSet = accessMgr.authorizedRoles( session );
        
        // If User has authorized roles.
        if ( ( authZRoleSet != null ) && ( authZRoleSet.size() > 0 ) )
        {
            // Convert the Set into a List before returning:
            list = new ArrayList<String>( authZRoleSet );
        }
        
        return list;
    }

    /**
     * Utility to write any object into a Base64 string.  Used by this class to serialize {@link TcPrincipal} object to be returned by its toString method..
     */
    private String serialize( Object obj ) throws SecurityException
    {
        String szRetVal = null;
        
        if ( obj != null )
        {
            try
            {
                ByteArrayOutputStream bo = new ByteArrayOutputStream();
                ObjectOutputStream so = new ObjectOutputStream( bo );
                so.writeObject( obj );
                so.flush();
                
                // This encoding induces a bijection between byte[] and String (unlike UTF-8)
                szRetVal = bo.toString( "ISO-8859-1" );
            }
            catch ( IOException ioe )
            {
                String error = "serialize caught IOException: " + ioe;
                throw new SecurityException( org.apache.directory.fortress.realm.GlobalIds.CONTEXT_SERIALIZATION_FAILED, error, ioe );
            }
        }
        
        return szRetVal;
    }

    /**
     * {@inheritDoc}
     */
    public Session deserialize( String str ) throws SecurityException
    {
        // deserialize the object
        try
        {
            // This encoding induces a bijection between byte[] and String (unlike UTF-8)
            byte b[] = str.getBytes("ISO-8859-1");
            ByteArrayInputStream bi = new ByteArrayInputStream(b);
            ObjectInputStream si = new ObjectInputStream(bi);
            return Session.class.cast(si.readObject());
        }
        catch (java.io.UnsupportedEncodingException e)
        {
            throw new SecurityException( org.apache.directory.fortress.realm.GlobalIds.CONTEXT_DESERIALIZATION_FAILED_UNSUPPORTED_ENCODING, "deserialize caught UnsupportedEncodingException:" + e, e );
        }
        catch (IOException e)
        {
            LOG.warn( "deserialize caught IOException:" + e);
            throw new SecurityException( org.apache.directory.fortress.realm.GlobalIds.CONTEXT_DESERIALIZATION_FAILED_IO, "deserialize caught IOException:" + e, e );
        }
        catch (ClassNotFoundException e)
        {
            LOG.warn( "deserialize caught ClassNotFoundException:" + e);
            throw new SecurityException( org.apache.directory.fortress.realm.GlobalIds.CONTEXT_DESERIALIZATION_FAILED_CLASS_NOT_FOUND, "deserialize caught ClassNotFoundException:" + e, e );
        }
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public final void setContextId(String contextId)
    {
        this.contextId = contextId;
        accessMgr.setContextId( contextId );
        reviewMgr.setContextId( contextId );
    }
}