/*
 *   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.web.control;

import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.directory.fortress.core.*;
import org.apache.directory.fortress.core.SecurityException;
import org.apache.directory.fortress.core.util.Config;
import org.apache.directory.fortress.core.model.UserRole;
import org.apache.directory.fortress.core.model.Warning;
import org.apache.directory.fortress.realm.*;
import org.apache.directory.fortress.realm.GlobalIds;
import org.apache.wicket.Component;
import org.apache.directory.fortress.core.model.Permission;
import org.apache.directory.fortress.core.model.Session;
import org.apache.directory.fortress.core.model.User;
import org.apache.wicket.ajax.AjaxRequestTarget;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import jakarta.servlet.http.HttpServletRequest;
import java.security.Principal;
import java.util.List;

/**
 * Common static utils and wrappers used by Wicket web apps to make fortress style security calls.
 *
 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
 * @version $Rev$
 */
public class SecUtils
{
    //private static final Logger LOG = LoggerFactory.getLogger( SecUtils.class.getName() );
    private static final Logger LOG = LoggerFactory.getLogger( SecUtils.class.getName() );
    private static final String PERMS_CACHED = "perms.cached";
    public static final boolean IS_PERM_CACHED = ( ( Config.getInstance().getProperty( PERMS_CACHED ) != null ) && ( Config.getInstance()
        .getProperty( PERMS_CACHED ).equalsIgnoreCase( "true" ) ) );

    /**
     * Return the fortress session that is cached within the wicket session object.
     *
     * @param component needed to get handle to wicket session.
     * @return fortress session object.
     */
    public static Session getSession(Component component)
    {
        return ( ( WicketSession ) component.getSession() ).getSession();
    }

    /**
     *  Used when web app needs to create a 'trusted' fortress session.
     *
     *  Does not check user's password.
     *
     * @param accessMgr fortress access mgr apis
     * @param userId required for rbac session creation.
     * @return rbac session.
     */
    public static Session createSession(AccessMgr accessMgr, String userId)
    {
        Session session;
        try
        {
            // Create an RBAC session and attach to Wicket session:
            session = accessMgr.createSession( new User( userId ), true );
            String message = "RBAC Session successfully created for userId: " + session.getUserId();
            LOG.debug( message );
        }
        catch ( org.apache.directory.fortress.core.SecurityException se )
        {
            String error = "createSession caught SecurityException=" + se;
            LOG.error( error );
            throw new RuntimeException( error );
        }
        return session;
    }

    /**
     * Here the wicket session is loaded with the fortress session and permissions.
     *
     *
     * @param delAccessMgr needed to pull back fortress arbac permissions.
     * @param session needed for call into accessMgr.
     */
    public static void loadPermissionsIntoSession( DelAccessMgr delAccessMgr, Session session)
    {
        try
        {
            // Retrieve user permissions and attach fortress session to Wicket session:
            ( ( WicketSession ) WicketSession.get() ).setSession( session );
            List<Permission> permissions = delAccessMgr.sessionPermissions( session );
            ( ( WicketSession ) WicketSession.get() ).setPermissions( permissions );
            String message = "Session successfully created for userId: " + session.getUserId();
            LOG.debug( message );
        }
        catch ( org.apache.directory.fortress.core.SecurityException se )
        {
            String error = "loadPermissionsIntoSession caught SecurityException=" + se;
            LOG.error( error );
            throw new RuntimeException( error );
        }
    }

    /**
     * Returns the fortress arbac perms that are cashed in the wicket session.
     *
     * @param component needed to get a handle on the wicket session object.
     * @return collection of fortress admin perms.
     */
    public static List<Permission> getPermissions(Component component)
    {
        List<Permission> perms;
        try
        {
            WicketSession wSess = ( WicketSession )component.getSession();
            perms = wSess.getPermissions();
        }
        catch(Exception e)
        {
            String error = "getPermissions caught Exception=" + e;
            LOG.error( error );
            throw new RuntimeException( error );
        }
        return perms;
    }

    /**
     * Retrieve RBAC session permissions from Fortress and place in the Wicket session.
     */
    public static void getPermissions( Component component, AccessMgr accessMgr )
    {
        try
        {
            if ( IS_PERM_CACHED )
            {
                WicketSession session = ( WicketSession ) component.getSession();
                List<Permission> permissions = accessMgr.sessionPermissions( session.getSession() );
                ( ( WicketSession ) WicketSession.get() ).setPermissions( permissions );
            }
        }
        catch ( org.apache.directory.fortress.core.SecurityException se )
        {
            String error = "getPermissions caught SecurityException=" + se;
            LOG.error( error );
            throw new RuntimeException( error );
        }
    }

