diff options
author | Andrew Arnott <andrewarnott@gmail.com> | 2009-11-09 08:44:30 -0800 |
---|---|---|
committer | Andrew Arnott <andrewarnott@gmail.com> | 2009-11-09 08:44:30 -0800 |
commit | 75737b85f5dce833c4fed0b1c839150fc1e6c3dc (patch) | |
tree | 7248275682931c1d88d4ec9a0002d4c88b1f1b7c | |
parent | b00d9da0af1cb5bcd958ec6c402032d9d95e6c0d (diff) | |
download | DotNetOpenAuth-75737b85f5dce833c4fed0b1c839150fc1e6c3dc.zip DotNetOpenAuth-75737b85f5dce833c4fed0b1c839150fc1e6c3dc.tar.gz DotNetOpenAuth-75737b85f5dce833c4fed0b1c839150fc1e6c3dc.tar.bz2 |
Added EmailAddressVerified column to users table and code to utilize it.
-rw-r--r-- | projecttemplates/WebFormsRelyingParty/Admin/CreateDatabase.sql | 4 | ||||
-rw-r--r-- | projecttemplates/WebFormsRelyingParty/Code/Policies.cs | 23 | ||||
-rw-r--r-- | projecttemplates/WebFormsRelyingParty/LoginFrame.aspx.cs | 11 | ||||
-rw-r--r-- | projecttemplates/WebFormsRelyingParty/Members/AccountInfo.aspx | 3 | ||||
-rw-r--r-- | projecttemplates/WebFormsRelyingParty/Members/AccountInfo.aspx.cs | 2 | ||||
-rw-r--r-- | projecttemplates/WebFormsRelyingParty/Members/AccountInfo.aspx.designer.cs | 9 | ||||
-rw-r--r-- | projecttemplates/WebFormsRelyingParty/Model.AuthenticationToken.cs (renamed from projecttemplates/WebFormsRelyingParty/Model.cs) | 0 | ||||
-rw-r--r-- | projecttemplates/WebFormsRelyingParty/Model.Designer.cs | 31 | ||||
-rw-r--r-- | projecttemplates/WebFormsRelyingParty/Model.User.cs | 13 | ||||
-rw-r--r-- | projecttemplates/WebFormsRelyingParty/Model.edmx | 18 | ||||
-rw-r--r-- | projecttemplates/WebFormsRelyingParty/WebFormsRelyingParty.csproj | 4 |
11 files changed, 105 insertions, 13 deletions
diff --git a/projecttemplates/WebFormsRelyingParty/Admin/CreateDatabase.sql b/projecttemplates/WebFormsRelyingParty/Admin/CreateDatabase.sql index 99ac9db..2030155 100644 --- a/projecttemplates/WebFormsRelyingParty/Admin/CreateDatabase.sql +++ b/projecttemplates/WebFormsRelyingParty/Admin/CreateDatabase.sql @@ -8,12 +8,16 @@ CREATE TABLE [dbo].[User]( [FirstName] [nvarchar](50) NULL, [LastName] [nvarchar](50) NULL, [EmailAddress] [nvarchar](100) NULL, + [EmailAddressVerified] [bit] NOT NULL, CONSTRAINT [PK_User] PRIMARY KEY CLUSTERED ( [Id] ASC )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] ) ON [PRIMARY] GO +ALTER TABLE [dbo].[User] ADD CONSTRAINT [DF_User_EmailAddressVerified] DEFAULT ((0)) FOR [EmailAddressVerified] +GO + /****** Object: Table [dbo].[Role] Script Date: 10/08/2009 18:10:17 ******/ SET ANSI_NULLS ON GO diff --git a/projecttemplates/WebFormsRelyingParty/Code/Policies.cs b/projecttemplates/WebFormsRelyingParty/Code/Policies.cs new file mode 100644 index 0000000..676b3f2 --- /dev/null +++ b/projecttemplates/WebFormsRelyingParty/Code/Policies.cs @@ -0,0 +1,23 @@ +//----------------------------------------------------------------------- +// <copyright file="Policies.cs" company="Andrew Arnott"> +// Copyright (c) Andrew Arnott. All rights reserved. +// </copyright> +//----------------------------------------------------------------------- + +namespace WebFormsRelyingParty.Code { + using System; + using System.Collections.Generic; + using System.Linq; + using System.Web; + + public class Policies { + /// <summary> + /// The set of OP Endpoints that we trust pre-verify email addresses before sending them + /// with positive assertions. + /// </summary> + public static readonly Uri[] ProviderEndpointsProvidingTrustedEmails = new Uri[] { + new Uri("https://www.google.com/accounts/o8/ud"), + new Uri("https://open.login.yahooapis.com/openid/op/auth"), + }; + } +} diff --git a/projecttemplates/WebFormsRelyingParty/LoginFrame.aspx.cs b/projecttemplates/WebFormsRelyingParty/LoginFrame.aspx.cs index 10461d4..b8a9f29 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 WebFormsRelyingParty.Code; public partial class LoginFrame : System.Web.UI.Page { protected void Page_Load(object sender, EventArgs e) { @@ -27,11 +28,13 @@ } protected void openIdSelector_LoggedIn(object sender, OpenIdEventArgs e) { - this.LoginUser(e.ClaimedIdentifier, e.Response.FriendlyIdentifierForDisplay, e.Response.GetExtension<ClaimsResponse>(), null); + bool trustedEmail = Policies.ProviderEndpointsProvidingTrustedEmails.Contains(e.Response.Provider.Uri); + this.LoginUser(e.ClaimedIdentifier, e.Response.FriendlyIdentifierForDisplay, e.Response.GetExtension<ClaimsResponse>(), null, trustedEmail); } protected void openIdSelector_ReceivedToken(object sender, ReceivedTokenEventArgs e) { - this.LoginUser(AuthenticationToken.SynthesizeClaimedIdentifierFromInfoCard(e.Token.UniqueId), e.Token.SiteSpecificId, null, e.Token); + bool trustedEmail = false; // we don't trust InfoCard email addresses, since these can be self-issued. + this.LoginUser(AuthenticationToken.SynthesizeClaimedIdentifierFromInfoCard(e.Token.UniqueId), e.Token.SiteSpecificId, null, e.Token, trustedEmail); } protected void openIdSelector_Failed(object sender, OpenIdEventArgs e) { @@ -46,7 +49,7 @@ this.errorPanel.Visible = true; } - private void LoginUser(string claimedIdentifier, string friendlyIdentifier, ClaimsResponse claims, Token samlToken) { + 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); if (openidToken == null) { @@ -62,6 +65,7 @@ if (claims != null) { if (!string.IsNullOrEmpty(claims.Email)) { user.EmailAddress = claims.Email; + user.EmailAddressVerified = trustedEmail; } if (!string.IsNullOrEmpty(claims.FullName)) { if (claims.FullName.IndexOf(' ') > 0) { @@ -75,6 +79,7 @@ string email, givenName, surname; if (samlToken.Claims.TryGetValue(ClaimTypes.Email, out email)) { user.EmailAddress = email; + user.EmailAddressVerified = trustedEmail; } if (samlToken.Claims.TryGetValue(ClaimTypes.GivenName, out givenName)) { user.FirstName = givenName; diff --git a/projecttemplates/WebFormsRelyingParty/Members/AccountInfo.aspx b/projecttemplates/WebFormsRelyingParty/Members/AccountInfo.aspx index fe99b75..5ed0745 100644 --- a/projecttemplates/WebFormsRelyingParty/Members/AccountInfo.aspx +++ b/projecttemplates/WebFormsRelyingParty/Members/AccountInfo.aspx @@ -51,7 +51,8 @@ <asp:TextBox ID="emailBox" runat="server" Columns="40" ValidationGroup="Profile" /> <asp:RegularExpressionValidator ID="RegularExpressionValidator1" runat="server" ControlToValidate="emailBox" ErrorMessage="Invalid email address" ValidationExpression="\w+([-+.']\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*" - ValidationGroup="Profile">invalid</asp:RegularExpressionValidator> + ValidationGroup="Profile" Text="invalid" Display="Dynamic" /> + <asp:Label runat="server" ID="emailVerifiedLabel" Text="verified" Visible="false" /> </td> </tr> <tr> diff --git a/projecttemplates/WebFormsRelyingParty/Members/AccountInfo.aspx.cs b/projecttemplates/WebFormsRelyingParty/Members/AccountInfo.aspx.cs index f1a40f7..f7d9794 100644 --- a/projecttemplates/WebFormsRelyingParty/Members/AccountInfo.aspx.cs +++ b/projecttemplates/WebFormsRelyingParty/Members/AccountInfo.aspx.cs @@ -21,6 +21,7 @@ namespace WebFormsRelyingParty.Members { if (!IsPostBack) { this.Repeater1.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; } @@ -48,6 +49,7 @@ namespace WebFormsRelyingParty.Members { Global.LoggedInUser.EmailAddress = this.emailBox.Text; Global.LoggedInUser.FirstName = this.firstNameBox.Text; Global.LoggedInUser.LastName = this.lastNameBox.Text; + this.emailVerifiedLabel.Visible = Global.LoggedInUser.EmailAddressVerified; } protected void InfoCardSelector1_ReceivedToken(object sender, ReceivedTokenEventArgs e) { diff --git a/projecttemplates/WebFormsRelyingParty/Members/AccountInfo.aspx.designer.cs b/projecttemplates/WebFormsRelyingParty/Members/AccountInfo.aspx.designer.cs index b7f43ce..bb08e65 100644 --- a/projecttemplates/WebFormsRelyingParty/Members/AccountInfo.aspx.designer.cs +++ b/projecttemplates/WebFormsRelyingParty/Members/AccountInfo.aspx.designer.cs @@ -68,6 +68,15 @@ namespace WebFormsRelyingParty.Members { protected global::System.Web.UI.WebControls.RegularExpressionValidator RegularExpressionValidator1; /// <summary> + /// emailVerifiedLabel control. + /// </summary> + /// <remarks> + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// </remarks> + protected global::System.Web.UI.WebControls.Label emailVerifiedLabel; + + /// <summary> /// saveChanges control. /// </summary> /// <remarks> diff --git a/projecttemplates/WebFormsRelyingParty/Model.cs b/projecttemplates/WebFormsRelyingParty/Model.AuthenticationToken.cs index 53ca10f..53ca10f 100644 --- a/projecttemplates/WebFormsRelyingParty/Model.cs +++ b/projecttemplates/WebFormsRelyingParty/Model.AuthenticationToken.cs diff --git a/projecttemplates/WebFormsRelyingParty/Model.Designer.cs b/projecttemplates/WebFormsRelyingParty/Model.Designer.cs index 5c7b138..321d83b 100644 --- a/projecttemplates/WebFormsRelyingParty/Model.Designer.cs +++ b/projecttemplates/WebFormsRelyingParty/Model.Designer.cs @@ -13,7 +13,7 @@ [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))] // Original file name: -// Generation date: 10/10/2009 9:43:51 AM +// Generation date: 11/9/2009 7:05:56 AM namespace WebFormsRelyingParty { @@ -350,10 +350,12 @@ namespace WebFormsRelyingParty /// Create a new User object. /// </summary> /// <param name="id">Initial value of Id.</param> - public static User CreateUser(int id) + /// <param name="emailAddressVerified">Initial value of EmailAddressVerified.</param> + public static User CreateUser(int id, bool emailAddressVerified) { User user = new User(); user.Id = id; + user.EmailAddressVerified = emailAddressVerified; return user; } /// <summary> @@ -426,7 +428,7 @@ namespace WebFormsRelyingParty partial void OnLastNameChanging(string value); partial void OnLastNameChanged(); /// <summary> - /// There are no comments for Property EmailAddress in the schema. + /// The email address claimed to be controlled by the user. Whether it is actually owned by the user is indicated by the EmailAddressVerified property. /// </summary> [global::System.Data.Objects.DataClasses.EdmScalarPropertyAttribute()] [global::System.Runtime.Serialization.DataMemberAttribute()] @@ -449,6 +451,29 @@ namespace WebFormsRelyingParty partial void OnEmailAddressChanging(string value); partial void OnEmailAddressChanged(); /// <summary> + /// A value indicating whether the email address has been verified as actually owned by this user. + /// </summary> + [global::System.Data.Objects.DataClasses.EdmScalarPropertyAttribute(IsNullable=false)] + [global::System.Runtime.Serialization.DataMemberAttribute()] + public bool EmailAddressVerified + { + get + { + return this._EmailAddressVerified; + } + set + { + this.OnEmailAddressVerifiedChanging(value); + this.ReportPropertyChanging("EmailAddressVerified"); + this._EmailAddressVerified = global::System.Data.Objects.DataClasses.StructuralObject.SetValidValue(value); + this.ReportPropertyChanged("EmailAddressVerified"); + this.OnEmailAddressVerifiedChanged(); + } + } + private bool _EmailAddressVerified; + partial void OnEmailAddressVerifiedChanging(bool value); + partial void OnEmailAddressVerifiedChanged(); + /// <summary> /// There are no comments for Roles in the schema. /// </summary> [global::System.Data.Objects.DataClasses.EdmRelationshipNavigationPropertyAttribute("DatabaseModel", "UserRole", "Role")] diff --git a/projecttemplates/WebFormsRelyingParty/Model.User.cs b/projecttemplates/WebFormsRelyingParty/Model.User.cs new file mode 100644 index 0000000..b2ea2f4 --- /dev/null +++ b/projecttemplates/WebFormsRelyingParty/Model.User.cs @@ -0,0 +1,13 @@ +namespace WebFormsRelyingParty { + using System; + using System.Collections.Generic; + using System.Linq; + using System.Web; + + public partial class User { + partial void OnEmailAddressChanged() { + // Whenever the email address is changed, we must reset its verified status. + this.EmailAddressVerified = false; + } + } +} diff --git a/projecttemplates/WebFormsRelyingParty/Model.edmx b/projecttemplates/WebFormsRelyingParty/Model.edmx index c23b3df..af72a25 100644 --- a/projecttemplates/WebFormsRelyingParty/Model.edmx +++ b/projecttemplates/WebFormsRelyingParty/Model.edmx @@ -47,6 +47,7 @@ <Property Name="FirstName" Type="nvarchar" MaxLength="50" /> <Property Name="LastName" Type="nvarchar" MaxLength="50" /> <Property Name="EmailAddress" Type="nvarchar" MaxLength="100" /> + <Property Name="EmailAddressVerified" Type="bit" Nullable="false" /> </EntityType> <EntityType Name="UserRole"> <Key> @@ -136,9 +137,15 @@ <Property Name="Id" Type="Int32" Nullable="false" a:SetterAccess="Private" xmlns:a="http://schemas.microsoft.com/ado/2006/04/codegeneration" /> <Property Name="FirstName" Type="String" MaxLength="50" Unicode="true" FixedLength="false" /> <Property Name="LastName" Type="String" MaxLength="50" Unicode="true" FixedLength="false" /> - <Property Name="EmailAddress" Type="String" MaxLength="100" Unicode="true" FixedLength="false" /> + <Property Name="EmailAddress" Type="String" MaxLength="100" Unicode="true" FixedLength="false" > + <Documentation> + <Summary>The email address claimed to be controlled by the user. Whether it is actually owned by the user is indicated by the EmailAddressVerified property.</Summary></Documentation></Property> <NavigationProperty Name="Roles" Relationship="DatabaseModel.UserRole" FromRole="User" ToRole="Role" /> - <NavigationProperty Name="AuthenticationTokens" Relationship="DatabaseModel.UserAuthenticationToken" FromRole="User" ToRole="AuthenticationToken" /></EntityType> + <NavigationProperty Name="AuthenticationTokens" Relationship="DatabaseModel.UserAuthenticationToken" FromRole="User" ToRole="AuthenticationToken" /> + <Property Name="EmailAddressVerified" Type="Boolean" Nullable="false" > + <Documentation> + <Summary>A value indicating whether the email address has been verified as actually owned by this user.</Summary></Documentation></Property> + </EntityType> <Association Name="UserRole"> <End Role="Role" Type="DatabaseModel.Role" Multiplicity="*" /> <End Role="User" Type="DatabaseModel.User" Multiplicity="*" /> @@ -162,6 +169,7 @@ <EntitySetMapping Name="User"> <EntityTypeMapping TypeName="IsTypeOf(DatabaseModel.User)"> <MappingFragment StoreEntitySet="User"> + <ScalarProperty Name="EmailAddressVerified" ColumnName="EmailAddressVerified" /> <ScalarProperty Name="Id" ColumnName="Id" /> <ScalarProperty Name="FirstName" ColumnName="FirstName" /> <ScalarProperty Name="LastName" ColumnName="LastName" /> @@ -211,7 +219,7 @@ <Diagram Name="Model"> <EntityTypeShape EntityType="DatabaseModel.AuthenticationToken" Width="1.875" PointX="5.25" PointY="1.125" Height="1.4033821614583335" IsExpanded="true" /> <EntityTypeShape EntityType="DatabaseModel.Role" Width="1.5" PointX="0.75" PointY="1.25" Height="1.5956835937500002" IsExpanded="true" /> - <EntityTypeShape EntityType="DatabaseModel.User" Width="1.75" PointX="2.875" PointY="0.875" Height="2.364889322916667" IsExpanded="true" /> + <EntityTypeShape EntityType="DatabaseModel.User" Width="1.75" PointX="2.875" PointY="0.875" Height="2.3648893229166661" IsExpanded="true" /> <AssociationConnector Association="DatabaseModel.UserRole" ManuallyRouted="false"> <ConnectorPoint PointX="2.25" PointY="2.0478417968750002" /> <ConnectorPoint PointX="2.875" PointY="2.0478417968750002" /></AssociationConnector> @@ -219,7 +227,7 @@ <ConnectorPoint PointX="6.5625" PointY="3.375" /> <ConnectorPoint PointX="6.5625" PointY="2.9129850260416665" /></InheritanceConnector> <AssociationConnector Association="DatabaseModel.UserAuthenticationToken"> - <ConnectorPoint PointX="4.625" PointY="1.8266910807291668" /> - <ConnectorPoint PointX="5.25" PointY="1.8266910807291668" /></AssociationConnector></Diagram></edmx:Diagrams> + <ConnectorPoint PointX="4.625" PointY="2.0189925130208337" /> + <ConnectorPoint PointX="5.25" PointY="2.0189925130208337" /></AssociationConnector></Diagram></edmx:Diagrams> </edmx:Designer> </edmx:Edmx>
\ No newline at end of file diff --git a/projecttemplates/WebFormsRelyingParty/WebFormsRelyingParty.csproj b/projecttemplates/WebFormsRelyingParty/WebFormsRelyingParty.csproj index 5c36d34..43bdef4 100644 --- a/projecttemplates/WebFormsRelyingParty/WebFormsRelyingParty.csproj +++ b/projecttemplates/WebFormsRelyingParty/WebFormsRelyingParty.csproj @@ -87,6 +87,8 @@ <Content Include="Web.config" /> </ItemGroup> <ItemGroup> + <Compile Include="Code\Policies.cs" /> + <Compile Include="Model.User.cs" /> <Compile Include="LoginFrame.aspx.cs"> <DependentUpon>LoginFrame.aspx</DependentUpon> <SubType>ASPXCodeBehind</SubType> @@ -146,7 +148,7 @@ <Compile Include="Members\Default.aspx.designer.cs"> <DependentUpon>Default.aspx</DependentUpon> </Compile> - <Compile Include="Model.cs" /> + <Compile Include="Model.AuthenticationToken.cs" /> <Compile Include="Model.Designer.cs"> <AutoGen>True</AutoGen> <DesignTime>True</DesignTime> |