diff options
Diffstat (limited to 'svl/source/passwordcontainer/syscreds.cxx')
-rw-r--r-- | svl/source/passwordcontainer/syscreds.cxx | 268 |
1 files changed, 268 insertions, 0 deletions
diff --git a/svl/source/passwordcontainer/syscreds.cxx b/svl/source/passwordcontainer/syscreds.cxx new file mode 100644 index 000000000..096046310 --- /dev/null +++ b/svl/source/passwordcontainer/syscreds.cxx @@ -0,0 +1,268 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * 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 . + */ + +#include "syscreds.hxx" +#include <osl/diagnose.h> +#include <comphelper/sequence.hxx> +#include <iterator> + +using namespace com::sun::star; + +SysCredentialsConfigItem::SysCredentialsConfigItem( + SysCredentialsConfig * pOwner ) +: utl::ConfigItem( "Office.Common/Passwords", ConfigItemMode::NONE ), + m_bInited( false ), + m_pOwner( pOwner ) +{ + uno::Sequence<OUString> aNode { "Office.Common/Passwords/AuthenticateUsingSystemCredentials" }; + EnableNotification( aNode ); +} + +//virtual +void SysCredentialsConfigItem::Notify( + const uno::Sequence< OUString > & /*seqPropertyNames*/ ) +{ + { + ::osl::MutexGuard aGuard( m_aMutex ); + m_bInited = false; + // rebuild m_seqURLs + getSystemCredentialsURLs(); + } + m_pOwner->persistentConfigChanged(); +} + +void SysCredentialsConfigItem::ImplCommit() +{ + // does nothing +} + +uno::Sequence< OUString > +SysCredentialsConfigItem::getSystemCredentialsURLs() +{ + ::osl::MutexGuard aGuard( m_aMutex ); + if ( !m_bInited ) + { + // read config item + uno::Sequence<OUString> aPropNames { "AuthenticateUsingSystemCredentials" }; + uno::Sequence< uno::Any > aAnyValues( + utl::ConfigItem::GetProperties( aPropNames ) ); + + OSL_ENSURE( + aAnyValues.getLength() == 1, + "SysCredentialsConfigItem::getSystemCredentialsURLs: " + "Error reading config item!" ); + + uno::Sequence< OUString > aValues; + if ( ( aAnyValues[ 0 ] >>= aValues ) || + ( !aAnyValues[ 0 ].hasValue() ) ) + { + m_seqURLs = aValues; + m_bInited = true; + } + } + return m_seqURLs; +} + +void SysCredentialsConfigItem::setSystemCredentialsURLs( + const uno::Sequence< OUString > & seqURLList ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + + // write config item. + uno::Sequence< OUString > aPropNames( 1 ); + uno::Sequence< uno::Any > aPropValues( 1 ); + aPropNames[ 0 ] = "AuthenticateUsingSystemCredentials"; + aPropValues[ 0 ] <<= seqURLList; + + utl::ConfigItem::SetModified(); + utl::ConfigItem::PutProperties( aPropNames, aPropValues ); + + m_seqURLs = seqURLList; + m_bInited = true; +} + + +namespace +{ + // TODO: This code is actually copied from svl/source/passwordcontainer.cxx + bool removeLastSegment( OUString & aURL ) + { + sal_Int32 aInd = aURL.lastIndexOf( '/' ); + + if( aInd > 0 ) + { + sal_Int32 aPrevInd = aURL.lastIndexOf( '/', aInd ); + if ( aURL.indexOf( "://" ) != aPrevInd - 2 || + aInd != aURL.getLength() - 1 ) + { + aURL = aURL.copy( 0, aInd ); + return true; + } + } + + return false; + } + + bool findURL( StringSet const & rContainer, OUString const & aURL, OUString & aResult ) + { + // TODO: This code is actually copied from svl/source/passwordcontainer.cxx + if( !rContainer.empty() && !aURL.isEmpty() ) + { + OUString aUrl( aURL ); + + // each iteration remove last '/...' section from the aUrl + // while it's possible, up to the most left '://' + do + { + // first look for <url>/somename and then look for <url>/somename/... + StringSet::const_iterator aIter = rContainer.find( aUrl ); + if( aIter != rContainer.end() ) + { + aResult = *aIter; + return true; + } + else + { + OUString tmpUrl( aUrl ); + if ( !tmpUrl.endsWith("/") ) + tmpUrl += "/"; + + aIter = rContainer.lower_bound( tmpUrl ); + if( aIter != rContainer.end() && aIter->match( tmpUrl ) ) + { + aResult = *aIter; + return true; + } + } + } + while( removeLastSegment( aUrl ) && !aUrl.isEmpty() ); + } + aResult.clear(); + return false; + } + +} // namespace + +SysCredentialsConfig::SysCredentialsConfig() +: m_aConfigItem( this ), + m_bCfgInited( false ) +{ +} + +void SysCredentialsConfig::initCfg() +{ + osl::MutexGuard aGuard( m_aMutex ); + if ( !m_bCfgInited ) + { + uno::Sequence< OUString > aURLs( + m_aConfigItem.getSystemCredentialsURLs() ); + std::copy(aURLs.begin(), aURLs.end(), + std::inserter(m_aCfgContainer, m_aCfgContainer.end())); + + m_bCfgInited = true; + } +} + +void SysCredentialsConfig::writeCfg() +{ + osl::MutexGuard aGuard( m_aMutex ); + + OSL_ENSURE( m_bCfgInited, "SysCredentialsConfig::writeCfg : not initialized!" ); + + m_aConfigItem.setSystemCredentialsURLs( comphelper::containerToSequence(m_aCfgContainer) ); +} + +OUString SysCredentialsConfig::find( OUString const & aURL ) +{ + osl::MutexGuard aGuard( m_aMutex ); + OUString aResult; + if ( findURL( m_aMemContainer, aURL, aResult ) ) + return aResult; + + initCfg(); + if ( findURL( m_aCfgContainer, aURL, aResult ) ) + return aResult; + + return OUString(); +} + +void SysCredentialsConfig::add( OUString const & rURL, bool bPersistent ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + + if ( bPersistent ) + { + m_aMemContainer.erase( rURL ); + + initCfg(); + m_aCfgContainer.insert( rURL ); + writeCfg(); + } + else + { + initCfg(); + if ( m_aCfgContainer.erase( rURL ) > 0 ) + writeCfg(); + + m_aMemContainer.insert( rURL ); + } +} + +void SysCredentialsConfig::remove( OUString const & rURL ) +{ + m_aMemContainer.erase( rURL ); + + initCfg(); + if ( m_aCfgContainer.erase( rURL ) > 0 ) + writeCfg(); +} + +uno::Sequence< OUString > SysCredentialsConfig::list( bool bOnlyPersistent ) +{ + initCfg(); + sal_Int32 nCount = m_aCfgContainer.size() + + ( bOnlyPersistent ? 0 : m_aMemContainer.size() ); + uno::Sequence< OUString > aResult( nCount ); + + sal_Int32 n = 0; + + for ( const auto& rItem : m_aCfgContainer ) + { + aResult[ n ] = rItem; + ++n; + } + + if ( !bOnlyPersistent ) + { + for ( const auto& rItem : m_aMemContainer ) + { + aResult[ n ] = rItem; + ++n; + } + } + return aResult; +} + +void SysCredentialsConfig::persistentConfigChanged() +{ + ::osl::MutexGuard aGuard( m_aMutex ); + m_bCfgInited = false; // re-init on demand. +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |