[mapguide-commits] r6896 - in branches/2.4/MgDev/Desktop: DesktopTestData MgDesktop MgDesktop/Services MgDesktop/Services/Feature UnitTest

svn_mapguide at osgeo.org svn_mapguide at osgeo.org
Sat Jul 14 08:24:43 PDT 2012


Author: jng
Date: 2012-07-14 08:24:43 -0700 (Sat, 14 Jul 2012)
New Revision: 6896

Added:
   branches/2.4/MgDev/Desktop/DesktopTestData/SecuredCredentials.fs
Modified:
   branches/2.4/MgDev/Desktop/MgDesktop/MgDesktop.vcproj
   branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/FdoConnectionUtil.cpp
   branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/FdoConnectionUtil.h
   branches/2.4/MgDev/Desktop/MgDesktop/Services/ResourceService.cpp
   branches/2.4/MgDev/Desktop/MgDesktop/Services/ResourceService.h
   branches/2.4/MgDev/Desktop/UnitTest/TestFeatureService.cpp
   branches/2.4/MgDev/Desktop/UnitTest/TestFeatureService.h
   branches/2.4/MgDev/Desktop/UnitTest/main.cpp
Log:
mg-desktop updates:
 - #2067: Add secured credential support (%MG_USERNAME% and %MG_PASSWORD%)
 - Invalidate caches related to the target resource in any CopyResource or MoveResource operation

Added: branches/2.4/MgDev/Desktop/DesktopTestData/SecuredCredentials.fs
===================================================================
--- branches/2.4/MgDev/Desktop/DesktopTestData/SecuredCredentials.fs	                        (rev 0)
+++ branches/2.4/MgDev/Desktop/DesktopTestData/SecuredCredentials.fs	2012-07-14 15:24:43 UTC (rev 6896)
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<FeatureSource xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="FeatureSource-1.0.0.xsd">
+  <Provider>OSGeo.SQLServerSpatial</Provider>
+  <Parameter>
+    <Name>Service</Name>
+    <Value>(local)\SQLEXPRESS</Value>
+  </Parameter>
+  <Parameter>
+    <Name>DataStore</Name>
+    <Value>MgUnitTest</Value>
+  </Parameter>
+  <Parameter>
+    <Name>Username</Name>
+    <Value>%MG_USERNAME%</Value>
+  </Parameter>
+  <Parameter>
+    <Name>Password</Name>
+    <Value>%MG_PASSWORD%</Value>
+  </Parameter>
+</FeatureSource>

Modified: branches/2.4/MgDev/Desktop/MgDesktop/MgDesktop.vcproj
===================================================================
--- branches/2.4/MgDev/Desktop/MgDesktop/MgDesktop.vcproj	2012-07-11 15:58:11 UTC (rev 6895)
+++ branches/2.4/MgDev/Desktop/MgDesktop/MgDesktop.vcproj	2012-07-14 15:24:43 UTC (rev 6896)
@@ -45,7 +45,7 @@
 				Name="VCCLCompilerTool"
 				Optimization="0"
 				EnableIntrinsicFunctions="false"
-				AdditionalIncludeDirectories="..\..\Common\Foundation;..\..\Common\PlatformBase;..\..\Common\Geometry;..\..\Common\MdfModel;..\..\Common\MdfParser;..\..\Oem\ACE\ACE_wrappers;"..\..\Oem\dbxml\xerces-c-src\src";..\..\Oem\FDO\Inc;..\..\Oem\FDO\Inc\ExpressionEngine;..\..\Common\Renderers;..\..\Common\Stylization;..\..\Oem\DWFTK7.1\develop\global\src;..\..\Oem\DWFTK7.1\develop\global\src\dwf;..\..\Server\src\Gws\Include;..\..\Server\src\Gws\GwsCommon\inc;..\..\Server\src\Gws\GwsQueryEngine\inc"
+				AdditionalIncludeDirectories="..\..\Common\Foundation;..\..\Common\PlatformBase;..\..\Common\Geometry;..\..\Common\MdfModel;..\..\Common\MdfParser;..\..\Oem\ACE\ACE_wrappers;"..\..\Oem\dbxml\xerces-c-src\src";..\..\Oem\FDO\Inc;..\..\Oem\FDO\Inc\ExpressionEngine;..\..\Common\Renderers;..\..\Common\Stylization;..\..\Oem\DWFTK7.1\develop\global\src;..\..\Oem\DWFTK7.1\develop\global\src\dwf;..\..\Server\src\Gws\Include;..\..\Server\src\Gws\GwsCommon\inc;..\..\Server\src\Gws\GwsQueryEngine\inc;..\..\Common\Security"
 				PreprocessorDefinitions="WIN32;DEBUG;_WINDOWS;_USRDLL;DESKTOP_EXPORTS;DWFCORE_STATIC;DWFTK_STATIC;DWFTK_USE_DWFCORE_ZLIB;DWFTK_BUILD_EXPAT;WHIP_STATIC_LIB"
 				MinimalRebuild="true"
 				ExceptionHandling="1"
@@ -66,7 +66,7 @@
 			/>
 			<Tool
 				Name="VCLinkerTool"
-				AdditionalDependencies="FDO.lib FDOCommon.lib FDOGeometry.lib ExpressionEngine.lib ACEd.lib MgFoundationd.lib MgGeometryd.lib MgMdfModeld.lib MgMdfParserd.lib MgPlatformBased.lib MgRenderersd.lib MgStylizationd.lib MgGwsCommond.lib MgGwsQueryEngined.lib xerces-c_3mgD.lib dwfcore_wt.1.1.1.lib dwftk_wt.7.1.1.lib whiptk_wt.7.7.601.lib"
+				AdditionalDependencies="FDO.lib FDOCommon.lib FDOGeometry.lib ExpressionEngine.lib ACEd.lib MgFoundationd.lib MgGeometryd.lib MgMdfModeld.lib MgMdfParserd.lib MgPlatformBased.lib MgRenderersd.lib MgStylizationd.lib MgGwsCommond.lib MgGwsQueryEngined.lib xerces-c_3mgD.lib dwfcore_wt.1.1.1.lib dwftk_wt.7.1.1.lib whiptk_wt.7.7.601.lib MgSecurity.lib"
 				ShowProgress="0"
 				OutputFile="$(OutDir)\MgDesktopd.dll"
 				LinkIncremental="1"