    /**
     * Wrapper for the httpservlet isUserInRole api.
     *
     * @param roleName contains the name of role being checked.
     * @param servletReq handle used to make inquiry.
     * @return true if authorized, false otherwise.
     */
    public static boolean isAuthorized( String roleName, HttpServletRequest servletReq )
    {
        boolean isAuthorized = false;
        if ( servletReq.isUserInRole( roleName ) )
        {
            isAuthorized = true;
        }
        return isAuthorized;
    }

    /**
     * Is the supplied permission in the wicket session cache?  Called by buttons.
     * if not found, button will be invisible.
     *
     * @param permission fortress perm requires {link @Permission#objName} and {link @Permission#opName} are set.
     * @param component needed to get handle on the wicket session object.
     * @return true if found, false otherwise
     */
    public static boolean isFound( Permission permission, Component component )
    {
        List<Permission> permissions = SecUtils.getPermissions( component );
        return CollectionUtils.isNotEmpty( permissions ) && permissions.contains( permission );
    }

    /**
     * Wrapper to fortress checkAccess api.
     *
     * @param component contains the wicket session handle.
     * @param accessMgr has the checkAccess api
     * @param objName string value
     * @param opName string value
     * @param objId string value
     * @return true if success, false otherwise.
     * @throws org.apache.directory.fortress.core.SecurityException checked exception for system errors.
     */
    public static boolean checkAccess(Component component, AccessMgr accessMgr, String objName, String opName, String objId ) throws org.apache.directory.fortress.core.SecurityException
    {
        WicketSession session = ( WicketSession )component.getSession();
        Permission permission = new Permission( objName, opName, objId );
        return accessMgr.checkAccess( session.getSession(), permission );
    }

    /**
     * Convert the principal into fortress session and load into wicket session along with perms.
     *
     * @param component contains handle to wicket session.
     * @param j2eePolicyMgr used to call deserize api
     * @param accessMgr used to call fortress api for role op
     * @param szPrincipal contains the instance of fortress session deserialized.
     */
    public static void initializeSession(Component component, J2eePolicyMgr j2eePolicyMgr, AccessMgr accessMgr, String szPrincipal ) throws SecurityException
    {
        Session realmSession = null;

        if(j2eePolicyMgr == null || accessMgr == null)
        {
            throw new SecurityException( GlobalIds.SESSION_INITIALIZATION_FAILED, "initializeSession failed - verify the injection of fortress spring beans into your application" );
        }
        try
        {
            if( StringUtils.isNotEmpty( szPrincipal ))
                realmSession = j2eePolicyMgr.deserialize( szPrincipal );
        }
        catch( SecurityException se )
        {
            throw new RuntimeException( se );
        }
        if(realmSession != null)
        {
            synchronized ( ( WicketSession ) WicketSession.get() )
            {
                if ( SecUtils.getSession( component ) == null )
                {
                    LOG.info( "realmSession user: " + realmSession.getUserId() );
                    // Retrieve user permissions and attach RBAC session to Wicket session:
                    ( ( WicketSession ) WicketSession.get() ).setSession( realmSession );
                    getPermissions( component, accessMgr );
                }
            }
        }
    }

