/**************************************************************
 *
 * 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.
 *
 *************************************************************/



// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_scripting.hxx"

#include <com/sun/star/lang/XMultiComponentFactory.hpp>
#include <com/sun/star/lang/XMultiServiceFactory.hpp>
#include <com/sun/star/lang/XComponent.hpp>
#include <com/sun/star/lang/WrappedTargetException.hpp>
#include <com/sun/star/beans/XPropertySet.hpp>
#include <com/sun/star/beans/PropertyValue.hpp>
#include <com/sun/star/beans/UnknownPropertyException.hpp>
#include <com/sun/star/container/XNameReplace.hpp>
#include <com/sun/star/util/XChangesBatch.hpp>
#include <com/sun/star/util/XMacroExpander.hpp>
#include <com/sun/star/util/XStringSubstitution.hpp>
#include <com/sun/star/awt/XDialog.hpp>
#include <com/sun/star/security/AccessControlException.hpp>
#include <com/sun/star/security/RuntimePermission.hpp>
#include <drafts/com/sun/star/script/framework/storage/XScriptStorageManager.hpp>
#include <drafts/com/sun/star/script/framework/storage/XScriptInfoAccess.hpp>
#include "ScriptSecurityManager.hxx"
#include <util/util.hxx>
#include <util/scriptingconstants.hxx>
#include <tools/diagnose_ex.h>

using namespace ::rtl;
using namespace ::osl;
using namespace ::com::sun::star;
using namespace ::com::sun::star::uno;
using namespace ::drafts::com::sun::star::script::framework;

// is this in the utils?
const char* const SCRIPTSTORAGEMANAGER_SERVICE =
    "/singletons/drafts.com.sun.star.script.framework.storage.theScriptStorageManager";