@@ -132,7 +132,7 @@
 				Name="VCCLCompilerTool"
 				Optimization="0"
 				EnableIntrinsicFunctions="false"
-				AdditionalIncludeDirectories="..\..\Common\Foundation;..\..\Common\PlatformBase;..\..\Common\Geometry;..\..\Common\MdfModel;..\..\Common\MdfParser;..\..\Oem\ACE\ACE_wrappers;"..\..\Oem\dbxml\xerces-c-src\src";..\..\Oem\FDO\Inc;..\..\Oem\FDO\Inc\ExpressionEngine;..\..\Common\Renderers;..\..\Common\Stylization;..\..\Oem\DWFTK7.1\develop\global\src;..\..\Oem\DWFTK7.1\develop\global\src\dwf;..\..\Server\src\Gws\Include;..\..\Server\src\Gws\GwsCommon\inc;..\..\Server\src\Gws\GwsQueryEngine\inc"
+				AdditionalIncludeDirectories="..\..\Common\Foundation;..\..\Common\PlatformBase;..\..\Common\Geometry;..\..\Common\MdfModel;..\..\Common\MdfParser;..\..\Oem\ACE\ACE_wrappers;"..\..\Oem\dbxml\xerces-c-src\src";..\..\Oem\FDO\Inc;..\..\Oem\FDO\Inc\ExpressionEngine;..\..\Common\Renderers;..\..\Common\Stylization;..\..\Oem\DWFTK7.1\develop\global\src;..\..\Oem\DWFTK7.1\develop\global\src\dwf;..\..\Server\src\Gws\Include;..\..\Server\src\Gws\GwsCommon\inc;..\..\Server\src\Gws\GwsQueryEngine\inc;..\..\Common\Security"
 				PreprocessorDefinitions="WIN32;DEBUG;_WINDOWS;_USRDLL;DESKTOP_EXPORTS;DWFCORE_STATIC;DWFTK_STATIC;DWFTK_USE_DWFCORE_ZLIB;DWFTK_BUILD_EXPAT;WHIP_STATIC_LIB"
 				MinimalRebuild="true"
 				ExceptionHandling="1"
@@ -153,7 +153,7 @@
 			/>
 			<Tool
 				Name="VCLinkerTool"
-				AdditionalDependencies="FDO.lib FDOCommon.lib FDOGeometry.lib ExpressionEngine.lib ACEd.lib MgFoundationd.lib MgGeometryd.lib MgMdfModeld.lib MgMdfParserd.lib MgPlatformBased.lib MgRenderersd.lib MgStylizationd.lib MgGwsCommond.lib MgGwsQueryEngined.lib xerces-c_3mgD.lib dwfcore_wt.1.1.1.lib dwftk_wt.7.1.1.lib whiptk_wt.7.7.601.lib"
+				AdditionalDependencies="FDO.lib FDOCommon.lib FDOGeometry.lib ExpressionEngine.lib ACEd.lib MgFoundationd.lib MgGeometryd.lib MgMdfModeld.lib MgMdfParserd.lib MgPlatformBased.lib MgRenderersd.lib MgStylizationd.lib MgGwsCommond.lib MgGwsQueryEngined.lib xerces-c_3mgD.lib dwfcore_wt.1.1.1.lib dwftk_wt.7.1.1.lib whiptk_wt.7.7.601.lib MgSecurityd.lib"
 				ShowProgress="0"
 				OutputFile="$(OutDir)\MgDesktopd.dll"
 				LinkIncremental="1"
@@ -218,7 +218,7 @@
 				Name="VCCLCompilerTool"
 				Optimization="2"
 				EnableIntrinsicFunctions="true"
-				AdditionalIncludeDirectories="..\..\Common\Foundation;..\..\Common\PlatformBase;..\..\Common\Geometry;..\..\Common\MdfModel;..\..\Common\MdfParser;..\..\Oem\ACE\ACE_wrappers;"..\..\Oem\dbxml\xerces-c-src\src";..\..\Oem\FDO\Inc;..\..\Oem\FDO\Inc\ExpressionEngine;..\..\Common\Renderers;..\..\Common\Stylization;..\..\Oem\DWFTK7.1\develop\global\src;..\..\Oem\DWFTK7.1\develop\global\src\dwf;..\..\Server\src\Gws\Include;..\..\Server\src\Gws\GwsCommon\inc;..\..\Server\src\Gws\GwsQueryEngine\inc"
+				AdditionalIncludeDirectories="..\..\Common\Foundation;..\..\Common\PlatformBase;..\..\Common\Geometry;..\..\Common\MdfModel;..\..\Common\MdfParser;..\..\Oem\ACE\ACE_wrappers;"..\..\Oem\dbxml\xerces-c-src\src";..\..\Oem\FDO\Inc;..\..\Oem\FDO\Inc\ExpressionEngine;..\..\Common\Renderers;..\..\Common\Stylization;..\..\Oem\DWFTK7.1\develop\global\src;..\..\Oem\DWFTK7.1\develop\global\src\dwf;..\..\Server\src\Gws\Include;..\..\Server\src\Gws\GwsCommon\inc;..\..\Server\src\Gws\GwsQueryEngine\inc;..\..\Common\Security"
 				PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;DESKTOP_EXPORTS;DWFCORE_STATIC;DWFTK_STATIC;DWFTK_USE_DWFCORE_ZLIB;DWFTK_BUILD_EXPAT;WHIP_STATIC_LIB"
 				ExceptionHandling="1"
 				RuntimeLibrary="2"
