From 42a4c12782cb5ddcc251d8e6a60fc4e991cb999f Mon Sep 17 00:00:00 2001
From: Ilya Chudin
Date: Tue, 16 May 2017 18:22:08 +0500
Subject: [PATCH 1/8] VS 2017 migration
---
LinqToDB.Identity.sln | 15 +++--
global.json | 3 -
.../IdentitySample.Mvc.csproj | 57 ++++++++++++++++++
.../IdentitySample.Mvc.xproj | 18 ------
samples/IdentitySample.Mvc/project.json | 59 -------------------
.../LinqToDB.Identity.csproj | 47 +++++++++++++++
src/LinqToDB.Identity/LinqToDB.Identity.xproj | 17 ------
src/LinqToDB.Identity/TaskTools.cs | 28 +++++++++
src/LinqToDB.Identity/project.json | 47 ---------------
...y.EntityFrameworkCore.InMemory.Test.csproj | 48 +++++++++++++++
...ty.EntityFrameworkCore.InMemory.Test.xproj | 20 -------
.../project.json | 33 -----------
...e.Identity.EntityFrameworkCore.Test.csproj | 56 ++++++++++++++++++
...re.Identity.EntityFrameworkCore.Test.xproj | 20 -------
.../project.json | 46 ---------------
15 files changed, 243 insertions(+), 271 deletions(-)
delete mode 100644 global.json
create mode 100644 samples/IdentitySample.Mvc/IdentitySample.Mvc.csproj
delete mode 100644 samples/IdentitySample.Mvc/IdentitySample.Mvc.xproj
delete mode 100644 samples/IdentitySample.Mvc/project.json
create mode 100644 src/LinqToDB.Identity/LinqToDB.Identity.csproj
delete mode 100644 src/LinqToDB.Identity/LinqToDB.Identity.xproj
create mode 100644 src/LinqToDB.Identity/TaskTools.cs
delete mode 100644 src/LinqToDB.Identity/project.json
create mode 100644 test/Microsoft.AspNetCore.Identity.EntityFrameworkCore.InMemory.Test/Microsoft.AspNetCore.Identity.EntityFrameworkCore.InMemory.Test.csproj
delete mode 100644 test/Microsoft.AspNetCore.Identity.EntityFrameworkCore.InMemory.Test/Microsoft.AspNetCore.Identity.EntityFrameworkCore.InMemory.Test.xproj
delete mode 100644 test/Microsoft.AspNetCore.Identity.EntityFrameworkCore.InMemory.Test/project.json
create mode 100644 test/Microsoft.AspNetCore.Identity.EntityFrameworkCore.Test/Microsoft.AspNetCore.Identity.EntityFrameworkCore.Test.csproj
delete mode 100644 test/Microsoft.AspNetCore.Identity.EntityFrameworkCore.Test/Microsoft.AspNetCore.Identity.EntityFrameworkCore.Test.xproj
delete mode 100644 test/Microsoft.AspNetCore.Identity.EntityFrameworkCore.Test/project.json
diff --git a/LinqToDB.Identity.sln b/LinqToDB.Identity.sln
index 5c8552b34..604af4f06 100644
--- a/LinqToDB.Identity.sln
+++ b/LinqToDB.Identity.sln
@@ -1,6 +1,6 @@
Microsoft Visual Studio Solution File, Format Version 12.00
-# Visual Studio 14
-VisualStudioVersion = 14.0.25420.1
+# Visual Studio 15
+VisualStudioVersion = 15.0.26403.7
MinimumVisualStudioVersion = 10.0.40219.1
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{0F647068-6602-4E24-B1DC-8ED91481A50A}"
EndProject
@@ -8,22 +8,21 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{52D59F18-6
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "samples", "samples", "{58D94A0E-C2B7-43A7-8826-99ECBB1E0A50}"
EndProject
-Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "IdentitySample.Mvc", "samples\IdentitySample.Mvc\IdentitySample.Mvc.xproj", "{E1BFA023-CFFD-49CE-8466-1C28DD2EC1F6}"
-EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{970CAB07-F853-4712-AA12-BD8961C8E430}"
ProjectSection(SolutionItems) = preProject
appveyor.yml = appveyor.yml
build.cmd = build.cmd
build.ps1 = build.ps1
- global.json = global.json
NuGet.config = NuGet.config
EndProjectSection
EndProject
-Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.AspNetCore.Identity.EntityFrameworkCore.Test", "test\Microsoft.AspNetCore.Identity.EntityFrameworkCore.Test\Microsoft.AspNetCore.Identity.EntityFrameworkCore.Test.xproj", "{37236EA3-915D-46D5-997C-DF513C500E4B}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "IdentitySample.Mvc", "samples\IdentitySample.Mvc\IdentitySample.Mvc.csproj", "{E1BFA023-CFFD-49CE-8466-1C28DD2EC1F6}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.Identity.EntityFrameworkCore.Test", "test\Microsoft.AspNetCore.Identity.EntityFrameworkCore.Test\Microsoft.AspNetCore.Identity.EntityFrameworkCore.Test.csproj", "{37236EA3-915D-46D5-997C-DF513C500E4B}"
EndProject
-Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.AspNetCore.Identity.EntityFrameworkCore.InMemory.Test", "test\Microsoft.AspNetCore.Identity.EntityFrameworkCore.InMemory.Test\Microsoft.AspNetCore.Identity.EntityFrameworkCore.InMemory.Test.xproj", "{EA7EB28F-53B8-4009-9C6B-74DB090CA8DD}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.Identity.EntityFrameworkCore.InMemory.Test", "test\Microsoft.AspNetCore.Identity.EntityFrameworkCore.InMemory.Test\Microsoft.AspNetCore.Identity.EntityFrameworkCore.InMemory.Test.csproj", "{EA7EB28F-53B8-4009-9C6B-74DB090CA8DD}"
EndProject
-Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "LinqToDB.Identity", "src\LinqToDB.Identity\LinqToDB.Identity.xproj", "{4490894C-3572-4E63-86F1-EE5105CE8A06}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LinqToDB.Identity", "src\LinqToDB.Identity\LinqToDB.Identity.csproj", "{4490894C-3572-4E63-86F1-EE5105CE8A06}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
diff --git a/global.json b/global.json
deleted file mode 100644
index 983ba0401..000000000
--- a/global.json
+++ /dev/null
@@ -1,3 +0,0 @@
-{
- "projects": ["src"]
-}
diff --git a/samples/IdentitySample.Mvc/IdentitySample.Mvc.csproj b/samples/IdentitySample.Mvc/IdentitySample.Mvc.csproj
new file mode 100644
index 000000000..7bfc545e8
--- /dev/null
+++ b/samples/IdentitySample.Mvc/IdentitySample.Mvc.csproj
@@ -0,0 +1,57 @@
+
+
+
+ Identity sample MVC application on ASP.NET Core
+ 1.1.0
+ Microsoft
+ net451;netcoreapp1.1
+ true
+ IdentitySample.Mvc
+ Exe
+ IdentitySample.Mvc
+ 1.1.1
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/samples/IdentitySample.Mvc/IdentitySample.Mvc.xproj b/samples/IdentitySample.Mvc/IdentitySample.Mvc.xproj
deleted file mode 100644
index 5f83d0d09..000000000
--- a/samples/IdentitySample.Mvc/IdentitySample.Mvc.xproj
+++ /dev/null
@@ -1,18 +0,0 @@
-
-
-
- 14.0
- $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)
-
-
-
- e1bfa023-cffd-49ce-8466-1c28dd2ec1f6
- .\obj
- .\bin\
-
-
- 2.0
- 41532
-
-
-
\ No newline at end of file
diff --git a/samples/IdentitySample.Mvc/project.json b/samples/IdentitySample.Mvc/project.json
deleted file mode 100644
index 9111a0216..000000000
--- a/samples/IdentitySample.Mvc/project.json
+++ /dev/null
@@ -1,59 +0,0 @@
-{
- "authors": [
- "Microsoft"
- ],
- "description": "Identity sample MVC application on ASP.NET Core",
- "version": "1.1.0-*",
- "dependencies": {
- "Microsoft.AspNetCore.Authentication.Cookies": "1.1.0-*",
- "Microsoft.AspNetCore.Authentication.Facebook": "1.1.0-*",
- "Microsoft.AspNetCore.Authentication.Google": "1.1.0-*",
- "Microsoft.AspNetCore.Authentication.Twitter": "1.1.0-*",
- "Microsoft.AspNetCore.Authorization": "1.1.0-*",
- "Microsoft.AspNetCore.DataProtection.Extensions": "1.1.0-*",
- "Microsoft.AspNetCore.Diagnostics": "1.1.0-*",
- "Microsoft.AspNetCore.Identity": "1.1.0-*",
- "Microsoft.AspNetCore.Mvc": "1.1.0-*",
- "Microsoft.AspNetCore.Mvc.TagHelpers": "1.1.0-*",
- "Microsoft.AspNetCore.Server.IISIntegration": "1.1.0-*",
- "Microsoft.AspNetCore.Server.Kestrel": "1.1.0-*",
- "Microsoft.AspNetCore.StaticFiles": "1.1.0-*",
- "Microsoft.Extensions.Configuration.EnvironmentVariables": "1.1.0-*",
- "Microsoft.Extensions.Configuration.Json": "1.1.0-*",
- "Microsoft.Extensions.Configuration.UserSecrets": "1.1.0-*",
- "Microsoft.Extensions.Logging.Console": "1.1.0-*",
- "Microsoft.Extensions.Logging.Debug": "1.1.0-*",
-
- "LinqToDB.Identity": "1.1.0-*"
- },
- "buildOptions": {
- "emitEntryPoint": true,
- "preserveCompilationContext": true,
- "compile": {
- "exclude": [
- "./Data/Migrations/*.cs"
- ]
- }
- },
- "frameworks": {
- "net451": {},
- "netcoreapp1.1": {
- "dependencies": {
- "Microsoft.NETCore.App": {
- "version": "1.1.0-*",
- "type": "platform"
- }
- }
- }
- },
- "tools": {
- "Microsoft.AspNetCore.Server.IISIntegration.Tools": "1.0.0-*",
- "Microsoft.EntityFrameworkCore.Tools.DotNet": "1.0.0-*"
- },
- "publishOptions": {
- "include": [
- "appsettings.json",
- "web.config"
- ]
- }
-}
\ No newline at end of file
diff --git a/src/LinqToDB.Identity/LinqToDB.Identity.csproj b/src/LinqToDB.Identity/LinqToDB.Identity.csproj
new file mode 100644
index 000000000..34fb69419
--- /dev/null
+++ b/src/LinqToDB.Identity/LinqToDB.Identity.csproj
@@ -0,0 +1,47 @@
+
+
+
+ ASP.NET Core Identity provider that uses LinqToDB.
+ 1.1.0
+ Ilya Chudin
+ netstandard1.6;net451;
+ true
+ true
+ LinqToDB.Identity
+ ../../tools/newkey.snk
+ true
+ true
+ LinqToDB.Identity
+ aspnetcore;linq2db;identity;membership;LinqToDB
+ http://www.gravatar.com/avatar/fc2e509b6ed116b9aa29a7988fdb8990?s=320
+ https://github.com/ili/LinqToDB.Identity
+ https://opensource.org/licenses/MIT
+ git
+ git://github.com/ili/LinqToDB.Identity
+ 1.6.1
+ false
+ false
+ false
+ false
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/LinqToDB.Identity/LinqToDB.Identity.xproj b/src/LinqToDB.Identity/LinqToDB.Identity.xproj
deleted file mode 100644
index b920c8a85..000000000
--- a/src/LinqToDB.Identity/LinqToDB.Identity.xproj
+++ /dev/null
@@ -1,17 +0,0 @@
-
-
-
- 14.0
- $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)
-
-
-
- 4490894c-3572-4e63-86f1-ee5105ce8a06
- .\obj
- .\bin\
-
-
- 2.0
-
-
-
\ No newline at end of file
diff --git a/src/LinqToDB.Identity/TaskTools.cs b/src/LinqToDB.Identity/TaskTools.cs
new file mode 100644
index 000000000..18153af9e
--- /dev/null
+++ b/src/LinqToDB.Identity/TaskTools.cs
@@ -0,0 +1,28 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace LinqToDB.Identity
+{
+ internal static class TaskCache
+ {
+ ///
+ /// Gets a completed with the value of default(T) .
+ ///
+ public static Task DefaultCompletedTask { get; } = Task.FromResult(default(T));
+ }
+
+ internal static class TaskCache
+ {
+ ///
+ /// A that's already completed successfully.
+ ///
+ ///
+ /// We're caching this in a static readonly field to make it more inlinable and avoid the volatile lookup done
+ /// by Task.CompletedTask .
+ ///
+ public static readonly Task CompletedTask = Task.FromResult(0);
+ }
+
+}
diff --git a/src/LinqToDB.Identity/project.json b/src/LinqToDB.Identity/project.json
deleted file mode 100644
index b2efabb05..000000000
--- a/src/LinqToDB.Identity/project.json
+++ /dev/null
@@ -1,47 +0,0 @@
-{
- "description": "ASP.NET Core Identity provider that uses LinqToDB.",
- "authors": ["Ilya Chudin"],
- "version": "1.1.0-*",
- "buildOptions": {
- "warningsAsErrors": true,
- "keyFile": "../../tools/newkey.snk",
- "xmlDoc": true,
- "embed": [ "**/*.resx" ]
- },
- "packOptions": {
- "licenseUrl": "https://opensource.org/licenses/MIT",
- "projectUrl": "https://github.com/ili/LinqToDB.Identity",
- "iconUrl": "http://www.gravatar.com/avatar/fc2e509b6ed116b9aa29a7988fdb8990?s=320",
-
- "requireLicenseAcceptance": false,
- "repository": {
- "type": "git",
- "url": "git://github.com/ili/LinqToDB.Identity"
- },
- "tags": [
- "aspnetcore",
- "linq2db",
- "identity",
- "membership",
- "LinqToDB"
- ]
- },
- "dependencies": {
- "Microsoft.Extensions.TaskCache.Sources": {
- "version": "1.1.0-*",
- "type": "build"
- },
- "Microsoft.AspNetCore.Identity": "1.1.0-preview1-final",
- "NETStandard.Library": "1.6.1-*",
- "linq2db.core": "1.7.5-*",
- "Microsoft.Extensions.DependencyInjection": "1.1.0-preview1-final"
- },
- "frameworks": {
- "netstandard1.6": {
- "dependencies": {
- "System.ComponentModel.TypeConverter": "4.3.0"
- }
- },
- "net451": {}
- }
-}
\ No newline at end of file
diff --git a/test/Microsoft.AspNetCore.Identity.EntityFrameworkCore.InMemory.Test/Microsoft.AspNetCore.Identity.EntityFrameworkCore.InMemory.Test.csproj b/test/Microsoft.AspNetCore.Identity.EntityFrameworkCore.InMemory.Test/Microsoft.AspNetCore.Identity.EntityFrameworkCore.InMemory.Test.csproj
new file mode 100644
index 000000000..ce4d118ab
--- /dev/null
+++ b/test/Microsoft.AspNetCore.Identity.EntityFrameworkCore.InMemory.Test/Microsoft.AspNetCore.Identity.EntityFrameworkCore.InMemory.Test.csproj
@@ -0,0 +1,48 @@
+
+
+
+ netcoreapp1.0
+ true
+ Microsoft.AspNetCore.Identity.EntityFrameworkCore.InMemory.Test
+ ../../tools/Key.snk
+ true
+ true
+ Microsoft.AspNetCore.Identity.EntityFrameworkCore.InMemory.Test
+ true
+ 1.0.4
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/test/Microsoft.AspNetCore.Identity.EntityFrameworkCore.InMemory.Test/Microsoft.AspNetCore.Identity.EntityFrameworkCore.InMemory.Test.xproj b/test/Microsoft.AspNetCore.Identity.EntityFrameworkCore.InMemory.Test/Microsoft.AspNetCore.Identity.EntityFrameworkCore.InMemory.Test.xproj
deleted file mode 100644
index 5ad5dbce5..000000000
--- a/test/Microsoft.AspNetCore.Identity.EntityFrameworkCore.InMemory.Test/Microsoft.AspNetCore.Identity.EntityFrameworkCore.InMemory.Test.xproj
+++ /dev/null
@@ -1,20 +0,0 @@
-
-
-
- 14.0
- $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)
-
-
-
- ea7eb28f-53b8-4009-9c6b-74db090ca8dd
- .\obj
- .\bin\
-
-
- 2.0
-
-
-
-
-
-
\ No newline at end of file
diff --git a/test/Microsoft.AspNetCore.Identity.EntityFrameworkCore.InMemory.Test/project.json b/test/Microsoft.AspNetCore.Identity.EntityFrameworkCore.InMemory.Test/project.json
deleted file mode 100644
index 8ce369ab3..000000000
--- a/test/Microsoft.AspNetCore.Identity.EntityFrameworkCore.InMemory.Test/project.json
+++ /dev/null
@@ -1,33 +0,0 @@
-{
- "buildOptions": {
- "warningsAsErrors": true,
- "keyFile": "../../tools/Key.snk",
- "compile": {
- "include": "../Shared/*.cs"
- }
- },
- "dependencies": {
- "dotnet-test-xunit": "2.2.0-*",
- "Microsoft.AspNetCore.Hosting": "1.1.0-preview1-final",
- "Microsoft.AspNetCore.Http": "1.1.0-preview1-final",
- "Microsoft.AspNetCore.Identity": "1.1.0-preview1-final",
- "LinqToDB.Identity": "1.1.0",
- "Microsoft.AspNetCore.Testing": "1.1.0-*",
- "Moq": "4.6.36-*",
- "xunit": "2.2.0-*",
- "Microsoft.Data.SQLite": "1.0.0"
- },
- "frameworks": {
- "netcoreapp1.0": {
- "dependencies": {
- "Microsoft.NETCore.App": {
- "version": "1.0.0",
- "type": "platform"
- },
- "System.Diagnostics.TraceSource": "4.3.0"
- }
- },
- "net451": {}
- },
- "testRunner": "xunit"
-}
\ No newline at end of file
diff --git a/test/Microsoft.AspNetCore.Identity.EntityFrameworkCore.Test/Microsoft.AspNetCore.Identity.EntityFrameworkCore.Test.csproj b/test/Microsoft.AspNetCore.Identity.EntityFrameworkCore.Test/Microsoft.AspNetCore.Identity.EntityFrameworkCore.Test.csproj
new file mode 100644
index 000000000..ad796fa8c
--- /dev/null
+++ b/test/Microsoft.AspNetCore.Identity.EntityFrameworkCore.Test/Microsoft.AspNetCore.Identity.EntityFrameworkCore.Test.csproj
@@ -0,0 +1,56 @@
+
+
+
+ netcoreapp1.0
+ true
+ Microsoft.AspNetCore.Identity.EntityFrameworkCore.Test
+ ../../tools/Key.snk
+ true
+ true
+ Microsoft.AspNetCore.Identity.EntityFrameworkCore.Test
+ true
+ 1.0.4
+
+
+
+
+
+ PreserveNewest
+ PreserveNewest
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/test/Microsoft.AspNetCore.Identity.EntityFrameworkCore.Test/Microsoft.AspNetCore.Identity.EntityFrameworkCore.Test.xproj b/test/Microsoft.AspNetCore.Identity.EntityFrameworkCore.Test/Microsoft.AspNetCore.Identity.EntityFrameworkCore.Test.xproj
deleted file mode 100644
index 5a7ba5926..000000000
--- a/test/Microsoft.AspNetCore.Identity.EntityFrameworkCore.Test/Microsoft.AspNetCore.Identity.EntityFrameworkCore.Test.xproj
+++ /dev/null
@@ -1,20 +0,0 @@
-
-
-
- 14.0
- $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)
-
-
-
- 37236ea3-915d-46d5-997c-df513c500e4b
- .\obj
- .\bin\
-
-
- 2.0
-
-
-
-
-
-
\ No newline at end of file
diff --git a/test/Microsoft.AspNetCore.Identity.EntityFrameworkCore.Test/project.json b/test/Microsoft.AspNetCore.Identity.EntityFrameworkCore.Test/project.json
deleted file mode 100644
index cc1b0cb89..000000000
--- a/test/Microsoft.AspNetCore.Identity.EntityFrameworkCore.Test/project.json
+++ /dev/null
@@ -1,46 +0,0 @@
-{
- "buildOptions": {
- "warningsAsErrors": true,
- "keyFile": "../../tools/Key.snk",
- "copyToOutput": {
- "include": "config.json"
- },
- "compile": {
- "include": "../Shared/*.cs"
- }
- },
- "publishOptions": {
- "include": [
- "config.json"
- ]
- },
- "dependencies": {
- "dotnet-test-xunit": "2.2.0-*",
- "Microsoft.AspNetCore.Hosting": "1.1.0-preview1-final",
- "Microsoft.AspNetCore.Http": "1.1.0-preview1-final",
- "Microsoft.AspNetCore.Identity": "1.1.0-preview1-final",
- "LinqToDB.Identity": "1.1.0",
- "Microsoft.AspNetCore.TestHost": "1.1.0-preview1-final",
- "Microsoft.AspNetCore.Testing": "1.1.0-*",
- "Microsoft.Extensions.Configuration.EnvironmentVariables": "1.1.0-preview1-final",
- "Microsoft.Extensions.Configuration.FileExtensions": "1.1.0-preview1-final",
- "Microsoft.Extensions.Configuration.Json": "1.1.0-preview1-final",
- "Moq": "4.6.36-*",
- "xunit": "2.2.0-*",
-
- "Microsoft.Data.SQLite": "1.0.0"
- },
- "frameworks": {
- "netcoreapp1.0": {
- "dependencies": {
- "Microsoft.NETCore.App": {
- "version": "1.0.0",
- "type": "platform"
- },
- "System.Diagnostics.TraceSource": "4.3.0"
- }
- },
- "net451": {}
- },
- "testRunner": "xunit"
-}
\ No newline at end of file
From cba9bd09f668856155fa7a8273c22d92317d3648 Mon Sep 17 00:00:00 2001
From: Ilya Chudin
Date: Tue, 16 May 2017 18:43:06 +0500
Subject: [PATCH 2/8] new appveyor configuration
new package name (linq2db.Identity)
---
LinqToDB.Identity.sln | 1 +
README.md | 28 ++++++++++++++-----
appveyor.yml | 10 ++++---
.../LinqToDB.Identity.csproj | 2 +-
4 files changed, 29 insertions(+), 12 deletions(-)
diff --git a/LinqToDB.Identity.sln b/LinqToDB.Identity.sln
index 604af4f06..1fb384c5b 100644
--- a/LinqToDB.Identity.sln
+++ b/LinqToDB.Identity.sln
@@ -14,6 +14,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
build.cmd = build.cmd
build.ps1 = build.ps1
NuGet.config = NuGet.config
+ README.md = README.md
EndProjectSection
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "IdentitySample.Mvc", "samples\IdentitySample.Mvc\IdentitySample.Mvc.csproj", "{E1BFA023-CFFD-49CE-8466-1C28DD2EC1F6}"
diff --git a/README.md b/README.md
index 8ba333f75..04a05a340 100644
--- a/README.md
+++ b/README.md
@@ -1,17 +1,31 @@
[LinqToDB](https://github.com/linq2db/linq2db) Identity store provider for [ASP.NET Core Identity](https://github.com/aspnet/Identity)
===
-AppVeyor last build: [![Build status](https://ci.appveyor.com/api/projects/status/x15cyc688w9247oj?svg=true)](https://ci.appveyor.com/project/ili/linqtodb-identity)
+* Current build status [![Build status](https://ci.appveyor.com/api/projects/status/2d8k9n1x5ggsuv3f?svg=true)](https://ci.appveyor.com/project/igor-tkachev/linqtodb-identity)
+* Master build status [![Build status](https://ci.appveyor.com/api/projects/status/2d8k9n1x5ggsuv3f/branch/master?svg=true)](https://ci.appveyor.com/project/igor-tkachev/linqtodb-identity/branch/master)
-AppVeyor master build: [![Build status](https://ci.appveyor.com/api/projects/status/x15cyc688w9247oj/branch/master?svg=true)](https://ci.appveyor.com/project/ili/linqtodb-identity/branch/master)
-
-## NuGet
-* [NuGet.org](https://www.nuget.org/packages/LinqToDB.Identity/)
-* [MyGet.org](https://www.myget.org/feed/ili/package/nuget/LinqToDB.Identity) feed: https://www.myget.org/F/ili/api/v3/index.json
+## Feeds
+* Release builds can be found on [NuGet](https://www.nuget.org/packages?q=linq2db)
+* [MyGet](https://www.myget.org/gallery/linq2db)
+ * V2 `https://www.myget.org/F/linq2db/api/v2`
+ * V3 `https://www.myget.org/F/linq2db/api/v3/index.json`
## Usage
-In general this is the same as for Entity Framework, just call `AddLinqToDBStores` instead of `AddEntityFrameworkStores` in your `Startup.cs` like [here](https://github.com/ili/LinqToDB.Identity/blob/master/samples/IdentitySample.Mvc/Startup.cs#L62)
+Install package:
+
+`PM> Install-Package linq2db.Identity`
+
+In general this is the same as for Entity Framework, just call `AddLinqToDBStores` instead of `AddEntityFrameworkStores` in your `Startup.cs` like [here](https://github.com/linq2db/LinqToDB.Identity/blob/master/samples/IdentitySample.Mvc/Startup.cs#L62):
+```cs
+services.AddIdentity(options => {
+ options.Cookies.ApplicationCookie.AuthenticationScheme = "ApplicationCookie";
+ options.Cookies.ApplicationCookie.CookieName = "Interop";
+ options.Cookies.ApplicationCookie.DataProtectionProvider = DataProtectionProvider.Create(new DirectoryInfo("C:\\Github\\Identity\\artifacts"));
+})
+ .AddLinqToDBStores(new DefaultConnectionFactory()) //here
+ .AddDefaultTokenProviders();
+```
The main difference with Entity Framework Core storage provider are:
* We do not use hardcoded classes - interfaces like `IIdentityUser` are used (but yes, we do have default implementation)
diff --git a/appveyor.yml b/appveyor.yml
index 9116c1ccd..9d3a9f482 100644
--- a/appveyor.yml
+++ b/appveyor.yml
@@ -58,14 +58,16 @@ artifacts:
deploy:
- provider: NuGet
- server: https://www.myget.org/F/ili/api/v2
+ server: https://www.myget.org/F/linq2db/api/v2
api_key:
- secure: pFvgey1/w68ZvVHFN/GWZdDFjSABpBRfb0XfLnW3wvhlfyEUiSyfr3dAUcbmlpsk
+ secure: LDw0jeA1Yo3R4/TKv2kmlgJR8dTT6Wun2MONq3uDvtVQJG4LOU9LjvVTAc7IgRfm
skip_symbols: true
+ on:
+ branch: master
- provider: NuGet
api_key:
- secure: 9BjFlmIycM3Q3tpwlQRsoC9SPL+BqIoqHKkHihvfR9TvTpYLd9jLcnLnh8eRSmfV
+ secure: oTYw2IwTnz4qMD8c/MR/6mo+Nx3wa5Pp8MYfsKBCKCVuU6QCHlj+6QMXpnQses8G
skip_symbols: false
on:
- branch: master
\ No newline at end of file
+ branch: release
\ No newline at end of file
diff --git a/src/LinqToDB.Identity/LinqToDB.Identity.csproj b/src/LinqToDB.Identity/LinqToDB.Identity.csproj
index 34fb69419..59052432c 100644
--- a/src/LinqToDB.Identity/LinqToDB.Identity.csproj
+++ b/src/LinqToDB.Identity/LinqToDB.Identity.csproj
@@ -11,7 +11,7 @@
../../tools/newkey.snk
true
true
- LinqToDB.Identity
+ linq2db.Identity
aspnetcore;linq2db;identity;membership;LinqToDB
http://www.gravatar.com/avatar/fc2e509b6ed116b9aa29a7988fdb8990?s=320
https://github.com/ili/LinqToDB.Identity
From 406b7c284f89419295a9fe9e997134f77e299dd1 Mon Sep 17 00:00:00 2001
From: Ilya Chudin
Date: Wed, 17 May 2017 15:17:41 +0500
Subject: [PATCH 3/8] migrating to Cake build
---
.gitignore | 3 +-
LinqToDB.Identity.sln | 3 +-
tools/Key.snk => Tests.snk | Bin
appveyor.yml | 52 ++---
build.cake | 135 +++++++++++
build.cmd | 2 -
build.ps1 | 218 ++++++++++++++----
build.sh | 133 +++++++----
linq2db.snk | Bin 0 -> 596 bytes
.../LinqToDB.Identity.csproj | 2 +-
...y.EntityFrameworkCore.InMemory.Test.csproj | 2 +-
...e.Identity.EntityFrameworkCore.Test.csproj | 2 +-
tools/newkey.snk | Bin 596 -> 0 bytes
13 files changed, 419 insertions(+), 133 deletions(-)
rename tools/Key.snk => Tests.snk (100%)
create mode 100644 build.cake
delete mode 100644 build.cmd
create mode 100644 linq2db.snk
delete mode 100644 tools/newkey.snk
diff --git a/.gitignore b/.gitignore
index 0fb89cd89..03fa9e40a 100644
--- a/.gitignore
+++ b/.gitignore
@@ -27,4 +27,5 @@ nuget.exe
project.lock.json
.vs
.build/
-.testPublish/
\ No newline at end of file
+.testPublish/
+tools/*
diff --git a/LinqToDB.Identity.sln b/LinqToDB.Identity.sln
index 1fb384c5b..922309590 100644
--- a/LinqToDB.Identity.sln
+++ b/LinqToDB.Identity.sln
@@ -11,8 +11,9 @@ EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{970CAB07-F853-4712-AA12-BD8961C8E430}"
ProjectSection(SolutionItems) = preProject
appveyor.yml = appveyor.yml
- build.cmd = build.cmd
+ build.cake = build.cake
build.ps1 = build.ps1
+ linq2db.snk = linq2db.snk
NuGet.config = NuGet.config
README.md = README.md
EndProjectSection
diff --git a/tools/Key.snk b/Tests.snk
similarity index 100%
rename from tools/Key.snk
rename to Tests.snk
diff --git a/appveyor.yml b/appveyor.yml
index 9d3a9f482..7a673913d 100644
--- a/appveyor.yml
+++ b/appveyor.yml
@@ -1,60 +1,34 @@
init:
- git config --global core.autocrlf true
-
-version: 1.1.0.{build}
-
-configuration: Release
+- ps: |
+ [Environment]::SetEnvironmentVariable("Test:SqlServer:DefaultConnectionString", "Server=(local)\SQL2012SP1;Database=master;Integrated Security=true", "Machine")
+ [Environment]::SetEnvironmentVariable("Test:SqlServer:DefaultConnectionString", "Server=(local)\SQL2012SP1;Database=master;Integrated Security=true")
cache:
- packages -> **\packages.config
- '%USERPROFILE%\.nuget\packages -> **\project.json'
+environment:
+ nugetVersion: 1.0.0
-assembly_info:
- patch: true
- file: '**\AssemblyInfo.*'
- assembly_version: '{version}'
- assembly_file_version: '{version}'
- assembly_informational_version: '{version}'
+version: $(nugetVersion).{build}
+
+build_script:
+- ps: .\build.ps1
+test: off
+
+artifacts:
+- path: artifacts/packages/*.nupkg
services:
- mssql2012sp1
#- mysql
#- postgresql
-before_build:
-- cmd: dotnet restore
-
build:
project: LinqToDB.Identity.sln
verbosity: minimal
-after_build:
-- cmd: dotnet pack --no-build src/LinqToDB.Identity/project.json --version-suffix=preview1-final -c=Release
-
-before_test:
-- ps: |
- [Environment]::SetEnvironmentVariable("Test:SqlServer:DefaultConnectionString", "Server=(local)\SQL2012SP1;Database=master;Integrated Security=true", "Machine")
- [Environment]::SetEnvironmentVariable("Test:SqlServer:DefaultConnectionString", "Server=(local)\SQL2012SP1;Database=master;Integrated Security=true")
-
-test_script:
-- ps: |
- Write-Host "Connection string"
- Write-Host $([Environment]::GetEnvironmentVariable("Test:SqlServer:DefaultConnectionString"))
- dotnet test test\Microsoft.AspNetCore.Identity.EntityFrameworkCore.Test -c Release -f netcoreapp1.0
- $test1res = $LASTEXITCODE
- # upload results to AppVeyor
- #$wc = New-Object 'System.Net.WebClient'
- #$wc.UploadFile("https://ci.appveyor.com/api/testresults/xunit/$($env:APPVEYOR_JOB_ID)", (Resolve-Path .\TestResult.xml))
- dotnet test test\Microsoft.AspNetCore.Identity.EntityFrameworkCore.InMemory.Test -c Release -f netcoreapp1.0
- $test2res = $LASTEXITCODE
- # upload results to AppVeyor
- #$wc = New-Object 'System.Net.WebClient'
- #$wc.UploadFile("https://ci.appveyor.com/api/testresults/xunit/$($env:APPVEYOR_JOB_ID)", (Resolve-Path .\TestResult.xml))
- IF ($test1res -ne 0 -or $test2res -ne 0) { exit -1 }
-
-artifacts:
-- path: src\**\*.nupkg
deploy:
- provider: NuGet
diff --git a/build.cake b/build.cake
new file mode 100644
index 000000000..870e5937a
--- /dev/null
+++ b/build.cake
@@ -0,0 +1,135 @@
+#addin "MagicChunks"
+
+var target = Argument("target", "Default");
+var configuration = Argument("configuration", "Release");
+
+///////////////////////////////////////////////////////////////////////////////
+// GLOBAL VARIABLES
+///////////////////////////////////////////////////////////////////////////////
+var isLocalBuild = !AppVeyor.IsRunningOnAppVeyor;
+var packPath = Directory("./src/LinqToDB.Identity");
+var sourcePath = Directory("./src");
+var testsPath = Directory("test");
+var buildArtifacts = Directory("./artifacts/packages");
+var solutionName = "./LinqToDB.Identity.sln";
+var envPackageVersion = EnvironmentVariable("nugetVersion");
+var argRelease = Argument("Release", null);
+
+var packageSuffix = "";
+var packageVersion = "";
+var fullPackageVersion = "";
+
+Task("Build")
+ .IsDependentOn("Clean")
+ .IsDependentOn("Restore")
+ .Does(() =>
+{
+
+ // Patch Version for CI builds
+ if (!isLocalBuild || envPackageVersion != null)
+ {
+ packageVersion = envPackageVersion;
+ var assemblyVersion = packageVersion + ".0";
+
+ if (AppVeyor.Environment.Repository.Branch.ToLower() != "release" && argRelease == null)
+ {
+ packageSuffix = "rc" + AppVeyor.Environment.Build.Number.ToString();
+ fullPackageVersion = packageVersion + "-" + packageSuffix;
+ }
+
+ Console.WriteLine("Package Version: {0}", packageVersion);
+ Console.WriteLine("Package Suffix : {0}", packageSuffix);
+ Console.WriteLine("Assembly Version: {0}", assemblyVersion);
+
+
+ TransformConfig("./src/LinqToDB.Identity/LinqToDB.Identity.csproj", "./src/LinqToDB.Identity/LinqToDB.Identity.csproj",
+ new TransformationCollection {
+ { "Project/PropertyGroup/Version", fullPackageVersion },
+ { "Project/PropertyGroup/VersionPrefix", packageVersion },
+ { "Project/PropertyGroup/VersionSuffix", packageSuffix },
+ { "Project/PropertyGroup/AssemblyVersion", assemblyVersion },
+ { "Project/PropertyGroup/FileVersion", assemblyVersion },
+ });
+
+ }
+
+ var settings = new DotNetCoreBuildSettings
+ {
+ Configuration = configuration
+ // Runtime = IsRunningOnWindows() ? null : "unix-x64"
+ };
+
+ DotNetCoreBuild(solutionName, settings);
+});
+
+Task("RunTests")
+ .IsDependentOn("Restore")
+ .IsDependentOn("Clean")
+ .Does(() =>
+{
+ var projects = GetFiles("./test/**/*.csproj");
+
+ foreach(var project in projects)
+ {
+ var settings = new DotNetCoreTestSettings
+ {
+ Configuration = configuration,
+ NoBuild = true
+ };
+
+ Console.WriteLine(project.FullPath);
+
+ DotNetCoreTest(project.FullPath, settings);
+ }
+});
+
+Task("Pack")
+ .IsDependentOn("Restore")
+ .IsDependentOn("Clean")
+ .Does(() =>
+{
+ var settings = new DotNetCorePackSettings
+ {
+ Configuration = configuration,
+ OutputDirectory = buildArtifacts,
+ NoBuild = true,
+ VersionSuffix = packageSuffix
+ };
+
+/*
+ if (!string.IsNullOrEmpty(packageVersion))
+ settings.ArgumentCustomization = b =>
+ {
+ Console.WriteLine("Package Version: {0}", packageVersion);
+
+ b.Append(" /p:VersionSuffix=" + "rc10");
+ return b;
+ };
+*/
+
+ DotNetCorePack(packPath, settings);
+});
+
+Task("Clean")
+ .Does(() =>
+{
+ CleanDirectories(new DirectoryPath[] { buildArtifacts });
+});
+
+Task("Restore")
+ .Does(() =>
+{
+ var settings = new DotNetCoreRestoreSettings
+ {
+ //Sources = new [] { "https://api.nuget.org/v3/index.json" }
+ };
+
+ DotNetCoreRestore(solutionName, settings);
+});
+
+Task("Default")
+ .IsDependentOn("Build")
+ .IsDependentOn("RunTests")
+ .IsDependentOn("Pack");
+
+RunTarget(target);
\ No newline at end of file
diff --git a/build.cmd b/build.cmd
deleted file mode 100644
index 7d4894cb4..000000000
--- a/build.cmd
+++ /dev/null
@@ -1,2 +0,0 @@
-@ECHO OFF
-PowerShell -NoProfile -NoLogo -ExecutionPolicy unrestricted -Command "[System.Threading.Thread]::CurrentThread.CurrentCulture = ''; [System.Threading.Thread]::CurrentThread.CurrentUICulture = '';& '%~dp0build.ps1' %*; exit $LASTEXITCODE"
\ No newline at end of file
diff --git a/build.ps1 b/build.ps1
index 787f63ac0..44de57932 100644
--- a/build.ps1
+++ b/build.ps1
@@ -1,67 +1,189 @@
-$ErrorActionPreference = "Stop"
+##########################################################################
+# This is the Cake bootstrapper script for PowerShell.
+# This file was downloaded from https://github.com/cake-build/resources
+# Feel free to change this file to fit your needs.
+##########################################################################
-function DownloadWithRetry([string] $url, [string] $downloadLocation, [int] $retries)
+<#
+
+.SYNOPSIS
+This is a Powershell script to bootstrap a Cake build.
+
+.DESCRIPTION
+This Powershell script will download NuGet if missing, restore NuGet tools (including Cake)
+and execute your Cake build script with the parameters you provide.
+
+.PARAMETER Script
+The build script to execute.
+.PARAMETER Target
+The build script target to run.
+.PARAMETER Configuration
+The build configuration to use.
+.PARAMETER Verbosity
+Specifies the amount of information to be displayed.
+.PARAMETER Experimental
+Tells Cake to use the latest Roslyn release.
+.PARAMETER WhatIf
+Performs a dry run of the build script.
+No tasks will be executed.
+.PARAMETER Mono
+Tells Cake to use the Mono scripting engine.
+.PARAMETER SkipToolPackageRestore
+Skips restoring of packages.
+.PARAMETER ScriptArgs
+Remaining arguments are added here.
+
+.LINK
+http://cakebuild.net
+
+#>
+
+[CmdletBinding()]
+Param(
+ [string]$Script = "build.cake",
+ [string]$Target = "Default",
+ [ValidateSet("Release", "Debug")]
+ [string]$Configuration = "Release",
+ [ValidateSet("Quiet", "Minimal", "Normal", "Verbose", "Diagnostic")]
+ [string]$Verbosity = "Verbose",
+ [switch]$Experimental,
+ [Alias("DryRun","Noop")]
+ [switch]$WhatIf,
+ [switch]$Mono,
+ [switch]$SkipToolPackageRestore,
+ [Parameter(Position=0,Mandatory=$false,ValueFromRemainingArguments=$true)]
+ [string[]]$ScriptArgs
+)
+
+[Reflection.Assembly]::LoadWithPartialName("System.Security") | Out-Null
+function MD5HashFile([string] $filePath)
{
- while($true)
+ if ([string]::IsNullOrEmpty($filePath) -or !(Test-Path $filePath -PathType Leaf))
{
- try
- {
- Invoke-WebRequest $url -OutFile $downloadLocation
- break
- }
- catch
+ return $null
+ }
+
+ [System.IO.Stream] $file = $null;
+ [System.Security.Cryptography.MD5] $md5 = $null;
+ try
+ {
+ $md5 = [System.Security.Cryptography.MD5]::Create()
+ $file = [System.IO.File]::OpenRead($filePath)
+ return [System.BitConverter]::ToString($md5.ComputeHash($file))
+ }
+ finally
+ {
+ if ($file -ne $null)
{
- $exceptionMessage = $_.Exception.Message
- Write-Host "Failed to download '$url': $exceptionMessage"
- if ($retries -gt 0) {
- $retries--
- Write-Host "Waiting 10 seconds before retrying. Retries left: $retries"
- Start-Sleep -Seconds 10
-
- }
- else
- {
- $exception = $_.Exception
- throw $exception
- }
+ $file.Dispose()
}
}
}
-cd $PSScriptRoot
+Write-Host "Preparing to run build script..."
-$repoFolder = $PSScriptRoot
-$env:REPO_FOLDER = $repoFolder
+if(!$PSScriptRoot){
+ $PSScriptRoot = Split-Path $MyInvocation.MyCommand.Path -Parent
+}
-$koreBuildZip="https://github.com/aspnet/KoreBuild/archive/rel/1.1.0-preview1.zip"
-if ($env:KOREBUILD_ZIP)
-{
- $koreBuildZip=$env:KOREBUILD_ZIP
+$TOOLS_DIR = Join-Path $PSScriptRoot "tools"
+$NUGET_EXE = Join-Path $TOOLS_DIR "nuget.exe"
+$CAKE_EXE = Join-Path $TOOLS_DIR "Cake/Cake.exe"
+$NUGET_URL = "https://dist.nuget.org/win-x86-commandline/latest/nuget.exe"
+$PACKAGES_CONFIG = Join-Path $TOOLS_DIR "packages.config"
+$PACKAGES_CONFIG_MD5 = Join-Path $TOOLS_DIR "packages.config.md5sum"
+
+# Should we use mono?
+$UseMono = "";
+if($Mono.IsPresent) {
+ Write-Verbose -Message "Using the Mono based scripting engine."
+ $UseMono = "-mono"
}
-$buildFolder = ".build"
-$buildFile="$buildFolder\KoreBuild.ps1"
+# Should we use the new Roslyn?
+$UseExperimental = "";
+if($Experimental.IsPresent -and !($Mono.IsPresent)) {
+ Write-Verbose -Message "Using experimental version of Roslyn."
+ $UseExperimental = "-experimental"
+}
-if (!(Test-Path $buildFolder)) {
- Write-Host "Downloading KoreBuild from $koreBuildZip"
-
- $tempFolder=$env:TEMP + "\KoreBuild-" + [guid]::NewGuid()
- New-Item -Path "$tempFolder" -Type directory | Out-Null
+# Is this a dry run?
+$UseDryRun = "";
+if($WhatIf.IsPresent) {
+ $UseDryRun = "-dryrun"
+}
- $localZipFile="$tempFolder\korebuild.zip"
-
- DownloadWithRetry -url $koreBuildZip -downloadLocation $localZipFile -retries 6
+# Make sure tools folder exists
+if ((Test-Path $PSScriptRoot) -and !(Test-Path $TOOLS_DIR)) {
+ Write-Verbose -Message "Creating tools directory..."
+ New-Item -Path $TOOLS_DIR -Type directory | out-null
+}
+
+# Make sure that packages.config exist.
+if (!(Test-Path $PACKAGES_CONFIG)) {
+ Write-Verbose -Message "Downloading packages.config..."
+ try { (New-Object System.Net.WebClient).DownloadFile("http://cakebuild.net/download/bootstrapper/packages", $PACKAGES_CONFIG) } catch {
+ Throw "Could not download packages.config."
+ }
+}
+
+# Try find NuGet.exe in path if not exists
+if (!(Test-Path $NUGET_EXE)) {
+ Write-Verbose -Message "Trying to find nuget.exe in PATH..."
+ $existingPaths = $Env:Path -Split ';' | Where-Object { (![string]::IsNullOrEmpty($_)) -and (Test-Path $_) }
+ $NUGET_EXE_IN_PATH = Get-ChildItem -Path $existingPaths -Filter "nuget.exe" | Select -First 1
+ if ($NUGET_EXE_IN_PATH -ne $null -and (Test-Path $NUGET_EXE_IN_PATH.FullName)) {
+ Write-Verbose -Message "Found in PATH at $($NUGET_EXE_IN_PATH.FullName)."
+ $NUGET_EXE = $NUGET_EXE_IN_PATH.FullName
+ }
+}
+
+# Try download NuGet.exe if not exists
+if (!(Test-Path $NUGET_EXE)) {
+ Write-Verbose -Message "Downloading NuGet.exe..."
+ try {
+ (New-Object System.Net.WebClient).DownloadFile($NUGET_URL, $NUGET_EXE)
+ } catch {
+ Throw "Could not download NuGet.exe."
+ }
+}
+
+# Save nuget.exe path to environment to be available to child processed
+$ENV:NUGET_EXE = $NUGET_EXE
+
+# Restore tools from NuGet?
+if(-Not $SkipToolPackageRestore.IsPresent) {
+ Push-Location
+ Set-Location $TOOLS_DIR
+
+ # Check for changes in packages.config and remove installed tools if true.
+ [string] $md5Hash = MD5HashFile($PACKAGES_CONFIG)
+ if((!(Test-Path $PACKAGES_CONFIG_MD5)) -Or
+ ($md5Hash -ne (Get-Content $PACKAGES_CONFIG_MD5 ))) {
+ Write-Verbose -Message "Missing or changed package.config hash..."
+ Remove-Item * -Recurse -Exclude packages.config,nuget.exe
+ }
- Add-Type -AssemblyName System.IO.Compression.FileSystem
- [System.IO.Compression.ZipFile]::ExtractToDirectory($localZipFile, $tempFolder)
-
- New-Item -Path "$buildFolder" -Type directory | Out-Null
- copy-item "$tempFolder\**\build\*" $buildFolder -Recurse
+ Write-Verbose -Message "Restoring tools from NuGet..."
+ $NuGetOutput = Invoke-Expression "&`"$NUGET_EXE`" install -ExcludeVersion -OutputDirectory `"$TOOLS_DIR`""
- # Cleanup
- if (Test-Path $tempFolder) {
- Remove-Item -Recurse -Force $tempFolder
+ if ($LASTEXITCODE -ne 0) {
+ Throw "An error occured while restoring NuGet tools."
}
+ else
+ {
+ $md5Hash | Out-File $PACKAGES_CONFIG_MD5 -Encoding "ASCII"
+ }
+ Write-Verbose -Message ($NuGetOutput | out-string)
+ Pop-Location
+}
+
+# Make sure that Cake has been installed.
+if (!(Test-Path $CAKE_EXE)) {
+ Throw "Could not find Cake.exe at $CAKE_EXE"
}
-&"$buildFile" $args
\ No newline at end of file
+# Start Cake
+Write-Host "Running build script..."
+Invoke-Expression "& `"$CAKE_EXE`" `"$Script`" -target=`"$Target`" -configuration=`"$Configuration`" -verbosity=`"$Verbosity`" $UseMono $UseDryRun $UseExperimental $ScriptArgs"
+exit $LASTEXITCODE
\ No newline at end of file
diff --git a/build.sh b/build.sh
index 355c68285..6e8f207c8 100755
--- a/build.sh
+++ b/build.sh
@@ -1,46 +1,101 @@
#!/usr/bin/env bash
-repoFolder="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
-cd $repoFolder
-koreBuildZip="https://github.com/aspnet/KoreBuild/archive/rel/1.1.0-preview1.zip"
-if [ ! -z $KOREBUILD_ZIP ]; then
- koreBuildZip=$KOREBUILD_ZIP
+##########################################################################
+# This is the Cake bootstrapper script for Linux and OS X.
+# This file was downloaded from https://github.com/cake-build/resources
+# Feel free to change this file to fit your needs.
+##########################################################################
+
+# Define directories.
+SCRIPT_DIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )
+TOOLS_DIR=$SCRIPT_DIR/tools
+NUGET_EXE=$TOOLS_DIR/nuget.exe
+CAKE_EXE=$TOOLS_DIR/Cake/Cake.exe
+PACKAGES_CONFIG=$TOOLS_DIR/packages.config
+PACKAGES_CONFIG_MD5=$TOOLS_DIR/packages.config.md5sum
+
+# Define md5sum or md5 depending on Linux/OSX
+MD5_EXE=
+if [[ "$(uname -s)" == "Darwin" ]]; then
+ MD5_EXE="md5 -r"
+else
+ MD5_EXE="md5sum"
+fi
+
+# Define default arguments.
+SCRIPT="build.cake"
+TARGET="Default"
+CONFIGURATION="Release"
+VERBOSITY="verbose"
+DRYRUN=
+SHOW_VERSION=false
+SCRIPT_ARGUMENTS=()
+
+# Parse arguments.
+for i in "$@"; do
+ case $1 in
+ -s|--script) SCRIPT="$2"; shift ;;
+ -t|--target) TARGET="$2"; shift ;;
+ -c|--configuration) CONFIGURATION="$2"; shift ;;
+ -v|--verbosity) VERBOSITY="$2"; shift ;;
+ -d|--dryrun) DRYRUN="-dryrun" ;;
+ --version) SHOW_VERSION=true ;;
+ --) shift; SCRIPT_ARGUMENTS+=("$@"); break ;;
+ *) SCRIPT_ARGUMENTS+=("$1") ;;
+ esac
+ shift
+done
+
+# Make sure the tools folder exist.
+if [ ! -d "$TOOLS_DIR" ]; then
+ mkdir "$TOOLS_DIR"
+fi
+
+# Make sure that packages.config exist.
+if [ ! -f "$TOOLS_DIR/packages.config" ]; then
+ echo "Downloading packages.config..."
+ curl -Lsfo "$TOOLS_DIR/packages.config" http://cakebuild.net/download/bootstrapper/packages
+ if [ $? -ne 0 ]; then
+ echo "An error occured while downloading packages.config."
+ exit 1
+ fi
fi
-buildFolder=".build"
-buildFile="$buildFolder/KoreBuild.sh"
-
-if test ! -d $buildFolder; then
- echo "Downloading KoreBuild from $koreBuildZip"
-
- tempFolder="/tmp/KoreBuild-$(uuidgen)"
- mkdir $tempFolder
-
- localZipFile="$tempFolder/korebuild.zip"
-
- retries=6
- until (wget -O $localZipFile $koreBuildZip 2>/dev/null || curl -o $localZipFile --location $koreBuildZip 2>/dev/null)
- do
- echo "Failed to download '$koreBuildZip'"
- if [ "$retries" -le 0 ]; then
- exit 1
- fi
- retries=$((retries - 1))
- echo "Waiting 10 seconds before retrying. Retries left: $retries"
- sleep 10s
- done
-
- unzip -q -d $tempFolder $localZipFile
-
- mkdir $buildFolder
- cp -r $tempFolder/**/build/** $buildFolder
-
- chmod +x $buildFile
-
- # Cleanup
- if test ! -d $tempFolder; then
- rm -rf $tempFolder
+# Download NuGet if it does not exist.
+if [ ! -f "$NUGET_EXE" ]; then
+ echo "Downloading NuGet..."
+ curl -Lsfo "$NUGET_EXE" https://dist.nuget.org/win-x86-commandline/latest/nuget.exe
+ if [ $? -ne 0 ]; then
+ echo "An error occured while downloading nuget.exe."
+ exit 1
fi
fi
-$buildFile -r $repoFolder "$@"
\ No newline at end of file
+# Restore tools from NuGet.
+pushd "$TOOLS_DIR" >/dev/null
+if [ ! -f $PACKAGES_CONFIG_MD5 ] || [ "$( cat $PACKAGES_CONFIG_MD5 | sed 's/\r$//' )" != "$( $MD5_EXE $PACKAGES_CONFIG | awk '{ print $1 }' )" ]; then
+ find . -type d ! -name . | xargs rm -rf
+fi
+
+mono "$NUGET_EXE" install -ExcludeVersion
+if [ $? -ne 0 ]; then
+ echo "Could not restore NuGet packages."
+ exit 1
+fi
+
+$MD5_EXE $PACKAGES_CONFIG | awk '{ print $1 }' >| $PACKAGES_CONFIG_MD5
+
+popd >/dev/null
+
+# Make sure that Cake has been installed.
+if [ ! -f "$CAKE_EXE" ]; then
+ echo "Could not find Cake.exe at '$CAKE_EXE'."
+ exit 1
+fi
+
+# Start Cake
+if $SHOW_VERSION; then
+ exec mono "$CAKE_EXE" -version
+else
+ exec mono "$CAKE_EXE" $SCRIPT -verbosity=$VERBOSITY -configuration=$CONFIGURATION -target=$TARGET $DRYRUN "${SCRIPT_ARGUMENTS[@]}"
+fi
\ No newline at end of file
diff --git a/linq2db.snk b/linq2db.snk
new file mode 100644
index 0000000000000000000000000000000000000000..774bb0a9abbc205e6d9889970ab5562f48d85c6c
GIT binary patch
literal 596
zcmV-a0;~N80ssI2Bme+XQ$aES1ONa500971>7<@|%^N8&F=^aQ
zBkf&MKuesq#nLnAvnX*xz5Q*;&8s$4_0o1MY%qu_ozq0;nJmaccmN!00T4W)=%H
z-x+vm&GSbu5dHfpN>16lnk3|lwV8p0x~YwDep2XERIpt{KwvG{t&=@##bLtq77}h_
z+fF2|EX1cJ5I}l`e|+dIjr*F6aO>ZVlBHnry$Ok2X-r`!W)&LEXia#Y*@pf>KiUfR
z&@8Zjw04I03N(epB_LwgGCKkp8Wpwy8*(mPwxA&y0$dF=@tWar&F-(Rqiz^A7}Jc#*p-wf=3{~MJwpmy?%vY{JJ6
zd=(N#;?yjG=Zqb0s9S)HXubh?o!J(E8>}ojl+3W`JI=ij+&aw5_6^2(?@d4`kf1A`
z$s8e%Q8HljiMjg_?$g!WCyqt6=M~;$3gjSQ(m$|KOvN(PB#>({o@9}S*^|uVCYazI
iG6q0fhX`CYjipz@YHH{)H29u6y!ykg!LTK!h^3yEXCOQP
literal 0
HcmV?d00001
diff --git a/src/LinqToDB.Identity/LinqToDB.Identity.csproj b/src/LinqToDB.Identity/LinqToDB.Identity.csproj
index 59052432c..eb6779336 100644
--- a/src/LinqToDB.Identity/LinqToDB.Identity.csproj
+++ b/src/LinqToDB.Identity/LinqToDB.Identity.csproj
@@ -8,7 +8,7 @@
true
true
LinqToDB.Identity
- ../../tools/newkey.snk
+ $(SolutionDir)linq2db.snk
true
true
linq2db.Identity
diff --git a/test/Microsoft.AspNetCore.Identity.EntityFrameworkCore.InMemory.Test/Microsoft.AspNetCore.Identity.EntityFrameworkCore.InMemory.Test.csproj b/test/Microsoft.AspNetCore.Identity.EntityFrameworkCore.InMemory.Test/Microsoft.AspNetCore.Identity.EntityFrameworkCore.InMemory.Test.csproj
index ce4d118ab..e50d6c756 100644
--- a/test/Microsoft.AspNetCore.Identity.EntityFrameworkCore.InMemory.Test/Microsoft.AspNetCore.Identity.EntityFrameworkCore.InMemory.Test.csproj
+++ b/test/Microsoft.AspNetCore.Identity.EntityFrameworkCore.InMemory.Test/Microsoft.AspNetCore.Identity.EntityFrameworkCore.InMemory.Test.csproj
@@ -4,7 +4,7 @@
netcoreapp1.0
true
Microsoft.AspNetCore.Identity.EntityFrameworkCore.InMemory.Test
- ../../tools/Key.snk
+ $(SolutionDir)Tests.snk
true
true
Microsoft.AspNetCore.Identity.EntityFrameworkCore.InMemory.Test
diff --git a/test/Microsoft.AspNetCore.Identity.EntityFrameworkCore.Test/Microsoft.AspNetCore.Identity.EntityFrameworkCore.Test.csproj b/test/Microsoft.AspNetCore.Identity.EntityFrameworkCore.Test/Microsoft.AspNetCore.Identity.EntityFrameworkCore.Test.csproj
index ad796fa8c..2c2cc2774 100644
--- a/test/Microsoft.AspNetCore.Identity.EntityFrameworkCore.Test/Microsoft.AspNetCore.Identity.EntityFrameworkCore.Test.csproj
+++ b/test/Microsoft.AspNetCore.Identity.EntityFrameworkCore.Test/Microsoft.AspNetCore.Identity.EntityFrameworkCore.Test.csproj
@@ -4,7 +4,7 @@
netcoreapp1.0
true
Microsoft.AspNetCore.Identity.EntityFrameworkCore.Test
- ../../tools/Key.snk
+ $(SolutionDir)Tests.snk
true
true
Microsoft.AspNetCore.Identity.EntityFrameworkCore.Test
diff --git a/tools/newkey.snk b/tools/newkey.snk
deleted file mode 100644
index 2e1bc24bd8ad1fd69ccde3f68f3c3a0ecad92c0e..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001
literal 596
zcmV-a0;~N80ssI2Bme+XQ$aES1ONa50096u3^)ak4y8^%Ao+ZDG8f
zKoLi_eV>@K3h^`H$Tdt(&C6Y3x|$|x&L>OXk-cnt9o^kDXJ5?8FI$5Mk5%JpkIv*b
z-X|GIBvqdE8w`BY0*K1RRCv1zWqkKZ&>oi6E!Z9JN86{aVl}sA
zj%NB@V^Rv<&&c%wLTYXsXenet2Xj-2VL{Oz3Xt52X0|vq1f(u*&j|KCr!G?@-d0|)
z2Nhfk=1Cnkx@;W4K~u?q6(M+0xhkvH^TX~23S(qYUm!6
z6u+3i^fL|nw@!N+hm00En%fk8^SfZQ>e;UIkN_BTCrlzXZ*i+y%-E5-#6v``{IpX(_NWt08
zz0)VZmRM^6@@n@0+sXkTTBzDO^H0Rm-uQj#~r(|{iRMA-W|oMMPlbO0E2E|Fai&-EYKo)Q?kf1gC`
Date: Wed, 17 May 2017 15:22:12 +0500
Subject: [PATCH 4/8] cleanup
---
build.cake | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/build.cake b/build.cake
index 870e5937a..2ddb75630 100644
--- a/build.cake
+++ b/build.cake
@@ -12,6 +12,7 @@ var sourcePath = Directory("./src");
var testsPath = Directory("test");
var buildArtifacts = Directory("./artifacts/packages");
var solutionName = "./LinqToDB.Identity.sln";
+var nugetProject = "./src/LinqToDB.Identity/LinqToDB.Identity.csproj";
var envPackageVersion = EnvironmentVariable("nugetVersion");
var argRelease = Argument("Release", null);
@@ -42,7 +43,7 @@ Task("Build")
Console.WriteLine("Assembly Version: {0}", assemblyVersion);
- TransformConfig("./src/LinqToDB.Identity/LinqToDB.Identity.csproj", "./src/LinqToDB.Identity/LinqToDB.Identity.csproj",
+ TransformConfig(nugetProject, nugetProject,
new TransformationCollection {
{ "Project/PropertyGroup/Version", fullPackageVersion },
{ "Project/PropertyGroup/VersionPrefix", packageVersion },
From 13d1be7f538314a77fd07d45db15118c230feb7e Mon Sep 17 00:00:00 2001
From: Ilya Chudin
Date: Wed, 17 May 2017 15:29:55 +0500
Subject: [PATCH 5/8] appveyor.yml
---
appveyor.yml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/appveyor.yml b/appveyor.yml
index 7a673913d..a8b7d9a56 100644
--- a/appveyor.yml
+++ b/appveyor.yml
@@ -1,6 +1,6 @@
init:
- git config --global core.autocrlf true
-- ps: |
+ - ps: |
[Environment]::SetEnvironmentVariable("Test:SqlServer:DefaultConnectionString", "Server=(local)\SQL2012SP1;Database=master;Integrated Security=true", "Machine")
[Environment]::SetEnvironmentVariable("Test:SqlServer:DefaultConnectionString", "Server=(local)\SQL2012SP1;Database=master;Integrated Security=true")
From e28b4c9ec83ac232583467b1cf4dbf7c726d5709 Mon Sep 17 00:00:00 2001
From: Ilya Chudin
Date: Wed, 17 May 2017 15:31:56 +0500
Subject: [PATCH 6/8] appveyor.yml
---
appveyor.yml | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/appveyor.yml b/appveyor.yml
index a8b7d9a56..9e6615786 100644
--- a/appveyor.yml
+++ b/appveyor.yml
@@ -1,8 +1,7 @@
init:
- git config --global core.autocrlf true
- - ps: |
- [Environment]::SetEnvironmentVariable("Test:SqlServer:DefaultConnectionString", "Server=(local)\SQL2012SP1;Database=master;Integrated Security=true", "Machine")
- [Environment]::SetEnvironmentVariable("Test:SqlServer:DefaultConnectionString", "Server=(local)\SQL2012SP1;Database=master;Integrated Security=true")
+ - ps: [Environment]::SetEnvironmentVariable("Test:SqlServer:DefaultConnectionString", "Server=(local)\SQL2012SP1;Database=master;Integrated Security=true", "Machine")
+ - ps: [Environment]::SetEnvironmentVariable("Test:SqlServer:DefaultConnectionString", "Server=(local)\SQL2012SP1;Database=master;Integrated Security=true")
cache:
- packages -> **\packages.config
@@ -15,6 +14,7 @@ version: $(nugetVersion).{build}
build_script:
- ps: .\build.ps1
+
test: off
artifacts:
From cf88353bd6268739d411d3be084694dd0c8df27c Mon Sep 17 00:00:00 2001
From: Ilya Chudin
Date: Wed, 17 May 2017 15:43:26 +0500
Subject: [PATCH 7/8] cleanup
---
NuGet.config | 11 +-
appveyor.yml | 3 +-
.../Controllers/AccountController.cs | 871 ++--
.../Controllers/HomeController.cs | 40 +-
.../Controllers/ManageController.cs | 624 ++-
samples/IdentitySample.Mvc/MessageServices.cs | 27 +-
.../ExternalLoginConfirmationViewModel.cs | 20 +-
.../ForgotPasswordViewModel.cs | 20 +-
.../AccountViewModels/LoginViewModel.cs | 30 +-
.../AccountViewModels/RegisterViewModel.cs | 40 +-
.../ResetPasswordViewModel.cs | 38 +-
.../AccountViewModels/SendCodeViewModel.cs | 19 +-
.../AccountViewModels/VerifyCodeViewModel.cs | 32 +-
.../Models/ApplicationDbContext.cs | 12 +-
.../Models/ApplicationUser.cs | 14 +-
.../AddPhoneNumberViewModel.cs | 22 +-
.../ChangePasswordViewModel.cs | 40 +-
.../ConfigureTwoFactorViewModel.cs | 15 +-
.../ManageViewModels/FactorViewModel.cs | 17 +-
.../Models/ManageViewModels/IndexViewModel.cs | 21 +-
.../ManageViewModels/ManageLoginsViewModel.cs | 15 +-
.../ManageViewModels/RemoveLoginViewModel.cs | 20 +-
.../ManageViewModels/SetPasswordViewModel.cs | 32 +-
.../VerifyPhoneNumberViewModel.cs | 26 +-
samples/IdentitySample.Mvc/Program.cs | 30 +-
.../Properties/launchSettings.json | 46 +-
.../Services/IEmailSender.cs | 15 +-
.../IdentitySample.Mvc/Services/ISmsSender.cs | 15 +-
.../Services/MessageServices.cs | 39 +-
samples/IdentitySample.Mvc/Startup.cs | 232 +-
.../Views/Account/ConfirmEmail.cshtml | 10 +-
.../Account/ExternalLoginConfirmation.cshtml | 46 +-
.../Views/Account/ExternalLoginFailure.cshtml | 8 +-
.../Views/Account/ForgotPassword.cshtml | 8 +-
.../Account/ForgotPasswordConfirmation.cshtml | 6 +-
.../Views/Account/Lockout.cshtml | 8 +-
.../Views/Account/Login.cshtml | 159 +-
.../Views/Account/Register.cshtml | 64 +-
.../Views/Account/ResetPassword.cshtml | 66 +-
.../Account/ResetPasswordConfirmation.cshtml | 6 +-
.../Views/Account/SendCode.cshtml | 22 +-
.../Views/Account/VerifyCode.cshtml | 56 +-
.../Views/Home/Index.cshtml | 448 +-
.../Views/Manage/AddPhoneNumber.cshtml | 36 +-
.../Views/Manage/ChangePassword.cshtml | 64 +-
.../Views/Manage/Index.cshtml | 74 +-
.../Views/Manage/ManageLogins.cshtml | 83 +-
.../Views/Manage/SetPassword.cshtml | 54 +-
.../Views/Manage/VerifyPhoneNumber.cshtml | 40 +-
.../Views/Shared/_Layout.cshtml | 90 +-
.../Views/Shared/_LoginPartial.cshtml | 35 +-
.../Shared/_ValidationScriptsPartial.cshtml | 4 +-
.../Views/_ViewImports.cshtml | 2 +-
.../Views/_ViewStart.cshtml | 4 +-
samples/IdentitySample.Mvc/appsettings.json | 29 +-
samples/IdentitySample.Mvc/web.Debug.config | 10 +-
samples/IdentitySample.Mvc/web.Release.config | 12 +-
samples/IdentitySample.Mvc/web.config | 14 +-
.../IdentitySample.Mvc/wwwroot/css/site.css | 34 +-
.../DefaultConnectionFactory.cs | 10 +-
src/LinqToDB.Identity/Extensions.cs | 6 +-
.../IdentityDataConnection.cs | 8 +-
.../IdentityLinqToDbBuilderExtensions.cs | 3 +-
src/LinqToDB.Identity/IdentityRole.cs | 5 +-
src/LinqToDB.Identity/IdentityUser.cs | 2 +-
src/LinqToDB.Identity/RoleStore.cs | 15 +-
src/LinqToDB.Identity/TaskTools.cs | 16 +-
src/LinqToDB.Identity/UserStore.cs | 77 +-
.../InMemoryContext.cs | 3 +-
.../InMemoryEFUserStoreTest.cs | 152 +-
.../InMemoryStoreWithGenericsTest.cs | 607 +--
.../RoleStoreTest.cs | 139 +-
.../TestIdentityFactory.cs | 75 +-
.../CustomPocoTest.cs | 260 +-
.../DbUtil.cs | 42 +-
.../DefaultPocoTest.cs | 350 +-
.../MiscTest.cs | 12 +-
.../SqlStoreTestBase.cs | 683 +--
.../UserStoreGuidKeyTest.cs | 95 +-
.../UserStoreIntKeyTest.cs | 52 +-
.../UserStoreStringKeyTest.cs | 52 +-
.../UserStoreTest.cs | 787 ++--
.../UserStoreWithGenericsTest.cs | 695 +--
.../EntityFrameworkServiceBuilderExtension.cs | 12 +-
.../Utilities/ScratchDatabaseFixture.cs | 20 +-
.../Utilities/SqlServerTestStore.cs | 312 +-
.../Utilities/TestEnvironment.cs | 28 +-
.../config.json | 8 +-
test/Shared/ApiConsistencyTestBase.cs | 144 +-
test/Shared/IdentityResultAssert.cs | 73 +-
test/Shared/MockHelpers.cs | 158 +-
test/Shared/PasswordHasherOptionsAccessor.cs | 9 +-
test/Shared/PriorityOrderer.cs | 108 +-
test/Shared/TestLogger.cs | 53 +-
test/Shared/TestRole.cs | 111 +-
test/Shared/TestRoleClaim.cs | 50 +-
test/Shared/TestUser.cs | 180 +-
test/Shared/TestUserClaim.cs | 50 +-
test/Shared/TestUserLogin.cs | 50 +-
test/Shared/TestUserRole.cs | 34 +-
test/Shared/TestUserToken.cs | 50 +-
test/Shared/UserManagerTestBase.cs | 3790 ++++++++---------
102 files changed, 6515 insertions(+), 6749 deletions(-)
diff --git a/NuGet.config b/NuGet.config
index fe4af3374..1db8e2134 100644
--- a/NuGet.config
+++ b/NuGet.config
@@ -1,8 +1,9 @@
-
+
+
-
-
-
+
+
+
-
+
\ No newline at end of file
diff --git a/appveyor.yml b/appveyor.yml
index 9e6615786..944147f3d 100644
--- a/appveyor.yml
+++ b/appveyor.yml
@@ -1,7 +1,6 @@
init:
- git config --global core.autocrlf true
- - ps: [Environment]::SetEnvironmentVariable("Test:SqlServer:DefaultConnectionString", "Server=(local)\SQL2012SP1;Database=master;Integrated Security=true", "Machine")
- - ps: [Environment]::SetEnvironmentVariable("Test:SqlServer:DefaultConnectionString", "Server=(local)\SQL2012SP1;Database=master;Integrated Security=true")
+ - ps: $env:TestSqlServerDefaultConnectionString = "Server=(local)\SQL2012SP1;Database=master;Integrated Security=true"
cache:
- packages -> **\packages.config
diff --git a/samples/IdentitySample.Mvc/Controllers/AccountController.cs b/samples/IdentitySample.Mvc/Controllers/AccountController.cs
index 036806e21..90d6a52bb 100644
--- a/samples/IdentitySample.Mvc/Controllers/AccountController.cs
+++ b/samples/IdentitySample.Mvc/Controllers/AccountController.cs
@@ -1,475 +1,418 @@
-using System;
-using System.Collections.Generic;
using System.Linq;
using System.Security.Claims;
using System.Threading.Tasks;
+using IdentitySample.Models;
+using IdentitySample.Models.AccountViewModels;
+using IdentitySample.Services;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Rendering;
using Microsoft.Extensions.Logging;
-using IdentitySample.Models;
-using IdentitySample.Models.AccountViewModels;
-using IdentitySample.Services;
namespace IdentitySample.Controllers
{
- [Authorize]
- public class AccountController : Controller
- {
- private readonly UserManager _userManager;
- private readonly SignInManager _signInManager;
- private readonly IEmailSender _emailSender;
- private readonly ISmsSender _smsSender;
- private readonly ILogger _logger;
-
- public AccountController(
- UserManager userManager,
- SignInManager signInManager,
- IEmailSender emailSender,
- ISmsSender smsSender,
- ILoggerFactory loggerFactory)
- {
- _userManager = userManager;
- _signInManager = signInManager;
- _emailSender = emailSender;
- _smsSender = smsSender;
- _logger = loggerFactory.CreateLogger();
- }
-
- //
- // GET: /Account/Login
- [HttpGet]
- [AllowAnonymous]
- public IActionResult Login(string returnUrl = null)
- {
- ViewData["ReturnUrl"] = returnUrl;
- return View();
- }
-
- //
- // POST: /Account/Login
- [HttpPost]
- [AllowAnonymous]
- [ValidateAntiForgeryToken]
- public async Task Login(LoginViewModel model, string returnUrl = null)
- {
- ViewData["ReturnUrl"] = returnUrl;
- if (ModelState.IsValid)
- {
- // This doesn't count login failures towards account lockout
- // To enable password failures to trigger account lockout, set lockoutOnFailure: true
- var result = await _signInManager.PasswordSignInAsync(model.Email, model.Password, model.RememberMe, lockoutOnFailure: false);
- if (result.Succeeded)
- {
- _logger.LogInformation(1, "User logged in.");
- return RedirectToLocal(returnUrl);
- }
- if (result.RequiresTwoFactor)
- {
- return RedirectToAction(nameof(SendCode), new { ReturnUrl = returnUrl, RememberMe = model.RememberMe });
- }
- if (result.IsLockedOut)
- {
- _logger.LogWarning(2, "User account locked out.");
- return View("Lockout");
- }
- else
- {
- ModelState.AddModelError(string.Empty, "Invalid login attempt.");
- return View(model);
- }
- }
-
- // If we got this far, something failed, redisplay form
- return View(model);
- }
-
- //
- // GET: /Account/Register
- [HttpGet]
- [AllowAnonymous]
- public IActionResult Register(string returnUrl = null)
- {
- ViewData["ReturnUrl"] = returnUrl;
- return View();
- }
-
- //
- // POST: /Account/Register
- [HttpPost]
- [AllowAnonymous]
- [ValidateAntiForgeryToken]
- public async Task Register(RegisterViewModel model, string returnUrl = null)
- {
- ViewData["ReturnUrl"] = returnUrl;
- if (ModelState.IsValid)
- {
- var user = new ApplicationUser { UserName = model.Email, Email = model.Email };
- var result = await _userManager.CreateAsync(user, model.Password);
- if (result.Succeeded)
- {
- // For more information on how to enable account confirmation and password reset please visit http://go.microsoft.com/fwlink/?LinkID=532713
- // Send an email with this link
- //var code = await _userManager.GenerateEmailConfirmationTokenAsync(user);
- //var callbackUrl = Url.Action("ConfirmEmail", "Account", new { userId = user.Id, code = code }, protocol: HttpContext.Request.Scheme);
- //await _emailSender.SendEmailAsync(model.Email, "Confirm your account",
- // "Please confirm your account by clicking this link: link ");
- await _signInManager.SignInAsync(user, isPersistent: false);
- _logger.LogInformation(3, "User created a new account with password.");
- return RedirectToLocal(returnUrl);
- }
- AddErrors(result);
- }
-
- // If we got this far, something failed, redisplay form
- return View(model);
- }
-
- //
- // POST: /Account/LogOff
- [HttpPost]
- [ValidateAntiForgeryToken]
- public async Task LogOff()
- {
- await _signInManager.SignOutAsync();
- _logger.LogInformation(4, "User logged out.");
- return RedirectToAction(nameof(HomeController.Index), "Home");
- }
-
- //
- // POST: /Account/ExternalLogin
- [HttpPost]
- [AllowAnonymous]
- [ValidateAntiForgeryToken]
- public IActionResult ExternalLogin(string provider, string returnUrl = null)
- {
- // Request a redirect to the external login provider.
- var redirectUrl = Url.Action("ExternalLoginCallback", "Account", new { ReturnUrl = returnUrl });
- var properties = _signInManager.ConfigureExternalAuthenticationProperties(provider, redirectUrl);
- return Challenge(properties, provider);
- }
-
- //
- // GET: /Account/ExternalLoginCallback
- [HttpGet]
- [AllowAnonymous]
- public async Task ExternalLoginCallback(string returnUrl = null, string remoteError = null)
- {
- if (remoteError != null)
- {
- ModelState.AddModelError(string.Empty, $"Error from external provider: {remoteError}");
- return View(nameof(Login));
- }
- var info = await _signInManager.GetExternalLoginInfoAsync();
- if (info == null)
- {
- return RedirectToAction(nameof(Login));
- }
-
- // Sign in the user with this external login provider if the user already has a login.
- var result = await _signInManager.ExternalLoginSignInAsync(info.LoginProvider, info.ProviderKey, isPersistent: false);
- if (result.Succeeded)
- {
- // Update any authentication tokens if login succeeded
- await _signInManager.UpdateExternalAuthenticationTokensAsync(info);
-
- _logger.LogInformation(5, "User logged in with {Name} provider.", info.LoginProvider);
- return RedirectToLocal(returnUrl);
- }
- if (result.RequiresTwoFactor)
- {
- return RedirectToAction(nameof(SendCode), new { ReturnUrl = returnUrl });
- }
- if (result.IsLockedOut)
- {
- return View("Lockout");
- }
- else
- {
- // If the user does not have an account, then ask the user to create an account.
- ViewData["ReturnUrl"] = returnUrl;
- ViewData["LoginProvider"] = info.LoginProvider;
- var email = info.Principal.FindFirstValue(ClaimTypes.Email);
- return View("ExternalLoginConfirmation", new ExternalLoginConfirmationViewModel { Email = email });
- }
- }
-
- //
- // POST: /Account/ExternalLoginConfirmation
- [HttpPost]
- [AllowAnonymous]
- [ValidateAntiForgeryToken]
- public async Task ExternalLoginConfirmation(ExternalLoginConfirmationViewModel model, string returnUrl = null)
- {
- if (ModelState.IsValid)
- {
- // Get the information about the user from the external login provider
- var info = await _signInManager.GetExternalLoginInfoAsync();
- if (info == null)
- {
- return View("ExternalLoginFailure");
- }
- var user = new ApplicationUser { UserName = model.Email, Email = model.Email };
- var result = await _userManager.CreateAsync(user);
- if (result.Succeeded)
- {
- result = await _userManager.AddLoginAsync(user, info);
- if (result.Succeeded)
- {
- await _signInManager.SignInAsync(user, isPersistent: false);
- _logger.LogInformation(6, "User created an account using {Name} provider.", info.LoginProvider);
-
- // Update any authentication tokens as well
- await _signInManager.UpdateExternalAuthenticationTokensAsync(info);
-
- return RedirectToLocal(returnUrl);
- }
- }
- AddErrors(result);
- }
-
- ViewData["ReturnUrl"] = returnUrl;
- return View(model);
- }
-
- // GET: /Account/ConfirmEmail
- [HttpGet]
- [AllowAnonymous]
- public async Task ConfirmEmail(string userId, string code)
- {
- if (userId == null || code == null)
- {
- return View("Error");
- }
- var user = await _userManager.FindByIdAsync(userId);
- if (user == null)
- {
- return View("Error");
- }
- var result = await _userManager.ConfirmEmailAsync(user, code);
- return View(result.Succeeded ? "ConfirmEmail" : "Error");
- }
-
- //
- // GET: /Account/ForgotPassword
- [HttpGet]
- [AllowAnonymous]
- public IActionResult ForgotPassword()
- {
- return View();
- }
-
- //
- // POST: /Account/ForgotPassword
- [HttpPost]
- [AllowAnonymous]
- [ValidateAntiForgeryToken]
- public async Task ForgotPassword(ForgotPasswordViewModel model)
- {
- if (ModelState.IsValid)
- {
- var user = await _userManager.FindByNameAsync(model.Email);
- if (user == null || !(await _userManager.IsEmailConfirmedAsync(user)))
- {
- // Don't reveal that the user does not exist or is not confirmed
- return View("ForgotPasswordConfirmation");
- }
-
- // For more information on how to enable account confirmation and password reset please visit http://go.microsoft.com/fwlink/?LinkID=532713
- // Send an email with this link
- //var code = await _userManager.GeneratePasswordResetTokenAsync(user);
- //var callbackUrl = Url.Action("ResetPassword", "Account", new { userId = user.Id, code = code }, protocol: HttpContext.Request.Scheme);
- //await _emailSender.SendEmailAsync(model.Email, "Reset Password",
- // "Please reset your password by clicking here: link ");
- //return View("ForgotPasswordConfirmation");
- }
-
- // If we got this far, something failed, redisplay form
- return View(model);
- }
-
- //
- // GET: /Account/ForgotPasswordConfirmation
- [HttpGet]
- [AllowAnonymous]
- public IActionResult ForgotPasswordConfirmation()
- {
- return View();
- }
-
- //
- // GET: /Account/ResetPassword
- [HttpGet]
- [AllowAnonymous]
- public IActionResult ResetPassword(string code = null)
- {
- return code == null ? View("Error") : View();
- }
-
- //
- // POST: /Account/ResetPassword
- [HttpPost]
- [AllowAnonymous]
- [ValidateAntiForgeryToken]
- public async Task ResetPassword(ResetPasswordViewModel model)
- {
- if (!ModelState.IsValid)
- {
- return View(model);
- }
- var user = await _userManager.FindByNameAsync(model.Email);
- if (user == null)
- {
- // Don't reveal that the user does not exist
- return RedirectToAction(nameof(AccountController.ResetPasswordConfirmation), "Account");
- }
- var result = await _userManager.ResetPasswordAsync(user, model.Code, model.Password);
- if (result.Succeeded)
- {
- return RedirectToAction(nameof(AccountController.ResetPasswordConfirmation), "Account");
- }
- AddErrors(result);
- return View();
- }
-
- //
- // GET: /Account/ResetPasswordConfirmation
- [HttpGet]
- [AllowAnonymous]
- public IActionResult ResetPasswordConfirmation()
- {
- return View();
- }
-
- //
- // GET: /Account/SendCode
- [HttpGet]
- [AllowAnonymous]
- public async Task SendCode(string returnUrl = null, bool rememberMe = false)
- {
- var user = await _signInManager.GetTwoFactorAuthenticationUserAsync();
- if (user == null)
- {
- return View("Error");
- }
- var userFactors = await _userManager.GetValidTwoFactorProvidersAsync(user);
- var factorOptions = userFactors.Select(purpose => new SelectListItem { Text = purpose, Value = purpose }).ToList();
- return View(new SendCodeViewModel { Providers = factorOptions, ReturnUrl = returnUrl, RememberMe = rememberMe });
- }
-
- //
- // POST: /Account/SendCode
- [HttpPost]
- [AllowAnonymous]
- [ValidateAntiForgeryToken]
- public async Task SendCode(SendCodeViewModel model)
- {
- if (!ModelState.IsValid)
- {
- return View();
- }
-
- var user = await _signInManager.GetTwoFactorAuthenticationUserAsync();
- if (user == null)
- {
- return View("Error");
- }
-
- // Generate the token and send it
- var code = await _userManager.GenerateTwoFactorTokenAsync(user, model.SelectedProvider);
- if (string.IsNullOrWhiteSpace(code))
- {
- return View("Error");
- }
-
- var message = "Your security code is: " + code;
- if (model.SelectedProvider == "Email")
- {
- await _emailSender.SendEmailAsync(await _userManager.GetEmailAsync(user), "Security Code", message);
- }
- else if (model.SelectedProvider == "Phone")
- {
- await _smsSender.SendSmsAsync(await _userManager.GetPhoneNumberAsync(user), message);
- }
-
- return RedirectToAction(nameof(VerifyCode), new { Provider = model.SelectedProvider, ReturnUrl = model.ReturnUrl, RememberMe = model.RememberMe });
- }
-
- //
- // GET: /Account/VerifyCode
- [HttpGet]
- [AllowAnonymous]
- public async Task VerifyCode(string provider, bool rememberMe, string returnUrl = null)
- {
- // Require that the user has already logged in via username/password or external login
- var user = await _signInManager.GetTwoFactorAuthenticationUserAsync();
- if (user == null)
- {
- return View("Error");
- }
- return View(new VerifyCodeViewModel { Provider = provider, ReturnUrl = returnUrl, RememberMe = rememberMe });
- }
-
- //
- // POST: /Account/VerifyCode
- [HttpPost]
- [AllowAnonymous]
- [ValidateAntiForgeryToken]
- public async Task VerifyCode(VerifyCodeViewModel model)
- {
- if (!ModelState.IsValid)
- {
- return View(model);
- }
-
- // The following code protects for brute force attacks against the two factor codes.
- // If a user enters incorrect codes for a specified amount of time then the user account
- // will be locked out for a specified amount of time.
- var result = await _signInManager.TwoFactorSignInAsync(model.Provider, model.Code, model.RememberMe, model.RememberBrowser);
- if (result.Succeeded)
- {
- return RedirectToLocal(model.ReturnUrl);
- }
- if (result.IsLockedOut)
- {
- _logger.LogWarning(7, "User account locked out.");
- return View("Lockout");
- }
- else
- {
- ModelState.AddModelError(string.Empty, "Invalid code.");
- return View(model);
- }
- }
-
- #region Helpers
-
- private void AddErrors(IdentityResult result)
- {
- foreach (var error in result.Errors)
- {
- ModelState.AddModelError(string.Empty, error.Description);
- }
- }
-
- private Task GetCurrentUserAsync()
- {
- return _userManager.GetUserAsync(HttpContext.User);
- }
-
- private IActionResult RedirectToLocal(string returnUrl)
- {
- if (Url.IsLocalUrl(returnUrl))
- {
- return Redirect(returnUrl);
- }
- else
- {
- return RedirectToAction(nameof(HomeController.Index), "Home");
- }
- }
-
- #endregion
- }
-}
+ [Authorize]
+ public class AccountController : Controller
+ {
+ private readonly IEmailSender _emailSender;
+ private readonly ILogger _logger;
+ private readonly SignInManager _signInManager;
+ private readonly ISmsSender _smsSender;
+ private readonly UserManager _userManager;
+
+ public AccountController(
+ UserManager userManager,
+ SignInManager signInManager,
+ IEmailSender emailSender,
+ ISmsSender smsSender,
+ ILoggerFactory loggerFactory)
+ {
+ _userManager = userManager;
+ _signInManager = signInManager;
+ _emailSender = emailSender;
+ _smsSender = smsSender;
+ _logger = loggerFactory.CreateLogger();
+ }
+
+ //
+ // GET: /Account/Login
+ [HttpGet]
+ [AllowAnonymous]
+ public IActionResult Login(string returnUrl = null)
+ {
+ ViewData["ReturnUrl"] = returnUrl;
+ return View();
+ }
+
+ //
+ // POST: /Account/Login
+ [HttpPost]
+ [AllowAnonymous]
+ [ValidateAntiForgeryToken]
+ public async Task Login(LoginViewModel model, string returnUrl = null)
+ {
+ ViewData["ReturnUrl"] = returnUrl;
+ if (ModelState.IsValid)
+ {
+ // This doesn't count login failures towards account lockout
+ // To enable password failures to trigger account lockout, set lockoutOnFailure: true
+ var result = await _signInManager.PasswordSignInAsync(model.Email, model.Password, model.RememberMe, false);
+ if (result.Succeeded)
+ {
+ _logger.LogInformation(1, "User logged in.");
+ return RedirectToLocal(returnUrl);
+ }
+ if (result.RequiresTwoFactor)
+ return RedirectToAction(nameof(SendCode), new {ReturnUrl = returnUrl, model.RememberMe});
+ if (result.IsLockedOut)
+ {
+ _logger.LogWarning(2, "User account locked out.");
+ return View("Lockout");
+ }
+ ModelState.AddModelError(string.Empty, "Invalid login attempt.");
+ return View(model);
+ }
+
+ // If we got this far, something failed, redisplay form
+ return View(model);
+ }
+
+ //
+ // GET: /Account/Register
+ [HttpGet]
+ [AllowAnonymous]
+ public IActionResult Register(string returnUrl = null)
+ {
+ ViewData["ReturnUrl"] = returnUrl;
+ return View();
+ }
+
+ //
+ // POST: /Account/Register
+ [HttpPost]
+ [AllowAnonymous]
+ [ValidateAntiForgeryToken]
+ public async Task Register(RegisterViewModel model, string returnUrl = null)
+ {
+ ViewData["ReturnUrl"] = returnUrl;
+ if (ModelState.IsValid)
+ {
+ var user = new ApplicationUser {UserName = model.Email, Email = model.Email};
+ var result = await _userManager.CreateAsync(user, model.Password);
+ if (result.Succeeded)
+ {
+ // For more information on how to enable account confirmation and password reset please visit http://go.microsoft.com/fwlink/?LinkID=532713
+ // Send an email with this link
+ //var code = await _userManager.GenerateEmailConfirmationTokenAsync(user);
+ //var callbackUrl = Url.Action("ConfirmEmail", "Account", new { userId = user.Id, code = code }, protocol: HttpContext.Request.Scheme);
+ //await _emailSender.SendEmailAsync(model.Email, "Confirm your account",
+ // "Please confirm your account by clicking this link: link ");
+ await _signInManager.SignInAsync(user, false);
+ _logger.LogInformation(3, "User created a new account with password.");
+ return RedirectToLocal(returnUrl);
+ }
+ AddErrors(result);
+ }
+
+ // If we got this far, something failed, redisplay form
+ return View(model);
+ }
+
+ //
+ // POST: /Account/LogOff
+ [HttpPost]
+ [ValidateAntiForgeryToken]
+ public async Task LogOff()
+ {
+ await _signInManager.SignOutAsync();
+ _logger.LogInformation(4, "User logged out.");
+ return RedirectToAction(nameof(HomeController.Index), "Home");
+ }
+
+ //
+ // POST: /Account/ExternalLogin
+ [HttpPost]
+ [AllowAnonymous]
+ [ValidateAntiForgeryToken]
+ public IActionResult ExternalLogin(string provider, string returnUrl = null)
+ {
+ // Request a redirect to the external login provider.
+ var redirectUrl = Url.Action("ExternalLoginCallback", "Account", new {ReturnUrl = returnUrl});
+ var properties = _signInManager.ConfigureExternalAuthenticationProperties(provider, redirectUrl);
+ return Challenge(properties, provider);
+ }
+
+ //
+ // GET: /Account/ExternalLoginCallback
+ [HttpGet]
+ [AllowAnonymous]
+ public async Task ExternalLoginCallback(string returnUrl = null, string remoteError = null)
+ {
+ if (remoteError != null)
+ {
+ ModelState.AddModelError(string.Empty, $"Error from external provider: {remoteError}");
+ return View(nameof(Login));
+ }
+ var info = await _signInManager.GetExternalLoginInfoAsync();
+ if (info == null)
+ return RedirectToAction(nameof(Login));
+
+ // Sign in the user with this external login provider if the user already has a login.
+ var result = await _signInManager.ExternalLoginSignInAsync(info.LoginProvider, info.ProviderKey, false);
+ if (result.Succeeded)
+ {
+ // Update any authentication tokens if login succeeded
+ await _signInManager.UpdateExternalAuthenticationTokensAsync(info);
+
+ _logger.LogInformation(5, "User logged in with {Name} provider.", info.LoginProvider);
+ return RedirectToLocal(returnUrl);
+ }
+ if (result.RequiresTwoFactor)
+ return RedirectToAction(nameof(SendCode), new {ReturnUrl = returnUrl});
+ if (result.IsLockedOut)
+ return View("Lockout");
+ // If the user does not have an account, then ask the user to create an account.
+ ViewData["ReturnUrl"] = returnUrl;
+ ViewData["LoginProvider"] = info.LoginProvider;
+ var email = info.Principal.FindFirstValue(ClaimTypes.Email);
+ return View("ExternalLoginConfirmation", new ExternalLoginConfirmationViewModel {Email = email});
+ }
+
+ //
+ // POST: /Account/ExternalLoginConfirmation
+ [HttpPost]
+ [AllowAnonymous]
+ [ValidateAntiForgeryToken]
+ public async Task ExternalLoginConfirmation(ExternalLoginConfirmationViewModel model,
+ string returnUrl = null)
+ {
+ if (ModelState.IsValid)
+ {
+ // Get the information about the user from the external login provider
+ var info = await _signInManager.GetExternalLoginInfoAsync();
+ if (info == null)
+ return View("ExternalLoginFailure");
+ var user = new ApplicationUser {UserName = model.Email, Email = model.Email};
+ var result = await _userManager.CreateAsync(user);
+ if (result.Succeeded)
+ {
+ result = await _userManager.AddLoginAsync(user, info);
+ if (result.Succeeded)
+ {
+ await _signInManager.SignInAsync(user, false);
+ _logger.LogInformation(6, "User created an account using {Name} provider.", info.LoginProvider);
+
+ // Update any authentication tokens as well
+ await _signInManager.UpdateExternalAuthenticationTokensAsync(info);
+
+ return RedirectToLocal(returnUrl);
+ }
+ }
+ AddErrors(result);
+ }
+
+ ViewData["ReturnUrl"] = returnUrl;
+ return View(model);
+ }
+
+ // GET: /Account/ConfirmEmail
+ [HttpGet]
+ [AllowAnonymous]
+ public async Task ConfirmEmail(string userId, string code)
+ {
+ if (userId == null || code == null)
+ return View("Error");
+ var user = await _userManager.FindByIdAsync(userId);
+ if (user == null)
+ return View("Error");
+ var result = await _userManager.ConfirmEmailAsync(user, code);
+ return View(result.Succeeded ? "ConfirmEmail" : "Error");
+ }
+
+ //
+ // GET: /Account/ForgotPassword
+ [HttpGet]
+ [AllowAnonymous]
+ public IActionResult ForgotPassword()
+ {
+ return View();
+ }
+
+ //
+ // POST: /Account/ForgotPassword
+ [HttpPost]
+ [AllowAnonymous]
+ [ValidateAntiForgeryToken]
+ public async Task ForgotPassword(ForgotPasswordViewModel model)
+ {
+ if (ModelState.IsValid)
+ {
+ var user = await _userManager.FindByNameAsync(model.Email);
+ if (user == null || !await _userManager.IsEmailConfirmedAsync(user))
+ return View("ForgotPasswordConfirmation");
+
+ // For more information on how to enable account confirmation and password reset please visit http://go.microsoft.com/fwlink/?LinkID=532713
+ // Send an email with this link
+ //var code = await _userManager.GeneratePasswordResetTokenAsync(user);
+ //var callbackUrl = Url.Action("ResetPassword", "Account", new { userId = user.Id, code = code }, protocol: HttpContext.Request.Scheme);
+ //await _emailSender.SendEmailAsync(model.Email, "Reset Password",
+ // "Please reset your password by clicking here: link ");
+ //return View("ForgotPasswordConfirmation");
+ }
+
+ // If we got this far, something failed, redisplay form
+ return View(model);
+ }
+
+ //
+ // GET: /Account/ForgotPasswordConfirmation
+ [HttpGet]
+ [AllowAnonymous]
+ public IActionResult ForgotPasswordConfirmation()
+ {
+ return View();
+ }
+
+ //
+ // GET: /Account/ResetPassword
+ [HttpGet]
+ [AllowAnonymous]
+ public IActionResult ResetPassword(string code = null)
+ {
+ return code == null ? View("Error") : View();
+ }
+
+ //
+ // POST: /Account/ResetPassword
+ [HttpPost]
+ [AllowAnonymous]
+ [ValidateAntiForgeryToken]
+ public async Task ResetPassword(ResetPasswordViewModel model)
+ {
+ if (!ModelState.IsValid)
+ return View(model);
+ var user = await _userManager.FindByNameAsync(model.Email);
+ if (user == null)
+ return RedirectToAction(nameof(ResetPasswordConfirmation), "Account");
+ var result = await _userManager.ResetPasswordAsync(user, model.Code, model.Password);
+ if (result.Succeeded)
+ return RedirectToAction(nameof(ResetPasswordConfirmation), "Account");
+ AddErrors(result);
+ return View();
+ }
+
+ //
+ // GET: /Account/ResetPasswordConfirmation
+ [HttpGet]
+ [AllowAnonymous]
+ public IActionResult ResetPasswordConfirmation()
+ {
+ return View();
+ }
+
+ //
+ // GET: /Account/SendCode
+ [HttpGet]
+ [AllowAnonymous]
+ public async Task SendCode(string returnUrl = null, bool rememberMe = false)
+ {
+ var user = await _signInManager.GetTwoFactorAuthenticationUserAsync();
+ if (user == null)
+ return View("Error");
+ var userFactors = await _userManager.GetValidTwoFactorProvidersAsync(user);
+ var factorOptions = userFactors.Select(purpose => new SelectListItem {Text = purpose, Value = purpose}).ToList();
+ return View(new SendCodeViewModel {Providers = factorOptions, ReturnUrl = returnUrl, RememberMe = rememberMe});
+ }
+
+ //
+ // POST: /Account/SendCode
+ [HttpPost]
+ [AllowAnonymous]
+ [ValidateAntiForgeryToken]
+ public async Task SendCode(SendCodeViewModel model)
+ {
+ if (!ModelState.IsValid)
+ return View();
+
+ var user = await _signInManager.GetTwoFactorAuthenticationUserAsync();
+ if (user == null)
+ return View("Error");
+
+ // Generate the token and send it
+ var code = await _userManager.GenerateTwoFactorTokenAsync(user, model.SelectedProvider);
+ if (string.IsNullOrWhiteSpace(code))
+ return View("Error");
+
+ var message = "Your security code is: " + code;
+ if (model.SelectedProvider == "Email")
+ await _emailSender.SendEmailAsync(await _userManager.GetEmailAsync(user), "Security Code", message);
+ else if (model.SelectedProvider == "Phone")
+ await _smsSender.SendSmsAsync(await _userManager.GetPhoneNumberAsync(user), message);
+
+ return RedirectToAction(nameof(VerifyCode),
+ new {Provider = model.SelectedProvider, model.ReturnUrl, model.RememberMe});
+ }
+
+ //
+ // GET: /Account/VerifyCode
+ [HttpGet]
+ [AllowAnonymous]
+ public async Task VerifyCode(string provider, bool rememberMe, string returnUrl = null)
+ {
+ // Require that the user has already logged in via username/password or external login
+ var user = await _signInManager.GetTwoFactorAuthenticationUserAsync();
+ if (user == null)
+ return View("Error");
+ return View(new VerifyCodeViewModel {Provider = provider, ReturnUrl = returnUrl, RememberMe = rememberMe});
+ }
+
+ //
+ // POST: /Account/VerifyCode
+ [HttpPost]
+ [AllowAnonymous]
+ [ValidateAntiForgeryToken]
+ public async Task VerifyCode(VerifyCodeViewModel model)
+ {
+ if (!ModelState.IsValid)
+ return View(model);
+
+ // The following code protects for brute force attacks against the two factor codes.
+ // If a user enters incorrect codes for a specified amount of time then the user account
+ // will be locked out for a specified amount of time.
+ var result = await _signInManager.TwoFactorSignInAsync(model.Provider, model.Code, model.RememberMe,
+ model.RememberBrowser);
+ if (result.Succeeded)
+ return RedirectToLocal(model.ReturnUrl);
+ if (result.IsLockedOut)
+ {
+ _logger.LogWarning(7, "User account locked out.");
+ return View("Lockout");
+ }
+ ModelState.AddModelError(string.Empty, "Invalid code.");
+ return View(model);
+ }
+
+ #region Helpers
+
+ private void AddErrors(IdentityResult result)
+ {
+ foreach (var error in result.Errors)
+ ModelState.AddModelError(string.Empty, error.Description);
+ }
+
+ private Task GetCurrentUserAsync()
+ {
+ return _userManager.GetUserAsync(HttpContext.User);
+ }
+
+ private IActionResult RedirectToLocal(string returnUrl)
+ {
+ if (Url.IsLocalUrl(returnUrl))
+ return Redirect(returnUrl);
+ return RedirectToAction(nameof(HomeController.Index), "Home");
+ }
+
+ #endregion
+ }
+}
\ No newline at end of file
diff --git a/samples/IdentitySample.Mvc/Controllers/HomeController.cs b/samples/IdentitySample.Mvc/Controllers/HomeController.cs
index e9c45b37a..7ae5a3c2a 100644
--- a/samples/IdentitySample.Mvc/Controllers/HomeController.cs
+++ b/samples/IdentitySample.Mvc/Controllers/HomeController.cs
@@ -2,28 +2,28 @@
namespace IdentitySample.Controllers
{
- public class HomeController : Controller
- {
- [HttpGet]
- public IActionResult Index()
- {
- return View();
- }
+ public class HomeController : Controller
+ {
+ [HttpGet]
+ public IActionResult Index()
+ {
+ return View();
+ }
- [HttpGet]
- public IActionResult About()
- {
- ViewBag.Message = "Your app description page.";
+ [HttpGet]
+ public IActionResult About()
+ {
+ ViewBag.Message = "Your app description page.";
- return View();
- }
+ return View();
+ }
- [HttpGet]
- public IActionResult Contact()
- {
- ViewBag.Message = "Your contact page.";
+ [HttpGet]
+ public IActionResult Contact()
+ {
+ ViewBag.Message = "Your contact page.";
- return View();
- }
- }
+ return View();
+ }
+ }
}
\ No newline at end of file
diff --git a/samples/IdentitySample.Mvc/Controllers/ManageController.cs b/samples/IdentitySample.Mvc/Controllers/ManageController.cs
index 3d3f5146c..3bfd59b88 100644
--- a/samples/IdentitySample.Mvc/Controllers/ManageController.cs
+++ b/samples/IdentitySample.Mvc/Controllers/ManageController.cs
@@ -1,349 +1,341 @@
-using System;
-using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
-using System.Security.Claims;
+using IdentitySample.Models;
+using IdentitySample.Models.ManageViewModels;
+using IdentitySample.Services;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
-using IdentitySample.Models;
-using IdentitySample.Models.ManageViewModels;
-using IdentitySample.Services;
namespace IdentitySamples.Controllers
{
+ [Authorize]
+ public class ManageController : Controller
+ {
+ private readonly IEmailSender _emailSender;
+ private readonly ILogger _logger;
+ private readonly SignInManager _signInManager;
+ private readonly ISmsSender _smsSender;
+ private readonly UserManager _userManager;
- [Authorize]
- public class ManageController : Controller
- {
- private readonly UserManager _userManager;
- private readonly SignInManager _signInManager;
- private readonly IEmailSender _emailSender;
- private readonly ISmsSender _smsSender;
- private readonly ILogger _logger;
-
- public ManageController(
- UserManager userManager,
- SignInManager signInManager,
- IEmailSender emailSender,
- ISmsSender smsSender,
- ILoggerFactory loggerFactory)
- {
- _userManager = userManager;
- _signInManager = signInManager;
- _emailSender = emailSender;
- _smsSender = smsSender;
- _logger = loggerFactory.CreateLogger();
- }
+ public ManageController(
+ UserManager userManager,
+ SignInManager signInManager,
+ IEmailSender emailSender,
+ ISmsSender smsSender,
+ ILoggerFactory loggerFactory)
+ {
+ _userManager = userManager;
+ _signInManager = signInManager;
+ _emailSender = emailSender;
+ _smsSender = smsSender;
+ _logger = loggerFactory.CreateLogger();
+ }
- //
- // GET: /Manage/Index
- [HttpGet]
- public async Task Index(ManageMessageId? message = null)
- {
- ViewData["StatusMessage"] =
- message == ManageMessageId.ChangePasswordSuccess ? "Your password has been changed."
- : message == ManageMessageId.SetPasswordSuccess ? "Your password has been set."
- : message == ManageMessageId.SetTwoFactorSuccess ? "Your two-factor authentication provider has been set."
- : message == ManageMessageId.Error ? "An error has occurred."
- : message == ManageMessageId.AddPhoneSuccess ? "Your phone number was added."
- : message == ManageMessageId.RemovePhoneSuccess ? "Your phone number was removed."
- : "";
+ //
+ // GET: /Manage/Index
+ [HttpGet]
+ public async Task Index(ManageMessageId? message = null)
+ {
+ ViewData["StatusMessage"] =
+ message == ManageMessageId.ChangePasswordSuccess
+ ? "Your password has been changed."
+ : message == ManageMessageId.SetPasswordSuccess
+ ? "Your password has been set."
+ : message == ManageMessageId.SetTwoFactorSuccess
+ ? "Your two-factor authentication provider has been set."
+ : message == ManageMessageId.Error
+ ? "An error has occurred."
+ : message == ManageMessageId.AddPhoneSuccess
+ ? "Your phone number was added."
+ : message == ManageMessageId.RemovePhoneSuccess
+ ? "Your phone number was removed."
+ : "";
- var user = await GetCurrentUserAsync();
- var model = new IndexViewModel
- {
- HasPassword = await _userManager.HasPasswordAsync(user),
- PhoneNumber = await _userManager.GetPhoneNumberAsync(user),
- TwoFactor = await _userManager.GetTwoFactorEnabledAsync(user),
- Logins = await _userManager.GetLoginsAsync(user),
- BrowserRemembered = await _signInManager.IsTwoFactorClientRememberedAsync(user)
- };
- return View(model);
- }
+ var user = await GetCurrentUserAsync();
+ var model = new IndexViewModel
+ {
+ HasPassword = await _userManager.HasPasswordAsync(user),
+ PhoneNumber = await _userManager.GetPhoneNumberAsync(user),
+ TwoFactor = await _userManager.GetTwoFactorEnabledAsync(user),
+ Logins = await _userManager.GetLoginsAsync(user),
+ BrowserRemembered = await _signInManager.IsTwoFactorClientRememberedAsync(user)
+ };
+ return View(model);
+ }
- //
- // POST: /Manage/RemoveLogin
- [HttpPost]
- [ValidateAntiForgeryToken]
- public async Task RemoveLogin(RemoveLoginViewModel account)
- {
- ManageMessageId? message = ManageMessageId.Error;
- var user = await GetCurrentUserAsync();
- if (user != null)
- {
- var result = await _userManager.RemoveLoginAsync(user, account.LoginProvider, account.ProviderKey);
- if (result.Succeeded)
- {
- await _signInManager.SignInAsync(user, isPersistent: false);
- message = ManageMessageId.RemoveLoginSuccess;
- }
- }
- return RedirectToAction(nameof(ManageLogins), new { Message = message });
- }
+ //
+ // POST: /Manage/RemoveLogin
+ [HttpPost]
+ [ValidateAntiForgeryToken]
+ public async Task RemoveLogin(RemoveLoginViewModel account)
+ {
+ ManageMessageId? message = ManageMessageId.Error;
+ var user = await GetCurrentUserAsync();
+ if (user != null)
+ {
+ var result = await _userManager.RemoveLoginAsync(user, account.LoginProvider, account.ProviderKey);
+ if (result.Succeeded)
+ {
+ await _signInManager.SignInAsync(user, false);
+ message = ManageMessageId.RemoveLoginSuccess;
+ }
+ }
+ return RedirectToAction(nameof(ManageLogins), new {Message = message});
+ }
- //
- // GET: /Manage/AddPhoneNumber
- public IActionResult AddPhoneNumber()
- {
- return View();
- }
+ //
+ // GET: /Manage/AddPhoneNumber
+ public IActionResult AddPhoneNumber()
+ {
+ return View();
+ }
- //
- // POST: /Manage/AddPhoneNumber
- [HttpPost]
- [ValidateAntiForgeryToken]
- public async Task AddPhoneNumber(AddPhoneNumberViewModel model)
- {
- if (!ModelState.IsValid)
- {
- return View(model);
- }
- // Generate the token and send it
- var user = await GetCurrentUserAsync();
- var code = await _userManager.GenerateChangePhoneNumberTokenAsync(user, model.PhoneNumber);
- await _smsSender.SendSmsAsync(model.PhoneNumber, "Your security code is: " + code);
- return RedirectToAction(nameof(VerifyPhoneNumber), new { PhoneNumber = model.PhoneNumber });
- }
+ //
+ // POST: /Manage/AddPhoneNumber
+ [HttpPost]
+ [ValidateAntiForgeryToken]
+ public async Task AddPhoneNumber(AddPhoneNumberViewModel model)
+ {
+ if (!ModelState.IsValid)
+ return View(model);
+ // Generate the token and send it
+ var user = await GetCurrentUserAsync();
+ var code = await _userManager.GenerateChangePhoneNumberTokenAsync(user, model.PhoneNumber);
+ await _smsSender.SendSmsAsync(model.PhoneNumber, "Your security code is: " + code);
+ return RedirectToAction(nameof(VerifyPhoneNumber), new {model.PhoneNumber});
+ }
- //
- // POST: /Manage/EnableTwoFactorAuthentication
- [HttpPost]
- [ValidateAntiForgeryToken]
- public async Task EnableTwoFactorAuthentication()
- {
- var user = await GetCurrentUserAsync();
- if (user != null)
- {
- await _userManager.SetTwoFactorEnabledAsync(user, true);
- await _signInManager.SignInAsync(user, isPersistent: false);
- _logger.LogInformation(1, "User enabled two-factor authentication.");
- }
- return RedirectToAction(nameof(Index), "Manage");
- }
+ //
+ // POST: /Manage/EnableTwoFactorAuthentication
+ [HttpPost]
+ [ValidateAntiForgeryToken]
+ public async Task EnableTwoFactorAuthentication()
+ {
+ var user = await GetCurrentUserAsync();
+ if (user != null)
+ {
+ await _userManager.SetTwoFactorEnabledAsync(user, true);
+ await _signInManager.SignInAsync(user, false);
+ _logger.LogInformation(1, "User enabled two-factor authentication.");
+ }
+ return RedirectToAction(nameof(Index), "Manage");
+ }
- //
- // POST: /Manage/DisableTwoFactorAuthentication
- [HttpPost]
- [ValidateAntiForgeryToken]
- public async Task DisableTwoFactorAuthentication()
- {
- var user = await GetCurrentUserAsync();
- if (user != null)
- {
- await _userManager.SetTwoFactorEnabledAsync(user, false);
- await _signInManager.SignInAsync(user, isPersistent: false);
- _logger.LogInformation(2, "User disabled two-factor authentication.");
- }
- return RedirectToAction(nameof(Index), "Manage");
- }
+ //
+ // POST: /Manage/DisableTwoFactorAuthentication
+ [HttpPost]
+ [ValidateAntiForgeryToken]
+ public async Task DisableTwoFactorAuthentication()
+ {
+ var user = await GetCurrentUserAsync();
+ if (user != null)
+ {
+ await _userManager.SetTwoFactorEnabledAsync(user, false);
+ await _signInManager.SignInAsync(user, false);
+ _logger.LogInformation(2, "User disabled two-factor authentication.");
+ }
+ return RedirectToAction(nameof(Index), "Manage");
+ }
- //
- // GET: /Manage/VerifyPhoneNumber
- [HttpGet]
- public async Task VerifyPhoneNumber(string phoneNumber)
- {
- var code = await _userManager.GenerateChangePhoneNumberTokenAsync(await GetCurrentUserAsync(), phoneNumber);
- // Send an SMS to verify the phone number
- return phoneNumber == null ? View("Error") : View(new VerifyPhoneNumberViewModel { PhoneNumber = phoneNumber });
- }
+ //
+ // GET: /Manage/VerifyPhoneNumber
+ [HttpGet]
+ public async Task VerifyPhoneNumber(string phoneNumber)
+ {
+ var code = await _userManager.GenerateChangePhoneNumberTokenAsync(await GetCurrentUserAsync(), phoneNumber);
+ // Send an SMS to verify the phone number
+ return phoneNumber == null ? View("Error") : View(new VerifyPhoneNumberViewModel {PhoneNumber = phoneNumber});
+ }
- //
- // POST: /Manage/VerifyPhoneNumber
- [HttpPost]
- [ValidateAntiForgeryToken]
- public async Task VerifyPhoneNumber(VerifyPhoneNumberViewModel model)
- {
- if (!ModelState.IsValid)
- {
- return View(model);
- }
- var user = await GetCurrentUserAsync();
- if (user != null)
- {
- var result = await _userManager.ChangePhoneNumberAsync(user, model.PhoneNumber, model.Code);
- if (result.Succeeded)
- {
- await _signInManager.SignInAsync(user, isPersistent: false);
- return RedirectToAction(nameof(Index), new { Message = ManageMessageId.AddPhoneSuccess });
- }
- }
- // If we got this far, something failed, redisplay the form
- ModelState.AddModelError(string.Empty, "Failed to verify phone number");
- return View(model);
- }
+ //
+ // POST: /Manage/VerifyPhoneNumber
+ [HttpPost]
+ [ValidateAntiForgeryToken]
+ public async Task VerifyPhoneNumber(VerifyPhoneNumberViewModel model)
+ {
+ if (!ModelState.IsValid)
+ return View(model);
+ var user = await GetCurrentUserAsync();
+ if (user != null)
+ {
+ var result = await _userManager.ChangePhoneNumberAsync(user, model.PhoneNumber, model.Code);
+ if (result.Succeeded)
+ {
+ await _signInManager.SignInAsync(user, false);
+ return RedirectToAction(nameof(Index), new {Message = ManageMessageId.AddPhoneSuccess});
+ }
+ }
+ // If we got this far, something failed, redisplay the form
+ ModelState.AddModelError(string.Empty, "Failed to verify phone number");
+ return View(model);
+ }
- //
- // GET: /Manage/RemovePhoneNumber
- [HttpPost]
- [ValidateAntiForgeryToken]
- public async Task RemovePhoneNumber()
- {
- var user = await GetCurrentUserAsync();
- if (user != null)
- {
- var result = await _userManager.SetPhoneNumberAsync(user, null);
- if (result.Succeeded)
- {
- await _signInManager.SignInAsync(user, isPersistent: false);
- return RedirectToAction(nameof(Index), new { Message = ManageMessageId.RemovePhoneSuccess });
- }
- }
- return RedirectToAction(nameof(Index), new { Message = ManageMessageId.Error });
- }
+ //
+ // GET: /Manage/RemovePhoneNumber
+ [HttpPost]
+ [ValidateAntiForgeryToken]
+ public async Task RemovePhoneNumber()
+ {
+ var user = await GetCurrentUserAsync();
+ if (user != null)
+ {
+ var result = await _userManager.SetPhoneNumberAsync(user, null);
+ if (result.Succeeded)
+ {
+ await _signInManager.SignInAsync(user, false);
+ return RedirectToAction(nameof(Index), new {Message = ManageMessageId.RemovePhoneSuccess});
+ }
+ }
+ return RedirectToAction(nameof(Index), new {Message = ManageMessageId.Error});
+ }
- //
- // GET: /Manage/ChangePassword
- [HttpGet]
- public IActionResult ChangePassword()
- {
- return View();
- }
+ //
+ // GET: /Manage/ChangePassword
+ [HttpGet]
+ public IActionResult ChangePassword()
+ {
+ return View();
+ }
- //
- // POST: /Manage/ChangePassword
- [HttpPost]
- [ValidateAntiForgeryToken]
- public async Task ChangePassword(ChangePasswordViewModel model)
- {
- if (!ModelState.IsValid)
- {
- return View(model);
- }
- var user = await GetCurrentUserAsync();
- if (user != null)
- {
- var result = await _userManager.ChangePasswordAsync(user, model.OldPassword, model.NewPassword);
- if (result.Succeeded)
- {
- await _signInManager.SignInAsync(user, isPersistent: false);
- _logger.LogInformation(3, "User changed their password successfully.");
- return RedirectToAction(nameof(Index), new { Message = ManageMessageId.ChangePasswordSuccess });
- }
- AddErrors(result);
- return View(model);
- }
- return RedirectToAction(nameof(Index), new { Message = ManageMessageId.Error });
- }
+ //
+ // POST: /Manage/ChangePassword
+ [HttpPost]
+ [ValidateAntiForgeryToken]
+ public async Task ChangePassword(ChangePasswordViewModel model)
+ {
+ if (!ModelState.IsValid)
+ return View(model);
+ var user = await GetCurrentUserAsync();
+ if (user != null)
+ {
+ var result = await _userManager.ChangePasswordAsync(user, model.OldPassword, model.NewPassword);
+ if (result.Succeeded)
+ {
+ await _signInManager.SignInAsync(user, false);
+ _logger.LogInformation(3, "User changed their password successfully.");
+ return RedirectToAction(nameof(Index), new {Message = ManageMessageId.ChangePasswordSuccess});
+ }
+ AddErrors(result);
+ return View(model);
+ }
+ return RedirectToAction(nameof(Index), new {Message = ManageMessageId.Error});
+ }
- //
- // GET: /Manage/SetPassword
- [HttpGet]
- public IActionResult SetPassword()
- {
- return View();
- }
+ //
+ // GET: /Manage/SetPassword
+ [HttpGet]
+ public IActionResult SetPassword()
+ {
+ return View();
+ }
- //
- // POST: /Manage/SetPassword
- [HttpPost]
- [ValidateAntiForgeryToken]
- public async Task SetPassword(SetPasswordViewModel model)
- {
- if (!ModelState.IsValid)
- {
- return View(model);
- }
+ //
+ // POST: /Manage/SetPassword
+ [HttpPost]
+ [ValidateAntiForgeryToken]
+ public async Task SetPassword(SetPasswordViewModel model)
+ {
+ if (!ModelState.IsValid)
+ return View(model);
- var user = await GetCurrentUserAsync();
- if (user != null)
- {
- var result = await _userManager.AddPasswordAsync(user, model.NewPassword);
- if (result.Succeeded)
- {
- await _signInManager.SignInAsync(user, isPersistent: false);
- return RedirectToAction(nameof(Index), new { Message = ManageMessageId.SetPasswordSuccess });
- }
- AddErrors(result);
- return View(model);
- }
- return RedirectToAction(nameof(Index), new { Message = ManageMessageId.Error });
- }
+ var user = await GetCurrentUserAsync();
+ if (user != null)
+ {
+ var result = await _userManager.AddPasswordAsync(user, model.NewPassword);
+ if (result.Succeeded)
+ {
+ await _signInManager.SignInAsync(user, false);
+ return RedirectToAction(nameof(Index), new {Message = ManageMessageId.SetPasswordSuccess});
+ }
+ AddErrors(result);
+ return View(model);
+ }
+ return RedirectToAction(nameof(Index), new {Message = ManageMessageId.Error});
+ }
- //GET: /Manage/ManageLogins
- [HttpGet]
- public async Task ManageLogins(ManageMessageId? message = null)
- {
- ViewData["StatusMessage"] =
- message == ManageMessageId.RemoveLoginSuccess ? "The external login was removed."
- : message == ManageMessageId.AddLoginSuccess ? "The external login was added."
- : message == ManageMessageId.Error ? "An error has occurred."
- : "";
- var user = await GetCurrentUserAsync();
- if (user == null)
- {
- return View("Error");
- }
- var userLogins = await _userManager.GetLoginsAsync(user);
- var otherLogins = _signInManager.GetExternalAuthenticationSchemes().Where(auth => userLogins.All(ul => auth.AuthenticationScheme != ul.LoginProvider)).ToList();
- ViewData["ShowRemoveButton"] = user.PasswordHash != null || userLogins.Count > 1;
- return View(new ManageLoginsViewModel
- {
- CurrentLogins = userLogins,
- OtherLogins = otherLogins
- });
- }
+ //GET: /Manage/ManageLogins
+ [HttpGet]
+ public async Task ManageLogins(ManageMessageId? message = null)
+ {
+ ViewData["StatusMessage"] =
+ message == ManageMessageId.RemoveLoginSuccess
+ ? "The external login was removed."
+ : message == ManageMessageId.AddLoginSuccess
+ ? "The external login was added."
+ : message == ManageMessageId.Error
+ ? "An error has occurred."
+ : "";
+ var user = await GetCurrentUserAsync();
+ if (user == null)
+ return View("Error");
+ var userLogins = await _userManager.GetLoginsAsync(user);
+ var otherLogins = _signInManager.GetExternalAuthenticationSchemes()
+ .Where(auth => userLogins.All(ul => auth.AuthenticationScheme != ul.LoginProvider))
+ .ToList();
+ ViewData["ShowRemoveButton"] = user.PasswordHash != null || userLogins.Count > 1;
+ return View(new ManageLoginsViewModel
+ {
+ CurrentLogins = userLogins,
+ OtherLogins = otherLogins
+ });
+ }
- //
- // POST: /Manage/LinkLogin
- [HttpPost]
- [ValidateAntiForgeryToken]
- public IActionResult LinkLogin(string provider)
- {
- // Request a redirect to the external login provider to link a login for the current user
- var redirectUrl = Url.Action("LinkLoginCallback", "Manage");
- var properties = _signInManager.ConfigureExternalAuthenticationProperties(provider, redirectUrl, _userManager.GetUserId(User));
- return Challenge(properties, provider);
- }
+ //
+ // POST: /Manage/LinkLogin
+ [HttpPost]
+ [ValidateAntiForgeryToken]
+ public IActionResult LinkLogin(string provider)
+ {
+ // Request a redirect to the external login provider to link a login for the current user
+ var redirectUrl = Url.Action("LinkLoginCallback", "Manage");
+ var properties =
+ _signInManager.ConfigureExternalAuthenticationProperties(provider, redirectUrl, _userManager.GetUserId(User));
+ return Challenge(properties, provider);
+ }
- //
- // GET: /Manage/LinkLoginCallback
- [HttpGet]
- public async Task LinkLoginCallback()
- {
- var user = await GetCurrentUserAsync();
- if (user == null)
- {
- return View("Error");
- }
- var info = await _signInManager.GetExternalLoginInfoAsync(await _userManager.GetUserIdAsync(user));
- if (info == null)
- {
- return RedirectToAction(nameof(ManageLogins), new { Message = ManageMessageId.Error });
- }
- var result = await _userManager.AddLoginAsync(user, info);
- var message = result.Succeeded ? ManageMessageId.AddLoginSuccess : ManageMessageId.Error;
- return RedirectToAction(nameof(ManageLogins), new { Message = message });
- }
+ //
+ // GET: /Manage/LinkLoginCallback
+ [HttpGet]
+ public async Task LinkLoginCallback()
+ {
+ var user = await GetCurrentUserAsync();
+ if (user == null)
+ return View("Error");
+ var info = await _signInManager.GetExternalLoginInfoAsync(await _userManager.GetUserIdAsync(user));
+ if (info == null)
+ return RedirectToAction(nameof(ManageLogins), new {Message = ManageMessageId.Error});
+ var result = await _userManager.AddLoginAsync(user, info);
+ var message = result.Succeeded ? ManageMessageId.AddLoginSuccess : ManageMessageId.Error;
+ return RedirectToAction(nameof(ManageLogins), new {Message = message});
+ }
- #region Helpers
+ #region Helpers
- private void AddErrors(IdentityResult result)
- {
- foreach (var error in result.Errors)
- {
- ModelState.AddModelError(string.Empty, error.Description);
- }
- }
+ private void AddErrors(IdentityResult result)
+ {
+ foreach (var error in result.Errors)
+ ModelState.AddModelError(string.Empty, error.Description);
+ }
- public enum ManageMessageId
- {
- AddPhoneSuccess,
- AddLoginSuccess,
- ChangePasswordSuccess,
- SetTwoFactorSuccess,
- SetPasswordSuccess,
- RemoveLoginSuccess,
- RemovePhoneSuccess,
- Error
- }
+ public enum ManageMessageId
+ {
+ AddPhoneSuccess,
+ AddLoginSuccess,
+ ChangePasswordSuccess,
+ SetTwoFactorSuccess,
+ SetPasswordSuccess,
+ RemoveLoginSuccess,
+ RemovePhoneSuccess,
+ Error
+ }
- private Task GetCurrentUserAsync()
- {
- return _userManager.GetUserAsync(HttpContext.User);
- }
+ private Task GetCurrentUserAsync()
+ {
+ return _userManager.GetUserAsync(HttpContext.User);
+ }
- #endregion
- }
-}
+ #endregion
+ }
+}
\ No newline at end of file
diff --git a/samples/IdentitySample.Mvc/MessageServices.cs b/samples/IdentitySample.Mvc/MessageServices.cs
index 6860d99af..8110b05ef 100644
--- a/samples/IdentitySample.Mvc/MessageServices.cs
+++ b/samples/IdentitySample.Mvc/MessageServices.cs
@@ -2,19 +2,18 @@
namespace IdentitySamples
{
- public static class MessageServices
- {
- public static Task SendEmailAsync(string email, string subject, string message)
- {
- // Plug in your email service
- return Task.FromResult(0);
- }
+ public static class MessageServices
+ {
+ public static Task SendEmailAsync(string email, string subject, string message)
+ {
+ // Plug in your email service
+ return Task.FromResult(0);
+ }
- public static Task SendSmsAsync(string number, string message)
- {
- // Plug in your sms service
- return Task.FromResult(0);
- }
-
- }
+ public static Task SendSmsAsync(string number, string message)
+ {
+ // Plug in your sms service
+ return Task.FromResult(0);
+ }
+ }
}
\ No newline at end of file
diff --git a/samples/IdentitySample.Mvc/Models/AccountViewModels/ExternalLoginConfirmationViewModel.cs b/samples/IdentitySample.Mvc/Models/AccountViewModels/ExternalLoginConfirmationViewModel.cs
index da18df3ef..aabe12be7 100644
--- a/samples/IdentitySample.Mvc/Models/AccountViewModels/ExternalLoginConfirmationViewModel.cs
+++ b/samples/IdentitySample.Mvc/Models/AccountViewModels/ExternalLoginConfirmationViewModel.cs
@@ -1,15 +1,11 @@
-using System;
-using System.Collections.Generic;
-using System.ComponentModel.DataAnnotations;
-using System.Linq;
-using System.Threading.Tasks;
+using System.ComponentModel.DataAnnotations;
namespace IdentitySample.Models.AccountViewModels
{
- public class ExternalLoginConfirmationViewModel
- {
- [Required]
- [EmailAddress]
- public string Email { get; set; }
- }
-}
+ public class ExternalLoginConfirmationViewModel
+ {
+ [Required]
+ [EmailAddress]
+ public string Email { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/samples/IdentitySample.Mvc/Models/AccountViewModels/ForgotPasswordViewModel.cs b/samples/IdentitySample.Mvc/Models/AccountViewModels/ForgotPasswordViewModel.cs
index 7685e0ec1..f4d5193d2 100644
--- a/samples/IdentitySample.Mvc/Models/AccountViewModels/ForgotPasswordViewModel.cs
+++ b/samples/IdentitySample.Mvc/Models/AccountViewModels/ForgotPasswordViewModel.cs
@@ -1,15 +1,11 @@
-using System;
-using System.Collections.Generic;
-using System.ComponentModel.DataAnnotations;
-using System.Linq;
-using System.Threading.Tasks;
+using System.ComponentModel.DataAnnotations;
namespace IdentitySample.Models.AccountViewModels
{
- public class ForgotPasswordViewModel
- {
- [Required]
- [EmailAddress]
- public string Email { get; set; }
- }
-}
+ public class ForgotPasswordViewModel
+ {
+ [Required]
+ [EmailAddress]
+ public string Email { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/samples/IdentitySample.Mvc/Models/AccountViewModels/LoginViewModel.cs b/samples/IdentitySample.Mvc/Models/AccountViewModels/LoginViewModel.cs
index 7b269fb51..15959fd1e 100644
--- a/samples/IdentitySample.Mvc/Models/AccountViewModels/LoginViewModel.cs
+++ b/samples/IdentitySample.Mvc/Models/AccountViewModels/LoginViewModel.cs
@@ -1,22 +1,18 @@
-using System;
-using System.Collections.Generic;
-using System.ComponentModel.DataAnnotations;
-using System.Linq;
-using System.Threading.Tasks;
+using System.ComponentModel.DataAnnotations;
namespace IdentitySample.Models.AccountViewModels
{
- public class LoginViewModel
- {
- [Required]
- [EmailAddress]
- public string Email { get; set; }
+ public class LoginViewModel
+ {
+ [Required]
+ [EmailAddress]
+ public string Email { get; set; }
- [Required]
- [DataType(DataType.Password)]
- public string Password { get; set; }
+ [Required]
+ [DataType(DataType.Password)]
+ public string Password { get; set; }
- [Display(Name = "Remember me?")]
- public bool RememberMe { get; set; }
- }
-}
+ [Display(Name = "Remember me?")]
+ public bool RememberMe { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/samples/IdentitySample.Mvc/Models/AccountViewModels/RegisterViewModel.cs b/samples/IdentitySample.Mvc/Models/AccountViewModels/RegisterViewModel.cs
index 99bf5fa91..8497b75bc 100644
--- a/samples/IdentitySample.Mvc/Models/AccountViewModels/RegisterViewModel.cs
+++ b/samples/IdentitySample.Mvc/Models/AccountViewModels/RegisterViewModel.cs
@@ -1,27 +1,23 @@
-using System;
-using System.Collections.Generic;
-using System.ComponentModel.DataAnnotations;
-using System.Linq;
-using System.Threading.Tasks;
+using System.ComponentModel.DataAnnotations;
namespace IdentitySample.Models.AccountViewModels
{
- public class RegisterViewModel
- {
- [Required]
- [EmailAddress]
- [Display(Name = "Email")]
- public string Email { get; set; }
+ public class RegisterViewModel
+ {
+ [Required]
+ [EmailAddress]
+ [Display(Name = "Email")]
+ public string Email { get; set; }
- [Required]
- [StringLength(100, ErrorMessage = "The {0} must be at least {2} characters long.", MinimumLength = 6)]
- [DataType(DataType.Password)]
- [Display(Name = "Password")]
- public string Password { get; set; }
+ [Required]
+ [StringLength(100, ErrorMessage = "The {0} must be at least {2} characters long.", MinimumLength = 6)]
+ [DataType(DataType.Password)]
+ [Display(Name = "Password")]
+ public string Password { get; set; }
- [DataType(DataType.Password)]
- [Display(Name = "Confirm password")]
- [Compare("Password", ErrorMessage = "The password and confirmation password do not match.")]
- public string ConfirmPassword { get; set; }
- }
-}
+ [DataType(DataType.Password)]
+ [Display(Name = "Confirm password")]
+ [Compare("Password", ErrorMessage = "The password and confirmation password do not match.")]
+ public string ConfirmPassword { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/samples/IdentitySample.Mvc/Models/AccountViewModels/ResetPasswordViewModel.cs b/samples/IdentitySample.Mvc/Models/AccountViewModels/ResetPasswordViewModel.cs
index 89959c847..5be0a8109 100644
--- a/samples/IdentitySample.Mvc/Models/AccountViewModels/ResetPasswordViewModel.cs
+++ b/samples/IdentitySample.Mvc/Models/AccountViewModels/ResetPasswordViewModel.cs
@@ -1,27 +1,23 @@
-using System;
-using System.Collections.Generic;
-using System.ComponentModel.DataAnnotations;
-using System.Linq;
-using System.Threading.Tasks;
+using System.ComponentModel.DataAnnotations;
namespace IdentitySample.Models.AccountViewModels
{
- public class ResetPasswordViewModel
- {
- [Required]
- [EmailAddress]
- public string Email { get; set; }
+ public class ResetPasswordViewModel
+ {
+ [Required]
+ [EmailAddress]
+ public string Email { get; set; }
- [Required]
- [StringLength(100, ErrorMessage = "The {0} must be at least {2} characters long.", MinimumLength = 6)]
- [DataType(DataType.Password)]
- public string Password { get; set; }
+ [Required]
+ [StringLength(100, ErrorMessage = "The {0} must be at least {2} characters long.", MinimumLength = 6)]
+ [DataType(DataType.Password)]
+ public string Password { get; set; }
- [DataType(DataType.Password)]
- [Display(Name = "Confirm password")]
- [Compare("Password", ErrorMessage = "The password and confirmation password do not match.")]
- public string ConfirmPassword { get; set; }
+ [DataType(DataType.Password)]
+ [Display(Name = "Confirm password")]
+ [Compare("Password", ErrorMessage = "The password and confirmation password do not match.")]
+ public string ConfirmPassword { get; set; }
- public string Code { get; set; }
- }
-}
+ public string Code { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/samples/IdentitySample.Mvc/Models/AccountViewModels/SendCodeViewModel.cs b/samples/IdentitySample.Mvc/Models/AccountViewModels/SendCodeViewModel.cs
index 7d8716745..65de762b3 100644
--- a/samples/IdentitySample.Mvc/Models/AccountViewModels/SendCodeViewModel.cs
+++ b/samples/IdentitySample.Mvc/Models/AccountViewModels/SendCodeViewModel.cs
@@ -1,19 +1,16 @@
-using System;
using System.Collections.Generic;
-using System.Linq;
-using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc.Rendering;
namespace IdentitySample.Models.AccountViewModels
{
- public class SendCodeViewModel
- {
- public string SelectedProvider { get; set; }
+ public class SendCodeViewModel
+ {
+ public string SelectedProvider { get; set; }
- public ICollection Providers { get; set; }
+ public ICollection Providers { get; set; }
- public string ReturnUrl { get; set; }
+ public string ReturnUrl { get; set; }
- public bool RememberMe { get; set; }
- }
-}
+ public bool RememberMe { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/samples/IdentitySample.Mvc/Models/AccountViewModels/VerifyCodeViewModel.cs b/samples/IdentitySample.Mvc/Models/AccountViewModels/VerifyCodeViewModel.cs
index df6dce271..e78d84ab7 100644
--- a/samples/IdentitySample.Mvc/Models/AccountViewModels/VerifyCodeViewModel.cs
+++ b/samples/IdentitySample.Mvc/Models/AccountViewModels/VerifyCodeViewModel.cs
@@ -1,25 +1,21 @@
-using System;
-using System.Collections.Generic;
-using System.ComponentModel.DataAnnotations;
-using System.Linq;
-using System.Threading.Tasks;
+using System.ComponentModel.DataAnnotations;
namespace IdentitySample.Models.AccountViewModels
{
- public class VerifyCodeViewModel
- {
- [Required]
- public string Provider { get; set; }
+ public class VerifyCodeViewModel
+ {
+ [Required]
+ public string Provider { get; set; }
- [Required]
- public string Code { get; set; }
+ [Required]
+ public string Code { get; set; }
- public string ReturnUrl { get; set; }
+ public string ReturnUrl { get; set; }
- [Display(Name = "Remember this browser?")]
- public bool RememberBrowser { get; set; }
+ [Display(Name = "Remember this browser?")]
+ public bool RememberBrowser { get; set; }
- [Display(Name = "Remember me?")]
- public bool RememberMe { get; set; }
- }
-}
+ [Display(Name = "Remember me?")]
+ public bool RememberMe { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/samples/IdentitySample.Mvc/Models/ApplicationDbContext.cs b/samples/IdentitySample.Mvc/Models/ApplicationDbContext.cs
index 55b0a62b0..e12ffd0ff 100644
--- a/samples/IdentitySample.Mvc/Models/ApplicationDbContext.cs
+++ b/samples/IdentitySample.Mvc/Models/ApplicationDbContext.cs
@@ -1,12 +1,8 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Threading.Tasks;
using LinqToDB.Identity;
namespace IdentitySample.Models
{
- public class ApplicationDataConnection : IdentityDataConnection
- {
- }
-}
+ public class ApplicationDataConnection : IdentityDataConnection
+ {
+ }
+}
\ No newline at end of file
diff --git a/samples/IdentitySample.Mvc/Models/ApplicationUser.cs b/samples/IdentitySample.Mvc/Models/ApplicationUser.cs
index a4be7d067..30c5957e6 100644
--- a/samples/IdentitySample.Mvc/Models/ApplicationUser.cs
+++ b/samples/IdentitySample.Mvc/Models/ApplicationUser.cs
@@ -1,13 +1,9 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Threading.Tasks;
using LinqToDB.Identity;
namespace IdentitySample.Models
{
- // Add profile data for application users by adding properties to the ApplicationUser class
- public class ApplicationUser : IdentityUser
- {
- }
-}
+ // Add profile data for application users by adding properties to the ApplicationUser class
+ public class ApplicationUser : IdentityUser
+ {
+ }
+}
\ No newline at end of file
diff --git a/samples/IdentitySample.Mvc/Models/ManageViewModels/AddPhoneNumberViewModel.cs b/samples/IdentitySample.Mvc/Models/ManageViewModels/AddPhoneNumberViewModel.cs
index 28f0d3aaf..e679b60bb 100644
--- a/samples/IdentitySample.Mvc/Models/ManageViewModels/AddPhoneNumberViewModel.cs
+++ b/samples/IdentitySample.Mvc/Models/ManageViewModels/AddPhoneNumberViewModel.cs
@@ -1,16 +1,12 @@
-using System;
-using System.Collections.Generic;
-using System.ComponentModel.DataAnnotations;
-using System.Linq;
-using System.Threading.Tasks;
+using System.ComponentModel.DataAnnotations;
namespace IdentitySample.Models.ManageViewModels
{
- public class AddPhoneNumberViewModel
- {
- [Required]
- [Phone]
- [Display(Name = "Phone number")]
- public string PhoneNumber { get; set; }
- }
-}
+ public class AddPhoneNumberViewModel
+ {
+ [Required]
+ [Phone]
+ [Display(Name = "Phone number")]
+ public string PhoneNumber { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/samples/IdentitySample.Mvc/Models/ManageViewModels/ChangePasswordViewModel.cs b/samples/IdentitySample.Mvc/Models/ManageViewModels/ChangePasswordViewModel.cs
index c30745e58..aad52d470 100644
--- a/samples/IdentitySample.Mvc/Models/ManageViewModels/ChangePasswordViewModel.cs
+++ b/samples/IdentitySample.Mvc/Models/ManageViewModels/ChangePasswordViewModel.cs
@@ -1,27 +1,23 @@
-using System;
-using System.Collections.Generic;
-using System.ComponentModel.DataAnnotations;
-using System.Linq;
-using System.Threading.Tasks;
+using System.ComponentModel.DataAnnotations;
namespace IdentitySample.Models.ManageViewModels
{
- public class ChangePasswordViewModel
- {
- [Required]
- [DataType(DataType.Password)]
- [Display(Name = "Current password")]
- public string OldPassword { get; set; }
+ public class ChangePasswordViewModel
+ {
+ [Required]
+ [DataType(DataType.Password)]
+ [Display(Name = "Current password")]
+ public string OldPassword { get; set; }
- [Required]
- [StringLength(100, ErrorMessage = "The {0} must be at least {2} characters long.", MinimumLength = 6)]
- [DataType(DataType.Password)]
- [Display(Name = "New password")]
- public string NewPassword { get; set; }
+ [Required]
+ [StringLength(100, ErrorMessage = "The {0} must be at least {2} characters long.", MinimumLength = 6)]
+ [DataType(DataType.Password)]
+ [Display(Name = "New password")]
+ public string NewPassword { get; set; }
- [DataType(DataType.Password)]
- [Display(Name = "Confirm new password")]
- [Compare("NewPassword", ErrorMessage = "The new password and confirmation password do not match.")]
- public string ConfirmPassword { get; set; }
- }
-}
+ [DataType(DataType.Password)]
+ [Display(Name = "Confirm new password")]
+ [Compare("NewPassword", ErrorMessage = "The new password and confirmation password do not match.")]
+ public string ConfirmPassword { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/samples/IdentitySample.Mvc/Models/ManageViewModels/ConfigureTwoFactorViewModel.cs b/samples/IdentitySample.Mvc/Models/ManageViewModels/ConfigureTwoFactorViewModel.cs
index 76d371bfd..5f507e37a 100644
--- a/samples/IdentitySample.Mvc/Models/ManageViewModels/ConfigureTwoFactorViewModel.cs
+++ b/samples/IdentitySample.Mvc/Models/ManageViewModels/ConfigureTwoFactorViewModel.cs
@@ -1,15 +1,12 @@
-using System;
using System.Collections.Generic;
-using System.Linq;
-using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc.Rendering;
namespace IdentitySample.Models.ManageViewModels
{
- public class ConfigureTwoFactorViewModel
- {
- public string SelectedProvider { get; set; }
+ public class ConfigureTwoFactorViewModel
+ {
+ public string SelectedProvider { get; set; }
- public ICollection Providers { get; set; }
- }
-}
+ public ICollection Providers { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/samples/IdentitySample.Mvc/Models/ManageViewModels/FactorViewModel.cs b/samples/IdentitySample.Mvc/Models/ManageViewModels/FactorViewModel.cs
index 88b968ae7..0569a21b9 100644
--- a/samples/IdentitySample.Mvc/Models/ManageViewModels/FactorViewModel.cs
+++ b/samples/IdentitySample.Mvc/Models/ManageViewModels/FactorViewModel.cs
@@ -1,12 +1,7 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Threading.Tasks;
-
-namespace IdentitySample.Models.ManageViewModels
+namespace IdentitySample.Models.ManageViewModels
{
- public class FactorViewModel
- {
- public string Purpose { get; set; }
- }
-}
+ public class FactorViewModel
+ {
+ public string Purpose { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/samples/IdentitySample.Mvc/Models/ManageViewModels/IndexViewModel.cs b/samples/IdentitySample.Mvc/Models/ManageViewModels/IndexViewModel.cs
index 09ce077c8..6e615c70d 100644
--- a/samples/IdentitySample.Mvc/Models/ManageViewModels/IndexViewModel.cs
+++ b/samples/IdentitySample.Mvc/Models/ManageViewModels/IndexViewModel.cs
@@ -1,21 +1,18 @@
-using System;
using System.Collections.Generic;
-using System.Linq;
-using System.Threading.Tasks;
using Microsoft.AspNetCore.Identity;
namespace IdentitySample.Models.ManageViewModels
{
- public class IndexViewModel
- {
- public bool HasPassword { get; set; }
+ public class IndexViewModel
+ {
+ public bool HasPassword { get; set; }
- public IList Logins { get; set; }
+ public IList Logins { get; set; }
- public string PhoneNumber { get; set; }
+ public string PhoneNumber { get; set; }
- public bool TwoFactor { get; set; }
+ public bool TwoFactor { get; set; }
- public bool BrowserRemembered { get; set; }
- }
-}
+ public bool BrowserRemembered { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/samples/IdentitySample.Mvc/Models/ManageViewModels/ManageLoginsViewModel.cs b/samples/IdentitySample.Mvc/Models/ManageViewModels/ManageLoginsViewModel.cs
index 70948effa..bf1ffb623 100644
--- a/samples/IdentitySample.Mvc/Models/ManageViewModels/ManageLoginsViewModel.cs
+++ b/samples/IdentitySample.Mvc/Models/ManageViewModels/ManageLoginsViewModel.cs
@@ -1,16 +1,13 @@
-using System;
using System.Collections.Generic;
-using System.Linq;
-using System.Threading.Tasks;
using Microsoft.AspNetCore.Http.Authentication;
using Microsoft.AspNetCore.Identity;
namespace IdentitySample.Models.ManageViewModels
{
- public class ManageLoginsViewModel
- {
- public IList CurrentLogins { get; set; }
+ public class ManageLoginsViewModel
+ {
+ public IList CurrentLogins { get; set; }
- public IList OtherLogins { get; set; }
- }
-}
+ public IList OtherLogins { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/samples/IdentitySample.Mvc/Models/ManageViewModels/RemoveLoginViewModel.cs b/samples/IdentitySample.Mvc/Models/ManageViewModels/RemoveLoginViewModel.cs
index b46474e66..fe1e9ae1b 100644
--- a/samples/IdentitySample.Mvc/Models/ManageViewModels/RemoveLoginViewModel.cs
+++ b/samples/IdentitySample.Mvc/Models/ManageViewModels/RemoveLoginViewModel.cs
@@ -1,14 +1,8 @@
-using System;
-using System.Collections.Generic;
-using System.ComponentModel.DataAnnotations;
-using System.Linq;
-using System.Threading.Tasks;
-
-namespace IdentitySample.Models.ManageViewModels
+namespace IdentitySample.Models.ManageViewModels
{
- public class RemoveLoginViewModel
- {
- public string LoginProvider { get; set; }
- public string ProviderKey { get; set; }
- }
-}
+ public class RemoveLoginViewModel
+ {
+ public string LoginProvider { get; set; }
+ public string ProviderKey { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/samples/IdentitySample.Mvc/Models/ManageViewModels/SetPasswordViewModel.cs b/samples/IdentitySample.Mvc/Models/ManageViewModels/SetPasswordViewModel.cs
index 2e5fc4369..253827c15 100644
--- a/samples/IdentitySample.Mvc/Models/ManageViewModels/SetPasswordViewModel.cs
+++ b/samples/IdentitySample.Mvc/Models/ManageViewModels/SetPasswordViewModel.cs
@@ -1,22 +1,18 @@
-using System;
-using System.Collections.Generic;
-using System.ComponentModel.DataAnnotations;
-using System.Linq;
-using System.Threading.Tasks;
+using System.ComponentModel.DataAnnotations;
namespace IdentitySample.Models.ManageViewModels
{
- public class SetPasswordViewModel
- {
- [Required]
- [StringLength(100, ErrorMessage = "The {0} must be at least {2} characters long.", MinimumLength = 6)]
- [DataType(DataType.Password)]
- [Display(Name = "New password")]
- public string NewPassword { get; set; }
+ public class SetPasswordViewModel
+ {
+ [Required]
+ [StringLength(100, ErrorMessage = "The {0} must be at least {2} characters long.", MinimumLength = 6)]
+ [DataType(DataType.Password)]
+ [Display(Name = "New password")]
+ public string NewPassword { get; set; }
- [DataType(DataType.Password)]
- [Display(Name = "Confirm new password")]
- [Compare("NewPassword", ErrorMessage = "The new password and confirmation password do not match.")]
- public string ConfirmPassword { get; set; }
- }
-}
+ [DataType(DataType.Password)]
+ [Display(Name = "Confirm new password")]
+ [Compare("NewPassword", ErrorMessage = "The new password and confirmation password do not match.")]
+ public string ConfirmPassword { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/samples/IdentitySample.Mvc/Models/ManageViewModels/VerifyPhoneNumberViewModel.cs b/samples/IdentitySample.Mvc/Models/ManageViewModels/VerifyPhoneNumberViewModel.cs
index fbe22f4c8..7e1c4d610 100644
--- a/samples/IdentitySample.Mvc/Models/ManageViewModels/VerifyPhoneNumberViewModel.cs
+++ b/samples/IdentitySample.Mvc/Models/ManageViewModels/VerifyPhoneNumberViewModel.cs
@@ -1,19 +1,15 @@
-using System;
-using System.Collections.Generic;
-using System.ComponentModel.DataAnnotations;
-using System.Linq;
-using System.Threading.Tasks;
+using System.ComponentModel.DataAnnotations;
namespace IdentitySample.Models.ManageViewModels
{
- public class VerifyPhoneNumberViewModel
- {
- [Required]
- public string Code { get; set; }
+ public class VerifyPhoneNumberViewModel
+ {
+ [Required]
+ public string Code { get; set; }
- [Required]
- [Phone]
- [Display(Name = "Phone number")]
- public string PhoneNumber { get; set; }
- }
-}
+ [Required]
+ [Phone]
+ [Display(Name = "Phone number")]
+ public string PhoneNumber { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/samples/IdentitySample.Mvc/Program.cs b/samples/IdentitySample.Mvc/Program.cs
index b186e6812..b48f01d8c 100644
--- a/samples/IdentitySample.Mvc/Program.cs
+++ b/samples/IdentitySample.Mvc/Program.cs
@@ -4,21 +4,21 @@
namespace IdentitySample
{
- public static class Program
- {
- public static void Main(string[] args)
- {
- var config = new ConfigurationBuilder().AddEnvironmentVariables("ASPNETCORE_").Build();
+ public static class Program
+ {
+ public static void Main(string[] args)
+ {
+ var config = new ConfigurationBuilder().AddEnvironmentVariables("ASPNETCORE_").Build();
- var host = new WebHostBuilder()
- .UseKestrel()
- .UseConfiguration(config)
- .UseContentRoot(Directory.GetCurrentDirectory())
- .UseIISIntegration()
- .UseStartup()
- .Build();
+ var host = new WebHostBuilder()
+ .UseKestrel()
+ .UseConfiguration(config)
+ .UseContentRoot(Directory.GetCurrentDirectory())
+ .UseIISIntegration()
+ .UseStartup()
+ .Build();
- host.Run();
- }
- }
+ host.Run();
+ }
+ }
}
\ No newline at end of file
diff --git a/samples/IdentitySample.Mvc/Properties/launchSettings.json b/samples/IdentitySample.Mvc/Properties/launchSettings.json
index 485fe8532..500d8b107 100644
--- a/samples/IdentitySample.Mvc/Properties/launchSettings.json
+++ b/samples/IdentitySample.Mvc/Properties/launchSettings.json
@@ -1,25 +1,25 @@
{
- "iisSettings": {
- "windowsAuthentication": false,
- "anonymousAuthentication": true,
- "iisExpress": {
- "applicationUrl": "http://localhost:28248/",
- "sslPort": 0
- }
- },
- "profiles": {
- "IIS Express": {
- "commandName": "IISExpress",
- "launchBrowser": true,
- "environmentVariables": {
- "ASPNET_ENVIRONMENT": "Development"
- }
- },
- "web": {
- "commandName": "web",
- "environmentVariables": {
- "ASPNET_ENVIRONMENT": "Development"
- }
- }
- }
+ "iisSettings": {
+ "windowsAuthentication": false,
+ "anonymousAuthentication": true,
+ "iisExpress": {
+ "applicationUrl": "http://localhost:28248/",
+ "sslPort": 0
+ }
+ },
+ "profiles": {
+ "IIS Express": {
+ "commandName": "IISExpress",
+ "launchBrowser": true,
+ "environmentVariables": {
+ "ASPNET_ENVIRONMENT": "Development"
+ }
+ },
+ "web": {
+ "commandName": "web",
+ "environmentVariables": {
+ "ASPNET_ENVIRONMENT": "Development"
+ }
+ }
+ }
}
\ No newline at end of file
diff --git a/samples/IdentitySample.Mvc/Services/IEmailSender.cs b/samples/IdentitySample.Mvc/Services/IEmailSender.cs
index f8a5ef6d5..427ee59d0 100644
--- a/samples/IdentitySample.Mvc/Services/IEmailSender.cs
+++ b/samples/IdentitySample.Mvc/Services/IEmailSender.cs
@@ -1,12 +1,9 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Threading.Tasks;
+using System.Threading.Tasks;
namespace IdentitySample.Services
{
- public interface IEmailSender
- {
- Task SendEmailAsync(string email, string subject, string message);
- }
-}
+ public interface IEmailSender
+ {
+ Task SendEmailAsync(string email, string subject, string message);
+ }
+}
\ No newline at end of file
diff --git a/samples/IdentitySample.Mvc/Services/ISmsSender.cs b/samples/IdentitySample.Mvc/Services/ISmsSender.cs
index 169b56bac..197bb886d 100644
--- a/samples/IdentitySample.Mvc/Services/ISmsSender.cs
+++ b/samples/IdentitySample.Mvc/Services/ISmsSender.cs
@@ -1,12 +1,9 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Threading.Tasks;
+using System.Threading.Tasks;
namespace IdentitySample.Services
{
- public interface ISmsSender
- {
- Task SendSmsAsync(string number, string message);
- }
-}
+ public interface ISmsSender
+ {
+ Task SendSmsAsync(string number, string message);
+ }
+}
\ No newline at end of file
diff --git a/samples/IdentitySample.Mvc/Services/MessageServices.cs b/samples/IdentitySample.Mvc/Services/MessageServices.cs
index 469bb05c7..4c2ea1923 100644
--- a/samples/IdentitySample.Mvc/Services/MessageServices.cs
+++ b/samples/IdentitySample.Mvc/Services/MessageServices.cs
@@ -1,25 +1,22 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Threading.Tasks;
+using System.Threading.Tasks;
namespace IdentitySample.Services
{
- // This class is used by the application to send Email and SMS
- // when you turn on two-factor authentication in ASP.NET Identity.
- // For more details see this link http://go.microsoft.com/fwlink/?LinkID=532713
- public class AuthMessageSender : IEmailSender, ISmsSender
- {
- public Task SendEmailAsync(string email, string subject, string message)
- {
- // Plug in your email service here to send an email.
- return Task.FromResult(0);
- }
+ // This class is used by the application to send Email and SMS
+ // when you turn on two-factor authentication in ASP.NET Identity.
+ // For more details see this link http://go.microsoft.com/fwlink/?LinkID=532713
+ public class AuthMessageSender : IEmailSender, ISmsSender
+ {
+ public Task SendEmailAsync(string email, string subject, string message)
+ {
+ // Plug in your email service here to send an email.
+ return Task.FromResult(0);
+ }
- public Task SendSmsAsync(string number, string message)
- {
- // Plug in your SMS service here to send a text message.
- return Task.FromResult(0);
- }
- }
-}
+ public Task SendSmsAsync(string number, string message)
+ {
+ // Plug in your SMS service here to send a text message.
+ return Task.FromResult(0);
+ }
+ }
+}
\ No newline at end of file
diff --git a/samples/IdentitySample.Mvc/Startup.cs b/samples/IdentitySample.Mvc/Startup.cs
index ca4af1de0..d54b6eaac 100644
--- a/samples/IdentitySample.Mvc/Startup.cs
+++ b/samples/IdentitySample.Mvc/Startup.cs
@@ -1,110 +1,98 @@
-using System;
-using System.Collections.Generic;
using System.Data.SqlClient;
-using System.Linq;
-using System.Threading.Tasks;
-using Microsoft.AspNetCore.Builder;
-using Microsoft.AspNetCore.Hosting;
-using Microsoft.Extensions.Configuration;
-using Microsoft.Extensions.DependencyInjection;
-using Microsoft.Extensions.Logging;
+using System.IO;
using IdentitySample.Models;
using IdentitySample.Services;
-using Microsoft.AspNetCore.Identity;
-using Microsoft.AspNetCore.DataProtection;
-using System.IO;
using LinqToDB;
using LinqToDB.Data;
using LinqToDB.DataProvider.SqlServer;
using LinqToDB.Identity;
+using Microsoft.AspNetCore.Builder;
+using Microsoft.AspNetCore.DataProtection;
+using Microsoft.AspNetCore.Hosting;
+using Microsoft.Extensions.Configuration;
+using Microsoft.Extensions.DependencyInjection;
+using Microsoft.Extensions.Logging;
namespace IdentitySample
{
- public class Startup
- {
- public Startup(IHostingEnvironment env)
- {
- // Set up configuration sources.
- var builder = new ConfigurationBuilder()
- .SetBasePath(Directory.GetCurrentDirectory())
- .AddJsonFile("appsettings.json")
- .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true);
-
- if (env.IsDevelopment())
- {
- // For more details on using the user secret store see http://go.microsoft.com/fwlink/?LinkID=532709
- builder.AddUserSecrets();
- }
-
- builder.AddEnvironmentVariables();
- Configuration = builder.Build();
- }
-
- public IConfigurationRoot Configuration { get; set; }
-
- // This method gets called by the runtime. Use this method to add services to the container.
- public void ConfigureServices(IServiceCollection services)
- {
- // Set connection configuration
- DataConnection
- .AddConfiguration(
- "Default",
- Configuration["Data:DefaultConnection:ConnectionString"],
- new SqlServerDataProvider("Default", SqlServerVersion.v2012));
-
- DataConnection.DefaultConfiguration = "Default";
-
- services.AddIdentity(options => {
- options.Cookies.ApplicationCookie.AuthenticationScheme = "ApplicationCookie";
- options.Cookies.ApplicationCookie.CookieName = "Interop";
- options.Cookies.ApplicationCookie.DataProtectionProvider = DataProtectionProvider.Create(new DirectoryInfo("C:\\Github\\Identity\\artifacts"));
- })
- .AddLinqToDBStores(new DefaultConnectionFactory())
- .AddDefaultTokenProviders();
-
- services.AddMvc();
-
- // Add application services.
- services.AddTransient();
- services.AddTransient();
- }
-
- // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
- public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
- {
- loggerFactory.AddConsole(Configuration.GetSection("Logging"));
- loggerFactory.AddDebug();
-
- if (env.IsDevelopment())
- {
- app.UseDeveloperExceptionPage();
- //app.UseDatabaseErrorPage();
- }
- else
- {
- app.UseExceptionHandler("/Home/Error");
- }
-
- var connectionString = new SqlConnectionStringBuilder(Configuration["Data:DefaultConnection:ConnectionString"])
- {
- InitialCatalog = "master"
- }.ConnectionString;
-
- using (var db = new DataConnection(SqlServerTools.GetDataProvider(), connectionString))
- {
- try
- {
- var sql = "create database [" +
- new SqlConnectionStringBuilder(Configuration["Data:DefaultConnection:ConnectionString"])
- .InitialCatalog + "]";
- db.Execute(sql);
- }
- catch
- {
- //
- }
-
- }
+ public class Startup
+ {
+ public Startup(IHostingEnvironment env)
+ {
+ // Set up configuration sources.
+ var builder = new ConfigurationBuilder()
+ .SetBasePath(Directory.GetCurrentDirectory())
+ .AddJsonFile("appsettings.json")
+ .AddJsonFile($"appsettings.{env.EnvironmentName}.json", true);
+
+ if (env.IsDevelopment())
+ builder.AddUserSecrets();
+
+ builder.AddEnvironmentVariables();
+ Configuration = builder.Build();
+ }
+
+ public IConfigurationRoot Configuration { get; set; }
+
+ // This method gets called by the runtime. Use this method to add services to the container.
+ public void ConfigureServices(IServiceCollection services)
+ {
+ // Set connection configuration
+ DataConnection
+ .AddConfiguration(
+ "Default",
+ Configuration["Data:DefaultConnection:ConnectionString"],
+ new SqlServerDataProvider("Default", SqlServerVersion.v2012));
+
+ DataConnection.DefaultConfiguration = "Default";
+
+ services.AddIdentity(options =>
+ {
+ options.Cookies.ApplicationCookie.AuthenticationScheme = "ApplicationCookie";
+ options.Cookies.ApplicationCookie.CookieName = "Interop";
+ options.Cookies.ApplicationCookie.DataProtectionProvider =
+ DataProtectionProvider.Create(new DirectoryInfo("C:\\Github\\Identity\\artifacts"));
+ })
+ .AddLinqToDBStores(new DefaultConnectionFactory())
+ .AddDefaultTokenProviders();
+
+ services.AddMvc();
+
+ // Add application services.
+ services.AddTransient();
+ services.AddTransient();
+ }
+
+ // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
+ public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
+ {
+ loggerFactory.AddConsole(Configuration.GetSection("Logging"));
+ loggerFactory.AddDebug();
+
+ if (env.IsDevelopment())
+ app.UseDeveloperExceptionPage();
+ else
+ app.UseExceptionHandler("/Home/Error");
+
+ var connectionString = new SqlConnectionStringBuilder(Configuration["Data:DefaultConnection:ConnectionString"])
+ {
+ InitialCatalog = "master"
+ }.ConnectionString;
+
+ using (var db = new DataConnection(SqlServerTools.GetDataProvider(), connectionString))
+ {
+ try
+ {
+ var sql = "create database [" +
+ new SqlConnectionStringBuilder(Configuration["Data:DefaultConnection:ConnectionString"])
+ .InitialCatalog + "]";
+ db.Execute(sql);
+ }
+ catch
+ {
+ //
+ }
+ }
// Try to create tables
using (var db = new ApplicationDataConnection())
@@ -116,34 +104,32 @@ public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerF
TryCreateTable>(db);
TryCreateTable>(db);
TryCreateTable>(db);
-
}
app.UseStaticFiles();
- app.UseIdentity();
- // To configure external authentication please see http://go.microsoft.com/fwlink/?LinkID=532715
-
- app.UseMvc(routes =>
- {
- routes.MapRoute(
- name: "default",
- template: "{controller=Home}/{action=Index}/{id?}");
- });
- }
-
- private void TryCreateTable(ApplicationDataConnection db)
- where T : class
- {
- try
- {
- db.CreateTable();
- }
- catch
- {
- //
- }
- }
- }
-}
+ app.UseIdentity();
+ // To configure external authentication please see http://go.microsoft.com/fwlink/?LinkID=532715
+ app.UseMvc(routes =>
+ {
+ routes.MapRoute(
+ "default",
+ "{controller=Home}/{action=Index}/{id?}");
+ });
+ }
+
+ private void TryCreateTable(ApplicationDataConnection db)
+ where T : class
+ {
+ try
+ {
+ db.CreateTable();
+ }
+ catch
+ {
+ //
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/samples/IdentitySample.Mvc/Views/Account/ConfirmEmail.cshtml b/samples/IdentitySample.Mvc/Views/Account/ConfirmEmail.cshtml
index 3244fef5f..6ea5b414c 100644
--- a/samples/IdentitySample.Mvc/Views/Account/ConfirmEmail.cshtml
+++ b/samples/IdentitySample.Mvc/Views/Account/ConfirmEmail.cshtml
@@ -1,10 +1,10 @@
@{
- ViewData["Title"] = "Confirm Email";
+ ViewData["Title"] = "Confirm Email";
}
@ViewData["Title"].
+
+ Thank you for confirming your email. Please Click here to Log in .
+
+
\ No newline at end of file
diff --git a/samples/IdentitySample.Mvc/Views/Account/ExternalLoginConfirmation.cshtml b/samples/IdentitySample.Mvc/Views/Account/ExternalLoginConfirmation.cshtml
index fcd3b1869..45ce406a7 100644
--- a/samples/IdentitySample.Mvc/Views/Account/ExternalLoginConfirmation.cshtml
+++ b/samples/IdentitySample.Mvc/Views/Account/ExternalLoginConfirmation.cshtml
@@ -1,35 +1,35 @@
@model ExternalLoginConfirmationViewModel
@{
- ViewData["Title"] = "Register";
+ ViewData["Title"] = "Register";
}
@ViewData["Title"].
Associate your @ViewData["LoginProvider"] account.
@section Scripts {
- @{ await Html.RenderPartialAsync("_ValidationScriptsPartial"); }
-}
+ @{ await Html.RenderPartialAsync("_ValidationScriptsPartial"); }
+}
\ No newline at end of file
diff --git a/samples/IdentitySample.Mvc/Views/Account/ExternalLoginFailure.cshtml b/samples/IdentitySample.Mvc/Views/Account/ExternalLoginFailure.cshtml
index d89339e01..1c093a83b 100644
--- a/samples/IdentitySample.Mvc/Views/Account/ExternalLoginFailure.cshtml
+++ b/samples/IdentitySample.Mvc/Views/Account/ExternalLoginFailure.cshtml
@@ -1,8 +1,8 @@
@{
- ViewData["Title"] = "Login Failure";
+ ViewData["Title"] = "Login Failure";
}
+ @ViewData["Title"].
+ Unsuccessful login with service.
+
\ No newline at end of file
diff --git a/samples/IdentitySample.Mvc/Views/Account/ForgotPassword.cshtml b/samples/IdentitySample.Mvc/Views/Account/ForgotPassword.cshtml
index 8400cc7e2..a1db8e91d 100644
--- a/samples/IdentitySample.Mvc/Views/Account/ForgotPassword.cshtml
+++ b/samples/IdentitySample.Mvc/Views/Account/ForgotPassword.cshtml
@@ -1,11 +1,11 @@
@model ForgotPasswordViewModel
@{
- ViewData["Title"] = "Forgot your password?";
+ ViewData["Title"] = "Forgot your password?";
}
@ViewData["Title"].
- For more information on how to enable reset password please see this article .
+ For more information on how to enable reset password please see this article .
@**@
@section Scripts {
- @{ await Html.RenderPartialAsync("_ValidationScriptsPartial"); }
-}
+ @{ await Html.RenderPartialAsync("_ValidationScriptsPartial"); }
+}
\ No newline at end of file
diff --git a/samples/IdentitySample.Mvc/Views/Account/ForgotPasswordConfirmation.cshtml b/samples/IdentitySample.Mvc/Views/Account/ForgotPasswordConfirmation.cshtml
index ab9bf44c8..e278df7ed 100644
--- a/samples/IdentitySample.Mvc/Views/Account/ForgotPasswordConfirmation.cshtml
+++ b/samples/IdentitySample.Mvc/Views/Account/ForgotPasswordConfirmation.cshtml
@@ -1,8 +1,8 @@
@{
- ViewData["Title"] = "Forgot Password Confirmation";
+ ViewData["Title"] = "Forgot Password Confirmation";
}
@ViewData["Title"].
- Please check your email to reset your password.
-
+ Please check your email to reset your password.
+
\ No newline at end of file
diff --git a/samples/IdentitySample.Mvc/Views/Account/Lockout.cshtml b/samples/IdentitySample.Mvc/Views/Account/Lockout.cshtml
index 2cc946d5c..c5c90bb8a 100644
--- a/samples/IdentitySample.Mvc/Views/Account/Lockout.cshtml
+++ b/samples/IdentitySample.Mvc/Views/Account/Lockout.cshtml
@@ -1,8 +1,8 @@
@{
- ViewData["Title"] = "Locked out";
+ ViewData["Title"] = "Locked out";
}
+ Locked out.
+ This account has been locked out, please try again later.
+
\ No newline at end of file
diff --git a/samples/IdentitySample.Mvc/Views/Account/Login.cshtml b/samples/IdentitySample.Mvc/Views/Account/Login.cshtml
index e788eec18..679fac83b 100644
--- a/samples/IdentitySample.Mvc/Views/Account/Login.cshtml
+++ b/samples/IdentitySample.Mvc/Views/Account/Login.cshtml
@@ -1,92 +1,89 @@
-@using System.Collections.Generic
-@using Microsoft.AspNetCore.Http
-@using Microsoft.AspNetCore.Http.Authentication
@model LoginViewModel
@inject SignInManager SignInManager
@{
- ViewData["Title"] = "Log in";
+ ViewData["Title"] = "Log in";
}
@ViewData["Title"].
-
-
-
- Use another service to log in.
-
- @{
- var loginProviders = SignInManager.GetExternalAuthenticationSchemes().ToList();
- if (loginProviders.Count == 0)
- {
-
-
- There are no external authentication services configured. See this article
- for details on setting up this ASP.NET application to support logging in via external services.
-
-
- }
- else
- {
-
- }
- }
-
-
+
+
+
+ Use another service to log in.
+
+ @{
+ var loginProviders = SignInManager.GetExternalAuthenticationSchemes().ToList();
+ if (loginProviders.Count == 0)
+ {
+
+
+ There are no external authentication services configured. See this article
+ for details on setting up this ASP.NET application to support logging in via external services.
+
+
+ }
+ else
+ {
+
+ }
+ }
+
+
@section Scripts {
- @{ await Html.RenderPartialAsync("_ValidationScriptsPartial"); }
-}
+ @{ await Html.RenderPartialAsync("_ValidationScriptsPartial"); }
+}
\ No newline at end of file
diff --git a/samples/IdentitySample.Mvc/Views/Account/Register.cshtml b/samples/IdentitySample.Mvc/Views/Account/Register.cshtml
index 7d064f1b6..257c3f7af 100644
--- a/samples/IdentitySample.Mvc/Views/Account/Register.cshtml
+++ b/samples/IdentitySample.Mvc/Views/Account/Register.cshtml
@@ -1,42 +1,42 @@
@model RegisterViewModel
@{
- ViewData["Title"] = "Register";
+ ViewData["Title"] = "Register";
}
@ViewData["Title"].
@section Scripts {
- @{ await Html.RenderPartialAsync("_ValidationScriptsPartial"); }
-}
+ @{ await Html.RenderPartialAsync("_ValidationScriptsPartial"); }
+}
\ No newline at end of file
diff --git a/samples/IdentitySample.Mvc/Views/Account/ResetPassword.cshtml b/samples/IdentitySample.Mvc/Views/Account/ResetPassword.cshtml
index 8ab27b68e..f2a5c4b49 100644
--- a/samples/IdentitySample.Mvc/Views/Account/ResetPassword.cshtml
+++ b/samples/IdentitySample.Mvc/Views/Account/ResetPassword.cshtml
@@ -1,43 +1,43 @@
@model ResetPasswordViewModel
@{
- ViewData["Title"] = "Reset password";
+ ViewData["Title"] = "Reset password";
}
@ViewData["Title"].
@section Scripts {
- @{ await Html.RenderPartialAsync("_ValidationScriptsPartial"); }
-}
+ @{ await Html.RenderPartialAsync("_ValidationScriptsPartial"); }
+}
\ No newline at end of file
diff --git a/samples/IdentitySample.Mvc/Views/Account/ResetPasswordConfirmation.cshtml b/samples/IdentitySample.Mvc/Views/Account/ResetPasswordConfirmation.cshtml
index bef2e4570..14f07ecde 100644
--- a/samples/IdentitySample.Mvc/Views/Account/ResetPasswordConfirmation.cshtml
+++ b/samples/IdentitySample.Mvc/Views/Account/ResetPasswordConfirmation.cshtml
@@ -1,8 +1,8 @@
@{
- ViewData["Title"] = "Reset password confirmation";
+ ViewData["Title"] = "Reset password confirmation";
}
@ViewData["Title"].
- Your password has been reset. Please Click here to log in .
-
+ Your password has been reset. Please Click here to log in .
+
\ No newline at end of file
diff --git a/samples/IdentitySample.Mvc/Views/Account/SendCode.cshtml b/samples/IdentitySample.Mvc/Views/Account/SendCode.cshtml
index 0c8762998..2a6f4453f 100644
--- a/samples/IdentitySample.Mvc/Views/Account/SendCode.cshtml
+++ b/samples/IdentitySample.Mvc/Views/Account/SendCode.cshtml
@@ -1,21 +1,21 @@
@model SendCodeViewModel
@{
- ViewData["Title"] = "Send Verification Code";
+ ViewData["Title"] = "Send Verification Code";
}
@ViewData["Title"].
@section Scripts {
- @{await Html.RenderPartialAsync("_ValidationScriptsPartial"); }
-}
+ @{ await Html.RenderPartialAsync("_ValidationScriptsPartial"); }
+}
\ No newline at end of file
diff --git a/samples/IdentitySample.Mvc/Views/Account/VerifyCode.cshtml b/samples/IdentitySample.Mvc/Views/Account/VerifyCode.cshtml
index 3689cbba4..95125ac76 100644
--- a/samples/IdentitySample.Mvc/Views/Account/VerifyCode.cshtml
+++ b/samples/IdentitySample.Mvc/Views/Account/VerifyCode.cshtml
@@ -1,38 +1,38 @@
@model VerifyCodeViewModel
@{
- ViewData["Title"] = "Verify";
+ ViewData["Title"] = "Verify";
}
@ViewData["Title"].
@section Scripts {
- @{ await Html.RenderPartialAsync("_ValidationScriptsPartial"); }
-}
+ @{ await Html.RenderPartialAsync("_ValidationScriptsPartial"); }
+}
\ No newline at end of file
diff --git a/samples/IdentitySample.Mvc/Views/Home/Index.cshtml b/samples/IdentitySample.Mvc/Views/Home/Index.cshtml
index 59dc45d93..b07d5cd07 100644
--- a/samples/IdentitySample.Mvc/Views/Home/Index.cshtml
+++ b/samples/IdentitySample.Mvc/Views/Home/Index.cshtml
@@ -1,233 +1,235 @@
@{
- Layout = "/Views/Shared/_Layout.cshtml";
- ViewBag.Title = "Home Page";
+ Layout = "/Views/Shared/_Layout.cshtml";
+ ViewBag.Title = "Home Page";
}
-
ASP.NET Identity
-
ASP.NET Identity is the membership system for ASP.NET apps. Following are the features of ASP.NET Identity in this sample application.
-
Learn more »
+
ASP.NET Identity
+
ASP.NET Identity is the membership system for ASP.NET apps. Following are the features of ASP.NET Identity in this sample application.
+
+ Learn more »
+
-
-
- Initialize ASP.NET Identity
-
- You can initialize ASP.NET Identity when the application starts. Since ASP.NET Identity is Entity Framework based in this sample,
- you can create DatabaseInitializer which is configured to get called each time the app starts.
- Please look in App_Start\IdentityConfig.cs
- This code shows the following
-
- When should the Initializer run and when should the database be created
- Create Admin user
- Create Admin role
- Add Admin user to Admin role
-
-
-
-
-
-
- Add profile data for the user
-
- Please follow this tutorial.
+
+
+ Initialize ASP.NET Identity
+
+ You can initialize ASP.NET Identity when the application starts. Since ASP.NET Identity is Entity Framework based in this sample,
+ you can create DatabaseInitializer which is configured to get called each time the app starts.
+ Please look in App_Start\IdentityConfig.cs
+ This code shows the following
+
+ When should the Initializer run and when should the database be created
+ Create Admin user
+ Create Admin role
+ Add Admin user to Admin role
+
+
+
+
+
+
+ Add profile data for the user
+
+ Please follow this tutorial.
-
- Add profile information in the Users Table
- Look in Models\IdentityModels.cs for examples
-
-
-
-
-
-
- Validation
-
- When you create a User using a username or password, the Identity system performs validation on the username and password, and the passwords are hashed before they are
- stored in the database. You can customize the validation by changing some of the properties of the validators such as Turn alphanumeric on/off, set minimum password length
- or you can write your own custom validators and register them with the UserManager.
-
-
-
-
-
- Register a user and login
-
- Click @Html.ActionLink("Register", "Register", "Account") and see the code in AccountController.cs and Register Action.
- Click @Html.ActionLink("Log in", "Login", "Account") and see the code in AccountController.cs and Login Action.
-
-
-
-
-
- Social Logins
-
- You can the support so that users can login using their Facebook, Google, Twitter, Microsoft Account and more.
-
-
-
-
-
-
-
-
- Basic User Management
-
- Do Create, Update, List and Delete Users.
- Assign a Role to a User.
- Only Users In Role Admin can access this page. This uses the [Authorize(Roles = "Admin")] on the UserAdmin controller.
-
-
-
-
-
- Basic Role Management
-
- Do Create, Update, List and Delete Roles.
- Only Users In Role Admin can access this page. This authorization is done by using the [Authorize(Roles = "Admin")] on the RolesAdmin controller.
-
-
-
-
-
- Account Confirmation
-
- When you register a new account, you will be sent an email confirmation.
- You can use an email service such as SendGrid which integrates nicely with Windows Azure and requires no configuration or
- set up an SMTP server to send email.
- You can send email using the EmailService which is registered in App_Start\IdentityConfig.cs
-
-
-
-
-
- Two-Factor Authentication
-
- This sample shows how you can use Two-Factor authentication. This sample has a SMS and email service registered where you can send SMS or email for sending the security code.
- You can add more two-factor authentication factors such as QR codes and plug them into ASP.NET Identity.
-
-
- You can use a SMS using Twilio or use any means of sending SMS. Please read for more details on using Twilio.
- You can send SMS using the SmsService which is registered in App_Start\IdentityConfig.cs
-
-
- You can use an email service such as SendGrid or
- set up an SMTP server to send email.
- You can send email using the EmailService which is registered in App_Start\IdentityConfig.cs
-
+
+ Add profile information in the Users Table
+ Look in Models\IdentityModels.cs for examples
+
+
+
+
+
+
+ Validation
+
+ When you create a User using a username or password, the Identity system performs validation on the username and password, and the passwords are hashed before they are
+ stored in the database. You can customize the validation by changing some of the properties of the validators such as Turn alphanumeric on/off, set minimum password length
+ or you can write your own custom validators and register them with the UserManager.
+
+
+
+
+
+ Register a user and login
+
+ Click @Html.ActionLink("Register", "Register", "Account") and see the code in AccountController.cs and Register Action.
+ Click @Html.ActionLink("Log in", "Login", "Account") and see the code in AccountController.cs and Login Action.
+
+
+
+
+
+ Social Logins
+
+ You can the support so that users can login using their Facebook, Google, Twitter, Microsoft Account and more.
+
+
+
+
+
+
+
+
+ Basic User Management
+
+ Do Create, Update, List and Delete Users.
+ Assign a Role to a User.
+ Only Users In Role Admin can access this page. This uses the [Authorize(Roles = "Admin")] on the UserAdmin controller.
+
+
+
+
+
+ Basic Role Management
+
+ Do Create, Update, List and Delete Roles.
+ Only Users In Role Admin can access this page. This authorization is done by using the [Authorize(Roles = "Admin")] on the RolesAdmin controller.
+
+
+
+
+
+ Account Confirmation
+
+ When you register a new account, you will be sent an email confirmation.
+ You can use an email service such as SendGrid which integrates nicely with Windows Azure and requires no configuration or
+ set up an SMTP server to send email.
+ You can send email using the EmailService which is registered in App_Start\IdentityConfig.cs
+
+
+
+
+
+ Two-Factor Authentication
+
+ This sample shows how you can use Two-Factor authentication. This sample has a SMS and email service registered where you can send SMS or email for sending the security code.
+ You can add more two-factor authentication factors such as QR codes and plug them into ASP.NET Identity.
+
+
+ You can use a SMS using Twilio or use any means of sending SMS. Please read for more details on using Twilio.
+ You can send SMS using the SmsService which is registered in App_Start\IdentityConfig.cs
+
+
+ You can use an email service such as SendGrid or
+ set up an SMTP server to send email.
+ You can send email using the EmailService which is registered in App_Start\IdentityConfig.cs
+
-
- When you login, you can add a phone number by clicking the Manage page.
-
-
- Once you add a phone number and have the Phone service hooked to send a SMS, you will get a code through SMS to confirm your phone number.
-
-
- In the Manage page, you can turn on Two-Factor authentication.
-
-
- When you logout and login, after you enter the username and password, you will get an option of how to get the security code to use for two-factor authentication.
-
-
- You can copy the code from your SMS or email and enter in the form to login.
-
-
- The sample also shows how to protect against Brute force attacks against two-factor codes. When you enter a code incorrectly for 5 times then you will be
- lockedout for 5 min before you can enter a new code. These settings can be configured in App_Start\IdentityConfig.cs by setting DefaultAccountLockoutTimeSpan and MaxFailedAccessAttemptsBeforeLockout on the UserManager.
-
-
- If the machine you are browsing this website is your own machine, you can choose to check the "Remember Me" option after you enter the code.
- This option will remember you forever on this machine and will not ask you for the two-factor authentication, the next time when you login to the website.
- You can change your "Remember Me" settings for two-factor authentication in the Manage page.
-
-
-
-
-
-
-
- Account Lockout
-
- Provide a way to Lockout out the user if the user enters their password or two-factor codes incorrectly.
- The number of invalid attempts and the timespan for the users are locked out can be configured.
- A developer can optionally turn off Account Lockout for certain user accounts should they need to.
-
-
- Account LockOut settings can be configured in the UserManager in IdentityConfig.cs
-
-
-
-
-
- Security Token provider
-
- Support a way to regenerate the Security Token for the user in cases when the User changes there password or any other security related information such as removing an associated login(such as Facebook, Google, Microsoft Account etc).
- This is needed to ensure that any tokens generated with the old password are invalidated. In the sample project, if you change the users password then a new token is generated for the user and any previous tokens are invalidated.
- This feature provides an extra layer of security to your application since when you change your password, you will be logged out from everywhere (all other browsers) where you have logged into this application.
-
-
-
- The provider is registered when you add CookieAuthentication in StartupAuth to your application.
-
-
-
-
-
-
- Password Reset
-
- Allows the user to reset their passwords if they have forgotten their password. In this sample users need to confirm their email before they can reset their passwords.
-
-
-
-
-
- Custom Storage providers
-
- You can extend ASP.NET Identity to write your own custom storage provider for storing the ASP.NET Identity system and user data
- in a persistance system of your choice such as MondoDb, RavenDb, Azure Table Storage etc.
-
-
-
-
-
-
-
-
- Documentation
-
-
-
-
-
+
+ When you login, you can add a phone number by clicking the Manage page.
+
+
+ Once you add a phone number and have the Phone service hooked to send a SMS, you will get a code through SMS to confirm your phone number.
+
+
+ In the Manage page, you can turn on Two-Factor authentication.
+
+
+ When you logout and login, after you enter the username and password, you will get an option of how to get the security code to use for two-factor authentication.
+
+
+ You can copy the code from your SMS or email and enter in the form to login.
+
+
+ The sample also shows how to protect against Brute force attacks against two-factor codes. When you enter a code incorrectly for 5 times then you will be
+ lockedout for 5 min before you can enter a new code. These settings can be configured in App_Start\IdentityConfig.cs by setting DefaultAccountLockoutTimeSpan and MaxFailedAccessAttemptsBeforeLockout on the UserManager.
+
+
+ If the machine you are browsing this website is your own machine, you can choose to check the "Remember Me" option after you enter the code.
+ This option will remember you forever on this machine and will not ask you for the two-factor authentication, the next time when you login to the website.
+ You can change your "Remember Me" settings for two-factor authentication in the Manage page.
+
+
+
+
+
+
+
+ Account Lockout
+
+ Provide a way to Lockout out the user if the user enters their password or two-factor codes incorrectly.
+ The number of invalid attempts and the timespan for the users are locked out can be configured.
+ A developer can optionally turn off Account Lockout for certain user accounts should they need to.
+
+
+ Account LockOut settings can be configured in the UserManager in IdentityConfig.cs
+
+
+
+
+
+ Security Token provider
+
+ Support a way to regenerate the Security Token for the user in cases when the User changes there password or any other security related information such as removing an associated login(such as Facebook, Google, Microsoft Account etc).
+ This is needed to ensure that any tokens generated with the old password are invalidated. In the sample project, if you change the users password then a new token is generated for the user and any previous tokens are invalidated.
+ This feature provides an extra layer of security to your application since when you change your password, you will be logged out from everywhere (all other browsers) where you have logged into this application.
+
+
+
+ The provider is registered when you add CookieAuthentication in StartupAuth to your application.
+
+
+
+
+
+
+ Password Reset
+
+ Allows the user to reset their passwords if they have forgotten their password. In this sample users need to confirm their email before they can reset their passwords.
+
+
+
+
+
+ Custom Storage providers
+
+ You can extend ASP.NET Identity to write your own custom storage provider for storing the ASP.NET Identity system and user data
+ in a persistance system of your choice such as MondoDb, RavenDb, Azure Table Storage etc.
+
+
+
+
+
+
+
+
+ Documentation
+
+
+
+
+
\ No newline at end of file
diff --git a/samples/IdentitySample.Mvc/Views/Manage/AddPhoneNumber.cshtml b/samples/IdentitySample.Mvc/Views/Manage/AddPhoneNumber.cshtml
index 1e09409ca..4782b5e7d 100644
--- a/samples/IdentitySample.Mvc/Views/Manage/AddPhoneNumber.cshtml
+++ b/samples/IdentitySample.Mvc/Views/Manage/AddPhoneNumber.cshtml
@@ -1,27 +1,27 @@
@model AddPhoneNumberViewModel
@{
- ViewData["Title"] = "Add Phone Number";
+ ViewData["Title"] = "Add Phone Number";
}
@ViewData["Title"].
@section Scripts {
- @{ await Html.RenderPartialAsync("_ValidationScriptsPartial"); }
-}
+ @{ await Html.RenderPartialAsync("_ValidationScriptsPartial"); }
+}
\ No newline at end of file
diff --git a/samples/IdentitySample.Mvc/Views/Manage/ChangePassword.cshtml b/samples/IdentitySample.Mvc/Views/Manage/ChangePassword.cshtml
index 6127082df..f903b5639 100644
--- a/samples/IdentitySample.Mvc/Views/Manage/ChangePassword.cshtml
+++ b/samples/IdentitySample.Mvc/Views/Manage/ChangePassword.cshtml
@@ -1,42 +1,42 @@
@model ChangePasswordViewModel
@{
- ViewData["Title"] = "Change Password";
+ ViewData["Title"] = "Change Password";
}
@ViewData["Title"].
@section Scripts {
- @{ await Html.RenderPartialAsync("_ValidationScriptsPartial"); }
-}
+ @{ await Html.RenderPartialAsync("_ValidationScriptsPartial"); }
+}
\ No newline at end of file
diff --git a/samples/IdentitySample.Mvc/Views/Manage/Index.cshtml b/samples/IdentitySample.Mvc/Views/Manage/Index.cshtml
index 79a2d97dd..8a4a84213 100644
--- a/samples/IdentitySample.Mvc/Views/Manage/Index.cshtml
+++ b/samples/IdentitySample.Mvc/Views/Manage/Index.cshtml
@@ -1,38 +1,38 @@
@model IndexViewModel
@{
- ViewData["Title"] = "Manage your account";
+ ViewData["Title"] = "Manage your account";
}
@ViewData["Title"].
@ViewData["StatusMessage"]
-
Change your account settings
-
-
- Password:
-
- @if (Model.HasPassword)
- {
- [ Change ]
- }
- else
- {
- [ Create ]
- }
-
- External Logins:
-
- @Model.Logins.Count [ Manage ]
-
- Phone Number:
-
-
- Phone Numbers can used as a second factor of verification in two-factor authentication.
- See this article
- for details on setting up this ASP.NET application to support two-factor authentication using SMS.
-
- @*@(Model.PhoneNumber ?? "None")
+ Change your account settings
+
+
+ Password:
+
+ @if (Model.HasPassword)
+ {
+ [ Change ]
+ }
+ else
+ {
+ [ Create ]
+ }
+
+ External Logins:
+
+ @Model.Logins.Count [ Manage ]
+
+ Phone Number:
+
+
+ Phone Numbers can used as a second factor of verification in two-factor authentication.
+ See this article
+ for details on setting up this ASP.NET application to support two-factor authentication using SMS.
+
+ @*@(Model.PhoneNumber ?? "None")
@if (Model.PhoneNumber != null)
{
@@ -45,15 +45,15 @@
{
[ Add ]
}*@
-
+
- Two-Factor Authentication:
-
-
- There are no two-factor authentication providers configured. See this article
- for setting up this application to support two-factor authentication.
-
- @*@if (Model.TwoFactor)
+ Two-Factor Authentication:
+
+
+ There are no two-factor authentication providers configured. See this article
+ for setting up this application to support two-factor authentication.
+
+ @*@if (Model.TwoFactor)
{
}*@
-
-
+
+
\ No newline at end of file
diff --git a/samples/IdentitySample.Mvc/Views/Manage/ManageLogins.cshtml b/samples/IdentitySample.Mvc/Views/Manage/ManageLogins.cshtml
index 1bfb1d8af..7f8a0e52d 100644
--- a/samples/IdentitySample.Mvc/Views/Manage/ManageLogins.cshtml
+++ b/samples/IdentitySample.Mvc/Views/Manage/ManageLogins.cshtml
@@ -1,7 +1,6 @@
@model ManageLoginsViewModel
-@using Microsoft.AspNetCore.Http.Authentication
@{
- ViewData["Title"] = "Manage your external logins";
+ ViewData["Title"] = "Manage your external logins";
}
@ViewData["Title"].
@@ -9,46 +8,46 @@
@ViewData["StatusMessage"]
@if (Model.CurrentLogins.Count > 0)
{
- Registered Logins
-
-
- @for (var index = 0; index < Model.CurrentLogins.Count; index++)
- {
-
- @Model.CurrentLogins[index].LoginProvider
-
- @if ((bool)ViewData["ShowRemoveButton"])
- {
-
- }
- else
- {
- @:
- }
-
-
- }
-
-
+ Registered Logins
+
+
+ @for (var index = 0; index < Model.CurrentLogins.Count; index++)
+ {
+
+ @Model.CurrentLogins[index].LoginProvider
+
+ @if ((bool) ViewData["ShowRemoveButton"])
+ {
+
+ }
+ else
+ {
+ @:
+ }
+
+
+ }
+
+
}
@if (Model.OtherLogins.Count > 0)
{
- Add another service to log in.
-
-
-}
+ Add another service to log in.
+
+
+}
\ No newline at end of file
diff --git a/samples/IdentitySample.Mvc/Views/Manage/SetPassword.cshtml b/samples/IdentitySample.Mvc/Views/Manage/SetPassword.cshtml
index d1a1b77a4..4a1dbe62d 100644
--- a/samples/IdentitySample.Mvc/Views/Manage/SetPassword.cshtml
+++ b/samples/IdentitySample.Mvc/Views/Manage/SetPassword.cshtml
@@ -1,38 +1,38 @@
@model SetPasswordViewModel
@{
- ViewData["Title"] = "Set Password";
+ ViewData["Title"] = "Set Password";
}
- You do not have a local username/password for this site. Add a local
- account so you can log in without an external login.
+ You do not have a local username/password for this site. Add a local
+ account so you can log in without an external login.
@section Scripts {
- @{ await Html.RenderPartialAsync("_ValidationScriptsPartial"); }
-}
+ @{ await Html.RenderPartialAsync("_ValidationScriptsPartial"); }
+}
\ No newline at end of file
diff --git a/samples/IdentitySample.Mvc/Views/Manage/VerifyPhoneNumber.cshtml b/samples/IdentitySample.Mvc/Views/Manage/VerifyPhoneNumber.cshtml
index 17787816b..f93adb4c3 100644
--- a/samples/IdentitySample.Mvc/Views/Manage/VerifyPhoneNumber.cshtml
+++ b/samples/IdentitySample.Mvc/Views/Manage/VerifyPhoneNumber.cshtml
@@ -1,30 +1,30 @@
@model VerifyPhoneNumberViewModel
@{
- ViewData["Title"] = "Verify Phone Number";
+ ViewData["Title"] = "Verify Phone Number";
}
@ViewData["Title"].
@section Scripts {
- @{ await Html.RenderPartialAsync("_ValidationScriptsPartial"); }
-}
+ @{ await Html.RenderPartialAsync("_ValidationScriptsPartial"); }
+}
\ No newline at end of file
diff --git a/samples/IdentitySample.Mvc/Views/Shared/_Layout.cshtml b/samples/IdentitySample.Mvc/Views/Shared/_Layout.cshtml
index 912a38b7a..42a09564a 100644
--- a/samples/IdentitySample.Mvc/Views/Shared/_Layout.cshtml
+++ b/samples/IdentitySample.Mvc/Views/Shared/_Layout.cshtml
@@ -1,46 +1,52 @@
-
-
-
- @ViewData["Title"] - Identity Sample
-
-
-
-
-
-
-
-
-
- @await Html.PartialAsync("_LoginPartial")
-
-
-
-
+
+
+
+ @ViewData["Title"] - Identity Sample
+
+
+
+
+
+
+
+
+
+ @await Html.PartialAsync("_LoginPartial")
+
+
+
+
-
-
-
+
+
+
- @RenderSection("scripts", required: false)
-
-
+@RenderSection("scripts", false)
+
+