Edit UI is in progress. Updated to .NET Framework 4.6.2 Update Default to use new framework features. Most of the form is there. Still need the combo boxes loading correctlypull/136/head
@ -1,3 +0,0 @@ | |||
* | |||
!obj\Docker\publish\* | |||
!obj\Docker\empty\ |
@ -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,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,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 = "" | |||
//}); | |||
} | |||
} | |||
} |
@ -1,4 +0,0 @@ | |||
FROM microsoft/aspnet | |||
ARG source | |||
WORKDIR /inetpub/wwwroot | |||
COPY ${source:-obj/Docker/publish} . |
@ -0,0 +1,41 @@ | |||
<%@ 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" | |||
SelectMethod="EditCatalogItemForm_GetItem" | |||
UpdateMethod="EditCatalogItemForm_UpdateItem" | |||
InsertMethod="EditCatalogItemForm_InsertItem"> | |||
<EditItemTemplate> | |||
<section> | |||
<div class="col-md-6"> | |||
<form> | |||
<div class="form-group"> | |||
<label class="control-label form-label" for="ItemName">Name</label> | |||
<input name="ItemName" class="form-control form-input form-input-center" value="<%#Item.Name%>" /> | |||
</div> | |||
<div class="form-group"> | |||
<label class="control-label form-label" for="ItemDescription">Description</label> | |||
<input name="ItemDescription" class="form-control form-input form-input-center" value="<%#Item.Description%>" /> | |||
</div> | |||
<div class="form-group"> | |||
<label class="control-label form-label" for="ItemPrice">Price</label> | |||
<input name="ItemPrice" class="form-control form-input form-input-center" value="<%#Item.Price%>" /> | |||
</div> | |||
<div class="form-group"> | |||
<label class="control-label form-label" for="ItemBrand">Brand</label> | |||
<asp:DropDownList ID="ItemBrand" runat="server" DataTextField="Brand" /> | |||
</div> | |||
<div class="form-group"> | |||
<label class="control-label form-label" for="ItemType">Type</label> | |||
<asp:DropDownList ID="ItemType" runat="server" DataTextField="Type" /> | |||
</div> | |||
<div class="col-md-6"> | |||
This is where the picture to edit goes | |||
</div> | |||
</form> | |||
</div> | |||
</section> | |||
</EditItemTemplate> | |||
</asp:FormView> | |||
</asp:Content> |
@ -0,0 +1,72 @@ | |||
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> EditCatalogItemForm_GetItem([QueryString]int id) | |||
{ | |||
// TODO: If null, go into insert mode. | |||
var itemToEdit = await catalog?.GetCatalogItemAsync(id.ToString()); | |||
return itemToEdit; | |||
} | |||
// The id parameter name should match the DataKeyNames value set on the control | |||
public void EditCatalogItemForm_UpdateItem(int id) | |||
{ | |||
eShopOnContainers.Core.Models.Catalog.CatalogItem item = null; | |||
// Load the item here, e.g. item = MyDataLayer.Find(id); | |||
if (item == null) | |||
{ | |||
// The item wasn't found | |||
ModelState.AddModelError("", String.Format("Item with id {0} was not found", id)); | |||
return; | |||
} | |||
TryUpdateModel(item); | |||
if (ModelState.IsValid) | |||
{ | |||
// Save changes here, e.g. MyDataLayer.SaveChanges(); | |||
} | |||
} | |||
public void EditCatalogItemForm_InsertItem() | |||
{ | |||
var item = new eShopOnContainers.Core.Models.Catalog.CatalogItem(); | |||
TryUpdateModel(item); | |||
if (ModelState.IsValid) | |||
{ | |||
// Save changes here | |||
} | |||
} | |||
} | |||
} |
@ -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; | |||
} | |||
} |
@ -1 +1 @@ | |||
<%@ Application Codebehind="Global.asax.cs" Inherits="Microsoft.eShopOnContainers.Catalog.WebForms.Global" Language="C#" %> | |||
<%@ Application Codebehind="Global.asax.cs" Inherits="eShopOnContainers.Catalog.WebForms.Global" Language="C#" %> |
@ -1,19 +1,21 @@ | |||
using System; | |||
using System.Collections.Generic; | |||
using System.Linq; | |||
using System.Web; | |||
using System.Web.Optimization; | |||
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 | |||
{ | |||
void Application_Start(object sender, EventArgs e) | |||
{ | |||
// Code that runs on application startup | |||
RouteConfig.RegisterRoutes(RouteTable.Routes); | |||
BundleConfig.RegisterBundles(BundleTable.Bundles); | |||
} | |||
} | |||
} |
@ -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 |
@ -1,17 +1,81 @@ | |||
using System; | |||
using System.Collections.Generic; | |||
using System.Linq; | |||
using System.Security.Claims; | |||
using System.Security.Principal; | |||
using System.Web; | |||
using System.Web.Security; | |||
using System.Web.UI; | |||
using System.Web.UI.WebControls; | |||
using Microsoft.AspNet.Identity; | |||
namespace Microsoft.eShopOnContainers.Catalog.WebForms | |||
namespace eShopOnContainers.Catalog.WebForms | |||
{ | |||
public partial class SiteMaster : MasterPage | |||
{ | |||
private const string AntiXsrfTokenKey = "__AntiXsrfToken"; | |||
private const string AntiXsrfUserNameKey = "__AntiXsrfUserName"; | |||
private string _antiXsrfTokenValue; | |||
protected void Page_Init(object sender, EventArgs e) | |||
{ | |||
// The code below helps to protect against XSRF attacks | |||
var requestCookie = Request.Cookies[AntiXsrfTokenKey]; | |||
Guid requestCookieGuidValue; | |||
if (requestCookie != null && Guid.TryParse(requestCookie.Value, out requestCookieGuidValue)) | |||
{ | |||
// Use the Anti-XSRF token from the cookie | |||
_antiXsrfTokenValue = requestCookie.Value; | |||
Page.ViewStateUserKey = _antiXsrfTokenValue; | |||
} | |||
else | |||
{ | |||
// Generate a new Anti-XSRF token and save to the cookie | |||
_antiXsrfTokenValue = Guid.NewGuid().ToString("N"); | |||
Page.ViewStateUserKey = _antiXsrfTokenValue; | |||
var responseCookie = new HttpCookie(AntiXsrfTokenKey) | |||
{ | |||
HttpOnly = true, | |||
Value = _antiXsrfTokenValue | |||
}; | |||
if (FormsAuthentication.RequireSSL && Request.IsSecureConnection) | |||
{ | |||
responseCookie.Secure = true; | |||
} | |||
Response.Cookies.Set(responseCookie); | |||
} | |||
Page.PreLoad += master_Page_PreLoad; | |||
} | |||
protected void master_Page_PreLoad(object sender, EventArgs e) | |||
{ | |||
if (!IsPostBack) | |||
{ | |||
// Set Anti-XSRF token | |||
ViewState[AntiXsrfTokenKey] = Page.ViewStateUserKey; | |||
ViewState[AntiXsrfUserNameKey] = Context.User.Identity.Name ?? String.Empty; | |||
} | |||
else | |||
{ | |||
// Validate the Anti-XSRF token | |||
if ((string)ViewState[AntiXsrfTokenKey] != _antiXsrfTokenValue | |||
|| (string)ViewState[AntiXsrfUserNameKey] != (Context.User.Identity.Name ?? String.Empty)) | |||
{ | |||
throw new InvalidOperationException("Validation of Anti-XSRF token failed."); | |||
} | |||
} | |||
} | |||
protected void Page_Load(object sender, EventArgs e) | |||
{ | |||
} | |||
protected void Unnamed_LoggingOut(object sender, LoginCancelEventArgs e) | |||
{ | |||
Context.GetOwinContext().Authentication.SignOut(DefaultAuthenticationTypes.ApplicationCookie); | |||
} | |||
} | |||
} |
@ -0,0 +1,12 @@ | |||
using Microsoft.Owin; | |||
using Owin; | |||
[assembly: OwinStartupAttribute(typeof(eShopOnContainers.Catalog.WebForms.Startup))] | |||
namespace eShopOnContainers.Catalog.WebForms | |||
{ | |||
public partial class Startup { | |||
public void Configuration(IAppBuilder app) { | |||
ConfigureAuth(app); | |||
} | |||
} | |||
} |
@ -1,4 +1,4 @@ | |||
<%@ Control Language="C#" AutoEventWireup="true" CodeBehind="ViewSwitcher.ascx.cs" Inherits="Microsoft.eShopOnContainers.Catalog.WebForms.ViewSwitcher" %> | |||
<%@ Control Language="C#" AutoEventWireup="true" CodeBehind="ViewSwitcher.ascx.cs" Inherits="eShopOnContainers.Catalog.WebForms.ViewSwitcher" %> | |||
<div id="viewSwitcher"> | |||
<%: CurrentView %> view | <a href="<%: SwitchUrl %>" data-ajax="false">Switch to <%: AlternateView %></a> | |||
</div> |
@ -1,29 +1,44 @@ | |||
<?xml version="1.0" encoding="utf-8"?> | |||
<packages> | |||
<package id="Antlr" version="3.4.1.9004" targetFramework="net452" /> | |||
<package id="AspNet.ScriptManager.bootstrap" version="3.0.0" targetFramework="net452" /> | |||
<package id="AspNet.ScriptManager.jQuery" version="1.10.2" targetFramework="net452" /> | |||
<package id="Autofac" version="4.3.0" targetFramework="net452" /> | |||
<package id="bootstrap" version="3.0.0" targetFramework="net452" /> | |||
<package id="jQuery" version="1.10.2" targetFramework="net452" /> | |||
<package id="Microsoft.ApplicationInsights" version="2.2.0" targetFramework="net452" /> | |||
<package id="Microsoft.ApplicationInsights.Agent.Intercept" version="2.0.6" targetFramework="net452" /> | |||
<package id="Microsoft.ApplicationInsights.DependencyCollector" version="2.2.0" targetFramework="net452" /> | |||
<package id="Microsoft.ApplicationInsights.PerfCounterCollector" version="2.2.0" targetFramework="net452" /> | |||
<package id="Microsoft.ApplicationInsights.Web" version="2.2.0" targetFramework="net452" /> | |||
<package id="Microsoft.ApplicationInsights.WindowsServer" version="2.2.0" targetFramework="net452" /> | |||
<package id="Microsoft.ApplicationInsights.WindowsServer.TelemetryChannel" version="2.2.0" targetFramework="net452" /> | |||
<package id="Microsoft.AspNet.FriendlyUrls" version="1.0.2" targetFramework="net452" /> | |||
<package id="Microsoft.AspNet.FriendlyUrls.Core" version="1.0.2" targetFramework="net452" /> | |||
<package id="Microsoft.AspNet.ScriptManager.MSAjax" version="5.0.0" targetFramework="net452" /> | |||
<package id="Microsoft.AspNet.ScriptManager.WebForms" version="5.0.0" targetFramework="net452" /> | |||
<package id="Microsoft.AspNet.Web.Optimization" version="1.1.3" targetFramework="net452" /> | |||
<package id="Microsoft.AspNet.Web.Optimization.WebForms" version="1.1.3" targetFramework="net452" /> | |||
<package id="Microsoft.CodeDom.Providers.DotNetCompilerPlatform" version="1.0.3" targetFramework="net452" /> | |||
<package id="Microsoft.Net.Compilers" version="2.0.1" targetFramework="net452" developmentDependency="true" /> | |||
<package id="Microsoft.Web.Infrastructure" version="1.0.0.0" targetFramework="net452" /> | |||
<package id="Modernizr" version="2.6.2" targetFramework="net452" /> | |||
<package id="Newtonsoft.Json" version="6.0.4" targetFramework="net452" /> | |||
<package id="Respond" version="1.2.0" targetFramework="net452" /> | |||
<package id="WebGrease" version="1.5.2" targetFramework="net452" /> | |||
<package id="Antlr" version="3.4.1.9004" targetFramework="net462" /> | |||
<package id="AspNet.ScriptManager.bootstrap" version="3.0.0" targetFramework="net462" /> | |||
<package id="AspNet.ScriptManager.jQuery" version="1.10.2" targetFramework="net462" /> | |||
<package id="Autofac" version="4.4.0" targetFramework="net462" /> | |||
<package id="bootstrap" version="3.0.0" targetFramework="net462" /> | |||
<package id="EntityFramework" version="6.1.3" targetFramework="net462" /> | |||
<package id="jQuery" version="1.10.2" targetFramework="net462" /> | |||
<package id="Microsoft.ApplicationInsights" version="2.2.0" targetFramework="net462" /> | |||
<package id="Microsoft.ApplicationInsights.Agent.Intercept" version="2.0.6" targetFramework="net462" /> | |||
<package id="Microsoft.ApplicationInsights.DependencyCollector" version="2.2.0" targetFramework="net462" /> | |||
<package id="Microsoft.ApplicationInsights.PerfCounterCollector" version="2.2.0" targetFramework="net462" /> | |||
<package id="Microsoft.ApplicationInsights.Web" version="2.2.0" targetFramework="net462" /> | |||
<package id="Microsoft.ApplicationInsights.WindowsServer" version="2.2.0" targetFramework="net462" /> | |||
<package id="Microsoft.ApplicationInsights.WindowsServer.TelemetryChannel" version="2.2.0" targetFramework="net462" /> | |||
<package id="Microsoft.AspNet.FriendlyUrls" version="1.0.2" targetFramework="net462" /> | |||
<package id="Microsoft.AspNet.FriendlyUrls.Core" version="1.0.2" targetFramework="net462" /> | |||
<package id="Microsoft.AspNet.Identity.Core" version="2.2.1" targetFramework="net462" /> | |||
<package id="Microsoft.AspNet.Identity.EntityFramework" version="2.2.1" targetFramework="net462" /> | |||
<package id="Microsoft.AspNet.Identity.Owin" version="2.2.1" targetFramework="net462" /> | |||
<package id="Microsoft.AspNet.Providers.Core" version="2.0.0" targetFramework="net462" /> | |||
<package id="Microsoft.AspNet.ScriptManager.MSAjax" version="5.0.0" targetFramework="net462" /> | |||
<package id="Microsoft.AspNet.ScriptManager.WebForms" version="5.0.0" targetFramework="net462" /> | |||
<package id="Microsoft.AspNet.Web.Optimization" version="1.1.3" targetFramework="net462" /> | |||
<package id="Microsoft.AspNet.Web.Optimization.WebForms" version="1.1.3" targetFramework="net462" /> | |||
<package id="Microsoft.CodeDom.Providers.DotNetCompilerPlatform" version="1.0.3" targetFramework="net462" /> | |||
<package id="Microsoft.Net.Compilers" version="2.0.1" targetFramework="net462" developmentDependency="true" /> | |||
<package id="Microsoft.Owin" version="3.0.1" targetFramework="net462" /> | |||
<package id="Microsoft.Owin.Host.SystemWeb" version="3.0.1" targetFramework="net462" /> | |||
<package id="Microsoft.Owin.Security" version="3.0.1" targetFramework="net462" /> | |||
<package id="Microsoft.Owin.Security.Cookies" version="3.0.1" targetFramework="net462" /> | |||
<package id="Microsoft.Owin.Security.Facebook" version="3.0.1" targetFramework="net462" /> | |||
<package id="Microsoft.Owin.Security.Google" version="3.0.1" targetFramework="net462" /> | |||
<package id="Microsoft.Owin.Security.MicrosoftAccount" version="3.0.1" targetFramework="net462" /> | |||
<package id="Microsoft.Owin.Security.OAuth" version="3.0.1" targetFramework="net462" /> | |||
<package id="Microsoft.Owin.Security.Twitter" version="3.0.1" targetFramework="net462" /> | |||
<package id="Microsoft.Web.Infrastructure" version="1.0.0.0" targetFramework="net462" /> | |||
<package id="Modernizr" version="2.6.2" targetFramework="net462" /> | |||
<package id="Newtonsoft.Json" version="6.0.4" targetFramework="net462" /> | |||
<package id="Owin" version="1.0" targetFramework="net462" /> | |||
<package id="Respond" version="1.2.0" targetFramework="net462" /> | |||
<package id="WebGrease" version="1.5.2" targetFramework="net462" /> | |||
</packages> |
@ -1 +0,0 @@ | |||
version: '2.1' |
@ -1,22 +0,0 @@ | |||
<?xml version="1.0" encoding="utf-8"?> | |||
<Project ToolsVersion="15.0" Sdk="Microsoft.Docker.Sdk"> | |||
<PropertyGroup Label="Globals"> | |||
<ProjectGuid>7816bbb6-20b9-4d5a-864d-47b7c6e3d3d5</ProjectGuid> | |||
<DockerLaunchBrowser>True</DockerLaunchBrowser> | |||
<DockerServiceUrl>http://{ServiceIPAddress}</DockerServiceUrl> | |||
<DockerServiceName>catalog.webforms</DockerServiceName> | |||
</PropertyGroup> | |||
<ItemGroup> | |||
<None Include="docker-compose.ci.build.yml" /> | |||
<None Include="docker-compose.override.yml"> | |||
<DependentUpon>docker-compose.yml</DependentUpon> | |||
</None> | |||
<None Include="docker-compose.vs.debug.yml"> | |||
<DependentUpon>docker-compose.yml</DependentUpon> | |||
</None> | |||
<None Include="docker-compose.vs.release.yml"> | |||
<DependentUpon>docker-compose.yml</DependentUpon> | |||
</None> | |||
<None Include="docker-compose.yml" /> | |||
</ItemGroup> | |||
</Project> |
@ -1,23 +0,0 @@ | |||
version: '2.1' | |||
services: | |||
sql.data: | |||
environment: | |||
- ACCEPT_EULA=Y | |||
catalog.api: | |||
environment: | |||
- ASPNETCORE_ENVIRONMENT=Development | |||
- ConnectionString=Server=sql.data;Database=Microsoft.eShopOnContainers.Services.CatalogDb;User Id=sa;Password=Pass@word | |||
#- ExternalCatalogBaseUrl=http://13.88.8.119:5101 #Remote: VM Needs to have public access at 5105. | |||
- ExternalCatalogBaseUrl=http://localhost:5101 #Local: You need to open your local dev-machine firewall at range 5100-5105. at range 5100-5105. | |||
ports: | |||
- "5101:5101" | |||
catalog.webforms: | |||
ports: | |||
- "80" | |||
networks: | |||
default: | |||
external: | |||
name: nat |
@ -1,28 +0,0 @@ | |||
version: '2.1' | |||
services: | |||
catalog.api: | |||
image: eshop/catalog.api:dev | |||
build: | |||
args: | |||
source: ${DOCKER_BUILD_SOURCE} | |||
environment: | |||
- DOTNET_USE_POLLING_FILE_WATCHER=1 | |||
volumes: | |||
- ../../Services/Catalog/Catalog.API:/app | |||
- ~/.nuget/packages:/root/.nuget/packages:ro | |||
- ~/clrdbg:/clrdbg:ro | |||
entrypoint: tail -f /dev/null | |||
labels: | |||
- "com.microsoft.visualstudio.targetoperatingsystem=linux" | |||
catalog.webforms: | |||
image: catalog.webforms:dev | |||
build: | |||
args: | |||
source: ${DOCKER_BUILD_SOURCE} | |||
volumes: | |||
- .\Catalog.WebForms:C:\inetpub\wwwroot | |||
- ~\msvsmon:C:\msvsmon:ro | |||
labels: | |||
- "com.microsoft.visualstudio.targetoperatingsystem=windows" |
@ -1,21 +0,0 @@ | |||
version: '2.1' | |||
services: | |||
catalog.api: | |||
build: | |||
args: | |||
source: ${DOCKER_BUILD_SOURCE} | |||
volumes: | |||
- ~/clrdbg:/clrdbg:ro | |||
entrypoint: tail -f /dev/null | |||
labels: | |||
- "com.microsoft.visualstudio.targetoperatingsystem=linux" | |||
catalog.webforms: | |||
build: | |||
args: | |||
source: ${DOCKER_BUILD_SOURCE} | |||
volumes: | |||
- ~\msvsmon:C:\msvsmon:ro | |||
labels: | |||
- "com.microsoft.visualstudio.targetoperatingsystem=windows" |
@ -1,22 +0,0 @@ | |||
version: '2.1' | |||
services: | |||
catalog.webforms: | |||
image: catalog.webforms | |||
build: | |||
context: .\Catalog.WebForms | |||
dockerfile: Dockerfile | |||
depends_on: | |||
- catalog.api | |||
catalog.api: | |||
image: eshop/catalog.api | |||
build: | |||
context: ../../Services/Catalog/Catalog.API | |||
dockerfile: Dockerfile.nanowin | |||
depends_on: | |||
- sql.data | |||
sql.data: | |||
image: microsoft/mssql-server-windows | |||