@@ -237,7 +237,7 @@
 			/>
 			<Tool
 				Name="VCLinkerTool"
-				AdditionalDependencies="FDO.lib FDOCommon.lib FDOGeometry.lib ExpressionEngine.lib ACE.lib MgFoundation.lib MgGeometry.lib MgMdfModel.lib MgMdfParser.lib MgPlatformBase.lib MgRenderers.lib MgStylization.lib MgGwsCommon.lib MgGwsQueryEngine.lib xerces-c_3mg.lib dwfcore_wt.1.1.1.lib dwftk_wt.7.1.1.lib whiptk_wt.7.7.601.lib"
+				AdditionalDependencies="FDO.lib FDOCommon.lib FDOGeometry.lib ExpressionEngine.lib ACE.lib MgFoundation.lib MgGeometry.lib MgMdfModel.lib MgMdfParser.lib MgPlatformBase.lib MgRenderers.lib MgStylization.lib MgGwsCommon.lib MgGwsQueryEngine.lib xerces-c_3mg.lib dwfcore_wt.1.1.1.lib dwftk_wt.7.1.1.lib whiptk_wt.7.7.601.lib MgSecurity.lib"
 				OutputFile="$(OutDir)\$(ProjectName).dll"
 				LinkIncremental="1"
 				AdditionalLibraryDirectories="..\..\Oem\ACE\ACE_wrappers\lib;..\..\Oem\FDO\Lib;..\..\Oem\DWFTK7.1\develop\global\lib\static\release\vc8.0;"..\..\Oem\dbxml\xerces-c-src\Build\Win32\VC9\Release";..\..\Common\lib\release;..\..\Server\lib\release"
@@ -300,7 +300,7 @@
 				Name="VCCLCompilerTool"
 				Optimization="2"
 				EnableIntrinsicFunctions="true"
-				AdditionalIncludeDirectories="..\..\Common\Foundation;..\..\Common\PlatformBase;..\..\Common\Geometry;..\..\Common\MdfModel;..\..\Common\MdfParser;..\..\Oem\ACE\ACE_wrappers;"..\..\Oem\dbxml\xerces-c-src\src";..\..\Oem\FDO\Inc;..\..\Oem\FDO\Inc\ExpressionEngine;..\..\Common\Renderers;..\..\Common\Stylization;..\..\Oem\DWFTK7.1\develop\global\src;..\..\Oem\DWFTK7.1\develop\global\src\dwf;..\..\Server\src\Gws\Include;..\..\Server\src\Gws\GwsCommon\inc;..\..\Server\src\Gws\GwsQueryEngine\inc"
+				AdditionalIncludeDirectories="..\..\Common\Foundation;..\..\Common\PlatformBase;..\..\Common\Geometry;..\..\Common\MdfModel;..\..\Common\MdfParser;..\..\Oem\ACE\ACE_wrappers;"..\..\Oem\dbxml\xerces-c-src\src";..\..\Oem\FDO\Inc;..\..\Oem\FDO\Inc\ExpressionEngine;..\..\Common\Renderers;..\..\Common\Stylization;..\..\Oem\DWFTK7.1\develop\global\src;..\..\Oem\DWFTK7.1\develop\global\src\dwf;..\..\Server\src\Gws\Include;..\..\Server\src\Gws\GwsCommon\inc;..\..\Server\src\Gws\GwsQueryEngine\inc;..\..\Common\Security"
 				PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;DESKTOP_EXPORTS;DWFCORE_STATIC;DWFTK_STATIC;DWFTK_USE_DWFCORE_ZLIB;DWFTK_BUILD_EXPAT;WHIP_STATIC_LIB"
 				ExceptionHandling="1"
 				RuntimeLibrary="2"
@@ -319,7 +319,7 @@
 			/>
 			<Tool
 				Name="VCLinkerTool"
-				AdditionalDependencies="FDO.lib FDOCommon.lib FDOGeometry.lib ExpressionEngine.lib ACE.lib MgFoundation.lib MgGeometry.lib MgMdfModel.lib MgMdfParser.lib MgPlatformBase.lib MgRenderers.lib MgStylization.lib MgGwsCommon.lib MgGwsQueryEngine.lib xerces-c_3mg.lib dwfcore_wt.1.1.1.lib dwftk_wt.7.1.1.lib whiptk_wt.7.7.601.lib"
+				AdditionalDependencies="FDO.lib FDOCommon.lib FDOGeometry.lib ExpressionEngine.lib ACE.lib MgFoundation.lib MgGeometry.lib MgMdfModel.lib MgMdfParser.lib MgPlatformBase.lib MgRenderers.lib MgStylization.lib MgGwsCommon.lib MgGwsQueryEngine.lib xerces-c_3mg.lib dwfcore_wt.1.1.1.lib dwftk_wt.7.1.1.lib whiptk_wt.7.7.601.lib MgSecurity.lib"
 				OutputFile="$(OutDir)\$(ProjectName).dll"
 				LinkIncremental="1"
 				AdditionalLibraryDirectories="..\..\Oem\ACE\ACE_wrappers\lib64;..\..\Oem\FDO\Lib64;..\..\Oem\DWFTK7.1\develop\global\lib\static\release64\vc8.0;"..\..\Oem\dbxml\xerces-c-src\Build\x64\VC9\Release";..\..\Common\lib\release64;..\..\Server\lib\release64"

Modified: branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/FdoConnectionUtil.cpp
===================================================================
--- branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/FdoConnectionUtil.cpp	2012-07-11 15:58:11 UTC (rev 6895)
+++ branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/FdoConnectionUtil.cpp	2012-07-14 15:24:43 UTC (rev 6896)
@@ -3,6 +3,7 @@
 #include "Fdo.h"
 #include "FeatureServiceCache.h"
 #include "Services/Resource/UnmanagedDataManager.h"