namespace scripting_securitymgr
{

static OUString s_configProv = ::rtl::OUString::createFromAscii(
    "com.sun.star.configuration.ConfigurationProvider");

static OUString s_configAccess = ::rtl::OUString::createFromAscii(
    "com.sun.star.configuration.ConfigurationAccess");

static OUString s_configUpdate = ::rtl::OUString::createFromAscii(
    "com.sun.star.configuration.ConfigurationUpdateAccess");

static OUString s_securityDialog = ::rtl::OUString::createFromAscii(
    "com.sun.star.script.framework.security.SecurityDialog");

static const int PERMISSION_NEVER = 0;
static const int PERMISSION_PATHLIST = 1;
static const int PERMISSION_ALWAYS = 2;

static const int ALLOW_RUN = 1;
static const int ADD_TO_PATH = 2;

//*************************************************************************
// ScriptSecurityManager Constructor
ScriptSecurityManager::ScriptSecurityManager(
    const Reference< XComponentContext > & xContext ) throw ( RuntimeException )
    : m_xContext( xContext, UNO_SET_THROW )
{
    OSL_TRACE( "< ScriptSecurityManager ctor called >\n" );

    // get the service manager from the context
    Reference< lang::XMultiComponentFactory > xMgr( m_xContext->getServiceManager(), UNO_SET_THROW );

    // create an instance of the ConfigurationProvider
    m_xConfigProvFactory.set( xMgr->createInstanceWithContext( s_configProv, m_xContext ), UNO_QUERY_THROW );
}

void ScriptSecurityManager::addScriptStorage( rtl::OUString scriptStorageURL,
    sal_Int32 storageID)
throw ( RuntimeException )
{
    Permission_Hash::const_iterator ph_it = m_permissionSettings.find( scriptStorageURL );
    if ( ph_it != m_permissionSettings.end() )
    {
        OSL_TRACE( "ScriptSecurityManager::addScriptStorage: already called for %s",
            ::rtl::OUStringToOString( scriptStorageURL,
                RTL_TEXTENCODING_ASCII_US ).pData->buffer);
        return;
    }
    StoragePerm newPerm;
    newPerm.scriptStorageURL=scriptStorageURL;
    newPerm.storageID=storageID;

    // we err on the side of caution!!
    newPerm.execPermission=sal_False;

    //need to check if storage has any scripts
    try
    {
        // we have some scripts so read config & decide on that basis
        // Setup flags: m_runMacroSetting, m_warning, m_confirmationRequired,
        readConfiguration();
    }
    catch ( RuntimeException & rte )
    {
        OSL_TRACE( "ScriptSecurityManager::addScriptStorage: caught RuntimeException: %s",
            ::rtl::OUStringToOString( rte.Message,
                RTL_TEXTENCODING_ASCII_US ).pData->buffer);
        throw RuntimeException(
            OUSTR( "ScriptSecurityManager::addScriptStorage: caught RuntimeException" ).concat( rte.Message ),
        Reference< XInterface >() );
    }

    switch( m_runMacroSetting )
    {
        case PERMISSION_NEVER:         // never
        {
            OSL_TRACE("never run");
            break;
        }
        case PERMISSION_PATHLIST:         // according to path list
        {
            OSL_TRACE("according to path");
            // check path
            rtl::OUString path = scriptStorageURL.copy( 0, scriptStorageURL.lastIndexOf( '/' ) );
            OSL_TRACE( "no of elts in path list = %d",
                (int)m_secureURL.getLength() );
            bool match = isSecureURL( path );
            if( match &&  ( m_warning == sal_True ) )
            {
                OSL_TRACE("path match & warning dialog");
                int result = (int)executeStandardDialog();
                OSL_TRACE("result = %d", (int)result);
                if ( (result&ALLOW_RUN) == ALLOW_RUN )
                {
                    newPerm.execPermission=sal_True;
                }
                break;
            }
            else if ( match )
            {
                OSL_TRACE("path match & no warning dialog");
                newPerm.execPermission=sal_True;
                break;
            }
            else if( m_confirmationRequired == sal_True )
            {
                OSL_TRACE("no path match & confirmation dialog");
                int result = (int)executePathDialog( path );
                OSL_TRACE("result = %d", (int)result);
                if ( (result&ALLOW_RUN) == ALLOW_RUN )
                {
                    newPerm.execPermission=sal_True;
                }
                if ( (result&ADD_TO_PATH) == ADD_TO_PATH )
                {
                    /* if checkbox clicked then need to add path to registry*/
                    addToSecurePaths(path);
                }
            }
            break;
        }
        case PERMISSION_ALWAYS:         // always
            if( m_warning == sal_True )
            {
                OSL_TRACE("always & warning dialog");
                short result = executeStandardDialog();
                if ( (result&ALLOW_RUN) == ALLOW_RUN )
                {
                    newPerm.execPermission=sal_True;
                }
            }
            else
            {
                OSL_TRACE("always & no warning dialog");
                newPerm.execPermission=sal_True;
            }
            break;
        default:
                //
                throw RuntimeException(
                    OUSTR( "ScriptSecurityManager::addScriptStorage got invalid OfficeBasic setting"),
                    Reference< XInterface > ());
    }

    if ( newPerm.execPermission == sal_True )
    {
        OSL_TRACE("setting exec permission to true for %s",
            ::rtl::OUStringToOString( scriptStorageURL,
                RTL_TEXTENCODING_ASCII_US ).pData->buffer );
    }
    else
    {
        OSL_TRACE("setting exec permission to false for %s",
            ::rtl::OUStringToOString( scriptStorageURL,
                RTL_TEXTENCODING_ASCII_US ).pData->buffer );
    }

    m_permissionSettings[ scriptStorageURL ] = newPerm;
}

bool ScriptSecurityManager::isSecureURL( const OUString & path )
{
    bool match = false;
    OSL_TRACE( "no of elts in path list = %d",
        (int)m_secureURL.getLength() );
    OSL_TRACE("document path: %s",
        ::rtl::OUStringToOString( path,
            RTL_TEXTENCODING_ASCII_US ).pData->buffer);
    int length = m_secureURL.getLength();
    for( int j = 0; j < length ; j++ )
    {
        OSL_TRACE("path list element: %s",
            ::rtl::OUStringToOString( m_secureURL[j],
                RTL_TEXTENCODING_ASCII_US ).pData->buffer);
#ifdef WIN32
        OSL_TRACE("case insensitive comparison");
        if( path.equalsIgnoreAsciiCase( m_secureURL[j] ) )
#else
        OSL_TRACE("case sensitive comparison");
        if( path.equals( m_secureURL[j] ) )
#endif
        {
            match = true;
            break;
        }
    }
    return match;
}

short ScriptSecurityManager::executeStandardDialog()
throw ( RuntimeException )
{
    OUString dummyString;
    return executeDialog( dummyString );
}

short ScriptSecurityManager::executePathDialog( const OUString & path )
throw ( RuntimeException )
{
    return executeDialog( path );
}

short ScriptSecurityManager::executeDialog( const OUString & path )
throw ( RuntimeException )
{
    Sequence < Any > aArgs;
    if( path.getLength() != 0 )
    {
        OSL_TRACE("reallocing");
        aArgs.realloc(1);
        aArgs[ 0 ] <<= path;
    }
    short result;
    try
    {
        Reference< lang::XMultiComponentFactory > xMgr( m_xContext->getServiceManager(), UNO_SET_THROW );
        Reference< awt::XDialog > xDialog(
            xMgr->createInstanceWithArgumentsAndContext( s_securityDialog, aArgs, m_xContext ),
            UNO_QUERY_THROW );
        result = xDialog->execute();
        Reference< lang::XComponent > xComponent( xDialog, UNO_QUERY_THROW );
        xComponent->dispose();
    }
    catch ( RuntimeException & rte )
    {
        throw RuntimeException(
            OUSTR( "ScriptSecurityManager::executeDialog: caught RuntimeException: ").concat( rte.Message ),
            Reference< XInterface > ());
    }
    catch ( Exception & e )
    {
        throw RuntimeException(
            OUSTR( "ScriptSecurityManager::executeDialog: caught Exception: ").concat( e.Message ),
            Reference< XInterface > ());
    }
    return result;
}

/**
 * checks to see whether the requested ScriptPermission is allowed.
 * This was modelled after the Java AccessController, but at this time
 * we can't see a good reason not to return a bool, rather than throw
 * an exception if the request is not granted (as is the case in Java).
 */
void ScriptSecurityManager::checkPermission( const OUString & scriptStorageURL,
    const OUString & permissionRequest )
    throw ( RuntimeException, lang::IllegalArgumentException, security::AccessControlException )
{
    if( permissionRequest.equals( OUString::createFromAscii( "execute" ) ) )
    {
        OSL_TRACE(
            "ScriptSecurityManager::checkPermission: execute permission request for %s",
            ::rtl::OUStringToOString( scriptStorageURL,
                RTL_TEXTENCODING_ASCII_US ).pData->buffer);
        Permission_Hash::const_iterator ph_it = m_permissionSettings.find( scriptStorageURL );
        Permission_Hash::const_iterator ph_itend =
            m_permissionSettings.end();
        if ( ph_it != ph_itend )
        {
            if ( ph_it->second.execPermission )
            {
                return;
            }
            else
            {
                OSL_TRACE( "permission refused" );
                Any aPermission;
                security::RuntimePermission permission;
                permission.Name = OUString::createFromAscii( "execute" ).concat( scriptStorageURL );
                aPermission <<= permission;
                throw security::AccessControlException(
                    OUString::createFromAscii( "ScriptSecurityManager::checkPermission: no execute permission for URL" ).concat( scriptStorageURL ),
                    Reference< XInterface > (), aPermission );
            }
        }
        // we should never get here!!
        throw lang::IllegalArgumentException( OUString::createFromAscii( "ScriptSecurityManager::checkPermission: storageURL not found" ), Reference< XInterface > (), 0 );
    }
    // inappropriate permission request
    throw lang::IllegalArgumentException( OUString::createFromAscii( "ScriptSecurityManager::checkPermission: storageURL not found" ), Reference< XInterface > (), 1 );
}

void ScriptSecurityManager::removePermissionSettings ( ::rtl::OUString & scriptStorageURL )
{
    Permission_Hash::const_iterator ph_it =
        m_permissionSettings.find( scriptStorageURL );

    if ( ph_it == m_permissionSettings.end() )
    {
        OSL_TRACE( "Entry for storage url %s doesn't exist in map",
            ::rtl::OUStringToOString( scriptStorageURL,
                RTL_TEXTENCODING_ASCII_US ).pData->buffer);
        return;
    }

    // erase the entry from the hash
    m_permissionSettings.erase( scriptStorageURL );

}

void ScriptSecurityManager::readConfiguration()
    throw ( RuntimeException)
{
    try
    {
        beans::PropertyValue configPath;
        configPath.Name = ::rtl::OUString::createFromAscii( "nodepath" );
        configPath.Value <<= ::rtl::OUString::createFromAscii( "org.openoffice.Office.Common/Security/Scripting" );
        Sequence < Any > aargs( 1 );
        aargs[ 0 ] <<= configPath;
        ENSURE_OR_THROW( m_xConfigProvFactory.is(),
            "ScriptSecurityManager::readConfiguration: ConfigProviderFactory no longer valid!" );
        // get the XPropertySet interface from the ConfigurationAccess service
        Reference < beans::XPropertySet > xPropSet( m_xConfigProvFactory->createInstanceWithArguments( s_configAccess, aargs ), UNO_QUERY_THROW );

        m_confirmationRequired = sal_True;
        OSL_VERIFY( xPropSet->getPropertyValue( OUSTR( "Confirmation" ) ) >>= m_confirmationRequired );
        if ( m_confirmationRequired == sal_True )
        {
            OSL_TRACE( "ScriptSecurityManager:readConfiguration: confirmation is true" );
        }
        else
        {
            OSL_TRACE( "ScriptSecurityManager:readConfiguration: confirmation is false" );
        }

        m_warning = true;
        OSL_VERIFY( xPropSet->getPropertyValue( OUSTR( "Warning" ) ) >>= m_warning );

        if ( m_warning == sal_True )
        {
            OSL_TRACE( "ScriptSecurityManager:readConfiguration: warning is true" );
        }
        else
        {
            OSL_TRACE( "ScriptSecurityManager:readConfiguration: warning is false" );
        }

        m_runMacroSetting = sal_True;
        OSL_VERIFY( xPropSet->getPropertyValue( OUSTR( "OfficeBasic" ) ) >>= m_runMacroSetting );
        OSL_TRACE( "ScriptSecurityManager:readConfiguration: OfficeBasic = %d", m_runMacroSetting );

        m_secureURL = ::rtl::OUString();
        OSL_VERIFY( xPropSet->getPropertyValue( OUSTR( "SecureURL" ) ) >>= m_secureURL );
    }
    catch ( beans::UnknownPropertyException & upe )
    {
        throw RuntimeException(
            OUSTR( "ScriptSecurityManager:readConfiguration: Attempt to read unknown property: " ).concat( upe.Message ),
            Reference< XInterface > () );
    }
    catch ( lang::WrappedTargetException & wte )
    {
        throw RuntimeException(
            OUSTR( "ScriptSecurityManager:readConfiguration: wrapped target exception? :" ).concat( wte.Message ),
            Reference< XInterface > () );
    }
    catch ( Exception & e )
    {
        OSL_TRACE( "Unknown exception in readconf: %s",
            ::rtl::OUStringToOString(e.Message ,
            RTL_TEXTENCODING_ASCII_US ).pData->buffer  );
        throw RuntimeException(
            OUSTR( "ScriptSecurityManager:readConfiguration: exception? :" ).concat( e.Message ),
            Reference< XInterface > () );
    }
#ifdef _DEBUG
    catch ( ... )
    {
        OSL_TRACE( "Completely Unknown exception in readconf!!!!!!");
        throw RuntimeException(
            OUSTR( "ScriptSecurityManager:readConfiguration: exception? :" ),
            Reference< XInterface > () );
    }
#endif

    int length = m_secureURL.getLength();

    // PathSubstitution needed to interpret variables found in config
    Reference< lang::XMultiComponentFactory > xMgr( m_xContext->getServiceManager(), UNO_SET_THROW );
    Reference< XInterface > xInterface = );
    Reference< util::XStringSubstitution > xStringSubstitution(
        xMgr->createInstanceWithContext(
            ::rtl::OUString::createFromAscii( "com.sun.star.util.PathSubstitution" ), m_xContext
        ),
        UNO_QUERY_THROW
    );
    for( int i = 0; i < length; i++ )
    {
        OSL_TRACE( "ScriptSecurityManager:readConfiguration path = %s",
            ::rtl::OUStringToOString(m_secureURL[i] ,
            RTL_TEXTENCODING_ASCII_US ).pData->buffer  );

        OSL_TRACE( "ScriptSecurityManager: subpath = %s",
            ::rtl::OUStringToOString(
            xStringSubstitution->substituteVariables( m_secureURL[i], true ),
            RTL_TEXTENCODING_ASCII_US ).pData->buffer );
        m_secureURL[i] = xStringSubstitution->substituteVariables( m_secureURL[i], true );
    }
#ifdef _DEBUG
    int length2 = m_secureURL.getLength();
    for( int j = 0; j < length2 ; j++ )
    {
        OSL_TRACE( "ScriptSecurityManager: path = %s",
            ::rtl::OUStringToOString(m_secureURL[j] ,
            RTL_TEXTENCODING_ASCII_US ).pData->buffer  );
    }
#endif
}

