diff options
48 files changed, 951 insertions, 461 deletions
@@ -5,7 +5,7 @@ <SolutionPath>$(ProjectRoot)\src\$(ProductName).sln</SolutionPath> <ILMergeOutputAssemblyDirectory>$(OutputPath)\unified\</ILMergeOutputAssemblyDirectory> <ILMergeOutputAssembly>$(ILMergeOutputAssemblyDirectory)\$(ProductName).dll</ILMergeOutputAssembly> - <ProjectTemplatesLayoutPath>$(ProjectRoot)\obj\$(Configuration)\projecttemplates\</ProjectTemplatesLayoutPath> + <ProjectTemplatesLayoutPath>$(IntermediatePath)projecttemplates\</ProjectTemplatesLayoutPath> </PropertyGroup> <Import Project="$(ProjectRoot)\tools\$(ProductName).Versioning.targets"/> @@ -153,9 +153,7 @@ $(ProjectRoot)\projecttemplates\**\StyleCop.Cache; $(ProjectRoot)\projecttemplates\**\*.user; $(ProjectRoot)\projecttemplates\**\obj\**; - $(ProjectRoot)\projecttemplates\**\bin\DotNetOpenAuth.dll; - $(ProjectRoot)\projecttemplates\**\bin\DotNetOpenAuth.pdb; - $(ProjectRoot)\projecttemplates\**\bin\Microsoft.Contracts.dll; + $(ProjectRoot)\projecttemplates\**\bin\**; $(ProjectRoot)\projecttemplates\**\*.ldf; $(ProjectRoot)\projecttemplates\**\*.mdf; "/> @@ -175,17 +173,28 @@ <ProjectTemplatesLayout Include="@(ProjectTemplatesSource->'$(ProjectTemplatesLayoutPath)%(RecursiveDir)%(FileName)%(Extension)')"/> <ProjectTemplatesTransformLayout Include="@(_ProjectTemplatesTransformSource->'$(ProjectTemplatesLayoutPath)%(RecursiveDir)%(FileName)%(Extension)')"/> + <VSProjectTemplates Include="@(ProjectTemplatesLayout)" Condition="'%(Extension)' == '.vstemplate'" /> + <TopLevelVSProjectTemplates Include="@(VSProjectTemplates)" Condition="'%(RootDir)%(Directory)' == '$(ProjectTemplatesLayoutPath)'" /> + <!-- Include the template icon --> - <ProjectTemplatesSource Include="@(ProjectTemplates->'$(ProjectRoot)\doc\logo\dotnetopenid.ico')" /> - <ProjectTemplatesLayout Include="@(ProjectTemplates->'$(ProjectTemplatesLayoutPath)%(RecursiveDir)__TemplateIcon.ico')" /> + <ProjectTemplatesSource Include="$(ProjectRoot)\doc\logo\dotnetopenid.ico" /> + <ProjectTemplatesLayout Include="$(ProjectTemplatesLayoutPath)__TemplateIcon.ico" /> + <!-- Add external libraries --> <!-- Include the unified, signed version of the library --> - <ProjectTemplatesSource Include="@(ProjectTemplates->'$(ILMergeOutputAssembly)')" /> - <ProjectTemplatesSource Include="@(ProjectTemplates->'$(ILMergeOutputAssemblyDirectory)\$(ProductName).pdb')" /> - <ProjectTemplatesSource Include="@(ProjectTemplates->'$(OutputPath)\$(ProductName).Contracts.dll')" /> - <ProjectTemplatesLayout Include="@(ProjectTemplates->'$(ProjectTemplatesLayoutPath)%(RecursiveDir)bin\$(ProductName).dll')" /> - <ProjectTemplatesLayout Include="@(ProjectTemplates->'$(ProjectTemplatesLayoutPath)%(RecursiveDir)bin\$(ProductName).pdb')" /> - <ProjectTemplatesLayout Include="@(ProjectTemplates->'$(ProjectTemplatesLayoutPath)%(RecursiveDir)bin\$(ProductName).Contracts.dll')" /> + <ProjectTemplateLibraries Include="$(ILMergeOutputAssembly)" /> + <ProjectTemplateLibraries Include="$(ILMergeOutputAssemblyDirectory)\$(ProductName).pdb" /> + <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)')" /> </ItemGroup> <Trim Inputs="@(_ProjectTemplatesTransformSource)" MetadataName="BeforeTokens" AllAfter="\"> <Output TaskParameter="Outputs" ItemName="ProjectTemplatesTransformSource" /> @@ -199,22 +208,61 @@ <ChangeProjectReferenceToAssemblyReference Projects="@(CopiedProjectTemplateFiles)" Condition="'%(Extension)' == '.csproj'" - ProjectReference="..\..\src\$(ProductName)\$(ProductName).csproj" - Reference="Bin\$(ProductName).dll" /> + 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="ProjectTemplates" DependsOnTargets="ProjectTemplatesLayout"> - <PropertyGroup> - <WebFormsRelyingPartyZipFile>$(ProjectTemplatesLayoutPath)\WebFormsRelyingParty.zip</WebFormsRelyingPartyZipFile> - </PropertyGroup> <ItemGroup> - <WebFormsRelyingPartyProjectTemplateLayout Include="$(ProjectTemplatesLayoutPath)\WebFormsRelyingParty\**\*" /> + <VSProjectTemplateZipFiles Include="@(TopLevelVSProjectTemplates->'%(RootDir)%(Directory)%(FileName).zip')" /> </ItemGroup> - <Delete Files="$(WebFormsRelyingPartyZipFile)" /> + + <DiscoverProjectTemplates TopLevelTemplates="@(TopLevelVSProjectTemplates)"> + <Output TaskParameter="ProjectTemplates" ItemName="SubVSTemplates" /> + <Output TaskParameter="ProjectTemplateContents" ItemName="TemplateItemContents" /> + </DiscoverProjectTemplates> + + <ItemGroup> + <!-- Include in each template .zip file the top-level .vstemplate file itself. --> + <VSProjectTemplateContents Include="@(TopLevelVSProjectTemplates)"> + <ZipFile>$(ProjectTemplatesLayoutPath)%(FileName).zip</ZipFile> + <WorkingDirectory>$(ProjectTemplatesLayoutPath)</WorkingDirectory> + </VSProjectTemplateContents> + + <!-- Now throw in all the files in each of the project-level template's directories and their children. --> + <VSProjectTemplateContents Include="@(TemplateItemContents)"> + <ZipFile>$(ProjectTemplatesLayoutPath)%(TemplateItemContents.TopLevelTemplateFileName).zip</ZipFile> + <WorkingDirectory>$(ProjectTemplatesLayoutPath)</WorkingDirectory> + </VSProjectTemplateContents> + + <!-- Include the template icon for each .zip file. --> + <VSProjectTemplateContents Include="@(TopLevelVSProjectTemplates->'$(ProjectTemplatesLayoutPath)__TemplateIcon.ico')"> + <ZipFile>$(ProjectTemplatesLayoutPath)%(TopLevelVSProjectTemplates.FileName).zip</ZipFile> + <WorkingDirectory>$(ProjectTemplatesLayoutPath)</WorkingDirectory> + </VSProjectTemplateContents> + </ItemGroup> + + <Delete Files="@(VSProjectTemplateZipFiles)" /> <Zip - Files="@(WebFormsRelyingPartyProjectTemplateLayout)" - ZipFileName="$(WebFormsRelyingPartyZipFile)" - WorkingDirectory="$(ProjectTemplatesLayoutPath)\WebFormsRelyingParty" /> + Files="@(VSProjectTemplateContents)" + ZipFileName="%(VSProjectTemplateContents.ZipFile)" + WorkingDirectory="%(VSProjectTemplateContents.WorkingDirectory)" + /> </Target> <Target Name="Documentation" DependsOnTargets="BuildProduct;Chm" Condition="'$(NoDocumentation)' != 'true'"> diff --git a/lib/DotNetOpenAuth.BuildTasks.dll b/lib/DotNetOpenAuth.BuildTasks.dll Binary files differindex a246041..0c4e4a9 100644 --- a/lib/DotNetOpenAuth.BuildTasks.dll +++ b/lib/DotNetOpenAuth.BuildTasks.dll diff --git a/lib/DotNetOpenAuth.BuildTasks.pdb b/lib/DotNetOpenAuth.BuildTasks.pdb Binary files differindex 96ea71a..98e94f8 100644 --- a/lib/DotNetOpenAuth.BuildTasks.pdb +++ b/lib/DotNetOpenAuth.BuildTasks.pdb diff --git a/lib/DotNetOpenAuth.BuildTasks.targets b/lib/DotNetOpenAuth.BuildTasks.targets index cfc9e18..e376877 100644 --- a/lib/DotNetOpenAuth.BuildTasks.targets +++ b/lib/DotNetOpenAuth.BuildTasks.targets @@ -3,6 +3,10 @@ <PropertyGroup> <ProjectRoot Condition="'$(ProjectRoot)' == ''">$(MSBuildProjectDirectory)\..\..</ProjectRoot> </PropertyGroup> + <ItemGroup> + <VsTemplateParameterReplaceExtensions Include=".cs;.csproj;.sql;.config;.Master;.aspx;.vb" /> + <VsTemplateProjectItemTypes Include="Compile;EmbeddedResource;EntityDeploy;Content;None" /> + </ItemGroup> <UsingTask AssemblyFile="$(ProjectRoot)\lib\DotNetOpenAuth.BuildTasks.dll" TaskName="GetBuildVersion" /> <UsingTask AssemblyFile="$(ProjectRoot)\lib\DotNetOpenAuth.BuildTasks.dll" TaskName="SetEnvironmentVariable" /> @@ -17,5 +21,9 @@ <UsingTask AssemblyFile="$(ProjectRoot)\lib\DotNetOpenAuth.BuildTasks.dll" TaskName="FilterItems" /> <UsingTask AssemblyFile="$(ProjectRoot)\lib\DotNetOpenAuth.BuildTasks.dll" TaskName="JsPack" /> <UsingTask AssemblyFile="$(ProjectRoot)\lib\DotNetOpenAuth.BuildTasks.dll" TaskName="CopyWithTokenSubstitution" /> + <UsingTask AssemblyFile="$(ProjectRoot)\lib\DotNetOpenAuth.BuildTasks.dll" TaskName="MergeProjectWithVSTemplate" /> + <UsingTask AssemblyFile="$(ProjectRoot)\lib\DotNetOpenAuth.BuildTasks.dll" TaskName="DiscoverProjectTemplates" /> + <UsingTask AssemblyFile="$(ProjectRoot)\lib\DotNetOpenAuth.BuildTasks.dll" TaskName="FixupReferenceHintPaths" /> + <UsingTask AssemblyFile="$(ProjectRoot)\lib\DotNetOpenAuth.BuildTasks.dll" TaskName="AddProjectItems" /> </Project> diff --git a/projecttemplates/WebFormsRelyingParty/Admin/CreateDatabase.sql b/projecttemplates/RelyingPartyLogic/CreateDatabase.sql index 52ca669..52ca669 100644 --- a/projecttemplates/WebFormsRelyingParty/Admin/CreateDatabase.sql +++ b/projecttemplates/RelyingPartyLogic/CreateDatabase.sql diff --git a/projecttemplates/WebFormsRelyingParty/Code/DataRoleProvider.cs b/projecttemplates/RelyingPartyLogic/DataRoleProvider.cs index 8117e4b..1171646 100644 --- a/projecttemplates/WebFormsRelyingParty/Code/DataRoleProvider.cs +++ b/projecttemplates/RelyingPartyLogic/DataRoleProvider.cs @@ -4,7 +4,7 @@ // </copyright> //----------------------------------------------------------------------- -namespace WebFormsRelyingParty.Code { +namespace RelyingPartyLogic { using System; using System.Collections.Generic; using System.Linq; @@ -18,10 +18,10 @@ namespace WebFormsRelyingParty.Code { } public override void AddUsersToRoles(string[] usernames, string[] roleNames) { - var users = from token in Global.DataContext.AuthenticationToken + var users = from token in Database.DataContext.AuthenticationToken where usernames.Contains(token.ClaimedIdentifier) select token.User; - var roles = from role in Global.DataContext.Role + var roles = from role in Database.DataContext.Role where roleNames.Contains(role.Name, StringComparer.OrdinalIgnoreCase) select role; foreach (User user in users) { @@ -32,10 +32,10 @@ namespace WebFormsRelyingParty.Code { } public override void RemoveUsersFromRoles(string[] usernames, string[] roleNames) { - var users = from token in Global.DataContext.AuthenticationToken + var users = from token in Database.DataContext.AuthenticationToken where usernames.Contains(token.ClaimedIdentifier) select token.User; - var roles = from role in Global.DataContext.Role + var roles = from role in Database.DataContext.Role where roleNames.Contains(role.Name, StringComparer.OrdinalIgnoreCase) select role; foreach (User user in users) { @@ -46,7 +46,7 @@ namespace WebFormsRelyingParty.Code { } public override void CreateRole(string roleName) { - Global.DataContext.AddToRole(new Role { Name = roleName }); + Database.DataContext.AddToRole(new Role { Name = roleName }); } /// <summary> @@ -58,7 +58,7 @@ namespace WebFormsRelyingParty.Code { /// true if the role was successfully deleted; otherwise, false. /// </returns> public override bool DeleteRole(string roleName, bool throwOnPopulatedRole) { - Role role = Global.DataContext.Role.SingleOrDefault(r => r.Name == roleName); + Role role = Database.DataContext.Role.SingleOrDefault(r => r.Name == roleName); if (role == null) { return false; } @@ -67,7 +67,7 @@ namespace WebFormsRelyingParty.Code { throw new InvalidOperationException(); } - Global.DataContext.DeleteObject(roleName); + Database.DataContext.DeleteObject(roleName); return true; } @@ -80,7 +80,7 @@ namespace WebFormsRelyingParty.Code { /// A string array containing the names of all the users where the user name matches <paramref name="usernameToMatch"/> and the user is a member of the specified role. /// </returns> public override string[] FindUsersInRole(string roleName, string usernameToMatch) { - return (from role in Global.DataContext.Role + return (from role in Database.DataContext.Role where role.Name == roleName from user in role.Users from authTokens in user.AuthenticationTokens @@ -89,18 +89,18 @@ namespace WebFormsRelyingParty.Code { } public override string[] GetAllRoles() { - return Global.DataContext.Role.Select(role => role.Name).ToArray(); + return Database.DataContext.Role.Select(role => role.Name).ToArray(); } public override string[] GetRolesForUser(string username) { - return (from authToken in Global.DataContext.AuthenticationToken + return (from authToken in Database.DataContext.AuthenticationToken where authToken.ClaimedIdentifier == username from role in authToken.User.Roles select role.Name).ToArray(); } public override string[] GetUsersInRole(string roleName) { - return (from role in Global.DataContext.Role + return (from role in Database.DataContext.Role where string.Equals(role.Name, roleName, StringComparison.OrdinalIgnoreCase) from user in role.Users from token in user.AuthenticationTokens @@ -108,7 +108,7 @@ namespace WebFormsRelyingParty.Code { } public override bool IsUserInRole(string username, string roleName) { - Role role = Global.DataContext.Role.SingleOrDefault(r => string.Equals(r.Name, roleName, StringComparison.OrdinalIgnoreCase)); + Role role = Database.DataContext.Role.SingleOrDefault(r => string.Equals(r.Name, roleName, StringComparison.OrdinalIgnoreCase)); if (role != null) { return role.Users.Any(user => user.AuthenticationTokens.Any(token => token.ClaimedIdentifier == username)); } @@ -117,7 +117,7 @@ namespace WebFormsRelyingParty.Code { } public override bool RoleExists(string roleName) { - return Global.DataContext.Role.Any(role => string.Equals(role.Name, roleName, StringComparison.OrdinalIgnoreCase)); + return Database.DataContext.Role.Any(role => string.Equals(role.Name, roleName, StringComparison.OrdinalIgnoreCase)); } } } diff --git a/projecttemplates/RelyingPartyLogic/Database.cs b/projecttemplates/RelyingPartyLogic/Database.cs new file mode 100644 index 0000000..a1e17a6 --- /dev/null +++ b/projecttemplates/RelyingPartyLogic/Database.cs @@ -0,0 +1,150 @@ +//----------------------------------------------------------------------- +// <copyright file="Database.cs" company="Andrew Arnott"> +// Copyright (c) Andrew Arnott. All rights reserved. +// </copyright> +//----------------------------------------------------------------------- + +namespace RelyingPartyLogic { + using System; + using System.Collections.Generic; + using System.Data; + using System.Data.SqlClient; + using System.Linq; + using System.ServiceModel; + using System.Text; + using System.Web; + + public class Database : IHttpModule, IDisposable { + private const string DataContextKey = "DataContext"; + + private const string DataContextTransactionKey = "DataContextTransaction"; + + /// <summary> + /// Initializes a new instance of the <see cref="Database"/> class. + /// </summary> + public Database() { + } + + public static User LoggedInUser { + get { return DataContext.AuthenticationToken.Where(token => token.ClaimedIdentifier == HttpContext.Current.User.Identity.Name).Select(token => token.User).FirstOrDefault(); } + } + + /// <summary> + /// Gets the transaction-protected database connection for the current request. + /// </summary> + public static DatabaseEntities DataContext { + get { + DatabaseEntities dataContext = DataContextSimple; + if (dataContext == null) { + dataContext = new DatabaseEntities(); + try { + dataContext.Connection.Open(); + } catch (EntityException entityEx) { + var sqlEx = entityEx.InnerException as SqlException; + if (sqlEx != null) { + if (sqlEx.Class == 14 && sqlEx.Number == 15350) { + // Most likely the database schema hasn't been created yet. + HttpContext.Current.Response.Redirect("~/Setup.aspx"); + } + } + + throw; + } + + DataContextTransactionSimple = dataContext.Connection.BeginTransaction(); + DataContextSimple = dataContext; + } + + return dataContext; + } + } + + private static DatabaseEntities DataContextSimple { + get { + if (HttpContext.Current != null) { + return HttpContext.Current.Items[DataContextKey] as DatabaseEntities; + } else if (OperationContext.Current != null) { + object data; + if (OperationContext.Current.IncomingMessageProperties.TryGetValue(DataContextKey, out data)) { + return data as DatabaseEntities; + } else { + return null; + } + } else { + throw new InvalidOperationException(); + } + } + + set { + if (HttpContext.Current != null) { + HttpContext.Current.Items[DataContextKey] = value; + } else if (OperationContext.Current != null) { + OperationContext.Current.IncomingMessageProperties[DataContextKey] = value; + } else { + throw new InvalidOperationException(); + } + } + } + + private static IDbTransaction DataContextTransactionSimple { + get { + if (HttpContext.Current != null) { + return HttpContext.Current.Items[DataContextTransactionKey] as IDbTransaction; + } else if (OperationContext.Current != null) { + object data; + if (OperationContext.Current.IncomingMessageProperties.TryGetValue(DataContextTransactionKey, out data)) { + return data as IDbTransaction; + } else { + return null; + } + } else { + throw new InvalidOperationException(); + } + } + + set { + if (HttpContext.Current != null) { + HttpContext.Current.Items[DataContextTransactionKey] = value; + } else if (OperationContext.Current != null) { + OperationContext.Current.IncomingMessageProperties[DataContextTransactionKey] = value; + } else { + throw new InvalidOperationException(); + } + } + } + + public void Dispose() { + } + + void IHttpModule.Init(HttpApplication context) { + context.EndRequest += this.Application_EndRequest; + context.Error += this.Application_Error; + } + + protected void Application_EndRequest(object sender, EventArgs e) { + CommitAndCloseDatabaseIfNecessary(); + } + + protected void Application_Error(object sender, EventArgs e) { + if (DataContextTransactionSimple != null) { + DataContextTransactionSimple.Rollback(); + DataContextTransactionSimple.Dispose(); + DataContextTransactionSimple = null; + } + } + + private static void CommitAndCloseDatabaseIfNecessary() { + var dataContext = DataContextSimple; + if (dataContext != null) { + dataContext.SaveChanges(); + if (DataContextTransactionSimple != null) { + DataContextTransactionSimple.Commit(); + DataContextTransactionSimple.Dispose(); + } + + dataContext.Dispose(); + DataContextSimple = null; + } + } + } +} diff --git a/projecttemplates/WebFormsRelyingParty/Model.AuthenticationToken.cs b/projecttemplates/RelyingPartyLogic/Model.AuthenticationToken.cs index 53ca10f..e44fd83 100644 --- a/projecttemplates/WebFormsRelyingParty/Model.AuthenticationToken.cs +++ b/projecttemplates/RelyingPartyLogic/Model.AuthenticationToken.cs @@ -1,4 +1,4 @@ -namespace WebFormsRelyingParty { +namespace RelyingPartyLogic { using System; using System.Collections.Generic; using System.Linq; @@ -10,7 +10,7 @@ } private static string UriPrefixForInfoCard { - get { return new Uri(HttpContext.Current.Request.Url, Global.ApplicationPath + "infocard/").AbsoluteUri; } + get { return new Uri(Utilities.ApplicationRoot, "infocard/").AbsoluteUri; } } public static string SynthesizeClaimedIdentifierFromInfoCard(string uniqueId) { diff --git a/projecttemplates/WebFormsRelyingParty/Model.Consumer.cs b/projecttemplates/RelyingPartyLogic/Model.Consumer.cs index 5076d6d..a09029a 100644 --- a/projecttemplates/WebFormsRelyingParty/Model.Consumer.cs +++ b/projecttemplates/RelyingPartyLogic/Model.Consumer.cs @@ -4,7 +4,7 @@ // </copyright> //----------------------------------------------------------------------- -namespace WebFormsRelyingParty { +namespace RelyingPartyLogic { using System; using System.Collections.Generic; using System.Linq; diff --git a/projecttemplates/WebFormsRelyingParty/Model.Designer.cs b/projecttemplates/RelyingPartyLogic/Model.Designer.cs index d265efa..d19d305 100644 --- a/projecttemplates/WebFormsRelyingParty/Model.Designer.cs +++ b/projecttemplates/RelyingPartyLogic/Model.Designer.cs @@ -9,14 +9,14 @@ //------------------------------------------------------------------------------ [assembly: global::System.Data.Objects.DataClasses.EdmSchemaAttribute()] -[assembly: global::System.Data.Objects.DataClasses.EdmRelationshipAttribute("DatabaseModel", "UserRole", "Role", global::System.Data.Metadata.Edm.RelationshipMultiplicity.Many, typeof(WebFormsRelyingParty.Role), "User", global::System.Data.Metadata.Edm.RelationshipMultiplicity.Many, typeof(WebFormsRelyingParty.User))] -[assembly: global::System.Data.Objects.DataClasses.EdmRelationshipAttribute("DatabaseModel", "UserAuthenticationToken", "User", global::System.Data.Metadata.Edm.RelationshipMultiplicity.One, typeof(WebFormsRelyingParty.User), "AuthenticationToken", global::System.Data.Metadata.Edm.RelationshipMultiplicity.Many, typeof(WebFormsRelyingParty.AuthenticationToken))] -[assembly: global::System.Data.Objects.DataClasses.EdmRelationshipAttribute("DatabaseModel", "FK_IssuedToken_Consumer", "Consumer", global::System.Data.Metadata.Edm.RelationshipMultiplicity.One, typeof(WebFormsRelyingParty.Consumer), "IssuedTokens", global::System.Data.Metadata.Edm.RelationshipMultiplicity.Many, typeof(WebFormsRelyingParty.IssuedToken))] -[assembly: global::System.Data.Objects.DataClasses.EdmRelationshipAttribute("DatabaseModel", "FK_IssuedToken_User", "User", global::System.Data.Metadata.Edm.RelationshipMultiplicity.ZeroOrOne, typeof(WebFormsRelyingParty.User), "IssuedTokens", global::System.Data.Metadata.Edm.RelationshipMultiplicity.Many, typeof(WebFormsRelyingParty.IssuedToken))] +[assembly: global::System.Data.Objects.DataClasses.EdmRelationshipAttribute("DatabaseModel", "UserRole", "Role", global::System.Data.Metadata.Edm.RelationshipMultiplicity.Many, typeof(RelyingPartyLogic.Role), "User", global::System.Data.Metadata.Edm.RelationshipMultiplicity.Many, typeof(RelyingPartyLogic.User))] +[assembly: global::System.Data.Objects.DataClasses.EdmRelationshipAttribute("DatabaseModel", "UserAuthenticationToken", "User", global::System.Data.Metadata.Edm.RelationshipMultiplicity.One, typeof(RelyingPartyLogic.User), "AuthenticationToken", global::System.Data.Metadata.Edm.RelationshipMultiplicity.Many, typeof(RelyingPartyLogic.AuthenticationToken))] +[assembly: global::System.Data.Objects.DataClasses.EdmRelationshipAttribute("DatabaseModel", "FK_IssuedToken_Consumer", "Consumer", global::System.Data.Metadata.Edm.RelationshipMultiplicity.One, typeof(RelyingPartyLogic.Consumer), "IssuedTokens", global::System.Data.Metadata.Edm.RelationshipMultiplicity.Many, typeof(RelyingPartyLogic.IssuedToken))] +[assembly: global::System.Data.Objects.DataClasses.EdmRelationshipAttribute("DatabaseModel", "FK_IssuedToken_User", "User", global::System.Data.Metadata.Edm.RelationshipMultiplicity.ZeroOrOne, typeof(RelyingPartyLogic.User), "IssuedTokens", global::System.Data.Metadata.Edm.RelationshipMultiplicity.Many, typeof(RelyingPartyLogic.IssuedToken))] // Original file name: -// Generation date: 11/11/2009 10:26:25 PM -namespace WebFormsRelyingParty +// Generation date: 11/13/2009 4:45:45 PM +namespace RelyingPartyLogic { /// <summary> @@ -823,8 +823,8 @@ namespace WebFormsRelyingParty [global::System.Data.Objects.DataClasses.EdmEntityTypeAttribute(NamespaceName="DatabaseModel", Name="IssuedToken")] [global::System.Runtime.Serialization.DataContractAttribute(IsReference=true)] [global::System.Serializable()] - [global::System.Runtime.Serialization.KnownTypeAttribute(typeof(global::WebFormsRelyingParty.IssuedRequestToken))] - [global::System.Runtime.Serialization.KnownTypeAttribute(typeof(global::WebFormsRelyingParty.IssuedAccessToken))] + [global::System.Runtime.Serialization.KnownTypeAttribute(typeof(global::RelyingPartyLogic.IssuedRequestToken))] + [global::System.Runtime.Serialization.KnownTypeAttribute(typeof(global::RelyingPartyLogic.IssuedAccessToken))] public abstract partial class IssuedToken : global::System.Data.Objects.DataClasses.EntityObject { /// <summary> diff --git a/projecttemplates/WebFormsRelyingParty/Model.IssuedAccessToken.cs b/projecttemplates/RelyingPartyLogic/Model.IssuedAccessToken.cs index ab064c3..fff27af 100644 --- a/projecttemplates/WebFormsRelyingParty/Model.IssuedAccessToken.cs +++ b/projecttemplates/RelyingPartyLogic/Model.IssuedAccessToken.cs @@ -4,7 +4,7 @@ // </copyright> //----------------------------------------------------------------------- -namespace WebFormsRelyingParty { +namespace RelyingPartyLogic { using System; using System.Collections.Generic; using System.Linq; diff --git a/projecttemplates/WebFormsRelyingParty/Model.IssuedRequestToken.cs b/projecttemplates/RelyingPartyLogic/Model.IssuedRequestToken.cs index 1352e54..c62f5c4 100644 --- a/projecttemplates/WebFormsRelyingParty/Model.IssuedRequestToken.cs +++ b/projecttemplates/RelyingPartyLogic/Model.IssuedRequestToken.cs @@ -4,7 +4,7 @@ // </copyright> //----------------------------------------------------------------------- -namespace WebFormsRelyingParty { +namespace RelyingPartyLogic { using System; using System.Collections.Generic; using System.Linq; @@ -49,8 +49,8 @@ namespace WebFormsRelyingParty { /// Call this method when the user has completed web-based authorization. /// </remarks> public void Authorize() { - this.User = Global.LoggedInUser; - Global.DataContext.SaveChanges(); + this.User = Database.LoggedInUser; + Database.DataContext.SaveChanges(); } } } diff --git a/projecttemplates/WebFormsRelyingParty/Model.User.cs b/projecttemplates/RelyingPartyLogic/Model.User.cs index 1493603..16980e2 100644 --- a/projecttemplates/WebFormsRelyingParty/Model.User.cs +++ b/projecttemplates/RelyingPartyLogic/Model.User.cs @@ -4,7 +4,7 @@ // </copyright> //----------------------------------------------------------------------- -namespace WebFormsRelyingParty { +namespace RelyingPartyLogic { using System; using System.Collections.Generic; using System.Linq; diff --git a/projecttemplates/WebFormsRelyingParty/Model.edmx b/projecttemplates/RelyingPartyLogic/Model.edmx index f37aa6c..f37aa6c 100644 --- a/projecttemplates/WebFormsRelyingParty/Model.edmx +++ b/projecttemplates/RelyingPartyLogic/Model.edmx diff --git a/projecttemplates/WebFormsRelyingParty/Code/OAuthAuthenticationModule.cs b/projecttemplates/RelyingPartyLogic/OAuthAuthenticationModule.cs index 426dce5..e47e4ee 100644 --- a/projecttemplates/WebFormsRelyingParty/Code/OAuthAuthenticationModule.cs +++ b/projecttemplates/RelyingPartyLogic/OAuthAuthenticationModule.cs @@ -4,7 +4,7 @@ // </copyright> //----------------------------------------------------------------------- -namespace WebFormsRelyingParty.Code { +namespace RelyingPartyLogic { using System; using System.Collections.Generic; using System.Linq; diff --git a/projecttemplates/WebFormsRelyingParty/Code/OAuthAuthorizationManager.cs b/projecttemplates/RelyingPartyLogic/OAuthAuthorizationManager.cs index 480e1b9..752e2eb 100644 --- a/projecttemplates/WebFormsRelyingParty/Code/OAuthAuthorizationManager.cs +++ b/projecttemplates/RelyingPartyLogic/OAuthAuthorizationManager.cs @@ -4,7 +4,7 @@ // </copyright> //----------------------------------------------------------------------- -namespace WebFormsRelyingParty.Code { +namespace RelyingPartyLogic { using System; using System.Collections.Generic; using System.IdentityModel.Policy; @@ -33,7 +33,7 @@ namespace WebFormsRelyingParty.Code { ServiceProvider sp = OAuthServiceProvider.ServiceProvider; var auth = sp.ReadProtectedResourceAuthorization(httpDetails, requestUri); if (auth != null) { - var accessToken = Global.DataContext.IssuedToken.OfType<IssuedAccessToken>().First(token => token.Token == auth.AccessToken); + var accessToken = Database.DataContext.IssuedToken.OfType<IssuedAccessToken>().First(token => token.Token == auth.AccessToken); var principal = sp.CreatePrincipal(auth); var policy = new OAuthPrincipalAuthorizationPolicy(principal); diff --git a/projecttemplates/WebFormsRelyingParty/Code/OAuthConsumerTokenManager.cs b/projecttemplates/RelyingPartyLogic/OAuthConsumerTokenManager.cs index 107934b..64e6be8 100644 --- a/projecttemplates/WebFormsRelyingParty/Code/OAuthConsumerTokenManager.cs +++ b/projecttemplates/RelyingPartyLogic/OAuthConsumerTokenManager.cs @@ -4,7 +4,7 @@ // </copyright> //----------------------------------------------------------------------- -namespace WebFormsRelyingParty.Code { +namespace RelyingPartyLogic { using System; using System.Collections.Generic; using System.Linq; diff --git a/projecttemplates/WebFormsRelyingParty/Code/OAuthPrincipalAuthorizationPolicy.cs b/projecttemplates/RelyingPartyLogic/OAuthPrincipalAuthorizationPolicy.cs index b2c9a2d..ddd0b3f 100644 --- a/projecttemplates/WebFormsRelyingParty/Code/OAuthPrincipalAuthorizationPolicy.cs +++ b/projecttemplates/RelyingPartyLogic/OAuthPrincipalAuthorizationPolicy.cs @@ -4,7 +4,7 @@ // </copyright> //----------------------------------------------------------------------- -namespace WebFormsRelyingParty.Code { +namespace RelyingPartyLogic { using System; using System.Collections.Generic; using System.IdentityModel.Claims; diff --git a/projecttemplates/WebFormsRelyingParty/Code/OAuthServiceProvider.cs b/projecttemplates/RelyingPartyLogic/OAuthServiceProvider.cs index b914315..8d582ab 100644 --- a/projecttemplates/WebFormsRelyingParty/Code/OAuthServiceProvider.cs +++ b/projecttemplates/RelyingPartyLogic/OAuthServiceProvider.cs @@ -4,7 +4,7 @@ // </copyright> //----------------------------------------------------------------------- -namespace WebFormsRelyingParty.Code { +namespace RelyingPartyLogic { using System; using System.Collections.Generic; using System.Linq; @@ -61,14 +61,14 @@ namespace WebFormsRelyingParty.Code { set { HttpContext.Current.Session[PendingAuthorizationRequestSessionKey] = value; } } - public static WebFormsRelyingParty.Consumer PendingAuthorizationConsumer { + public static Consumer PendingAuthorizationConsumer { get { ITokenContainingMessage message = PendingAuthorizationRequest; if (message == null) { throw new InvalidOperationException(); } - return Global.DataContext.IssuedToken.OfType<IssuedRequestToken>().Include("Consumer").First(t => t.Token == message.Token).Consumer; + return Database.DataContext.IssuedToken.OfType<IssuedRequestToken>().Include("Consumer").First(t => t.Token == message.Token).Consumer; } } @@ -79,7 +79,7 @@ namespace WebFormsRelyingParty.Code { } ITokenContainingMessage msg = pendingRequest; - var token = Global.DataContext.IssuedToken.OfType<IssuedRequestToken>().First(t => t.Token == msg.Token); + var token = Database.DataContext.IssuedToken.OfType<IssuedRequestToken>().First(t => t.Token == msg.Token); token.Authorize(); PendingAuthorizationRequest = null; diff --git a/projecttemplates/WebFormsRelyingParty/Code/OAuthServiceProviderTokenManager.cs b/projecttemplates/RelyingPartyLogic/OAuthServiceProviderTokenManager.cs index 224a181..be53180 100644 --- a/projecttemplates/WebFormsRelyingParty/Code/OAuthServiceProviderTokenManager.cs +++ b/projecttemplates/RelyingPartyLogic/OAuthServiceProviderTokenManager.cs @@ -4,7 +4,7 @@ // </copyright> //----------------------------------------------------------------------- -namespace WebFormsRelyingParty.Code { +namespace RelyingPartyLogic { using System; using System.Collections.Generic; using System.Linq; @@ -30,7 +30,7 @@ namespace WebFormsRelyingParty.Code { /// <exception cref="KeyNotFoundException">Thrown if the consumer key cannot be found.</exception> public IConsumerDescription GetConsumer(string consumerKey) { try { - return Global.DataContext.Consumer.First(c => c.ConsumerKey == consumerKey); + return Database.DataContext.Consumer.First(c => c.ConsumerKey == consumerKey); } catch (InvalidOperationException) { throw new KeyNotFoundException(); } @@ -47,7 +47,7 @@ namespace WebFormsRelyingParty.Code { /// been authorized, has expired or does not exist. /// </returns> public bool IsRequestTokenAuthorized(string requestToken) { - return Global.DataContext.IssuedToken.OfType<IssuedRequestToken>().Any( + return Database.DataContext.IssuedToken.OfType<IssuedRequestToken>().Any( t => t.Token == requestToken && t.User != null); } @@ -65,7 +65,7 @@ namespace WebFormsRelyingParty.Code { /// </remarks> public IServiceProviderRequestToken GetRequestToken(string token) { try { - return Global.DataContext.IssuedToken.OfType<IssuedRequestToken>().First(tok => tok.Token == token); + return Database.DataContext.IssuedToken.OfType<IssuedRequestToken>().First(tok => tok.Token == token); } catch (InvalidOperationException) { throw new KeyNotFoundException(); } @@ -85,7 +85,7 @@ namespace WebFormsRelyingParty.Code { /// </remarks> public IServiceProviderAccessToken GetAccessToken(string token) { try { - return Global.DataContext.IssuedToken.OfType<IssuedAccessToken>().First(tok => tok.Token == token); + return Database.DataContext.IssuedToken.OfType<IssuedAccessToken>().First(tok => tok.Token == token); } catch (InvalidOperationException) { throw new KeyNotFoundException(); } @@ -104,7 +104,7 @@ namespace WebFormsRelyingParty.Code { /// will automatically be saved without any extra handling). /// </remarks> public void UpdateToken(IServiceProviderRequestToken token) { - Global.DataContext.SaveChanges(); + Database.DataContext.SaveChanges(); } #endregion diff --git a/projecttemplates/WebFormsRelyingParty/Code/OAuthTokenManager.cs b/projecttemplates/RelyingPartyLogic/OAuthTokenManager.cs index ff757c9..fbba776 100644 --- a/projecttemplates/WebFormsRelyingParty/Code/OAuthTokenManager.cs +++ b/projecttemplates/RelyingPartyLogic/OAuthTokenManager.cs @@ -4,7 +4,7 @@ // </copyright> //----------------------------------------------------------------------- -namespace WebFormsRelyingParty.Code { +namespace RelyingPartyLogic { using System; using System.Collections.Generic; using System.Linq; @@ -37,7 +37,7 @@ namespace WebFormsRelyingParty.Code { /// <exception cref="ArgumentException">Thrown if the secret cannot be found for the given token.</exception> public string GetTokenSecret(string token) { try { - return Global.DataContext.IssuedToken.First(t => t.Token == token).TokenSecret; + return Database.DataContext.IssuedToken.First(t => t.Token == token).TokenSecret; } catch (InvalidOperationException) { throw new ArgumentOutOfRangeException(); } @@ -59,7 +59,7 @@ namespace WebFormsRelyingParty.Code { public void StoreNewRequestToken(UnauthorizedTokenRequest request, ITokenSecretContainingMessage response) { Consumer consumer; try { - consumer = Global.DataContext.Consumer.First(c => c.ConsumerKey == request.ConsumerKey); + consumer = Database.DataContext.Consumer.First(c => c.ConsumerKey == request.ConsumerKey); } catch (InvalidOperationException) { throw new ArgumentOutOfRangeException(); } @@ -75,8 +75,8 @@ namespace WebFormsRelyingParty.Code { if (request.ExtraData.TryGetValue("scope", out scope)) { token.Scope = scope; } - Global.DataContext.AddToIssuedToken(token); - Global.DataContext.SaveChanges(); + Database.DataContext.AddToIssuedToken(token); + Database.DataContext.SaveChanges(); } /// <summary> @@ -103,7 +103,7 @@ namespace WebFormsRelyingParty.Code { /// </para> /// </remarks> public void ExpireRequestTokenAndStoreNewAccessToken(string consumerKey, string requestToken, string accessToken, string accessTokenSecret) { - var requestTokenEntity = Global.DataContext.IssuedToken.OfType<IssuedRequestToken>() + var requestTokenEntity = Database.DataContext.IssuedToken.OfType<IssuedRequestToken>() .Include("User") .First(t => t.Consumer.ConsumerKey == consumerKey && t.Token == requestToken); @@ -117,9 +117,9 @@ namespace WebFormsRelyingParty.Code { Consumer = requestTokenEntity.Consumer, }; - Global.DataContext.DeleteObject(requestTokenEntity); - Global.DataContext.AddToIssuedToken(accessTokenEntity); - Global.DataContext.SaveChanges(); + Database.DataContext.DeleteObject(requestTokenEntity); + Database.DataContext.AddToIssuedToken(accessTokenEntity); + Database.DataContext.SaveChanges(); } /// <summary> @@ -130,7 +130,7 @@ namespace WebFormsRelyingParty.Code { /// Request or Access token, or invalid if the token is not recognized. /// </returns> public TokenType GetTokenType(string token) { - IssuedToken tok = Global.DataContext.IssuedToken.FirstOrDefault(t => t.Token == token); + IssuedToken tok = Database.DataContext.IssuedToken.FirstOrDefault(t => t.Token == token); if (tok == null) { return TokenType.InvalidToken; } else { diff --git a/projecttemplates/WebFormsRelyingParty/Code/Policies.cs b/projecttemplates/RelyingPartyLogic/Policies.cs index 676b3f2..6bf72d3 100644 --- a/projecttemplates/WebFormsRelyingParty/Code/Policies.cs +++ b/projecttemplates/RelyingPartyLogic/Policies.cs @@ -4,7 +4,7 @@ // </copyright> //----------------------------------------------------------------------- -namespace WebFormsRelyingParty.Code { +namespace RelyingPartyLogic { using System; using System.Collections.Generic; using System.Linq; diff --git a/projecttemplates/RelyingPartyLogic/Properties/AssemblyInfo.cs b/projecttemplates/RelyingPartyLogic/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..8cb040c --- /dev/null +++ b/projecttemplates/RelyingPartyLogic/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("RelyingPartyLogic")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("Microsoft IT")] +[assembly: AssemblyProduct("RelyingPartyLogic")] +[assembly: AssemblyCopyright("Copyright © Microsoft IT 2009")] +[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("86d51499-3206-4eea-9bfe-b7950dac606b")] + +// 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/projecttemplates/RelyingPartyLogic/RelyingPartyLogic.csproj b/projecttemplates/RelyingPartyLogic/RelyingPartyLogic.csproj new file mode 100644 index 0000000..7000e2b --- /dev/null +++ b/projecttemplates/RelyingPartyLogic/RelyingPartyLogic.csproj @@ -0,0 +1,131 @@ +<?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>{17932639-1F50-48AF-B0A5-E2BF832F82CC}</ProjectGuid> + <OutputType>Library</OutputType> + <AppDesignerFolder>Properties</AppDesignerFolder> + <RootNamespace>RelyingPartyLogic</RootNamespace> + <AssemblyName>RelyingPartyLogic</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>bin\Debug\</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>bin\Release\</OutputPath> + <DefineConstants>TRACE</DefineConstants> + <ErrorReport>prompt</ErrorReport> + <WarningLevel>4</WarningLevel> + </PropertyGroup> + <ItemGroup> + <Reference Include="log4net, Version=1.2.10.0, Culture=neutral, PublicKeyToken=1b44e1d426115821, processorArchitecture=MSIL"> + <SpecificVersion>False</SpecificVersion> + <HintPath>..\..\lib\log4net.dll</HintPath> + </Reference> + <Reference Include="Microsoft.SqlServer.ConnectionInfo" /> + <Reference Include="Microsoft.SqlServer.Smo" /> + <Reference Include="Microsoft.SqlServer.Management.Sdk.Sfc" /> + <Reference Include="System" /> + <Reference Include="System.Data" /> + <Reference Include="System.Core"> + <RequiredTargetFramework>3.5</RequiredTargetFramework> + </Reference> + <Reference Include="System.Data.DataSetExtensions"> + <RequiredTargetFramework>3.5</RequiredTargetFramework> + </Reference> + <Reference Include="System.Data.Entity"> + <RequiredTargetFramework>3.5</RequiredTargetFramework> + </Reference> + <Reference Include="System.Data.Linq"> + <RequiredTargetFramework>3.5</RequiredTargetFramework> + </Reference> + <Reference Include="System.IdentityModel"> + <RequiredTargetFramework>3.0</RequiredTargetFramework> + </Reference> + <Reference Include="System.Runtime.Serialization"> + <RequiredTargetFramework>3.0</RequiredTargetFramework> + </Reference> + <Reference Include="System.Security" /> + <Reference Include="System.ServiceModel"> + <RequiredTargetFramework>3.0</RequiredTargetFramework> + </Reference> + <Reference Include="System.Web.Entity, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089, processorArchitecture=MSIL"> + <SpecificVersion>False</SpecificVersion> + <HintPath>..\..\..\Windows\assembly\GAC_MSIL\System.Web.Entity\3.5.0.0__b77a5c561934e089\System.Web.Entity.dll</HintPath> + <RequiredTargetFramework>3.5</RequiredTargetFramework> + </Reference> + <Reference Include="System.Web.Extensions"> + <RequiredTargetFramework>3.5</RequiredTargetFramework> + </Reference> + <Reference Include="System.Xml.Linq"> + <RequiredTargetFramework>3.5</RequiredTargetFramework> + </Reference> + <Reference Include="System.Drawing" /> + <Reference Include="System.Web" /> + <Reference Include="System.Xml" /> + <Reference Include="System.Configuration" /> + <Reference Include="System.Web.Services" /> + <Reference Include="System.EnterpriseServices" /> + <Reference Include="System.Web.Mobile" /> + </ItemGroup> + <ItemGroup> + <Compile Include="Database.cs" /> + <Compile Include="DataRoleProvider.cs" /> + <Compile Include="Model.AuthenticationToken.cs" /> + <Compile Include="Model.Consumer.cs" /> + <Compile Include="Model.Designer.cs"> + <DependentUpon>Model.edmx</DependentUpon> + <AutoGen>True</AutoGen> + <DesignTime>True</DesignTime> + </Compile> + <Compile Include="Model.IssuedAccessToken.cs" /> + <Compile Include="Model.IssuedRequestToken.cs" /> + <Compile Include="Model.User.cs" /> + <Compile Include="OAuthAuthenticationModule.cs" /> + <Compile Include="OAuthAuthorizationManager.cs" /> + <Compile Include="OAuthConsumerTokenManager.cs" /> + <Compile Include="OAuthPrincipalAuthorizationPolicy.cs" /> + <Compile Include="OAuthServiceProvider.cs" /> + <Compile Include="OAuthServiceProviderTokenManager.cs" /> + <Compile Include="OAuthTokenManager.cs" /> + <Compile Include="Policies.cs" /> + <Compile Include="Properties\AssemblyInfo.cs" /> + <Compile Include="Utilities.cs" /> + </ItemGroup> + <ItemGroup> + <EntityDeploy Include="Model.edmx"> + <Generator>EntityModelCodeGenerator</Generator> + <LastGenOutput>Model.Designer.cs</LastGenOutput> + </EntityDeploy> + </ItemGroup> + <ItemGroup> + <ProjectReference Include="..\..\src\DotNetOpenAuth\DotNetOpenAuth.csproj"> + <Project>{3191B653-F76D-4C1A-9A5A-347BC3AAAAB7}</Project> + <Name>DotNetOpenAuth</Name> + </ProjectReference> + </ItemGroup> + <ItemGroup> + <EmbeddedResource Include="CreateDatabase.sql" /> + </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/projecttemplates/RelyingPartyLogic/RelyingPartyLogic.vstemplate b/projecttemplates/RelyingPartyLogic/RelyingPartyLogic.vstemplate new file mode 100644 index 0000000..243d820 --- /dev/null +++ b/projecttemplates/RelyingPartyLogic/RelyingPartyLogic.vstemplate @@ -0,0 +1,11 @@ +<VSTemplate Version="2.0.0" xmlns="http://schemas.microsoft.com/developer/vstemplate/2005" Type="Project"> + <TemplateData> + <Name>ASP.NET OpenID-InfoCard RP</Name> + <Description>An ASP.NET web forms web site that accepts OpenID and InfoCard logins</Description> + <ProjectType>CSharp</ProjectType> + <Icon>__TemplateIcon.ico</Icon> + </TemplateData> + <TemplateContent> + <Project File="RelyingPartyLogic.csproj" ReplaceParameters="true" /> + </TemplateContent> +</VSTemplate>
\ No newline at end of file diff --git a/projecttemplates/RelyingPartyLogic/Utilities.cs b/projecttemplates/RelyingPartyLogic/Utilities.cs new file mode 100644 index 0000000..02eb273 --- /dev/null +++ b/projecttemplates/RelyingPartyLogic/Utilities.cs @@ -0,0 +1,64 @@ +//----------------------------------------------------------------------- +// <copyright file="Utilities.cs" company="Andrew Arnott"> +// Copyright (c) Andrew Arnott. All rights reserved. +// </copyright> +//----------------------------------------------------------------------- + +namespace RelyingPartyLogic { + using System; + using System.Collections.Generic; + using System.Globalization; + using System.IO; + using System.Linq; + using System.Reflection; + using System.Text; + using System.Web; + using DotNetOpenAuth.OpenId; + using Microsoft.SqlServer.Management.Common; + using Microsoft.SqlServer.Management.Smo; + + public class Utilities { + internal const string DefaultNamespace = "RelyingPartyLogic"; + + /// <summary> + /// Gets the full URI of the web application root. Guaranteed to end in a slash. + /// </summary> + public static Uri ApplicationRoot { + get { + string appRoot = HttpContext.Current.Request.ApplicationPath; + if (!appRoot.EndsWith("/", StringComparison.Ordinal)) { + appRoot += "/"; + } + + return new Uri(HttpContext.Current.Request.Url, appRoot); + } + } + + public static void CreateDatabase(Identifier claimedId, string friendlyId) { + const string SqlFormat = @" +CREATE DATABASE [{0}] ON (NAME='{0}', FILENAME='{0}') +GO +USE ""{0}"" +GO +{1} +EXEC [dbo].[AddUser] 'admin', 'admin', '{2}', '{3}' +GO +"; + string schemaSql; + using (var sr = new StreamReader(Assembly.GetExecutingAssembly().GetManifestResourceStream(DefaultNamespace + ".CreateDatabase.sql"))) { + schemaSql = sr.ReadToEnd(); + } + string databasePath = HttpContext.Current.Server.MapPath("~/App_Data/Database.mdf"); + string sql = string.Format(CultureInfo.InvariantCulture, SqlFormat, databasePath, schemaSql, claimedId, "Admin"); + + var serverConnection = new ServerConnection(".\\sqlexpress"); + try { + serverConnection.ExecuteNonQuery(sql); + var server = new Server(serverConnection); + server.DetachDatabase(databasePath, true); + } finally { + serverConnection.Disconnect(); + } + } + } +} diff --git a/projecttemplates/WebFormsRelyingParty.vstemplate b/projecttemplates/WebFormsRelyingParty.vstemplate new file mode 100644 index 0000000..e582d63 --- /dev/null +++ b/projecttemplates/WebFormsRelyingParty.vstemplate @@ -0,0 +1,23 @@ +<VSTemplate Version="2.0.0" xmlns="http://schemas.microsoft.com/developer/vstemplate/2005" Type="ProjectGroup"> + <TemplateData> + <Name>ASP.NET OpenID-InfoCard RP</Name> + <RequiredFrameworkVersion>3.5</RequiredFrameworkVersion> + <Description>An ASP.NET web forms web site that accepts OpenID and InfoCard logins</Description> + <ProjectType>CSharp</ProjectType> + <ProjectSubType>Web</ProjectSubType> + <NumberOfParentCategoriesToRollUp>2</NumberOfParentCategoriesToRollUp> + <SortOrder>1000</SortOrder> + <CreateNewFolder>true</CreateNewFolder> + <DefaultName>WebRPApplication</DefaultName> + <ProvideDefaultName>true</ProvideDefaultName> + <LocationField>Enabled</LocationField> + <EnableLocationBrowseButton>true</EnableLocationBrowseButton> + <Icon>__TemplateIcon.ico</Icon> + </TemplateData> + <TemplateContent> + <ProjectCollection> + <ProjectTemplateLink ProjectName="$projectname$">WebFormsRelyingParty\WebFormsRelyingParty.vstemplate</ProjectTemplateLink> + <ProjectTemplateLink ProjectName="RelyingPartyLogic">RelyingPartyLogic\RelyingPartyLogic.vstemplate</ProjectTemplateLink> + </ProjectCollection> + </TemplateContent> +</VSTemplate>
\ No newline at end of file diff --git a/projecttemplates/WebFormsRelyingParty/Admin/Default.aspx.cs b/projecttemplates/WebFormsRelyingParty/Admin/Default.aspx.cs index cc9abf1..261ddea 100644 --- a/projecttemplates/WebFormsRelyingParty/Admin/Default.aspx.cs +++ b/projecttemplates/WebFormsRelyingParty/Admin/Default.aspx.cs @@ -14,10 +14,11 @@ namespace WebFormsRelyingParty.Admin { using System.Web; using System.Web.UI; using System.Web.UI.WebControls; + using RelyingPartyLogic; public partial class Default : System.Web.UI.Page { protected void Page_Load(object sender, EventArgs e) { - this.usersRepeater.DataSource = Global.DataContext.User.Include("AuthenticationTokens"); + this.usersRepeater.DataSource = Database.DataContext.User.Include("AuthenticationTokens"); this.usersRepeater.DataBind(); } } diff --git a/projecttemplates/WebFormsRelyingParty/Code/Utilities.cs b/projecttemplates/WebFormsRelyingParty/Code/Utilities.cs index 25d293e..43c5236 100644 --- a/projecttemplates/WebFormsRelyingParty/Code/Utilities.cs +++ b/projecttemplates/WebFormsRelyingParty/Code/Utilities.cs @@ -15,20 +15,6 @@ namespace WebFormsRelyingParty.Code { private const string CsrfCookieName = "CsrfCookie"; private static readonly RandomNumberGenerator CryptoRandomDataGenerator = new RNGCryptoServiceProvider(); - /// <summary> - /// Gets the full URI of the web application root. Guaranteed to end in a slash. - /// </summary> - public static Uri ApplicationRoot { - get { - string appRoot = HttpContext.Current.Request.ApplicationPath; - if (!appRoot.EndsWith("/", StringComparison.Ordinal)) { - appRoot += "/"; - } - - return new Uri(HttpContext.Current.Request.Url, appRoot); - } - } - public static string SetCsrfCookie() { // Generate an unpredictable secret that goes to the user agent and must come back // with authorization to guarantee the user interacted with this page rather than diff --git a/projecttemplates/WebFormsRelyingParty/Default.aspx.cs b/projecttemplates/WebFormsRelyingParty/Default.aspx.cs index 72e8973..cf78d83 100644 --- a/projecttemplates/WebFormsRelyingParty/Default.aspx.cs +++ b/projecttemplates/WebFormsRelyingParty/Default.aspx.cs @@ -11,10 +11,11 @@ namespace WebFormsRelyingParty { using System.Web; using System.Web.UI; using System.Web.UI.WebControls; + using RelyingPartyLogic; public partial class _Default : System.Web.UI.Page { protected void Page_Load(object sender, EventArgs e) { - User user = Global.LoggedInUser; + User user = Database.LoggedInUser; this.Label1.Text = user != null ? HttpUtility.HtmlEncode(user.FirstName) : "<not logged in>"; } } diff --git a/projecttemplates/WebFormsRelyingParty/Global.asax.cs b/projecttemplates/WebFormsRelyingParty/Global.asax.cs index 8a14dfc..31928fd 100644 --- a/projecttemplates/WebFormsRelyingParty/Global.asax.cs +++ b/projecttemplates/WebFormsRelyingParty/Global.asax.cs @@ -13,10 +13,6 @@ namespace WebFormsRelyingParty { using System.Web; public class Global : System.Web.HttpApplication { - private const string DataContextKey = "DataContext"; - - private const string DataContextTransactionKey = "DataContextTransaction"; - /// <summary> /// The logger for this sample to use. /// </summary> @@ -26,105 +22,6 @@ namespace WebFormsRelyingParty { get { return logger; } } - public static User LoggedInUser { - get { return Global.DataContext.AuthenticationToken.Where(token => token.ClaimedIdentifier == HttpContext.Current.User.Identity.Name).Select(token => token.User).FirstOrDefault(); } - } - - public static string ApplicationPath { - get { - string path = HttpContext.Current.Request.ApplicationPath; - if (!path.EndsWith("/")) { - path += "/"; - } - - return path; - } - } - - /// <summary> - /// Gets the transaction-protected database connection for the current request. - /// </summary> - public static DatabaseEntities DataContext { - get { - DatabaseEntities dataContext = DataContextSimple; - if (dataContext == null) { - dataContext = new DatabaseEntities(); - try { - dataContext.Connection.Open(); - } catch (EntityException entityEx) { - var sqlEx = entityEx.InnerException as SqlException; - if (sqlEx != null) { - if (sqlEx.Class == 14 && sqlEx.Number == 15350) { - // Most likely the database schema hasn't been created yet. - HttpContext.Current.Response.Redirect("~/Setup.aspx"); - } - } - - throw; - } - - DataContextTransactionSimple = dataContext.Connection.BeginTransaction(); - DataContextSimple = dataContext; - } - - return dataContext; - } - } - - private static DatabaseEntities DataContextSimple { - get { - if (HttpContext.Current != null) { - return HttpContext.Current.Items[DataContextKey] as DatabaseEntities; - } else if (OperationContext.Current != null) { - object data; - if (OperationContext.Current.IncomingMessageProperties.TryGetValue(DataContextKey, out data)) { - return data as DatabaseEntities; - } else { - return null; - } - } else { - throw new InvalidOperationException(); - } - } - - set { - if (HttpContext.Current != null) { - HttpContext.Current.Items[DataContextKey] = value; - } else if (OperationContext.Current != null) { - OperationContext.Current.IncomingMessageProperties[DataContextKey] = value; - } else { - throw new InvalidOperationException(); - } - } - } - - private static IDbTransaction DataContextTransactionSimple { - get { - if (HttpContext.Current != null) { - return HttpContext.Current.Items[DataContextTransactionKey] as IDbTransaction; - } else if (OperationContext.Current != null) { - object data; - if (OperationContext.Current.IncomingMessageProperties.TryGetValue(DataContextTransactionKey, out data)) { - return data as IDbTransaction; - } else { - return null; - } - } else { - throw new InvalidOperationException(); - } - } - - set { - if (HttpContext.Current != null) { - HttpContext.Current.Items[DataContextTransactionKey] = value; - } else if (OperationContext.Current != null) { - OperationContext.Current.IncomingMessageProperties[DataContextTransactionKey] = value; - } else { - throw new InvalidOperationException(); - } - } - } - protected void Application_Start(object sender, EventArgs e) { log4net.Config.XmlConfigurator.Configure(); Logger.Info("Web application starting..."); @@ -137,7 +34,6 @@ namespace WebFormsRelyingParty { } protected void Application_EndRequest(object sender, EventArgs e) { - CommitAndCloseDatabaseIfNecessary(); } protected void Application_AuthenticateRequest(object sender, EventArgs e) { @@ -145,11 +41,6 @@ namespace WebFormsRelyingParty { protected void Application_Error(object sender, EventArgs e) { Logger.Error("An unhandled exception occurred in ASP.NET processing: " + Server.GetLastError(), Server.GetLastError()); - if (DataContextTransactionSimple != null) { - DataContextTransactionSimple.Rollback(); - DataContextTransactionSimple.Dispose(); - DataContextTransactionSimple = null; - } } protected void Session_End(object sender, EventArgs e) { @@ -161,19 +52,5 @@ namespace WebFormsRelyingParty { // this would be automatic, but in partial trust scenarios it is not. log4net.LogManager.Shutdown(); } - - private static void CommitAndCloseDatabaseIfNecessary() { - var dataContext = DataContextSimple; - if (dataContext != null) { - dataContext.SaveChanges(); - if (DataContextTransactionSimple != null) { - DataContextTransactionSimple.Commit(); - DataContextTransactionSimple.Dispose(); - } - - dataContext.Dispose(); - DataContextSimple = null; - } - } } }
\ No newline at end of file diff --git a/projecttemplates/WebFormsRelyingParty/LoginFrame.aspx.cs b/projecttemplates/WebFormsRelyingParty/LoginFrame.aspx.cs index 0d7e7fc..aebf266 100644 --- a/projecttemplates/WebFormsRelyingParty/LoginFrame.aspx.cs +++ b/projecttemplates/WebFormsRelyingParty/LoginFrame.aspx.cs @@ -12,6 +12,7 @@ using DotNetOpenAuth.Messaging; using DotNetOpenAuth.OpenId.Extensions.SimpleRegistration; using DotNetOpenAuth.OpenId.RelyingParty; + using RelyingPartyLogic; using WebFormsRelyingParty.Code; public partial class LoginFrame : System.Web.UI.Page { @@ -51,7 +52,7 @@ private void LoginUser(string claimedIdentifier, string friendlyIdentifier, ClaimsResponse claims, Token samlToken, bool trustedEmail) { // Create an account for this user if we don't already have one. - AuthenticationToken openidToken = Global.DataContext.AuthenticationToken.FirstOrDefault(token => token.ClaimedIdentifier == claimedIdentifier); + AuthenticationToken openidToken = Database.DataContext.AuthenticationToken.FirstOrDefault(token => token.ClaimedIdentifier == claimedIdentifier); if (openidToken == null) { // this is a user we haven't seen before. User user = new User(); @@ -89,7 +90,7 @@ } } - Global.DataContext.AddToUser(user); + Database.DataContext.AddToUser(user); } bool persistentCookie = false; diff --git a/projecttemplates/WebFormsRelyingParty/Members/AccountInfo.aspx.cs b/projecttemplates/WebFormsRelyingParty/Members/AccountInfo.aspx.cs index c3a143f..21b15d2 100644 --- a/projecttemplates/WebFormsRelyingParty/Members/AccountInfo.aspx.cs +++ b/projecttemplates/WebFormsRelyingParty/Members/AccountInfo.aspx.cs @@ -13,30 +13,31 @@ namespace WebFormsRelyingParty.Members { using System.Web.UI.WebControls; using DotNetOpenAuth.InfoCard; using DotNetOpenAuth.OpenId.RelyingParty; + using RelyingPartyLogic; public partial class AccountInfo : System.Web.UI.Page { protected void Page_Load(object sender, EventArgs e) { - Global.LoggedInUser.AuthenticationTokens.Load(); - this.Repeater1.DataSource = Global.LoggedInUser.AuthenticationTokens; + Database.LoggedInUser.AuthenticationTokens.Load(); + this.Repeater1.DataSource = Database.LoggedInUser.AuthenticationTokens; - if (!Global.LoggedInUser.IssuedToken.IsLoaded) { - Global.LoggedInUser.IssuedToken.Load(); + if (!Database.LoggedInUser.IssuedToken.IsLoaded) { + Database.LoggedInUser.IssuedToken.Load(); } - this.tokenListRepeater.DataSource = Global.LoggedInUser.IssuedToken; - foreach (var token in Global.LoggedInUser.IssuedToken) { + this.tokenListRepeater.DataSource = Database.LoggedInUser.IssuedToken; + foreach (var token in Database.LoggedInUser.IssuedToken) { if (!token.ConsumerReference.IsLoaded) { token.ConsumerReference.Load(); } } - this.authorizedClientsPanel.Visible = Global.LoggedInUser.IssuedToken.Count > 0; + this.authorizedClientsPanel.Visible = Database.LoggedInUser.IssuedToken.Count > 0; if (!IsPostBack) { this.Repeater1.DataBind(); this.tokenListRepeater.DataBind(); - this.emailBox.Text = Global.LoggedInUser.EmailAddress; - this.emailVerifiedLabel.Visible = Global.LoggedInUser.EmailAddressVerified; - this.firstNameBox.Text = Global.LoggedInUser.FirstName; - this.lastNameBox.Text = Global.LoggedInUser.LastName; + this.emailBox.Text = Database.LoggedInUser.EmailAddress; + this.emailVerifiedLabel.Visible = Database.LoggedInUser.EmailAddressVerified; + this.firstNameBox.Text = Database.LoggedInUser.FirstName; + this.lastNameBox.Text = Database.LoggedInUser.LastName; } this.firstNameBox.Focus(); @@ -48,9 +49,9 @@ namespace WebFormsRelyingParty.Members { protected void deleteOpenId_Command(object sender, CommandEventArgs e) { string claimedId = (string)e.CommandArgument; - var token = Global.DataContext.AuthenticationToken.First(t => t.ClaimedIdentifier == claimedId && t.User.Id == Global.LoggedInUser.Id); - Global.DataContext.DeleteObject(token); - Global.DataContext.SaveChanges(); + var token = Database.DataContext.AuthenticationToken.First(t => t.ClaimedIdentifier == claimedId && t.User.Id == Database.LoggedInUser.Id); + Database.DataContext.DeleteObject(token); + Database.DataContext.SaveChanges(); this.Repeater1.DataBind(); } @@ -59,10 +60,10 @@ namespace WebFormsRelyingParty.Members { return; } - Global.LoggedInUser.EmailAddress = this.emailBox.Text; - Global.LoggedInUser.FirstName = this.firstNameBox.Text; - Global.LoggedInUser.LastName = this.lastNameBox.Text; - this.emailVerifiedLabel.Visible = Global.LoggedInUser.EmailAddressVerified; + Database.LoggedInUser.EmailAddress = this.emailBox.Text; + Database.LoggedInUser.FirstName = this.firstNameBox.Text; + Database.LoggedInUser.LastName = this.lastNameBox.Text; + this.emailVerifiedLabel.Visible = Database.LoggedInUser.EmailAddressVerified; } protected void InfoCardSelector1_ReceivedToken(object sender, ReceivedTokenEventArgs e) { @@ -71,32 +72,32 @@ namespace WebFormsRelyingParty.Members { protected void revokeToken_Command(object sender, CommandEventArgs e) { string token = (string)e.CommandArgument; - var tokenToRevoke = Global.DataContext.IssuedToken.FirstOrDefault(t => t.Token == token && t.User.Id == Global.LoggedInUser.Id); + var tokenToRevoke = Database.DataContext.IssuedToken.FirstOrDefault(t => t.Token == token && t.User.Id == Database.LoggedInUser.Id); if (tokenToRevoke != null) { - Global.DataContext.DeleteObject(tokenToRevoke); + Database.DataContext.DeleteObject(tokenToRevoke); } this.tokenListRepeater.DataBind(); - this.noAuthorizedClientsPanel.Visible = Global.LoggedInUser.IssuedToken.Count == 0; + this.noAuthorizedClientsPanel.Visible = Database.LoggedInUser.IssuedToken.Count == 0; } private void AddIdentifier(string claimedId, string friendlyId) { // Check that this identifier isn't already tied to a user account. // We do this again here in case the LoggingIn event couldn't verify // and in case somehow the OP changed it anyway. - var existingToken = Global.DataContext.AuthenticationToken.FirstOrDefault(token => token.ClaimedIdentifier == claimedId); + var existingToken = Database.DataContext.AuthenticationToken.FirstOrDefault(token => token.ClaimedIdentifier == claimedId); if (existingToken == null) { var token = new AuthenticationToken(); token.ClaimedIdentifier = claimedId; token.FriendlyIdentifier = friendlyId; - Global.LoggedInUser.AuthenticationTokens.Add(token); - Global.DataContext.SaveChanges(); + Database.LoggedInUser.AuthenticationTokens.Add(token); + Database.DataContext.SaveChanges(); this.Repeater1.DataBind(); // Clear the box for the next entry this.openIdSelector.Identifier = null; } else { - if (existingToken.User == Global.LoggedInUser) { + if (existingToken.User == Database.LoggedInUser) { this.alreadyLinkedLabel.Visible = true; } else { this.differentAccountLabel.Visible = true; diff --git a/projecttemplates/WebFormsRelyingParty/Members/OAuthAuthorize.aspx.cs b/projecttemplates/WebFormsRelyingParty/Members/OAuthAuthorize.aspx.cs index 044e9c0..935e8ab 100644 --- a/projecttemplates/WebFormsRelyingParty/Members/OAuthAuthorize.aspx.cs +++ b/projecttemplates/WebFormsRelyingParty/Members/OAuthAuthorize.aspx.cs @@ -13,6 +13,7 @@ namespace WebFormsRelyingParty.Members { using System.Web.UI.WebControls; using DotNetOpenAuth.OAuth; using DotNetOpenAuth.OAuth.Messages; + using RelyingPartyLogic; using WebFormsRelyingParty.Code; public partial class OAuthAuthorize : System.Web.UI.Page { @@ -23,14 +24,14 @@ namespace WebFormsRelyingParty.Members { Response.Redirect("AccountInfo.aspx"); } - this.csrfCheck.Value = Utilities.SetCsrfCookie(); + this.csrfCheck.Value = Code.Utilities.SetCsrfCookie(); this.consumerNameLabel.Text = HttpUtility.HtmlEncode(OAuthServiceProvider.PendingAuthorizationConsumer.Name); OAuth10ConsumerWarning.Visible = pendingRequest.IsUnsafeRequest; serviceProviderDomainNameLabel.Text = HttpUtility.HtmlEncode(this.Request.Url.Host); this.consumerDomainNameLabel3.Text = this.consumerDomainNameLabel2.Text = this.consumerDomainNameLabel1.Text = HttpUtility.HtmlEncode(OAuthServiceProvider.PendingAuthorizationConsumer.Name); } else { - Utilities.VerifyCsrfCookie(this.csrfCheck.Value); + Code.Utilities.VerifyCsrfCookie(this.csrfCheck.Value); } } diff --git a/projecttemplates/WebFormsRelyingParty/MyTemplate.vstemplate b/projecttemplates/WebFormsRelyingParty/MyTemplate.vstemplate deleted file mode 100644 index d472aaa..0000000 --- a/projecttemplates/WebFormsRelyingParty/MyTemplate.vstemplate +++ /dev/null @@ -1,150 +0,0 @@ -<VSTemplate Version="2.0.0" xmlns="http://schemas.microsoft.com/developer/vstemplate/2005" Type="Project"> - <TemplateData> - <Name>ASP.NET OpenID-InfoCard RP</Name> - <RequiredFrameworkVersion>3.5</RequiredFrameworkVersion> - <Description>An ASP.NET web forms web site that accepts OpenID and InfoCard logins</Description> - <ProjectType>CSharp</ProjectType> - <ProjectSubType>Web</ProjectSubType> - <NumberOfParentCategoriesToRollUp>2</NumberOfParentCategoriesToRollUp> - <SortOrder>1000</SortOrder> - <CreateNewFolder>true</CreateNewFolder> - <DefaultName>WebRPApplication</DefaultName> - <ProvideDefaultName>true</ProvideDefaultName> - <LocationField>Enabled</LocationField> - <EnableLocationBrowseButton>true</EnableLocationBrowseButton> - <Icon>__TemplateIcon.ico</Icon> - </TemplateData> - <TemplateContent> - <Project TargetFileName="WebFormsRelyingParty.csproj" File="WebFormsRelyingParty.csproj" ReplaceParameters="true"> - <Folder Name="Admin" TargetFolderName="Admin"> - <ProjectItem ReplaceParameters="true" TargetFileName="Admin.Master">Admin.Master</ProjectItem> - <ProjectItem ReplaceParameters="true" TargetFileName="Admin.Master.cs">Admin.Master.cs</ProjectItem> - <ProjectItem ReplaceParameters="true" TargetFileName="Admin.Master.designer.cs">Admin.Master.designer.cs</ProjectItem> - <ProjectItem ReplaceParameters="true" TargetFileName="CreateDatabase.sql">CreateDatabase.sql</ProjectItem> - <ProjectItem ReplaceParameters="true" TargetFileName="Default.aspx">Default.aspx</ProjectItem> - <ProjectItem ReplaceParameters="true" TargetFileName="Default.aspx.cs">Default.aspx.cs</ProjectItem> - <ProjectItem ReplaceParameters="true" TargetFileName="Default.aspx.designer.cs">Default.aspx.designer.cs</ProjectItem> - <ProjectItem ReplaceParameters="true" TargetFileName="Web.config">Web.config</ProjectItem> - </Folder> - <Folder Name="App_Data" TargetFolderName="App_Data" /> - <Folder Name="bin" TargetFolderName="bin"> - <ProjectItem ReplaceParameters="false" TargetFileName="DotNetOpenAuth.dll">DotNetOpenAuth.dll</ProjectItem> - <ProjectItem ReplaceParameters="false" TargetFileName="DotNetOpenAuth.Contracts.dll">DotNetOpenAuth.Contracts.dll</ProjectItem> - <ProjectItem ReplaceParameters="false" TargetFileName="DotNetOpenAuth.pdb">DotNetOpenAuth.pdb</ProjectItem> - <ProjectItem ReplaceParameters="true" TargetFileName="DotNetOpenAuth.xml">DotNetOpenAuth.xml</ProjectItem> - <ProjectItem ReplaceParameters="false" TargetFileName="log4net.dll">log4net.dll</ProjectItem> - <ProjectItem ReplaceParameters="true" TargetFileName="log4net.xml">log4net.xml</ProjectItem> - </Folder> - <Folder Name="Code" TargetFolderName="Code"> - <ProjectItem ReplaceParameters="true">DataRoleProvider.cs</ProjectItem> - <ProjectItem ReplaceParameters="true">OAuthAuthenticationModule.cs</ProjectItem> - <ProjectItem ReplaceParameters="true">OAuthAuthorizationManager.cs</ProjectItem> - <ProjectItem ReplaceParameters="true">OAuthConsumerTokenManager.cs</ProjectItem> - <ProjectItem ReplaceParameters="true">OAuthPrincipalAuthorizationPolicy.cs</ProjectItem> - <ProjectItem ReplaceParameters="true">OAuthServiceProvider.cs</ProjectItem> - <ProjectItem ReplaceParameters="true">OAuthServiceProviderTokenManager.cs</ProjectItem> - <ProjectItem ReplaceParameters="true">OAuthTokenManager.cs</ProjectItem> - <ProjectItem ReplaceParameters="true">Policies.cs</ProjectItem> - <ProjectItem ReplaceParameters="true">Utilities.cs</ProjectItem> - </Folder> - <ProjectItem ReplaceParameters="true" TargetFileName="Default.aspx">Default.aspx</ProjectItem> - <ProjectItem ReplaceParameters="true" TargetFileName="Default.aspx.cs">Default.aspx.cs</ProjectItem> - <ProjectItem ReplaceParameters="true" TargetFileName="Default.aspx.designer.cs">Default.aspx.designer.cs</ProjectItem> - <ProjectItem ReplaceParameters="true" TargetFileName="Global.asax">Global.asax</ProjectItem> - <ProjectItem ReplaceParameters="true" TargetFileName="Global.asax.cs">Global.asax.cs</ProjectItem> - <Folder Name="images" TargetFolderName="images"> - <ProjectItem ReplaceParameters="false" TargetFileName="google.gif">google.gif</ProjectItem> - <ProjectItem ReplaceParameters="false" TargetFileName="infocard_23x16.png">infocard_23x16.png</ProjectItem> - <ProjectItem ReplaceParameters="false" TargetFileName="openid_login.gif">openid_login.gif</ProjectItem> - <ProjectItem ReplaceParameters="false" TargetFileName="yahoo.gif">yahoo.gif</ProjectItem> - <ProjectItem>myopenid.png</ProjectItem> - <ProjectItem>openid.gif</ProjectItem> - <ProjectItem ReplaceParameters="false" TargetFileName="yahoo_login.png">yahoo_login.png</ProjectItem> - </Folder> - <ProjectItem ReplaceParameters="true" TargetFileName="Login.aspx">Login.aspx</ProjectItem> - <ProjectItem ReplaceParameters="true" TargetFileName="Login.aspx.cs">Login.aspx.cs</ProjectItem> - <ProjectItem ReplaceParameters="true" TargetFileName="Login.aspx.designer.cs">Login.aspx.designer.cs</ProjectItem> - <ProjectItem ReplaceParameters="true" TargetFileName="LoginFrame.aspx">LoginFrame.aspx</ProjectItem> - <ProjectItem ReplaceParameters="true" TargetFileName="LoginFrame.aspx.cs">LoginFrame.aspx.cs</ProjectItem> - <ProjectItem ReplaceParameters="true" TargetFileName="LoginFrame.aspx.designer.cs">LoginFrame.aspx.designer.cs</ProjectItem> - <ProjectItem ReplaceParameters="true" TargetFileName="Logout.aspx">Logout.aspx</ProjectItem> - <ProjectItem ReplaceParameters="true" TargetFileName="Logout.aspx.cs">Logout.aspx.cs</ProjectItem> - <ProjectItem ReplaceParameters="true" TargetFileName="Logout.aspx.designer.cs">Logout.aspx.designer.cs</ProjectItem> - <Folder Name="Members" TargetFolderName="Members"> - <ProjectItem ReplaceParameters="true" TargetFileName="AccountInfo.aspx">AccountInfo.aspx</ProjectItem> - <ProjectItem ReplaceParameters="true" TargetFileName="AccountInfo.aspx.cs">AccountInfo.aspx.cs</ProjectItem> - <ProjectItem ReplaceParameters="true" TargetFileName="AccountInfo.aspx.designer.cs">AccountInfo.aspx.designer.cs</ProjectItem> - <ProjectItem ReplaceParameters="true" TargetFileName="Default.aspx">Default.aspx</ProjectItem> - <ProjectItem ReplaceParameters="true" TargetFileName="Default.aspx.cs">Default.aspx.cs</ProjectItem> - <ProjectItem ReplaceParameters="true" TargetFileName="Default.aspx.designer.cs">Default.aspx.designer.cs</ProjectItem> - <ProjectItem ReplaceParameters="true" TargetFileName="Web.config">Web.config</ProjectItem> - <ProjectItem ReplaceParameters="true">OAuthAuthorize.aspx</ProjectItem> - <ProjectItem ReplaceParameters="true">OAuthAuthorize.aspx.cs</ProjectItem> - <ProjectItem ReplaceParameters="true">OAuthAuthorize.aspx.designer.cs</ProjectItem> - </Folder> - <ProjectItem ReplaceParameters="true">Model.IssuedAccessToken.cs</ProjectItem> - <ProjectItem ReplaceParameters="true">Model.IssuedRequestToken.cs</ProjectItem> - <ProjectItem ReplaceParameters="true">Model.AuthenticationToken.cs</ProjectItem> - <ProjectItem ReplaceParameters="true">Model.User.cs</ProjectItem> - <ProjectItem ReplaceParameters="true">Model.Consumer.cs</ProjectItem> - <ProjectItem ReplaceParameters="false" TargetFileName="Model.edmx">Model.edmx</ProjectItem> - <ProjectItem ReplaceParameters="true" TargetFileName="Model.Designer.cs">Model.Designer.cs</ProjectItem> - <ProjectItem ReplaceParameters="true">OAuth.ashx</ProjectItem> - <ProjectItem ReplaceParameters="true">OAuth.ashx.cs</ProjectItem> - <Folder Name="Properties" TargetFolderName="Properties"> - <ProjectItem ReplaceParameters="true" TargetFileName="AssemblyInfo.cs">AssemblyInfo.cs</ProjectItem> - </Folder> - <Folder Name="scripts" TargetFolderName="scripts"> - <ProjectItem>jquery-1.3.1.js</ProjectItem> - <ProjectItem>jquery-ui-personalized-1.6rc6.js</ProjectItem> - <ProjectItem>jquery-ui-personalized-1.6rc6.min.js</ProjectItem> - <ProjectItem>jquery.cookie.js</ProjectItem> - <ProjectItem>LoginLink.js</ProjectItem> - </Folder> - <Folder Name="styles"> - <ProjectItem>loginpopup.css</ProjectItem> - <ProjectItem>Standard.css</ProjectItem> - </Folder> - <Folder Name="theme"> - <Folder Name="images"> - <ProjectItem>ui-bg_flat_55_999999_40x100.png</ProjectItem> - <ProjectItem>ui-bg_flat_75_aaaaaa_40x100.png</ProjectItem> - <ProjectItem>ui-bg_glass_45_0078ae_1x400.png</ProjectItem> - <ProjectItem>ui-bg_glass_55_f8da4e_1x400.png</ProjectItem> - <ProjectItem>ui-bg_glass_75_79c9ec_1x400.png</ProjectItem> - <ProjectItem>ui-bg_gloss-wave_45_e14f1c_500x100.png</ProjectItem> - <ProjectItem>ui-bg_gloss-wave_50_6eac2c_500x100.png</ProjectItem> - <ProjectItem>ui-bg_gloss-wave_75_2191c0_500x100.png</ProjectItem> - <ProjectItem>ui-bg_inset-hard_100_fcfdfd_1x100.png</ProjectItem> - <ProjectItem>ui-icons_0078ae_256x240.png</ProjectItem> - <ProjectItem>ui-icons_056b93_256x240.png</ProjectItem> - <ProjectItem>ui-icons_d8e7f3_256x240.png</ProjectItem> - <ProjectItem>ui-icons_e0fdff_256x240.png</ProjectItem> - <ProjectItem>ui-icons_f5e175_256x240.png</ProjectItem> - <ProjectItem>ui-icons_f7a50d_256x240.png</ProjectItem> - <ProjectItem>ui-icons_fcd113_256x240.png</ProjectItem> - </Folder> - <ProjectItem>ui.accordion.css</ProjectItem> - <ProjectItem>ui.all.css</ProjectItem> - <ProjectItem>ui.base.css</ProjectItem> - <ProjectItem>ui.core.css</ProjectItem> - <ProjectItem>ui.datepicker.css</ProjectItem> - <ProjectItem>ui.dialog.css</ProjectItem> - <ProjectItem>ui.progressbar.css</ProjectItem> - <ProjectItem>ui.resizable.css</ProjectItem> - <ProjectItem>ui.slider.css</ProjectItem> - <ProjectItem>ui.tabs.css</ProjectItem> - <ProjectItem>ui.theme.css</ProjectItem> - </Folder> - <ProjectItem ReplaceParameters="true" TargetFileName="Setup.aspx">Setup.aspx</ProjectItem> - <ProjectItem ReplaceParameters="true" TargetFileName="Setup.aspx.cs">Setup.aspx.cs</ProjectItem> - <ProjectItem ReplaceParameters="true" TargetFileName="Setup.aspx.designer.cs">Setup.aspx.designer.cs</ProjectItem> - <ProjectItem ReplaceParameters="true" TargetFileName="Site.Master">Site.Master</ProjectItem> - <ProjectItem ReplaceParameters="true" TargetFileName="Site.Master.cs">Site.Master.cs</ProjectItem> - <ProjectItem ReplaceParameters="true" TargetFileName="Site.Master.designer.cs">Site.Master.designer.cs</ProjectItem> - <ProjectItem ReplaceParameters="true" TargetFileName="GettingStarted.htm" OpenInWebBrowser="true">GettingStarted.htm</ProjectItem> - <ProjectItem ReplaceParameters="true" TargetFileName="Web.config">Web.config</ProjectItem> - <ProjectItem>xrds.aspx</ProjectItem> - </Project> - </TemplateContent> -</VSTemplate>
\ No newline at end of file diff --git a/projecttemplates/WebFormsRelyingParty/OAuth.ashx.cs b/projecttemplates/WebFormsRelyingParty/OAuth.ashx.cs index 274b5da..e7d1619 100644 --- a/projecttemplates/WebFormsRelyingParty/OAuth.ashx.cs +++ b/projecttemplates/WebFormsRelyingParty/OAuth.ashx.cs @@ -13,6 +13,7 @@ namespace WebFormsRelyingParty { using DotNetOpenAuth.Messaging; using DotNetOpenAuth.OAuth; using DotNetOpenAuth.OAuth.Messages; + using RelyingPartyLogic; using WebFormsRelyingParty.Code; /// <summary> diff --git a/projecttemplates/WebFormsRelyingParty/Setup.aspx.cs b/projecttemplates/WebFormsRelyingParty/Setup.aspx.cs index 4f73c5f..22125a4 100644 --- a/projecttemplates/WebFormsRelyingParty/Setup.aspx.cs +++ b/projecttemplates/WebFormsRelyingParty/Setup.aspx.cs @@ -9,8 +9,7 @@ using System.Web.UI.WebControls; using DotNetOpenAuth.OpenId; using DotNetOpenAuth.OpenId.RelyingParty; - using Microsoft.SqlServer.Management.Common; - using Microsoft.SqlServer.Management.Smo; + using RelyingPartyLogic; public partial class Setup : System.Web.UI.Page { private bool databaseCreated; @@ -27,7 +26,7 @@ if (e.IsDirectedIdentity) { this.noOPIdentifierLabel.Visible = true; } else if (!this.databaseCreated) { - this.CreateDatabase(e.ClaimedIdentifier, this.openidLogin.Text); + Utilities.CreateDatabase(e.ClaimedIdentifier, this.openidLogin.Text); this.MultiView1.ActiveViewIndex = 1; // indicate we have already created the database so that if the @@ -36,29 +35,5 @@ this.databaseCreated = true; } } - - private void CreateDatabase(Identifier claimedId, string friendlyId) { - const string SqlFormat = @" -CREATE DATABASE [{0}] ON (NAME='{0}', FILENAME='{0}') -GO -USE ""{0}"" -GO -{1} -EXEC [dbo].[AddUser] 'admin', 'admin', '{2}', '{3}' -GO -"; - string databasePath = HttpContext.Current.Server.MapPath("~/App_Data/Database.mdf"); - string schemaSql = File.ReadAllText(HttpContext.Current.Server.MapPath("~/Admin/CreateDatabase.sql")); - string sql = string.Format(CultureInfo.InvariantCulture, SqlFormat, databasePath, schemaSql, claimedId, "Admin"); - - var serverConnection = new ServerConnection(".\\sqlexpress"); - try { - serverConnection.ExecuteNonQuery(sql); - var server = new Server(serverConnection); - server.DetachDatabase(databasePath, true); - } finally { - serverConnection.Disconnect(); - } - } } } diff --git a/projecttemplates/WebFormsRelyingParty/Site.Master b/projecttemplates/WebFormsRelyingParty/Site.Master index f4e1a25..3cf191e 100644 --- a/projecttemplates/WebFormsRelyingParty/Site.Master +++ b/projecttemplates/WebFormsRelyingParty/Site.Master @@ -1,6 +1,6 @@ <%@ Master Language="C#" AutoEventWireup="true" CodeBehind="Site.master.cs" Inherits="WebFormsRelyingParty.Site" %> -<%@ Import Namespace="WebFormsRelyingParty" %> +<%@ Import Namespace="RelyingPartyLogic" %> <%@ Import Namespace="System.Linq" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> @@ -16,7 +16,7 @@ <asp:LoginView runat="server"> <LoggedInTemplate> <% - var authToken = Global.DataContext.AuthenticationToken.Include("User").First(token => token.ClaimedIdentifier == Page.User.Identity.Name); + var authToken = Database.DataContext.AuthenticationToken.Include("User").First(token => token.ClaimedIdentifier == Page.User.Identity.Name); if (!string.IsNullOrEmpty(authToken.User.EmailAddress)) { Response.Write(HttpUtility.HtmlEncode(authToken.User.EmailAddress)); } else if (!string.IsNullOrEmpty(authToken.User.FirstName)) { diff --git a/projecttemplates/WebFormsRelyingParty/Web.config b/projecttemplates/WebFormsRelyingParty/Web.config index b38a25a..e02090d 100644 --- a/projecttemplates/WebFormsRelyingParty/Web.config +++ b/projecttemplates/WebFormsRelyingParty/Web.config @@ -129,11 +129,12 @@ </httpHandlers> <httpModules> <add name="ScriptModule" type="System.Web.Handlers.ScriptModule, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" /> - <add name="OAuthAuthenticationModule" type="WebFormsRelyingParty.Code.OAuthAuthenticationModule" /> + <add name="OAuthAuthenticationModule" type="RelyingPartyLogic.OAuthAuthenticationModule, RelyingPartyLogic" /> + <add name="Database" type="RelyingPartyLogic.Database, RelyingPartyLogic"/> </httpModules> <roleManager enabled="true" defaultProvider="Database"> <providers> - <add name="Database" type="WebFormsRelyingParty.Code.DataRoleProvider" /> + <add name="Database" type="RelyingPartyLogic.DataRoleProvider, RelyingPartyLogic" /> </providers> </roleManager> </system.web> diff --git a/projecttemplates/WebFormsRelyingParty/WebFormsRelyingParty.csproj b/projecttemplates/WebFormsRelyingParty/WebFormsRelyingParty.csproj index b1ba4b7..3b86f6c 100644 --- a/projecttemplates/WebFormsRelyingParty/WebFormsRelyingParty.csproj +++ b/projecttemplates/WebFormsRelyingParty/WebFormsRelyingParty.csproj @@ -34,9 +34,6 @@ <SpecificVersion>False</SpecificVersion> <HintPath>..\..\lib\log4net.dll</HintPath> </Reference> - <Reference Include="Microsoft.SqlServer.ConnectionInfo" /> - <Reference Include="Microsoft.SqlServer.Smo" /> - <Reference Include="Microsoft.SqlServer.Management.Sdk.Sfc" /> <Reference Include="System" /> <Reference Include="System.Data" /> <Reference Include="System.Core"> @@ -87,14 +84,6 @@ <Content Include="Web.config" /> </ItemGroup> <ItemGroup> - <Compile Include="Code\OAuthAuthenticationModule.cs" /> - <Compile Include="Code\OAuthAuthorizationManager.cs" /> - <Compile Include="Code\OAuthConsumerTokenManager.cs" /> - <Compile Include="Code\OAuthPrincipalAuthorizationPolicy.cs" /> - <Compile Include="Code\OAuthServiceProvider.cs" /> - <Compile Include="Code\OAuthServiceProviderTokenManager.cs" /> - <Compile Include="Code\OAuthTokenManager.cs" /> - <Compile Include="Code\Policies.cs" /> <Compile Include="Code\Utilities.cs" /> <Compile Include="Members\OAuthAuthorize.aspx.cs"> <DependentUpon>OAuthAuthorize.aspx</DependentUpon> @@ -103,10 +92,6 @@ <Compile Include="Members\OAuthAuthorize.aspx.designer.cs"> <DependentUpon>OAuthAuthorize.aspx</DependentUpon> </Compile> - <Compile Include="Model.IssuedRequestToken.cs" /> - <Compile Include="Model.IssuedAccessToken.cs" /> - <Compile Include="Model.Consumer.cs" /> - <Compile Include="Model.User.cs" /> <Compile Include="LoginFrame.aspx.cs"> <DependentUpon>LoginFrame.aspx</DependentUpon> <SubType>ASPXCodeBehind</SubType> @@ -166,22 +151,10 @@ <Compile Include="Members\Default.aspx.designer.cs"> <DependentUpon>Default.aspx</DependentUpon> </Compile> - <Compile Include="Model.AuthenticationToken.cs" /> - <Compile Include="Model.Designer.cs"> - <AutoGen>True</AutoGen> - <DesignTime>True</DesignTime> - <DependentUpon>Model.edmx</DependentUpon> - </Compile> <Compile Include="OAuth.ashx.cs"> <DependentUpon>OAuth.ashx</DependentUpon> </Compile> <Compile Include="Properties\AssemblyInfo.cs" /> - <EntityDeploy Include="Model.edmx"> - <Generator>EntityModelCodeGenerator</Generator> - <LastGenOutput>Model.Designer.cs</LastGenOutput> - </EntityDeploy> - <Compile Include="Code\DataRoleProvider.cs"> - </Compile> <Compile Include="Setup.aspx.cs"> <DependentUpon>Setup.aspx</DependentUpon> <SubType>ASPXCodeBehind</SubType> @@ -213,11 +186,6 @@ <Content Include="styles\Standard.css" /> </ItemGroup> <ItemGroup> - <Content Include="bin\DotNetOpenAuth.dll" /> - <Content Include="bin\DotNetOpenAuth.pdb" /> - <Content Include="bin\DotNetOpenAuth.xml" /> - <Content Include="bin\log4net.dll" /> - <Content Include="bin\log4net.xml" /> <Content Include="GettingStarted.htm" /> <Content Include="images\infocard_23x16.png" /> <Content Include="images\myopenid.png" /> @@ -265,7 +233,6 @@ <Content Include="xrds.aspx" /> </ItemGroup> <ItemGroup> - <None Include="Admin\CreateDatabase.sql" /> <Content Include="Members\OAuthAuthorize.aspx" /> <Content Include="OAuth.ashx" /> </ItemGroup> @@ -274,9 +241,14 @@ <Project>{3191B653-F76D-4C1A-9A5A-347BC3AAAAB7}</Project> <Name>DotNetOpenAuth</Name> </ProjectReference> + <ProjectReference Include="..\RelyingPartyLogic\RelyingPartyLogic.csproj"> + <Project>{17932639-1F50-48AF-B0A5-E2BF832F82CC}</Project> + <Name>RelyingPartyLogic</Name> + </ProjectReference> </ItemGroup> <ItemGroup> <Folder Include="App_Data\" /> + <Folder Include="bin\" /> </ItemGroup> <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" /> <Import Project="$(MSBuildExtensionsPath)\Microsoft\VisualStudio\v9.0\WebApplications\Microsoft.WebApplication.targets" /> diff --git a/projecttemplates/WebFormsRelyingParty/WebFormsRelyingParty.vstemplate b/projecttemplates/WebFormsRelyingParty/WebFormsRelyingParty.vstemplate new file mode 100644 index 0000000..551e6bd --- /dev/null +++ b/projecttemplates/WebFormsRelyingParty/WebFormsRelyingParty.vstemplate @@ -0,0 +1,11 @@ +<VSTemplate Version="2.0.0" xmlns="http://schemas.microsoft.com/developer/vstemplate/2005" Type="Project"> + <TemplateData> + <Name>ASP.NET OpenID-InfoCard RP</Name> + <Description>An ASP.NET web forms web site that accepts OpenID and InfoCard logins</Description> + <ProjectType>CSharp</ProjectType> + <Icon>__TemplateIcon.ico</Icon> + </TemplateData> + <TemplateContent> + <Project File="WebFormsRelyingParty.csproj" ReplaceParameters="true" /> + </TemplateContent> +</VSTemplate>
\ No newline at end of file diff --git a/src/DotNetOpenAuth.BuildTasks/AddProjectItems.cs b/src/DotNetOpenAuth.BuildTasks/AddProjectItems.cs new file mode 100644 index 0000000..30fa284 --- /dev/null +++ b/src/DotNetOpenAuth.BuildTasks/AddProjectItems.cs @@ -0,0 +1,62 @@ +//----------------------------------------------------------------------- +// <copyright file="AddProjectItems.cs" company="Andrew Arnott"> +// Copyright (c) Andrew Arnott. All rights reserved. +// </copyright> +//----------------------------------------------------------------------- + +namespace DotNetOpenAuth.BuildTasks { + using System; + using System.Collections.Generic; + using System.Linq; + using System.Text; + using Microsoft.Build.BuildEngine; + using Microsoft.Build.Framework; + using Microsoft.Build.Utilities; + using System.Collections; + + public class AddProjectItems : Task { + /// <summary> + /// Gets or sets the projects to add items to. + /// </summary> + /// <value>The projects.</value> + [Required] + public ITaskItem[] Projects { get; set; } + + /// <summary> + /// Gets or sets the items to add to each project. + /// </summary> + /// <value>The items.</value> + /// <remarks> + /// Use the metadata "ItemType" on each item to specify the item type to use for the new + /// project item. If the metadata is absent, "None" is used as the item type. + /// </remarks> + [Required] + public ITaskItem[] Items { get; set; } + + /// <summary> + /// Executes this instance. + /// </summary> + public override bool Execute() { + foreach (var projectTaskItem in this.Projects) { + var project = new Project(); + project.Load(projectTaskItem.ItemSpec); + + foreach (var projectItem in this.Items) { + string itemType = projectItem.GetMetadata("ItemType"); + if (string.IsNullOrEmpty(itemType)) { + itemType = "None"; + } + 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); + } + } + + project.Save(projectTaskItem.ItemSpec); + } + + return !this.Log.HasLoggedErrors; + } + } +} diff --git a/src/DotNetOpenAuth.BuildTasks/ChangeProjectReferenceToAssemblyReference.cs b/src/DotNetOpenAuth.BuildTasks/ChangeProjectReferenceToAssemblyReference.cs index 973d8d6..f940a72 100644 --- a/src/DotNetOpenAuth.BuildTasks/ChangeProjectReferenceToAssemblyReference.cs +++ b/src/DotNetOpenAuth.BuildTasks/ChangeProjectReferenceToAssemblyReference.cs @@ -40,7 +40,7 @@ namespace DotNetOpenAuth.BuildTasks { item => item.Name == "ProjectReference" && item.Include == ProjectReference).Single(); doc.RemoveItem(projectReference); - var newReference = doc.AddNewItem("Reference", Path.GetFileNameWithoutExtension(Reference)); + var newReference = doc.AddNewItem("Reference", Path.GetFileNameWithoutExtension(Reference), true); newReference.SetMetadata("HintPath", Reference); doc.Save(project.ItemSpec); diff --git a/src/DotNetOpenAuth.BuildTasks/DiscoverProjectTemplates.cs b/src/DotNetOpenAuth.BuildTasks/DiscoverProjectTemplates.cs new file mode 100644 index 0000000..0162c16 --- /dev/null +++ b/src/DotNetOpenAuth.BuildTasks/DiscoverProjectTemplates.cs @@ -0,0 +1,63 @@ +//----------------------------------------------------------------------- +// <copyright file="DiscoverProjectTemplates.cs" company="Andrew Arnott"> +// Copyright (c) Andrew Arnott. All rights reserved. +// </copyright> +//----------------------------------------------------------------------- + +namespace DotNetOpenAuth.BuildTasks { + using System; + using System.Collections.Generic; + using System.IO; + using System.Linq; + using System.Text; + using System.Xml.Linq; + using Microsoft.Build.Framework; + using Microsoft.Build.Utilities; + + public class DiscoverProjectTemplates : Task { + public ITaskItem[] TopLevelTemplates { get; set; } + + [Output] + public ITaskItem[] ProjectTemplates { get; set; } + + [Output] + public ITaskItem[] ProjectTemplateContents { get; set; } + + /// <summary> + /// Executes this instance. + /// </summary> + public override bool Execute() { + List<ITaskItem> projectTemplates = new List<ITaskItem>(); + List<ITaskItem> projectTemplateContents = new List<ITaskItem>(); + foreach (ITaskItem topLevelTemplate in this.TopLevelTemplates) { + var vsTemplate = XElement.Load(topLevelTemplate.ItemSpec); + var templateContent = vsTemplate.Element(XName.Get("TemplateContent", MergeProjectWithVSTemplate.VSTemplateNamespace)); + var projectCollection = templateContent.Element(XName.Get("ProjectCollection", MergeProjectWithVSTemplate.VSTemplateNamespace)); + var links = projectCollection.Elements(XName.Get("ProjectTemplateLink", MergeProjectWithVSTemplate.VSTemplateNamespace)); + var subTemplates = links.Select( + link => (ITaskItem)new TaskItem( + link.Value, + new Dictionary<string, string> { + { "TopLevelTemplate", topLevelTemplate.ItemSpec }, + { "TopLevelTemplateFileName", Path.GetFileNameWithoutExtension(topLevelTemplate.ItemSpec) }, + })); + projectTemplates.AddRange(subTemplates); + + foreach (var link in links.Select(link => link.Value)) { + string[] files = Directory.GetFiles(Path.Combine(Path.GetDirectoryName(topLevelTemplate.ItemSpec), Path.GetDirectoryName(link)), "*.*", SearchOption.AllDirectories); + projectTemplateContents.AddRange(files.Select(file => (ITaskItem)new TaskItem( + file, + new Dictionary<string, string> { + { "TopLevelTemplate", topLevelTemplate.ItemSpec }, + { "TopLevelTemplateFileName", Path.GetFileNameWithoutExtension(topLevelTemplate.ItemSpec) }, + }))); + } + } + + this.ProjectTemplates = projectTemplates.ToArray(); + this.ProjectTemplateContents = projectTemplateContents.ToArray(); + + return !this.Log.HasLoggedErrors; + } + } +} diff --git a/src/DotNetOpenAuth.BuildTasks/DotNetOpenAuth.BuildTasks.csproj b/src/DotNetOpenAuth.BuildTasks/DotNetOpenAuth.BuildTasks.csproj index 3b22fff..7f84787 100644 --- a/src/DotNetOpenAuth.BuildTasks/DotNetOpenAuth.BuildTasks.csproj +++ b/src/DotNetOpenAuth.BuildTasks/DotNetOpenAuth.BuildTasks.csproj @@ -21,6 +21,33 @@ <DefineConstants>DEBUG;TRACE</DefineConstants> <ErrorReport>prompt</ErrorReport> <WarningLevel>4</WarningLevel> + <CodeContractsEnableRuntimeChecking>True</CodeContractsEnableRuntimeChecking> + <CodeContractsRuntimeOnlyPublicSurface>False</CodeContractsRuntimeOnlyPublicSurface> + <CodeContractsRuntimeThrowOnFailure>False</CodeContractsRuntimeThrowOnFailure> + <CodeContractsRuntimeCallSiteRequires>False</CodeContractsRuntimeCallSiteRequires> + <CodeContractsRunCodeAnalysis>False</CodeContractsRunCodeAnalysis> + <CodeContractsNonNullObligations>False</CodeContractsNonNullObligations> + <CodeContractsBoundsObligations>False</CodeContractsBoundsObligations> + <CodeContractsArithmeticObligations>False</CodeContractsArithmeticObligations> + <CodeContractsRedundantAssumptions>False</CodeContractsRedundantAssumptions> + <CodeContractsRunInBackground>True</CodeContractsRunInBackground> + <CodeContractsShowSquigglies>False</CodeContractsShowSquigglies> + <CodeContractsUseBaseLine>False</CodeContractsUseBaseLine> + <CodeContractsEmitXMLDocs>False</CodeContractsEmitXMLDocs> + <CodeContractsCustomRewriterAssembly> + </CodeContractsCustomRewriterAssembly> + <CodeContractsCustomRewriterClass> + </CodeContractsCustomRewriterClass> + <CodeContractsLibPaths> + </CodeContractsLibPaths> + <CodeContractsPlatformPath> + </CodeContractsPlatformPath> + <CodeContractsExtraAnalysisOptions> + </CodeContractsExtraAnalysisOptions> + <CodeContractsBaseLineFile> + </CodeContractsBaseLineFile> + <CodeContractsRuntimeCheckingLevel>Full</CodeContractsRuntimeCheckingLevel> + <CodeContractsReferenceAssembly>%28none%29</CodeContractsReferenceAssembly> </PropertyGroup> <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' "> <DebugType>pdbonly</DebugType> @@ -36,6 +63,7 @@ <Reference Include="Microsoft.Build.Utilities.v3.5"> <RequiredTargetFramework>3.5</RequiredTargetFramework> </Reference> + <Reference Include="Microsoft.Contracts, Version=1.0.0.0, Culture=neutral, PublicKeyToken=736440c9b414ea16, processorArchitecture=MSIL" /> <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> @@ -46,16 +74,23 @@ </Reference> <Reference Include="System.Data" /> <Reference Include="System.Xml" /> + <Reference Include="System.Xml.Linq"> + <RequiredTargetFramework>3.5</RequiredTargetFramework> + </Reference> </ItemGroup> <ItemGroup> + <Compile Include="AddProjectItems.cs" /> <Compile Include="ChangeProjectReferenceToAssemblyReference.cs" /> <Compile Include="CompareFiles.cs" /> <Compile Include="ChangeAssemblyReference.cs" /> <Compile Include="CopyWithTokenSubstitution.cs" /> <Compile Include="CreateWebApplication.cs" /> <Compile Include="DeleteWebApplication.cs" /> + <Compile Include="DiscoverProjectTemplates.cs" /> <Compile Include="ECMAScriptPacker.cs" /> <Compile Include="FilterItems.cs" /> + <Compile Include="FixupReferenceHintPaths.cs" /> + <Compile Include="MergeProjectWithVSTemplate.cs" /> <Compile Include="GetBuildVersion.cs" /> <Compile Include="CheckAdminRights.cs" /> <Compile Include="JsPack.cs" /> diff --git a/src/DotNetOpenAuth.BuildTasks/FixupReferenceHintPaths.cs b/src/DotNetOpenAuth.BuildTasks/FixupReferenceHintPaths.cs new file mode 100644 index 0000000..13a4b8f --- /dev/null +++ b/src/DotNetOpenAuth.BuildTasks/FixupReferenceHintPaths.cs @@ -0,0 +1,71 @@ +//----------------------------------------------------------------------- +// <copyright file="FixupReferenceHintPaths.cs" company="Andrew Arnott"> +// Copyright (c) Andrew Arnott. All rights reserved. +// </copyright> +//----------------------------------------------------------------------- + +namespace DotNetOpenAuth.BuildTasks { + using System; + using System.Collections.Generic; + using System.IO; + using System.Linq; + using System.Reflection; + using System.Text; + using Microsoft.Build.BuildEngine; + using Microsoft.Build.Framework; + using Microsoft.Build.Utilities; + + public class FixupReferenceHintPaths : Task { + /// <summary> + /// Gets or sets the projects to fixup references for. + /// </summary> + [Required] + public ITaskItem[] Projects { get; set; } + + /// <summary> + /// Gets or sets the set of full paths to assemblies that may be found in any of the <see cref="Projects"/>. + /// </summary> + [Required] + public ITaskItem[] References { get; set; } + + /// <summary> + /// Executes this instance. + /// </summary> + public override bool Execute() { + if (this.References.Length == 0 || this.Projects.Length == 0) { + this.Log.LogMessage(MessageImportance.Low, "Skipping reference hintpath fixup because no projects or no references were supplied."); + return !this.Log.HasLoggedErrors; + } + + // 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); + } + + foreach (var projectTaskItem in this.Projects) { + var project = new Project(); + Uri projectUri = new Uri(projectTaskItem.GetMetadata("FullPath")); + project.Load(projectTaskItem.ItemSpec); + + foreach (BuildItem referenceItem in project.GetEvaluatedItemsByName("Reference")) { + var referenceAssemblyName = new AssemblyName(referenceItem.Include); + var matchingReference = availableReferences.FirstOrDefault(r => string.Equals(r.Name, referenceAssemblyName.Name, StringComparison.OrdinalIgnoreCase)); + if (matchingReference != null) { + var originalSuppliedReferenceItem = this.References[Array.IndexOf(availableReferences, matchingReference)]; + string hintPath = originalSuppliedReferenceItem.GetMetadata("HintPath"); + if (string.IsNullOrEmpty(hintPath)) { + hintPath = projectUri.MakeRelativeUri(new Uri(matchingReference.CodeBase)).OriginalString.Replace(Path.AltDirectorySeparatorChar, Path.DirectorySeparatorChar); + } + this.Log.LogMessage("Fixing up HintPath to \"{0}\" in project \"{1}\".", referenceAssemblyName.Name, projectTaskItem.ItemSpec); + referenceItem.SetMetadata("HintPath", hintPath); + } + } + + project.Save(projectTaskItem.ItemSpec); + } + + return !this.Log.HasLoggedErrors; + } + } +} diff --git a/src/DotNetOpenAuth.BuildTasks/MergeProjectWithVSTemplate.cs b/src/DotNetOpenAuth.BuildTasks/MergeProjectWithVSTemplate.cs new file mode 100644 index 0000000..a2fd46b --- /dev/null +++ b/src/DotNetOpenAuth.BuildTasks/MergeProjectWithVSTemplate.cs @@ -0,0 +1,101 @@ +//----------------------------------------------------------------------- +// <copyright file="MergeProjectWithVSTemplate.cs" company="Andrew Arnott"> +// Copyright (c) Andrew Arnott. All rights reserved. +// </copyright> +//----------------------------------------------------------------------- + +namespace DotNetOpenAuth.BuildTasks { + using System; + using System.Collections.Generic; + using System.Linq; + using System.Text; + using Microsoft.Build.Framework; + using Microsoft.Build.Utilities; + using System.Xml.Linq; + using System.IO; + using Microsoft.Build.BuildEngine; + using System.Diagnostics.Contracts; + + public class MergeProjectWithVSTemplate : Task { + internal const string VSTemplateNamespace = "http://schemas.microsoft.com/developer/vstemplate/2005"; + + [Required] + public string[] ProjectItemTypes { get; set; } + + [Required] + public string[] ReplaceParametersExtensions { get; set; } + + [Required] + public ITaskItem[] Templates { get; set; } + + /// <summary> + /// Executes this instance. + /// </summary> + public override bool Execute() { + foreach(ITaskItem sourceTemplateTaskItem in this.Templates) { + var template = XElement.Load(sourceTemplateTaskItem.ItemSpec); + var templateContentElement = template.Element(XName.Get("TemplateContent", VSTemplateNamespace)); + var projectElement = templateContentElement.Element(XName.Get("Project", VSTemplateNamespace)); + if (projectElement == null) { + Log.LogMessage("Skipping merge of \"{0}\" with a project because no project was referenced from the template.", sourceTemplateTaskItem.ItemSpec); + continue; + } + + var projectPath = Path.Combine(Path.GetDirectoryName(sourceTemplateTaskItem.ItemSpec), projectElement.Attribute("File").Value); + Log.LogMessage("Merging project \"{0}\" with \"{1}\".", projectPath, sourceTemplateTaskItem.ItemSpec); + var sourceProject = new Project(); + sourceProject.Load(projectPath); + + // 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)); + var projectItem = new XElement( + XName.Get("ProjectItem", VSTemplateNamespace), + Path.GetFileName(item.Include)); + if (replaceParameters) { + projectItem.SetAttributeValue("ReplaceParameters", "true"); + } + parentNode.Add(projectItem); + } + } + + template.Save(sourceTemplateTaskItem.ItemSpec); + } + + return !Log.HasLoggedErrors; + } + + private static XElement FindOrCreateParent(string directoryName, XElement projectElement) { + Contract.Requires<ArgumentNullException>(projectElement != null); + + if (string.IsNullOrEmpty(directoryName)) { + return projectElement; + } + + string[] segments = directoryName.Split(Path.DirectorySeparatorChar); + XElement parent = projectElement; + for (int i = 0; i < segments.Length; i++) { + var candidateName = XName.Get("Folder", VSTemplateNamespace); + var candidate = parent.Elements(XName.Get("Folder", VSTemplateNamespace)).FirstOrDefault(n => n.Attribute("Name").Value == segments[i]); + if (candidate == null) { + candidate = new XElement( + candidateName, + new XAttribute("Name", segments[i])); + parent.Add(candidate); + } + + parent = candidate; + } + + return parent; + } + } +} diff --git a/src/DotNetOpenAuth.sln b/src/DotNetOpenAuth.sln index 2c15c50..3233865 100644 --- a/src/DotNetOpenAuth.sln +++ b/src/DotNetOpenAuth.sln @@ -168,6 +168,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Project Templates", "Projec EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WebFormsRelyingParty", "..\projecttemplates\WebFormsRelyingParty\WebFormsRelyingParty.csproj", "{A78F8FC6-7B03-4230-BE41-761E400D6810}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RelyingPartyLogic", "..\projecttemplates\RelyingPartyLogic\RelyingPartyLogic.csproj", "{17932639-1F50-48AF-B0A5-E2BF832F82CC}" +EndProject Global GlobalSection(TestCaseManagementSettings) = postSolution CategoryFile = DotNetOpenAuth.vsmdi @@ -268,6 +270,12 @@ Global {A78F8FC6-7B03-4230-BE41-761E400D6810}.Debug|Any CPU.Build.0 = Debug|Any CPU {A78F8FC6-7B03-4230-BE41-761E400D6810}.Release|Any CPU.ActiveCfg = Release|Any CPU {A78F8FC6-7B03-4230-BE41-761E400D6810}.Release|Any CPU.Build.0 = Release|Any CPU + {17932639-1F50-48AF-B0A5-E2BF832F82CC}.CodeAnalysis|Any CPU.ActiveCfg = Release|Any CPU + {17932639-1F50-48AF-B0A5-E2BF832F82CC}.CodeAnalysis|Any CPU.Build.0 = Release|Any CPU + {17932639-1F50-48AF-B0A5-E2BF832F82CC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {17932639-1F50-48AF-B0A5-E2BF832F82CC}.Debug|Any CPU.Build.0 = Debug|Any CPU + {17932639-1F50-48AF-B0A5-E2BF832F82CC}.Release|Any CPU.ActiveCfg = Release|Any CPU + {17932639-1F50-48AF-B0A5-E2BF832F82CC}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -289,5 +297,6 @@ Global {7ADCCD5C-AC2B-4340-9410-FE3A31A48191} = {1E2CBAA5-60A3-4AED-912E-541F5753CDC6} {5C65603B-235F-47E6-B536-06385C60DE7F} = {E9ED920D-1F83-48C0-9A4B-09CCE505FE6D} {A78F8FC6-7B03-4230-BE41-761E400D6810} = {B9EB8729-4B54-4453-B089-FE6761BA3057} + {17932639-1F50-48AF-B0A5-E2BF832F82CC} = {B9EB8729-4B54-4453-B089-FE6761BA3057} EndGlobalSection EndGlobal |