+#include "CryptographyUtil.h"
 
 FdoIConnection* MgFdoConnectionUtil::CreateConnection(CREFSTRING providerName, CREFSTRING connectionString)
 {
@@ -76,6 +77,33 @@
 	FdoPtr<FdoIConnectionInfo> connInfo = conn->GetConnectionInfo();
 	FdoPtr<FdoIConnectionPropertyDictionary> dict = connInfo->GetConnectionProperties();
 
+    STRING username;
+    STRING password;
+
+    Ptr<MgByteReader> resData = resSvc->EnumerateResourceData(resource);
+    Ptr<MgByteSink> sink = new MgByteSink(resData);
+    STRING resDataXml;
+    sink->ToString(resDataXml);
+
+    if (resDataXml.find(MgResourceDataName::UserCredentials) != STRING::npos)
+    {
+        Ptr<MgByteReader> blob = resSvc->GetRawCredentials(resource);
+        if (NULL != blob.p)
+        {
+            Ptr<MgByteSink> credSink = new MgByteSink(blob);
+            std::string credentials;
+            credSink->ToStringUtf8(credentials);
+
+            MgCryptographyUtil crypto;
+            std::string mbUsername;
+            std::string mbPassword;
+            crypto.DecryptCredentials(credentials, mbUsername, mbPassword);
+
+            username = MgUtil::MultiByteToWideChar(mbUsername);
+            password = MgUtil::MultiByteToWideChar(mbPassword);
+        }
+    }
+
 	MdfModel::NameStringPairCollection* params = fs->GetParameters();
 	for (INT32 i = 0; i < params->GetCount(); i++)
 	{
@@ -85,7 +113,7 @@
         STRING v = pair->GetValue();
 
         //Perform tag substitution if found
-        PerformTagSubstitution(resSvc, v, resource);
+        PerformTagSubstitution(resSvc, v, resource, username, password);
 
 		dict->SetProperty(n.c_str(), v.c_str());
 	}
@@ -132,16 +160,29 @@
 	return conn.Detach();
 }
 
-void MgFdoConnectionUtil::PerformTagSubstitution(MgdResourceService* resSvc, REFSTRING str, MgResourceIdentifier* resource)
+void MgFdoConnectionUtil::PerformTagSubstitution(MgdResourceService* resSvc, REFSTRING str, MgResourceIdentifier* resource, CREFSTRING username, CREFSTRING password)
 {
-    STRING dataToken = L"%MG_DATA_FILE_PATH%";
-    const int pos = str.find(dataToken);
-    if (pos >= 0)
+    const int dataTokenPos = str.find(MgResourceTag::DataFilePath);
+    const int dataAliasPos = str.find(MgResourceTag::DataPathAliasBegin);
+    const int usernamePos = str.find(MgResourceTag::Username);
+    const int passwordPos = str.find(MgResourceTag::Password);
+    if (dataTokenPos != STRING::npos)
     {
         STRING dataPath = resSvc->ResolveDataPath(resource);
-        str.replace(pos, dataToken.size(), dataPath);
+        str.replace(dataTokenPos, MgResourceTag::DataFilePath.size(), dataPath);
     }
-    MgUnmanagedDataManager::SubstituteDataPathAliases(str);
+    else if (dataAliasPos != STRING::npos)
+    {
+        MgUnmanagedDataManager::SubstituteDataPathAliases(str);
+    }
+    else if (usernamePos != STRING::npos && !username.empty())
+    {
+        str.replace(usernamePos, MgResourceTag::Username.size(), username);
+    }
+    else if (passwordPos != STRING::npos && !password.empty())
+    {
+        str.replace(passwordPos, MgResourceTag::Password.size(), password);
+    }
 }
 
 STRING MgFdoConnectionUtil::ParseNonQualifiedProviderName(CREFSTRING providerName)

Modified: branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/FdoConnectionUtil.h
===================================================================
--- branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/FdoConnectionUtil.h	2012-07-11 15:58:11 UTC (rev 6895)
+++ branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/FdoConnectionUtil.h	2012-07-14 15:24:43 UTC (rev 6896)
@@ -20,7 +20,7 @@
     static MdfModel::FeatureSource* GetFeatureSource(MgResourceIdentifier* resource);
 
 private:
-    static void PerformTagSubstitution(MgdResourceService* resSvc, REFSTRING str, MgResourceIdentifier* resource);
+    static void PerformTagSubstitution(MgdResourceService* resSvc, REFSTRING str, MgResourceIdentifier* resource, CREFSTRING username = L"", CREFSTRING password = L"");
     static STRING ParseNonQualifiedProviderName(CREFSTRING providerName);
 
     //Creates a connection by feature source ID. Any tag and aliases present in the connection parameters

Modified: branches/2.4/MgDev/Desktop/MgDesktop/Services/ResourceService.cpp
===================================================================
--- branches/2.4/MgDev/Desktop/MgDesktop/Services/ResourceService.cpp	2012-07-11 15:58:11 UTC (rev 6895)
+++ branches/2.4/MgDev/Desktop/MgDesktop/Services/ResourceService.cpp	2012-07-14 15:24:43 UTC (rev 6896)
@@ -6,6 +6,7 @@
 #include "Services/Resource/UnmanagedDataManager.h"
 #include "ace/Dirent_Selector.h"
 #include "Services/Feature/FdoConnectionPool.h"
