├── .gitattributes ├── .gitignore ├── KriaSoft.AspNet.Identity.sln ├── LICENSE.txt ├── README.md ├── Settings.StyleCop ├── docs └── Database-First.md ├── examples └── KriaSoft.AspNet.Identity.DbFirst │ ├── KriaSoft.AspNet.Identity.DbFirst.csproj │ ├── Properties │ └── AssemblyInfo.cs │ ├── Security │ └── ApplicationOAuthProvider.cs │ ├── Startup.cs │ ├── Web.config │ ├── app.js │ ├── index.html │ └── packages.config ├── src ├── KriaSoft.AspNet.Identity.Database │ ├── KriaSoft.AspNet.Identity.Database.sqlproj │ ├── Publish Profiles │ │ └── Local.publish.xml │ ├── Reference Data │ │ ├── User.sql │ │ ├── UserRole.sql │ │ └── UserUserRole.sql │ ├── Scripts │ │ └── PostDeployment.sql │ ├── Tables │ │ ├── User.sql │ │ ├── UserClaim.sql │ │ ├── UserLogin.sql │ │ ├── UserRole.sql │ │ └── UserUserRole.sql │ └── User Defined Types │ │ ├── Email.sql │ │ ├── Flag.sql │ │ ├── Name.sql │ │ └── Phone.sql └── KriaSoft.AspNet.Identity.EntityFramework │ ├── App.config │ ├── KriaSoft.AspNet.Identity.EntityFramework.csproj │ ├── Model.Context.cs │ ├── Model.Context.tt │ ├── Model.Designer.cs │ ├── Model.cs │ ├── Model.edmx │ ├── Model.edmx.diagram │ ├── Model.tt │ ├── Properties │ └── AssemblyInfo.cs │ ├── Resources.Designer.cs │ ├── Resources.resx │ ├── RoleStore.cs │ ├── User.cs │ ├── UserClaim.cs │ ├── UserEntity.cs │ ├── UserLogin.cs │ ├── UserRole.cs │ ├── UserRoleEntity.cs │ ├── UserStore.cs │ └── packages.config └── test └── KriaSoft.AspNet.Identity.EntityFramework.Tests ├── KriaSoft.AspNet.Identity.EntityFramework.Tests.csproj ├── Properties └── AssemblyInfo.cs └── packages.config /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | 4 | # Custom for Visual Studio 5 | *.cs diff=csharp 6 | *.sln merge=union 7 | *.csproj merge=union 8 | *.vbproj merge=union 9 | *.fsproj merge=union 10 | *.sqlproj merge=union 11 | 12 | # Standard to msysgit 13 | *.doc diff=astextplain 14 | *.DOC diff=astextplain 15 | *.docx diff=astextplain 16 | *.DOCX diff=astextplain 17 | *.dot diff=astextplain 18 | *.DOT diff=astextplain 19 | *.pdf diff=astextplain 20 | *.PDF diff=astextplain 21 | *.rtf diff=astextplain 22 | *.RTF diff=astextplain 23 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ################# 2 | ## Eclipse 3 | ################# 4 | 5 | *.pydevproject 6 | .project 7 | .metadata 8 | bin/ 9 | tmp/ 10 | *.tmp 11 | *.bak 12 | *.swp 13 | *~.nib 14 | local.properties 15 | .classpath 16 | .settings/ 17 | .loadpath 18 | 19 | # External tool builders 20 | .externalToolBuilders/ 21 | 22 | # Locally stored "Eclipse launch configurations" 23 | *.launch 24 | 25 | # CDT-specific 26 | .cproject 27 | 28 | # PDT-specific 29 | .buildpath 30 | 31 | 32 | ################# 33 | ## Visual Studio 34 | ################# 35 | 36 | ## Ignore Visual Studio temporary files, build results, and 37 | ## files generated by popular Visual Studio add-ons. 38 | 39 | # User-specific files 40 | *.suo 41 | *.user 42 | *.sln.docstates 43 | 44 | # Build results 45 | 46 | [Dd]ebug/ 47 | [Rr]elease/ 48 | x64/ 49 | build/ 50 | [Bb]in/ 51 | [Oo]bj/ 52 | 53 | # MSTest test Results 54 | [Tt]est[Rr]esult*/ 55 | [Bb]uild[Ll]og.* 56 | 57 | *_i.c 58 | *_p.c 59 | *.ilk 60 | *.meta 61 | *.obj 62 | *.pch 63 | *.pdb 64 | *.pgc 65 | *.pgd 66 | *.rsp 67 | *.sbr 68 | *.tlb 69 | *.tli 70 | *.tlh 71 | *.tmp 72 | *.tmp_proj 73 | *.log 74 | *.vspscc 75 | *.vssscc 76 | .builds 77 | *.pidb 78 | *.log 79 | *.scc 80 | 81 | # Visual C++ cache files 82 | ipch/ 83 | *.aps 84 | *.ncb 85 | *.opensdf 86 | *.sdf 87 | *.cachefile 88 | 89 | # Visual Studio profiler 90 | *.psess 91 | *.vsp 92 | *.vspx 93 | 94 | # Guidance Automation Toolkit 95 | *.gpState 96 | 97 | # ReSharper is a .NET coding add-in 98 | _ReSharper*/ 99 | *.[Rr]e[Ss]harper 100 | 101 | # TeamCity is a build add-in 102 | _TeamCity* 103 | 104 | # DotCover is a Code Coverage Tool 105 | *.dotCover 106 | 107 | # NCrunch 108 | *.ncrunch* 109 | .*crunch*.local.xml 110 | 111 | # Installshield output folder 112 | [Ee]xpress/ 113 | 114 | # DocProject is a documentation generator add-in 115 | DocProject/buildhelp/ 116 | DocProject/Help/*.HxT 117 | DocProject/Help/*.HxC 118 | DocProject/Help/*.hhc 119 | DocProject/Help/*.hhk 120 | DocProject/Help/*.hhp 121 | DocProject/Help/Html2 122 | DocProject/Help/html 123 | 124 | # Click-Once directory 125 | publish/ 126 | 127 | # Publish Web Output 128 | #*.Publish.xml 129 | *.pubxml 130 | 131 | # NuGet Packages Directory 132 | packages/ 133 | 134 | # Windows Azure Build Output 135 | csx 136 | *.build.csdef 137 | 138 | # Windows Store app package directory 139 | AppPackages/ 140 | 141 | # Others 142 | sql/ 143 | *.Cache 144 | ClientBin/ 145 | [Ss]tyle[Cc]op.* 146 | ~$* 147 | *~ 148 | *.dbmdl 149 | #*.[Pp]ublish.xml 150 | *.pfx 151 | *.publishsettings 152 | 153 | # RIA/Silverlight projects 154 | Generated_Code/ 155 | 156 | # Backup & report files from converting an old project file to a newer 157 | # Visual Studio version. Backup files are not needed, because we have git ;-) 158 | _UpgradeReport_Files/ 159 | Backup*/ 160 | UpgradeLog*.XML 161 | UpgradeLog*.htm 162 | 163 | # SQL Server files 164 | App_Data/*.mdf 165 | App_Data/*.ldf 166 | 167 | ############# 168 | ## Windows detritus 169 | ############# 170 | 171 | # Windows image file caches 172 | Thumbs.db 173 | ehthumbs.db 174 | 175 | # Folder config file 176 | Desktop.ini 177 | 178 | # Recycle Bin used on file shares 179 | $RECYCLE.BIN/ 180 | 181 | # Mac crap 182 | .DS_Store 183 | 184 | 185 | ############# 186 | ## Python 187 | ############# 188 | 189 | *.py[co] 190 | 191 | # Packages 192 | *.egg 193 | *.egg-info 194 | dist/ 195 | build/ 196 | eggs/ 197 | parts/ 198 | var/ 199 | sdist/ 200 | develop-eggs/ 201 | .installed.cfg 202 | 203 | # Installer logs 204 | pip-log.txt 205 | 206 | # Unit test / coverage reports 207 | .coverage 208 | .tox 209 | 210 | #Translations 211 | *.mo 212 | 213 | #Mr Developer 214 | .mr.developer.cfg 215 | 216 | 217 | README.html 218 | README.min.html 219 | docs/*.html 220 | src/Templates -------------------------------------------------------------------------------- /KriaSoft.AspNet.Identity.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 2013 4 | VisualStudioVersion = 12.0.30110.0 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".settings", ".settings", "{37F10E31-9EC4-4119-8DB5-03C780D049F6}" 7 | ProjectSection(SolutionItems) = preProject 8 | .gitattributes = .gitattributes 9 | .gitignore = .gitignore 10 | LICENSE.txt = LICENSE.txt 11 | README.md = README.md 12 | Settings.StyleCop = Settings.StyleCop 13 | EndProjectSection 14 | EndProject 15 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "examples", "examples", "{BC75208A-D1F8-45F5-9109-A07252BAE377}" 16 | EndProject 17 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "KriaSoft.AspNet.Identity.DbFirst", "examples\KriaSoft.AspNet.Identity.DbFirst\KriaSoft.AspNet.Identity.DbFirst.csproj", "{6F013146-8A52-4B79-9B87-762647CD8600}" 18 | EndProject 19 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{D306510E-56AA-46E9-A882-0B65386D51EE}" 20 | EndProject 21 | Project("{00D1A9C2-B5F0-4AF3-8072-F6C62B433612}") = "KriaSoft.AspNet.Identity.Database", "src\KriaSoft.AspNet.Identity.Database\KriaSoft.AspNet.Identity.Database.sqlproj", "{C77AFCBD-25B7-4500-92DC-1248EDD6A89E}" 22 | EndProject 23 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "KriaSoft.AspNet.Identity.EntityFramework", "src\KriaSoft.AspNet.Identity.EntityFramework\KriaSoft.AspNet.Identity.EntityFramework.csproj", "{311FECA9-F3CE-49A7-B085-B9DAFA25CA0A}" 24 | EndProject 25 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{51153F63-66A3-4DC4-A7DA-1AA66F966D91}" 26 | EndProject 27 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "KriaSoft.AspNet.Identity.EntityFramework.Tests", "test\KriaSoft.AspNet.Identity.EntityFramework.Tests\KriaSoft.AspNet.Identity.EntityFramework.Tests.csproj", "{EDB5DE31-B19F-4105-8150-093CADEEB206}" 28 | EndProject 29 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "docs", "docs", "{C82E2BD5-3C58-4AF1-8596-613F67CA0090}" 30 | ProjectSection(SolutionItems) = preProject 31 | docs\Database-First.md = docs\Database-First.md 32 | EndProjectSection 33 | EndProject 34 | Global 35 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 36 | Debug|Any CPU = Debug|Any CPU 37 | Release|Any CPU = Release|Any CPU 38 | EndGlobalSection 39 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 40 | {6F013146-8A52-4B79-9B87-762647CD8600}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 41 | {6F013146-8A52-4B79-9B87-762647CD8600}.Debug|Any CPU.Build.0 = Debug|Any CPU 42 | {6F013146-8A52-4B79-9B87-762647CD8600}.Release|Any CPU.ActiveCfg = Release|Any CPU 43 | {6F013146-8A52-4B79-9B87-762647CD8600}.Release|Any CPU.Build.0 = Release|Any CPU 44 | {C77AFCBD-25B7-4500-92DC-1248EDD6A89E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 45 | {C77AFCBD-25B7-4500-92DC-1248EDD6A89E}.Debug|Any CPU.Build.0 = Debug|Any CPU 46 | {C77AFCBD-25B7-4500-92DC-1248EDD6A89E}.Debug|Any CPU.Deploy.0 = Debug|Any CPU 47 | {C77AFCBD-25B7-4500-92DC-1248EDD6A89E}.Release|Any CPU.ActiveCfg = Release|Any CPU 48 | {C77AFCBD-25B7-4500-92DC-1248EDD6A89E}.Release|Any CPU.Build.0 = Release|Any CPU 49 | {C77AFCBD-25B7-4500-92DC-1248EDD6A89E}.Release|Any CPU.Deploy.0 = Release|Any CPU 50 | {311FECA9-F3CE-49A7-B085-B9DAFA25CA0A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 51 | {311FECA9-F3CE-49A7-B085-B9DAFA25CA0A}.Debug|Any CPU.Build.0 = Debug|Any CPU 52 | {311FECA9-F3CE-49A7-B085-B9DAFA25CA0A}.Release|Any CPU.ActiveCfg = Release|Any CPU 53 | {311FECA9-F3CE-49A7-B085-B9DAFA25CA0A}.Release|Any CPU.Build.0 = Release|Any CPU 54 | {EDB5DE31-B19F-4105-8150-093CADEEB206}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 55 | {EDB5DE31-B19F-4105-8150-093CADEEB206}.Debug|Any CPU.Build.0 = Debug|Any CPU 56 | {EDB5DE31-B19F-4105-8150-093CADEEB206}.Release|Any CPU.ActiveCfg = Release|Any CPU 57 | {EDB5DE31-B19F-4105-8150-093CADEEB206}.Release|Any CPU.Build.0 = Release|Any CPU 58 | EndGlobalSection 59 | GlobalSection(SolutionProperties) = preSolution 60 | HideSolutionNode = FALSE 61 | EndGlobalSection 62 | GlobalSection(NestedProjects) = preSolution 63 | {6F013146-8A52-4B79-9B87-762647CD8600} = {BC75208A-D1F8-45F5-9109-A07252BAE377} 64 | {C77AFCBD-25B7-4500-92DC-1248EDD6A89E} = {D306510E-56AA-46E9-A882-0B65386D51EE} 65 | {311FECA9-F3CE-49A7-B085-B9DAFA25CA0A} = {D306510E-56AA-46E9-A882-0B65386D51EE} 66 | {EDB5DE31-B19F-4105-8150-093CADEEB206} = {51153F63-66A3-4DC4-A7DA-1AA66F966D91} 67 | EndGlobalSection 68 | EndGlobal 69 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) 2014 Konstantin Tarkus, KriaSoft LLC. 2 | 3 | Licensed under the Apache License, Version 2.0 (the "License"); 4 | you may not use this file except in compliance with the License. 5 | You may obtain a copy of the License at 6 | 7 | http://www.apache.org/licenses/LICENSE-2.0 8 | 9 | Unless required by applicable law or agreed to in writing, software 10 | distributed under the License is distributed on an "AS IS" BASIS, 11 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | See the License for the specific language governing permissions and 13 | limitations under the License. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ASP.NET Identity with EF DbFirst 2 | ================================ 3 | 4 | > This projects demonstrates how to use [ASP.NET Identity](http://asp.net/identity) with 5 | > Entity Framework Database-First model. 6 | 7 | [Getting Started with ASP.NET Identity and EF Database-First](./docs/Database-First.md) 8 | 9 | ![ASP.NET Identity Model](http://i.imgur.com/KHDqq3B.png) 10 | 11 | ### Download 12 | 13 | http://visualstudiogallery.msdn.microsoft.com/6780f8e4-d204-4e88-83c2-853098727ffb 14 | 15 | ![ASP.NET Identity Database Project Template](http://i.imgur.com/5rxiyS2.png) 16 | 17 | ![ASP.NET Identity Database](http://i.imgur.com/9jV1deH.png) 18 | 19 | ### Authors 20 | 21 | * [Konstantin Tarkus](https://angel.co/koistya) ([hello@tarkus.me](mailto:hello@tarkuks.me?subject=ASP.NET+Identity+Providers)), KriaSoft LLC. 22 | 23 | ### License 24 | 25 | * **Source code**: the [Apache License 2.0](http://www.apache.org/licenses/LICENSE-2.0) (see [LICENSE.txt](./LICENSE.txt)) 26 | * **Documentation**: the [Creative Commons Attribution 4.0 International License](http://creativecommons.org/licenses/by/4.0/) 27 | -------------------------------------------------------------------------------- /Settings.StyleCop: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | False 8 | 9 | 10 | 11 | 12 | False 13 | 14 | 15 | 16 | 17 | False 18 | 19 | 20 | 21 | 22 | False 23 | 24 | 25 | 26 | 27 | False 28 | 29 | 30 | 31 | 32 | False 33 | 34 | 35 | 36 | 37 | False 38 | 39 | 40 | 41 | 42 | False 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | False 52 | 53 | 54 | 55 | 56 | 57 | 58 | -------------------------------------------------------------------------------- /docs/Database-First.md: -------------------------------------------------------------------------------- 1 | Getting Started with ASP.NET Identity and EF DbFirst 2 | ---------------------------------------------------- 3 | 4 | ### 1. Publish ASP.NET Identity Database Project 5 | 6 | SQL Database Project (SSDT): 7 | 8 | > `./src/KriaSoft.AspNet.Identity.Database` 9 | 10 | You can publish it by double-clicking on the `./Publish Profiles/Local.publish.xml` file in the Solution Explorer. 11 | 12 | ### 2. Generate Entity Framework model using EF Designer 13 | 14 | See ASP.NET Identity Database-First model example: 15 | 16 | > `./src/KriaSoft.AspNet.Identity.EntityFramework/Model.edmx` 17 | 18 | ### 3. Copy UserEntity.cs, UserRoleEntity.cs, RoleStore.cs, UserStore.cs and Resources into your project 19 | 20 | > See: `./src/KriaSoft.AspNet.Identity.EntityFramework/` 21 | 22 | And make sure property names in User, UserLogin, UserRole and UserClaim entities match the ones used in RoleStore and UserStore providers. 23 | 24 | ![ASP.NET Identity Model](http://i.imgur.com/KHDqq3B.png) 25 | 26 | ### 4. Done! You can use it like this: 27 | 28 | ```csharp 29 | var db = new ApplicationDbContext(); // your custom EF model 30 | var userManager = new UserManager(new UserStore(db)); 31 | 32 | userManager.CreateUserAsync(new User { UserName = "demouser" }); 33 | ``` 34 | -------------------------------------------------------------------------------- /examples/KriaSoft.AspNet.Identity.DbFirst/KriaSoft.AspNet.Identity.DbFirst.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | 8 | 9 | 2.0 10 | {6F013146-8A52-4B79-9B87-762647CD8600} 11 | {349c5851-65df-11da-9384-00065b846f21};{fae04ec0-301f-11d3-bf4b-00c04f79efbc} 12 | Library 13 | Properties 14 | KriaSoft.AspNet.Identity.DbFirst 15 | KriaSoft.AspNet.Identity.DbFirst 16 | v4.5.1 17 | true 18 | 19 | 20 | 21 | 22 | 23 | 24 | true 25 | full 26 | false 27 | bin\ 28 | DEBUG;TRACE 29 | prompt 30 | 4 31 | 32 | 33 | pdbonly 34 | true 35 | bin\ 36 | TRACE 37 | prompt 38 | 4 39 | 40 | 41 | 42 | ..\..\packages\EntityFramework.6.1.0\lib\net45\EntityFramework.dll 43 | 44 | 45 | ..\..\packages\EntityFramework.6.1.0\lib\net45\EntityFramework.SqlServer.dll 46 | 47 | 48 | ..\..\packages\Microsoft.AspNet.Identity.Core.2.0.0\lib\net45\Microsoft.AspNet.Identity.Core.dll 49 | 50 | 51 | ..\..\packages\Microsoft.AspNet.Identity.Owin.2.0.0\lib\net45\Microsoft.AspNet.Identity.Owin.dll 52 | 53 | 54 | 55 | ..\..\packages\Microsoft.Owin.3.0.0-beta1\lib\net45\Microsoft.Owin.dll 56 | 57 | 58 | ..\..\packages\Microsoft.Owin.Host.SystemWeb.3.0.0-beta1\lib\net45\Microsoft.Owin.Host.SystemWeb.dll 59 | 60 | 61 | ..\..\packages\Microsoft.Owin.Security.2.1.0\lib\net45\Microsoft.Owin.Security.dll 62 | 63 | 64 | ..\..\packages\Microsoft.Owin.Security.Cookies.2.1.0\lib\net45\Microsoft.Owin.Security.Cookies.dll 65 | 66 | 67 | ..\..\packages\Microsoft.Owin.Security.OAuth.2.1.0\lib\net45\Microsoft.Owin.Security.OAuth.dll 68 | 69 | 70 | ..\..\packages\Newtonsoft.Json.4.5.11\lib\net40\Newtonsoft.Json.dll 71 | 72 | 73 | ..\..\packages\Owin.1.0\lib\net40\Owin.dll 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | Designer 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | {311feca9-f3ce-49a7-b085-b9dafa25ca0a} 109 | KriaSoft.AspNet.Identity.EntityFramework 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 10.0 121 | $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | True 131 | True 132 | 59898 133 | / 134 | http://localhost:59898/ 135 | False 136 | False 137 | 138 | 139 | False 140 | 141 | 142 | 143 | 144 | 151 | -------------------------------------------------------------------------------- /examples/KriaSoft.AspNet.Identity.DbFirst/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.InteropServices; 3 | 4 | // General Information about an assembly is controlled through the following 5 | // set of attributes. Change these attribute values to modify the information 6 | // associated with an assembly. 7 | [assembly: AssemblyTitle("KriaSoft.AspNet.Identity.DbFirst")] 8 | [assembly: AssemblyDescription("")] 9 | [assembly: AssemblyConfiguration("")] 10 | [assembly: AssemblyCompany("KriaSoft")] 11 | [assembly: AssemblyProduct("KriaSoft.AspNet.Identity.DbFirst")] 12 | [assembly: AssemblyCopyright("Copyright © 2014 KriaSoft")] 13 | [assembly: AssemblyTrademark("")] 14 | [assembly: AssemblyCulture("")] 15 | 16 | // Setting ComVisible to false makes the types in this assembly not visible 17 | // to COM components. If you need to access a type in this assembly from 18 | // COM, set the ComVisible attribute to true on that type. 19 | [assembly: ComVisible(false)] 20 | 21 | // The following GUID is for the ID of the typelib if this project is exposed to COM 22 | [assembly: Guid("041141b3-d83e-474a-83b8-d14a88e772af")] 23 | 24 | // Version information for an assembly consists of the following four values: 25 | // 26 | // Major Version 27 | // Minor Version 28 | // Build Number 29 | // Revision 30 | // 31 | // You can specify all the values or you can default the Revision and Build Numbers 32 | // by using the '*' as shown below: 33 | [assembly: AssemblyVersion("1.0.0.0")] 34 | [assembly: AssemblyFileVersion("1.0.0.0")] 35 | -------------------------------------------------------------------------------- /examples/KriaSoft.AspNet.Identity.DbFirst/Security/ApplicationOAuthProvider.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Threading.Tasks; 4 | 5 | using Microsoft.AspNet.Identity; 6 | using Microsoft.Owin.Security; 7 | using Microsoft.Owin.Security.Cookies; 8 | using Microsoft.Owin.Security.OAuth; 9 | using KriaSoft.AspNet.Identity.EntityFramework; 10 | 11 | namespace KriaSoft.AspNet.Identity.DbFirst.Security 12 | { 13 | public class ApplicationOAuthProvider : OAuthAuthorizationServerProvider 14 | { 15 | private readonly string publicClientId; 16 | private readonly Func> userManagerFactory; 17 | 18 | public ApplicationOAuthProvider(string publicClientId, Func> userManagerFactory) 19 | { 20 | if (publicClientId == null) 21 | { 22 | throw new ArgumentNullException("publicClientId"); 23 | } 24 | 25 | if (userManagerFactory == null) 26 | { 27 | throw new ArgumentNullException("userManagerFactory"); 28 | } 29 | 30 | this.publicClientId = publicClientId; 31 | this.userManagerFactory = userManagerFactory; 32 | } 33 | 34 | public static AuthenticationProperties CreateProperties(User user) 35 | { 36 | return new AuthenticationProperties(new Dictionary 37 | { 38 | { "userName", user.UserName }, 39 | { "email", user.Email }, 40 | { "emailConfirmed", user.EmailConfirmed.ToString() } 41 | }); 42 | } 43 | 44 | public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context) 45 | { 46 | using (var userManager = this.userManagerFactory()) 47 | { 48 | var user = await userManager.FindAsync(context.UserName, context.Password); 49 | 50 | if (user == null) 51 | { 52 | context.SetError("invalid_grant", "The user name or password is incorrect."); 53 | return; 54 | } 55 | 56 | var oauthIdentity = await userManager.CreateIdentityAsync( 57 | user, context.Options.AuthenticationType); 58 | var cookiesIdentity = await userManager.CreateIdentityAsync( 59 | user, CookieAuthenticationDefaults.AuthenticationType); 60 | var properties = CreateProperties(user); 61 | var ticket = new AuthenticationTicket(oauthIdentity, properties); 62 | context.Validated(ticket); 63 | context.Request.Context.Authentication.SignIn(cookiesIdentity); 64 | } 65 | } 66 | 67 | public override Task TokenEndpoint(OAuthTokenEndpointContext context) 68 | { 69 | foreach (var property in context.Properties.Dictionary) 70 | { 71 | context.AdditionalResponseParameters.Add(property.Key, property.Value); 72 | } 73 | 74 | return Task.FromResult(null); 75 | } 76 | 77 | public override Task ValidateClientAuthentication(OAuthValidateClientAuthenticationContext context) 78 | { 79 | // Resource owner password credentials does not provide a client ID. 80 | if (context.ClientId == null) 81 | { 82 | context.Validated(); 83 | } 84 | 85 | return Task.FromResult(null); 86 | } 87 | 88 | public override Task ValidateClientRedirectUri(OAuthValidateClientRedirectUriContext context) 89 | { 90 | if (context.ClientId == this.publicClientId) 91 | { 92 | var expectedRootUri = new Uri(context.Request.Uri, "/"); 93 | 94 | if (expectedRootUri.AbsoluteUri == context.RedirectUri) 95 | { 96 | context.Validated(); 97 | } 98 | } 99 | 100 | return Task.FromResult(null); 101 | } 102 | } 103 | } -------------------------------------------------------------------------------- /examples/KriaSoft.AspNet.Identity.DbFirst/Startup.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Web; 3 | 4 | using KriaSoft.AspNet.Identity.DbFirst; 5 | using KriaSoft.AspNet.Identity.DbFirst.Security; 6 | using KriaSoft.AspNet.Identity.EntityFramework; 7 | using Microsoft.AspNet.Identity; 8 | using Microsoft.AspNet.Identity.Owin; 9 | using Microsoft.Owin; 10 | using Microsoft.Owin.Security.OAuth; 11 | using Owin; 12 | 13 | [assembly: OwinStartup(typeof(Startup))] 14 | 15 | namespace KriaSoft.AspNet.Identity.DbFirst 16 | { 17 | public class Startup 18 | { 19 | public void Configuration(IAppBuilder app) 20 | { 21 | // Register UserManager in ApplicationDbContext in OWIN context 22 | app.CreatePerOwinContext(() => new ApplicationDbContext()); 23 | app.CreatePerOwinContext>( 24 | (IdentityFactoryOptions> options, IOwinContext context) => 25 | new UserManager(new UserStore(context.Get()))); 26 | 27 | // Enable the application to use bearer tokens to authenticate users 28 | app.UseOAuthBearerTokens(new OAuthAuthorizationServerOptions 29 | { 30 | TokenEndpointPath = new PathString("/token"), 31 | Provider = new ApplicationOAuthProvider( 32 | "self", () => HttpContext.Current.GetOwinContext().GetUserManager>()), 33 | AuthorizeEndpointPath = new PathString("/api/account/authorize"), 34 | AccessTokenExpireTimeSpan = TimeSpan.FromDays(14), 35 | AllowInsecureHttp = true 36 | }); 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /examples/KriaSoft.AspNet.Identity.DbFirst/Web.config: -------------------------------------------------------------------------------- 1 |  2 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /examples/KriaSoft.AspNet.Identity.DbFirst/app.js: -------------------------------------------------------------------------------- 1 | /// 2 | 3 | angular.module('app', ['ngRoute']) 4 | 5 | .config(function ($routeProvider) { 6 | $routeProvider 7 | .when('/', { templateUrl: '/home' }) 8 | .when('/about', { templateUrl: '/about' }) 9 | .when('/page-not-found', { templateUrl: '/page-not-found' }) 10 | .when('/login', { templateUrl: '/login', controller: 'LoginCtrl' }) 11 | .otherwise({ redirectTo: '/page-not-found' }); 12 | }) 13 | 14 | .controller('MainCtrl', function ($scope, $rootScope, $location) { 15 | $scope.logout = function () { 16 | $rootScope.token = null; 17 | $location.path('/'); 18 | }; 19 | }) 20 | 21 | .controller('LoginCtrl', function ($scope, $rootScope, $http, $location) { 22 | 23 | // Sample credentials 24 | $scope.username = 'user'; 25 | $scope.password = 'Passw0rd'; 26 | 27 | $scope.login = function (username, password) { 28 | $http({ 29 | method: 'POST', 30 | url: '/token', 31 | data: 'grant_type=password&username=' + encodeURIComponent(username) + 32 | '&password=' + encodeURIComponent(password), 33 | headers: { 'Content-Type': 'application/x-www-form-urlencoded' } 34 | }).success(function (data) { 35 | $rootScope.token = data; 36 | $location.path('/'); 37 | }); 38 | }; 39 | }); -------------------------------------------------------------------------------- /examples/KriaSoft.AspNet.Identity.DbFirst/index.html: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | ASP.NET Identity Demo 7 | 8 | 9 | 10 | 11 | 12 | 13 | 16 | 17 | 35 | 36 |
37 | 38 | 43 | 44 | 48 | 49 | 54 | 55 | 78 | 79 | 80 | 81 | 82 | 83 | -------------------------------------------------------------------------------- /examples/KriaSoft.AspNet.Identity.DbFirst/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /src/KriaSoft.AspNet.Identity.Database/KriaSoft.AspNet.Identity.Database.sqlproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | KriaSoft.AspNet.Identity.Database 8 | 2.0 9 | 4.1 10 | {c77afcbd-25b7-4500-92dc-1248edd6a89e} 11 | Microsoft.Data.Tools.Schema.Sql.Sql110DatabaseSchemaProvider 12 | Database 13 | 14 | 15 | KriaSoft.AspNet.Identity.Database 16 | KriaSoft.AspNet.Identity.Database 17 | 1033, CI 18 | BySchemaAndSchemaType 19 | True 20 | v4.5.1 21 | CS 22 | Properties 23 | False 24 | True 25 | True 26 | 27 | 28 | bin\Release\ 29 | $(MSBuildProjectName).sql 30 | False 31 | pdbonly 32 | true 33 | false 34 | true 35 | prompt 36 | 4 37 | 38 | 39 | bin\Debug\ 40 | $(MSBuildProjectName).sql 41 | false 42 | true 43 | full 44 | false 45 | true 46 | true 47 | prompt 48 | 4 49 | 50 | 51 | 11.0 52 | 53 | True 54 | 11.0 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | -------------------------------------------------------------------------------- /src/KriaSoft.AspNet.Identity.Database/Publish Profiles/Local.publish.xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | True 5 | AspNetIdentity 6 | Database.sql 7 | Data Source=(LocalDb)\v11.0;Integrated Security=True;Pooling=False;Connect Timeout=30 8 | True 9 | True 10 | 1 11 | 12 | -------------------------------------------------------------------------------- /src/KriaSoft.AspNet.Identity.Database/Reference Data/User.sql: -------------------------------------------------------------------------------- 1 | SET IDENTITY_INSERT [dbo].[User] ON; 2 | GO 3 | 4 | MERGE INTO [dbo].[User] AS Target 5 | USING (VALUES 6 | 7 | (1, N'admin', N'admin@example.com', 0, N'ACe+kHUdH61ms8NbkXSCXyV34CEP7tjfj93JrtlKRPfShGurFdAujQrmbVA7J9MDbg==', 8 | N'9771f91d-b4a0-45e0-8971-899b907c5863', NULL, 0, 0, NULL, 0, 0), 9 | (2, N'user', N'user@example.com', 0, N'ACe+kHUdH61ms8NbkXSCXyV34CEP7tjfj93JrtlKRPfShGurFdAujQrmbVA7J9MDbg==', 10 | N'9771f91d-b4a0-45e0-8971-899b907c5863', NULL, 0, 0, NULL, 0, 0) 11 | 12 | ) AS Source ( 13 | [UserID], 14 | [UserName], 15 | [Email], 16 | [EmailConfirmed], 17 | [PasswordHash], 18 | [SecurityStamp], 19 | [PhoneNumber], 20 | [PhoneNumberConfirmed], 21 | [TwoFactorEnabled], 22 | [LockoutEndDateUtc], 23 | [LockoutEnabled], 24 | [AccessFailedCount] 25 | ) 26 | ON Target.[UserID] = Source.[UserID] 27 | -- Update matched rows 28 | WHEN MATCHED THEN 29 | UPDATE SET 30 | [UserName] = Source.[UserName], 31 | [Email] = Source.[Email], 32 | [EmailConfirmed] = Source.[EmailConfirmed], 33 | [PasswordHash] = Source.[PasswordHash], 34 | [SecurityStamp] = Source.[SecurityStamp], 35 | [PhoneNumber] = Source.[PhoneNumber], 36 | [PhoneNumberConfirmed] = Source.[PhoneNumberConfirmed], 37 | [TwoFactorEnabled] = Source.[TwoFactorEnabled], 38 | [LockoutEndDateUtc] = Source.[LockoutEndDateUtc], 39 | [LockoutEnabled] = Source.[LockoutEnabled], 40 | [AccessFailedCount] = Source.[AccessFailedCount] 41 | -- Insert new rows 42 | WHEN NOT MATCHED BY TARGET THEN 43 | INSERT ( 44 | [UserID], 45 | [UserName], 46 | [Email], 47 | [EmailConfirmed], 48 | [PasswordHash], 49 | [SecurityStamp], 50 | [PhoneNumber], 51 | [PhoneNumberConfirmed], 52 | [TwoFactorEnabled], 53 | [LockoutEndDateUtc], 54 | [LockoutEnabled], 55 | [AccessFailedCount] 56 | ) 57 | VALUES ( 58 | [UserID], 59 | [UserName], 60 | [Email], 61 | [EmailConfirmed], 62 | [PasswordHash], 63 | [SecurityStamp], 64 | [PhoneNumber], 65 | [PhoneNumberConfirmed], 66 | [TwoFactorEnabled], 67 | [LockoutEndDateUtc], 68 | [LockoutEnabled], 69 | [AccessFailedCount] 70 | ); 71 | GO 72 | 73 | SET IDENTITY_INSERT [dbo].[User] OFF; 74 | GO -------------------------------------------------------------------------------- /src/KriaSoft.AspNet.Identity.Database/Reference Data/UserRole.sql: -------------------------------------------------------------------------------- 1 | MERGE INTO [dbo].[UserRole] AS Target 2 | USING (VALUES 3 | 4 | (1, N'Administrator'), 5 | (2, N'Moderator') 6 | 7 | ) AS Source ([RoleID], [Name]) 8 | ON Target.[RoleID] = Source.[RoleID] 9 | -- Update matched rows 10 | WHEN MATCHED THEN 11 | UPDATE SET [Name] = Source.[Name] 12 | -- Insert new rows 13 | WHEN NOT MATCHED BY TARGET THEN 14 | INSERT ([RoleID], [Name]) 15 | VALUES ([RoleID], [Name]) 16 | -- Delete rows that are in the target but not the source 17 | WHEN NOT MATCHED BY SOURCE THEN 18 | DELETE; 19 | GO -------------------------------------------------------------------------------- /src/KriaSoft.AspNet.Identity.Database/Reference Data/UserUserRole.sql: -------------------------------------------------------------------------------- 1 | MERGE INTO [dbo].[UserUserRole] AS Target 2 | USING (VALUES 3 | 4 | (1, 1) 5 | 6 | ) AS Source ([UserID], [RoleID]) 7 | ON Target.[UserID] = Source.[UserID] AND Target.[RoleID] = Source.[RoleID] 8 | WHEN NOT MATCHED BY TARGET THEN 9 | -- Insert new rows 10 | INSERT ([UserID], [RoleID]) 11 | VALUES ([UserID], [RoleID]); 12 | GO -------------------------------------------------------------------------------- /src/KriaSoft.AspNet.Identity.Database/Scripts/PostDeployment.sql: -------------------------------------------------------------------------------- 1 | /* 2 | Post-Deployment Script Template 3 | -------------------------------------------------------------------------------------- 4 | This file contains SQL statements that will be appended to the build script. 5 | Use SQLCMD syntax to include a file in the post-deployment script. 6 | Example: :r .\myfile.sql 7 | Use SQLCMD syntax to reference a variable in the post-deployment script. 8 | Example: :setvar TableName MyTable 9 | SELECT * FROM [$(TableName)] 10 | -------------------------------------------------------------------------------------- 11 | */ 12 | 13 | :r "..\Reference Data\User.sql" 14 | :r "..\Reference Data\UserRole.sql" 15 | :r "..\Reference Data\UserUserRole.sql" 16 | -------------------------------------------------------------------------------- /src/KriaSoft.AspNet.Identity.Database/Tables/User.sql: -------------------------------------------------------------------------------- 1 | CREATE TABLE [dbo].[User] 2 | ( 3 | [UserID] INT IDENTITY (1000, 1) NOT NULL, 4 | [UserName] [dbo].[Name] NOT NULL, 5 | [Email] [dbo].[Email] NULL, 6 | [EmailConfirmed] [dbo].[Flag] NOT NULL, 7 | [PasswordHash] NVARCHAR (100) NULL, 8 | [SecurityStamp] NVARCHAR (100) NULL, 9 | [PhoneNumber] [dbo].[Phone] NULL, 10 | [PhoneNumberConfirmed] [dbo].[Flag] NOT NULL, 11 | [TwoFactorEnabled] [dbo].[Flag] NOT NULL, 12 | [LockoutEndDateUtc] DATETIME NULL, 13 | [LockoutEnabled] [dbo].[Flag] NOT NULL, 14 | [AccessFailedCount] INT NOT NULL, 15 | 16 | CONSTRAINT [PK_User_UserID] PRIMARY KEY CLUSTERED ([UserID] ASC), 17 | CONSTRAINT [UK_User_UserName] UNIQUE NONCLUSTERED ([UserName] ASC) 18 | ); 19 | -------------------------------------------------------------------------------- /src/KriaSoft.AspNet.Identity.Database/Tables/UserClaim.sql: -------------------------------------------------------------------------------- 1 | CREATE TABLE [dbo].[UserClaim] 2 | ( 3 | [UserID] INT NOT NULL, 4 | [ClaimID] INT IDENTITY (1000,1) NOT NULL, 5 | [ClaimType] NVARCHAR (MAX) NULL, 6 | [ClaimValue] NVARCHAR (MAX) NULL, 7 | 8 | CONSTRAINT [PK_UserClaim_ClaimID] PRIMARY KEY CLUSTERED ([ClaimID] ASC), 9 | CONSTRAINT [FK_UserClaim_User] FOREIGN KEY ([UserID]) REFERENCES [dbo].[User] ([UserID]) ON DELETE CASCADE 10 | ); 11 | 12 | GO 13 | CREATE NONCLUSTERED INDEX [IX_UserClaim_UserID] 14 | ON [dbo].[UserClaim] ([UserID] ASC); -------------------------------------------------------------------------------- /src/KriaSoft.AspNet.Identity.Database/Tables/UserLogin.sql: -------------------------------------------------------------------------------- 1 | CREATE TABLE [dbo].[UserLogin] 2 | ( 3 | [UserID] INT NOT NULL, 4 | [LoginProvider] NVARCHAR (128) NOT NULL, 5 | [ProviderKey] NVARCHAR (128) NOT NULL, 6 | 7 | CONSTRAINT [PK_UserLogin_UserID_LoginProvider_ProviderKey] PRIMARY KEY CLUSTERED ([UserID] ASC, [LoginProvider] ASC, [ProviderKey] ASC), 8 | CONSTRAINT [FK_UserLogin_User] FOREIGN KEY ([UserID]) REFERENCES [dbo].[User] ([UserID]) ON DELETE CASCADE 9 | ); 10 | 11 | GO 12 | CREATE NONCLUSTERED INDEX [IX_UserLogin_UserID] 13 | ON [dbo].[UserLogin] ([UserID] ASC); 14 | -------------------------------------------------------------------------------- /src/KriaSoft.AspNet.Identity.Database/Tables/UserRole.sql: -------------------------------------------------------------------------------- 1 | CREATE TABLE [dbo].[UserRole] 2 | ( 3 | [RoleID] INT NOT NULL, 4 | [Name] [dbo].[Name] NOT NULL, 5 | 6 | CONSTRAINT [PK_UserRole_RoleID] PRIMARY KEY CLUSTERED ([RoleID] ASC), 7 | CONSTRAINT [UK_UserRole_Name] UNIQUE NONCLUSTERED ([Name] ASC) 8 | ); 9 | -------------------------------------------------------------------------------- /src/KriaSoft.AspNet.Identity.Database/Tables/UserUserRole.sql: -------------------------------------------------------------------------------- 1 | CREATE TABLE [dbo].[UserUserRole] 2 | ( 3 | [UserID] INT NOT NULL, 4 | [RoleID] INT NOT NULL, 5 | 6 | CONSTRAINT [PK_UserUserRole_UserID_RoleID] PRIMARY KEY CLUSTERED ([UserID] ASC, [RoleID] ASC), 7 | CONSTRAINT [FK_UserUserRole_User] FOREIGN KEY ([UserID]) REFERENCES [dbo].[User] ([UserID]) ON DELETE CASCADE, 8 | CONSTRAINT [FK_UserUserRole_UserRole] FOREIGN KEY ([RoleID]) REFERENCES [dbo].[UserRole] ([RoleID]) ON DELETE CASCADE 9 | ); 10 | 11 | GO 12 | CREATE NONCLUSTERED INDEX [IX_UserUserRole_UserID] 13 | ON [dbo].[UserUserRole] ([UserID] ASC); 14 | 15 | GO 16 | CREATE NONCLUSTERED INDEX [IX_UserUserRole_RoleID] 17 | ON [dbo].[UserUserRole] ([RoleID] ASC); 18 | -------------------------------------------------------------------------------- /src/KriaSoft.AspNet.Identity.Database/User Defined Types/Email.sql: -------------------------------------------------------------------------------- 1 | CREATE TYPE [dbo].[Email] 2 | FROM NVARCHAR (100) NULL; 3 | -------------------------------------------------------------------------------- /src/KriaSoft.AspNet.Identity.Database/User Defined Types/Flag.sql: -------------------------------------------------------------------------------- 1 | CREATE TYPE [dbo].[Flag] 2 | FROM BIT NOT NULL; 3 | -------------------------------------------------------------------------------- /src/KriaSoft.AspNet.Identity.Database/User Defined Types/Name.sql: -------------------------------------------------------------------------------- 1 | CREATE TYPE [dbo].[Name] 2 | FROM NVARCHAR (50) NOT NULL; 3 | -------------------------------------------------------------------------------- /src/KriaSoft.AspNet.Identity.Database/User Defined Types/Phone.sql: -------------------------------------------------------------------------------- 1 | CREATE TYPE [dbo].[Phone] 2 | FROM NVARCHAR (25) NULL; 3 | -------------------------------------------------------------------------------- /src/KriaSoft.AspNet.Identity.EntityFramework/App.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /src/KriaSoft.AspNet.Identity.EntityFramework/KriaSoft.AspNet.Identity.EntityFramework.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {311FECA9-F3CE-49A7-B085-B9DAFA25CA0A} 8 | Library 9 | Properties 10 | KriaSoft.AspNet.Identity.EntityFramework 11 | KriaSoft.AspNet.Identity.EntityFramework 12 | v4.5.1 13 | 512 14 | 15 | 16 | true 17 | full 18 | false 19 | bin\Debug\ 20 | DEBUG;TRACE 21 | prompt 22 | 4 23 | 24 | 25 | pdbonly 26 | true 27 | bin\Release\ 28 | TRACE 29 | prompt 30 | 4 31 | 32 | 33 | 34 | ..\..\packages\EntityFramework.6.1.0\lib\net45\EntityFramework.dll 35 | 36 | 37 | ..\..\packages\EntityFramework.6.1.0\lib\net45\EntityFramework.SqlServer.dll 38 | 39 | 40 | ..\..\packages\Microsoft.AspNet.Identity.Core.2.0.0\lib\net45\Microsoft.AspNet.Identity.Core.dll 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | True 56 | True 57 | Model.Context.tt 58 | 59 | 60 | True 61 | True 62 | Model.tt 63 | 64 | 65 | True 66 | True 67 | Model.edmx 68 | 69 | 70 | 71 | True 72 | True 73 | Resources.resx 74 | 75 | 76 | 77 | Model.tt 78 | 79 | 80 | Model.tt 81 | 82 | 83 | 84 | 85 | Model.tt 86 | 87 | 88 | Model.tt 89 | 90 | 91 | 92 | 93 | 94 | 95 | EntityModelCodeGenerator 96 | Model.Designer.cs 97 | 98 | 99 | TextTemplatingFileGenerator 100 | Model.edmx 101 | Model.Context.cs 102 | 103 | 104 | Model.edmx 105 | 106 | 107 | TextTemplatingFileGenerator 108 | Model.edmx 109 | Model.cs 110 | 111 | 112 | 113 | 114 | 115 | ResXFileCodeGenerator 116 | Resources.Designer.cs 117 | 118 | 119 | 120 | 121 | 122 | 123 | 130 | -------------------------------------------------------------------------------- /src/KriaSoft.AspNet.Identity.EntityFramework/Model.Context.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // This code was generated from a template. 4 | // 5 | // Manual changes to this file may cause unexpected behavior in your application. 6 | // Manual changes to this file will be overwritten if the code is regenerated. 7 | // 8 | //------------------------------------------------------------------------------ 9 | 10 | namespace KriaSoft.AspNet.Identity.EntityFramework 11 | { 12 | using System; 13 | using System.Data.Entity; 14 | using System.Data.Entity.Infrastructure; 15 | 16 | public partial class ApplicationDbContext : DbContext 17 | { 18 | public ApplicationDbContext() 19 | : base("name=ApplicationDbContext") 20 | { 21 | } 22 | 23 | protected override void OnModelCreating(DbModelBuilder modelBuilder) 24 | { 25 | throw new UnintentionalCodeFirstException(); 26 | } 27 | 28 | public virtual DbSet Users { get; set; } 29 | public virtual DbSet UserClaims { get; set; } 30 | public virtual DbSet UserLogins { get; set; } 31 | public virtual DbSet UserRoles { get; set; } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/KriaSoft.AspNet.Identity.EntityFramework/Model.Context.tt: -------------------------------------------------------------------------------- 1 | <#@ template language="C#" debug="false" hostspecific="true"#> 2 | <#@ include file="EF6.Utility.CS.ttinclude"#><#@ 3 | output extension=".cs"#><# 4 | 5 | const string inputFile = @"Model.edmx"; 6 | var textTransform = DynamicTextTransformation.Create(this); 7 | var code = new CodeGenerationTools(this); 8 | var ef = new MetadataTools(this); 9 | var typeMapper = new TypeMapper(code, ef, textTransform.Errors); 10 | var loader = new EdmMetadataLoader(textTransform.Host, textTransform.Errors); 11 | var itemCollection = loader.CreateEdmItemCollection(inputFile); 12 | var modelNamespace = loader.GetModelNamespace(inputFile); 13 | var codeStringGenerator = new CodeStringGenerator(code, typeMapper, ef); 14 | 15 | var container = itemCollection.OfType().FirstOrDefault(); 16 | if (container == null) 17 | { 18 | return string.Empty; 19 | } 20 | #> 21 | //------------------------------------------------------------------------------ 22 | // 23 | // <#=CodeGenerationTools.GetResourceString("Template_GeneratedCodeCommentLine1")#> 24 | // 25 | // <#=CodeGenerationTools.GetResourceString("Template_GeneratedCodeCommentLine2")#> 26 | // <#=CodeGenerationTools.GetResourceString("Template_GeneratedCodeCommentLine3")#> 27 | // 28 | //------------------------------------------------------------------------------ 29 | 30 | <# 31 | 32 | var codeNamespace = code.VsNamespaceSuggestion(); 33 | if (!String.IsNullOrEmpty(codeNamespace)) 34 | { 35 | #> 36 | namespace <#=code.EscapeNamespace(codeNamespace)#> 37 | { 38 | <# 39 | PushIndent(" "); 40 | } 41 | 42 | #> 43 | using System; 44 | using System.Data.Entity; 45 | using System.Data.Entity.Infrastructure; 46 | <# 47 | if (container.FunctionImports.Any()) 48 | { 49 | #> 50 | using System.Data.Entity.Core.Objects; 51 | using System.Linq; 52 | <# 53 | } 54 | #> 55 | 56 | <#=Accessibility.ForType(container)#> partial class <#=code.Escape(container)#> : DbContext 57 | { 58 | public <#=code.Escape(container)#>() 59 | : base("name=<#=container.Name#>") 60 | { 61 | <# 62 | if (!loader.IsLazyLoadingEnabled(container)) 63 | { 64 | #> 65 | this.Configuration.LazyLoadingEnabled = false; 66 | <# 67 | } 68 | 69 | foreach (var entitySet in container.BaseEntitySets.OfType()) 70 | { 71 | // Note: the DbSet members are defined below such that the getter and 72 | // setter always have the same accessibility as the DbSet definition 73 | if (Accessibility.ForReadOnlyProperty(entitySet) != "public") 74 | { 75 | #> 76 | <#=codeStringGenerator.DbSetInitializer(entitySet)#> 77 | <# 78 | } 79 | } 80 | #> 81 | } 82 | 83 | protected override void OnModelCreating(DbModelBuilder modelBuilder) 84 | { 85 | throw new UnintentionalCodeFirstException(); 86 | } 87 | 88 | <# 89 | foreach (var entitySet in container.BaseEntitySets.OfType()) 90 | { 91 | #> 92 | <#=codeStringGenerator.DbSet(entitySet)#> 93 | <# 94 | } 95 | 96 | foreach (var edmFunction in container.FunctionImports) 97 | { 98 | WriteFunctionImport(typeMapper, codeStringGenerator, edmFunction, modelNamespace, includeMergeOption: false); 99 | } 100 | #> 101 | } 102 | <# 103 | 104 | if (!String.IsNullOrEmpty(codeNamespace)) 105 | { 106 | PopIndent(); 107 | #> 108 | } 109 | <# 110 | } 111 | #> 112 | <#+ 113 | 114 | private void WriteFunctionImport(TypeMapper typeMapper, CodeStringGenerator codeStringGenerator, EdmFunction edmFunction, string modelNamespace, bool includeMergeOption) 115 | { 116 | if (typeMapper.IsComposable(edmFunction)) 117 | { 118 | #> 119 | 120 | [DbFunction("<#=edmFunction.NamespaceName#>", "<#=edmFunction.Name#>")] 121 | <#=codeStringGenerator.ComposableFunctionMethod(edmFunction, modelNamespace)#> 122 | { 123 | <#+ 124 | codeStringGenerator.WriteFunctionParameters(edmFunction, WriteFunctionParameter); 125 | #> 126 | <#=codeStringGenerator.ComposableCreateQuery(edmFunction, modelNamespace)#> 127 | } 128 | <#+ 129 | } 130 | else 131 | { 132 | #> 133 | 134 | <#=codeStringGenerator.FunctionMethod(edmFunction, modelNamespace, includeMergeOption)#> 135 | { 136 | <#+ 137 | codeStringGenerator.WriteFunctionParameters(edmFunction, WriteFunctionParameter); 138 | #> 139 | <#=codeStringGenerator.ExecuteFunction(edmFunction, modelNamespace, includeMergeOption)#> 140 | } 141 | <#+ 142 | if (typeMapper.GenerateMergeOptionFunction(edmFunction, includeMergeOption)) 143 | { 144 | WriteFunctionImport(typeMapper, codeStringGenerator, edmFunction, modelNamespace, includeMergeOption: true); 145 | } 146 | } 147 | } 148 | 149 | public void WriteFunctionParameter(string name, string isNotNull, string notNullInit, string nullInit) 150 | { 151 | #> 152 | var <#=name#> = <#=isNotNull#> ? 153 | <#=notNullInit#> : 154 | <#=nullInit#>; 155 | 156 | <#+ 157 | } 158 | 159 | public const string TemplateId = "CSharp_DbContext_Context_EF6"; 160 | 161 | public class CodeStringGenerator 162 | { 163 | private readonly CodeGenerationTools _code; 164 | private readonly TypeMapper _typeMapper; 165 | private readonly MetadataTools _ef; 166 | 167 | public CodeStringGenerator(CodeGenerationTools code, TypeMapper typeMapper, MetadataTools ef) 168 | { 169 | ArgumentNotNull(code, "code"); 170 | ArgumentNotNull(typeMapper, "typeMapper"); 171 | ArgumentNotNull(ef, "ef"); 172 | 173 | _code = code; 174 | _typeMapper = typeMapper; 175 | _ef = ef; 176 | } 177 | 178 | public string Property(EdmProperty edmProperty) 179 | { 180 | return string.Format( 181 | CultureInfo.InvariantCulture, 182 | "{0} {1} {2} {{ {3}get; {4}set; }}", 183 | Accessibility.ForProperty(edmProperty), 184 | _typeMapper.GetTypeName(edmProperty.TypeUsage), 185 | _code.Escape(edmProperty), 186 | _code.SpaceAfter(Accessibility.ForGetter(edmProperty)), 187 | _code.SpaceAfter(Accessibility.ForSetter(edmProperty))); 188 | } 189 | 190 | public string NavigationProperty(NavigationProperty navProp) 191 | { 192 | var endType = _typeMapper.GetTypeName(navProp.ToEndMember.GetEntityType()); 193 | return string.Format( 194 | CultureInfo.InvariantCulture, 195 | "{0} {1} {2} {{ {3}get; {4}set; }}", 196 | AccessibilityAndVirtual(Accessibility.ForNavigationProperty(navProp)), 197 | navProp.ToEndMember.RelationshipMultiplicity == RelationshipMultiplicity.Many ? ("ICollection<" + endType + ">") : endType, 198 | _code.Escape(navProp), 199 | _code.SpaceAfter(Accessibility.ForGetter(navProp)), 200 | _code.SpaceAfter(Accessibility.ForSetter(navProp))); 201 | } 202 | 203 | public string AccessibilityAndVirtual(string accessibility) 204 | { 205 | return accessibility + (accessibility != "private" ? " virtual" : ""); 206 | } 207 | 208 | public string EntityClassOpening(EntityType entity) 209 | { 210 | return string.Format( 211 | CultureInfo.InvariantCulture, 212 | "{0} {1}partial class {2}{3}", 213 | Accessibility.ForType(entity), 214 | _code.SpaceAfter(_code.AbstractOption(entity)), 215 | _code.Escape(entity), 216 | _code.StringBefore(" : ", _typeMapper.GetTypeName(entity.BaseType))); 217 | } 218 | 219 | public string EnumOpening(SimpleType enumType) 220 | { 221 | return string.Format( 222 | CultureInfo.InvariantCulture, 223 | "{0} enum {1} : {2}", 224 | Accessibility.ForType(enumType), 225 | _code.Escape(enumType), 226 | _code.Escape(_typeMapper.UnderlyingClrType(enumType))); 227 | } 228 | 229 | public void WriteFunctionParameters(EdmFunction edmFunction, Action writeParameter) 230 | { 231 | var parameters = FunctionImportParameter.Create(edmFunction.Parameters, _code, _ef); 232 | foreach (var parameter in parameters.Where(p => p.NeedsLocalVariable)) 233 | { 234 | var isNotNull = parameter.IsNullableOfT ? parameter.FunctionParameterName + ".HasValue" : parameter.FunctionParameterName + " != null"; 235 | var notNullInit = "new ObjectParameter(\"" + parameter.EsqlParameterName + "\", " + parameter.FunctionParameterName + ")"; 236 | var nullInit = "new ObjectParameter(\"" + parameter.EsqlParameterName + "\", typeof(" + TypeMapper.FixNamespaces(parameter.RawClrTypeName) + "))"; 237 | writeParameter(parameter.LocalVariableName, isNotNull, notNullInit, nullInit); 238 | } 239 | } 240 | 241 | public string ComposableFunctionMethod(EdmFunction edmFunction, string modelNamespace) 242 | { 243 | var parameters = _typeMapper.GetParameters(edmFunction); 244 | 245 | return string.Format( 246 | CultureInfo.InvariantCulture, 247 | "{0} IQueryable<{1}> {2}({3})", 248 | AccessibilityAndVirtual(Accessibility.ForMethod(edmFunction)), 249 | _typeMapper.GetTypeName(_typeMapper.GetReturnType(edmFunction), modelNamespace), 250 | _code.Escape(edmFunction), 251 | string.Join(", ", parameters.Select(p => TypeMapper.FixNamespaces(p.FunctionParameterType) + " " + p.FunctionParameterName).ToArray())); 252 | } 253 | 254 | public string ComposableCreateQuery(EdmFunction edmFunction, string modelNamespace) 255 | { 256 | var parameters = _typeMapper.GetParameters(edmFunction); 257 | 258 | return string.Format( 259 | CultureInfo.InvariantCulture, 260 | "return ((IObjectContextAdapter)this).ObjectContext.CreateQuery<{0}>(\"[{1}].[{2}]({3})\"{4});", 261 | _typeMapper.GetTypeName(_typeMapper.GetReturnType(edmFunction), modelNamespace), 262 | edmFunction.NamespaceName, 263 | edmFunction.Name, 264 | string.Join(", ", parameters.Select(p => "@" + p.EsqlParameterName).ToArray()), 265 | _code.StringBefore(", ", string.Join(", ", parameters.Select(p => p.ExecuteParameterName).ToArray()))); 266 | } 267 | 268 | public string FunctionMethod(EdmFunction edmFunction, string modelNamespace, bool includeMergeOption) 269 | { 270 | var parameters = _typeMapper.GetParameters(edmFunction); 271 | var returnType = _typeMapper.GetReturnType(edmFunction); 272 | 273 | var paramList = String.Join(", ", parameters.Select(p => TypeMapper.FixNamespaces(p.FunctionParameterType) + " " + p.FunctionParameterName).ToArray()); 274 | if (includeMergeOption) 275 | { 276 | paramList = _code.StringAfter(paramList, ", ") + "MergeOption mergeOption"; 277 | } 278 | 279 | return string.Format( 280 | CultureInfo.InvariantCulture, 281 | "{0} {1} {2}({3})", 282 | AccessibilityAndVirtual(Accessibility.ForMethod(edmFunction)), 283 | returnType == null ? "int" : "ObjectResult<" + _typeMapper.GetTypeName(returnType, modelNamespace) + ">", 284 | _code.Escape(edmFunction), 285 | paramList); 286 | } 287 | 288 | public string ExecuteFunction(EdmFunction edmFunction, string modelNamespace, bool includeMergeOption) 289 | { 290 | var parameters = _typeMapper.GetParameters(edmFunction); 291 | var returnType = _typeMapper.GetReturnType(edmFunction); 292 | 293 | var callParams = _code.StringBefore(", ", String.Join(", ", parameters.Select(p => p.ExecuteParameterName).ToArray())); 294 | if (includeMergeOption) 295 | { 296 | callParams = ", mergeOption" + callParams; 297 | } 298 | 299 | return string.Format( 300 | CultureInfo.InvariantCulture, 301 | "return ((IObjectContextAdapter)this).ObjectContext.ExecuteFunction{0}(\"{1}\"{2});", 302 | returnType == null ? "" : "<" + _typeMapper.GetTypeName(returnType, modelNamespace) + ">", 303 | edmFunction.Name, 304 | callParams); 305 | } 306 | 307 | public string DbSet(EntitySet entitySet) 308 | { 309 | return string.Format( 310 | CultureInfo.InvariantCulture, 311 | "{0} virtual DbSet<{1}> {2} {{ get; set; }}", 312 | Accessibility.ForReadOnlyProperty(entitySet), 313 | _typeMapper.GetTypeName(entitySet.ElementType), 314 | _code.Escape(entitySet)); 315 | } 316 | 317 | public string DbSetInitializer(EntitySet entitySet) 318 | { 319 | return string.Format( 320 | CultureInfo.InvariantCulture, 321 | "{0} = Set<{1}>();", 322 | _code.Escape(entitySet), 323 | _typeMapper.GetTypeName(entitySet.ElementType)); 324 | } 325 | 326 | public string UsingDirectives(bool inHeader, bool includeCollections = true) 327 | { 328 | return inHeader == string.IsNullOrEmpty(_code.VsNamespaceSuggestion()) 329 | ? string.Format( 330 | CultureInfo.InvariantCulture, 331 | "{0}using System;{1}" + 332 | "{2}", 333 | inHeader ? Environment.NewLine : "", 334 | includeCollections ? (Environment.NewLine + "using System.Collections.Generic;") : "", 335 | inHeader ? "" : Environment.NewLine) 336 | : ""; 337 | } 338 | } 339 | 340 | public class TypeMapper 341 | { 342 | private const string ExternalTypeNameAttributeName = @"http://schemas.microsoft.com/ado/2006/04/codegeneration:ExternalTypeName"; 343 | 344 | private readonly System.Collections.IList _errors; 345 | private readonly CodeGenerationTools _code; 346 | private readonly MetadataTools _ef; 347 | 348 | public static string FixNamespaces(string typeName) 349 | { 350 | return typeName.Replace("System.Data.Spatial.", "System.Data.Entity.Spatial."); 351 | } 352 | 353 | public TypeMapper(CodeGenerationTools code, MetadataTools ef, System.Collections.IList errors) 354 | { 355 | ArgumentNotNull(code, "code"); 356 | ArgumentNotNull(ef, "ef"); 357 | ArgumentNotNull(errors, "errors"); 358 | 359 | _code = code; 360 | _ef = ef; 361 | _errors = errors; 362 | } 363 | 364 | public string GetTypeName(TypeUsage typeUsage) 365 | { 366 | return typeUsage == null ? null : GetTypeName(typeUsage.EdmType, _ef.IsNullable(typeUsage), modelNamespace: null); 367 | } 368 | 369 | public string GetTypeName(EdmType edmType) 370 | { 371 | return GetTypeName(edmType, isNullable: null, modelNamespace: null); 372 | } 373 | 374 | public string GetTypeName(TypeUsage typeUsage, string modelNamespace) 375 | { 376 | return typeUsage == null ? null : GetTypeName(typeUsage.EdmType, _ef.IsNullable(typeUsage), modelNamespace); 377 | } 378 | 379 | public string GetTypeName(EdmType edmType, string modelNamespace) 380 | { 381 | return GetTypeName(edmType, isNullable: null, modelNamespace: modelNamespace); 382 | } 383 | 384 | public string GetTypeName(EdmType edmType, bool? isNullable, string modelNamespace) 385 | { 386 | if (edmType == null) 387 | { 388 | return null; 389 | } 390 | 391 | var collectionType = edmType as CollectionType; 392 | if (collectionType != null) 393 | { 394 | return String.Format(CultureInfo.InvariantCulture, "ICollection<{0}>", GetTypeName(collectionType.TypeUsage, modelNamespace)); 395 | } 396 | 397 | var typeName = _code.Escape(edmType.MetadataProperties 398 | .Where(p => p.Name == ExternalTypeNameAttributeName) 399 | .Select(p => (string)p.Value) 400 | .FirstOrDefault()) 401 | ?? (modelNamespace != null && edmType.NamespaceName != modelNamespace ? 402 | _code.CreateFullName(_code.EscapeNamespace(edmType.NamespaceName), _code.Escape(edmType)) : 403 | _code.Escape(edmType)); 404 | 405 | if (edmType is StructuralType) 406 | { 407 | return typeName; 408 | } 409 | 410 | if (edmType is SimpleType) 411 | { 412 | var clrType = UnderlyingClrType(edmType); 413 | if (!IsEnumType(edmType)) 414 | { 415 | typeName = _code.Escape(clrType); 416 | } 417 | 418 | typeName = FixNamespaces(typeName); 419 | 420 | return clrType.IsValueType && isNullable == true ? 421 | String.Format(CultureInfo.InvariantCulture, "Nullable<{0}>", typeName) : 422 | typeName; 423 | } 424 | 425 | throw new ArgumentException("edmType"); 426 | } 427 | 428 | public Type UnderlyingClrType(EdmType edmType) 429 | { 430 | ArgumentNotNull(edmType, "edmType"); 431 | 432 | var primitiveType = edmType as PrimitiveType; 433 | if (primitiveType != null) 434 | { 435 | return primitiveType.ClrEquivalentType; 436 | } 437 | 438 | if (IsEnumType(edmType)) 439 | { 440 | return GetEnumUnderlyingType(edmType).ClrEquivalentType; 441 | } 442 | 443 | return typeof(object); 444 | } 445 | 446 | public object GetEnumMemberValue(MetadataItem enumMember) 447 | { 448 | ArgumentNotNull(enumMember, "enumMember"); 449 | 450 | var valueProperty = enumMember.GetType().GetProperty("Value"); 451 | return valueProperty == null ? null : valueProperty.GetValue(enumMember, null); 452 | } 453 | 454 | public string GetEnumMemberName(MetadataItem enumMember) 455 | { 456 | ArgumentNotNull(enumMember, "enumMember"); 457 | 458 | var nameProperty = enumMember.GetType().GetProperty("Name"); 459 | return nameProperty == null ? null : (string)nameProperty.GetValue(enumMember, null); 460 | } 461 | 462 | public System.Collections.IEnumerable GetEnumMembers(EdmType enumType) 463 | { 464 | ArgumentNotNull(enumType, "enumType"); 465 | 466 | var membersProperty = enumType.GetType().GetProperty("Members"); 467 | return membersProperty != null 468 | ? (System.Collections.IEnumerable)membersProperty.GetValue(enumType, null) 469 | : Enumerable.Empty(); 470 | } 471 | 472 | public bool EnumIsFlags(EdmType enumType) 473 | { 474 | ArgumentNotNull(enumType, "enumType"); 475 | 476 | var isFlagsProperty = enumType.GetType().GetProperty("IsFlags"); 477 | return isFlagsProperty != null && (bool)isFlagsProperty.GetValue(enumType, null); 478 | } 479 | 480 | public bool IsEnumType(GlobalItem edmType) 481 | { 482 | ArgumentNotNull(edmType, "edmType"); 483 | 484 | return edmType.GetType().Name == "EnumType"; 485 | } 486 | 487 | public PrimitiveType GetEnumUnderlyingType(EdmType enumType) 488 | { 489 | ArgumentNotNull(enumType, "enumType"); 490 | 491 | return (PrimitiveType)enumType.GetType().GetProperty("UnderlyingType").GetValue(enumType, null); 492 | } 493 | 494 | public string CreateLiteral(object value) 495 | { 496 | if (value == null || value.GetType() != typeof(TimeSpan)) 497 | { 498 | return _code.CreateLiteral(value); 499 | } 500 | 501 | return string.Format(CultureInfo.InvariantCulture, "new TimeSpan({0})", ((TimeSpan)value).Ticks); 502 | } 503 | 504 | public bool VerifyCaseInsensitiveTypeUniqueness(IEnumerable types, string sourceFile) 505 | { 506 | ArgumentNotNull(types, "types"); 507 | ArgumentNotNull(sourceFile, "sourceFile"); 508 | 509 | var hash = new HashSet(StringComparer.InvariantCultureIgnoreCase); 510 | if (types.Any(item => !hash.Add(item))) 511 | { 512 | _errors.Add( 513 | new CompilerError(sourceFile, -1, -1, "6023", 514 | String.Format(CultureInfo.CurrentCulture, CodeGenerationTools.GetResourceString("Template_CaseInsensitiveTypeConflict")))); 515 | return false; 516 | } 517 | return true; 518 | } 519 | 520 | public IEnumerable GetEnumItemsToGenerate(IEnumerable itemCollection) 521 | { 522 | return GetItemsToGenerate(itemCollection) 523 | .Where(e => IsEnumType(e)); 524 | } 525 | 526 | public IEnumerable GetItemsToGenerate(IEnumerable itemCollection) where T: EdmType 527 | { 528 | return itemCollection 529 | .OfType() 530 | .Where(i => !i.MetadataProperties.Any(p => p.Name == ExternalTypeNameAttributeName)) 531 | .OrderBy(i => i.Name); 532 | } 533 | 534 | public IEnumerable GetAllGlobalItems(IEnumerable itemCollection) 535 | { 536 | return itemCollection 537 | .Where(i => i is EntityType || i is ComplexType || i is EntityContainer || IsEnumType(i)) 538 | .Select(g => GetGlobalItemName(g)); 539 | } 540 | 541 | public string GetGlobalItemName(GlobalItem item) 542 | { 543 | if (item is EdmType) 544 | { 545 | return ((EdmType)item).Name; 546 | } 547 | else 548 | { 549 | return ((EntityContainer)item).Name; 550 | } 551 | } 552 | 553 | public IEnumerable GetSimpleProperties(EntityType type) 554 | { 555 | return type.Properties.Where(p => p.TypeUsage.EdmType is SimpleType && p.DeclaringType == type); 556 | } 557 | 558 | public IEnumerable GetSimpleProperties(ComplexType type) 559 | { 560 | return type.Properties.Where(p => p.TypeUsage.EdmType is SimpleType && p.DeclaringType == type); 561 | } 562 | 563 | public IEnumerable GetComplexProperties(EntityType type) 564 | { 565 | return type.Properties.Where(p => p.TypeUsage.EdmType is ComplexType && p.DeclaringType == type); 566 | } 567 | 568 | public IEnumerable GetComplexProperties(ComplexType type) 569 | { 570 | return type.Properties.Where(p => p.TypeUsage.EdmType is ComplexType && p.DeclaringType == type); 571 | } 572 | 573 | public IEnumerable GetPropertiesWithDefaultValues(EntityType type) 574 | { 575 | return type.Properties.Where(p => p.TypeUsage.EdmType is SimpleType && p.DeclaringType == type && p.DefaultValue != null); 576 | } 577 | 578 | public IEnumerable GetPropertiesWithDefaultValues(ComplexType type) 579 | { 580 | return type.Properties.Where(p => p.TypeUsage.EdmType is SimpleType && p.DeclaringType == type && p.DefaultValue != null); 581 | } 582 | 583 | public IEnumerable GetNavigationProperties(EntityType type) 584 | { 585 | return type.NavigationProperties.Where(np => np.DeclaringType == type); 586 | } 587 | 588 | public IEnumerable GetCollectionNavigationProperties(EntityType type) 589 | { 590 | return type.NavigationProperties.Where(np => np.DeclaringType == type && np.ToEndMember.RelationshipMultiplicity == RelationshipMultiplicity.Many); 591 | } 592 | 593 | public FunctionParameter GetReturnParameter(EdmFunction edmFunction) 594 | { 595 | ArgumentNotNull(edmFunction, "edmFunction"); 596 | 597 | var returnParamsProperty = edmFunction.GetType().GetProperty("ReturnParameters"); 598 | return returnParamsProperty == null 599 | ? edmFunction.ReturnParameter 600 | : ((IEnumerable)returnParamsProperty.GetValue(edmFunction, null)).FirstOrDefault(); 601 | } 602 | 603 | public bool IsComposable(EdmFunction edmFunction) 604 | { 605 | ArgumentNotNull(edmFunction, "edmFunction"); 606 | 607 | var isComposableProperty = edmFunction.GetType().GetProperty("IsComposableAttribute"); 608 | return isComposableProperty != null && (bool)isComposableProperty.GetValue(edmFunction, null); 609 | } 610 | 611 | public IEnumerable GetParameters(EdmFunction edmFunction) 612 | { 613 | return FunctionImportParameter.Create(edmFunction.Parameters, _code, _ef); 614 | } 615 | 616 | public TypeUsage GetReturnType(EdmFunction edmFunction) 617 | { 618 | var returnParam = GetReturnParameter(edmFunction); 619 | return returnParam == null ? null : _ef.GetElementType(returnParam.TypeUsage); 620 | } 621 | 622 | public bool GenerateMergeOptionFunction(EdmFunction edmFunction, bool includeMergeOption) 623 | { 624 | var returnType = GetReturnType(edmFunction); 625 | return !includeMergeOption && returnType != null && returnType.EdmType.BuiltInTypeKind == BuiltInTypeKind.EntityType; 626 | } 627 | } 628 | 629 | public static void ArgumentNotNull(T arg, string name) where T : class 630 | { 631 | if (arg == null) 632 | { 633 | throw new ArgumentNullException(name); 634 | } 635 | } 636 | #> -------------------------------------------------------------------------------- /src/KriaSoft.AspNet.Identity.EntityFramework/Model.Designer.cs: -------------------------------------------------------------------------------- 1 | // T4 code generation is enabled for model 'C:\Projects\KriaSoft.AspNet.Identity\src\KriaSoft.AspNet.Identity.EntityFramework\Model.edmx'. 2 | // To enable legacy code generation, change the value of the 'Code Generation Strategy' designer 3 | // property to 'Legacy ObjectContext'. This property is available in the Properties Window when the model 4 | // is open in the designer. 5 | 6 | // If no context and entity classes have been generated, it may be because you created an empty model but 7 | // have not yet chosen which version of Entity Framework to use. To generate a context class and entity 8 | // classes for your model, open the model in the designer, right-click on the designer surface, and 9 | // select 'Update Model from Database...', 'Generate Database from Model...', or 'Add Code Generation 10 | // Item...'. -------------------------------------------------------------------------------- /src/KriaSoft.AspNet.Identity.EntityFramework/Model.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // This code was generated from a template. 4 | // 5 | // Manual changes to this file may cause unexpected behavior in your application. 6 | // Manual changes to this file will be overwritten if the code is regenerated. 7 | // 8 | //------------------------------------------------------------------------------ 9 | 10 | -------------------------------------------------------------------------------- /src/KriaSoft.AspNet.Identity.EntityFramework/Model.edmx: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | 243 | 244 | 245 | 246 | 247 | 248 | 249 | 250 | 251 | 252 | 253 | 254 | 255 | 256 | 257 | 258 | 259 | 260 | 261 | 262 | 263 | 264 | 265 | 266 | 267 | 268 | 269 | 270 | 271 | 272 | 273 | 274 | 275 | 276 | 277 | 278 | 279 | 280 | 281 | 282 | 283 | 284 | 285 | 286 | 287 | 288 | 289 | 290 | 291 | 292 | 293 | 294 | 295 | 296 | 297 | 298 | 299 | 300 | 301 | 302 | 303 | 304 | 305 | 306 | 307 | 308 | 309 | 310 | 311 | 312 | 313 | 314 | 315 | 316 | 317 | 318 | 319 | 320 | 321 | 322 | 323 | -------------------------------------------------------------------------------- /src/KriaSoft.AspNet.Identity.EntityFramework/Model.edmx.diagram: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /src/KriaSoft.AspNet.Identity.EntityFramework/Model.tt: -------------------------------------------------------------------------------- 1 | <#@ template language="C#" debug="false" hostspecific="true"#> 2 | <#@ include file="EF6.Utility.CS.ttinclude"#><#@ 3 | output extension=".cs"#><# 4 | 5 | const string inputFile = @"Model.edmx"; 6 | var textTransform = DynamicTextTransformation.Create(this); 7 | var code = new CodeGenerationTools(this); 8 | var ef = new MetadataTools(this); 9 | var typeMapper = new TypeMapper(code, ef, textTransform.Errors); 10 | var fileManager = EntityFrameworkTemplateFileManager.Create(this); 11 | var itemCollection = new EdmMetadataLoader(textTransform.Host, textTransform.Errors).CreateEdmItemCollection(inputFile); 12 | var codeStringGenerator = new CodeStringGenerator(code, typeMapper, ef); 13 | 14 | if (!typeMapper.VerifyCaseInsensitiveTypeUniqueness(typeMapper.GetAllGlobalItems(itemCollection), inputFile)) 15 | { 16 | return string.Empty; 17 | } 18 | 19 | WriteHeader(codeStringGenerator, fileManager); 20 | 21 | foreach (var entity in typeMapper.GetItemsToGenerate(itemCollection)) 22 | { 23 | fileManager.StartNewFile(entity.Name + ".cs"); 24 | BeginNamespace(code); 25 | #> 26 | <#=codeStringGenerator.UsingDirectives(inHeader: false)#> 27 | <#=codeStringGenerator.EntityClassOpening(entity)#> 28 | { 29 | <# 30 | var propertiesWithDefaultValues = typeMapper.GetPropertiesWithDefaultValues(entity); 31 | var collectionNavigationProperties = typeMapper.GetCollectionNavigationProperties(entity); 32 | var complexProperties = typeMapper.GetComplexProperties(entity); 33 | 34 | if (propertiesWithDefaultValues.Any() || collectionNavigationProperties.Any() || complexProperties.Any()) 35 | { 36 | #> 37 | public <#=code.Escape(entity)#>() 38 | { 39 | <# 40 | foreach (var edmProperty in propertiesWithDefaultValues) 41 | { 42 | #> 43 | this.<#=code.Escape(edmProperty)#> = <#=typeMapper.CreateLiteral(edmProperty.DefaultValue)#>; 44 | <# 45 | } 46 | 47 | foreach (var navigationProperty in collectionNavigationProperties) 48 | { 49 | #> 50 | this.<#=code.Escape(navigationProperty)#> = new HashSet<<#=typeMapper.GetTypeName(navigationProperty.ToEndMember.GetEntityType())#>>(); 51 | <# 52 | } 53 | 54 | foreach (var complexProperty in complexProperties) 55 | { 56 | #> 57 | this.<#=code.Escape(complexProperty)#> = new <#=typeMapper.GetTypeName(complexProperty.TypeUsage)#>(); 58 | <# 59 | } 60 | #> 61 | } 62 | 63 | <# 64 | } 65 | 66 | var simpleProperties = typeMapper.GetSimpleProperties(entity); 67 | if (simpleProperties.Any()) 68 | { 69 | foreach (var edmProperty in simpleProperties) 70 | { 71 | #> 72 | <#=codeStringGenerator.Property(edmProperty)#> 73 | <# 74 | } 75 | } 76 | 77 | if (complexProperties.Any()) 78 | { 79 | #> 80 | 81 | <# 82 | foreach(var complexProperty in complexProperties) 83 | { 84 | #> 85 | <#=codeStringGenerator.Property(complexProperty)#> 86 | <# 87 | } 88 | } 89 | 90 | var navigationProperties = typeMapper.GetNavigationProperties(entity); 91 | if (navigationProperties.Any()) 92 | { 93 | #> 94 | 95 | <# 96 | foreach (var navigationProperty in navigationProperties) 97 | { 98 | #> 99 | <#=codeStringGenerator.NavigationProperty(navigationProperty)#> 100 | <# 101 | } 102 | } 103 | #> 104 | } 105 | <# 106 | EndNamespace(code); 107 | } 108 | 109 | foreach (var complex in typeMapper.GetItemsToGenerate(itemCollection)) 110 | { 111 | fileManager.StartNewFile(complex.Name + ".cs"); 112 | BeginNamespace(code); 113 | #> 114 | <#=codeStringGenerator.UsingDirectives(inHeader: false, includeCollections: false)#> 115 | <#=Accessibility.ForType(complex)#> partial class <#=code.Escape(complex)#> 116 | { 117 | <# 118 | var complexProperties = typeMapper.GetComplexProperties(complex); 119 | var propertiesWithDefaultValues = typeMapper.GetPropertiesWithDefaultValues(complex); 120 | 121 | if (propertiesWithDefaultValues.Any() || complexProperties.Any()) 122 | { 123 | #> 124 | public <#=code.Escape(complex)#>() 125 | { 126 | <# 127 | foreach (var edmProperty in propertiesWithDefaultValues) 128 | { 129 | #> 130 | this.<#=code.Escape(edmProperty)#> = <#=typeMapper.CreateLiteral(edmProperty.DefaultValue)#>; 131 | <# 132 | } 133 | 134 | foreach (var complexProperty in complexProperties) 135 | { 136 | #> 137 | this.<#=code.Escape(complexProperty)#> = new <#=typeMapper.GetTypeName(complexProperty.TypeUsage)#>(); 138 | <# 139 | } 140 | #> 141 | } 142 | 143 | <# 144 | } 145 | 146 | var simpleProperties = typeMapper.GetSimpleProperties(complex); 147 | if (simpleProperties.Any()) 148 | { 149 | foreach(var edmProperty in simpleProperties) 150 | { 151 | #> 152 | <#=codeStringGenerator.Property(edmProperty)#> 153 | <# 154 | } 155 | } 156 | 157 | if (complexProperties.Any()) 158 | { 159 | #> 160 | 161 | <# 162 | foreach(var edmProperty in complexProperties) 163 | { 164 | #> 165 | <#=codeStringGenerator.Property(edmProperty)#> 166 | <# 167 | } 168 | } 169 | #> 170 | } 171 | <# 172 | EndNamespace(code); 173 | } 174 | 175 | foreach (var enumType in typeMapper.GetEnumItemsToGenerate(itemCollection)) 176 | { 177 | fileManager.StartNewFile(enumType.Name + ".cs"); 178 | BeginNamespace(code); 179 | #> 180 | <#=codeStringGenerator.UsingDirectives(inHeader: false, includeCollections: false)#> 181 | <# 182 | if (typeMapper.EnumIsFlags(enumType)) 183 | { 184 | #> 185 | [Flags] 186 | <# 187 | } 188 | #> 189 | <#=codeStringGenerator.EnumOpening(enumType)#> 190 | { 191 | <# 192 | var foundOne = false; 193 | 194 | foreach (MetadataItem member in typeMapper.GetEnumMembers(enumType)) 195 | { 196 | foundOne = true; 197 | #> 198 | <#=code.Escape(typeMapper.GetEnumMemberName(member))#> = <#=typeMapper.GetEnumMemberValue(member)#>, 199 | <# 200 | } 201 | 202 | if (foundOne) 203 | { 204 | this.GenerationEnvironment.Remove(this.GenerationEnvironment.Length - 3, 1); 205 | } 206 | #> 207 | } 208 | <# 209 | EndNamespace(code); 210 | } 211 | 212 | fileManager.Process(); 213 | 214 | #> 215 | <#+ 216 | 217 | public void WriteHeader(CodeStringGenerator codeStringGenerator, EntityFrameworkTemplateFileManager fileManager) 218 | { 219 | fileManager.StartHeader(); 220 | #> 221 | //------------------------------------------------------------------------------ 222 | // 223 | // <#=CodeGenerationTools.GetResourceString("Template_GeneratedCodeCommentLine1")#> 224 | // 225 | // <#=CodeGenerationTools.GetResourceString("Template_GeneratedCodeCommentLine2")#> 226 | // <#=CodeGenerationTools.GetResourceString("Template_GeneratedCodeCommentLine3")#> 227 | // 228 | //------------------------------------------------------------------------------ 229 | <#=codeStringGenerator.UsingDirectives(inHeader: true)#> 230 | <#+ 231 | fileManager.EndBlock(); 232 | } 233 | 234 | public void BeginNamespace(CodeGenerationTools code) 235 | { 236 | var codeNamespace = code.VsNamespaceSuggestion(); 237 | if (!String.IsNullOrEmpty(codeNamespace)) 238 | { 239 | #> 240 | namespace <#=code.EscapeNamespace(codeNamespace)#> 241 | { 242 | <#+ 243 | PushIndent(" "); 244 | } 245 | } 246 | 247 | public void EndNamespace(CodeGenerationTools code) 248 | { 249 | if (!String.IsNullOrEmpty(code.VsNamespaceSuggestion())) 250 | { 251 | PopIndent(); 252 | #> 253 | } 254 | <#+ 255 | } 256 | } 257 | 258 | public const string TemplateId = "CSharp_DbContext_Types_EF6"; 259 | 260 | public class CodeStringGenerator 261 | { 262 | private readonly CodeGenerationTools _code; 263 | private readonly TypeMapper _typeMapper; 264 | private readonly MetadataTools _ef; 265 | 266 | public CodeStringGenerator(CodeGenerationTools code, TypeMapper typeMapper, MetadataTools ef) 267 | { 268 | ArgumentNotNull(code, "code"); 269 | ArgumentNotNull(typeMapper, "typeMapper"); 270 | ArgumentNotNull(ef, "ef"); 271 | 272 | _code = code; 273 | _typeMapper = typeMapper; 274 | _ef = ef; 275 | } 276 | 277 | public string Property(EdmProperty edmProperty) 278 | { 279 | return string.Format( 280 | CultureInfo.InvariantCulture, 281 | "{0} {1} {2} {{ {3}get; {4}set; }}", 282 | Accessibility.ForProperty(edmProperty), 283 | _typeMapper.GetTypeName(edmProperty.TypeUsage), 284 | _code.Escape(edmProperty), 285 | _code.SpaceAfter(Accessibility.ForGetter(edmProperty)), 286 | _code.SpaceAfter(Accessibility.ForSetter(edmProperty))); 287 | } 288 | 289 | public string NavigationProperty(NavigationProperty navProp) 290 | { 291 | var endType = _typeMapper.GetTypeName(navProp.ToEndMember.GetEntityType()); 292 | return string.Format( 293 | CultureInfo.InvariantCulture, 294 | "{0} {1} {2} {{ {3}get; {4}set; }}", 295 | AccessibilityAndVirtual(Accessibility.ForNavigationProperty(navProp)), 296 | navProp.ToEndMember.RelationshipMultiplicity == RelationshipMultiplicity.Many ? ("ICollection<" + endType + ">") : endType, 297 | _code.Escape(navProp), 298 | _code.SpaceAfter(Accessibility.ForGetter(navProp)), 299 | _code.SpaceAfter(Accessibility.ForSetter(navProp))); 300 | } 301 | 302 | public string AccessibilityAndVirtual(string accessibility) 303 | { 304 | return accessibility + (accessibility != "private" ? " virtual" : ""); 305 | } 306 | 307 | public string EntityClassOpening(EntityType entity) 308 | { 309 | return string.Format( 310 | CultureInfo.InvariantCulture, 311 | "{0} {1}partial class {2}{3}", 312 | Accessibility.ForType(entity), 313 | _code.SpaceAfter(_code.AbstractOption(entity)), 314 | _code.Escape(entity), 315 | _code.StringBefore(" : ", _typeMapper.GetTypeName(entity.BaseType))); 316 | } 317 | 318 | public string EnumOpening(SimpleType enumType) 319 | { 320 | return string.Format( 321 | CultureInfo.InvariantCulture, 322 | "{0} enum {1} : {2}", 323 | Accessibility.ForType(enumType), 324 | _code.Escape(enumType), 325 | _code.Escape(_typeMapper.UnderlyingClrType(enumType))); 326 | } 327 | 328 | public void WriteFunctionParameters(EdmFunction edmFunction, Action writeParameter) 329 | { 330 | var parameters = FunctionImportParameter.Create(edmFunction.Parameters, _code, _ef); 331 | foreach (var parameter in parameters.Where(p => p.NeedsLocalVariable)) 332 | { 333 | var isNotNull = parameter.IsNullableOfT ? parameter.FunctionParameterName + ".HasValue" : parameter.FunctionParameterName + " != null"; 334 | var notNullInit = "new ObjectParameter(\"" + parameter.EsqlParameterName + "\", " + parameter.FunctionParameterName + ")"; 335 | var nullInit = "new ObjectParameter(\"" + parameter.EsqlParameterName + "\", typeof(" + TypeMapper.FixNamespaces(parameter.RawClrTypeName) + "))"; 336 | writeParameter(parameter.LocalVariableName, isNotNull, notNullInit, nullInit); 337 | } 338 | } 339 | 340 | public string ComposableFunctionMethod(EdmFunction edmFunction, string modelNamespace) 341 | { 342 | var parameters = _typeMapper.GetParameters(edmFunction); 343 | 344 | return string.Format( 345 | CultureInfo.InvariantCulture, 346 | "{0} IQueryable<{1}> {2}({3})", 347 | AccessibilityAndVirtual(Accessibility.ForMethod(edmFunction)), 348 | _typeMapper.GetTypeName(_typeMapper.GetReturnType(edmFunction), modelNamespace), 349 | _code.Escape(edmFunction), 350 | string.Join(", ", parameters.Select(p => TypeMapper.FixNamespaces(p.FunctionParameterType) + " " + p.FunctionParameterName).ToArray())); 351 | } 352 | 353 | public string ComposableCreateQuery(EdmFunction edmFunction, string modelNamespace) 354 | { 355 | var parameters = _typeMapper.GetParameters(edmFunction); 356 | 357 | return string.Format( 358 | CultureInfo.InvariantCulture, 359 | "return ((IObjectContextAdapter)this).ObjectContext.CreateQuery<{0}>(\"[{1}].[{2}]({3})\"{4});", 360 | _typeMapper.GetTypeName(_typeMapper.GetReturnType(edmFunction), modelNamespace), 361 | edmFunction.NamespaceName, 362 | edmFunction.Name, 363 | string.Join(", ", parameters.Select(p => "@" + p.EsqlParameterName).ToArray()), 364 | _code.StringBefore(", ", string.Join(", ", parameters.Select(p => p.ExecuteParameterName).ToArray()))); 365 | } 366 | 367 | public string FunctionMethod(EdmFunction edmFunction, string modelNamespace, bool includeMergeOption) 368 | { 369 | var parameters = _typeMapper.GetParameters(edmFunction); 370 | var returnType = _typeMapper.GetReturnType(edmFunction); 371 | 372 | var paramList = String.Join(", ", parameters.Select(p => TypeMapper.FixNamespaces(p.FunctionParameterType) + " " + p.FunctionParameterName).ToArray()); 373 | if (includeMergeOption) 374 | { 375 | paramList = _code.StringAfter(paramList, ", ") + "MergeOption mergeOption"; 376 | } 377 | 378 | return string.Format( 379 | CultureInfo.InvariantCulture, 380 | "{0} {1} {2}({3})", 381 | AccessibilityAndVirtual(Accessibility.ForMethod(edmFunction)), 382 | returnType == null ? "int" : "ObjectResult<" + _typeMapper.GetTypeName(returnType, modelNamespace) + ">", 383 | _code.Escape(edmFunction), 384 | paramList); 385 | } 386 | 387 | public string ExecuteFunction(EdmFunction edmFunction, string modelNamespace, bool includeMergeOption) 388 | { 389 | var parameters = _typeMapper.GetParameters(edmFunction); 390 | var returnType = _typeMapper.GetReturnType(edmFunction); 391 | 392 | var callParams = _code.StringBefore(", ", String.Join(", ", parameters.Select(p => p.ExecuteParameterName).ToArray())); 393 | if (includeMergeOption) 394 | { 395 | callParams = ", mergeOption" + callParams; 396 | } 397 | 398 | return string.Format( 399 | CultureInfo.InvariantCulture, 400 | "return ((IObjectContextAdapter)this).ObjectContext.ExecuteFunction{0}(\"{1}\"{2});", 401 | returnType == null ? "" : "<" + _typeMapper.GetTypeName(returnType, modelNamespace) + ">", 402 | edmFunction.Name, 403 | callParams); 404 | } 405 | 406 | public string DbSet(EntitySet entitySet) 407 | { 408 | return string.Format( 409 | CultureInfo.InvariantCulture, 410 | "{0} virtual DbSet<{1}> {2} {{ get; set; }}", 411 | Accessibility.ForReadOnlyProperty(entitySet), 412 | _typeMapper.GetTypeName(entitySet.ElementType), 413 | _code.Escape(entitySet)); 414 | } 415 | 416 | public string UsingDirectives(bool inHeader, bool includeCollections = true) 417 | { 418 | return inHeader == string.IsNullOrEmpty(_code.VsNamespaceSuggestion()) 419 | ? string.Format( 420 | CultureInfo.InvariantCulture, 421 | "{0}using System;{1}" + 422 | "{2}", 423 | inHeader ? Environment.NewLine : "", 424 | includeCollections ? (Environment.NewLine + "using System.Collections.Generic;") : "", 425 | inHeader ? "" : Environment.NewLine) 426 | : ""; 427 | } 428 | } 429 | 430 | public class TypeMapper 431 | { 432 | private const string ExternalTypeNameAttributeName = @"http://schemas.microsoft.com/ado/2006/04/codegeneration:ExternalTypeName"; 433 | 434 | private readonly System.Collections.IList _errors; 435 | private readonly CodeGenerationTools _code; 436 | private readonly MetadataTools _ef; 437 | 438 | public TypeMapper(CodeGenerationTools code, MetadataTools ef, System.Collections.IList errors) 439 | { 440 | ArgumentNotNull(code, "code"); 441 | ArgumentNotNull(ef, "ef"); 442 | ArgumentNotNull(errors, "errors"); 443 | 444 | _code = code; 445 | _ef = ef; 446 | _errors = errors; 447 | } 448 | 449 | public static string FixNamespaces(string typeName) 450 | { 451 | return typeName.Replace("System.Data.Spatial.", "System.Data.Entity.Spatial."); 452 | } 453 | 454 | public string GetTypeName(TypeUsage typeUsage) 455 | { 456 | return typeUsage == null ? null : GetTypeName(typeUsage.EdmType, _ef.IsNullable(typeUsage), modelNamespace: null); 457 | } 458 | 459 | public string GetTypeName(EdmType edmType) 460 | { 461 | return GetTypeName(edmType, isNullable: null, modelNamespace: null); 462 | } 463 | 464 | public string GetTypeName(TypeUsage typeUsage, string modelNamespace) 465 | { 466 | return typeUsage == null ? null : GetTypeName(typeUsage.EdmType, _ef.IsNullable(typeUsage), modelNamespace); 467 | } 468 | 469 | public string GetTypeName(EdmType edmType, string modelNamespace) 470 | { 471 | return GetTypeName(edmType, isNullable: null, modelNamespace: modelNamespace); 472 | } 473 | 474 | public string GetTypeName(EdmType edmType, bool? isNullable, string modelNamespace) 475 | { 476 | if (edmType == null) 477 | { 478 | return null; 479 | } 480 | 481 | var collectionType = edmType as CollectionType; 482 | if (collectionType != null) 483 | { 484 | return String.Format(CultureInfo.InvariantCulture, "ICollection<{0}>", GetTypeName(collectionType.TypeUsage, modelNamespace)); 485 | } 486 | 487 | var typeName = _code.Escape(edmType.MetadataProperties 488 | .Where(p => p.Name == ExternalTypeNameAttributeName) 489 | .Select(p => (string)p.Value) 490 | .FirstOrDefault()) 491 | ?? (modelNamespace != null && edmType.NamespaceName != modelNamespace ? 492 | _code.CreateFullName(_code.EscapeNamespace(edmType.NamespaceName), _code.Escape(edmType)) : 493 | _code.Escape(edmType)); 494 | 495 | if (edmType is StructuralType) 496 | { 497 | return typeName; 498 | } 499 | 500 | if (edmType is SimpleType) 501 | { 502 | var clrType = UnderlyingClrType(edmType); 503 | if (!IsEnumType(edmType)) 504 | { 505 | typeName = _code.Escape(clrType); 506 | } 507 | 508 | typeName = FixNamespaces(typeName); 509 | 510 | return clrType.IsValueType && isNullable == true ? 511 | String.Format(CultureInfo.InvariantCulture, "Nullable<{0}>", typeName) : 512 | typeName; 513 | } 514 | 515 | throw new ArgumentException("edmType"); 516 | } 517 | 518 | public Type UnderlyingClrType(EdmType edmType) 519 | { 520 | ArgumentNotNull(edmType, "edmType"); 521 | 522 | var primitiveType = edmType as PrimitiveType; 523 | if (primitiveType != null) 524 | { 525 | return primitiveType.ClrEquivalentType; 526 | } 527 | 528 | if (IsEnumType(edmType)) 529 | { 530 | return GetEnumUnderlyingType(edmType).ClrEquivalentType; 531 | } 532 | 533 | return typeof(object); 534 | } 535 | 536 | public object GetEnumMemberValue(MetadataItem enumMember) 537 | { 538 | ArgumentNotNull(enumMember, "enumMember"); 539 | 540 | var valueProperty = enumMember.GetType().GetProperty("Value"); 541 | return valueProperty == null ? null : valueProperty.GetValue(enumMember, null); 542 | } 543 | 544 | public string GetEnumMemberName(MetadataItem enumMember) 545 | { 546 | ArgumentNotNull(enumMember, "enumMember"); 547 | 548 | var nameProperty = enumMember.GetType().GetProperty("Name"); 549 | return nameProperty == null ? null : (string)nameProperty.GetValue(enumMember, null); 550 | } 551 | 552 | public System.Collections.IEnumerable GetEnumMembers(EdmType enumType) 553 | { 554 | ArgumentNotNull(enumType, "enumType"); 555 | 556 | var membersProperty = enumType.GetType().GetProperty("Members"); 557 | return membersProperty != null 558 | ? (System.Collections.IEnumerable)membersProperty.GetValue(enumType, null) 559 | : Enumerable.Empty(); 560 | } 561 | 562 | public bool EnumIsFlags(EdmType enumType) 563 | { 564 | ArgumentNotNull(enumType, "enumType"); 565 | 566 | var isFlagsProperty = enumType.GetType().GetProperty("IsFlags"); 567 | return isFlagsProperty != null && (bool)isFlagsProperty.GetValue(enumType, null); 568 | } 569 | 570 | public bool IsEnumType(GlobalItem edmType) 571 | { 572 | ArgumentNotNull(edmType, "edmType"); 573 | 574 | return edmType.GetType().Name == "EnumType"; 575 | } 576 | 577 | public PrimitiveType GetEnumUnderlyingType(EdmType enumType) 578 | { 579 | ArgumentNotNull(enumType, "enumType"); 580 | 581 | return (PrimitiveType)enumType.GetType().GetProperty("UnderlyingType").GetValue(enumType, null); 582 | } 583 | 584 | public string CreateLiteral(object value) 585 | { 586 | if (value == null || value.GetType() != typeof(TimeSpan)) 587 | { 588 | return _code.CreateLiteral(value); 589 | } 590 | 591 | return string.Format(CultureInfo.InvariantCulture, "new TimeSpan({0})", ((TimeSpan)value).Ticks); 592 | } 593 | 594 | public bool VerifyCaseInsensitiveTypeUniqueness(IEnumerable types, string sourceFile) 595 | { 596 | ArgumentNotNull(types, "types"); 597 | ArgumentNotNull(sourceFile, "sourceFile"); 598 | 599 | var hash = new HashSet(StringComparer.InvariantCultureIgnoreCase); 600 | if (types.Any(item => !hash.Add(item))) 601 | { 602 | _errors.Add( 603 | new CompilerError(sourceFile, -1, -1, "6023", 604 | String.Format(CultureInfo.CurrentCulture, CodeGenerationTools.GetResourceString("Template_CaseInsensitiveTypeConflict")))); 605 | return false; 606 | } 607 | return true; 608 | } 609 | 610 | public IEnumerable GetEnumItemsToGenerate(IEnumerable itemCollection) 611 | { 612 | return GetItemsToGenerate(itemCollection) 613 | .Where(e => IsEnumType(e)); 614 | } 615 | 616 | public IEnumerable GetItemsToGenerate(IEnumerable itemCollection) where T: EdmType 617 | { 618 | return itemCollection 619 | .OfType() 620 | .Where(i => !i.MetadataProperties.Any(p => p.Name == ExternalTypeNameAttributeName)) 621 | .OrderBy(i => i.Name); 622 | } 623 | 624 | public IEnumerable GetAllGlobalItems(IEnumerable itemCollection) 625 | { 626 | return itemCollection 627 | .Where(i => i is EntityType || i is ComplexType || i is EntityContainer || IsEnumType(i)) 628 | .Select(g => GetGlobalItemName(g)); 629 | } 630 | 631 | public string GetGlobalItemName(GlobalItem item) 632 | { 633 | if (item is EdmType) 634 | { 635 | return ((EdmType)item).Name; 636 | } 637 | else 638 | { 639 | return ((EntityContainer)item).Name; 640 | } 641 | } 642 | 643 | public IEnumerable GetSimpleProperties(EntityType type) 644 | { 645 | return type.Properties.Where(p => p.TypeUsage.EdmType is SimpleType && p.DeclaringType == type); 646 | } 647 | 648 | public IEnumerable GetSimpleProperties(ComplexType type) 649 | { 650 | return type.Properties.Where(p => p.TypeUsage.EdmType is SimpleType && p.DeclaringType == type); 651 | } 652 | 653 | public IEnumerable GetComplexProperties(EntityType type) 654 | { 655 | return type.Properties.Where(p => p.TypeUsage.EdmType is ComplexType && p.DeclaringType == type); 656 | } 657 | 658 | public IEnumerable GetComplexProperties(ComplexType type) 659 | { 660 | return type.Properties.Where(p => p.TypeUsage.EdmType is ComplexType && p.DeclaringType == type); 661 | } 662 | 663 | public IEnumerable GetPropertiesWithDefaultValues(EntityType type) 664 | { 665 | return type.Properties.Where(p => p.TypeUsage.EdmType is SimpleType && p.DeclaringType == type && p.DefaultValue != null); 666 | } 667 | 668 | public IEnumerable GetPropertiesWithDefaultValues(ComplexType type) 669 | { 670 | return type.Properties.Where(p => p.TypeUsage.EdmType is SimpleType && p.DeclaringType == type && p.DefaultValue != null); 671 | } 672 | 673 | public IEnumerable GetNavigationProperties(EntityType type) 674 | { 675 | return type.NavigationProperties.Where(np => np.DeclaringType == type); 676 | } 677 | 678 | public IEnumerable GetCollectionNavigationProperties(EntityType type) 679 | { 680 | return type.NavigationProperties.Where(np => np.DeclaringType == type && np.ToEndMember.RelationshipMultiplicity == RelationshipMultiplicity.Many); 681 | } 682 | 683 | public FunctionParameter GetReturnParameter(EdmFunction edmFunction) 684 | { 685 | ArgumentNotNull(edmFunction, "edmFunction"); 686 | 687 | var returnParamsProperty = edmFunction.GetType().GetProperty("ReturnParameters"); 688 | return returnParamsProperty == null 689 | ? edmFunction.ReturnParameter 690 | : ((IEnumerable)returnParamsProperty.GetValue(edmFunction, null)).FirstOrDefault(); 691 | } 692 | 693 | public bool IsComposable(EdmFunction edmFunction) 694 | { 695 | ArgumentNotNull(edmFunction, "edmFunction"); 696 | 697 | var isComposableProperty = edmFunction.GetType().GetProperty("IsComposableAttribute"); 698 | return isComposableProperty != null && (bool)isComposableProperty.GetValue(edmFunction, null); 699 | } 700 | 701 | public IEnumerable GetParameters(EdmFunction edmFunction) 702 | { 703 | return FunctionImportParameter.Create(edmFunction.Parameters, _code, _ef); 704 | } 705 | 706 | public TypeUsage GetReturnType(EdmFunction edmFunction) 707 | { 708 | var returnParam = GetReturnParameter(edmFunction); 709 | return returnParam == null ? null : _ef.GetElementType(returnParam.TypeUsage); 710 | } 711 | 712 | public bool GenerateMergeOptionFunction(EdmFunction edmFunction, bool includeMergeOption) 713 | { 714 | var returnType = GetReturnType(edmFunction); 715 | return !includeMergeOption && returnType != null && returnType.EdmType.BuiltInTypeKind == BuiltInTypeKind.EntityType; 716 | } 717 | } 718 | 719 | public static void ArgumentNotNull(T arg, string name) where T : class 720 | { 721 | if (arg == null) 722 | { 723 | throw new ArgumentNullException(name); 724 | } 725 | } 726 | #> -------------------------------------------------------------------------------- /src/KriaSoft.AspNet.Identity.EntityFramework/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) KriaSoft, LLC. All rights reserved. See LICENSE.txt in the project root for license information. 2 | 3 | using System.Reflection; 4 | using System.Runtime.InteropServices; 5 | 6 | // General Information about an assembly is controlled through the following 7 | // set of attributes. Change these attribute values to modify the information 8 | // associated with an assembly. 9 | [assembly: AssemblyTitle("KriaSoft.AspNet.Identity.EntityFramework")] 10 | [assembly: AssemblyDescription("")] 11 | [assembly: AssemblyConfiguration("")] 12 | [assembly: AssemblyCompany("KriaSoft")] 13 | [assembly: AssemblyProduct("KriaSoft.AspNet.Identity.EntityFramework")] 14 | [assembly: AssemblyCopyright("Copyright © 2014 KriaSoft")] 15 | [assembly: AssemblyTrademark("")] 16 | [assembly: AssemblyCulture("")] 17 | 18 | // Setting ComVisible to false makes the types in this assembly not visible 19 | // to COM components. If you need to access a type in this assembly from 20 | // COM, set the ComVisible attribute to true on that type. 21 | [assembly: ComVisible(false)] 22 | 23 | // The following GUID is for the ID of the typelib if this project is exposed to COM 24 | [assembly: Guid("d6f41fdb-1bf1-4ef1-a2eb-d54e6808fa9f")] 25 | 26 | // Version information for an assembly consists of the following four values: 27 | // 28 | // Major Version 29 | // Minor Version 30 | // Build Number 31 | // Revision 32 | // 33 | // You can specify all the values or you can default the Build and Revision Numbers 34 | // by using the '*' as shown below: 35 | // [assembly: AssemblyVersion("1.0.*")] 36 | [assembly: AssemblyVersion("1.0.0.0")] 37 | [assembly: AssemblyFileVersion("1.0.0.0")] 38 | -------------------------------------------------------------------------------- /src/KriaSoft.AspNet.Identity.EntityFramework/Resources.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // This code was generated by a tool. 4 | // Runtime Version:4.0.30319.34014 5 | // 6 | // Changes to this file may cause incorrect behavior and will be lost if 7 | // the code is regenerated. 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | namespace KriaSoft.AspNet.Identity.EntityFramework { 12 | using System; 13 | 14 | 15 | /// 16 | /// A strongly-typed resource class, for looking up localized strings, etc. 17 | /// 18 | // This class was auto-generated by the StronglyTypedResourceBuilder 19 | // class via a tool like ResGen or Visual Studio. 20 | // To add or remove a member, edit your .ResX file then rerun ResGen 21 | // with the /str option, or rebuild your VS project. 22 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] 23 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 24 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 25 | internal class Resources { 26 | 27 | private static global::System.Resources.ResourceManager resourceMan; 28 | 29 | private static global::System.Globalization.CultureInfo resourceCulture; 30 | 31 | [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] 32 | internal Resources() { 33 | } 34 | 35 | /// 36 | /// Returns the cached ResourceManager instance used by this class. 37 | /// 38 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 39 | internal static global::System.Resources.ResourceManager ResourceManager { 40 | get { 41 | if (object.ReferenceEquals(resourceMan, null)) { 42 | global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("KriaSoft.AspNet.Identity.EntityFramework.Resources", typeof(Resources).Assembly); 43 | resourceMan = temp; 44 | } 45 | return resourceMan; 46 | } 47 | } 48 | 49 | /// 50 | /// Overrides the current thread's CurrentUICulture property for all 51 | /// resource lookups using this strongly typed resource class. 52 | /// 53 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 54 | internal static global::System.Globalization.CultureInfo Culture { 55 | get { 56 | return resourceCulture; 57 | } 58 | set { 59 | resourceCulture = value; 60 | } 61 | } 62 | 63 | /// 64 | /// Looks up a localized string similar to Role {0} does not exist.. 65 | /// 66 | internal static string RoleNotFound { 67 | get { 68 | return ResourceManager.GetString("RoleNotFound", resourceCulture); 69 | } 70 | } 71 | 72 | /// 73 | /// Looks up a localized string similar to Value cannot be null or empty.. 74 | /// 75 | internal static string ValueCannotBeNullOrEmpty { 76 | get { 77 | return ResourceManager.GetString("ValueCannotBeNullOrEmpty", resourceCulture); 78 | } 79 | } 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /src/KriaSoft.AspNet.Identity.EntityFramework/Resources.resx: -------------------------------------------------------------------------------- 1 |  2 | 3 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | text/microsoft-resx 110 | 111 | 112 | 2.0 113 | 114 | 115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | 118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 119 | 120 | 121 | Role {0} does not exist. 122 | 123 | 124 | Value cannot be null or empty. 125 | 126 | -------------------------------------------------------------------------------- /src/KriaSoft.AspNet.Identity.EntityFramework/RoleStore.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) KriaSoft, LLC. All rights reserved. See LICENSE.txt in the project root for license information. 2 | 3 | using System; 4 | using System.Data.Entity; 5 | using System.Linq; 6 | using System.Threading.Tasks; 7 | 8 | using Microsoft.AspNet.Identity; 9 | 10 | namespace KriaSoft.AspNet.Identity.EntityFramework 11 | { 12 | public class RoleStore : IQueryableRoleStore 13 | { 14 | private readonly ApplicationDbContext db; 15 | 16 | public RoleStore(ApplicationDbContext db) 17 | { 18 | this.db = db; 19 | } 20 | 21 | //// IQueryableRoleStore 22 | 23 | public IQueryable Roles 24 | { 25 | get { return this.db.UserRoles; } 26 | } 27 | 28 | //// IRoleStore 29 | 30 | public virtual Task CreateAsync(UserRole role) 31 | { 32 | if (role == null) 33 | { 34 | throw new ArgumentNullException("role"); 35 | } 36 | 37 | this.db.UserRoles.Add(role); 38 | return this.db.SaveChangesAsync(); 39 | } 40 | 41 | public Task DeleteAsync(UserRole role) 42 | { 43 | if (role == null) 44 | { 45 | throw new ArgumentNullException("role"); 46 | } 47 | 48 | this.db.UserRoles.Remove(role); 49 | return this.db.SaveChangesAsync(); 50 | } 51 | 52 | public Task FindByIdAsync(int roleId) 53 | { 54 | return this.db.UserRoles.FindAsync(new[] { roleId }); 55 | } 56 | 57 | public Task FindByNameAsync(string roleName) 58 | { 59 | return this.db.UserRoles.FirstOrDefaultAsync(r => r.Name == roleName); 60 | } 61 | 62 | public Task UpdateAsync(UserRole role) 63 | { 64 | if (role == null) 65 | { 66 | throw new ArgumentNullException("role"); 67 | } 68 | 69 | this.db.Entry(role).State = EntityState.Modified; 70 | return this.db.SaveChangesAsync(); 71 | } 72 | 73 | //// IDisposable 74 | 75 | public void Dispose() 76 | { 77 | this.Dispose(true); 78 | GC.SuppressFinalize(this); 79 | } 80 | 81 | protected virtual void Dispose(bool disposing) 82 | { 83 | if (disposing && this.db != null) 84 | { 85 | this.db.Dispose(); 86 | } 87 | } 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /src/KriaSoft.AspNet.Identity.EntityFramework/User.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // This code was generated from a template. 4 | // 5 | // Manual changes to this file may cause unexpected behavior in your application. 6 | // Manual changes to this file will be overwritten if the code is regenerated. 7 | // 8 | //------------------------------------------------------------------------------ 9 | 10 | namespace KriaSoft.AspNet.Identity.EntityFramework 11 | { 12 | using System; 13 | using System.Collections.Generic; 14 | 15 | public partial class User 16 | { 17 | public User() 18 | { 19 | this.Claims = new HashSet(); 20 | this.Logins = new HashSet(); 21 | this.Roles = new HashSet(); 22 | } 23 | 24 | public int Id { get; set; } 25 | public string UserName { get; set; } 26 | public string Email { get; set; } 27 | public bool EmailConfirmed { get; set; } 28 | public string PasswordHash { get; set; } 29 | public string SecurityStamp { get; set; } 30 | public string PhoneNumber { get; set; } 31 | public bool PhoneNumberConfirmed { get; set; } 32 | public bool TwoFactorEnabled { get; set; } 33 | public Nullable LockoutEndDateUtc { get; set; } 34 | public bool LockoutEnabled { get; set; } 35 | public int AccessFailedCount { get; set; } 36 | 37 | public virtual ICollection Claims { get; set; } 38 | public virtual ICollection Logins { get; set; } 39 | public virtual ICollection Roles { get; set; } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/KriaSoft.AspNet.Identity.EntityFramework/UserClaim.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // This code was generated from a template. 4 | // 5 | // Manual changes to this file may cause unexpected behavior in your application. 6 | // Manual changes to this file will be overwritten if the code is regenerated. 7 | // 8 | //------------------------------------------------------------------------------ 9 | 10 | namespace KriaSoft.AspNet.Identity.EntityFramework 11 | { 12 | using System; 13 | using System.Collections.Generic; 14 | 15 | public partial class UserClaim 16 | { 17 | public int Id { get; set; } 18 | public int UserId { get; set; } 19 | public string ClaimType { get; set; } 20 | public string ClaimValue { get; set; } 21 | 22 | public virtual User User { get; set; } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/KriaSoft.AspNet.Identity.EntityFramework/UserEntity.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) KriaSoft, LLC. All rights reserved. See LICENSE.txt in the project root for license information. 2 | 3 | namespace KriaSoft.AspNet.Identity.EntityFramework 4 | { 5 | using Microsoft.AspNet.Identity; 6 | 7 | public partial class User : IUser 8 | { 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /src/KriaSoft.AspNet.Identity.EntityFramework/UserLogin.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // This code was generated from a template. 4 | // 5 | // Manual changes to this file may cause unexpected behavior in your application. 6 | // Manual changes to this file will be overwritten if the code is regenerated. 7 | // 8 | //------------------------------------------------------------------------------ 9 | 10 | namespace KriaSoft.AspNet.Identity.EntityFramework 11 | { 12 | using System; 13 | using System.Collections.Generic; 14 | 15 | public partial class UserLogin 16 | { 17 | public int UserId { get; set; } 18 | public string LoginProvider { get; set; } 19 | public string ProviderKey { get; set; } 20 | 21 | public virtual User User { get; set; } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/KriaSoft.AspNet.Identity.EntityFramework/UserRole.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // This code was generated from a template. 4 | // 5 | // Manual changes to this file may cause unexpected behavior in your application. 6 | // Manual changes to this file will be overwritten if the code is regenerated. 7 | // 8 | //------------------------------------------------------------------------------ 9 | 10 | namespace KriaSoft.AspNet.Identity.EntityFramework 11 | { 12 | using System; 13 | using System.Collections.Generic; 14 | 15 | public partial class UserRole 16 | { 17 | public UserRole() 18 | { 19 | this.Users = new HashSet(); 20 | } 21 | 22 | public int Id { get; set; } 23 | public string Name { get; set; } 24 | 25 | public virtual ICollection Users { get; set; } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/KriaSoft.AspNet.Identity.EntityFramework/UserRoleEntity.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) KriaSoft, LLC. All rights reserved. See LICENSE.txt in the project root for license information. 2 | 3 | namespace KriaSoft.AspNet.Identity.EntityFramework 4 | { 5 | using Microsoft.AspNet.Identity; 6 | 7 | public partial class UserRole : IRole 8 | { 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /src/KriaSoft.AspNet.Identity.EntityFramework/UserStore.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) KriaSoft, LLC. All rights reserved. See LICENSE.txt in the project root for license information. 2 | 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Data.Entity; 6 | using System.Globalization; 7 | using System.Linq; 8 | using System.Security.Claims; 9 | using System.Threading.Tasks; 10 | 11 | using Microsoft.AspNet.Identity; 12 | 13 | namespace KriaSoft.AspNet.Identity.EntityFramework 14 | { 15 | public partial class UserStore : 16 | IQueryableUserStore, IUserPasswordStore, IUserLoginStore, 17 | IUserClaimStore, IUserRoleStore, IUserSecurityStampStore, 18 | IUserEmailStore, IUserPhoneNumberStore, IUserTwoFactorStore, 19 | IUserLockoutStore 20 | { 21 | private readonly ApplicationDbContext db; 22 | 23 | public UserStore(ApplicationDbContext db) 24 | { 25 | if (db == null) 26 | { 27 | throw new ArgumentNullException("db"); 28 | } 29 | 30 | this.db = db; 31 | } 32 | 33 | //// IQueryableUserStore 34 | 35 | public IQueryable Users 36 | { 37 | get { return this.db.Users; } 38 | } 39 | 40 | //// IUserStore 41 | 42 | public Task CreateAsync(User user) 43 | { 44 | this.db.Users.Add(user); 45 | return this.db.SaveChangesAsync(); 46 | } 47 | 48 | public Task DeleteAsync(User user) 49 | { 50 | this.db.Users.Remove(user); 51 | return this.db.SaveChangesAsync(); 52 | } 53 | 54 | public Task FindByIdAsync(int userId) 55 | { 56 | return this.db.Users 57 | .Include(u => u.Logins).Include(u => u.Roles).Include(u => u.Claims) 58 | .FirstOrDefaultAsync(u => u.Id.Equals(userId)); 59 | } 60 | 61 | public Task FindByNameAsync(string userName) 62 | { 63 | return this.db.Users 64 | .Include(u => u.Logins).Include(u => u.Roles).Include(u => u.Claims) 65 | .FirstOrDefaultAsync(u => u.UserName == userName); 66 | } 67 | 68 | public Task UpdateAsync(User user) 69 | { 70 | this.db.Entry(user).State = EntityState.Modified; 71 | return this.db.SaveChangesAsync(); 72 | } 73 | 74 | //// IUserPasswordStore 75 | 76 | public Task GetPasswordHashAsync(User user) 77 | { 78 | if (user == null) 79 | { 80 | throw new ArgumentNullException("user"); 81 | } 82 | 83 | return Task.FromResult(user.PasswordHash); 84 | } 85 | 86 | public Task HasPasswordAsync(User user) 87 | { 88 | return Task.FromResult(user.PasswordHash != null); 89 | } 90 | 91 | public Task SetPasswordHashAsync(User user, string passwordHash) 92 | { 93 | if (user == null) 94 | { 95 | throw new ArgumentNullException("user"); 96 | } 97 | 98 | user.PasswordHash = passwordHash; 99 | return Task.FromResult(0); 100 | } 101 | 102 | //// IUserLoginStore 103 | 104 | public Task AddLoginAsync(User user, UserLoginInfo login) 105 | { 106 | if (user == null) 107 | { 108 | throw new ArgumentNullException("user"); 109 | } 110 | 111 | if (login == null) 112 | { 113 | throw new ArgumentNullException("login"); 114 | } 115 | 116 | var userLogin = Activator.CreateInstance(); 117 | userLogin.UserId = user.Id; 118 | userLogin.LoginProvider = login.LoginProvider; 119 | userLogin.ProviderKey = login.ProviderKey; 120 | user.Logins.Add(userLogin); 121 | return Task.FromResult(0); 122 | } 123 | 124 | public async Task FindAsync(UserLoginInfo login) 125 | { 126 | if (login == null) 127 | { 128 | throw new ArgumentNullException("login"); 129 | } 130 | 131 | var provider = login.LoginProvider; 132 | var key = login.ProviderKey; 133 | 134 | var userLogin = await this.db.UserLogins.FirstOrDefaultAsync(l => l.LoginProvider == provider && l.ProviderKey == key); 135 | 136 | if (userLogin == null) 137 | { 138 | return default(User); 139 | } 140 | 141 | return await this.db.Users 142 | .Include(u => u.Logins).Include(u => u.Roles).Include(u => u.Claims) 143 | .FirstOrDefaultAsync(u => u.Id.Equals(userLogin.UserId)); 144 | } 145 | 146 | public Task> GetLoginsAsync(User user) 147 | { 148 | if (user == null) 149 | { 150 | throw new ArgumentNullException("user"); 151 | } 152 | 153 | return Task.FromResult>(user.Logins.Select(l => new UserLoginInfo(l.LoginProvider, l.ProviderKey)).ToList()); 154 | } 155 | 156 | public Task RemoveLoginAsync(User user, UserLoginInfo login) 157 | { 158 | if (user == null) 159 | { 160 | throw new ArgumentNullException("user"); 161 | } 162 | 163 | if (login == null) 164 | { 165 | throw new ArgumentNullException("login"); 166 | } 167 | 168 | var provider = login.LoginProvider; 169 | var key = login.ProviderKey; 170 | 171 | var item = user.Logins.SingleOrDefault(l => l.LoginProvider == provider && l.ProviderKey == key); 172 | 173 | if (item != null) 174 | { 175 | user.Logins.Remove(item); 176 | } 177 | 178 | return Task.FromResult(0); 179 | } 180 | 181 | //// IUserClaimStore 182 | 183 | public Task AddClaimAsync(User user, Claim claim) 184 | { 185 | if (user == null) 186 | { 187 | throw new ArgumentNullException("user"); 188 | } 189 | 190 | if (claim == null) 191 | { 192 | throw new ArgumentNullException("claim"); 193 | } 194 | 195 | var item = Activator.CreateInstance(); 196 | item.UserId = user.Id; 197 | item.ClaimType = claim.Type; 198 | item.ClaimValue = claim.Value; 199 | user.Claims.Add(item); 200 | return Task.FromResult(0); 201 | } 202 | 203 | public Task> GetClaimsAsync(User user) 204 | { 205 | if (user == null) 206 | { 207 | throw new ArgumentNullException("user"); 208 | } 209 | 210 | return Task.FromResult>(user.Claims.Select(c => new Claim(c.ClaimType, c.ClaimValue)).ToList()); 211 | } 212 | 213 | public Task RemoveClaimAsync(User user, Claim claim) 214 | { 215 | if (user == null) 216 | { 217 | throw new ArgumentNullException("user"); 218 | } 219 | 220 | if (claim == null) 221 | { 222 | throw new ArgumentNullException("claim"); 223 | } 224 | 225 | foreach (var item in user.Claims.Where(uc => uc.ClaimValue == claim.Value && uc.ClaimType == claim.Type).ToList()) 226 | { 227 | user.Claims.Remove(item); 228 | } 229 | 230 | foreach (var item in this.db.UserClaims.Where(uc => uc.UserId.Equals(user.Id) && uc.ClaimValue == claim.Value && uc.ClaimType == claim.Type).ToList()) 231 | { 232 | this.db.UserClaims.Remove(item); 233 | } 234 | 235 | return Task.FromResult(0); 236 | } 237 | 238 | //// IUserRoleStore 239 | 240 | public Task AddToRoleAsync(User user, string roleName) 241 | { 242 | if (user == null) 243 | { 244 | throw new ArgumentNullException("user"); 245 | } 246 | 247 | if (string.IsNullOrWhiteSpace(roleName)) 248 | { 249 | throw new ArgumentException(Resources.ValueCannotBeNullOrEmpty, "roleName"); 250 | } 251 | 252 | var userRole = this.db.UserRoles.SingleOrDefault(r => r.Name == roleName); 253 | 254 | if (userRole == null) 255 | { 256 | throw new InvalidOperationException(string.Format(CultureInfo.CurrentCulture, Resources.RoleNotFound, new object[] { roleName })); 257 | } 258 | 259 | user.Roles.Add(userRole); 260 | return Task.FromResult(0); 261 | } 262 | 263 | public Task> GetRolesAsync(User user) 264 | { 265 | if (user == null) 266 | { 267 | throw new ArgumentNullException("user"); 268 | } 269 | 270 | return Task.FromResult>(user.Roles.Join(this.db.UserRoles, ur => ur.Id, r => r.Id, (ur, r) => r.Name).ToList()); 271 | } 272 | 273 | public Task IsInRoleAsync(User user, string roleName) 274 | { 275 | if (user == null) 276 | { 277 | throw new ArgumentNullException("user"); 278 | } 279 | 280 | if (string.IsNullOrWhiteSpace(roleName)) 281 | { 282 | throw new ArgumentException(Resources.ValueCannotBeNullOrEmpty, "roleName"); 283 | } 284 | 285 | return 286 | Task.FromResult( 287 | this.db.UserRoles.Any(r => r.Name == roleName && r.Users.Any(u => u.Id.Equals(user.Id)))); 288 | } 289 | 290 | public Task RemoveFromRoleAsync(User user, string roleName) 291 | { 292 | if (user == null) 293 | { 294 | throw new ArgumentNullException("user"); 295 | } 296 | 297 | if (string.IsNullOrWhiteSpace(roleName)) 298 | { 299 | throw new ArgumentException(Resources.ValueCannotBeNullOrEmpty, "roleName"); 300 | } 301 | 302 | var userRole = user.Roles.SingleOrDefault(r => r.Name == roleName); 303 | 304 | if (userRole != null) 305 | { 306 | user.Roles.Remove(userRole); 307 | } 308 | 309 | return Task.FromResult(0); 310 | } 311 | 312 | //// IUserSecurityStampStore 313 | 314 | public Task GetSecurityStampAsync(User user) 315 | { 316 | if (user == null) 317 | { 318 | throw new ArgumentNullException("user"); 319 | } 320 | 321 | return Task.FromResult(user.SecurityStamp); 322 | } 323 | 324 | public Task SetSecurityStampAsync(User user, string stamp) 325 | { 326 | if (user == null) 327 | { 328 | throw new ArgumentNullException("user"); 329 | } 330 | 331 | user.SecurityStamp = stamp; 332 | return Task.FromResult(0); 333 | } 334 | 335 | //// IUserEmailStore 336 | 337 | public Task FindByEmailAsync(string email) 338 | { 339 | return this.db.Users 340 | .Include(u => u.Logins).Include(u => u.Roles).Include(u => u.Claims) 341 | .FirstOrDefaultAsync(u => u.Email == email); 342 | } 343 | 344 | public Task GetEmailAsync(User user) 345 | { 346 | if (user == null) 347 | { 348 | throw new ArgumentNullException("user"); 349 | } 350 | 351 | return Task.FromResult(user.Email); 352 | } 353 | 354 | public Task GetEmailConfirmedAsync(User user) 355 | { 356 | if (user == null) 357 | { 358 | throw new ArgumentNullException("user"); 359 | } 360 | 361 | return Task.FromResult(user.EmailConfirmed); 362 | } 363 | 364 | public Task SetEmailAsync(User user, string email) 365 | { 366 | if (user == null) 367 | { 368 | throw new ArgumentNullException("user"); 369 | } 370 | 371 | user.Email = email; 372 | return Task.FromResult(0); 373 | } 374 | 375 | public Task SetEmailConfirmedAsync(User user, bool confirmed) 376 | { 377 | if (user == null) 378 | { 379 | throw new ArgumentNullException("user"); 380 | } 381 | 382 | user.EmailConfirmed = confirmed; 383 | return Task.FromResult(0); 384 | } 385 | 386 | //// IUserPhoneNumberStore 387 | 388 | public Task GetPhoneNumberAsync(User user) 389 | { 390 | if (user == null) 391 | { 392 | throw new ArgumentNullException("user"); 393 | } 394 | 395 | return Task.FromResult(user.PhoneNumber); 396 | } 397 | 398 | public Task GetPhoneNumberConfirmedAsync(User user) 399 | { 400 | if (user == null) 401 | { 402 | throw new ArgumentNullException("user"); 403 | } 404 | 405 | return Task.FromResult(user.PhoneNumberConfirmed); 406 | } 407 | 408 | public Task SetPhoneNumberAsync(User user, string phoneNumber) 409 | { 410 | if (user == null) 411 | { 412 | throw new ArgumentNullException("user"); 413 | } 414 | 415 | user.PhoneNumber = phoneNumber; 416 | return Task.FromResult(0); 417 | } 418 | 419 | public Task SetPhoneNumberConfirmedAsync(User user, bool confirmed) 420 | { 421 | if (user == null) 422 | { 423 | throw new ArgumentNullException("user"); 424 | } 425 | 426 | user.PhoneNumberConfirmed = confirmed; 427 | return Task.FromResult(0); 428 | } 429 | 430 | //// IUserTwoFactorStore 431 | 432 | public Task GetTwoFactorEnabledAsync(User user) 433 | { 434 | if (user == null) 435 | { 436 | throw new ArgumentNullException("user"); 437 | } 438 | 439 | return Task.FromResult(user.TwoFactorEnabled); 440 | } 441 | 442 | public Task SetTwoFactorEnabledAsync(User user, bool enabled) 443 | { 444 | if (user == null) 445 | { 446 | throw new ArgumentNullException("user"); 447 | } 448 | 449 | user.TwoFactorEnabled = enabled; 450 | return Task.FromResult(0); 451 | } 452 | 453 | //// IUserLockoutStore 454 | 455 | public Task GetAccessFailedCountAsync(User user) 456 | { 457 | if (user == null) 458 | { 459 | throw new ArgumentNullException("user"); 460 | } 461 | 462 | return Task.FromResult(user.AccessFailedCount); 463 | } 464 | 465 | public Task GetLockoutEnabledAsync(User user) 466 | { 467 | if (user == null) 468 | { 469 | throw new ArgumentNullException("user"); 470 | } 471 | 472 | return Task.FromResult(user.LockoutEnabled); 473 | } 474 | 475 | public Task GetLockoutEndDateAsync(User user) 476 | { 477 | if (user == null) 478 | { 479 | throw new ArgumentNullException("user"); 480 | } 481 | 482 | return Task.FromResult( 483 | user.LockoutEndDateUtc.HasValue ? 484 | new DateTimeOffset(DateTime.SpecifyKind(user.LockoutEndDateUtc.Value, DateTimeKind.Utc)) : 485 | new DateTimeOffset()); 486 | } 487 | 488 | public Task IncrementAccessFailedCountAsync(User user) 489 | { 490 | if (user == null) 491 | { 492 | throw new ArgumentNullException("user"); 493 | } 494 | 495 | user.AccessFailedCount++; 496 | return Task.FromResult(user.AccessFailedCount); 497 | } 498 | 499 | public Task ResetAccessFailedCountAsync(User user) 500 | { 501 | if (user == null) 502 | { 503 | throw new ArgumentNullException("user"); 504 | } 505 | 506 | user.AccessFailedCount = 0; 507 | return Task.FromResult(0); 508 | } 509 | 510 | public Task SetLockoutEnabledAsync(User user, bool enabled) 511 | { 512 | if (user == null) 513 | { 514 | throw new ArgumentNullException("user"); 515 | } 516 | 517 | user.LockoutEnabled = enabled; 518 | return Task.FromResult(0); 519 | } 520 | 521 | public Task SetLockoutEndDateAsync(User user, DateTimeOffset lockoutEnd) 522 | { 523 | if (user == null) 524 | { 525 | throw new ArgumentNullException("user"); 526 | } 527 | 528 | user.LockoutEndDateUtc = lockoutEnd == DateTimeOffset.MinValue ? null : new DateTime?(lockoutEnd.UtcDateTime); 529 | return Task.FromResult(0); 530 | } 531 | 532 | //// IDisposable 533 | 534 | public void Dispose() 535 | { 536 | this.Dispose(true); 537 | GC.SuppressFinalize(this); 538 | } 539 | 540 | protected virtual void Dispose(bool disposing) 541 | { 542 | if (disposing && this.db != null) 543 | { 544 | this.db.Dispose(); 545 | } 546 | } 547 | } 548 | } 549 | -------------------------------------------------------------------------------- /src/KriaSoft.AspNet.Identity.EntityFramework/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /test/KriaSoft.AspNet.Identity.EntityFramework.Tests/KriaSoft.AspNet.Identity.EntityFramework.Tests.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Debug 5 | AnyCPU 6 | {EDB5DE31-B19F-4105-8150-093CADEEB206} 7 | Library 8 | Properties 9 | KriaSoft.AspNet.Identity.Model.Tests 10 | KriaSoft.AspNet.Identity.Model.Tests 11 | v4.5.1 12 | 512 13 | {3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} 14 | 10.0 15 | $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) 16 | $(ProgramFiles)\Common Files\microsoft shared\VSTT\$(VisualStudioVersion)\UITestExtensionPackages 17 | False 18 | UnitTest 19 | 20 | 21 | true 22 | full 23 | false 24 | bin\Debug\ 25 | DEBUG;TRACE 26 | prompt 27 | 4 28 | 29 | 30 | pdbonly 31 | true 32 | bin\Release\ 33 | TRACE 34 | prompt 35 | 4 36 | 37 | 38 | 39 | ..\..\packages\Microsoft.AspNet.Identity.Core.2.0.0\lib\net45\Microsoft.AspNet.Identity.Core.dll 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | {311feca9-f3ce-49a7-b085-b9dafa25ca0a} 61 | KriaSoft.AspNet.Identity.EntityFramework 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | False 72 | 73 | 74 | False 75 | 76 | 77 | False 78 | 79 | 80 | False 81 | 82 | 83 | 84 | 85 | 86 | 87 | 94 | -------------------------------------------------------------------------------- /test/KriaSoft.AspNet.Identity.EntityFramework.Tests/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) KriaSoft, LLC. All rights reserved. See LICENSE.txt in the project root for license information. 2 | 3 | using System.Reflection; 4 | using System.Runtime.InteropServices; 5 | 6 | // General Information about an assembly is controlled through the following 7 | // set of attributes. Change these attribute values to modify the information 8 | // associated with an assembly. 9 | [assembly: AssemblyTitle("KriaSoft.AspNet.Identity.EntityFramework.Tests")] 10 | [assembly: AssemblyDescription("")] 11 | [assembly: AssemblyConfiguration("")] 12 | [assembly: AssemblyCompany("KriaSoft")] 13 | [assembly: AssemblyProduct("KriaSoft.AspNet.Identity.EntityFramework.Tests")] 14 | [assembly: AssemblyCopyright("Copyright © 2014 KriaSoft")] 15 | [assembly: AssemblyTrademark("")] 16 | [assembly: AssemblyCulture("")] 17 | 18 | // Setting ComVisible to false makes the types in this assembly not visible 19 | // to COM components. If you need to access a type in this assembly from 20 | // COM, set the ComVisible attribute to true on that type. 21 | [assembly: ComVisible(false)] 22 | 23 | // The following GUID is for the ID of the typelib if this project is exposed to COM 24 | [assembly: Guid("dbc81833-d8bb-4ce8-b6c5-2ef6b5bb7f55")] 25 | 26 | // Version information for an assembly consists of the following four values: 27 | // 28 | // Major Version 29 | // Minor Version 30 | // Build Number 31 | // Revision 32 | // 33 | // You can specify all the values or you can default the Build and Revision Numbers 34 | // by using the '*' as shown below: 35 | // [assembly: AssemblyVersion("1.0.*")] 36 | [assembly: AssemblyVersion("1.0.0.0")] 37 | [assembly: AssemblyFileVersion("1.0.0.0")] 38 | -------------------------------------------------------------------------------- /test/KriaSoft.AspNet.Identity.EntityFramework.Tests/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | --------------------------------------------------------------------------------