@ -0,0 +1,6 @@ | |||||
FROM microsoft/aspnet | |||||
ARG source | |||||
WORKDIR /app | |||||
EXPOSE 80 | |||||
COPY ${source:-obj/Docker/publish} . | |||||
ENTRYPOINT ["dotnet", "Catalog.API.dll"] |
@ -0,0 +1,8 @@ | |||||
# Compose supports declaring default environment variables in an environment file named .env placed in the folder docker-compose command is executed from (current working directory). | |||||
# Compose expects each line in an env file to be in VAR=VAL format. Lines beginning with # (i.e. comments) are ignored, as are blank lines. | |||||
# Note: Values present in the environment at runtime will always override those defined inside the .env file. Similarly, values passed via command-line arguments take precedence as well. | |||||
# The IP below should be swapped to your real IP or DNS name, like 192.168.88.248, etc. if testing from remote browsers or mobile devices | |||||
ESHOP_EXTERNAL_DNS_NAME_OR_IP=192.168.1.103 | |||||
ESHOP_PROD_EXTERNAL_DNS_NAME_OR_IP=10.121.122.92 |
@ -0,0 +1,70 @@ | |||||
| |||||
Microsoft Visual Studio Solution File, Format Version 12.00 | |||||
# Visual Studio 15 | |||||
VisualStudioVersion = 15.0.26502.1 | |||||
MinimumVisualStudioVersion = 10.0.40219.1 | |||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Catalog.WebForms", "Catalog.WebForms\Catalog.WebForms.csproj", "{487A4E92-FAA3-415C-A019-6EDADB8AB1D9}" | |||||
EndProject | |||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Catalog.API", "..\..\Services\Catalog\Catalog.API\Catalog.API.csproj", "{3D130B2D-632C-4839-8CF7-F2F70EA43306}" | |||||
EndProject | |||||
Project("{E53339B2-1760-4266-BCC7-CA923CBCF16C}") = "docker-compose", "docker-compose.dcproj", "{E562EED3-9F2F-459B-83AE-C6F15706B7AD}" | |||||
EndProject | |||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.HealthChecks", "..\..\BuildingBlocks\HealthChecks\src\Microsoft.AspNetCore.HealthChecks\Microsoft.AspNetCore.HealthChecks.csproj", "{B053B0BE-CE51-4DBE-BCDC-27D0984C9F73}" | |||||
EndProject | |||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Extensions.HealthChecks", "..\..\BuildingBlocks\HealthChecks\src\Microsoft.Extensions.HealthChecks\Microsoft.Extensions.HealthChecks.csproj", "{BCDE5D98-B852-4406-9B4C-08351AE516F8}" | |||||
EndProject | |||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Extensions.HealthChecks.SqlServer", "..\..\BuildingBlocks\HealthChecks\src\Microsoft.Extensions.HealthChecks.SqlServer\Microsoft.Extensions.HealthChecks.SqlServer.csproj", "{69B6619F-07EF-4151-A1E0-B7401A0986FB}" | |||||
EndProject | |||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EventBus", "..\..\BuildingBlocks\EventBus\EventBus\EventBus.csproj", "{4AA18AC1-AD5F-4A2B-B9EB-584DABAD4A47}" | |||||
EndProject | |||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EventBusRabbitMQ", "..\..\BuildingBlocks\EventBus\EventBusRabbitMQ\EventBusRabbitMQ.csproj", "{8BF49A04-E535-4E04-83EB-76EBF60E4921}" | |||||
EndProject | |||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "IntegrationEventLogEF", "..\..\BuildingBlocks\EventBus\IntegrationEventLogEF\IntegrationEventLogEF.csproj", "{5370E624-A71C-4D3B-A2E1-870F5E908A05}" | |||||
EndProject | |||||
Global | |||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution | |||||
Debug|Any CPU = Debug|Any CPU | |||||
Release|Any CPU = Release|Any CPU | |||||
EndGlobalSection | |||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution | |||||
{487A4E92-FAA3-415C-A019-6EDADB8AB1D9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU | |||||
{487A4E92-FAA3-415C-A019-6EDADB8AB1D9}.Debug|Any CPU.Build.0 = Debug|Any CPU | |||||
{487A4E92-FAA3-415C-A019-6EDADB8AB1D9}.Release|Any CPU.ActiveCfg = Release|Any CPU | |||||
{487A4E92-FAA3-415C-A019-6EDADB8AB1D9}.Release|Any CPU.Build.0 = Release|Any CPU | |||||
{3D130B2D-632C-4839-8CF7-F2F70EA43306}.Debug|Any CPU.ActiveCfg = Debug|Any CPU | |||||
{3D130B2D-632C-4839-8CF7-F2F70EA43306}.Debug|Any CPU.Build.0 = Debug|Any CPU | |||||
{3D130B2D-632C-4839-8CF7-F2F70EA43306}.Release|Any CPU.ActiveCfg = Release|Any CPU | |||||
{3D130B2D-632C-4839-8CF7-F2F70EA43306}.Release|Any CPU.Build.0 = Release|Any CPU | |||||
{E562EED3-9F2F-459B-83AE-C6F15706B7AD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU | |||||
{E562EED3-9F2F-459B-83AE-C6F15706B7AD}.Debug|Any CPU.Build.0 = Debug|Any CPU | |||||
{E562EED3-9F2F-459B-83AE-C6F15706B7AD}.Release|Any CPU.ActiveCfg = Release|Any CPU | |||||
{E562EED3-9F2F-459B-83AE-C6F15706B7AD}.Release|Any CPU.Build.0 = Release|Any CPU | |||||
{B053B0BE-CE51-4DBE-BCDC-27D0984C9F73}.Debug|Any CPU.ActiveCfg = Debug|Any CPU | |||||
{B053B0BE-CE51-4DBE-BCDC-27D0984C9F73}.Debug|Any CPU.Build.0 = Debug|Any CPU | |||||
{B053B0BE-CE51-4DBE-BCDC-27D0984C9F73}.Release|Any CPU.ActiveCfg = Release|Any CPU | |||||
{B053B0BE-CE51-4DBE-BCDC-27D0984C9F73}.Release|Any CPU.Build.0 = Release|Any CPU | |||||
{BCDE5D98-B852-4406-9B4C-08351AE516F8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU | |||||
{BCDE5D98-B852-4406-9B4C-08351AE516F8}.Debug|Any CPU.Build.0 = Debug|Any CPU | |||||
{BCDE5D98-B852-4406-9B4C-08351AE516F8}.Release|Any CPU.ActiveCfg = Release|Any CPU | |||||
{BCDE5D98-B852-4406-9B4C-08351AE516F8}.Release|Any CPU.Build.0 = Release|Any CPU | |||||
{69B6619F-07EF-4151-A1E0-B7401A0986FB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU | |||||
{69B6619F-07EF-4151-A1E0-B7401A0986FB}.Debug|Any CPU.Build.0 = Debug|Any CPU | |||||
{69B6619F-07EF-4151-A1E0-B7401A0986FB}.Release|Any CPU.ActiveCfg = Release|Any CPU | |||||
{69B6619F-07EF-4151-A1E0-B7401A0986FB}.Release|Any CPU.Build.0 = Release|Any CPU | |||||
{4AA18AC1-AD5F-4A2B-B9EB-584DABAD4A47}.Debug|Any CPU.ActiveCfg = Debug|Any CPU | |||||
{4AA18AC1-AD5F-4A2B-B9EB-584DABAD4A47}.Debug|Any CPU.Build.0 = Debug|Any CPU | |||||
{4AA18AC1-AD5F-4A2B-B9EB-584DABAD4A47}.Release|Any CPU.ActiveCfg = Release|Any CPU | |||||
{4AA18AC1-AD5F-4A2B-B9EB-584DABAD4A47}.Release|Any CPU.Build.0 = Release|Any CPU | |||||
{8BF49A04-E535-4E04-83EB-76EBF60E4921}.Debug|Any CPU.ActiveCfg = Debug|Any CPU | |||||
{8BF49A04-E535-4E04-83EB-76EBF60E4921}.Debug|Any CPU.Build.0 = Debug|Any CPU | |||||
{8BF49A04-E535-4E04-83EB-76EBF60E4921}.Release|Any CPU.ActiveCfg = Release|Any CPU | |||||
{8BF49A04-E535-4E04-83EB-76EBF60E4921}.Release|Any CPU.Build.0 = Release|Any CPU | |||||
{5370E624-A71C-4D3B-A2E1-870F5E908A05}.Debug|Any CPU.ActiveCfg = Debug|Any CPU | |||||
{5370E624-A71C-4D3B-A2E1-870F5E908A05}.Debug|Any CPU.Build.0 = Debug|Any CPU | |||||
{5370E624-A71C-4D3B-A2E1-870F5E908A05}.Release|Any CPU.ActiveCfg = Release|Any CPU | |||||
{5370E624-A71C-4D3B-A2E1-870F5E908A05}.Release|Any CPU.Build.0 = Release|Any CPU | |||||
EndGlobalSection | |||||
GlobalSection(SolutionProperties) = preSolution | |||||
HideSolutionNode = FALSE | |||||
EndGlobalSection | |||||
EndGlobal |
@ -0,0 +1,3 @@ | |||||
* | |||||
!obj\Docker\publish\* | |||||
!obj\Docker\empty\ |
@ -0,0 +1,7 @@ | |||||
<%@ Page Title="About" Language="C#" MasterPageFile="~/Site.Master" AutoEventWireup="true" CodeBehind="About.aspx.cs" Inherits="eShopOnContainers.Catalog.WebForms.About" %> | |||||
<asp:Content ID="BodyContent" ContentPlaceHolderID="MainContent" runat="server"> | |||||
<h2><%: Title %>.</h2> | |||||
<h3>Your application description page.</h3> | |||||
<p>Use this area to provide additional information.</p> | |||||
</asp:Content> |
@ -0,0 +1,17 @@ | |||||
using System; | |||||
using System.Collections.Generic; | |||||
using System.Linq; | |||||
using System.Web; | |||||
using System.Web.UI; | |||||
using System.Web.UI.WebControls; | |||||
namespace eShopOnContainers.Catalog.WebForms | |||||
{ | |||||
public partial class About : Page | |||||
{ | |||||
protected void Page_Load(object sender, EventArgs e) | |||||
{ | |||||
} | |||||
} | |||||
} |
@ -0,0 +1,17 @@ | |||||
//------------------------------------------------------------------------------ | |||||
// <auto-generated> | |||||
// This code was generated by a tool. | |||||
// | |||||
// Changes to this file may cause incorrect behavior and will be lost if | |||||
// the code is regenerated. | |||||
// </auto-generated> | |||||
//------------------------------------------------------------------------------ | |||||
namespace eShopOnContainers.Catalog.WebForms | |||||
{ | |||||
public partial class About | |||||
{ | |||||
} | |||||
} |
@ -0,0 +1,28 @@ | |||||
<%@ Page Title="Phone Number" Language="C#" MasterPageFile="~/Site.Master" AutoEventWireup="true" CodeBehind="AddPhoneNumber.aspx.cs" Inherits="eShopOnContainers.Catalog.WebForms.Account.AddPhoneNumber" %> | |||||
<asp:Content ID="BodyContent" ContentPlaceHolderID="MainContent" runat="server"> | |||||
<h2><%: Title %>.</h2> | |||||
<div class="form-horizontal"> | |||||
<h4>Add a phone number</h4> | |||||
<hr /> | |||||
<asp:ValidationSummary runat="server" CssClass="text-danger" /> | |||||
<p class="text-danger"> | |||||
<asp:Literal runat="server" ID="ErrorMessage" /> | |||||
</p> | |||||
<div class="form-group"> | |||||
<asp:Label runat="server" AssociatedControlID="PhoneNumber" CssClass="col-md-2 control-label">Phone Number</asp:Label> | |||||
<div class="col-md-10"> | |||||
<asp:TextBox runat="server" ID="PhoneNumber" CssClass="form-control" TextMode="Phone" /> | |||||
<asp:RequiredFieldValidator runat="server" ControlToValidate="PhoneNumber" | |||||
CssClass="text-danger" ErrorMessage="The PhoneNumber field is required." /> | |||||
</div> | |||||
</div> | |||||
<div class="form-group"> | |||||
<div class="col-md-offset-2 col-md-10"> | |||||
<asp:Button runat="server" OnClick="PhoneNumber_Click" | |||||
Text="Submit" CssClass="btn btn-default" /> | |||||
</div> | |||||
</div> | |||||
</div> | |||||
</asp:Content> |
@ -0,0 +1,34 @@ | |||||
using System; | |||||
using System.Collections.Generic; | |||||
using System.Linq; | |||||
using System.Web; | |||||
using System.Web.UI; | |||||
using System.Web.UI.WebControls; | |||||
using Microsoft.AspNet.Identity; | |||||
using Microsoft.AspNet.Identity.Owin; | |||||
using System.Threading.Tasks; | |||||
using eShopOnContainers.Catalog.WebForms.Models; | |||||
namespace eShopOnContainers.Catalog.WebForms.Account | |||||
{ | |||||
public partial class AddPhoneNumber : System.Web.UI.Page | |||||
{ | |||||
protected void PhoneNumber_Click(object sender, EventArgs e) | |||||
{ | |||||
var manager = Context.GetOwinContext().GetUserManager<ApplicationUserManager>(); | |||||
var code = manager.GenerateChangePhoneNumberToken(User.Identity.GetUserId(), PhoneNumber.Text); | |||||
if (manager.SmsService != null) | |||||
{ | |||||
var message = new IdentityMessage | |||||
{ | |||||
Destination = PhoneNumber.Text, | |||||
Body = "Your security code is " + code | |||||
}; | |||||
manager.SmsService.Send(message); | |||||
} | |||||
Response.Redirect("/Account/VerifyPhoneNumber?PhoneNumber=" + HttpUtility.UrlEncode(PhoneNumber.Text)); | |||||
} | |||||
} | |||||
} |
@ -0,0 +1,33 @@ | |||||
//------------------------------------------------------------------------------ | |||||
// <auto-generated> | |||||
// This code was generated by a tool. | |||||
// | |||||
// Changes to this file may cause incorrect behavior and will be lost if | |||||
// the code is regenerated. | |||||
// </auto-generated> | |||||
//------------------------------------------------------------------------------ | |||||
namespace eShopOnContainers.Catalog.WebForms.Account { | |||||
public partial class AddPhoneNumber { | |||||
/// <summary> | |||||
/// ErrorMessage 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.Literal ErrorMessage; | |||||
/// <summary> | |||||
/// PhoneNumber 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.TextBox PhoneNumber; | |||||
} | |||||
} |
@ -0,0 +1,18 @@ | |||||
<%@ Page Title="Account Confirmation" Language="C#" MasterPageFile="~/Site.Master" AutoEventWireup="true" CodeBehind="Confirm.aspx.cs" Inherits="eShopOnContainers.Catalog.WebForms.Account.Confirm" Async="true" %> | |||||
<asp:Content runat="server" ID="BodyContent" ContentPlaceHolderID="MainContent"> | |||||
<h2><%: Title %>.</h2> | |||||
<div> | |||||
<asp:PlaceHolder runat="server" ID="successPanel" ViewStateMode="Disabled" Visible="true"> | |||||
<p> | |||||
Thank you for confirming your account. Click <asp:HyperLink ID="login" runat="server" NavigateUrl="~/Account/Login">here</asp:HyperLink> to login | |||||
</p> | |||||
</asp:PlaceHolder> | |||||
<asp:PlaceHolder runat="server" ID="errorPanel" ViewStateMode="Disabled" Visible="false"> | |||||
<p class="text-danger"> | |||||
An error has occurred. | |||||
</p> | |||||
</asp:PlaceHolder> | |||||
</div> | |||||
</asp:Content> |
@ -0,0 +1,37 @@ | |||||
using System; | |||||
using System.Web; | |||||
using System.Web.UI; | |||||
using Microsoft.AspNet.Identity; | |||||
using Microsoft.AspNet.Identity.Owin; | |||||
using Owin; | |||||
using eShopOnContainers.Catalog.WebForms.Models; | |||||
namespace eShopOnContainers.Catalog.WebForms.Account | |||||
{ | |||||
public partial class Confirm : Page | |||||
{ | |||||
protected string StatusMessage | |||||
{ | |||||
get; | |||||
private set; | |||||
} | |||||
protected void Page_Load(object sender, EventArgs e) | |||||
{ | |||||
string code = IdentityHelper.GetCodeFromRequest(Request); | |||||
string userId = IdentityHelper.GetUserIdFromRequest(Request); | |||||
if (code != null && userId != null) | |||||
{ | |||||
var manager = Context.GetOwinContext().GetUserManager<ApplicationUserManager>(); | |||||
var result = manager.ConfirmEmail(userId, code); | |||||
if (result.Succeeded) | |||||
{ | |||||
successPanel.Visible = true; | |||||
return; | |||||
} | |||||
} | |||||
successPanel.Visible = false; | |||||
errorPanel.Visible = true; | |||||
} | |||||
} | |||||
} |
@ -0,0 +1,43 @@ | |||||
//------------------------------------------------------------------------------ | |||||
// <auto-generated> | |||||
// This code was generated by a tool. | |||||
// | |||||
// Changes to this file may cause incorrect behavior and will be lost if | |||||
// the code is regenerated. | |||||
// </auto-generated> | |||||
//------------------------------------------------------------------------------ | |||||
namespace eShopOnContainers.Catalog.WebForms.Account { | |||||
public partial class Confirm { | |||||
/// <summary> | |||||
/// successPanel 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.PlaceHolder successPanel; | |||||
/// <summary> | |||||
/// login 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.HyperLink login; | |||||
/// <summary> | |||||
/// errorPanel 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.PlaceHolder errorPanel; | |||||
} | |||||
} |
@ -0,0 +1,39 @@ | |||||
<%@ Page Title="Forgot password" Language="C#" MasterPageFile="~/Site.Master" AutoEventWireup="true" CodeBehind="Forgot.aspx.cs" Inherits="eShopOnContainers.Catalog.WebForms.Account.ForgotPassword" Async="true" %> | |||||
<asp:Content runat="server" ID="BodyContent" ContentPlaceHolderID="MainContent"> | |||||
<h2><%: Title %>.</h2> | |||||
<div class="row"> | |||||
<div class="col-md-8"> | |||||
<asp:PlaceHolder id="loginForm" runat="server"> | |||||
<div class="form-horizontal"> | |||||
<h4>Forgot your password?</h4> | |||||
<hr /> | |||||
<asp:PlaceHolder runat="server" ID="ErrorMessage" Visible="false"> | |||||
<p class="text-danger"> | |||||
<asp:Literal runat="server" ID="FailureText" /> | |||||
</p> | |||||
</asp:PlaceHolder> | |||||
<div class="form-group"> | |||||
<asp:Label runat="server" AssociatedControlID="Email" CssClass="col-md-2 control-label">Email</asp:Label> | |||||
<div class="col-md-10"> | |||||
<asp:TextBox runat="server" ID="Email" CssClass="form-control" TextMode="Email" /> | |||||
<asp:RequiredFieldValidator runat="server" ControlToValidate="Email" | |||||
CssClass="text-danger" ErrorMessage="The email field is required." /> | |||||
</div> | |||||
</div> | |||||
<div class="form-group"> | |||||
<div class="col-md-offset-2 col-md-10"> | |||||
<asp:Button runat="server" OnClick="Forgot" Text="Email Link" CssClass="btn btn-default" /> | |||||
</div> | |||||
</div> | |||||
</div> | |||||
</asp:PlaceHolder> | |||||
<asp:PlaceHolder runat="server" ID="DisplayEmail" Visible="false"> | |||||
<p class="text-info"> | |||||
Please check your email to reset your password. | |||||
</p> | |||||
</asp:PlaceHolder> | |||||
</div> | |||||
</div> | |||||
</asp:Content> |
@ -0,0 +1,40 @@ | |||||
using System; | |||||
using System.Web; | |||||
using System.Web.UI; | |||||
using Microsoft.AspNet.Identity; | |||||
using Microsoft.AspNet.Identity.Owin; | |||||
using Owin; | |||||
using eShopOnContainers.Catalog.WebForms.Models; | |||||
namespace eShopOnContainers.Catalog.WebForms.Account | |||||
{ | |||||
public partial class ForgotPassword : Page | |||||
{ | |||||
protected void Page_Load(object sender, EventArgs e) | |||||
{ | |||||
} | |||||
protected void Forgot(object sender, EventArgs e) | |||||
{ | |||||
if (IsValid) | |||||
{ | |||||
// Validate the user's email address | |||||
var manager = Context.GetOwinContext().GetUserManager<ApplicationUserManager>(); | |||||
ApplicationUser user = manager.FindByName(Email.Text); | |||||
if (user == null || !manager.IsEmailConfirmed(user.Id)) | |||||
{ | |||||
FailureText.Text = "The user either does not exist or is not confirmed."; | |||||
ErrorMessage.Visible = true; | |||||
return; | |||||
} | |||||
// For more information on how to enable account confirmation and password reset please visit https://go.microsoft.com/fwlink/?LinkID=320771 | |||||
// Send email with the code and the redirect to reset password page | |||||
//string code = manager.GeneratePasswordResetToken(user.Id); | |||||
//string callbackUrl = IdentityHelper.GetResetPasswordRedirectUrl(code, Request); | |||||
//manager.SendEmail(user.Id, "Reset Password", "Please reset your password by clicking <a href=\"" + callbackUrl + "\">here</a>."); | |||||
loginForm.Visible = false; | |||||
DisplayEmail.Visible = true; | |||||
} | |||||
} | |||||
} | |||||
} |
@ -0,0 +1,60 @@ | |||||
//------------------------------------------------------------------------------ | |||||
// <auto-generated> | |||||
// This code was generated by a tool. | |||||
// | |||||
// Changes to this file may cause incorrect behavior and will be lost if | |||||
// the code is regenerated. | |||||
// </auto-generated> | |||||
//------------------------------------------------------------------------------ | |||||
namespace eShopOnContainers.Catalog.WebForms.Account { | |||||
public partial class ForgotPassword { | |||||
/// <summary> | |||||
/// loginForm 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.PlaceHolder loginForm; | |||||
/// <summary> | |||||
/// ErrorMessage 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.PlaceHolder ErrorMessage; | |||||
/// <summary> | |||||
/// FailureText 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.Literal FailureText; | |||||
/// <summary> | |||||
/// Email 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.TextBox Email; | |||||
/// <summary> | |||||
/// DisplayEmail 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.PlaceHolder DisplayEmail; | |||||
} | |||||
} |
@ -0,0 +1,8 @@ | |||||
<%@ Page Title="" Language="C#" MasterPageFile="~/Site.Master" AutoEventWireup="true" CodeBehind="Lockout.aspx.cs" Inherits="eShopOnContainers.Catalog.WebForms.Account.Lockout" %> | |||||
<asp:Content ID="BodyContent" ContentPlaceHolderID="MainContent" runat="server"> | |||||
<hgroup> | |||||
<h1>Locked out.</h1> | |||||
<h2 class="text-danger">This account has been locked out, please try again later.</h2> | |||||
</hgroup> | |||||
</asp:Content> |
@ -0,0 +1,17 @@ | |||||
using System; | |||||
using System.Collections.Generic; | |||||
using System.Linq; | |||||
using System.Web; | |||||
using System.Web.UI; | |||||
using System.Web.UI.WebControls; | |||||
namespace eShopOnContainers.Catalog.WebForms.Account | |||||
{ | |||||
public partial class Lockout : System.Web.UI.Page | |||||
{ | |||||
protected void Page_Load(object sender, EventArgs e) | |||||
{ | |||||
} | |||||
} | |||||
} |
@ -0,0 +1,17 @@ | |||||
//------------------------------------------------------------------------------ | |||||
// <auto-generated> | |||||
// This code was generated by a tool. | |||||
// | |||||
// Changes to this file may cause incorrect behavior and will be lost if | |||||
// the code is regenerated. | |||||
// </auto-generated> | |||||
//------------------------------------------------------------------------------ | |||||
namespace eShopOnContainers.Catalog.WebForms.Account | |||||
{ | |||||
public partial class Lockout | |||||
{ | |||||
} | |||||
} |
@ -0,0 +1,65 @@ | |||||
<%@ Page Title="Log in" Language="C#" MasterPageFile="~/Site.Master" AutoEventWireup="true" CodeBehind="Login.aspx.cs" Inherits="eShopOnContainers.Catalog.WebForms.Account.Login" Async="true" %> | |||||
<%@ Register Src="~/Account/OpenAuthProviders.ascx" TagPrefix="uc" TagName="OpenAuthProviders" %> | |||||
<asp:Content runat="server" ID="BodyContent" ContentPlaceHolderID="MainContent"> | |||||
<h2><%: Title %>.</h2> | |||||
<div class="row"> | |||||
<div class="col-md-8"> | |||||
<section id="loginForm"> | |||||
<div class="form-horizontal"> | |||||
<h4>Use a local account to log in.</h4> | |||||
<hr /> | |||||
<asp:PlaceHolder runat="server" ID="ErrorMessage" Visible="false"> | |||||
<p class="text-danger"> | |||||
<asp:Literal runat="server" ID="FailureText" /> | |||||
</p> | |||||
</asp:PlaceHolder> | |||||
<div class="form-group"> | |||||
<asp:Label runat="server" AssociatedControlID="Email" CssClass="col-md-2 control-label">Email</asp:Label> | |||||
<div class="col-md-10"> | |||||
<asp:TextBox runat="server" ID="Email" CssClass="form-control" TextMode="Email" /> | |||||
<asp:RequiredFieldValidator runat="server" ControlToValidate="Email" | |||||
CssClass="text-danger" ErrorMessage="The email field is required." /> | |||||
</div> | |||||
</div> | |||||
<div class="form-group"> | |||||
<asp:Label runat="server" AssociatedControlID="Password" CssClass="col-md-2 control-label">Password</asp:Label> | |||||
<div class="col-md-10"> | |||||
<asp:TextBox runat="server" ID="Password" TextMode="Password" CssClass="form-control" /> | |||||
<asp:RequiredFieldValidator runat="server" ControlToValidate="Password" CssClass="text-danger" ErrorMessage="The password field is required." /> | |||||
</div> | |||||
</div> | |||||
<div class="form-group"> | |||||
<div class="col-md-offset-2 col-md-10"> | |||||
<div class="checkbox"> | |||||
<asp:CheckBox runat="server" ID="RememberMe" /> | |||||
<asp:Label runat="server" AssociatedControlID="RememberMe">Remember me?</asp:Label> | |||||
</div> | |||||
</div> | |||||
</div> | |||||
<div class="form-group"> | |||||
<div class="col-md-offset-2 col-md-10"> | |||||
<asp:Button runat="server" OnClick="LogIn" Text="Log in" CssClass="btn btn-default" /> | |||||
</div> | |||||
</div> | |||||
</div> | |||||
<p> | |||||
<asp:HyperLink runat="server" ID="RegisterHyperLink" ViewStateMode="Disabled">Register as a new user</asp:HyperLink> | |||||
</p> | |||||
<p> | |||||
<%-- Enable this once you have account confirmation enabled for password reset functionality | |||||
<asp:HyperLink runat="server" ID="ForgotPasswordHyperLink" ViewStateMode="Disabled">Forgot your password?</asp:HyperLink> | |||||
--%> | |||||
</p> | |||||
</section> | |||||
</div> | |||||
<div class="col-md-4"> | |||||
<section id="socialLoginForm"> | |||||
<uc:OpenAuthProviders runat="server" ID="OpenAuthLogin" /> | |||||
</section> | |||||
</div> | |||||
</div> | |||||
</asp:Content> |
@ -0,0 +1,61 @@ | |||||
using System; | |||||
using System.Web; | |||||
using System.Web.UI; | |||||
using Microsoft.AspNet.Identity; | |||||
using Microsoft.AspNet.Identity.Owin; | |||||
using Owin; | |||||
using eShopOnContainers.Catalog.WebForms.Models; | |||||
namespace eShopOnContainers.Catalog.WebForms.Account | |||||
{ | |||||
public partial class Login : Page | |||||
{ | |||||
protected void Page_Load(object sender, EventArgs e) | |||||
{ | |||||
RegisterHyperLink.NavigateUrl = "Register"; | |||||
// Enable this once you have account confirmation enabled for password reset functionality | |||||
//ForgotPasswordHyperLink.NavigateUrl = "Forgot"; | |||||
OpenAuthLogin.ReturnUrl = Request.QueryString["ReturnUrl"]; | |||||
var returnUrl = HttpUtility.UrlEncode(Request.QueryString["ReturnUrl"]); | |||||
if (!String.IsNullOrEmpty(returnUrl)) | |||||
{ | |||||
RegisterHyperLink.NavigateUrl += "?ReturnUrl=" + returnUrl; | |||||
} | |||||
} | |||||
protected void LogIn(object sender, EventArgs e) | |||||
{ | |||||
if (IsValid) | |||||
{ | |||||
// Validate the user password | |||||
var manager = Context.GetOwinContext().GetUserManager<ApplicationUserManager>(); | |||||
var signinManager = Context.GetOwinContext().GetUserManager<ApplicationSignInManager>(); | |||||
// This doen't count login failures towards account lockout | |||||
// To enable password failures to trigger lockout, change to shouldLockout: true | |||||
var result = signinManager.PasswordSignIn(Email.Text, Password.Text, RememberMe.Checked, shouldLockout: false); | |||||
switch (result) | |||||
{ | |||||
case SignInStatus.Success: | |||||
IdentityHelper.RedirectToReturnUrl(Request.QueryString["ReturnUrl"], Response); | |||||
break; | |||||
case SignInStatus.LockedOut: | |||||
Response.Redirect("/Account/Lockout"); | |||||
break; | |||||
case SignInStatus.RequiresVerification: | |||||
Response.Redirect(String.Format("/Account/TwoFactorAuthenticationSignIn?ReturnUrl={0}&RememberMe={1}", | |||||
Request.QueryString["ReturnUrl"], | |||||
RememberMe.Checked), | |||||
true); | |||||
break; | |||||
case SignInStatus.Failure: | |||||
default: | |||||
FailureText.Text = "Invalid login attempt"; | |||||
ErrorMessage.Visible = true; | |||||
break; | |||||
} | |||||
} | |||||
} | |||||
} | |||||
} |
@ -0,0 +1,78 @@ | |||||
//------------------------------------------------------------------------------ | |||||
// <auto-generated> | |||||
// This code was generated by a tool. | |||||
// | |||||
// Changes to this file may cause incorrect behavior and will be lost if | |||||
// the code is regenerated. | |||||
// </auto-generated> | |||||
//------------------------------------------------------------------------------ | |||||
namespace eShopOnContainers.Catalog.WebForms.Account { | |||||
public partial class Login { | |||||
/// <summary> | |||||
/// ErrorMessage 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.PlaceHolder ErrorMessage; | |||||
/// <summary> | |||||
/// FailureText 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.Literal FailureText; | |||||
/// <summary> | |||||
/// Email 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.TextBox Email; | |||||
/// <summary> | |||||
/// Password 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.TextBox Password; | |||||
/// <summary> | |||||
/// RememberMe control. | |||||
/// </summary> | |||||
/// <remarks> | |||||
/// Auto-generated field. | |||||
/// To modify move field declaration from designer file to code-behind file. | |||||
/// </remarks> | |||||
protected global::System.Web.UI.WebControls.CheckBox RememberMe; | |||||
/// <summary> | |||||
/// RegisterHyperLink 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.HyperLink RegisterHyperLink; | |||||
/// <summary> | |||||
/// OpenAuthLogin control. | |||||
/// </summary> | |||||
/// <remarks> | |||||
/// Auto-generated field. | |||||
/// To modify move field declaration from designer file to code-behind file. | |||||
/// </remarks> | |||||
protected global::eShopOnContainers.Catalog.WebForms.Account.OpenAuthProviders OpenAuthLogin; | |||||
} | |||||
} |
@ -0,0 +1,80 @@ | |||||
<%@ Page Title="Manage Account" Language="C#" MasterPageFile="~/Site.Master" AutoEventWireup="true" CodeBehind="Manage.aspx.cs" Inherits="eShopOnContainers.Catalog.WebForms.Account.Manage" %> | |||||
<%@ Register Src="~/Account/OpenAuthProviders.ascx" TagPrefix="uc" TagName="OpenAuthProviders" %> | |||||
<asp:Content ContentPlaceHolderID="MainContent" runat="server"> | |||||
<h2><%: Title %>.</h2> | |||||
<div> | |||||
<asp:PlaceHolder runat="server" ID="successMessage" Visible="false" ViewStateMode="Disabled"> | |||||
<p class="text-success"><%: SuccessMessage %></p> | |||||
</asp:PlaceHolder> | |||||
</div> | |||||
<div class="row"> | |||||
<div class="col-md-12"> | |||||
<div class="form-horizontal"> | |||||
<h4>Change your account settings</h4> | |||||
<hr /> | |||||
<dl class="dl-horizontal"> | |||||
<dt>Password:</dt> | |||||
<dd> | |||||
<asp:HyperLink NavigateUrl="/Account/ManagePassword" Text="[Change]" Visible="false" ID="ChangePassword" runat="server" /> | |||||
<asp:HyperLink NavigateUrl="/Account/ManagePassword" Text="[Create]" Visible="false" ID="CreatePassword" runat="server" /> | |||||
</dd> | |||||
<dt>External Logins:</dt> | |||||
<dd><%: LoginsCount %> | |||||
<asp:HyperLink NavigateUrl="/Account/ManageLogins" Text="[Manage]" runat="server" /> | |||||
</dd> | |||||
<%-- | |||||
Phone Numbers can used as a second factor of verification in a two-factor authentication system. | |||||
See <a href="https://go.microsoft.com/fwlink/?LinkId=403804">this article</a> | |||||
for details on setting up this ASP.NET application to support two-factor authentication using SMS. | |||||
Uncomment the following blocks after you have set up two-factor authentication | |||||
--%> | |||||
<%-- | |||||
<dt>Phone Number:</dt> | |||||
<% if (HasPhoneNumber) | |||||
{ %> | |||||
<dd> | |||||
<asp:HyperLink NavigateUrl="/Account/AddPhoneNumber" runat="server" Text="[Add]" /> | |||||
</dd> | |||||
<% } | |||||
else | |||||
{ %> | |||||
<dd> | |||||
<asp:Label Text="" ID="PhoneNumber" runat="server" /> | |||||
<asp:HyperLink NavigateUrl="/Account/AddPhoneNumber" runat="server" Text="[Change]" /> | | |||||
<asp:LinkButton Text="[Remove]" OnClick="RemovePhone_Click" runat="server" /> | |||||
</dd> | |||||
<% } %> | |||||
--%> | |||||
<dt>Two-Factor Authentication:</dt> | |||||
<dd> | |||||
<p> | |||||
There are no two-factor authentication providers configured. See <a href="https://go.microsoft.com/fwlink/?LinkId=403804">this article</a> | |||||
for details on setting up this ASP.NET application to support two-factor authentication. | |||||
</p> | |||||
<% if (TwoFactorEnabled) | |||||
{ %> | |||||
<%-- | |||||
Enabled | |||||
<asp:LinkButton Text="[Disable]" runat="server" CommandArgument="false" OnClick="TwoFactorDisable_Click" /> | |||||
--%> | |||||
<% } | |||||
else | |||||
{ %> | |||||
<%-- | |||||
Disabled | |||||
<asp:LinkButton Text="[Enable]" CommandArgument="true" OnClick="TwoFactorEnable_Click" runat="server" /> | |||||
--%> | |||||
<% } %> | |||||
</dd> | |||||
</dl> | |||||
</div> | |||||
</div> | |||||
</div> | |||||
</asp:Content> |
@ -0,0 +1,128 @@ | |||||
using System; | |||||
using System.Collections.Generic; | |||||
using System.Linq; | |||||
using System.Threading.Tasks; | |||||
using System.Web; | |||||
using Microsoft.AspNet.Identity; | |||||
using Microsoft.AspNet.Identity.EntityFramework; | |||||
using Microsoft.AspNet.Identity.Owin; | |||||
using Microsoft.Owin.Security; | |||||
using Owin; | |||||
using eShopOnContainers.Catalog.WebForms.Models; | |||||
namespace eShopOnContainers.Catalog.WebForms.Account | |||||
{ | |||||
public partial class Manage : System.Web.UI.Page | |||||
{ | |||||
protected string SuccessMessage | |||||
{ | |||||
get; | |||||
private set; | |||||
} | |||||
private bool HasPassword(ApplicationUserManager manager) | |||||
{ | |||||
return manager.HasPassword(User.Identity.GetUserId()); | |||||
} | |||||
public bool HasPhoneNumber { get; private set; } | |||||
public bool TwoFactorEnabled { get; private set; } | |||||
public bool TwoFactorBrowserRemembered { get; private set; } | |||||
public int LoginsCount { get; set; } | |||||
protected void Page_Load() | |||||
{ | |||||
var manager = Context.GetOwinContext().GetUserManager<ApplicationUserManager>(); | |||||
HasPhoneNumber = String.IsNullOrEmpty(manager.GetPhoneNumber(User.Identity.GetUserId())); | |||||
// Enable this after setting up two-factor authentientication | |||||
//PhoneNumber.Text = manager.GetPhoneNumber(User.Identity.GetUserId()) ?? String.Empty; | |||||
TwoFactorEnabled = manager.GetTwoFactorEnabled(User.Identity.GetUserId()); | |||||
LoginsCount = manager.GetLogins(User.Identity.GetUserId()).Count; | |||||
var authenticationManager = HttpContext.Current.GetOwinContext().Authentication; | |||||
if (!IsPostBack) | |||||
{ | |||||
// Determine the sections to render | |||||
if (HasPassword(manager)) | |||||
{ | |||||
ChangePassword.Visible = true; | |||||
} | |||||
else | |||||
{ | |||||
CreatePassword.Visible = true; | |||||
ChangePassword.Visible = false; | |||||
} | |||||
// Render success message | |||||
var message = Request.QueryString["m"]; | |||||
if (message != null) | |||||
{ | |||||
// Strip the query string from action | |||||
Form.Action = ResolveUrl("~/Account/Manage"); | |||||
SuccessMessage = | |||||
message == "ChangePwdSuccess" ? "Your password has been changed." | |||||
: message == "SetPwdSuccess" ? "Your password has been set." | |||||
: message == "RemoveLoginSuccess" ? "The account was removed." | |||||
: message == "AddPhoneNumberSuccess" ? "Phone number has been added" | |||||
: message == "RemovePhoneNumberSuccess" ? "Phone number was removed" | |||||
: String.Empty; | |||||
successMessage.Visible = !String.IsNullOrEmpty(SuccessMessage); | |||||
} | |||||
} | |||||
} | |||||
private void AddErrors(IdentityResult result) | |||||
{ | |||||
foreach (var error in result.Errors) | |||||
{ | |||||
ModelState.AddModelError("", error); | |||||
} | |||||
} | |||||
// Remove phonenumber from user | |||||
protected void RemovePhone_Click(object sender, EventArgs e) | |||||
{ | |||||
var manager = Context.GetOwinContext().GetUserManager<ApplicationUserManager>(); | |||||
var signInManager = Context.GetOwinContext().Get<ApplicationSignInManager>(); | |||||
var result = manager.SetPhoneNumber(User.Identity.GetUserId(), null); | |||||
if (!result.Succeeded) | |||||
{ | |||||
return; | |||||
} | |||||
var user = manager.FindById(User.Identity.GetUserId()); | |||||
if (user != null) | |||||
{ | |||||
signInManager.SignIn(user, isPersistent: false, rememberBrowser: false); | |||||
Response.Redirect("/Account/Manage?m=RemovePhoneNumberSuccess"); | |||||
} | |||||
} | |||||
// DisableTwoFactorAuthentication | |||||
protected void TwoFactorDisable_Click(object sender, EventArgs e) | |||||
{ | |||||
var manager = Context.GetOwinContext().GetUserManager<ApplicationUserManager>(); | |||||
manager.SetTwoFactorEnabled(User.Identity.GetUserId(), false); | |||||
Response.Redirect("/Account/Manage"); | |||||
} | |||||
//EnableTwoFactorAuthentication | |||||
protected void TwoFactorEnable_Click(object sender, EventArgs e) | |||||
{ | |||||
var manager = Context.GetOwinContext().GetUserManager<ApplicationUserManager>(); | |||||
manager.SetTwoFactorEnabled(User.Identity.GetUserId(), true); | |||||
Response.Redirect("/Account/Manage"); | |||||
} | |||||
} | |||||
} |
@ -0,0 +1,42 @@ | |||||
//------------------------------------------------------------------------------ | |||||
// <auto-generated> | |||||
// This code was generated by a tool. | |||||
// | |||||
// Changes to this file may cause incorrect behavior and will be lost if | |||||
// the code is regenerated. | |||||
// </auto-generated> | |||||
//------------------------------------------------------------------------------ | |||||
namespace eShopOnContainers.Catalog.WebForms.Account { | |||||
public partial class Manage { | |||||
/// <summary> | |||||
/// successMessage 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.PlaceHolder successMessage; | |||||
/// <summary> | |||||
/// ChangePassword 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.HyperLink ChangePassword; | |||||
/// <summary> | |||||
/// CreatePassword 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.HyperLink CreatePassword; | |||||
} | |||||
} |
@ -0,0 +1,42 @@ | |||||
<%@ Page Title="" Language="C#" MasterPageFile="~/Site.Master" AutoEventWireup="true" CodeBehind="ManageLogins.aspx.cs" Inherits="eShopOnContainers.Catalog.WebForms.Account.ManageLogins" %> | |||||
<%@ Register Src="~/Account/OpenAuthProviders.ascx" TagPrefix="uc" TagName="OpenAuthProviders" %> | |||||
<asp:Content ID="BodyContent" ContentPlaceHolderID="MainContent" runat="server"> | |||||
<h2>Manage your external logins.</h2> | |||||
<asp:PlaceHolder runat="server" ID="successMessage" Visible="false" ViewStateMode="Disabled"> | |||||
<p class="text-success"><%: SuccessMessage %></p> | |||||
</asp:PlaceHolder> | |||||
<div> | |||||
<section id="externalLoginsForm"> | |||||
<asp:ListView runat="server" | |||||
ItemType="Microsoft.AspNet.Identity.UserLoginInfo" | |||||
SelectMethod="GetLogins" DeleteMethod="RemoveLogin" DataKeyNames="LoginProvider,ProviderKey"> | |||||
<LayoutTemplate> | |||||
<h4>Registered Logins</h4> | |||||
<table class="table"> | |||||
<tbody> | |||||
<tr runat="server" id="itemPlaceholder"></tr> | |||||
</tbody> | |||||
</table> | |||||
</LayoutTemplate> | |||||
<ItemTemplate> | |||||
<tr> | |||||
<td><%#: Item.LoginProvider %></td> | |||||
<td> | |||||
<asp:Button runat="server" Text="Remove" CommandName="Delete" CausesValidation="false" | |||||
ToolTip='<%# "Remove this " + Item.LoginProvider + " login from your account" %>' | |||||
Visible="<%# CanRemoveExternalLogins %>" CssClass="btn btn-default" /> | |||||
</td> | |||||
</tr> | |||||
</ItemTemplate> | |||||
</asp:ListView> | |||||
</section> | |||||
</div> | |||||
<div> | |||||
<uc:OpenAuthProviders runat="server" ReturnUrl="~/Account/ManageLogins" /> | |||||
</div> | |||||
</asp:Content> |
@ -0,0 +1,62 @@ | |||||
using System; | |||||
using System.Collections.Generic; | |||||
using System.Linq; | |||||
using System.Web; | |||||
using System.Web.UI; | |||||
using System.Web.UI.WebControls; | |||||
using Microsoft.AspNet.Identity; | |||||
using Microsoft.AspNet.Identity.Owin; | |||||
namespace eShopOnContainers.Catalog.WebForms.Account | |||||
{ | |||||
public partial class ManageLogins : System.Web.UI.Page | |||||
{ | |||||
protected string SuccessMessage | |||||
{ | |||||
get; | |||||
private set; | |||||
} | |||||
protected bool CanRemoveExternalLogins | |||||
{ | |||||
get; | |||||
private set; | |||||
} | |||||
private bool HasPassword(ApplicationUserManager manager) | |||||
{ | |||||
return manager.HasPassword(User.Identity.GetUserId()); | |||||
} | |||||
protected void Page_Load(object sender, EventArgs e) | |||||
{ | |||||
var manager = Context.GetOwinContext().GetUserManager<ApplicationUserManager>(); | |||||
CanRemoveExternalLogins = manager.GetLogins(User.Identity.GetUserId()).Count() > 1; | |||||
SuccessMessage = String.Empty; | |||||
successMessage.Visible = !String.IsNullOrEmpty(SuccessMessage); | |||||
} | |||||
public IEnumerable<UserLoginInfo> GetLogins() | |||||
{ | |||||
var manager = Context.GetOwinContext().GetUserManager<ApplicationUserManager>(); | |||||
var accounts = manager.GetLogins(User.Identity.GetUserId()); | |||||
CanRemoveExternalLogins = accounts.Count() > 1 || HasPassword(manager); | |||||
return accounts; | |||||
} | |||||
public void RemoveLogin(string loginProvider, string providerKey) | |||||
{ | |||||
var manager = Context.GetOwinContext().GetUserManager<ApplicationUserManager>(); | |||||
var signInManager = Context.GetOwinContext().Get<ApplicationSignInManager>(); | |||||
var result = manager.RemoveLogin(User.Identity.GetUserId(), new UserLoginInfo(loginProvider, providerKey)); | |||||
string msg = String.Empty; | |||||
if (result.Succeeded) | |||||
{ | |||||
var user = manager.FindById(User.Identity.GetUserId()); | |||||
signInManager.SignIn(user, isPersistent: false, rememberBrowser: false); | |||||
msg = "?m=RemoveLoginSuccess"; | |||||
} | |||||
Response.Redirect("~/Account/ManageLogins" + msg); | |||||
} | |||||
} | |||||
} |
@ -0,0 +1,24 @@ | |||||
//------------------------------------------------------------------------------ | |||||
// <auto-generated> | |||||
// This code was generated by a tool. | |||||
// | |||||
// Changes to this file may cause incorrect behavior and will be lost if | |||||
// the code is regenerated. | |||||
// </auto-generated> | |||||
//------------------------------------------------------------------------------ | |||||
namespace eShopOnContainers.Catalog.WebForms.Account { | |||||
public partial class ManageLogins { | |||||
/// <summary> | |||||
/// successMessage 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.PlaceHolder successMessage; | |||||
} | |||||
} |
@ -0,0 +1,93 @@ | |||||
<%@ Page Title="Manage Password" Language="C#" MasterPageFile="~/Site.Master" AutoEventWireup="true" CodeBehind="ManagePassword.aspx.cs" Inherits="eShopOnContainers.Catalog.WebForms.Account.ManagePassword" %> | |||||
<asp:Content ID="BodyContent" ContentPlaceHolderID="MainContent" runat="server"> | |||||
<h2><%: Title %>.</h2> | |||||
<div class="form-horizontal"> | |||||
<section id="passwordForm"> | |||||
<asp:PlaceHolder runat="server" ID="setPassword" Visible="false"> | |||||
<p> | |||||
You do not have a local password for this site. Add a local | |||||
password so you can log in without an external login. | |||||
</p> | |||||
<div class="form-horizontal"> | |||||
<h4>Set Password Form</h4> | |||||
<asp:ValidationSummary runat="server" ShowModelStateErrors="true" CssClass="text-danger" /> | |||||
<hr /> | |||||
<div class="form-group"> | |||||
<asp:Label runat="server" AssociatedControlID="password" CssClass="col-md-2 control-label">Password</asp:Label> | |||||
<div class="col-md-10"> | |||||
<asp:TextBox runat="server" ID="password" TextMode="Password" CssClass="form-control" /> | |||||
<asp:RequiredFieldValidator runat="server" ControlToValidate="password" | |||||
CssClass="text-danger" ErrorMessage="The password field is required." | |||||
Display="Dynamic" ValidationGroup="SetPassword" /> | |||||
<asp:ModelErrorMessage runat="server" ModelStateKey="NewPassword" AssociatedControlID="password" | |||||
CssClass="text-danger" SetFocusOnError="true" /> | |||||
</div> | |||||
</div> | |||||
<div class="form-group"> | |||||
<asp:Label runat="server" AssociatedControlID="confirmPassword" CssClass="col-md-2 control-label">Confirm password</asp:Label> | |||||
<div class="col-md-10"> | |||||
<asp:TextBox runat="server" ID="confirmPassword" TextMode="Password" CssClass="form-control" /> | |||||
<asp:RequiredFieldValidator runat="server" ControlToValidate="confirmPassword" | |||||
CssClass="text-danger" Display="Dynamic" ErrorMessage="The confirm password field is required." | |||||
ValidationGroup="SetPassword" /> | |||||
<asp:CompareValidator runat="server" ControlToCompare="Password" ControlToValidate="confirmPassword" | |||||
CssClass="text-danger" Display="Dynamic" ErrorMessage="The password and confirmation password do not match." | |||||
ValidationGroup="SetPassword" /> | |||||
</div> | |||||
</div> | |||||
<div class="form-group"> | |||||
<div class="col-md-offset-2 col-md-10"> | |||||
<asp:Button runat="server" Text="Set Password" ValidationGroup="SetPassword" OnClick="SetPassword_Click" CssClass="btn btn-default" /> | |||||
</div> | |||||
</div> | |||||
</div> | |||||
</asp:PlaceHolder> | |||||
<asp:PlaceHolder runat="server" ID="changePasswordHolder" Visible="false"> | |||||
<div class="form-horizontal"> | |||||
<h4>Change Password Form</h4> | |||||
<hr /> | |||||
<asp:ValidationSummary runat="server" ShowModelStateErrors="true" CssClass="text-danger" /> | |||||
<div class="form-group"> | |||||
<asp:Label runat="server" ID="CurrentPasswordLabel" AssociatedControlID="CurrentPassword" CssClass="col-md-2 control-label">Current password</asp:Label> | |||||
<div class="col-md-10"> | |||||
<asp:TextBox runat="server" ID="CurrentPassword" TextMode="Password" CssClass="form-control" /> | |||||
<asp:RequiredFieldValidator runat="server" ControlToValidate="CurrentPassword" | |||||
CssClass="text-danger" ErrorMessage="The current password field is required." | |||||
ValidationGroup="ChangePassword" /> | |||||
</div> | |||||
</div> | |||||
<div class="form-group"> | |||||
<asp:Label runat="server" ID="NewPasswordLabel" AssociatedControlID="NewPassword" CssClass="col-md-2 control-label">New password</asp:Label> | |||||
<div class="col-md-10"> | |||||
<asp:TextBox runat="server" ID="NewPassword" TextMode="Password" CssClass="form-control" /> | |||||
<asp:RequiredFieldValidator runat="server" ControlToValidate="NewPassword" | |||||
CssClass="text-danger" ErrorMessage="The new password is required." | |||||
ValidationGroup="ChangePassword" /> | |||||
</div> | |||||
</div> | |||||
<div class="form-group"> | |||||
<asp:Label runat="server" ID="ConfirmNewPasswordLabel" AssociatedControlID="ConfirmNewPassword" CssClass="col-md-2 control-label">Confirm new password</asp:Label> | |||||
<div class="col-md-10"> | |||||
<asp:TextBox runat="server" ID="ConfirmNewPassword" TextMode="Password" CssClass="form-control" /> | |||||
<asp:RequiredFieldValidator runat="server" ControlToValidate="ConfirmNewPassword" | |||||
CssClass="text-danger" Display="Dynamic" ErrorMessage="Confirm new password is required." | |||||
ValidationGroup="ChangePassword" /> | |||||
<asp:CompareValidator runat="server" ControlToCompare="NewPassword" ControlToValidate="ConfirmNewPassword" | |||||
CssClass="text-danger" Display="Dynamic" ErrorMessage="The new password and confirmation password do not match." | |||||
ValidationGroup="ChangePassword" /> | |||||
</div> | |||||
</div> | |||||
<div class="form-group"> | |||||
<div class="col-md-offset-2 col-md-10"> | |||||
<asp:Button runat="server" Text="Change Password" ValidationGroup="ChangePassword" OnClick="ChangePassword_Click" CssClass="btn btn-default" /> | |||||
</div> | |||||
</div> | |||||
</div> | |||||
</asp:PlaceHolder> | |||||
</section> | |||||
</div> | |||||
</asp:Content> |
@ -0,0 +1,98 @@ | |||||
using System; | |||||
using System.Collections.Generic; | |||||
using System.Linq; | |||||
using System.Web; | |||||
using System.Web.UI; | |||||
using System.Web.UI.WebControls; | |||||
using Microsoft.AspNet.Identity; | |||||
using Microsoft.AspNet.Identity.Owin; | |||||
namespace eShopOnContainers.Catalog.WebForms.Account | |||||
{ | |||||
public partial class ManagePassword : System.Web.UI.Page | |||||
{ | |||||
protected string SuccessMessage | |||||
{ | |||||
get; | |||||
private set; | |||||
} | |||||
private bool HasPassword(ApplicationUserManager manager) | |||||
{ | |||||
return manager.HasPassword(User.Identity.GetUserId()); | |||||
} | |||||
protected void Page_Load(object sender, EventArgs e) | |||||
{ | |||||
var manager = Context.GetOwinContext().GetUserManager<ApplicationUserManager>(); | |||||
if (!IsPostBack) | |||||
{ | |||||
// Determine the sections to render | |||||
if (HasPassword(manager)) | |||||
{ | |||||
changePasswordHolder.Visible = true; | |||||
} | |||||
else | |||||
{ | |||||
setPassword.Visible = true; | |||||
changePasswordHolder.Visible = false; | |||||
} | |||||
// Render success message | |||||
var message = Request.QueryString["m"]; | |||||
if (message != null) | |||||
{ | |||||
// Strip the query string from action | |||||
Form.Action = ResolveUrl("~/Account/Manage"); | |||||
} | |||||
} | |||||
} | |||||
protected void ChangePassword_Click(object sender, EventArgs e) | |||||
{ | |||||
if (IsValid) | |||||
{ | |||||
var manager = Context.GetOwinContext().GetUserManager<ApplicationUserManager>(); | |||||
var signInManager = Context.GetOwinContext().Get<ApplicationSignInManager>(); | |||||
IdentityResult result = manager.ChangePassword(User.Identity.GetUserId(), CurrentPassword.Text, NewPassword.Text); | |||||
if (result.Succeeded) | |||||
{ | |||||
var user = manager.FindById(User.Identity.GetUserId()); | |||||
signInManager.SignIn( user, isPersistent: false, rememberBrowser: false); | |||||
Response.Redirect("~/Account/Manage?m=ChangePwdSuccess"); | |||||
} | |||||
else | |||||
{ | |||||
AddErrors(result); | |||||
} | |||||
} | |||||
} | |||||
protected void SetPassword_Click(object sender, EventArgs e) | |||||
{ | |||||
if (IsValid) | |||||
{ | |||||
// Create the local login info and link the local account to the user | |||||
var manager = Context.GetOwinContext().GetUserManager<ApplicationUserManager>(); | |||||
IdentityResult result = manager.AddPassword(User.Identity.GetUserId(), password.Text); | |||||
if (result.Succeeded) | |||||
{ | |||||
Response.Redirect("~/Account/Manage?m=SetPwdSuccess"); | |||||
} | |||||
else | |||||
{ | |||||
AddErrors(result); | |||||
} | |||||
} | |||||
} | |||||
private void AddErrors(IdentityResult result) | |||||
{ | |||||
foreach (var error in result.Errors) | |||||
{ | |||||
ModelState.AddModelError("", error); | |||||
} | |||||
} | |||||
} | |||||
} |
@ -0,0 +1,105 @@ | |||||
//------------------------------------------------------------------------------ | |||||
// <auto-generated> | |||||
// This code was generated by a tool. | |||||
// | |||||
// Changes to this file may cause incorrect behavior and will be lost if | |||||
// the code is regenerated. | |||||
// </auto-generated> | |||||
//------------------------------------------------------------------------------ | |||||
namespace eShopOnContainers.Catalog.WebForms.Account { | |||||
public partial class ManagePassword { | |||||
/// <summary> | |||||
/// setPassword 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.PlaceHolder setPassword; | |||||
/// <summary> | |||||
/// password 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.TextBox password; | |||||
/// <summary> | |||||
/// confirmPassword 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.TextBox confirmPassword; | |||||
/// <summary> | |||||
/// changePasswordHolder 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.PlaceHolder changePasswordHolder; | |||||
/// <summary> | |||||
/// CurrentPasswordLabel 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 CurrentPasswordLabel; | |||||
/// <summary> | |||||
/// CurrentPassword 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.TextBox CurrentPassword; | |||||
/// <summary> | |||||
/// NewPasswordLabel 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 NewPasswordLabel; | |||||
/// <summary> | |||||
/// NewPassword 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.TextBox NewPassword; | |||||
/// <summary> | |||||
/// ConfirmNewPasswordLabel 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 ConfirmNewPasswordLabel; | |||||
/// <summary> | |||||
/// ConfirmNewPassword 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.TextBox ConfirmNewPassword; | |||||
} | |||||
} |
@ -0,0 +1,22 @@ | |||||
<%@ Control Language="C#" AutoEventWireup="true" CodeBehind="OpenAuthProviders.ascx.cs" Inherits="eShopOnContainers.Catalog.WebForms.Account.OpenAuthProviders" %> | |||||
<div id="socialLoginList"> | |||||
<h4>Use another service to log in.</h4> | |||||
<hr /> | |||||
<asp:ListView runat="server" ID="providerDetails" ItemType="System.String" | |||||
SelectMethod="GetProviderNames" ViewStateMode="Disabled"> | |||||
<ItemTemplate> | |||||
<p> | |||||
<button type="submit" class="btn btn-default" name="provider" value="<%#: Item %>" | |||||
title="Log in using your <%#: Item %> account."> | |||||
<%#: Item %> | |||||
</button> | |||||
</p> | |||||
</ItemTemplate> | |||||
<EmptyDataTemplate> | |||||
<div> | |||||
<p>There are no external authentication services configured. See <a href="https://go.microsoft.com/fwlink/?LinkId=252803">this article</a> for details on setting up this ASP.NET application to support logging in via external services.</p> | |||||
</div> | |||||
</EmptyDataTemplate> | |||||
</asp:ListView> | |||||
</div> |
@ -0,0 +1,43 @@ | |||||
using System; | |||||
using System.Collections.Generic; | |||||
using System.Globalization; | |||||
using System.Linq; | |||||
using System.Web; | |||||
using Microsoft.AspNet.Identity; | |||||
using Microsoft.Owin.Security; | |||||
namespace eShopOnContainers.Catalog.WebForms.Account | |||||
{ | |||||
public partial class OpenAuthProviders : System.Web.UI.UserControl | |||||
{ | |||||
protected void Page_Load(object sender, EventArgs e) | |||||
{ | |||||
if (IsPostBack) | |||||
{ | |||||
var provider = Request.Form["provider"]; | |||||
if (provider == null) | |||||
{ | |||||
return; | |||||
} | |||||
// Request a redirect to the external login provider | |||||
string redirectUrl = ResolveUrl(String.Format(CultureInfo.InvariantCulture, "~/Account/RegisterExternalLogin?{0}={1}&returnUrl={2}", IdentityHelper.ProviderNameKey, provider, ReturnUrl)); | |||||
var properties = new AuthenticationProperties() { RedirectUri = redirectUrl }; | |||||
// Add xsrf verification when linking accounts | |||||
if (Context.User.Identity.IsAuthenticated) | |||||
{ | |||||
properties.Dictionary[IdentityHelper.XsrfKey] = Context.User.Identity.GetUserId(); | |||||
} | |||||
Context.GetOwinContext().Authentication.Challenge(properties, provider); | |||||
Response.StatusCode = 401; | |||||
Response.End(); | |||||
} | |||||
} | |||||
public string ReturnUrl { get; set; } | |||||
public IEnumerable<string> GetProviderNames() | |||||
{ | |||||
return Context.GetOwinContext().Authentication.GetExternalAuthenticationTypes().Select(t => t.AuthenticationType); | |||||
} | |||||
} | |||||
} |
@ -0,0 +1,24 @@ | |||||
//------------------------------------------------------------------------------ | |||||
// <auto-generated> | |||||
// This code was generated by a tool. | |||||
// | |||||
// Changes to this file may cause incorrect behavior and will be lost if | |||||
// the code is regenerated. | |||||
// </auto-generated> | |||||
//------------------------------------------------------------------------------ | |||||
namespace eShopOnContainers.Catalog.WebForms.Account { | |||||
public partial class OpenAuthProviders { | |||||
/// <summary> | |||||
/// providerDetails 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.ListView providerDetails; | |||||
} | |||||
} |
@ -0,0 +1,45 @@ | |||||
<%@ Page Title="Register" Language="C#" MasterPageFile="~/Site.Master" AutoEventWireup="true" CodeBehind="Register.aspx.cs" Inherits="eShopOnContainers.Catalog.WebForms.Account.Register" %> | |||||
<asp:Content runat="server" ID="BodyContent" ContentPlaceHolderID="MainContent"> | |||||
<h2><%: Title %>.</h2> | |||||
<p class="text-danger"> | |||||
<asp:Literal runat="server" ID="ErrorMessage" /> | |||||
</p> | |||||
<div class="form-horizontal"> | |||||
<h4>Create a new account</h4> | |||||
<hr /> | |||||
<asp:ValidationSummary runat="server" CssClass="text-danger" /> | |||||
<div class="form-group"> | |||||
<asp:Label runat="server" AssociatedControlID="Email" CssClass="col-md-2 control-label">Email</asp:Label> | |||||
<div class="col-md-10"> | |||||
<asp:TextBox runat="server" ID="Email" CssClass="form-control" TextMode="Email" /> | |||||
<asp:RequiredFieldValidator runat="server" ControlToValidate="Email" | |||||
CssClass="text-danger" ErrorMessage="The email field is required." /> | |||||
</div> | |||||
</div> | |||||
<div class="form-group"> | |||||
<asp:Label runat="server" AssociatedControlID="Password" CssClass="col-md-2 control-label">Password</asp:Label> | |||||
<div class="col-md-10"> | |||||
<asp:TextBox runat="server" ID="Password" TextMode="Password" CssClass="form-control" /> | |||||
<asp:RequiredFieldValidator runat="server" ControlToValidate="Password" | |||||
CssClass="text-danger" ErrorMessage="The password field is required." /> | |||||
</div> | |||||
</div> | |||||
<div class="form-group"> | |||||
<asp:Label runat="server" AssociatedControlID="ConfirmPassword" CssClass="col-md-2 control-label">Confirm password</asp:Label> | |||||
<div class="col-md-10"> | |||||
<asp:TextBox runat="server" ID="ConfirmPassword" TextMode="Password" CssClass="form-control" /> | |||||
<asp:RequiredFieldValidator runat="server" ControlToValidate="ConfirmPassword" | |||||
CssClass="text-danger" Display="Dynamic" ErrorMessage="The confirm password field is required." /> | |||||
<asp:CompareValidator runat="server" ControlToCompare="Password" ControlToValidate="ConfirmPassword" | |||||
CssClass="text-danger" Display="Dynamic" ErrorMessage="The password and confirmation password do not match." /> | |||||
</div> | |||||
</div> | |||||
<div class="form-group"> | |||||
<div class="col-md-offset-2 col-md-10"> | |||||
<asp:Button runat="server" OnClick="CreateUser_Click" Text="Register" CssClass="btn btn-default" /> | |||||
</div> | |||||
</div> | |||||
</div> | |||||
</asp:Content> |
@ -0,0 +1,36 @@ | |||||
using System; | |||||
using System.Linq; | |||||
using System.Web; | |||||
using System.Web.UI; | |||||
using Microsoft.AspNet.Identity; | |||||
using Microsoft.AspNet.Identity.Owin; | |||||
using Owin; | |||||
using eShopOnContainers.Catalog.WebForms.Models; | |||||
namespace eShopOnContainers.Catalog.WebForms.Account | |||||
{ | |||||
public partial class Register : Page | |||||
{ | |||||
protected void CreateUser_Click(object sender, EventArgs e) | |||||
{ | |||||
var manager = Context.GetOwinContext().GetUserManager<ApplicationUserManager>(); | |||||
var signInManager = Context.GetOwinContext().Get<ApplicationSignInManager>(); | |||||
var user = new ApplicationUser() { UserName = Email.Text, Email = Email.Text }; | |||||
IdentityResult result = manager.Create(user, Password.Text); | |||||
if (result.Succeeded) | |||||
{ | |||||
// For more information on how to enable account confirmation and password reset please visit https://go.microsoft.com/fwlink/?LinkID=320771 | |||||
//string code = manager.GenerateEmailConfirmationToken(user.Id); | |||||
//string callbackUrl = IdentityHelper.GetUserConfirmationRedirectUrl(code, user.Id, Request); | |||||
//manager.SendEmail(user.Id, "Confirm your account", "Please confirm your account by clicking <a href=\"" + callbackUrl + "\">here</a>."); | |||||
signInManager.SignIn( user, isPersistent: false, rememberBrowser: false); | |||||
IdentityHelper.RedirectToReturnUrl(Request.QueryString["ReturnUrl"], Response); | |||||
} | |||||
else | |||||
{ | |||||
ErrorMessage.Text = result.Errors.FirstOrDefault(); | |||||
} | |||||
} | |||||
} | |||||
} |
@ -0,0 +1,51 @@ | |||||
//------------------------------------------------------------------------------ | |||||
// <auto-generated> | |||||
// This code was generated by a tool. | |||||
// | |||||
// Changes to this file may cause incorrect behavior and will be lost if | |||||
// the code is regenerated. | |||||
// </auto-generated> | |||||
//------------------------------------------------------------------------------ | |||||
namespace eShopOnContainers.Catalog.WebForms.Account { | |||||
public partial class Register { | |||||
/// <summary> | |||||
/// ErrorMessage 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.Literal ErrorMessage; | |||||
/// <summary> | |||||
/// Email 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.TextBox Email; | |||||
/// <summary> | |||||
/// Password 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.TextBox Password; | |||||
/// <summary> | |||||
/// ConfirmPassword 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.TextBox ConfirmPassword; | |||||
} | |||||
} |
@ -0,0 +1,33 @@ | |||||
<%@ Page Title="Register an external login" Language="C#" MasterPageFile="~/Site.Master" AutoEventWireup="true" CodeBehind="RegisterExternalLogin.aspx.cs" Inherits="eShopOnContainers.Catalog.WebForms.Account.RegisterExternalLogin" Async="true" %> | |||||
<asp:Content runat="server" ID="BodyContent" ContentPlaceHolderID="MainContent"> | |||||
<h3>Register with your <%: ProviderName %> account</h3> | |||||
<asp:PlaceHolder runat="server"> | |||||
<div class="form-horizontal"> | |||||
<h4>Association Form</h4> | |||||
<hr /> | |||||
<asp:ValidationSummary runat="server" ShowModelStateErrors="true" CssClass="text-danger" /> | |||||
<p class="text-info"> | |||||
You've authenticated with <strong><%: ProviderName %></strong>. Please enter an email below for the current site | |||||
and click the Log in button. | |||||
</p> | |||||
<div class="form-group"> | |||||
<asp:Label runat="server" AssociatedControlID="email" CssClass="col-md-2 control-label">Email</asp:Label> | |||||
<div class="col-md-10"> | |||||
<asp:TextBox runat="server" ID="email" CssClass="form-control" TextMode="Email" /> | |||||
<asp:RequiredFieldValidator runat="server" ControlToValidate="email" | |||||
Display="Dynamic" CssClass="text-danger" ErrorMessage="Email is required" /> | |||||
<asp:ModelErrorMessage runat="server" ModelStateKey="email" CssClass="text-error" /> | |||||
</div> | |||||
</div> | |||||
<div class="form-group"> | |||||
<div class="col-md-offset-2 col-md-10"> | |||||
<asp:Button runat="server" Text="Log in" CssClass="btn btn-default" OnClick="LogIn_Click" /> | |||||
</div> | |||||
</div> | |||||
</div> | |||||
</asp:PlaceHolder> | |||||
</asp:Content> |
@ -0,0 +1,130 @@ | |||||
using System; | |||||
using System.Web; | |||||
using Microsoft.AspNet.Identity; | |||||
using Microsoft.AspNet.Identity.Owin; | |||||
using Microsoft.Owin.Security; | |||||
using Owin; | |||||
using eShopOnContainers.Catalog.WebForms.Models; | |||||
namespace eShopOnContainers.Catalog.WebForms.Account | |||||
{ | |||||
public partial class RegisterExternalLogin : System.Web.UI.Page | |||||
{ | |||||
protected string ProviderName | |||||
{ | |||||
get { return (string)ViewState["ProviderName"] ?? String.Empty; } | |||||
private set { ViewState["ProviderName"] = value; } | |||||
} | |||||
protected string ProviderAccountKey | |||||
{ | |||||
get { return (string)ViewState["ProviderAccountKey"] ?? String.Empty; } | |||||
private set { ViewState["ProviderAccountKey"] = value; } | |||||
} | |||||
private void RedirectOnFail() | |||||
{ | |||||
Response.Redirect((User.Identity.IsAuthenticated) ? "~/Account/Manage" : "~/Account/Login"); | |||||
} | |||||
protected void Page_Load() | |||||
{ | |||||
// Process the result from an auth provider in the request | |||||
ProviderName = IdentityHelper.GetProviderNameFromRequest(Request); | |||||
if (String.IsNullOrEmpty(ProviderName)) | |||||
{ | |||||
RedirectOnFail(); | |||||
return; | |||||
} | |||||
if (!IsPostBack) | |||||
{ | |||||
var manager = Context.GetOwinContext().GetUserManager<ApplicationUserManager>(); | |||||
var signInManager = Context.GetOwinContext().Get<ApplicationSignInManager>(); | |||||
var loginInfo = Context.GetOwinContext().Authentication.GetExternalLoginInfo(); | |||||
if (loginInfo == null) | |||||
{ | |||||
RedirectOnFail(); | |||||
return; | |||||
} | |||||
var user = manager.Find(loginInfo.Login); | |||||
if (user != null) | |||||
{ | |||||
signInManager.SignIn(user, isPersistent: false, rememberBrowser: false); | |||||
IdentityHelper.RedirectToReturnUrl(Request.QueryString["ReturnUrl"], Response); | |||||
} | |||||
else if (User.Identity.IsAuthenticated) | |||||
{ | |||||
// Apply Xsrf check when linking | |||||
var verifiedloginInfo = Context.GetOwinContext().Authentication.GetExternalLoginInfo(IdentityHelper.XsrfKey, User.Identity.GetUserId()); | |||||
if (verifiedloginInfo == null) | |||||
{ | |||||
RedirectOnFail(); | |||||
return; | |||||
} | |||||
var result = manager.AddLogin(User.Identity.GetUserId(), verifiedloginInfo.Login); | |||||
if (result.Succeeded) | |||||
{ | |||||
IdentityHelper.RedirectToReturnUrl(Request.QueryString["ReturnUrl"], Response); | |||||
} | |||||
else | |||||
{ | |||||
AddErrors(result); | |||||
return; | |||||
} | |||||
} | |||||
else | |||||
{ | |||||
email.Text = loginInfo.Email; | |||||
} | |||||
} | |||||
} | |||||
protected void LogIn_Click(object sender, EventArgs e) | |||||
{ | |||||
CreateAndLoginUser(); | |||||
} | |||||
private void CreateAndLoginUser() | |||||
{ | |||||
if (!IsValid) | |||||
{ | |||||
return; | |||||
} | |||||
var manager = Context.GetOwinContext().GetUserManager<ApplicationUserManager>(); | |||||
var signInManager = Context.GetOwinContext().GetUserManager<ApplicationSignInManager>(); | |||||
var user = new ApplicationUser() { UserName = email.Text, Email = email.Text }; | |||||
IdentityResult result = manager.Create(user); | |||||
if (result.Succeeded) | |||||
{ | |||||
var loginInfo = Context.GetOwinContext().Authentication.GetExternalLoginInfo(); | |||||
if (loginInfo == null) | |||||
{ | |||||
RedirectOnFail(); | |||||
return; | |||||
} | |||||
result = manager.AddLogin(user.Id, loginInfo.Login); | |||||
if (result.Succeeded) | |||||
{ | |||||
signInManager.SignIn(user, isPersistent: false, rememberBrowser: false); | |||||
// For more information on how to enable account confirmation and password reset please visit https://go.microsoft.com/fwlink/?LinkID=320771 | |||||
// var code = manager.GenerateEmailConfirmationToken(user.Id); | |||||
// Send this link via email: IdentityHelper.GetUserConfirmationRedirectUrl(code, user.Id) | |||||
IdentityHelper.RedirectToReturnUrl(Request.QueryString["ReturnUrl"], Response); | |||||
return; | |||||
} | |||||
} | |||||
AddErrors(result); | |||||
} | |||||
private void AddErrors(IdentityResult result) | |||||
{ | |||||
foreach (var error in result.Errors) | |||||
{ | |||||
ModelState.AddModelError("", error); | |||||
} | |||||
} | |||||
} | |||||
} |
@ -0,0 +1,24 @@ | |||||
//------------------------------------------------------------------------------ | |||||
// <auto-generated> | |||||
// This code was generated by a tool. | |||||
// | |||||
// Changes to this file may cause incorrect behavior and will be lost if | |||||
// the code is regenerated. | |||||
// </auto-generated> | |||||
//------------------------------------------------------------------------------ | |||||
namespace eShopOnContainers.Catalog.WebForms.Account { | |||||
public partial class RegisterExternalLogin { | |||||
/// <summary> | |||||
/// email 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.TextBox email; | |||||
} | |||||
} |
@ -0,0 +1,45 @@ | |||||
<%@ Page Title="Reset Password" Language="C#" MasterPageFile="~/Site.Master" AutoEventWireup="true" CodeBehind="ResetPassword.aspx.cs" Inherits="eShopOnContainers.Catalog.WebForms.Account.ResetPassword" Async="true" %> | |||||
<asp:Content runat="server" ID="BodyContent" ContentPlaceHolderID="MainContent"> | |||||
<h2><%: Title %>.</h2> | |||||
<p class="text-danger"> | |||||
<asp:Literal runat="server" ID="ErrorMessage" /> | |||||
</p> | |||||
<div class="form-horizontal"> | |||||
<h4>Enter your new password</h4> | |||||
<hr /> | |||||
<asp:ValidationSummary runat="server" CssClass="text-danger" /> | |||||
<div class="form-group"> | |||||
<asp:Label runat="server" AssociatedControlID="Email" CssClass="col-md-2 control-label">Email</asp:Label> | |||||
<div class="col-md-10"> | |||||
<asp:TextBox runat="server" ID="Email" CssClass="form-control" TextMode="Email" /> | |||||
<asp:RequiredFieldValidator runat="server" ControlToValidate="Email" | |||||
CssClass="text-danger" ErrorMessage="The email field is required." /> | |||||
</div> | |||||
</div> | |||||
<div class="form-group"> | |||||
<asp:Label runat="server" AssociatedControlID="Password" CssClass="col-md-2 control-label">Password</asp:Label> | |||||
<div class="col-md-10"> | |||||
<asp:TextBox runat="server" ID="Password" TextMode="Password" CssClass="form-control" /> | |||||
<asp:RequiredFieldValidator runat="server" ControlToValidate="Password" | |||||
CssClass="text-danger" ErrorMessage="The password field is required." /> | |||||
</div> | |||||
</div> | |||||
<div class="form-group"> | |||||
<asp:Label runat="server" AssociatedControlID="ConfirmPassword" CssClass="col-md-2 control-label">Confirm password</asp:Label> | |||||
<div class="col-md-10"> | |||||
<asp:TextBox runat="server" ID="ConfirmPassword" TextMode="Password" CssClass="form-control" /> | |||||
<asp:RequiredFieldValidator runat="server" ControlToValidate="ConfirmPassword" | |||||
CssClass="text-danger" Display="Dynamic" ErrorMessage="The confirm password field is required." /> | |||||
<asp:CompareValidator runat="server" ControlToCompare="Password" ControlToValidate="ConfirmPassword" | |||||
CssClass="text-danger" Display="Dynamic" ErrorMessage="The password and confirmation password do not match." /> | |||||
</div> | |||||
</div> | |||||
<div class="form-group"> | |||||
<div class="col-md-offset-2 col-md-10"> | |||||
<asp:Button runat="server" OnClick="Reset_Click" Text="Reset" CssClass="btn btn-default" /> | |||||
</div> | |||||
</div> | |||||
</div> | |||||
</asp:Content> |
@ -0,0 +1,46 @@ | |||||
using System; | |||||
using System.Linq; | |||||
using System.Web; | |||||
using System.Web.UI; | |||||
using Microsoft.AspNet.Identity; | |||||
using Microsoft.AspNet.Identity.Owin; | |||||
using Owin; | |||||
using eShopOnContainers.Catalog.WebForms.Models; | |||||
namespace eShopOnContainers.Catalog.WebForms.Account | |||||
{ | |||||
public partial class ResetPassword : Page | |||||
{ | |||||
protected string StatusMessage | |||||
{ | |||||
get; | |||||
private set; | |||||
} | |||||
protected void Reset_Click(object sender, EventArgs e) | |||||
{ | |||||
string code = IdentityHelper.GetCodeFromRequest(Request); | |||||
if (code != null) | |||||
{ | |||||
var manager = Context.GetOwinContext().GetUserManager<ApplicationUserManager>(); | |||||
var user = manager.FindByName(Email.Text); | |||||
if (user == null) | |||||
{ | |||||
ErrorMessage.Text = "No user found"; | |||||
return; | |||||
} | |||||
var result = manager.ResetPassword(user.Id, code, Password.Text); | |||||
if (result.Succeeded) | |||||
{ | |||||
Response.Redirect("~/Account/ResetPasswordConfirmation"); | |||||
return; | |||||
} | |||||
ErrorMessage.Text = result.Errors.FirstOrDefault(); | |||||
return; | |||||
} | |||||
ErrorMessage.Text = "An error has occurred"; | |||||
} | |||||
} | |||||
} |
@ -0,0 +1,51 @@ | |||||
//------------------------------------------------------------------------------ | |||||
// <auto-generated> | |||||
// This code was generated by a tool. | |||||
// | |||||
// Changes to this file may cause incorrect behavior and will be lost if | |||||
// the code is regenerated. | |||||
// </auto-generated> | |||||
//------------------------------------------------------------------------------ | |||||
namespace eShopOnContainers.Catalog.WebForms.Account { | |||||
public partial class ResetPassword { | |||||
/// <summary> | |||||
/// ErrorMessage 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.Literal ErrorMessage; | |||||
/// <summary> | |||||
/// Email 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.TextBox Email; | |||||
/// <summary> | |||||
/// Password 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.TextBox Password; | |||||
/// <summary> | |||||
/// ConfirmPassword 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.TextBox ConfirmPassword; | |||||
} | |||||
} |
@ -0,0 +1,8 @@ | |||||
<%@ Page Title="Password Changed" Language="C#" MasterPageFile="~/Site.Master" AutoEventWireup="true" CodeBehind="ResetPasswordConfirmation.aspx.cs" Inherits="eShopOnContainers.Catalog.WebForms.Account.ResetPasswordConfirmation" Async="true" %> | |||||
<asp:Content runat="server" ID="BodyContent" ContentPlaceHolderID="MainContent"> | |||||
<h2><%: Title %>.</h2> | |||||
<div> | |||||
<p>Your password has been changed. Click <asp:HyperLink ID="login" runat="server" NavigateUrl="~/Account/Login">here</asp:HyperLink> to login </p> | |||||
</div> | |||||
</asp:Content> |
@ -0,0 +1,8 @@ | |||||
using System.Web.UI; | |||||
namespace eShopOnContainers.Catalog.WebForms.Account | |||||
{ | |||||
public partial class ResetPasswordConfirmation : Page | |||||
{ | |||||
} | |||||
} |
@ -0,0 +1,24 @@ | |||||
//------------------------------------------------------------------------------ | |||||
// <auto-generated> | |||||
// This code was generated by a tool. | |||||
// | |||||
// Changes to this file may cause incorrect behavior and will be lost if | |||||
// the code is regenerated. | |||||
// </auto-generated> | |||||
//------------------------------------------------------------------------------ | |||||
namespace eShopOnContainers.Catalog.WebForms.Account { | |||||
public partial class ResetPasswordConfirmation { | |||||
/// <summary> | |||||
/// login 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.HyperLink login; | |||||
} | |||||
} |
@ -0,0 +1,50 @@ | |||||
<%@ Page Title="Two-Factor Authentication" Language="C#" MasterPageFile="~/Site.Master" AutoEventWireup="true" CodeBehind="TwoFactorAuthenticationSignIn.aspx.cs" Inherits="eShopOnContainers.Catalog.WebForms.Account.TwoFactorAuthenticationSignIn" %> | |||||
<asp:Content ID="BodyContent" ContentPlaceHolderID="MainContent" runat="server"> | |||||
<h2><%: Title %>.</h2> | |||||
<asp:PlaceHolder runat="server" ID="sendcode"> | |||||
<section> | |||||
<h4>Send verification code</h4> | |||||
<hr /> | |||||
<div class="row"> | |||||
<div class="col-md-12"> | |||||
Select Two-Factor Authentication Provider: | |||||
<asp:DropDownList runat="server" ID="Providers"> | |||||
</asp:DropDownList> | |||||
<asp:Button Text="Submit" ID="ProviderSubmit" OnClick="ProviderSubmit_Click" CssClass="btn btn-default" runat="server" /> | |||||
</div> | |||||
</div> | |||||
</section> | |||||
</asp:PlaceHolder> | |||||
<asp:PlaceHolder runat="server" ID="verifycode" Visible="false"> | |||||
<section> | |||||
<h4>Enter verification code</h4> | |||||
<hr /> | |||||
<asp:HiddenField ID="SelectedProvider" runat="server" /> | |||||
<asp:PlaceHolder runat="server" ID="ErrorMessage" Visible="false"> | |||||
<p class="text-danger"> | |||||
<asp:Literal runat="server" ID="FailureText" /> | |||||
</p> | |||||
</asp:PlaceHolder> | |||||
<div class="form-group"> | |||||
<asp:Label Text="Code:" runat="server" AssociatedControlID="Code" CssClass="col-md-2 control-label" /> | |||||
<div class="col-md-10"> | |||||
<asp:TextBox runat="server" ID="Code" CssClass="form-control" /> | |||||
</div> | |||||
</div> | |||||
<div class="form-group"> | |||||
<div class="col-md-offset-2 col-md-10"> | |||||
<div class="checkbox"> | |||||
<asp:Label Text="Remember Browser" runat="server" /> | |||||
<asp:CheckBox Text="" ID="RememberBrowser" runat="server" /> | |||||
</div> | |||||
</div> | |||||
</div> | |||||
<div class="form-group"> | |||||
<div class="col-md-offset-2 col-md-10"> | |||||
<asp:Button Text="Submit" ID="CodeSubmit" OnClick="CodeSubmit_Click" CssClass="btn btn-default" runat="server" /> | |||||
</div> | |||||
</div> | |||||
</section> | |||||
</asp:PlaceHolder> | |||||
</asp:Content> |
@ -0,0 +1,77 @@ | |||||
using System; | |||||
using System.Collections.Generic; | |||||
using System.Linq; | |||||
using System.Threading.Tasks; | |||||
using System.Web; | |||||
using System.Web.UI; | |||||
using System.Web.UI.WebControls; | |||||
using Microsoft.AspNet.Identity; | |||||
using Microsoft.AspNet.Identity.Owin; | |||||
using eShopOnContainers.Catalog.WebForms.Models; | |||||
namespace eShopOnContainers.Catalog.WebForms.Account | |||||
{ | |||||
public partial class TwoFactorAuthenticationSignIn : System.Web.UI.Page | |||||
{ | |||||
private ApplicationSignInManager signinManager; | |||||
private ApplicationUserManager manager; | |||||
public TwoFactorAuthenticationSignIn() | |||||
{ | |||||
manager = Context.GetOwinContext().GetUserManager<ApplicationUserManager>(); | |||||
signinManager = Context.GetOwinContext().GetUserManager<ApplicationSignInManager>(); | |||||
} | |||||
protected void Page_Load(object sender, EventArgs e) | |||||
{ | |||||
var userId = signinManager.GetVerifiedUserId<ApplicationUser, string>(); | |||||
if (userId == null) | |||||
{ | |||||
Response.Redirect("/Account/Error", true); | |||||
} | |||||
var userFactors = manager.GetValidTwoFactorProviders(userId); | |||||
Providers.DataSource = userFactors.Select(x => x).ToList(); | |||||
Providers.DataBind(); | |||||
} | |||||
protected void CodeSubmit_Click(object sender, EventArgs e) | |||||
{ | |||||
bool rememberMe = false; | |||||
bool.TryParse(Request.QueryString["RememberMe"], out rememberMe); | |||||
var result = signinManager.TwoFactorSignIn<ApplicationUser, string>(SelectedProvider.Value, Code.Text, isPersistent: rememberMe, rememberBrowser: RememberBrowser.Checked); | |||||
switch (result) | |||||
{ | |||||
case SignInStatus.Success: | |||||
IdentityHelper.RedirectToReturnUrl(Request.QueryString["ReturnUrl"], Response); | |||||
break; | |||||
case SignInStatus.LockedOut: | |||||
Response.Redirect("/Account/Lockout"); | |||||
break; | |||||
case SignInStatus.Failure: | |||||
default: | |||||
FailureText.Text = "Invalid code"; | |||||
ErrorMessage.Visible = true; | |||||
break; | |||||
} | |||||
} | |||||
protected void ProviderSubmit_Click(object sender, EventArgs e) | |||||
{ | |||||
if (!signinManager.SendTwoFactorCode(Providers.SelectedValue)) | |||||
{ | |||||
Response.Redirect("/Account/Error"); | |||||
} | |||||
var user = manager.FindById(signinManager.GetVerifiedUserId<ApplicationUser, string>()); | |||||
if (user != null) | |||||
{ | |||||
var code = manager.GenerateTwoFactorToken(user.Id, Providers.SelectedValue); | |||||
} | |||||
SelectedProvider.Value = Providers.SelectedValue; | |||||
sendcode.Visible = false; | |||||
verifycode.Visible = true; | |||||
} | |||||
} | |||||
} |
@ -0,0 +1,105 @@ | |||||
//------------------------------------------------------------------------------ | |||||
// <auto-generated> | |||||
// This code was generated by a tool. | |||||
// | |||||
// Changes to this file may cause incorrect behavior and will be lost if | |||||
// the code is regenerated. | |||||
// </auto-generated> | |||||
//------------------------------------------------------------------------------ | |||||
namespace eShopOnContainers.Catalog.WebForms.Account { | |||||
public partial class TwoFactorAuthenticationSignIn { | |||||
/// <summary> | |||||
/// sendcode 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.PlaceHolder sendcode; | |||||
/// <summary> | |||||
/// Providers 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.DropDownList Providers; | |||||
/// <summary> | |||||
/// ProviderSubmit 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.Button ProviderSubmit; | |||||
/// <summary> | |||||
/// verifycode 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.PlaceHolder verifycode; | |||||
/// <summary> | |||||
/// SelectedProvider 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.HiddenField SelectedProvider; | |||||
/// <summary> | |||||
/// ErrorMessage 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.PlaceHolder ErrorMessage; | |||||
/// <summary> | |||||
/// FailureText 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.Literal FailureText; | |||||
/// <summary> | |||||
/// Code 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.TextBox Code; | |||||
/// <summary> | |||||
/// RememberBrowser control. | |||||
/// </summary> | |||||
/// <remarks> | |||||
/// Auto-generated field. | |||||
/// To modify move field declaration from designer file to code-behind file. | |||||
/// </remarks> | |||||
protected global::System.Web.UI.WebControls.CheckBox RememberBrowser; | |||||
/// <summary> | |||||
/// CodeSubmit 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.Button CodeSubmit; | |||||
} | |||||
} |
@ -0,0 +1,28 @@ | |||||
<%@ Page Title="Verify Phone Number" Language="C#" MasterPageFile="~/Site.Master" AutoEventWireup="true" CodeBehind="VerifyPhoneNumber.aspx.cs" Inherits="eShopOnContainers.Catalog.WebForms.Account.VerifyPhoneNumber" %> | |||||
<asp:Content ID="BodyContent" ContentPlaceHolderID="MainContent" runat="server"> | |||||
<h2><%: Title %>.</h2> | |||||
<p class="text-danger"> | |||||
<asp:Literal runat="server" ID="ErrorMessage" /> | |||||
</p> | |||||
<div class="form-horizontal"> | |||||
<h4>Enter verification code</h4> | |||||
<hr /> | |||||
<asp:HiddenField runat="server" ID="PhoneNumber" /> | |||||
<asp:ValidationSummary runat="server" CssClass="text-danger" /> | |||||
<div class="form-group"> | |||||
<asp:Label runat="server" AssociatedControlID="Code" CssClass="col-md-2 control-label">Code</asp:Label> | |||||
<div class="col-md-10"> | |||||
<asp:TextBox runat="server" ID="Code" CssClass="form-control" /> | |||||
<asp:RequiredFieldValidator runat="server" ControlToValidate="Code" | |||||
CssClass="text-danger" ErrorMessage="The Code field is required." /> | |||||
</div> | |||||
</div> | |||||
<div class="form-group"> | |||||
<div class="col-md-offset-2 col-md-10"> | |||||
<asp:Button runat="server" OnClick="Code_Click" | |||||
Text="Submit" CssClass="btn btn-default" /> | |||||
</div> | |||||
</div> | |||||
</div> | |||||
</asp:Content> |
@ -0,0 +1,50 @@ | |||||
using System; | |||||
using System.Collections.Generic; | |||||
using System.Linq; | |||||
using System.Web; | |||||
using System.Web.UI; | |||||
using System.Web.UI.WebControls; | |||||
using Microsoft.AspNet.Identity; | |||||
using Microsoft.AspNet.Identity.Owin; | |||||
namespace eShopOnContainers.Catalog.WebForms.Account | |||||
{ | |||||
public partial class VerifyPhoneNumber : System.Web.UI.Page | |||||
{ | |||||
protected void Page_Load(object sender, EventArgs e) | |||||
{ | |||||
var manager = Context.GetOwinContext().GetUserManager<ApplicationUserManager>(); | |||||
var phonenumber = Request.QueryString["PhoneNumber"]; | |||||
var code = manager.GenerateChangePhoneNumberToken(User.Identity.GetUserId(), phonenumber); | |||||
PhoneNumber.Value = phonenumber; | |||||
} | |||||
protected void Code_Click(object sender, EventArgs e) | |||||
{ | |||||
if (!ModelState.IsValid) | |||||
{ | |||||
ModelState.AddModelError("", "Invalid code"); | |||||
return; | |||||
} | |||||
var manager = Context.GetOwinContext().GetUserManager<ApplicationUserManager>(); | |||||
var signInManager = Context.GetOwinContext().Get<ApplicationSignInManager>(); | |||||
var result = manager.ChangePhoneNumber(User.Identity.GetUserId(), PhoneNumber.Value, Code.Text); | |||||
if (result.Succeeded) | |||||
{ | |||||
var user = manager.FindById(User.Identity.GetUserId()); | |||||
if (user != null) | |||||
{ | |||||
signInManager.SignIn(user, isPersistent: false, rememberBrowser: false); | |||||
Response.Redirect("/Account/Manage?m=AddPhoneNumberSuccess"); | |||||
} | |||||
} | |||||
// If we got this far, something failed, redisplay form | |||||
ModelState.AddModelError("", "Failed to verify phone"); | |||||
} | |||||
} | |||||
} |
@ -0,0 +1,42 @@ | |||||
//------------------------------------------------------------------------------ | |||||
// <auto-generated> | |||||
// This code was generated by a tool. | |||||
// | |||||
// Changes to this file may cause incorrect behavior and will be lost if | |||||
// the code is regenerated. | |||||
// </auto-generated> | |||||
//------------------------------------------------------------------------------ | |||||
namespace eShopOnContainers.Catalog.WebForms.Account { | |||||
public partial class VerifyPhoneNumber { | |||||
/// <summary> | |||||
/// ErrorMessage 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.Literal ErrorMessage; | |||||
/// <summary> | |||||
/// PhoneNumber 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.HiddenField PhoneNumber; | |||||
/// <summary> | |||||
/// Code 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.TextBox Code; | |||||
} | |||||
} |
@ -0,0 +1,12 @@ | |||||
<?xml version="1.0"?> | |||||
<configuration> | |||||
<location path="Manage.aspx"> | |||||
<system.web> | |||||
<authorization> | |||||
<deny users="?"/> | |||||
</authorization> | |||||
</system.web> | |||||
</location> | |||||
</configuration> |
@ -0,0 +1,46 @@ | |||||
using System; | |||||
using System.Collections.Generic; | |||||
using System.Linq; | |||||
using System.Web; | |||||
using System.Web.Optimization; | |||||
using System.Web.UI; | |||||
namespace eShopOnContainers.Catalog.WebForms | |||||
{ | |||||
public class BundleConfig | |||||
{ | |||||
// For more information on Bundling, visit https://go.microsoft.com/fwlink/?LinkID=303951 | |||||
public static void RegisterBundles(BundleCollection bundles) | |||||
{ | |||||
bundles.Add(new ScriptBundle("~/bundles/WebFormsJs").Include( | |||||
"~/Scripts/WebForms/WebForms.js", | |||||
"~/Scripts/WebForms/WebUIValidation.js", | |||||
"~/Scripts/WebForms/MenuStandards.js", | |||||
"~/Scripts/WebForms/Focus.js", | |||||
"~/Scripts/WebForms/GridView.js", | |||||
"~/Scripts/WebForms/DetailsView.js", | |||||
"~/Scripts/WebForms/TreeView.js", | |||||
"~/Scripts/WebForms/WebParts.js")); | |||||
// Order is very important for these files to work, they have explicit dependencies | |||||
bundles.Add(new ScriptBundle("~/bundles/MsAjaxJs").Include( | |||||
"~/Scripts/WebForms/MsAjax/MicrosoftAjax.js", | |||||
"~/Scripts/WebForms/MsAjax/MicrosoftAjaxApplicationServices.js", | |||||
"~/Scripts/WebForms/MsAjax/MicrosoftAjaxTimer.js", | |||||
"~/Scripts/WebForms/MsAjax/MicrosoftAjaxWebForms.js")); | |||||
// Use the Development version of Modernizr to develop with and learn from. Then, when you’re | |||||
// ready for production, use the build tool at https://modernizr.com to pick only the tests you need | |||||
bundles.Add(new ScriptBundle("~/bundles/modernizr").Include( | |||||
"~/Scripts/modernizr-*")); | |||||
ScriptManager.ScriptResourceMapping.AddDefinition( | |||||
"respond", | |||||
new ScriptResourceDefinition | |||||
{ | |||||
Path = "~/Scripts/respond.min.js", | |||||
DebugPath = "~/Scripts/respond.js", | |||||
}); | |||||
} | |||||
} | |||||
} |
@ -0,0 +1,102 @@ | |||||
using System; | |||||
using System.Security.Claims; | |||||
using System.Threading.Tasks; | |||||
using Microsoft.AspNet.Identity; | |||||
using Microsoft.AspNet.Identity.EntityFramework; | |||||
using Microsoft.AspNet.Identity.Owin; | |||||
using Microsoft.Owin; | |||||
using Microsoft.Owin.Security; | |||||
using eShopOnContainers.Catalog.WebForms.Models; | |||||
namespace eShopOnContainers.Catalog.WebForms | |||||
{ | |||||
public class EmailService : IIdentityMessageService | |||||
{ | |||||
public Task SendAsync(IdentityMessage message) | |||||
{ | |||||
// Plug in your email service here to send an email. | |||||
return Task.FromResult(0); | |||||
} | |||||
} | |||||
public class SmsService : IIdentityMessageService | |||||
{ | |||||
public Task SendAsync(IdentityMessage message) | |||||
{ | |||||
// Plug in your SMS service here to send a text message. | |||||
return Task.FromResult(0); | |||||
} | |||||
} | |||||
// Configure the application user manager used in this application. UserManager is defined in ASP.NET Identity and is used by the application. | |||||
public class ApplicationUserManager : UserManager<ApplicationUser> | |||||
{ | |||||
public ApplicationUserManager(IUserStore<ApplicationUser> store) | |||||
: base(store) | |||||
{ | |||||
} | |||||
public static ApplicationUserManager Create(IdentityFactoryOptions<ApplicationUserManager> options, IOwinContext context) | |||||
{ | |||||
var manager = new ApplicationUserManager(new UserStore<ApplicationUser>(context.Get<ApplicationDbContext>())); | |||||
// Configure validation logic for usernames | |||||
manager.UserValidator = new UserValidator<ApplicationUser>(manager) | |||||
{ | |||||
AllowOnlyAlphanumericUserNames = false, | |||||
RequireUniqueEmail = true | |||||
}; | |||||
// Configure validation logic for passwords | |||||
manager.PasswordValidator = new PasswordValidator | |||||
{ | |||||
RequiredLength = 6, | |||||
RequireNonLetterOrDigit = true, | |||||
RequireDigit = true, | |||||
RequireLowercase = true, | |||||
RequireUppercase = true, | |||||
}; | |||||
// Register two factor authentication providers. This application uses Phone and Emails as a step of receiving a code for verifying the user | |||||
// You can write your own provider and plug it in here. | |||||
manager.RegisterTwoFactorProvider("Phone Code", new PhoneNumberTokenProvider<ApplicationUser> | |||||
{ | |||||
MessageFormat = "Your security code is {0}" | |||||
}); | |||||
manager.RegisterTwoFactorProvider("Email Code", new EmailTokenProvider<ApplicationUser> | |||||
{ | |||||
Subject = "Security Code", | |||||
BodyFormat = "Your security code is {0}" | |||||
}); | |||||
// Configure user lockout defaults | |||||
manager.UserLockoutEnabledByDefault = true; | |||||
manager.DefaultAccountLockoutTimeSpan = TimeSpan.FromMinutes(5); | |||||
manager.MaxFailedAccessAttemptsBeforeLockout = 5; | |||||
manager.EmailService = new EmailService(); | |||||
manager.SmsService = new SmsService(); | |||||
var dataProtectionProvider = options.DataProtectionProvider; | |||||
if (dataProtectionProvider != null) | |||||
{ | |||||
manager.UserTokenProvider = new DataProtectorTokenProvider<ApplicationUser>(dataProtectionProvider.Create("ASP.NET Identity")); | |||||
} | |||||
return manager; | |||||
} | |||||
} | |||||
public class ApplicationSignInManager : SignInManager<ApplicationUser, string> | |||||
{ | |||||
public ApplicationSignInManager(ApplicationUserManager userManager, IAuthenticationManager authenticationManager) : | |||||
base(userManager, authenticationManager) { } | |||||
public override Task<ClaimsIdentity> CreateUserIdentityAsync(ApplicationUser user) | |||||
{ | |||||
return user.GenerateUserIdentityAsync((ApplicationUserManager)UserManager); | |||||
} | |||||
public static ApplicationSignInManager Create(IdentityFactoryOptions<ApplicationSignInManager> options, IOwinContext context) | |||||
{ | |||||
return new ApplicationSignInManager(context.GetUserManager<ApplicationUserManager>(), context.Authentication); | |||||
} | |||||
} | |||||
} |
@ -0,0 +1,18 @@ | |||||
using System; | |||||
using System.Collections.Generic; | |||||
using System.Web; | |||||
using System.Web.Routing; | |||||
using Microsoft.AspNet.FriendlyUrls; | |||||
namespace eShopOnContainers.Catalog.WebForms | |||||
{ | |||||
public static class RouteConfig | |||||
{ | |||||
public static void RegisterRoutes(RouteCollection routes) | |||||
{ | |||||
var settings = new FriendlyUrlSettings(); | |||||
settings.AutoRedirectMode = RedirectMode.Permanent; | |||||
routes.EnableFriendlyUrls(settings); | |||||
} | |||||
} | |||||
} |
@ -0,0 +1,69 @@ | |||||
using System; | |||||
using Microsoft.AspNet.Identity; | |||||
using Microsoft.AspNet.Identity.EntityFramework; | |||||
using Microsoft.AspNet.Identity.Owin; | |||||
using Microsoft.Owin; | |||||
using Microsoft.Owin.Security.Cookies; | |||||
using Microsoft.Owin.Security.DataProtection; | |||||
using Microsoft.Owin.Security.Google; | |||||
using Owin; | |||||
using eShopOnContainers.Catalog.WebForms.Models; | |||||
namespace eShopOnContainers.Catalog.WebForms | |||||
{ | |||||
public partial class Startup { | |||||
// For more information on configuring authentication, please visit https://go.microsoft.com/fwlink/?LinkId=301883 | |||||
public void ConfigureAuth(IAppBuilder app) | |||||
{ | |||||
// Configure the db context, user manager and signin manager to use a single instance per request | |||||
app.CreatePerOwinContext(ApplicationDbContext.Create); | |||||
app.CreatePerOwinContext<ApplicationUserManager>(ApplicationUserManager.Create); | |||||
app.CreatePerOwinContext<ApplicationSignInManager>(ApplicationSignInManager.Create); | |||||
// Enable the application to use a cookie to store information for the signed in user | |||||
// and to use a cookie to temporarily store information about a user logging in with a third party login provider | |||||
// Configure the sign in cookie | |||||
app.UseCookieAuthentication(new CookieAuthenticationOptions | |||||
{ | |||||
AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie, | |||||
LoginPath = new PathString("/Account/Login"), | |||||
Provider = new CookieAuthenticationProvider | |||||
{ | |||||
OnValidateIdentity = SecurityStampValidator.OnValidateIdentity<ApplicationUserManager, ApplicationUser>( | |||||
validateInterval: TimeSpan.FromMinutes(30), | |||||
regenerateIdentity: (manager, user) => user.GenerateUserIdentityAsync(manager)) | |||||
} | |||||
}); | |||||
// Use a cookie to temporarily store information about a user logging in with a third party login provider | |||||
app.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie); | |||||
// Enables the application to temporarily store user information when they are verifying the second factor in the two-factor authentication process. | |||||
app.UseTwoFactorSignInCookie(DefaultAuthenticationTypes.TwoFactorCookie, TimeSpan.FromMinutes(5)); | |||||
// Enables the application to remember the second login verification factor such as phone or email. | |||||
// Once you check this option, your second step of verification during the login process will be remembered on the device where you logged in from. | |||||
// This is similar to the RememberMe option when you log in. | |||||
app.UseTwoFactorRememberBrowserCookie(DefaultAuthenticationTypes.TwoFactorRememberBrowserCookie); | |||||
// Uncomment the following lines to enable logging in with third party login providers | |||||
//app.UseMicrosoftAccountAuthentication( | |||||
// clientId: "", | |||||
// clientSecret: ""); | |||||
//app.UseTwitterAuthentication( | |||||
// consumerKey: "", | |||||
// consumerSecret: ""); | |||||
//app.UseFacebookAuthentication( | |||||
// appId: "", | |||||
// appSecret: ""); | |||||
//app.UseGoogleAuthentication(new GoogleOAuth2AuthenticationOptions() | |||||
//{ | |||||
// ClientId = "", | |||||
// ClientSecret = "" | |||||
//}); | |||||
} | |||||
} | |||||
} |
@ -0,0 +1,79 @@ | |||||
<?xml version="1.0" encoding="utf-8"?> | |||||
<ApplicationInsights xmlns="http://schemas.microsoft.com/ApplicationInsights/2013/Settings"> | |||||
<TelemetryInitializers> | |||||
<Add Type="Microsoft.ApplicationInsights.DependencyCollector.HttpDependenciesParsingTelemetryInitializer, Microsoft.AI.DependencyCollector"/> | |||||
<Add Type="Microsoft.ApplicationInsights.WindowsServer.AzureRoleEnvironmentTelemetryInitializer, Microsoft.AI.WindowsServer"/> | |||||
<Add Type="Microsoft.ApplicationInsights.WindowsServer.AzureWebAppRoleEnvironmentTelemetryInitializer, Microsoft.AI.WindowsServer"/> | |||||
<Add Type="Microsoft.ApplicationInsights.WindowsServer.BuildInfoConfigComponentVersionTelemetryInitializer, Microsoft.AI.WindowsServer"/> | |||||
<Add Type="Microsoft.ApplicationInsights.Web.WebTestTelemetryInitializer, Microsoft.AI.Web"/> | |||||
<Add Type="Microsoft.ApplicationInsights.Web.SyntheticUserAgentTelemetryInitializer, Microsoft.AI.Web"> | |||||
<!-- Extended list of bots: | |||||
search|spider|crawl|Bot|Monitor|BrowserMob|BingPreview|PagePeeker|WebThumb|URL2PNG|ZooShot|GomezA|Google SketchUp|Read Later|KTXN|KHTE|Keynote|Pingdom|AlwaysOn|zao|borg|oegp|silk|Xenu|zeal|NING|htdig|lycos|slurp|teoma|voila|yahoo|Sogou|CiBra|Nutch|Java|JNLP|Daumoa|Genieo|ichiro|larbin|pompos|Scrapy|snappy|speedy|vortex|favicon|indexer|Riddler|scooter|scraper|scrubby|WhatWeb|WinHTTP|voyager|archiver|Icarus6j|mogimogi|Netvibes|altavista|charlotte|findlinks|Retreiver|TLSProber|WordPress|wsr-agent|http client|Python-urllib|AppEngine-Google|semanticdiscovery|facebookexternalhit|web/snippet|Google-HTTP-Java-Client--> | |||||
<Filters>search|spider|crawl|Bot|Monitor|AlwaysOn</Filters> | |||||
</Add> | |||||
<Add Type="Microsoft.ApplicationInsights.Web.ClientIpHeaderTelemetryInitializer, Microsoft.AI.Web"/> | |||||
<Add Type="Microsoft.ApplicationInsights.Web.OperationNameTelemetryInitializer, Microsoft.AI.Web"/> | |||||
<Add Type="Microsoft.ApplicationInsights.Web.OperationCorrelationTelemetryInitializer, Microsoft.AI.Web"/> | |||||
<Add Type="Microsoft.ApplicationInsights.Web.UserTelemetryInitializer, Microsoft.AI.Web"/> | |||||
<Add Type="Microsoft.ApplicationInsights.Web.AuthenticatedUserIdTelemetryInitializer, Microsoft.AI.Web"/> | |||||
<Add Type="Microsoft.ApplicationInsights.Web.AccountIdTelemetryInitializer, Microsoft.AI.Web"/> | |||||
<Add Type="Microsoft.ApplicationInsights.Web.SessionTelemetryInitializer, Microsoft.AI.Web"/> | |||||
</TelemetryInitializers> | |||||
<TelemetryModules> | |||||
<Add Type="Microsoft.ApplicationInsights.DependencyCollector.DependencyTrackingTelemetryModule, Microsoft.AI.DependencyCollector"/> | |||||
<Add Type="Microsoft.ApplicationInsights.Extensibility.PerfCounterCollector.PerformanceCollectorModule, Microsoft.AI.PerfCounterCollector"> | |||||
<!-- | |||||
Use the following syntax here to collect additional performance counters: | |||||
<Counters> | |||||
<Add PerformanceCounter="\Process(??APP_WIN32_PROC??)\Handle Count" ReportAs="Process handle count" /> | |||||
... | |||||
</Counters> | |||||
PerformanceCounter must be either \CategoryName(InstanceName)\CounterName or \CategoryName\CounterName | |||||
NOTE: performance counters configuration will be lost upon NuGet upgrade. | |||||
The following placeholders are supported as InstanceName: | |||||
??APP_WIN32_PROC?? - instance name of the application process for Win32 counters. | |||||
??APP_W3SVC_PROC?? - instance name of the application IIS worker process for IIS/ASP.NET counters. | |||||
??APP_CLR_PROC?? - instance name of the application CLR process for .NET counters. | |||||
--> | |||||
</Add> | |||||
<Add Type="Microsoft.ApplicationInsights.Extensibility.PerfCounterCollector.QuickPulse.QuickPulseTelemetryModule, Microsoft.AI.PerfCounterCollector"/> | |||||
<Add Type="Microsoft.ApplicationInsights.WindowsServer.DeveloperModeWithDebuggerAttachedTelemetryModule, Microsoft.AI.WindowsServer"/> | |||||
<Add Type="Microsoft.ApplicationInsights.WindowsServer.UnhandledExceptionTelemetryModule, Microsoft.AI.WindowsServer"/> | |||||
<Add Type="Microsoft.ApplicationInsights.WindowsServer.UnobservedExceptionTelemetryModule, Microsoft.AI.WindowsServer"/> | |||||
<Add Type="Microsoft.ApplicationInsights.Web.RequestTrackingTelemetryModule, Microsoft.AI.Web"> | |||||
<Handlers> | |||||
<!-- | |||||
Add entries here to filter out additional handlers: | |||||
NOTE: handler configuration will be lost upon NuGet upgrade. | |||||
--> | |||||
<Add>System.Web.Handlers.TransferRequestHandler</Add> | |||||
<Add>Microsoft.VisualStudio.Web.PageInspector.Runtime.Tracing.RequestDataHttpHandler</Add> | |||||
<Add>System.Web.StaticFileHandler</Add> | |||||
<Add>System.Web.Handlers.AssemblyResourceLoader</Add> | |||||
<Add>System.Web.Optimization.BundleHandler</Add> | |||||
<Add>System.Web.Script.Services.ScriptHandlerFactory</Add> | |||||
<Add>System.Web.Handlers.TraceHandler</Add> | |||||
<Add>System.Web.Services.Discovery.DiscoveryRequestHandler</Add> | |||||
<Add>System.Web.HttpDebugHandler</Add> | |||||
</Handlers> | |||||
</Add> | |||||
<Add Type="Microsoft.ApplicationInsights.Web.ExceptionTrackingTelemetryModule, Microsoft.AI.Web"/> | |||||
</TelemetryModules> | |||||
<TelemetryProcessors> | |||||
<Add Type="Microsoft.ApplicationInsights.Extensibility.PerfCounterCollector.QuickPulse.QuickPulseTelemetryProcessor, Microsoft.AI.PerfCounterCollector"/> | |||||
<Add Type="Microsoft.ApplicationInsights.WindowsServer.TelemetryChannel.AdaptiveSamplingTelemetryProcessor, Microsoft.AI.ServerTelemetryChannel"> | |||||
<MaxTelemetryItemsPerSecond>5</MaxTelemetryItemsPerSecond> | |||||
</Add> | |||||
</TelemetryProcessors> | |||||
<TelemetryChannel Type="Microsoft.ApplicationInsights.WindowsServer.TelemetryChannel.ServerTelemetryChannel, Microsoft.AI.ServerTelemetryChannel"/> | |||||
<!-- | |||||
Learn more about Application Insights configuration with ApplicationInsights.config here: | |||||
http://go.microsoft.com/fwlink/?LinkID=513840 | |||||
Note: If not present, please add <InstrumentationKey>Your Key</InstrumentationKey> to the top of this file. | |||||
--></ApplicationInsights> |
@ -0,0 +1,7 @@ | |||||
<?xml version="1.0" encoding="utf-8" ?> | |||||
<bundles version="1.0"> | |||||
<styleBundle path="~/Content/css"> | |||||
<include path="~/Content/bootstrap.css" /> | |||||
<include path="~/Content/Site.css" /> | |||||
</styleBundle> | |||||
</bundles> |
@ -0,0 +1,17 @@ | |||||
<%@ Page Title="Contact" Language="C#" MasterPageFile="~/Site.Master" AutoEventWireup="true" CodeBehind="Contact.aspx.cs" Inherits="eShopOnContainers.Catalog.WebForms.Contact" %> | |||||
<asp:Content ID="BodyContent" ContentPlaceHolderID="MainContent" runat="server"> | |||||
<h2><%: Title %>.</h2> | |||||
<h3>Your contact page.</h3> | |||||
<address> | |||||
One Microsoft Way<br /> | |||||
Redmond, WA 98052-6399<br /> | |||||
<abbr title="Phone">P:</abbr> | |||||
425.555.0100 | |||||
</address> | |||||
<address> | |||||
<strong>Support:</strong> <a href="mailto:Support@example.com">Support@example.com</a><br /> | |||||
<strong>Marketing:</strong> <a href="mailto:Marketing@example.com">Marketing@example.com</a> | |||||
</address> | |||||
</asp:Content> |
@ -0,0 +1,17 @@ | |||||
using System; | |||||
using System.Collections.Generic; | |||||
using System.Linq; | |||||
using System.Web; | |||||
using System.Web.UI; | |||||
using System.Web.UI.WebControls; | |||||
namespace eShopOnContainers.Catalog.WebForms | |||||
{ | |||||
public partial class Contact : Page | |||||
{ | |||||
protected void Page_Load(object sender, EventArgs e) | |||||
{ | |||||
} | |||||
} | |||||
} |
@ -0,0 +1,17 @@ | |||||
//------------------------------------------------------------------------------ | |||||
// <auto-generated> | |||||
// This code was generated by a tool. | |||||
// | |||||
// Changes to this file may cause incorrect behavior and will be lost if | |||||
// the code is regenerated. | |||||
// </auto-generated> | |||||
//------------------------------------------------------------------------------ | |||||
namespace eShopOnContainers.Catalog.WebForms | |||||
{ | |||||
public partial class Contact | |||||
{ | |||||
} | |||||
} |
@ -0,0 +1,38 @@ | |||||
/* Move down content because we have a fixed navbar that is 50px tall */ | |||||
body { | |||||
padding-top: 50px; | |||||
padding-bottom: 20px; | |||||
} | |||||
/* Wrapping element */ | |||||
/* Set some basic padding to keep content from hitting the edges */ | |||||
.body-content { | |||||
padding-left: 15px; | |||||
padding-right: 15px; | |||||
} | |||||
/* Override the default bootstrap behavior where horizontal description lists | |||||
will truncate terms that are too long to fit in the left column | |||||
*/ | |||||
.dl-horizontal dt { | |||||
white-space: normal; | |||||
} | |||||
/* Set widths on the form inputs since otherwise they're 100% wide */ | |||||
input[type="text"], | |||||
input[type="password"], | |||||
input[type="email"], | |||||
input[type="tel"], | |||||
input[type="select"] { | |||||
max-width: 280px; | |||||
} | |||||
/* Responsive: Portrait tablets and up */ | |||||
@media screen and (min-width: 768px) { | |||||
.jumbotron { | |||||
margin-top: 20px; | |||||
} | |||||
.body-content { | |||||
padding: 0; | |||||
} | |||||
} |
@ -0,0 +1,24 @@ | |||||
.esh-app-footer { | |||||
background-color: #000000; | |||||
border-top: 1px solid #EEEEEE; | |||||
margin-top: 2.5rem; | |||||
padding-bottom: 2.5rem; | |||||
padding-top: 2.5rem; | |||||
width: 100%; | |||||
} | |||||
.esh-app-footer-brand { | |||||
height: 50px; | |||||
width: 230px; | |||||
} | |||||
.esh-app-footer-text { | |||||
color: #83D01B; | |||||
line-height: 50px; | |||||
text-align: right; | |||||
width: 100%; | |||||
} | |||||
.table-full-width { | |||||
width: 100%; | |||||
} |
@ -0,0 +1,156 @@ | |||||
.esh-catalog-hero { | |||||
background-image: url("../Content/main_banner.png"); | |||||
background-size: cover; | |||||
height: 260px; | |||||
width: 100%; | |||||
} | |||||
.esh-catalog-title { | |||||
position: relative; | |||||
top: 74.28571px; | |||||
} | |||||
/* | |||||
.esh-catalog-filters { | |||||
background-color: #00A69C; | |||||
height: 65px; | |||||
} | |||||
.esh-catalog-filter { | |||||
background-color: transparent; | |||||
border-color: #00d9cc; | |||||
color: #FFFFFF; | |||||
cursor: pointer; | |||||
margin-right: 1rem; | |||||
margin-top: .5rem; | |||||
outline-color: #83D01B; | |||||
padding-bottom: 0; | |||||
padding-left: 0.5rem; | |||||
padding-right: 0.5rem; | |||||
padding-top: 1.5rem; | |||||
min-width: 140px; | |||||
-webkit-appearance: none; | |||||
} | |||||
.esh-catalog-filter option { | |||||
background-color: #00A69C; | |||||
} | |||||
*/ | |||||
.esh-catalog-label { | |||||
display: inline-block; | |||||
position: relative; | |||||
z-index: 0; | |||||
} | |||||
.esh-catalog-label::before { | |||||
color: rgba(255, 255, 255, 0.5); | |||||
content: attr(data-title); | |||||
font-size: 0.65rem; | |||||
margin-top: 0.65rem; | |||||
margin-left: 0.5rem; | |||||
position: absolute; | |||||
text-transform: uppercase; | |||||
z-index: 1; | |||||
} | |||||
.esh-catalog-label::after { | |||||
background-image: url("../../images/arrow-down.png"); | |||||
height: 7px; | |||||
content: ''; | |||||
position: absolute; | |||||
right: 1.5rem; | |||||
top: 2.5rem; | |||||
width: 10px; | |||||
z-index: 1; | |||||
} | |||||
/* | |||||
.esh-catalog-send { | |||||
background-color: #83D01B; | |||||
color: #FFFFFF; | |||||
cursor: pointer; | |||||
font-size: 1rem; | |||||
transform: translateY(.5rem); | |||||
padding: 0.5rem; | |||||
transition: all 0.35s; | |||||
} | |||||
.esh-catalog-send:hover { | |||||
background-color: #4a760f; | |||||
transition: all 0.35s; | |||||
} | |||||
.esh-catalog-items { | |||||
margin-top: 1rem; | |||||
} | |||||
.esh-catalog-item { | |||||
text-align: center; | |||||
margin-bottom: 1.5rem; | |||||
width: 33%; | |||||
display: inline-block; | |||||
float: none !important; | |||||
} | |||||
@media screen and (max-width: 1024px) { | |||||
.esh-catalog-item { | |||||
width: 50%; | |||||
} | |||||
} | |||||
@media screen and (max-width: 768px) { | |||||
.esh-catalog-item { | |||||
width: 100%; | |||||
} | |||||
} | |||||
*/ | |||||
.esh-catalog-thumbnail { | |||||
max-width: 370px; | |||||
width: 100%; | |||||
} | |||||
/* | |||||
.esh-catalog-button { | |||||
background-color: #83D01B; | |||||
border: none; | |||||
color: #FFFFFF; | |||||
cursor: pointer; | |||||
font-size: 1rem; | |||||
height: 3rem; | |||||
margin-top: 1rem; | |||||
transition: all 0.35s; | |||||
width: 80%; | |||||
} | |||||
.esh-catalog-button.is-disabled { | |||||
opacity: .5; | |||||
pointer-events: none; | |||||
} | |||||
.esh-catalog-button:hover { | |||||
background-color: #4a760f; | |||||
transition: all 0.35s; | |||||
} | |||||
*/ | |||||
.esh-catalog-name { | |||||
font-size: 1rem; | |||||
font-weight: 300; | |||||
margin-top: .5rem; | |||||
text-align: center; | |||||
text-transform: uppercase; | |||||
} | |||||
.esh-catalog-price { | |||||
text-align: center; | |||||
font-weight: 900; | |||||
font-size: 28px; | |||||
} | |||||
/* | |||||
.esh-catalog-price::before { | |||||
content: '$'; | |||||
} | |||||
*/ |
@ -0,0 +1,56 @@ | |||||
<%@ Page Title="eShopOnContainers - Home Page" Language="C#" MasterPageFile="~/Site.Master" AutoEventWireup="true" | |||||
CodeBehind="Default.aspx.cs" Inherits="eShopOnContainers.Catalog.WebForms._Default" Async="true" %> | |||||
<asp:Content ID="BodyContent" ContentPlaceHolderID="MainContent" runat="server"> | |||||
<asp:ListView ID="catalogList" runat="server" | |||||
DataKeyNames="Id" GroupItemCount="3" | |||||
ItemType="eShopOnContainers.Core.Models.Catalog.CatalogItem" | |||||
SelectMethod="GetCatalogDataAsync" | |||||
DeleteMethod="DeleteCatalogItemAsync"> | |||||
<EmptyDataTemplate> | |||||
<div class="row"> | |||||
<span class="col-md-10 col-md-offset-1">There's nothing in the catalog to display at this time. | |||||
</span> | |||||
</div> | |||||
</EmptyDataTemplate> | |||||
<LayoutTemplate> | |||||
<div id="groupPlaceholder" runat="server"></div> | |||||
</LayoutTemplate> | |||||
<GroupTemplate> | |||||
<div id="itemPlaceholderConatiner" class="row"> | |||||
<div id="itemPlaceholder" runat="server"></div> | |||||
</div> | |||||
<br /> | |||||
<br /> | |||||
</GroupTemplate> | |||||
<ItemTemplate> | |||||
<div class="col-md-4"> | |||||
<a href="EditCatalogItem.aspx?id=<%#:Item.Id%>"> | |||||
<img class="esh-catalog-thumbnail" src="<%#:Item.PictureUri%>" | |||||
style="border: solid" /> | |||||
<br /> | |||||
<span class="esh-catalog-name"> | |||||
<%#:Item.Name%> | |||||
</span> | |||||
<br /> | |||||
<span class="esh-catalog-price"> | |||||
<b>Price: </b><%#:String.Format("{0:c}", Item.Price)%> | |||||
</span> | |||||
<br /> | |||||
</a> | |||||
<span class="esh-catalog-label"> | |||||
<asp:LinkButton ID="DeleteItem" CommandArgument="<%= Item.Id %>" | |||||
runat="server" CommandName="Delete" | |||||
Text="Delete">Delete</asp:LinkButton> | |||||
</span> | |||||
</div> | |||||
</ItemTemplate> | |||||
</asp:ListView> | |||||
<div class="row"> | |||||
<span class="esh-catalog-label col-md-4 col-md-offset-2l"> | |||||
<a href="EditCatalogItem.aspx"> | |||||
Insert item | |||||
</a> | |||||
</span> | |||||
</div> | |||||
</asp:Content> |
@ -0,0 +1,24 @@ | |||||
//------------------------------------------------------------------------------ | |||||
// <auto-generated> | |||||
// This code was generated by a tool. | |||||
// | |||||
// Changes to this file may cause incorrect behavior and will be lost if | |||||
// the code is regenerated. | |||||
// </auto-generated> | |||||
//------------------------------------------------------------------------------ | |||||
namespace eShopOnContainers.Catalog.WebForms { | |||||
public partial class _Default { | |||||
/// <summary> | |||||
/// catalogList 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.ListView catalogList; | |||||
} | |||||
} |
@ -0,0 +1,4 @@ | |||||
FROM microsoft/aspnet | |||||
ARG source | |||||
WORKDIR /inetpub/wwwroot | |||||
COPY ${source:-obj/Docker/publish} . |
@ -0,0 +1,129 @@ | |||||
<%@ Page Title="" Language="C#" MasterPageFile="~/Site.Master" AutoEventWireup="true" CodeBehind="EditCatalogItem.aspx.cs" Inherits="eShopOnContainers.Catalog.WebForms.EditCatalogItem" Async="true" %> | |||||
<asp:Content ID="Content1" ContentPlaceHolderID="MainContent" runat="server"> | |||||
<asp:FormView ID="EditCatalogItemForm" runat="server" DefaultMode="Edit" | |||||
ItemType="eShopOnContainers.Core.Models.Catalog.CatalogItem" DataKeyNames="Id" | |||||
SelectMethod="GetCatalogItemAsync" | |||||
UpdateMethod="UpdateCatalogItemAsync" | |||||
InsertMethod="InsertCatalogItemAsync" | |||||
CssClass="table-compact table-full-width"> | |||||
<EditItemTemplate> | |||||
<div class="row form-inline"> | |||||
<div class="col-md-6"> | |||||
<img class="esh-catalog-thumbnail" src="<%#:Item.PictureUri%>" | |||||
style="border: solid" /> | |||||
</div> | |||||
<div class="col-md-6"> | |||||
<div class="container"> | |||||
<div class="row"> | |||||
<div class="col-md-12 form-group"> | |||||
<label>Name</label> | |||||
<asp:TextBox runat="server" ID="itemName" CssClass="form-control form-input form-input-center" Text='<%# Bind("Name")%>' /> | |||||
</div> | |||||
</div> | |||||
<div class="row"> | |||||
<div class="col-md-12 form-group"> | |||||
<label for="ItemDescription">Description</label> | |||||
<asp:TextBox runat="server" Width="100%" ID="ItemDescription" CssClass="form-control form-input form-input-center" Text='<%# Bind("Description")%>' /> | |||||
</div> | |||||
</div> | |||||
<div class="row"> | |||||
<div class="col-md-12 form-group"> | |||||
<label for="ItemPrice">Price</label> | |||||
<asp:TextBox runat="server" TextMode="Number" Width="75%" ID="ItemPrice" CssClass="form-control form-input form-input-center" Text='<%# Bind("Price")%>' /> | |||||
</div> | |||||
</div> | |||||
<div class="row"> | |||||
<div class="col-md-12 form-group"> | |||||
<label class="control-label form-label" for="ItemBrand">Brand</label> | |||||
<asp:DropDownList ID="ItemBrand" runat="server" | |||||
ItemType="eShopOnContainers.Core.Models.Catalog.CatalogBrand" | |||||
SelectMethod="GetBrandsAsync" | |||||
DataTextField="Brand" | |||||
DataValueField="Id" | |||||
SelectedValue="<%# BindItem.CatalogBrandId %>" /> | |||||
</div> | |||||
</div> | |||||
<div class="row"> | |||||
<div class="col-md-12 form-group"> | |||||
<label class="control-label form-label" for="ItemType">Type</label> | |||||
<asp:DropDownList ID="ItemType" runat="server" | |||||
SelectMethod="GetTypesAsync" | |||||
DataTextField="Type" | |||||
DataValueField="Id" | |||||
SelectedValue="<%# BindItem.CatalogTypeId %>" /> | |||||
</div> | |||||
</div> | |||||
<div class="row"> | |||||
<div class="col-md-6 form-group"> | |||||
<asp:LinkButton runat="server" Text="Update" CommandName="Update" /> | |||||
</div> | |||||
<div class="col-md-6 form-group"> | |||||
<asp:LinkButton runat="server" Text="Cancel" CommandName="Cancel" /> | |||||
</div> | |||||
</div> | |||||
</div> | |||||
</div> | |||||
</div> | |||||
</EditItemTemplate> | |||||
<InsertItemTemplate> | |||||
<div class="row form-inline"> | |||||
<div class="col-md-6"> | |||||
<asp:FileUpload CssClass="esh-catalog-thumbnail" runat="server" /> | |||||
</div> | |||||
<div class="col-md-6"> | |||||
<div class="container"> | |||||
<div class="row"> | |||||
<div class="col-md-12 form-group"> | |||||
<label>Name</label> | |||||
<asp:TextBox runat="server" ID="itemName" CssClass="form-control form-input form-input-center" Text='<%# Bind("Name")%>' /> | |||||
</div> | |||||
</div> | |||||
<div class="row"> | |||||
<div class="col-md-12 form-group"> | |||||
<label for="ItemDescription">Description</label> | |||||
<asp:TextBox runat="server" Width="100%" ID="ItemDescription" CssClass="form-control form-input form-input-center" Text='<%# Bind("Description")%>' /> | |||||
</div> | |||||
</div> | |||||
<div class="row"> | |||||
<div class="col-md-12 form-group"> | |||||
<label for="ItemPrice">Price</label> | |||||
<asp:TextBox runat="server" TextMode="Number" Width="75%" ID="ItemPrice" CssClass="form-control form-input form-input-center" Text='<%# Bind("Price")%>' /> | |||||
</div> | |||||
</div> | |||||
<div class="row"> | |||||
<div class="col-md-12 form-group"> | |||||
<label class="control-label form-label" for="ItemBrand">Brand</label> | |||||
<asp:DropDownList ID="ItemBrand" runat="server" | |||||
ItemType="eShopOnContainers.Core.Models.Catalog.CatalogBrand" | |||||
SelectMethod="GetBrandsAsync" | |||||
DataTextField="Brand" | |||||
DataValueField="Id" | |||||
SelectedValue="<%# BindItem.CatalogBrandId %>" /> | |||||
</div> | |||||
</div> | |||||
<div class="row"> | |||||
<div class="col-md-12 form-group"> | |||||
<label class="control-label form-label" for="ItemType">Type</label> | |||||
<asp:DropDownList ID="ItemType" runat="server" | |||||
SelectMethod="GetTypesAsync" | |||||
DataTextField="Type" | |||||
DataValueField="Id" | |||||
SelectedValue="<%# BindItem.CatalogTypeId %>" /> | |||||
</div> | |||||
</div> | |||||
<div class="row"> | |||||
<div class="col-md-6 form-group"> | |||||
<asp:LinkButton runat="server" Text="Add" CommandName="Insert" /> | |||||
</div> | |||||
<div class="col-md-6 form-group"> | |||||
<asp:LinkButton runat="server" Text="Cancel" CommandName="Cancel" /> | |||||
</div> | |||||
</div> | |||||
</div> | |||||
</div> | |||||
</div> | |||||
</InsertItemTemplate> | |||||
</asp:FormView> | |||||
</asp:Content> |
@ -0,0 +1,90 @@ | |||||
using eShopOnContainers.Core.Models.Catalog; | |||||
using eShopOnContainers.Core.Services.Catalog; | |||||
using System; | |||||
using System.Collections.Generic; | |||||
using System.Linq; | |||||
using System.Threading.Tasks; | |||||
using System.Web; | |||||
using System.Web.ModelBinding; | |||||
using System.Web.UI; | |||||
using System.Web.UI.WebControls; | |||||
namespace eShopOnContainers.Catalog.WebForms | |||||
{ | |||||
public partial class EditCatalogItem : System.Web.UI.Page | |||||
{ | |||||
private ICatalogService catalog; | |||||
public IEnumerable<CatalogBrand> Brands; | |||||
public IEnumerable<CatalogType> Types; | |||||
protected EditCatalogItem() { } | |||||
public EditCatalogItem(ICatalogService catalog) | |||||
{ | |||||
this.catalog = catalog; | |||||
} | |||||
protected void Page_Load(object sender, EventArgs e) | |||||
{ | |||||
} | |||||
// The id parameter should match the DataKeyNames value set on the control | |||||
// or be decorated with a value provider attribute, e.g. [QueryString]int id | |||||
public async Task<CatalogItem> GetCatalogItemAsync([QueryString]int? id) | |||||
{ | |||||
if (id.HasValue) | |||||
{ | |||||
var itemToEdit = await catalog?.GetCatalogItemAsync(id.ToString()); | |||||
return itemToEdit; | |||||
} | |||||
else | |||||
{ | |||||
EditCatalogItemForm.ChangeMode(FormViewMode.Insert); | |||||
return new CatalogItem(); | |||||
} | |||||
} | |||||
// The id parameter name should match the DataKeyNames value set on the control | |||||
public async Task UpdateCatalogItemAsync(int id) | |||||
{ | |||||
CatalogItem item = await catalog?.GetCatalogItemAsync(id.ToString()); | |||||
if (item == null) | |||||
{ | |||||
// The item wasn't found | |||||
ModelState.AddModelError("", String.Format("Item with id {0} was not found", id)); | |||||
return; | |||||
} | |||||
if (TryUpdateModel(item) && (ModelState.IsValid)) | |||||
{ | |||||
await catalog?.UpdateCatalogItemAsync(item); | |||||
Response.Redirect("~"); | |||||
} | |||||
} | |||||
public async Task InsertCatalogItemAsync() | |||||
{ | |||||
var item = new eShopOnContainers.Core.Models.Catalog.CatalogItem(); | |||||
TryUpdateModel(item); | |||||
if (ModelState.IsValid) | |||||
{ | |||||
// Save changes here | |||||
await catalog?.CreateCatalogItemAsync(item); | |||||
Response.Redirect("~"); | |||||
} | |||||
} | |||||
public async Task<IEnumerable<CatalogBrand>> GetBrandsAsync() | |||||
{ | |||||
var brands = await catalog?.GetCatalogBrandAsync(); | |||||
return brands.AsEnumerable(); | |||||
} | |||||
public async Task<IEnumerable<CatalogType>> GetTypesAsync() | |||||
{ | |||||
var types = await catalog?.GetCatalogTypeAsync(); | |||||
return types.AsEnumerable(); | |||||
} | |||||
} | |||||
} |
@ -0,0 +1,24 @@ | |||||
//------------------------------------------------------------------------------ | |||||
// <auto-generated> | |||||
// This code was generated by a tool. | |||||
// | |||||
// Changes to this file may cause incorrect behavior and will be lost if | |||||
// the code is regenerated. | |||||
// </auto-generated> | |||||
//------------------------------------------------------------------------------ | |||||
namespace eShopOnContainers.Catalog.WebForms { | |||||
public partial class EditCatalogItem { | |||||
/// <summary> | |||||
/// EditCatalogItemForm 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.FormView EditCatalogItemForm; | |||||
} | |||||
} |
@ -0,0 +1,28 @@ | |||||
using System.Collections.Generic; | |||||
using System.Collections.ObjectModel; | |||||
namespace eShopOnContainers.Core.Extensions | |||||
{ | |||||
public static class ObservableExtension | |||||
{ | |||||
public static ObservableCollection<T> ToObservableCollection<T>(this IEnumerable<T> source) | |||||
{ | |||||
ObservableCollection<T> collection = new ObservableCollection<T>(); | |||||
try | |||||
{ | |||||
foreach (T item in source) | |||||
{ | |||||
collection.Add(item); | |||||
} | |||||
return collection; | |||||
} | |||||
// Really? | |||||
catch | |||||
{ | |||||
return collection; | |||||
} | |||||
} | |||||
} | |||||
} |
@ -0,0 +1 @@ | |||||
<%@ Application Codebehind="Global.asax.cs" Inherits="eShopOnContainers.Catalog.WebForms.Global" Language="C#" %> |
@ -1,19 +1,21 @@ | |||||
using System; | using System; | ||||
using System.Collections.Generic; | |||||
using System.Linq; | |||||
using System.Web; | using System.Web; | ||||
using System.Web.Optimization; | using System.Web.Optimization; | ||||
using System.Web.Routing; | using System.Web.Routing; | ||||
using System.Web.Security; | |||||
using System.Web.SessionState; | |||||
namespace Microsoft.eShopOnContainers.Catalog.WebForms | |||||
namespace eShopOnContainers.Catalog.WebForms | |||||
{ | { | ||||
public class Global : HttpApplication | public class Global : HttpApplication | ||||
{ | { | ||||
void Application_Start(object sender, EventArgs e) | void Application_Start(object sender, EventArgs e) | ||||
{ | { | ||||
// Code that runs on application startup | // Code that runs on application startup | ||||
RouteConfig.RegisterRoutes(RouteTable.Routes); | RouteConfig.RegisterRoutes(RouteTable.Routes); | ||||
BundleConfig.RegisterBundles(BundleTable.Bundles); | BundleConfig.RegisterBundles(BundleTable.Bundles); | ||||
} | } | ||||
} | } | ||||
} | } |
@ -0,0 +1,13 @@ | |||||
// Taken from https://github.com/dotnet/eShopOnContainers/blob/vs2017/src/Mobile/eShopOnContainers/eShopOnContainers.Core/Models/Catalog/CatalogBrand.cs | |||||
// Issue: How to make this DRY and still support the monolithic lift and shift scenario? | |||||
namespace eShopOnContainers.Core.Models.Catalog | |||||
{ | |||||
public class CatalogBrand | |||||
{ | |||||
public int Id { get; set; } | |||||
public string Brand { get; set; } | |||||
public override string ToString() => Brand; | |||||
} | |||||
} |
@ -0,0 +1,17 @@ | |||||
// Taken from https://github.com/dotnet/eShopOnContainers/blob/vs2017/src/Mobile/eShopOnContainers/eShopOnContainers.Core/Models/Catalog/CatalogItem.cs | |||||
// Issue: How to make this DRY and still support the monolithic lift and shift scenario? | |||||
namespace eShopOnContainers.Core.Models.Catalog | |||||
{ | |||||
public class CatalogItem | |||||
{ | |||||
public string Id { get; set; } | |||||
public string Name { get; set; } | |||||
public string Description { get; set; } | |||||
public decimal Price { get; set; } | |||||
public string PictureUri { get; set; } | |||||
public int CatalogBrandId { get; set; } | |||||
public string CatalogBrand { get; set; } | |||||
public int CatalogTypeId { get; set; } | |||||
public string CatalogType { get; set; } | |||||
} | |||||
} |
@ -0,0 +1,12 @@ | |||||
using System.Collections.Generic; | |||||
namespace eShopOnContainers.Core.Models.Catalog | |||||
{ | |||||
public class CatalogRoot | |||||
{ | |||||
public int PageIndex { get; set; } | |||||
public int PageSize { get; set; } | |||||
public int Count { get; set; } | |||||
public List<CatalogItem> Data { get; set; } | |||||
} | |||||
} |
@ -0,0 +1,12 @@ | |||||
// Taken from https://github.com/dotnet/eShopOnContainers/blob/vs2017/src/Mobile/eShopOnContainers/eShopOnContainers.Core/Models/Catalog/CatalogType.cs | |||||
// Issue: How to make this DRY and still support the monolithic lift and shift scenario? | |||||
namespace eShopOnContainers.Core.Models.Catalog | |||||
{ | |||||
public class CatalogType | |||||
{ | |||||
public int Id { get; set; } | |||||
public string Type { get; set; } | |||||
public override string ToString() => Type; | |||||
} | |||||
} |
@ -0,0 +1,100 @@ | |||||
using System; | |||||
using System.Security.Claims; | |||||
using System.Threading.Tasks; | |||||
using System.Web; | |||||
using Microsoft.AspNet.Identity; | |||||
using Microsoft.AspNet.Identity.EntityFramework; | |||||
using Microsoft.AspNet.Identity.Owin; | |||||
using Microsoft.Owin.Security; | |||||
using eShopOnContainers.Catalog.WebForms.Models; | |||||
namespace eShopOnContainers.Catalog.WebForms.Models | |||||
{ | |||||
// You can add User data for the user by adding more properties to your User class, please visit https://go.microsoft.com/fwlink/?LinkID=317594 to learn more. | |||||
public class ApplicationUser : IdentityUser | |||||
{ | |||||
public ClaimsIdentity GenerateUserIdentity(ApplicationUserManager manager) | |||||
{ | |||||
// Note the authenticationType must match the one defined in CookieAuthenticationOptions.AuthenticationType | |||||
var userIdentity = manager.CreateIdentity(this, DefaultAuthenticationTypes.ApplicationCookie); | |||||
// Add custom user claims here | |||||
return userIdentity; | |||||
} | |||||
public Task<ClaimsIdentity> GenerateUserIdentityAsync(ApplicationUserManager manager) | |||||
{ | |||||
return Task.FromResult(GenerateUserIdentity(manager)); | |||||
} | |||||
} | |||||
public class ApplicationDbContext : IdentityDbContext<ApplicationUser> | |||||
{ | |||||
public ApplicationDbContext() | |||||
: base("DefaultConnection", throwIfV1Schema: false) | |||||
{ | |||||
} | |||||
public static ApplicationDbContext Create() | |||||
{ | |||||
return new ApplicationDbContext(); | |||||
} | |||||
} | |||||
} | |||||
#region Helpers | |||||
namespace eShopOnContainers.Catalog.WebForms | |||||
{ | |||||
public static class IdentityHelper | |||||
{ | |||||
// Used for XSRF when linking external logins | |||||
public const string XsrfKey = "XsrfId"; | |||||
public const string ProviderNameKey = "providerName"; | |||||
public static string GetProviderNameFromRequest(HttpRequest request) | |||||
{ | |||||
return request.QueryString[ProviderNameKey]; | |||||
} | |||||
public const string CodeKey = "code"; | |||||
public static string GetCodeFromRequest(HttpRequest request) | |||||
{ | |||||
return request.QueryString[CodeKey]; | |||||
} | |||||
public const string UserIdKey = "userId"; | |||||
public static string GetUserIdFromRequest(HttpRequest request) | |||||
{ | |||||
return HttpUtility.UrlDecode(request.QueryString[UserIdKey]); | |||||
} | |||||
public static string GetResetPasswordRedirectUrl(string code, HttpRequest request) | |||||
{ | |||||
var absoluteUri = "/Account/ResetPassword?" + CodeKey + "=" + HttpUtility.UrlEncode(code); | |||||
return new Uri(request.Url, absoluteUri).AbsoluteUri.ToString(); | |||||
} | |||||
public static string GetUserConfirmationRedirectUrl(string code, string userId, HttpRequest request) | |||||
{ | |||||
var absoluteUri = "/Account/Confirm?" + CodeKey + "=" + HttpUtility.UrlEncode(code) + "&" + UserIdKey + "=" + HttpUtility.UrlEncode(userId); | |||||
return new Uri(request.Url, absoluteUri).AbsoluteUri.ToString(); | |||||
} | |||||
private static bool IsLocalUrl(string url) | |||||
{ | |||||
return !string.IsNullOrEmpty(url) && ((url[0] == '/' && (url.Length == 1 || (url[1] != '/' && url[1] != '\\'))) || (url.Length > 1 && url[0] == '~' && url[1] == '/')); | |||||
} | |||||
public static void RedirectToReturnUrl(string returnUrl, HttpResponse response) | |||||
{ | |||||
if (!String.IsNullOrEmpty(returnUrl) && IsLocalUrl(returnUrl)) | |||||
{ | |||||
response.Redirect(returnUrl); | |||||
} | |||||
else | |||||
{ | |||||
response.Redirect("~/"); | |||||
} | |||||
} | |||||
} | |||||
} | |||||
#endregion |
@ -0,0 +1,35 @@ | |||||
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("Catalog.WebForms")] | |||||
[assembly: AssemblyDescription("")] | |||||
[assembly: AssemblyConfiguration("")] | |||||
[assembly: AssemblyCompany("")] | |||||
[assembly: AssemblyProduct("Catalog.WebForms")] | |||||
[assembly: AssemblyCopyright("Copyright © 2017")] | |||||
[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("487a4e92-faa3-415c-a019-6edadb8ab1d9")] | |||||
// 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 Revision and Build Numbers | |||||
// by using the '*' as shown below: | |||||
[assembly: AssemblyVersion("1.0.0.0")] | |||||
[assembly: AssemblyFileVersion("1.0.0.0")] |
@ -0,0 +1,34 @@ | |||||
//CdnPath=http://ajax.aspnetcdn.com/ajax/4.5.1/1/DetailsView.js | |||||
function DetailsView() { | |||||
this.pageIndex = null; | |||||
this.dataKeys = null; | |||||
this.createPropertyString = DetailsView_createPropertyString; | |||||
this.setStateField = DetailsView_setStateValue; | |||||
this.getHiddenFieldContents = DetailsView_getHiddenFieldContents; | |||||
this.stateField = null; | |||||
this.panelElement = null; | |||||
this.callback = null; | |||||
} | |||||
function DetailsView_createPropertyString() { | |||||
return createPropertyStringFromValues_DetailsView(this.pageIndex, this.dataKeys); | |||||
} | |||||
function DetailsView_setStateValue() { | |||||
this.stateField.value = this.createPropertyString(); | |||||
} | |||||
function DetailsView_OnCallback (result, context) { | |||||
var value = new String(result); | |||||
var valsArray = value.split("|"); | |||||
var innerHtml = valsArray[2]; | |||||
for (var i = 3; i < valsArray.length; i++) { | |||||
innerHtml += "|" + valsArray[i]; | |||||
} | |||||
context.panelElement.innerHTML = innerHtml; | |||||
context.stateField.value = createPropertyStringFromValues_DetailsView(valsArray[0], valsArray[1]); | |||||
} | |||||
function DetailsView_getHiddenFieldContents(arg) { | |||||
return arg + "|" + this.stateField.value; | |||||
} | |||||
function createPropertyStringFromValues_DetailsView(pageIndex, dataKeys) { | |||||
var value = new Array(pageIndex, dataKeys); | |||||
return value.join("|"); | |||||
} |
@ -0,0 +1,93 @@ | |||||
//CdnPath=http://ajax.aspnetcdn.com/ajax/4.5.1/1/WebForms.js | |||||
function WebForm_FindFirstFocusableChild(control) { | |||||
if (!control || !(control.tagName)) { | |||||
return null; | |||||
} | |||||
var tagName = control.tagName.toLowerCase(); | |||||
if (tagName == "undefined") { | |||||
return null; | |||||
} | |||||
var children = control.childNodes; | |||||
if (children) { | |||||
for (var i = 0; i < children.length; i++) { | |||||
try { | |||||
if (WebForm_CanFocus(children[i])) { | |||||
return children[i]; | |||||
} | |||||
else { | |||||
var focused = WebForm_FindFirstFocusableChild(children[i]); | |||||
if (WebForm_CanFocus(focused)) { | |||||
return focused; | |||||
} | |||||
} | |||||
} catch (e) { | |||||
} | |||||
} | |||||
} | |||||
return null; | |||||
} | |||||
function WebForm_AutoFocus(focusId) { | |||||
var targetControl; | |||||
if (__nonMSDOMBrowser) { | |||||
targetControl = document.getElementById(focusId); | |||||
} | |||||
else { | |||||
targetControl = document.all[focusId]; | |||||
} | |||||
var focused = targetControl; | |||||
if (targetControl && (!WebForm_CanFocus(targetControl)) ) { | |||||
focused = WebForm_FindFirstFocusableChild(targetControl); | |||||
} | |||||
if (focused) { | |||||
try { | |||||
focused.focus(); | |||||
if (__nonMSDOMBrowser) { | |||||
focused.scrollIntoView(false); | |||||
} | |||||
if (window.__smartNav) { | |||||
window.__smartNav.ae = focused.id; | |||||
} | |||||
} | |||||
catch (e) { | |||||
} | |||||
} | |||||
} | |||||
function WebForm_CanFocus(element) { | |||||
if (!element || !(element.tagName)) return false; | |||||
var tagName = element.tagName.toLowerCase(); | |||||
return (!(element.disabled) && | |||||
(!(element.type) || element.type.toLowerCase() != "hidden") && | |||||
WebForm_IsFocusableTag(tagName) && | |||||
WebForm_IsInVisibleContainer(element) | |||||
); | |||||
} | |||||
function WebForm_IsFocusableTag(tagName) { | |||||
return (tagName == "input" || | |||||
tagName == "textarea" || | |||||
tagName == "select" || | |||||
tagName == "button" || | |||||
tagName == "a"); | |||||
} | |||||
function WebForm_IsInVisibleContainer(ctrl) { | |||||
var current = ctrl; | |||||
while((typeof(current) != "undefined") && (current != null)) { | |||||
if (current.disabled || | |||||
( typeof(current.style) != "undefined" && | |||||
( ( typeof(current.style.display) != "undefined" && | |||||
current.style.display == "none") || | |||||
( typeof(current.style.visibility) != "undefined" && | |||||
current.style.visibility == "hidden") ) ) ) { | |||||
return false; | |||||
} | |||||
if (typeof(current.parentNode) != "undefined" && | |||||
current.parentNode != null && | |||||
current.parentNode != current && | |||||
current.parentNode.tagName.toLowerCase() != "body") { | |||||
current = current.parentNode; | |||||
} | |||||
else { | |||||
return true; | |||||
} | |||||
} | |||||
return true; | |||||
} |