diff options
Diffstat (limited to 'src')
30 files changed, 1163 insertions, 31 deletions
diff --git a/src/DotNetOpenAuth.BuildTasks/ChangeAssemblyReference.cs b/src/DotNetOpenAuth.BuildTasks/ChangeAssemblyReference.cs new file mode 100644 index 0000000..3ad5eb0 --- /dev/null +++ b/src/DotNetOpenAuth.BuildTasks/ChangeAssemblyReference.cs @@ -0,0 +1,47 @@ +using System; +using System.Linq; +using System.IO; +using System.Xml; + +using Microsoft.Build.Framework; +using Microsoft.Build.Utilities; +using Microsoft.Build.BuildEngine; + +namespace DotNetOpenAuth.BuildTasks { + /// <summary> + /// Replaces Reference items HintPaths in a set of projects. + /// </summary> + public class ChangeAssemblyReference : Task { + /// <summary> + /// The projects to alter. + /// </summary> + [Required] + public ITaskItem[] Projects { get; set; } + /// <summary> + /// The project reference to remove. + /// </summary> + [Required] + public string OldReference { get; set; } + /// <summary> + /// The assembly reference to add. + /// </summary> + [Required] + public string NewReference { get; set; } + + const string msbuildNamespace = "http://schemas.microsoft.com/developer/msbuild/2003"; + public override bool Execute() { + foreach (var project in Projects) { + Project doc = new Project(); + doc.Load(project.ItemSpec); + + var reference = doc.GetEvaluatedItemsByName("Reference").OfType<BuildItem>(). + Where(item => string.Equals(item.GetMetadata("HintPath"), OldReference, StringComparison.OrdinalIgnoreCase)).Single(); + reference.SetMetadata("HintPath", NewReference); + + doc.Save(project.ItemSpec); + } + + return true; + } + } +} diff --git a/src/DotNetOpenAuth.BuildTasks/ChangeProjectReferenceToAssemblyReference.cs b/src/DotNetOpenAuth.BuildTasks/ChangeProjectReferenceToAssemblyReference.cs new file mode 100644 index 0000000..72415d9 --- /dev/null +++ b/src/DotNetOpenAuth.BuildTasks/ChangeProjectReferenceToAssemblyReference.cs @@ -0,0 +1,50 @@ +using System; +using System.Linq; +using System.IO; +using System.Xml; + +using Microsoft.Build.Framework; +using Microsoft.Build.Utilities; +using Microsoft.Build.BuildEngine; + +namespace DotNetOpenAuth.BuildTasks { + /// <summary> + /// Replaces ProjectReference items in a set of projects with Reference items. + /// </summary> + public class ChangeProjectReferenceToAssemblyReference : Task { + /// <summary> + /// The projects to alter. + /// </summary> + [Required] + public ITaskItem[] Projects { get; set; } + /// <summary> + /// The project reference to remove. + /// </summary> + [Required] + public string ProjectReference { get; set; } + /// <summary> + /// The assembly reference to add. + /// </summary> + [Required] + public string Reference { get; set; } + + const string msbuildNamespace = "http://schemas.microsoft.com/developer/msbuild/2003"; + public override bool Execute() { + foreach (var project in Projects) { + Project doc = new Project(); + doc.Load(project.ItemSpec); + + var projectReference = doc.EvaluatedItems.OfType<BuildItem>().Where( + item => item.Name == "ProjectReference" && item.Include == ProjectReference).Single(); + doc.RemoveItem(projectReference); + + var newReference = doc.AddNewItem("Reference", Path.GetFileNameWithoutExtension(Reference)); + newReference.SetMetadata("HintPath", Reference); + + doc.Save(project.ItemSpec); + } + + return true; + } + } +} diff --git a/src/DotNetOpenAuth.BuildTasks/CheckAdminRights.cs b/src/DotNetOpenAuth.BuildTasks/CheckAdminRights.cs new file mode 100644 index 0000000..9cfd35d --- /dev/null +++ b/src/DotNetOpenAuth.BuildTasks/CheckAdminRights.cs @@ -0,0 +1,30 @@ +//----------------------------------------------------------------------- +// <copyright file="CheckAdminRights.cs" company="Andrew Arnott"> +// Copyright (c) Andrew Arnott. All rights reserved. +// </copyright> +//----------------------------------------------------------------------- + +namespace DotNetOpenAuth.BuildTasks { + using System.Security.Principal; + using Microsoft.Build.Framework; + using Microsoft.Build.Utilities; + + public class CheckAdminRights : Task { + /// <summary> + /// Gets or sets a value indicating whether this process has elevated permissions. + /// </summary> + [Output] + public bool IsElevated { get; set; } + + /// <summary> + /// Executes this instance. + /// </summary> + public override bool Execute() { + WindowsIdentity id = WindowsIdentity.GetCurrent(); + WindowsPrincipal p = new WindowsPrincipal(id); + this.IsElevated = p.IsInRole(WindowsBuiltInRole.Administrator); + + return true; + } + } +} diff --git a/src/DotNetOpenAuth.BuildTasks/CompareFiles.cs b/src/DotNetOpenAuth.BuildTasks/CompareFiles.cs new file mode 100644 index 0000000..691df20 --- /dev/null +++ b/src/DotNetOpenAuth.BuildTasks/CompareFiles.cs @@ -0,0 +1,85 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Microsoft.Build.Utilities; +using Microsoft.Build.Framework; +using System.IO; + +namespace DotNetOpenAuth.BuildTasks { + public class CompareFiles : Task { + /// <summary> + /// One set of items to compare. + /// </summary> + [Required] + public ITaskItem[] OriginalItems { get; set; } + + /// <summary> + /// The other set of items to compare. + /// </summary> + [Required] + public ITaskItem[] NewItems { get; set; } + + /// <summary> + /// Gets whether the items lists contain items that are identical going down the list. + /// </summary> + [Output] + public bool AreSame { get; private set; } + + /// <summary> + /// Same as <see cref="AreSame"/>, but opposite. + /// </summary> + [Output] + public bool AreChanged { get { return !AreSame; } } + + public override bool Execute() { + AreSame = AreFilesIdentical(); + return true; + } + + private bool AreFilesIdentical() { + if (OriginalItems.Length != NewItems.Length) { + return false; + } + + for (int i = 0; i < OriginalItems.Length; i++) { + if (!IsContentOfFilesTheSame(OriginalItems[i].ItemSpec, NewItems[i].ItemSpec)) { + return false; + } + } + + return true; + } + + private bool IsContentOfFilesTheSame(string file1, string file2) { + // If exactly one file is missing, that's different. + if (File.Exists(file1) ^ File.Exists(file2)) return false; + // If both are missing, that's the same. + if (!File.Exists(file1)) return true; + // If both are present, we need to do a content comparison. + using (FileStream fileStream1 = File.OpenRead(file1)) { + using (FileStream fileStream2 = File.OpenRead(file2)) { + if (fileStream1.Length != fileStream2.Length) return false; + byte[] buffer1 = new byte[4096]; + byte[] buffer2 = new byte[buffer1.Length]; + int bytesRead; + do { + bytesRead = fileStream1.Read(buffer1, 0, buffer1.Length); + if (fileStream2.Read(buffer2, 0, buffer2.Length) != bytesRead) { + // We should never get here since we compared file lengths, but + // this is a sanity check. + return false; + } + for (int i = 0; i < bytesRead; i++) { + if (buffer1[i] != buffer2[i]) { + return false; + } + } + } while (bytesRead == buffer1.Length); + } + } + + return true; + } + } +} diff --git a/src/DotNetOpenAuth.BuildTasks/CreateWebApplication.cs b/src/DotNetOpenAuth.BuildTasks/CreateWebApplication.cs new file mode 100644 index 0000000..4980898 --- /dev/null +++ b/src/DotNetOpenAuth.BuildTasks/CreateWebApplication.cs @@ -0,0 +1,95 @@ +//----------------------------------------------------------------------- +// <copyright file="CreateWebApplication.cs" company="Andrew Arnott"> +// Copyright (c) Andrew Arnott. All rights reserved. +// </copyright> +//----------------------------------------------------------------------- + +namespace DotNetOpenAuth.BuildTasks { + using System; + using System.Linq; + using Microsoft.Build.Framework; + using Microsoft.Build.Utilities; + using Microsoft.Web.Administration; + + /// <summary> + /// Creates or updates web applications within an existing web site in IIS. + /// </summary> + public class CreateWebApplication : Task { + /// <summary> + /// Gets or sets the name of the application pool that should host the web application. + /// </summary> + /// <value>The name of an existing application pool.</value> + public string ApplicationPoolName { get; set; } + + /// <summary> + /// Gets or sets the name of the web site under which to create the web application. + /// </summary> + /// <value>The name of the existing web site.</value> + [Required] + public string WebSiteName { get; set; } + + /// <summary> + /// Gets or sets the virtual paths within the web site that will access these applications. + /// </summary> + /// <value>The virtual path, which must start with '/'.</value> + [Required] + public ITaskItem[] VirtualPaths { get; set; } + + /// <summary> + /// Gets or sets the full file system paths to the web applications. + /// </summary> + /// <value>The physical path.</value> + [Required] + public ITaskItem[] PhysicalPaths { get; set; } + + /// <summary> + /// Executes this instance. + /// </summary> + /// <returns>A value indicating whether the task completed successfully.</returns> + public override bool Execute() { + var serverManager = new ServerManager(); + + if (this.PhysicalPaths.Length != this.VirtualPaths.Length) { + Log.LogError(TaskStrings.MismatchingArrayLengths, "PhysicalPath", "VirtualPath"); + return false; + } + + if (this.VirtualPaths.Length == 0) { + // Nothing to do. + return true; + } + + // Find the root web site that this web application will be created under. + var site = serverManager.Sites.FirstOrDefault(s => string.Equals(s.Name, this.WebSiteName, StringComparison.OrdinalIgnoreCase)); + if (site == null) { + Log.LogError(TaskStrings.NoMatchingWebSiteFound, this.WebSiteName); + return false; + } + + Log.LogMessage(MessageImportance.Normal, "Creating web applications under web site: {0}", site.Name); + + for (int i = 0; i < this.PhysicalPaths.Length; i++) { + string physicalPath = this.PhysicalPaths[i].ItemSpec; + string virtualPath = this.VirtualPaths[i].ItemSpec; + + Log.LogMessage(MessageImportance.Normal, "\t{0} -> {1}", virtualPath, physicalPath); + + var app = site.Applications.FirstOrDefault(a => string.Equals(a.Path, virtualPath, StringComparison.OrdinalIgnoreCase)); + if (app == null) { + app = site.Applications.Add(virtualPath, physicalPath); + } else { + // Ensure physical path is set correctly. + var appRoot = app.VirtualDirectories.First(vd => vd.Path == "/"); + appRoot.PhysicalPath = physicalPath; + } + + if (!string.IsNullOrEmpty(this.ApplicationPoolName)) { + app.ApplicationPoolName = this.ApplicationPoolName; + } + } + + serverManager.CommitChanges(); + return true; + } + } +} diff --git a/src/DotNetOpenAuth.BuildTasks/CustomMsBuildTasks.sln b/src/DotNetOpenAuth.BuildTasks/CustomMsBuildTasks.sln new file mode 100644 index 0000000..6eae4e0 --- /dev/null +++ b/src/DotNetOpenAuth.BuildTasks/CustomMsBuildTasks.sln @@ -0,0 +1,20 @@ + +Microsoft Visual Studio Solution File, Format Version 10.00 +# Visual Studio 2008 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DotNetOpenAuth.BuildTasks", "DotNetOpenAuth.BuildTasks.csproj", "{AC231A51-EF60-437C-A33F-AF8ADEB8EB74}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {AC231A51-EF60-437C-A33F-AF8ADEB8EB74}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {AC231A51-EF60-437C-A33F-AF8ADEB8EB74}.Debug|Any CPU.Build.0 = Debug|Any CPU + {AC231A51-EF60-437C-A33F-AF8ADEB8EB74}.Release|Any CPU.ActiveCfg = Release|Any CPU + {AC231A51-EF60-437C-A33F-AF8ADEB8EB74}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/src/DotNetOpenAuth.BuildTasks/DeleteWebApplication.cs b/src/DotNetOpenAuth.BuildTasks/DeleteWebApplication.cs new file mode 100644 index 0000000..930a8c4 --- /dev/null +++ b/src/DotNetOpenAuth.BuildTasks/DeleteWebApplication.cs @@ -0,0 +1,66 @@ +//----------------------------------------------------------------------- +// <copyright file="DeleteWebApplication.cs" company="Andrew Arnott"> +// Copyright (c) Andrew Arnott. All rights reserved. +// </copyright> +//----------------------------------------------------------------------- + +namespace DotNetOpenAuth.BuildTasks { + using System; + using System.Linq; + using Microsoft.Build.Framework; + using Microsoft.Build.Utilities; + using Microsoft.Web.Administration; + + /// <summary> + /// Deletes a web application from IIS. + /// </summary> + public class DeleteWebApplication : Task { + /// <summary> + /// Gets or sets the name of the web site under which to create the web application. + /// </summary> + /// <value>The name of the existing web site.</value> + [Required] + public string WebSiteName { get; set; } + + /// <summary> + /// Gets or sets the virtual paths within the web site that will access these applications. + /// </summary> + /// <value>The virtual path, which must start with '/'.</value> + [Required] + public ITaskItem[] VirtualPaths { get; set; } + + /// <summary> + /// Executes this instance. + /// </summary> + /// <returns>A value indicating whether the task completed successfully.</returns> + public override bool Execute() { + var serverManager = new ServerManager(); + + // Find the root web site that this web application will be created under. + var site = serverManager.Sites.FirstOrDefault(s => string.Equals(s.Name, this.WebSiteName, StringComparison.OrdinalIgnoreCase)); + if (site == null) { + Log.LogMessage(MessageImportance.Low, TaskStrings.NoMatchingWebSiteFound, this.WebSiteName); + return true; + } + + if (this.VirtualPaths.Length == 0) { + // Nothing to do. + return true; + } + + foreach (ITaskItem path in this.VirtualPaths) { + var app = site.Applications.FirstOrDefault(a => string.Equals(a.Path, path.ItemSpec, StringComparison.OrdinalIgnoreCase)); + if (app != null) { + site.Applications.Remove(app); + Log.LogMessage(MessageImportance.Normal, TaskStrings.DeletedWebApplication, app.Path); + } else { + Log.LogMessage(MessageImportance.Low, TaskStrings.WebApplicationNotFoundSoNotDeleted, path.ItemSpec); + } + } + + serverManager.CommitChanges(); + + return true; + } + } +} diff --git a/src/DotNetOpenAuth.BuildTasks/DotNetOpenAuth.BuildTasks.csproj b/src/DotNetOpenAuth.BuildTasks/DotNetOpenAuth.BuildTasks.csproj new file mode 100644 index 0000000..4eb920e --- /dev/null +++ b/src/DotNetOpenAuth.BuildTasks/DotNetOpenAuth.BuildTasks.csproj @@ -0,0 +1,85 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="3.5" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <PropertyGroup> + <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> + <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform> + <ProductVersion>9.0.30729</ProductVersion> + <SchemaVersion>2.0</SchemaVersion> + <ProjectGuid>{AC231A51-EF60-437C-A33F-AF8ADEB8EB74}</ProjectGuid> + <OutputType>Library</OutputType> + <AppDesignerFolder>Properties</AppDesignerFolder> + <RootNamespace>DotNetOpenAuth.BuildTasks</RootNamespace> + <AssemblyName>DotNetOpenAuth.BuildTasks</AssemblyName> + <TargetFrameworkVersion>v3.5</TargetFrameworkVersion> + <FileAlignment>512</FileAlignment> + </PropertyGroup> + <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "> + <DebugSymbols>true</DebugSymbols> + <DebugType>full</DebugType> + <Optimize>false</Optimize> + <OutputPath>..\..\lib\</OutputPath> + <DefineConstants>DEBUG;TRACE</DefineConstants> + <ErrorReport>prompt</ErrorReport> + <WarningLevel>4</WarningLevel> + </PropertyGroup> + <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' "> + <DebugType>pdbonly</DebugType> + <Optimize>true</Optimize> + <OutputPath>..\..\lib\</OutputPath> + <DefineConstants>TRACE</DefineConstants> + <ErrorReport>prompt</ErrorReport> + <WarningLevel>4</WarningLevel> + </PropertyGroup> + <ItemGroup> + <Reference Include="Microsoft.Build.Engine" /> + <Reference Include="Microsoft.Build.Framework" /> + <Reference Include="Microsoft.Build.Utilities.v3.5"> + <RequiredTargetFramework>3.5</RequiredTargetFramework> + </Reference> + <Reference Include="Microsoft.Web.Administration, Version=7.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL"> + <SpecificVersion>False</SpecificVersion> + <HintPath>$(SystemRoot)\System32\inetsrv\Microsoft.Web.Administration.dll</HintPath> + </Reference> + <Reference Include="System" /> + <Reference Include="System.Core"> + <RequiredTargetFramework>3.5</RequiredTargetFramework> + </Reference> + <Reference Include="System.Data" /> + <Reference Include="System.Xml" /> + </ItemGroup> + <ItemGroup> + <Compile Include="ChangeProjectReferenceToAssemblyReference.cs" /> + <Compile Include="CompareFiles.cs" /> + <Compile Include="ChangeAssemblyReference.cs" /> + <Compile Include="CreateWebApplication.cs" /> + <Compile Include="DeleteWebApplication.cs" /> + <Compile Include="FilterItems.cs" /> + <Compile Include="GetBuildVersion.cs" /> + <Compile Include="CheckAdminRights.cs" /> + <Compile Include="ReSignDelaySignedAssemblies.cs" /> + <Compile Include="SetEnvironmentVariable.cs" /> + <Compile Include="Properties\AssemblyInfo.cs" /> + <Compile Include="SignatureVerification.cs" /> + <Compile Include="SnToolTask.cs" /> + <Compile Include="TaskStrings.Designer.cs"> + <AutoGen>True</AutoGen> + <DesignTime>True</DesignTime> + <DependentUpon>TaskStrings.resx</DependentUpon> + </Compile> + <Compile Include="Trim.cs" /> + </ItemGroup> + <ItemGroup> + <EmbeddedResource Include="TaskStrings.resx"> + <Generator>ResXFileCodeGenerator</Generator> + <LastGenOutput>TaskStrings.Designer.cs</LastGenOutput> + </EmbeddedResource> + </ItemGroup> + <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> + <!-- To modify your build process, add your task inside one of the targets below and uncomment it. + Other similar extension points exist, see Microsoft.Common.targets. + <Target Name="BeforeBuild"> + </Target> + <Target Name="AfterBuild"> + </Target> + --> +</Project>
\ No newline at end of file diff --git a/src/DotNetOpenAuth.BuildTasks/FilterItems.cs b/src/DotNetOpenAuth.BuildTasks/FilterItems.cs new file mode 100644 index 0000000..97631c6 --- /dev/null +++ b/src/DotNetOpenAuth.BuildTasks/FilterItems.cs @@ -0,0 +1,24 @@ +namespace DotNetOpenAuth.BuildTasks { + using System; + using System.Collections.Generic; + using System.Linq; + using System.Text; + using Microsoft.Build.Utilities; + using Microsoft.Build.Framework; + + public class FilterItems : Task { + [Required] + public ITaskItem[] InputItems { get; set; } + + [Required] + public ITaskItem[] StartsWithAny { get; set; } + + [Output] + public ITaskItem[] FilteredItems { get; set; } + + public override bool Execute() { + FilteredItems = InputItems.Where(item => StartsWithAny.Any(filter => item.ItemSpec.StartsWith(filter.ItemSpec, StringComparison.OrdinalIgnoreCase))).ToArray(); + return true; + } + } +} diff --git a/src/DotNetOpenAuth.BuildTasks/GetBuildVersion.cs b/src/DotNetOpenAuth.BuildTasks/GetBuildVersion.cs new file mode 100644 index 0000000..e40eb78 --- /dev/null +++ b/src/DotNetOpenAuth.BuildTasks/GetBuildVersion.cs @@ -0,0 +1,51 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Microsoft.Build.Utilities; +using Microsoft.Build.Framework; +using System.IO; + +namespace DotNetOpenAuth.BuildTasks { + public class GetBuildVersion : Task { + + /// <summary> + /// Gets the version string to use in the compiled assemblies. + /// </summary> + [Output] + public string Version { get; private set; } + + /// <summary> + /// The file that contains the version base (Major.Minor.Build) to use. + /// </summary> + [Required] + public string VersionFile { get; set; } + + public override bool Execute() { + try { + Version typedVersion = ReadVersionFromFile(); + typedVersion = new Version(typedVersion.Major, typedVersion.Minor, typedVersion.Build, CalculateJDate(DateTime.Now)); + Version = typedVersion.ToString(); + } catch (ArgumentOutOfRangeException ex) { + Log.LogErrorFromException(ex); + return false; + } + + return true; + } + + private Version ReadVersionFromFile() { + string[] lines = File.ReadAllLines(VersionFile); + string versionLine = lines[0]; + return new Version(versionLine); + } + + private int CalculateJDate(DateTime date) { + int yearLastDigit = date.Year % 10; + DateTime firstOfYear = new DateTime(date.Year, 1, 1); + int dayOfYear = (date - firstOfYear).Days + 1; + int jdate = yearLastDigit * 1000 + dayOfYear; + return jdate; + } + } +} diff --git a/src/DotNetOpenAuth.BuildTasks/Properties/AssemblyInfo.cs b/src/DotNetOpenAuth.BuildTasks/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..6fdcc21 --- /dev/null +++ b/src/DotNetOpenAuth.BuildTasks/Properties/AssemblyInfo.cs @@ -0,0 +1,36 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("CustomMsBuildTasks")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("CustomMsBuildTasks")] +[assembly: AssemblyCopyright("Copyright © 2008")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("952e3aaa-5dc6-4b71-8c9c-6b485263be19")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/src/DotNetOpenAuth.BuildTasks/ReSignDelaySignedAssemblies.cs b/src/DotNetOpenAuth.BuildTasks/ReSignDelaySignedAssemblies.cs new file mode 100644 index 0000000..a0ba386 --- /dev/null +++ b/src/DotNetOpenAuth.BuildTasks/ReSignDelaySignedAssemblies.cs @@ -0,0 +1,56 @@ +//----------------------------------------------------------------------- +// <copyright file="ReSignDelaySignedAssemblies.cs" company="Andrew Arnott"> +// Copyright (c) Andrew Arnott. All rights reserved. +// </copyright> +//----------------------------------------------------------------------- + +namespace DotNetOpenAuth.BuildTasks { + using System; + using Microsoft.Build.Framework; + using Microsoft.Build.Utilities; + + public class ReSignDelaySignedAssemblies : SnToolTask { + /// <summary> + /// Gets or sets the key file to use for signing. + /// </summary> + public ITaskItem KeyFile { get; set; } + + /// <summary> + /// Gets or sets the key container. + /// </summary> + public ITaskItem KeyContainer { get; set; } + + /// <summary> + /// Gets or sets the assemblies to re-sign. + /// </summary> + public ITaskItem[] Assemblies { get; set; } + + /// <summary> + /// Generates the command line commands. + /// </summary> + protected override string GenerateCommandLineCommands() { + ////if (this.Assemblies.Length != 1) { + //// throw new NotSupportedException("Exactly 1 assembly for signing is supported."); + ////} + CommandLineBuilder args = new CommandLineBuilder(); + args.AppendSwitch("-q"); + + if (this.KeyFile != null) { + args.AppendSwitch("-R"); + } else if (this.KeyContainer != null) { + args.AppendSwitch("-Rc"); + } else { + throw new InvalidOperationException("Either KeyFile or KeyContainer must be set."); + } + + args.AppendFileNameIfNotNull(this.Assemblies[0]); + if (this.KeyFile != null) { + args.AppendFileNameIfNotNull(this.KeyFile); + } else { + args.AppendFileNameIfNotNull(this.KeyContainer); + } + + return args.ToString(); + } + } +} diff --git a/src/DotNetOpenAuth.BuildTasks/SetEnvironmentVariable.cs b/src/DotNetOpenAuth.BuildTasks/SetEnvironmentVariable.cs new file mode 100644 index 0000000..2de5976 --- /dev/null +++ b/src/DotNetOpenAuth.BuildTasks/SetEnvironmentVariable.cs @@ -0,0 +1,33 @@ +using System; +using System.Collections.Generic; +using System.Text; +using Microsoft.Build.Utilities; +using Microsoft.Build.Framework; + +namespace DotNetOpenAuth.BuildTasks { + public class SetEnvironmentVariable : Task { + public SetEnvironmentVariable() { + Scope = EnvironmentVariableTarget.Process; + } + + /// <summary> + /// The name of the environment variable to set or clear. + /// </summary> + [Required] + public string Name { get; set; } + /// <summary> + /// The value of the environment variable, or the empty string to clear it. + /// </summary> + [Required] + public string Value { get; set; } + /// <summary> + /// The target environment for the variable. Machine, User, or Process. + /// </summary> + public EnvironmentVariableTarget Scope { get; set; } + + public override bool Execute() { + Environment.SetEnvironmentVariable(Name, Value, Scope); + return true; + } + } +} diff --git a/src/DotNetOpenAuth.BuildTasks/SignatureVerification.cs b/src/DotNetOpenAuth.BuildTasks/SignatureVerification.cs new file mode 100644 index 0000000..2e69926 --- /dev/null +++ b/src/DotNetOpenAuth.BuildTasks/SignatureVerification.cs @@ -0,0 +1,45 @@ +//----------------------------------------------------------------------- +// <copyright file="SignatureVerification.cs" company="Andrew Arnott"> +// Copyright (c) Andrew Arnott. All rights reserved. +// </copyright> +//----------------------------------------------------------------------- + +namespace DotNetOpenAuth.BuildTasks { + using Microsoft.Build.Utilities; + + public class SignatureVerification : SnToolTask { + /// <summary> + /// Gets or sets a value indicating whether to register the given assembly and public key token + /// for skip verification or clear any pre-existing skip verification entry. + /// </summary> + public bool SkipVerification { get; set; } + + /// <summary> + /// Gets or sets the name of the assembly. + /// </summary> + /// <value>The name of the assembly.</value> + public string AssemblyName { get; set; } + + /// <summary> + /// Gets or sets the public key token. + /// </summary> + /// <value>The public key token.</value> + public string PublicKeyToken { get; set; } + + /// <summary> + /// Generates the command line commands. + /// </summary> + protected override string GenerateCommandLineCommands() { + CommandLineBuilder builder = new CommandLineBuilder(); + builder.AppendSwitch("-q"); + if (this.SkipVerification) { + builder.AppendSwitch("-Vr"); + } else { + builder.AppendSwitch("-Vu"); + } + + builder.AppendFileNameIfNotNull(this.AssemblyName + "," + this.PublicKeyToken); + return builder.ToString(); + } + } +} diff --git a/src/DotNetOpenAuth.BuildTasks/SnToolTask.cs b/src/DotNetOpenAuth.BuildTasks/SnToolTask.cs new file mode 100644 index 0000000..1c32632 --- /dev/null +++ b/src/DotNetOpenAuth.BuildTasks/SnToolTask.cs @@ -0,0 +1,37 @@ +//----------------------------------------------------------------------- +// <copyright file="SnToolTask.cs" company="Andrew Arnott"> +// Copyright (c) Andrew Arnott. All rights reserved. +// </copyright> +//----------------------------------------------------------------------- + +namespace DotNetOpenAuth.BuildTasks { + using System; + using System.IO; + using Microsoft.Build.Utilities; + + public abstract class SnToolTask : ToolTask { + /// <summary> + /// Gets the name of the tool. + /// </summary> + /// <value>The name of the tool.</value> + protected override string ToolName { + get { return "sn.exe"; } + } + + /// <summary> + /// Generates the full path to tool. + /// </summary> + protected override string GenerateFullPathToTool() { + string[] versions = new[] { "v6.0A", "v6.1" }; + string fullPath = null; + foreach (string version in versions) { + fullPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles), @"Microsoft SDKs\Windows\" + version + @"\bin\" + this.ToolName); + if (File.Exists(fullPath)) { + return fullPath; + } + } + + throw new FileNotFoundException("Unable to find sn.exe tool.", fullPath); + } + } +} diff --git a/src/DotNetOpenAuth.BuildTasks/TaskStrings.Designer.cs b/src/DotNetOpenAuth.BuildTasks/TaskStrings.Designer.cs new file mode 100644 index 0000000..a727695 --- /dev/null +++ b/src/DotNetOpenAuth.BuildTasks/TaskStrings.Designer.cs @@ -0,0 +1,99 @@ +//------------------------------------------------------------------------------ +// <auto-generated> +// This code was generated by a tool. +// Runtime Version:2.0.50727.4918 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// </auto-generated> +//------------------------------------------------------------------------------ + +namespace DotNetOpenAuth.BuildTasks { + using System; + + + /// <summary> + /// A strongly-typed resource class, for looking up localized strings, etc. + /// </summary> + // This class was auto-generated by the StronglyTypedResourceBuilder + // class via a tool like ResGen or Visual Studio. + // To add or remove a member, edit your .ResX file then rerun ResGen + // with the /str option, or rebuild your VS project. + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "2.0.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + internal class TaskStrings { + + private static global::System.Resources.ResourceManager resourceMan; + + private static global::System.Globalization.CultureInfo resourceCulture; + + [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + internal TaskStrings() { + } + + /// <summary> + /// Returns the cached ResourceManager instance used by this class. + /// </summary> + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Resources.ResourceManager ResourceManager { + get { + if (object.ReferenceEquals(resourceMan, null)) { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("DotNetOpenAuth.BuildTasks.TaskStrings", typeof(TaskStrings).Assembly); + resourceMan = temp; + } + return resourceMan; + } + } + + /// <summary> + /// Overrides the current thread's CurrentUICulture property for all + /// resource lookups using this strongly typed resource class. + /// </summary> + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Globalization.CultureInfo Culture { + get { + return resourceCulture; + } + set { + resourceCulture = value; + } + } + + /// <summary> + /// Looks up a localized string similar to Web application '{0}' deleted.. + /// </summary> + internal static string DeletedWebApplication { + get { + return ResourceManager.GetString("DeletedWebApplication", resourceCulture); + } + } + + /// <summary> + /// Looks up a localized string similar to The {0} and {1} properties must be set to arrays of equal length.. + /// </summary> + internal static string MismatchingArrayLengths { + get { + return ResourceManager.GetString("MismatchingArrayLengths", resourceCulture); + } + } + + /// <summary> + /// Looks up a localized string similar to No web site with the name '{0}' found.. + /// </summary> + internal static string NoMatchingWebSiteFound { + get { + return ResourceManager.GetString("NoMatchingWebSiteFound", resourceCulture); + } + } + + /// <summary> + /// Looks up a localized string similar to Web application '{0}' was not found, so it was not deleted.. + /// </summary> + internal static string WebApplicationNotFoundSoNotDeleted { + get { + return ResourceManager.GetString("WebApplicationNotFoundSoNotDeleted", resourceCulture); + } + } + } +} diff --git a/src/DotNetOpenAuth.BuildTasks/TaskStrings.resx b/src/DotNetOpenAuth.BuildTasks/TaskStrings.resx new file mode 100644 index 0000000..2aaa32e --- /dev/null +++ b/src/DotNetOpenAuth.BuildTasks/TaskStrings.resx @@ -0,0 +1,132 @@ +<?xml version="1.0" encoding="utf-8"?> +<root> + <!-- + Microsoft ResX Schema + + Version 2.0 + + The primary goals of this format is to allow a simple XML format + that is mostly human readable. The generation and parsing of the + various data types are done through the TypeConverter classes + associated with the data types. + + Example: + + ... ado.net/XML headers & schema ... + <resheader name="resmimetype">text/microsoft-resx</resheader> + <resheader name="version">2.0</resheader> + <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader> + <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader> + <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data> + <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data> + <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64"> + <value>[base64 mime encoded serialized .NET Framework object]</value> + </data> + <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64"> + <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value> + <comment>This is a comment</comment> + </data> + + There are any number of "resheader" rows that contain simple + name/value pairs. + + Each data row contains a name, and value. The row also contains a + type or mimetype. Type corresponds to a .NET class that support + text/value conversion through the TypeConverter architecture. + Classes that don't support this are serialized and stored with the + mimetype set. + + The mimetype is used for serialized objects, and tells the + ResXResourceReader how to depersist the object. This is currently not + extensible. For a given mimetype the value must be set accordingly: + + Note - application/x-microsoft.net.object.binary.base64 is the format + that the ResXResourceWriter will generate, however the reader can + read any of the formats listed below. + + mimetype: application/x-microsoft.net.object.binary.base64 + value : The object must be serialized with + : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter + : and then encoded with base64 encoding. + + mimetype: application/x-microsoft.net.object.soap.base64 + value : The object must be serialized with + : System.Runtime.Serialization.Formatters.Soap.SoapFormatter + : and then encoded with base64 encoding. + + mimetype: application/x-microsoft.net.object.bytearray.base64 + value : The object must be serialized into a byte array + : using a System.ComponentModel.TypeConverter + : and then encoded with base64 encoding. + --> + <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata"> + <xsd:import namespace="http://www.w3.org/XML/1998/namespace" /> + <xsd:element name="root" msdata:IsDataSet="true"> + <xsd:complexType> + <xsd:choice maxOccurs="unbounded"> + <xsd:element name="metadata"> + <xsd:complexType> + <xsd:sequence> + <xsd:element name="value" type="xsd:string" minOccurs="0" /> + </xsd:sequence> + <xsd:attribute name="name" use="required" type="xsd:string" /> + <xsd:attribute name="type" type="xsd:string" /> + <xsd:attribute name="mimetype" type="xsd:string" /> + <xsd:attribute ref="xml:space" /> + </xsd:complexType> + </xsd:element> + <xsd:element name="assembly"> + <xsd:complexType> + <xsd:attribute name="alias" type="xsd:string" /> + <xsd:attribute name="name" type="xsd:string" /> + </xsd:complexType> + </xsd:element> + <xsd:element name="data"> + <xsd:complexType> + <xsd:sequence> + <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" /> + <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" /> + </xsd:sequence> + <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" /> + <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" /> + <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" /> + <xsd:attribute ref="xml:space" /> + </xsd:complexType> + </xsd:element> + <xsd:element name="resheader"> + <xsd:complexType> + <xsd:sequence> + <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" /> + </xsd:sequence> + <xsd:attribute name="name" type="xsd:string" use="required" /> + </xsd:complexType> + </xsd:element> + </xsd:choice> + </xsd:complexType> + </xsd:element> + </xsd:schema> + <resheader name="resmimetype"> + <value>text/microsoft-resx</value> + </resheader> + <resheader name="version"> + <value>2.0</value> + </resheader> + <resheader name="reader"> + <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> + </resheader> + <resheader name="writer"> + <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> + </resheader> + <data name="DeletedWebApplication" xml:space="preserve"> + <value>Web application '{0}' deleted.</value> + </data> + <data name="MismatchingArrayLengths" xml:space="preserve"> + <value>The {0} and {1} properties must be set to arrays of equal length.</value> + </data> + <data name="NoMatchingWebSiteFound" xml:space="preserve"> + <value>No web site with the name '{0}' found.</value> + </data> + <data name="WebApplicationNotFoundSoNotDeleted" xml:space="preserve"> + <value>Web application '{0}' was not found, so it was not deleted.</value> + </data> +</root>
\ No newline at end of file diff --git a/src/DotNetOpenAuth.BuildTasks/Trim.cs b/src/DotNetOpenAuth.BuildTasks/Trim.cs new file mode 100644 index 0000000..1cc943e --- /dev/null +++ b/src/DotNetOpenAuth.BuildTasks/Trim.cs @@ -0,0 +1,56 @@ +//----------------------------------------------------------------------- +// <copyright file="Trim.cs" company="Andrew Arnott"> +// Copyright (c) Andrew Arnott. All rights reserved. +// </copyright> +//----------------------------------------------------------------------- + +namespace DotNetOpenAuth.BuildTasks { + using Microsoft.Build.Framework; + using Microsoft.Build.Utilities; + + /// <summary> + /// Trims item identities. + /// </summary> + public class Trim : Task { + /// <summary> + /// Gets or sets the characters that should be trimmed off if found at the start of items' ItemSpecs. + /// </summary> + public string StartCharacters { get; set; } + + /// <summary> + /// Gets or sets the characters that should be trimmed off if found at the end of items' ItemSpecs. + /// </summary> + public string EndCharacters { get; set; } + + /// <summary> + /// Gets or sets the items with ItemSpec's to be trimmed. + /// </summary> + [Required] + public ITaskItem[] Inputs { get; set; } + + /// <summary> + /// Gets or sets the items with trimmed ItemSpec strings. + /// </summary> + [Output] + public ITaskItem[] Outputs { get; set; } + + /// <summary> + /// Executes this instance. + /// </summary> + /// <returns>A value indicating whether the task completed successfully.</returns> + public override bool Execute() { + this.Outputs = new ITaskItem[this.Inputs.Length]; + for (int i = 0; i < this.Inputs.Length; i++) { + this.Outputs[i] = new TaskItem(this.Inputs[i]); + if (!string.IsNullOrEmpty(this.StartCharacters)) { + this.Outputs[i].ItemSpec = this.Outputs[i].ItemSpec.TrimStart(this.StartCharacters.ToCharArray()); + } + if (!string.IsNullOrEmpty(this.EndCharacters)) { + this.Outputs[i].ItemSpec = this.Outputs[i].ItemSpec.TrimEnd(this.EndCharacters.ToCharArray()); + } + } + + return true; + } + } +} diff --git a/src/DotNetOpenAuth.Test/DotNetOpenAuth.Test.csproj b/src/DotNetOpenAuth.Test/DotNetOpenAuth.Test.csproj index f9ec80e..414d3d0 100644 --- a/src/DotNetOpenAuth.Test/DotNetOpenAuth.Test.csproj +++ b/src/DotNetOpenAuth.Test/DotNetOpenAuth.Test.csproj @@ -53,9 +53,10 @@ <ErrorReport>prompt</ErrorReport> <WarningLevel>4</WarningLevel> </PropertyGroup> - <PropertyGroup Condition=" '$(Sign)' == 'true' "> + <PropertyGroup> <SignAssembly>true</SignAssembly> - <AssemblyOriginatorKeyFile>..\official-build-key.pfx</AssemblyOriginatorKeyFile> + <DelaySign>true</DelaySign> + <AssemblyOriginatorKeyFile>..\official-build-key.pub</AssemblyOriginatorKeyFile> </PropertyGroup> <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'CodeAnalysis|AnyCPU' "> <DebugSymbols>true</DebugSymbols> diff --git a/src/DotNetOpenAuth.vsmdi b/src/DotNetOpenAuth.vsmdi index 8874d7e..bed7c96 100644 --- a/src/DotNetOpenAuth.vsmdi +++ b/src/DotNetOpenAuth.vsmdi @@ -144,7 +144,7 @@ <TestLink id="f4537b23-bb5e-5c6f-da53-64b34472f0dc" name="ChannelGetter" storage="..\bin\debug\dotnetopenauth.test.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, PublicKeyToken=b03f5f7f11d50a3a" /> <TestLink id="75fa4664-bb0e-3a54-de29-c18ac712b231" name="Mode" storage="..\bin\debug\dotnetopenauth.test.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, PublicKeyToken=b03f5f7f11d50a3a" /> <TestLink id="94ba9fd3-851d-13b2-e273-6294b167c13e" name="HttpsSignatureVerification" storage="..\bin\debug\dotnetopenauth.test.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, PublicKeyToken=b03f5f7f11d50a3a" /> - <TestLink id="ff78d828-b437-aaeb-e48a-85a5ad1fe396" name="Ctor" storage="..\bin\debug\dotnetopenauth.test.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, PublicKeyToken=b03f5f7f11d50a3a" /> + <TestLink id="cbfeb75b-d031-7df3-c281-3c9e1c450042" name="CtorFromRequest" storage="..\bin\debug\dotnetopenauth.test.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, PublicKeyToken=b03f5f7f11d50a3a" /> <TestLink id="5460f9c6-ec9d-969d-5aff-b946d6776e25" name="CtorWithNullProtocolMessage" storage="..\bin\debug\dotnetopenauth.test.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, PublicKeyToken=b03f5f7f11d50a3a" /> <TestLink id="d5f4e610-eabe-1dc0-ab3f-7c9dcb17fcc3" name="CtorImpliedLocalIdentifier" storage="..\bin\debug\dotnetopenauth.test.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, PublicKeyToken=b03f5f7f11d50a3a" /> <TestLink id="64d8c630-76c6-e420-937b-19c889dd7f59" name="CtorNonMessageType" storage="..\bin\debug\dotnetopenauth.test.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, PublicKeyToken=b03f5f7f11d50a3a" /> @@ -241,7 +241,7 @@ <TestLink id="704a32d0-3f50-d462-f767-fd9cf1981b7f" name="ProviderVersion" storage="..\bin\debug\dotnetopenauth.test.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, PublicKeyToken=b03f5f7f11d50a3a" /> <TestLink id="f362baf3-da5b-1b8c-39ae-7c9b2051270a" name="AuthenticationTimeUtcSetUtc" storage="..\bin\debug\dotnetopenauth.test.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, PublicKeyToken=b03f5f7f11d50a3a" /> <TestLink id="3bb818b4-5423-ad91-8cd9-8606ec85d2cb" name="ReadFromRequestAuthorizationScattered" storage="..\bin\debug\dotnetopenauth.test.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, PublicKeyToken=b03f5f7f11d50a3a" /> - <TestLink id="cbfeb75b-d031-7df3-c281-3c9e1c450042" name="CtorFromRequest" storage="..\bin\debug\dotnetopenauth.test.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, PublicKeyToken=b03f5f7f11d50a3a" /> + <TestLink id="30f3c12b-e510-de63-5acd-ae8e32866592" name="CreateQueryString" storage="..\bin\debug\dotnetopenauth.test.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, PublicKeyToken=b03f5f7f11d50a3a" /> <TestLink id="9302541c-9c30-9ce7-66db-348ee4e9f6ee" name="UnifyExtensionsAsSregWithSreg" storage="..\bin\debug\dotnetopenauth.test.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, PublicKeyToken=b03f5f7f11d50a3a" /> <TestLink id="997253fb-7591-c151-1705-02976b400f27" name="AddAttributeTwice" storage="..\bin\debug\dotnetopenauth.test.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, PublicKeyToken=b03f5f7f11d50a3a" /> <TestLink id="88ae5661-da27-91c5-4d78-1f43cd716127" name="EqualsTest" storage="..\bin\debug\dotnetopenauth.test.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, PublicKeyToken=b03f5f7f11d50a3a" /> @@ -331,7 +331,7 @@ <TestLink id="d083396b-db68-1318-e62b-6dc9f89e26bd" name="CtorDefault" storage="..\bin\debug\dotnetopenauth.test.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, PublicKeyToken=b03f5f7f11d50a3a" /> <TestLink id="2f6a81c5-cd04-0ca0-22ee-d4213f9cf147" name="EqualityTests" storage="..\bin\debug\dotnetopenauth.test.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, PublicKeyToken=b03f5f7f11d50a3a" /> <TestLink id="72d3f240-67f2-0b04-bd31-a99c3f7a8e12" name="SharedAssociationPositive" storage="..\bin\debug\dotnetopenauth.test.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, PublicKeyToken=b03f5f7f11d50a3a" /> - <TestLink id="30f3c12b-e510-de63-5acd-ae8e32866592" name="CreateQueryString" storage="..\bin\debug\dotnetopenauth.test.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, PublicKeyToken=b03f5f7f11d50a3a" /> + <TestLink id="3cd9447e-9ffd-f706-37bb-e7eb5828e430" name="InvalidRealmEmpty" storage="..\bin\debug\dotnetopenauth.test.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, PublicKeyToken=b03f5f7f11d50a3a" /> <TestLink id="28fe030c-d36e-13cf-475c-7813210bf886" name="AddAttributeRequestAgain" storage="..\bin\debug\dotnetopenauth.test.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, PublicKeyToken=b03f5f7f11d50a3a" /> <TestLink id="e7a41771-7dda-be44-0755-e06300f3cd92" name="IsSaneTest" storage="..\bin\debug\dotnetopenauth.test.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, PublicKeyToken=b03f5f7f11d50a3a" /> <TestLink id="2e23dc5a-93ea-11a5-d00d-02d294794e5f" name="AssociateDiffieHellmanOverHttps" storage="..\bin\debug\dotnetopenauth.test.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, PublicKeyToken=b03f5f7f11d50a3a" /> @@ -349,6 +349,7 @@ <TestLink id="313faac6-6357-5468-2d4d-4c9fba001678" name="TryParseNoThrow" storage="..\bin\debug\dotnetopenauth.test.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, PublicKeyToken=b03f5f7f11d50a3a" /> <TestLink id="7cbe4350-38d0-db7e-335c-93d9398fc95b" name="ExtensionOnlyFacadeLevel" storage="..\bin\debug\dotnetopenauth.test.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, PublicKeyToken=b03f5f7f11d50a3a" /> <TestLink id="2f5cfa57-bcb4-39af-e769-2d7c34e2598e" name="Ctor" storage="..\bin\debug\dotnetopenauth.test.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, PublicKeyToken=b03f5f7f11d50a3a" /> + <TestLink id="ff78d828-b437-aaeb-e48a-85a5ad1fe396" name="Ctor" storage="..\bin\debug\dotnetopenauth.test.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, PublicKeyToken=b03f5f7f11d50a3a" /> <TestLink id="29e45877-ca7a-85de-5c39-6d43befe1a1e" name="DiscoveryRequireSslWithInsecureXrdsButSecureLinkTags" storage="..\bin\debug\dotnetopenauth.test.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, PublicKeyToken=b03f5f7f11d50a3a" /> <TestLink id="c351c660-d583-d869-0129-2e312665d815" name="CtorBlank" storage="..\bin\debug\dotnetopenauth.test.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, PublicKeyToken=b03f5f7f11d50a3a" /> <TestLink id="f063a3c6-5a36-2801-53d7-5142416199a9" name="ImplicitConversionFromStringTests" storage="..\bin\debug\dotnetopenauth.test.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, PublicKeyToken=b03f5f7f11d50a3a" /> @@ -405,7 +406,6 @@ <TestLink id="7cdabb8a-aefa-e90e-c32e-047404b64c2d" name="SerializeTest" storage="..\bin\debug\dotnetopenauth.test.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, PublicKeyToken=b03f5f7f11d50a3a" /> <TestLink id="f6979feb-7016-4e2b-14e2-e6c2c392419f" name="RemoveByKeyValuePair" storage="..\bin\debug\dotnetopenauth.test.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, PublicKeyToken=b03f5f7f11d50a3a" /> <TestLink id="58df167c-cf19-351c-cb09-5c52ae9f97be" name="DeserializeNull" storage="..\bin\debug\dotnetopenauth.test.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, PublicKeyToken=b03f5f7f11d50a3a" /> - <TestLink id="80719076-10fd-20a7-7ff3-a0aa2bc661cb" name="CtorNull" storage="..\bin\debug\dotnetopenauth.test.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, PublicKeyToken=b03f5f7f11d50a3a" /> <TestLink id="a778f331-f14e-9d6e-f942-a023423540f6" name="Ctor" storage="..\bin\debug\dotnetopenauth.test.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, PublicKeyToken=b03f5f7f11d50a3a" /> <TestLink id="a1ff4ada-fe5d-d2f3-b7fb-8e72db02b3c3" name="Full" storage="..\bin\debug\dotnetopenauth.test.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, PublicKeyToken=b03f5f7f11d50a3a" /> <TestLink id="be00d3ef-f24d-eb8a-d251-4d691736ee6f" name="AddAttributeRequestNull" storage="..\bin\debug\dotnetopenauth.test.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, PublicKeyToken=b03f5f7f11d50a3a" /> @@ -454,7 +454,7 @@ <TestLink id="62c6ee5b-ac29-461c-2373-bf620e948825" name="InvalidRealmNoScheme" storage="..\bin\debug\dotnetopenauth.test.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, PublicKeyToken=b03f5f7f11d50a3a" /> <TestLink id="115283b9-d95c-9a92-2197-96685ee8e96a" name="TwoExtensionsSameTypeUri" storage="..\bin\debug\dotnetopenauth.test.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, PublicKeyToken=b03f5f7f11d50a3a" /> <TestLink id="352d9fd6-cf38-4b72-478f-e3e17ace55f5" name="NoValueLoose" storage="..\bin\debug\dotnetopenauth.test.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, PublicKeyToken=b03f5f7f11d50a3a" /> - <TestLink id="3cd9447e-9ffd-f706-37bb-e7eb5828e430" name="InvalidRealmEmpty" storage="..\bin\debug\dotnetopenauth.test.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, PublicKeyToken=b03f5f7f11d50a3a" /> + <TestLink id="80719076-10fd-20a7-7ff3-a0aa2bc661cb" name="CtorNull" storage="..\bin\debug\dotnetopenauth.test.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, PublicKeyToken=b03f5f7f11d50a3a" /> <TestLink id="b2b54c72-1d26-8c28-ebf5-7a5a4beeec43" name="VerifyNonZeroLengthOnNull" storage="..\bin\debug\dotnetopenauth.test.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, PublicKeyToken=b03f5f7f11d50a3a" /> <TestLink id="9684f7bf-cdda-a2c5-0822-29cb0add3835" name="ResponseNonceGetter" storage="..\bin\debug\dotnetopenauth.test.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, PublicKeyToken=b03f5f7f11d50a3a" /> <TestLink id="c4001e1c-75ad-236b-284f-318905d2bc3a" name="CreateRequestOnNonOpenID" storage="..\bin\debug\dotnetopenauth.test.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, PublicKeyToken=b03f5f7f11d50a3a" /> diff --git a/src/DotNetOpenAuth/DotNetOpenAuth.csproj b/src/DotNetOpenAuth/DotNetOpenAuth.csproj index 3da8526..aba573d 100644 --- a/src/DotNetOpenAuth/DotNetOpenAuth.csproj +++ b/src/DotNetOpenAuth/DotNetOpenAuth.csproj @@ -25,7 +25,7 @@ <DocumentationFile>..\..\bin\Debug\DotNetOpenAuth.xml</DocumentationFile> <RunCodeAnalysis>false</RunCodeAnalysis> <CodeAnalysisRules>-Microsoft.Design#CA1054;-Microsoft.Design#CA1056;-Microsoft.Design#CA1055</CodeAnalysisRules> - <CodeContractsEnableRuntimeChecking>False</CodeContractsEnableRuntimeChecking> + <CodeContractsEnableRuntimeChecking>True</CodeContractsEnableRuntimeChecking> <CodeContractsCustomRewriterAssembly> </CodeContractsCustomRewriterAssembly> <CodeContractsCustomRewriterClass> @@ -48,6 +48,8 @@ <CodeContractsShowSquigglies>True</CodeContractsShowSquigglies> <CodeContractsArithmeticObligations>False</CodeContractsArithmeticObligations> <CodeContractsRuntimeOnlyPublicSurface>False</CodeContractsRuntimeOnlyPublicSurface> + <CodeContractsRuntimeThrowOnFailure>False</CodeContractsRuntimeThrowOnFailure> + <CodeContractsRuntimeCallSiteRequires>False</CodeContractsRuntimeCallSiteRequires> </PropertyGroup> <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' "> <DebugType>pdbonly</DebugType> @@ -60,7 +62,7 @@ <DocumentationFile>..\..\bin\Release\DotNetOpenAuth.xml</DocumentationFile> <RunCodeAnalysis>true</RunCodeAnalysis> <CodeAnalysisRules>-Microsoft.Design#CA1054;-Microsoft.Design#CA1056;-Microsoft.Design#CA1055</CodeAnalysisRules> - <CodeContractsEnableRuntimeChecking>False</CodeContractsEnableRuntimeChecking> + <CodeContractsEnableRuntimeChecking>True</CodeContractsEnableRuntimeChecking> <CodeContractsCustomRewriterAssembly> </CodeContractsCustomRewriterAssembly> <CodeContractsCustomRewriterClass> @@ -81,16 +83,21 @@ <CodeContractsUseBaseLine>False</CodeContractsUseBaseLine> <CodeContractsRunInBackground>True</CodeContractsRunInBackground> <CodeContractsShowSquigglies>False</CodeContractsShowSquigglies> + <CodeContractsRuntimeOnlyPublicSurface>False</CodeContractsRuntimeOnlyPublicSurface> + <CodeContractsRuntimeThrowOnFailure>False</CodeContractsRuntimeThrowOnFailure> + <CodeContractsRuntimeCallSiteRequires>False</CodeContractsRuntimeCallSiteRequires> + <CodeContractsArithmeticObligations>False</CodeContractsArithmeticObligations> </PropertyGroup> - <PropertyGroup Condition=" '$(Sign)' == 'true' "> + <PropertyGroup> <SignAssembly>true</SignAssembly> - <AssemblyOriginatorKeyFile>..\official-build-key.pfx</AssemblyOriginatorKeyFile> + <DelaySign>true</DelaySign> + <AssemblyOriginatorKeyFile>..\official-build-key.pub</AssemblyOriginatorKeyFile> <DefineConstants>$(DefineConstants);StrongNameSigned</DefineConstants> </PropertyGroup> <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'CodeAnalysis|AnyCPU' "> <DebugSymbols>true</DebugSymbols> <OutputPath>..\..\bin\CodeAnalysis\</OutputPath> - <DefineConstants>CONTRACTS_FULL;DEBUG;TRACE</DefineConstants> + <DefineConstants>$(DefineConstants);CONTRACTS_FULL;DEBUG;TRACE</DefineConstants> <DocumentationFile>..\..\bin\CodeAnalysis\DotNetOpenAuth.xml</DocumentationFile> <DebugType>full</DebugType> <PlatformTarget>AnyCPU</PlatformTarget> diff --git a/src/DotNetOpenAuth/OAuth/ChannelElements/ICombinedOpenIdProviderTokenManager.cs b/src/DotNetOpenAuth/OAuth/ChannelElements/ICombinedOpenIdProviderTokenManager.cs index ff004cb..dd28e71 100644 --- a/src/DotNetOpenAuth/OAuth/ChannelElements/ICombinedOpenIdProviderTokenManager.cs +++ b/src/DotNetOpenAuth/OAuth/ChannelElements/ICombinedOpenIdProviderTokenManager.cs @@ -15,7 +15,7 @@ namespace DotNetOpenAuth.OAuth.ChannelElements { /// This interface should be implemented by the same class that implements /// <see cref="ITokenManager"/> in order to enable the OpenID+OAuth extension. /// </remarks> - public interface ICombinedOpenIdProviderTokenManager { + public interface ICombinedOpenIdProviderTokenManager : IOpenIdOAuthTokenManager, ITokenManager { /// <summary> /// Gets the OAuth consumer key for a given OpenID relying party realm. /// </summary> diff --git a/src/DotNetOpenAuth/OAuth/ChannelElements/PlaintextSigningBindingElement.cs b/src/DotNetOpenAuth/OAuth/ChannelElements/PlaintextSigningBindingElement.cs index 9f99066..22e5f20 100644 --- a/src/DotNetOpenAuth/OAuth/ChannelElements/PlaintextSigningBindingElement.cs +++ b/src/DotNetOpenAuth/OAuth/ChannelElements/PlaintextSigningBindingElement.cs @@ -41,7 +41,12 @@ namespace DotNetOpenAuth.OAuth.ChannelElements { /// <param name="message">The message that needs to be signed.</param> /// <returns>True if this binding element can be used to sign the message. False otherwise.</returns> protected override bool IsMessageApplicable(ITamperResistantOAuthMessage message) { - return string.Equals(message.Recipient.Scheme, "https", StringComparison.OrdinalIgnoreCase); + if (string.Equals(message.Recipient.Scheme, "https", StringComparison.OrdinalIgnoreCase)) { + return true; + } else { + Logger.Bindings.DebugFormat("The {0} element will not sign this message because the URI scheme is not https.", this.GetType().Name); + return false; + } } /// <summary> diff --git a/src/DotNetOpenAuth/OAuth/ServiceProvider.cs b/src/DotNetOpenAuth/OAuth/ServiceProvider.cs index 242e0db..9c37815 100644 --- a/src/DotNetOpenAuth/OAuth/ServiceProvider.cs +++ b/src/DotNetOpenAuth/OAuth/ServiceProvider.cs @@ -236,11 +236,12 @@ namespace DotNetOpenAuth.OAuth { /// <summary> /// Gets the OAuth authorization request included with an OpenID authentication - /// request. + /// request, if there is one. /// </summary> /// <param name="openIdRequest">The OpenID authentication request.</param> /// <returns> - /// The scope of access the relying party is requesting. + /// The scope of access the relying party is requesting, or null if no OAuth request + /// is present. /// </returns> /// <remarks> /// <para>Call this method rather than simply extracting the OAuth extension @@ -270,24 +271,43 @@ namespace DotNetOpenAuth.OAuth { return authzRequest; } - /// <summary> + /// <summary> /// Attaches the authorization response to an OpenID authentication response. /// </summary> /// <param name="openIdAuthenticationRequest">The OpenID authentication request.</param> - /// <param name="consumerKey">The consumer key. May and should be <c>null</c> if and only if <paramref name="scope"/> is null.</param> + /// <param name="consumerKey">The consumer key. Must be <c>null</c> if and only if <paramref name="scope"/> is null.</param> /// <param name="scope">The approved access scope. Use <c>null</c> to indicate no access was granted. The empty string will be interpreted as some default level of access is granted.</param> [SuppressMessage("Microsoft.Design", "CA1011:ConsiderPassingBaseTypesAsParameters", Justification = "We want to take IAuthenticationRequest because that's the only supported use case.")] - public void AttachAuthorizationResponse(IAuthenticationRequest openIdAuthenticationRequest, string consumerKey, string scope) { + [Obsolete("Call the overload that doesn't take a consumerKey instead.")] + public void AttachAuthorizationResponse(IHostProcessedRequest openIdAuthenticationRequest, string consumerKey, string scope) { Contract.Requires(openIdAuthenticationRequest != null); Contract.Requires((consumerKey == null) == (scope == null)); Contract.Requires(this.TokenManager is IOpenIdOAuthTokenManager); ErrorUtilities.VerifyArgumentNotNull(openIdAuthenticationRequest, "openIdAuthenticationRequest"); - var openidTokenManager = this.TokenManager as IOpenIdOAuthTokenManager; + var openidTokenManager = this.TokenManager as ICombinedOpenIdProviderTokenManager; ErrorUtilities.VerifyOperation(openidTokenManager != null, OAuthStrings.OpenIdOAuthExtensionRequiresSpecialTokenManagerInterface, typeof(IOpenIdOAuthTokenManager).FullName); + ErrorUtilities.VerifyArgument(consumerKey == null || consumerKey == openidTokenManager.GetConsumerKey(openIdAuthenticationRequest.Realm), "The consumer key and the realm did not match according to the token manager."); + + this.AttachAuthorizationResponse(openIdAuthenticationRequest, scope); + } + + /// <summary> + /// Attaches the authorization response to an OpenID authentication response. + /// </summary> + /// <param name="openIdAuthenticationRequest">The OpenID authentication request.</param> + /// <param name="scope">The approved access scope. Use <c>null</c> to indicate no access was granted. The empty string will be interpreted as some default level of access is granted.</param> + [SuppressMessage("Microsoft.Design", "CA1011:ConsiderPassingBaseTypesAsParameters", Justification = "We want to take IAuthenticationRequest because that's the only supported use case.")] + public void AttachAuthorizationResponse(IHostProcessedRequest openIdAuthenticationRequest, string scope) { + Contract.Requires(openIdAuthenticationRequest != null); + Contract.Requires(this.TokenManager is IOpenIdOAuthTokenManager); + ErrorUtilities.VerifyArgumentNotNull(openIdAuthenticationRequest, "openIdAuthenticationRequest"); + var openidTokenManager = this.TokenManager as ICombinedOpenIdProviderTokenManager; + ErrorUtilities.VerifyOperation(openidTokenManager != null, OAuthStrings.OpenIdOAuthExtensionRequiresSpecialTokenManagerInterface, typeof(ICombinedOpenIdProviderTokenManager).FullName); IOpenIdMessageExtension response; if (scope != null) { // Generate an authorized request token to return to the relying party. + string consumerKey = openidTokenManager.GetConsumerKey(openIdAuthenticationRequest.Realm); var approvedResponse = new AuthorizationApprovedResponse { RequestToken = this.TokenGenerator.GenerateRequestToken(consumerKey), Scope = scope, diff --git a/src/DotNetOpenAuth/OAuth/WebConsumer.cs b/src/DotNetOpenAuth/OAuth/WebConsumer.cs index 56d3029..d86444d 100644 --- a/src/DotNetOpenAuth/OAuth/WebConsumer.cs +++ b/src/DotNetOpenAuth/OAuth/WebConsumer.cs @@ -120,7 +120,8 @@ namespace DotNetOpenAuth.OAuth { } // Prepare a message to exchange the request token for an access token. - var requestAccess = new AuthorizedTokenRequest(this.ServiceProvider.AccessTokenEndpoint, this.ServiceProvider.Version) { + // We are careful to use a v1.0 message version so that the oauth_verifier is not required. + var requestAccess = new AuthorizedTokenRequest(this.ServiceProvider.AccessTokenEndpoint, Protocol.V10.Version) { RequestToken = positiveAuthorization.RequestToken, ConsumerKey = this.ConsumerKey, }; diff --git a/src/DotNetOpenAuth/OpenId/RelyingParty/AuthenticationRequest.cs b/src/DotNetOpenAuth/OpenId/RelyingParty/AuthenticationRequest.cs index 9912d0b..060ef21 100644 --- a/src/DotNetOpenAuth/OpenId/RelyingParty/AuthenticationRequest.cs +++ b/src/DotNetOpenAuth/OpenId/RelyingParty/AuthenticationRequest.cs @@ -345,11 +345,12 @@ namespace DotNetOpenAuth.OpenId.RelyingParty { /// before calling this method. /// </remarks> private static IEnumerable<AuthenticationRequest> CreateInternal(Identifier userSuppliedIdentifier, OpenIdRelyingParty relyingParty, Realm realm, Uri returnToUrl, IEnumerable<ServiceEndpoint> serviceEndpoints, bool createNewAssociationsAsNeeded) { - Contract.Requires(userSuppliedIdentifier != null); - Contract.Requires(relyingParty != null); - Contract.Requires(realm != null); - Contract.Requires(serviceEndpoints != null); - Contract.Ensures(Contract.Result<IEnumerable<AuthenticationRequest>>() != null); + // DO NOT USE CODE CONTRACTS IN THIS METHOD, since it uses yield return + ErrorUtilities.VerifyArgumentNotNull(userSuppliedIdentifier, "userSuppliedIdentifier"); + ErrorUtilities.VerifyArgumentNotNull(relyingParty, "relyingParty"); + ErrorUtilities.VerifyArgumentNotNull(realm, "realm"); + ErrorUtilities.VerifyArgumentNotNull(serviceEndpoints, "serviceEndpoints"); + ////Contract.Ensures(Contract.Result<IEnumerable<AuthenticationRequest>>() != null); // If shared associations are required, then we had better have an association store. ErrorUtilities.VerifyOperation(!relyingParty.SecuritySettings.RequireAssociation || relyingParty.AssociationManager.HasAssociationStore, OpenIdStrings.AssociationStoreRequired); diff --git a/src/DotNetOpenAuth/OpenId/RelyingParty/OpenIdRelyingPartyControlBase.cs b/src/DotNetOpenAuth/OpenId/RelyingParty/OpenIdRelyingPartyControlBase.cs index 8451dbd..c584580 100644 --- a/src/DotNetOpenAuth/OpenId/RelyingParty/OpenIdRelyingPartyControlBase.cs +++ b/src/DotNetOpenAuth/OpenId/RelyingParty/OpenIdRelyingPartyControlBase.cs @@ -73,6 +73,11 @@ namespace DotNetOpenAuth.OpenId.RelyingParty { private const bool UsePersistentCookieDefault = false; /// <summary> + /// Default value of <see cref="LoginMode"/>. + /// </summary> + private const LoginSiteNotification LoginModeDefault = LoginSiteNotification.FormsAuthentication; + + /// <summary> /// The default value for the <see cref="RealmUrl"/> property. /// </summary> private const string RealmUrlDefault = "~/"; @@ -102,6 +107,11 @@ namespace DotNetOpenAuth.OpenId.RelyingParty { private const string UsePersistentCookieViewStateKey = "UsePersistentCookie"; /// <summary> + /// The viewstate key to use for the <see cref="LoginMode"/> property. + /// </summary> + private const string LoginModeViewStateKey = "LoginMode"; + + /// <summary> /// The viewstate key to use for the <see cref="RealmUrl"/> property. /// </summary> private const string RealmUrlViewStateKey = "RealmUrl"; @@ -200,6 +210,25 @@ namespace DotNetOpenAuth.OpenId.RelyingParty { #endregion /// <summary> + /// Methods of indicating to the rest of the web site that the user has logged in. + /// </summary> + public enum LoginSiteNotification { + /// <summary> + /// The rest of the web site is unaware that the user just completed an OpenID login. + /// </summary> + None, + + /// <summary> + /// After the <see cref="OpenIdRelyingPartyControlBase.LoggedIn"/> event is fired + /// the control automatically calls <see cref="System.Web.Security.FormsAuthentication.RedirectFromLoginPage(string, bool)"/> + /// with the <see cref="IAuthenticationResponse.ClaimedIdentifier"/> as the username + /// unless the <see cref="OpenIdRelyingPartyControlBase.LoggedIn"/> event handler sets + /// <see cref="OpenIdEventArgs.Cancel"/> property to true. + /// </summary> + FormsAuthentication, + } + + /// <summary> /// Gets or sets the <see cref="OpenIdRelyingParty"/> instance to use. /// </summary> /// <value>The default value is an <see cref="OpenIdRelyingParty"/> instance initialized according to the web.config file.</value> @@ -312,6 +341,16 @@ namespace DotNetOpenAuth.OpenId.RelyingParty { } /// <summary> + /// Gets or sets the way a completed login is communicated to the rest of the web site. + /// </summary> + [Bindable(true), DefaultValue(LoginModeDefault), Category(BehaviorCategory)] + [Description("The way a completed login is communicated to the rest of the web site.")] + public LoginSiteNotification LoginMode { + get { return (LoginSiteNotification)(this.ViewState[LoginModeViewStateKey] ?? LoginModeDefault); } + set { this.ViewState[LoginModeViewStateKey] = value; } + } + + /// <summary> /// Gets or sets a value indicating when to use a popup window to complete the login experience. /// </summary> /// <value>The default value is <see cref="PopupBehavior.Never"/>.</value> @@ -515,7 +554,14 @@ namespace DotNetOpenAuth.OpenId.RelyingParty { } if (!args.Cancel) { - FormsAuthentication.RedirectFromLoginPage(response.ClaimedIdentifier, this.UsePersistentCookie); + switch (this.LoginMode) { + case LoginSiteNotification.FormsAuthentication: + FormsAuthentication.RedirectFromLoginPage(response.ClaimedIdentifier, this.UsePersistentCookie); + break; + case LoginSiteNotification.None: + default: + break; + } } } diff --git a/src/DotNetOpenAuth/Util.cs b/src/DotNetOpenAuth/Util.cs index 1a67966..aeeba88 100644 --- a/src/DotNetOpenAuth/Util.cs +++ b/src/DotNetOpenAuth/Util.cs @@ -11,6 +11,7 @@ namespace DotNetOpenAuth { using System.Net; using System.Reflection; using System.Text; + using DotNetOpenAuth.Messaging; /// <summary> /// A grab-bag utility class. @@ -74,7 +75,8 @@ namespace DotNetOpenAuth { return new DelayedToString<IEnumerable<KeyValuePair<K, V>>>( pairs, p => { - Contract.Requires(pairs != null); + ////Contract.Requires(pairs != null); // CC: anonymous method can't handle it + ErrorUtilities.VerifyArgumentNotNull(pairs, "pairs"); var dictionary = pairs as IDictionary<K, V>; StringBuilder sb = new StringBuilder(dictionary != null ? dictionary.Count * 40 : 200); foreach (var pair in pairs) { @@ -102,13 +104,15 @@ namespace DotNetOpenAuth { /// <param name="list">The list of elements.</param> /// <param name="multiLineElements">if set to <c>true</c>, special formatting will be applied to the output to make it clear where one element ends and the next begins.</param> /// <returns>An object whose ToString method will perform the actual work of generating the string.</returns> + [ContractVerification(false)] internal static object ToStringDeferred<T>(this IEnumerable<T> list, bool multiLineElements) { return new DelayedToString<IEnumerable<T>>( list, l => { - Contract.Requires(l != null); + ////Contract.Requires(l != null); // CC: anonymous method can't handle it + ErrorUtilities.VerifyArgumentNotNull(l, "l"); string newLine = Environment.NewLine; - Contract.Assume(newLine != null && newLine.Length > 0); + ////Contract.Assume(newLine != null && newLine.Length > 0); // CC: anonymous method can't handle it StringBuilder sb = new StringBuilder(); if (multiLineElements) { sb.AppendLine("[{"); diff --git a/src/official-build-key.pub b/src/official-build-key.pub Binary files differnew file mode 100644 index 0000000..6e68f53 --- /dev/null +++ b/src/official-build-key.pub diff --git a/src/version.txt b/src/version.txt index e4604e3..15a2799 100644 --- a/src/version.txt +++ b/src/version.txt @@ -1 +1 @@ -3.2.1 +3.3.0 |