[shibboleth-sp2] 76/82: SSPCPP-756
Etienne Dysli Metref
edm-guest at moszumanska.debian.org
Thu Nov 16 08:16:27 UTC 2017
This is an automated email from the git hooks/post-receive script.
edm-guest pushed a commit to branch master
in repository shibboleth-sp2.
commit cedc37b94a625d63a9dd78f77ef7a5cdf1c66cca
Author: Rod Widdowson <rdw at steadingsoftware.com>
Date: Fri Oct 13 16:34:06 2017 +0100
SSPCPP-756
https://issues.shibboleth.net/jira/browse/SSPCPP-756
Checkpoint work in progress in test harness for poking at the Dynamic Metadata Provider.
---
Projects/vc15/UnitTests/UnitTests.vcxproj | 8 +
Projects/vc15/UnitTests/UnitTests.vcxproj.filters | 34 ++++-
unittests/DynamicMetadataProviderTest.h | 68 +++++++--
unittests/SPTest.h | 12 ++
unittests/TestApplication.cpp | 177 ++++++++++++++++++++++
unittests/TestApplication.h | 67 ++++++++
unittests/data/regexFromFile.xml | 1 +
unittests/data/templateFromRepo.xml | 2 +-
8 files changed, 348 insertions(+), 21 deletions(-)
diff --git a/Projects/vc15/UnitTests/UnitTests.vcxproj b/Projects/vc15/UnitTests/UnitTests.vcxproj
index 0ded90a..bcad500 100644
--- a/Projects/vc15/UnitTests/UnitTests.vcxproj
+++ b/Projects/vc15/UnitTests/UnitTests.vcxproj
@@ -73,6 +73,7 @@
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<IntDir>$(SolutionDir)..\..\Build\VC15\$(projectName)\$(Platform)\$(Configuration)\</IntDir>
<OutDir>$(SolutionDir)\..\..\Build\VC15\$(Configuration)\</OutDir>
+ <IncludePath>$(ProjectDir)\..\..\..\unittests;$(IncludePath)</IncludePath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<IntDir>$(SolutionDir)..\..\Build\VC15\$(projectName)\$(Platform)\$(Configuration)\</IntDir>
@@ -80,6 +81,7 @@
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<IntDir>$(SolutionDir)..\..\Build\VC15\$(projectName)\$(Platform)\$(Configuration)\</IntDir>
<OutDir>$(SolutionDir)\..\..\Build\VC15\$(Platform)\$(Configuration)\</OutDir>
+ <IncludePath>$(ProjectDir)\..\..\..\unittests;$(IncludePath)</IncludePath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<IntDir>$(SolutionDir)..\..\Build\VC15\$(projectName)\$(Platform)\$(Configuration)\</IntDir>
@@ -148,6 +150,7 @@
</ItemDefinitionGroup>
<ItemGroup>
<ClInclude Include="..\..\..\unittests\BaseTestCase.h" />
+ <ClInclude Include="..\..\..\unittests\TestApplication.h" />
<CustomBuild Include="..\..\..\unittests\SPTest.h">
<Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">perl.exe -w $(CxxTestRoot)\cxxtestgen.pl --error-printer --have-eh --have-std --abort-on-fail -o "$(IntDir)%(Filename)".cpp "%(FullPath)"</Command>
<Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">perl.exe -w $(CxxTestRoot)\cxxtestgen.pl --error-printer --have-eh --have-std --abort-on-fail -o "$(IntDir)%(Filename)".cpp "%(FullPath)"</Command>
@@ -172,11 +175,16 @@
<ItemGroup>
<ClCompile Include="..\..\..\Build\VC15\UnitTests\x64\Debug\DynamicMetadataProviderTest.cpp" />
<ClCompile Include="..\..\..\Build\VC15\UnitTests\x64\Debug\SPTest.cpp" />
+ <ClCompile Include="..\..\..\unittests\TestApplication.cpp" />
</ItemGroup>
<ItemGroup>
+ <Xml Include="..\..\..\unittests\data\08ced64cddc9f1578598b2cf71ae747b11d11472.xml" />
+ <Xml Include="..\..\..\unittests\data\fromMDQ.xml" />
+ <Xml Include="..\..\..\unittests\data\spp.xml" />
<Xml Include="..\..\..\unittests\data\templateFromFile.xml" />
<Xml Include="..\..\..\unittests\data\regexFromFile.xml" />
<Xml Include="..\..\..\unittests\data\templateFromRepo.xml" />
+ <Xml Include="..\..\..\unittests\data\www.example.org.xml" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
diff --git a/Projects/vc15/UnitTests/UnitTests.vcxproj.filters b/Projects/vc15/UnitTests/UnitTests.vcxproj.filters
index 987036a..1310a16 100644
--- a/Projects/vc15/UnitTests/UnitTests.vcxproj.filters
+++ b/Projects/vc15/UnitTests/UnitTests.vcxproj.filters
@@ -11,11 +11,12 @@
<Filter Include="Data">
<UniqueIdentifier>{c7232fb3-a33b-4038-80d4-eb48b209a285}</UniqueIdentifier>
</Filter>
- </ItemGroup>
- <ItemGroup>
- <ClInclude Include="..\..\..\unittests\BaseTestCase.h">
- <Filter>UnitTests</Filter>
- </ClInclude>
+ <Filter Include="Headers">
+ <UniqueIdentifier>{cf42e119-7cf9-4ff7-a27d-a4148c214ddd}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Source">
+ <UniqueIdentifier>{63179b9d-7e8f-4fc1-aeed-19174ecf134b}</UniqueIdentifier>
+ </Filter>
</ItemGroup>
<ItemGroup>
<CustomBuild Include="..\..\..\unittests\DynamicMetadataProviderTest.h">
@@ -32,6 +33,9 @@
<ClCompile Include="..\..\..\Build\VC15\UnitTests\x64\Debug\SPTest.cpp">
<Filter>GeneratedCode</Filter>
</ClCompile>
+ <ClCompile Include="..\..\..\unittests\TestApplication.cpp">
+ <Filter>Source</Filter>
+ </ClCompile>
</ItemGroup>
<ItemGroup>
<Xml Include="..\..\..\unittests\data\templateFromFile.xml">
@@ -43,5 +47,25 @@
<Xml Include="..\..\..\unittests\data\regexFromFile.xml">
<Filter>Data</Filter>
</Xml>
+ <Xml Include="..\..\..\unittests\data\08ced64cddc9f1578598b2cf71ae747b11d11472.xml">
+ <Filter>Data</Filter>
+ </Xml>
+ <Xml Include="..\..\..\unittests\data\www.example.org.xml">
+ <Filter>Data</Filter>
+ </Xml>
+ <Xml Include="..\..\..\unittests\data\fromMDQ.xml">
+ <Filter>Data</Filter>
+ </Xml>
+ <Xml Include="..\..\..\unittests\data\spp.xml">
+ <Filter>Data</Filter>
+ </Xml>
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="..\..\..\unittests\BaseTestCase.h">
+ <Filter>Headers</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\unittests\TestApplication.h">
+ <Filter>Headers</Filter>
+ </ClInclude>
</ItemGroup>
</Project>
\ No newline at end of file
diff --git a/unittests/DynamicMetadataProviderTest.h b/unittests/DynamicMetadataProviderTest.h
index 1da9a38..930213f 100644
--- a/unittests/DynamicMetadataProviderTest.h
+++ b/unittests/DynamicMetadataProviderTest.h
@@ -20,26 +20,54 @@
#include <fstream>
#include "BaseTestCase.h"
-#include <xercesc\dom\DOMDocument.hpp>
-#include <cpp-xmltooling\xmltooling\XMLToolingConfig.h>
-#include <cpp-xmltooling\xmltooling\util\XMLHelper.h>
-#include <cpp-xmltooling\xmltooling\util\ParserPool.h>
-#include <cpp-opensaml\saml\SAMLConfig.h>
-#include <cpp-opensaml\saml\saml2\metadata\MetadataProvider.h>
+#include <xercesc/dom/DOMDocument.hpp>
+#include <xmltooling/XMLToolingConfig.h>
+#include <xmltooling/util/XMLHelper.h>
+#include <xmltooling/util/ParserPool.h>
+#include <xmltooling/security/SecurityHelper.h>
+
+#include <saml/SAMLConfig.h>
+#include <saml/saml2/metadata/MetadataProvider.h>
+#include <saml/saml2/binding/SAML2ArtifactType0004.h>
+#include <saml/saml2/binding/SAML2Artifact.h>
+#include <saml/saml2/metadata/Metadata.h>
+
+#include <shibsp/Application.h>
+#include <shibsp/SPConfig.h>
+#include <shibsp/ServiceProvider.h>
+#include <shibsp/metadata/MetadataProviderCriteria.h>
+#include <shibsp/util/DOMPropertySet.h>
+#include <TestApplication.h>
using namespace xmltooling;
using namespace xercesc;
using namespace std;
using namespace opensaml::saml2md;
+using namespace opensaml::saml2p;
+using namespace shibsp;
extern string data_path;
class DynamicMetadataTest : public CxxTest::TestSuite {
+ private:
+ const string m_entityId;
+ const MetadataProvider::Criteria m_entityIdCriteria;
+ auto_ptr<SAML2ArtifactType0004> m_artifact;
+ MetadataProvider::Criteria m_artifactCriteria;
public:
+ DynamicMetadataTest() : CxxTest::TestSuite(), m_entityId("https://www.example.org/sp"), m_entityIdCriteria(m_entityId.c_str()),
+ m_artifact(nullptr)
+ {
+
+ }
+
void setUp()
- {}
+ {
+ m_artifact.reset(new SAML2ArtifactType0004(SecurityHelper::doHash("SHA1", m_entityId.data(), m_entityId.length(), false), 666));
+ m_artifactCriteria = MetadataProvider::Criteria(m_artifact.get());
+ }
void tearDown()
{}
@@ -49,15 +77,24 @@ public:
ifstream in(config.c_str());
XMLToolingConfig& xcf = XMLToolingConfig::getConfig();
ParserPool& pool = xcf.getParser();
- DOMDocument* doc = pool.parse(in);
- XercesJanitor<DOMDocument> janitor(doc);
+ XercesJanitor<DOMDocument> janitor(pool.parse(in));
auto_ptr<MetadataProvider> metadataProvider(
- opensaml::SAMLConfig::getConfig().MetadataProviderManager.newPlugin(DYNAMIC_METADATA_PROVIDER, doc->getDocumentElement())
+ opensaml::SAMLConfig::getConfig().MetadataProviderManager.newPlugin(DYNAMIC_METADATA_PROVIDER, janitor.get()->getDocumentElement())
);
+
+
+
+ ta::TestApplication testApp(SPConfig::getConfig().getServiceProvider(), metadataProvider.get());
+ MetadataProviderCriteria crit(testApp, m_entityId.c_str());
try {
metadataProvider->init();
- pair<const EntityDescriptor*, const RoleDescriptor*> pair = metadataProvider->getEntityDescriptor( opensaml::saml2md::MetadataProvider::Criteria("https://www.example.org/sp"));
+ pair<const EntityDescriptor*, const RoleDescriptor*> thePair = metadataProvider->getEntityDescriptor(crit);
+ TS_ASSERT(nullptr != thePair.first);
+
+ const EntityDescriptor* foo = thePair.first;
+ auto f = foo->getEntityID();
+
}
catch (XMLToolingException& ex) {
TS_TRACE(ex.what());
@@ -79,9 +116,12 @@ public:
);
try {
metadataProvider->init();
- pair<const EntityDescriptor*, const RoleDescriptor*> thePair = metadataProvider->getEntityDescriptor(opensaml::saml2md::MetadataProvider::Criteria("https://www.example.org/sp"));
+ pair<const EntityDescriptor*, const RoleDescriptor*> thePair = metadataProvider->getEntityDescriptor(m_entityIdCriteria);
TS_ASSERT(nullptr != thePair.first);
+ pair<const EntityDescriptor*, const RoleDescriptor*> artefactPair = metadataProvider->getEntityDescriptor(m_artifactCriteria);
+
+
} catch (XMLToolingException& ex) {
TS_TRACE(ex.what());
throw;
@@ -102,7 +142,7 @@ public:
);
try {
metadataProvider->init();
- pair<const EntityDescriptor*, const RoleDescriptor*> thePair = metadataProvider->getEntityDescriptor(opensaml::saml2md::MetadataProvider::Criteria("https://www.example.org/sp"));
+ pair<const EntityDescriptor*, const RoleDescriptor*> thePair = metadataProvider->getEntityDescriptor(m_entityIdCriteria);
TS_ASSERT(nullptr != thePair.first);
} catch (XMLToolingException& ex) {
@@ -114,5 +154,3 @@ public:
};
-
-
diff --git a/unittests/SPTest.h b/unittests/SPTest.h
index 4808f6a..18b8e42 100644
--- a/unittests/SPTest.h
+++ b/unittests/SPTest.h
@@ -25,12 +25,24 @@ public:
return false;
}
+ if (!conf.instantiate("./configs/shibboleth2.xml")) /*
+
+ (std::string("<SPConfig type='XML' xmlns='urn:mace:shibboleth:2.0:native:sp:config' xmlns:conf='urn:mace:shibboleth:2.0:native:sp:config'\n") +
+ std::string("xmlns:saml='urn:oasis:names:tc:SAML:2.0:assertion' xmlns:samlp='urn:oasis:names:tc:SAML:2.0:protocol'\n") +
+ std::string("xmlns:md='urn:oasis:names:tc:SAML:2.0:metadata' clockSkew='180'> \n") +
+ std::string("<conf:SecurityPolicyProvider type='XML' validate='true' path='..\cpp-sp\configs\security-policy.xml' /> </SPConfig>\n")).c_str()))/*
+ "<SecurityPolicyProvider xmlns='urn:mace:shibboleth:2.0:native:sp:config' type='XML' validate='true' path='../cpp-sp/configs/security-policy.xml' />"))*/ {
+ fprintf(stderr, "configuration is invalid, see console for specific problems\n");
+ return false;
+ }
+
registerMetadataExtClasses();
return true;
}
bool tearDownWorld() {
SPConfig::getConfig().term();
+ SPConfig::getConfig().getServiceProvider();
return true;
}
};
diff --git a/unittests/TestApplication.cpp b/unittests/TestApplication.cpp
new file mode 100644
index 0000000..f9fd1f5
--- /dev/null
+++ b/unittests/TestApplication.cpp
@@ -0,0 +1,177 @@
+
+#include <xmltooling\unicode.h>
+
+#include <shibsp/Application.h>
+#include <shibsp/util/DOMPropertySet.h>
+#include <TestApplication.h>
+using namespace std;
+using namespace shibsp;
+using namespace opensaml;
+using namespace opensaml::saml2md;
+
+namespace ta {
+ TestApplication::TestApplication(const ServiceProvider *sp, MetadataProvider* provider) : Application(sp), m_provider(provider)
+ {};
+
+ const char* TestApplication::getHash() const
+ {
+ return "";
+ }
+
+ MetadataProvider* TestApplication::getMetadataProvider(bool required) const
+ {
+ return m_provider;
+ }
+
+ xmltooling::TrustEngine* TestApplication::getTrustEngine(bool required) const
+ {
+ return nullptr;
+ }
+
+
+ AttributeExtractor* TestApplication::getAttributeExtractor() const
+ {
+ return nullptr;
+ }
+
+ AttributeFilter* TestApplication::getAttributeFilter() const
+ {
+ return nullptr;
+ }
+
+ AttributeResolver* TestApplication::getAttributeResolver() const
+ {
+ return nullptr;
+ }
+
+ xmltooling::CredentialResolver* TestApplication::getCredentialResolver() const
+ {
+ return nullptr;
+ }
+
+ const PropertySet* TestApplication::getRelyingParty(const opensaml::saml2md::EntityDescriptor* provider) const
+ {
+ return nullptr;
+ }
+
+
+ const PropertySet* TestApplication::getRelyingParty(const XMLCh* entityID) const
+ {
+ return this;
+ }
+
+
+ const vector<const XMLCh*>* TestApplication::getAudiences() const
+ {
+ return nullptr;
+ }
+
+ string TestApplication::getNotificationURL(const char* request, bool front, unsigned int index) const
+ {
+ return "";
+ }
+
+ const vector<string>& TestApplication::getRemoteUserAttributeIds() const
+ {
+ static const vector<string> retVal(0);
+ return retVal;
+ }
+
+ const SessionInitiator* TestApplication::getDefaultSessionInitiator() const
+ {
+ return nullptr;
+ }
+
+ const SessionInitiator* TestApplication::getSessionInitiatorById(const char* id) const
+ {
+ return nullptr;
+ }
+
+ const Handler* TestApplication::getDefaultAssertionConsumerService() const
+ {
+ return nullptr;
+ }
+
+ const Handler* TestApplication::getAssertionConsumerServiceByIndex(unsigned short index) const
+ {
+ return nullptr;
+ }
+
+ const vector<const Handler*>& TestApplication::getAssertionConsumerServicesByBinding(const XMLCh* binding) const
+ {
+ static const vector<const Handler*> retVal(0);
+ return retVal;
+ }
+
+ const Handler* TestApplication::getHandler(const char* path) const
+ {
+ return nullptr;
+ }
+
+ void TestApplication::getHandlers(vector<const Handler*>& handlers) const
+ {
+ return;
+ }
+
+ SAMLArtifact* TestApplication::generateSAML1Artifact(const EntityDescriptor* relyingParty) const
+ {
+ return nullptr;
+ }
+
+ saml2p::SAML2Artifact* TestApplication::generateSAML2Artifact(const EntityDescriptor* relyingParty) const
+ {
+ return nullptr;
+ }
+
+
+ const PropertySet* TestApplication::getParent() const
+ {
+ return nullptr;
+ }
+ void TestApplication::setParent(const PropertySet* parent)
+ {
+ return;
+ }
+ pair<bool, bool> TestApplication::getBool(const char* name, const char* ns) const
+ {
+ static const pair<bool, bool> retVal(false, false);
+ return retVal;
+ }
+ pair<bool, const char*> TestApplication::getString(const char* name, const char* ns) const
+ {
+ if (!strcmp(name, "entityID")) {
+ return pair<bool, const char*>(true, "http://localhost/Shibboleth");
+ }
+ if (!strcmp(name, "authType")) {
+ return pair<bool, const char*>(true, "NONE");
+ }
+ return pair<bool, const char*>(false, "");
+ }
+ pair<bool, const XMLCh*> TestApplication::getXMLString(const char* name, const char* ns) const
+ {
+ static const pair<bool, const XMLCh*> retVal(false, nullptr);
+ return retVal;
+ }
+ pair<bool, unsigned int> TestApplication::getUnsignedInt(const char* name, const char* ns) const
+ {
+ static const pair<bool, unsigned int> retVal(false, 1);
+ return retVal;
+ }
+ pair<bool, int> TestApplication::getInt(const char* name, const char* ns) const
+ {
+ static const pair<bool, int> retVal(false, -1);
+ return retVal;
+ }
+ void TestApplication::getAll(std::map<std::string, const char*>& properties) const
+ {
+ }
+ const PropertySet* TestApplication::getPropertySet(const char* name, const char* ns) const
+ {
+ return nullptr;
+ }
+ const xercesc::DOMElement* TestApplication::getElement() const
+ {
+ return nullptr;
+ }
+
+}
\ No newline at end of file
diff --git a/unittests/TestApplication.h b/unittests/TestApplication.h
new file mode 100644
index 0000000..2efaf59
--- /dev/null
+++ b/unittests/TestApplication.h
@@ -0,0 +1,67 @@
+#include <shibsp/spconfig.h>
+#include <shibsp/Application.h>
+#include <shibsp/util/DOMPropertySet.h>
+#include <saml/saml2/metadata/MetadataProvider.h>
+#include <saml/binding/SAMLArtifact.h>
+#include <saml/saml2/binding/SAML2Artifact.h>
+
+#if defined (_MSC_VER)
+#pragma warning( push )
+#pragma warning( disable : 4250 )
+#endif
+
+namespace ta {
+
+ using namespace std;
+ using namespace shibsp;
+ using namespace opensaml::saml2md;
+ using namespace opensaml;
+
+ class TestApplication : public Application {
+ public:
+ TestApplication(const ServiceProvider *sp, MetadataProvider* provider);
+
+ // Application
+ virtual const char* getHash() const;
+ virtual MetadataProvider* getMetadataProvider(bool required=true) const;
+ virtual xmltooling::TrustEngine* getTrustEngine(bool required=true) const;
+ virtual AttributeExtractor* getAttributeExtractor() const;
+ virtual AttributeFilter* getAttributeFilter() const;
+ virtual AttributeResolver* getAttributeResolver() const;
+ virtual xmltooling::CredentialResolver* getCredentialResolver() const;
+ virtual const PropertySet* getRelyingParty(const EntityDescriptor* provider) const;
+ virtual const PropertySet* getRelyingParty(const XMLCh* entityID) const;
+ virtual const vector<const XMLCh*>* getAudiences() const;
+ virtual string getNotificationURL(const char* request, bool front, unsigned int index) const;
+ virtual const vector<string>& getRemoteUserAttributeIds() const;
+ virtual const SessionInitiator* getDefaultSessionInitiator() const;
+ virtual const SessionInitiator* getSessionInitiatorById(const char* id) const;
+ virtual const Handler* getDefaultAssertionConsumerService() const;
+ virtual const Handler* getAssertionConsumerServiceByIndex(unsigned short index) const;
+ virtual const vector<const Handler*>& getAssertionConsumerServicesByBinding(const XMLCh* binding) const;
+ virtual const Handler* getHandler(const char* path) const;
+ virtual void getHandlers(vector<const Handler*>& handlers) const;
+ virtual SAMLArtifact* generateSAML1Artifact(const EntityDescriptor* relyingParty) const;
+ virtual saml2p::SAML2Artifact* generateSAML2Artifact(const EntityDescriptor* relyingParty) const;
+
+ // PropertySet
+ virtual const PropertySet* getParent() const;
+ virtual void setParent(const PropertySet* parent);
+ virtual pair<bool, bool> getBool(const char* name, const char* ns=nullptr) const;
+ virtual pair<bool, const char*> getString(const char* name, const char* ns=nullptr) const;
+ virtual pair<bool, const XMLCh*> getXMLString(const char* name, const char* ns=nullptr) const;
+ virtual pair<bool, unsigned int> getUnsignedInt(const char* name, const char* ns=nullptr) const;
+ virtual pair<bool, int> getInt(const char* name, const char* ns=nullptr) const;
+ virtual void getAll(std::map<std::string, const char*>& properties) const;
+ virtual const PropertySet* getPropertySet(const char* name, const char* ns=shibspconstants::ASCII_SHIB2SPCONFIG_NS) const;
+ virtual const xercesc::DOMElement* getElement() const;
+
+ private:
+ MetadataProvider* m_provider;
+ };
+
+}
+
+#if defined (_MSC_VER)
+#pragma warning( pop )
+#endif
diff --git a/unittests/data/regexFromFile.xml b/unittests/data/regexFromFile.xml
index 8bd6554..2f0d7d3 100644
--- a/unittests/data/regexFromFile.xml
+++ b/unittests/data/regexFromFile.xml
@@ -1,3 +1,4 @@
<MetadataProvider type="Dynamic" ignoreTransport="true" >
<Regex match="^https?://([a-zA-Z0-9\\.]+).*$">file:///H:/Perforce/VS2017/cpp-sp/unittests/data/$1.xml</Regex>
</MetadataProvider>
+
diff --git a/unittests/data/templateFromRepo.xml b/unittests/data/templateFromRepo.xml
index 8b77fb0..de2ca1b 100644
--- a/unittests/data/templateFromRepo.xml
+++ b/unittests/data/templateFromRepo.xml
@@ -1,3 +1,3 @@
<MetadataProvider type="Dynamic" ignoreTransport="true" >
-<Subst hashed="SHA1">https://git.shibboleth.net/view/?p=java-opensaml.git&a=blob_plain&f=opensaml-saml-impl/src/test/resources/org/opensaml/saml/metadata/resolver/impl/$entityID.xml&hb=master</Subst>
+<Subst hashed="SHA1">http://git.shibboleth.net/view/?p=java-opensaml.git&a=blob_plain&f=opensaml-saml-impl/src/test/resources/org/opensaml/saml/metadata/resolver/impl/$entityID.xml&hb=master</Subst>
</MetadataProvider>
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-shibboleth/shibboleth-sp2.git
More information about the Pkg-shibboleth-devel
mailing list