+#include "CryptographyUtil.h"
 
 static int MgDirEntrySelector(const ACE_DIRENT *d)
 {
@@ -561,6 +562,7 @@
     }
     else
     {
+        ReleasePotentialLocks(destResource);
         if (!MgFileUtil::PathnameExists(dstContentDir))
             MgFileUtil::CreateDirectory(dstContentDir, false, true);
         MgFileUtil::CopyFile(srcContentPath, dstContentPath, overwrite);
@@ -698,6 +700,7 @@
     }
     else
     {
+        ReleasePotentialLocks(destResource);
         if (!MgFileUtil::PathnameExists(dstContentDir))
             MgFileUtil::CreateDirectory(dstContentDir, false, true);
         MgFileUtil::CopyFile(srcContentPath, dstContentPath, overwrite);
@@ -730,7 +733,7 @@
 
     // Successful operation
     MG_LOG_OPERATION_MESSAGE_ADD_STRING(MgResources::Success.c_str());
-
+    
     MG_RESOURCE_SERVICE_CATCH(L"MgdResourceService::MoveResource")
 
     if (mgException != NULL)
@@ -1547,7 +1550,11 @@
 
 MgByteReader* MgdResourceService::GetResourceData(MgResourceIdentifier* resource,
     CREFSTRING dataName, CREFSTRING preProcessTags) 
-{ 
+{
+    Ptr<MgByteReader> reader;
+
+    MG_RESOURCE_SERVICE_TRY()
+
 	CHECKARGUMENTNULL(resource, L"MgdResourceService::GetResourceData");
     if (!ResourceExists(resource))
     {
@@ -1565,12 +1572,66 @@
 	if (!MgFileUtil::IsFile(path))
 		throw new MgResourceDataNotFoundException(L"MgdResourceService::GetResourceData", __LINE__, __WFILE__, NULL, L"", NULL);
 
-	Ptr<MgByteReader> reader;
-	Ptr<MgByteSource> source = new MgByteSource(path);
-	reader = source->GetReader();
+	Ptr<MgByteSource> source;
+
+    //As per MapGuide Server behaviour, if request is for MG_USER_CREDENTIALS return the decrypted username only
+    if (dataName == MgResourceDataName::UserCredentials)
+    {
+        source = new MgByteSource(path);
+        reader = source->GetReader();
+        Ptr<MgByteSink> sink = new MgByteSink(reader);
+        std::string data;
+        sink->ToStringUtf8(data);
+
+        std::string mbUsername;
+        std::string mbPassword;
+        MgCryptographyUtil crypto;
+        crypto.DecryptCredentials(data, mbUsername, mbPassword);
+
+        source = NULL;
+        reader = NULL;
+        source = new MgByteSource((BYTE_ARRAY_IN)mbUsername.c_str(), mbUsername.length());
+        reader = source->GetReader();
+    }
+    else
+    {
+        source = new MgByteSource(path);
+	    reader = source->GetReader();
+    }
+
+    MG_RESOURCE_SERVICE_CATCH_AND_THROW(L"MgdResourceService::GetResourceData")
+
 	return reader.Detach();
 }
 
+MgByteReader* MgdResourceService::GetRawCredentials(MgResourceIdentifier* resource)
+{
+    Ptr<MgByteReader> blob;
+
+    MG_RESOURCE_SERVICE_TRY()
+
+    CHECKARGUMENTNULL(resource, L"MgdResourceService::GetResourceData");
+    if (!ResourceExists(resource))
+    {
+        MgStringCollection arguments;
+        arguments.Add(resource->ToString());
+        throw new MgResourceNotFoundException(L"MgdResourceService::GetResourceData", __LINE__, __WFILE__, &arguments, L"", NULL);
+    }
+
+    STRING path = ResolveDataPath(resource);
+    path += MgResourceDataName::UserCredentials;
+
+	if (!MgFileUtil::IsFile(path))
+		throw new MgResourceDataNotFoundException(L"MgdResourceService::GetResourceData", __LINE__, __WFILE__, NULL, L"", NULL);
+
+    Ptr<MgByteSource> source = new MgByteSource(path);
+    blob = source->GetReader();
+
+    MG_RESOURCE_SERVICE_CATCH_AND_THROW(L"MgdResourceService::GetRawCredentials")
+
+    return blob.Detach();
+}
+
 MgDateTime* MgdResourceService::GetResourceModifiedDate(MgResourceIdentifier* resource) 
 { 
 	CHECKARGUMENTNULL(resource, L"MgdResourceService::GetResourceModifiedDate");
@@ -1656,4 +1717,56 @@
     MG_RESOURCE_SERVICE_THROW()
 
     return byteReader.Detach();
-};
\ No newline at end of file
+};
+
+void MgdResourceService::SetResourceCredentials(MgResourceIdentifier* resource, CREFSTRING userName, CREFSTRING password)
+{
+    MG_LOG_OPERATION_MESSAGE(L"SetResourceCredentials");
+
+    MG_RESOURCE_SERVICE_TRY()
+
+    MG_LOG_OPERATION_MESSAGE_INIT(MG_API_VERSION(1, 0, 0), 3);
+    MG_LOG_OPERATION_MESSAGE_PARAMETERS_START();
+    MG_LOG_OPERATION_MESSAGE_ADD_STRING((NULL == resource) ? L"MgResourceIdentifier" : resource->ToString().c_str());
+    MG_LOG_OPERATION_MESSAGE_ADD_SEPARATOR();
+    MG_LOG_OPERATION_MESSAGE_ADD_STRING(userName.c_str());
+    MG_LOG_OPERATION_MESSAGE_ADD_SEPARATOR();
+    MG_LOG_OPERATION_MESSAGE_ADD_STRING(L"<Password>");
+    MG_LOG_OPERATION_MESSAGE_PARAMETERS_END();
+
+    MG_LOG_TRACE_ENTRY(L"MgdResourceService::SetResourceCredentials()");
+
+    std::string data;
+    std::string mgUsername = MgUtil::WideCharToMultiByte(userName);
+    std::string mgPassword = MgUtil::WideCharToMultiByte(password);
+    MgCryptographyUtil crypto;
+    crypto.EncryptCredentials(mgUsername, mgPassword, data);
+
+    Ptr<MgByteSource> bs = new MgByteSource((BYTE_ARRAY_IN)data.c_str(), data.length());
+    Ptr<MgByteReader> br = bs->GetReader();
+
+    //Invalidate any cached connections as they may use old credentials
+    if (resource->GetResourceType() == MgResourceType::FeatureSource)
+    {
+        MgFdoConnectionPool::PurgeCachedConnections(resource);
+    }
+
+    SetResourceData(resource, MgResourceDataName::UserCredentials, MgResourceDataType::File, br);
+
+    // Successful operation
+    MG_LOG_OPERATION_MESSAGE_ADD_STRING(MgResources::Success.c_str());
+
+    MG_RESOURCE_SERVICE_CATCH(L"MgdResourceService::SetResourceCredentials")
+
+    if (mgException != NULL)
+    {
+        // Failed operation
+        MG_LOG_OPERATION_MESSAGE_ADD_STRING(MgResources::Failure.c_str());
+        MG_DESKTOP_LOG_EXCEPTION();
+    }
+
+    // Add access log entry for operation
+    MG_LOG_OPERATION_MESSAGE_ACCESS_ENTRY();
+
+    MG_RESOURCE_SERVICE_THROW()
+}
\ No newline at end of file

Modified: branches/2.4/MgDev/Desktop/MgDesktop/Services/ResourceService.h
===================================================================
--- branches/2.4/MgDev/Desktop/MgDesktop/Services/ResourceService.h	2012-07-11 15:58:11 UTC (rev 6895)
+++ branches/2.4/MgDev/Desktop/MgDesktop/Services/ResourceService.h	2012-07-14 15:24:43 UTC (rev 6896)
@@ -5,6 +5,8 @@
 
 class MG_DESKTOP_API MgdResourceService : public MgResourceService
 {
+    friend class MgFdoConnectionUtil;
+
     DECLARE_CLASSNAME(MgdResourceService)
 
 INTERNAL_API:
@@ -62,6 +64,8 @@
 
     virtual MgByteReader* EnumerateUnmanagedData(CREFSTRING path, bool recursive, CREFSTRING type, CREFSTRING filter);
 
+    void SetResourceCredentials(MgResourceIdentifier* resource, CREFSTRING userName, CREFSTRING password);
+
 INTERNAL_API:
     virtual MgByteReader* EnumerateResources(MgResourceIdentifier* resource,
         INT32 depth, CREFSTRING type, INT32 properties,
@@ -97,6 +101,7 @@
 	virtual void Dispose() { delete this; }
 
 private:
+    MgByteReader* GetRawCredentials(MgResourceIdentifier* resource);
     void ReleasePotentialLocks(MgResourceIdentifier* resource);
     static bool ListDirectories(MgStringCollection* directoryNames, CREFSTRING path);
     void WriteResourceFolderEntry(REFSTRING xml, INT32 maxDepth, STRING type, MgResourceIdentifier* resId, CREFSTRING enumeratedFolderId = L"");

Modified: branches/2.4/MgDev/Desktop/UnitTest/TestFeatureService.cpp
===================================================================
--- branches/2.4/MgDev/Desktop/UnitTest/TestFeatureService.cpp	2012-07-11 15:58:11 UTC (rev 6895)
+++ branches/2.4/MgDev/Desktop/UnitTest/TestFeatureService.cpp	2012-07-14 15:24:43 UTC (rev 6896)
@@ -52,8 +52,13 @@
         Ptr<MgResourceService> pService = dynamic_cast<MgResourceService*>(fact->CreateService(MgServiceType::ResourceService));
         if (pService == 0)
         {
-            throw new MgServiceNotAvailableException(L"TestResourceService.setUp", __LINE__, __WFILE__, NULL, L"", NULL);
+            throw new MgServiceNotAvailableException(L"TestFeatureService.TestStart", __LINE__, __WFILE__, NULL, L"", NULL);
         }
+        Ptr<MgdFeatureService> featSvc = dynamic_cast<MgdFeatureService*>(fact->CreateService(MgServiceType::FeatureService));
+        if (featSvc == 0)
+        {
+            throw new MgServiceNotAvailableException(L"TestFeatureService.TestStart", __LINE__, __WFILE__, NULL, L"", NULL);
+        }
 
         // publish the map definition
         Ptr<MgResourceIdentifier> mapres1 = new MgResourceIdentifier(L"Library://UnitTests/Maps/SheboyganWriteable.MapDefinition");
@@ -83,6 +88,7 @@
         MgResourceIdentifier resourceIdentifier6(L"Library://UnitTests/Data/Empty.FeatureSource");
         MgResourceIdentifier resourceIdentifier7(L"Library://UnitTests/Data/Sheboygan_Parcels_Writable.FeatureSource");
         MgResourceIdentifier resourceIdentifier8(L"Library://UnitTests/Data/FdoJoin.FeatureSource");
+        MgResourceIdentifier resourceIdentifier9(L"Library://UnitTests/Data/SecuredCredentials.FeatureSource");
 #ifdef _WIN32
         STRING resourceContentFileName1 = L"..\\UnitTestFiles\\Sheboygan_Parcels.FeatureSource";
         STRING resourceContentFileName2 = L"..\\UnitTestFiles\\Redding_Parcels.FeatureSource";
@@ -92,6 +98,7 @@
         STRING resourceContentFileName6=  L"..\\UnitTestFiles\\Empty.FeatureSource";
         STRING resourceContentFileName7=  L"..\\UnitTestFiles\\Sheboygan_Parcels_Writable.FeatureSource";
         STRING resourceContentFileName8=  L"..\\UnitTestFiles\\UT_FdoJoin.FeatureSource";
+        STRING resourceContentFileName9=  L"..\\UnitTestFiles\\SecuredCredentials.fs";
         STRING dataFileName1 = L"..\\UnitTestFiles\\Sheboygan_Parcels.sdf";
         STRING dataFileName2 = L"..\\UnitTestFiles\\Redding_Parcels.shp";
         STRING dataFileName3 = L"..\\UnitTestFiles\\Redding_Parcels.dbf";
@@ -109,6 +116,7 @@
         STRING resourceContentFileName6 = L"../UnitTestFiles/Empty.FeatureSource";
         STRING resourceContentFileName7=  L"../UnitTestFiles/Sheboygan_Parcels_Writable.FeatureSource";
         STRING resourceContentFileName8=  L"../UnitTestFiles/UT_FdoJoin.FeatureSource";
+        STRING resourceContentFileName9=  L"../UnitTestFiles/SecuredCredentials.fs";
         STRING dataFileName1 = L"../UnitTestFiles/Sheboygan_Parcels.sdf";
         STRING dataFileName2 = L"../UnitTestFiles/Redding_Parcels.shp";
         STRING dataFileName3 = L"../UnitTestFiles/Redding_Parcels.dbf";
@@ -152,6 +160,10 @@
         Ptr<MgByteReader> contentReader8 = contentSource8->GetReader();
         pService->SetResource(&resourceIdentifier8, contentReader8, NULL);
 
+        Ptr<MgByteSource> contentSource9 = new MgByteSource(resourceContentFileName9);
+        Ptr<MgByteReader> contentReader9 = contentSource9->GetReader();
+        pService->SetResource(&resourceIdentifier9, contentReader9, NULL);
+
         //Set the resource data
         Ptr<MgByteSource> dataSource1 = new MgByteSource(dataFileName1);
         Ptr<MgByteReader> dataReader1 = dataSource1->GetReader();
@@ -299,6 +311,9 @@
         Ptr<MgResourceIdentifier> fsres8 = new MgResourceIdentifier(L"Library://UnitTests/Data/FdoJoin.FeatureSource");
         pService->DeleteResource(fsres8);
         
+        Ptr<MgResourceIdentifier> fsres9 = new MgResourceIdentifier(L"Library://UnitTests/Data/SecuredCredentials.FeatureSource");
+        pService->DeleteResource(fsres9);
+
         //Ptr<MgResourceIdentifier> folder = new MgResourceIdentifier(L"Library://UnitTests/");
         //pService->DeleteResource(folder);
     }
@@ -2939,7 +2954,6 @@
     }
 }
 
-/*
 ///----------------------------------------------------------------------------
 /// Test Case Description:
 ///
@@ -2951,7 +2965,8 @@
     {
         ACE_DEBUG((LM_INFO, ACE_TEXT("\nTestFeatureService::TestCase_BenchmarkSelectFeatures() - Start\n")));
 
-        Ptr<MgFeatureService> pService = MgServiceFactory::CreateFeatureService();
+        Ptr<MgServiceFactory> factory = new MgServiceFactory();
+        Ptr<MgFeatureService> pService = dynamic_cast<MgFeatureService*>(factory->CreateService(MgServiceType::FeatureService));
         if (pService == 0)
         {
             throw new MgServiceNotAvailableException(L"TestFeatureService.TestCase_BenchmarkSelectFeatures", __LINE__, __WFILE__, NULL, L"", NULL);
@@ -3002,8 +3017,91 @@
     {
         throw;
     }
-}*/
+}
 