void ScriptSecurityManager::addToSecurePaths( const OUString & path )
throw ( RuntimeException )
{
    OSL_TRACE( "--->ScriptSecurityManager::addToSecurePaths" );
    beans::PropertyValue configPath;
    configPath.Name = ::rtl::OUString::createFromAscii( "nodepath" );
    configPath.Value <<= ::rtl::OUString::createFromAscii( "org.openoffice.Office.Common/Security/Scripting" );
    Sequence < Any > aargs( 1 );
    aargs[ 0 ] <<= configPath;
    Reference < container::XNameReplace > xNameReplace(
        m_xConfigProvFactory->createInstanceWithArguments( s_configUpdate, aargs ), UNO_QUERY_THROW );
    Reference < util::XChangesBatch > xChangesBatch( xNameReplace, UNO_QUERY_THROW );

    OSL_TRACE( "--->ScriptSecurityManager::addToSecurePaths: after if stuff" );
    Reference < beans::XPropertySet > xPropSet( xInterface, UNO_QUERY );
    css::uno::Sequence< rtl::OUString > newSecureURL;
    Any value;
    OUString pathListPropName = OUSTR ( "SecureURL" );
    value=xPropSet->getPropertyValue( pathListPropName );
    if ( sal_False == ( value >>= newSecureURL ) )
    {
        throw RuntimeException(
            OUSTR( "ScriptSecurityManager::addToSecurePaths: can't get SecureURL setting" ),
            Reference< XInterface > () );
    }
    try
    {
        sal_Int32 length = newSecureURL.getLength();
        newSecureURL.realloc( length + 1 );
        newSecureURL[ length ] = path;
        Any aNewSecureURL;
        aNewSecureURL <<= newSecureURL;
        xNameReplace->replaceByName( pathListPropName, aNewSecureURL );
        xChangesBatch->commitChanges();
        m_secureURL = newSecureURL;
    }
    catch ( Exception & e )
    {
        OSL_TRACE( "Error updating secure paths: " );
        throw RuntimeException(
            OUSTR( "ScriptSecurityManager::addToSecurePaths: error updating SecureURL setting" ).concat( e.Message ),
            Reference< XInterface > () );
    }
}

//*************************************************************************
// ScriptSecurityManager Destructor
ScriptSecurityManager::~ScriptSecurityManager()
{
    OSL_TRACE( "< ScriptSecurityManager dtor called >\n" );
}

} // Namespace
