summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndrew Arnott <andrewarnott@gmail.com>2010-12-23 13:05:36 -0800
committerAndrew Arnott <andrewarnott@gmail.com>2010-12-23 13:05:36 -0800
commitd79f0d578c9c80c7528bf5c57eb883b1ff550e2d (patch)
treece8888fba22103188b369e36e1f558fde58300ca
parent7e959b5c555e81c875b43cdf0d82c13437c437f3 (diff)
parent1b87e9b8d74afe71b70d842ee435523e7f1aad46 (diff)
downloadDotNetOpenAuth-d79f0d578c9c80c7528bf5c57eb883b1ff550e2d.zip
DotNetOpenAuth-d79f0d578c9c80c7528bf5c57eb883b1ff550e2d.tar.gz
DotNetOpenAuth-d79f0d578c9c80c7528bf5c57eb883b1ff550e2d.tar.bz2
Merge branch 'v3.4'
-rw-r--r--.gitignore1
-rw-r--r--EnlistmentInfo.props2
-rw-r--r--build.proj13
-rw-r--r--doc/doc.proj26
-rw-r--r--lib/DotNetOpenAuth.BuildTasks.dllbin101376 -> 104960 bytes
-rw-r--r--lib/DotNetOpenAuth.BuildTasks.pdbbin245248 -> 257536 bytes
-rw-r--r--lib/DotNetOpenAuth.BuildTasks.targets2
-rw-r--r--nuget/DotNetOpenAuth.nuspec20
-rw-r--r--nuget/content/web.config.transform63
-rw-r--r--nuget/nuget.proj65
-rw-r--r--samples/OAuthServiceProvider/Code/DatabaseTokenManager.cs6
-rw-r--r--samples/OAuthServiceProvider/Code/OAuthToken.cs29
-rw-r--r--samples/OpenIdProviderMvc/Controllers/OpenIdController.cs192
-rw-r--r--samples/OpenIdProviderMvc/OpenIdProviderMvc.csproj1
-rw-r--r--samples/OpenIdProviderMvc/Views/OpenId/AskUser.aspx38
-rw-r--r--samples/OpenIdProviderMvc/Web.config1
-rw-r--r--samples/OpenIdProviderWebForms/Code/InMemoryTokenManager.cs2
-rw-r--r--samples/OpenIdProviderWebForms/Provider.ashx.cs3
-rw-r--r--samples/OpenIdRelyingPartyClassicAsp/default.asp8
-rw-r--r--samples/OpenIdRelyingPartyClassicAsp/login.asp13
-rw-r--r--samples/OpenIdRelyingPartyWebForms/NoIdentityOpenId.aspx18
-rw-r--r--samples/OpenIdRelyingPartyWebForms/NoIdentityOpenId.aspx.cs2
-rw-r--r--samples/OpenIdRelyingPartyWebForms/NoIdentityOpenId.aspx.designer.cs12
-rw-r--r--samples/Samples.proj50
-rw-r--r--samples/tools.proj27
-rw-r--r--src/DotNetOpenAuth.BuildTasks/AddFilesTo7Zip.cs105
-rw-r--r--src/DotNetOpenAuth.BuildTasks/ChangeProjectReferenceToAssemblyReference.cs2
-rw-r--r--src/DotNetOpenAuth.BuildTasks/DotNetOpenAuth.BuildTasks.csproj13
-rw-r--r--src/DotNetOpenAuth.BuildTasks/DotNetOpenAuth.BuildTasks.sln17
-rw-r--r--src/DotNetOpenAuth.BuildTasks/NuGetPack.cs108
-rw-r--r--src/DotNetOpenAuth.BuildTasks/ReSignDelaySignedAssemblies.cs2
-rw-r--r--src/DotNetOpenAuth.BuildTasks/TaskStrings.Designer.cs4
-rw-r--r--src/DotNetOpenAuth.Test/DotNetOpenAuth.Test.csproj1
-rw-r--r--src/DotNetOpenAuth.Test/Messaging/ChannelTests.cs2
-rw-r--r--src/DotNetOpenAuth.Test/Messaging/MessagingUtilitiesTests.cs2
-rw-r--r--src/DotNetOpenAuth.Test/OAuth/ChannelElements/OAuthChannelTests.cs2
-rw-r--r--src/DotNetOpenAuth.Test/OpenId/Extensions/SimpleRegistration/ClaimsResponseTests.cs12
-rw-r--r--src/DotNetOpenAuth.Test/OpenId/RelyingParty/PositiveAuthenticationResponseSnapshotTests.cs6
-rw-r--r--src/DotNetOpenAuth/Configuration/DotNetOpenAuth.xsd19
-rw-r--r--src/DotNetOpenAuth/Configuration/DotNetOpenAuthSection.cs14
-rw-r--r--src/DotNetOpenAuth/DotNetOpenAuth.csproj1
-rw-r--r--src/DotNetOpenAuth/IEmbeddedResourceRetrieval.cs22
-rw-r--r--src/DotNetOpenAuth/Messaging/Channel.cs27
-rw-r--r--src/DotNetOpenAuth/Messaging/MessagingStrings.Designer.cs9
-rw-r--r--src/DotNetOpenAuth/Messaging/MessagingStrings.resx3
-rw-r--r--src/DotNetOpenAuth/Messaging/MessagingUtilities.cs6
-rw-r--r--src/DotNetOpenAuth/Mvc/OpenIdHelper.cs79
-rw-r--r--src/DotNetOpenAuth/OpenId/Extensions/SimpleRegistration/ClaimsRequest.cs10
-rw-r--r--src/DotNetOpenAuth/OpenId/Extensions/SimpleRegistration/ClaimsResponse.cs4
-rw-r--r--src/DotNetOpenAuth/OpenId/Extensions/SimpleRegistration/Constants.cs8
-rw-r--r--src/DotNetOpenAuth/OpenId/Interop/AuthenticationResponseShim.cs7
-rw-r--r--src/DotNetOpenAuth/Reporting.cs9
-rw-r--r--src/DotNetOpenAuth/Strings.Designer.cs11
-rw-r--r--src/DotNetOpenAuth/Strings.resx5
-rw-r--r--src/DotNetOpenAuth/Util.cs35
-rw-r--r--src/DotNetOpenAuth/Yadis/Yadis.cs19
-rw-r--r--tools/7-Zip.x86/7-zip.chmbin0 -> 91020 bytes
-rw-r--r--tools/7-Zip.x86/7za.exebin0 -> 587776 bytes
-rw-r--r--tools/7-Zip.x86/license.txt29
-rw-r--r--tools/7-Zip.x86/readme.txt41
-rw-r--r--tools/DotNetOpenAuth.props3
-rw-r--r--tools/NuGet/NuGet.exebin0 -> 267264 bytes
-rw-r--r--tools/drop.proj9
63 files changed, 1052 insertions, 188 deletions
diff --git a/.gitignore b/.gitignore
index 11bd284..f0ec04d 100644
--- a/.gitignore
+++ b/.gitignore
@@ -10,6 +10,7 @@ StyleCop.Cache
*~
PrecompiledWeb
*.suo
+*.log
*.cache
*.user
*.tmp
diff --git a/EnlistmentInfo.props b/EnlistmentInfo.props
index 69cacb4..0c5d62d 100644
--- a/EnlistmentInfo.props
+++ b/EnlistmentInfo.props
@@ -5,6 +5,6 @@
<StyleCopTreatErrorsAsWarnings Condition=" '$(StyleCopTreatErrorsAsWarnings)' == '' and '$(Configuration)' == 'Release' ">false</StyleCopTreatErrorsAsWarnings>
<StyleCopTreatErrorsAsWarnings Condition=" '$(StyleCopTreatErrorsAsWarnings)' == '' ">true</StyleCopTreatErrorsAsWarnings>
- <ProjectRoot>$(MSBuildThisFileDirectory)\</ProjectRoot>
+ <ProjectRoot>$(MSBuildThisFileDirectory)</ProjectRoot>
</PropertyGroup>
</Project> \ No newline at end of file
diff --git a/build.proj b/build.proj
index 09eb966..9079c70 100644
--- a/build.proj
+++ b/build.proj
@@ -4,14 +4,17 @@
<Import Project="$(ProjectRoot)tools\Translation.targets"/>
<ItemGroup>
- <ProjectsInDrop Include="
+ <NightlyProjects Include="
samples\tools.proj;
tools\drop.proj;
+ nuget\nuget.proj;
" />
- <ProjectsToPublish Include="
+ <NightlyProjects Include="
samples\samples.proj;
doc\doc.proj;
- " />
+ ">
+ <Targets>DeployableArchive</Targets>
+ </NightlyProjects>
<ProjectsToClean Include="
$(SolutionPath);
@@ -61,11 +64,11 @@
</Target>
<Target Name="Nightly">
- <MSBuild Projects="@(ProjectsInDrop)" Targets="%(ProjectsInDrop.Targets)" BuildInParallel="$(BuildInParallel)" />
+ <MSBuild Projects="@(NightlyProjects)" Targets="%(NightlyProjects.Targets)" BuildInParallel="$(BuildInParallel)" />
</Target>
<Target Name="Publish">
- <MSBuild Projects="@(ProjectsToPublish)" Targets="Publish" BuildInParallel="$(BuildInParallel)" />
+ <MSBuild Projects="@(ProjectsToPublish)" Targets="%(ProjectsToPublish.Targets)" BuildInParallel="$(BuildInParallel)" />
</Target>
<Import Project="$(ProjectRoot)tools\DotNetOpenAuth.automated.targets"/>
diff --git a/doc/doc.proj b/doc/doc.proj
index e75565c..55b2cb8 100644
--- a/doc/doc.proj
+++ b/doc/doc.proj
@@ -22,26 +22,30 @@
</PropertyGroup>
</Target>
- <Target Name="PrepareForPublish" DependsOnTargets="Prepare;BuildProduct;Html">
+ <Target Name="PrepareForPublish" DependsOnTargets="BuildProduct;Html">
+ <PropertyGroup>
+ <DocZip>$(DropDirectoryNoSlash)-htmldoc$(ZipFormat)</DocZip>
+ </PropertyGroup>
+
<ItemGroup>
<DocSources Include="$(ProjectRoot)doc\api\**\*" />
- <DocTargets Include="@(DocSources->'$(DocWebRoot)\$(BranchName)\%(RecursiveDir)%(Filename)%(Extension)')" />
</ItemGroup>
</Target>
- <Target Name="Publish"
+ <Target Name="DeployableArchive"
DependsOnTargets="PrepareForPublish"
Inputs="@(DocSources)"
- Outputs="@(DocTargets)">
- <RemoveDir Directories="$(DocWebRoot)\$(BranchName)" />
- <MakeDir Directories="$(DocWebRoot)\$(BranchName)" />
- <Copy SourceFiles="@(DocSources)" DestinationFiles="@(DocTargets)" SkipUnchangedFiles="true" />
+ Outputs="$(DocZip)">
+ <Delete Files="$(DocZip)" />
+ <AddFilesTo7Zip
+ Files="@(DocSources)"
+ ZipFileName="$(DocZip)"
+ WorkingDirectory="$(ProjectRoot)doc\api\"
+ ToolPath="$(Zip7ToolPath)" />
</Target>
- <Target Name="Unpublish"
- DependsOnTargets="DeleteSiteOnIis"
- Condition=" '$(DocWebRoot)' != '' ">
- </Target>
+ <Target Name="Publish"
+ DependsOnTargets="DeployableArchive" />
<Target Name="CreateSiteOnIis" DependsOnTargets="Prepare">
<Error Text="The PublishDocsWebSiteName property must be set." Condition=" '$(PublishDocsWebSiteName)' == '' "/>
diff --git a/lib/DotNetOpenAuth.BuildTasks.dll b/lib/DotNetOpenAuth.BuildTasks.dll
index 27631d5..bb667f9 100644
--- a/lib/DotNetOpenAuth.BuildTasks.dll
+++ b/lib/DotNetOpenAuth.BuildTasks.dll
Binary files differ
diff --git a/lib/DotNetOpenAuth.BuildTasks.pdb b/lib/DotNetOpenAuth.BuildTasks.pdb
index b01adda..bcb8d51 100644
--- a/lib/DotNetOpenAuth.BuildTasks.pdb
+++ b/lib/DotNetOpenAuth.BuildTasks.pdb
Binary files differ
diff --git a/lib/DotNetOpenAuth.BuildTasks.targets b/lib/DotNetOpenAuth.BuildTasks.targets
index e57ec97..27ca0ed 100644
--- a/lib/DotNetOpenAuth.BuildTasks.targets
+++ b/lib/DotNetOpenAuth.BuildTasks.targets
@@ -28,4 +28,6 @@
<UsingTask AssemblyFile="DotNetOpenAuth.BuildTasks.dll" TaskName="DowngradeProjects" />
<UsingTask AssemblyFile="DotNetOpenAuth.BuildTasks.dll" TaskName="HardLinkCopy" />
<UsingTask AssemblyFile="DotNetOpenAuth.BuildTasks.dll" TaskName="PrepareOhlohRelease" />
+ <UsingTask AssemblyFile="DotNetOpenAuth.BuildTasks.dll" TaskName="AddFilesTo7Zip" />
+ <UsingTask AssemblyFile="DotNetOpenAuth.BuildTasks.dll" TaskName="NuGetPack" />
</Project>
diff --git a/nuget/DotNetOpenAuth.nuspec b/nuget/DotNetOpenAuth.nuspec
new file mode 100644
index 0000000..05fc5f1
--- /dev/null
+++ b/nuget/DotNetOpenAuth.nuspec
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<package>
+ <metadata>
+ <id>DotNetOpenAuth</id>
+ <version>$version$</version>
+ <authors>Andrew Arnott</authors>
+ <owners>Andrew Arnott</owners>
+ <projectUrl>http://www.dotnetopenauth.net/</projectUrl>
+ <iconUrl>https://github.com/AArnott/dotnetopenid/raw/v3.4/doc/logo/dnoa-logo_32x32.png</iconUrl>
+ <licenseUrl>http://www.opensource.org/licenses/ms-pl.html</licenseUrl>
+ <requireLicenseAcceptance>false</requireLicenseAcceptance>
+ <summary>OpenID, OAuth, &amp; InfoCard library for web sites/services and apps.</summary>
+ <description>A C# library that adds OpenID 2.0 Provider and Relying Party, OAuth Consumer and Service Provider, and InfoCard Selector support to your web site both programmatically and through convenient drop-in ASP.NET controls.</description>
+ <language>en-US</language>
+ <dependencies>
+ <!-- optional -->
+ <!--<dependency id="log4net" version="1.2.10" />-->
+ </dependencies>
+ </metadata>
+</package> \ No newline at end of file
diff --git a/nuget/content/web.config.transform b/nuget/content/web.config.transform
new file mode 100644
index 0000000..07e22d9
--- /dev/null
+++ b/nuget/content/web.config.transform
@@ -0,0 +1,63 @@
+<configuration>
+ <configSections>
+ <section name="uri" type="System.Configuration.UriSection, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
+ <section name="dotNetOpenAuth" type="DotNetOpenAuth.Configuration.DotNetOpenAuthSection" requirePermission="false" allowLocation="true"/>
+ </configSections>
+
+ <uri>
+ <!-- The uri section is necessary to turn on .NET 3.5 support for IDN (international domain names),
+ which is necessary for OpenID urls with unicode characters in the domain/host name.
+ It is also required to put the Uri class into RFC 3986 escaping mode, which OpenID and OAuth require. -->
+ <idn enabled="All"/>
+ <iriParsing enabled="true"/>
+ </uri>
+
+ <system.net>
+ <defaultProxy enabled="true" />
+ <settings>
+ <!-- This setting causes .NET to check certificate revocation lists (CRL)
+ before trusting HTTPS certificates. But this setting tends to not
+ be allowed in shared hosting environments. -->
+ <!--<servicePointManager checkCertificateRevocationList="true"/>-->
+ </settings>
+ </system.net>
+
+ <runtime>
+ <!-- This prevents the Windows Event Log from frequently logging that HMAC1 is being used (when the other party needs it). -->
+ <legacyHMACWarning enabled="0" />
+
+ <!-- When targeting ASP.NET MVC 2, this assemblyBinding makes MVC 1 references relink
+ to MVC 2 so libraries such as DotNetOpenAuth that compile against MVC 1 will work with it. -->
+ <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
+ <dependentAssembly>
+ <assemblyIdentity name="System.Web.Mvc" publicKeyToken="31bf3856ad364e35" />
+ <bindingRedirect oldVersion="1.0.0.0" newVersion="2.0.0.0" />
+ </dependentAssembly>
+ </assemblyBinding>
+ </runtime>
+
+ <dotNetOpenAuth>
+ <!-- This is an optional configuration section where aspects of dotnetopenauth can be customized. -->
+ <!-- For a complete set of configuration options see http://www.dotnetopenauth.net/developers/code-snippets/configuration-options/ -->
+ <openid>
+ <relyingParty>
+ <security requireSsl="false" />
+ <behaviors>
+ <!-- The following OPTIONAL behavior allows RPs to use SREG only, but be compatible
+ with OPs that use Attribute Exchange (in various formats). -->
+ <add type="DotNetOpenAuth.OpenId.Behaviors.AXFetchAsSregTransform, DotNetOpenAuth" />
+ </behaviors>
+ </relyingParty>
+ </openid>
+ <messaging>
+ <untrustedWebRequest>
+ <whitelistHosts>
+ <!-- Uncomment to enable communication with localhost (should generally not activate in production!) -->
+ <!--<add name="localhost" />-->
+ </whitelistHosts>
+ </untrustedWebRequest>
+ </messaging>
+ <!-- Allow DotNetOpenAuth to publish usage statistics to library authors to improve the library. -->
+ <reporting enabled="true" />
+ </dotNetOpenAuth>
+</configuration> \ No newline at end of file
diff --git a/nuget/nuget.proj b/nuget/nuget.proj
new file mode 100644
index 0000000..f8b8e93
--- /dev/null
+++ b/nuget/nuget.proj
@@ -0,0 +1,65 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildProjectDirectory), EnlistmentInfo.props))\EnlistmentInfo.props" Condition=" '$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildProjectDirectory), EnlistmentInfo.props))' != '' " />
+ <Import Project="$(MSBuildProjectDirectory)\..\tools\DotNetOpenAuth.automated.props"/>
+
+ <Target Name="Layout" DependsOnTargets="BuildUnifiedProduct;ReSignDelaySignedAssemblies">
+ <PropertyGroup>
+ <NuGetLayoutPath>$(DropsRoot)NuGet\$(BuildVersion)\</NuGetLayoutPath>
+ </PropertyGroup>
+
+ <MSBuild Projects="$(ProjectRoot)src\DotNetOpenAuth\DotNetOpenAuth.csproj" Targets="DocumentationProjectOutputGroup" BuildInParallel="$(BuildInParallel)">
+ <Output TaskParameter="TargetOutputs" ItemName="NuGetSource"/>
+ </MSBuild>
+
+ <!-- IMPORTANT: These must appear as separate ItemGroups or else batching screws it up. -->
+ <ItemGroup>
+ <NuGetSource Include="%(ResignedAssembliesOutputs.Identity)" Condition=" '%(FileName)%(Extension)' == 'DotNetOpenAuth.dll' "/>
+ <NuGetSource>
+ <TargetPath>$(NuGetLayoutPath)lib\%(FileName)%(Extension)</TargetPath>
+ </NuGetSource>
+ </ItemGroup>
+ <ItemGroup>
+ <NuGetContentSource Include="$(ProjectRoot)NuGet\content\**"/>
+ </ItemGroup>
+ <ItemGroup>
+ <NuGetSource Include="@(NuGetContentSource)">
+ <TargetPath>$(NuGetLayoutPath)content\%(RecursiveDir)%(FileName)%(Extension)</TargetPath>
+ </NuGetSource>
+
+ <NuSpecSource Include="DotNetOpenAuth.nuspec">
+ <LayoutPath>$(NuGetLayoutPath)</LayoutPath>
+ <BeforeTokens>$version$</BeforeTokens>
+ <AfterTokens>$(BuildVersion)</AfterTokens>
+ </NuSpecSource>
+
+ <NuSpecTarget Include="@(NuSpecSource->'$(NuGetLayoutPath)%(FileName)%(Extension)')" />
+ </ItemGroup>
+ <ItemGroup>
+ <NuGetContentsTarget Include="%(NuGetSource.TargetPath)" />
+ </ItemGroup>
+
+ <CopyWithTokenSubstitution
+ SourceFiles="@(NuSpecSource)"
+ DestinationFiles="@(NuSpecTarget)"
+ />
+
+ <Copy
+ SourceFiles="@(NuGetSource)"
+ DestinationFiles="@(NuGetContentsTarget)"
+ SkipUnchangedFiles="true" />
+
+ <Purge Directories="$(NuGetLayoutPath)" IntendedFiles="@(NuGetContentsTarget);@(NuSpecTarget)" />
+ </Target>
+
+ <Target Name="Build" DependsOnTargets="Layout">
+ <NuGetPack
+ NuSpec="%(NuSpecTarget.Identity)"
+ BaseDirectory="%(NuSpecTarget.LayoutPath)"
+ OutputPackageDirectory="$(DropsRoot)"
+ ToolPath="$(NuGetToolPath)" />
+ </Target>
+
+ <Import Project="$(ProjectRoot)tools\DotNetOpenAuth.automated.targets"/>
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildProjectDirectory), EnlistmentInfo.targets))\EnlistmentInfo.targets" Condition=" '$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildProjectDirectory), EnlistmentInfo.targets))' != '' " />
+</Project> \ No newline at end of file
diff --git a/samples/OAuthServiceProvider/Code/DatabaseTokenManager.cs b/samples/OAuthServiceProvider/Code/DatabaseTokenManager.cs
index 721e124..ff586dc 100644
--- a/samples/OAuthServiceProvider/Code/DatabaseTokenManager.cs
+++ b/samples/OAuthServiceProvider/Code/DatabaseTokenManager.cs
@@ -42,7 +42,11 @@ namespace OAuthServiceProvider.Code {
}
public void UpdateToken(IServiceProviderRequestToken token) {
- // Nothing to do here, since we're using Linq To SQL.
+ // Nothing to do here, since we're using Linq To SQL, and
+ // We call LinqToSql's SubmitChanges method via our Global.Application_EndRequest method.
+ // This is a good pattern because we only save changes if the request didn't end up somehow failing.
+ // But if you DO want to save changes at this point, you could do it like so:
+ ////Global.DataContext.SubmitChanges();
}
#endregion
diff --git a/samples/OAuthServiceProvider/Code/OAuthToken.cs b/samples/OAuthServiceProvider/Code/OAuthToken.cs
index 182a3e3..9099237 100644
--- a/samples/OAuthServiceProvider/Code/OAuthToken.cs
+++ b/samples/OAuthServiceProvider/Code/OAuthToken.cs
@@ -62,5 +62,34 @@ namespace OAuthServiceProvider.Code {
}
#endregion
+
+ /// <summary>
+ /// Called by LinqToSql when the <see cref="IssueDate"/> property is about to change.
+ /// </summary>
+ /// <param name="value">The value.</param>
+ partial void OnIssueDateChanging(DateTime value) {
+ if (value.Kind == DateTimeKind.Unspecified) {
+ throw new ArgumentException("The DateTime.Kind cannot be Unspecified to ensure accurate timestamp checks.");
+ }
+ }
+
+ /// <summary>
+ /// Called by LinqToSql when <see cref="IssueDate"/> has changed.
+ /// </summary>
+ partial void OnIssueDateChanged() {
+ if (this.IssueDate.Kind == DateTimeKind.Local) {
+ this._IssueDate = this.IssueDate.ToUniversalTime();
+ }
+ }
+
+ /// <summary>
+ /// Called by LinqToSql when a token instance is deserialized.
+ /// </summary>
+ partial void OnLoaded() {
+ if (this.IssueDate.Kind == DateTimeKind.Unspecified) {
+ // this detail gets lost in db storage, but must be reaffirmed so that expiratoin checks succeed.
+ this._IssueDate = DateTime.SpecifyKind(this.IssueDate, DateTimeKind.Utc);
+ }
+ }
}
} \ No newline at end of file
diff --git a/samples/OpenIdProviderMvc/Controllers/OpenIdController.cs b/samples/OpenIdProviderMvc/Controllers/OpenIdController.cs
index bd0fdbf..5445875 100644
--- a/samples/OpenIdProviderMvc/Controllers/OpenIdController.cs
+++ b/samples/OpenIdProviderMvc/Controllers/OpenIdController.cs
@@ -9,63 +9,193 @@ namespace OpenIdProviderMvc.Controllers {
using DotNetOpenAuth.OpenId;
using DotNetOpenAuth.OpenId.Behaviors;
using DotNetOpenAuth.OpenId.Extensions.ProviderAuthenticationPolicy;
+ using DotNetOpenAuth.OpenId.Extensions.SimpleRegistration;
using DotNetOpenAuth.OpenId.Provider;
using OpenIdProviderMvc.Code;
public class OpenIdController : Controller {
internal static OpenIdProvider OpenIdProvider = new OpenIdProvider();
- internal static IAuthenticationRequest PendingAuthenticationRequest {
- get { return ProviderEndpoint.PendingAuthenticationRequest; }
- set { ProviderEndpoint.PendingAuthenticationRequest = value; }
- }
-
[ValidateInput(false)]
public ActionResult Provider() {
IRequest request = OpenIdProvider.GetRequest();
if (request != null) {
- var authRequest = request as IAuthenticationRequest;
- if (authRequest != null) {
- PendingAuthenticationRequest = authRequest;
- if (authRequest.IsReturnUrlDiscoverable(OpenIdProvider) == RelyingPartyDiscoveryResult.Success &&
- User.Identity.IsAuthenticated &&
- (authRequest.IsDirectedIdentity || this.UserControlsIdentifier(authRequest))) {
- return this.SendAssertion();
- } else {
- return RedirectToAction("LogOn", "Account", new { returnUrl = Url.Action("SendAssertion") });
- }
- }
-
+ // Some requests are automatically handled by DotNetOpenAuth. If this is one, go ahead and let it go.
if (request.IsResponseReady) {
return OpenIdProvider.PrepareResponse(request).AsActionResult();
- } else {
- return RedirectToAction("LogOn", "Account");
}
+
+ // This is apparently one that the host (the web site itself) has to respond to.
+ ProviderEndpoint.PendingRequest = (IHostProcessedRequest)request;
+
+ // Try responding immediately if possible.
+ ActionResult response;
+ if (this.AutoRespondIfPossible(out response)) {
+ return response;
+ }
+
+ // We can't respond immediately with a positive result. But if we still have to respond immediately...
+ if (ProviderEndpoint.PendingRequest.Immediate) {
+ // We can't stop to prompt the user -- we must just return a negative response.
+ return this.SendAssertion();
+ }
+
+ return this.RedirectToAction("AskUser");
} else {
- return View();
+ // No OpenID request was recognized. This may be a user that stumbled on the OP Endpoint.
+ return this.View();
}
}
+ /// <summary>
+ /// Displays a confirmation page.
+ /// </summary>
+ /// <returns>The response for the user agent.</returns>
[Authorize]
+ public ActionResult AskUser() {
+ if (ProviderEndpoint.PendingRequest == null) {
+ // Oops... precious little we can confirm without a pending OpenID request.
+ return this.RedirectToAction("Index", "Home");
+ }
+
+ // The user MAY have just logged in. Try again to respond automatically to the RP if appropriate.
+ ActionResult response;
+ if (this.AutoRespondIfPossible(out response)) {
+ return response;
+ }
+
+ this.ViewData["Realm"] = ProviderEndpoint.PendingRequest.Realm;
+
+ return this.View();
+ }
+
+ [HttpPost, Authorize, ValidateAntiForgeryToken]
+ public ActionResult AskUserResponse(bool confirmed) {
+ if (ProviderEndpoint.PendingAnonymousRequest != null) {
+ ProviderEndpoint.PendingAnonymousRequest.IsApproved = confirmed;
+ } else if (ProviderEndpoint.PendingAuthenticationRequest != null) {
+ ProviderEndpoint.PendingAuthenticationRequest.IsAuthenticated = confirmed;
+ } else {
+ throw new InvalidOperationException("There's no pending authentication request!");
+ }
+
+ return this.SendAssertion();
+ }
+
+ /// <summary>
+ /// Sends a positive or a negative assertion, based on how the pending request is currently marked.
+ /// </summary>
+ /// <returns>An MVC redirect result.</returns>
public ActionResult SendAssertion() {
- IAuthenticationRequest authReq = PendingAuthenticationRequest;
- PendingAuthenticationRequest = null; // clear session static so we don't do this again
- if (authReq == null) {
+ var pendingRequest = ProviderEndpoint.PendingRequest;
+ var authReq = pendingRequest as IAuthenticationRequest;
+ var anonReq = pendingRequest as IAnonymousRequest;
+ ProviderEndpoint.PendingRequest = null; // clear session static so we don't do this again
+ if (pendingRequest == null) {
throw new InvalidOperationException("There's no pending authentication request!");
}
- if (authReq.IsDirectedIdentity) {
- authReq.LocalIdentifier = Models.User.GetClaimedIdentifierForUser(User.Identity.Name);
+ // Set safe defaults if somehow the user ended up (perhaps through XSRF) here before electing to send data to the RP.
+ if (anonReq != null && !anonReq.IsApproved.HasValue) {
+ anonReq.IsApproved = false;
}
- if (!authReq.IsDelegatedIdentifier) {
- authReq.ClaimedIdentifier = authReq.LocalIdentifier;
+
+ if (authReq != null && !authReq.IsAuthenticated.HasValue) {
+ authReq.IsAuthenticated = false;
}
- // Respond to AX/sreg extension requests.
- //// Real web sites would have code here
+ if (authReq != null && authReq.IsAuthenticated.Value) {
+ if (authReq.IsDirectedIdentity) {
+ authReq.LocalIdentifier = Models.User.GetClaimedIdentifierForUser(User.Identity.Name);
+ }
+
+ if (!authReq.IsDelegatedIdentifier) {
+ authReq.ClaimedIdentifier = authReq.LocalIdentifier;
+ }
+ }
+
+ // Respond to AX/sreg extension requests only on a positive result.
+ if ((authReq != null && authReq.IsAuthenticated.Value) ||
+ (anonReq != null && anonReq.IsApproved.Value)) {
+ // Look for a Simple Registration request. When the AXFetchAsSregTransform behavior is turned on
+ // in the web.config file as it is in this sample, AX requests will come in as SReg requests.
+ var claimsRequest = pendingRequest.GetExtension<ClaimsRequest>();
+ if (claimsRequest != null) {
+ var claimsResponse = claimsRequest.CreateResponse();
+
+ // This simple respond to a request check may be enhanced to only respond to an individual attribute
+ // request if the user consents to it explicitly, in which case this response extension creation can take
+ // place in the confirmation page action rather than here.
+ if (claimsRequest.Email != DemandLevel.NoRequest) {
+ claimsResponse.Email = User.Identity.Name + "@dotnetopenauth.net";
+ }
+
+ pendingRequest.AddResponseExtension(claimsResponse);
+ }
+ }
+
+ return OpenIdProvider.PrepareResponse(pendingRequest).AsActionResult();
+ }
+
+ /// <summary>
+ /// Attempts to formulate an automatic response to the RP if the user's profile allows it.
+ /// </summary>
+ /// <param name="response">Receives the ActionResult for the caller to return, or <c>null</c> if no automatic response can be made.</param>
+ /// <returns>A value indicating whether an automatic response is possible.</returns>
+ private bool AutoRespondIfPossible(out ActionResult response) {
+ // If the odds are good we can respond to this one immediately (without prompting the user)...
+ if (ProviderEndpoint.PendingRequest.IsReturnUrlDiscoverable(OpenIdProvider) == RelyingPartyDiscoveryResult.Success
+ && User.Identity.IsAuthenticated
+ && this.HasUserAuthorizedAutoLogin(ProviderEndpoint.PendingRequest)) {
+ // Is this is an identity authentication request? (as opposed to an anonymous request)...
+ if (ProviderEndpoint.PendingAuthenticationRequest != null) {
+ // If this is directed identity, or if the claimed identifier being checked is controlled by the current user...
+ if (ProviderEndpoint.PendingAuthenticationRequest.IsDirectedIdentity
+ || this.UserControlsIdentifier(ProviderEndpoint.PendingAuthenticationRequest)) {
+ ProviderEndpoint.PendingAuthenticationRequest.IsAuthenticated = true;
+ response = this.SendAssertion();
+ return true;
+ }
+ }
+
+ // If this is an anonymous request, we can respond to that too.
+ if (ProviderEndpoint.PendingAnonymousRequest != null) {
+ ProviderEndpoint.PendingAnonymousRequest.IsApproved = true;
+ response = this.SendAssertion();
+ return true;
+ }
+ }
+
+ response = null;
+ return false;
+ }
+
+ /// <summary>
+ /// Determines whether the currently logged in user has authorized auto login to the requesting relying party.
+ /// </summary>
+ /// <param name="request">The incoming request.</param>
+ /// <returns>
+ /// <c>true</c> if it is safe to respond affirmatively to this request and all extensions
+ /// without further user confirmation; otherwise, <c>false</c>.
+ /// </returns>
+ private bool HasUserAuthorizedAutoLogin(IHostProcessedRequest request) {
+ // TODO: host should implement this method meaningfully, consulting their user database.
+ // Make sure the user likes the RP
+ if (true/*User.UserLikesRP(request.Realm))*/) {
+ // And make sure the RP is only asking for information about the user that the user has granted before.
+ if (true/*User.HasGrantedExtensions(request)*/) {
+ // For now for the purposes of the sample, we'll disallow auto-logins when an sreg request is present.
+ if (request.GetExtension<ClaimsRequest>() != null) {
+ return false;
+ }
+
+ return true;
+ }
+ }
- authReq.IsAuthenticated = this.UserControlsIdentifier(authReq);
- return OpenIdProvider.PrepareResponse(authReq).AsActionResult();
+ // If we aren't sure the user likes this site and is willing to disclose the requested info, return false
+ // so the user has the opportunity to explicity choose whether to share his/her info.
+ return false;
}
/// <summary>
diff --git a/samples/OpenIdProviderMvc/OpenIdProviderMvc.csproj b/samples/OpenIdProviderMvc/OpenIdProviderMvc.csproj
index 794a91e..9dc060e 100644
--- a/samples/OpenIdProviderMvc/OpenIdProviderMvc.csproj
+++ b/samples/OpenIdProviderMvc/OpenIdProviderMvc.csproj
@@ -92,6 +92,7 @@
<Content Include="Views\Account\ChangePassword.aspx" />
<Content Include="Views\Account\ChangePasswordSuccess.aspx" />
<Content Include="Views\Account\Register.aspx" />
+ <Content Include="Views\OpenId\AskUser.aspx" />
<Content Include="Views\Shared\Xrds.aspx" />
<Content Include="Views\OpenId\Provider.aspx" />
<Content Include="Views\User\Identity.aspx" />
diff --git a/samples/OpenIdProviderMvc/Views/OpenId/AskUser.aspx b/samples/OpenIdProviderMvc/Views/OpenId/AskUser.aspx
new file mode 100644
index 0000000..5098325
--- /dev/null
+++ b/samples/OpenIdProviderMvc/Views/OpenId/AskUser.aspx
@@ -0,0 +1,38 @@
+<%@ Page Title="Do you want to log into another web site?" Language="C#" MasterPageFile="~/Views/Shared/Site.Master"
+ Inherits="System.Web.Mvc.ViewPage" %>
+
+<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
+ <h2>
+ Logging in somewhere?
+ </h2>
+ <p>
+ Are you trying to log into
+ <b><%= Html.Encode(ViewData["Realm"]) %></b>?
+ </p>
+ <% using (Html.BeginForm("AskUserResponse", "OpenId")) { %>
+ <%= Html.AntiForgeryToken() %>
+ <%= Html.Hidden("confirmed", "false") %>
+ <div style="display: none" id="responseButtonsDiv">
+ <input type="submit" value="yes" onclick="document.getElementsByName('confirmed')[0].value = 'true'; return true;" />
+ <input type="submit" value="no" />
+ </div>
+ <div id="javascriptDisabled">
+ <b>Javascript appears to be disabled in your browser. </b>This page requires Javascript
+ to be enabled to better protect your security.
+ </div>
+ <script language="javascript" type="text/javascript">
+ //<![CDATA[
+ // we use HTML to hide the action buttons and Javascript to show them
+ // to protect against click-jacking in an iframe whose javascript is disabled.
+ document.getElementById('responseButtonsDiv').style.display = 'block';
+ document.getElementById('javascriptDisabled').style.display = 'none';
+
+ // Frame busting code (to protect us from being hosted in an iframe).
+ // This protects us from click-jacking.
+ if (document.location !== window.top.location) {
+ window.top.location = document.location;
+ }
+ //]]>
+ </script>
+ <% } %>
+</asp:Content>
diff --git a/samples/OpenIdProviderMvc/Web.config b/samples/OpenIdProviderMvc/Web.config
index cc30638..9b1eb90 100644
--- a/samples/OpenIdProviderMvc/Web.config
+++ b/samples/OpenIdProviderMvc/Web.config
@@ -46,6 +46,7 @@
profile matches, the default behavior is assumed. -->
<!--<add type="DotNetOpenAuth.OpenId.Behaviors.GsaIcamProfile, DotNetOpenAuth" />-->
<add type="DotNetOpenAuth.OpenId.Behaviors.PpidGeneration, DotNetOpenAuth" />
+ <add type="DotNetOpenAuth.OpenId.Behaviors.AXFetchAsSregTransform, DotNetOpenAuth" />
</behaviors>
<!-- Uncomment the following to activate the sample custom store. -->
<!--<store type="RelyingPartyWebForms.CustomStore, RelyingPartyWebForms" />-->
diff --git a/samples/OpenIdProviderWebForms/Code/InMemoryTokenManager.cs b/samples/OpenIdProviderWebForms/Code/InMemoryTokenManager.cs
index b04f736..1cb7094 100644
--- a/samples/OpenIdProviderWebForms/Code/InMemoryTokenManager.cs
+++ b/samples/OpenIdProviderWebForms/Code/InMemoryTokenManager.cs
@@ -49,7 +49,7 @@ namespace OpenIdProviderWebForms.Code {
}
public void UpdateToken(IServiceProviderRequestToken token) {
- // Nothing to do here, since there's not database in this sample.
+ // Nothing to do here, since there's no database in this sample.
}
#endregion
diff --git a/samples/OpenIdProviderWebForms/Provider.ashx.cs b/samples/OpenIdProviderWebForms/Provider.ashx.cs
index c8441cf..3285b57 100644
--- a/samples/OpenIdProviderWebForms/Provider.ashx.cs
+++ b/samples/OpenIdProviderWebForms/Provider.ashx.cs
@@ -28,8 +28,7 @@
// redirects and user prompts can appear and eventually some page can decide
// to respond to the OpenID authentication request either affirmatively or
// negatively.
- ProviderEndpoint.PendingAnonymousRequest = request as IAnonymousRequest;
- ProviderEndpoint.PendingAuthenticationRequest = request as IAuthenticationRequest;
+ ProviderEndpoint.PendingRequest = request as IHostProcessedRequest;
// We delegate that approval process to our utility method that we share
// with our other Provider sample page server.aspx.
diff --git a/samples/OpenIdRelyingPartyClassicAsp/default.asp b/samples/OpenIdRelyingPartyClassicAsp/default.asp
index cc2bd57..ddb8dc0 100644
--- a/samples/OpenIdRelyingPartyClassicAsp/default.asp
+++ b/samples/OpenIdRelyingPartyClassicAsp/default.asp
@@ -25,10 +25,14 @@
assembly is found.</li>
<li>Register DotNetOpenAuth as a COM server:<br />
<span class="command">%windir%\Microsoft.NET\Framework\v2.0.50727\RegAsm.exe
- /tlb DotNetOpenAuth.dll</span></li>
+ /tlb DotNetOpenAuth.dll</span><br />
+ Note that you may need to copy System.Web.Mvc.dll into the same directory as dotnetopenauth.dll
+ if it is not already in your GAC.</li>
<li>Install DotNetOpenAuth into the GAC.&nbsp; The gacutil.exe tool may be in an SDK
directory, which will be in your path if you opened a Visual Studio Command Prompt.<br />
- <span class="command">gacutil.exe /i DotNetOpenAuth.dll</span></li>
+ <span class="command">gacutil.exe /i DotNetOpenAuth.dll</span><br />
+ Be sure to use a gacutil.exe that comes from a .NET 2.0-3.5 directory (not .NET 1.x).
+ </li>
</ol>
<p>Another thing to be aware of is that with classic ASP there is no Web.config
file in which to customize DotNetOpenAuth behavior.&nbsp; And the COM interfaces
diff --git a/samples/OpenIdRelyingPartyClassicAsp/login.asp b/samples/OpenIdRelyingPartyClassicAsp/login.asp
index 18c4d4f..90112f9 100644
--- a/samples/OpenIdRelyingPartyClassicAsp/login.asp
+++ b/samples/OpenIdRelyingPartyClassicAsp/login.asp
@@ -13,17 +13,19 @@
<h2>Login Page</h2>
<%
dim realm, thisPageUrl, requestUrl, dnoi, authentication
- realm = "http://" + Request.ServerVariables("HTTP_HOST") + "/classicaspdnoi/"
- thisPageUrl = "http://" + Request.ServerVariables("HTTP_HOST") + Request.ServerVariables("URL")
- requestUrl = "http://" + Request.ServerVariables("HTTP_HOST") + Request.ServerVariables("HTTP_URL")
+ realm = "http://" + Request.ServerVariables("HTTP_HOST") + "/classicaspdnoi/" ' change this to be the home page of your web site, without the filename.
+ requestUrl = "http://" + Request.ServerVariables("HTTP_HOST") + Request.ServerVariables("HTTP_URL") ' this is the full URL of the current incoming request.
Set dnoi = server.CreateObject("DotNetOpenAuth.OpenId.RelyingParty.OpenIdRelyingParty")
On Error Resume Next
+ ' Since this page both starts the OpenID authentication flow and receives the response, we don't
+ ' yet know whether this particular request is already in the response phase. Check that now.
Set authentication = dnoi.ProcessAuthentication(requestUrl, Request.Form)
If Err.number <> 0 Then
+ ' Oops, report something that went wrong.
Response.Write "<p>" + Server.HTMLEncode(Err.Description) + "</p>"
End If
On Error Goto 0
- if Not authentication Is Nothing then
+ if Not authentication Is Nothing then ' if this WAS an OpenID response coming in...
If authentication.Successful Then
Session("ClaimedIdentifier") = authentication.ClaimedIdentifier
If Not authentication.ClaimsResponse Is Nothing Then
@@ -35,9 +37,10 @@
else
Response.Write "Authentication failed: " + authentication.ExceptionMessage
end if
- elseif Request.Form("openid_identifier") <> "" then
+ elseif Request.Form("openid_identifier") <> "" then ' if the user is only now starting the authentication flow...
dim redirectUrl
On Error Resume Next
+ thisPageUrl = "http://" + Request.ServerVariables("HTTP_HOST") + Request.ServerVariables("URL") ' this is the URL that will receive the response from the OpenID Provider.
' redirectUrl = dnoi.CreateRequest(Request.Form("openid_identifier"), realm, thisPageUrl)
redirectUrl = dnoi.CreateRequestWithSimpleRegistration(Request.Form("openid_identifier"), realm, thisPageUrl, "nickname,email", "fullname")
If Err.number <> 0 Then
diff --git a/samples/OpenIdRelyingPartyWebForms/NoIdentityOpenId.aspx b/samples/OpenIdRelyingPartyWebForms/NoIdentityOpenId.aspx
index dc0c2bb..cec5f49 100644
--- a/samples/OpenIdRelyingPartyWebForms/NoIdentityOpenId.aspx
+++ b/samples/OpenIdRelyingPartyWebForms/NoIdentityOpenId.aspx
@@ -10,17 +10,23 @@
in an organization. </p>
<p><b>Note: </b>At time of this writing, most OPs do not support this feature, although
it is documented in the OpenID 2.0 spec. </p>
- <asp:Label ID="Label1" runat="server" Text="OpenID Identifier" /> <asp:TextBox ID="openIdBox"
- runat="server" />
- <asp:Button ID="beginButton" runat="server" Text="Begin" OnClick="beginButton_Click" />
- <asp:CustomValidator runat="server" ID="openidValidator" ErrorMessage="Invalid OpenID Identifier"
- ControlToValidate="openIdBox" EnableViewState="false" Display="Dynamic" OnServerValidate="openidValidator_ServerValidate" />
- <asp:Label runat="server" EnableViewState="false" ID="resultMessage" />
+ <asp:Panel runat="server" DefaultButton="beginButton">
+ <asp:Label ID="Label1" runat="server" Text="OpenID Identifier" /> <asp:TextBox ID="openIdBox"
+ runat="server" />
+ <asp:Button ID="beginButton" runat="server" Text="Begin" OnClick="beginButton_Click" />
+ <asp:CustomValidator runat="server" ID="openidValidator" ErrorMessage="Invalid OpenID Identifier"
+ ControlToValidate="openIdBox" EnableViewState="false" Display="Dynamic" OnServerValidate="openidValidator_ServerValidate" />
+ <asp:Label runat="server" EnableViewState="false" ID="resultMessage" />
+ </asp:Panel>
<asp:Panel runat="server" ID="ExtensionResponsesPanel" EnableViewState="false" Visible="false">
<p>We have received a reasonable response from the Provider. Below is the Simple Registration
response we received, if any: </p>
<table id="profileFieldsTable" runat="server">
<tr>
+ <td>Email </td>
+ <td><asp:Label runat="server" ID="emailLabel" /> </td>
+ </tr>
+ <tr>
<td>Gender </td>
<td><asp:Label runat="server" ID="genderLabel" /> </td>
</tr>
diff --git a/samples/OpenIdRelyingPartyWebForms/NoIdentityOpenId.aspx.cs b/samples/OpenIdRelyingPartyWebForms/NoIdentityOpenId.aspx.cs
index 37a5515..ca12964 100644
--- a/samples/OpenIdRelyingPartyWebForms/NoIdentityOpenId.aspx.cs
+++ b/samples/OpenIdRelyingPartyWebForms/NoIdentityOpenId.aspx.cs
@@ -19,6 +19,7 @@
// This is the "success" status we get when no authentication was requested.
var sreg = response.GetExtension<ClaimsResponse>();
if (sreg != null) {
+ this.emailLabel.Text = sreg.Email;
this.timeZoneLabel.Text = sreg.TimeZone;
this.postalCodeLabel.Text = sreg.PostalCode;
this.countryLabel.Text = sreg.Country;
@@ -55,6 +56,7 @@
// This is where you would add any OpenID extensions you wanted
// to include in the request.
request.AddExtension(new ClaimsRequest {
+ Email = DemandLevel.Request,
Country = DemandLevel.Request,
Gender = DemandLevel.Require,
PostalCode = DemandLevel.Require,
diff --git a/samples/OpenIdRelyingPartyWebForms/NoIdentityOpenId.aspx.designer.cs b/samples/OpenIdRelyingPartyWebForms/NoIdentityOpenId.aspx.designer.cs
index fb959a3..348ea31 100644
--- a/samples/OpenIdRelyingPartyWebForms/NoIdentityOpenId.aspx.designer.cs
+++ b/samples/OpenIdRelyingPartyWebForms/NoIdentityOpenId.aspx.designer.cs
@@ -1,10 +1,9 @@
//------------------------------------------------------------------------------
// <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.
+// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
@@ -77,6 +76,15 @@ namespace OpenIdRelyingPartyWebForms {
protected global::System.Web.UI.HtmlControls.HtmlTable profileFieldsTable;
/// <summary>
+ /// emailLabel 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.Label emailLabel;
+
+ /// <summary>
/// genderLabel control.
/// </summary>
/// <remarks>
diff --git a/samples/Samples.proj b/samples/Samples.proj
index b1f212f..e6ac9f8 100644
--- a/samples/Samples.proj
+++ b/samples/Samples.proj
@@ -20,11 +20,20 @@
<ProjectsToClean Include="$(SolutionPath)">
<Targets>@(SampleSites->'%(Identity):Clean')</Targets>
</ProjectsToClean>
+
+ <_SampleWebConfigs Include="$(ProjectRoot)samples\*\web.config" />
+ <PublishableWebSamples Include="@(_SampleWebConfigs->'%(RootDir)%(Directory)')" />
</ItemGroup>
<Target Name="Build" DependsOnTargets="SkipVerification">
- <MSBuild Projects="@(SampleProjects)" BuildInParallel="$(BuildInParallel)" />
- <MSBuild Projects="$(SolutionPath)" Targets="@(SampleSites)" BuildInParallel="$(BuildInParallel)" />
+ <ItemGroup>
+ <SampleProjectsToBuild Include="@(SampleProjects)" />
+ <SampleProjectsToBuild Include="$(SolutionPath)">
+ <Targets>%(SampleSites.Identity)</Targets>
+ </SampleProjectsToBuild>
+ </ItemGroup>
+
+ <MSBuild Projects="@(SampleProjectsToBuild)" Targets="%(SampleProjectsToBuild.Targets)" BuildInParallel="$(BuildInParallel)" />
</Target>
<Target Name="Prepare">
@@ -33,10 +42,6 @@
<PropertyGroup>
<PublishSamplesWebSiteVirtualPath>/$(BranchName)</PublishSamplesWebSiteVirtualPath>
</PropertyGroup>
- <ItemGroup>
- <_SampleWebConfigs Include="$(ProjectRoot)samples\*\web.config" />
- <PublishableWebSamples Include="@(_SampleWebConfigs->'%(RootDir)%(Directory)')" />
- </ItemGroup>
<!-- Trim the trailing slash on the web sample paths so we can just get the leaf directory name. -->
<Trim
@@ -51,12 +56,13 @@
</ItemGroup>
</Target>
- <Target Name="PrepareForPublish" DependsOnTargets="Prepare;Build">
+ <Target Name="PrepareForPublish" DependsOnTargets="Build">
+ <PropertyGroup>
+ <SamplesZip>$(DropDirectoryNoSlash)-samples$(ZipFormat)</SamplesZip>
+ </PropertyGroup>
+
<ItemGroup>
<SampleSources Include="$(ProjectRoot)samples\**\*" />
- <SampleSources>
- <PublishedLocation>$(SampleWebRoot)\$(BranchName)\%(RecursiveDir)%(Filename)%(Extension)</PublishedLocation>
- </SampleSources>
</ItemGroup>
<FilterItems
@@ -64,26 +70,22 @@
StartsWithAny="@(PublishableWebSamples)">
<Output TaskParameter="FilteredItems" ItemName="PublishableWebSampleSources" />
</FilterItems>
-
- <ItemGroup>
- <PublishableWebSampleTargets Include="@(PublishableWebSampleSources->'%(PublishedLocation)')" />
- </ItemGroup>
</Target>
- <Target Name="Publish"
+ <Target Name="DeployableArchive"
DependsOnTargets="PrepareForPublish"
Inputs="@(PublishableWebSampleSources)"
- Outputs="@(PublishableWebSampleTargets)"
- Condition=" '$(SampleWebRoot)' != '' ">
- <RemoveDir Directories="$(SampleWebRoot)\$(BranchName)" />
- <MakeDir Directories="$(SampleWebRoot)\$(BranchName)" />
- <Copy SourceFiles="@(PublishableWebSampleSources)" DestinationFiles="@(PublishableWebSampleTargets)" SkipUnchangedFiles="true" />
+ Outputs="$(SamplesZip)">
+ <Delete Files="$(SamplesZip)" />
+ <AddFilesTo7Zip
+ Files="@(PublishableWebSampleSources)"
+ ZipFileName="$(SamplesZip)"
+ WorkingDirectory="$(ProjectRoot)samples\"
+ ToolPath="$(Zip7ToolPath)" />
</Target>
- <Target Name="Unpublish"
- DependsOnTargets="DeleteSitesOnIis"
- Condition=" '$(SampleWebRoot)' != '' ">
- </Target>
+ <Target Name="Publish"
+ DependsOnTargets="DeployableArchive" />
<Target Name="CreateSitesOnIis" DependsOnTargets="Prepare">
<Error Text="The PublishSamplesWebSiteName property must be set." Condition=" '$(PublishSamplesWebSiteName)' == '' "/>
diff --git a/samples/tools.proj b/samples/tools.proj
index e7d89d9..0c413b7 100644
--- a/samples/tools.proj
+++ b/samples/tools.proj
@@ -15,13 +15,20 @@
</ToolProjects>
</ItemGroup>
- <MSBuild Projects="@(ToolProjects)" Targets="%(ToolProjects.Targets)" BuildInParallel="$(BuildInParallel)">
- <Output TaskParameter="TargetOutputs" ItemName="OfflineProvider"/>
+ <MSBuild Projects="@(ToolProjects)" Targets="%(ToolProjects.Targets);BuiltProjectOutputGroupDependencies" BuildInParallel="$(BuildInParallel)">
+ <Output TaskParameter="TargetOutputs" ItemName="ToolProjectsOutputs"/>
</MSBuild>
<ItemGroup>
- <!-- Remove the un-unified assembly. -->
- <OfflineProvider Remove="$(OutputPath)$(SignedSubPath)$(ProductName).dll" />
+ <!-- Exclude the un-unified assemblies. -->
+ <OfflineProvider Include="@(ToolProjectsOutputs)"
+ Condition=" '%(ToolProjectsOutputs.CopyLocal)' != 'false' "
+ Exclude="
+ $(OutputPath)$(ProductName).dll;
+ $(OutputPath)$(SignedSubPath)$(ProductName).dll;
+ $(ProjectRoot)lib\Microsoft.Contracts.dll;
+ " />
+
<!-- add the PDBs -->
<OfflineProvider Include="@(OfflineProvider->'%(SymbolPath)')" />
<OfflineProviderTargets Include="
@@ -40,7 +47,7 @@
<Target Name="Build" DependsOnTargets="Layout" Returns="@(RedistributableFiles)">
<PropertyGroup>
- <ToolsZip>$(ToolsDirectoryNoSlash).zip</ToolsZip>
+ <ToolsZip>$(ToolsDirectoryNoSlash)$(ZipFormat)</ToolsZip>
</PropertyGroup>
<ItemGroup>
<RedistributableFiles Include="$(ToolsZip)">
@@ -49,10 +56,12 @@
</RedistributableFiles>
</ItemGroup>
- <Zip ZipFileName="$(ToolsZip)"
- Files="@(AllToolTargets)"
- WorkingDirectory="$(ToolsDirectory)"
- ZipLevel="$(ZipLevel)" />
+ <Delete Files="$(ToolsZip)" />
+ <AddFilesTo7Zip
+ ZipFileName="$(ToolsZip)"
+ Files="@(AllToolTargets)"
+ WorkingDirectory="$(ToolsDirectory)"
+ ToolPath="$(Zip7ToolPath)" />
</Target>
<Import Project="$(ProjectRoot)tools\DotNetOpenAuth.automated.targets"/>
diff --git a/src/DotNetOpenAuth.BuildTasks/AddFilesTo7Zip.cs b/src/DotNetOpenAuth.BuildTasks/AddFilesTo7Zip.cs
new file mode 100644
index 0000000..8bf3e16
--- /dev/null
+++ b/src/DotNetOpenAuth.BuildTasks/AddFilesTo7Zip.cs
@@ -0,0 +1,105 @@
+//-----------------------------------------------------------------------
+// <copyright file="AddFilesTo7Zip.cs" company="Andrew Arnott">
+// Copyright (c) Andrew Arnott. All rights reserved.
+// </copyright>
+//-----------------------------------------------------------------------
+
+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 AddFilesTo7Zip : ToolTask {
+ /// <summary>
+ /// Initializes a new instance of the <see cref="AddFilesTo7Zip"/> class.
+ /// </summary>
+ public AddFilesTo7Zip() {
+ this.YieldDuringToolExecution = true;
+ }
+
+ [Required]
+ public ITaskItem ZipFileName { get; set; }
+
+ [Required]
+ public ITaskItem[] Files { get; set; }
+
+ public string WorkingDirectory { get; set; }
+
+ /// <summary>
+ /// Gets the name of the tool.
+ /// </summary>
+ /// <value>
+ /// The name of the tool.
+ /// </value>
+ protected override string ToolName {
+ get { return "7za.exe"; }
+ }
+
+ /// <summary>
+ /// Generates the full path to tool.
+ /// </summary>
+ protected override string GenerateFullPathToTool() {
+ return this.ToolPath;
+ }
+
+ protected override string GenerateCommandLineCommands() {
+ var args = new CommandLineBuilder();
+
+ args.AppendSwitch("a");
+ args.AppendSwitch("--");
+
+ args.AppendFileNameIfNotNull(this.ZipFileName);
+
+ return args.ToString();
+ }
+
+ /// <summary>
+ /// Gets the response file switch.
+ /// </summary>
+ /// <param name="responseFilePath">The response file path.</param>
+ protected override string GetResponseFileSwitch(string responseFilePath) {
+ return "@" + responseFilePath;
+ }
+
+ /// <summary>
+ /// Gets the response file encoding.
+ /// </summary>
+ /// <value>
+ /// The response file encoding.
+ /// </value>
+ protected override Encoding ResponseFileEncoding {
+ get { return Encoding.UTF8; }
+ }
+
+ /// <summary>
+ /// Generates the response file commands.
+ /// </summary>
+ protected override string GenerateResponseFileCommands() {
+ var args = new CommandLineBuilder();
+ args.AppendFileNamesIfNotNull(this.Files.Select(GetWorkingDirectoryRelativePath).ToArray(), Environment.NewLine);
+ return args.ToString();
+ }
+
+ /// <summary>
+ /// Gets the working directory.
+ /// </summary>
+ protected override string GetWorkingDirectory() {
+ if (!String.IsNullOrEmpty(this.WorkingDirectory)) {
+ return this.WorkingDirectory;
+ } else {
+ return base.GetWorkingDirectory();
+ }
+ }
+
+ private string GetWorkingDirectoryRelativePath(ITaskItem taskItem) {
+ if (taskItem.ItemSpec.StartsWith(this.WorkingDirectory, StringComparison.OrdinalIgnoreCase)) {
+ return taskItem.ItemSpec.Substring(this.WorkingDirectory.Length);
+ } else {
+ return taskItem.ItemSpec;
+ }
+ }
+ }
+}
diff --git a/src/DotNetOpenAuth.BuildTasks/ChangeProjectReferenceToAssemblyReference.cs b/src/DotNetOpenAuth.BuildTasks/ChangeProjectReferenceToAssemblyReference.cs
index 503e168..fb42ade 100644
--- a/src/DotNetOpenAuth.BuildTasks/ChangeProjectReferenceToAssemblyReference.cs
+++ b/src/DotNetOpenAuth.BuildTasks/ChangeProjectReferenceToAssemblyReference.cs
@@ -38,7 +38,7 @@
foreach (var project in Projects) {
Project doc = new Project();
- doc.Load(project.ItemSpec);
+ doc.Load(project.ItemSpec, ProjectLoadSettings.IgnoreMissingImports);
var projectReferences = doc.EvaluatedItems.OfType<BuildItem>().Where(item => item.Name == "ProjectReference");
var matchingReferences = from reference in projectReferences
diff --git a/src/DotNetOpenAuth.BuildTasks/DotNetOpenAuth.BuildTasks.csproj b/src/DotNetOpenAuth.BuildTasks/DotNetOpenAuth.BuildTasks.csproj
index 179c825..310ee9d 100644
--- a/src/DotNetOpenAuth.BuildTasks/DotNetOpenAuth.BuildTasks.csproj
+++ b/src/DotNetOpenAuth.BuildTasks/DotNetOpenAuth.BuildTasks.csproj
@@ -11,7 +11,7 @@
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>DotNetOpenAuth.BuildTasks</RootNamespace>
<AssemblyName>DotNetOpenAuth.BuildTasks</AssemblyName>
- <TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
+ <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<PublishUrl>publish\</PublishUrl>
<Install>true</Install>
@@ -29,6 +29,7 @@
<UseApplicationTrust>false</UseApplicationTrust>
<BootstrapperEnabled>true</BootstrapperEnabled>
<CodeContractsAssemblyMode>1</CodeContractsAssemblyMode>
+ <TargetFrameworkProfile />
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
@@ -78,14 +79,10 @@
<CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
<ItemGroup>
+ <Reference Include="Microsoft.Build" />
<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.Contracts, Version=1.0.0.0, Culture=neutral, PublicKeyToken=736440c9b414ea16, processorArchitecture=MSIL">
- <Private>False</Private>
- </Reference>
+ <Reference Include="Microsoft.Build.Utilities.v4.0" />
<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>
@@ -101,6 +98,7 @@
</Reference>
</ItemGroup>
<ItemGroup>
+ <Compile Include="AddFilesTo7Zip.cs" />
<Compile Include="AddProjectItems.cs" />
<Compile Include="ChangeProjectReferenceToAssemblyReference.cs" />
<Compile Include="CompareFiles.cs" />
@@ -120,6 +118,7 @@
<Compile Include="CheckAdminRights.cs" />
<Compile Include="JsPack.cs" />
<Compile Include="NativeMethods.cs" />
+ <Compile Include="NuGetPack.cs" />
<Compile Include="ParseMaster.cs" />
<Compile Include="PathSegment.cs" />
<Compile Include="PrepareOhlohRelease.cs" />
diff --git a/src/DotNetOpenAuth.BuildTasks/DotNetOpenAuth.BuildTasks.sln b/src/DotNetOpenAuth.BuildTasks/DotNetOpenAuth.BuildTasks.sln
index a144f1c..5c2ffbb 100644
--- a/src/DotNetOpenAuth.BuildTasks/DotNetOpenAuth.BuildTasks.sln
+++ b/src/DotNetOpenAuth.BuildTasks/DotNetOpenAuth.BuildTasks.sln
@@ -9,12 +9,14 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
..\..\tools\DotNetOpenAuth.automated.targets = ..\..\tools\DotNetOpenAuth.automated.targets
..\..\lib\DotNetOpenAuth.BuildTasks.targets = ..\..\lib\DotNetOpenAuth.BuildTasks.targets
..\..\tools\DotNetOpenAuth.Common.Settings.targets = ..\..\tools\DotNetOpenAuth.Common.Settings.targets
+ ..\..\nuget\DotNetOpenAuth.nuspec = ..\..\nuget\DotNetOpenAuth.nuspec
..\..\tools\DotNetOpenAuth.props = ..\..\tools\DotNetOpenAuth.props
..\..\tools\DotNetOpenAuth.targets = ..\..\tools\DotNetOpenAuth.targets
..\..\tools\DotNetOpenAuth.Versioning.targets = ..\..\tools\DotNetOpenAuth.Versioning.targets
..\..\tools\drop.proj = ..\..\tools\drop.proj
..\..\EnlistmentInfo.props = ..\..\EnlistmentInfo.props
..\..\EnlistmentInfo.targets = ..\..\EnlistmentInfo.targets
+ ..\..\nuget\nuget.proj = ..\..\nuget\nuget.proj
..\..\tools\ohloh.proj = ..\..\tools\ohloh.proj
..\..\projecttemplates\projecttemplates.proj = ..\..\projecttemplates\projecttemplates.proj
..\..\samples\Samples.proj = ..\..\samples\Samples.proj
@@ -25,6 +27,17 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DotNetOpenAuth.BuildTasks", "DotNetOpenAuth.BuildTasks.csproj", "{AC231A51-EF60-437C-A33F-AF8ADEB8EB74}"
EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "NuGet", "NuGet", "{D49E2011-0E1C-4AB5-9887-BD1D42266503}"
+ ProjectSection(SolutionItems) = preProject
+ ..\..\nuget\DotNetOpenAuth.nuspec = ..\..\nuget\DotNetOpenAuth.nuspec
+ ..\..\nuget\nuget.proj = ..\..\nuget\nuget.proj
+ EndProjectSection
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "content", "content", "{BF3868D6-3BBA-4E40-B180-213370C15494}"
+ ProjectSection(SolutionItems) = preProject
+ ..\..\nuget\content\web.config.transform = ..\..\nuget\content\web.config.transform
+ EndProjectSection
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -39,4 +52,8 @@ Global
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
+ GlobalSection(NestedProjects) = preSolution
+ {D49E2011-0E1C-4AB5-9887-BD1D42266503} = {ABBE14A3-0404-4123-9093-E598C3DD3E9B}
+ {BF3868D6-3BBA-4E40-B180-213370C15494} = {D49E2011-0E1C-4AB5-9887-BD1D42266503}
+ EndGlobalSection
EndGlobal
diff --git a/src/DotNetOpenAuth.BuildTasks/NuGetPack.cs b/src/DotNetOpenAuth.BuildTasks/NuGetPack.cs
new file mode 100644
index 0000000..356c51f
--- /dev/null
+++ b/src/DotNetOpenAuth.BuildTasks/NuGetPack.cs
@@ -0,0 +1,108 @@
+//-----------------------------------------------------------------------
+// <copyright file="NuGetPack.cs" company="Andrew Arnott">
+// Copyright (c) Andrew Arnott. All rights reserved.
+// </copyright>
+//-----------------------------------------------------------------------
+
+namespace DotNetOpenAuth.BuildTasks {
+ using System;
+ using System.Collections.Generic;
+ using System.IO;
+ using System.Linq;
+ using System.Text;
+ using System.Xml.Linq;
+ using Microsoft.Build.Framework;
+ using Microsoft.Build.Utilities;
+
+ /// <summary>
+ /// Creates a .nupkg archive from a .nuspec file and content files.
+ /// </summary>
+ public class NuGetPack : ToolTask {
+ /// <summary>
+ /// Gets or sets the path to the .nuspec file.
+ /// </summary>
+ [Required]
+ public ITaskItem NuSpec { get; set; }
+
+ /// <summary>
+ /// Gets or sets the base directory, the contents of which gets included in the .nupkg archive.
+ /// </summary>
+ public ITaskItem BaseDirectory { get; set; }
+
+ /// <summary>
+ /// Gets or sets the path to the directory that will contain the generated .nupkg archive.
+ /// </summary>
+ public ITaskItem OutputPackageDirectory { get; set; }
+
+ /// <summary>
+ /// Returns the fully qualified path to the executable file.
+ /// </summary>
+ /// <returns>
+ /// The fully qualified path to the executable file.
+ /// </returns>
+ protected override string GenerateFullPathToTool() {
+ return this.ToolPath;
+ }
+
+ /// <summary>
+ /// Gets the name of the executable file to run.
+ /// </summary>
+ /// <returns>The name of the executable file to run.</returns>
+ protected override string ToolName {
+ get { return "NuGet.exe"; }
+ }
+
+ /// <summary>
+ /// Runs the exectuable file with the specified task parameters.
+ /// </summary>
+ /// <returns>
+ /// true if the task runs successfully; otherwise, false.
+ /// </returns>
+ public override bool Execute() {
+ if (this.OutputPackageDirectory != null && Path.GetDirectoryName(this.OutputPackageDirectory.ItemSpec).Length > 0) {
+ Directory.CreateDirectory(Path.GetDirectoryName(this.OutputPackageDirectory.ItemSpec));
+ }
+
+ string fullPackagePath = this.DeriveFullPackagePath();
+ this.Log.LogMessage("Creating NuGet package '{0}'.", fullPackagePath);
+
+ bool result = base.Execute();
+
+ if (result) {
+ this.Log.LogMessage(MessageImportance.High, "Successfully created package '{0}'.", fullPackagePath);
+ }
+
+ return result;
+ }
+
+ /// <summary>
+ /// Returns a string value containing the command line arguments to pass directly to the executable file.
+ /// </summary>
+ /// <returns>
+ /// A string value containing the command line arguments to pass directly to the executable file.
+ /// </returns>
+ protected override string GenerateCommandLineCommands() {
+ var args = new CommandLineBuilder();
+
+ args.AppendSwitch("pack");
+ args.AppendFileNameIfNotNull(this.NuSpec);
+ args.AppendSwitchIfNotNull("-b ", this.BaseDirectory);
+ args.AppendSwitchIfNotNull("-o ", this.OutputPackageDirectory);
+
+ return args.ToString();
+ }
+
+ /// <summary>
+ /// Derives the path to the generated .nupkg file.
+ /// </summary>
+ /// <returns>A relative path.</returns>
+ private string DeriveFullPackagePath() {
+ var spec = XDocument.Load(this.NuSpec.ItemSpec);
+ var metadata = spec.Element("package").Element("metadata");
+ string id = metadata.Element("id").Value;
+ string version = metadata.Element("version").Value;
+ string baseDirectory = this.OutputPackageDirectory != null ? this.OutputPackageDirectory.ItemSpec : String.Empty;
+ return Path.Combine(baseDirectory, String.Format("{0}.{1}.nupkg", id, version));
+ }
+ }
+}
diff --git a/src/DotNetOpenAuth.BuildTasks/ReSignDelaySignedAssemblies.cs b/src/DotNetOpenAuth.BuildTasks/ReSignDelaySignedAssemblies.cs
index a0ba386..2bcc160 100644
--- a/src/DotNetOpenAuth.BuildTasks/ReSignDelaySignedAssemblies.cs
+++ b/src/DotNetOpenAuth.BuildTasks/ReSignDelaySignedAssemblies.cs
@@ -32,7 +32,7 @@ namespace DotNetOpenAuth.BuildTasks {
////if (this.Assemblies.Length != 1) {
//// throw new NotSupportedException("Exactly 1 assembly for signing is supported.");
////}
- CommandLineBuilder args = new CommandLineBuilder();
+ var args = new CommandLineBuilder();
args.AppendSwitch("-q");
if (this.KeyFile != null) {
diff --git a/src/DotNetOpenAuth.BuildTasks/TaskStrings.Designer.cs b/src/DotNetOpenAuth.BuildTasks/TaskStrings.Designer.cs
index 17647fd..d5a80a4 100644
--- a/src/DotNetOpenAuth.BuildTasks/TaskStrings.Designer.cs
+++ b/src/DotNetOpenAuth.BuildTasks/TaskStrings.Designer.cs
@@ -1,7 +1,7 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
-// Runtime Version:2.0.50727.4927
+// Runtime Version:4.0.30319.1
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
@@ -19,7 +19,7 @@ namespace DotNetOpenAuth.BuildTasks {
// 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.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
internal class TaskStrings {
diff --git a/src/DotNetOpenAuth.Test/DotNetOpenAuth.Test.csproj b/src/DotNetOpenAuth.Test/DotNetOpenAuth.Test.csproj
index d7f97e5..5e80f2c 100644
--- a/src/DotNetOpenAuth.Test/DotNetOpenAuth.Test.csproj
+++ b/src/DotNetOpenAuth.Test/DotNetOpenAuth.Test.csproj
@@ -153,7 +153,6 @@
</PropertyGroup>
<ItemGroup>
<Reference Include="log4net" />
- <Reference Include="Microsoft.VisualStudio.QualityTools.UnitTestFramework" />
<Reference Include="Moq" />
<Reference Include="NUnit.Framework" />
<Reference Include="System" />
diff --git a/src/DotNetOpenAuth.Test/Messaging/ChannelTests.cs b/src/DotNetOpenAuth.Test/Messaging/ChannelTests.cs
index 5d31d40..acb200f 100644
--- a/src/DotNetOpenAuth.Test/Messaging/ChannelTests.cs
+++ b/src/DotNetOpenAuth.Test/Messaging/ChannelTests.cs
@@ -77,6 +77,8 @@ namespace DotNetOpenAuth.Test.Messaging {
OutgoingWebResponse response = this.Channel.PrepareResponse(message);
Assert.AreEqual(HttpStatusCode.Redirect, response.Status);
+ Assert.AreEqual("text/html; charset=utf-8", response.Headers[HttpResponseHeader.ContentType]);
+ Assert.IsTrue(response.Body != null && response.Body.Length > 0); // a non-empty body helps get passed filters like WebSense
StringAssert.StartsWith("http://provider/path", response.Headers[HttpResponseHeader.Location]);
foreach (var pair in expected) {
string key = MessagingUtilities.EscapeUriDataStringRfc3986(pair.Key);
diff --git a/src/DotNetOpenAuth.Test/Messaging/MessagingUtilitiesTests.cs b/src/DotNetOpenAuth.Test/Messaging/MessagingUtilitiesTests.cs
index 10084b6..33970a5 100644
--- a/src/DotNetOpenAuth.Test/Messaging/MessagingUtilitiesTests.cs
+++ b/src/DotNetOpenAuth.Test/Messaging/MessagingUtilitiesTests.cs
@@ -258,7 +258,7 @@ namespace DotNetOpenAuth.Test.Messaging {
}
almostMatchTimer.Stop();
- const double ToleranceFactor = 0.06;
+ const double ToleranceFactor = 0.12;
long averageTimeTicks = (totalMismatchTimer.ElapsedTicks + almostMatchTimer.ElapsedTicks) / 2;
var tolerableDifference = TimeSpan.FromTicks((long)(averageTimeTicks * ToleranceFactor));
var absoluteDifference = TimeSpan.FromTicks(Math.Abs(totalMismatchTimer.ElapsedTicks - almostMatchTimer.ElapsedTicks));
diff --git a/src/DotNetOpenAuth.Test/OAuth/ChannelElements/OAuthChannelTests.cs b/src/DotNetOpenAuth.Test/OAuth/ChannelElements/OAuthChannelTests.cs
index 54ed37e..479375a 100644
--- a/src/DotNetOpenAuth.Test/OAuth/ChannelElements/OAuthChannelTests.cs
+++ b/src/DotNetOpenAuth.Test/OAuth/ChannelElements/OAuthChannelTests.cs
@@ -125,7 +125,7 @@ namespace DotNetOpenAuth.Test.OAuth.ChannelElements {
OutgoingWebResponse response = this.channel.PrepareResponse(message);
Assert.AreSame(message, response.OriginalMessage);
Assert.AreEqual(HttpStatusCode.OK, response.Status);
- Assert.AreEqual(0, response.Headers.Count);
+ Assert.AreEqual(2, response.Headers.Count);
NameValueCollection body = HttpUtility.ParseQueryString(response.Body);
Assert.AreEqual("15", body["age"]);
diff --git a/src/DotNetOpenAuth.Test/OpenId/Extensions/SimpleRegistration/ClaimsResponseTests.cs b/src/DotNetOpenAuth.Test/OpenId/Extensions/SimpleRegistration/ClaimsResponseTests.cs
index 0bdc36e..69bb935 100644
--- a/src/DotNetOpenAuth.Test/OpenId/Extensions/SimpleRegistration/ClaimsResponseTests.cs
+++ b/src/DotNetOpenAuth.Test/OpenId/Extensions/SimpleRegistration/ClaimsResponseTests.cs
@@ -11,6 +11,7 @@ namespace DotNetOpenAuth.Test.OpenId.Extensions {
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
using System.Xml.Serialization;
+ using DotNetOpenAuth.OpenId;
using DotNetOpenAuth.OpenId.Extensions.SimpleRegistration;
using NUnit.Framework;
@@ -130,6 +131,17 @@ namespace DotNetOpenAuth.Test.OpenId.Extensions {
response.BirthDateRaw = "2008";
}
+ [TestCase]
+ public void ResponseAlternateTypeUriTests() {
+ var request = new ClaimsRequest(Constants.sreg_ns10);
+ request.Email = DemandLevel.Require;
+
+ var response = new ClaimsResponse(Constants.sreg_ns10);
+ response.Email = "a@b.com";
+
+ ExtensionTestUtilities.Roundtrip(Protocol.Default, new[] { request }, new[] { response });
+ }
+
private ClaimsResponse GetFilledData() {
return new ClaimsResponse(Constants.sreg_ns) {
BirthDate = new DateTime(2005, 2, 3),
diff --git a/src/DotNetOpenAuth.Test/OpenId/RelyingParty/PositiveAuthenticationResponseSnapshotTests.cs b/src/DotNetOpenAuth.Test/OpenId/RelyingParty/PositiveAuthenticationResponseSnapshotTests.cs
index e069c44..0bb994c 100644
--- a/src/DotNetOpenAuth.Test/OpenId/RelyingParty/PositiveAuthenticationResponseSnapshotTests.cs
+++ b/src/DotNetOpenAuth.Test/OpenId/RelyingParty/PositiveAuthenticationResponseSnapshotTests.cs
@@ -12,16 +12,16 @@ namespace DotNetOpenAuth.Test.OpenId.RelyingParty {
using DotNetOpenAuth.OpenId;
using DotNetOpenAuth.OpenId.Messages;
using DotNetOpenAuth.OpenId.RelyingParty;
- using Microsoft.VisualStudio.TestTools.UnitTesting;
using Moq;
+ using NUnit.Framework;
- [TestClass]
+ [TestFixture]
public class PositiveAuthenticationResponseSnapshotTests : OpenIdTestBase {
/// <summary>
/// Verifies that the PositiveAuthenticationResponseSnapshot is serializable,
/// as required by the <see cref="OpenIdRelyingPartyAjaxControlBase"/> class.
/// </summary>
- [TestMethod]
+ [Test]
public void Serializable() {
var response = new Mock<IAuthenticationResponse>(MockBehavior.Strict);
response.Setup(o => o.ClaimedIdentifier).Returns(VanityUri);
diff --git a/src/DotNetOpenAuth/Configuration/DotNetOpenAuth.xsd b/src/DotNetOpenAuth/Configuration/DotNetOpenAuth.xsd
index fda2aaf..9c0ab77 100644
--- a/src/DotNetOpenAuth/Configuration/DotNetOpenAuth.xsd
+++ b/src/DotNetOpenAuth/Configuration/DotNetOpenAuth.xsd
@@ -878,6 +878,25 @@
</xs:attribute>
</xs:complexType>
</xs:element>
+ <xs:element name="webResourceUrlProvider">
+ <xs:annotation>
+ <xs:documentation>
+ The type that implements the DotNetOpenAuth.IEmbeddedResourceRetrieval interface
+ to instantiate for obtaining URLs that fetch embedded resource streams.
+ Primarily useful when the System.Web.UI.Page class is not used in the ASP.NET pipeline.
+ </xs:documentation>
+ </xs:annotation>
+ <xs:complexType>
+ <xs:attribute name="type" type="xs:string" use="optional">
+ <xs:annotation>
+ <xs:documentation>
+ The fully-qualified name of the type that implements the IEmbeddedResourceRetrieval interface.
+ </xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+ <xs:attribute name="xaml" type="xs:string" use="optional" />
+ </xs:complexType>
+ </xs:element>
</xs:choice>
</xs:complexType>
</xs:element>
diff --git a/src/DotNetOpenAuth/Configuration/DotNetOpenAuthSection.cs b/src/DotNetOpenAuth/Configuration/DotNetOpenAuthSection.cs
index 117a542..409fca9 100644
--- a/src/DotNetOpenAuth/Configuration/DotNetOpenAuthSection.cs
+++ b/src/DotNetOpenAuth/Configuration/DotNetOpenAuthSection.cs
@@ -40,6 +40,11 @@ namespace DotNetOpenAuth.Configuration {
private const string ReportingElementName = "reporting";
/// <summary>
+ /// The name of the &lt;webResourceUrlProvider&gt; sub-element.
+ /// </summary>
+ private const string WebResourceUrlProviderName = "webResourceUrlProvider";
+
+ /// <summary>
/// Initializes a new instance of the <see cref="DotNetOpenAuthSection"/> class.
/// </summary>
internal DotNetOpenAuthSection() {
@@ -116,5 +121,14 @@ namespace DotNetOpenAuth.Configuration {
this[ReportingElementName] = value;
}
}
+
+ /// <summary>
+ /// Gets or sets the type to use for obtaining URLs that fetch embedded resource streams.
+ /// </summary>
+ [ConfigurationProperty(WebResourceUrlProviderName)]
+ internal TypeConfigurationElement<IEmbeddedResourceRetrieval> EmbeddedResourceRetrievalProvider {
+ get { return (TypeConfigurationElement<IEmbeddedResourceRetrieval>)this[WebResourceUrlProviderName] ?? new TypeConfigurationElement<IEmbeddedResourceRetrieval>(); }
+ set { this[WebResourceUrlProviderName] = value; }
+ }
}
}
diff --git a/src/DotNetOpenAuth/DotNetOpenAuth.csproj b/src/DotNetOpenAuth/DotNetOpenAuth.csproj
index c9900ea..15aa698 100644
--- a/src/DotNetOpenAuth/DotNetOpenAuth.csproj
+++ b/src/DotNetOpenAuth/DotNetOpenAuth.csproj
@@ -301,6 +301,7 @@ http://opensource.org/licenses/ms-pl.html
<Compile Include="Configuration\HostNameOrRegexCollection.cs" />
<Compile Include="Configuration\HostNameElement.cs" />
<Compile Include="Configuration\XriResolverElement.cs" />
+ <Compile Include="IEmbeddedResourceRetrieval.cs" />
<Compile Include="InfoCard\ClaimType.cs" />
<Compile Include="InfoCard\InfoCardImage.cs" />
<Compile Include="InfoCard\InfoCardStrings.Designer.cs">
diff --git a/src/DotNetOpenAuth/IEmbeddedResourceRetrieval.cs b/src/DotNetOpenAuth/IEmbeddedResourceRetrieval.cs
new file mode 100644
index 0000000..b9a6fd0
--- /dev/null
+++ b/src/DotNetOpenAuth/IEmbeddedResourceRetrieval.cs
@@ -0,0 +1,22 @@
+//-----------------------------------------------------------------------
+// <copyright file="IEmbeddedResourceRetrieval.cs" company="Andrew Arnott">
+// Copyright (c) Andrew Arnott. All rights reserved.
+// </copyright>
+//-----------------------------------------------------------------------
+
+namespace DotNetOpenAuth {
+ using System;
+
+ /// <summary>
+ /// An interface that provides URLs from which embedded resources can be obtained.
+ /// </summary>
+ public interface IEmbeddedResourceRetrieval {
+ /// <summary>
+ /// Gets the URL from which the given manifest resource may be downloaded by the user agent.
+ /// </summary>
+ /// <param name="someTypeInResourceAssembly">Some type in the assembly containing the desired resource.</param>
+ /// <param name="manifestResourceName">Manifest name of the desired resource.</param>
+ /// <returns>An absolute URL.</returns>
+ Uri GetWebResourceUrl(Type someTypeInResourceAssembly, string manifestResourceName);
+ }
+}
diff --git a/src/DotNetOpenAuth/Messaging/Channel.cs b/src/DotNetOpenAuth/Messaging/Channel.cs
index 3d56f02..84dbe3c 100644
--- a/src/DotNetOpenAuth/Messaging/Channel.cs
+++ b/src/DotNetOpenAuth/Messaging/Channel.cs
@@ -55,6 +55,14 @@ namespace DotNetOpenAuth.Messaging {
private const int IndirectMessageGetToPostThreshold = 2 * 1024; // 2KB, recommended by OpenID group
/// <summary>
+ /// The HTML that should be returned to the user agent as part of a 301 Redirect.
+ /// </summary>
+ /// <value>A string that should be used as the first argument to String.Format, where the {0} should be replaced with the URL to redirect to.</value>
+ private const string RedirectResponseBodyFormat = @"<html><head><title>Object moved</title></head><body>
+<h2>Object moved to <a href=""{0}"">here</a>.</h2>
+</body></html>";
+
+ /// <summary>
/// A list of binding elements in the order they must be applied to outgoing messages.
/// </summary>
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
@@ -260,10 +268,12 @@ namespace DotNetOpenAuth.Messaging {
this.ProcessOutgoingMessage(message);
Logger.Channel.DebugFormat("Sending message: {0}", message.GetType().Name);
+ OutgoingWebResponse result;
switch (message.Transport) {
case MessageTransport.Direct:
// This is a response to a direct message.
- return this.PrepareDirectResponse(message);
+ result = this.PrepareDirectResponse(message);
+ break;
case MessageTransport.Indirect:
var directedMessage = message as IDirectedProtocolMessage;
ErrorUtilities.VerifyArgumentNamed(
@@ -275,7 +285,8 @@ namespace DotNetOpenAuth.Messaging {
directedMessage.Recipient != null,
"message",
MessagingStrings.DirectedMessageMissingRecipient);
- return this.PrepareIndirectResponse(directedMessage);
+ result = this.PrepareIndirectResponse(directedMessage);
+ break;
default:
throw ErrorUtilities.ThrowArgumentNamed(
"message",
@@ -283,6 +294,13 @@ namespace DotNetOpenAuth.Messaging {
"Transport",
message.Transport);
}
+
+ // Apply caching policy to any response. We want to disable all caching because in auth* protocols,
+ // caching can be utilized in identity spoofing attacks.
+ result.Headers[HttpResponseHeader.CacheControl] = "no-cache, no-store, max-age=0, must-revalidate";
+ result.Headers[HttpResponseHeader.Pragma] = "no-cache";
+
+ return result;
}
/// <summary>
@@ -733,15 +751,18 @@ namespace DotNetOpenAuth.Messaging {
Contract.Requires<ArgumentNullException>(fields != null);
Contract.Ensures(Contract.Result<OutgoingWebResponse>() != null);
+ // As part of this redirect, we include an HTML body in order to get passed some proxy filters
+ // such as WebSense.
WebHeaderCollection headers = new WebHeaderCollection();
UriBuilder builder = new UriBuilder(message.Recipient);
MessagingUtilities.AppendQueryArgs(builder, fields);
headers.Add(HttpResponseHeader.Location, builder.Uri.AbsoluteUri);
+ headers.Add(HttpResponseHeader.ContentType, "text/html; charset=utf-8");
Logger.Http.DebugFormat("Redirecting to {0}", builder.Uri.AbsoluteUri);
OutgoingWebResponse response = new OutgoingWebResponse {
Status = HttpStatusCode.Redirect,
Headers = headers,
- Body = null,
+ Body = string.Format(CultureInfo.InvariantCulture, RedirectResponseBodyFormat, builder.Uri.AbsoluteUri),
OriginalMessage = message
};
diff --git a/src/DotNetOpenAuth/Messaging/MessagingStrings.Designer.cs b/src/DotNetOpenAuth/Messaging/MessagingStrings.Designer.cs
index ca69f5f..e2638c9 100644
--- a/src/DotNetOpenAuth/Messaging/MessagingStrings.Designer.cs
+++ b/src/DotNetOpenAuth/Messaging/MessagingStrings.Designer.cs
@@ -187,6 +187,15 @@ namespace DotNetOpenAuth.Messaging {
}
/// <summary>
+ /// Looks up a localized string similar to Failed to add extra parameter &apos;{0}&apos; with value &apos;{1}&apos;..
+ /// </summary>
+ internal static string ExtraParameterAddFailure {
+ get {
+ return ResourceManager.GetString("ExtraParameterAddFailure", resourceCulture);
+ }
+ }
+
+ /// <summary>
/// Looks up a localized string similar to At least one of GET or POST flags must be present..
/// </summary>
internal static string GetOrPostFlagsRequired {
diff --git a/src/DotNetOpenAuth/Messaging/MessagingStrings.resx b/src/DotNetOpenAuth/Messaging/MessagingStrings.resx
index 102f044..30490c7 100644
--- a/src/DotNetOpenAuth/Messaging/MessagingStrings.resx
+++ b/src/DotNetOpenAuth/Messaging/MessagingStrings.resx
@@ -306,4 +306,7 @@
<data name="MessageTimestampInFuture" xml:space="preserve">
<value>This message has a timestamp of {0}, which is beyond the allowable clock skew for in the future.</value>
</data>
+ <data name="ExtraParameterAddFailure" xml:space="preserve">
+ <value>Failed to add extra parameter '{0}' with value '{1}'.</value>
+ </data>
</root>
diff --git a/src/DotNetOpenAuth/Messaging/MessagingUtilities.cs b/src/DotNetOpenAuth/Messaging/MessagingUtilities.cs
index 7c25f73..85ba9a9 100644
--- a/src/DotNetOpenAuth/Messaging/MessagingUtilities.cs
+++ b/src/DotNetOpenAuth/Messaging/MessagingUtilities.cs
@@ -774,7 +774,11 @@ namespace DotNetOpenAuth.Messaging {
if (extraParameters != null) {
foreach (var pair in extraParameters) {
- messageDictionary.Add(pair);
+ try {
+ messageDictionary.Add(pair);
+ } catch (ArgumentException ex) {
+ throw ErrorUtilities.Wrap(ex, MessagingStrings.ExtraParameterAddFailure, pair.Key, pair.Value);
+ }
}
}
}
diff --git a/src/DotNetOpenAuth/Mvc/OpenIdHelper.cs b/src/DotNetOpenAuth/Mvc/OpenIdHelper.cs
index 193e445..ffde271 100644
--- a/src/DotNetOpenAuth/Mvc/OpenIdHelper.cs
+++ b/src/DotNetOpenAuth/Mvc/OpenIdHelper.cs
@@ -30,16 +30,14 @@ namespace DotNetOpenAuth.Mvc {
/// Emits a series of stylesheet import tags to support the AJAX OpenID Selector.
/// </summary>
/// <param name="html">The <see cref="HtmlHelper"/> on the view.</param>
- /// <param name="page">The page being rendered.</param>
/// <returns>HTML that should be sent directly to the browser.</returns>
- public static string OpenIdSelectorStyles(this HtmlHelper html, Page page) {
+ public static string OpenIdSelectorStyles(this HtmlHelper html) {
Contract.Requires<ArgumentNullException>(html != null);
- Contract.Requires<ArgumentNullException>(page != null);
Contract.Ensures(Contract.Result<string>() != null);
StringWriter result = new StringWriter();
- result.WriteStylesheetLink(page, OpenId.RelyingParty.OpenIdSelector.EmbeddedStylesheetResourceName);
- result.WriteStylesheetLink(page, OpenId.RelyingParty.OpenIdAjaxTextBox.EmbeddedStylesheetResourceName);
+ result.WriteStylesheetLink(OpenId.RelyingParty.OpenIdSelector.EmbeddedStylesheetResourceName);
+ result.WriteStylesheetLink(OpenId.RelyingParty.OpenIdAjaxTextBox.EmbeddedStylesheetResourceName);
return result.ToString();
}
@@ -47,25 +45,22 @@ namespace DotNetOpenAuth.Mvc {
/// Emits a series of script import tags and some inline script to support the AJAX OpenID Selector.
/// </summary>
/// <param name="html">The <see cref="HtmlHelper"/> on the view.</param>
- /// <param name="page">The page being rendered.</param>
/// <returns>HTML that should be sent directly to the browser.</returns>
- public static string OpenIdSelectorScripts(this HtmlHelper html, Page page) {
- return OpenIdSelectorScripts(html, page, null, null);
+ public static string OpenIdSelectorScripts(this HtmlHelper html) {
+ return OpenIdSelectorScripts(html, null, null);
}
/// <summary>
/// Emits a series of script import tags and some inline script to support the AJAX OpenID Selector.
/// </summary>
/// <param name="html">The <see cref="HtmlHelper"/> on the view.</param>
- /// <param name="page">The page being rendered.</param>
/// <param name="selectorOptions">An optional instance of an <see cref="OpenIdSelector"/> control, whose properties have been customized to express how this MVC control should be rendered.</param>
/// <param name="additionalOptions">An optional set of additional script customizations.</param>
/// <returns>
/// HTML that should be sent directly to the browser.
/// </returns>
- public static string OpenIdSelectorScripts(this HtmlHelper html, Page page, OpenIdSelector selectorOptions, OpenIdAjaxOptions additionalOptions) {
+ public static string OpenIdSelectorScripts(this HtmlHelper html, OpenIdSelector selectorOptions, OpenIdAjaxOptions additionalOptions) {
Contract.Requires<ArgumentNullException>(html != null);
- Contract.Requires<ArgumentNullException>(page != null);
Contract.Ensures(Contract.Result<string>() != null);
if (selectorOptions == null) {
@@ -92,10 +87,10 @@ window.openid_trace = {1}; // causes lots of messages";
OpenIdRelyingPartyAjaxControlBase.EmbeddedAjaxJavascriptResource,
OpenId.RelyingParty.OpenIdAjaxTextBox.EmbeddedScriptResourceName,
};
- result.WriteScriptTags(page, scriptResources);
+ result.WriteScriptTags(scriptResources);
if (selectorOptions.DownloadYahooUILibrary) {
- result.WriteScriptTags(new[] { "https://ajax.googleapis.com/ajax/libs/yui/2.8.0r4/build/yuiloader/yuiloader-min.js" });
+ result.WriteScriptTagsUrls(new[] { "https://ajax.googleapis.com/ajax/libs/yui/2.8.0r4/build/yuiloader/yuiloader-min.js" });
}
var blockBuilder = new StringWriter();
@@ -163,10 +158,10 @@ window.openid_trace = {1}; // causes lots of messages";
}});";
blockBuilder.WriteLine(
blockFormat,
- MessagingUtilities.GetSafeJavascriptValue(page.ClientScript.GetWebResourceUrl(typeof(OpenIdRelyingPartyControlBase), OpenIdTextBox.EmbeddedLogoResourceName)),
- MessagingUtilities.GetSafeJavascriptValue(page.ClientScript.GetWebResourceUrl(typeof(OpenIdRelyingPartyControlBase), OpenId.RelyingParty.OpenIdAjaxTextBox.EmbeddedSpinnerResourceName)),
- MessagingUtilities.GetSafeJavascriptValue(page.ClientScript.GetWebResourceUrl(typeof(OpenIdRelyingPartyControlBase), OpenId.RelyingParty.OpenIdAjaxTextBox.EmbeddedLoginSuccessResourceName)),
- MessagingUtilities.GetSafeJavascriptValue(page.ClientScript.GetWebResourceUrl(typeof(OpenIdRelyingPartyControlBase), OpenId.RelyingParty.OpenIdAjaxTextBox.EmbeddedLoginFailureResourceName)),
+ MessagingUtilities.GetSafeJavascriptValue(Util.GetWebResourceUrl(typeof(OpenIdRelyingPartyControlBase), OpenIdTextBox.EmbeddedLogoResourceName)),
+ MessagingUtilities.GetSafeJavascriptValue(Util.GetWebResourceUrl(typeof(OpenIdRelyingPartyControlBase), OpenId.RelyingParty.OpenIdAjaxTextBox.EmbeddedSpinnerResourceName)),
+ MessagingUtilities.GetSafeJavascriptValue(Util.GetWebResourceUrl(typeof(OpenIdRelyingPartyControlBase), OpenId.RelyingParty.OpenIdAjaxTextBox.EmbeddedLoginSuccessResourceName)),
+ MessagingUtilities.GetSafeJavascriptValue(Util.GetWebResourceUrl(typeof(OpenIdRelyingPartyControlBase), OpenId.RelyingParty.OpenIdAjaxTextBox.EmbeddedLoginFailureResourceName)),
selectorOptions.Throttle,
selectorOptions.Timeout.TotalMilliseconds,
MessagingUtilities.GetSafeJavascriptValue(selectorOptions.TextBox.LogOnText),
@@ -183,7 +178,7 @@ window.openid_trace = {1}; // causes lots of messages";
MessagingUtilities.GetSafeJavascriptValue(selectorOptions.TextBox.AuthenticationFailedToolTip));
result.WriteScriptBlock(blockBuilder.ToString());
- result.WriteScriptTags(page, OpenId.RelyingParty.OpenIdSelector.EmbeddedScriptResourceName);
+ result.WriteScriptTags(OpenId.RelyingParty.OpenIdSelector.EmbeddedScriptResourceName);
Reporting.RecordFeatureUse("MVC " + typeof(OpenIdSelector).Name);
return result.ToString();
@@ -193,20 +188,18 @@ window.openid_trace = {1}; // causes lots of messages";
/// Emits the HTML to render an OpenID Provider button as a part of the overall OpenID Selector UI.
/// </summary>
/// <param name="html">The <see cref="HtmlHelper"/> on the view.</param>
- /// <param name="page">The page being rendered.</param>
/// <param name="providerIdentifier">The OP Identifier.</param>
/// <param name="imageUrl">The URL of the image to display on the button.</param>
/// <returns>
/// HTML that should be sent directly to the browser.
/// </returns>
- public static string OpenIdSelectorOPButton(this HtmlHelper html, Page page, Identifier providerIdentifier, string imageUrl) {
+ public static string OpenIdSelectorOPButton(this HtmlHelper html, Identifier providerIdentifier, string imageUrl) {
Contract.Requires<ArgumentNullException>(html != null);
- Contract.Requires<ArgumentNullException>(page != null);
Contract.Requires<ArgumentNullException>(providerIdentifier != null);
Contract.Requires<ArgumentException>(!string.IsNullOrEmpty(imageUrl));
Contract.Ensures(Contract.Result<string>() != null);
- return OpenIdSelectorButton(html, page, providerIdentifier, "OPButton", imageUrl);
+ return OpenIdSelectorButton(html, providerIdentifier, "OPButton", imageUrl);
}
/// <summary>
@@ -214,32 +207,28 @@ window.openid_trace = {1}; // causes lots of messages";
/// allowing the user to enter their own OpenID.
/// </summary>
/// <param name="html">The <see cref="HtmlHelper"/> on the view.</param>
- /// <param name="page">The page being rendered.</param>
/// <param name="imageUrl">The URL of the image to display on the button.</param>
/// <returns>
/// HTML that should be sent directly to the browser.
/// </returns>
- public static string OpenIdSelectorOpenIdButton(this HtmlHelper html, Page page, string imageUrl) {
+ public static string OpenIdSelectorOpenIdButton(this HtmlHelper html, string imageUrl) {
Contract.Requires<ArgumentNullException>(html != null);
- Contract.Requires<ArgumentNullException>(page != null);
Contract.Requires<ArgumentException>(!string.IsNullOrEmpty(imageUrl));
Contract.Ensures(Contract.Result<string>() != null);
- return OpenIdSelectorButton(html, page, "OpenIDButton", "OpenIDButton", imageUrl);
+ return OpenIdSelectorButton(html, "OpenIDButton", "OpenIDButton", imageUrl);
}
/// <summary>
/// Emits the HTML to render the entire OpenID Selector UI.
/// </summary>
/// <param name="html">The <see cref="HtmlHelper"/> on the view.</param>
- /// <param name="page">The page being rendered.</param>
/// <param name="buttons">The buttons to include on the selector.</param>
/// <returns>
/// HTML that should be sent directly to the browser.
/// </returns>
- public static string OpenIdSelector(this HtmlHelper html, Page page, params SelectorButton[] buttons) {
+ public static string OpenIdSelector(this HtmlHelper html, params SelectorButton[] buttons) {
Contract.Requires<ArgumentNullException>(html != null);
- Contract.Requires<ArgumentNullException>(page != null);
Contract.Requires<ArgumentNullException>(buttons != null);
Contract.Ensures(Contract.Result<string>() != null);
@@ -252,13 +241,13 @@ window.openid_trace = {1}; // causes lots of messages";
foreach (SelectorButton button in buttons) {
var op = button as SelectorProviderButton;
if (op != null) {
- h.Write(OpenIdSelectorOPButton(html, page, op.OPIdentifier, op.Image));
+ h.Write(OpenIdSelectorOPButton(html, op.OPIdentifier, op.Image));
continue;
}
var openid = button as SelectorOpenIdButton;
if (openid != null) {
- h.Write(OpenIdSelectorOpenIdButton(html, page, openid.Image));
+ h.Write(OpenIdSelectorOpenIdButton(html, openid.Image));
continue;
}
@@ -294,16 +283,14 @@ window.openid_trace = {1}; // causes lots of messages";
/// Emits the HTML to render a button as a part of the overall OpenID Selector UI.
/// </summary>
/// <param name="html">The <see cref="HtmlHelper"/> on the view.</param>
- /// <param name="page">The page being rendered.</param>
/// <param name="id">The value to assign to the HTML id attribute.</param>
/// <param name="cssClass">The value to assign to the HTML class attribute.</param>
/// <param name="imageUrl">The URL of the image to draw on the button.</param>
/// <returns>
/// HTML that should be sent directly to the browser.
/// </returns>
- private static string OpenIdSelectorButton(this HtmlHelper html, Page page, string id, string cssClass, string imageUrl) {
+ private static string OpenIdSelectorButton(this HtmlHelper html, string id, string cssClass, string imageUrl) {
Contract.Requires<ArgumentNullException>(html != null);
- Contract.Requires<ArgumentNullException>(page != null);
Contract.Requires<ArgumentNullException>(id != null);
Contract.Requires<ArgumentException>(!string.IsNullOrEmpty(imageUrl));
Contract.Ensures(Contract.Result<string>() != null);
@@ -327,7 +314,7 @@ window.openid_trace = {1}; // causes lots of messages";
h.RenderBeginTag(HtmlTextWriterTag.Img);
h.RenderEndTag();
- h.AddAttribute(HtmlTextWriterAttribute.Src, page.ClientScript.GetWebResourceUrl(typeof(OpenIdSelector), OpenId.RelyingParty.OpenIdAjaxTextBox.EmbeddedLoginSuccessResourceName));
+ h.AddAttribute(HtmlTextWriterAttribute.Src, Util.GetWebResourceUrl(typeof(OpenIdSelector), OpenId.RelyingParty.OpenIdAjaxTextBox.EmbeddedLoginSuccessResourceName));
h.AddAttribute(HtmlTextWriterAttribute.Class, "loginSuccess");
h.AddAttribute(HtmlTextWriterAttribute.Title, "Authenticated as {0}");
h.RenderBeginTag(HtmlTextWriterTag.Img);
@@ -351,7 +338,7 @@ window.openid_trace = {1}; // causes lots of messages";
/// </summary>
/// <param name="writer">The writer to emit the tags to.</param>
/// <param name="scriptUrls">The locations of the scripts to import.</param>
- private static void WriteScriptTags(this TextWriter writer, IEnumerable<string> scriptUrls) {
+ private static void WriteScriptTagsUrls(this TextWriter writer, IEnumerable<string> scriptUrls) {
Contract.Requires<ArgumentNullException>(writer != null);
Contract.Requires<ArgumentNullException>(scriptUrls != null);
@@ -364,28 +351,24 @@ window.openid_trace = {1}; // causes lots of messages";
/// Writes out script tags that import a script from resources embedded in this assembly.
/// </summary>
/// <param name="writer">The writer to emit the tags to.</param>
- /// <param name="page">The page being rendered.</param>
/// <param name="resourceName">Name of the resource.</param>
- private static void WriteScriptTags(this TextWriter writer, Page page, string resourceName) {
+ private static void WriteScriptTags(this TextWriter writer, string resourceName) {
Contract.Requires<ArgumentNullException>(writer != null);
- Contract.Requires<ArgumentNullException>(page != null);
Contract.Requires<ArgumentException>(!string.IsNullOrEmpty(resourceName));
- WriteScriptTags(writer, page, new[] { resourceName });
+ WriteScriptTags(writer, new[] { resourceName });
}
/// <summary>
/// Writes out script tags that import scripts from resources embedded in this assembly.
/// </summary>
/// <param name="writer">The writer to emit the tags to.</param>
- /// <param name="page">The page being rendered.</param>
/// <param name="resourceNames">The resource names.</param>
- private static void WriteScriptTags(this TextWriter writer, Page page, IEnumerable<string> resourceNames) {
+ private static void WriteScriptTags(this TextWriter writer, IEnumerable<string> resourceNames) {
Contract.Requires<ArgumentNullException>(writer != null);
- Contract.Requires<ArgumentNullException>(page != null);
Contract.Requires<ArgumentNullException>(resourceNames != null);
- writer.WriteScriptTags(resourceNames.Select(r => page.ClientScript.GetWebResourceUrl(typeof(OpenIdRelyingPartyControlBase), r)));
+ writer.WriteScriptTagsUrls(resourceNames.Select(r => Util.GetWebResourceUrl(typeof(OpenIdRelyingPartyControlBase), r)));
}
/// <summary>
@@ -407,14 +390,12 @@ window.openid_trace = {1}; // causes lots of messages";
/// Writes a given CSS link.
/// </summary>
/// <param name="writer">The writer to emit the tags to.</param>
- /// <param name="page">The page being rendered.</param>
/// <param name="resourceName">Name of the resource containing the CSS content.</param>
- private static void WriteStylesheetLink(this TextWriter writer, Page page, string resourceName) {
+ private static void WriteStylesheetLink(this TextWriter writer, string resourceName) {
Contract.Requires<ArgumentNullException>(writer != null);
- Contract.Requires<ArgumentNullException>(page != null);
Contract.Requires<ArgumentException>(!string.IsNullOrEmpty(resourceName));
- WriteStylesheetLink(writer, page.ClientScript.GetWebResourceUrl(typeof(OpenIdRelyingPartyAjaxControlBase), resourceName));
+ WriteStylesheetLinkUrl(writer, Util.GetWebResourceUrl(typeof(OpenIdRelyingPartyAjaxControlBase), resourceName));
}
/// <summary>
@@ -422,7 +403,7 @@ window.openid_trace = {1}; // causes lots of messages";
/// </summary>
/// <param name="writer">The writer to emit the tags to.</param>
/// <param name="stylesheet">The stylesheet to link in.</param>
- private static void WriteStylesheetLink(this TextWriter writer, string stylesheet) {
+ private static void WriteStylesheetLinkUrl(this TextWriter writer, string stylesheet) {
Contract.Requires<ArgumentNullException>(writer != null);
Contract.Requires<ArgumentException>(!string.IsNullOrEmpty(stylesheet));
diff --git a/src/DotNetOpenAuth/OpenId/Extensions/SimpleRegistration/ClaimsRequest.cs b/src/DotNetOpenAuth/OpenId/Extensions/SimpleRegistration/ClaimsRequest.cs
index f775492..cec8042 100644
--- a/src/DotNetOpenAuth/OpenId/Extensions/SimpleRegistration/ClaimsRequest.cs
+++ b/src/DotNetOpenAuth/OpenId/Extensions/SimpleRegistration/ClaimsRequest.cs
@@ -32,14 +32,6 @@ namespace DotNetOpenAuth.OpenId.Extensions.SimpleRegistration {
};
/// <summary>
- /// Additional type URIs that this extension is sometimes known by remote parties.
- /// </summary>
- private static readonly string[] additionalTypeUris = new string[] {
- Constants.sreg_ns10,
- Constants.sreg_ns11other,
- };
-
- /// <summary>
/// The type URI that this particular (deserialized) extension was read in using,
/// allowing a response to alter be crafted using the same type URI.
/// </summary>
@@ -49,7 +41,7 @@ namespace DotNetOpenAuth.OpenId.Extensions.SimpleRegistration {
/// Initializes a new instance of the <see cref="ClaimsRequest"/> class.
/// </summary>
public ClaimsRequest()
- : base(new Version(1, 0), Constants.sreg_ns, additionalTypeUris) {
+ : base(new Version(1, 0), Constants.sreg_ns, Constants.AdditionalTypeUris) {
}
/// <summary>
diff --git a/src/DotNetOpenAuth/OpenId/Extensions/SimpleRegistration/ClaimsResponse.cs b/src/DotNetOpenAuth/OpenId/Extensions/SimpleRegistration/ClaimsResponse.cs
index 7db6d45..d4df028 100644
--- a/src/DotNetOpenAuth/OpenId/Extensions/SimpleRegistration/ClaimsResponse.cs
+++ b/src/DotNetOpenAuth/OpenId/Extensions/SimpleRegistration/ClaimsResponse.cs
@@ -27,7 +27,7 @@ namespace DotNetOpenAuth.OpenId.Extensions.SimpleRegistration {
/// The factory method that may be used in deserialization of this message.
/// </summary>
internal static readonly StandardOpenIdExtensionFactory.CreateDelegate Factory = (typeUri, data, baseMessage, isProviderRole) => {
- if (typeUri == Constants.sreg_ns && !isProviderRole) {
+ if ((typeUri == Constants.sreg_ns || Array.IndexOf(Constants.AdditionalTypeUris, typeUri) >= 0) && !isProviderRole) {
return new ClaimsResponse(typeUri);
}
@@ -69,7 +69,7 @@ namespace DotNetOpenAuth.OpenId.Extensions.SimpleRegistration {
/// This value should be the same one the relying party used to send the extension request.
/// </param>
internal ClaimsResponse(string typeUriToUse)
- : base(new Version(1, 0), typeUriToUse, EmptyList<string>.Instance) {
+ : base(new Version(1, 0), typeUriToUse, Constants.AdditionalTypeUris) {
Contract.Requires<ArgumentException>(!String.IsNullOrEmpty(typeUriToUse));
}
diff --git a/src/DotNetOpenAuth/OpenId/Extensions/SimpleRegistration/Constants.cs b/src/DotNetOpenAuth/OpenId/Extensions/SimpleRegistration/Constants.cs
index 544ba77..9e00137 100644
--- a/src/DotNetOpenAuth/OpenId/Extensions/SimpleRegistration/Constants.cs
+++ b/src/DotNetOpenAuth/OpenId/Extensions/SimpleRegistration/Constants.cs
@@ -34,5 +34,13 @@ namespace DotNetOpenAuth.OpenId.Extensions.SimpleRegistration {
internal const string Male = "M";
internal const string Female = "F";
}
+
+ /// <summary>
+ /// Additional type URIs that this extension is sometimes known by remote parties.
+ /// </summary>
+ internal static readonly string[] AdditionalTypeUris = new string[] {
+ Constants.sreg_ns10,
+ Constants.sreg_ns11other,
+ };
}
}
diff --git a/src/DotNetOpenAuth/OpenId/Interop/AuthenticationResponseShim.cs b/src/DotNetOpenAuth/OpenId/Interop/AuthenticationResponseShim.cs
index 6319c02..c0354ac 100644
--- a/src/DotNetOpenAuth/OpenId/Interop/AuthenticationResponseShim.cs
+++ b/src/DotNetOpenAuth/OpenId/Interop/AuthenticationResponseShim.cs
@@ -92,6 +92,13 @@ namespace DotNetOpenAuth.OpenId.Interop {
}
/// <summary>
+ /// Gets the provider endpoint that sent the assertion.
+ /// </summary>
+ public string ProviderEndpoint {
+ get { return this.response.Provider != null ? this.response.Provider.Uri.AbsoluteUri : null; }
+ }
+
+ /// <summary>
/// Gets a value indicating whether the authentication attempt succeeded.
/// </summary>
public bool Successful {
diff --git a/src/DotNetOpenAuth/Reporting.cs b/src/DotNetOpenAuth/Reporting.cs
index 612845f..2f93416 100644
--- a/src/DotNetOpenAuth/Reporting.cs
+++ b/src/DotNetOpenAuth/Reporting.cs
@@ -32,6 +32,11 @@ namespace DotNetOpenAuth {
/// </summary>
public static class Reporting {
/// <summary>
+ /// A UTF8 encoder that doesn't emit the preamble. Used for mid-stream writers.
+ /// </summary>
+ private static readonly Encoding Utf8NoPreamble = new UTF8Encoding(false);
+
+ /// <summary>
/// A value indicating whether reporting is desirable or not. Must be logical-AND'd with !<see cref="broken"/>.
/// </summary>
private static bool enabled;
@@ -665,7 +670,7 @@ namespace DotNetOpenAuth {
this.memorySet.Add(this.reader.ReadLine());
}
- this.writer = new StreamWriter(this.fileStream, Encoding.UTF8);
+ this.writer = new StreamWriter(this.fileStream, Utf8NoPreamble);
this.lastFlushed = DateTime.Now;
}
@@ -818,7 +823,7 @@ namespace DotNetOpenAuth {
}
}
- this.writer = new StreamWriter(this.fileStream, Encoding.UTF8);
+ this.writer = new StreamWriter(this.fileStream, Utf8NoPreamble);
this.lastFlushed = DateTime.Now;
}
diff --git a/src/DotNetOpenAuth/Strings.Designer.cs b/src/DotNetOpenAuth/Strings.Designer.cs
index 70b9fb2..1461f83 100644
--- a/src/DotNetOpenAuth/Strings.Designer.cs
+++ b/src/DotNetOpenAuth/Strings.Designer.cs
@@ -1,7 +1,7 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
-// Runtime Version:4.0.30104.0
+// Runtime Version:4.0.30319.1
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
@@ -79,6 +79,15 @@ namespace DotNetOpenAuth {
}
/// <summary>
+ /// Looks up a localized string similar to The current IHttpHandler is not one of types: {0}. An embedded resource URL provider must be set in your .config file..
+ /// </summary>
+ internal static string EmbeddedResourceUrlProviderRequired {
+ get {
+ return ResourceManager.GetString("EmbeddedResourceUrlProviderRequired", resourceCulture);
+ }
+ }
+
+ /// <summary>
/// Looks up a localized string similar to No current HttpContext was detected, so an {0} instance must be explicitly provided or specified in the .config file. Call the constructor overload that takes an {0}..
/// </summary>
internal static string StoreRequiredWhenNoHttpContextAvailable {
diff --git a/src/DotNetOpenAuth/Strings.resx b/src/DotNetOpenAuth/Strings.resx
index a7f080d..4b78664 100644
--- a/src/DotNetOpenAuth/Strings.resx
+++ b/src/DotNetOpenAuth/Strings.resx
@@ -126,4 +126,7 @@
<data name="ConfigurationXamlReferenceRequiresHttpContext" xml:space="preserve">
<value>The configuration XAML reference to {0} requires a current HttpContext to resolve.</value>
</data>
-</root>
+ <data name="EmbeddedResourceUrlProviderRequired" xml:space="preserve">
+ <value>The current IHttpHandler is not one of types: {0}. An embedded resource URL provider must be set in your .config file.</value>
+ </data>
+</root> \ No newline at end of file
diff --git a/src/DotNetOpenAuth/Util.cs b/src/DotNetOpenAuth/Util.cs
index 8a18ef8..0317c4d 100644
--- a/src/DotNetOpenAuth/Util.cs
+++ b/src/DotNetOpenAuth/Util.cs
@@ -11,6 +11,10 @@ namespace DotNetOpenAuth {
using System.Net;
using System.Reflection;
using System.Text;
+ using System.Web;
+ using System.Web.UI;
+
+ using DotNetOpenAuth.Configuration;
using DotNetOpenAuth.Messaging;
/// <summary>
@@ -24,6 +28,11 @@ namespace DotNetOpenAuth {
internal const string DefaultNamespace = "DotNetOpenAuth";
/// <summary>
+ /// The web.config file-specified provider of web resource URLs.
+ /// </summary>
+ private static IEmbeddedResourceRetrieval embeddedResourceRetrieval = DotNetOpenAuthSection.Configuration.EmbeddedResourceRetrievalProvider.CreateInstance(null, false);
+
+ /// <summary>
/// Gets a human-readable description of the library name and version, including
/// whether the build is an official or private one.
/// </summary>
@@ -154,6 +163,32 @@ namespace DotNetOpenAuth {
}
/// <summary>
+ /// Gets the web resource URL from a Page or <see cref="IEmbeddedResourceRetrieval"/> object.
+ /// </summary>
+ /// <param name="someTypeInResourceAssembly">Some type in resource assembly.</param>
+ /// <param name="manifestResourceName">Name of the manifest resource.</param>
+ /// <returns>An absolute URL</returns>
+ internal static string GetWebResourceUrl(Type someTypeInResourceAssembly, string manifestResourceName) {
+ Page page;
+ IEmbeddedResourceRetrieval retrieval;
+
+ if (embeddedResourceRetrieval != null) {
+ Uri url = embeddedResourceRetrieval.GetWebResourceUrl(someTypeInResourceAssembly, manifestResourceName);
+ return url != null ? url.AbsoluteUri : null;
+ } else if ((page = HttpContext.Current.CurrentHandler as Page) != null) {
+ return page.ClientScript.GetWebResourceUrl(someTypeInResourceAssembly, manifestResourceName);
+ } else if ((retrieval = HttpContext.Current.CurrentHandler as IEmbeddedResourceRetrieval) != null) {
+ return retrieval.GetWebResourceUrl(someTypeInResourceAssembly, manifestResourceName).AbsoluteUri;
+ } else {
+ throw new InvalidOperationException(
+ string.Format(
+ CultureInfo.CurrentCulture,
+ Strings.EmbeddedResourceUrlProviderRequired,
+ string.Join(", ", new string[] { typeof(Page).FullName, typeof(IEmbeddedResourceRetrieval).FullName })));
+ }
+ }
+
+ /// <summary>
/// Manages an individual deferred ToString call.
/// </summary>
/// <typeparam name="T">The type of object to be serialized as a string.</typeparam>
diff --git a/src/DotNetOpenAuth/Yadis/Yadis.cs b/src/DotNetOpenAuth/Yadis/Yadis.cs
index 8b8c20f..357dd8d 100644
--- a/src/DotNetOpenAuth/Yadis/Yadis.cs
+++ b/src/DotNetOpenAuth/Yadis/Yadis.cs
@@ -151,7 +151,24 @@ namespace DotNetOpenAuth.Yadis {
options |= DirectWebRequestOptions.RequireSsl;
}
- return requestHandler.GetResponse(request, options);
+ try {
+ return requestHandler.GetResponse(request, options);
+ } catch (ProtocolException ex) {
+ var webException = ex.InnerException as WebException;
+ if (webException != null) {
+ var response = webException.Response as HttpWebResponse;
+ if (response != null && response.IsFromCache) {
+ // We don't want to report error responses from the cache, since the server may have fixed
+ // whatever was causing the problem. So try again with cache disabled.
+ Logger.Messaging.Error("An HTTP error response was obtained from the cache. Retrying with cache disabled.", ex);
+ var nonCachingRequest = request.Clone();
+ nonCachingRequest.CachePolicy = new HttpRequestCachePolicy(HttpRequestCacheLevel.Reload);
+ return requestHandler.GetResponse(nonCachingRequest, options);
+ }
+ }
+
+ throw;
+ }
}
/// <summary>
diff --git a/tools/7-Zip.x86/7-zip.chm b/tools/7-Zip.x86/7-zip.chm
new file mode 100644
index 0000000..08e4df2
--- /dev/null
+++ b/tools/7-Zip.x86/7-zip.chm
Binary files differ
diff --git a/tools/7-Zip.x86/7za.exe b/tools/7-Zip.x86/7za.exe
new file mode 100644
index 0000000..7f6bf86
--- /dev/null
+++ b/tools/7-Zip.x86/7za.exe
Binary files differ
diff --git a/tools/7-Zip.x86/license.txt b/tools/7-Zip.x86/license.txt
new file mode 100644
index 0000000..530ff36
--- /dev/null
+++ b/tools/7-Zip.x86/license.txt
@@ -0,0 +1,29 @@
+ 7-Zip Command line version
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~
+ License for use and distribution
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+ 7-Zip Copyright (C) 1999-2010 Igor Pavlov.
+
+ 7za.exe is distributed under the GNU LGPL license
+
+ Notes:
+ You can use 7-Zip on any computer, including a computer in a commercial
+ organization. You don't need to register or pay for 7-Zip.
+
+
+ GNU LGPL information
+ --------------------
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You can receive a copy of the GNU Lesser General Public License from
+ http://www.gnu.org/
diff --git a/tools/7-Zip.x86/readme.txt b/tools/7-Zip.x86/readme.txt
new file mode 100644
index 0000000..9ae4222
--- /dev/null
+++ b/tools/7-Zip.x86/readme.txt
@@ -0,0 +1,41 @@
+7-Zip Command line version 9.20
+-------------------------------
+
+7-Zip is a file archiver with high compression ratio.
+7za.exe is a standalone command line version of 7-Zip.
+
+7-Zip Copyright (C) 1999-2010 Igor Pavlov.
+
+Features of 7za.exe:
+ - High compression ratio in new 7z format
+ - Supported formats:
+ - Packing / unpacking: 7z, xz, ZIP, GZIP, BZIP2 and TAR
+ - Unpacking only: Z, lzma
+ - Highest compression ratio for ZIP and GZIP formats.
+ - Fast compression and decompression
+ - Strong AES-256 encryption in 7z and ZIP formats.
+
+7za.exe is a free software distributed under the GNU LGPL.
+Read license.txt for more information.
+
+Source code of 7za.exe and 7-Zip can be found at
+http://www.7-zip.org/
+
+7za.exe can work in Windows 95/98/ME/NT/2000/2003/2008/XP/Vista/7.
+
+There is also port of 7za.exe for POSIX systems like Unix (Linux, Solaris, OpenBSD,
+FreeBSD, Cygwin, AIX, ...), MacOS X and BeOS:
+
+http://p7zip.sourceforge.net/
+
+
+ This distributive packet contains the following files:
+
+ 7za.exe - 7-Zip standalone command line version.
+ readme.txt - This file.
+ license.txt - License information.
+ 7-zip.chm - User's Manual in HTML Help format.
+
+
+---
+End of document
diff --git a/tools/DotNetOpenAuth.props b/tools/DotNetOpenAuth.props
index b282db5..3e826bc 100644
--- a/tools/DotNetOpenAuth.props
+++ b/tools/DotNetOpenAuth.props
@@ -11,6 +11,9 @@
<BaseIntermediateOutputPath Condition=" '$(BaseIntermediateOutputPath)' == '' ">obj\$(TargetFrameworkVersion)\</BaseIntermediateOutputPath>
<ToolsDir>$(ProjectRoot)tools\</ToolsDir>
<ZipLevel>6</ZipLevel>
+ <Zip7ToolPath>$(ToolsDir)7-Zip.x86\</Zip7ToolPath>
+ <NuGetToolPath>$(ToolsDir)NuGet\</NuGetToolPath>
+ <ZipFormat Condition=" '$(ZipFormat)' == '' ">.7z</ZipFormat>
<ClrVersion Condition=" '$(TargetFrameworkVersion)' == 'v4.0' ">4</ClrVersion>
<ClrVersion Condition=" '$(TargetFrameworkVersion)' != 'v4.0' ">2</ClrVersion>
diff --git a/tools/NuGet/NuGet.exe b/tools/NuGet/NuGet.exe
new file mode 100644
index 0000000..907d24d
--- /dev/null
+++ b/tools/NuGet/NuGet.exe
Binary files differ
diff --git a/tools/drop.proj b/tools/drop.proj
index 4ceb6bd..fa088cb 100644
--- a/tools/drop.proj
+++ b/tools/drop.proj
@@ -150,14 +150,19 @@
<Target Name="Build" DependsOnTargets="Layout" Returns="@(RedistributableFiles)">
<PropertyGroup>
- <DropZip>$(DropDirectoryNoSlash).zip</DropZip>
+ <DropZip>$(DropDirectoryNoSlash)$(ZipFormat)</DropZip>
</PropertyGroup>
<ItemGroup>
<RedistributableFiles Include="$(DropZip)">
<Package>DotNetOpenAuth</Package>
</RedistributableFiles>
</ItemGroup>
- <Zip Files="@(AllDropTargets)" ZipFileName="$(DropZip)" WorkingDirectory="$(DropsRoot)" ZipLevel="$(ZipLevel)" />
+ <Delete Files="$(DropZip)" />
+ <AddFilesTo7Zip
+ Files="@(AllDropTargets)"
+ ZipFileName="$(DropZip)"
+ WorkingDirectory="$(DropsRoot)"
+ ToolPath="$(Zip7ToolPath)" />
</Target>
<Import Project="$(ProjectRoot)tools\DotNetOpenAuth.automated.targets"/>