+void TestFeatureService::TestCase_SecuredCredentials()
+{
+    //This test requires SQL Server express with a MgUnitTest database created.
+    //Once these requirements are met, fill in the required SQL Server credentials here
+    STRING username = L"";
+    STRING password = L"";
+    try
+    {
+        Ptr<MgServiceFactory> factory = new MgServiceFactory();
+        Ptr<MgFeatureService> featSvc = dynamic_cast<MgFeatureService*>(factory->CreateService(MgServiceType::FeatureService));
+        if (featSvc == 0)
+        {
+            throw new MgServiceNotAvailableException(L"TestFeatureService.TestCase_SecuredCredentials", __LINE__, __WFILE__, NULL, L"", NULL);
+        }
+        Ptr<MgdResourceService> resSvc = dynamic_cast<MgdResourceService*>(factory->CreateService(MgServiceType::ResourceService));
+        if (resSvc == 0)
+        {
+            throw new MgServiceNotAvailableException(L"TestFeatureService.TestCase_SecuredCredentials", __LINE__, __WFILE__, NULL, L"", NULL);
+        }
+        
+        Ptr<MgResourceIdentifier> fsId = new MgResourceIdentifier(L"Library://UnitTests/Data/SecuredCredentials.FeatureSource");
+        //Test as-is, this should be bad (false or exception, just as long as it is not true)
+        try
+        {
+            bool bResult = featSvc->TestConnection(fsId);
+            CPPUNIT_ASSERT(false == bResult);
+        }
+        catch (MgFdoException* ex)
+        {
+            SAFE_RELEASE(ex);
+        }
+
+        //Now apply credentials
+        resSvc->SetResourceCredentials(fsId, username, password);
+        CPPUNIT_ASSERT(true == featSvc->TestConnection(fsId));
+
+        //Now apply bad credentials
+        username = L"foo";
+        password = L"bar";
+        resSvc->SetResourceCredentials(fsId, username, password);
+        //this should be bad (false or exception, just as long as it is not true)
+        try
+        {
+            bool bResult = featSvc->TestConnection(fsId);
+            CPPUNIT_ASSERT(false == bResult);
+        }
+        catch (MgFdoException* ex)
+        {
+            SAFE_RELEASE(ex);
+        }
+
+        //Try again without MG_USER_CREDENTIALS
+        resSvc->DeleteResourceData(fsId, MgResourceDataName::UserCredentials);
+        //this should be bad (false or exception, just as long as it is not true)
+        try
+        {
+            bool bResult = featSvc->TestConnection(fsId);
+            CPPUNIT_ASSERT(false == bResult);
+        }
+        catch (MgFdoException* ex)
+        {
+            SAFE_RELEASE(ex);
+        }
+    }
+    catch(MgException* e)
+    {
+        STRING message = e->GetDetails(TEST_LOCALE);
+        SAFE_RELEASE(e);
+        CPPUNIT_FAIL(MG_WCHAR_TO_CHAR(message.c_str()));
+    }
+    catch(FdoException* e)
+    {
+        STRING message = L"FdoException occurred: ";
+        message += e->GetExceptionMessage();
+        FDO_SAFE_RELEASE(e);
+        CPPUNIT_FAIL(MG_WCHAR_TO_CHAR(message.c_str()));
+    }
+    catch(...)
+    {
+        throw;
+    }
+}
+
 MgdMap* TestFeatureService::CreateTestMap()
 {
     Ptr<MgResourceIdentifier> mdfres = new MgResourceIdentifier(L"Library://UnitTests/Maps/SheboyganWriteable.MapDefinition");

Modified: branches/2.4/MgDev/Desktop/UnitTest/TestFeatureService.h
===================================================================
--- branches/2.4/MgDev/Desktop/UnitTest/TestFeatureService.h	2012-07-11 15:58:11 UTC (rev 6895)
+++ branches/2.4/MgDev/Desktop/UnitTest/TestFeatureService.h	2012-07-14 15:24:43 UTC (rev 6896)
@@ -58,9 +58,10 @@
     //Our sortability check has broken this for some reason
     CPPUNIT_TEST(TestCase_JoinFeaturesChainedInner1ToMany);
     CPPUNIT_TEST(TestCase_JoinFdoFeatures);
-    //CPPUNIT_TEST(TestCase_BenchmarkSelectFeatures);
+    CPPUNIT_TEST(TestCase_BenchmarkSelectFeatures);
     //CPPUNIT_TEST(TestCase_ConcurrentAccess);
 
+    //CPPUNIT_TEST(TestCase_SecuredCredentials);
     CPPUNIT_TEST(TestCase_LayerInsertFeatures);
     CPPUNIT_TEST(TestCase_LayerUpdateFeatures);
     CPPUNIT_TEST(TestCase_LayerDeleteFeatures);
@@ -114,7 +115,7 @@
     void TestCase_JoinFeaturesChainedInner1ToMany();
     void TestCase_JoinFdoFeatures();
     void TestCase_CreateFeatureSource();
-    //void TestCase_BenchmarkSelectFeatures();
+    void TestCase_BenchmarkSelectFeatures();
     //void TestCase_ConcurrentAccess();
 
     void TestCase_BenchmarkSdfJoin();
@@ -124,6 +125,7 @@
     void TestCase_BenchmarkNestedLoopsSortedBlockJoin();
     void TestCase_BenchmarkNestedLoopsJoin();
 
+    void TestCase_SecuredCredentials();
     void TestCase_LayerInsertFeatures();
     void TestCase_LayerUpdateFeatures();
     void TestCase_LayerDeleteFeatures();

Modified: branches/2.4/MgDev/Desktop/UnitTest/main.cpp
===================================================================
--- branches/2.4/MgDev/Desktop/UnitTest/main.cpp	2012-07-11 15:58:11 UTC (rev 6895)
+++ branches/2.4/MgDev/Desktop/UnitTest/main.cpp	2012-07-14 15:24:43 UTC (rev 6896)
@@ -24,6 +24,15 @@
 #endif
 */
 
+#define TEST_COORDINATE_SYSTEM  0
+#define TEST_LOG_MANAGER        1
+#define TEST_RESOURCE_SERVICE   1
+#define TEST_FEATURE_SERVICE    1
+#define TEST_MAPPING_SERVICE    1
+#define TEST_PROFILING_SERVICE  1
+#define TEST_RENDERING_SERVICE  1
+#define TEST_TILE_SERVICE       1
+
 int main(int argc, char** argv)
 {
 /*
@@ -58,23 +67,38 @@
 
     // Add all of the tests
     //NOTE: Leave trace log off, otherwise one of the tests here will fail
+#if TEST_LOG_MANAGER == 1
     runner.addTest(CppUnit::TestFactoryRegistry::getRegistry("TestLogManager").makeTest());
+#endif
 #ifdef _DEBUG
     ACE_DEBUG((LM_INFO, ACE_TEXT(">>>>> Running all unit tests - Excluding Performance and CoordinateSystem. <<<<<\n\n")));
 #else
     ACE_DEBUG((LM_INFO, ACE_TEXT(">>>>> Running all unit tests - Excluding Performance. <<<<<\n\n")));
-    //runner.addTest(CppUnit::TestFactoryRegistry::getRegistry("TestCoordinateSystem").makeTest());
+    #if TEST_COORDINATE_SYSTEM == 1
+    runner.addTest(CppUnit::TestFactoryRegistry::getRegistry("TestCoordinateSystem").makeTest());
+    #endif
 #endif
+#if TEST_RESOURCE_SERVICE == 1
     runner.addTest(CppUnit::TestFactoryRegistry::getRegistry("TestResourceService").makeTest());
+#endif
+#if TEST_RENDERING_SERVICE == 1
     runner.addTest(CppUnit::TestFactoryRegistry::getRegistry("TestRenderingService").makeTest());
+#endif
+#if TEST_FEATURE_SERVICE == 1
     runner.addTest(CppUnit::TestFactoryRegistry::getRegistry("TestFeatureService").makeTest());
+#endif
+#if TEST_MAPPING_SERVICE == 1
     runner.addTest(CppUnit::TestFactoryRegistry::getRegistry("TestMappingService").makeTest());
+#endif
+#if TEST_PROFILING_SERVICE == 1
 	runner.addTest(CppUnit::TestFactoryRegistry::getRegistry("TestProfilingService").makeTest());
-    
+#endif
+#if TEST_TILE_SERVICE == 1
     //This causes access violations in Visual Leak Detector when run in debug mode. Only uncommment
     //to verify functionality, but don't use VLD for memory leak detection. Seek an alternate tool/library
     //in this case.
     runner.addTest(CppUnit::TestFactoryRegistry::getRegistry("TestTileService").makeTest());
+#endif
 
     STRING fileName = L"UnitTestResults.xml";
     if (fileName.size() > 0)



More information about the mapguide-commits mailing list