    /**
     * Call RBAC addActiveRole to activate a new role into user's session.
     * This routine must first retrieves the wicket session.
     * It is needed because it contains the fortress session which is required for api.
     * Next it invokes the fortress addActiveRole method.
     * If all successful refresh user's perms cached as they've changed.
     *
     * @param component contains handle to wicket session.
     * @param target used to display modal if something goes wrong
     * @param accessMgr used to call fortress api for role op
     * @param roleName contains the role name target
     * @return true if success, false otherwise.
     */
    public static boolean addActiveRole( Component component, AjaxRequestTarget target, AccessMgr accessMgr, String roleName )
    {
        boolean isSuccessful = false;
        try
        {
            WicketSession session = ( WicketSession ) component.getSession();
            session.getSession().setWarnings( null );
            accessMgr.addActiveRole( session.getSession(), new UserRole( roleName ) );
            List<Warning> warnings = session.getSession().getWarnings();
            if ( CollectionUtils.isNotEmpty( warnings ) )
            {
                for ( Warning warning : warnings )
                {
                    LOG.info( "Warning: " + warning.getMsg() + " errCode: " + warning.getId() + " name: " + warning
                        .getName() + " type: " + warning.getType().toString() );
                    if ( warning.getType() == Warning.Type.ROLE && warning.getName().equalsIgnoreCase( roleName ) )
                    {
                        String error = warning.getMsg() + " code: " + warning.getId();
                        LOG.error( error );
                        target.appendJavaScript( ";alert('" + error + "');" );
                        return false;
                    }
                }
            }

            // User's active role set changed so refresh their permissions:
            SecUtils.getPermissions( component, accessMgr );
            isSuccessful = true;
            String message = "Activate role name: " + roleName + " successful";
            LOG.info( message );
        }
        catch ( org.apache.directory.fortress.core.SecurityException se )
        {
            String msg = "Role selection " + roleName + " activation failed because of ";
            if ( se.getErrorId() == GlobalErrIds.DSD_VALIDATION_FAILED )
            {
                msg += "Dynamic SoD rule violation";
            }
            else if ( se.getErrorId() == GlobalErrIds.URLE_ALREADY_ACTIVE )
            {
                msg += "Role already active in Session";
            }
            else
            {
                msg += "System error: " + se + ", " + "errId=" + se.getErrorId();
            }
            LOG.error( msg );
            target.appendJavaScript( ";alert('" + msg + "');" );
        }
        return isSuccessful;
    }

    /**
     * Call RBAC dropActiveRole to deactivate a new role from user's session.
     * This routine must first retrieves the wicket session.
     * It is needed because it contains the fortress session which is required for api.
     * Next it invokes the fortress dropActiveRole method.
     * If all successful refresh user's perms cached as they've changed.
     *
     * @param component contains handle to wicket session.
     * @param target used to display modal if something goes wrong
     * @param accessMgr used to call fortress api for role op
     * @param roleName contains the role name target
     * @return true if success, false otherwise.
     */
    public static boolean dropActiveRole( Component component, AjaxRequestTarget target, AccessMgr accessMgr, String roleName )
    {
        boolean isSuccessful = false;
        try
        {
            WicketSession session = ( WicketSession ) component.getSession();
            accessMgr.dropActiveRole( session.getSession(), new UserRole( roleName ) );
            // User's active role set changed so refresh their permissions:
            SecUtils.getPermissions( component, accessMgr );
            isSuccessful = true;
            LOG.info( "Fortress dropActiveRole roleName: " + roleName + " was successful" );
        }
        catch ( SecurityException se )
        {
            String msg = "Role selection " + roleName + " deactivation failed because of ";
            if ( se.getErrorId() == GlobalErrIds.URLE_NOT_ACTIVE )
            {
                msg += "Role not active in session";
            }
            else
            {
                msg += "System error: " + se + ", " + "errId=" + se.getErrorId();
            }
            LOG.error( msg );
            target.appendJavaScript( ";alert('" + msg + "');" );
        }
        return isSuccessful;
    }

    /**
     * Enables fortress session on behalf of a java.security.Principal retrieved from the container.
     *
     * @param component
     * @param servletReq
     * @param j2eePolicyMgr
     * @param accessMgr
     * @throws SecurityException
     */
    public static void enableFortress( Component component, HttpServletRequest servletReq, J2eePolicyMgr j2eePolicyMgr, AccessMgr accessMgr ) throws SecurityException
    {
        // Get the principal from the container:
        Principal principal = servletReq.getUserPrincipal();
        // Is this a Java EE secured page && has the User successfully authenticated already?
        boolean isSecured = principal != null;
        if(isSecured)
        {
            //linksLabel += " for " + principal.getName();
            if( !isLoggedIn( component ) )
            {
                String szPrincipal = principal.toString();
                // Pull the fortress session from the realm and assert into the Web app's session along with user's perms:
                SecUtils.initializeSession( component, j2eePolicyMgr, accessMgr, szPrincipal );
            }
        }
    }

    /**
     * If user has a wicket session then considered logged in.
     *
     * @return true if wicket session is not null
     */
    public static boolean isLoggedIn( Component component )
    {
        boolean isLoggedIn = false;
        if ( getSession( component ) != null )
        {
            isLoggedIn = true;
        }
        return isLoggedIn;
    }

    public static Permission getPermFromId( String id )
    {
        Permission perm = null;
        String[] parts = id.split( "\\." );
        if( parts.length > 1)
        {
            String objName = parts[0];
            String opName = parts[1];
            perm = new Permission( objName, opName );
        }
        return perm;
    }

}
