summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndrew Arnott <andrewarnott@gmail.com>2010-02-20 13:55:13 -0800
committerAndrew Arnott <andrewarnott@gmail.com>2010-02-20 13:55:13 -0800
commit5e219c5f01391d2d47b108d68c945fa9dcf7d9bc (patch)
tree3a2b38566e42ad77f720f41e773fdee64c04c109
parent5e1a57ba973e31fa11875fc07fb317b5e2c582b7 (diff)
parentf1718afbd134c9b4a5db2dfe3c3ec1f804312123 (diff)
downloadDotNetOpenAuth-5e219c5f01391d2d47b108d68c945fa9dcf7d9bc.zip
DotNetOpenAuth-5e219c5f01391d2d47b108d68c945fa9dcf7d9bc.tar.gz
DotNetOpenAuth-5e219c5f01391d2d47b108d68c945fa9dcf7d9bc.tar.bz2
Merge branch 'master' into oauthWRAP
Conflicts: src/DotNetOpenAuth/DotNetOpenAuth.csproj
-rw-r--r--build.proj590
-rw-r--r--doc/doc.proj65
-rw-r--r--lib/DotNetOpenAuth.BuildTasks.dllbin67072 -> 91648 bytes
-rw-r--r--lib/DotNetOpenAuth.BuildTasks.pdbbin167424 -> 196096 bytes
-rw-r--r--lib/Moq.pdbbin298496 -> 0 bytes
-rw-r--r--projecttemplates/MvcRelyingParty.vsixmanifest27
-rw-r--r--projecttemplates/MvcRelyingParty/Web.config1
-rw-r--r--projecttemplates/RelyingPartyLogic/CreateDatabase.sql4
-rw-r--r--projecttemplates/RelyingPartyLogic/OAuthAuthorizationManager.cs50
-rw-r--r--projecttemplates/RelyingPartyLogic/RelyingPartyLogic.csproj6
-rw-r--r--projecttemplates/WebFormsRelyingParty.vsixmanifest27
-rw-r--r--projecttemplates/WebFormsRelyingParty/Web.config1
-rw-r--r--projecttemplates/projecttemplates.proj256
-rw-r--r--projecttemplates/projecttemplates.props8
-rw-r--r--samples/InfoCardRelyingParty/web.config1
-rw-r--r--samples/OAuthConsumer/Web.config1
-rw-r--r--samples/OAuthServiceProvider/App_Code/OAuthAuthorizationManager.cs52
-rw-r--r--samples/OAuthServiceProvider/Web.config1
-rw-r--r--samples/OpenIdOfflineProvider/OpenIdOfflineProvider.csproj2
-rw-r--r--samples/OpenIdProviderMvc/Web.config1
-rw-r--r--samples/OpenIdProviderWebForms/Web.config1
-rw-r--r--samples/OpenIdRelyingPartyMvc/Web.config1
-rw-r--r--samples/OpenIdRelyingPartyWebForms/Web.config6
-rw-r--r--samples/OpenIdRelyingPartyWebForms/loginProgrammatic.aspx1
-rw-r--r--samples/OpenIdRelyingPartyWebForms/loginProgrammatic.aspx.designer.cs11
-rw-r--r--samples/OpenIdRelyingPartyWebFormsVB/Web.config6
-rw-r--r--samples/OpenIdWebRingSsoProvider/Web.config1
-rw-r--r--samples/OpenIdWebRingSsoRelyingParty/Web.config1
-rw-r--r--samples/Samples.proj (renamed from tools/Publish.targets)96
-rw-r--r--samples/tools.proj52
-rw-r--r--src/DotNetOpenAuth.BuildTasks/AddProjectItems.cs7
-rw-r--r--src/DotNetOpenAuth.BuildTasks/ChangeProjectReferenceToAssemblyReference.cs56
-rw-r--r--src/DotNetOpenAuth.BuildTasks/CopyWithTokenSubstitution.cs12
-rw-r--r--src/DotNetOpenAuth.BuildTasks/DotNetOpenAuth.BuildTasks.csproj2
-rw-r--r--src/DotNetOpenAuth.BuildTasks/DotNetOpenAuth.BuildTasks.sln9
-rw-r--r--src/DotNetOpenAuth.BuildTasks/FixupReferenceHintPaths.cs8
-rw-r--r--src/DotNetOpenAuth.BuildTasks/MergeProjectWithVSTemplate.cs108
-rw-r--r--src/DotNetOpenAuth.BuildTasks/PathSegment.cs321
-rw-r--r--src/DotNetOpenAuth.BuildTasks/Purge.cs9
-rw-r--r--src/DotNetOpenAuth.BuildTasks/Utilities.cs31
-rw-r--r--src/DotNetOpenAuth.Test/DotNetOpenAuth.Test.csproj3
-rw-r--r--src/DotNetOpenAuth.Test/Messaging/MessagingUtilitiesTests.cs1
-rw-r--r--src/DotNetOpenAuth.Test/Messaging/OutgoingWebResponseTests.cs4
-rw-r--r--src/DotNetOpenAuth.Test/OpenId/RelyingParty/PositiveAuthenticationResponseSnapshotTests.cs39
-rw-r--r--src/DotNetOpenAuth/Configuration/DotNetOpenAuth.xsd8
-rw-r--r--src/DotNetOpenAuth/Configuration/DotNetOpenAuthSection.cs45
-rw-r--r--src/DotNetOpenAuth/DotNetOpenAuth.csproj28
-rw-r--r--src/DotNetOpenAuth/Messaging/Channel.cs16
-rw-r--r--src/DotNetOpenAuth/Messaging/HttpRequestInfo.cs4
-rw-r--r--src/DotNetOpenAuth/Messaging/MessagingUtilities.cs21
-rw-r--r--src/DotNetOpenAuth/Messaging/OutgoingWebResponse.cs17
-rw-r--r--src/DotNetOpenAuth/OAuth/ChannelElements/OAuthChannel.cs10
-rw-r--r--src/DotNetOpenAuth/OAuth/ConsumerBase.cs2
-rw-r--r--src/DotNetOpenAuth/OpenId/Extensions/AttributeExchange/AttributeRequest.cs1
-rw-r--r--src/DotNetOpenAuth/OpenId/Extensions/AttributeExchange/AttributeValues.cs2
-rw-r--r--src/DotNetOpenAuth/OpenId/Extensions/AttributeExchange/FetchRequest.cs6
-rw-r--r--src/DotNetOpenAuth/OpenId/Extensions/AttributeExchange/FetchResponse.cs6
-rw-r--r--src/DotNetOpenAuth/OpenId/Identifier.cs7
-rw-r--r--src/DotNetOpenAuth/OpenId/Provider/ProviderEndpoint.cs41
-rw-r--r--src/DotNetOpenAuth/OpenId/ProviderEndpointDescription.cs1
-rw-r--r--src/DotNetOpenAuth/OpenId/Realm.cs5
-rw-r--r--src/DotNetOpenAuth/OpenId/RelyingParty/OpenIdLogin.cs14
-rw-r--r--src/DotNetOpenAuth/OpenId/RelyingParty/OpenIdRelyingParty.cs5
-rw-r--r--src/DotNetOpenAuth/Reporting.cs102
-rw-r--r--tools/Documentation.targets1
-rw-r--r--tools/DotNetOpenAuth.automated.props13
-rw-r--r--tools/DotNetOpenAuth.automated.targets45
-rw-r--r--tools/DotNetOpenAuth.props15
-rw-r--r--tools/DotNetOpenAuth.targets69
-rw-r--r--tools/drop.proj146
-rw-r--r--vsi/vsi.proj52
-rw-r--r--vsix/DotNetOpenAuthSDK.pkgdef5
-rw-r--r--vsix/extension.vsixmanifest2
-rw-r--r--vsix/vsix.proj131
74 files changed, 1872 insertions, 827 deletions
diff --git a/build.proj b/build.proj
index 11e5e68..139fdc4 100644
--- a/build.proj
+++ b/build.proj
@@ -1,446 +1,49 @@
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <Import Project="$(MSBuildProjectDirectory)\tools\DotNetOpenAuth.props"/>
- <PropertyGroup>
- <AutomatedBuild>true</AutomatedBuild>
- <SolutionPath>$(ProjectRoot)src\$(ProductName).sln</SolutionPath>
- <ILMergeOutputAssemblyDirectory>$(OutputPath)unified\</ILMergeOutputAssemblyDirectory>
- <ILMergeOutputAssembly>$(ILMergeOutputAssemblyDirectory)$(ProductName).dll</ILMergeOutputAssembly>
- <ProjectTemplatesLayoutPath>$(IntermediatePath)projecttemplates\</ProjectTemplatesLayoutPath>
-
- <VS2008ProjectTemplatesDirectory>$(IntermediatePath)VS2008projecttemplates\</VS2008ProjectTemplatesDirectory>
- <ProjectTemplatesVsiDirectory>$(IntermediatePath)vsi\</ProjectTemplatesVsiDirectory>
-
- <VS2010ProjectTemplatesDirectory>$(IntermediatePath)VS2010projecttemplates\</VS2010ProjectTemplatesDirectory>
- <ExtensionVsixLayoutDirectory>$(IntermediatePath)Vsix\</ExtensionVsixLayoutDirectory>
- <ZipLevel>6</ZipLevel>
- </PropertyGroup>
-
- <Import Project="$(ProjectRoot)tools\$(ProductName).Versioning.targets"/>
- <Import Project="$(ProjectRoot)tools\Documentation.targets"/>
- <Import Project="$(ProjectRoot)tools\Publish.targets"/>
+ <Import Project="$(MSBuildProjectDirectory)\tools\DotNetOpenAuth.automated.props"/>
<Import Project="$(ProjectRoot)tools\Translation.targets"/>
- <UsingTask AssemblyFile="$(ProjectRoot)lib\MSBuild.Community.Tasks.dll" TaskName="Zip"/>
- <UsingTask AssemblyFile="$(ProjectRoot)lib\MSBuild.Community.Tasks.dll" TaskName="ILMerge"/>
- <UsingTask AssemblyFile="$(ProjectRoot)lib\MSBuild.Community.Tasks.dll" TaskName="NUnit" />
<ItemGroup>
- <SampleProjects Include="$(ProjectRoot)samples\**\*.csproj;$(ProjectRoot)samples\**\*.vbproj" />
- <SampleSites Include="OAuthConsumer;OAuthServiceProvider;InfoCardRelyingParty" />
- <ProjectTemplates Include="$(ProjectRoot)projecttemplates\**\*.csproj" />
- <ILMergeInputAssemblies Include="$(OutputPath)$(ProductName).dll;
- $(ProjectRoot)lib\Microsoft.Contracts.dll; "/>
- <DelaySignedAssemblies Include="$(ILMergeOutputAssembly);
- $(OutputPath)$(ProductName).dll;
- $(OutputPath)$(ProductName).Contracts.dll;
- $(OutputPath)$(ProductName).Test.dll;
- $(ProjectRoot)samples\OpenIdOfflineProvider\bin\$(Configuration)\OpenIdOfflineProvider.exe" />
- </ItemGroup>
-
- <Target Name="Clean" DependsOnTargets="CleanDocumentation;UnpublishSamples;UnpublishDocumentation">
- <MSBuild Projects="$(SolutionPath)" Targets="Clean" />
- <ItemGroup>
- <DirtyDirectories Include="
+ <ProjectsInDrop Include="
+ samples\tools.proj;
+ tools\drop.proj;
+ " />
+ <ProjectsToPublish Include="
+ samples\samples.proj;
+ doc\doc.proj;
+ " />
+
+ <ProjectsToClean Include="
+ $(SolutionPath);
+ projecttemplates\projecttemplates.proj;
+ vsi\vsi.proj;
+ vsix\vsix.proj;
+ samples\samples.proj;
+ doc\doc.proj;
+ "/>
+
+ <DirectoriesToClean Include="
$(ProjectRoot)bin;
$(ProjectRoot)**\obj;
$(DropsRoot);
$(ProjectRoot)src\PrecompiledWeb;
- $(ProjectTemplatesLayoutPath);
" />
- <DirtyDirectories Include="@(SampleDirectories->'%(FullPath)\bin')" />
- <DirtyDirectories Include="@(SampleDirectories->'%(FullPath)\obj')" />
- <DirtyFiles Include="
- $(ProjectRoot)**\*~;
- $(ProjectRoot)**\*.log*;
- $(ProjectRoot)doc\$(ProductName).chm;
- " />
- </ItemGroup>
- <Delete Files="@(DirtyFiles)" />
- <RemoveDir Directories="@(DirtyDirectories)" />
- </Target>
-
- <Target Name="SkipVerification" Condition="'$(IsElevated)' == 'true'">
- <SignatureVerification SkipVerification="true" AssemblyName="*" PublicKeyToken="$(PublicKeyToken)" />
- </Target>
-
- <Target Name="BuildProduct" DependsOnTargets="SkipVerification">
- <MSBuild Projects="$(ProjectRoot)src\$(ProductName)\$(ProductName).csproj" />
- </Target>
+ <FilesToClean Include="
+ $(ProjectRoot)**\*~;
+ $(ProjectRoot)**\*.log*;
+ $(ProjectRoot)doc\$(ProductName).chm;
+ " />
+ </ItemGroup>
<Target Name="BuildTests" DependsOnTargets="SkipVerification">
- <MSBuild Projects="$(SolutionPath)" Targets="DotNetOpenAuth_Test;DotNetOpenAuth_TestWeb" />
- </Target>
-
- <Target Name="BuildSamples" DependsOnTargets="SkipVerification">
- <MSBuild Projects="@(SampleProjects)" />
- <MSBuild Projects="$(SolutionPath)" Targets="@(SampleSites)" />
+ <MSBuild Projects="$(SolutionPath)" Targets="DotNetOpenAuth_Test;DotNetOpenAuth_TestWeb" BuildInParallel="$(BuildInParallel)" />
</Target>
<Target Name="Build" DependsOnTargets="SkipVerification">
- <MSBuild Projects="$(SolutionPath)" />
+ <MSBuild Projects="$(SolutionPath)" BuildInParallel="$(BuildInParallel)" />
</Target>
<Target Name="Rebuild" DependsOnTargets="SkipVerification">
- <MSBuild Projects="$(SolutionPath)" Targets="Rebuild" />
- </Target>
-
- <Target Name="BuildUnifiedProduct"
- DependsOnTargets="BuildProduct"
- Inputs="@(ILMergeInputAssemblies)"
- Outputs="$(ILMergeOutputAssembly)">
- <MakeDir Directories="$(ILMergeOutputAssemblyDirectory)" />
- <ILMerge ExcludeFile="$(ProjectRoot)ILMergeInternalizeExceptions.txt"
- InputAssemblies="@(ILMergeInputAssemblies)"
- OutputFile="$(ILMergeOutputAssembly)"
- KeyFile="$(PublicKeyFile)"
- DelaySign="true"
- />
- </Target>
-
- <Target Name="ReSignDelaySignedAssemblies">
- <Message Text="Signing delay-signed assemblies using key pair container $(KeyPairContainer)." />
- <ReSignDelaySignedAssemblies
- KeyContainer="$(KeyPairContainer)"
- Assemblies="@(DelaySignedAssemblies)"
- Condition="Exists(%(Identity))" />
- </Target>
-
- <Target Name="ToolsLayout" DependsOnTargets="GetBuildVersion;_SetDropProperties;BuildUnifiedProduct">
- <PropertyGroup>
- <ToolsDirectoryNoSlash>$(DropsRoot)$(ProductName)-Tools-$(BuildVersion)</ToolsDirectoryNoSlash>
- <ToolsDirectory>$(ToolsDirectoryNoSlash)\</ToolsDirectory>
- </PropertyGroup>
-
- <ItemGroup>
- <ToolProjects Include="$(ProjectRoot)Samples\OpenIdOfflineProvider\OpenIdOfflineProvider.csproj" />
- </ItemGroup>
-
- <MSBuild Projects="@(ToolProjects)" />
-
- <ItemGroup>
- <OfflineProvider Include="
- $(OutputPath)**\*.dll;
- $(OutputPath)OpenIdOfflineProvider.exe"
- Exclude="
- $(OutputPath)$(ProductName).*;
- $(ILMergeOutputAssembly);
- "/>
- <OfflineProviderTargets Include="
- @(OfflineProvider->'$(ToolsDirectory)%(RecursiveDir)%(FileName)%(Extension)')"/>
- <OfflineProvider Include="$(ILMergeOutputAssembly)" />
- <OfflineProviderTargets Include="$(ToolsDirectory)$(ProductName).dll" />
-
- <AllToolSources Include="@(OfflineProvider)" />
- <AllToolTargets Include="@(OfflineProviderTargets)" />
- </ItemGroup>
-
- <MakeDir Directories="@(ToolsDirectory)" />
- <Copy SourceFiles="@(AllToolSources)" DestinationFiles="@(AllToolTargets)" SkipUnchangedFiles="true" />
-
- <!-- remove files that shouldn't be in the directory (perhaps from a previous version). -->
- <Purge Directories="$(ToolsDirectory)" IntendedFiles="@(AllToolTargets)" />
- </Target>
-
- <Target Name="Tools" DependsOnTargets="ToolsLayout">
- <PropertyGroup>
- <ToolsZip>$(ToolsDirectoryNoSlash).zip</ToolsZip>
- </PropertyGroup>
-
- <Zip ZipFileName="$(ToolsZip)"
- Files="@(AllToolTargets)"
- WorkingDirectory="$(ToolsDirectory)"
- ZipLevel="$(ZipLevel)" />
- </Target>
-
- <Target Name="BuildProjectTemplates">
- <!-- Deploy the latest SQL script first, so that the class library can embed the latest version. -->
- <MSBuild Projects="$(ProjectRoot)projecttemplates\RelyingPartyDatabase\RelyingPartyDatabase.dbproj" Targets="Build;Deploy" />
-
- <MSBuild Projects="@(ProjectTemplates)" />
- </Target>
-
- <Target Name="ProjectTemplatesLayout" DependsOnTargets="GetBuildVersion;BuildUnifiedProduct;ReSignDelaySignedAssemblies;BuildProjectTemplates">
- <ItemGroup>
- <ProjectTemplatesSource Include="$(ProjectRoot)projecttemplates\**\*"
- Exclude="
- $(ProjectRoot)projecttemplates\**\*.sln.cache;
- $(ProjectRoot)projecttemplates\**\*.suo;
- $(ProjectRoot)projecttemplates\**\*.gitignore;
- $(ProjectRoot)projecttemplates\**\*.log*;
- $(ProjectRoot)projecttemplates\**\*~;
- $(ProjectRoot)projecttemplates\**\Settings.StyleCop;
- $(ProjectRoot)projecttemplates\**\StyleCop.Cache;
- $(ProjectRoot)projecttemplates\**\*.user;
- $(ProjectRoot)projecttemplates\**\obj\**;
- $(ProjectRoot)projecttemplates\**\bin\**;
- $(ProjectRoot)projecttemplates\**\*.ldf;
- $(ProjectRoot)projecttemplates\**\*.mdf;
- "/>
- <_ProjectTemplatesTransformSource Include="@(ProjectTemplatesSource)" Condition="
- '%(Extension)' == '.cs'
- or '%(Extension)' == '.csproj'
- or '%(Extension)' == '.sql'
- or '%(Extension)' == '.config'
- or '%(Extension)' == '.Master'
- or '%(Extension)' == '.aspx'
- or '%(Extension)' == '.ascx'
- or '%(Extension)' == '.asax'
- or '%(Extension)' == '.ashx'
- ">
- <BeforeTokens>%(RecursiveDir)</BeforeTokens>
- <AfterTokens>$safeprojectname$</AfterTokens>
- <!-- Projects can get changed after the transform+copy operation, so don't skip copying them. -->
- <SkipUnchangedFiles Condition="'%(Extension)' != '.csproj'">true</SkipUnchangedFiles>
- <SkipUnchangedFiles Condition="'%(Extension)' == '.csproj'">false</SkipUnchangedFiles>
- </_ProjectTemplatesTransformSource>
- <ProjectTemplatesSource Remove="@(_ProjectTemplatesTransformSource)" />
-
- <ProjectTemplatesLayout Include="@(ProjectTemplatesSource->'$(ProjectTemplatesLayoutPath)%(RecursiveDir)%(FileName)%(Extension)')"/>
- <ProjectTemplatesTransformLayout Include="@(_ProjectTemplatesTransformSource->'$(ProjectTemplatesLayoutPath)%(RecursiveDir)%(FileName)%(Extension)')"/>
-
- <!-- Include the template icon -->
- <ProjectTemplatesSource Include="$(ProjectRoot)doc\logo\favicon.ico" />
- <ProjectTemplatesLayout Include="$(ProjectTemplatesLayoutPath)__TemplateIcon.ico" />
-
- <!-- Add external libraries -->
- <!-- Include the unified, signed version of the library -->
- <ProjectTemplateLibraries Include="$(ILMergeOutputAssembly)" />
- <ProjectTemplateLibraries Include="$(ILMergeOutputAssemblyDirectory)$(ProductName).pdb" />
- <ProjectTemplateLibraries Include="$(OutputPath)$(ProductName).xml" />
- <ProjectTemplateLibraries Include="$(OutputPath)$(ProductName).Contracts.dll" />
- <!-- ... and log4net -->
- <ProjectTemplateLibraries Include="$(ProjectRoot)lib\log4net.dll" />
- <ProjectTemplateLibraries Include="$(ProjectRoot)lib\log4net.xml" />
- <ProjectTemplateLibrariesTargets Include="@(ProjectTemplateLibraries->'$(ProjectTemplatesLayoutPath)RelyingPartyLogic\lib\%(FileName)%(Extension)')" />
-
- <ProjectTemplatesSource Include="@(ProjectTemplateLibraries)" />
- <ProjectTemplatesLayout Include="@(ProjectTemplateLibrariesTargets)" />
- <FixupReferenceAssemblies Include="@(ProjectTemplateLibrariesTargets)" Condition="'%(Extension)' == '.dll'" />
-
- <InjectedLibraryItems Include="@(ProjectTemplateLibrariesTargets->'lib\%(FileName)%(Extension)')" />
- <VSProjectTemplates Include="@(ProjectTemplatesLayout)" Condition="'%(Extension)' == '.vstemplate'" />
- </ItemGroup>
-
- <Trim Inputs="@(_ProjectTemplatesTransformSource)" MetadataName="BeforeTokens" AllAfter="\">
- <Output TaskParameter="Outputs" ItemName="ProjectTemplatesTransformSource" />
- </Trim>
- <!--<MSBuild Projects="@(ProjectTemplates)" />-->
- <Copy SourceFiles="@(ProjectTemplatesSource)" DestinationFiles="@(ProjectTemplatesLayout)" SkipUnchangedFiles="true" />
- <CopyWithTokenSubstitution SourceFiles="@(ProjectTemplatesTransformSource)" DestinationFiles="@(ProjectTemplatesTransformLayout)">
- <Output TaskParameter="CopiedFiles" ItemName="CopiedProjectTemplateFiles" />
- </CopyWithTokenSubstitution>
- <Purge Directories="$(ProjectTemplatesLayoutPath)"
- IntendedFiles="
- @(ProjectTemplatesLayout);
- @(ProjectTemplatesTransformLayout);
- " />
- <ChangeProjectReferenceToAssemblyReference
- Projects="@(CopiedProjectTemplateFiles)"
- Condition="'%(Extension)' == '.csproj'"
- ProjectReference="..\..\src\$(ProductName)\$(ProductName).csproj"
- Reference="Lib\$(ProductName).dll" />
- <FixupReferenceHintPaths
- Projects="@(CopiedProjectTemplateFiles)"
- Condition="'%(CopiedProjectTemplateFiles.Extension)' == '.csproj'"
- References="@(FixupReferenceAssemblies)"
- />
- <AddProjectItems
- Projects="@(CopiedProjectTemplateFiles)"
- Condition="'%(CopiedProjectTemplateFiles.FileName)%(CopiedProjectTemplateFiles.Extension)' == 'RelyingPartyLogic.csproj'"
- Items="@(InjectedLibraryItems)"
- />
- <MergeProjectWithVSTemplate
- ProjectItemTypes="@(VsTemplateProjectItemTypes)"
- ReplaceParametersExtensions="@(VsTemplateParameterReplaceExtensions)"
- Templates="@(VSProjectTemplates)"
- />
- </Target>
-
- <Target Name="ProjectTemplates2008" DependsOnTargets="ProjectTemplatesLayout">
- <ItemGroup>
- <ProjectTemplates2008Source Include="$(ProjectTemplatesLayoutPath)**" />
- <ProjectTemplates2008Layout Include="@(ProjectTemplates2008Source->'$(VS2008ProjectTemplatesDirectory)%(RecursiveDir)%(FileName)%(Extension)')" />
- <ProjectTemplates2008Layout>
- <HardLink Condition=" '%(Extension)' != '.csproj' ">true</HardLink>
- </ProjectTemplates2008Layout>
-
- <VS2008ProjectTemplates Include="@(ProjectTemplates2008Layout)" Condition="'%(Extension)' == '.vstemplate'" />
- <TopLevelVS2008ProjectTemplates Include="@(VS2008ProjectTemplates)" Condition="'%(RootDir)%(Directory)' == '$(VS2008ProjectTemplatesDirectory)'" />
- <VS2008ProjectTemplateZipFiles Include="@(TopLevelVS2008ProjectTemplates->'%(RootDir)%(Directory)%(FileName).zip')" />
- </ItemGroup>
-
- <HardLinkCopy SourceFiles="@(ProjectTemplates2008Source)" DestinationFiles="@(ProjectTemplates2008Layout)" />
-
- <DowngradeProjects
- Projects="@(ProjectTemplates2008Layout)"
- Condition="'%(Extension)' == '.csproj'"
- DowngradeMvc2ToMvc1="true"
- />
-
- <Purge Directories="$(VS2008ProjectTemplatesDirectory)" IntendedFiles="@(ProjectTemplates2008Layout)" />
-
- <DiscoverProjectTemplates TopLevelTemplates="@(TopLevelVS2008ProjectTemplates)">
- <Output TaskParameter="ProjectTemplates" ItemName="SubVS2008Templates" />
- <Output TaskParameter="ProjectTemplateContents" ItemName="VS2008TemplateItemContents" />
- </DiscoverProjectTemplates>
-
- <ItemGroup>
- <!-- Include in each template .zip file the top-level .vstemplate file itself. -->
- <VS2008ProjectTemplateContents Include="@(TopLevelVS2008ProjectTemplates)">
- <ZipFile>$(ProjectTemplatesVsiDirectory)%(FileName).zip</ZipFile>
- <WorkingDirectory>$(VS2008ProjectTemplatesDirectory)</WorkingDirectory>
- </VS2008ProjectTemplateContents>
-
- <!-- Now throw in all the files in each of the project-level template's directories and their children. -->
- <VS2008ProjectTemplateContents Include="@(VS2008TemplateItemContents)">
- <ZipFile>$(ProjectTemplatesVsiDirectory)%(VS2008TemplateItemContents.TopLevelTemplateFileName).zip</ZipFile>
- <WorkingDirectory>$(VS2008ProjectTemplatesDirectory)</WorkingDirectory>
- </VS2008ProjectTemplateContents>
-
- <!-- Include the template icon for each .zip file. -->
- <VS2008ProjectTemplateContents Include="@(TopLevelVS2008ProjectTemplates->'$(VS2008ProjectTemplatesDirectory)__TemplateIcon.ico')">
- <ZipFile>$(ProjectTemplatesVsiDirectory)%(TopLevelVS2008ProjectTemplates.FileName).zip</ZipFile>
- <WorkingDirectory>$(VS2008ProjectTemplatesDirectory)</WorkingDirectory>
- </VS2008ProjectTemplateContents>
- </ItemGroup>
-
- <Zip
- Files="@(VS2008ProjectTemplateContents)"
- ZipFileName="%(VS2008ProjectTemplateContents.ZipFile)"
- WorkingDirectory="%(VS2008ProjectTemplateContents.WorkingDirectory)"
- ZipLevel="$(ZipLevel)"
- />
- </Target>
-
- <Target Name="ProjectTemplates2010" DependsOnTargets="ProjectTemplatesLayout">
- <PropertyGroup>
- <ProjectTemplateSubdirectory>$(ExtensionVsixLayoutDirectory)PT\CSharp\Web\</ProjectTemplateSubdirectory>
- </PropertyGroup>
- <ItemGroup>
- <ProjectTemplates2010Source Include="$(ProjectTemplatesLayoutPath)**" />
- <ProjectTemplates2010Layout Include="@(ProjectTemplates2010Source->'$(VS2010ProjectTemplatesDirectory)%(RecursiveDir)%(FileName)%(Extension)')" />
- <ProjectTemplates2010Layout>
- <HardLink Condition=" '%(Extension)' != '.csproj' ">true</HardLink>
- </ProjectTemplates2010Layout>
-
- <VS2010ProjectTemplates Include="@(ProjectTemplates2010Layout)" Condition="'%(Extension)' == '.vstemplate'" />
- <TopLevelVS2010ProjectTemplates Include="@(VS2010ProjectTemplates)" Condition="'%(RootDir)%(Directory)' == '$(VS2010ProjectTemplatesDirectory)'" />
- <VS2010ProjectTemplateZipFiles Include="@(TopLevelVS2010ProjectTemplates->'%(RootDir)%(Directory)%(FileName).zip')" />
- </ItemGroup>
-
- <HardLinkCopy SourceFiles="@(ProjectTemplates2010Source)" DestinationFiles="@(ProjectTemplates2010Layout)" />
-
- <Purge Directories="$(VS2010ProjectTemplatesDirectory)" IntendedFiles="@(ProjectTemplates2010Layout)" />
-
- <DiscoverProjectTemplates TopLevelTemplates="@(TopLevelVS2010ProjectTemplates)">
- <Output TaskParameter="ProjectTemplates" ItemName="SubVS2010Templates" />
- <Output TaskParameter="ProjectTemplateContents" ItemName="VS2010TemplateItemContents" />
- </DiscoverProjectTemplates>
-
- <ItemGroup>
- <!-- Include in each template .zip file the top-level .vstemplate file itself. -->
- <VS2010ProjectTemplateContents Include="@(TopLevelVS2010ProjectTemplates)">
- <ZipFile>$(ProjectTemplateSubdirectory)%(FileName).zip</ZipFile>
- <WorkingDirectory>$(VS2010ProjectTemplatesDirectory)</WorkingDirectory>
- </VS2010ProjectTemplateContents>
-
- <!-- Now throw in all the files in each of the project-level template's directories and their children. -->
- <VS2010ProjectTemplateContents Include="@(VS2010TemplateItemContents)">
- <ZipFile>$(ProjectTemplateSubdirectory)%(VS2010TemplateItemContents.TopLevelTemplateFileName).zip</ZipFile>
- <WorkingDirectory>$(VS2010ProjectTemplatesDirectory)</WorkingDirectory>
- </VS2010ProjectTemplateContents>
-
- <!-- Include the template icon for each .zip file. -->
- <VS2010ProjectTemplateContents Include="@(TopLevelVS2010ProjectTemplates->'$(VS2010ProjectTemplatesDirectory)__TemplateIcon.ico')">
- <ZipFile>$(ProjectTemplateSubdirectory)%(TopLevelVS2010ProjectTemplates.FileName).zip</ZipFile>
- <WorkingDirectory>$(VS2010ProjectTemplatesDirectory)</WorkingDirectory>
- </VS2010ProjectTemplateContents>
-
- <ExtensionVsixContents Include="%(VS2010ProjectTemplateContents.ZipFile)" />
- </ItemGroup>
-
- <Zip
- Files="@(VS2010ProjectTemplateContents)"
- ZipFileName="%(VS2010ProjectTemplateContents.ZipFile)"
- WorkingDirectory="%(VS2010ProjectTemplateContents.WorkingDirectory)"
- ZipLevel="$(ZipLevel)"
- />
- </Target>
-
- <Target Name="vsi" DependsOnTargets="ProjectTemplates2008;_SetDropProperties">
- <PropertyGroup>
- <ProjectTemplatesVsi>$(DropDirectoryNoSlash).vsi</ProjectTemplatesVsi>
- </PropertyGroup>
- <ItemGroup>
- <VsiTransformSource Include="$(ProjectRoot)vsi\*.vscontent">
- <BeforeTokens>$version$</BeforeTokens>
- <AfterTokens>$(BuildVersion)</AfterTokens>
- <SkipUnchangedFiles>false</SkipUnchangedFiles>
- </VsiTransformSource>
- <VsiTransformLayout Include="@(VsiTransformSource->'$(ProjectTemplatesVsiDirectory)%(RecursiveDir)%(FileName)%(Extension)')" />
-
- <ProjectTemplateVsiContents Include="
- $(ProjectTemplatesVsiDirectory)*.zip;
- @(VsiTransformLayout);
- " />
- </ItemGroup>
-
- <CopyWithTokenSubstitution SourceFiles="@(VsiTransformSource)" DestinationFiles="@(VsiTransformLayout)" />
-
- <Zip
- Files="@(ProjectTemplateVsiContents)"
- ZipFileName="$(ProjectTemplatesVsi)"
- WorkingDirectory="$(ProjectTemplatesVsiDirectory)"
- ZipLevel="$(ZipLevel)"
- />
- </Target>
-
- <Target Name="VsixLayout" DependsOnTargets="ProjectTemplates2010">
- <ItemGroup>
- <ProjectTemplates2010TransformSource Include="
- $(ProjectRoot)vsix\extension.vsixmanifest;
- $(ProjectRoot)LICENSE.txt;
- ">
- <BeforeTokens>$version$</BeforeTokens>
- <AfterTokens>$(BuildVersion)</AfterTokens>
- <SkipUnchangedFiles>false</SkipUnchangedFiles>
- </ProjectTemplates2010TransformSource>
- <ProjectTemplates2010TransformLayout Include="@(ProjectTemplates2010TransformSource->'$(ExtensionVsixLayoutDirectory)%(RecursiveDir)%(FileName)%(Extension)')" />
-
- <ExtensionVsixSources Include="
- $(ProjectRoot)vsix\*;
- " Exclude="
- $(ProjectRoot)vsix\extension.vsixmanifest;
- ">
- <SkipUnchangedFiles>true</SkipUnchangedFiles>
- </ExtensionVsixSources>
-
- <ExtensionVsixTargets Include="@(ExtensionVsixSources->'$(ExtensionVsixLayoutDirectory)%(FileName)%(Extension)')" />
-
- <ExtensionVsixContents Include="
- @(ExtensionVsixTargets);
- @(ProjectTemplates2010TransformLayout);
- "/>
- </ItemGroup>
-
- <Copy SourceFiles="@(ExtensionVsixSources)" DestinationFiles="@(ExtensionVsixTargets)" SkipUnchangedFiles="true" />
- <CopyWithTokenSubstitution SourceFiles="@(ProjectTemplates2010TransformSource)" DestinationFiles="@(ProjectTemplates2010TransformLayout)" />
-
- <Purge Directories="$(ExtensionVsixLayoutDirectory)" IntendedFiles="@(ExtensionVsixContents)" />
- </Target>
-
- <Target Name="vsix" DependsOnTargets="VsixLayout;_SetDropProperties">
- <PropertyGroup>
- <ExtensionVsix>$(DropDirectoryNoSlash).vsix</ExtensionVsix>
- </PropertyGroup>
- <Zip
- Files="@(ExtensionVsixContents)"
- ZipFileName="$(ExtensionVsix)"
- WorkingDirectory="$(ExtensionVsixLayoutDirectory)"
- ZipLevel="$(ZipLevel)"
- />
- </Target>
-
- <Target Name="Documentation" DependsOnTargets="BuildProduct;Chm" Condition="'$(NoDocumentation)' != 'true'">
+ <MSBuild Projects="$(SolutionPath)" Targets="Rebuild" BuildInParallel="$(BuildInParallel)" />
</Target>
<Target Name="Test" DependsOnTargets="BuildTests"
@@ -456,138 +59,13 @@
ExcludeCategory="$(NUnitExcludeCategories)"/>
</Target>
- <Target Name="_SetDropProperties">
- <!-- This target is necessary because PropertyGroups within the same Target as
- where CallTarget is fired do NOT affect those called targets. -->
- <!-- The rest of these are here so that other DependsOn targets have access to these properties. -->
- <PropertyGroup>
- <DropDirectoryNoSlash>$(DropsRoot)$(ProductName)-$(BuildVersion)</DropDirectoryNoSlash>
- <DropDirectory>$(DropDirectoryNoSlash)\</DropDirectory>
- </PropertyGroup>
- </Target>
-
- <Target Name="DropLayout" DependsOnTargets="GetBuildVersion;_SetDropProperties;BuildUnifiedProduct;ReSignDelaySignedAssemblies;BuildSamples;vsi;vsix;Documentation">
- <PropertyGroup>
- <DropBinDirectory>$(DropDirectory)Bin\</DropBinDirectory>
- <DropLibDirectory>$(DropDirectory)Lib\</DropLibDirectory>
- <DropProjectTemplatesDirectory>$(DropDirectory)Project Templates\</DropProjectTemplatesDirectory>
- <DropSamplesDirectory>$(DropDirectory)Samples\</DropSamplesDirectory>
- <DropSpecsDirectory>$(DropDirectory)Specs\</DropSpecsDirectory>
- </PropertyGroup>
- <ItemGroup>
- <DropDirectories Include="
- $(DropDirectory);
- $(DropBinDirectory);
- $(DropLibDirectory);
- $(DropProjectTemplatesDirectory);
- $(DropSamplesDirectory);
- $(DropSpecsDirectory);
- " />
-
- <DropSourceFiles Include="
- $(ProjectRoot)Doc\$(ProductName).chm;
- $(ProjectRoot)Doc\*.htm*;
- $(ProjectRoot)LICENSE.txt;
- $(ProjectRoot)CONTRIB.txt;
- "
- Exclude="$(ProjectRoot)Doc\README.*.html;" />
- <DropBinSourceFiles Include="
- $(ILMergeOutputAssemblyDirectory)$(ProductName).???;
- $(OutputPath)**\$(ProductName).resources.dll;
- $(OutputPath)$(ProductName).xml;
- $(OutputPath)$(ProductName).Contracts.???;
- $(ProjectRoot)Doc\README.Bin.html;
- $(ProjectRoot)src\$(ProductName)\Configuration\$(ProductName).xsd;
- " />
- <DropLibSourceFiles Include="
- $(ProjectRoot)Lib\log4net.*;
- " />
- <DropProjectTemplatesSourceFiles Include="$(ProjectTemplatesVsi)" />
- <DropVsixSourceFiles Include="$(ExtensionVsix)" />
- <DropSamplesSourceFiles Include="$(ProjectRoot)Samples\**" Exclude="
- $(ProjectRoot)**\obj\**;
- $(ProjectRoot)**\*.sln.cache;
- $(ProjectRoot)**\*.suo;
- $(ProjectRoot)**\*.user;
- $(ProjectRoot)**\*.gitignore;
- $(ProjectRoot)**\*.ldf;
- $(ProjectRoot)**\*.log*;
- $(ProjectRoot)**\*~;
- $(ProjectRoot)**\Debug\**;
- $(ProjectRoot)**\Settings.StyleCop;
- $(ProjectRoot)**\StyleCop.Cache;
- $(ProjectRoot)Samples\**\DotNetOpenAuth.???;
- $(ProjectRoot)Samples\**\log4net.???;
- $(ProjectRoot)Samples\**\PresentationCore.dll;
- $(ProjectRoot)Samples\**\System.Printing.dll;
- $(ProjectRoot)Samples\**\*.refresh_;
- " />
- <!-- Some .refresh files are only applicable to drop builds, so we rename them from *.refresh_ -->
- <DropSamplesRefreshSourceFiles Include="$(ProjectRoot)Samples\**\*.refresh_" />
- <DropSpecsSourceFiles Include="$(ProjectRoot)Doc\specs\*.htm*" />
-
- <DropFiles Include="@(DropSourceFiles->'$(DropDirectory)%(RecursiveDir)%(FileName)%(Extension)')"/>
- <DropBinFiles Include="@(DropBinSourceFiles->'$(DropBinDirectory)%(RecursiveDir)%(FileName)%(Extension)')"/>
- <DropLibFiles Include="@(DropLibSourceFiles->'$(DropLibDirectory)%(RecursiveDir)%(FileName)%(Extension)')"/>
- <DropProjectTemplatesFiles Include="@(DropProjectTemplatesSourceFiles->'$(DropProjectTemplatesDirectory)%(FileName)%(Extension)')" />
- <DropVsixFiles Include="@(DropVsixSourceFiles->'$(DropProjectTemplatesDirectory)%(FileName)%(Extension)')" />
- <DropSamplesFiles Include="@(DropSamplesSourceFiles->'$(DropSamplesDirectory)%(RecursiveDir)%(FileName)%(Extension)')"/>
- <DropSamplesRefreshFiles Include="@(DropSamplesRefreshSourceFiles->'$(DropSamplesDirectory)%(RecursiveDir)%(FileName).refresh')"/>
- <DropSamplesToolsProjects Include="$(DropSamplesDirectory)OpenIdOfflineProvider\OpenIdOfflineProvider.csproj" />
- <DropSpecsFiles Include="@(DropSpecsSourceFiles->'$(DropSpecsDirectory)%(RecursiveDir)%(FileName)%(Extension)')"/>
-
- <AllDropSources Include="
- @(DropSourceFiles);
- @(DropBinSourceFiles);
- @(DropLibSourceFiles);
- @(DropProjectTemplatesSourceFiles);
- @(DropVsixSourceFiles);
- @(DropSamplesSourceFiles);
- @(DropSamplesRefreshSourceFiles);
- @(DropDocSourceFiles);
- @(DropSpecsSourceFiles);
- " />
-
- <AllDropTargets Include="
- @(DropFiles);
- @(DropBinFiles);
- @(DropLibFiles);
- @(DropProjectTemplatesFiles);
- @(DropVsixFiles);
- @(DropSamplesFiles);
- @(DropSamplesRefreshFiles);
- @(DropDocFiles);
- @(DropSpecsFiles)
- " />
- </ItemGroup>
-
- <!-- clean up any previous drop with the same name so we don't aggregate files. -->
- <MakeDir Directories="@(DropDirectories)" />
- <Copy SourceFiles="@(AllDropSources)" DestinationFiles="@(AllDropTargets)" SkipUnchangedFiles="true" />
- <Purge Directories="$(DropDirectory)" IntendedFiles="@(AllDropTargets)" />
- <!-- fix up the samples so that they will compile right out of the drop -->
- <ItemGroup>
- <SampleProjectTargets Include="$(DropSamplesDirectory)**\*.*proj" />
- <SampleSolutionTargets Include="$(DropSamplesDirectory)**\*.sln" />
- </ItemGroup>
- <FixupShippingToolSamples Projects="@(DropSamplesToolsProjects)"
- RemoveImportsStartingWith="%24(ProjectRoot)tools\"
- AddReferences="Microsoft.Contracts"/>
- <ChangeProjectReferenceToAssemblyReference Projects="@(SampleProjectTargets)"
- ProjectReference="..\..\src\$(ProductName)\$(ProductName).csproj" Reference="..\..\Bin\$(ProductName).dll" />
- <DowngradeProjects Projects="@(SampleProjectTargets);@(SampleSolutionTargets)" DowngradeMvc2ToMvc1="true" />
+ <Target Name="Nightly">
+ <MSBuild Projects="@(ProjectsInDrop)" Targets="%(ProjectsInDrop.Targets)" BuildInParallel="$(BuildInParallel)" />
</Target>
- <Target Name="Drop" DependsOnTargets="DropLayout">
- <PropertyGroup>
- <DropZip>$(DropDirectoryNoSlash).zip</DropZip>
- </PropertyGroup>
- <Zip Files="@(AllDropTargets)" ZipFileName="$(DropZip)" WorkingDirectory="$(DropsRoot)" ZipLevel="$(ZipLevel)" />
+ <Target Name="Publish">
+ <MSBuild Projects="@(ProjectsToPublish)" Targets="Publish" BuildInParallel="$(BuildInParallel)" />
</Target>
- <!-- Although Nightly includes publishing samples and docs, those targets are conditioned for
- running only when the SampleWebRoot and DocWebRoot properties are set, respectively. -->
- <Target Name="Nightly" DependsOnTargets="Drop;Tools;PublishSamples;PublishDocumentation">
-
- </Target>
+ <Import Project="$(ProjectRoot)tools\DotNetOpenAuth.automated.targets"/>
</Project>
diff --git a/doc/doc.proj b/doc/doc.proj
new file mode 100644
index 0000000..75f3cdc
--- /dev/null
+++ b/doc/doc.proj
@@ -0,0 +1,65 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <!-- Properties that must be set for these targets to function:
+ $(BranchName): The name of the branch being built. Used to determine the web subdirectory for publishing.
+
+ For creating web sites:
+ $(PublishDocsWebSiteName): The name of the web site under which the documentation web applications will be created/deleted.
+
+ For creating or publishing to web sites:
+ $(DocWebRoot): the full physical path to where documentation should be copied to, excluding $(BranchName)
+ -->
+
+ <Import Project="$(MSBuildProjectDirectory)\..\tools\DotNetOpenAuth.automated.props"/>
+
+ <Target Name="Build" DependsOnTargets="BuildProduct;Chm" Condition=" '$(NoDocumentation)' != 'true' " />
+
+ <Target Name="Prepare">
+ <Error Text="The BranchName property must be set." Condition=" '$(BranchName)' == '' " />
+ <Error Text="The DocWebRoot property must be set." Condition=" '$(DocWebRoot)' == '' " />
+ <PropertyGroup>
+ <PublishDocsWebSiteVirtualPath>/$(BranchName)</PublishDocsWebSiteVirtualPath>
+ </PropertyGroup>
+ </Target>
+
+ <Target Name="PrepareForPublish" DependsOnTargets="Prepare;BuildProduct;Html">
+ <ItemGroup>
+ <DocSources Include="$(ProjectRoot)doc\api\**\*" />
+ <DocTargets Include="@(DocSources->'$(DocWebRoot)\$(BranchName)\%(RecursiveDir)%(Filename)%(Extension)')" />
+ </ItemGroup>
+ </Target>
+
+ <Target Name="Publish"
+ DependsOnTargets="PrepareForPublish"
+ Inputs="@(DocSources)"
+ Outputs="@(DocTargets)">
+ <RemoveDir Directories="$(DocWebRoot)\$(BranchName)" />
+ <MakeDir Directories="$(DocWebRoot)\$(BranchName)" />
+ <Copy SourceFiles="@(DocSources)" DestinationFiles="@(DocTargets)" SkipUnchangedFiles="true" />
+ </Target>
+
+ <Target Name="Unpublish"
+ DependsOnTargets="DeleteSiteOnIis"
+ Condition=" '$(DocWebRoot)' != '' ">
+ </Target>
+
+ <Target Name="CreateSiteOnIis" DependsOnTargets="Prepare">
+ <Error Text="The PublishDocsWebSiteName property must be set." Condition=" '$(PublishDocsWebSiteName)' == '' "/>
+ <CreateWebApplication
+ WebSiteName="$(PublishDocsWebSiteName)"
+ PhysicalPaths="$(DocWebRoot)\$(BranchName)"
+ VirtualPaths="$(PublishDocsWebSiteVirtualPath)"
+ />
+ </Target>
+
+ <Target Name="DeleteSiteOnIis" DependsOnTargets="Prepare">
+ <Error Text="The PublishDocsWebSiteName property must be set." Condition=" '$(PublishDocsWebSiteName)' == '' "/>
+ <DeleteWebApplication
+ WebSiteName="$(PublishDocsWebSiteName)"
+ VirtualPaths="$(PublishDocsWebSiteVirtualPath)"
+ />
+ </Target>
+
+ <Import Project="$(ProjectRoot)tools\Documentation.targets"/>
+ <Import Project="$(ProjectRoot)tools\DotNetOpenAuth.automated.targets"/>
+</Project> \ No newline at end of file
diff --git a/lib/DotNetOpenAuth.BuildTasks.dll b/lib/DotNetOpenAuth.BuildTasks.dll
index 8edc333..b3c6244 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 e9ed7e3..676ff46 100644
--- a/lib/DotNetOpenAuth.BuildTasks.pdb
+++ b/lib/DotNetOpenAuth.BuildTasks.pdb
Binary files differ
diff --git a/lib/Moq.pdb b/lib/Moq.pdb
deleted file mode 100644
index 3964e06..0000000
--- a/lib/Moq.pdb
+++ /dev/null
Binary files differ
diff --git a/projecttemplates/MvcRelyingParty.vsixmanifest b/projecttemplates/MvcRelyingParty.vsixmanifest
new file mode 100644
index 0000000..f401277
--- /dev/null
+++ b/projecttemplates/MvcRelyingParty.vsixmanifest
@@ -0,0 +1,27 @@
+<?xml version="1.0"?>
+<Vsix xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" Version="1.0" xmlns="http://schemas.microsoft.com/developer/vsx-schema/2010">
+ <Identifier Id="DotNetOpenAuth.MvcRelyingParty.15E8EC96-BDC3-47E2-8BB1-0483E9D16705">
+ <Name>ASP.NET MVC OpenID web site (C#)</Name>
+ <Author>DotNetOpenAuth</Author>
+ <Version>$version$</Version>
+ <Description>Resources for developing applications that use OpenID, OAuth, and InfoCard.</Description>
+ <Locale>1033</Locale>
+ <License>LICENSE.txt</License>
+ <GettingStartedGuide>http://www.dotnetopenauth.net/ProjectTemplateGettingStarted</GettingStartedGuide>
+ <Icon>VSIXProject_small.png</Icon>
+ <PreviewImage>VSIXProject_large.png</PreviewImage>
+ <InstalledByMsi>false</InstalledByMsi>
+ <SupportedProducts>
+ <VisualStudio Version="10.0">
+ <Edition>VSTS</Edition>
+ <Edition>VSTD</Edition>
+ <Edition>Pro</Edition>
+ </VisualStudio>
+ </SupportedProducts>
+ <SupportedFrameworkRuntimeEdition MinVersion="3.5" MaxVersion="3.5" />
+ </Identifier>
+ <References />
+ <Content>
+ <ProjectTemplate>PT</ProjectTemplate>
+ </Content>
+</Vsix>
diff --git a/projecttemplates/MvcRelyingParty/Web.config b/projecttemplates/MvcRelyingParty/Web.config
index 8bd0dfc..706b0a1 100644
--- a/projecttemplates/MvcRelyingParty/Web.config
+++ b/projecttemplates/MvcRelyingParty/Web.config
@@ -165,6 +165,7 @@
<add assembly="System.Data.Entity, Version=3.5.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089"/>
<add assembly="System.Xml.Linq, Version=3.5.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089"/>
<add assembly="System.Data.Linq, Version=3.5.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089" />
+ <remove assembly="DotNetOpenAuth.Contracts"/>
</assemblies>
</compilation>
diff --git a/projecttemplates/RelyingPartyLogic/CreateDatabase.sql b/projecttemplates/RelyingPartyLogic/CreateDatabase.sql
index dd7a69e..0fa1b43 100644
--- a/projecttemplates/RelyingPartyLogic/CreateDatabase.sql
+++ b/projecttemplates/RelyingPartyLogic/CreateDatabase.sql
@@ -711,6 +711,10 @@ PRINT N'Checking existing data against newly created constraints';
GO
+USE [$(DatabaseName)];
+
+
+GO
ALTER TABLE [dbo].[AuthenticationToken] WITH CHECK CHECK CONSTRAINT [FK_AuthenticationToken_User];
ALTER TABLE [dbo].[IssuedToken] WITH CHECK CHECK CONSTRAINT [FK_IssuedToken_Consumer];
diff --git a/projecttemplates/RelyingPartyLogic/OAuthAuthorizationManager.cs b/projecttemplates/RelyingPartyLogic/OAuthAuthorizationManager.cs
index f57faab..35af472 100644
--- a/projecttemplates/RelyingPartyLogic/OAuthAuthorizationManager.cs
+++ b/projecttemplates/RelyingPartyLogic/OAuthAuthorizationManager.cs
@@ -31,34 +31,38 @@ namespace RelyingPartyLogic {
HttpRequestMessageProperty httpDetails = operationContext.RequestContext.RequestMessage.Properties[HttpRequestMessageProperty.Name] as HttpRequestMessageProperty;
Uri requestUri = operationContext.RequestContext.RequestMessage.Properties["OriginalHttpRequestUri"] as Uri;
ServiceProvider sp = OAuthServiceProvider.ServiceProvider;
- var auth = sp.ReadProtectedResourceAuthorization(httpDetails, requestUri);
- if (auth != null) {
- var accessToken = Database.DataContext.IssuedTokens.OfType<IssuedAccessToken>().First(token => token.Token == auth.AccessToken);
+ try {
+ var auth = sp.ReadProtectedResourceAuthorization(httpDetails, requestUri);
+ if (auth != null) {
+ var accessToken = Database.DataContext.IssuedTokens.OfType<IssuedAccessToken>().First(token => token.Token == auth.AccessToken);
- var principal = sp.CreatePrincipal(auth);
- var policy = new OAuthPrincipalAuthorizationPolicy(principal);
- var policies = new List<IAuthorizationPolicy> {
- policy,
- };
-
- var securityContext = new ServiceSecurityContext(policies.AsReadOnly());
- if (operationContext.IncomingMessageProperties.Security != null) {
- operationContext.IncomingMessageProperties.Security.ServiceSecurityContext = securityContext;
- } else {
- operationContext.IncomingMessageProperties.Security = new SecurityMessageProperty {
- ServiceSecurityContext = securityContext,
+ var principal = sp.CreatePrincipal(auth);
+ var policy = new OAuthPrincipalAuthorizationPolicy(principal);
+ var policies = new List<IAuthorizationPolicy> {
+ policy,
};
- }
- securityContext.AuthorizationContext.Properties["Identities"] = new List<IIdentity> {
- principal.Identity,
- };
+ var securityContext = new ServiceSecurityContext(policies.AsReadOnly());
+ if (operationContext.IncomingMessageProperties.Security != null) {
+ operationContext.IncomingMessageProperties.Security.ServiceSecurityContext = securityContext;
+ } else {
+ operationContext.IncomingMessageProperties.Security = new SecurityMessageProperty {
+ ServiceSecurityContext = securityContext,
+ };
+ }
+
+ securityContext.AuthorizationContext.Properties["Identities"] = new List<IIdentity> {
+ principal.Identity,
+ };
- // Only allow this method call if the access token scope permits it.
- string[] scopes = accessToken.Scope.Split('|');
- if (scopes.Contains(operationContext.IncomingMessageHeaders.Action)) {
- return true;
+ // Only allow this method call if the access token scope permits it.
+ string[] scopes = accessToken.Scope.Split('|');
+ if (scopes.Contains(operationContext.IncomingMessageHeaders.Action)) {
+ return true;
+ }
}
+ } catch (ProtocolException /*ex*/) {
+ ////Logger.Error("Error processing OAuth messages.", ex);
}
return false;
diff --git a/projecttemplates/RelyingPartyLogic/RelyingPartyLogic.csproj b/projecttemplates/RelyingPartyLogic/RelyingPartyLogic.csproj
index 9f58bfa..07f267d 100644
--- a/projecttemplates/RelyingPartyLogic/RelyingPartyLogic.csproj
+++ b/projecttemplates/RelyingPartyLogic/RelyingPartyLogic.csproj
@@ -143,6 +143,12 @@
<Project>{3191B653-F76D-4C1A-9A5A-347BC3AAAAB7}</Project>
<Name>DotNetOpenAuth</Name>
</ProjectReference>
+ <ProjectReference Include="..\RelyingPartyDatabase\RelyingPartyDatabase.dbproj">
+ <Name>RelyingPartyDatabase</Name>
+ <!-- Deploy the latest SQL script first, so that this project can embed the latest version. -->
+ <Targets>Build;Deploy</Targets>
+ <ReferenceOutputAssembly>false</ReferenceOutputAssembly>
+ </ProjectReference>
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="CreateDatabase.sql" />
diff --git a/projecttemplates/WebFormsRelyingParty.vsixmanifest b/projecttemplates/WebFormsRelyingParty.vsixmanifest
new file mode 100644
index 0000000..75a3646
--- /dev/null
+++ b/projecttemplates/WebFormsRelyingParty.vsixmanifest
@@ -0,0 +1,27 @@
+<?xml version="1.0"?>
+<Vsix xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" Version="1.0" xmlns="http://schemas.microsoft.com/developer/vsx-schema/2010">
+ <Identifier Id="DotNetOpenAuth.WebFormsRelyingParty.FB0AB0B2-B447-4F10-A03E-F488DDAF024A">
+ <Name>ASP.NET OpenID web site (C#)</Name>
+ <Author>DotNetOpenAuth</Author>
+ <Version>$version$</Version>
+ <Description>Resources for developing applications that use OpenID, OAuth, and InfoCard.</Description>
+ <Locale>1033</Locale>
+ <License>LICENSE.txt</License>
+ <GettingStartedGuide>http://www.dotnetopenauth.net/ProjectTemplateGettingStarted</GettingStartedGuide>
+ <Icon>VSIXProject_small.png</Icon>
+ <PreviewImage>VSIXProject_large.png</PreviewImage>
+ <InstalledByMsi>false</InstalledByMsi>
+ <SupportedProducts>
+ <VisualStudio Version="10.0">
+ <Edition>VSTS</Edition>
+ <Edition>VSTD</Edition>
+ <Edition>Pro</Edition>
+ </VisualStudio>
+ </SupportedProducts>
+ <SupportedFrameworkRuntimeEdition MinVersion="3.5" MaxVersion="3.5" />
+ </Identifier>
+ <References />
+ <Content>
+ <ProjectTemplate>PT</ProjectTemplate>
+ </Content>
+</Vsix>
diff --git a/projecttemplates/WebFormsRelyingParty/Web.config b/projecttemplates/WebFormsRelyingParty/Web.config
index 2092ba0..eabe925 100644
--- a/projecttemplates/WebFormsRelyingParty/Web.config
+++ b/projecttemplates/WebFormsRelyingParty/Web.config
@@ -158,6 +158,7 @@
<add assembly="System.Xml.Linq, Version=3.5.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089" />
<add assembly="System.Data.Entity, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
<add assembly="System.Web.Entity, Version=3.5.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089" />
+ <remove assembly="DotNetOpenAuth.Contracts"/>
</assemblies>
</compilation>
<!--
diff --git a/projecttemplates/projecttemplates.proj b/projecttemplates/projecttemplates.proj
new file mode 100644
index 0000000..9df3fa8
--- /dev/null
+++ b/projecttemplates/projecttemplates.proj
@@ -0,0 +1,256 @@
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <Import Project="$(MSBuildProjectDirectory)\..\tools\DotNetOpenAuth.automated.props"/>
+ <Import Project="ProjectTemplates.props"/>
+
+ <PropertyGroup>
+ <ProjectTemplateMaxPath Condition=" '$(ProjectTemplateMaxPath)' == '' ">6</ProjectTemplateMaxPath>
+
+ <LayoutDependsOn>
+ BuildUnifiedProduct;
+ ReSignDelaySignedAssemblies;
+ DeploySql;
+ LayoutProjects;
+ </LayoutDependsOn>
+
+ <!-- We don't need to build the project templates, but to make sure we're not shipping junk,
+ we default to building them as a validation step. -->
+ <LayoutDependsOn Condition=" '$(Validation)' == 'Full' ">
+ Validate;
+ $(LayoutDependsOn);
+ </LayoutDependsOn>
+ </PropertyGroup>
+
+ <ItemGroup>
+ <ProjectTemplates Include="**\*.*proj" Exclude="$(MSBuildThisFile)" />
+ </ItemGroup>
+
+ <Target Name="Validate">
+ <MSBuild Projects="@(ProjectTemplates)" BuildInParallel="$(BuildInParallel)" />
+ </Target>
+
+ <Target Name="DeploySql">
+ <!-- This causes the SQL script that generates the database to be deployed to the RelyingPartyLogic class library. -->
+ <MSBuild Projects="RelyingPartyDatabase\RelyingPartyDatabase.dbproj" Targets="Build;Deploy" BuildInParallel="$(BuildInParallel)" />
+ </Target>
+
+ <Target Name="LayoutProjects">
+ <MSBuild Projects="..\src\$(ProductName)\$(ProductName).csproj" Targets="Sign" BuildInParallel="$(BuildInParallel)">
+ <Output TaskParameter="TargetOutputs" ItemName="SignedProductAssemblies" />
+ </MSBuild>
+ <ItemGroup>
+ <TemplateProjects Include="**\*.csproj" Exclude="$(MSBuildThisFile)">
+ <AfterTokens>$safeprojectname$</AfterTokens>
+ <!-- Projects can get changed after the transform+copy operation, so don't skip copying them. -->
+ <SkipUnchangedFiles>false</SkipUnchangedFiles>
+ </TemplateProjects>
+ <TemplateProjects>
+ <BeforeTokens>%(RecursiveDir)</BeforeTokens>
+ </TemplateProjects>
+ <TemplateProjectsLayout Include="@(TemplateProjects->'$(ProjectTemplatesLayoutPath)%(RecursiveDir)%(FileName)%(Extension)')"/>
+
+ <!-- Add external libraries and their symbols -->
+ <ProjectTemplateLibraries Include="@(SignedProductAssemblies)" />
+ <ProjectTemplateLibraries Include="@(SignedProductAssemblies->'%(SymbolPath)')" />
+ <ProjectTemplateLibraries Include="$(OutputPath)$(ProductName).xml" />
+ <!-- ... and log4net -->
+ <ProjectTemplateLibraries Include="$(ProjectRoot)lib\log4net.dll" />
+ <ProjectTemplateLibraries Include="$(ProjectRoot)lib\log4net.xml" />
+ <ProjectTemplateLibrariesTargets Include="@(ProjectTemplateLibraries->'$(ProjectTemplatesLayoutPath)RelyingPartyLogic\lib\%(CultureDir)%(FileName)%(Extension)')">
+ <ApparentSource>RelyingPartyLogic\lib\%(ProjectTemplateLibraries.CultureDir)%(FileName)%(Extension)</ApparentSource>
+ <ActualSource>%(Identity)</ActualSource>
+ </ProjectTemplateLibrariesTargets>
+ <ProjectTemplateLibrariesSourceExceptions Include="@(ProjectTemplateLibrariesTargets->'%(ApparentSource)')"/>
+
+ <FixupReferenceAssemblies Include="@(ProjectTemplateLibrariesTargets)" Condition="'%(Extension)' == '.dll'" />
+ <InjectedLibraryItems Include="@(ProjectTemplateLibraries->'lib\%(CultureDir)%(FileName)%(Extension)')">
+ <Visible/>
+ <UnsignedAssemblyPath/>
+ <SymbolPath/>
+ <OriginalItemSpec/>
+ <MSBuildSourceProjectFile/>
+ <MSBuildSourceTargetName/>
+ <CultureDir/>
+ </InjectedLibraryItems>
+
+ <VSProjectTemplates Include="**\*.vstemplate" Exclude="*.vstemplate" />
+ <VSProjectTemplatesLayout Include="@(VSProjectTemplates->'$(ProjectTemplatesLayoutPath)%(RecursiveDir)%(FileName)%(Extension)')" />
+ </ItemGroup>
+
+ <Trim Inputs="@(TemplateProjects)" MetadataName="BeforeTokens" AllAfter="\">
+ <Output TaskParameter="Outputs" ItemName="TemplateProjectsTransformSource" />
+ </Trim>
+ <CopyWithTokenSubstitution SourceFiles="@(TemplateProjectsTransformSource)" DestinationFiles="@(TemplateProjectsLayout)">
+ <Output TaskParameter="CopiedFiles" ItemName="CopiedProjectFiles" />
+ </CopyWithTokenSubstitution>
+ <ChangeProjectReferenceToAssemblyReference
+ Projects="@(CopiedProjectFiles)"
+ Condition=" '%(Extension)' == '.csproj' "
+ ProjectReferences="..\..\src\$(ProductName)\$(ProductName).csproj;..\RelyingPartyDatabase\RelyingPartyDatabase.dbproj"
+ References="Lib\$(ProductName).dll;REMOVE" />
+ <FixupReferenceHintPaths
+ Projects="@(CopiedProjectFiles)"
+ References="@(FixupReferenceAssemblies)"
+ />
+ <AddProjectItems
+ Projects="@(CopiedProjectFiles)"
+ Condition="'%(CopiedProjectFiles.FileName)%(CopiedProjectFiles.Extension)' == 'RelyingPartyLogic.csproj'"
+ Items="@(InjectedLibraryItems)"
+ />
+ <MergeProjectWithVSTemplate
+ ProjectItemTypes="@(VsTemplateProjectItemTypes)"
+ ReplaceParametersExtensions="@(VsTemplateParameterReplaceExtensions)"
+ SourceTemplates="@(VSProjectTemplates)"
+ SourceProjects="@(TemplateProjectsLayout)"
+ DestinationTemplates="@(VSProjectTemplatesLayout)"
+ SourcePathExceptions="@(ProjectTemplateLibrariesSourceExceptions)"
+ MaximumRelativePathLength="$(ProjectTemplateMaxPath)"
+ >
+ <Output TaskParameter="ProjectItems" ItemName="TemplateProjectItems"/>
+ </MergeProjectWithVSTemplate>
+ </Target>
+
+ <Target Name="Layout" DependsOnTargets="$(LayoutDependsOn)">
+ <ItemGroup>
+ <TemplateProjectItems Condition=" '%(Transform)' == 'true' ">
+ <BeforeTokens>%(RecursiveDir)</BeforeTokens>
+ <AfterTokens>$safeprojectname$</AfterTokens>
+ </TemplateProjectItems>
+ <TemplateProjectItems>
+ <SkipUnchangedFiles>true</SkipUnchangedFiles>
+ </TemplateProjectItems>
+ <TemplateProjectItemsForTransformSource Include="@(TemplateProjectItems->'%(SourceFullPath)')" />
+ <TemplateProjectItemsForTransformLayout Include="@(TemplateProjectItems->'%(DestinationFullPath)')" />
+ <RootVsTemplateSource Include="*.vstemplate" />
+ <ProjectTemplatesSource Include="@(RootVsTemplateSource)" />
+ <ProjectTemplatesLayout Include="@(RootVsTemplateSource->'$(ProjectTemplatesLayoutPath)%(FileName)%(Extension)')" />
+
+ <!-- Include the template icon -->
+ <ProjectTemplatesSource Include="$(ProjectRoot)doc\logo\favicon.ico" />
+ <ProjectTemplatesLayout Include="$(ProjectTemplatesLayoutPath)__TemplateIcon.ico" />
+
+ <TopLevelVS2010ProjectTemplates Include="@(ProjectTemplatesLayout)" Condition=" '%(Extension)' == '.vstemplate' and '%(RootDir)%(Directory)' == '$(ProjectTemplatesLayoutPath)' " />
+ <VS2010ProjectTemplateZipFiles Include="@(TopLevelVS2010ProjectTemplates->'%(RootDir)%(Directory)%(FileName).zip')" />
+ </ItemGroup>
+
+ <Copy
+ SourceFiles="@(ProjectTemplatesSource)"
+ DestinationFiles="@(ProjectTemplatesLayout)"
+ SkipUnchangedFiles="true" />
+ <CopyWithTokenSubstitution
+ SourceFiles="@(TemplateProjectItemsForTransformSource)"
+ DestinationFiles="@(TemplateProjectItemsForTransformLayout)" />
+
+ <ItemGroup>
+ <ProjectTemplateIntendedFiles Include="
+ @(ProjectTemplatesLayout);
+ @(TemplateProjectItemsForTransformLayout);
+ @(VSProjectTemplatesLayout);
+ @(TemplateProjectsLayout);
+ @(VS2010ProjectTemplateZipFiles);
+ " />
+ <ProjectTemplateIntendedFiles Remove="@(ProjectItemShortPathAdjustments)" />
+ </ItemGroup>
+ <Purge Directories="$(ProjectTemplatesLayoutPath)"
+ IntendedFiles="@(ProjectTemplateIntendedFiles)" />
+ </Target>
+
+ <Target Name="Zip" DependsOnTargets="Layout" Returns="%(VS2010ProjectTemplateContents.ZipFile)">
+ <DiscoverProjectTemplates TopLevelTemplates="@(TopLevelVS2010ProjectTemplates)">
+ <Output TaskParameter="ProjectTemplates" ItemName="SubVS2010Templates" />
+ <Output TaskParameter="ProjectTemplateContents" ItemName="VS2010TemplateItemContents" />
+ </DiscoverProjectTemplates>
+
+ <ItemGroup>
+ <!-- Include in each template .zip file the top-level .vstemplate file itself. -->
+ <VS2010ProjectTemplateContents Include="@(TopLevelVS2010ProjectTemplates)">
+ <ZipFile>$(ProjectTemplatesLayoutPath)%(FileName).zip</ZipFile>
+ <WorkingDirectory>$(ProjectTemplatesLayoutPath)</WorkingDirectory>
+ </VS2010ProjectTemplateContents>
+
+ <!-- Now throw in all the files in each of the project-level template's directories and their children. -->
+ <VS2010ProjectTemplateContents Include="@(VS2010TemplateItemContents)">
+ <ZipFile>$(ProjectTemplatesLayoutPath)%(VS2010TemplateItemContents.TopLevelTemplateFileName).zip</ZipFile>
+ <WorkingDirectory>$(ProjectTemplatesLayoutPath)</WorkingDirectory>
+ </VS2010ProjectTemplateContents>
+
+ <!-- Include the template icon for each .zip file. -->
+ <VS2010ProjectTemplateContents Include="@(TopLevelVS2010ProjectTemplates->'$(ProjectTemplatesLayoutPath)__TemplateIcon.ico')">
+ <ZipFile>$(ProjectTemplatesLayoutPath)%(TopLevelVS2010ProjectTemplates.FileName).zip</ZipFile>
+ <WorkingDirectory>$(ProjectTemplatesLayoutPath)</WorkingDirectory>
+ </VS2010ProjectTemplateContents>
+
+ <ExtensionVsixContents Include="%(VS2010ProjectTemplateContents.ZipFile)" />
+ </ItemGroup>
+
+ <Zip
+ Files="@(VS2010ProjectTemplateContents)"
+ ZipFileName="%(VS2010ProjectTemplateContents.ZipFile)"
+ WorkingDirectory="%(VS2010ProjectTemplateContents.WorkingDirectory)"
+ ZipLevel="$(ZipLevel)"
+ />
+ </Target>
+
+ <Target Name="Layout2008" DependsOnTargets="Layout">
+ <ItemGroup>
+ <ProjectTemplates2008Source Include="$(ProjectTemplatesLayoutPath)**" Exclude="$(ProjectTemplatesLayoutPath)*.zip" />
+ <ProjectTemplates2008Layout Include="@(ProjectTemplates2008Source->'$(ProjectTemplates2008LayoutPath)%(RecursiveDir)%(FileName)%(Extension)')" />
+ <ProjectTemplates2008Layout>
+ <HardLink Condition=" '%(Extension)' != '.csproj' ">true</HardLink>
+ </ProjectTemplates2008Layout>
+
+ <VS2008ProjectTemplates Include="@(ProjectTemplates2008Layout)" Condition="'%(Extension)' == '.vstemplate'" />
+ <TopLevelVS2008ProjectTemplates Include="@(VS2008ProjectTemplates)" Condition="'%(RootDir)%(Directory)' == '$(ProjectTemplates2008LayoutPath)'" />
+ <VS2008ProjectTemplateZipFiles Include="@(TopLevelVS2008ProjectTemplates->'%(RootDir)%(Directory)%(FileName).zip')" />
+ </ItemGroup>
+ <Message Text="VS2008ProjectTemplates: @(VS2008ProjectTemplates)" />
+
+ <HardLinkCopy SourceFiles="@(ProjectTemplates2008Source)" DestinationFiles="@(ProjectTemplates2008Layout)" />
+
+ <DowngradeProjects
+ Projects="@(ProjectTemplates2008Layout)"
+ Condition="'%(Extension)' == '.csproj'"
+ DowngradeMvc2ToMvc1="true"
+ />
+
+ <Purge Directories="$(ProjectTemplates2008LayoutPath)"
+ IntendedFiles="@(ProjectTemplates2008Layout);@(VS2008ProjectTemplateZipFiles)" />
+ </Target>
+
+ <Target Name="Zip2008" DependsOnTargets="Layout2008" Returns="%(VS2008ProjectTemplateContents.ZipFile)">
+ <DiscoverProjectTemplates TopLevelTemplates="@(TopLevelVS2008ProjectTemplates)">
+ <Output TaskParameter="ProjectTemplates" ItemName="SubVS2008Templates" />
+ <Output TaskParameter="ProjectTemplateContents" ItemName="VS2008TemplateItemContents" />
+ </DiscoverProjectTemplates>
+
+ <ItemGroup>
+ <!-- Include in each template .zip file the top-level .vstemplate file itself. -->
+ <VS2008ProjectTemplateContents Include="@(TopLevelVS2008ProjectTemplates)">
+ <ZipFile>$(ProjectTemplates2008LayoutPath)%(FileName).zip</ZipFile>
+ <WorkingDirectory>$(ProjectTemplates2008LayoutPath)</WorkingDirectory>
+ </VS2008ProjectTemplateContents>
+
+ <!-- Now throw in all the files in each of the project-level template's directories and their children. -->
+ <VS2008ProjectTemplateContents Include="@(VS2008TemplateItemContents)">
+ <ZipFile>$(ProjectTemplates2008LayoutPath)%(VS2008TemplateItemContents.TopLevelTemplateFileName).zip</ZipFile>
+ <WorkingDirectory>$(ProjectTemplates2008LayoutPath)</WorkingDirectory>
+ </VS2008ProjectTemplateContents>
+
+ <!-- Include the template icon for each .zip file. -->
+ <VS2008ProjectTemplateContents Include="@(TopLevelVS2008ProjectTemplates->'$(ProjectTemplates2008LayoutPath)__TemplateIcon.ico')">
+ <ZipFile>$(ProjectTemplates2008LayoutPath)%(TopLevelVS2008ProjectTemplates.FileName).zip</ZipFile>
+ <WorkingDirectory>$(ProjectTemplates2008LayoutPath)</WorkingDirectory>
+ </VS2008ProjectTemplateContents>
+ </ItemGroup>
+
+ <Zip
+ Files="@(VS2008ProjectTemplateContents)"
+ ZipFileName="%(VS2008ProjectTemplateContents.ZipFile)"
+ WorkingDirectory="%(VS2008ProjectTemplateContents.WorkingDirectory)"
+ ZipLevel="$(ZipLevel)"
+ />
+ </Target>
+
+ <Target Name="Build" DependsOnTargets="Zip;Zip2008" />
+
+ <Import Project="$(ProjectRoot)tools\DotNetOpenAuth.automated.targets"/>
+</Project> \ No newline at end of file
diff --git a/projecttemplates/projecttemplates.props b/projecttemplates/projecttemplates.props
new file mode 100644
index 0000000..2bdc859
--- /dev/null
+++ b/projecttemplates/projecttemplates.props
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup>
+ <!-- We use GetFullPath here because IntermediatePath may be a relative directory, and we need to do full path comparisons. -->
+ <ProjectTemplatesLayoutPath>$([System.IO.Path]::GetFullPath('$(IntermediatePath)projecttemplates\'))</ProjectTemplatesLayoutPath>
+ <ProjectTemplates2008LayoutPath>$([System.IO.Path]::GetFullPath('$(IntermediatePath)projecttemplates2008\'))</ProjectTemplates2008LayoutPath>
+ </PropertyGroup>
+</Project> \ No newline at end of file
diff --git a/samples/InfoCardRelyingParty/web.config b/samples/InfoCardRelyingParty/web.config
index d91f9e8..7599561 100644
--- a/samples/InfoCardRelyingParty/web.config
+++ b/samples/InfoCardRelyingParty/web.config
@@ -65,6 +65,7 @@
<add assembly="System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
<add assembly="System.Data.DataSetExtensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089"/>
<add assembly="System.Xml.Linq, Version=3.5.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089"/>
+ <remove assembly="DotNetOpenAuth.Contracts"/>
</assemblies>
</compilation>
<pages>
diff --git a/samples/OAuthConsumer/Web.config b/samples/OAuthConsumer/Web.config
index 9467175..496da95 100644
--- a/samples/OAuthConsumer/Web.config
+++ b/samples/OAuthConsumer/Web.config
@@ -66,6 +66,7 @@
<add assembly="System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
<add assembly="System.Data.DataSetExtensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089"/>
<add assembly="System.Xml.Linq, Version=3.5.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089"/>
+ <remove assembly="DotNetOpenAuth.Contracts"/>
</assemblies>
</compilation>
<!--
diff --git a/samples/OAuthServiceProvider/App_Code/OAuthAuthorizationManager.cs b/samples/OAuthServiceProvider/App_Code/OAuthAuthorizationManager.cs
index 8589932..ee90364 100644
--- a/samples/OAuthServiceProvider/App_Code/OAuthAuthorizationManager.cs
+++ b/samples/OAuthServiceProvider/App_Code/OAuthAuthorizationManager.cs
@@ -24,34 +24,38 @@ public class OAuthAuthorizationManager : ServiceAuthorizationManager {
HttpRequestMessageProperty httpDetails = operationContext.RequestContext.RequestMessage.Properties[HttpRequestMessageProperty.Name] as HttpRequestMessageProperty;
Uri requestUri = operationContext.RequestContext.RequestMessage.Properties["OriginalHttpRequestUri"] as Uri;
ServiceProvider sp = Constants.CreateServiceProvider();
- var auth = sp.ReadProtectedResourceAuthorization(httpDetails, requestUri);
- if (auth != null) {
- var accessToken = Global.DataContext.OAuthTokens.Single(token => token.Token == auth.AccessToken);
-
- var principal = sp.CreatePrincipal(auth);
- var policy = new OAuthPrincipalAuthorizationPolicy(principal);
- var policies = new List<IAuthorizationPolicy> {
- policy,
- };
-
- var securityContext = new ServiceSecurityContext(policies.AsReadOnly());
- if (operationContext.IncomingMessageProperties.Security != null) {
- operationContext.IncomingMessageProperties.Security.ServiceSecurityContext = securityContext;
- } else {
- operationContext.IncomingMessageProperties.Security = new SecurityMessageProperty {
- ServiceSecurityContext = securityContext,
+ try {
+ var auth = sp.ReadProtectedResourceAuthorization(httpDetails, requestUri);
+ if (auth != null) {
+ var accessToken = Global.DataContext.OAuthTokens.Single(token => token.Token == auth.AccessToken);
+
+ var principal = sp.CreatePrincipal(auth);
+ var policy = new OAuthPrincipalAuthorizationPolicy(principal);
+ var policies = new List<IAuthorizationPolicy> {
+ policy,
};
- }
- securityContext.AuthorizationContext.Properties["Identities"] = new List<IIdentity> {
- principal.Identity,
- };
+ var securityContext = new ServiceSecurityContext(policies.AsReadOnly());
+ if (operationContext.IncomingMessageProperties.Security != null) {
+ operationContext.IncomingMessageProperties.Security.ServiceSecurityContext = securityContext;
+ } else {
+ operationContext.IncomingMessageProperties.Security = new SecurityMessageProperty {
+ ServiceSecurityContext = securityContext,
+ };
+ }
+
+ securityContext.AuthorizationContext.Properties["Identities"] = new List<IIdentity> {
+ principal.Identity,
+ };
- // Only allow this method call if the access token scope permits it.
- string[] scopes = accessToken.Scope.Split('|');
- if (scopes.Contains(operationContext.IncomingMessageHeaders.Action)) {
- return true;
+ // Only allow this method call if the access token scope permits it.
+ string[] scopes = accessToken.Scope.Split('|');
+ if (scopes.Contains(operationContext.IncomingMessageHeaders.Action)) {
+ return true;
+ }
}
+ } catch (ProtocolException ex) {
+ Global.Logger.Error("Error processing OAuth messages.", ex);
}
return false;
diff --git a/samples/OAuthServiceProvider/Web.config b/samples/OAuthServiceProvider/Web.config
index c21ebd4..3ea490f 100644
--- a/samples/OAuthServiceProvider/Web.config
+++ b/samples/OAuthServiceProvider/Web.config
@@ -61,6 +61,7 @@
<add assembly="System.Data.DataSetExtensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089"/>
<add assembly="System.Xml.Linq, Version=3.5.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089"/>
<add assembly="System.Data.Linq, Version=3.5.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089"/>
+ <remove assembly="DotNetOpenAuth.Contracts"/>
</assemblies>
</compilation>
<authentication mode="Forms">
diff --git a/samples/OpenIdOfflineProvider/OpenIdOfflineProvider.csproj b/samples/OpenIdOfflineProvider/OpenIdOfflineProvider.csproj
index a2a56ba..564ddae 100644
--- a/samples/OpenIdOfflineProvider/OpenIdOfflineProvider.csproj
+++ b/samples/OpenIdOfflineProvider/OpenIdOfflineProvider.csproj
@@ -19,7 +19,7 @@
<WarningLevel>4</WarningLevel>
<UICulture>en-US</UICulture>
<TargetFrameworkVersion Condition=" '$(TargetFrameworkVersion)' == '' ">v3.5</TargetFrameworkVersion>
- <OutputPath>bin\$(TargetFrameworkVersion)\$(Configuration)\</OutputPath>
+ <OutputPath Condition=" '$(OutputPath)' == '' ">bin\$(TargetFrameworkVersion)\$(Configuration)\</OutputPath>
<ApplicationIcon>openid.ico</ApplicationIcon>
<FileUpgradeFlags>
</FileUpgradeFlags>
diff --git a/samples/OpenIdProviderMvc/Web.config b/samples/OpenIdProviderMvc/Web.config
index fcca524..8f145b0 100644
--- a/samples/OpenIdProviderMvc/Web.config
+++ b/samples/OpenIdProviderMvc/Web.config
@@ -81,6 +81,7 @@
<add assembly="System.Data.DataSetExtensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089"/>
<add assembly="System.Xml.Linq, Version=3.5.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089"/>
<add assembly="System.Data.Linq, Version=3.5.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089"/>
+ <remove assembly="DotNetOpenAuth.Contracts"/>
</assemblies>
</compilation>
<!--
diff --git a/samples/OpenIdProviderWebForms/Web.config b/samples/OpenIdProviderWebForms/Web.config
index a978dc7..b76231b 100644
--- a/samples/OpenIdProviderWebForms/Web.config
+++ b/samples/OpenIdProviderWebForms/Web.config
@@ -75,6 +75,7 @@
<add assembly="System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
<add assembly="System.Xml.Linq, Version=3.5.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089"/>
<add assembly="System.Data.DataSetExtensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089"/>
+ <remove assembly="DotNetOpenAuth.Contracts"/>
</assemblies>
</compilation>
<sessionState mode="InProc" cookieless="false"/>
diff --git a/samples/OpenIdRelyingPartyMvc/Web.config b/samples/OpenIdRelyingPartyMvc/Web.config
index f23c5d7..a17e00f 100644
--- a/samples/OpenIdRelyingPartyMvc/Web.config
+++ b/samples/OpenIdRelyingPartyMvc/Web.config
@@ -77,6 +77,7 @@
<add assembly="System.Data.DataSetExtensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089"/>
<add assembly="System.Xml.Linq, Version=3.5.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089"/>
<add assembly="System.Data.Linq, Version=3.5.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089"/>
+ <remove assembly="DotNetOpenAuth.Contracts"/>
</assemblies>
</compilation>
<!--
diff --git a/samples/OpenIdRelyingPartyWebForms/Web.config b/samples/OpenIdRelyingPartyWebForms/Web.config
index b0aa965..5d3a33b 100644
--- a/samples/OpenIdRelyingPartyWebForms/Web.config
+++ b/samples/OpenIdRelyingPartyWebForms/Web.config
@@ -61,7 +61,11 @@
<system.web>
<!--<sessionState cookieless="true" />-->
- <compilation debug="true"/>
+ <compilation debug="true">
+ <assemblies>
+ <remove assembly="DotNetOpenAuth.Contracts"/>
+ </assemblies>
+ </compilation>
<customErrors mode="RemoteOnly"/>
<authentication mode="Forms">
<forms name="OpenIdRelyingPartySession"/> <!-- named cookie prevents conflicts with other samples -->
diff --git a/samples/OpenIdRelyingPartyWebForms/loginProgrammatic.aspx b/samples/OpenIdRelyingPartyWebForms/loginProgrammatic.aspx
index 78179f7..a00eccd 100644
--- a/samples/OpenIdRelyingPartyWebForms/loginProgrammatic.aspx
+++ b/samples/OpenIdRelyingPartyWebForms/loginProgrammatic.aspx
@@ -12,5 +12,4 @@
Visible="False" />
<asp:Label ID="loginCanceledLabel" runat="server" EnableViewState="False" Text="Login canceled"
Visible="False" />
- <asp:CheckBox ID="noLoginCheckBox" runat="server" Text="Extensions only (no login) -- most OPs don't yet support this" />
</asp:Content> \ No newline at end of file
diff --git a/samples/OpenIdRelyingPartyWebForms/loginProgrammatic.aspx.designer.cs b/samples/OpenIdRelyingPartyWebForms/loginProgrammatic.aspx.designer.cs
index 239d7b8..088e305 100644
--- a/samples/OpenIdRelyingPartyWebForms/loginProgrammatic.aspx.designer.cs
+++ b/samples/OpenIdRelyingPartyWebForms/loginProgrammatic.aspx.designer.cs
@@ -1,7 +1,7 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
-// Runtime Version:2.0.50727.4918
+// Runtime Version:2.0.50727.4927
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
@@ -66,14 +66,5 @@ namespace OpenIdRelyingPartyWebForms {
/// To modify move field declaration from designer file to code-behind file.
/// </remarks>
protected global::System.Web.UI.WebControls.Label loginCanceledLabel;
-
- /// <summary>
- /// noLoginCheckBox control.
- /// </summary>
- /// <remarks>
- /// Auto-generated field.
- /// To modify move field declaration from designer file to code-behind file.
- /// </remarks>
- protected global::System.Web.UI.WebControls.CheckBox noLoginCheckBox;
}
}
diff --git a/samples/OpenIdRelyingPartyWebFormsVB/Web.config b/samples/OpenIdRelyingPartyWebFormsVB/Web.config
index f488900..36174a5 100644
--- a/samples/OpenIdRelyingPartyWebFormsVB/Web.config
+++ b/samples/OpenIdRelyingPartyWebFormsVB/Web.config
@@ -61,7 +61,11 @@
<system.web>
<!--<sessionState cookieless="true" />-->
- <compilation debug="true"/>
+ <compilation debug="true">
+ <assemblies>
+ <remove assembly="DotNetOpenAuth.Contracts"/>
+ </assemblies>
+ </compilation>
<customErrors mode="RemoteOnly"/>
<authentication mode="Forms">
<forms name="OpenIdRelyingPartyVBSession"/> <!-- named cookie prevents conflicts with other samples -->
diff --git a/samples/OpenIdWebRingSsoProvider/Web.config b/samples/OpenIdWebRingSsoProvider/Web.config
index c32e0e3..163c08b 100644
--- a/samples/OpenIdWebRingSsoProvider/Web.config
+++ b/samples/OpenIdWebRingSsoProvider/Web.config
@@ -79,6 +79,7 @@
<add assembly="System.Data.DataSetExtensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089"/>
<add assembly="System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
<add assembly="System.Xml.Linq, Version=3.5.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089"/>
+ <remove assembly="DotNetOpenAuth.Contracts"/>
</assemblies>
</compilation>
diff --git a/samples/OpenIdWebRingSsoRelyingParty/Web.config b/samples/OpenIdWebRingSsoRelyingParty/Web.config
index 94ef60c..3f50723 100644
--- a/samples/OpenIdWebRingSsoRelyingParty/Web.config
+++ b/samples/OpenIdWebRingSsoRelyingParty/Web.config
@@ -83,6 +83,7 @@
<add assembly="System.Data.DataSetExtensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089"/>
<add assembly="System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
<add assembly="System.Xml.Linq, Version=3.5.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089"/>
+ <remove assembly="DotNetOpenAuth.Contracts"/>
</assemblies>
</compilation>
diff --git a/tools/Publish.targets b/samples/Samples.proj
index 415750c..c79a0a4 100644
--- a/tools/Publish.targets
+++ b/samples/Samples.proj
@@ -1,37 +1,40 @@
+<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<!-- Properties that must be set for these targets to function:
$(BranchName): The name of the branch being built. Used to determine the web subdirectory for publishing.
For creating web sites:
$(PublishSamplesWebSiteName): The name of the web site under which the sample web applications will be created/deleted.
- $(PublishDocsWebSiteName): The name of the web site under which the documentation web applications will be created/deleted.
For creating or publishing to web sites:
$(SampleWebRoot): the full physical path to where samples should be copied to, excluding $(BranchName)
- $(DocWebRoot): the full physical path to where documentation should be copied to, excluding $(BranchName)
-->
+ <Import Project="$(MSBuildProjectDirectory)\..\tools\DotNetOpenAuth.automated.props"/>
- <Target Name="PrepareForIIS">
+ <ItemGroup>
+ <SampleProjects Include="**\*.csproj;**\*.vbproj" />
+ <SampleSites Include="OAuthConsumer;OAuthServiceProvider;InfoCardRelyingParty" />
+
+ <ProjectsToClean Include="@(SampleProjects)" />
+ <ProjectsToClean Include="$(SolutionPath)">
+ <Targets>@(SampleSites->'%(Identity):Clean')</Targets>
+ </ProjectsToClean>
+ </ItemGroup>
+
+ <Target Name="Build" DependsOnTargets="SkipVerification">
+ <MSBuild Projects="@(SampleProjects)" BuildInParallel="$(BuildInParallel)" />
+ <MSBuild Projects="$(SolutionPath)" Targets="@(SampleSites)" BuildInParallel="$(BuildInParallel)" />
+ </Target>
+
+ <Target Name="Prepare">
<Error Text="The BranchName property must be set." Condition=" '$(BranchName)' == '' " />
-
+ <Error Text="The SampleWebRoot property must be set." Condition=" '$(SampleWebRoot)' == '' " />
<PropertyGroup>
<PublishSamplesWebSiteVirtualPath>/$(BranchName)</PublishSamplesWebSiteVirtualPath>
- <PublishDocsWebSiteVirtualPath>/$(BranchName)</PublishDocsWebSiteVirtualPath>
</PropertyGroup>
- </Target>
-
- <Target Name="PrepareForPublishSamples"
- Condition=" '$(SampleWebRoot)' != '' "
- DependsOnTargets="BuildSamples">
- <Error Text="The BranchName property must be set." Condition=" '$(BranchName)' == '' " />
-
<ItemGroup>
<_SampleWebConfigs Include="$(ProjectRoot)samples\*\web.config" />
<PublishableWebSamples Include="@(_SampleWebConfigs->'%(RootDir)%(Directory)')" />
- <SampleSources Include="$(ProjectRoot)samples\**\*" />
- <SampleSources>
- <PublishedLocation>$(SampleWebRoot)\$(BranchName)\%(RecursiveDir)%(Filename)%(Extension)</PublishedLocation>
- </SampleSources>
</ItemGroup>
<!-- Trim the trailing slash on the web sample paths so we can just get the leaf directory name. -->
@@ -45,6 +48,15 @@
<PublishableWebSamplesVirtualPaths Include="@(_PublishableWebSamplesNoTrailingSlash->'$(PublishSamplesWebSiteVirtualPath)/%(Filename)')" />
<PublishableWebSamplesPhysicalPaths Include="@(_PublishableWebSamplesNoTrailingSlash->'$(SampleWebRoot)\$(BranchName)\%(Filename)')" />
</ItemGroup>
+ </Target>
+
+ <Target Name="PrepareForPublish" DependsOnTargets="Prepare;Build">
+ <ItemGroup>
+ <SampleSources Include="$(ProjectRoot)samples\**\*" />
+ <SampleSources>
+ <PublishedLocation>$(SampleWebRoot)\$(BranchName)\%(RecursiveDir)%(Filename)%(Extension)</PublishedLocation>
+ </SampleSources>
+ </ItemGroup>
<FilterItems
InputItems="@(SampleSources)"
@@ -57,8 +69,8 @@
</ItemGroup>
</Target>
- <Target Name="PublishSamples"
- DependsOnTargets="PrepareForPublishSamples"
+ <Target Name="Publish"
+ DependsOnTargets="PrepareForPublish"
Inputs="@(PublishableWebSampleSources)"
Outputs="@(PublishableWebSampleTargets)"
Condition=" '$(SampleWebRoot)' != '' ">
@@ -67,34 +79,12 @@
<Copy SourceFiles="@(PublishableWebSampleSources)" DestinationFiles="@(PublishableWebSampleTargets)" SkipUnchangedFiles="true" />
</Target>
- <Target Name="UnpublishSamples"
- DependsOnTargets="DeleteSampleSitesOnIis"
+ <Target Name="Unpublish"
+ DependsOnTargets="DeleteSitesOnIis"
Condition=" '$(SampleWebRoot)' != '' ">
</Target>
-
- <Target Name="PrepareForPublishDocumentation" DependsOnTargets="Documentation">
- <ItemGroup>
- <DocSources Include="$(ProjectRoot)doc\api\**\*" />
- <DocTargets Include="@(DocSources->'$(DocWebRoot)\$(BranchName)\%(RecursiveDir)%(Filename)%(Extension)')" />
- </ItemGroup>
- </Target>
-
- <Target Name="PublishDocumentation"
- DependsOnTargets="PrepareForPublishDocumentation"
- Inputs="@(DocSources)"
- Outputs="@(DocTargets)"
- Condition=" '$(DocWebRoot)' != '' ">
- <RemoveDir Directories="$(DocWebRoot)\$(BranchName)" />
- <MakeDir Directories="$(DocWebRoot)\$(BranchName)" />
- <Copy SourceFiles="@(DocSources)" DestinationFiles="@(DocTargets)" SkipUnchangedFiles="true" />
- </Target>
- <Target Name="UnpublishDocumentation"
- DependsOnTargets="DeleteDocumentationSiteOnIis"
- Condition=" '$(DocWebRoot)' != '' ">
- </Target>
-
- <Target Name="CreateSampleSitesOnIis" DependsOnTargets="PrepareForIIS;PrepareForPublishSamples">
+ <Target Name="CreateSitesOnIis" DependsOnTargets="Prepare">
<Error Text="The PublishSamplesWebSiteName property must be set." Condition=" '$(PublishSamplesWebSiteName)' == '' "/>
<Error Text="The SampleWebRoot property must be set." Condition=" '$(SampleWebRoot)' == '' " />
<CreateWebApplication
@@ -104,7 +94,7 @@
/>
</Target>
- <Target Name="DeleteSampleSitesOnIis" DependsOnTargets="PrepareForIIS">
+ <Target Name="DeleteSitesOnIis" DependsOnTargets="Prepare">
<Error Text="The PublishSamplesWebSiteName property must be set." Condition=" '$(PublishSamplesWebSiteName)' == '' "/>
<DeleteWebApplication
WebSiteName="$(PublishSamplesWebSiteName)"
@@ -112,21 +102,5 @@
/>
</Target>
- <Target Name="CreateDocumentationSiteOnIis" DependsOnTargets="PrepareForIIS">
- <Error Text="The PublishDocsWebSiteName property must be set." Condition=" '$(PublishDocsWebSiteName)' == '' "/>
- <Error Text="The DocWebRoot property must be set." Condition=" '$(DocWebRoot)' == '' " />
- <CreateWebApplication
- WebSiteName="$(PublishDocsWebSiteName)"
- PhysicalPaths="$(DocWebRoot)\$(BranchName)"
- VirtualPaths="$(PublishDocsWebSiteVirtualPath)"
- />
- </Target>
-
- <Target Name="DeleteDocumentationSiteOnIis" DependsOnTargets="PrepareForIIS">
- <Error Text="The PublishDocsWebSiteName property must be set." Condition=" '$(PublishDocsWebSiteName)' == '' "/>
- <DeleteWebApplication
- WebSiteName="$(PublishDocsWebSiteName)"
- VirtualPaths="$(PublishDocsWebSiteVirtualPath)"
- />
- </Target>
+ <Import Project="$(ProjectRoot)tools\DotNetOpenAuth.automated.targets"/>
</Project>
diff --git a/samples/tools.proj b/samples/tools.proj
new file mode 100644
index 0000000..74f6457
--- /dev/null
+++ b/samples/tools.proj
@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <Import Project="$(MSBuildProjectDirectory)\..\tools\DotNetOpenAuth.automated.props"/>
+
+ <Target Name="Layout">
+ <PropertyGroup>
+ <ToolsDirectoryNoSlash>$(DropsRoot)$(ProductName)-Tools-$(BuildVersion)</ToolsDirectoryNoSlash>
+ <ToolsDirectory>$(ToolsDirectoryNoSlash)\</ToolsDirectory>
+ </PropertyGroup>
+
+ <ItemGroup>
+ <ToolProjects Include="$(ProjectRoot)Samples\OpenIdOfflineProvider\OpenIdOfflineProvider.csproj">
+ <Targets>Sign</Targets>
+ </ToolProjects>
+ </ItemGroup>
+
+ <MSBuild Projects="@(ToolProjects)" Targets="%(ToolProjects.Targets)" BuildInParallel="$(BuildInParallel)">
+ <Output TaskParameter="TargetOutputs" ItemName="OfflineProvider"/>
+ </MSBuild>
+
+ <ItemGroup>
+ <!-- Remove the un-unified assembly. -->
+ <OfflineProvider Remove="$(OutputPath)$(SignedSubPath)$(ProductName).dll" />
+ <!-- add the PDBs -->
+ <OfflineProvider Include="@(OfflineProvider->'%(SymbolPath)')" />
+ <OfflineProviderTargets Include="
+ @(OfflineProvider->'$(ToolsDirectory)%(CultureDir)%(FileName)%(Extension)')"/>
+
+ <AllToolSources Include="@(OfflineProvider)" />
+ <AllToolTargets Include="@(OfflineProviderTargets)" />
+ </ItemGroup>
+
+ <MakeDir Directories="@(ToolsDirectory)" />
+ <Copy SourceFiles="@(AllToolSources)" DestinationFiles="@(AllToolTargets)" SkipUnchangedFiles="true" />
+
+ <!-- remove files that shouldn't be in the directory (perhaps from a previous version). -->
+ <Purge Directories="$(ToolsDirectory)" IntendedFiles="@(AllToolTargets)" />
+ </Target>
+
+ <Target Name="Build" DependsOnTargets="Layout">
+ <PropertyGroup>
+ <ToolsZip>$(ToolsDirectoryNoSlash).zip</ToolsZip>
+ </PropertyGroup>
+
+ <Zip ZipFileName="$(ToolsZip)"
+ Files="@(AllToolTargets)"
+ WorkingDirectory="$(ToolsDirectory)"
+ ZipLevel="$(ZipLevel)" />
+ </Target>
+
+ <Import Project="$(ProjectRoot)tools\DotNetOpenAuth.automated.targets"/>
+</Project> \ No newline at end of file
diff --git a/src/DotNetOpenAuth.BuildTasks/AddProjectItems.cs b/src/DotNetOpenAuth.BuildTasks/AddProjectItems.cs
index 30fa284..0b84398 100644
--- a/src/DotNetOpenAuth.BuildTasks/AddProjectItems.cs
+++ b/src/DotNetOpenAuth.BuildTasks/AddProjectItems.cs
@@ -6,13 +6,13 @@
namespace DotNetOpenAuth.BuildTasks {
using System;
+ using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Build.BuildEngine;
using Microsoft.Build.Framework;
using Microsoft.Build.Utilities;
- using System.Collections;
public class AddProjectItems : Task {
/// <summary>
@@ -49,7 +49,10 @@ namespace DotNetOpenAuth.BuildTasks {
BuildItem newItem = project.AddNewItem(itemType, projectItem.ItemSpec, false);
var customMetadata = projectItem.CloneCustomMetadata();
foreach (DictionaryEntry entry in customMetadata) {
- newItem.SetMetadata((string)entry.Key, (string)entry.Value);
+ string value = (string)entry.Value;
+ if (value.Length > 0) {
+ newItem.SetMetadata((string)entry.Key, value);
+ }
}
}
diff --git a/src/DotNetOpenAuth.BuildTasks/ChangeProjectReferenceToAssemblyReference.cs b/src/DotNetOpenAuth.BuildTasks/ChangeProjectReferenceToAssemblyReference.cs
index f940a72..503e168 100644
--- a/src/DotNetOpenAuth.BuildTasks/ChangeProjectReferenceToAssemblyReference.cs
+++ b/src/DotNetOpenAuth.BuildTasks/ChangeProjectReferenceToAssemblyReference.cs
@@ -1,47 +1,59 @@
-using System;
-using System.Linq;
-using System.IO;
-using System.Xml;
+namespace DotNetOpenAuth.BuildTasks {
+ using System;
+ using System.IO;
+ using System.Linq;
+ using System.Xml;
+ using Microsoft.Build.BuildEngine;
+ using Microsoft.Build.Framework;
+ using Microsoft.Build.Utilities;
-using Microsoft.Build.Framework;
-using Microsoft.Build.Utilities;
-using Microsoft.Build.BuildEngine;
-
-namespace DotNetOpenAuth.BuildTasks {
/// <summary>
/// Replaces ProjectReference items in a set of projects with Reference items.
/// </summary>
public class ChangeProjectReferenceToAssemblyReference : Task {
+ private const string msbuildNamespace = "http://schemas.microsoft.com/developer/msbuild/2003";
+
/// <summary>
/// The projects to alter.
/// </summary>
[Required]
public ITaskItem[] Projects { get; set; }
+
/// <summary>
- /// The project reference to remove.
+ /// The project references to remove.
/// </summary>
[Required]
- public string ProjectReference { get; set; }
+ public ITaskItem[] ProjectReferences { get; set; }
+
/// <summary>
- /// The assembly reference to add.
+ /// The assembly references to add.
/// </summary>
[Required]
- public string Reference { get; set; }
+ public ITaskItem[] References { get; set; }
- const string msbuildNamespace = "http://schemas.microsoft.com/developer/msbuild/2003";
public override bool Execute() {
- foreach (var project in Projects) {
- Log.LogMessage(MessageImportance.Normal, "Changing P2P references to assembly references in \"{0}\".", project.ItemSpec);
+ if (this.ProjectReferences.Length != this.References.Length) {
+ this.Log.LogError("ProjectReferences and References arrays do not have matching lengths.");
+ }
+ foreach (var project in Projects) {
Project doc = new Project();
doc.Load(project.ItemSpec);
-
- var projectReference = doc.EvaluatedItems.OfType<BuildItem>().Where(
- item => item.Name == "ProjectReference" && item.Include == ProjectReference).Single();
- doc.RemoveItem(projectReference);
- var newReference = doc.AddNewItem("Reference", Path.GetFileNameWithoutExtension(Reference), true);
- newReference.SetMetadata("HintPath", Reference);
+ var projectReferences = doc.EvaluatedItems.OfType<BuildItem>().Where(item => item.Name == "ProjectReference");
+ var matchingReferences = from reference in projectReferences
+ join refToRemove in this.ProjectReferences on reference.Include equals refToRemove.ItemSpec
+ let addIndex = Array.IndexOf(this.ProjectReferences, refToRemove)
+ select new { Remove = reference, Add = this.References[addIndex] };
+ foreach (var matchingReference in matchingReferences) {
+ this.Log.LogMessage("Removing project reference to \"{0}\" from \"{1}\".", matchingReference.Remove.Include, project.ItemSpec);
+ doc.RemoveItem(matchingReference.Remove);
+ if (matchingReference.Add.ItemSpec != "REMOVE") {
+ this.Log.LogMessage("Adding assembly reference to \"{0}\" to \"{1}\".", matchingReference.Add.ItemSpec, project.ItemSpec);
+ var newReference = doc.AddNewItem("Reference", Path.GetFileNameWithoutExtension(matchingReference.Add.ItemSpec), true);
+ newReference.SetMetadata("HintPath", matchingReference.Add.ItemSpec);
+ }
+ }
doc.Save(project.ItemSpec);
}
diff --git a/src/DotNetOpenAuth.BuildTasks/CopyWithTokenSubstitution.cs b/src/DotNetOpenAuth.BuildTasks/CopyWithTokenSubstitution.cs
index 38f3b50..5b097ab 100644
--- a/src/DotNetOpenAuth.BuildTasks/CopyWithTokenSubstitution.cs
+++ b/src/DotNetOpenAuth.BuildTasks/CopyWithTokenSubstitution.cs
@@ -56,7 +56,12 @@ namespace DotNetOpenAuth.BuildTasks {
for (int i = 0; i < this.SourceFiles.Length; i++) {
string sourcePath = this.SourceFiles[i].ItemSpec;
string destPath = this.DestinationFiles[i].ItemSpec;
- bool skipUnchangedFiles = bool.Parse(this.SourceFiles[i].GetMetadata("SkipUnchangedFiles"));
+ bool skipUnchangedFiles;
+ bool.TryParse(this.SourceFiles[i].GetMetadata("SkipUnchangedFiles"), out skipUnchangedFiles);
+
+ if (!Directory.Exists(Path.GetDirectoryName(destPath))) {
+ Directory.CreateDirectory(Path.GetDirectoryName(destPath));
+ }
if (string.IsNullOrEmpty(this.SourceFiles[i].GetMetadata("BeforeTokens"))) {
// this is just a standard copy without token substitution
@@ -65,7 +70,7 @@ namespace DotNetOpenAuth.BuildTasks {
continue;
}
- Log.LogMessage(MessageImportance.Normal, "Copying \"{0}\" -> \"{1}\"", sourcePath, destPath);
+ Log.LogMessage(MessageImportance.Normal, "Copying file from \"{0}\" to \"{1}\"", sourcePath, destPath);
File.Copy(sourcePath, destPath, true);
} else {
// We deliberably consider newer destination files to be up-to-date rather than
@@ -85,9 +90,6 @@ namespace DotNetOpenAuth.BuildTasks {
}
using (StreamReader sr = File.OpenText(sourcePath)) {
- if (!Directory.Exists(Path.GetDirectoryName(destPath))) {
- Directory.CreateDirectory(Path.GetDirectoryName(destPath));
- }
using (StreamWriter sw = File.CreateText(destPath)) {
StringBuilder line = new StringBuilder();
while (!sr.EndOfStream) {
diff --git a/src/DotNetOpenAuth.BuildTasks/DotNetOpenAuth.BuildTasks.csproj b/src/DotNetOpenAuth.BuildTasks/DotNetOpenAuth.BuildTasks.csproj
index 3f76f78..365bec5 100644
--- a/src/DotNetOpenAuth.BuildTasks/DotNetOpenAuth.BuildTasks.csproj
+++ b/src/DotNetOpenAuth.BuildTasks/DotNetOpenAuth.BuildTasks.csproj
@@ -118,6 +118,7 @@
<Compile Include="JsPack.cs" />
<Compile Include="NativeMethods.cs" />
<Compile Include="ParseMaster.cs" />
+ <Compile Include="PathSegment.cs" />
<Compile Include="Publicize.cs" />
<Compile Include="Purge.cs" />
<Compile Include="ReSignDelaySignedAssemblies.cs" />
@@ -131,6 +132,7 @@
<DependentUpon>TaskStrings.resx</DependentUpon>
</Compile>
<Compile Include="Trim.cs" />
+ <Compile Include="Utilities.cs" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="TaskStrings.resx">
diff --git a/src/DotNetOpenAuth.BuildTasks/DotNetOpenAuth.BuildTasks.sln b/src/DotNetOpenAuth.BuildTasks/DotNetOpenAuth.BuildTasks.sln
index 34a8e46..f3e3982 100644
--- a/src/DotNetOpenAuth.BuildTasks/DotNetOpenAuth.BuildTasks.sln
+++ b/src/DotNetOpenAuth.BuildTasks/DotNetOpenAuth.BuildTasks.sln
@@ -4,11 +4,20 @@ Microsoft Visual Studio Solution File, Format Version 11.00
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{ABBE14A3-0404-4123-9093-E598C3DD3E9B}"
ProjectSection(SolutionItems) = preProject
..\..\build.proj = ..\..\build.proj
+ ..\..\doc\doc.proj = ..\..\doc\doc.proj
+ ..\..\tools\DotNetOpenAuth.automated.props = ..\..\tools\DotNetOpenAuth.automated.props
+ ..\..\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
..\..\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
+ ..\..\projecttemplates\projecttemplates.proj = ..\..\projecttemplates\projecttemplates.proj
+ ..\..\samples\Samples.proj = ..\..\samples\Samples.proj
+ ..\..\samples\tools.proj = ..\..\samples\tools.proj
+ ..\..\vsi\vsi.proj = ..\..\vsi\vsi.proj
+ ..\..\vsix\vsix.proj = ..\..\vsix\vsix.proj
EndProjectSection
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DotNetOpenAuth.BuildTasks", "DotNetOpenAuth.BuildTasks.csproj", "{AC231A51-EF60-437C-A33F-AF8ADEB8EB74}"
diff --git a/src/DotNetOpenAuth.BuildTasks/FixupReferenceHintPaths.cs b/src/DotNetOpenAuth.BuildTasks/FixupReferenceHintPaths.cs
index 13a4b8f..babaab3 100644
--- a/src/DotNetOpenAuth.BuildTasks/FixupReferenceHintPaths.cs
+++ b/src/DotNetOpenAuth.BuildTasks/FixupReferenceHintPaths.cs
@@ -40,7 +40,13 @@ namespace DotNetOpenAuth.BuildTasks {
// Figure out what the assembly names are of the references that are available.
AssemblyName[] availableReferences = new AssemblyName[this.References.Length];
for (int i = 0; i < this.References.Length; i++) {
- availableReferences[i] = AssemblyName.GetAssemblyName(this.References[i].ItemSpec);
+ if (File.Exists(this.References[i].ItemSpec)) {
+ availableReferences[i] = AssemblyName.GetAssemblyName(this.References[i].ItemSpec);
+ } else {
+ availableReferences[i] = new AssemblyName(Path.GetFileNameWithoutExtension(this.References[i].ItemSpec)) {
+ CodeBase = this.References[i].GetMetadata("FullPath"),
+ };
+ }
}
foreach (var projectTaskItem in this.Projects) {
diff --git a/src/DotNetOpenAuth.BuildTasks/MergeProjectWithVSTemplate.cs b/src/DotNetOpenAuth.BuildTasks/MergeProjectWithVSTemplate.cs
index 1a8a17d..d162cd6 100644
--- a/src/DotNetOpenAuth.BuildTasks/MergeProjectWithVSTemplate.cs
+++ b/src/DotNetOpenAuth.BuildTasks/MergeProjectWithVSTemplate.cs
@@ -7,18 +7,27 @@
namespace DotNetOpenAuth.BuildTasks {
using System;
using System.Collections.Generic;
+ using System.Collections.ObjectModel;
+ using System.Diagnostics.Contracts;
+ using System.Globalization;
+ using System.IO;
using System.Linq;
using System.Text;
- using Microsoft.Build.Framework;
- using Microsoft.Build.Utilities;
using System.Xml.Linq;
- using System.IO;
using Microsoft.Build.BuildEngine;
- using System.Diagnostics.Contracts;
+ using Microsoft.Build.Framework;
+ using Microsoft.Build.Utilities;
public class MergeProjectWithVSTemplate : Task {
internal const string VSTemplateNamespace = "http://schemas.microsoft.com/developer/vstemplate/2005";
+ internal const string VsixNamespace = "http://schemas.microsoft.com/developer/vsx-schema/2010";
+
+ /// <summary>
+ /// A dictionary where the key is the project name and the value is the path contribution.
+ /// </summary>
+ private Dictionary<string, string> vsixContributionToPath = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
+
[Required]
public string[] ProjectItemTypes { get; set; }
@@ -26,13 +35,44 @@ namespace DotNetOpenAuth.BuildTasks {
public string[] ReplaceParametersExtensions { get; set; }
[Required]
- public ITaskItem[] Templates { get; set; }
+ public ITaskItem[] SourceTemplates { get; set; }
+
+ [Required]
+ public ITaskItem[] SourceProjects { get; set; }
+
+ [Required]
+ public ITaskItem[] DestinationTemplates { get; set; }
+
+ public ITaskItem[] SourcePathExceptions { get; set; }
+
+ /// <summary>
+ /// Gets or sets the maximum length a project item's relative path should
+ /// be limited to, artificially renaming them as necessary.
+ /// </summary>
+ /// <value>Use 0 to disable the renaming feature.</value>
+ public int MaximumRelativePathLength { get; set; }
+
+ /// <summary>
+ /// Gets or sets the project item paths from the source project to copy to the destination location.
+ /// </summary>
+ [Output]
+ public ITaskItem[] ProjectItems { get; set; }
/// <summary>
/// Executes this instance.
/// </summary>
public override bool Execute() {
- foreach(ITaskItem sourceTemplateTaskItem in this.Templates) {
+ if (this.DestinationTemplates.Length != this.SourceTemplates.Length) {
+ this.Log.LogError("SourceTemplates array has length {0} while DestinationTemplates array has length {1}, but must equal.", this.SourceTemplates.Length, this.DestinationTemplates.Length);
+ }
+ if (this.SourceProjects.Length != this.SourceTemplates.Length) {
+ this.Log.LogError("SourceTemplates array has length {0} while SourceProjects array has length {1}, but must equal.", this.SourceTemplates.Length, this.SourceProjects.Length);
+ }
+
+ var projectItemsToCopy = new List<ITaskItem>();
+
+ for (int iTemplate = 0; iTemplate < this.SourceTemplates.Length; iTemplate++) {
+ ITaskItem sourceTemplateTaskItem = this.SourceTemplates[iTemplate];
var template = XElement.Load(sourceTemplateTaskItem.ItemSpec);
var templateContentElement = template.Element(XName.Get("TemplateContent", VSTemplateNamespace));
var projectElement = templateContentElement.Element(XName.Get("Project", VSTemplateNamespace));
@@ -41,37 +81,65 @@ namespace DotNetOpenAuth.BuildTasks {
continue;
}
- var projectPath = Path.Combine(Path.GetDirectoryName(sourceTemplateTaskItem.ItemSpec), projectElement.Attribute("File").Value);
+ var projectPath = this.SourceProjects[iTemplate].ItemSpec;
+ var projectDirectory = Path.GetDirectoryName(Path.Combine(Path.GetDirectoryName(sourceTemplateTaskItem.GetMetadata("FullPath")), projectElement.Attribute("File").Value));
Log.LogMessage("Merging project \"{0}\" with \"{1}\".", projectPath, sourceTemplateTaskItem.ItemSpec);
var sourceProject = new Project();
sourceProject.Load(projectPath);
+ var projectItems = sourceProject.EvaluatedItems.Cast<BuildItem>().Where(item => this.ProjectItemTypes.Contains(item.Name));
+
+ // Figure out where every project item is in source, and where it will go in the destination,
+ // taking into account a given maximum path length that may require that we shorten the path.
+ PathSegment root = new PathSegment();
+ root.Add(projectItems.Select(item => item.Include));
+ root.EnsureSelfAndChildrenNoLongerThan(this.MaximumRelativePathLength);
// Collect the project items from the project that are appropriate
// to include in the .vstemplate file.
- var itemsByFolder = from item in sourceProject.EvaluatedItems.Cast<BuildItem>()
- where this.ProjectItemTypes.Contains(item.Name)
- orderby item.Include
- group item by Path.GetDirectoryName(item.Include);
- foreach (var folder in itemsByFolder) {
- XElement parentNode = FindOrCreateParent(folder.Key, projectElement);
-
- foreach (var item in folder) {
- bool replaceParameters = this.ReplaceParametersExtensions.Contains(Path.GetExtension(item.Include));
+ foreach (var folder in root.SelfAndDescendents.Where(path => !path.IsLeaf && path.LeafChildren.Any())) {
+ XElement parentNode = projectElement;
+ parentNode = FindOrCreateParent(folder.CurrentPath, projectElement);
+ if (folder.NameChanged) {
+ parentNode.SetAttributeValue("TargetFolderName", folder.OriginalName);
+ }
+
+ foreach (var item in folder.LeafChildren) {
var itemName = XName.Get("ProjectItem", VSTemplateNamespace);
- var projectItem = parentNode.Elements(itemName).FirstOrDefault(el => string.Equals(el.Value, Path.GetFileName(item.Include), StringComparison.OrdinalIgnoreCase));
+ // The project item MAY be hard-coded in the .vstemplate file, under the original name.
+ var projectItem = parentNode.Elements(itemName).FirstOrDefault(el => string.Equals(el.Value, Path.GetFileName(item.OriginalName), StringComparison.OrdinalIgnoreCase));
if (projectItem == null) {
- projectItem = new XElement(itemName, Path.GetFileName(item.Include));
+ projectItem = new XElement(itemName, item.CurrentName);
parentNode.Add(projectItem);
}
- if (replaceParameters) {
+ if (item.NameChanged) {
+ projectItem.Value = item.CurrentName; // set Value in case it was a hard-coded item in the .vstemplate file.
+ projectItem.SetAttributeValue("TargetFileName", item.OriginalName);
+ }
+ if (this.ReplaceParametersExtensions.Contains(Path.GetExtension(item.OriginalPath))) {
projectItem.SetAttributeValue("ReplaceParameters", "true");
}
}
}
- template.Save(sourceTemplateTaskItem.ItemSpec);
+ template.Save(this.DestinationTemplates[iTemplate].ItemSpec);
+ foreach (var pair in root.LeafDescendents) {
+ TaskItem item = new TaskItem(Path.Combine(Path.GetDirectoryName(this.SourceTemplates[iTemplate].ItemSpec), pair.OriginalPath));
+ string apparentSource = Path.Combine(Path.GetDirectoryName(this.SourceTemplates[iTemplate].ItemSpec), pair.OriginalPath);
+ var sourcePathException = this.SourcePathExceptions.FirstOrDefault(ex => string.Equals(ex.ItemSpec, apparentSource));
+ if (sourcePathException != null) {
+ item.SetMetadata("SourceFullPath", sourcePathException.GetMetadata("ActualSource"));
+ } else {
+ item.SetMetadata("SourceFullPath", Path.GetFullPath(apparentSource));
+ }
+ item.SetMetadata("DestinationFullPath", Path.GetFullPath(Path.Combine(Path.GetDirectoryName(this.DestinationTemplates[iTemplate].ItemSpec), pair.CurrentPath)));
+ item.SetMetadata("RecursiveDir", Path.GetDirectoryName(this.SourceTemplates[iTemplate].ItemSpec));
+ item.SetMetadata("Transform", this.ReplaceParametersExtensions.Contains(Path.GetExtension(pair.OriginalName)) ? "true" : "false");
+ projectItemsToCopy.Add(item);
+ }
}
+ this.ProjectItems = projectItemsToCopy.ToArray();
+
return !Log.HasLoggedErrors;
}
diff --git a/src/DotNetOpenAuth.BuildTasks/PathSegment.cs b/src/DotNetOpenAuth.BuildTasks/PathSegment.cs
new file mode 100644
index 0000000..56655ff
--- /dev/null
+++ b/src/DotNetOpenAuth.BuildTasks/PathSegment.cs
@@ -0,0 +1,321 @@
+//-----------------------------------------------------------------------
+// <copyright file="PathSegment.cs" company="Andrew Arnott">
+// Copyright (c) Andrew Arnott. All rights reserved.
+// </copyright>
+//-----------------------------------------------------------------------
+
+namespace DotNetOpenAuth.BuildTasks {
+ using System;
+ using System.Collections.Generic;
+ using System.Collections.ObjectModel;
+ using System.Diagnostics;
+ using System.Diagnostics.Contracts;
+ using System.IO;
+ using System.Linq;
+ using System.Text;
+
+ internal class PathSegment {
+ private const float ParentChildResizeThreshold = 0.30f;
+ private readonly PathSegment parent;
+ private readonly string originalName;
+ private string currentName;
+ private bool minimized;
+ private static readonly string[] ReservedFileNames = "CON PRN AUX CLOCK$ NUL COM0 COM1 COM2 COM3 COM4 COM5 COM6 COM7 COM8 COM9 LPT0 LPT1 LPT2 LPT3 LPT4 LPT5 LPT6 LPT7 LPT8 LPT9".Split(' ');
+
+ internal PathSegment() {
+ this.currentName = string.Empty;
+ this.originalName = string.Empty;
+ this.minimized = true;
+ this.Children = new Collection<PathSegment>();
+ }
+
+ private PathSegment(string originalName, PathSegment parent)
+ : this() {
+ Contract.Requires<ArgumentException>(!string.IsNullOrEmpty(originalName));
+ Contract.Requires<ArgumentNullException>(parent != null);
+ this.currentName = this.originalName = originalName;
+ this.parent = parent;
+ this.minimized = false;
+ }
+
+ internal string OriginalPath {
+ get {
+ if (this.parent != null) {
+ return Path.Combine(this.parent.OriginalPath, this.originalName);
+ } else {
+ return this.originalName;
+ }
+ }
+ }
+
+ internal string CurrentPath {
+ get {
+ if (this.parent != null) {
+ return Path.Combine(this.parent.CurrentPath, this.currentName);
+ } else {
+ return this.currentName;
+ }
+ }
+ }
+
+ internal string CurrentName {
+ get { return this.currentName; }
+ }
+
+ internal string OriginalName {
+ get { return this.originalName; }
+ }
+
+ private int SegmentCount {
+ get {
+ int parents = this.parent != null ? this.parent.SegmentCount : 0;
+ return parents + 1;
+ }
+ }
+
+ internal int FullLength {
+ get {
+ if (this.parent != null) {
+ int parentLength = this.parent.FullLength;
+ if (parentLength > 0) {
+ parentLength++; // allow for an in between slash
+ }
+ return parentLength + this.currentName.Length;
+ } else {
+ return this.currentName.Length;
+ }
+ }
+ }
+
+ internal bool NameChanged {
+ get { return !string.Equals(this.currentName, this.originalName, StringComparison.OrdinalIgnoreCase); }
+ }
+
+ internal bool IsLeaf {
+ get { return this.Children.Count == 0; }
+ }
+
+ internal IEnumerable<PathSegment> Descendents {
+ get {
+ IEnumerable<PathSegment> result = this.Children;
+ foreach (PathSegment child in this.Children) {
+ result = result.Concat(child.Descendents);
+ }
+
+ return result;
+ }
+ }
+
+ internal IEnumerable<PathSegment> Ancestors {
+ get {
+ PathSegment parent = this.parent;
+ while (parent != null) {
+ yield return parent;
+ parent = parent.parent;
+ }
+ }
+ }
+
+ internal IEnumerable<PathSegment> SelfAndDescendents {
+ get {
+ yield return this;
+ foreach (var child in this.Descendents) {
+ yield return child;
+ }
+ }
+ }
+
+ internal IEnumerable<PathSegment> SelfAndAncestors {
+ get {
+ yield return this;
+ foreach (var parent in this.Ancestors) {
+ yield return parent;
+ }
+ }
+ }
+
+ internal IEnumerable<PathSegment> LeafChildren {
+ get { return this.Children.Where(child => child.IsLeaf); }
+ }
+
+ internal IEnumerable<PathSegment> LeafDescendents {
+ get { return this.Descendents.Where(child => child.IsLeaf); }
+ }
+
+ internal IEnumerable<PathSegment> Siblings {
+ get { return this.parent != null ? this.parent.Children : Enumerable.Empty<PathSegment>(); }
+ }
+
+ internal Collection<PathSegment> Children { get; private set; }
+
+ public override string ToString() {
+ string path;
+ if (this.NameChanged) {
+ path = "{" + this.originalName + " => " + this.currentName + "}";
+ } else {
+ path = this.currentName;
+ }
+
+ if (path.Length > 0 && !this.IsLeaf) {
+ path += "\\";
+ }
+
+ if (this.parent != null) {
+ path = parent.ToString() + path;
+ }
+
+ return path;
+ }
+
+ internal PathSegment Add(string originalPath) {
+ Contract.Requires<ArgumentException>(!string.IsNullOrEmpty(originalPath));
+ Contract.Ensures(Contract.Result<PathSegment>() != null);
+ string[] segments = originalPath.Split(Path.DirectorySeparatorChar);
+ return this.Add(segments, 0);
+ }
+
+ internal void Add(IEnumerable<string> originalPaths) {
+ foreach (string path in originalPaths) {
+ this.Add(path);
+ }
+ }
+
+ internal int EnsureSelfAndChildrenNoLongerThan(int maxLength) {
+ Contract.Requires<ArgumentOutOfRangeException>(maxLength > 0, "A path can only have a positive length.");
+ Contract.Requires<ArgumentOutOfRangeException>(this.parent == null || maxLength > this.parent.FullLength + 1, "A child path cannot possibly be made shorter than its parent.");
+ Contract.Ensures(Contract.Result<int>() <= maxLength);
+ const int uniqueBase = 16;
+
+ // Find the items that are too long, and always work on the longest one
+ var longPaths = this.SelfAndDescendents.Where(path => path.FullLength > maxLength).OrderByDescending(path => path.FullLength);
+ PathSegment longPath;
+ while ((longPath = longPaths.FirstOrDefault()) != null) {
+ // Keep working on this one until it's short enough.
+ do {
+ int tooLongBy = longPath.FullLength - maxLength;
+ var longSegments = longPath.SelfAndAncestors.Where(segment => !segment.minimized).OrderByDescending(segment => segment.CurrentName.Length);
+ PathSegment longestSegment = longSegments.FirstOrDefault();
+ if (longestSegment == null) {
+ throw new InvalidOperationException("Unable to shrink path length sufficiently.");
+ }
+ PathSegment secondLongestSegment = longSegments.Skip(1).FirstOrDefault();
+ int shortenByUpTo;
+ if (secondLongestSegment != null) {
+ shortenByUpTo = Math.Min(tooLongBy, Math.Max(1, longestSegment.CurrentName.Length - secondLongestSegment.CurrentName.Length));
+ } else {
+ shortenByUpTo = tooLongBy;
+ }
+ int minimumGuaranteedUniqueLength = Math.Max(1, RoundUp(Math.Log(longestSegment.Siblings.Count(), uniqueBase)));
+ int allowableSegmentLength = Math.Max(minimumGuaranteedUniqueLength, longestSegment.CurrentName.Length - shortenByUpTo);
+ if (allowableSegmentLength >= longestSegment.CurrentName.Length) {
+ // We can't make this segment any shorter.
+ longestSegment.minimized = true;
+ }
+ longestSegment.currentName = longestSegment.CreateUniqueShortFileName(longestSegment.CurrentName, allowableSegmentLength);
+ } while (longPath.FullLength > maxLength);
+ }
+
+ // Return the total length of self or longest child.
+ return this.SelfAndDescendents.Max(c => c.FullLength);
+ }
+
+ internal PathSegment FindByOriginalPath(string originalPath) {
+ Contract.Requires<ArgumentException>(!string.IsNullOrEmpty(originalPath));
+ string[] segments = originalPath.Split(Path.DirectorySeparatorChar);
+ return this.FindByOriginalPath(segments, 0);
+ }
+
+ private string GetUniqueShortName(string preferredPrefix, string preferredSuffix, int allowableLength) {
+ Contract.Requires<ArgumentNullException>(preferredPrefix != null);
+ Contract.Requires<ArgumentNullException>(preferredSuffix != null);
+ Contract.Requires<ArgumentException>(allowableLength > 0);
+ Contract.Ensures(!string.IsNullOrEmpty(Contract.Result<string>()));
+ Contract.Ensures(Contract.Result<string>().Length <= allowableLength);
+ string candidateName = string.Empty;
+ int i;
+ for (i = -1; candidateName.Length == 0 || ReservedFileNames.Contains(candidateName, StringComparer.OrdinalIgnoreCase) || this.Siblings.Any(child => string.Equals(child.CurrentName, candidateName, StringComparison.OrdinalIgnoreCase)); i++) {
+ string unique = i < 0 ? string.Empty : i.ToString("x");
+ if (allowableLength < unique.Length) {
+ throw new InvalidOperationException("Unable to shorten path sufficiently to fit constraints.");
+ }
+
+ candidateName = unique;
+
+ // Suffix gets higher priority than the prefix, but only if the entire suffix can be appended.
+ if (candidateName.Length + preferredSuffix.Length <= allowableLength) {
+ candidateName += preferredSuffix;
+ }
+
+ // Now prepend as much of the prefix as fits.
+ candidateName = preferredPrefix.Substring(0, Math.Min(allowableLength - candidateName.Length, preferredPrefix.Length)) + candidateName;
+ }
+
+ return candidateName;
+ }
+
+ private static int RoundUp(double value) {
+ int roundedValue = (int)value;
+ if (roundedValue < value) {
+ roundedValue++;
+ }
+
+ return roundedValue;
+ }
+
+ private string CreateUniqueShortFileName(string fileName, int targetLength) {
+ Contract.Requires<ArgumentException>(!string.IsNullOrEmpty(fileName));
+ Contract.Ensures(!string.IsNullOrEmpty(Contract.Result<string>()));
+ Contract.Ensures(Contract.Result<string>().Length <= targetLength);
+
+ // The filename may already full within the target length.
+ if (fileName.Length <= targetLength) {
+ return fileName;
+ }
+
+ string preferredPrefix = Path.GetFileNameWithoutExtension(fileName);
+ string preferredSuffix = Path.GetExtension(fileName);
+
+ string shortenedFileName = GetUniqueShortName(preferredPrefix, preferredSuffix, targetLength);
+ return shortenedFileName;
+ }
+
+ private void ShortenThis(int targetLength) {
+ this.currentName = CreateUniqueShortFileName(this.originalName, targetLength);
+ }
+
+ private PathSegment Add(string[] segments, int segmentIndex) {
+ Contract.Requires<ArgumentNullException>(segments != null);
+ Contract.Requires<ArgumentOutOfRangeException>(segmentIndex < segments.Length);
+ Contract.Ensures(Contract.Result<PathSegment>() != null);
+ var match = this.Children.SingleOrDefault(child => String.Equals(child.originalName, segments[segmentIndex]));
+ if (match == null) {
+ match = new PathSegment(segments[segmentIndex], this);
+ this.Children.Add(match);
+ if (segments.Length == segmentIndex + 1) {
+ return match;
+ }
+ }
+
+ return match.Add(segments, segmentIndex + 1);
+ }
+
+ private PathSegment FindByOriginalPath(string[] segments, int segmentIndex) {
+ Contract.Requires<ArgumentNullException>(segments != null);
+ Contract.Requires<ArgumentOutOfRangeException>(segmentIndex < segments.Length);
+ if (string.Equals(this.originalName, segments[segmentIndex], StringComparison.OrdinalIgnoreCase)) {
+ if (segmentIndex == segments.Length - 1) {
+ return this;
+ }
+
+ foreach (var child in this.Children) {
+ var match = child.FindByOriginalPath(segments, segmentIndex + 1);
+ if (match != null) {
+ return match;
+ }
+ }
+ }
+
+ return null;
+ }
+ }
+}
diff --git a/src/DotNetOpenAuth.BuildTasks/Purge.cs b/src/DotNetOpenAuth.BuildTasks/Purge.cs
index e19e485..cf1a214 100644
--- a/src/DotNetOpenAuth.BuildTasks/Purge.cs
+++ b/src/DotNetOpenAuth.BuildTasks/Purge.cs
@@ -7,12 +7,12 @@
namespace DotNetOpenAuth.BuildTasks {
using System;
using System.Collections.Generic;
+ using System.IO;
using System.Linq;
using System.Text;
- using Microsoft.Build.Utilities;
- using Microsoft.Build.Framework;
- using System.IO;
using System.Text.RegularExpressions;
+ using Microsoft.Build.Framework;
+ using Microsoft.Build.Utilities;
/// <summary>
/// Purges directory trees of all directories and files that are not on a whitelist.
@@ -40,6 +40,7 @@ namespace DotNetOpenAuth.BuildTasks {
/// <summary>
/// Gets or sets the files that should be NOT be purged.
/// </summary>
+ [Required]
public ITaskItem[] IntendedFiles { get; set; }
/// <summary>
@@ -82,7 +83,7 @@ namespace DotNetOpenAuth.BuildTasks {
}
private static string NormalizePath(string path) {
- return Regex.Replace(path, @"\\+", @"\");
+ return Path.GetFullPath(Regex.Replace(path, @"\\+", @"\"));
}
}
}
diff --git a/src/DotNetOpenAuth.BuildTasks/Utilities.cs b/src/DotNetOpenAuth.BuildTasks/Utilities.cs
new file mode 100644
index 0000000..80e1733
--- /dev/null
+++ b/src/DotNetOpenAuth.BuildTasks/Utilities.cs
@@ -0,0 +1,31 @@
+//-----------------------------------------------------------------------
+// <copyright file="Utilities.cs" company="Andrew Arnott">
+// Copyright (c) Andrew Arnott. All rights reserved.
+// </copyright>
+//-----------------------------------------------------------------------
+
+namespace DotNetOpenAuth.BuildTasks {
+ using System;
+ using System.Collections.Generic;
+ using System.Diagnostics.Contracts;
+ using System.Linq;
+ using System.Text;
+
+ internal static class Utilities {
+ internal static string SuppressCharacters(string fileName, char[] suppress, char replacement) {
+ Contract.Requires<ArgumentNullException>(fileName != null);
+ Contract.Requires<ArgumentNullException>(suppress != null);
+
+ if (fileName.IndexOfAny(suppress) < 0) {
+ return fileName;
+ }
+
+ StringBuilder builder = new StringBuilder(fileName);
+ foreach (char ch in suppress) {
+ builder.Replace(ch, replacement);
+ }
+
+ return builder.ToString();
+ }
+ }
+}
diff --git a/src/DotNetOpenAuth.Test/DotNetOpenAuth.Test.csproj b/src/DotNetOpenAuth.Test/DotNetOpenAuth.Test.csproj
index 632d2fd..6540714 100644
--- a/src/DotNetOpenAuth.Test/DotNetOpenAuth.Test.csproj
+++ b/src/DotNetOpenAuth.Test/DotNetOpenAuth.Test.csproj
@@ -289,6 +289,7 @@
<Compile Include="OpenId\RelyingParty\NegativeAuthenticationResponseTests.cs" />
<Compile Include="OpenId\RelyingParty\OpenIdTextBoxTests.cs" />
<Compile Include="OpenId\RelyingParty\PositiveAnonymousResponseTests.cs" />
+ <Compile Include="OpenId\RelyingParty\PositiveAuthenticationResponseSnapshotTests.cs" />
<Compile Include="OpenId\RelyingParty\PositiveAuthenticationResponseTests.cs" />
<Compile Include="OpenId\RelyingParty\OpenIdRelyingPartyTests.cs" />
<Compile Include="OpenId\RelyingParty\RelyingPartySecuritySettingsTests.cs" />
@@ -374,4 +375,4 @@
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<Import Project="$(ProjectRoot)tools\DotNetOpenAuth.targets" />
-</Project>
+</Project> \ No newline at end of file
diff --git a/src/DotNetOpenAuth.Test/Messaging/MessagingUtilitiesTests.cs b/src/DotNetOpenAuth.Test/Messaging/MessagingUtilitiesTests.cs
index 8a8ae25..2b0e8f9 100644
--- a/src/DotNetOpenAuth.Test/Messaging/MessagingUtilitiesTests.cs
+++ b/src/DotNetOpenAuth.Test/Messaging/MessagingUtilitiesTests.cs
@@ -153,6 +153,7 @@ namespace DotNetOpenAuth.Test.Messaging
Match m = Regex.Match(req.ContentType, "multipart/form-data; boundary=(.+)");
Assert.IsTrue(m.Success, "Content-Type HTTP header not set correctly.");
string boundary = m.Groups[1].Value;
+ boundary = boundary.Substring(0, boundary.IndexOf(';')); // trim off charset
string expectedEntity = "--{0}\r\nContent-Disposition: form-data; name=\"a\"\r\n\r\nb\r\n--{0}--\r\n";
expectedEntity = string.Format(expectedEntity, boundary);
string actualEntity = httpHandler.RequestEntityAsString;
diff --git a/src/DotNetOpenAuth.Test/Messaging/OutgoingWebResponseTests.cs b/src/DotNetOpenAuth.Test/Messaging/OutgoingWebResponseTests.cs
index 16576d6..10045de 100644
--- a/src/DotNetOpenAuth.Test/Messaging/OutgoingWebResponseTests.cs
+++ b/src/DotNetOpenAuth.Test/Messaging/OutgoingWebResponseTests.cs
@@ -6,6 +6,7 @@
namespace DotNetOpenAuth.Test.Messaging {
using System.Net;
+ using System.Net.Mime;
using System.Text;
using DotNetOpenAuth.Messaging;
using NUnit.Framework;
@@ -30,7 +31,8 @@ namespace DotNetOpenAuth.Test.Messaging {
CollectionAssert.AreEqual(expectedBuffer, actualBuffer);
// Verify that the header was set correctly.
- Assert.AreEqual(encoding.HeaderName, response.Headers[HttpResponseHeader.ContentEncoding]);
+ Assert.IsNull(response.Headers[HttpResponseHeader.ContentEncoding]);
+ Assert.AreEqual(encoding.HeaderName, new ContentType(response.Headers[HttpResponseHeader.ContentType]).CharSet);
}
}
}
diff --git a/src/DotNetOpenAuth.Test/OpenId/RelyingParty/PositiveAuthenticationResponseSnapshotTests.cs b/src/DotNetOpenAuth.Test/OpenId/RelyingParty/PositiveAuthenticationResponseSnapshotTests.cs
new file mode 100644
index 0000000..e069c44
--- /dev/null
+++ b/src/DotNetOpenAuth.Test/OpenId/RelyingParty/PositiveAuthenticationResponseSnapshotTests.cs
@@ -0,0 +1,39 @@
+//-----------------------------------------------------------------------
+// <copyright file="PositiveAuthenticationResponseSnapshotTests.cs" company="Andrew Arnott">
+// Copyright (c) Andrew Arnott. All rights reserved.
+// </copyright>
+//-----------------------------------------------------------------------
+
+namespace DotNetOpenAuth.Test.OpenId.RelyingParty {
+ using System.Collections.Generic;
+ using System.IO;
+ using System.Runtime.Serialization;
+ using System.Runtime.Serialization.Formatters.Binary;
+ using DotNetOpenAuth.OpenId;
+ using DotNetOpenAuth.OpenId.Messages;
+ using DotNetOpenAuth.OpenId.RelyingParty;
+ using Microsoft.VisualStudio.TestTools.UnitTesting;
+ using Moq;
+
+ [TestClass]
+ public class PositiveAuthenticationResponseSnapshotTests : OpenIdTestBase {
+ /// <summary>
+ /// Verifies that the PositiveAuthenticationResponseSnapshot is serializable,
+ /// as required by the <see cref="OpenIdRelyingPartyAjaxControlBase"/> class.
+ /// </summary>
+ [TestMethod]
+ public void Serializable() {
+ var response = new Mock<IAuthenticationResponse>(MockBehavior.Strict);
+ response.Setup(o => o.ClaimedIdentifier).Returns(VanityUri);
+ response.Setup(o => o.FriendlyIdentifierForDisplay).Returns(VanityUri.AbsoluteUri);
+ response.Setup(o => o.Status).Returns(AuthenticationStatus.Authenticated);
+ response.Setup(o => o.Provider).Returns(new ProviderEndpointDescription(OPUri, Protocol.Default.Version));
+ response.Setup(o => o.GetUntrustedCallbackArguments()).Returns(new Dictionary<string, string>());
+ response.Setup(o => o.GetCallbackArguments()).Returns(new Dictionary<string, string>());
+ var snapshot = new PositiveAuthenticationResponseSnapshot(response.Object);
+ MemoryStream ms = new MemoryStream();
+ IFormatter formatter = new BinaryFormatter();
+ formatter.Serialize(ms, snapshot);
+ }
+ }
+}
diff --git a/src/DotNetOpenAuth/Configuration/DotNetOpenAuth.xsd b/src/DotNetOpenAuth/Configuration/DotNetOpenAuth.xsd
index 18e1c5c..a9c5965 100644
--- a/src/DotNetOpenAuth/Configuration/DotNetOpenAuth.xsd
+++ b/src/DotNetOpenAuth/Configuration/DotNetOpenAuth.xsd
@@ -658,6 +658,14 @@
</xs:documentation>
</xs:annotation>
</xs:attribute>
+ <xs:attribute name="cacheDiscovery" type="xs:boolean">
+ <xs:annotation>
+ <xs:documentation>
+ Whether the results of identifier discovery should be cached for a short time to improve performance
+ on subsequent requests, at the potential risk of reading stale data.
+ </xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
</xs:complexType>
</xs:element>
<xs:element name="oauth">
diff --git a/src/DotNetOpenAuth/Configuration/DotNetOpenAuthSection.cs b/src/DotNetOpenAuth/Configuration/DotNetOpenAuthSection.cs
index aa956d1..117a542 100644
--- a/src/DotNetOpenAuth/Configuration/DotNetOpenAuthSection.cs
+++ b/src/DotNetOpenAuth/Configuration/DotNetOpenAuthSection.cs
@@ -51,7 +51,10 @@ namespace DotNetOpenAuth.Configuration {
/// Gets the configuration section from the .config file.
/// </summary>
public static DotNetOpenAuthSection Configuration {
- get { return (DotNetOpenAuthSection)ConfigurationManager.GetSection(SectionName) ?? new DotNetOpenAuthSection(); }
+ get {
+ Contract.Ensures(Contract.Result<DotNetOpenAuthSection>() != null);
+ return (DotNetOpenAuthSection)ConfigurationManager.GetSection(SectionName) ?? new DotNetOpenAuthSection();
+ }
}
/// <summary>
@@ -59,8 +62,14 @@ namespace DotNetOpenAuth.Configuration {
/// </summary>
[ConfigurationProperty(MessagingElementName)]
public MessagingElement Messaging {
- get { return (MessagingElement)this[MessagingElementName] ?? new MessagingElement(); }
- set { this[MessagingElementName] = value; }
+ get {
+ Contract.Ensures(Contract.Result<MessagingElement>() != null);
+ return (MessagingElement)this[MessagingElementName] ?? new MessagingElement();
+ }
+
+ set {
+ this[MessagingElementName] = value;
+ }
}
/// <summary>
@@ -68,8 +77,14 @@ namespace DotNetOpenAuth.Configuration {
/// </summary>
[ConfigurationProperty(OpenIdElementName)]
internal OpenIdElement OpenId {
- get { return (OpenIdElement)this[OpenIdElementName] ?? new OpenIdElement(); }
- set { this[OpenIdElementName] = value; }
+ get {
+ Contract.Ensures(Contract.Result<OpenIdElement>() != null);
+ return (OpenIdElement)this[OpenIdElementName] ?? new OpenIdElement();
+ }
+
+ set {
+ this[OpenIdElementName] = value;
+ }
}
/// <summary>
@@ -77,8 +92,14 @@ namespace DotNetOpenAuth.Configuration {
/// </summary>
[ConfigurationProperty(OAuthElementName)]
internal OAuthElement OAuth {
- get { return (OAuthElement)this[OAuthElementName] ?? new OAuthElement(); }
- set { this[OAuthElementName] = value; }
+ get {
+ Contract.Ensures(Contract.Result<OAuthElement>() != null);
+ return (OAuthElement)this[OAuthElementName] ?? new OAuthElement();
+ }
+
+ set {
+ this[OAuthElementName] = value;
+ }
}
/// <summary>
@@ -86,8 +107,14 @@ namespace DotNetOpenAuth.Configuration {
/// </summary>
[ConfigurationProperty(ReportingElementName)]
internal ReportingElement Reporting {
- get { return (ReportingElement)this[ReportingElementName] ?? new ReportingElement(); }
- set { this[ReportingElementName] = value; }
+ get {
+ Contract.Ensures(Contract.Result<ReportingElement>() != null);
+ return (ReportingElement)this[ReportingElementName] ?? new ReportingElement();
+ }
+
+ set {
+ this[ReportingElementName] = value;
+ }
}
}
}
diff --git a/src/DotNetOpenAuth/DotNetOpenAuth.csproj b/src/DotNetOpenAuth/DotNetOpenAuth.csproj
index d0c4d94..7f5b298 100644
--- a/src/DotNetOpenAuth/DotNetOpenAuth.csproj
+++ b/src/DotNetOpenAuth/DotNetOpenAuth.csproj
@@ -775,7 +775,31 @@ http://opensource.org/licenses/ms-pl.html
</BootstrapperPackage>
<Content Include="DotNetOpenAuth.ico" />
</ItemGroup>
- <ItemGroup />
+
+ <ItemGroup>
+ <SignDependsOn Include="BuildUnifiedProduct" />
+ <DelaySignedAssemblies Include="$(ILMergeOutputAssembly);
+ $(OutputPath)$(ProductName).Contracts.dll;
+ " />
+ </ItemGroup>
+ <PropertyGroup>
+ <!-- Don't sign the non-unified version of the assembly. -->
+ <SuppressTargetPathDelaySignedAssembly>true</SuppressTargetPathDelaySignedAssembly>
+ </PropertyGroup>
+
+ <Target Name="BuildUnifiedProduct"
+ DependsOnTargets="Build"
+ Inputs="@(ILMergeInputAssemblies)"
+ Outputs="$(ILMergeOutputAssembly)">
+ <MakeDir Directories="$(ILMergeOutputAssemblyDirectory)" />
+ <ILMerge ExcludeFile="$(ProjectRoot)ILMergeInternalizeExceptions.txt"
+ InputAssemblies="@(ILMergeInputAssemblies)"
+ OutputFile="$(ILMergeOutputAssembly)"
+ KeyFile="$(PublicKeyFile)"
+ DelaySign="true"
+ />
+ </Target>
+
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<Import Project="$(ProjectRoot)tools\DotNetOpenAuth.targets" />
-</Project> \ No newline at end of file
+</Project>
diff --git a/src/DotNetOpenAuth/Messaging/Channel.cs b/src/DotNetOpenAuth/Messaging/Channel.cs
index 1bddf02..7198c78 100644
--- a/src/DotNetOpenAuth/Messaging/Channel.cs
+++ b/src/DotNetOpenAuth/Messaging/Channel.cs
@@ -16,6 +16,7 @@ namespace DotNetOpenAuth.Messaging {
using System.Linq;
using System.Net;
using System.Net.Cache;
+ using System.Net.Mime;
using System.Text;
using System.Threading;
using System.Web;
@@ -39,6 +40,13 @@ namespace DotNetOpenAuth.Messaging {
protected internal const string HttpFormUrlEncoded = "application/x-www-form-urlencoded";
/// <summary>
+ /// The content-type used on HTTP POST requests where the POST entity is a
+ /// URL-encoded series of key=value pairs.
+ /// This includes the <see cref="PostEntityEncoding"/> character encoding.
+ /// </summary>
+ protected internal static readonly ContentType HttpFormUrlEncodedContentType = new ContentType(HttpFormUrlEncoded) { CharSet = PostEntityEncoding.WebName };
+
+ /// <summary>
/// The maximum allowable size for a 301 Redirect response before we send
/// a 200 OK response with a scripted form POST with the parameters instead
/// in order to ensure successfully sending a large payload to another server
@@ -927,15 +935,9 @@ namespace DotNetOpenAuth.Messaging {
Contract.Requires<ArgumentNullException>(httpRequest != null);
Contract.Requires<ArgumentNullException>(fields != null);
- httpRequest.ContentType = HttpFormUrlEncoded;
-
- // Setting the content-encoding to "utf-8" causes Google to reply
- // with a 415 UnsupportedMediaType. But adding it doesn't buy us
- // anything specific, so we disable it until we know how to get it right.
- ////httpRequest.Headers[HttpRequestHeader.ContentEncoding] = PostEntityEncoding.WebName;
-
string requestBody = MessagingUtilities.CreateQueryString(fields);
byte[] requestBytes = PostEntityEncoding.GetBytes(requestBody);
+ httpRequest.ContentType = HttpFormUrlEncodedContentType.ToString();
httpRequest.ContentLength = requestBytes.Length;
Stream requestStream = this.WebRequestHandler.GetRequestStream(httpRequest);
try {
diff --git a/src/DotNetOpenAuth/Messaging/HttpRequestInfo.cs b/src/DotNetOpenAuth/Messaging/HttpRequestInfo.cs
index 94990c8..6ce87a8 100644
--- a/src/DotNetOpenAuth/Messaging/HttpRequestInfo.cs
+++ b/src/DotNetOpenAuth/Messaging/HttpRequestInfo.cs
@@ -13,6 +13,7 @@ namespace DotNetOpenAuth.Messaging {
using System.Globalization;
using System.IO;
using System.Net;
+ using System.Net.Mime;
using System.ServiceModel.Channels;
using System.Web;
@@ -233,7 +234,8 @@ namespace DotNetOpenAuth.Messaging {
get {
Contract.Ensures(Contract.Result<NameValueCollection>() != null);
if (this.form == null) {
- if (this.HttpMethod == "POST" && this.Headers[HttpRequestHeader.ContentType] == Channel.HttpFormUrlEncoded) {
+ ContentType contentType = string.IsNullOrEmpty(this.Headers[HttpRequestHeader.ContentType]) ? null : new ContentType(this.Headers[HttpRequestHeader.ContentType]);
+ if (this.HttpMethod == "POST" && contentType != null && string.Equals(contentType.MediaType, Channel.HttpFormUrlEncoded, StringComparison.Ordinal)) {
StreamReader reader = new StreamReader(this.InputStream);
long originalPosition = 0;
if (this.InputStream.CanSeek) {
diff --git a/src/DotNetOpenAuth/Messaging/MessagingUtilities.cs b/src/DotNetOpenAuth/Messaging/MessagingUtilities.cs
index c29ec8c..a52f51b 100644
--- a/src/DotNetOpenAuth/Messaging/MessagingUtilities.cs
+++ b/src/DotNetOpenAuth/Messaging/MessagingUtilities.cs
@@ -14,6 +14,7 @@ namespace DotNetOpenAuth.Messaging {
using System.IO;
using System.Linq;
using System.Net;
+ using System.Net.Mime;
using System.Security;
using System.Security.Cryptography;
using System.Text;
@@ -106,14 +107,7 @@ namespace DotNetOpenAuth.Messaging {
Contract.Requires<InvalidOperationException>(HttpContext.Current != null && HttpContext.Current.Request != null, MessagingStrings.HttpContextRequired);
HttpContext context = HttpContext.Current;
- // We use Request.Url for the full path to the server, and modify it
- // with Request.RawUrl to capture both the cookieless session "directory" if it exists
- // and the original path in case URL rewriting is going on. We don't want to be
- // fooled by URL rewriting because we're comparing the actual URL with what's in
- // the return_to parameter in some cases.
- // Response.ApplyAppPathModifier(builder.Path) would have worked for the cookieless
- // session, but not the URL rewriting problem.
- return new Uri(context.Request.Url, context.Request.RawUrl);
+ return HttpRequestInfo.GetPublicFacingUrl(context.Request, context.Request.ServerVariables);
}
/// <summary>
@@ -198,20 +192,19 @@ namespace DotNetOpenAuth.Messaging {
string initialPartLeadingBoundary = string.Format(CultureInfo.InvariantCulture, "--{0}\r\n", boundary);
string partLeadingBoundary = string.Format(CultureInfo.InvariantCulture, "\r\n--{0}\r\n", boundary);
string finalTrailingBoundary = string.Format(CultureInfo.InvariantCulture, "\r\n--{0}--\r\n", boundary);
+ var contentType = new ContentType("multipart/form-data") {
+ Boundary = boundary,
+ CharSet = Channel.PostEntityEncoding.WebName,
+ };
request.Method = "POST";
- request.ContentType = "multipart/form-data; boundary=" + boundary;
+ request.ContentType = contentType.ToString();
long contentLength = parts.Sum(p => partLeadingBoundary.Length + p.Length) + finalTrailingBoundary.Length;
if (parts.Any()) {
contentLength -= 2; // the initial part leading boundary has no leading \r\n
}
request.ContentLength = contentLength;
- // Setting the content-encoding to "utf-8" causes Google to reply
- // with a 415 UnsupportedMediaType. But adding it doesn't buy us
- // anything specific, so we disable it until we know how to get it right.
- ////request.Headers[HttpRequestHeader.ContentEncoding] = Channel.PostEntityEncoding.WebName;
-
var requestStream = requestHandler.GetRequestStream(request);
try {
StreamWriter writer = new StreamWriter(requestStream, Channel.PostEntityEncoding);
diff --git a/src/DotNetOpenAuth/Messaging/OutgoingWebResponse.cs b/src/DotNetOpenAuth/Messaging/OutgoingWebResponse.cs
index 52d0e39..cf22bb2 100644
--- a/src/DotNetOpenAuth/Messaging/OutgoingWebResponse.cs
+++ b/src/DotNetOpenAuth/Messaging/OutgoingWebResponse.cs
@@ -10,6 +10,7 @@ namespace DotNetOpenAuth.Messaging {
using System.Diagnostics.Contracts;
using System.IO;
using System.Net;
+ using System.Net.Mime;
using System.Text;
using System.Threading;
using System.Web;
@@ -87,7 +88,7 @@ namespace DotNetOpenAuth.Messaging {
/// </summary>
public string Body {
get { return this.ResponseStream != null ? this.GetResponseReader().ReadToEnd() : null; }
- set { this.SetResponse(value); }
+ set { this.SetResponse(value, null); }
}
/// <summary>
@@ -205,13 +206,23 @@ namespace DotNetOpenAuth.Messaging {
/// Sets the response to some string, encoded as UTF-8.
/// </summary>
/// <param name="body">The string to set the response to.</param>
- internal void SetResponse(string body) {
+ /// <param name="contentType">Type of the content. May be null.</param>
+ internal void SetResponse(string body, ContentType contentType) {
if (body == null) {
this.ResponseStream = null;
return;
}
- this.Headers[HttpResponseHeader.ContentEncoding] = bodyStringEncoder.HeaderName;
+ if (contentType == null) {
+ contentType = new ContentType("text/html");
+ contentType.CharSet = bodyStringEncoder.WebName;
+ } else if (contentType.CharSet != bodyStringEncoder.WebName) {
+ // clone the original so we're not tampering with our inputs if it came as a parameter.
+ contentType = new ContentType(contentType.ToString());
+ contentType.CharSet = bodyStringEncoder.WebName;
+ }
+
+ this.Headers[HttpResponseHeader.ContentType] = contentType.ToString();
this.ResponseStream = new MemoryStream();
StreamWriter writer = new StreamWriter(this.ResponseStream, bodyStringEncoder);
writer.Write(body);
diff --git a/src/DotNetOpenAuth/OAuth/ChannelElements/OAuthChannel.cs b/src/DotNetOpenAuth/OAuth/ChannelElements/OAuthChannel.cs
index b0e938f..ed41183 100644
--- a/src/DotNetOpenAuth/OAuth/ChannelElements/OAuthChannel.cs
+++ b/src/DotNetOpenAuth/OAuth/ChannelElements/OAuthChannel.cs
@@ -13,6 +13,7 @@ namespace DotNetOpenAuth.OAuth.ChannelElements {
using System.IO;
using System.Linq;
using System.Net;
+ using System.Net.Mime;
using System.Text;
using System.Web;
using DotNetOpenAuth.Messaging;
@@ -141,9 +142,12 @@ namespace DotNetOpenAuth.OAuth.ChannelElements {
}
// Scrape the entity
- if (string.Equals(request.Headers[HttpRequestHeader.ContentType], HttpFormUrlEncoded, StringComparison.Ordinal)) {
- foreach (string key in request.Form) {
- fields.Add(key, request.Form[key]);
+ if (!string.IsNullOrEmpty(request.Headers[HttpRequestHeader.ContentType])) {
+ ContentType contentType = new ContentType(request.Headers[HttpRequestHeader.ContentType]);
+ if (string.Equals(contentType.MediaType, HttpFormUrlEncoded, StringComparison.Ordinal)) {
+ foreach (string key in request.Form) {
+ fields.Add(key, request.Form[key]);
+ }
}
}
diff --git a/src/DotNetOpenAuth/OAuth/ConsumerBase.cs b/src/DotNetOpenAuth/OAuth/ConsumerBase.cs
index 48f54d7..dddbe9e 100644
--- a/src/DotNetOpenAuth/OAuth/ConsumerBase.cs
+++ b/src/DotNetOpenAuth/OAuth/ConsumerBase.cs
@@ -224,7 +224,7 @@ namespace DotNetOpenAuth.OAuth {
// Fine-tune our understanding of the SP's supported OAuth version if it's wrong.
if (this.ServiceProvider.Version != requestTokenResponse.Version) {
- Logger.OAuth.WarnFormat("Expected OAuth service provider at endpoint {0} to use OAuth {1} but {2} was detected. Adjusting service description to new version.", this.ServiceProvider.RequestTokenEndpoint, this.ServiceProvider.Version, requestTokenResponse.Version);
+ Logger.OAuth.WarnFormat("Expected OAuth service provider at endpoint {0} to use OAuth {1} but {2} was detected. Adjusting service description to new version.", this.ServiceProvider.RequestTokenEndpoint.Location, this.ServiceProvider.Version, requestTokenResponse.Version);
this.ServiceProvider.ProtocolVersion = Protocol.Lookup(requestTokenResponse.Version).ProtocolVersion;
}
diff --git a/src/DotNetOpenAuth/OpenId/Extensions/AttributeExchange/AttributeRequest.cs b/src/DotNetOpenAuth/OpenId/Extensions/AttributeExchange/AttributeRequest.cs
index 358db9b..2dc9c69 100644
--- a/src/DotNetOpenAuth/OpenId/Extensions/AttributeExchange/AttributeRequest.cs
+++ b/src/DotNetOpenAuth/OpenId/Extensions/AttributeExchange/AttributeRequest.cs
@@ -15,6 +15,7 @@ namespace DotNetOpenAuth.OpenId.Extensions.AttributeExchange {
/// the Attribute Exchange extension.
/// </summary>
[Serializable]
+ [DebuggerDisplay("{TypeUri} (required: {IsRequired}) ({Count})")]
public class AttributeRequest {
/// <summary>
/// Backing field for the <see cref="Count"/> property.
diff --git a/src/DotNetOpenAuth/OpenId/Extensions/AttributeExchange/AttributeValues.cs b/src/DotNetOpenAuth/OpenId/Extensions/AttributeExchange/AttributeValues.cs
index 6466cda..b2fc1fe 100644
--- a/src/DotNetOpenAuth/OpenId/Extensions/AttributeExchange/AttributeValues.cs
+++ b/src/DotNetOpenAuth/OpenId/Extensions/AttributeExchange/AttributeValues.cs
@@ -7,6 +7,7 @@
namespace DotNetOpenAuth.OpenId.Extensions.AttributeExchange {
using System;
using System.Collections.Generic;
+ using System.Diagnostics;
using System.Diagnostics.Contracts;
using DotNetOpenAuth.Messaging;
@@ -16,6 +17,7 @@ namespace DotNetOpenAuth.OpenId.Extensions.AttributeExchange {
/// a fetch request, or by a relying party as part of a store request.
/// </summary>
[Serializable]
+ [DebuggerDisplay("{TypeUri}")]
public class AttributeValues {
/// <summary>
/// Initializes a new instance of the <see cref="AttributeValues"/> class.
diff --git a/src/DotNetOpenAuth/OpenId/Extensions/AttributeExchange/FetchRequest.cs b/src/DotNetOpenAuth/OpenId/Extensions/AttributeExchange/FetchRequest.cs
index a69e226..124a18c 100644
--- a/src/DotNetOpenAuth/OpenId/Extensions/AttributeExchange/FetchRequest.cs
+++ b/src/DotNetOpenAuth/OpenId/Extensions/AttributeExchange/FetchRequest.cs
@@ -8,6 +8,7 @@ namespace DotNetOpenAuth.OpenId.Extensions.AttributeExchange {
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
+ using System.Diagnostics.Contracts;
using System.Globalization;
using System.Linq;
using DotNetOpenAuth.Messaging;
@@ -67,7 +68,10 @@ namespace DotNetOpenAuth.OpenId.Extensions.AttributeExchange {
/// <value>A collection where the keys are the attribute type URIs, and the value
/// is all the attribute request details.</value>
public KeyedCollection<string, AttributeRequest> Attributes {
- get { return this.attributes; }
+ get {
+ Contract.Ensures(Contract.Result<KeyedCollection<string, AttributeRequest>>() != null);
+ return this.attributes;
+ }
}
/// <summary>
diff --git a/src/DotNetOpenAuth/OpenId/Extensions/AttributeExchange/FetchResponse.cs b/src/DotNetOpenAuth/OpenId/Extensions/AttributeExchange/FetchResponse.cs
index 758b20c..14b1caa 100644
--- a/src/DotNetOpenAuth/OpenId/Extensions/AttributeExchange/FetchResponse.cs
+++ b/src/DotNetOpenAuth/OpenId/Extensions/AttributeExchange/FetchResponse.cs
@@ -7,6 +7,7 @@
namespace DotNetOpenAuth.OpenId.Extensions.AttributeExchange {
using System;
using System.Collections.ObjectModel;
+ using System.Diagnostics.Contracts;
using System.Linq;
using DotNetOpenAuth.Messaging;
using DotNetOpenAuth.OpenId.Messages;
@@ -52,7 +53,10 @@ namespace DotNetOpenAuth.OpenId.Extensions.AttributeExchange {
/// Gets a sequence of the attributes whose values are provided by the OpenID Provider.
/// </summary>
public KeyedCollection<string, AttributeValues> Attributes {
- get { return this.attributesProvided; }
+ get {
+ Contract.Ensures(Contract.Result<KeyedCollection<string, AttributeValues>>() != null);
+ return this.attributesProvided;
+ }
}
/// <summary>
diff --git a/src/DotNetOpenAuth/OpenId/Identifier.cs b/src/DotNetOpenAuth/OpenId/Identifier.cs
index 548a673..2ab5360 100644
--- a/src/DotNetOpenAuth/OpenId/Identifier.cs
+++ b/src/DotNetOpenAuth/OpenId/Identifier.cs
@@ -68,6 +68,8 @@ namespace DotNetOpenAuth.OpenId {
[DebuggerStepThrough]
public static implicit operator Identifier(string identifier) {
Contract.Requires<ArgumentException>(identifier == null || identifier.Length > 0);
+ Contract.Ensures((identifier == null) == (Contract.Result<Identifier>() == null));
+
if (identifier == null) {
return null;
}
@@ -82,6 +84,7 @@ namespace DotNetOpenAuth.OpenId {
[SuppressMessage("Microsoft.Usage", "CA2225:OperatorOverloadsHaveNamedAlternates", Justification = "We have a Parse function.")]
[DebuggerStepThrough]
public static implicit operator Identifier(Uri identifier) {
+ Contract.Ensures((identifier == null) == (Contract.Result<Identifier>() == null));
if (identifier == null) {
return null;
}
@@ -97,7 +100,7 @@ namespace DotNetOpenAuth.OpenId {
[SuppressMessage("Microsoft.Usage", "CA2225:OperatorOverloadsHaveNamedAlternates", Justification = "We have a Parse function.")]
[DebuggerStepThrough]
public static implicit operator string(Identifier identifier) {
- Contract.Ensures((identifier == null && Contract.Result<string>() == null) || (identifier != null && Contract.Result<string>() != null));
+ Contract.Ensures((identifier == null) == (Contract.Result<string>() == null));
if (identifier == null) {
return null;
}
@@ -113,6 +116,8 @@ namespace DotNetOpenAuth.OpenId {
[SuppressMessage("Microsoft.Usage", "CA2234:PassSystemUriObjectsInsteadOfStrings", Justification = "Some of these identifiers are not properly formatted to be Uris at this stage.")]
public static Identifier Parse(string identifier) {
Contract.Requires<ArgumentException>(!String.IsNullOrEmpty(identifier));
+ Contract.Ensures(Contract.Result<Identifier>() != null);
+
if (XriIdentifier.IsValidXri(identifier)) {
return new XriIdentifier(identifier);
} else {
diff --git a/src/DotNetOpenAuth/OpenId/Provider/ProviderEndpoint.cs b/src/DotNetOpenAuth/OpenId/Provider/ProviderEndpoint.cs
index f778b76..445978e 100644
--- a/src/DotNetOpenAuth/OpenId/Provider/ProviderEndpoint.cs
+++ b/src/DotNetOpenAuth/OpenId/Provider/ProviderEndpoint.cs
@@ -43,7 +43,12 @@ namespace DotNetOpenAuth.OpenId.Provider {
/// <summary>
/// Backing field for the <see cref="Provider"/> property.
/// </summary>
- private static OpenIdProvider provider = CreateProvider();
+ private static OpenIdProvider provider;
+
+ /// <summary>
+ /// The lock that must be obtained when initializing the provider field.
+ /// </summary>
+ private static object providerInitializerLock = new object();
/// <summary>
/// Fired when an incoming OpenID request is an authentication challenge
@@ -64,6 +69,15 @@ namespace DotNetOpenAuth.OpenId.Provider {
/// <value>The default value is an <see cref="OpenIdProvider"/> instance initialized according to the web.config file.</value>
public static OpenIdProvider Provider {
get {
+ Contract.Ensures(Contract.Result<OpenIdProvider>() != null);
+ if (provider == null) {
+ lock (providerInitializerLock) {
+ if (provider == null) {
+ provider = CreateProvider();
+ }
+ }
+ }
+
return provider;
}
@@ -83,8 +97,14 @@ namespace DotNetOpenAuth.OpenId.Provider {
/// before responding to the relying party's authentication request.
/// </remarks>
public static IAuthenticationRequest PendingAuthenticationRequest {
- get { return HttpContext.Current.Session[PendingRequestKey] as IAuthenticationRequest; }
- set { HttpContext.Current.Session[PendingRequestKey] = value; }
+ get {
+ Contract.Ensures(Contract.Result<IAuthenticationRequest>() == null || PendingRequest != null);
+ return HttpContext.Current.Session[PendingRequestKey] as IAuthenticationRequest;
+ }
+
+ set {
+ HttpContext.Current.Session[PendingRequestKey] = value;
+ }
}
/// <summary>
@@ -97,8 +117,14 @@ namespace DotNetOpenAuth.OpenId.Provider {
/// before responding to the relying party's request.
/// </remarks>
public static IAnonymousRequest PendingAnonymousRequest {
- get { return HttpContext.Current.Session[PendingRequestKey] as IAnonymousRequest; }
- set { HttpContext.Current.Session[PendingRequestKey] = value; }
+ get {
+ Contract.Ensures(Contract.Result<IAnonymousRequest>() == null || PendingRequest != null);
+ return HttpContext.Current.Session[PendingRequestKey] as IAnonymousRequest;
+ }
+
+ set {
+ HttpContext.Current.Session[PendingRequestKey] = value;
+ }
}
/// <summary>
@@ -159,7 +185,7 @@ namespace DotNetOpenAuth.OpenId.Provider {
// Then try the configuration file specified one. Finally, use the default
// in-memory one that's built into OpenIdProvider.
// determine what incoming message was received
- IRequest request = provider.GetRequest();
+ IRequest request = Provider.GetRequest();
if (request != null) {
PendingRequest = null;
@@ -179,7 +205,7 @@ namespace DotNetOpenAuth.OpenId.Provider {
}
}
if (request.IsResponseReady) {
- provider.SendResponse(request);
+ Provider.SendResponse(request);
Page.Response.End();
PendingAuthenticationRequest = null;
}
@@ -218,6 +244,7 @@ namespace DotNetOpenAuth.OpenId.Provider {
/// </summary>
/// <returns>The new instance of OpenIdProvider.</returns>
private static OpenIdProvider CreateProvider() {
+ Contract.Ensures(Contract.Result<OpenIdProvider>() != null);
return new OpenIdProvider(DotNetOpenAuthSection.Configuration.OpenId.Provider.ApplicationStore.CreateInstance(OpenIdProvider.HttpApplicationStore));
}
}
diff --git a/src/DotNetOpenAuth/OpenId/ProviderEndpointDescription.cs b/src/DotNetOpenAuth/OpenId/ProviderEndpointDescription.cs
index bb4a9ba..6514ffd 100644
--- a/src/DotNetOpenAuth/OpenId/ProviderEndpointDescription.cs
+++ b/src/DotNetOpenAuth/OpenId/ProviderEndpointDescription.cs
@@ -21,6 +21,7 @@ namespace DotNetOpenAuth.OpenId {
/// <remarks>
/// This is an immutable type.
/// </remarks>
+ [Serializable]
internal sealed class ProviderEndpointDescription : IProviderEndpoint {
/// <summary>
/// Initializes a new instance of the <see cref="ProviderEndpointDescription"/> class.
diff --git a/src/DotNetOpenAuth/OpenId/Realm.cs b/src/DotNetOpenAuth/OpenId/Realm.cs
index 818718a..4137c72 100644
--- a/src/DotNetOpenAuth/OpenId/Realm.cs
+++ b/src/DotNetOpenAuth/OpenId/Realm.cs
@@ -112,6 +112,8 @@ namespace DotNetOpenAuth.OpenId {
public static Realm AutoDetect {
get {
Contract.Requires<InvalidOperationException>(HttpContext.Current != null && HttpContext.Current.Request != null, MessagingStrings.HttpContextRequired);
+ Contract.Ensures(Contract.Result<Realm>() != null);
+
HttpRequestInfo requestInfo = new HttpRequestInfo(HttpContext.Current.Request);
UriBuilder realmUrl = new UriBuilder(requestInfo.UrlBeforeRewriting);
realmUrl.Path = HttpContext.Current.Request.ApplicationPath;
@@ -252,6 +254,7 @@ namespace DotNetOpenAuth.OpenId {
[SuppressMessage("Microsoft.Usage", "CA2234:PassSystemUriObjectsInsteadOfStrings", Justification = "Not all Realms are valid URLs.")]
[DebuggerStepThrough]
public static implicit operator Realm(string uri) {
+ Contract.Ensures((Contract.Result<Realm>() != null) == (uri != null));
return uri != null ? new Realm(uri) : null;
}
@@ -262,6 +265,7 @@ namespace DotNetOpenAuth.OpenId {
/// <returns>The result of the conversion.</returns>
[DebuggerStepThrough]
public static implicit operator Realm(Uri uri) {
+ Contract.Ensures((Contract.Result<Realm>() != null) == (uri != null));
return uri != null ? new Realm(uri) : null;
}
@@ -272,6 +276,7 @@ namespace DotNetOpenAuth.OpenId {
/// <returns>The result of the conversion.</returns>
[DebuggerStepThrough]
public static implicit operator string(Realm realm) {
+ Contract.Ensures((Contract.Result<string>() != null) == (realm != null));
return realm != null ? realm.ToString() : null;
}
diff --git a/src/DotNetOpenAuth/OpenId/RelyingParty/OpenIdLogin.cs b/src/DotNetOpenAuth/OpenId/RelyingParty/OpenIdLogin.cs
index f89ec0a..c13c61c 100644
--- a/src/DotNetOpenAuth/OpenId/RelyingParty/OpenIdLogin.cs
+++ b/src/DotNetOpenAuth/OpenId/RelyingParty/OpenIdLogin.cs
@@ -643,11 +643,13 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
set {
base.UsePersistentCookie = value;
- // use conditional here to prevent infinite recursion
- // with CheckedChanged event.
- bool rememberMe = value != LogOnPersistence.Session;
- if (this.rememberMeCheckBox.Checked != rememberMe) {
- this.rememberMeCheckBox.Checked = rememberMe;
+ if (this.rememberMeCheckBox != null) {
+ // use conditional here to prevent infinite recursion
+ // with CheckedChanged event.
+ bool rememberMe = value != LogOnPersistence.Session;
+ if (this.rememberMeCheckBox.Checked != rememberMe) {
+ this.rememberMeCheckBox.Checked = rememberMe;
+ }
}
}
}
@@ -782,7 +784,7 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
cell = new TableCell();
this.rememberMeCheckBox = new CheckBox();
this.rememberMeCheckBox.Text = RememberMeTextDefault;
- this.rememberMeCheckBox.Checked = RememberMeDefault;
+ this.rememberMeCheckBox.Checked = this.UsePersistentCookie != LogOnPersistence.Session;
this.rememberMeCheckBox.Visible = RememberMeVisibleDefault;
this.rememberMeCheckBox.CheckedChanged += this.RememberMeCheckBox_CheckedChanged;
cell.Controls.Add(this.rememberMeCheckBox);
diff --git a/src/DotNetOpenAuth/OpenId/RelyingParty/OpenIdRelyingParty.cs b/src/DotNetOpenAuth/OpenId/RelyingParty/OpenIdRelyingParty.cs
index c9106de..a0a0fb9 100644
--- a/src/DotNetOpenAuth/OpenId/RelyingParty/OpenIdRelyingParty.cs
+++ b/src/DotNetOpenAuth/OpenId/RelyingParty/OpenIdRelyingParty.cs
@@ -109,7 +109,10 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
// replay attacks. But only 2.0+ Providers can be expected to provide
// replay protection.
if (nonceStore == null) {
- this.SecuritySettings.MinimumRequiredOpenIdVersion = ProtocolVersion.V20;
+ if (this.SecuritySettings.MinimumRequiredOpenIdVersion < ProtocolVersion.V20) {
+ Logger.OpenId.Warn("Raising minimum OpenID version requirement for Providers to 2.0 to protect this stateless RP from replay attacks.");
+ this.SecuritySettings.MinimumRequiredOpenIdVersion = ProtocolVersion.V20;
+ }
}
this.channel = new OpenIdChannel(associationStore, nonceStore, this.SecuritySettings);
diff --git a/src/DotNetOpenAuth/Reporting.cs b/src/DotNetOpenAuth/Reporting.cs
index 2235986..c4421c4 100644
--- a/src/DotNetOpenAuth/Reporting.cs
+++ b/src/DotNetOpenAuth/Reporting.cs
@@ -30,7 +30,27 @@ namespace DotNetOpenAuth {
/// The statistical reporting mechanism used so this library's project authors
/// know what versions and features are in use.
/// </summary>
- internal static class Reporting {
+ public static class Reporting {
+ /// <summary>
+ /// A value indicating whether reporting is desirable or not. Must be logical-AND'd with !<see cref="broken"/>.
+ /// </summary>
+ private static bool enabled;
+
+ /// <summary>
+ /// A value indicating whether reporting experienced an error and cannot be enabled.
+ /// </summary>
+ private static bool broken;
+
+ /// <summary>
+ /// A value indicating whether the reporting class has been initialized or not.
+ /// </summary>
+ private static bool initialized;
+
+ /// <summary>
+ /// The object to lock during initialization.
+ /// </summary>
+ private static object initializationSync = new object();
+
/// <summary>
/// The isolated storage to use for collecting data in between published reports.
/// </summary>
@@ -93,37 +113,31 @@ namespace DotNetOpenAuth {
[SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Justification = "Reporting MUST NOT cause unhandled exceptions.")]
static Reporting() {
Enabled = DotNetOpenAuthSection.Configuration.Reporting.Enabled;
- if (Enabled) {
- try {
- file = GetIsolatedStorage();
- reportOriginIdentity = GetOrCreateOriginIdentity();
-
- webRequestHandler = new StandardWebRequestHandler();
- observations.Add(observedRequests = new PersistentHashSet(file, "requests.txt", 3));
- observations.Add(observedCultures = new PersistentHashSet(file, "cultures.txt", 20));
- observations.Add(observedFeatures = new PersistentHashSet(file, "features.txt", int.MaxValue));
-
- // Record site-wide features in use.
- if (HttpContext.Current != null && HttpContext.Current.ApplicationInstance != null) {
- // MVC or web forms?
- // front-end or back end web farm?
- // url rewriting?
- ////RecordFeatureUse(IsMVC ? "ASP.NET MVC" : "ASP.NET Web Forms");
- }
- } catch (Exception e) {
- // This is supposed to be as low-risk as possible, so if it fails, just disable reporting
- // and avoid rethrowing.
- Enabled = false;
- Logger.Library.Error("Error while trying to initialize reporting.", e);
- }
- }
}
/// <summary>
/// Gets or sets a value indicating whether this reporting is enabled.
/// </summary>
/// <value><c>true</c> if enabled; otherwise, <c>false</c>.</value>
- internal static bool Enabled { get; set; }
+ /// <remarks>
+ /// Setting this property to <c>true</c> <i>may</i> have no effect
+ /// if reporting has already experienced a failure of some kind.
+ /// </remarks>
+ public static bool Enabled {
+ get {
+ return enabled && !broken;
+ }
+
+ set {
+ if (value) {
+ Initialize();
+ }
+
+ // Only set the static field here, so that other threads
+ // don't try to use reporting while we're initializing it.
+ enabled = value;
+ }
+ }
/// <summary>
/// Gets the configuration to use for reporting.
@@ -302,6 +316,40 @@ namespace DotNetOpenAuth {
}
/// <summary>
+ /// Initializes Reporting if it has not been initialized yet.
+ /// </summary>
+ private static void Initialize() {
+ lock (initializationSync) {
+ if (!broken && !initialized) {
+ try {
+ file = GetIsolatedStorage();
+ reportOriginIdentity = GetOrCreateOriginIdentity();
+
+ webRequestHandler = new StandardWebRequestHandler();
+ observations.Add(observedRequests = new PersistentHashSet(file, "requests.txt", 3));
+ observations.Add(observedCultures = new PersistentHashSet(file, "cultures.txt", 20));
+ observations.Add(observedFeatures = new PersistentHashSet(file, "features.txt", int.MaxValue));
+
+ // Record site-wide features in use.
+ if (HttpContext.Current != null && HttpContext.Current.ApplicationInstance != null) {
+ // MVC or web forms?
+ // front-end or back end web farm?
+ // url rewriting?
+ ////RecordFeatureUse(IsMVC ? "ASP.NET MVC" : "ASP.NET Web Forms");
+ }
+
+ initialized = true;
+ } catch (Exception e) {
+ // This is supposed to be as low-risk as possible, so if it fails, just disable reporting
+ // and avoid rethrowing.
+ broken = true;
+ Logger.Library.Error("Error while trying to initialize reporting.", e);
+ }
+ }
+ }
+ }
+
+ /// <summary>
/// Assembles a report for submission.
/// </summary>
/// <returns>A stream that contains the report.</returns>
@@ -459,7 +507,7 @@ namespace DotNetOpenAuth {
} catch (Exception ex) {
// Something bad and unexpected happened. Just deactivate to avoid more trouble.
Logger.Library.Error("Error while trying to submit statistical report.", ex);
- Enabled = false;
+ broken = true;
}
});
}
diff --git a/tools/Documentation.targets b/tools/Documentation.targets
index dff4d88..faf1f75 100644
--- a/tools/Documentation.targets
+++ b/tools/Documentation.targets
@@ -5,7 +5,6 @@
<ProjectRoot Condition="'$(ProjectRoot)' == ''">$(MSBuildProjectDirectory)\..\..\</ProjectRoot>
<OutputAssembly>DotNetOpenAuth</OutputAssembly>
<DocOutputPath>$(ProjectRoot)doc\</DocOutputPath>
- <IntermediatePath>$(ProjectRoot)obj\$(Configuration)\</IntermediatePath>
<DocumentationFile>$(OutputPath)$(OutputAssembly).xml</DocumentationFile>
</PropertyGroup>
diff --git a/tools/DotNetOpenAuth.automated.props b/tools/DotNetOpenAuth.automated.props
new file mode 100644
index 0000000..f66c1fe
--- /dev/null
+++ b/tools/DotNetOpenAuth.automated.props
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="4.0">
+ <Import Project="DotNetOpenAuth.props"/>
+
+ <PropertyGroup>
+ <AutomatedBuild>true</AutomatedBuild>
+ <SolutionPath>$(ProjectRoot)src\$(ProductName).sln</SolutionPath>
+ <BuildInParallel Condition=" '$(BuildInParallel)' == '' ">true</BuildInParallel>
+ <!-- Validation controls whether extra builds are done in order to fully validate what we're distributing,
+ even if we're not distributing the built bits (as is the case for project templates). -->
+ <Validation Condition=" '$(Validation)' == '' ">Full</Validation>
+ </PropertyGroup>
+</Project>
diff --git a/tools/DotNetOpenAuth.automated.targets b/tools/DotNetOpenAuth.automated.targets
new file mode 100644
index 0000000..5333b34
--- /dev/null
+++ b/tools/DotNetOpenAuth.automated.targets
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="4.0" InitialTargets="_SetDropProperties">
+ <Import Project="$(ProjectRoot)tools\$(ProductName).targets"/>
+ <UsingTask AssemblyFile="$(ProjectRoot)lib\MSBuild.Community.Tasks.dll" TaskName="Zip"/>
+ <UsingTask AssemblyFile="$(ProjectRoot)lib\MSBuild.Community.Tasks.dll" TaskName="NUnit" />
+
+ <Target Name="Rebuild" DependsOnTargets="Clean;Build"/>
+
+ <Target Name="Clean">
+ <ItemGroup>
+ <ProjectsToClean>
+ <Targets Condition=" '%(ProjectsToClean.Targets)' == '' ">Clean</Targets>
+ </ProjectsToClean>
+ </ItemGroup>
+
+ <Delete Files="@(FilesToClean)" />
+ <RemoveDir Directories="@(DirectoriesToClean)" />
+ <MSBuild Projects="@(ProjectsToClean)" Targets="%(ProjectsToClean.Targets)" BuildInParallel="$(BuildInParallel)" />
+ </Target>
+
+ <Target Name="_SetDropProperties" DependsOnTargets="GetBuildVersion">
+ <!-- This target is necessary because PropertyGroups within the same Target as
+ where CallTarget is fired do NOT affect those called targets. -->
+ <!-- The rest of these are here so that other DependsOn targets have access to these properties. -->
+ <PropertyGroup>
+ <DropDirectoryNoSlash>$(DropsRoot)$(ProductName)-$(BuildVersion)</DropDirectoryNoSlash>
+ <DropDirectory>$(DropDirectoryNoSlash)\</DropDirectory>
+ </PropertyGroup>
+ </Target>
+
+ <Target Name="SkipVerification" Condition="'$(IsElevated)' == 'true'">
+ <SignatureVerification SkipVerification="true" AssemblyName="*" PublicKeyToken="$(PublicKeyToken)" />
+ </Target>
+
+ <Target Name="BuildProduct" DependsOnTargets="SkipVerification">
+ <MSBuild BuildInParallel="$(BuildInParallel)"
+ Projects="$(ProjectRoot)src\$(ProductName)\$(ProductName).csproj" />
+ </Target>
+
+ <Target Name="BuildUnifiedProduct" DependsOnTargets="BuildProduct">
+ <MSBuild BuildInParallel="$(BuildInParallel)"
+ Projects="$(ProjectRoot)src\$(ProductName)\$(ProductName).csproj"
+ Targets="BuildUnifiedProduct" />
+ </Target>
+</Project>
diff --git a/tools/DotNetOpenAuth.props b/tools/DotNetOpenAuth.props
index a3ad973..6815fca 100644
--- a/tools/DotNetOpenAuth.props
+++ b/tools/DotNetOpenAuth.props
@@ -4,13 +4,14 @@
<ProductName>DotNetOpenAuth</ProductName>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<TargetFrameworkVersion Condition=" '$(TargetFrameworkVersion)' == '' ">v3.5</TargetFrameworkVersion>
- <ProjectRoot Condition="'$(ProjectRoot)' == ''">$(MSBuildProjectDirectory)\</ProjectRoot>
- <DropsRoot>$(ProjectRoot)drops\$(Configuration)\</DropsRoot>
+ <ProjectRoot Condition="'$(ProjectRoot)' == ''">$([System.IO.Path]::GetFullPath('$(MSBuildThisFileDirectory)..\'))</ProjectRoot>
+ <DropsRoot>$(ProjectRoot)drops\$(TargetFrameworkVersion)\$(Configuration)\</DropsRoot>
<OutputPath>$(ProjectRoot)bin\$(TargetFrameworkVersion)\$(Configuration)\</OutputPath>
<DocOutputPath>$(ProjectRoot)doc\</DocOutputPath>
<IntermediatePath>$(ProjectRoot)obj\$(TargetFrameworkVersion)\$(Configuration)\</IntermediatePath>
<BaseIntermediateOutputPath Condition=" '$(BaseIntermediateOutputPath)' == '' ">obj\$(TargetFrameworkVersion)\</BaseIntermediateOutputPath>
<ToolsDir>$(ProjectRoot)tools\</ToolsDir>
+ <ZipLevel>6</ZipLevel>
<ClrVersion Condition=" '$(TargetFrameworkVersion)' == 'v4.0' ">4</ClrVersion>
<ClrVersion Condition=" '$(TargetFrameworkVersion)' != 'v4.0' ">2</ClrVersion>
@@ -20,8 +21,18 @@
<KeyPairContainer Condition="'$(KeyPairContainer)' == ''">DotNetOpenAuth</KeyPairContainer>
<PublicKeyToken>2780CCD10D57B246</PublicKeyToken>
<DelaySign>true</DelaySign>
+ <SignedSubPath>signed\</SignedSubPath>
+
+ <ILMergeOutputAssemblyDirectory>$(OutputPath)unified\</ILMergeOutputAssemblyDirectory>
+ <ILMergeOutputAssembly>$(ILMergeOutputAssemblyDirectory)$(ProductName).dll</ILMergeOutputAssembly>
</PropertyGroup>
+ <ItemGroup>
+ <SignDependsOn Include="Build" />
+ <ILMergeInputAssemblies Include="$(OutputPath)$(ProductName).dll;
+ $(ProjectRoot)lib\Microsoft.Contracts.dll; "/>
+ </ItemGroup>
+
<Import Project="$(ProjectRoot)lib\DotNetOpenAuth.BuildTasks.targets" />
<Target Name="InitializeProps">
diff --git a/tools/DotNetOpenAuth.targets b/tools/DotNetOpenAuth.targets
index 9a2c6f9..cab4413 100644
--- a/tools/DotNetOpenAuth.targets
+++ b/tools/DotNetOpenAuth.targets
@@ -2,12 +2,27 @@
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="4.0">
<Import Project="DotNetOpenAuth.Versioning.targets" />
<Import Project="JavascriptPacker.targets" />
+ <UsingTask AssemblyFile="$(ProjectRoot)lib\MSBuild.Community.Tasks.dll" TaskName="ILMerge"/>
+
+ <!-- Prevent our own item types from appearing in Solution Explorer. -->
+ <ItemDefinitionGroup>
+ <SignDependsOn>
+ <Visible>false</Visible>
+ </SignDependsOn>
+ <DelaySignedAssemblies>
+ <Visible>false</Visible>
+ </DelaySignedAssemblies>
+ </ItemDefinitionGroup>
<PropertyGroup>
<DefineConstants Condition=" '$(SignAssembly)' == 'true' ">$(DefineConstants);StrongNameSigned</DefineConstants>
<DefineConstants Condition=" '$(ClrVersion)' == '4' ">$(DefineConstants);CLR4</DefineConstants>
</PropertyGroup>
+ <ItemGroup>
+ <DelaySignedAssemblies Include="$(TargetPath)" Condition=" '$(SuppressTargetPathDelaySignedAssembly)' != 'true' "/>
+ </ItemGroup>
+
<ItemGroup Condition=" '$(ClrVersion)' != '4' ">
<Reference Include="Microsoft.Contracts, Version=1.0.0.0, Culture=neutral, PublicKeyToken=736440c9b414ea16, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
@@ -48,4 +63,58 @@
<Output TaskParameter="AccessorAssembly" ItemName="ReferencePath" />
</Publicize>
</Target>
+
+ <Target Name="Sign" DependsOnTargets="@(SignDependsOn)" Outputs="@(SignedDependencies);@(SignedAssemblyTargets)" Condition=" '@(DelaySignedAssemblies)' != '' ">
+ <!-- Make sure that all dependencies are also signed. -->
+ <MSBuild Projects="@(ProjectReference)" Targets="Sign" BuildInParallel="$(BuildInParallel)">
+ <Output TaskParameter="TargetOutputs" ItemName="SignedDependencies"/>
+ </MSBuild>
+
+ <!-- Add the resource assemblies. -->
+ <ItemGroup>
+ <!-- Make sure that we consider the TargetPath's satellites even if TargetPath itself was suppressed. -->
+ <DelaySignedAssembliesForSatellites Include="@(DelaySignedAssemblies)" />
+ <DelaySignedAssembliesForSatellites Include="$(TargetPath)" Condition=" '$(SuppressTargetPathDelaySignedAssembly)' == 'true' "/>
+ </ItemGroup>
+ <PropertyGroup>
+ <DelaySignedSatelliteAssembliesPattern>@(DelaySignedAssembliesForSatellites->'%(RootDir)%(Directory)*\%(FileName).resources.*')</DelaySignedSatelliteAssembliesPattern>
+ </PropertyGroup>
+ <ItemGroup>
+ <DelaySignedSatelliteAssemblies Include="$(DelaySignedSatelliteAssembliesPattern)" />
+ <DelaySignedSatelliteAssemblies>
+ <CultureDir>$([System.IO.Path]::GetFileName($([System.IO.Path]::GetDirectoryName('%(Directory)'))))\</CultureDir>
+ </DelaySignedSatelliteAssemblies>
+ </ItemGroup>
+
+ <!-- Don't sign assemblies in place. Lots of reasons for this, not the least of which is that
+ subsequent builds of web site projects will cause the satellite assemblies to be regenerated (bizarre)
+ and erase the signature. -->
+ <ItemGroup>
+ <AssembliesToSign Include="@(DelaySignedAssemblies);@(DelaySignedSatelliteAssemblies)" />
+ <SignedAssemblyTargets Include="@(AssembliesToSign->'%(RootDir)%(Directory)$(SignedSubPath)%(FileName)%(Extension)')">
+ <UnsignedAssemblyPath>%(AssembliesToSign.Identity)</UnsignedAssemblyPath>
+ <SymbolPath Condition="Exists('%(RootDir)%(Directory)%(FileName).pdb')">%(RootDir)%(Directory)%(FileName).pdb</SymbolPath>
+ </SignedAssemblyTargets>
+ </ItemGroup>
+
+ <Message Text="Signing delay-signed assemblies using key pair container $(KeyPairContainer)." />
+ <Copy SourceFiles="@(AssembliesToSign)" DestinationFiles="@(SignedAssemblyTargets)" />
+ <ReSignDelaySignedAssemblies
+ KeyContainer="$(KeyPairContainer)"
+ Assemblies="@(SignedAssemblyTargets)"
+ Condition="Exists(%(Identity))" />
+ </Target>
+
+ <Target Name="ResignDelaySignedAssemblies" Outputs="@(ResignedAssembliesOutputs)">
+ <ItemGroup>
+ <DelaySignedProjects Include="
+ $(ProjectRoot)src\dotnetopenauth\dotnetopenauth.csproj;
+ $(ProjectRoot)src\dotnetopenauth.test\dotnetopenauth.test.csproj;
+ $(ProjectRoot)samples\openidofflineprovider\openidofflineprovider.csproj;
+ " />
+ </ItemGroup>
+ <MSBuild Projects="@(DelaySignedProjects)" Targets="Sign" BuildInParallel="$(BuildInParallel)">
+ <Output TaskParameter="TargetOutputs" ItemName="ResignedAssembliesOutputs"/>
+ </MSBuild>
+ </Target>
</Project>
diff --git a/tools/drop.proj b/tools/drop.proj
new file mode 100644
index 0000000..02fdd20
--- /dev/null
+++ b/tools/drop.proj
@@ -0,0 +1,146 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <Import Project="$(MSBuildProjectDirectory)\DotNetOpenAuth.automated.props"/>
+
+ <Target Name="Layout" DependsOnTargets="BuildUnifiedProduct;ReSignDelaySignedAssemblies">
+ <!-- Note that we use an MSBuild task for these dependencies rather than individual DependsOnTargets entries
+ so that these builds can be executed in parallel. -->
+ <MSBuild BuildInParallel="$(BuildInParallel)"
+ Projects="
+ $(ProjectRoot)samples\samples.proj;
+ $(ProjectRoot)vsi\vsi.proj;
+ $(ProjectRoot)vsix\vsix.proj;
+ $(ProjectRoot)doc\doc.proj;
+ ">
+ <Output TaskParameter="TargetOutputs" ItemName="DropLayoutDependencies"/>
+ </MSBuild>
+ <PropertyGroup>
+ <DropBinDirectory>$(DropDirectory)Bin\</DropBinDirectory>
+ <DropLibDirectory>$(DropDirectory)Lib\</DropLibDirectory>
+ <DropProjectTemplatesDirectory>$(DropDirectory)Project Templates\</DropProjectTemplatesDirectory>
+ <DropSamplesDirectory>$(DropDirectory)Samples\</DropSamplesDirectory>
+ <DropSpecsDirectory>$(DropDirectory)Specs\</DropSpecsDirectory>
+ </PropertyGroup>
+ <ItemGroup>
+ <ExtensionVsix Include="@(DropLayoutDependencies)" Condition=" '%(DropLayoutDependencies.MSBuildSourceProjectFile)' == '$(ProjectRoot)vsix\vsix.proj' " />
+ <ProjectTemplatesVsi Include="@(DropLayoutDependencies)" Condition=" '%(DropLayoutDependencies.MSBuildSourceProjectFile)' == '$(ProjectRoot)vsi\vsi.proj' " />
+ <DropDirectories Include="
+ $(DropDirectory);
+ $(DropBinDirectory);
+ $(DropLibDirectory);
+ $(DropProjectTemplatesDirectory);
+ $(DropSamplesDirectory);
+ $(DropSpecsDirectory);
+ " />
+
+ <DropSourceFiles Include="
+ $(ProjectRoot)Doc\$(ProductName).chm;
+ $(ProjectRoot)Doc\*.htm*;
+ $(ProjectRoot)LICENSE.txt;
+ $(ProjectRoot)CONTRIB.txt;
+ "
+ Exclude="$(ProjectRoot)Doc\README.*.html;" />
+ <DropBinSourceFiles Include="
+ $(ILMergeOutputAssemblyDirectory)$(SignedSubPath)$(ProductName).???;
+ $(OutputPath)$(ProductName).xml;
+ $(OutputPath)$(SignedSubPath)$(ProductName).Contracts.???;
+ $(ProjectRoot)Doc\README.Bin.html;
+ $(ProjectRoot)src\$(ProductName)\Configuration\$(ProductName).xsd;
+ " />
+ <DropSatelliteSourceFiles Include="$(OutputPath)**\$(SignedSubPath)$(ProductName).resources.dll" />
+ <DropSatelliteSourceFiles>
+ <CultureDir>$([System.IO.Path]::GetDirectoryName('$([System.IO.Path]::GetDirectoryName('%(RecursiveDir)'))'))\</CultureDir>
+ </DropSatelliteSourceFiles>
+ <DropLibSourceFiles Include="
+ $(ProjectRoot)Lib\log4net.*;
+ " />
+ <DropProjectTemplatesSourceFiles Include="@(ProjectTemplatesVsi)" />
+ <DropVsixSourceFiles Include="@(ExtensionVsix)" Condition=" '%(ExtensionVsix.IncludeInDrop)' == 'true' " />
+ <DropSamplesSourceFiles Include="$(ProjectRoot)Samples\**" Exclude="
+ $(ProjectRoot)**\obj\**;
+ $(ProjectRoot)**\*.sln.cache;
+ $(ProjectRoot)**\*.suo;
+ $(ProjectRoot)**\*.user;
+ $(ProjectRoot)**\*.gitignore;
+ $(ProjectRoot)**\*.ldf;
+ $(ProjectRoot)**\*.log*;
+ $(ProjectRoot)**\*~;
+ $(ProjectRoot)**\Debug\**;
+ $(ProjectRoot)**\Settings.StyleCop;
+ $(ProjectRoot)**\StyleCop.Cache;
+ $(ProjectRoot)Samples\**\DotNetOpenAuth.???;
+ $(ProjectRoot)Samples\**\DotNetOpenAuth.resources.???;
+ $(ProjectRoot)Samples\**\log4net.???;
+ $(ProjectRoot)Samples\**\PresentationCore.dll;
+ $(ProjectRoot)Samples\**\System.Printing.dll;
+ $(ProjectRoot)Samples\**\*.refresh_;
+ $(ProjectRoot)Samples\*.proj;
+ " />
+ <!-- Some .refresh files are only applicable to drop builds, so we rename them from *.refresh_ -->
+ <DropSamplesRefreshSourceFiles Include="$(ProjectRoot)Samples\**\*.refresh_" />
+ <DropSpecsSourceFiles Include="$(ProjectRoot)Doc\specs\*.htm*" />
+
+ <DropFiles Include="@(DropSourceFiles->'$(DropDirectory)%(RecursiveDir)%(FileName)%(Extension)')"/>
+ <DropBinFiles Include="@(DropBinSourceFiles->'$(DropBinDirectory)%(RecursiveDir)%(FileName)%(Extension)')"/>
+ <DropSatelliteFiles Include="@(DropSatelliteSourceFiles->'$(DropBinDirectory)%(CultureDir)%(FileName)%(Extension)')" />
+ <DropLibFiles Include="@(DropLibSourceFiles->'$(DropLibDirectory)%(RecursiveDir)%(FileName)%(Extension)')"/>
+ <DropProjectTemplatesFiles Include="@(DropProjectTemplatesSourceFiles->'$(DropProjectTemplatesDirectory)%(FileName)%(Extension)')" />
+ <DropVsixFiles Include="@(DropVsixSourceFiles->'$(DropProjectTemplatesDirectory)%(FileName)%(Extension)')" />
+ <DropSamplesFiles Include="@(DropSamplesSourceFiles->'$(DropSamplesDirectory)%(RecursiveDir)%(FileName)%(Extension)')"/>
+ <DropSamplesRefreshFiles Include="@(DropSamplesRefreshSourceFiles->'$(DropSamplesDirectory)%(RecursiveDir)%(FileName).refresh')"/>
+ <DropSamplesToolsProjects Include="$(DropSamplesDirectory)OpenIdOfflineProvider\OpenIdOfflineProvider.csproj" />
+ <DropSpecsFiles Include="@(DropSpecsSourceFiles->'$(DropSpecsDirectory)%(RecursiveDir)%(FileName)%(Extension)')"/>
+
+ <AllDropSources Include="
+ @(DropSourceFiles);
+ @(DropBinSourceFiles);
+ @(DropSatelliteSourceFiles);
+ @(DropLibSourceFiles);
+ @(DropProjectTemplatesSourceFiles);
+ @(DropVsixSourceFiles);
+ @(DropSamplesSourceFiles);
+ @(DropSamplesRefreshSourceFiles);
+ @(DropDocSourceFiles);
+ @(DropSpecsSourceFiles);
+ " />
+
+ <AllDropTargets Include="
+ @(DropFiles);
+ @(DropBinFiles);
+ @(DropSatelliteFiles);
+ @(DropLibFiles);
+ @(DropProjectTemplatesFiles);
+ @(DropVsixFiles);
+ @(DropSamplesFiles);
+ @(DropSamplesRefreshFiles);
+ @(DropDocFiles);
+ @(DropSpecsFiles)
+ " />
+ </ItemGroup>
+
+ <!-- clean up any previous drop with the same name so we don't aggregate files. -->
+ <MakeDir Directories="@(DropDirectories)" />
+ <Copy SourceFiles="@(AllDropSources)" DestinationFiles="@(AllDropTargets)" SkipUnchangedFiles="true" />
+ <Purge Directories="$(DropDirectory)" IntendedFiles="@(AllDropTargets)" />
+ <!-- fix up the samples so that they will compile right out of the drop -->
+ <ItemGroup>
+ <SampleProjectTargets Include="$(DropSamplesDirectory)**\*.*proj" />
+ <SampleSolutionTargets Include="$(DropSamplesDirectory)**\*.sln" />
+ </ItemGroup>
+ <FixupShippingToolSamples Projects="@(DropSamplesToolsProjects)"
+ RemoveImportsStartingWith="%24(ProjectRoot)tools\"
+ AddReferences="Microsoft.Contracts"/>
+ <ChangeProjectReferenceToAssemblyReference Projects="@(SampleProjectTargets)"
+ ProjectReferences="..\..\src\$(ProductName)\$(ProductName).csproj" References="..\..\Bin\$(ProductName).dll" />
+ <DowngradeProjects Projects="@(SampleProjectTargets);@(SampleSolutionTargets)" DowngradeMvc2ToMvc1="true" />
+ </Target>
+
+ <Target Name="Build" DependsOnTargets="Layout">
+ <PropertyGroup>
+ <DropZip>$(DropDirectoryNoSlash).zip</DropZip>
+ </PropertyGroup>
+ <Zip Files="@(AllDropTargets)" ZipFileName="$(DropZip)" WorkingDirectory="$(DropsRoot)" ZipLevel="$(ZipLevel)" />
+ </Target>
+
+ <Import Project="$(ProjectRoot)tools\DotNetOpenAuth.automated.targets"/>
+</Project> \ No newline at end of file
diff --git a/vsi/vsi.proj b/vsi/vsi.proj
new file mode 100644
index 0000000..be0c73b
--- /dev/null
+++ b/vsi/vsi.proj
@@ -0,0 +1,52 @@
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <Import Project="$(MSBuildProjectDirectory)\..\tools\DotNetOpenAuth.automated.props"/>
+ <Import Project="..\projecttemplates\ProjectTemplates.props"/>
+
+ <PropertyGroup>
+ <ProjectTemplatesVsiDirectory>$(IntermediatePath)vsi\</ProjectTemplatesVsiDirectory>
+ </PropertyGroup>
+
+ <ItemGroup>
+ <DirectoriesToClean Include="$(ProjectTemplatesLayoutPath)" />
+ <ProjectTemplates Include="$(ProjectRoot)projecttemplates\**\*.*proj" />
+ </ItemGroup>
+
+ <Target Name="Build" Returns="$(ProjectTemplatesVsi)">
+ <MSBuild Projects="..\projecttemplates\projecttemplates.proj" Targets="Zip2008" BuildInParallel="$(BuildInParallel)">
+ <Output TaskParameter="TargetOutputs" ItemName="ProjectTemplate2008ZipSource"/>
+ </MSBuild>
+
+ <PropertyGroup>
+ <ProjectTemplatesVsi>$(DropDirectoryNoSlash).vsi</ProjectTemplatesVsi>
+ </PropertyGroup>
+ <ItemGroup>
+ <VsiTransformSource Include="*.vscontent">
+ <BeforeTokens>$version$</BeforeTokens>
+ <AfterTokens>$(BuildVersion)</AfterTokens>
+ <SkipUnchangedFiles>false</SkipUnchangedFiles>
+ </VsiTransformSource>
+ <VsiTransformLayout Include="@(VsiTransformSource->'$(ProjectTemplatesVsiDirectory)%(RecursiveDir)%(FileName)%(Extension)')" />
+
+ <ProjectTemplate2008ZipSource>
+ <HardLink>true</HardLink>
+ </ProjectTemplate2008ZipSource>
+ <ProjectTemplate2008ZipTargets Include="@(ProjectTemplate2008ZipSource->'$(ProjectTemplatesVsiDirectory)%(FileName)%(Extension)')" />
+ <ProjectTemplateVsiContents Include="
+ @(VsiTransformLayout);
+ @(ProjectTemplate2008ZipTargets);
+ " />
+ </ItemGroup>
+
+ <CopyWithTokenSubstitution SourceFiles="@(VsiTransformSource)" DestinationFiles="@(VsiTransformLayout)" />
+ <HardLinkCopy SourceFiles="@(ProjectTemplate2008ZipSource)" DestinationFiles="@(ProjectTemplate2008ZipTargets)" />
+
+ <Zip
+ Files="@(ProjectTemplateVsiContents)"
+ ZipFileName="$(ProjectTemplatesVsi)"
+ WorkingDirectory="$(ProjectTemplatesVsiDirectory)"
+ ZipLevel="$(ZipLevel)"
+ />
+ </Target>
+
+ <Import Project="$(ProjectRoot)tools\DotNetOpenAuth.automated.targets"/>
+</Project> \ No newline at end of file
diff --git a/vsix/DotNetOpenAuthSDK.pkgdef b/vsix/DotNetOpenAuthSDK.pkgdef
deleted file mode 100644
index 1a515e1..0000000
--- a/vsix/DotNetOpenAuthSDK.pkgdef
+++ /dev/null
@@ -1,5 +0,0 @@
-[$RootKey$\Packages\{d2122791-8de4-4d3b-a414-7563c9a8cd6e}]
-@="Hey there"
-
-;[HKEY_CURRENT_USER\Software\Microsoft\.NETFramework\v2.0.50727\AssemblyFoldersEx\DotNetOpenAuth SDK]
-;@="$PackageFolder$" \ No newline at end of file
diff --git a/vsix/extension.vsixmanifest b/vsix/extension.vsixmanifest
index 4bb59dc..20c2472 100644
--- a/vsix/extension.vsixmanifest
+++ b/vsix/extension.vsixmanifest
@@ -23,6 +23,6 @@
<References />
<Content>
<ProjectTemplate>PT</ProjectTemplate>
- <VsPackage>DotNetOpenAuthSDK.pkgdef</VsPackage>
+ <!--<VsPackage>DotNetOpenAuthSDK.pkgdef</VsPackage>-->
</Content>
</Vsix>
diff --git a/vsix/vsix.proj b/vsix/vsix.proj
new file mode 100644
index 0000000..dcd0e85
--- /dev/null
+++ b/vsix/vsix.proj
@@ -0,0 +1,131 @@
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <Import Project="$(MSBuildProjectDirectory)\..\tools\DotNetOpenAuth.automated.props"/>
+ <Import Project="..\projecttemplates\ProjectTemplates.props"/>
+
+ <PropertyGroup>
+ <ExtensionVsixLayoutDirectory>$(IntermediatePath)vsix\</ExtensionVsixLayoutDirectory>
+ <ProjectTemplateSubdirectory>$(ExtensionVsixLayoutDirectory)PT\CSharp\Web\</ProjectTemplateSubdirectory>
+ </PropertyGroup>
+
+ <Target Name="Layout">
+ <MSBuild Projects="..\projecttemplates\projecttemplates.proj" Targets="Zip" BuildInParallel="$(BuildInParallel)">
+ <Output TaskParameter="TargetOutputs" ItemName="ProjectTemplateZipSource"/>
+ </MSBuild>
+
+ <ItemGroup>
+ <ProjectTemplateZipSource>
+ <HardLink>true</HardLink>
+ </ProjectTemplateZipSource>
+ <ProjectTemplateZipTargets Include="@(ProjectTemplateZipSource->'$(ProjectTemplateSubdirectory)%(FileName)%(Extension)')" />
+
+ <ExtensionVsixTransformSource Include="
+ $(ProjectRoot)vsix\extension.vsixmanifest;
+ $(ProjectRoot)LICENSE.txt;
+ ">
+ <BeforeTokens>$version$</BeforeTokens>
+ <AfterTokens>$(BuildVersion)</AfterTokens>
+ <SkipUnchangedFiles>false</SkipUnchangedFiles>
+ </ExtensionVsixTransformSource>
+ <ExtensionVsixTransformLayout Include="@(ExtensionVsixTransformSource->'$(ExtensionVsixLayoutDirectory)%(RecursiveDir)%(FileName)%(Extension)')" />
+
+ <ExtensionVsixSources Include="
+ $(ProjectRoot)vsix\*;
+ " Exclude="
+ $(ProjectRoot)vsix\extension.vsixmanifest;
+ $(ProjectRoot)vsix\$(MSBuildThisFile);
+ ">
+ <SkipUnchangedFiles>true</SkipUnchangedFiles>
+ </ExtensionVsixSources>
+ <ExtensionVsixTargets Include="@(ExtensionVsixSources->'$(ExtensionVsixLayoutDirectory)%(FileName)%(Extension)')" />
+
+ <ExtensionVsixContents Include="
+ @(ExtensionVsixTargets);
+ @(ExtensionVsixTransformLayout);
+ @(ProjectTemplateZipTargets);
+ "/>
+ </ItemGroup>
+
+ <CopyWithTokenSubstitution SourceFiles="@(ExtensionVsixTransformSource)" DestinationFiles="@(ExtensionVsixTransformLayout)" />
+ <Copy SourceFiles="@(ExtensionVsixSources)" DestinationFiles="@(ExtensionVsixTargets)" SkipUnchangedFiles="true" />
+ <HardLinkCopy SourceFiles="@(ProjectTemplateZipSource)" DestinationFiles="@(ProjectTemplateZipTargets)" />
+ <Purge Directories="$(ExtensionVsixLayoutDirectory)" IntendedFiles="@(ExtensionVsixContents)" />
+ </Target>
+
+ <Target Name="VSGalleryVsixLayout" DependsOnTargets="Layout">
+ <!-- Build individual VSIX files for each project template for the Visual Studio Gallery,
+ which only allows one project template per VSIX. -->
+ <ItemGroup>
+ <VSGalleryVsixRawSources Include="$(ExtensionVsixLayoutDirectory)*"
+ Exclude="$(ExtensionVsixLayoutDirectory)*.vsixmanifest">
+ <VSGalleryVsix>$(DropsRoot)$(ProductName) %(ProjectTemplateZipTargets.FileName)-$(BuildVersion).vsix</VSGalleryVsix>
+ <TopLevelTemplate>%(ProjectTemplateZipTargets.FileName)</TopLevelTemplate>
+ </VSGalleryVsixRawSources>
+ <VSGalleryVsixSources Include="@(VSGalleryVsixRawSources)">
+ <TargetPath>$(IntermediatePath)%(TopLevelTemplate).vsix\%(FileName)%(Extension)</TargetPath>
+ </VSGalleryVsixSources>
+
+ <VSGalleryVsixZipSources Include="$(ExtensionVsixLayoutDirectory)**\*.zip" />
+ <VSGalleryVsixSources Include="@(VSGalleryVsixZipSources)">
+ <TopLevelTemplate>%(FileName)</TopLevelTemplate>
+ <VSGalleryVsix>$(DropsRoot)$(ProductName) %(FileName)-$(BuildVersion).vsix</VSGalleryVsix>
+ <!-- The A in the path below used to be %(FileName), but to fit inside MAX_PATH when VS expands, we shorten it. -->
+ <TargetPath>$(IntermediatePath)%(FileName).vsix\%(RecursiveDir)A%(Extension)</TargetPath>
+ </VSGalleryVsixSources>
+
+ <VSGalleryVsixSources Include="@(ProjectTemplateZipTargets->'$(ProjectRoot)projecttemplates\%(FileName).vsixmanifest')">
+ <VSGalleryVsix>$(DropsRoot)$(ProductName) %(ProjectTemplateZipTargets.FileName)-$(BuildVersion).vsix</VSGalleryVsix>
+ <TopLevelTemplate>%(ProjectTemplateZipTargets.FileName)</TopLevelTemplate>
+ <TargetPath>$(IntermediatePath)%(ProjectTemplateZipTargets.FileName).vsix\extension.vsixmanifest</TargetPath>
+ <Transform>true</Transform>
+ <BeforeTokens>$version$</BeforeTokens>
+ <AfterTokens>$(BuildVersion)</AfterTokens>
+ <SkipUnchangedFiles>false</SkipUnchangedFiles>
+ </VSGalleryVsixSources>
+
+ <VSGalleryVsixTargets Include="@(VSGalleryVsixSources->'%(TargetPath)')">
+ <WorkingDirectory>$(IntermediatePath)%(TopLevelTemplate).vsix</WorkingDirectory>
+ </VSGalleryVsixTargets>
+ <VSGalleryVsixPathsToPurge Include="@(ProjectTemplateZipTargets->'$(IntermediatePath)%(FileName).vsix')"/>
+ </ItemGroup>
+
+ <HardLinkCopy
+ SourceFiles="@(VSGalleryVsixSources)"
+ DestinationFiles="%(VSGalleryVsixSources.TargetPath)"
+ Condition=" '%(VSGalleryVsixSources.Transform)' != 'true' "/>
+ <CopyWithTokenSubstitution
+ SourceFiles="@(VSGalleryVsixSources)"
+ DestinationFiles="%(VSGalleryVsixSources.TargetPath)"
+ Condition=" '%(VSGalleryVsixSources.Transform)' == 'true' "/>
+ <Purge
+ Directories="@(VSGalleryVsixPathsToPurge)"
+ IntendedFiles="@(VSGalleryVsixTargets)" />
+ </Target>
+
+ <Target Name="Build" DependsOnTargets="Layout;VSGalleryVsixLayout" Returns="@(GeneratedVsix)">
+ <PropertyGroup>
+ <ExtensionVsix>$(DropsRoot)$(ProductName) SDK-$(BuildVersion).vsix</ExtensionVsix>
+ </PropertyGroup>
+ <ItemGroup>
+ <GeneratedVsix Include="$(ExtensionVsix)">
+ <IncludeInDrop>true</IncludeInDrop>
+ </GeneratedVsix>
+ <GeneratedVsix Include="%(VSGalleryVsixTargets.VSGalleryVsix)" />
+ </ItemGroup>
+
+ <Zip
+ Files="@(ExtensionVsixContents)"
+ ZipFileName="$(ExtensionVsix)"
+ WorkingDirectory="$(ExtensionVsixLayoutDirectory)"
+ ZipLevel="$(ZipLevel)"
+ />
+
+ <Zip
+ Files="@(VSGalleryVsixTargets)"
+ ZipFileName="%(VSGalleryVsixTargets.VSGalleryVsix)"
+ WorkingDirectory="%(VSGalleryVsixTargets.WorkingDirectory)"
+ ZipLevel="$(ZipLevel)"
+ />
+ </Target>
+
+ <Import Project="$(ProjectRoot)tools\DotNetOpenAuth.automated.targets"/>
+</Project> \ No newline at end of file