summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ILMergeInternalizeExceptions.txt0
-rw-r--r--LICENSE.txt2
-rw-r--r--build.proj105
-rw-r--r--samples/OpenIdOfflineProvider/OpenIdOfflineProvider.csproj5
-rw-r--r--samples/OpenIdProviderWebForms/Code/InMemoryConsumerDescription.cs31
-rw-r--r--samples/OpenIdProviderWebForms/Code/InMemoryServiceProviderAccessToken.cs31
-rw-r--r--samples/OpenIdProviderWebForms/Code/InMemoryServiceProviderRequestToken.cs42
-rw-r--r--samples/OpenIdProviderWebForms/Code/InMemoryTokenManager.cs113
-rw-r--r--samples/OpenIdProviderWebForms/Code/OAuthHybrid.cs46
-rw-r--r--samples/OpenIdProviderWebForms/OpenIdProviderWebForms.csproj11
-rw-r--r--samples/OpenIdProviderWebForms/access_token.ashx1
-rw-r--r--samples/OpenIdProviderWebForms/access_token.ashx.cs23
-rw-r--r--samples/OpenIdProviderWebForms/decide.aspx4
-rw-r--r--samples/OpenIdProviderWebForms/decide.aspx.cs24
-rw-r--r--samples/OpenIdProviderWebForms/decide.aspx.designer.cs18
-rw-r--r--samples/OpenIdRelyingPartyWebForms/Global.asax.cs14
-rw-r--r--samples/OpenIdRelyingPartyWebForms/OpenIdRelyingPartyWebForms.csproj8
-rw-r--r--samples/OpenIdRelyingPartyWebForms/loginPlusOAuthSampleOP.aspx33
-rw-r--r--samples/OpenIdRelyingPartyWebForms/loginPlusOAuthSampleOP.aspx.cs53
-rw-r--r--samples/OpenIdRelyingPartyWebForms/loginPlusOAuthSampleOP.aspx.designer.cs88
-rw-r--r--samples/OpenIdRelyingPartyWebForms/xrds.aspx4
-rw-r--r--src/DotNetOpenAuth.BuildTasks/ChangeAssemblyReference.cs47
-rw-r--r--src/DotNetOpenAuth.BuildTasks/ChangeProjectReferenceToAssemblyReference.cs50
-rw-r--r--src/DotNetOpenAuth.BuildTasks/CheckAdminRights.cs30
-rw-r--r--src/DotNetOpenAuth.BuildTasks/CompareFiles.cs85
-rw-r--r--src/DotNetOpenAuth.BuildTasks/CreateWebApplication.cs95
-rw-r--r--src/DotNetOpenAuth.BuildTasks/CustomMsBuildTasks.sln20
-rw-r--r--src/DotNetOpenAuth.BuildTasks/DeleteWebApplication.cs66
-rw-r--r--src/DotNetOpenAuth.BuildTasks/DotNetOpenAuth.BuildTasks.csproj85
-rw-r--r--src/DotNetOpenAuth.BuildTasks/FilterItems.cs24
-rw-r--r--src/DotNetOpenAuth.BuildTasks/GetBuildVersion.cs51
-rw-r--r--src/DotNetOpenAuth.BuildTasks/Properties/AssemblyInfo.cs36
-rw-r--r--src/DotNetOpenAuth.BuildTasks/ReSignDelaySignedAssemblies.cs56
-rw-r--r--src/DotNetOpenAuth.BuildTasks/SetEnvironmentVariable.cs33
-rw-r--r--src/DotNetOpenAuth.BuildTasks/SignatureVerification.cs45
-rw-r--r--src/DotNetOpenAuth.BuildTasks/SnToolTask.cs37
-rw-r--r--src/DotNetOpenAuth.BuildTasks/TaskStrings.Designer.cs99
-rw-r--r--src/DotNetOpenAuth.BuildTasks/TaskStrings.resx132
-rw-r--r--src/DotNetOpenAuth.BuildTasks/Trim.cs56
-rw-r--r--src/DotNetOpenAuth.Test/DotNetOpenAuth.Test.csproj5
-rw-r--r--src/DotNetOpenAuth.vsmdi10
-rw-r--r--src/DotNetOpenAuth/DotNetOpenAuth.csproj17
-rw-r--r--src/DotNetOpenAuth/OAuth/ChannelElements/ICombinedOpenIdProviderTokenManager.cs2
-rw-r--r--src/DotNetOpenAuth/OAuth/ChannelElements/PlaintextSigningBindingElement.cs7
-rw-r--r--src/DotNetOpenAuth/OAuth/ServiceProvider.cs32
-rw-r--r--src/DotNetOpenAuth/OAuth/WebConsumer.cs3
-rw-r--r--src/DotNetOpenAuth/OpenId/RelyingParty/AuthenticationRequest.cs11
-rw-r--r--src/DotNetOpenAuth/OpenId/RelyingParty/OpenIdRelyingPartyControlBase.cs48
-rw-r--r--src/DotNetOpenAuth/Util.cs10
-rw-r--r--src/official-build-key.pubbin0 -> 160 bytes
-rw-r--r--src/version.txt2
-rw-r--r--tools/DotNetOpenAuth.Common.Settings.targets25
-rw-r--r--tools/DotNetOpenAuth.Versioning.targets2
53 files changed, 1790 insertions, 87 deletions
diff --git a/ILMergeInternalizeExceptions.txt b/ILMergeInternalizeExceptions.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/ILMergeInternalizeExceptions.txt
diff --git a/LICENSE.txt b/LICENSE.txt
index a3f32e1..906ff2c 100644
--- a/LICENSE.txt
+++ b/LICENSE.txt
@@ -4,7 +4,7 @@ Every file is bound by the following copyright and license unless explicitly
indicated otherwise in and/or for any individual file.
-Copyright (c) 2008, Andrew Arnott
+Copyright (c) 2008-2009, Andrew Arnott
All rights reserved.
Microsoft Public License (Ms-PL)
diff --git a/build.proj b/build.proj
index cd417d1..a2c39d1 100644
--- a/build.proj
+++ b/build.proj
@@ -3,16 +3,26 @@
<PropertyGroup>
<AutomatedBuild>true</AutomatedBuild>
<SolutionPath>$(ProjectRoot)\src\$(ProductName).sln</SolutionPath>
+ <ILMergeOutputAssemblyDirectory>$(OutputPath)\unified\</ILMergeOutputAssemblyDirectory>
+ <ILMergeOutputAssembly>$(ILMergeOutputAssemblyDirectory)\$(ProductName).dll</ILMergeOutputAssembly>
</PropertyGroup>
<Import Project="$(ProjectRoot)\tools\$(ProductName).Versioning.targets"/>
<Import Project="$(ProjectRoot)\tools\Documentation.targets"/>
<Import Project="$(ProjectRoot)\tools\Publish.targets"/>
<UsingTask AssemblyFile="$(ProjectRoot)\lib\MSBuild.Community.Tasks.dll" TaskName="Zip"/>
+ <UsingTask AssemblyFile="$(ProjectRoot)\lib\MSBuild.Community.Tasks.dll" TaskName="ILMerge"/>
<ItemGroup>
<SampleProjects Include="$(ProjectRoot)\samples\**\*.csproj" />
<SampleSites Include="OAuthConsumer;OAuthServiceProvider;InfoCardRelyingParty" />
+ <ILMergeInputAssemblies Include="$(OutputPath)\$(ProductName).dll;
+ $(ProjectRoot)\lib\Microsoft.Contracts.dll; "/>
+ <DelaySignedAssemblies Include="$(ILMergeOutputAssembly);
+ $(OutputPath)\$(ProductName).dll;
+ $(OutputPath)\$(ProductName).Contracts.dll;
+ $(OutputPath)\$(ProductName).Test.dll;
+ $(ProjectRoot)\samples\OpenIdOfflineProvider\bin\$(Configuration)\OpenIdOfflineProvider.exe" />
</ItemGroup>
<Target Name="Clean" DependsOnTargets="CleanDocumentation;UnpublishSamples;UnpublishDocumentation">
@@ -22,7 +32,7 @@
$(ProjectRoot)\bin;
$(ProjectRoot)\**\obj;
$(ProjectRoot)\doc\api;
- $(ProjectRoot)\drops;
+ $(DropsRoot);
$(ProjectRoot)\src\PrecompiledWeb;
" />
<DirtyDirectories Include="@(SampleDirectories->'%(FullPath)\bin')" />
@@ -37,50 +47,68 @@
<RemoveDir Directories="@(DirtyDirectories)" />
</Target>
- <Target Name="BuildProduct">
+ <Target Name="SkipVerification" Condition="'$(IsElevated)' == 'true'">
+ <SignatureVerification SkipVerification="true" AssemblyName="$(ProductName)" PublicKeyToken="$(PublicKeyToken)" />
+ <SignatureVerification SkipVerification="true" AssemblyName="$(ProductName)_Accessor" PublicKeyToken="$(PublicKeyToken)" />
+ <SignatureVerification SkipVerification="true" AssemblyName="$(ProductName).Test" PublicKeyToken="$(PublicKeyToken)" />
+ </Target>
+
+ <Target Name="BuildProduct" DependsOnTargets="SkipVerification">
<MSBuild Projects="$(ProjectRoot)\src\$(ProductName)\$(ProductName).csproj" />
</Target>
- <Target Name="BuildTests">
+ <Target Name="BuildTests" DependsOnTargets="SkipVerification">
<MSBuild Projects="$(ProjectRoot)\src\$(ProductName).Test\$(ProductName).Test.csproj" />
</Target>
- <Target Name="BuildSamples">
+ <Target Name="BuildSamples" DependsOnTargets="SkipVerification">
<MSBuild Projects="@(SampleProjects)" />
- <MSBuild Projects="$(SolutionPath)" Targets="@(SampleSites)" Properties="Sign=$(Sign)" />
+ <MSBuild Projects="$(SolutionPath)" Targets="@(SampleSites)" />
</Target>
- <Target Name="Build">
- <!-- We explicitly pass the Sign property in because if properties are set
- inside this very .proj file instead of being passed on the command-line, their
- values won't propagate automatically. -->
- <MSBuild Projects="$(SolutionPath)" Properties="Sign=$(Sign)" />
+ <Target Name="Build" DependsOnTargets="SkipVerification">
+ <MSBuild Projects="$(SolutionPath)" />
</Target>
- <Target Name="Rebuild">
- <!-- We explicitly pass the Sign property in because if properties are set
- inside this very .proj file instead of being passed on the command-line, their
- values won't propagate automatically. -->
- <MSBuild Projects="$(SolutionPath)" Targets="Rebuild" Properties="Sign=$(Sign)" />
+ <Target Name="Rebuild" DependsOnTargets="SkipVerification">
+ <MSBuild Projects="$(SolutionPath)" Targets="Rebuild" />
</Target>
- <Target Name="_EnsureCleanTools" DependsOnTargets="_SetToolsProperties" Condition="'$(NoClean)' != 'true'">
- <!-- clean up any previous drop with the same name so we don't aggregate files. -->
- <RemoveDir Directories="$(ToolsDirectory)" />
+ <Target Name="BuildUnifiedProduct"
+ DependsOnTargets="BuildProduct"
+ Inputs="@(ILMergeInputAssemblies)"
+ Outputs="$(ILMergeOutputAssembly)">
+ <MakeDir Directories="$(ILMergeOutputAssemblyDirectory)" />
+ <ILMerge ExcludeFile="$(ProjectRoot)\ILMergeInternalizeExceptions.txt"
+ InputAssemblies="@(ILMergeInputAssemblies)"
+ OutputFile="$(ILMergeOutputAssembly)"
+ KeyFile="$(PublicKeyFile)"
+ DelaySign="true"
+ />
+ </Target>
+
+ <Target Name="ReSignDelaySignedAssemblies">
+ <Message Text="Signing delay-signed assemblies." />
+ <ReSignDelaySignedAssemblies
+ KeyContainer="$(KeyPairContainer)"
+ Assemblies="@(DelaySignedAssemblies)"
+ Condition="Exists(%(Identity))" />
</Target>
- <Target Name="_SetToolsProperties">
+ <Target Name="ToolsLayout" DependsOnTargets="GetBuildVersion;_SetDropProperties;BuildUnifiedProduct">
<PropertyGroup>
- <ToolsDirectory>$(ProjectRoot)\drops\$(ProductName)-Tools-$(BuildVersion)</ToolsDirectory>
+ <ToolsDirectory>$(DropsRoot)\$(ProductName)-Tools-$(BuildVersion)</ToolsDirectory>
</PropertyGroup>
- </Target>
- <Target Name="ToolsLayout" DependsOnTargets="GetBuildVersion;_SetDropProperties;_SetToolsProperties;_EnsureCleanTools">
<ItemGroup>
<ToolProjects Include="$(ProjectRoot)\Samples\OpenIdOfflineProvider\OpenIdOfflineProvider.csproj" />
<OfflineProvider Include="
$(ProjectRoot)\Samples\OpenIdOfflineProvider\bin\$(Configuration)\**\*.dll;
- $(ProjectRoot)\Samples\OpenIdOfflineProvider\bin\$(Configuration)\OpenIdOfflineProvider.exe" />
+ $(ILMergeOutputAssembly).*;
+ $(ProjectRoot)\Samples\OpenIdOfflineProvider\bin\$(Configuration)\OpenIdOfflineProvider.exe"
+ Exclude="
+ $(ProjectRoot)\Samples\OpenIdOfflineProvider\bin\$(Configuration)\$(ProductName).*;
+ "/>
<OfflineProviderTargets Include="
@(OfflineProvider->'$(ToolsDirectory)\%(RecursiveDir)%(FileName)%(Extension)')"/>
@@ -88,8 +116,10 @@
<AllToolTargets Include="@(OfflineProviderTargets)" />
</ItemGroup>
- <MSBuild Projects="@(ToolProjects)" Properties="Sign=$(Sign)" />
+ <MSBuild Projects="@(ToolProjects)" />
+ <!-- clean up any previous drop with the same name so we don't aggregate files. -->
+ <RemoveDir Directories="$(ToolsDirectory)" Condition="'$(NoClean)' != 'true'" />
<MakeDir Directories="@(ToolsDirectory)" />
<Copy SourceFiles="@(AllToolSources)" DestinationFiles="@(AllToolTargets)" SkipUnchangedFiles="true" />
</Target>
@@ -119,28 +149,13 @@
<Target Name="_SetDropProperties">
<!-- This target is necessary because PropertyGroups within the same Target as
where CallTarget is fired do NOT affect those called targets. -->
- <PropertyGroup>
- <Sign Condition="'$(Sign)' == ''">true</Sign>
- </PropertyGroup>
-
<!-- The rest of these are here so that other DependsOn targets have access to these properties. -->
<PropertyGroup>
- <DropDirectory>$(ProjectRoot)\drops\$(ProductName)-$(BuildVersion)</DropDirectory>
+ <DropDirectory>$(DropsRoot)\$(ProductName)-$(BuildVersion)</DropDirectory>
</PropertyGroup>
</Target>
- <Target Name="_EnsureCleanDrop" Condition="'$(NoClean)' != 'true'">
- <!-- This target only does a clean sufficient to guarantee that our DotNetOpenAuth.dll is rebuilt, but
- we don't usually want to clean our documentation because that takes forever to build froms scratch. -->
- <MSBuild Projects="$(SolutionPath)" Targets="Clean" />
-
- <!-- clean up any previous drop with the same name so we don't aggregate files. -->
- <RemoveDir Directories="$(DropDirectory)" />
- </Target>
-
- <Target Name="DropLayout" DependsOnTargets="GetBuildVersion;_SetDropProperties;_EnsureCleanDrop;BuildProduct;BuildSamples;Documentation">
- <Warning Condition=" '$(Configuration)' != 'release' " Text="Building $(Configuration) instead of Release!" />
- <Warning Condition=" '$(Sign)' != 'true' " Text="Building unsigned!" />
+ <Target Name="DropLayout" DependsOnTargets="GetBuildVersion;_SetDropProperties;BuildUnifiedProduct;ReSignDelaySignedAssemblies;BuildSamples;Documentation">
<PropertyGroup>
<DropBinDirectory>$(DropDirectory)\Bin</DropBinDirectory>
<DropLibDirectory>$(DropDirectory)\Lib</DropLibDirectory>
@@ -164,7 +179,8 @@
"
Exclude="$(ProjectRoot)\Doc\README.*.html;" />
<DropBinSourceFiles Include="
- $(OutputPath)\$(ProductName).???;
+ $(ILMergeOutputAssemblyDirectory)\$(ProductName).???;
+ $(OutputPath)\$(ProductName).xml;
$(OutputPath)\$(ProductName).Contracts.???;
$(ProjectRoot)\Doc\README.Bin.html;
$(ProjectRoot)\src\$(ProductName)\Configuration\$(ProductName).xsd;
@@ -222,6 +238,8 @@
" />
</ItemGroup>
+ <!-- clean up any previous drop with the same name so we don't aggregate files. -->
+ <RemoveDir Directories="$(DropDirectory)" Condition="'$(NoClean)' != 'true'" />
<MakeDir Directories="@(DropDirectories)" />
<Copy SourceFiles="@(AllDropSources)" DestinationFiles="@(AllDropTargets)" SkipUnchangedFiles="true" />
<!-- fix up the samples so that they will compile right out of the drop -->
@@ -237,7 +255,7 @@
<DropZip>$(DropDirectory).zip</DropZip>
</PropertyGroup>
<Delete Files="$(DropZip)" />
- <Zip Files="@(AllDropTargets)" ZipFileName="$(DropZip)" WorkingDirectory="$(ProjectRoot)\drops" />
+ <Zip Files="@(AllDropTargets)" ZipFileName="$(DropZip)" WorkingDirectory="$(DropsRoot)" />
</Target>
<!-- Although Nightly includes publishing samples and docs, those targets are conditioned for
@@ -245,5 +263,4 @@
<Target Name="Nightly" DependsOnTargets="Drop;Tools;PublishSamples;PublishDocumentation">
</Target>
-
</Project>
diff --git a/samples/OpenIdOfflineProvider/OpenIdOfflineProvider.csproj b/samples/OpenIdOfflineProvider/OpenIdOfflineProvider.csproj
index 1bb2367..2f303bb 100644
--- a/samples/OpenIdOfflineProvider/OpenIdOfflineProvider.csproj
+++ b/samples/OpenIdOfflineProvider/OpenIdOfflineProvider.csproj
@@ -57,10 +57,11 @@
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
- <PropertyGroup Condition=" '$(Sign)' == 'true' ">
+ <PropertyGroup>
<SignAssembly>true</SignAssembly>
- <AssemblyOriginatorKeyFile>..\..\src\official-build-key.pfx</AssemblyOriginatorKeyFile>
<DefineConstants>$(DefineConstants);StrongNameSigned</DefineConstants>
+ <DelaySign>true</DelaySign>
+ <AssemblyOriginatorKeyFile>..\..\src\official-build-key.pub</AssemblyOriginatorKeyFile>
</PropertyGroup>
<ItemGroup>
<Reference Include="log4net, Version=1.2.10.0, Culture=neutral, PublicKeyToken=1b44e1d426115821, processorArchitecture=MSIL">
diff --git a/samples/OpenIdProviderWebForms/Code/InMemoryConsumerDescription.cs b/samples/OpenIdProviderWebForms/Code/InMemoryConsumerDescription.cs
new file mode 100644
index 0000000..de4505d
--- /dev/null
+++ b/samples/OpenIdProviderWebForms/Code/InMemoryConsumerDescription.cs
@@ -0,0 +1,31 @@
+//-----------------------------------------------------------------------
+// <copyright file="InMemoryConsumerDescription.cs" company="Andrew Arnott">
+// Copyright (c) Andrew Arnott. All rights reserved.
+// </copyright>
+//-----------------------------------------------------------------------
+
+namespace OpenIdProviderWebForms.Code {
+ using System;
+ using System.Collections.Generic;
+ using System.Linq;
+ using System.Web;
+ using DotNetOpenAuth.OAuth.ChannelElements;
+
+ public class InMemoryConsumerDescription : IConsumerDescription {
+ #region IConsumerDescription Members
+
+ public string Key { get; set; }
+
+ public string Secret { get; set; }
+
+ public System.Security.Cryptography.X509Certificates.X509Certificate2 Certificate { get; set; }
+
+ public Uri Callback { get; set; }
+
+ public DotNetOpenAuth.OAuth.VerificationCodeFormat VerificationCodeFormat { get; set; }
+
+ public int VerificationCodeLength { get; set; }
+
+ #endregion
+ }
+}
diff --git a/samples/OpenIdProviderWebForms/Code/InMemoryServiceProviderAccessToken.cs b/samples/OpenIdProviderWebForms/Code/InMemoryServiceProviderAccessToken.cs
new file mode 100644
index 0000000..7e26b45
--- /dev/null
+++ b/samples/OpenIdProviderWebForms/Code/InMemoryServiceProviderAccessToken.cs
@@ -0,0 +1,31 @@
+//-----------------------------------------------------------------------
+// <copyright file="InMemoryServiceProviderAccessToken.cs" company="Andrew Arnott">
+// Copyright (c) Andrew Arnott. All rights reserved.
+// </copyright>
+//-----------------------------------------------------------------------
+
+namespace OpenIdProviderWebForms.Code {
+ using System;
+ using System.Collections.Generic;
+ using System.Linq;
+ using System.Web;
+ using DotNetOpenAuth.OAuth.ChannelElements;
+
+ public class InMemoryServiceProviderAccessToken : IServiceProviderAccessToken {
+ #region IServiceProviderAccessToken Members
+
+ public string Token { get; set; }
+
+ public DateTime? ExpirationDate { get; set; }
+
+ public string Username { get; set; }
+
+ public string[] Roles { get; set; }
+
+ #endregion
+
+ public string Secret { get; set; }
+
+ public string Scope { get; set; }
+ }
+}
diff --git a/samples/OpenIdProviderWebForms/Code/InMemoryServiceProviderRequestToken.cs b/samples/OpenIdProviderWebForms/Code/InMemoryServiceProviderRequestToken.cs
new file mode 100644
index 0000000..9c02427
--- /dev/null
+++ b/samples/OpenIdProviderWebForms/Code/InMemoryServiceProviderRequestToken.cs
@@ -0,0 +1,42 @@
+//-----------------------------------------------------------------------
+// <copyright file="InMemoryServiceProviderRequestToken.cs" company="Andrew Arnott">
+// Copyright (c) Andrew Arnott. All rights reserved.
+// </copyright>
+//-----------------------------------------------------------------------
+
+namespace OpenIdProviderWebForms.Code {
+ using System;
+ using System.Collections.Generic;
+ using System.Linq;
+ using System.Web;
+ using DotNetOpenAuth.OAuth.ChannelElements;
+
+ public class InMemoryServiceProviderRequestToken : IServiceProviderRequestToken {
+ /// <summary>
+ /// Initializes a new instance of the <see cref="InMemoryServiceProviderRequestToken"/> class.
+ /// </summary>
+ public InMemoryServiceProviderRequestToken() {
+ this.CreatedOn = DateTime.Now;
+ }
+
+ #region IServiceProviderRequestToken Members
+
+ public string Token { get; set; }
+
+ public string ConsumerKey { get; set; }
+
+ public DateTime CreatedOn { get; set; }
+
+ public Uri Callback { get; set; }
+
+ public string VerificationCode { get; set; }
+
+ public Version ConsumerVersion { get; set; }
+
+ #endregion
+
+ public string Secret { get; set; }
+
+ public string Scope { get; set; }
+ }
+}
diff --git a/samples/OpenIdProviderWebForms/Code/InMemoryTokenManager.cs b/samples/OpenIdProviderWebForms/Code/InMemoryTokenManager.cs
new file mode 100644
index 0000000..2433f57
--- /dev/null
+++ b/samples/OpenIdProviderWebForms/Code/InMemoryTokenManager.cs
@@ -0,0 +1,113 @@
+//-----------------------------------------------------------------------
+// <copyright file="InMemoryTokenManager.cs" company="Andrew Arnott">
+// Copyright (c) Andrew Arnott. All rights reserved.
+// </copyright>
+//-----------------------------------------------------------------------
+
+namespace OpenIdProviderWebForms.Code {
+ using System;
+ using System.Collections.Generic;
+ using System.Linq;
+ using System.Web;
+ using DotNetOpenAuth.OAuth.ChannelElements;
+ using DotNetOpenAuth.OAuth.Messages;
+ using DotNetOpenAuth.OpenId.Extensions.OAuth;
+
+ /// <summary>
+ /// A simple in-memory token manager. JUST FOR PURPOSES OF KEEPING THE SAMPLE SIMPLE.
+ /// </summary>
+ /// <remarks>
+ /// This is merely a sample app. A real web app SHOULD NEVER store a memory-only
+ /// token manager in application. It should be an IServiceProviderTokenManager
+ /// implementation that is bound to a database.
+ /// </remarks>
+ public class InMemoryTokenManager : IServiceProviderTokenManager, IOpenIdOAuthTokenManager, ICombinedOpenIdProviderTokenManager {
+ private Dictionary<string, InMemoryServiceProviderRequestToken> requestTokens = new Dictionary<string, InMemoryServiceProviderRequestToken>();
+ private Dictionary<string, InMemoryServiceProviderAccessToken> accessTokens = new Dictionary<string, InMemoryServiceProviderAccessToken>();
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="InMemoryTokenManager"/> class.
+ /// </summary>
+ internal InMemoryTokenManager() {
+ }
+
+ #region IServiceProviderTokenManager Members
+
+ public IConsumerDescription GetConsumer(string consumerKey) {
+ return new InMemoryConsumerDescription {
+ Key = consumerKey,
+ Secret = "some crazy secret",
+ };
+ }
+
+ public IServiceProviderRequestToken GetRequestToken(string token) {
+ return this.requestTokens[token];
+ }
+
+ public IServiceProviderAccessToken GetAccessToken(string token) {
+ throw new NotImplementedException();
+ }
+
+ #endregion
+
+ #region ITokenManager Members
+
+ public string GetTokenSecret(string token) {
+ if (this.requestTokens.ContainsKey(token)) {
+ return this.requestTokens[token].Secret;
+ } else {
+ return this.accessTokens[token].Secret;
+ }
+ }
+
+ public void StoreNewRequestToken(DotNetOpenAuth.OAuth.Messages.UnauthorizedTokenRequest request, DotNetOpenAuth.OAuth.Messages.ITokenSecretContainingMessage response) {
+ throw new NotImplementedException();
+ }
+
+ public bool IsRequestTokenAuthorized(string requestToken) {
+ // In OpenID+OAuth scenarios, request tokens are always authorized.
+ return true;
+ }
+
+ public void ExpireRequestTokenAndStoreNewAccessToken(string consumerKey, string requestToken, string accessToken, string accessTokenSecret) {
+ this.requestTokens.Remove(requestToken);
+ this.accessTokens[accessToken] = new InMemoryServiceProviderAccessToken {
+ Token = accessToken,
+ Secret = accessTokenSecret,
+ };
+ }
+
+ public TokenType GetTokenType(string token) {
+ if (this.requestTokens.ContainsKey(token)) {
+ return TokenType.RequestToken;
+ } else if (this.accessTokens.ContainsKey(token)) {
+ return TokenType.AccessToken;
+ } else {
+ return TokenType.InvalidToken;
+ }
+ }
+
+ #endregion
+
+ #region IOpenIdOAuthTokenManager Members
+
+ public void StoreOpenIdAuthorizedRequestToken(string consumerKey, AuthorizationApprovedResponse authorization) {
+ this.requestTokens[authorization.RequestToken] = new InMemoryServiceProviderRequestToken {
+ Token = authorization.RequestToken,
+ Scope = authorization.Scope,
+ ConsumerVersion = authorization.Version,
+ };
+ }
+
+ #endregion
+
+ #region ICombinedOpenIdProviderTokenManager Members
+
+ public string GetConsumerKey(DotNetOpenAuth.OpenId.Realm realm) {
+ // We just use the realm as the consumer key, like Google does.
+ return realm;
+ }
+
+ #endregion
+ }
+}
diff --git a/samples/OpenIdProviderWebForms/Code/OAuthHybrid.cs b/samples/OpenIdProviderWebForms/Code/OAuthHybrid.cs
new file mode 100644
index 0000000..cc4beff
--- /dev/null
+++ b/samples/OpenIdProviderWebForms/Code/OAuthHybrid.cs
@@ -0,0 +1,46 @@
+//-----------------------------------------------------------------------
+// <copyright file="OAuthHybrid.cs" company="Andrew Arnott">
+// Copyright (c) Andrew Arnott. All rights reserved.
+// </copyright>
+//-----------------------------------------------------------------------
+
+namespace OpenIdProviderWebForms.Code {
+ using System;
+ using System.Collections.Generic;
+ using System.Linq;
+ using System.Web;
+ using DotNetOpenAuth.Messaging;
+ using DotNetOpenAuth.OAuth;
+ using DotNetOpenAuth.OAuth.ChannelElements;
+
+ internal class OAuthHybrid {
+ /// <summary>
+ /// Initializes static members of the <see cref="OAuthHybrid"/> class.
+ /// </summary>
+ static OAuthHybrid() {
+ ServiceProvider = new ServiceProvider(GetServiceDescription(), TokenManager);
+ }
+
+ internal static IServiceProviderTokenManager TokenManager {
+ get {
+ // This is merely a sample app. A real web app SHOULD NEVER store a memory-only
+ // token manager in application. It should be an IServiceProviderTokenManager
+ // implementation that is bound to a database.
+ var tokenManager = (IServiceProviderTokenManager)HttpContext.Current.Application["TokenManager"];
+ if (tokenManager == null) {
+ HttpContext.Current.Application["TokenManager"] = tokenManager = new InMemoryTokenManager();
+ }
+
+ return tokenManager;
+ }
+ }
+
+ internal static ServiceProvider ServiceProvider { get; private set; }
+
+ internal static ServiceProviderDescription GetServiceDescription() {
+ return new ServiceProviderDescription {
+ TamperProtectionElements = new ITamperProtectionChannelBindingElement[] { new HmacSha1SigningBindingElement() },
+ };
+ }
+ }
+}
diff --git a/samples/OpenIdProviderWebForms/OpenIdProviderWebForms.csproj b/samples/OpenIdProviderWebForms/OpenIdProviderWebForms.csproj
index ceea842..ffb0f2f 100644
--- a/samples/OpenIdProviderWebForms/OpenIdProviderWebForms.csproj
+++ b/samples/OpenIdProviderWebForms/OpenIdProviderWebForms.csproj
@@ -83,12 +83,20 @@
<Content Include="user_xrds.aspx" />
</ItemGroup>
<ItemGroup>
+ <Compile Include="access_token.ashx.cs">
+ <DependentUpon>access_token.ashx</DependentUpon>
+ </Compile>
+ <Compile Include="Code\InMemoryConsumerDescription.cs" />
+ <Compile Include="Code\InMemoryServiceProviderAccessToken.cs" />
<Compile Include="Code\CustomStore.cs" />
<Compile Include="Code\CustomStoreDataSet.Designer.cs">
<DependentUpon>CustomStoreDataSet.xsd</DependentUpon>
<AutoGen>True</AutoGen>
<DesignTime>True</DesignTime>
</Compile>
+ <Compile Include="Code\InMemoryServiceProviderRequestToken.cs" />
+ <Compile Include="Code\InMemoryTokenManager.cs" />
+ <Compile Include="Code\OAuthHybrid.cs" />
<Compile Include="Code\ReadOnlyXmlMembershipProvider.cs" />
<Compile Include="Code\TracePageAppender.cs" />
<Compile Include="Code\Util.cs" />
@@ -157,6 +165,7 @@
<Content Include="TracePage.aspx" />
</ItemGroup>
<ItemGroup>
+ <Content Include="access_token.ashx" />
<None Include="Code\CustomStoreDataSet.xsc">
<DependentUpon>CustomStoreDataSet.xsd</DependentUpon>
</None>
@@ -190,7 +199,7 @@
<FlavorProperties GUID="{349c5851-65df-11da-9384-00065b846f21}">
<WebProjectProperties>
<UseIIS>False</UseIIS>
- <AutoAssignPort>True</AutoAssignPort>
+ <AutoAssignPort>False</AutoAssignPort>
<DevelopmentServerPort>4860</DevelopmentServerPort>
<DevelopmentServerVPath>/</DevelopmentServerVPath>
<IISUrl>
diff --git a/samples/OpenIdProviderWebForms/access_token.ashx b/samples/OpenIdProviderWebForms/access_token.ashx
new file mode 100644
index 0000000..dcb088e
--- /dev/null
+++ b/samples/OpenIdProviderWebForms/access_token.ashx
@@ -0,0 +1 @@
+<%@ WebHandler Language="C#" CodeBehind="access_token.ashx.cs" Class="OpenIdProviderWebForms.access_token" %>
diff --git a/samples/OpenIdProviderWebForms/access_token.ashx.cs b/samples/OpenIdProviderWebForms/access_token.ashx.cs
new file mode 100644
index 0000000..b895da9
--- /dev/null
+++ b/samples/OpenIdProviderWebForms/access_token.ashx.cs
@@ -0,0 +1,23 @@
+namespace OpenIdProviderWebForms {
+ using System;
+ using System.Collections.Generic;
+ using System.Linq;
+ using System.Web;
+ using System.Web.Services;
+ using DotNetOpenAuth.OAuth;
+ using OpenIdProviderWebForms.Code;
+
+ [WebService(Namespace = "http://tempuri.org/")]
+ [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
+ public class access_token : IHttpHandler {
+ public bool IsReusable {
+ get { return true; }
+ }
+
+ public void ProcessRequest(HttpContext context) {
+ var request = OAuthHybrid.ServiceProvider.ReadAccessTokenRequest();
+ var response = OAuthHybrid.ServiceProvider.PrepareAccessTokenMessage(request);
+ OAuthHybrid.ServiceProvider.Channel.Send(response);
+ }
+ }
+}
diff --git a/samples/OpenIdProviderWebForms/decide.aspx b/samples/OpenIdProviderWebForms/decide.aspx
index 4a6e2d8..3788315 100644
--- a/samples/OpenIdProviderWebForms/decide.aspx
+++ b/samples/OpenIdProviderWebForms/decide.aspx
@@ -17,6 +17,10 @@
<td><asp:Label runat="server" ID='realmLabel' /> </td>
</tr>
</table>
+ <asp:Panel runat="server" ID="OAuthPanel">
+ <p>In addition the relying party has asked for permission to access your private data. </p>
+ <asp:CheckBox runat="server" Text="Allow the relying party to access my private data" ID="oauthPermission" />
+ </asp:Panel>
<p>Allow this to proceed? </p>
<uc1:ProfileFields ID="profileFields" runat="server" Visible="false" />
<asp:Button ID="yes_button" OnClick="Yes_Click" Text=" yes " runat="Server" />
diff --git a/samples/OpenIdProviderWebForms/decide.aspx.cs b/samples/OpenIdProviderWebForms/decide.aspx.cs
index 3a14cf7..6146bd2 100644
--- a/samples/OpenIdProviderWebForms/decide.aspx.cs
+++ b/samples/OpenIdProviderWebForms/decide.aspx.cs
@@ -6,6 +6,7 @@ namespace OpenIdProviderWebForms {
using DotNetOpenAuth.OpenId.Extensions.ProviderAuthenticationPolicy;
using DotNetOpenAuth.OpenId.Extensions.SimpleRegistration;
using DotNetOpenAuth.OpenId.Provider;
+ using OpenIdProviderWebForms.Code;
/// <summary>
/// Page for giving the user the option to continue or cancel out of authentication with a consumer.
@@ -21,6 +22,11 @@ namespace OpenIdProviderWebForms {
this.realmLabel.Text = ProviderEndpoint.PendingRequest.Realm.ToString();
+ var oauthRequest = OAuthHybrid.ServiceProvider.ReadAuthorizationRequest(ProviderEndpoint.PendingRequest);
+ if (oauthRequest != null) {
+ this.OAuthPanel.Visible = true;
+ }
+
if (ProviderEndpoint.PendingAuthenticationRequest != null) {
if (ProviderEndpoint.PendingAuthenticationRequest.IsDirectedIdentity) {
ProviderEndpoint.PendingAuthenticationRequest.LocalIdentifier = Code.Util.BuildIdentityUrl();
@@ -51,6 +57,24 @@ namespace OpenIdProviderWebForms {
}
protected void Yes_Click(object sender, EventArgs e) {
+ if (!Page.IsValid) {
+ return;
+ }
+
+ if (this.OAuthPanel.Visible) {
+ string consumerKey = null;
+ string grantedScope = null;
+ if (this.oauthPermission.Checked) {
+ // This SIMPLE sample merely uses the realm as the consumerKey,
+ // but in a real app this will probably involve a database lookup to translate
+ // the realm to a known consumerKey.
+ consumerKey = ProviderEndpoint.PendingRequest.Realm;
+ grantedScope = string.Empty; // we don't scope individual access rights on this sample
+ }
+
+ OAuthHybrid.ServiceProvider.AttachAuthorizationResponse(ProviderEndpoint.PendingRequest, consumerKey, grantedScope);
+ }
+
var sregRequest = ProviderEndpoint.PendingRequest.GetExtension<ClaimsRequest>();
ClaimsResponse sregResponse = null;
if (sregRequest != null) {
diff --git a/samples/OpenIdProviderWebForms/decide.aspx.designer.cs b/samples/OpenIdProviderWebForms/decide.aspx.designer.cs
index 05386cd..3aa6271 100644
--- a/samples/OpenIdProviderWebForms/decide.aspx.designer.cs
+++ b/samples/OpenIdProviderWebForms/decide.aspx.designer.cs
@@ -50,6 +50,24 @@ namespace OpenIdProviderWebForms {
protected global::System.Web.UI.WebControls.Label realmLabel;
/// <summary>
+ /// OAuthPanel control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.WebControls.Panel OAuthPanel;
+
+ /// <summary>
+ /// oauthPermission control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.WebControls.CheckBox oauthPermission;
+
+ /// <summary>
/// profileFields control.
/// </summary>
/// <remarks>
diff --git a/samples/OpenIdRelyingPartyWebForms/Global.asax.cs b/samples/OpenIdRelyingPartyWebForms/Global.asax.cs
index ac74853..6583289 100644
--- a/samples/OpenIdRelyingPartyWebForms/Global.asax.cs
+++ b/samples/OpenIdRelyingPartyWebForms/Global.asax.cs
@@ -42,6 +42,20 @@
}
}
+ internal static InMemoryTokenManager OwnSampleOPHybridTokenManager {
+ get {
+ var tokenManager = (InMemoryTokenManager)HttpContext.Current.Application["OwnSampleOPHybridTokenManager"];
+ if (tokenManager == null) {
+ string consumerKey = new Uri(HttpContext.Current.Request.Url, HttpContext.Current.Request.ApplicationPath).AbsoluteUri;
+ string consumerSecret = "some crazy secret";
+ tokenManager = new InMemoryTokenManager(consumerKey, consumerSecret);
+ HttpContext.Current.Application["OwnSampleOPHybridTokenManager"] = tokenManager;
+ }
+
+ return tokenManager;
+ }
+ }
+
public static string ToString(NameValueCollection collection) {
using (StringWriter sw = new StringWriter()) {
foreach (string key in collection.Keys) {
diff --git a/samples/OpenIdRelyingPartyWebForms/OpenIdRelyingPartyWebForms.csproj b/samples/OpenIdRelyingPartyWebForms/OpenIdRelyingPartyWebForms.csproj
index d3bf92c..6f5df5c 100644
--- a/samples/OpenIdRelyingPartyWebForms/OpenIdRelyingPartyWebForms.csproj
+++ b/samples/OpenIdRelyingPartyWebForms/OpenIdRelyingPartyWebForms.csproj
@@ -101,6 +101,13 @@
<Compile Include="Code\InMemoryTokenManager.cs" />
<Compile Include="Code\State.cs" />
<Compile Include="Code\TracePageAppender.cs" />
+ <Compile Include="loginPlusOAuthSampleOP.aspx.cs">
+ <DependentUpon>loginPlusOAuthSampleOP.aspx</DependentUpon>
+ <SubType>ASPXCodeBehind</SubType>
+ </Compile>
+ <Compile Include="loginPlusOAuthSampleOP.aspx.designer.cs">
+ <DependentUpon>loginPlusOAuthSampleOP.aspx</DependentUpon>
+ </Compile>
<Compile Include="Global.asax.cs">
<DependentUpon>Global.asax</DependentUpon>
</Compile>
@@ -169,6 +176,7 @@
<Content Include="xrds.aspx" />
</ItemGroup>
<ItemGroup>
+ <Content Include="loginPlusOAuthSampleOP.aspx" />
<Content Include="images\attention.png" />
<Content Include="images\dotnetopenid_tiny.gif" />
<Content Include="images\openid_login.gif" />
diff --git a/samples/OpenIdRelyingPartyWebForms/loginPlusOAuthSampleOP.aspx b/samples/OpenIdRelyingPartyWebForms/loginPlusOAuthSampleOP.aspx
new file mode 100644
index 0000000..adbb71a
--- /dev/null
+++ b/samples/OpenIdRelyingPartyWebForms/loginPlusOAuthSampleOP.aspx
@@ -0,0 +1,33 @@
+<%@ Page Language="C#" AutoEventWireup="True" CodeBehind="loginPlusOAuthSampleOP.aspx.cs"
+ Inherits="OpenIdRelyingPartyWebForms.loginPlusOAuthSampleOP" ValidateRequest="false"
+ MasterPageFile="~/Site.Master" %>
+
+<%@ Register Assembly="DotNetOpenAuth" Namespace="DotNetOpenAuth.OpenId.RelyingParty"
+ TagPrefix="rp" %>
+<asp:Content ID="Content1" runat="server" ContentPlaceHolderID="Main">
+ <h2>Login Page </h2>
+ <asp:MultiView ID="MultiView1" runat="server" ActiveViewIndex='0'>
+ <asp:View ID="View1" runat="server">
+ <asp:Label runat="server" Text="OpenIdProviderWebForms sample's OP Identifier or Claimed Identifier: " />
+ <rp:OpenIdTextBox runat="server" ID="identifierBox" Text="http://localhost:4860/"
+ OnCanceled="identifierBox_Failed" OnFailed="identifierBox_Failed" OnLoggedIn="identifierBox_LoggedIn" />
+ <asp:RequiredFieldValidator ID="RequiredFieldValidator1" runat="server" ErrorMessage="required"
+ ControlToValidate="identifierBox" />
+ <br />
+ <asp:Button ID="beginButton" runat="server" Text="Login + OAuth request" OnClick="beginButton_Click" />
+ </asp:View>
+ <asp:View ID="AuthorizationGiven" runat="server">
+ Authentication succeeded, and OAuth access was granted.
+ <p>The actual login step is aborted since this sample focuses on the process only
+ up to this point.</p>
+ </asp:View>
+ <asp:View ID="AuthorizationDenied" runat="server">
+ Authentication succeeded, but OAuth access was denied.
+ <p>The actual login step is aborted since this sample focuses on the process only
+ up to this point.</p>
+ </asp:View>
+ <asp:View ID="AuthenticationFailed" runat="server">
+ Authentication failed or was canceled.
+ </asp:View>
+ </asp:MultiView>
+</asp:Content>
diff --git a/samples/OpenIdRelyingPartyWebForms/loginPlusOAuthSampleOP.aspx.cs b/samples/OpenIdRelyingPartyWebForms/loginPlusOAuthSampleOP.aspx.cs
new file mode 100644
index 0000000..5a86f31
--- /dev/null
+++ b/samples/OpenIdRelyingPartyWebForms/loginPlusOAuthSampleOP.aspx.cs
@@ -0,0 +1,53 @@
+namespace OpenIdRelyingPartyWebForms {
+ using System;
+ using System.Web.Security;
+ using DotNetOpenAuth.ApplicationBlock;
+ using DotNetOpenAuth.Messaging;
+ using DotNetOpenAuth.OAuth;
+ using DotNetOpenAuth.OAuth.ChannelElements;
+ using DotNetOpenAuth.OAuth.Messages;
+ using DotNetOpenAuth.OpenId;
+ using DotNetOpenAuth.OpenId.Extensions.AttributeExchange;
+ using DotNetOpenAuth.OpenId.RelyingParty;
+
+ public partial class loginPlusOAuthSampleOP : System.Web.UI.Page {
+ protected void Page_Load(object sender, EventArgs e) {
+ }
+
+ protected void beginButton_Click(object sender, EventArgs e) {
+ if (!Page.IsValid) {
+ return;
+ }
+
+ this.identifierBox.LogOn();
+ }
+
+ protected void identifierBox_LoggedIn(object sender, OpenIdEventArgs e) {
+ State.FetchResponse = e.Response.GetExtension<FetchResponse>();
+
+ ServiceProviderDescription serviceDescription = new ServiceProviderDescription {
+ AccessTokenEndpoint = new MessageReceivingEndpoint(new Uri(e.Response.Provider.Uri, "/access_token.ashx"), HttpDeliveryMethods.AuthorizationHeaderRequest | HttpDeliveryMethods.PostRequest),
+ TamperProtectionElements = new ITamperProtectionChannelBindingElement[] { new HmacSha1SigningBindingElement() },
+ };
+ WebConsumer consumer = new WebConsumer(serviceDescription, Global.OwnSampleOPHybridTokenManager);
+
+ AuthorizedTokenResponse accessToken = consumer.ProcessUserAuthorization(e.Response);
+ if (accessToken != null) {
+ this.MultiView1.SetActiveView(this.AuthorizationGiven);
+
+ // At this point, the access token would be somehow associated with the user
+ // account at the RP.
+ ////Database.Associate(e.Response.ClaimedIdentifier, accessToken.AccessToken);
+ } else {
+ this.MultiView1.SetActiveView(this.AuthorizationDenied);
+ }
+
+ // Avoid the redirect
+ e.Cancel = true;
+ }
+
+ protected void identifierBox_Failed(object sender, OpenIdEventArgs e) {
+ this.MultiView1.SetActiveView(this.AuthenticationFailed);
+ }
+ }
+}
diff --git a/samples/OpenIdRelyingPartyWebForms/loginPlusOAuthSampleOP.aspx.designer.cs b/samples/OpenIdRelyingPartyWebForms/loginPlusOAuthSampleOP.aspx.designer.cs
new file mode 100644
index 0000000..9bf29b9
--- /dev/null
+++ b/samples/OpenIdRelyingPartyWebForms/loginPlusOAuthSampleOP.aspx.designer.cs
@@ -0,0 +1,88 @@
+//------------------------------------------------------------------------------
+// <auto-generated>
+// This code was generated by a tool.
+// Runtime Version:2.0.50727.4918
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+// </auto-generated>
+//------------------------------------------------------------------------------
+
+namespace OpenIdRelyingPartyWebForms {
+
+
+ public partial class loginPlusOAuthSampleOP {
+
+ /// <summary>
+ /// MultiView1 control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.WebControls.MultiView MultiView1;
+
+ /// <summary>
+ /// View1 control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.WebControls.View View1;
+
+ /// <summary>
+ /// identifierBox control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::DotNetOpenAuth.OpenId.RelyingParty.OpenIdTextBox identifierBox;
+
+ /// <summary>
+ /// RequiredFieldValidator1 control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.WebControls.RequiredFieldValidator RequiredFieldValidator1;
+
+ /// <summary>
+ /// beginButton control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.WebControls.Button beginButton;
+
+ /// <summary>
+ /// AuthorizationGiven control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.WebControls.View AuthorizationGiven;
+
+ /// <summary>
+ /// AuthorizationDenied control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.WebControls.View AuthorizationDenied;
+
+ /// <summary>
+ /// AuthenticationFailed control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.WebControls.View AuthenticationFailed;
+ }
+}
diff --git a/samples/OpenIdRelyingPartyWebForms/xrds.aspx b/samples/OpenIdRelyingPartyWebForms/xrds.aspx
index 9e201d0..99a535c 100644
--- a/samples/OpenIdRelyingPartyWebForms/xrds.aspx
+++ b/samples/OpenIdRelyingPartyWebForms/xrds.aspx
@@ -17,7 +17,9 @@ is default.aspx.
<URI priority="1"><%=new Uri(Request.Url, Response.ApplyAppPathModifier("~/login.aspx"))%></URI>
<URI priority="2"><%=new Uri(Request.Url, Response.ApplyAppPathModifier("~/loginProgrammatic.aspx"))%></URI>
<URI priority="3"><%=new Uri(Request.Url, Response.ApplyAppPathModifier("~/ajaxlogin.aspx"))%></URI>
- <URI priority="3"><%=new Uri(Request.Url, Response.ApplyAppPathModifier("~/NoIdentityOpenId.aspx"))%></URI>
+ <URI priority="4"><%=new Uri(Request.Url, Response.ApplyAppPathModifier("~/NoIdentityOpenId.aspx"))%></URI>
+ <URI priority="5"><%=new Uri(Request.Url, Response.ApplyAppPathModifier("~/loginPlusOAuth.aspx"))%></URI>
+ <URI priority="6"><%=new Uri(Request.Url, Response.ApplyAppPathModifier("~/loginPlusOAuthSampleOP.aspx"))%></URI>
</Service>
</XRD>
</xrds:XRDS>
diff --git a/src/DotNetOpenAuth.BuildTasks/ChangeAssemblyReference.cs b/src/DotNetOpenAuth.BuildTasks/ChangeAssemblyReference.cs
new file mode 100644
index 0000000..3ad5eb0
--- /dev/null
+++ b/src/DotNetOpenAuth.BuildTasks/ChangeAssemblyReference.cs
@@ -0,0 +1,47 @@
+using System;
+using System.Linq;
+using System.IO;
+using System.Xml;
+
+using Microsoft.Build.Framework;
+using Microsoft.Build.Utilities;
+using Microsoft.Build.BuildEngine;
+
+namespace DotNetOpenAuth.BuildTasks {
+ /// <summary>
+ /// Replaces Reference items HintPaths in a set of projects.
+ /// </summary>
+ public class ChangeAssemblyReference : Task {
+ /// <summary>
+ /// The projects to alter.
+ /// </summary>
+ [Required]
+ public ITaskItem[] Projects { get; set; }
+ /// <summary>
+ /// The project reference to remove.
+ /// </summary>
+ [Required]
+ public string OldReference { get; set; }
+ /// <summary>
+ /// The assembly reference to add.
+ /// </summary>
+ [Required]
+ public string NewReference { get; set; }
+
+ const string msbuildNamespace = "http://schemas.microsoft.com/developer/msbuild/2003";
+ public override bool Execute() {
+ foreach (var project in Projects) {
+ Project doc = new Project();
+ doc.Load(project.ItemSpec);
+
+ var reference = doc.GetEvaluatedItemsByName("Reference").OfType<BuildItem>().
+ Where(item => string.Equals(item.GetMetadata("HintPath"), OldReference, StringComparison.OrdinalIgnoreCase)).Single();
+ reference.SetMetadata("HintPath", NewReference);
+
+ doc.Save(project.ItemSpec);
+ }
+
+ return true;
+ }
+ }
+}
diff --git a/src/DotNetOpenAuth.BuildTasks/ChangeProjectReferenceToAssemblyReference.cs b/src/DotNetOpenAuth.BuildTasks/ChangeProjectReferenceToAssemblyReference.cs
new file mode 100644
index 0000000..72415d9
--- /dev/null
+++ b/src/DotNetOpenAuth.BuildTasks/ChangeProjectReferenceToAssemblyReference.cs
@@ -0,0 +1,50 @@
+using System;
+using System.Linq;
+using System.IO;
+using System.Xml;
+
+using Microsoft.Build.Framework;
+using Microsoft.Build.Utilities;
+using Microsoft.Build.BuildEngine;
+
+namespace DotNetOpenAuth.BuildTasks {
+ /// <summary>
+ /// Replaces ProjectReference items in a set of projects with Reference items.
+ /// </summary>
+ public class ChangeProjectReferenceToAssemblyReference : Task {
+ /// <summary>
+ /// The projects to alter.
+ /// </summary>
+ [Required]
+ public ITaskItem[] Projects { get; set; }
+ /// <summary>
+ /// The project reference to remove.
+ /// </summary>
+ [Required]
+ public string ProjectReference { get; set; }
+ /// <summary>
+ /// The assembly reference to add.
+ /// </summary>
+ [Required]
+ public string Reference { get; set; }
+
+ const string msbuildNamespace = "http://schemas.microsoft.com/developer/msbuild/2003";
+ public override bool Execute() {
+ foreach (var project in Projects) {
+ Project doc = new Project();
+ doc.Load(project.ItemSpec);
+
+ var projectReference = doc.EvaluatedItems.OfType<BuildItem>().Where(
+ item => item.Name == "ProjectReference" && item.Include == ProjectReference).Single();
+ doc.RemoveItem(projectReference);
+
+ var newReference = doc.AddNewItem("Reference", Path.GetFileNameWithoutExtension(Reference));
+ newReference.SetMetadata("HintPath", Reference);
+
+ doc.Save(project.ItemSpec);
+ }
+
+ return true;
+ }
+ }
+}
diff --git a/src/DotNetOpenAuth.BuildTasks/CheckAdminRights.cs b/src/DotNetOpenAuth.BuildTasks/CheckAdminRights.cs
new file mode 100644
index 0000000..9cfd35d
--- /dev/null
+++ b/src/DotNetOpenAuth.BuildTasks/CheckAdminRights.cs
@@ -0,0 +1,30 @@
+//-----------------------------------------------------------------------
+// <copyright file="CheckAdminRights.cs" company="Andrew Arnott">
+// Copyright (c) Andrew Arnott. All rights reserved.
+// </copyright>
+//-----------------------------------------------------------------------
+
+namespace DotNetOpenAuth.BuildTasks {
+ using System.Security.Principal;
+ using Microsoft.Build.Framework;
+ using Microsoft.Build.Utilities;
+
+ public class CheckAdminRights : Task {
+ /// <summary>
+ /// Gets or sets a value indicating whether this process has elevated permissions.
+ /// </summary>
+ [Output]
+ public bool IsElevated { get; set; }
+
+ /// <summary>
+ /// Executes this instance.
+ /// </summary>
+ public override bool Execute() {
+ WindowsIdentity id = WindowsIdentity.GetCurrent();
+ WindowsPrincipal p = new WindowsPrincipal(id);
+ this.IsElevated = p.IsInRole(WindowsBuiltInRole.Administrator);
+
+ return true;
+ }
+ }
+}
diff --git a/src/DotNetOpenAuth.BuildTasks/CompareFiles.cs b/src/DotNetOpenAuth.BuildTasks/CompareFiles.cs
new file mode 100644
index 0000000..691df20
--- /dev/null
+++ b/src/DotNetOpenAuth.BuildTasks/CompareFiles.cs
@@ -0,0 +1,85 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using Microsoft.Build.Utilities;
+using Microsoft.Build.Framework;
+using System.IO;
+
+namespace DotNetOpenAuth.BuildTasks {
+ public class CompareFiles : Task {
+ /// <summary>
+ /// One set of items to compare.
+ /// </summary>
+ [Required]
+ public ITaskItem[] OriginalItems { get; set; }
+
+ /// <summary>
+ /// The other set of items to compare.
+ /// </summary>
+ [Required]
+ public ITaskItem[] NewItems { get; set; }
+
+ /// <summary>
+ /// Gets whether the items lists contain items that are identical going down the list.
+ /// </summary>
+ [Output]
+ public bool AreSame { get; private set; }
+
+ /// <summary>
+ /// Same as <see cref="AreSame"/>, but opposite.
+ /// </summary>
+ [Output]
+ public bool AreChanged { get { return !AreSame; } }
+
+ public override bool Execute() {
+ AreSame = AreFilesIdentical();
+ return true;
+ }
+
+ private bool AreFilesIdentical() {
+ if (OriginalItems.Length != NewItems.Length) {
+ return false;
+ }
+
+ for (int i = 0; i < OriginalItems.Length; i++) {
+ if (!IsContentOfFilesTheSame(OriginalItems[i].ItemSpec, NewItems[i].ItemSpec)) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ private bool IsContentOfFilesTheSame(string file1, string file2) {
+ // If exactly one file is missing, that's different.
+ if (File.Exists(file1) ^ File.Exists(file2)) return false;
+ // If both are missing, that's the same.
+ if (!File.Exists(file1)) return true;
+ // If both are present, we need to do a content comparison.
+ using (FileStream fileStream1 = File.OpenRead(file1)) {
+ using (FileStream fileStream2 = File.OpenRead(file2)) {
+ if (fileStream1.Length != fileStream2.Length) return false;
+ byte[] buffer1 = new byte[4096];
+ byte[] buffer2 = new byte[buffer1.Length];
+ int bytesRead;
+ do {
+ bytesRead = fileStream1.Read(buffer1, 0, buffer1.Length);
+ if (fileStream2.Read(buffer2, 0, buffer2.Length) != bytesRead) {
+ // We should never get here since we compared file lengths, but
+ // this is a sanity check.
+ return false;
+ }
+ for (int i = 0; i < bytesRead; i++) {
+ if (buffer1[i] != buffer2[i]) {
+ return false;
+ }
+ }
+ } while (bytesRead == buffer1.Length);
+ }
+ }
+
+ return true;
+ }
+ }
+}
diff --git a/src/DotNetOpenAuth.BuildTasks/CreateWebApplication.cs b/src/DotNetOpenAuth.BuildTasks/CreateWebApplication.cs
new file mode 100644
index 0000000..4980898
--- /dev/null
+++ b/src/DotNetOpenAuth.BuildTasks/CreateWebApplication.cs
@@ -0,0 +1,95 @@
+//-----------------------------------------------------------------------
+// <copyright file="CreateWebApplication.cs" company="Andrew Arnott">
+// Copyright (c) Andrew Arnott. All rights reserved.
+// </copyright>
+//-----------------------------------------------------------------------
+
+namespace DotNetOpenAuth.BuildTasks {
+ using System;
+ using System.Linq;
+ using Microsoft.Build.Framework;
+ using Microsoft.Build.Utilities;
+ using Microsoft.Web.Administration;
+
+ /// <summary>
+ /// Creates or updates web applications within an existing web site in IIS.
+ /// </summary>
+ public class CreateWebApplication : Task {
+ /// <summary>
+ /// Gets or sets the name of the application pool that should host the web application.
+ /// </summary>
+ /// <value>The name of an existing application pool.</value>
+ public string ApplicationPoolName { get; set; }
+
+ /// <summary>
+ /// Gets or sets the name of the web site under which to create the web application.
+ /// </summary>
+ /// <value>The name of the existing web site.</value>
+ [Required]
+ public string WebSiteName { get; set; }
+
+ /// <summary>
+ /// Gets or sets the virtual paths within the web site that will access these applications.
+ /// </summary>
+ /// <value>The virtual path, which must start with '/'.</value>
+ [Required]
+ public ITaskItem[] VirtualPaths { get; set; }
+
+ /// <summary>
+ /// Gets or sets the full file system paths to the web applications.
+ /// </summary>
+ /// <value>The physical path.</value>
+ [Required]
+ public ITaskItem[] PhysicalPaths { get; set; }
+
+ /// <summary>
+ /// Executes this instance.
+ /// </summary>
+ /// <returns>A value indicating whether the task completed successfully.</returns>
+ public override bool Execute() {
+ var serverManager = new ServerManager();
+
+ if (this.PhysicalPaths.Length != this.VirtualPaths.Length) {
+ Log.LogError(TaskStrings.MismatchingArrayLengths, "PhysicalPath", "VirtualPath");
+ return false;
+ }
+
+ if (this.VirtualPaths.Length == 0) {
+ // Nothing to do.
+ return true;
+ }
+
+ // Find the root web site that this web application will be created under.
+ var site = serverManager.Sites.FirstOrDefault(s => string.Equals(s.Name, this.WebSiteName, StringComparison.OrdinalIgnoreCase));
+ if (site == null) {
+ Log.LogError(TaskStrings.NoMatchingWebSiteFound, this.WebSiteName);
+ return false;
+ }
+
+ Log.LogMessage(MessageImportance.Normal, "Creating web applications under web site: {0}", site.Name);
+
+ for (int i = 0; i < this.PhysicalPaths.Length; i++) {
+ string physicalPath = this.PhysicalPaths[i].ItemSpec;
+ string virtualPath = this.VirtualPaths[i].ItemSpec;
+
+ Log.LogMessage(MessageImportance.Normal, "\t{0} -> {1}", virtualPath, physicalPath);
+
+ var app = site.Applications.FirstOrDefault(a => string.Equals(a.Path, virtualPath, StringComparison.OrdinalIgnoreCase));
+ if (app == null) {
+ app = site.Applications.Add(virtualPath, physicalPath);
+ } else {
+ // Ensure physical path is set correctly.
+ var appRoot = app.VirtualDirectories.First(vd => vd.Path == "/");
+ appRoot.PhysicalPath = physicalPath;
+ }
+
+ if (!string.IsNullOrEmpty(this.ApplicationPoolName)) {
+ app.ApplicationPoolName = this.ApplicationPoolName;
+ }
+ }
+
+ serverManager.CommitChanges();
+ return true;
+ }
+ }
+}
diff --git a/src/DotNetOpenAuth.BuildTasks/CustomMsBuildTasks.sln b/src/DotNetOpenAuth.BuildTasks/CustomMsBuildTasks.sln
new file mode 100644
index 0000000..6eae4e0
--- /dev/null
+++ b/src/DotNetOpenAuth.BuildTasks/CustomMsBuildTasks.sln
@@ -0,0 +1,20 @@
+
+Microsoft Visual Studio Solution File, Format Version 10.00
+# Visual Studio 2008
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DotNetOpenAuth.BuildTasks", "DotNetOpenAuth.BuildTasks.csproj", "{AC231A51-EF60-437C-A33F-AF8ADEB8EB74}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {AC231A51-EF60-437C-A33F-AF8ADEB8EB74}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {AC231A51-EF60-437C-A33F-AF8ADEB8EB74}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {AC231A51-EF60-437C-A33F-AF8ADEB8EB74}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {AC231A51-EF60-437C-A33F-AF8ADEB8EB74}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/src/DotNetOpenAuth.BuildTasks/DeleteWebApplication.cs b/src/DotNetOpenAuth.BuildTasks/DeleteWebApplication.cs
new file mode 100644
index 0000000..930a8c4
--- /dev/null
+++ b/src/DotNetOpenAuth.BuildTasks/DeleteWebApplication.cs
@@ -0,0 +1,66 @@
+//-----------------------------------------------------------------------
+// <copyright file="DeleteWebApplication.cs" company="Andrew Arnott">
+// Copyright (c) Andrew Arnott. All rights reserved.
+// </copyright>
+//-----------------------------------------------------------------------
+
+namespace DotNetOpenAuth.BuildTasks {
+ using System;
+ using System.Linq;
+ using Microsoft.Build.Framework;
+ using Microsoft.Build.Utilities;
+ using Microsoft.Web.Administration;
+
+ /// <summary>
+ /// Deletes a web application from IIS.
+ /// </summary>
+ public class DeleteWebApplication : Task {
+ /// <summary>
+ /// Gets or sets the name of the web site under which to create the web application.
+ /// </summary>
+ /// <value>The name of the existing web site.</value>
+ [Required]
+ public string WebSiteName { get; set; }
+
+ /// <summary>
+ /// Gets or sets the virtual paths within the web site that will access these applications.
+ /// </summary>
+ /// <value>The virtual path, which must start with '/'.</value>
+ [Required]
+ public ITaskItem[] VirtualPaths { get; set; }
+
+ /// <summary>
+ /// Executes this instance.
+ /// </summary>
+ /// <returns>A value indicating whether the task completed successfully.</returns>
+ public override bool Execute() {
+ var serverManager = new ServerManager();
+
+ // Find the root web site that this web application will be created under.
+ var site = serverManager.Sites.FirstOrDefault(s => string.Equals(s.Name, this.WebSiteName, StringComparison.OrdinalIgnoreCase));
+ if (site == null) {
+ Log.LogMessage(MessageImportance.Low, TaskStrings.NoMatchingWebSiteFound, this.WebSiteName);
+ return true;
+ }
+
+ if (this.VirtualPaths.Length == 0) {
+ // Nothing to do.
+ return true;
+ }
+
+ foreach (ITaskItem path in this.VirtualPaths) {
+ var app = site.Applications.FirstOrDefault(a => string.Equals(a.Path, path.ItemSpec, StringComparison.OrdinalIgnoreCase));
+ if (app != null) {
+ site.Applications.Remove(app);
+ Log.LogMessage(MessageImportance.Normal, TaskStrings.DeletedWebApplication, app.Path);
+ } else {
+ Log.LogMessage(MessageImportance.Low, TaskStrings.WebApplicationNotFoundSoNotDeleted, path.ItemSpec);
+ }
+ }
+
+ serverManager.CommitChanges();
+
+ return true;
+ }
+ }
+}
diff --git a/src/DotNetOpenAuth.BuildTasks/DotNetOpenAuth.BuildTasks.csproj b/src/DotNetOpenAuth.BuildTasks/DotNetOpenAuth.BuildTasks.csproj
new file mode 100644
index 0000000..4eb920e
--- /dev/null
+++ b/src/DotNetOpenAuth.BuildTasks/DotNetOpenAuth.BuildTasks.csproj
@@ -0,0 +1,85 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="3.5" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <ProductVersion>9.0.30729</ProductVersion>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{AC231A51-EF60-437C-A33F-AF8ADEB8EB74}</ProjectGuid>
+ <OutputType>Library</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <RootNamespace>DotNetOpenAuth.BuildTasks</RootNamespace>
+ <AssemblyName>DotNetOpenAuth.BuildTasks</AssemblyName>
+ <TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
+ <FileAlignment>512</FileAlignment>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>..\..\lib\</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>..\..\lib\</OutputPath>
+ <DefineConstants>TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <ItemGroup>
+ <Reference Include="Microsoft.Build.Engine" />
+ <Reference Include="Microsoft.Build.Framework" />
+ <Reference Include="Microsoft.Build.Utilities.v3.5">
+ <RequiredTargetFramework>3.5</RequiredTargetFramework>
+ </Reference>
+ <Reference Include="Microsoft.Web.Administration, Version=7.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
+ <SpecificVersion>False</SpecificVersion>
+ <HintPath>$(SystemRoot)\System32\inetsrv\Microsoft.Web.Administration.dll</HintPath>
+ </Reference>
+ <Reference Include="System" />
+ <Reference Include="System.Core">
+ <RequiredTargetFramework>3.5</RequiredTargetFramework>
+ </Reference>
+ <Reference Include="System.Data" />
+ <Reference Include="System.Xml" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="ChangeProjectReferenceToAssemblyReference.cs" />
+ <Compile Include="CompareFiles.cs" />
+ <Compile Include="ChangeAssemblyReference.cs" />
+ <Compile Include="CreateWebApplication.cs" />
+ <Compile Include="DeleteWebApplication.cs" />
+ <Compile Include="FilterItems.cs" />
+ <Compile Include="GetBuildVersion.cs" />
+ <Compile Include="CheckAdminRights.cs" />
+ <Compile Include="ReSignDelaySignedAssemblies.cs" />
+ <Compile Include="SetEnvironmentVariable.cs" />
+ <Compile Include="Properties\AssemblyInfo.cs" />
+ <Compile Include="SignatureVerification.cs" />
+ <Compile Include="SnToolTask.cs" />
+ <Compile Include="TaskStrings.Designer.cs">
+ <AutoGen>True</AutoGen>
+ <DesignTime>True</DesignTime>
+ <DependentUpon>TaskStrings.resx</DependentUpon>
+ </Compile>
+ <Compile Include="Trim.cs" />
+ </ItemGroup>
+ <ItemGroup>
+ <EmbeddedResource Include="TaskStrings.resx">
+ <Generator>ResXFileCodeGenerator</Generator>
+ <LastGenOutput>TaskStrings.Designer.cs</LastGenOutput>
+ </EmbeddedResource>
+ </ItemGroup>
+ <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+ <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
+ Other similar extension points exist, see Microsoft.Common.targets.
+ <Target Name="BeforeBuild">
+ </Target>
+ <Target Name="AfterBuild">
+ </Target>
+ -->
+</Project> \ No newline at end of file
diff --git a/src/DotNetOpenAuth.BuildTasks/FilterItems.cs b/src/DotNetOpenAuth.BuildTasks/FilterItems.cs
new file mode 100644
index 0000000..97631c6
--- /dev/null
+++ b/src/DotNetOpenAuth.BuildTasks/FilterItems.cs
@@ -0,0 +1,24 @@
+namespace DotNetOpenAuth.BuildTasks {
+ using System;
+ using System.Collections.Generic;
+ using System.Linq;
+ using System.Text;
+ using Microsoft.Build.Utilities;
+ using Microsoft.Build.Framework;
+
+ public class FilterItems : Task {
+ [Required]
+ public ITaskItem[] InputItems { get; set; }
+
+ [Required]
+ public ITaskItem[] StartsWithAny { get; set; }
+
+ [Output]
+ public ITaskItem[] FilteredItems { get; set; }
+
+ public override bool Execute() {
+ FilteredItems = InputItems.Where(item => StartsWithAny.Any(filter => item.ItemSpec.StartsWith(filter.ItemSpec, StringComparison.OrdinalIgnoreCase))).ToArray();
+ return true;
+ }
+ }
+}
diff --git a/src/DotNetOpenAuth.BuildTasks/GetBuildVersion.cs b/src/DotNetOpenAuth.BuildTasks/GetBuildVersion.cs
new file mode 100644
index 0000000..e40eb78
--- /dev/null
+++ b/src/DotNetOpenAuth.BuildTasks/GetBuildVersion.cs
@@ -0,0 +1,51 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using Microsoft.Build.Utilities;
+using Microsoft.Build.Framework;
+using System.IO;
+
+namespace DotNetOpenAuth.BuildTasks {
+ public class GetBuildVersion : Task {
+
+ /// <summary>
+ /// Gets the version string to use in the compiled assemblies.
+ /// </summary>
+ [Output]
+ public string Version { get; private set; }
+
+ /// <summary>
+ /// The file that contains the version base (Major.Minor.Build) to use.
+ /// </summary>
+ [Required]
+ public string VersionFile { get; set; }
+
+ public override bool Execute() {
+ try {
+ Version typedVersion = ReadVersionFromFile();
+ typedVersion = new Version(typedVersion.Major, typedVersion.Minor, typedVersion.Build, CalculateJDate(DateTime.Now));
+ Version = typedVersion.ToString();
+ } catch (ArgumentOutOfRangeException ex) {
+ Log.LogErrorFromException(ex);
+ return false;
+ }
+
+ return true;
+ }
+
+ private Version ReadVersionFromFile() {
+ string[] lines = File.ReadAllLines(VersionFile);
+ string versionLine = lines[0];
+ return new Version(versionLine);
+ }
+
+ private int CalculateJDate(DateTime date) {
+ int yearLastDigit = date.Year % 10;
+ DateTime firstOfYear = new DateTime(date.Year, 1, 1);
+ int dayOfYear = (date - firstOfYear).Days + 1;
+ int jdate = yearLastDigit * 1000 + dayOfYear;
+ return jdate;
+ }
+ }
+}
diff --git a/src/DotNetOpenAuth.BuildTasks/Properties/AssemblyInfo.cs b/src/DotNetOpenAuth.BuildTasks/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..6fdcc21
--- /dev/null
+++ b/src/DotNetOpenAuth.BuildTasks/Properties/AssemblyInfo.cs
@@ -0,0 +1,36 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("CustomMsBuildTasks")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("CustomMsBuildTasks")]
+[assembly: AssemblyCopyright("Copyright © 2008")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("952e3aaa-5dc6-4b71-8c9c-6b485263be19")]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/src/DotNetOpenAuth.BuildTasks/ReSignDelaySignedAssemblies.cs b/src/DotNetOpenAuth.BuildTasks/ReSignDelaySignedAssemblies.cs
new file mode 100644
index 0000000..a0ba386
--- /dev/null
+++ b/src/DotNetOpenAuth.BuildTasks/ReSignDelaySignedAssemblies.cs
@@ -0,0 +1,56 @@
+//-----------------------------------------------------------------------
+// <copyright file="ReSignDelaySignedAssemblies.cs" company="Andrew Arnott">
+// Copyright (c) Andrew Arnott. All rights reserved.
+// </copyright>
+//-----------------------------------------------------------------------
+
+namespace DotNetOpenAuth.BuildTasks {
+ using System;
+ using Microsoft.Build.Framework;
+ using Microsoft.Build.Utilities;
+
+ public class ReSignDelaySignedAssemblies : SnToolTask {
+ /// <summary>
+ /// Gets or sets the key file to use for signing.
+ /// </summary>
+ public ITaskItem KeyFile { get; set; }
+
+ /// <summary>
+ /// Gets or sets the key container.
+ /// </summary>
+ public ITaskItem KeyContainer { get; set; }
+
+ /// <summary>
+ /// Gets or sets the assemblies to re-sign.
+ /// </summary>
+ public ITaskItem[] Assemblies { get; set; }
+
+ /// <summary>
+ /// Generates the command line commands.
+ /// </summary>
+ protected override string GenerateCommandLineCommands() {
+ ////if (this.Assemblies.Length != 1) {
+ //// throw new NotSupportedException("Exactly 1 assembly for signing is supported.");
+ ////}
+ CommandLineBuilder args = new CommandLineBuilder();
+ args.AppendSwitch("-q");
+
+ if (this.KeyFile != null) {
+ args.AppendSwitch("-R");
+ } else if (this.KeyContainer != null) {
+ args.AppendSwitch("-Rc");
+ } else {
+ throw new InvalidOperationException("Either KeyFile or KeyContainer must be set.");
+ }
+
+ args.AppendFileNameIfNotNull(this.Assemblies[0]);
+ if (this.KeyFile != null) {
+ args.AppendFileNameIfNotNull(this.KeyFile);
+ } else {
+ args.AppendFileNameIfNotNull(this.KeyContainer);
+ }
+
+ return args.ToString();
+ }
+ }
+}
diff --git a/src/DotNetOpenAuth.BuildTasks/SetEnvironmentVariable.cs b/src/DotNetOpenAuth.BuildTasks/SetEnvironmentVariable.cs
new file mode 100644
index 0000000..2de5976
--- /dev/null
+++ b/src/DotNetOpenAuth.BuildTasks/SetEnvironmentVariable.cs
@@ -0,0 +1,33 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+using Microsoft.Build.Utilities;
+using Microsoft.Build.Framework;
+
+namespace DotNetOpenAuth.BuildTasks {
+ public class SetEnvironmentVariable : Task {
+ public SetEnvironmentVariable() {
+ Scope = EnvironmentVariableTarget.Process;
+ }
+
+ /// <summary>
+ /// The name of the environment variable to set or clear.
+ /// </summary>
+ [Required]
+ public string Name { get; set; }
+ /// <summary>
+ /// The value of the environment variable, or the empty string to clear it.
+ /// </summary>
+ [Required]
+ public string Value { get; set; }
+ /// <summary>
+ /// The target environment for the variable. Machine, User, or Process.
+ /// </summary>
+ public EnvironmentVariableTarget Scope { get; set; }
+
+ public override bool Execute() {
+ Environment.SetEnvironmentVariable(Name, Value, Scope);
+ return true;
+ }
+ }
+}
diff --git a/src/DotNetOpenAuth.BuildTasks/SignatureVerification.cs b/src/DotNetOpenAuth.BuildTasks/SignatureVerification.cs
new file mode 100644
index 0000000..2e69926
--- /dev/null
+++ b/src/DotNetOpenAuth.BuildTasks/SignatureVerification.cs
@@ -0,0 +1,45 @@
+//-----------------------------------------------------------------------
+// <copyright file="SignatureVerification.cs" company="Andrew Arnott">
+// Copyright (c) Andrew Arnott. All rights reserved.
+// </copyright>
+//-----------------------------------------------------------------------
+
+namespace DotNetOpenAuth.BuildTasks {
+ using Microsoft.Build.Utilities;
+
+ public class SignatureVerification : SnToolTask {
+ /// <summary>
+ /// Gets or sets a value indicating whether to register the given assembly and public key token
+ /// for skip verification or clear any pre-existing skip verification entry.
+ /// </summary>
+ public bool SkipVerification { get; set; }
+
+ /// <summary>
+ /// Gets or sets the name of the assembly.
+ /// </summary>
+ /// <value>The name of the assembly.</value>
+ public string AssemblyName { get; set; }
+
+ /// <summary>
+ /// Gets or sets the public key token.
+ /// </summary>
+ /// <value>The public key token.</value>
+ public string PublicKeyToken { get; set; }
+
+ /// <summary>
+ /// Generates the command line commands.
+ /// </summary>
+ protected override string GenerateCommandLineCommands() {
+ CommandLineBuilder builder = new CommandLineBuilder();
+ builder.AppendSwitch("-q");
+ if (this.SkipVerification) {
+ builder.AppendSwitch("-Vr");
+ } else {
+ builder.AppendSwitch("-Vu");
+ }
+
+ builder.AppendFileNameIfNotNull(this.AssemblyName + "," + this.PublicKeyToken);
+ return builder.ToString();
+ }
+ }
+}
diff --git a/src/DotNetOpenAuth.BuildTasks/SnToolTask.cs b/src/DotNetOpenAuth.BuildTasks/SnToolTask.cs
new file mode 100644
index 0000000..1c32632
--- /dev/null
+++ b/src/DotNetOpenAuth.BuildTasks/SnToolTask.cs
@@ -0,0 +1,37 @@
+//-----------------------------------------------------------------------
+// <copyright file="SnToolTask.cs" company="Andrew Arnott">
+// Copyright (c) Andrew Arnott. All rights reserved.
+// </copyright>
+//-----------------------------------------------------------------------
+
+namespace DotNetOpenAuth.BuildTasks {
+ using System;
+ using System.IO;
+ using Microsoft.Build.Utilities;
+
+ public abstract class SnToolTask : ToolTask {
+ /// <summary>
+ /// Gets the name of the tool.
+ /// </summary>
+ /// <value>The name of the tool.</value>
+ protected override string ToolName {
+ get { return "sn.exe"; }
+ }
+
+ /// <summary>
+ /// Generates the full path to tool.
+ /// </summary>
+ protected override string GenerateFullPathToTool() {
+ string[] versions = new[] { "v6.0A", "v6.1" };
+ string fullPath = null;
+ foreach (string version in versions) {
+ fullPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles), @"Microsoft SDKs\Windows\" + version + @"\bin\" + this.ToolName);
+ if (File.Exists(fullPath)) {
+ return fullPath;
+ }
+ }
+
+ throw new FileNotFoundException("Unable to find sn.exe tool.", fullPath);
+ }
+ }
+}
diff --git a/src/DotNetOpenAuth.BuildTasks/TaskStrings.Designer.cs b/src/DotNetOpenAuth.BuildTasks/TaskStrings.Designer.cs
new file mode 100644
index 0000000..a727695
--- /dev/null
+++ b/src/DotNetOpenAuth.BuildTasks/TaskStrings.Designer.cs
@@ -0,0 +1,99 @@
+//------------------------------------------------------------------------------
+// <auto-generated>
+// This code was generated by a tool.
+// Runtime Version:2.0.50727.4918
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+// </auto-generated>
+//------------------------------------------------------------------------------
+
+namespace DotNetOpenAuth.BuildTasks {
+ using System;
+
+
+ /// <summary>
+ /// A strongly-typed resource class, for looking up localized strings, etc.
+ /// </summary>
+ // This class was auto-generated by the StronglyTypedResourceBuilder
+ // class via a tool like ResGen or Visual Studio.
+ // To add or remove a member, edit your .ResX file then rerun ResGen
+ // with the /str option, or rebuild your VS project.
+ [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "2.0.0.0")]
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
+ internal class TaskStrings {
+
+ private static global::System.Resources.ResourceManager resourceMan;
+
+ private static global::System.Globalization.CultureInfo resourceCulture;
+
+ [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
+ internal TaskStrings() {
+ }
+
+ /// <summary>
+ /// Returns the cached ResourceManager instance used by this class.
+ /// </summary>
+ [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
+ internal static global::System.Resources.ResourceManager ResourceManager {
+ get {
+ if (object.ReferenceEquals(resourceMan, null)) {
+ global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("DotNetOpenAuth.BuildTasks.TaskStrings", typeof(TaskStrings).Assembly);
+ resourceMan = temp;
+ }
+ return resourceMan;
+ }
+ }
+
+ /// <summary>
+ /// Overrides the current thread's CurrentUICulture property for all
+ /// resource lookups using this strongly typed resource class.
+ /// </summary>
+ [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
+ internal static global::System.Globalization.CultureInfo Culture {
+ get {
+ return resourceCulture;
+ }
+ set {
+ resourceCulture = value;
+ }
+ }
+
+ /// <summary>
+ /// Looks up a localized string similar to Web application &apos;{0}&apos; deleted..
+ /// </summary>
+ internal static string DeletedWebApplication {
+ get {
+ return ResourceManager.GetString("DeletedWebApplication", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// Looks up a localized string similar to The {0} and {1} properties must be set to arrays of equal length..
+ /// </summary>
+ internal static string MismatchingArrayLengths {
+ get {
+ return ResourceManager.GetString("MismatchingArrayLengths", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// Looks up a localized string similar to No web site with the name &apos;{0}&apos; found..
+ /// </summary>
+ internal static string NoMatchingWebSiteFound {
+ get {
+ return ResourceManager.GetString("NoMatchingWebSiteFound", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// Looks up a localized string similar to Web application &apos;{0}&apos; was not found, so it was not deleted..
+ /// </summary>
+ internal static string WebApplicationNotFoundSoNotDeleted {
+ get {
+ return ResourceManager.GetString("WebApplicationNotFoundSoNotDeleted", resourceCulture);
+ }
+ }
+ }
+}
diff --git a/src/DotNetOpenAuth.BuildTasks/TaskStrings.resx b/src/DotNetOpenAuth.BuildTasks/TaskStrings.resx
new file mode 100644
index 0000000..2aaa32e
--- /dev/null
+++ b/src/DotNetOpenAuth.BuildTasks/TaskStrings.resx
@@ -0,0 +1,132 @@
+<?xml version="1.0" encoding="utf-8"?>
+<root>
+ <!--
+ Microsoft ResX Schema
+
+ Version 2.0
+
+ The primary goals of this format is to allow a simple XML format
+ that is mostly human readable. The generation and parsing of the
+ various data types are done through the TypeConverter classes
+ associated with the data types.
+
+ Example:
+
+ ... ado.net/XML headers & schema ...
+ <resheader name="resmimetype">text/microsoft-resx</resheader>
+ <resheader name="version">2.0</resheader>
+ <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
+ <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
+ <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
+ <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
+ <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
+ <value>[base64 mime encoded serialized .NET Framework object]</value>
+ </data>
+ <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+ <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
+ <comment>This is a comment</comment>
+ </data>
+
+ There are any number of "resheader" rows that contain simple
+ name/value pairs.
+
+ Each data row contains a name, and value. The row also contains a
+ type or mimetype. Type corresponds to a .NET class that support
+ text/value conversion through the TypeConverter architecture.
+ Classes that don't support this are serialized and stored with the
+ mimetype set.
+
+ The mimetype is used for serialized objects, and tells the
+ ResXResourceReader how to depersist the object. This is currently not
+ extensible. For a given mimetype the value must be set accordingly:
+
+ Note - application/x-microsoft.net.object.binary.base64 is the format
+ that the ResXResourceWriter will generate, however the reader can
+ read any of the formats listed below.
+
+ mimetype: application/x-microsoft.net.object.binary.base64
+ value : The object must be serialized with
+ : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
+ : and then encoded with base64 encoding.
+
+ mimetype: application/x-microsoft.net.object.soap.base64
+ value : The object must be serialized with
+ : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
+ : and then encoded with base64 encoding.
+
+ mimetype: application/x-microsoft.net.object.bytearray.base64
+ value : The object must be serialized into a byte array
+ : using a System.ComponentModel.TypeConverter
+ : and then encoded with base64 encoding.
+ -->
+ <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
+ <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
+ <xsd:element name="root" msdata:IsDataSet="true">
+ <xsd:complexType>
+ <xsd:choice maxOccurs="unbounded">
+ <xsd:element name="metadata">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element name="value" type="xsd:string" minOccurs="0" />
+ </xsd:sequence>
+ <xsd:attribute name="name" use="required" type="xsd:string" />
+ <xsd:attribute name="type" type="xsd:string" />
+ <xsd:attribute name="mimetype" type="xsd:string" />
+ <xsd:attribute ref="xml:space" />
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="assembly">
+ <xsd:complexType>
+ <xsd:attribute name="alias" type="xsd:string" />
+ <xsd:attribute name="name" type="xsd:string" />
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="data">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+ <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
+ </xsd:sequence>
+ <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
+ <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
+ <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
+ <xsd:attribute ref="xml:space" />
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="resheader">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+ </xsd:sequence>
+ <xsd:attribute name="name" type="xsd:string" use="required" />
+ </xsd:complexType>
+ </xsd:element>
+ </xsd:choice>
+ </xsd:complexType>
+ </xsd:element>
+ </xsd:schema>
+ <resheader name="resmimetype">
+ <value>text/microsoft-resx</value>
+ </resheader>
+ <resheader name="version">
+ <value>2.0</value>
+ </resheader>
+ <resheader name="reader">
+ <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+ </resheader>
+ <resheader name="writer">
+ <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+ </resheader>
+ <data name="DeletedWebApplication" xml:space="preserve">
+ <value>Web application '{0}' deleted.</value>
+ </data>
+ <data name="MismatchingArrayLengths" xml:space="preserve">
+ <value>The {0} and {1} properties must be set to arrays of equal length.</value>
+ </data>
+ <data name="NoMatchingWebSiteFound" xml:space="preserve">
+ <value>No web site with the name '{0}' found.</value>
+ </data>
+ <data name="WebApplicationNotFoundSoNotDeleted" xml:space="preserve">
+ <value>Web application '{0}' was not found, so it was not deleted.</value>
+ </data>
+</root> \ No newline at end of file
diff --git a/src/DotNetOpenAuth.BuildTasks/Trim.cs b/src/DotNetOpenAuth.BuildTasks/Trim.cs
new file mode 100644
index 0000000..1cc943e
--- /dev/null
+++ b/src/DotNetOpenAuth.BuildTasks/Trim.cs
@@ -0,0 +1,56 @@
+//-----------------------------------------------------------------------
+// <copyright file="Trim.cs" company="Andrew Arnott">
+// Copyright (c) Andrew Arnott. All rights reserved.
+// </copyright>
+//-----------------------------------------------------------------------
+
+namespace DotNetOpenAuth.BuildTasks {
+ using Microsoft.Build.Framework;
+ using Microsoft.Build.Utilities;
+
+ /// <summary>
+ /// Trims item identities.
+ /// </summary>
+ public class Trim : Task {
+ /// <summary>
+ /// Gets or sets the characters that should be trimmed off if found at the start of items' ItemSpecs.
+ /// </summary>
+ public string StartCharacters { get; set; }
+
+ /// <summary>
+ /// Gets or sets the characters that should be trimmed off if found at the end of items' ItemSpecs.
+ /// </summary>
+ public string EndCharacters { get; set; }
+
+ /// <summary>
+ /// Gets or sets the items with ItemSpec's to be trimmed.
+ /// </summary>
+ [Required]
+ public ITaskItem[] Inputs { get; set; }
+
+ /// <summary>
+ /// Gets or sets the items with trimmed ItemSpec strings.
+ /// </summary>
+ [Output]
+ public ITaskItem[] Outputs { get; set; }
+
+ /// <summary>
+ /// Executes this instance.
+ /// </summary>
+ /// <returns>A value indicating whether the task completed successfully.</returns>
+ public override bool Execute() {
+ this.Outputs = new ITaskItem[this.Inputs.Length];
+ for (int i = 0; i < this.Inputs.Length; i++) {
+ this.Outputs[i] = new TaskItem(this.Inputs[i]);
+ if (!string.IsNullOrEmpty(this.StartCharacters)) {
+ this.Outputs[i].ItemSpec = this.Outputs[i].ItemSpec.TrimStart(this.StartCharacters.ToCharArray());
+ }
+ if (!string.IsNullOrEmpty(this.EndCharacters)) {
+ this.Outputs[i].ItemSpec = this.Outputs[i].ItemSpec.TrimEnd(this.EndCharacters.ToCharArray());
+ }
+ }
+
+ return true;
+ }
+ }
+}
diff --git a/src/DotNetOpenAuth.Test/DotNetOpenAuth.Test.csproj b/src/DotNetOpenAuth.Test/DotNetOpenAuth.Test.csproj
index f9ec80e..414d3d0 100644
--- a/src/DotNetOpenAuth.Test/DotNetOpenAuth.Test.csproj
+++ b/src/DotNetOpenAuth.Test/DotNetOpenAuth.Test.csproj
@@ -53,9 +53,10 @@
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
- <PropertyGroup Condition=" '$(Sign)' == 'true' ">
+ <PropertyGroup>
<SignAssembly>true</SignAssembly>
- <AssemblyOriginatorKeyFile>..\official-build-key.pfx</AssemblyOriginatorKeyFile>
+ <DelaySign>true</DelaySign>
+ <AssemblyOriginatorKeyFile>..\official-build-key.pub</AssemblyOriginatorKeyFile>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'CodeAnalysis|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
diff --git a/src/DotNetOpenAuth.vsmdi b/src/DotNetOpenAuth.vsmdi
index 8874d7e..bed7c96 100644
--- a/src/DotNetOpenAuth.vsmdi
+++ b/src/DotNetOpenAuth.vsmdi
@@ -144,7 +144,7 @@
<TestLink id="f4537b23-bb5e-5c6f-da53-64b34472f0dc" name="ChannelGetter" storage="..\bin\debug\dotnetopenauth.test.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, PublicKeyToken=b03f5f7f11d50a3a" />
<TestLink id="75fa4664-bb0e-3a54-de29-c18ac712b231" name="Mode" storage="..\bin\debug\dotnetopenauth.test.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, PublicKeyToken=b03f5f7f11d50a3a" />
<TestLink id="94ba9fd3-851d-13b2-e273-6294b167c13e" name="HttpsSignatureVerification" storage="..\bin\debug\dotnetopenauth.test.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, PublicKeyToken=b03f5f7f11d50a3a" />
- <TestLink id="ff78d828-b437-aaeb-e48a-85a5ad1fe396" name="Ctor" storage="..\bin\debug\dotnetopenauth.test.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, PublicKeyToken=b03f5f7f11d50a3a" />
+ <TestLink id="cbfeb75b-d031-7df3-c281-3c9e1c450042" name="CtorFromRequest" storage="..\bin\debug\dotnetopenauth.test.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, PublicKeyToken=b03f5f7f11d50a3a" />
<TestLink id="5460f9c6-ec9d-969d-5aff-b946d6776e25" name="CtorWithNullProtocolMessage" storage="..\bin\debug\dotnetopenauth.test.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, PublicKeyToken=b03f5f7f11d50a3a" />
<TestLink id="d5f4e610-eabe-1dc0-ab3f-7c9dcb17fcc3" name="CtorImpliedLocalIdentifier" storage="..\bin\debug\dotnetopenauth.test.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, PublicKeyToken=b03f5f7f11d50a3a" />
<TestLink id="64d8c630-76c6-e420-937b-19c889dd7f59" name="CtorNonMessageType" storage="..\bin\debug\dotnetopenauth.test.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, PublicKeyToken=b03f5f7f11d50a3a" />
@@ -241,7 +241,7 @@
<TestLink id="704a32d0-3f50-d462-f767-fd9cf1981b7f" name="ProviderVersion" storage="..\bin\debug\dotnetopenauth.test.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, PublicKeyToken=b03f5f7f11d50a3a" />
<TestLink id="f362baf3-da5b-1b8c-39ae-7c9b2051270a" name="AuthenticationTimeUtcSetUtc" storage="..\bin\debug\dotnetopenauth.test.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, PublicKeyToken=b03f5f7f11d50a3a" />
<TestLink id="3bb818b4-5423-ad91-8cd9-8606ec85d2cb" name="ReadFromRequestAuthorizationScattered" storage="..\bin\debug\dotnetopenauth.test.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, PublicKeyToken=b03f5f7f11d50a3a" />
- <TestLink id="cbfeb75b-d031-7df3-c281-3c9e1c450042" name="CtorFromRequest" storage="..\bin\debug\dotnetopenauth.test.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, PublicKeyToken=b03f5f7f11d50a3a" />
+ <TestLink id="30f3c12b-e510-de63-5acd-ae8e32866592" name="CreateQueryString" storage="..\bin\debug\dotnetopenauth.test.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, PublicKeyToken=b03f5f7f11d50a3a" />
<TestLink id="9302541c-9c30-9ce7-66db-348ee4e9f6ee" name="UnifyExtensionsAsSregWithSreg" storage="..\bin\debug\dotnetopenauth.test.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, PublicKeyToken=b03f5f7f11d50a3a" />
<TestLink id="997253fb-7591-c151-1705-02976b400f27" name="AddAttributeTwice" storage="..\bin\debug\dotnetopenauth.test.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, PublicKeyToken=b03f5f7f11d50a3a" />
<TestLink id="88ae5661-da27-91c5-4d78-1f43cd716127" name="EqualsTest" storage="..\bin\debug\dotnetopenauth.test.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, PublicKeyToken=b03f5f7f11d50a3a" />
@@ -331,7 +331,7 @@
<TestLink id="d083396b-db68-1318-e62b-6dc9f89e26bd" name="CtorDefault" storage="..\bin\debug\dotnetopenauth.test.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, PublicKeyToken=b03f5f7f11d50a3a" />
<TestLink id="2f6a81c5-cd04-0ca0-22ee-d4213f9cf147" name="EqualityTests" storage="..\bin\debug\dotnetopenauth.test.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, PublicKeyToken=b03f5f7f11d50a3a" />
<TestLink id="72d3f240-67f2-0b04-bd31-a99c3f7a8e12" name="SharedAssociationPositive" storage="..\bin\debug\dotnetopenauth.test.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, PublicKeyToken=b03f5f7f11d50a3a" />
- <TestLink id="30f3c12b-e510-de63-5acd-ae8e32866592" name="CreateQueryString" storage="..\bin\debug\dotnetopenauth.test.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, PublicKeyToken=b03f5f7f11d50a3a" />
+ <TestLink id="3cd9447e-9ffd-f706-37bb-e7eb5828e430" name="InvalidRealmEmpty" storage="..\bin\debug\dotnetopenauth.test.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, PublicKeyToken=b03f5f7f11d50a3a" />
<TestLink id="28fe030c-d36e-13cf-475c-7813210bf886" name="AddAttributeRequestAgain" storage="..\bin\debug\dotnetopenauth.test.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, PublicKeyToken=b03f5f7f11d50a3a" />
<TestLink id="e7a41771-7dda-be44-0755-e06300f3cd92" name="IsSaneTest" storage="..\bin\debug\dotnetopenauth.test.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, PublicKeyToken=b03f5f7f11d50a3a" />
<TestLink id="2e23dc5a-93ea-11a5-d00d-02d294794e5f" name="AssociateDiffieHellmanOverHttps" storage="..\bin\debug\dotnetopenauth.test.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, PublicKeyToken=b03f5f7f11d50a3a" />
@@ -349,6 +349,7 @@
<TestLink id="313faac6-6357-5468-2d4d-4c9fba001678" name="TryParseNoThrow" storage="..\bin\debug\dotnetopenauth.test.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, PublicKeyToken=b03f5f7f11d50a3a" />
<TestLink id="7cbe4350-38d0-db7e-335c-93d9398fc95b" name="ExtensionOnlyFacadeLevel" storage="..\bin\debug\dotnetopenauth.test.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, PublicKeyToken=b03f5f7f11d50a3a" />
<TestLink id="2f5cfa57-bcb4-39af-e769-2d7c34e2598e" name="Ctor" storage="..\bin\debug\dotnetopenauth.test.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, PublicKeyToken=b03f5f7f11d50a3a" />
+ <TestLink id="ff78d828-b437-aaeb-e48a-85a5ad1fe396" name="Ctor" storage="..\bin\debug\dotnetopenauth.test.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, PublicKeyToken=b03f5f7f11d50a3a" />
<TestLink id="29e45877-ca7a-85de-5c39-6d43befe1a1e" name="DiscoveryRequireSslWithInsecureXrdsButSecureLinkTags" storage="..\bin\debug\dotnetopenauth.test.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, PublicKeyToken=b03f5f7f11d50a3a" />
<TestLink id="c351c660-d583-d869-0129-2e312665d815" name="CtorBlank" storage="..\bin\debug\dotnetopenauth.test.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, PublicKeyToken=b03f5f7f11d50a3a" />
<TestLink id="f063a3c6-5a36-2801-53d7-5142416199a9" name="ImplicitConversionFromStringTests" storage="..\bin\debug\dotnetopenauth.test.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, PublicKeyToken=b03f5f7f11d50a3a" />
@@ -405,7 +406,6 @@
<TestLink id="7cdabb8a-aefa-e90e-c32e-047404b64c2d" name="SerializeTest" storage="..\bin\debug\dotnetopenauth.test.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, PublicKeyToken=b03f5f7f11d50a3a" />
<TestLink id="f6979feb-7016-4e2b-14e2-e6c2c392419f" name="RemoveByKeyValuePair" storage="..\bin\debug\dotnetopenauth.test.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, PublicKeyToken=b03f5f7f11d50a3a" />
<TestLink id="58df167c-cf19-351c-cb09-5c52ae9f97be" name="DeserializeNull" storage="..\bin\debug\dotnetopenauth.test.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, PublicKeyToken=b03f5f7f11d50a3a" />
- <TestLink id="80719076-10fd-20a7-7ff3-a0aa2bc661cb" name="CtorNull" storage="..\bin\debug\dotnetopenauth.test.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, PublicKeyToken=b03f5f7f11d50a3a" />
<TestLink id="a778f331-f14e-9d6e-f942-a023423540f6" name="Ctor" storage="..\bin\debug\dotnetopenauth.test.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, PublicKeyToken=b03f5f7f11d50a3a" />
<TestLink id="a1ff4ada-fe5d-d2f3-b7fb-8e72db02b3c3" name="Full" storage="..\bin\debug\dotnetopenauth.test.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, PublicKeyToken=b03f5f7f11d50a3a" />
<TestLink id="be00d3ef-f24d-eb8a-d251-4d691736ee6f" name="AddAttributeRequestNull" storage="..\bin\debug\dotnetopenauth.test.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, PublicKeyToken=b03f5f7f11d50a3a" />
@@ -454,7 +454,7 @@
<TestLink id="62c6ee5b-ac29-461c-2373-bf620e948825" name="InvalidRealmNoScheme" storage="..\bin\debug\dotnetopenauth.test.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, PublicKeyToken=b03f5f7f11d50a3a" />
<TestLink id="115283b9-d95c-9a92-2197-96685ee8e96a" name="TwoExtensionsSameTypeUri" storage="..\bin\debug\dotnetopenauth.test.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, PublicKeyToken=b03f5f7f11d50a3a" />
<TestLink id="352d9fd6-cf38-4b72-478f-e3e17ace55f5" name="NoValueLoose" storage="..\bin\debug\dotnetopenauth.test.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, PublicKeyToken=b03f5f7f11d50a3a" />
- <TestLink id="3cd9447e-9ffd-f706-37bb-e7eb5828e430" name="InvalidRealmEmpty" storage="..\bin\debug\dotnetopenauth.test.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, PublicKeyToken=b03f5f7f11d50a3a" />
+ <TestLink id="80719076-10fd-20a7-7ff3-a0aa2bc661cb" name="CtorNull" storage="..\bin\debug\dotnetopenauth.test.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, PublicKeyToken=b03f5f7f11d50a3a" />
<TestLink id="b2b54c72-1d26-8c28-ebf5-7a5a4beeec43" name="VerifyNonZeroLengthOnNull" storage="..\bin\debug\dotnetopenauth.test.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, PublicKeyToken=b03f5f7f11d50a3a" />
<TestLink id="9684f7bf-cdda-a2c5-0822-29cb0add3835" name="ResponseNonceGetter" storage="..\bin\debug\dotnetopenauth.test.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, PublicKeyToken=b03f5f7f11d50a3a" />
<TestLink id="c4001e1c-75ad-236b-284f-318905d2bc3a" name="CreateRequestOnNonOpenID" storage="..\bin\debug\dotnetopenauth.test.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, PublicKeyToken=b03f5f7f11d50a3a" />
diff --git a/src/DotNetOpenAuth/DotNetOpenAuth.csproj b/src/DotNetOpenAuth/DotNetOpenAuth.csproj
index 3da8526..aba573d 100644
--- a/src/DotNetOpenAuth/DotNetOpenAuth.csproj
+++ b/src/DotNetOpenAuth/DotNetOpenAuth.csproj
@@ -25,7 +25,7 @@
<DocumentationFile>..\..\bin\Debug\DotNetOpenAuth.xml</DocumentationFile>
<RunCodeAnalysis>false</RunCodeAnalysis>
<CodeAnalysisRules>-Microsoft.Design#CA1054;-Microsoft.Design#CA1056;-Microsoft.Design#CA1055</CodeAnalysisRules>
- <CodeContractsEnableRuntimeChecking>False</CodeContractsEnableRuntimeChecking>
+ <CodeContractsEnableRuntimeChecking>True</CodeContractsEnableRuntimeChecking>
<CodeContractsCustomRewriterAssembly>
</CodeContractsCustomRewriterAssembly>
<CodeContractsCustomRewriterClass>
@@ -48,6 +48,8 @@
<CodeContractsShowSquigglies>True</CodeContractsShowSquigglies>
<CodeContractsArithmeticObligations>False</CodeContractsArithmeticObligations>
<CodeContractsRuntimeOnlyPublicSurface>False</CodeContractsRuntimeOnlyPublicSurface>
+ <CodeContractsRuntimeThrowOnFailure>False</CodeContractsRuntimeThrowOnFailure>
+ <CodeContractsRuntimeCallSiteRequires>False</CodeContractsRuntimeCallSiteRequires>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
@@ -60,7 +62,7 @@
<DocumentationFile>..\..\bin\Release\DotNetOpenAuth.xml</DocumentationFile>
<RunCodeAnalysis>true</RunCodeAnalysis>
<CodeAnalysisRules>-Microsoft.Design#CA1054;-Microsoft.Design#CA1056;-Microsoft.Design#CA1055</CodeAnalysisRules>
- <CodeContractsEnableRuntimeChecking>False</CodeContractsEnableRuntimeChecking>
+ <CodeContractsEnableRuntimeChecking>True</CodeContractsEnableRuntimeChecking>
<CodeContractsCustomRewriterAssembly>
</CodeContractsCustomRewriterAssembly>
<CodeContractsCustomRewriterClass>
@@ -81,16 +83,21 @@
<CodeContractsUseBaseLine>False</CodeContractsUseBaseLine>
<CodeContractsRunInBackground>True</CodeContractsRunInBackground>
<CodeContractsShowSquigglies>False</CodeContractsShowSquigglies>
+ <CodeContractsRuntimeOnlyPublicSurface>False</CodeContractsRuntimeOnlyPublicSurface>
+ <CodeContractsRuntimeThrowOnFailure>False</CodeContractsRuntimeThrowOnFailure>
+ <CodeContractsRuntimeCallSiteRequires>False</CodeContractsRuntimeCallSiteRequires>
+ <CodeContractsArithmeticObligations>False</CodeContractsArithmeticObligations>
</PropertyGroup>
- <PropertyGroup Condition=" '$(Sign)' == 'true' ">
+ <PropertyGroup>
<SignAssembly>true</SignAssembly>
- <AssemblyOriginatorKeyFile>..\official-build-key.pfx</AssemblyOriginatorKeyFile>
+ <DelaySign>true</DelaySign>
+ <AssemblyOriginatorKeyFile>..\official-build-key.pub</AssemblyOriginatorKeyFile>
<DefineConstants>$(DefineConstants);StrongNameSigned</DefineConstants>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'CodeAnalysis|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<OutputPath>..\..\bin\CodeAnalysis\</OutputPath>
- <DefineConstants>CONTRACTS_FULL;DEBUG;TRACE</DefineConstants>
+ <DefineConstants>$(DefineConstants);CONTRACTS_FULL;DEBUG;TRACE</DefineConstants>
<DocumentationFile>..\..\bin\CodeAnalysis\DotNetOpenAuth.xml</DocumentationFile>
<DebugType>full</DebugType>
<PlatformTarget>AnyCPU</PlatformTarget>
diff --git a/src/DotNetOpenAuth/OAuth/ChannelElements/ICombinedOpenIdProviderTokenManager.cs b/src/DotNetOpenAuth/OAuth/ChannelElements/ICombinedOpenIdProviderTokenManager.cs
index ff004cb..dd28e71 100644
--- a/src/DotNetOpenAuth/OAuth/ChannelElements/ICombinedOpenIdProviderTokenManager.cs
+++ b/src/DotNetOpenAuth/OAuth/ChannelElements/ICombinedOpenIdProviderTokenManager.cs
@@ -15,7 +15,7 @@ namespace DotNetOpenAuth.OAuth.ChannelElements {
/// This interface should be implemented by the same class that implements
/// <see cref="ITokenManager"/> in order to enable the OpenID+OAuth extension.
/// </remarks>
- public interface ICombinedOpenIdProviderTokenManager {
+ public interface ICombinedOpenIdProviderTokenManager : IOpenIdOAuthTokenManager, ITokenManager {
/// <summary>
/// Gets the OAuth consumer key for a given OpenID relying party realm.
/// </summary>
diff --git a/src/DotNetOpenAuth/OAuth/ChannelElements/PlaintextSigningBindingElement.cs b/src/DotNetOpenAuth/OAuth/ChannelElements/PlaintextSigningBindingElement.cs
index 9f99066..22e5f20 100644
--- a/src/DotNetOpenAuth/OAuth/ChannelElements/PlaintextSigningBindingElement.cs
+++ b/src/DotNetOpenAuth/OAuth/ChannelElements/PlaintextSigningBindingElement.cs
@@ -41,7 +41,12 @@ namespace DotNetOpenAuth.OAuth.ChannelElements {
/// <param name="message">The message that needs to be signed.</param>
/// <returns>True if this binding element can be used to sign the message. False otherwise.</returns>
protected override bool IsMessageApplicable(ITamperResistantOAuthMessage message) {
- return string.Equals(message.Recipient.Scheme, "https", StringComparison.OrdinalIgnoreCase);
+ if (string.Equals(message.Recipient.Scheme, "https", StringComparison.OrdinalIgnoreCase)) {
+ return true;
+ } else {
+ Logger.Bindings.DebugFormat("The {0} element will not sign this message because the URI scheme is not https.", this.GetType().Name);
+ return false;
+ }
}
/// <summary>
diff --git a/src/DotNetOpenAuth/OAuth/ServiceProvider.cs b/src/DotNetOpenAuth/OAuth/ServiceProvider.cs
index 242e0db..9c37815 100644
--- a/src/DotNetOpenAuth/OAuth/ServiceProvider.cs
+++ b/src/DotNetOpenAuth/OAuth/ServiceProvider.cs
@@ -236,11 +236,12 @@ namespace DotNetOpenAuth.OAuth {
/// <summary>
/// Gets the OAuth authorization request included with an OpenID authentication
- /// request.
+ /// request, if there is one.
/// </summary>
/// <param name="openIdRequest">The OpenID authentication request.</param>
/// <returns>
- /// The scope of access the relying party is requesting.
+ /// The scope of access the relying party is requesting, or null if no OAuth request
+ /// is present.
/// </returns>
/// <remarks>
/// <para>Call this method rather than simply extracting the OAuth extension
@@ -270,24 +271,43 @@ namespace DotNetOpenAuth.OAuth {
return authzRequest;
}
- /// <summary>
+ /// <summary>
/// Attaches the authorization response to an OpenID authentication response.
/// </summary>
/// <param name="openIdAuthenticationRequest">The OpenID authentication request.</param>
- /// <param name="consumerKey">The consumer key. May and should be <c>null</c> if and only if <paramref name="scope"/> is null.</param>
+ /// <param name="consumerKey">The consumer key. Must be <c>null</c> if and only if <paramref name="scope"/> is null.</param>
/// <param name="scope">The approved access scope. Use <c>null</c> to indicate no access was granted. The empty string will be interpreted as some default level of access is granted.</param>
[SuppressMessage("Microsoft.Design", "CA1011:ConsiderPassingBaseTypesAsParameters", Justification = "We want to take IAuthenticationRequest because that's the only supported use case.")]
- public void AttachAuthorizationResponse(IAuthenticationRequest openIdAuthenticationRequest, string consumerKey, string scope) {
+ [Obsolete("Call the overload that doesn't take a consumerKey instead.")]
+ public void AttachAuthorizationResponse(IHostProcessedRequest openIdAuthenticationRequest, string consumerKey, string scope) {
Contract.Requires(openIdAuthenticationRequest != null);
Contract.Requires((consumerKey == null) == (scope == null));
Contract.Requires(this.TokenManager is IOpenIdOAuthTokenManager);
ErrorUtilities.VerifyArgumentNotNull(openIdAuthenticationRequest, "openIdAuthenticationRequest");
- var openidTokenManager = this.TokenManager as IOpenIdOAuthTokenManager;
+ var openidTokenManager = this.TokenManager as ICombinedOpenIdProviderTokenManager;
ErrorUtilities.VerifyOperation(openidTokenManager != null, OAuthStrings.OpenIdOAuthExtensionRequiresSpecialTokenManagerInterface, typeof(IOpenIdOAuthTokenManager).FullName);
+ ErrorUtilities.VerifyArgument(consumerKey == null || consumerKey == openidTokenManager.GetConsumerKey(openIdAuthenticationRequest.Realm), "The consumer key and the realm did not match according to the token manager.");
+
+ this.AttachAuthorizationResponse(openIdAuthenticationRequest, scope);
+ }
+
+ /// <summary>
+ /// Attaches the authorization response to an OpenID authentication response.
+ /// </summary>
+ /// <param name="openIdAuthenticationRequest">The OpenID authentication request.</param>
+ /// <param name="scope">The approved access scope. Use <c>null</c> to indicate no access was granted. The empty string will be interpreted as some default level of access is granted.</param>
+ [SuppressMessage("Microsoft.Design", "CA1011:ConsiderPassingBaseTypesAsParameters", Justification = "We want to take IAuthenticationRequest because that's the only supported use case.")]
+ public void AttachAuthorizationResponse(IHostProcessedRequest openIdAuthenticationRequest, string scope) {
+ Contract.Requires(openIdAuthenticationRequest != null);
+ Contract.Requires(this.TokenManager is IOpenIdOAuthTokenManager);
+ ErrorUtilities.VerifyArgumentNotNull(openIdAuthenticationRequest, "openIdAuthenticationRequest");
+ var openidTokenManager = this.TokenManager as ICombinedOpenIdProviderTokenManager;
+ ErrorUtilities.VerifyOperation(openidTokenManager != null, OAuthStrings.OpenIdOAuthExtensionRequiresSpecialTokenManagerInterface, typeof(ICombinedOpenIdProviderTokenManager).FullName);
IOpenIdMessageExtension response;
if (scope != null) {
// Generate an authorized request token to return to the relying party.
+ string consumerKey = openidTokenManager.GetConsumerKey(openIdAuthenticationRequest.Realm);
var approvedResponse = new AuthorizationApprovedResponse {
RequestToken = this.TokenGenerator.GenerateRequestToken(consumerKey),
Scope = scope,
diff --git a/src/DotNetOpenAuth/OAuth/WebConsumer.cs b/src/DotNetOpenAuth/OAuth/WebConsumer.cs
index 56d3029..d86444d 100644
--- a/src/DotNetOpenAuth/OAuth/WebConsumer.cs
+++ b/src/DotNetOpenAuth/OAuth/WebConsumer.cs
@@ -120,7 +120,8 @@ namespace DotNetOpenAuth.OAuth {
}
// Prepare a message to exchange the request token for an access token.
- var requestAccess = new AuthorizedTokenRequest(this.ServiceProvider.AccessTokenEndpoint, this.ServiceProvider.Version) {
+ // We are careful to use a v1.0 message version so that the oauth_verifier is not required.
+ var requestAccess = new AuthorizedTokenRequest(this.ServiceProvider.AccessTokenEndpoint, Protocol.V10.Version) {
RequestToken = positiveAuthorization.RequestToken,
ConsumerKey = this.ConsumerKey,
};
diff --git a/src/DotNetOpenAuth/OpenId/RelyingParty/AuthenticationRequest.cs b/src/DotNetOpenAuth/OpenId/RelyingParty/AuthenticationRequest.cs
index 9912d0b..060ef21 100644
--- a/src/DotNetOpenAuth/OpenId/RelyingParty/AuthenticationRequest.cs
+++ b/src/DotNetOpenAuth/OpenId/RelyingParty/AuthenticationRequest.cs
@@ -345,11 +345,12 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
/// before calling this method.
/// </remarks>
private static IEnumerable<AuthenticationRequest> CreateInternal(Identifier userSuppliedIdentifier, OpenIdRelyingParty relyingParty, Realm realm, Uri returnToUrl, IEnumerable<ServiceEndpoint> serviceEndpoints, bool createNewAssociationsAsNeeded) {
- Contract.Requires(userSuppliedIdentifier != null);
- Contract.Requires(relyingParty != null);
- Contract.Requires(realm != null);
- Contract.Requires(serviceEndpoints != null);
- Contract.Ensures(Contract.Result<IEnumerable<AuthenticationRequest>>() != null);
+ // DO NOT USE CODE CONTRACTS IN THIS METHOD, since it uses yield return
+ ErrorUtilities.VerifyArgumentNotNull(userSuppliedIdentifier, "userSuppliedIdentifier");
+ ErrorUtilities.VerifyArgumentNotNull(relyingParty, "relyingParty");
+ ErrorUtilities.VerifyArgumentNotNull(realm, "realm");
+ ErrorUtilities.VerifyArgumentNotNull(serviceEndpoints, "serviceEndpoints");
+ ////Contract.Ensures(Contract.Result<IEnumerable<AuthenticationRequest>>() != null);
// If shared associations are required, then we had better have an association store.
ErrorUtilities.VerifyOperation(!relyingParty.SecuritySettings.RequireAssociation || relyingParty.AssociationManager.HasAssociationStore, OpenIdStrings.AssociationStoreRequired);
diff --git a/src/DotNetOpenAuth/OpenId/RelyingParty/OpenIdRelyingPartyControlBase.cs b/src/DotNetOpenAuth/OpenId/RelyingParty/OpenIdRelyingPartyControlBase.cs
index 8451dbd..c584580 100644
--- a/src/DotNetOpenAuth/OpenId/RelyingParty/OpenIdRelyingPartyControlBase.cs
+++ b/src/DotNetOpenAuth/OpenId/RelyingParty/OpenIdRelyingPartyControlBase.cs
@@ -73,6 +73,11 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
private const bool UsePersistentCookieDefault = false;
/// <summary>
+ /// Default value of <see cref="LoginMode"/>.
+ /// </summary>
+ private const LoginSiteNotification LoginModeDefault = LoginSiteNotification.FormsAuthentication;
+
+ /// <summary>
/// The default value for the <see cref="RealmUrl"/> property.
/// </summary>
private const string RealmUrlDefault = "~/";
@@ -102,6 +107,11 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
private const string UsePersistentCookieViewStateKey = "UsePersistentCookie";
/// <summary>
+ /// The viewstate key to use for the <see cref="LoginMode"/> property.
+ /// </summary>
+ private const string LoginModeViewStateKey = "LoginMode";
+
+ /// <summary>
/// The viewstate key to use for the <see cref="RealmUrl"/> property.
/// </summary>
private const string RealmUrlViewStateKey = "RealmUrl";
@@ -200,6 +210,25 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
#endregion
/// <summary>
+ /// Methods of indicating to the rest of the web site that the user has logged in.
+ /// </summary>
+ public enum LoginSiteNotification {
+ /// <summary>
+ /// The rest of the web site is unaware that the user just completed an OpenID login.
+ /// </summary>
+ None,
+
+ /// <summary>
+ /// After the <see cref="OpenIdRelyingPartyControlBase.LoggedIn"/> event is fired
+ /// the control automatically calls <see cref="System.Web.Security.FormsAuthentication.RedirectFromLoginPage(string, bool)"/>
+ /// with the <see cref="IAuthenticationResponse.ClaimedIdentifier"/> as the username
+ /// unless the <see cref="OpenIdRelyingPartyControlBase.LoggedIn"/> event handler sets
+ /// <see cref="OpenIdEventArgs.Cancel"/> property to true.
+ /// </summary>
+ FormsAuthentication,
+ }
+
+ /// <summary>
/// Gets or sets the <see cref="OpenIdRelyingParty"/> instance to use.
/// </summary>
/// <value>The default value is an <see cref="OpenIdRelyingParty"/> instance initialized according to the web.config file.</value>
@@ -312,6 +341,16 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
}
/// <summary>
+ /// Gets or sets the way a completed login is communicated to the rest of the web site.
+ /// </summary>
+ [Bindable(true), DefaultValue(LoginModeDefault), Category(BehaviorCategory)]
+ [Description("The way a completed login is communicated to the rest of the web site.")]
+ public LoginSiteNotification LoginMode {
+ get { return (LoginSiteNotification)(this.ViewState[LoginModeViewStateKey] ?? LoginModeDefault); }
+ set { this.ViewState[LoginModeViewStateKey] = value; }
+ }
+
+ /// <summary>
/// Gets or sets a value indicating when to use a popup window to complete the login experience.
/// </summary>
/// <value>The default value is <see cref="PopupBehavior.Never"/>.</value>
@@ -515,7 +554,14 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
}
if (!args.Cancel) {
- FormsAuthentication.RedirectFromLoginPage(response.ClaimedIdentifier, this.UsePersistentCookie);
+ switch (this.LoginMode) {
+ case LoginSiteNotification.FormsAuthentication:
+ FormsAuthentication.RedirectFromLoginPage(response.ClaimedIdentifier, this.UsePersistentCookie);
+ break;
+ case LoginSiteNotification.None:
+ default:
+ break;
+ }
}
}
diff --git a/src/DotNetOpenAuth/Util.cs b/src/DotNetOpenAuth/Util.cs
index 1a67966..aeeba88 100644
--- a/src/DotNetOpenAuth/Util.cs
+++ b/src/DotNetOpenAuth/Util.cs
@@ -11,6 +11,7 @@ namespace DotNetOpenAuth {
using System.Net;
using System.Reflection;
using System.Text;
+ using DotNetOpenAuth.Messaging;
/// <summary>
/// A grab-bag utility class.
@@ -74,7 +75,8 @@ namespace DotNetOpenAuth {
return new DelayedToString<IEnumerable<KeyValuePair<K, V>>>(
pairs,
p => {
- Contract.Requires(pairs != null);
+ ////Contract.Requires(pairs != null); // CC: anonymous method can't handle it
+ ErrorUtilities.VerifyArgumentNotNull(pairs, "pairs");
var dictionary = pairs as IDictionary<K, V>;
StringBuilder sb = new StringBuilder(dictionary != null ? dictionary.Count * 40 : 200);
foreach (var pair in pairs) {
@@ -102,13 +104,15 @@ namespace DotNetOpenAuth {
/// <param name="list">The list of elements.</param>
/// <param name="multiLineElements">if set to <c>true</c>, special formatting will be applied to the output to make it clear where one element ends and the next begins.</param>
/// <returns>An object whose ToString method will perform the actual work of generating the string.</returns>
+ [ContractVerification(false)]
internal static object ToStringDeferred<T>(this IEnumerable<T> list, bool multiLineElements) {
return new DelayedToString<IEnumerable<T>>(
list,
l => {
- Contract.Requires(l != null);
+ ////Contract.Requires(l != null); // CC: anonymous method can't handle it
+ ErrorUtilities.VerifyArgumentNotNull(l, "l");
string newLine = Environment.NewLine;
- Contract.Assume(newLine != null && newLine.Length > 0);
+ ////Contract.Assume(newLine != null && newLine.Length > 0); // CC: anonymous method can't handle it
StringBuilder sb = new StringBuilder();
if (multiLineElements) {
sb.AppendLine("[{");
diff --git a/src/official-build-key.pub b/src/official-build-key.pub
new file mode 100644
index 0000000..6e68f53
--- /dev/null
+++ b/src/official-build-key.pub
Binary files differ
diff --git a/src/version.txt b/src/version.txt
index e4604e3..15a2799 100644
--- a/src/version.txt
+++ b/src/version.txt
@@ -1 +1 @@
-3.2.1
+3.3.0
diff --git a/tools/DotNetOpenAuth.Common.Settings.targets b/tools/DotNetOpenAuth.Common.Settings.targets
index 3257583..951366e 100644
--- a/tools/DotNetOpenAuth.Common.Settings.targets
+++ b/tools/DotNetOpenAuth.Common.Settings.targets
@@ -1,11 +1,24 @@
-<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" InitialTargets="InitializeProps">
<PropertyGroup>
<ProductName>DotNetOpenAuth</ProductName>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<ProjectRoot Condition="'$(ProjectRoot)' == ''">$(MSBuildProjectDirectory)</ProjectRoot>
- <OutputPath>$(ProjectRoot)\bin\$(Configuration)</OutputPath>
- <DocOutputPath>$(ProjectRoot)\doc</DocOutputPath>
- <IntermediatePath>$(ProjectRoot)\obj\$(Configuration)</IntermediatePath>
- <ToolsDir>$(ProjectRoot)\tools</ToolsDir>
+ <DropsRoot>$(ProjectRoot)\drops\$(Configuration)\</DropsRoot>
+ <OutputPath>$(ProjectRoot)\bin\$(Configuration)\</OutputPath>
+ <DocOutputPath>$(ProjectRoot)\doc\</DocOutputPath>
+ <IntermediatePath>$(ProjectRoot)\obj\$(Configuration)\</IntermediatePath>
+ <ToolsDir>$(ProjectRoot)\tools\</ToolsDir>
+ <PublicKeyFile>$(ProjectRoot)\src\official-build-key.pub</PublicKeyFile>
+ <KeyPairContainer>DotNetOpenAuth</KeyPairContainer>
+ <PublicKeyToken>2780CCD10D57B246</PublicKeyToken>
</PropertyGroup>
-</Project> \ No newline at end of file
+
+ <Import Project="$(ProjectRoot)\lib\DotNetOpenAuth.BuildTasks.targets" />
+
+ <Target Name="InitializeProps">
+ <CheckAdminRights>
+ <Output TaskParameter="IsElevated" PropertyName="IsElevated" />
+ </CheckAdminRights>
+ <Message Importance="High" Text="IsElevated = $(IsElevated)" />
+ </Target>
+</Project>
diff --git a/tools/DotNetOpenAuth.Versioning.targets b/tools/DotNetOpenAuth.Versioning.targets
index f4b12b0..65d212c 100644
--- a/tools/DotNetOpenAuth.Versioning.targets
+++ b/tools/DotNetOpenAuth.Versioning.targets
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="3.5">
- <!-- Import this .targets file to automaticaly generate AssemblyVersion
+ <!-- Import this .targets file to automatically generate AssemblyVersion
attribute according to DotNetOpenAuth convention. -->
<PropertyGroup>
<ProjectRoot Condition="'$(ProjectRoot)' == ''">$(MSBuildProjectDirectory)\..\..</ProjectRoot>