diff --git a/Abp.Zero.sln b/Abp.Zero.sln
index 6e6c9dee..1325916f 100644
--- a/Abp.Zero.sln
+++ b/Abp.Zero.sln
@@ -1,44 +1,71 @@
Microsoft Visual Studio Solution File, Format Version 12.00
-# Visual Studio 14
-VisualStudioVersion = 14.0.25420.1
+# Visual Studio 15
+VisualStudioVersion = 15.0.26430.6
MinimumVisualStudioVersion = 10.0.40219.1
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{364398C2-9B6A-40B3-9845-23ABFB8D12AB}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{974A8277-6807-4C84-A0EA-B98AEC770EF8}"
ProjectSection(SolutionItems) = preProject
- global.json = global.json
+ appveyor.yml = appveyor.yml
+ common.props = common.props
EndProjectSection
EndProject
-Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Abp.Zero", "src\Abp.Zero\Abp.Zero.xproj", "{E06353A0-8403-44A0-8D57-200D55E2F2C5}"
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{E1AD01DD-1A0D-40DF-AFBE-F2AA3B4160AB}"
EndProject
-Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Abp.Zero.Ldap", "src\Abp.Zero.Ldap\Abp.Zero.Ldap.xproj", "{C28F608B-F34E-411C-8D88-C5D566141735}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Abp.Zero", "src\Abp.Zero\Abp.Zero.csproj", "{E06353A0-8403-44A0-8D57-200D55E2F2C5}"
EndProject
-Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Abp.Zero.EntityFramework", "src\Abp.Zero.EntityFramework\Abp.Zero.EntityFramework.xproj", "{A57787C3-AD9A-40A8-B955-EDA596397429}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Abp.Zero.Ldap", "src\Abp.Zero.Ldap\Abp.Zero.Ldap.csproj", "{C28F608B-F34E-411C-8D88-C5D566141735}"
EndProject
-Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Abp.Zero.NHibernate", "src\Abp.Zero.NHibernate\Abp.Zero.NHibernate.xproj", "{C64C24CD-74CE-47A2-A03C-06F4F78413F1}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Abp.Zero.EntityFramework", "src\Abp.Zero.EntityFramework\Abp.Zero.EntityFramework.csproj", "{A57787C3-AD9A-40A8-B955-EDA596397429}"
EndProject
-Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{E1AD01DD-1A0D-40DF-AFBE-F2AA3B4160AB}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Abp.Zero.NHibernate", "src\Abp.Zero.NHibernate\Abp.Zero.NHibernate.csproj", "{C64C24CD-74CE-47A2-A03C-06F4F78413F1}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Abp.Zero.SampleApp", "test\Abp.Zero.SampleApp\Abp.Zero.SampleApp.csproj", "{667801A0-99A5-414A-8685-A035408BF413}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Abp.Zero.SampleApp.EntityFramework", "test\Abp.Zero.SampleApp.EntityFramework\Abp.Zero.SampleApp.EntityFramework.csproj", "{97670397-EDF9-4968-9A25-0EB71C68D5F8}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Abp.Zero.SampleApp.NHibernateTests", "test\Abp.Zero.SampleApp.NHibernateTests\Abp.Zero.SampleApp.NHibernateTests.csproj", "{FA3E87C5-7273-461C-AE9F-67B416E07949}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Abp.Zero.SampleApp.Tests", "test\Abp.Zero.SampleApp.Tests\Abp.Zero.SampleApp.Tests.csproj", "{41F88D4F-FAB9-4D0A-85E5-C71F8B63B973}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Abp.Zero.EntityFrameworkCore", "src\Abp.Zero.EntityFrameworkCore\Abp.Zero.EntityFrameworkCore.csproj", "{83108E5E-FD31-4762-8854-D795A8FB482F}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Abp.Zero.SampleApp.EntityFrameworkCore", "test\Abp.Zero.SampleApp.EntityFrameworkCore\Abp.Zero.SampleApp.EntityFrameworkCore.csproj", "{76E2CCE7-A61F-4700-9054-9923645E41CC}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Abp.Zero.SampleApp.EntityFrameworkCore.Tests", "test\Abp.Zero.SampleApp.EntityFrameworkCore.Tests\Abp.Zero.SampleApp.EntityFrameworkCore.Tests.csproj", "{9223F076-ECE7-4381-9BBF-F3E33073B91A}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Abp.Zero.SampleApp.EntityFrameworkCore.ConsoleAppTest", "test\Abp.Zero.SampleApp.EntityFrameworkCore.ConsoleAppTest\Abp.Zero.SampleApp.EntityFrameworkCore.ConsoleAppTest.csproj", "{25F73233-3922-4BC0-AC1C-2042613DEC5E}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Abp.Zero.Owin", "src\Abp.Zero.Owin\Abp.Zero.Owin.csproj", "{81D2351F-6CA1-4976-86EB-63946EBD0A36}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Abp.Zero.AspNetCore", "src\Abp.Zero.AspNetCore\Abp.Zero.AspNetCore.csproj", "{8EE2ACFF-CB44-4A7E-8FE7-5709AD245F44}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Abp.ZeroCore", "src\Abp.ZeroCore\Abp.ZeroCore.csproj", "{C5F4218F-2637-4629-B43B-7728D28CB19E}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Abp.Zero.Common", "src\Abp.Zero.Common\Abp.Zero.Common.csproj", "{EABE7BBB-A837-4607-9B0D-BE41E4A0F81F}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Abp.ZeroCore.EntityFrameworkCore", "src\Abp.ZeroCore.EntityFrameworkCore\Abp.ZeroCore.EntityFrameworkCore.csproj", "{39A3807E-4309-43D7-98C1-246547108006}"
EndProject
-Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Abp.Zero.SampleApp", "test\Abp.Zero.SampleApp\Abp.Zero.SampleApp.xproj", "{667801A0-99A5-414A-8685-A035408BF413}"
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "ZeroCore", "ZeroCore", "{A6CB86B2-8C58-42D7-917A-F1DEB29C121A}"
EndProject
-Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Abp.Zero.SampleApp.EntityFramework", "test\Abp.Zero.SampleApp.EntityFramework\Abp.Zero.SampleApp.EntityFramework.xproj", "{97670397-EDF9-4968-9A25-0EB71C68D5F8}"
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Zero", "Zero", "{22551F30-C7C5-40D5-AE24-3D675ABC9B46}"
EndProject
-Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Abp.Zero.SampleApp.NHibernateTests", "test\Abp.Zero.SampleApp.NHibernateTests\Abp.Zero.SampleApp.NHibernateTests.xproj", "{FA3E87C5-7273-461C-AE9F-67B416E07949}"
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Zero", "Zero", "{4A2AFB7B-F4F7-4E47-A8A3-F1F848C9F1B9}"
EndProject
-Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Abp.Zero.SampleApp.Tests", "test\Abp.Zero.SampleApp.Tests\Abp.Zero.SampleApp.Tests.xproj", "{41F88D4F-FAB9-4D0A-85E5-C71F8B63B973}"
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Shared", "Shared", "{12068527-E860-4AC1-88C3-62B435E4BBE5}"
EndProject
-Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Abp.Zero.EntityFrameworkCore", "src\Abp.Zero.EntityFrameworkCore\Abp.Zero.EntityFrameworkCore.xproj", "{83108E5E-FD31-4762-8854-D795A8FB482F}"
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Abp.ZeroCore.IdentityServer4", "src\Abp.ZeroCore.IdentityServer4\Abp.ZeroCore.IdentityServer4.csproj", "{41608BBD-C619-4579-AA32-CA6FC6B7F810}"
EndProject
-Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Abp.Zero.SampleApp.EntityFrameworkCore", "test\Abp.Zero.SampleApp.EntityFrameworkCore\Abp.Zero.SampleApp.EntityFrameworkCore.xproj", "{76E2CCE7-A61F-4700-9054-9923645E41CC}"
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "ZeroCore", "ZeroCore", "{01532A9D-77F4-477E-A43E-0E7078E4E9DD}"
EndProject
-Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Abp.Zero.SampleApp.EntityFrameworkCore.Tests", "test\Abp.Zero.SampleApp.EntityFrameworkCore.Tests\Abp.Zero.SampleApp.EntityFrameworkCore.Tests.xproj", "{9223F076-ECE7-4381-9BBF-F3E33073B91A}"
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Abp.ZeroCore.IdentityServer4.Tests", "test\Abp.ZeroCore.IdentityServer4.Tests\Abp.ZeroCore.IdentityServer4.Tests.csproj", "{4B03D73D-D453-4FCB-95C8-F23D1B300DE7}"
EndProject
-Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Abp.Zero.SampleApp.EntityFrameworkCore.ConsoleAppTest", "test\Abp.Zero.SampleApp.EntityFrameworkCore.ConsoleAppTest\Abp.Zero.SampleApp.EntityFrameworkCore.ConsoleAppTest.xproj", "{25F73233-3922-4BC0-AC1C-2042613DEC5E}"
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Abp.ZeroCore.SampleApp", "test\Abp.ZeroCore.SampleApp\Abp.ZeroCore.SampleApp.csproj", "{D1084B66-375B-433A-9742-FD4A703994E1}"
EndProject
-Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Abp.Zero.Owin", "src\Abp.Zero.Owin\Abp.Zero.Owin.xproj", "{81D2351F-6CA1-4976-86EB-63946EBD0A36}"
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Abp.ZeroCore.Tests", "test\Abp.ZeroCore.Tests\Abp.ZeroCore.Tests.csproj", "{72427FA6-BC94-42AA-B9AC-3CF2E257E41B}"
EndProject
-Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Abp.Zero.AspNetCore", "src\Abp.Zero.AspNetCore\Abp.Zero.AspNetCore.xproj", "{8EE2ACFF-CB44-4A7E-8FE7-5709AD245F44}"
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Abp.ZeroCore.IdentityServer4.EntityFrameworkCore", "src\Abp.ZeroCore.IdentityServer4.EntityFrameworkCore\Abp.ZeroCore.IdentityServer4.EntityFrameworkCore.csproj", "{F4A295A8-3FE6-4397-B3F5-0CFF9EC483E9}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@@ -102,24 +129,69 @@ Global
{8EE2ACFF-CB44-4A7E-8FE7-5709AD245F44}.Debug|Any CPU.Build.0 = Debug|Any CPU
{8EE2ACFF-CB44-4A7E-8FE7-5709AD245F44}.Release|Any CPU.ActiveCfg = Release|Any CPU
{8EE2ACFF-CB44-4A7E-8FE7-5709AD245F44}.Release|Any CPU.Build.0 = Release|Any CPU
+ {C5F4218F-2637-4629-B43B-7728D28CB19E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {C5F4218F-2637-4629-B43B-7728D28CB19E}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {C5F4218F-2637-4629-B43B-7728D28CB19E}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {C5F4218F-2637-4629-B43B-7728D28CB19E}.Release|Any CPU.Build.0 = Release|Any CPU
+ {EABE7BBB-A837-4607-9B0D-BE41E4A0F81F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {EABE7BBB-A837-4607-9B0D-BE41E4A0F81F}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {EABE7BBB-A837-4607-9B0D-BE41E4A0F81F}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {EABE7BBB-A837-4607-9B0D-BE41E4A0F81F}.Release|Any CPU.Build.0 = Release|Any CPU
+ {39A3807E-4309-43D7-98C1-246547108006}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {39A3807E-4309-43D7-98C1-246547108006}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {39A3807E-4309-43D7-98C1-246547108006}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {39A3807E-4309-43D7-98C1-246547108006}.Release|Any CPU.Build.0 = Release|Any CPU
+ {41608BBD-C619-4579-AA32-CA6FC6B7F810}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {41608BBD-C619-4579-AA32-CA6FC6B7F810}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {41608BBD-C619-4579-AA32-CA6FC6B7F810}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {41608BBD-C619-4579-AA32-CA6FC6B7F810}.Release|Any CPU.Build.0 = Release|Any CPU
+ {4B03D73D-D453-4FCB-95C8-F23D1B300DE7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {4B03D73D-D453-4FCB-95C8-F23D1B300DE7}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {4B03D73D-D453-4FCB-95C8-F23D1B300DE7}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {4B03D73D-D453-4FCB-95C8-F23D1B300DE7}.Release|Any CPU.Build.0 = Release|Any CPU
+ {D1084B66-375B-433A-9742-FD4A703994E1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {D1084B66-375B-433A-9742-FD4A703994E1}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {D1084B66-375B-433A-9742-FD4A703994E1}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {D1084B66-375B-433A-9742-FD4A703994E1}.Release|Any CPU.Build.0 = Release|Any CPU
+ {72427FA6-BC94-42AA-B9AC-3CF2E257E41B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {72427FA6-BC94-42AA-B9AC-3CF2E257E41B}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {72427FA6-BC94-42AA-B9AC-3CF2E257E41B}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {72427FA6-BC94-42AA-B9AC-3CF2E257E41B}.Release|Any CPU.Build.0 = Release|Any CPU
+ {F4A295A8-3FE6-4397-B3F5-0CFF9EC483E9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {F4A295A8-3FE6-4397-B3F5-0CFF9EC483E9}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {F4A295A8-3FE6-4397-B3F5-0CFF9EC483E9}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {F4A295A8-3FE6-4397-B3F5-0CFF9EC483E9}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
- {E06353A0-8403-44A0-8D57-200D55E2F2C5} = {364398C2-9B6A-40B3-9845-23ABFB8D12AB}
- {C28F608B-F34E-411C-8D88-C5D566141735} = {364398C2-9B6A-40B3-9845-23ABFB8D12AB}
- {A57787C3-AD9A-40A8-B955-EDA596397429} = {364398C2-9B6A-40B3-9845-23ABFB8D12AB}
- {C64C24CD-74CE-47A2-A03C-06F4F78413F1} = {364398C2-9B6A-40B3-9845-23ABFB8D12AB}
- {667801A0-99A5-414A-8685-A035408BF413} = {E1AD01DD-1A0D-40DF-AFBE-F2AA3B4160AB}
- {97670397-EDF9-4968-9A25-0EB71C68D5F8} = {E1AD01DD-1A0D-40DF-AFBE-F2AA3B4160AB}
- {FA3E87C5-7273-461C-AE9F-67B416E07949} = {E1AD01DD-1A0D-40DF-AFBE-F2AA3B4160AB}
- {41F88D4F-FAB9-4D0A-85E5-C71F8B63B973} = {E1AD01DD-1A0D-40DF-AFBE-F2AA3B4160AB}
- {83108E5E-FD31-4762-8854-D795A8FB482F} = {364398C2-9B6A-40B3-9845-23ABFB8D12AB}
- {76E2CCE7-A61F-4700-9054-9923645E41CC} = {E1AD01DD-1A0D-40DF-AFBE-F2AA3B4160AB}
- {9223F076-ECE7-4381-9BBF-F3E33073B91A} = {E1AD01DD-1A0D-40DF-AFBE-F2AA3B4160AB}
- {25F73233-3922-4BC0-AC1C-2042613DEC5E} = {E1AD01DD-1A0D-40DF-AFBE-F2AA3B4160AB}
- {81D2351F-6CA1-4976-86EB-63946EBD0A36} = {364398C2-9B6A-40B3-9845-23ABFB8D12AB}
- {8EE2ACFF-CB44-4A7E-8FE7-5709AD245F44} = {364398C2-9B6A-40B3-9845-23ABFB8D12AB}
+ {E06353A0-8403-44A0-8D57-200D55E2F2C5} = {22551F30-C7C5-40D5-AE24-3D675ABC9B46}
+ {C28F608B-F34E-411C-8D88-C5D566141735} = {12068527-E860-4AC1-88C3-62B435E4BBE5}
+ {A57787C3-AD9A-40A8-B955-EDA596397429} = {22551F30-C7C5-40D5-AE24-3D675ABC9B46}
+ {C64C24CD-74CE-47A2-A03C-06F4F78413F1} = {22551F30-C7C5-40D5-AE24-3D675ABC9B46}
+ {667801A0-99A5-414A-8685-A035408BF413} = {4A2AFB7B-F4F7-4E47-A8A3-F1F848C9F1B9}
+ {97670397-EDF9-4968-9A25-0EB71C68D5F8} = {4A2AFB7B-F4F7-4E47-A8A3-F1F848C9F1B9}
+ {FA3E87C5-7273-461C-AE9F-67B416E07949} = {4A2AFB7B-F4F7-4E47-A8A3-F1F848C9F1B9}
+ {41F88D4F-FAB9-4D0A-85E5-C71F8B63B973} = {4A2AFB7B-F4F7-4E47-A8A3-F1F848C9F1B9}
+ {83108E5E-FD31-4762-8854-D795A8FB482F} = {22551F30-C7C5-40D5-AE24-3D675ABC9B46}
+ {76E2CCE7-A61F-4700-9054-9923645E41CC} = {4A2AFB7B-F4F7-4E47-A8A3-F1F848C9F1B9}
+ {9223F076-ECE7-4381-9BBF-F3E33073B91A} = {4A2AFB7B-F4F7-4E47-A8A3-F1F848C9F1B9}
+ {25F73233-3922-4BC0-AC1C-2042613DEC5E} = {4A2AFB7B-F4F7-4E47-A8A3-F1F848C9F1B9}
+ {81D2351F-6CA1-4976-86EB-63946EBD0A36} = {22551F30-C7C5-40D5-AE24-3D675ABC9B46}
+ {8EE2ACFF-CB44-4A7E-8FE7-5709AD245F44} = {22551F30-C7C5-40D5-AE24-3D675ABC9B46}
+ {C5F4218F-2637-4629-B43B-7728D28CB19E} = {A6CB86B2-8C58-42D7-917A-F1DEB29C121A}
+ {EABE7BBB-A837-4607-9B0D-BE41E4A0F81F} = {12068527-E860-4AC1-88C3-62B435E4BBE5}
+ {39A3807E-4309-43D7-98C1-246547108006} = {A6CB86B2-8C58-42D7-917A-F1DEB29C121A}
+ {A6CB86B2-8C58-42D7-917A-F1DEB29C121A} = {364398C2-9B6A-40B3-9845-23ABFB8D12AB}
+ {22551F30-C7C5-40D5-AE24-3D675ABC9B46} = {364398C2-9B6A-40B3-9845-23ABFB8D12AB}
+ {4A2AFB7B-F4F7-4E47-A8A3-F1F848C9F1B9} = {E1AD01DD-1A0D-40DF-AFBE-F2AA3B4160AB}
+ {12068527-E860-4AC1-88C3-62B435E4BBE5} = {364398C2-9B6A-40B3-9845-23ABFB8D12AB}
+ {41608BBD-C619-4579-AA32-CA6FC6B7F810} = {A6CB86B2-8C58-42D7-917A-F1DEB29C121A}
+ {01532A9D-77F4-477E-A43E-0E7078E4E9DD} = {E1AD01DD-1A0D-40DF-AFBE-F2AA3B4160AB}
+ {4B03D73D-D453-4FCB-95C8-F23D1B300DE7} = {01532A9D-77F4-477E-A43E-0E7078E4E9DD}
+ {D1084B66-375B-433A-9742-FD4A703994E1} = {01532A9D-77F4-477E-A43E-0E7078E4E9DD}
+ {72427FA6-BC94-42AA-B9AC-3CF2E257E41B} = {01532A9D-77F4-477E-A43E-0E7078E4E9DD}
+ {F4A295A8-3FE6-4397-B3F5-0CFF9EC483E9} = {A6CB86B2-8C58-42D7-917A-F1DEB29C121A}
EndGlobalSection
EndGlobal
diff --git a/README.md b/README.md
index 5a9db717..90519d97 100644
--- a/README.md
+++ b/README.md
@@ -1,21 +1,3 @@
-ASP.NET Boilerplate - Module Zero
-===========
+**IMPORTANT NOTICE:** This repository is moved to ASP.NET Boilerplate repository and it is deprecated now. Please refer to ASP.NET Boilerplate repository.
-AppVeyor: [](https://ci.appveyor.com/project/hikalkan/module-zero)
-What is 'module zero'
-----------
-
-Module-Zero is the module that implements abstract concepts of ASP.NET Boilerplate framework, also adds some useful stuff for enterprise web applications:
-
-See http://www.aspnetboilerplate.com/Pages/Documents/Zero/Overall for more information.
-
-How to start?
--------------------
-Follow the documentation to start: http://www.aspnetboilerplate.com/Pages/Documents/Zero/Installation
-
-Sample Projects
--------------------
-
-* https://github.com/aspnetboilerplate/eventcloud
-* https://github.com/aspnetboilerplate/questions-answers
diff --git a/appveyor.yml b/appveyor.yml
new file mode 100644
index 00000000..af2aae6f
--- /dev/null
+++ b/appveyor.yml
@@ -0,0 +1,36 @@
+configuration: Release
+version: 2.0.0-beta{build}
+image: Visual Studio 2017
+
+nuget:
+ disable_publish_on_pr: true
+
+before_build:
+- cmd: set PATH=C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\MSBuild\15.0\Bin;C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\MSBuild\15.0\Bin;C:\Program Files (x86)\Microsoft Visual Studio\2017\Professional\MSBuild\15.0\Bin;%PATH%
+- cmd: nuget install nuget.commandline -source https://dotnet.myget.org/F/nuget-build -prerelease -excludeversion
+- cmd: set PATH=%appveyor_build_folder%\NuGet.CommandLine\tools;%PATH%
+- cmd: dotnet.exe restore
+
+after_build:
+- ps: >-
+ $versionSuffix=(Get-Item Env:APPVEYOR_BUILD_NUMBER).Value
+
+ Set-Location "nupkg"
+
+ .\pack.ps1 -versionSuffix "$versionSuffix"
+
+build:
+ verbosity: minimal
+
+pull_requests:
+ do_not_increment_build_number: true
+
+test:
+ assemblies:
+ - test\Abp.Zero.SampleApp.Tests\bin\Release\net452\Abp.Zero.SampleApp.Tests.dll
+ # - test\Abp.Zero.SampleApp.EntityFrameworkCore.Tests\bin\Release\net461\Abp.Zero.SampleApp.EntityFrameworkCore.Tests.dll
+ # - test\Abp.Zero.SampleApp.NHibernateTests\bin\Release\net452\Abp.Zero.SampleApp.NHibernateTests.dll
+
+artifacts:
+- path: nupkg\*.nupkg
+ name: nuget-packages
\ No newline at end of file
diff --git a/common.props b/common.props
new file mode 100644
index 00000000..04f695e1
--- /dev/null
+++ b/common.props
@@ -0,0 +1,19 @@
+
+
+ 2.3.0
+ $(NoWarn);CS1591
+ http://www.aspnetboilerplate.com/images/abp_nupkg.png
+ http://www.aspnetboilerplate.com/
+ https://github.com/aspnetboilerplate/aspnetboilerplate/blob/master/LICENSE
+ git
+ https://github.com/aspnetboilerplate/aspnetboilerplate
+
+
+
+ NET452
+
+
+
+
+
+
\ No newline at end of file
diff --git a/doc/img/module-zero-core-template.png b/doc/img/module-zero-core-template.png
new file mode 100644
index 00000000..3cecbf53
Binary files /dev/null and b/doc/img/module-zero-core-template.png differ
diff --git a/global.json b/global.json
deleted file mode 100644
index 5e6422e6..00000000
--- a/global.json
+++ /dev/null
@@ -1,3 +0,0 @@
-{
- "projects": [ "src", "test" ]
-}
diff --git a/nupkg/pack.bat b/nupkg/pack.bat
deleted file mode 100644
index dbd246c5..00000000
--- a/nupkg/pack.bat
+++ /dev/null
@@ -1,14 +0,0 @@
-REM "..\tools\gitlink\GitLink.exe" ..\ -u https://github.com/aspnetboilerplate/module-zero -c release
-
-@ECHO OFF
-SET /P VERSION_SUFFIX=Please enter version-suffix (can be left empty):
-
-dotnet "pack" "..\src\Abp.Zero" -c "Release" -o "." --version-suffix "%VERSION_SUFFIX%"
-dotnet "pack" "..\src\Abp.Zero.Owin" -c "Release" -o "." --version-suffix "%VERSION_SUFFIX%"
-dotnet "pack" "..\src\Abp.Zero.AspNetCore" -c "Release" -o "." --version-suffix "%VERSION_SUFFIX%"
-dotnet "pack" "..\src\Abp.Zero.Ldap" -c "Release" -o "." --version-suffix "%VERSION_SUFFIX%"
-dotnet "pack" "..\src\Abp.Zero.EntityFramework" -c "Release" -o "." --version-suffix "%VERSION_SUFFIX%"
-dotnet "pack" "..\src\Abp.Zero.EntityFrameworkCore" -c "Release" -o "." --version-suffix "%VERSION_SUFFIX%"
-dotnet "pack" "..\src\Abp.Zero.NHibernate" -c "Release" -o "." --version-suffix "%VERSION_SUFFIX%"
-
-pause
diff --git a/nupkg/pack.ps1 b/nupkg/pack.ps1
new file mode 100644
index 00000000..ce3e4452
--- /dev/null
+++ b/nupkg/pack.ps1
@@ -0,0 +1,43 @@
+# Paths
+$packFolder = (Get-Item -Path "./" -Verbose).FullName
+$slnPath = Join-Path $packFolder "../"
+$srcPath = Join-Path $slnPath "src"
+
+# List of projects
+$projects = (
+ "Abp.Zero.Common",
+ "Abp.Zero.Ldap",
+ "Abp.Zero",
+ "Abp.Zero.Owin",
+ "Abp.Zero.AspNetCore",
+ "Abp.Zero.EntityFramework",
+ "Abp.Zero.EntityFrameworkCore",
+ "Abp.Zero.NHibernate",
+ "Abp.ZeroCore",
+ "Abp.ZeroCore.EntityFrameworkCore",
+ "Abp.ZeroCore.IdentityServer4",
+ "Abp.ZeroCore.IdentityServer4.EntityFrameworkCore"
+)
+
+# Rebuild solution
+Set-Location $slnPath
+& dotnet restore
+
+# Copy all nuget packages to the pack folder
+foreach($project in $projects) {
+
+ $projectFolder = Join-Path $srcPath $project
+
+ # Create nuget pack
+ Set-Location $projectFolder
+ Remove-Item -Recurse (Join-Path $projectFolder "bin/Release")
+ & dotnet msbuild /t:pack /p:Configuration=Release /p:IncludeSymbols=true /p:SourceLinkCreate=true
+
+ # Copy nuget package
+ $projectPackPath = Join-Path $projectFolder ("/bin/Release/" + $project + ".*.nupkg")
+ Move-Item $projectPackPath $packFolder
+
+}
+
+# Go back to the pack folder
+Set-Location $packFolder
\ No newline at end of file
diff --git a/src/Abp.Zero.AspNetCore/Abp.Zero.AspNetCore.csproj b/src/Abp.Zero.AspNetCore/Abp.Zero.AspNetCore.csproj
new file mode 100644
index 00000000..b73e2dba
--- /dev/null
+++ b/src/Abp.Zero.AspNetCore/Abp.Zero.AspNetCore.csproj
@@ -0,0 +1,33 @@
+
+
+
+
+
+ net46
+ true
+ Abp.Zero.AspNetCore
+ Abp.Zero.AspNetCore
+ asp.net;asp.net mvc;boilerplate;application framework;web framework;framework;domain driven design;multitenancy;user management;role management;identity;aspnet core
+ false
+ false
+ false
+
+
+
+
+ lib/net46/
+ true
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Abp.Zero.AspNetCore/Abp.Zero.AspNetCore.xproj b/src/Abp.Zero.AspNetCore/Abp.Zero.AspNetCore.xproj
deleted file mode 100644
index 8a819dc2..00000000
--- a/src/Abp.Zero.AspNetCore/Abp.Zero.AspNetCore.xproj
+++ /dev/null
@@ -1,21 +0,0 @@
-
-
-
- 14.0
- $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)
-
-
-
-
- 8ee2acff-cb44-4a7e-8fe7-5709ad245f44
- Abp.Zero.AspNetCore
- .\obj
- .\bin\
- v4.6.1
-
-
-
- 2.0
-
-
-
diff --git a/src/Abp.Zero.AspNetCore/AbpZeroAspNetCoreModule.cs b/src/Abp.Zero.AspNetCore/AbpZeroAspNetCoreModule.cs
index 837c10fd..6f3b3a0c 100644
--- a/src/Abp.Zero.AspNetCore/AbpZeroAspNetCoreModule.cs
+++ b/src/Abp.Zero.AspNetCore/AbpZeroAspNetCoreModule.cs
@@ -1,4 +1,6 @@
using System.Reflection;
+using Abp.Authorization.Users;
+using Abp.Configuration.Startup;
using Abp.Modules;
namespace Abp.Zero.AspNetCore
@@ -9,6 +11,7 @@ public class AbpZeroAspNetCoreModule : AbpModule
public override void PreInitialize()
{
IocManager.Register();
+ Configuration.ReplaceService();
}
public override void Initialize()
diff --git a/src/Abp.Zero.AspNetCore/AspNetCoreUserTokenProviderAccessor.cs b/src/Abp.Zero.AspNetCore/AspNetCoreUserTokenProviderAccessor.cs
new file mode 100644
index 00000000..53244835
--- /dev/null
+++ b/src/Abp.Zero.AspNetCore/AspNetCoreUserTokenProviderAccessor.cs
@@ -0,0 +1,22 @@
+using Abp.Authorization.Users;
+using Microsoft.AspNet.Identity;
+using Microsoft.AspNetCore.DataProtection;
+
+namespace Abp.Zero.AspNetCore
+{
+ public class AspNetCoreUserTokenProviderAccessor : IUserTokenProviderAccessor
+ {
+ private readonly IDataProtectionProvider _dataProtectionProvider;
+
+ public AspNetCoreUserTokenProviderAccessor(IDataProtectionProvider dataProtectionProvider)
+ {
+ _dataProtectionProvider = dataProtectionProvider;
+ }
+
+ public IUserTokenProvider GetUserTokenProviderOrNull()
+ where TUser : AbpUser
+ {
+ return new DataProtectorUserTokenProvider(_dataProtectionProvider.CreateProtector("ASP.NET Identity"));
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Abp.Zero.AspNetCore/DataProtectorUserTokenProvider.cs b/src/Abp.Zero.AspNetCore/DataProtectorUserTokenProvider.cs
new file mode 100644
index 00000000..6645f800
--- /dev/null
+++ b/src/Abp.Zero.AspNetCore/DataProtectorUserTokenProvider.cs
@@ -0,0 +1,120 @@
+using System;
+using System.Globalization;
+using System.IO;
+using System.Threading.Tasks;
+using Abp.Zero.AspNetCore.Internal;
+using Microsoft.AspNet.Identity;
+using Microsoft.AspNetCore.DataProtection;
+
+namespace Abp.Zero.AspNetCore
+{
+ public class DataProtectorUserTokenProvider : IUserTokenProvider
+ where TUser : class, IUser
+ {
+ public IDataProtector Protector { get; }
+
+ public TimeSpan TokenLifespan { get; set; }
+
+ public DataProtectorUserTokenProvider(IDataProtector protector)
+ {
+ if (protector == null)
+ {
+ throw new ArgumentNullException(nameof(protector));
+ }
+
+ Protector = protector;
+ TokenLifespan = TimeSpan.FromDays(1.0);
+ }
+
+ public async Task GenerateAsync(string purpose, UserManager manager, TUser user)
+ {
+ if (user == null)
+ {
+ throw new ArgumentNullException(nameof(user));
+ }
+
+ using (var ms = new MemoryStream())
+ {
+ using (var binaryWriter = ms.CreateWriter())
+ {
+ binaryWriter.Write(DateTimeOffset.UtcNow);
+ binaryWriter.Write(Convert.ToString((object)user.Id, (IFormatProvider)CultureInfo.InvariantCulture));
+ binaryWriter.Write(purpose ?? "");
+
+ if (manager.SupportsUserSecurityStamp)
+ {
+ binaryWriter.Write(await manager.GetSecurityStampAsync(user.Id));
+ }
+ else
+ {
+ binaryWriter.Write("");
+ }
+ }
+
+ return Convert.ToBase64String(Protector.Protect(ms.ToArray()));
+ }
+ }
+
+ public Task IsValidProviderForUserAsync(UserManager manager, TUser user)
+ {
+ return Task.FromResult(true);
+ }
+
+ public Task NotifyAsync(string token, UserManager manager, TUser user)
+ {
+ return Task.FromResult(0);
+ }
+
+ public async Task ValidateAsync(string purpose, string token, UserManager manager, TUser user)
+ {
+ try
+ {
+ var unprotectedData = this.Protector.Unprotect(Convert.FromBase64String(token));
+ using (var ms = new MemoryStream(unprotectedData))
+ {
+ using (var binaryReader = ms.CreateReader())
+ {
+ var creationTime = binaryReader.ReadDateTimeOffset();
+ var expirationTime = creationTime + TokenLifespan;
+ if (expirationTime < DateTimeOffset.UtcNow)
+ {
+ return false;
+ }
+
+ var userId = binaryReader.ReadString();
+ if (!string.Equals(userId, Convert.ToString((object) user.Id, CultureInfo.InvariantCulture)))
+ {
+ return false;
+ }
+
+ var purp = binaryReader.ReadString();
+ if (!string.Equals(purp, purpose))
+ {
+ return false;
+ }
+
+ var stamp = binaryReader.ReadString();
+ if (binaryReader.PeekChar() != -1)
+ {
+ return false;
+ }
+
+ if (!manager.SupportsUserSecurityStamp)
+ {
+ return stamp == "";
+ }
+
+ var expectedStamp = await manager.GetSecurityStampAsync(user.Id);
+
+ return stamp == expectedStamp;
+ }
+ }
+ }
+ catch
+ {
+ }
+
+ return false;
+ }
+ }
+}
diff --git a/src/Abp.Zero.AspNetCore/Internal/StreamExtensions.cs b/src/Abp.Zero.AspNetCore/Internal/StreamExtensions.cs
new file mode 100644
index 00000000..af4f5609
--- /dev/null
+++ b/src/Abp.Zero.AspNetCore/Internal/StreamExtensions.cs
@@ -0,0 +1,31 @@
+using System;
+using System.IO;
+using System.Text;
+
+namespace Abp.Zero.AspNetCore.Internal
+{
+ internal static class StreamExtensions
+ {
+ internal static readonly Encoding DefaultEncoding = new UTF8Encoding(false, true);
+
+ public static BinaryReader CreateReader(this Stream stream)
+ {
+ return new BinaryReader(stream, DefaultEncoding, true);
+ }
+
+ public static BinaryWriter CreateWriter(this Stream stream)
+ {
+ return new BinaryWriter(stream, DefaultEncoding, true);
+ }
+
+ public static DateTimeOffset ReadDateTimeOffset(this BinaryReader reader)
+ {
+ return new DateTimeOffset(reader.ReadInt64(), TimeSpan.Zero);
+ }
+
+ public static void Write(this BinaryWriter writer, DateTimeOffset value)
+ {
+ writer.Write(value.UtcTicks);
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Abp.Zero.AspNetCore/project.json b/src/Abp.Zero.AspNetCore/project.json
deleted file mode 100644
index e7145a45..00000000
--- a/src/Abp.Zero.AspNetCore/project.json
+++ /dev/null
@@ -1,39 +0,0 @@
-{
- "version": "1.0.0.0-*",
-
- "dependencies": {
- "Abp.Zero": "1.0.0.0-*",
- "Microsoft.AspNetCore.Mvc": "1.0.0"
- },
-
- "frameworks": {
- "net461": {
- }
- },
-
- "buildOptions": {
- "nowarn": [
- "CS1591"
- ],
- "xmlDoc": true
- },
-
- "packOptions": {
- "summary": "ASP.NET Boilerplate - Module Zero - ASP.NET Core Adapter.",
- "tags": [ "asp.net", "asp.net mvc", "boilerplate", "application framework", "web framework", "framework", "domain driven design", "multitenancy", "user management", "role management", "identity", "aspnet core" ],
- "owners": [ "Halil İbrahim Kalkan" ],
- "iconUrl": "http://www.aspnetboilerplate.com/images/abp_nupkg.png",
- "projectUrl": "http://www.aspnetboilerplate.com/",
- "licenseUrl": "https://github.com/aspnetboilerplate/module-zero/blob/master/LICENSE",
- "requireLicenseAcceptance": false,
- "repository": {
- "type": "git",
- "url": "https://github.com/aspnetboilerplate/module-zero"
- },
- "files": {
- "mappings": {
- "lib/net461/": "bin/Release/net461/Abp.Zero.AspNetCore.pdb"
- }
- }
- }
-}
diff --git a/src/Abp.Zero.Common/Abp.Zero.Common.csproj b/src/Abp.Zero.Common/Abp.Zero.Common.csproj
new file mode 100644
index 00000000..d7b6be64
--- /dev/null
+++ b/src/Abp.Zero.Common/Abp.Zero.Common.csproj
@@ -0,0 +1,40 @@
+
+
+
+
+
+ net46;netstandard1.6
+ true
+ Abp.Zero.Common
+ Abp.Zero.Common
+ asp.net;asp.net mvc;boilerplate;application framework;web framework;framework;domain driven design;multitenancy;user management;role management;identity;aspnet core
+ false
+ false
+ false
+ Abp
+
+
+
+
+
+
+
+
+
+
+
+
+ lib/net46/
+ true
+
+
+ lib/netstandard1.6/
+ true
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/Abp.Zero/Application/Editions/AbpEditionManager.cs b/src/Abp.Zero.Common/Application/Editions/AbpEditionManager.cs
similarity index 93%
rename from src/Abp.Zero/Application/Editions/AbpEditionManager.cs
rename to src/Abp.Zero.Common/Application/Editions/AbpEditionManager.cs
index 462dd7b0..8779b85d 100644
--- a/src/Abp.Zero/Application/Editions/AbpEditionManager.cs
+++ b/src/Abp.Zero.Common/Application/Editions/AbpEditionManager.cs
@@ -1,92 +1,92 @@
-using System.Collections.Generic;
-using System.Linq;
-using System.Threading.Tasks;
-using Abp.Application.Features;
-using Abp.Collections.Extensions;
-using Abp.Domain.Repositories;
-using Abp.Domain.Services;
-using Abp.Runtime.Caching;
-
-namespace Abp.Application.Editions
-{
- public abstract class AbpEditionManager : IDomainService
- {
- private readonly IAbpZeroFeatureValueStore _featureValueStore;
-
- public IQueryable Editions => EditionRepository.GetAll();
-
- public ICacheManager CacheManager { get; set; }
-
- public IFeatureManager FeatureManager { get; set; }
-
- protected IRepository EditionRepository { get; set; }
-
- protected AbpEditionManager(
- IRepository editionRepository,
- IAbpZeroFeatureValueStore featureValueStore)
- {
- _featureValueStore = featureValueStore;
- EditionRepository = editionRepository;
- }
-
- public virtual Task GetFeatureValueOrNullAsync(int editionId, string featureName)
- {
- return _featureValueStore.GetEditionValueOrNullAsync(editionId, featureName);
- }
-
- public virtual Task SetFeatureValueAsync(int editionId, string featureName, string value)
- {
- return _featureValueStore.SetEditionFeatureValueAsync(editionId, featureName, value);
- }
-
- public virtual async Task> GetFeatureValuesAsync(int editionId)
- {
- var values = new List();
-
- foreach (var feature in FeatureManager.GetAll())
- {
- values.Add(new NameValue(feature.Name, await GetFeatureValueOrNullAsync(editionId, feature.Name) ?? feature.DefaultValue));
- }
-
- return values;
- }
-
- public virtual async Task SetFeatureValuesAsync(int editionId, params NameValue[] values)
- {
- if (values.IsNullOrEmpty())
- {
- return;
- }
-
- foreach (var value in values)
- {
- await SetFeatureValueAsync(editionId, value.Name, value.Value);
- }
- }
-
- public virtual Task CreateAsync(Edition edition)
- {
- return EditionRepository.InsertAsync(edition);
- }
-
- public virtual Task FindByNameAsync(string name)
- {
- return EditionRepository.FirstOrDefaultAsync(edition => edition.Name == name);
- }
-
- public virtual Task FindByIdAsync(int id)
- {
- return EditionRepository.FirstOrDefaultAsync(id);
- }
-
- public virtual Task GetByIdAsync(int id)
- {
- return EditionRepository.GetAsync(id);
- }
-
- public virtual Task DeleteAsync(Edition edition)
- {
- return EditionRepository.DeleteAsync(edition);
- }
- }
-}
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+using Abp.Application.Features;
+using Abp.Collections.Extensions;
+using Abp.Domain.Repositories;
+using Abp.Domain.Services;
+using Abp.Runtime.Caching;
+
+namespace Abp.Application.Editions
+{
+ public class AbpEditionManager : IDomainService
+ {
+ private readonly IAbpZeroFeatureValueStore _featureValueStore;
+
+ public IQueryable Editions => EditionRepository.GetAll();
+
+ public ICacheManager CacheManager { get; set; }
+
+ public IFeatureManager FeatureManager { get; set; }
+
+ protected IRepository EditionRepository { get; set; }
+
+ public AbpEditionManager(
+ IRepository editionRepository,
+ IAbpZeroFeatureValueStore featureValueStore)
+ {
+ _featureValueStore = featureValueStore;
+ EditionRepository = editionRepository;
+ }
+
+ public virtual Task GetFeatureValueOrNullAsync(int editionId, string featureName)
+ {
+ return _featureValueStore.GetEditionValueOrNullAsync(editionId, featureName);
+ }
+
+ public virtual Task SetFeatureValueAsync(int editionId, string featureName, string value)
+ {
+ return _featureValueStore.SetEditionFeatureValueAsync(editionId, featureName, value);
+ }
+
+ public virtual async Task> GetFeatureValuesAsync(int editionId)
+ {
+ var values = new List();
+
+ foreach (var feature in FeatureManager.GetAll())
+ {
+ values.Add(new NameValue(feature.Name, await GetFeatureValueOrNullAsync(editionId, feature.Name) ?? feature.DefaultValue));
+ }
+
+ return values;
+ }
+
+ public virtual async Task SetFeatureValuesAsync(int editionId, params NameValue[] values)
+ {
+ if (values.IsNullOrEmpty())
+ {
+ return;
+ }
+
+ foreach (var value in values)
+ {
+ await SetFeatureValueAsync(editionId, value.Name, value.Value);
+ }
+ }
+
+ public virtual Task CreateAsync(Edition edition)
+ {
+ return EditionRepository.InsertAsync(edition);
+ }
+
+ public virtual Task FindByNameAsync(string name)
+ {
+ return EditionRepository.FirstOrDefaultAsync(edition => edition.Name == name);
+ }
+
+ public virtual Task FindByIdAsync(int id)
+ {
+ return EditionRepository.FirstOrDefaultAsync(id);
+ }
+
+ public virtual Task GetByIdAsync(int id)
+ {
+ return EditionRepository.GetAsync(id);
+ }
+
+ public virtual Task DeleteAsync(Edition edition)
+ {
+ return EditionRepository.DeleteAsync(edition);
+ }
+ }
+}
diff --git a/src/Abp.Zero/Application/Editions/Edition.cs b/src/Abp.Zero.Common/Application/Editions/Edition.cs
similarity index 96%
rename from src/Abp.Zero/Application/Editions/Edition.cs
rename to src/Abp.Zero.Common/Application/Editions/Edition.cs
index 9ac9dc43..56cc1f92 100644
--- a/src/Abp.Zero/Application/Editions/Edition.cs
+++ b/src/Abp.Zero.Common/Application/Editions/Edition.cs
@@ -1,51 +1,51 @@
-using System;
-using System.ComponentModel.DataAnnotations;
-using System.ComponentModel.DataAnnotations.Schema;
-using Abp.Domain.Entities.Auditing;
-using Abp.MultiTenancy;
-
-namespace Abp.Application.Editions
-{
- ///
- /// Represents an edition of the application.
- ///
- [Table("AbpEditions")]
- [MultiTenancySide(MultiTenancySides.Host)]
- public class Edition : FullAuditedEntity
- {
- ///
- /// Maximum length of the property.
- ///
- public const int MaxNameLength = 32;
-
- ///
- /// Maximum length of the property.
- ///
- public const int MaxDisplayNameLength = 64;
-
- ///
- /// Unique name of this edition.
- ///
- [Required]
- [StringLength(MaxNameLength)]
- public virtual string Name { get; set; }
-
- ///
- /// Display name of this edition.
- ///
- [Required]
- [StringLength(MaxDisplayNameLength)]
- public virtual string DisplayName { get; set; }
-
- public Edition()
- {
- Name = Guid.NewGuid().ToString("N");
- }
-
- public Edition(string displayName)
- : this()
- {
- DisplayName = displayName;
- }
- }
+using System;
+using System.ComponentModel.DataAnnotations;
+using System.ComponentModel.DataAnnotations.Schema;
+using Abp.Domain.Entities.Auditing;
+using Abp.MultiTenancy;
+
+namespace Abp.Application.Editions
+{
+ ///
+ /// Represents an edition of the application.
+ ///
+ [Table("AbpEditions")]
+ [MultiTenancySide(MultiTenancySides.Host)]
+ public class Edition : FullAuditedEntity
+ {
+ ///
+ /// Maximum length of the property.
+ ///
+ public const int MaxNameLength = 32;
+
+ ///
+ /// Maximum length of the property.
+ ///
+ public const int MaxDisplayNameLength = 64;
+
+ ///
+ /// Unique name of this edition.
+ ///
+ [Required]
+ [StringLength(MaxNameLength)]
+ public virtual string Name { get; set; }
+
+ ///
+ /// Display name of this edition.
+ ///
+ [Required]
+ [StringLength(MaxDisplayNameLength)]
+ public virtual string DisplayName { get; set; }
+
+ public Edition()
+ {
+ Name = Guid.NewGuid().ToString("N");
+ }
+
+ public Edition(string displayName)
+ : this()
+ {
+ DisplayName = displayName;
+ }
+ }
}
\ No newline at end of file
diff --git a/src/Abp.Zero/Application/Editions/EditionfeatureCacheItem.cs b/src/Abp.Zero.Common/Application/Editions/EditionfeatureCacheItem.cs
similarity index 96%
rename from src/Abp.Zero/Application/Editions/EditionfeatureCacheItem.cs
rename to src/Abp.Zero.Common/Application/Editions/EditionfeatureCacheItem.cs
index ec9bb4f2..395d8dba 100644
--- a/src/Abp.Zero/Application/Editions/EditionfeatureCacheItem.cs
+++ b/src/Abp.Zero.Common/Application/Editions/EditionfeatureCacheItem.cs
@@ -1,18 +1,18 @@
-using System;
-using System.Collections.Generic;
-
-namespace Abp.Application.Editions
-{
- [Serializable]
- public class EditionfeatureCacheItem
- {
- public const string CacheStoreName = "AbpZeroEditionFeatures";
-
- public IDictionary FeatureValues { get; set; }
-
- public EditionfeatureCacheItem()
- {
- FeatureValues = new Dictionary();
- }
- }
+using System;
+using System.Collections.Generic;
+
+namespace Abp.Application.Editions
+{
+ [Serializable]
+ public class EditionfeatureCacheItem
+ {
+ public const string CacheStoreName = "AbpZeroEditionFeatures";
+
+ public IDictionary FeatureValues { get; set; }
+
+ public EditionfeatureCacheItem()
+ {
+ FeatureValues = new Dictionary();
+ }
+ }
}
\ No newline at end of file
diff --git a/src/Abp.Zero/Application/Features/AbpFeatureValueStore.cs b/src/Abp.Zero.Common/Application/Features/AbpFeatureValueStore.cs
similarity index 92%
rename from src/Abp.Zero/Application/Features/AbpFeatureValueStore.cs
rename to src/Abp.Zero.Common/Application/Features/AbpFeatureValueStore.cs
index 160bb841..55629c89 100644
--- a/src/Abp.Zero/Application/Features/AbpFeatureValueStore.cs
+++ b/src/Abp.Zero.Common/Application/Features/AbpFeatureValueStore.cs
@@ -1,190 +1,190 @@
-using System.Threading.Tasks;
-using Abp.Application.Editions;
-using Abp.Authorization.Users;
-using Abp.Collections.Extensions;
-using Abp.Dependency;
-using Abp.Domain.Repositories;
-using Abp.Domain.Uow;
-using Abp.Events.Bus.Entities;
-using Abp.Events.Bus.Handlers;
-using Abp.MultiTenancy;
-using Abp.Runtime.Caching;
-
-namespace Abp.Application.Features
-{
- ///
- /// Implements .
- ///
- public abstract class AbpFeatureValueStore :
- IAbpZeroFeatureValueStore,
- ITransientDependency,
- IEventHandler>,
- IEventHandler>
-
- where TTenant : AbpTenant
- where TUser : AbpUser
- {
- private readonly ICacheManager _cacheManager;
- private readonly IRepository _tenantFeatureRepository;
- private readonly IRepository _tenantRepository;
- private readonly IRepository _editionFeatureRepository;
- private readonly IFeatureManager _featureManager;
- private readonly IUnitOfWorkManager _unitOfWorkManager;
-
- ///
- /// Initializes a new instance of the class.
- ///
- protected AbpFeatureValueStore(
- ICacheManager cacheManager,
- IRepository tenantFeatureRepository,
- IRepository tenantRepository,
- IRepository editionFeatureRepository,
- IFeatureManager featureManager,
- IUnitOfWorkManager unitOfWorkManager)
- {
- _cacheManager = cacheManager;
- _tenantFeatureRepository = tenantFeatureRepository;
- _tenantRepository = tenantRepository;
- _editionFeatureRepository = editionFeatureRepository;
- _featureManager = featureManager;
- _unitOfWorkManager = unitOfWorkManager;
- }
-
- ///
- public virtual Task GetValueOrNullAsync(int tenantId, Feature feature)
- {
- return GetValueOrNullAsync(tenantId, feature.Name);
- }
-
- public virtual async Task GetEditionValueOrNullAsync(int editionId, string featureName)
- {
- var cacheItem = await GetEditionFeatureCacheItemAsync(editionId);
- return cacheItem.FeatureValues.GetOrDefault(featureName);
- }
-
- public async Task GetValueOrNullAsync(int tenantId, string featureName)
- {
- var cacheItem = await GetTenantFeatureCacheItemAsync(tenantId);
- var value = cacheItem.FeatureValues.GetOrDefault(featureName);
- if (value != null)
- {
- return value;
- }
-
- if (cacheItem.EditionId.HasValue)
- {
- value = await GetEditionValueOrNullAsync(cacheItem.EditionId.Value, featureName);
- if (value != null)
- {
- return value;
- }
- }
-
- return null;
- }
-
- [UnitOfWork]
- public virtual async Task SetEditionFeatureValueAsync(int editionId, string featureName, string value)
- {
- if (await GetEditionValueOrNullAsync(editionId, featureName) == value)
- {
- return;
- }
-
- var currentFeature = await _editionFeatureRepository.FirstOrDefaultAsync(f => f.EditionId == editionId && f.Name == featureName);
-
- var feature = _featureManager.GetOrNull(featureName);
- if (feature == null || feature.DefaultValue == value)
- {
- if (currentFeature != null)
- {
- await _editionFeatureRepository.DeleteAsync(currentFeature);
- }
-
- return;
- }
-
- if (currentFeature == null)
- {
- await _editionFeatureRepository.InsertAsync(new EditionFeatureSetting(editionId, featureName, value));
- }
- else
- {
- currentFeature.Value = value;
- }
- }
-
- protected async Task GetTenantFeatureCacheItemAsync(int tenantId)
- {
- return await _cacheManager.GetTenantFeatureCache().GetAsync(tenantId, async () =>
- {
- TTenant tenant;
- using (var uow = _unitOfWorkManager.Begin())
- {
- using (_unitOfWorkManager.Current.SetTenantId(null))
- {
- tenant = await _tenantRepository.GetAsync(tenantId);
-
- await uow.CompleteAsync();
- }
- }
-
- var newCacheItem = new TenantFeatureCacheItem { EditionId = tenant.EditionId };
-
- using (var uow = _unitOfWorkManager.Begin())
- {
- using (_unitOfWorkManager.Current.SetTenantId(tenantId))
- {
- var featureSettings = await _tenantFeatureRepository.GetAllListAsync();
- foreach (var featureSetting in featureSettings)
- {
- newCacheItem.FeatureValues[featureSetting.Name] = featureSetting.Value;
- }
-
- await uow.CompleteAsync();
- }
- }
-
- return newCacheItem;
- });
- }
-
- protected virtual async Task GetEditionFeatureCacheItemAsync(int editionId)
- {
- return await _cacheManager
- .GetEditionFeatureCache()
- .GetAsync(
- editionId,
- async () => await CreateEditionFeatureCacheItem(editionId)
- );
- }
-
- protected virtual async Task CreateEditionFeatureCacheItem(int editionId)
- {
- var newCacheItem = new EditionfeatureCacheItem();
-
- var featureSettings = await _editionFeatureRepository.GetAllListAsync(f => f.EditionId == editionId);
- foreach (var featureSetting in featureSettings)
- {
- newCacheItem.FeatureValues[featureSetting.Name] = featureSetting.Value;
- }
-
- return newCacheItem;
- }
-
- public virtual void HandleEvent(EntityChangedEventData eventData)
- {
- _cacheManager.GetEditionFeatureCache().Remove(eventData.Entity.EditionId);
- }
-
- public virtual void HandleEvent(EntityChangedEventData eventData)
- {
- if (eventData.Entity.IsTransient())
- {
- return;
- }
-
- _cacheManager.GetEditionFeatureCache().Remove(eventData.Entity.Id);
- }
- }
+using System.Threading.Tasks;
+using Abp.Application.Editions;
+using Abp.Authorization.Users;
+using Abp.Collections.Extensions;
+using Abp.Dependency;
+using Abp.Domain.Repositories;
+using Abp.Domain.Uow;
+using Abp.Events.Bus.Entities;
+using Abp.Events.Bus.Handlers;
+using Abp.MultiTenancy;
+using Abp.Runtime.Caching;
+
+namespace Abp.Application.Features
+{
+ ///
+ /// Implements .
+ ///
+ public class AbpFeatureValueStore :
+ IAbpZeroFeatureValueStore,
+ ITransientDependency,
+ IEventHandler>,
+ IEventHandler>
+
+ where TTenant : AbpTenant
+ where TUser : AbpUserBase
+ {
+ private readonly ICacheManager _cacheManager;
+ private readonly IRepository _tenantFeatureRepository;
+ private readonly IRepository _tenantRepository;
+ private readonly IRepository _editionFeatureRepository;
+ private readonly IFeatureManager _featureManager;
+ private readonly IUnitOfWorkManager _unitOfWorkManager;
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ public AbpFeatureValueStore(
+ ICacheManager cacheManager,
+ IRepository tenantFeatureRepository,
+ IRepository tenantRepository,
+ IRepository editionFeatureRepository,
+ IFeatureManager featureManager,
+ IUnitOfWorkManager unitOfWorkManager)
+ {
+ _cacheManager = cacheManager;
+ _tenantFeatureRepository = tenantFeatureRepository;
+ _tenantRepository = tenantRepository;
+ _editionFeatureRepository = editionFeatureRepository;
+ _featureManager = featureManager;
+ _unitOfWorkManager = unitOfWorkManager;
+ }
+
+ ///
+ public virtual Task GetValueOrNullAsync(int tenantId, Feature feature)
+ {
+ return GetValueOrNullAsync(tenantId, feature.Name);
+ }
+
+ public virtual async Task GetEditionValueOrNullAsync(int editionId, string featureName)
+ {
+ var cacheItem = await GetEditionFeatureCacheItemAsync(editionId);
+ return cacheItem.FeatureValues.GetOrDefault(featureName);
+ }
+
+ public virtual async Task GetValueOrNullAsync(int tenantId, string featureName)
+ {
+ var cacheItem = await GetTenantFeatureCacheItemAsync(tenantId);
+ var value = cacheItem.FeatureValues.GetOrDefault(featureName);
+ if (value != null)
+ {
+ return value;
+ }
+
+ if (cacheItem.EditionId.HasValue)
+ {
+ value = await GetEditionValueOrNullAsync(cacheItem.EditionId.Value, featureName);
+ if (value != null)
+ {
+ return value;
+ }
+ }
+
+ return null;
+ }
+
+ [UnitOfWork]
+ public virtual async Task SetEditionFeatureValueAsync(int editionId, string featureName, string value)
+ {
+ if (await GetEditionValueOrNullAsync(editionId, featureName) == value)
+ {
+ return;
+ }
+
+ var currentFeature = await _editionFeatureRepository.FirstOrDefaultAsync(f => f.EditionId == editionId && f.Name == featureName);
+
+ var feature = _featureManager.GetOrNull(featureName);
+ if (feature == null || feature.DefaultValue == value)
+ {
+ if (currentFeature != null)
+ {
+ await _editionFeatureRepository.DeleteAsync(currentFeature);
+ }
+
+ return;
+ }
+
+ if (currentFeature == null)
+ {
+ await _editionFeatureRepository.InsertAsync(new EditionFeatureSetting(editionId, featureName, value));
+ }
+ else
+ {
+ currentFeature.Value = value;
+ }
+ }
+
+ protected virtual async Task GetTenantFeatureCacheItemAsync(int tenantId)
+ {
+ return await _cacheManager.GetTenantFeatureCache().GetAsync(tenantId, async () =>
+ {
+ TTenant tenant;
+ using (var uow = _unitOfWorkManager.Begin())
+ {
+ using (_unitOfWorkManager.Current.SetTenantId(null))
+ {
+ tenant = await _tenantRepository.GetAsync(tenantId);
+
+ await uow.CompleteAsync();
+ }
+ }
+
+ var newCacheItem = new TenantFeatureCacheItem { EditionId = tenant.EditionId };
+
+ using (var uow = _unitOfWorkManager.Begin())
+ {
+ using (_unitOfWorkManager.Current.SetTenantId(tenantId))
+ {
+ var featureSettings = await _tenantFeatureRepository.GetAllListAsync();
+ foreach (var featureSetting in featureSettings)
+ {
+ newCacheItem.FeatureValues[featureSetting.Name] = featureSetting.Value;
+ }
+
+ await uow.CompleteAsync();
+ }
+ }
+
+ return newCacheItem;
+ });
+ }
+
+ protected virtual async Task GetEditionFeatureCacheItemAsync(int editionId)
+ {
+ return await _cacheManager
+ .GetEditionFeatureCache()
+ .GetAsync(
+ editionId,
+ async () => await CreateEditionFeatureCacheItem(editionId)
+ );
+ }
+
+ protected virtual async Task CreateEditionFeatureCacheItem(int editionId)
+ {
+ var newCacheItem = new EditionfeatureCacheItem();
+
+ var featureSettings = await _editionFeatureRepository.GetAllListAsync(f => f.EditionId == editionId);
+ foreach (var featureSetting in featureSettings)
+ {
+ newCacheItem.FeatureValues[featureSetting.Name] = featureSetting.Value;
+ }
+
+ return newCacheItem;
+ }
+
+ public virtual void HandleEvent(EntityChangedEventData eventData)
+ {
+ _cacheManager.GetEditionFeatureCache().Remove(eventData.Entity.EditionId);
+ }
+
+ public virtual void HandleEvent(EntityChangedEventData eventData)
+ {
+ if (eventData.Entity.IsTransient())
+ {
+ return;
+ }
+
+ _cacheManager.GetEditionFeatureCache().Remove(eventData.Entity.Id);
+ }
+ }
}
\ No newline at end of file
diff --git a/src/Abp.Zero/Application/Features/EditionFeatureSetting.cs b/src/Abp.Zero.Common/Application/Features/EditionFeatureSetting.cs
similarity index 96%
rename from src/Abp.Zero/Application/Features/EditionFeatureSetting.cs
rename to src/Abp.Zero.Common/Application/Features/EditionFeatureSetting.cs
index 7023c844..3d02c894 100644
--- a/src/Abp.Zero/Application/Features/EditionFeatureSetting.cs
+++ b/src/Abp.Zero.Common/Application/Features/EditionFeatureSetting.cs
@@ -1,48 +1,48 @@
-using System.ComponentModel.DataAnnotations.Schema;
-using Abp.Application.Editions;
-
-namespace Abp.Application.Features
-{
- ///
- /// Feature setting for an .
- ///
- public class EditionFeatureSetting : FeatureSetting
- {
- ///
- /// Gets or sets the edition.
- ///
- ///
- /// The edition.
- ///
- [ForeignKey("EditionId")]
- public virtual Edition Edition { get; set; }
-
- ///
- /// Gets or sets the edition Id.
- ///
- ///
- /// The edition Id.
- ///
- public virtual int EditionId { get; set; }
-
- ///
- /// Initializes a new instance of the class.
- ///
- public EditionFeatureSetting()
- {
-
- }
-
- ///
- /// Initializes a new instance of the class.
- ///
- /// The edition Id.
- /// Feature name.
- /// Feature value.
- public EditionFeatureSetting(int editionId, string name, string value)
- :base(name, value)
- {
- EditionId = editionId;
- }
- }
+using System.ComponentModel.DataAnnotations.Schema;
+using Abp.Application.Editions;
+
+namespace Abp.Application.Features
+{
+ ///
+ /// Feature setting for an .
+ ///
+ public class EditionFeatureSetting : FeatureSetting
+ {
+ ///
+ /// Gets or sets the edition.
+ ///
+ ///
+ /// The edition.
+ ///
+ [ForeignKey("EditionId")]
+ public virtual Edition Edition { get; set; }
+
+ ///
+ /// Gets or sets the edition Id.
+ ///
+ ///
+ /// The edition Id.
+ ///
+ public virtual int EditionId { get; set; }
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ public EditionFeatureSetting()
+ {
+
+ }
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The edition Id.
+ /// Feature name.
+ /// Feature value.
+ public EditionFeatureSetting(int editionId, string name, string value)
+ :base(name, value)
+ {
+ EditionId = editionId;
+ }
+ }
}
\ No newline at end of file
diff --git a/src/Abp.Zero/Application/Features/FeatureSetting.cs b/src/Abp.Zero.Common/Application/Features/FeatureSetting.cs
similarity index 96%
rename from src/Abp.Zero/Application/Features/FeatureSetting.cs
rename to src/Abp.Zero.Common/Application/Features/FeatureSetting.cs
index 19c4c89b..42eeee7b 100644
--- a/src/Abp.Zero/Application/Features/FeatureSetting.cs
+++ b/src/Abp.Zero.Common/Application/Features/FeatureSetting.cs
@@ -1,58 +1,58 @@
-using System.ComponentModel.DataAnnotations;
-using System.ComponentModel.DataAnnotations.Schema;
-using Abp.Domain.Entities.Auditing;
-using Abp.MultiTenancy;
-
-namespace Abp.Application.Features
-{
- ///
- /// Base class for feature settings
- ///
- [Table("AbpFeatures")]
- [MultiTenancySide(MultiTenancySides.Host)]
- public abstract class FeatureSetting : CreationAuditedEntity
- {
- ///
- /// Maximum length of the field.
- ///
- public const int MaxNameLength = 128;
-
- ///
- /// Maximum length of the property.
- ///
- public const int MaxValueLength = 2000;
-
- ///
- /// Feature name.
- ///
- [Required]
- [MaxLength(MaxNameLength)]
- public virtual string Name { get; set; }
-
- ///
- /// Value.
- ///
- [Required(AllowEmptyStrings = true)]
- [MaxLength(MaxValueLength)]
- public virtual string Value { get; set; }
-
- ///
- /// Initializes a new instance of the class.
- ///
- protected FeatureSetting()
- {
-
- }
-
- ///
- /// Initializes a new instance of the class.
- ///
- /// Feature name.
- /// Feature value.
- protected FeatureSetting(string name, string value)
- {
- Name = name;
- Value = value;
- }
- }
+using System.ComponentModel.DataAnnotations;
+using System.ComponentModel.DataAnnotations.Schema;
+using Abp.Domain.Entities.Auditing;
+using Abp.MultiTenancy;
+
+namespace Abp.Application.Features
+{
+ ///
+ /// Base class for feature settings
+ ///
+ [Table("AbpFeatures")]
+ [MultiTenancySide(MultiTenancySides.Host)]
+ public abstract class FeatureSetting : CreationAuditedEntity
+ {
+ ///
+ /// Maximum length of the field.
+ ///
+ public const int MaxNameLength = 128;
+
+ ///
+ /// Maximum length of the property.
+ ///
+ public const int MaxValueLength = 2000;
+
+ ///
+ /// Feature name.
+ ///
+ [Required]
+ [MaxLength(MaxNameLength)]
+ public virtual string Name { get; set; }
+
+ ///
+ /// Value.
+ ///
+ [Required(AllowEmptyStrings = true)]
+ [MaxLength(MaxValueLength)]
+ public virtual string Value { get; set; }
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ protected FeatureSetting()
+ {
+
+ }
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// Feature name.
+ /// Feature value.
+ protected FeatureSetting(string name, string value)
+ {
+ Name = name;
+ Value = value;
+ }
+ }
}
\ No newline at end of file
diff --git a/src/Abp.Zero/Application/Features/IAbpZeroFeatureValueStore.cs b/src/Abp.Zero.Common/Application/Features/IAbpZeroFeatureValueStore.cs
similarity index 100%
rename from src/Abp.Zero/Application/Features/IAbpZeroFeatureValueStore.cs
rename to src/Abp.Zero.Common/Application/Features/IAbpZeroFeatureValueStore.cs
diff --git a/src/Abp.Zero/Auditing/AuditLog.cs b/src/Abp.Zero.Common/Auditing/AuditLog.cs
similarity index 84%
rename from src/Abp.Zero/Auditing/AuditLog.cs
rename to src/Abp.Zero.Common/Auditing/AuditLog.cs
index a9c93323..0f4972ad 100644
--- a/src/Abp.Zero/Auditing/AuditLog.cs
+++ b/src/Abp.Zero.Common/Auditing/AuditLog.cs
@@ -1,168 +1,159 @@
-using System;
-using System.ComponentModel.DataAnnotations;
-using System.ComponentModel.DataAnnotations.Schema;
-using Abp.Domain.Entities;
-using Abp.Extensions;
-
-namespace Abp.Auditing
-{
- ///
- /// Used to store audit logs.
- ///
- [Table("AbpAuditLogs")]
- public class AuditLog : Entity, IMayHaveTenant
- {
- ///
- /// Maximum length of property.
- ///
- public const int MaxServiceNameLength = 256;
-
- ///
- /// Maximum length of property.
- ///
- public const int MaxMethodNameLength = 256;
-
- ///
- /// Maximum length of property.
- ///
- public const int MaxParametersLength = 1024;
-
- ///
- /// Maximum length of property.
- ///
- public const int MaxClientIpAddressLength = 64;
-
- ///
- /// Maximum length of property.
- ///
- public const int MaxClientNameLength = 128;
-
- ///
- /// Maximum length of property.
- ///
- public const int MaxBrowserInfoLength = 256;
-
- ///
- /// Maximum length of property.
- ///
- public const int MaxExceptionLength = 2000;
-
- ///
- /// Maximum length of property.
- ///
- public const int MaxCustomDataLength = 2000;
-
- ///
- /// TenantId.
- ///
- public virtual int? TenantId { get; set; }
-
- ///
- /// UserId.
- ///
- public virtual long? UserId { get; set; }
-
- ///
- /// Service (class/interface) name.
- ///
- [MaxLength(MaxServiceNameLength)]
- public virtual string ServiceName { get; set; }
-
- ///
- /// Executed method name.
- ///
- [MaxLength(MaxMethodNameLength)]
- public virtual string MethodName { get; set; }
-
- ///
- /// Calling parameters.
- ///
- [MaxLength(MaxParametersLength)]
- public virtual string Parameters { get; set; }
-
- ///
- /// Start time of the method execution.
- ///
- public virtual DateTime ExecutionTime { get; set; }
-
- ///
- /// Total duration of the method call as milliseconds.
- ///
- public virtual int ExecutionDuration { get; set; }
-
- ///
- /// IP address of the client.
- ///
- [MaxLength(MaxClientIpAddressLength)]
- public virtual string ClientIpAddress { get; set; }
-
- ///
- /// Name (generally computer name) of the client.
- ///
- [MaxLength(MaxClientNameLength)]
- public virtual string ClientName { get; set; }
-
- ///
- /// Browser information if this method is called in a web request.
- ///
- [MaxLength(MaxBrowserInfoLength)]
- public virtual string BrowserInfo { get; set; }
-
- ///
- /// Exception object, if an exception occured during execution of the method.
- ///
- [MaxLength(MaxExceptionLength)]
- public virtual string Exception { get; set; }
-
- ///
- /// .
- ///
- public virtual long? ImpersonatorUserId { get; set; }
-
- ///
- /// .
- ///
- public virtual int? ImpersonatorTenantId { get; set; }
-
- ///
- /// .
- ///
- [MaxLength(MaxCustomDataLength)]
- public virtual string CustomData { get; set; }
-
- ///
- /// Creates a new CreateFromAuditInfo from given .
- ///
- /// Source object
- /// The object that is created using
- public static AuditLog CreateFromAuditInfo(AuditInfo auditInfo)
- {
- var exceptionMessage = auditInfo.Exception != null ? auditInfo.Exception.ToString() : null;
- return new AuditLog
- {
- TenantId = auditInfo.TenantId,
- UserId = auditInfo.UserId,
- ServiceName = auditInfo.ServiceName.TruncateWithPostfix(MaxServiceNameLength),
- MethodName = auditInfo.MethodName.TruncateWithPostfix(MaxMethodNameLength),
- Parameters = auditInfo.Parameters.TruncateWithPostfix(MaxParametersLength),
- ExecutionTime = auditInfo.ExecutionTime,
- ExecutionDuration = auditInfo.ExecutionDuration,
- ClientIpAddress = auditInfo.ClientIpAddress.TruncateWithPostfix(MaxClientIpAddressLength),
- ClientName = auditInfo.ClientName.TruncateWithPostfix(MaxClientNameLength),
- BrowserInfo = auditInfo.BrowserInfo.TruncateWithPostfix(MaxBrowserInfoLength),
- Exception = exceptionMessage.TruncateWithPostfix(MaxExceptionLength),
- ImpersonatorUserId = auditInfo.ImpersonatorUserId,
- ImpersonatorTenantId = auditInfo.ImpersonatorTenantId,
- CustomData = auditInfo.CustomData.TruncateWithPostfix(MaxCustomDataLength)
- };
- }
-
- public override string ToString()
- {
- return string.Format(
- "AUDIT LOG: {0}.{1} is executed by user {2} in {3} ms from {4} IP address.",
- ServiceName, MethodName, UserId, ExecutionDuration, ClientIpAddress
- );
- }
- }
-}
+using System;
+using System.ComponentModel.DataAnnotations.Schema;
+using Abp.Domain.Entities;
+using Abp.Extensions;
+
+namespace Abp.Auditing
+{
+ ///
+ /// Used to store audit logs.
+ ///
+ [Table("AbpAuditLogs")]
+ public class AuditLog : Entity, IMayHaveTenant
+ {
+ ///
+ /// Maximum length of property.
+ ///
+ public static int MaxServiceNameLength = 256;
+
+ ///
+ /// Maximum length of property.
+ ///
+ public static int MaxMethodNameLength = 256;
+
+ ///
+ /// Maximum length of property.
+ ///
+ public static int MaxParametersLength = 1024;
+
+ ///
+ /// Maximum length of property.
+ ///
+ public static int MaxClientIpAddressLength = 64;
+
+ ///
+ /// Maximum length of property.
+ ///
+ public static int MaxClientNameLength = 128;
+
+ ///
+ /// Maximum length of property.
+ ///
+ public static int MaxBrowserInfoLength = 256;
+
+ ///
+ /// Maximum length of property.
+ ///
+ public static int MaxExceptionLength = 2000;
+
+ ///
+ /// Maximum length of property.
+ ///
+ public static int MaxCustomDataLength = 2000;
+
+ ///
+ /// TenantId.
+ ///
+ public virtual int? TenantId { get; set; }
+
+ ///
+ /// UserId.
+ ///
+ public virtual long? UserId { get; set; }
+
+ ///
+ /// Service (class/interface) name.
+ ///
+ public virtual string ServiceName { get; set; }
+
+ ///
+ /// Executed method name.
+ ///
+ public virtual string MethodName { get; set; }
+
+ ///
+ /// Calling parameters.
+ ///
+ public virtual string Parameters { get; set; }
+
+ ///
+ /// Start time of the method execution.
+ ///
+ public virtual DateTime ExecutionTime { get; set; }
+
+ ///
+ /// Total duration of the method call as milliseconds.
+ ///
+ public virtual int ExecutionDuration { get; set; }
+
+ ///
+ /// IP address of the client.
+ ///
+ public virtual string ClientIpAddress { get; set; }
+
+ ///
+ /// Name (generally computer name) of the client.
+ ///
+ public virtual string ClientName { get; set; }
+
+ ///
+ /// Browser information if this method is called in a web request.
+ ///
+ public virtual string BrowserInfo { get; set; }
+
+ ///
+ /// Exception object, if an exception occured during execution of the method.
+ ///
+ public virtual string Exception { get; set; }
+
+ ///
+ /// .
+ ///
+ public virtual long? ImpersonatorUserId { get; set; }
+
+ ///
+ /// .
+ ///
+ public virtual int? ImpersonatorTenantId { get; set; }
+
+ ///
+ /// .
+ ///
+ public virtual string CustomData { get; set; }
+
+ ///
+ /// Creates a new CreateFromAuditInfo from given .
+ ///
+ /// Source object
+ /// The object that is created using
+ public static AuditLog CreateFromAuditInfo(AuditInfo auditInfo)
+ {
+ var exceptionMessage = auditInfo.Exception != null ? auditInfo.Exception.ToString() : null;
+ return new AuditLog
+ {
+ TenantId = auditInfo.TenantId,
+ UserId = auditInfo.UserId,
+ ServiceName = auditInfo.ServiceName.TruncateWithPostfix(MaxServiceNameLength),
+ MethodName = auditInfo.MethodName.TruncateWithPostfix(MaxMethodNameLength),
+ Parameters = auditInfo.Parameters.TruncateWithPostfix(MaxParametersLength),
+ ExecutionTime = auditInfo.ExecutionTime,
+ ExecutionDuration = auditInfo.ExecutionDuration,
+ ClientIpAddress = auditInfo.ClientIpAddress.TruncateWithPostfix(MaxClientIpAddressLength),
+ ClientName = auditInfo.ClientName.TruncateWithPostfix(MaxClientNameLength),
+ BrowserInfo = auditInfo.BrowserInfo.TruncateWithPostfix(MaxBrowserInfoLength),
+ Exception = exceptionMessage.TruncateWithPostfix(MaxExceptionLength),
+ ImpersonatorUserId = auditInfo.ImpersonatorUserId,
+ ImpersonatorTenantId = auditInfo.ImpersonatorTenantId,
+ CustomData = auditInfo.CustomData.TruncateWithPostfix(MaxCustomDataLength)
+ };
+ }
+
+ public override string ToString()
+ {
+ return string.Format(
+ "AUDIT LOG: {0}.{1} is executed by user {2} in {3} ms from {4} IP address.",
+ ServiceName, MethodName, UserId, ExecutionDuration, ClientIpAddress
+ );
+ }
+ }
+}
diff --git a/src/Abp.Zero/Auditing/AuditingStore.cs b/src/Abp.Zero.Common/Auditing/AuditingStore.cs
similarity index 92%
rename from src/Abp.Zero/Auditing/AuditingStore.cs
rename to src/Abp.Zero.Common/Auditing/AuditingStore.cs
index 84d21db6..2c0a399b 100644
--- a/src/Abp.Zero/Auditing/AuditingStore.cs
+++ b/src/Abp.Zero.Common/Auditing/AuditingStore.cs
@@ -19,7 +19,7 @@ public AuditingStore(IRepository auditLogRepository)
_auditLogRepository = auditLogRepository;
}
- public Task SaveAsync(AuditInfo auditInfo)
+ public virtual Task SaveAsync(AuditInfo auditInfo)
{
return _auditLogRepository.InsertAsync(AuditLog.CreateFromAuditInfo(auditInfo));
}
diff --git a/src/Abp.Zero/Authorization/Users/AbpLoginResultType.cs b/src/Abp.Zero.Common/Authorization/AbpLoginResultType.cs
similarity index 76%
rename from src/Abp.Zero/Authorization/Users/AbpLoginResultType.cs
rename to src/Abp.Zero.Common/Authorization/AbpLoginResultType.cs
index d0e5dfaf..7becff79 100644
--- a/src/Abp.Zero/Authorization/Users/AbpLoginResultType.cs
+++ b/src/Abp.Zero.Common/Authorization/AbpLoginResultType.cs
@@ -1,23 +1,25 @@
-namespace Abp.Authorization.Users
-{
- public enum AbpLoginResultType : byte
- {
- Success = 1,
-
- InvalidUserNameOrEmailAddress,
-
- InvalidPassword,
-
- UserIsNotActive,
-
- InvalidTenancyName,
-
- TenantIsNotActive,
-
- UserEmailIsNotConfirmed,
-
- UnknownExternalLogin,
-
- LockedOut
- }
+namespace Abp.Authorization
+{
+ public enum AbpLoginResultType : byte
+ {
+ Success = 1,
+
+ InvalidUserNameOrEmailAddress,
+
+ InvalidPassword,
+
+ UserIsNotActive,
+
+ InvalidTenancyName,
+
+ TenantIsNotActive,
+
+ UserEmailIsNotConfirmed,
+
+ UnknownExternalLogin,
+
+ LockedOut,
+
+ UserPhoneNumberIsNotConfirmed,
+ }
}
\ No newline at end of file
diff --git a/src/Abp.Zero/Authorization/PermissionGrantInfo.cs b/src/Abp.Zero.Common/Authorization/PermissionGrantInfo.cs
similarity index 100%
rename from src/Abp.Zero/Authorization/PermissionGrantInfo.cs
rename to src/Abp.Zero.Common/Authorization/PermissionGrantInfo.cs
diff --git a/src/Abp.Zero/Authorization/PermissionSetting.cs b/src/Abp.Zero.Common/Authorization/PermissionSetting.cs
similarity index 100%
rename from src/Abp.Zero/Authorization/PermissionSetting.cs
rename to src/Abp.Zero.Common/Authorization/PermissionSetting.cs
diff --git a/src/Abp.Zero.Common/Authorization/Roles/AbpRoleBase.cs b/src/Abp.Zero.Common/Authorization/Roles/AbpRoleBase.cs
new file mode 100644
index 00000000..07ba941a
--- /dev/null
+++ b/src/Abp.Zero.Common/Authorization/Roles/AbpRoleBase.cs
@@ -0,0 +1,87 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel.DataAnnotations;
+using System.ComponentModel.DataAnnotations.Schema;
+using Abp.Authorization.Users;
+using Abp.Domain.Entities;
+using Abp.Domain.Entities.Auditing;
+
+namespace Abp.Authorization.Roles
+{
+ ///
+ /// Base class for role.
+ ///
+ [Table("AbpRoles")]
+ public abstract class AbpRoleBase : FullAuditedEntity, IMayHaveTenant
+ {
+ ///
+ /// Maximum length of the property.
+ ///
+ public const int MaxDisplayNameLength = 64;
+
+ ///
+ /// Maximum length of the property.
+ ///
+ public const int MaxNameLength = 32;
+
+ ///
+ /// Tenant's Id, if this role is a tenant-level role. Null, if not.
+ ///
+ public virtual int? TenantId { get; set; }
+
+ ///
+ /// Unique name of this role.
+ ///
+ [Required]
+ [StringLength(MaxNameLength)]
+ public virtual string Name { get; set; }
+
+ ///
+ /// Display name of this role.
+ ///
+ [Required]
+ [StringLength(MaxDisplayNameLength)]
+ public virtual string DisplayName { get; set; }
+
+ ///
+ /// Is this a static role?
+ /// Static roles can not be deleted, can not change their name.
+ /// They can be used programmatically.
+ ///
+ public virtual bool IsStatic { get; set; }
+
+ ///
+ /// Is this role will be assigned to new users as default?
+ ///
+ public virtual bool IsDefault { get; set; }
+
+ ///
+ /// List of permissions of the role.
+ ///
+ [ForeignKey("RoleId")]
+ public virtual ICollection Permissions { get; set; }
+
+ protected AbpRoleBase()
+ {
+ Name = Guid.NewGuid().ToString("N");
+ }
+
+ protected AbpRoleBase(int? tenantId, string displayName)
+ : this()
+ {
+ TenantId = tenantId;
+ DisplayName = displayName;
+ }
+
+ protected AbpRoleBase(int? tenantId, string name, string displayName)
+ : this(tenantId, displayName)
+ {
+ Name = name;
+ }
+
+ public override string ToString()
+ {
+ return $"[Role {Id}, Name={Name}]";
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Abp.Zero/Authorization/Roles/AbpRolePermissionCacheItemInvalidator.cs b/src/Abp.Zero.Common/Authorization/Roles/AbpRolePermissionCacheItemInvalidator.cs
similarity index 100%
rename from src/Abp.Zero/Authorization/Roles/AbpRolePermissionCacheItemInvalidator.cs
rename to src/Abp.Zero.Common/Authorization/Roles/AbpRolePermissionCacheItemInvalidator.cs
diff --git a/src/Abp.Zero/Authorization/Roles/IRolePermissionStore.cs b/src/Abp.Zero.Common/Authorization/Roles/IRolePermissionStore.cs
similarity index 90%
rename from src/Abp.Zero/Authorization/Roles/IRolePermissionStore.cs
rename to src/Abp.Zero.Common/Authorization/Roles/IRolePermissionStore.cs
index acd3baac..d6b6b2f7 100644
--- a/src/Abp.Zero/Authorization/Roles/IRolePermissionStore.cs
+++ b/src/Abp.Zero.Common/Authorization/Roles/IRolePermissionStore.cs
@@ -1,56 +1,54 @@
-using System.Collections.Generic;
-using System.Threading.Tasks;
-using Abp.Authorization.Users;
-
-namespace Abp.Authorization.Roles
-{
- ///
- /// Used to perform permission database operations for a role.
- ///
- public interface IRolePermissionStore
- where TRole : AbpRole
- where TUser : AbpUser
- {
- ///
- /// Adds a permission grant setting to a role.
- ///
- /// Role
- /// Permission grant setting info
- Task AddPermissionAsync(TRole role, PermissionGrantInfo permissionGrant);
-
- ///
- /// Removes a permission grant setting from a role.
- ///
- /// Role
- /// Permission grant setting info
- Task RemovePermissionAsync(TRole role, PermissionGrantInfo permissionGrant);
-
- ///
- /// Gets permission grant setting informations for a role.
- ///
- /// Role
- /// List of permission setting informations
- Task> GetPermissionsAsync(TRole role);
-
- ///
- /// Gets permission grant setting informations for a role.
- ///
- /// Role id
- /// List of permission setting informations
- Task> GetPermissionsAsync(int roleId);
-
- ///
- /// Checks whether a role has a permission grant setting info.
- ///
- /// Role id
- /// Permission grant setting info
- ///
- Task HasPermissionAsync(int roleId, PermissionGrantInfo permissionGrant);
-
- ///
- /// Deleted all permission settings for a role.
- ///
- /// Role
- Task RemoveAllPermissionSettingsAsync(TRole role);
- }
+using System.Collections.Generic;
+using System.Threading.Tasks;
+
+namespace Abp.Authorization.Roles
+{
+ ///
+ /// Used to perform permission database operations for a role.
+ ///
+ public interface IRolePermissionStore
+ where TRole : AbpRoleBase
+ {
+ ///
+ /// Adds a permission grant setting to a role.
+ ///
+ /// Role
+ /// Permission grant setting info
+ Task AddPermissionAsync(TRole role, PermissionGrantInfo permissionGrant);
+
+ ///
+ /// Removes a permission grant setting from a role.
+ ///
+ /// Role
+ /// Permission grant setting info
+ Task RemovePermissionAsync(TRole role, PermissionGrantInfo permissionGrant);
+
+ ///
+ /// Gets permission grant setting informations for a role.
+ ///
+ /// Role
+ /// List of permission setting informations
+ Task> GetPermissionsAsync(TRole role);
+
+ ///
+ /// Gets permission grant setting informations for a role.
+ ///
+ /// Role id
+ /// List of permission setting informations
+ Task> GetPermissionsAsync(int roleId);
+
+ ///
+ /// Checks whether a role has a permission grant setting info.
+ ///
+ /// Role id
+ /// Permission grant setting info
+ ///
+ Task HasPermissionAsync(int roleId, PermissionGrantInfo permissionGrant);
+
+ ///
+ /// Deleted all permission settings for a role.
+ ///
+ /// Role
+ Task RemoveAllPermissionSettingsAsync(TRole role);
+ }
}
\ No newline at end of file
diff --git a/src/Abp.Zero/Authorization/Roles/PermissionEqualityComparer.cs b/src/Abp.Zero.Common/Authorization/Roles/PermissionEqualityComparer.cs
similarity index 100%
rename from src/Abp.Zero/Authorization/Roles/PermissionEqualityComparer.cs
rename to src/Abp.Zero.Common/Authorization/Roles/PermissionEqualityComparer.cs
diff --git a/src/Abp.Zero.Common/Authorization/Roles/RoleClaim.cs b/src/Abp.Zero.Common/Authorization/Roles/RoleClaim.cs
new file mode 100644
index 00000000..41ffded0
--- /dev/null
+++ b/src/Abp.Zero.Common/Authorization/Roles/RoleClaim.cs
@@ -0,0 +1,32 @@
+using System.ComponentModel.DataAnnotations.Schema;
+using System.Security.Claims;
+using Abp.Domain.Entities;
+using Abp.Domain.Entities.Auditing;
+
+namespace Abp.Authorization.Roles
+{
+ [Table("AbpRoleClaims")]
+ public class RoleClaim : CreationAuditedEntity, IMayHaveTenant
+ {
+ public virtual int? TenantId { get; set; }
+
+ public virtual int RoleId { get; set; }
+
+ public virtual string ClaimType { get; set; }
+
+ public virtual string ClaimValue { get; set; }
+
+ public RoleClaim()
+ {
+
+ }
+
+ public RoleClaim(AbpRoleBase role, Claim claim)
+ {
+ TenantId = role.TenantId;
+ RoleId = role.Id;
+ ClaimType = claim.Type;
+ ClaimValue = claim.Value;
+ }
+ }
+}
diff --git a/src/Abp.Zero/Authorization/Roles/RolePermissionCacheItem.cs b/src/Abp.Zero.Common/Authorization/Roles/RolePermissionCacheItem.cs
similarity index 95%
rename from src/Abp.Zero/Authorization/Roles/RolePermissionCacheItem.cs
rename to src/Abp.Zero.Common/Authorization/Roles/RolePermissionCacheItem.cs
index f7e82701..b5d7b0b4 100644
--- a/src/Abp.Zero/Authorization/Roles/RolePermissionCacheItem.cs
+++ b/src/Abp.Zero.Common/Authorization/Roles/RolePermissionCacheItem.cs
@@ -1,29 +1,29 @@
-using System;
-using System.Collections.Generic;
-
-namespace Abp.Authorization.Roles
-{
- ///
- /// Used to cache permissions of a role.
- ///
- [Serializable]
- public class RolePermissionCacheItem
- {
- public const string CacheStoreName = "AbpZeroRolePermissions";
-
- public long RoleId { get; set; }
-
- public HashSet GrantedPermissions { get; set; }
-
- public RolePermissionCacheItem()
- {
- GrantedPermissions = new HashSet();
- }
-
- public RolePermissionCacheItem(int roleId)
- : this()
- {
- RoleId = roleId;
- }
- }
+using System;
+using System.Collections.Generic;
+
+namespace Abp.Authorization.Roles
+{
+ ///
+ /// Used to cache permissions of a role.
+ ///
+ [Serializable]
+ public class RolePermissionCacheItem
+ {
+ public const string CacheStoreName = "AbpZeroRolePermissions";
+
+ public long RoleId { get; set; }
+
+ public HashSet GrantedPermissions { get; set; }
+
+ public RolePermissionCacheItem()
+ {
+ GrantedPermissions = new HashSet();
+ }
+
+ public RolePermissionCacheItem(int roleId)
+ : this()
+ {
+ RoleId = roleId;
+ }
+ }
}
\ No newline at end of file
diff --git a/src/Abp.Zero/Authorization/Roles/RolePermissionSetting.cs b/src/Abp.Zero.Common/Authorization/Roles/RolePermissionSetting.cs
similarity index 100%
rename from src/Abp.Zero/Authorization/Roles/RolePermissionSetting.cs
rename to src/Abp.Zero.Common/Authorization/Roles/RolePermissionSetting.cs
diff --git a/src/Abp.Zero.Common/Authorization/Users/AbpUserBase.cs b/src/Abp.Zero.Common/Authorization/Users/AbpUserBase.cs
new file mode 100644
index 00000000..4c30cf74
--- /dev/null
+++ b/src/Abp.Zero.Common/Authorization/Users/AbpUserBase.cs
@@ -0,0 +1,251 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel.DataAnnotations;
+using System.ComponentModel.DataAnnotations.Schema;
+using Abp.Configuration;
+using Abp.Domain.Entities;
+using Abp.Domain.Entities.Auditing;
+using Abp.Extensions;
+
+namespace Abp.Authorization.Users
+{
+ ///
+ /// Base class for user.
+ ///
+ [Table("AbpUsers")]
+ public abstract class AbpUserBase : FullAuditedEntity, IMayHaveTenant, IPassivable
+ {
+ ///
+ /// Maximum length of the property.
+ ///
+ public const int MaxUserNameLength = 32;
+
+ ///
+ /// Maximum length of the property.
+ ///
+ public const int MaxEmailAddressLength = 256;
+
+ ///
+ /// Maximum length of the property.
+ ///
+ public const int MaxNameLength = 32;
+
+ ///
+ /// Maximum length of the property.
+ ///
+ public const int MaxSurnameLength = 32;
+
+ ///
+ /// Maximum length of the property.
+ ///
+ public const int MaxAuthenticationSourceLength = 64;
+
+ ///
+ /// UserName of the admin.
+ /// admin can not be deleted and UserName of the admin can not be changed.
+ ///
+ public const string AdminUserName = "admin";
+
+ ///
+ /// Maximum length of the property.
+ ///
+ public const int MaxPasswordLength = 128;
+
+ ///
+ /// Maximum length of the without hashed.
+ ///
+ public const int MaxPlainPasswordLength = 32;
+
+ ///
+ /// Maximum length of the property.
+ ///
+ public const int MaxEmailConfirmationCodeLength = 328;
+
+ ///
+ /// Maximum length of the property.
+ ///
+ public const int MaxPasswordResetCodeLength = 328;
+
+ ///
+ /// Authorization source name.
+ /// It's set to external authentication source name if created by an external source.
+ /// Default: null.
+ ///
+ [MaxLength(MaxAuthenticationSourceLength)]
+ public virtual string AuthenticationSource { get; set; }
+
+ ///
+ /// User name.
+ /// User name must be unique for it's tenant.
+ ///
+ [Required]
+ [StringLength(MaxUserNameLength)]
+ public virtual string UserName { get; set; }
+
+ ///
+ /// Tenant Id of this user.
+ ///
+ public virtual int? TenantId { get; set; }
+
+ ///
+ /// Email address of the user.
+ /// Email address must be unique for it's tenant.
+ ///
+ [Required]
+ [StringLength(MaxEmailAddressLength)]
+ public virtual string EmailAddress { get; set; }
+
+ ///
+ /// Name of the user.
+ ///
+ [Required]
+ [StringLength(MaxNameLength)]
+ public virtual string Name { get; set; }
+
+ ///
+ /// Surname of the user.
+ ///
+ [Required]
+ [StringLength(MaxSurnameLength)]
+ public virtual string Surname { get; set; }
+
+ ///
+ /// Return full name (Name Surname )
+ ///
+ [NotMapped]
+ public virtual string FullName { get { return this.Name + " " + this.Surname; } }
+
+ ///
+ /// Password of the user.
+ ///
+ [Required]
+ [StringLength(MaxPasswordLength)]
+ public virtual string Password { get; set; }
+
+ ///
+ /// Confirmation code for email.
+ ///
+ [StringLength(MaxEmailConfirmationCodeLength)]
+ public virtual string EmailConfirmationCode { get; set; }
+
+ ///
+ /// Reset code for password.
+ /// It's not valid if it's null.
+ /// It's for one usage and must be set to null after reset.
+ ///
+ [StringLength(MaxPasswordResetCodeLength)]
+ public virtual string PasswordResetCode { get; set; }
+
+ ///
+ /// Lockout end date.
+ ///
+ public virtual DateTime? LockoutEndDateUtc { get; set; }
+
+ ///
+ /// Gets or sets the access failed count.
+ ///
+ public virtual int AccessFailedCount { get; set; }
+
+ ///
+ /// Gets or sets the lockout enabled.
+ ///
+ public virtual bool IsLockoutEnabled { get; set; }
+
+ ///
+ /// Gets or sets the phone number.
+ ///
+ public virtual string PhoneNumber { get; set; }
+
+ ///
+ /// Is the confirmed.
+ ///
+ public virtual bool IsPhoneNumberConfirmed { get; set; }
+
+ ///
+ /// Gets or sets the security stamp.
+ ///
+ public virtual string SecurityStamp { get; set; }
+
+ ///
+ /// Is two factor auth enabled.
+ ///
+ public virtual bool IsTwoFactorEnabled { get; set; }
+
+ ///
+ /// Login definitions for this user.
+ ///
+ [ForeignKey("UserId")]
+ public virtual ICollection Logins { get; set; }
+
+ ///
+ /// Roles of this user.
+ ///
+ [ForeignKey("UserId")]
+ public virtual ICollection Roles { get; set; }
+
+ ///
+ /// Claims of this user.
+ ///
+ [ForeignKey("UserId")]
+ public virtual ICollection Claims { get; set; }
+
+ ///
+ /// Permission definitions for this user.
+ ///
+ [ForeignKey("UserId")]
+ public virtual ICollection Permissions { get; set; }
+
+ ///
+ /// Settings for this user.
+ ///
+ [ForeignKey("UserId")]
+ public virtual ICollection Settings { get; set; }
+
+ ///
+ /// Is the confirmed.
+ ///
+ public virtual bool IsEmailConfirmed { get; set; }
+
+ ///
+ /// Is this user active?
+ /// If as user is not active, he/she can not use the application.
+ ///
+ public virtual bool IsActive { get; set; }
+
+ ///
+ /// The last time this user entered to the system.
+ ///
+ public virtual DateTime? LastLoginTime { get; set; }
+
+ protected AbpUserBase()
+ {
+ IsActive = true;
+ IsLockoutEnabled = true;
+ SecurityStamp = SequentialGuidGenerator.Instance.Create().ToString();
+ }
+
+ public virtual void SetNewPasswordResetCode()
+ {
+ PasswordResetCode = Guid.NewGuid().ToString("N").Truncate(MaxPasswordResetCodeLength);
+ }
+
+ public virtual void SetNewEmailConfirmationCode()
+ {
+ EmailConfirmationCode = Guid.NewGuid().ToString("N").Truncate(MaxEmailConfirmationCodeLength);
+ }
+
+ ///
+ /// Creates from this User.
+ ///
+ ///
+ public virtual UserIdentifier ToUserIdentifier()
+ {
+ return new UserIdentifier(TenantId, Id);
+ }
+
+ public override string ToString()
+ {
+ return $"[User {Id}] {UserName}";
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Abp.Zero/Authorization/Users/AbpUserPermissionCacheItemInvalidator.cs b/src/Abp.Zero.Common/Authorization/Users/AbpUserPermissionCacheItemInvalidator.cs
similarity index 100%
rename from src/Abp.Zero/Authorization/Users/AbpUserPermissionCacheItemInvalidator.cs
rename to src/Abp.Zero.Common/Authorization/Users/AbpUserPermissionCacheItemInvalidator.cs
diff --git a/src/Abp.Zero/Authorization/Users/DefaultExternalAuthenticationSource.cs b/src/Abp.Zero.Common/Authorization/Users/DefaultExternalAuthenticationSource.cs
similarity index 97%
rename from src/Abp.Zero/Authorization/Users/DefaultExternalAuthenticationSource.cs
rename to src/Abp.Zero.Common/Authorization/Users/DefaultExternalAuthenticationSource.cs
index e45b39f4..e465a7f3 100644
--- a/src/Abp.Zero/Authorization/Users/DefaultExternalAuthenticationSource.cs
+++ b/src/Abp.Zero.Common/Authorization/Users/DefaultExternalAuthenticationSource.cs
@@ -11,7 +11,7 @@ namespace Abp.Authorization.Users
/// User type
public abstract class DefaultExternalAuthenticationSource : IExternalAuthenticationSource
where TTenant : AbpTenant
- where TUser : AbpUser, new()
+ where TUser : AbpUserBase, new()
{
///
public abstract string Name { get; }
diff --git a/src/Abp.Zero/Authorization/Users/IExternalAuthenticationSource.cs b/src/Abp.Zero.Common/Authorization/Users/IExternalAuthenticationSource.cs
similarity index 89%
rename from src/Abp.Zero/Authorization/Users/IExternalAuthenticationSource.cs
rename to src/Abp.Zero.Common/Authorization/Users/IExternalAuthenticationSource.cs
index d6adb2c6..cfd6dea0 100644
--- a/src/Abp.Zero/Authorization/Users/IExternalAuthenticationSource.cs
+++ b/src/Abp.Zero.Common/Authorization/Users/IExternalAuthenticationSource.cs
@@ -4,17 +4,17 @@
namespace Abp.Authorization.Users
{
///
- /// Defines an authorization source to be used by method.
+ /// Defines an external authorization source.
///
/// Tenant type
/// User type
public interface IExternalAuthenticationSource
where TTenant : AbpTenant
- where TUser : AbpUser
+ where TUser : AbpUserBase
{
///
/// Unique name of the authentication source.
- /// This source name is set to
+ /// This source name is set to
/// if the user authenticated by this authentication source
///
string Name { get; }
diff --git a/src/Abp.Zero/Authorization/Users/IUserPermissionStore.cs b/src/Abp.Zero.Common/Authorization/Users/IUserPermissionStore.cs
similarity index 95%
rename from src/Abp.Zero/Authorization/Users/IUserPermissionStore.cs
rename to src/Abp.Zero.Common/Authorization/Users/IUserPermissionStore.cs
index 808418d2..8bf692fe 100644
--- a/src/Abp.Zero/Authorization/Users/IUserPermissionStore.cs
+++ b/src/Abp.Zero.Common/Authorization/Users/IUserPermissionStore.cs
@@ -1,47 +1,47 @@
-using System.Collections.Generic;
-using System.Threading.Tasks;
-
-namespace Abp.Authorization.Users
-{
- ///
- /// Used to perform permission database operations for a user.
- ///
- public interface IUserPermissionStore
- where TUser : AbpUser
- {
- ///
- /// Adds a permission grant setting to a user.
- ///
- /// User
- /// Permission grant setting info
- Task AddPermissionAsync(TUser user, PermissionGrantInfo permissionGrant);
-
- ///
- /// Removes a permission grant setting from a user.
- ///
- /// User
- /// Permission grant setting info
- Task RemovePermissionAsync(TUser user, PermissionGrantInfo permissionGrant);
-
- ///
- /// Gets permission grant setting informations for a user.
- ///
- /// User id
- /// List of permission setting informations
- Task> GetPermissionsAsync(long userId);
-
- ///
- /// Checks whether a role has a permission grant setting info.
- ///
- /// User id
- /// Permission grant setting info
- ///
- Task HasPermissionAsync(long userId, PermissionGrantInfo permissionGrant);
-
- ///
- /// Deleted all permission settings for a role.
- ///
- /// User
- Task RemoveAllPermissionSettingsAsync(TUser user);
- }
+using System.Collections.Generic;
+using System.Threading.Tasks;
+
+namespace Abp.Authorization.Users
+{
+ ///
+ /// Used to perform permission database operations for a user.
+ ///
+ public interface IUserPermissionStore
+ where TUser : AbpUserBase
+ {
+ ///
+ /// Adds a permission grant setting to a user.
+ ///
+ /// User
+ /// Permission grant setting info
+ Task AddPermissionAsync(TUser user, PermissionGrantInfo permissionGrant);
+
+ ///
+ /// Removes a permission grant setting from a user.
+ ///
+ /// User
+ /// Permission grant setting info
+ Task RemovePermissionAsync(TUser user, PermissionGrantInfo permissionGrant);
+
+ ///
+ /// Gets permission grant setting informations for a user.
+ ///
+ /// User id
+ /// List of permission setting informations
+ Task> GetPermissionsAsync(long userId);
+
+ ///
+ /// Checks whether a role has a permission grant setting info.
+ ///
+ /// User id
+ /// Permission grant setting info
+ ///
+ Task HasPermissionAsync(long userId, PermissionGrantInfo permissionGrant);
+
+ ///
+ /// Deleted all permission settings for a role.
+ ///
+ /// User
+ Task RemoveAllPermissionSettingsAsync(TUser user);
+ }
}
\ No newline at end of file
diff --git a/src/Abp.Zero/Authorization/Users/UserAccount.cs b/src/Abp.Zero.Common/Authorization/Users/UserAccount.cs
similarity index 96%
rename from src/Abp.Zero/Authorization/Users/UserAccount.cs
rename to src/Abp.Zero.Common/Authorization/Users/UserAccount.cs
index a7864da9..c027cfe3 100644
--- a/src/Abp.Zero/Authorization/Users/UserAccount.cs
+++ b/src/Abp.Zero.Common/Authorization/Users/UserAccount.cs
@@ -1,27 +1,27 @@
-using System;
-using System.ComponentModel.DataAnnotations.Schema;
-using Abp.Domain.Entities.Auditing;
-using Abp.MultiTenancy;
-
-namespace Abp.Authorization.Users
-{
- ///
- /// Represents a summary user
- ///
- [Table("AbpUserAccounts")]
- [MultiTenancySide(MultiTenancySides.Host)]
- public class UserAccount : FullAuditedEntity
- {
- public virtual int? TenantId { get; set; }
-
- public virtual long UserId { get; set; }
-
- public virtual long? UserLinkId { get; set; }
-
- public virtual string UserName { get; set; }
-
- public virtual string EmailAddress { get; set; }
-
- public virtual DateTime? LastLoginTime { get; set; }
- }
+using System;
+using System.ComponentModel.DataAnnotations.Schema;
+using Abp.Domain.Entities.Auditing;
+using Abp.MultiTenancy;
+
+namespace Abp.Authorization.Users
+{
+ ///
+ /// Represents a summary user
+ ///
+ [Table("AbpUserAccounts")]
+ [MultiTenancySide(MultiTenancySides.Host)]
+ public class UserAccount : FullAuditedEntity
+ {
+ public virtual int? TenantId { get; set; }
+
+ public virtual long UserId { get; set; }
+
+ public virtual long? UserLinkId { get; set; }
+
+ public virtual string UserName { get; set; }
+
+ public virtual string EmailAddress { get; set; }
+
+ public virtual DateTime? LastLoginTime { get; set; }
+ }
}
\ No newline at end of file
diff --git a/src/Abp.Zero/Authorization/Users/UserAccountSynchronizer.cs b/src/Abp.Zero.Common/Authorization/Users/UserAccountSynchronizer.cs
similarity index 97%
rename from src/Abp.Zero/Authorization/Users/UserAccountSynchronizer.cs
rename to src/Abp.Zero.Common/Authorization/Users/UserAccountSynchronizer.cs
index 3cd059cf..42a89140 100644
--- a/src/Abp.Zero/Authorization/Users/UserAccountSynchronizer.cs
+++ b/src/Abp.Zero.Common/Authorization/Users/UserAccountSynchronizer.cs
@@ -1,90 +1,90 @@
-using Abp.Dependency;
-using Abp.Domain.Repositories;
-using Abp.Domain.Uow;
-using Abp.Events.Bus.Entities;
-using Abp.Events.Bus.Handlers;
-
-namespace Abp.Authorization.Users
-{
- ///
- /// Synchronizes a user's information to user account.
- ///
- public class UserAccountSynchronizer :
- IEventHandler>,
- IEventHandler>,
- IEventHandler>,
- ITransientDependency
- {
- private readonly IRepository _userAccountRepository;
- private readonly IUnitOfWorkManager _unitOfWorkManager;
-
- ///
- /// Constructor
- ///
- public UserAccountSynchronizer(
- IRepository userAccountRepository,
- IUnitOfWorkManager unitOfWorkManager)
- {
- _userAccountRepository = userAccountRepository;
- _unitOfWorkManager = unitOfWorkManager;
- }
-
- ///
- /// Handles creation event of user
- ///
- [UnitOfWork]
- public virtual void HandleEvent(EntityCreatedEventData eventData)
- {
- using (_unitOfWorkManager.Current.SetTenantId(null))
- {
- _userAccountRepository.Insert(new UserAccount
- {
- TenantId = eventData.Entity.TenantId,
- UserName = eventData.Entity.UserName,
- UserId = eventData.Entity.Id,
- EmailAddress = eventData.Entity.EmailAddress,
- LastLoginTime = eventData.Entity.LastLoginTime
- });
- }
- }
-
- ///
- /// Handles deletion event of user
- ///
- ///
- [UnitOfWork]
- public virtual void HandleEvent(EntityDeletedEventData eventData)
- {
- using (_unitOfWorkManager.Current.SetTenantId(null))
- {
- var userAccount =
- _userAccountRepository.FirstOrDefault(
- ua => ua.TenantId == eventData.Entity.TenantId && ua.UserId == eventData.Entity.Id);
- if (userAccount != null)
- {
- _userAccountRepository.Delete(userAccount);
- }
- }
- }
-
- ///
- /// Handles update event of user
- ///
- ///
- [UnitOfWork]
- public virtual void HandleEvent(EntityUpdatedEventData eventData)
- {
- using (_unitOfWorkManager.Current.SetTenantId(null))
- {
- var userAccount = _userAccountRepository.FirstOrDefault(ua => ua.TenantId == eventData.Entity.TenantId && ua.UserId == eventData.Entity.Id);
- if (userAccount != null)
- {
- userAccount.UserName = eventData.Entity.UserName;
- userAccount.EmailAddress = eventData.Entity.EmailAddress;
- userAccount.LastLoginTime = eventData.Entity.LastLoginTime;
- _userAccountRepository.Update(userAccount);
- }
- }
- }
- }
+using Abp.Dependency;
+using Abp.Domain.Repositories;
+using Abp.Domain.Uow;
+using Abp.Events.Bus.Entities;
+using Abp.Events.Bus.Handlers;
+
+namespace Abp.Authorization.Users
+{
+ ///
+ /// Synchronizes a user's information to user account.
+ ///
+ public class UserAccountSynchronizer :
+ IEventHandler>,
+ IEventHandler>,
+ IEventHandler>,
+ ITransientDependency
+ {
+ private readonly IRepository _userAccountRepository;
+ private readonly IUnitOfWorkManager _unitOfWorkManager;
+
+ ///
+ /// Constructor
+ ///
+ public UserAccountSynchronizer(
+ IRepository userAccountRepository,
+ IUnitOfWorkManager unitOfWorkManager)
+ {
+ _userAccountRepository = userAccountRepository;
+ _unitOfWorkManager = unitOfWorkManager;
+ }
+
+ ///
+ /// Handles creation event of user
+ ///
+ [UnitOfWork]
+ public virtual void HandleEvent(EntityCreatedEventData eventData)
+ {
+ using (_unitOfWorkManager.Current.SetTenantId(null))
+ {
+ _userAccountRepository.Insert(new UserAccount
+ {
+ TenantId = eventData.Entity.TenantId,
+ UserName = eventData.Entity.UserName,
+ UserId = eventData.Entity.Id,
+ EmailAddress = eventData.Entity.EmailAddress,
+ LastLoginTime = eventData.Entity.LastLoginTime
+ });
+ }
+ }
+
+ ///
+ /// Handles deletion event of user
+ ///
+ ///
+ [UnitOfWork]
+ public virtual void HandleEvent(EntityDeletedEventData eventData)
+ {
+ using (_unitOfWorkManager.Current.SetTenantId(null))
+ {
+ var userAccount =
+ _userAccountRepository.FirstOrDefault(
+ ua => ua.TenantId == eventData.Entity.TenantId && ua.UserId == eventData.Entity.Id);
+ if (userAccount != null)
+ {
+ _userAccountRepository.Delete(userAccount);
+ }
+ }
+ }
+
+ ///
+ /// Handles update event of user
+ ///
+ ///
+ [UnitOfWork]
+ public virtual void HandleEvent(EntityUpdatedEventData eventData)
+ {
+ using (_unitOfWorkManager.Current.SetTenantId(null))
+ {
+ var userAccount = _userAccountRepository.FirstOrDefault(ua => ua.TenantId == eventData.Entity.TenantId && ua.UserId == eventData.Entity.Id);
+ if (userAccount != null)
+ {
+ userAccount.UserName = eventData.Entity.UserName;
+ userAccount.EmailAddress = eventData.Entity.EmailAddress;
+ userAccount.LastLoginTime = eventData.Entity.LastLoginTime;
+ _userAccountRepository.Update(userAccount);
+ }
+ }
+ }
+ }
}
\ No newline at end of file
diff --git a/src/Abp.Zero/Authorization/Users/UserClaim.cs b/src/Abp.Zero.Common/Authorization/Users/UserClaim.cs
similarity index 95%
rename from src/Abp.Zero/Authorization/Users/UserClaim.cs
rename to src/Abp.Zero.Common/Authorization/Users/UserClaim.cs
index 7964afda..b328a17d 100644
--- a/src/Abp.Zero/Authorization/Users/UserClaim.cs
+++ b/src/Abp.Zero.Common/Authorization/Users/UserClaim.cs
@@ -26,7 +26,7 @@ public UserClaim(AbpUserBase user, Claim claim)
TenantId = user.TenantId;
UserId = user.Id;
ClaimType = claim.Type;
- ClaimType = claim.Value;
+ ClaimValue = claim.Value;
}
}
}
diff --git a/src/Abp.Zero/Authorization/Users/UserLogin.cs b/src/Abp.Zero.Common/Authorization/Users/UserLogin.cs
similarity index 80%
rename from src/Abp.Zero/Authorization/Users/UserLogin.cs
rename to src/Abp.Zero.Common/Authorization/Users/UserLogin.cs
index ac9d6da6..a3ca3ce9 100644
--- a/src/Abp.Zero/Authorization/Users/UserLogin.cs
+++ b/src/Abp.Zero.Common/Authorization/Users/UserLogin.cs
@@ -40,5 +40,18 @@ public class UserLogin : Entity, IMayHaveTenant
[Required]
[MaxLength(MaxProviderKeyLength)]
public virtual string ProviderKey { get; set; }
+
+ public UserLogin()
+ {
+
+ }
+
+ public UserLogin(int? tenantId, long userId, string loginProvider, string providerKey)
+ {
+ TenantId = tenantId;
+ UserId = userId;
+ LoginProvider = loginProvider;
+ ProviderKey = providerKey;
+ }
}
}
diff --git a/src/Abp.Zero/Authorization/Users/UserLoginAttempt.cs b/src/Abp.Zero.Common/Authorization/Users/UserLoginAttempt.cs
similarity index 100%
rename from src/Abp.Zero/Authorization/Users/UserLoginAttempt.cs
rename to src/Abp.Zero.Common/Authorization/Users/UserLoginAttempt.cs
diff --git a/src/Abp.Zero/Authorization/Users/UserOrganizationUnit.cs b/src/Abp.Zero.Common/Authorization/Users/UserOrganizationUnit.cs
similarity index 88%
rename from src/Abp.Zero/Authorization/Users/UserOrganizationUnit.cs
rename to src/Abp.Zero.Common/Authorization/Users/UserOrganizationUnit.cs
index 0733b102..98168237 100644
--- a/src/Abp.Zero/Authorization/Users/UserOrganizationUnit.cs
+++ b/src/Abp.Zero.Common/Authorization/Users/UserOrganizationUnit.cs
@@ -9,7 +9,7 @@ namespace Abp.Authorization.Users
/// Represents membership of a User to an OU.
///
[Table("AbpUserOrganizationUnits")]
- public class UserOrganizationUnit : CreationAuditedEntity, IMayHaveTenant
+ public class UserOrganizationUnit : CreationAuditedEntity, IMayHaveTenant, ISoftDelete
{
///
/// TenantId of this entity.
@@ -26,6 +26,11 @@ public class UserOrganizationUnit : CreationAuditedEntity, IMayHaveTenant
///
public virtual long OrganizationUnitId { get; set; }
+ ///
+ /// Specifies if the organization is soft deleted or not.
+ ///
+ public virtual bool IsDeleted { get; set; }
+
///
/// Initializes a new instance of the class.
///
diff --git a/src/Abp.Zero/Authorization/Users/UserOrganizationUnitRemover.cs b/src/Abp.Zero.Common/Authorization/Users/UserOrganizationUnitRemover.cs
similarity index 100%
rename from src/Abp.Zero/Authorization/Users/UserOrganizationUnitRemover.cs
rename to src/Abp.Zero.Common/Authorization/Users/UserOrganizationUnitRemover.cs
diff --git a/src/Abp.Zero/Authorization/Users/UserPermissionCacheItem.cs b/src/Abp.Zero.Common/Authorization/Users/UserPermissionCacheItem.cs
similarity index 96%
rename from src/Abp.Zero/Authorization/Users/UserPermissionCacheItem.cs
rename to src/Abp.Zero.Common/Authorization/Users/UserPermissionCacheItem.cs
index ed198ab8..ebf2f995 100644
--- a/src/Abp.Zero/Authorization/Users/UserPermissionCacheItem.cs
+++ b/src/Abp.Zero.Common/Authorization/Users/UserPermissionCacheItem.cs
@@ -1,35 +1,35 @@
-using System;
-using System.Collections.Generic;
-
-namespace Abp.Authorization.Users
-{
- ///
- /// Used to cache roles and permissions of a user.
- ///
- [Serializable]
- public class UserPermissionCacheItem
- {
- public const string CacheStoreName = "AbpZeroUserPermissions";
-
- public long UserId { get; set; }
-
- public List RoleIds { get; set; }
-
- public HashSet GrantedPermissions { get; set; }
-
- public HashSet ProhibitedPermissions { get; set; }
-
- public UserPermissionCacheItem()
- {
- RoleIds = new List();
- GrantedPermissions = new HashSet();
- ProhibitedPermissions = new HashSet();
- }
-
- public UserPermissionCacheItem(long userId)
- : this()
- {
- UserId = userId;
- }
- }
-}
+using System;
+using System.Collections.Generic;
+
+namespace Abp.Authorization.Users
+{
+ ///
+ /// Used to cache roles and permissions of a user.
+ ///
+ [Serializable]
+ public class UserPermissionCacheItem
+ {
+ public const string CacheStoreName = "AbpZeroUserPermissions";
+
+ public long UserId { get; set; }
+
+ public List RoleIds { get; set; }
+
+ public HashSet GrantedPermissions { get; set; }
+
+ public HashSet ProhibitedPermissions { get; set; }
+
+ public UserPermissionCacheItem()
+ {
+ RoleIds = new List();
+ GrantedPermissions = new HashSet();
+ ProhibitedPermissions = new HashSet();
+ }
+
+ public UserPermissionCacheItem(long userId)
+ : this()
+ {
+ UserId = userId;
+ }
+ }
+}
diff --git a/src/Abp.Zero/Authorization/Users/UserPermissionSetting.cs b/src/Abp.Zero.Common/Authorization/Users/UserPermissionSetting.cs
similarity index 100%
rename from src/Abp.Zero/Authorization/Users/UserPermissionSetting.cs
rename to src/Abp.Zero.Common/Authorization/Users/UserPermissionSetting.cs
diff --git a/src/Abp.Zero/Authorization/Users/UserRole.cs b/src/Abp.Zero.Common/Authorization/Users/UserRole.cs
similarity index 100%
rename from src/Abp.Zero/Authorization/Users/UserRole.cs
rename to src/Abp.Zero.Common/Authorization/Users/UserRole.cs
diff --git a/src/Abp.Zero/Authorization/Users/UserRoleRemover.cs b/src/Abp.Zero.Common/Authorization/Users/UserRoleRemover.cs
similarity index 93%
rename from src/Abp.Zero/Authorization/Users/UserRoleRemover.cs
rename to src/Abp.Zero.Common/Authorization/Users/UserRoleRemover.cs
index 6fcea0c1..0c477965 100644
--- a/src/Abp.Zero/Authorization/Users/UserRoleRemover.cs
+++ b/src/Abp.Zero.Common/Authorization/Users/UserRoleRemover.cs
@@ -7,7 +7,7 @@
namespace Abp.Authorization.Users
{
///
- /// Removes the user from all organization units when a user is deleted.
+ /// Removes the user from all user roles when a user is deleted.
///
public class UserRoleRemover :
IEventHandler>,
@@ -35,4 +35,4 @@ public virtual void HandleEvent(EntityDeletedEventData eventData)
}
}
}
-}
\ No newline at end of file
+}
diff --git a/src/Abp.Zero/BackgroundJobs/BackgroundJobStore.cs b/src/Abp.Zero.Common/BackgroundJobs/BackgroundJobStore.cs
similarity index 100%
rename from src/Abp.Zero/BackgroundJobs/BackgroundJobStore.cs
rename to src/Abp.Zero.Common/BackgroundJobs/BackgroundJobStore.cs
diff --git a/src/Abp.Zero/Configuration/Setting.cs b/src/Abp.Zero.Common/Configuration/Setting.cs
similarity index 100%
rename from src/Abp.Zero/Configuration/Setting.cs
rename to src/Abp.Zero.Common/Configuration/Setting.cs
diff --git a/src/Abp.Zero/Configuration/SettingExtensions.cs b/src/Abp.Zero.Common/Configuration/SettingExtensions.cs
similarity index 100%
rename from src/Abp.Zero/Configuration/SettingExtensions.cs
rename to src/Abp.Zero.Common/Configuration/SettingExtensions.cs
diff --git a/src/Abp.Zero/Configuration/SettingStore.cs b/src/Abp.Zero.Common/Configuration/SettingStore.cs
similarity index 100%
rename from src/Abp.Zero/Configuration/SettingStore.cs
rename to src/Abp.Zero.Common/Configuration/SettingStore.cs
diff --git a/src/Abp.Zero/Localization/ApplicationLanguage.cs b/src/Abp.Zero.Common/Localization/ApplicationLanguage.cs
similarity index 83%
rename from src/Abp.Zero/Localization/ApplicationLanguage.cs
rename to src/Abp.Zero.Common/Localization/ApplicationLanguage.cs
index c4a4bd2c..50c79432 100644
--- a/src/Abp.Zero/Localization/ApplicationLanguage.cs
+++ b/src/Abp.Zero.Common/Localization/ApplicationLanguage.cs
@@ -53,6 +53,11 @@ public class ApplicationLanguage : FullAuditedEntity, IMayHaveTenant
[StringLength(MaxIconLength)]
public virtual string Icon { get; set; }
+ ///
+ /// Is this language active. Inactive languages are not get by .
+ ///
+ public bool IsDisabled { get; set; }
+
///
/// Creates a new object.
///
@@ -60,17 +65,18 @@ public ApplicationLanguage()
{
}
- public ApplicationLanguage(int? tenantId, string name, string displayName, string icon = null)
+ public ApplicationLanguage(int? tenantId, string name, string displayName, string icon = null, bool isDisabled = false)
{
TenantId = tenantId;
Name = name;
DisplayName = displayName;
Icon = icon;
+ IsDisabled = isDisabled;
}
public virtual LanguageInfo ToLanguageInfo()
{
- return new LanguageInfo(Name, DisplayName, Icon);
+ return new LanguageInfo(Name, DisplayName, Icon, isDisabled: IsDisabled);
}
}
}
diff --git a/src/Abp.Zero/Localization/ApplicationLanguageManager.cs b/src/Abp.Zero.Common/Localization/ApplicationLanguageManager.cs
similarity index 92%
rename from src/Abp.Zero/Localization/ApplicationLanguageManager.cs
rename to src/Abp.Zero.Common/Localization/ApplicationLanguageManager.cs
index beb72a01..138cdb01 100644
--- a/src/Abp.Zero/Localization/ApplicationLanguageManager.cs
+++ b/src/Abp.Zero.Common/Localization/ApplicationLanguageManager.cs
@@ -1,6 +1,5 @@
using System.Collections.Generic;
using System.Collections.Immutable;
-using System.Globalization;
using System.Linq;
using System.Threading.Tasks;
using Abp.Configuration;
@@ -26,10 +25,7 @@ public class ApplicationLanguageManager :
///
public const string CacheName = "AbpZeroLanguages";
- private ITypedCache> LanguageListCache
- {
- get { return _cacheManager.GetCache>(CacheName); }
- }
+ private ITypedCache> LanguageListCache => _cacheManager.GetCache>(CacheName);
private readonly IRepository _languageRepository;
private readonly ICacheManager _cacheManager;
@@ -55,7 +51,7 @@ public ApplicationLanguageManager(
/// Gets list of all languages available to given tenant (or null for host)
///
/// TenantId or null for host
- public async Task> GetLanguagesAsync(int? tenantId)
+ public virtual async Task> GetLanguagesAsync(int? tenantId)
{
return (await GetLanguageDictionary(tenantId)).Values.ToImmutableList();
}
@@ -136,7 +132,7 @@ public virtual async Task UpdateAsync(int? tenantId, ApplicationLanguage languag
/// Gets the default language or null for a tenant or the host.
///
/// Tenant Id of null for host
- public async Task GetDefaultLanguageOrNullAsync(int? tenantId)
+ public virtual async Task GetDefaultLanguageOrNullAsync(int? tenantId)
{
var defaultLanguageName = tenantId.HasValue
? await _settingManager.GetSettingValueForTenantAsync(LocalizationSettingNames.DefaultLanguage, tenantId.Value)
@@ -150,9 +146,9 @@ public async Task GetDefaultLanguageOrNullAsync(int? tenant
///
/// Tenant Id of null for host
/// Name of the language.
- public async Task SetDefaultLanguageAsync(int? tenantId, string languageName)
+ public virtual async Task SetDefaultLanguageAsync(int? tenantId, string languageName)
{
- var cultureInfo = CultureInfo.GetCultureInfo(languageName);
+ var cultureInfo = CultureInfoHelper.Get(languageName);
if (tenantId.HasValue)
{
await _settingManager.ChangeSettingForTenantAsync(tenantId.Value, LocalizationSettingNames.DefaultLanguage, cultureInfo.Name);
@@ -171,7 +167,7 @@ public void HandleEvent(EntityChangedEventData eventData)
_cacheManager.GetCache("AbpLocalizationScripts").Clear();
}
- private async Task> GetLanguageDictionary(int? tenantId)
+ protected virtual async Task> GetLanguageDictionary(int? tenantId)
{
//Creates a copy of the cached dictionary (to not modify it)
var languageDictionary = new Dictionary(await GetLanguageDictionaryFromCacheAsync(null));
diff --git a/src/Abp.Zero/Localization/ApplicationLanguageProvider.cs b/src/Abp.Zero.Common/Localization/ApplicationLanguageProvider.cs
similarity index 100%
rename from src/Abp.Zero/Localization/ApplicationLanguageProvider.cs
rename to src/Abp.Zero.Common/Localization/ApplicationLanguageProvider.cs
diff --git a/src/Abp.Zero/Localization/ApplicationLanguageText.cs b/src/Abp.Zero.Common/Localization/ApplicationLanguageText.cs
similarity index 100%
rename from src/Abp.Zero/Localization/ApplicationLanguageText.cs
rename to src/Abp.Zero.Common/Localization/ApplicationLanguageText.cs
diff --git a/src/Abp.Zero/Localization/ApplicationLanguageTextManager.cs b/src/Abp.Zero.Common/Localization/ApplicationLanguageTextManager.cs
similarity index 100%
rename from src/Abp.Zero/Localization/ApplicationLanguageTextManager.cs
rename to src/Abp.Zero.Common/Localization/ApplicationLanguageTextManager.cs
diff --git a/src/Abp.Zero/Localization/EmptyDictionary.cs b/src/Abp.Zero.Common/Localization/EmptyDictionary.cs
similarity index 100%
rename from src/Abp.Zero/Localization/EmptyDictionary.cs
rename to src/Abp.Zero.Common/Localization/EmptyDictionary.cs
diff --git a/src/Abp.Zero/Localization/IApplicationLanguageManager.cs b/src/Abp.Zero.Common/Localization/IApplicationLanguageManager.cs
similarity index 100%
rename from src/Abp.Zero/Localization/IApplicationLanguageManager.cs
rename to src/Abp.Zero.Common/Localization/IApplicationLanguageManager.cs
diff --git a/src/Abp.Zero/Localization/IApplicationLanguageTextManager.cs b/src/Abp.Zero.Common/Localization/IApplicationLanguageTextManager.cs
similarity index 100%
rename from src/Abp.Zero/Localization/IApplicationLanguageTextManager.cs
rename to src/Abp.Zero.Common/Localization/IApplicationLanguageTextManager.cs
diff --git a/src/Abp.Zero/Localization/IMultiTenantLocalizationDictionary.cs b/src/Abp.Zero.Common/Localization/IMultiTenantLocalizationDictionary.cs
similarity index 100%
rename from src/Abp.Zero/Localization/IMultiTenantLocalizationDictionary.cs
rename to src/Abp.Zero.Common/Localization/IMultiTenantLocalizationDictionary.cs
diff --git a/src/Abp.Zero/Localization/IMultiTenantLocalizationSource.cs b/src/Abp.Zero.Common/Localization/IMultiTenantLocalizationSource.cs
similarity index 100%
rename from src/Abp.Zero/Localization/IMultiTenantLocalizationSource.cs
rename to src/Abp.Zero.Common/Localization/IMultiTenantLocalizationSource.cs
diff --git a/src/Abp.Zero/Localization/MultiTenantLocalizationDictionary.cs b/src/Abp.Zero.Common/Localization/MultiTenantLocalizationDictionary.cs
similarity index 100%
rename from src/Abp.Zero/Localization/MultiTenantLocalizationDictionary.cs
rename to src/Abp.Zero.Common/Localization/MultiTenantLocalizationDictionary.cs
diff --git a/src/Abp.Zero/Localization/MultiTenantLocalizationDictionaryCacheCleaner.cs b/src/Abp.Zero.Common/Localization/MultiTenantLocalizationDictionaryCacheCleaner.cs
similarity index 100%
rename from src/Abp.Zero/Localization/MultiTenantLocalizationDictionaryCacheCleaner.cs
rename to src/Abp.Zero.Common/Localization/MultiTenantLocalizationDictionaryCacheCleaner.cs
diff --git a/src/Abp.Zero/Localization/MultiTenantLocalizationDictionaryCacheHelper.cs b/src/Abp.Zero.Common/Localization/MultiTenantLocalizationDictionaryCacheHelper.cs
similarity index 100%
rename from src/Abp.Zero/Localization/MultiTenantLocalizationDictionaryCacheHelper.cs
rename to src/Abp.Zero.Common/Localization/MultiTenantLocalizationDictionaryCacheHelper.cs
diff --git a/src/Abp.Zero/Localization/MultiTenantLocalizationDictionaryProvider.cs b/src/Abp.Zero.Common/Localization/MultiTenantLocalizationDictionaryProvider.cs
similarity index 93%
rename from src/Abp.Zero/Localization/MultiTenantLocalizationDictionaryProvider.cs
rename to src/Abp.Zero.Common/Localization/MultiTenantLocalizationDictionaryProvider.cs
index 7bc343be..a7a1274b 100644
--- a/src/Abp.Zero/Localization/MultiTenantLocalizationDictionaryProvider.cs
+++ b/src/Abp.Zero.Common/Localization/MultiTenantLocalizationDictionaryProvider.cs
@@ -1,4 +1,3 @@
-using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Globalization;
@@ -6,7 +5,6 @@
using Abp.Collections.Extensions;
using Abp.Dependency;
using Abp.Localization.Dictionaries;
-using Abp.Collections.Extensions;
namespace Abp.Localization
{
@@ -68,13 +66,13 @@ protected virtual ILocalizationDictionary GetDefaultDictionary()
var languages = _languageManager.GetLanguages();
if (!languages.Any())
{
- throw new ApplicationException("No language defined!");
+ throw new AbpException("No language defined!");
}
var defaultLanguage = languages.FirstOrDefault(l => l.IsDefault);
if (defaultLanguage == null)
{
- throw new ApplicationException("Default language is not defined!");
+ throw new AbpException("Default language is not defined!");
}
return _dictionaries.GetOrAdd(defaultLanguage.Name, s => CreateLocalizationDictionary(defaultLanguage));
@@ -84,7 +82,7 @@ protected virtual IMultiTenantLocalizationDictionary CreateLocalizationDictionar
{
var internalDictionary =
_internalProvider.Dictionaries.GetOrDefault(language.Name) ??
- new EmptyDictionary(CultureInfo.GetCultureInfo(language.Name));
+ new EmptyDictionary(CultureInfoHelper.Get(language.Name));
var dictionary = _iocManager.Resolve(new
{
diff --git a/src/Abp.Zero/Localization/MultiTenantLocalizationSource.cs b/src/Abp.Zero.Common/Localization/MultiTenantLocalizationSource.cs
similarity index 99%
rename from src/Abp.Zero/Localization/MultiTenantLocalizationSource.cs
rename to src/Abp.Zero.Common/Localization/MultiTenantLocalizationSource.cs
index d3487005..c91a87a2 100644
--- a/src/Abp.Zero/Localization/MultiTenantLocalizationSource.cs
+++ b/src/Abp.Zero.Common/Localization/MultiTenantLocalizationSource.cs
@@ -107,7 +107,7 @@ public override void Extend(ILocalizationDictionary dictionary)
private static string GetBaseCultureName(string cultureName)
{
return cultureName.Contains("-")
- ? cultureName.Left(cultureName.IndexOf("-", StringComparison.InvariantCulture))
+ ? cultureName.Left(cultureName.IndexOf("-", StringComparison.Ordinal))
: cultureName;
}
}
diff --git a/src/Abp.Zero/MultiTenancy/AbpTenant.cs b/src/Abp.Zero.Common/MultiTenancy/AbpTenant.cs
similarity index 85%
rename from src/Abp.Zero/MultiTenancy/AbpTenant.cs
rename to src/Abp.Zero.Common/MultiTenancy/AbpTenant.cs
index ae41ca01..86742e4a 100644
--- a/src/Abp.Zero/MultiTenancy/AbpTenant.cs
+++ b/src/Abp.Zero.Common/MultiTenancy/AbpTenant.cs
@@ -1,84 +1,78 @@
-using System.ComponentModel.DataAnnotations;
-using Abp.Application.Editions;
-using Abp.Authorization.Users;
-using Abp.Domain.Entities;
-using Abp.Domain.Entities.Auditing;
-
-namespace Abp.MultiTenancy
-{
- ///
- /// Represents a Tenant of the application.
- ///
- public abstract class AbpTenant : AbpTenantBase, IFullAudited, IPassivable
- where TUser : AbpUser
- {
- ///
- /// "Default".
- ///
- public const string DefaultTenantName = "Default";
-
- ///
- /// "^[a-zA-Z][a-zA-Z0-9_-]{1,}$".
- ///
- public const string TenancyNameRegex = "^[a-zA-Z][a-zA-Z0-9_-]{1,}$";
-
- ///
- /// Max length of the property.
- ///
- public const int MaxNameLength = 128;
-
- ///
- /// Current of the Tenant.
- ///
- public virtual Edition Edition { get; set; }
- public virtual int? EditionId { get; set; }
-
- ///
- /// Display name of the Tenant.
- ///
- [Required]
- [StringLength(MaxNameLength)]
- public virtual string Name { get; set; }
-
- ///
- /// Is this tenant active?
- /// If as tenant is not active, no user of this tenant can use the application.
- ///
- public virtual bool IsActive { get; set; }
-
- ///
- /// Reference to the creator user of this entity.
- ///
- public virtual TUser CreatorUser { get; set; }
-
- ///
- /// Reference to the last modifier user of this entity.
- ///
- public virtual TUser LastModifierUser { get; set; }
-
- ///
- /// Reference to the deleter user of this entity.
- ///
- public virtual TUser DeleterUser { get; set; }
-
- ///
- /// Creates a new tenant.
- ///
- protected AbpTenant()
- {
- IsActive = true;
- }
-
- ///
- /// Creates a new tenant.
- ///
- /// UNIQUE name of this Tenant
- /// Display name of the Tenant
- protected AbpTenant(string tenancyName, string name)
- : this()
- {
- TenancyName = tenancyName;
- Name = name;
- }
- }
-}
+using System.ComponentModel.DataAnnotations;
+using Abp.Application.Editions;
+using Abp.Authorization.Users;
+using Abp.Domain.Entities;
+using Abp.Domain.Entities.Auditing;
+
+namespace Abp.MultiTenancy
+{
+ ///
+ /// Represents a Tenant of the application.
+ ///
+ public abstract class AbpTenant : AbpTenantBase, IFullAudited
+ where TUser : AbpUserBase
+ {
+ ///
+ /// "Default".
+ ///
+ public const string DefaultTenantName = "Default";
+
+ ///
+ /// "^[a-zA-Z][a-zA-Z0-9_-]{1,}$".
+ ///
+ public const string TenancyNameRegex = "^[a-zA-Z][a-zA-Z0-9_-]{1,}$";
+
+ ///
+ /// Max length of the property.
+ ///
+ public const int MaxNameLength = 128;
+
+ ///
+ /// Current of the Tenant.
+ ///
+ public virtual Edition Edition { get; set; }
+ public virtual int? EditionId { get; set; }
+
+ ///
+ /// Display name of the Tenant.
+ ///
+ [Required]
+ [StringLength(MaxNameLength)]
+ public virtual string Name { get; set; }
+
+ ///
+ /// Reference to the creator user of this entity.
+ ///
+ public virtual TUser CreatorUser { get; set; }
+
+ ///
+ /// Reference to the last modifier user of this entity.
+ ///
+ public virtual TUser LastModifierUser { get; set; }
+
+ ///
+ /// Reference to the deleter user of this entity.
+ ///
+ public virtual TUser DeleterUser { get; set; }
+
+ ///
+ /// Creates a new tenant.
+ ///
+ protected AbpTenant()
+ {
+ IsActive = true;
+ }
+
+ ///
+ /// Creates a new tenant.
+ ///
+ /// UNIQUE name of this Tenant
+ /// Display name of the Tenant
+ protected AbpTenant(string tenancyName, string name)
+ : this()
+ {
+ TenancyName = tenancyName;
+ Name = name;
+ }
+ }
+}
diff --git a/src/Abp.Zero/MultiTenancy/AbpTenantBase.cs b/src/Abp.Zero.Common/MultiTenancy/AbpTenantBase.cs
similarity index 84%
rename from src/Abp.Zero/MultiTenancy/AbpTenantBase.cs
rename to src/Abp.Zero.Common/MultiTenancy/AbpTenantBase.cs
index 2e035f0f..e5937ab0 100644
--- a/src/Abp.Zero/MultiTenancy/AbpTenantBase.cs
+++ b/src/Abp.Zero.Common/MultiTenancy/AbpTenantBase.cs
@@ -1,5 +1,6 @@
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
+using Abp.Domain.Entities;
using Abp.Domain.Entities.Auditing;
using Abp.Runtime.Security;
@@ -10,7 +11,7 @@ namespace Abp.MultiTenancy
///
[Table("AbpTenants")]
[MultiTenancySide(MultiTenancySides.Host)]
- public abstract class AbpTenantBase : FullAuditedEntity
+ public abstract class AbpTenantBase : FullAuditedEntity, IPassivable
{
///
/// Max length of the property.
@@ -37,5 +38,11 @@ public abstract class AbpTenantBase : FullAuditedEntity
///
[StringLength(MaxConnectionStringLength)]
public virtual string ConnectionString { get; set; }
+
+ ///
+ /// Is this tenant active?
+ /// If as tenant is not active, no user of this tenant can use the application.
+ ///
+ public virtual bool IsActive { get; set; }
}
}
\ No newline at end of file
diff --git a/src/Abp.Zero/MultiTenancy/AbpTenantManager.cs b/src/Abp.Zero.Common/MultiTenancy/AbpTenantManager.cs
similarity index 81%
rename from src/Abp.Zero/MultiTenancy/AbpTenantManager.cs
rename to src/Abp.Zero.Common/MultiTenancy/AbpTenantManager.cs
index 31f2c853..c5fb2872 100644
--- a/src/Abp.Zero/MultiTenancy/AbpTenantManager.cs
+++ b/src/Abp.Zero.Common/MultiTenancy/AbpTenantManager.cs
@@ -1,261 +1,247 @@
-using System.Collections.Generic;
-using System.Linq;
-using System.Text.RegularExpressions;
-using System.Threading.Tasks;
-using Abp.Application.Editions;
-using Abp.Application.Features;
-using Abp.Authorization.Users;
-using Abp.Collections.Extensions;
-using Abp.Domain.Repositories;
-using Abp.Domain.Services;
-using Abp.Domain.Uow;
-using Abp.Events.Bus.Entities;
-using Abp.Events.Bus.Handlers;
-using Abp.IdentityFramework;
-using Abp.Localization;
-using Abp.Runtime.Caching;
-using Abp.Zero;
-using Microsoft.AspNet.Identity;
-
-namespace Abp.MultiTenancy
-{
- ///
- /// Tenant manager.
- /// Implements domain logic for .
- ///
- /// Type of the application Tenant
- /// Type of the application User
- public abstract class AbpTenantManager : IDomainService,
- IEventHandler>,
- IEventHandler>
- where TTenant : AbpTenant
- where TUser : AbpUser
- {
- public AbpEditionManager EditionManager { get; set; }
-
- public ILocalizationManager LocalizationManager { get; set; }
-
- public ICacheManager CacheManager { get; set; }
-
- public IFeatureManager FeatureManager { get; set; }
-
- protected IRepository TenantRepository { get; set; }
-
- protected IRepository TenantFeatureRepository { get; set; }
-
- private readonly IAbpZeroFeatureValueStore _featureValueStore;
-
- protected AbpTenantManager(
- IRepository tenantRepository,
- IRepository tenantFeatureRepository,
- AbpEditionManager editionManager,
- IAbpZeroFeatureValueStore featureValueStore)
- {
- _featureValueStore = featureValueStore;
- TenantRepository = tenantRepository;
- TenantFeatureRepository = tenantFeatureRepository;
- EditionManager = editionManager;
- LocalizationManager = NullLocalizationManager.Instance;
- }
-
- public virtual IQueryable Tenants { get { return TenantRepository.GetAll(); } }
-
- public virtual async Task CreateAsync(TTenant tenant)
- {
- if (await TenantRepository.FirstOrDefaultAsync(t => t.TenancyName == tenant.TenancyName) != null)
- {
- return AbpIdentityResult.Failed(string.Format(L("TenancyNameIsAlreadyTaken"), tenant.TenancyName));
- }
-
- var validationResult = await ValidateTenantAsync(tenant);
- if (!validationResult.Succeeded)
- {
- return validationResult;
- }
-
- await TenantRepository.InsertAsync(tenant);
- return IdentityResult.Success;
- }
-
- public async Task UpdateAsync(TTenant tenant)
- {
- if (await TenantRepository.FirstOrDefaultAsync(t => t.TenancyName == tenant.TenancyName && t.Id != tenant.Id) != null)
- {
- return AbpIdentityResult.Failed(string.Format(L("TenancyNameIsAlreadyTaken"), tenant.TenancyName));
- }
-
- await TenantRepository.UpdateAsync(tenant);
- return IdentityResult.Success;
- }
-
- public virtual async Task FindByIdAsync(int id)
- {
- return await TenantRepository.FirstOrDefaultAsync(id);
- }
-
- public virtual async Task GetByIdAsync(int id)
- {
- var tenant = await FindByIdAsync(id);
- if (tenant == null)
- {
- throw new AbpException("There is no tenant with id: " + id);
- }
-
- return tenant;
- }
-
- public virtual Task FindByTenancyNameAsync(string tenancyName)
- {
- return TenantRepository.FirstOrDefaultAsync(t => t.TenancyName == tenancyName);
- }
-
- public virtual async Task DeleteAsync(TTenant tenant)
- {
- await TenantRepository.DeleteAsync(tenant);
- return IdentityResult.Success;
- }
-
- public Task GetFeatureValueOrNullAsync(int tenantId, string featureName)
- {
- return _featureValueStore.GetValueOrNullAsync(tenantId, featureName);
- }
-
- public virtual async Task> GetFeatureValuesAsync(int tenantId)
- {
- var values = new List();
-
- foreach (var feature in FeatureManager.GetAll())
- {
- values.Add(new NameValue(feature.Name, await GetFeatureValueOrNullAsync(tenantId, feature.Name) ?? feature.DefaultValue));
- }
-
- return values;
- }
-
- public virtual async Task SetFeatureValuesAsync(int tenantId, params NameValue[] values)
- {
- if (values.IsNullOrEmpty())
- {
- return;
- }
-
- foreach (var value in values)
- {
- await SetFeatureValueAsync(tenantId, value.Name, value.Value);
- }
- }
-
- [UnitOfWork]
- public virtual async Task SetFeatureValueAsync(int tenantId, string featureName, string value)
- {
- await SetFeatureValueAsync(await GetByIdAsync(tenantId), featureName, value);
- }
-
- [UnitOfWork]
- public virtual async Task SetFeatureValueAsync(TTenant tenant, string featureName, string value)
- {
- //No need to change if it's already equals to the current value
- if (await GetFeatureValueOrNullAsync(tenant.Id, featureName) == value)
- {
- return;
- }
-
- //Get the current feature setting
- var currentSetting = await TenantFeatureRepository.FirstOrDefaultAsync(f => f.TenantId == tenant.Id && f.Name == featureName);
-
- //Get the feature
- var feature = FeatureManager.GetOrNull(featureName);
- if (feature == null)
- {
- if (currentSetting != null)
- {
- await TenantFeatureRepository.DeleteAsync(currentSetting);
- }
-
- return;
- }
-
- //Determine default value
- var defaultValue = tenant.EditionId.HasValue
- ? (await EditionManager.GetFeatureValueOrNullAsync(tenant.EditionId.Value, featureName) ?? feature.DefaultValue)
- : feature.DefaultValue;
-
- //No need to store value if it's default
- if (value == defaultValue)
- {
- if (currentSetting != null)
- {
- await TenantFeatureRepository.DeleteAsync(currentSetting);
- }
-
- return;
- }
-
- //Insert/update the feature value
- if (currentSetting == null)
- {
- await TenantFeatureRepository.InsertAsync(new TenantFeatureSetting(tenant.Id, featureName, value));
- }
- else
- {
- currentSetting.Value = value;
- }
- }
-
- ///
- /// Resets all custom feature settings for a tenant.
- /// Tenant will have features according to it's edition.
- ///
- /// Tenant Id
- public async Task ResetAllFeaturesAsync(int tenantId)
- {
- await TenantFeatureRepository.DeleteAsync(f => f.TenantId == tenantId);
- }
-
- protected virtual async Task ValidateTenantAsync(TTenant tenant)
- {
- var nameValidationResult = await ValidateTenancyNameAsync(tenant.TenancyName);
- if (!nameValidationResult.Succeeded)
- {
- return nameValidationResult;
- }
-
- return IdentityResult.Success;
- }
-
- protected virtual async Task ValidateTenancyNameAsync(string tenancyName)
- {
- if (!Regex.IsMatch(tenancyName, AbpTenant.TenancyNameRegex))
- {
- return AbpIdentityResult.Failed(L("InvalidTenancyName"));
- }
-
- return IdentityResult.Success;
- }
-
- private string L(string name)
- {
- return LocalizationManager.GetString(AbpZeroConsts.LocalizationSourceName, name);
- }
-
- public void HandleEvent(EntityChangedEventData eventData)
- {
- if (eventData.Entity.IsTransient())
- {
- return;
- }
-
- CacheManager.GetTenantFeatureCache().Remove(eventData.Entity.Id);
- }
-
- [UnitOfWork]
- public virtual void HandleEvent(EntityDeletedEventData eventData)
- {
- var relatedTenants = TenantRepository.GetAllList(t => t.EditionId == eventData.Entity.Id);
- foreach (var relatedTenant in relatedTenants)
- {
- relatedTenant.EditionId = null;
- }
- }
- }
+using System.Collections.Generic;
+using System.Linq;
+using System.Text.RegularExpressions;
+using System.Threading.Tasks;
+using Abp.Application.Editions;
+using Abp.Application.Features;
+using Abp.Authorization.Users;
+using Abp.Collections.Extensions;
+using Abp.Domain.Repositories;
+using Abp.Domain.Services;
+using Abp.Domain.Uow;
+using Abp.Events.Bus.Entities;
+using Abp.Events.Bus.Handlers;
+using Abp.Localization;
+using Abp.Runtime.Caching;
+using Abp.UI;
+using Abp.Zero;
+
+namespace Abp.MultiTenancy
+{
+ ///
+ /// Tenant manager.
+ /// Implements domain logic for .
+ ///
+ /// Type of the application Tenant
+ /// Type of the application User
+ public class AbpTenantManager : IDomainService,
+ IEventHandler>,
+ IEventHandler>
+ where TTenant : AbpTenant
+ where TUser : AbpUserBase
+ {
+ public AbpEditionManager EditionManager { get; set; }
+
+ public ILocalizationManager LocalizationManager { get; set; }
+
+ public ICacheManager CacheManager { get; set; }
+
+ public IFeatureManager FeatureManager { get; set; }
+
+ protected IRepository TenantRepository { get; set; }
+
+ protected IRepository TenantFeatureRepository { get; set; }
+
+ private readonly IAbpZeroFeatureValueStore _featureValueStore;
+
+ public AbpTenantManager(
+ IRepository tenantRepository,
+ IRepository tenantFeatureRepository,
+ AbpEditionManager editionManager,
+ IAbpZeroFeatureValueStore featureValueStore)
+ {
+ _featureValueStore = featureValueStore;
+ TenantRepository = tenantRepository;
+ TenantFeatureRepository = tenantFeatureRepository;
+ EditionManager = editionManager;
+ LocalizationManager = NullLocalizationManager.Instance;
+ }
+
+ public virtual IQueryable Tenants { get { return TenantRepository.GetAll(); } }
+
+ public virtual async Task CreateAsync(TTenant tenant)
+ {
+ await ValidateTenantAsync(tenant);
+
+ if (await TenantRepository.FirstOrDefaultAsync(t => t.TenancyName == tenant.TenancyName) != null)
+ {
+ throw new UserFriendlyException(string.Format(L("TenancyNameIsAlreadyTaken"), tenant.TenancyName));
+ }
+
+ await TenantRepository.InsertAsync(tenant);
+ }
+
+ public async Task UpdateAsync(TTenant tenant)
+ {
+ if (await TenantRepository.FirstOrDefaultAsync(t => t.TenancyName == tenant.TenancyName && t.Id != tenant.Id) != null)
+ {
+ throw new UserFriendlyException(string.Format(L("TenancyNameIsAlreadyTaken"), tenant.TenancyName));
+ }
+
+ await TenantRepository.UpdateAsync(tenant);
+ }
+
+ public virtual async Task FindByIdAsync(int id)
+ {
+ return await TenantRepository.FirstOrDefaultAsync(id);
+ }
+
+ public virtual async Task GetByIdAsync(int id)
+ {
+ var tenant = await FindByIdAsync(id);
+ if (tenant == null)
+ {
+ throw new AbpException("There is no tenant with id: " + id);
+ }
+
+ return tenant;
+ }
+
+ public virtual Task FindByTenancyNameAsync(string tenancyName)
+ {
+ return TenantRepository.FirstOrDefaultAsync(t => t.TenancyName == tenancyName);
+ }
+
+ public virtual async Task DeleteAsync(TTenant tenant)
+ {
+ await TenantRepository.DeleteAsync(tenant);
+ }
+
+ public Task GetFeatureValueOrNullAsync(int tenantId, string featureName)
+ {
+ return _featureValueStore.GetValueOrNullAsync(tenantId, featureName);
+ }
+
+ public virtual async Task> GetFeatureValuesAsync(int tenantId)
+ {
+ var values = new List();
+
+ foreach (var feature in FeatureManager.GetAll())
+ {
+ values.Add(new NameValue(feature.Name, await GetFeatureValueOrNullAsync(tenantId, feature.Name) ?? feature.DefaultValue));
+ }
+
+ return values;
+ }
+
+ public virtual async Task SetFeatureValuesAsync(int tenantId, params NameValue[] values)
+ {
+ if (values.IsNullOrEmpty())
+ {
+ return;
+ }
+
+ foreach (var value in values)
+ {
+ await SetFeatureValueAsync(tenantId, value.Name, value.Value);
+ }
+ }
+
+ [UnitOfWork]
+ public virtual async Task SetFeatureValueAsync(int tenantId, string featureName, string value)
+ {
+ await SetFeatureValueAsync(await GetByIdAsync(tenantId), featureName, value);
+ }
+
+ [UnitOfWork]
+ public virtual async Task SetFeatureValueAsync(TTenant tenant, string featureName, string value)
+ {
+ //No need to change if it's already equals to the current value
+ if (await GetFeatureValueOrNullAsync(tenant.Id, featureName) == value)
+ {
+ return;
+ }
+
+ //Get the current feature setting
+ var currentSetting = await TenantFeatureRepository.FirstOrDefaultAsync(f => f.TenantId == tenant.Id && f.Name == featureName);
+
+ //Get the feature
+ var feature = FeatureManager.GetOrNull(featureName);
+ if (feature == null)
+ {
+ if (currentSetting != null)
+ {
+ await TenantFeatureRepository.DeleteAsync(currentSetting);
+ }
+
+ return;
+ }
+
+ //Determine default value
+ var defaultValue = tenant.EditionId.HasValue
+ ? (await EditionManager.GetFeatureValueOrNullAsync(tenant.EditionId.Value, featureName) ?? feature.DefaultValue)
+ : feature.DefaultValue;
+
+ //No need to store value if it's default
+ if (value == defaultValue)
+ {
+ if (currentSetting != null)
+ {
+ await TenantFeatureRepository.DeleteAsync(currentSetting);
+ }
+
+ return;
+ }
+
+ //Insert/update the feature value
+ if (currentSetting == null)
+ {
+ await TenantFeatureRepository.InsertAsync(new TenantFeatureSetting(tenant.Id, featureName, value));
+ }
+ else
+ {
+ currentSetting.Value = value;
+ }
+ }
+
+ ///
+ /// Resets all custom feature settings for a tenant.
+ /// Tenant will have features according to it's edition.
+ ///
+ /// Tenant Id
+ public async Task ResetAllFeaturesAsync(int tenantId)
+ {
+ await TenantFeatureRepository.DeleteAsync(f => f.TenantId == tenantId);
+ }
+
+ protected virtual async Task ValidateTenantAsync(TTenant tenant)
+ {
+ await ValidateTenancyNameAsync(tenant.TenancyName);
+ }
+
+ protected virtual Task ValidateTenancyNameAsync(string tenancyName)
+ {
+ if (!Regex.IsMatch(tenancyName, AbpTenant.TenancyNameRegex))
+ {
+ throw new UserFriendlyException(L("InvalidTenancyName"));
+ }
+
+ return Task.FromResult(0);
+ }
+
+ private string L(string name)
+ {
+ return LocalizationManager.GetString(AbpZeroConsts.LocalizationSourceName, name);
+ }
+
+ public void HandleEvent(EntityChangedEventData eventData)
+ {
+ if (eventData.Entity.IsTransient())
+ {
+ return;
+ }
+
+ CacheManager.GetTenantFeatureCache().Remove(eventData.Entity.Id);
+ }
+
+ [UnitOfWork]
+ public virtual void HandleEvent(EntityDeletedEventData eventData)
+ {
+ var relatedTenants = TenantRepository.GetAllList(t => t.EditionId == eventData.Entity.Id);
+ foreach (var relatedTenant in relatedTenants)
+ {
+ relatedTenant.EditionId = null;
+ }
+ }
+ }
}
\ No newline at end of file
diff --git a/src/Abp.Zero/MultiTenancy/AbpTenantManagerExtensions.cs b/src/Abp.Zero.Common/MultiTenancy/AbpTenantManagerExtensions.cs
similarity index 72%
rename from src/Abp.Zero/MultiTenancy/AbpTenantManagerExtensions.cs
rename to src/Abp.Zero.Common/MultiTenancy/AbpTenantManagerExtensions.cs
index 8f6bb93d..1873e755 100644
--- a/src/Abp.Zero/MultiTenancy/AbpTenantManagerExtensions.cs
+++ b/src/Abp.Zero.Common/MultiTenancy/AbpTenantManagerExtensions.cs
@@ -1,92 +1,91 @@
using System.Collections.Generic;
using Abp.Authorization.Users;
using Abp.Threading;
-using Microsoft.AspNet.Identity;
namespace Abp.MultiTenancy
{
public static class AbpTenantManagerExtensions
{
- public static IdentityResult Create(this AbpTenantManager tenantManager, TTenant tenant)
+ public static void Create(this AbpTenantManager tenantManager, TTenant tenant)
where TTenant : AbpTenant
- where TUser : AbpUser
+ where TUser : AbpUserBase
{
- return AsyncHelper.RunSync(() => tenantManager.CreateAsync(tenant));
+ AsyncHelper.RunSync(() => tenantManager.CreateAsync(tenant));
}
- public static IdentityResult Update(this AbpTenantManager tenantManager, TTenant tenant)
+ public static void Update(this AbpTenantManager tenantManager, TTenant tenant)
where TTenant : AbpTenant
- where TUser : AbpUser
+ where TUser : AbpUserBase
{
- return AsyncHelper.RunSync(() => tenantManager.UpdateAsync(tenant));
+ AsyncHelper.RunSync(() => tenantManager.UpdateAsync(tenant));
}
public static TTenant FindById(this AbpTenantManager tenantManager, int id)
where TTenant : AbpTenant
- where TUser : AbpUser
+ where TUser : AbpUserBase
{
return AsyncHelper.RunSync(() => tenantManager.FindByIdAsync(id));
}
public static TTenant GetById(this AbpTenantManager tenantManager, int id)
where TTenant : AbpTenant
- where TUser : AbpUser
+ where TUser : AbpUserBase
{
return AsyncHelper.RunSync(() => tenantManager.GetByIdAsync(id));
}
public static TTenant FindByTenancyName(this AbpTenantManager tenantManager, string tenancyName)
where TTenant : AbpTenant
- where TUser : AbpUser
+ where TUser : AbpUserBase
{
return AsyncHelper.RunSync(() => tenantManager.FindByTenancyNameAsync(tenancyName));
}
- public static IdentityResult Delete(this AbpTenantManager tenantManager, TTenant tenant)
+ public static void Delete(this AbpTenantManager tenantManager, TTenant tenant)
where TTenant : AbpTenant
- where TUser : AbpUser
+ where TUser : AbpUserBase
{
- return AsyncHelper.RunSync(() => tenantManager.DeleteAsync(tenant));
+ AsyncHelper.RunSync(() => tenantManager.DeleteAsync(tenant));
}
public static string GetFeatureValueOrNull(this AbpTenantManager tenantManager, int tenantId, string featureName)
where TTenant : AbpTenant
- where TUser : AbpUser
+ where TUser : AbpUserBase
{
return AsyncHelper.RunSync(() => tenantManager.GetFeatureValueOrNullAsync(tenantId, featureName));
}
public static IReadOnlyList GetFeatureValues(this AbpTenantManager tenantManager, int tenantId)
where TTenant : AbpTenant
- where TUser : AbpUser