This commit is contained in:
alirıza adıyahşi 2018-02-12 11:41:25 +03:00
Родитель dfc4d8714a
Коммит 15ca2bb948
396 изменённых файлов: 40945 добавлений и 2 удалений

63
.gitattributes поставляемый Normal file
Просмотреть файл

@ -0,0 +1,63 @@
###############################################################################
# Set default behavior to automatically normalize line endings.
###############################################################################
* text=auto
###############################################################################
# Set default behavior for command prompt diff.
#
# This is need for earlier builds of msysgit that does not have it on by
# default for csharp files.
# Note: This is only used by command line
###############################################################################
#*.cs diff=csharp
###############################################################################
# Set the merge driver for project and solution files
#
# Merging from the command prompt will add diff markers to the files if there
# are conflicts (Merging from VS is not affected by the settings below, in VS
# the diff markers are never inserted). Diff markers may cause the following
# file extensions to fail to load in VS. An alternative would be to treat
# these files as binary and thus will always conflict and require user
# intervention with every merge. To do so, just uncomment the entries below
###############################################################################
#*.sln merge=binary
#*.csproj merge=binary
#*.vbproj merge=binary
#*.vcxproj merge=binary
#*.vcproj merge=binary
#*.dbproj merge=binary
#*.fsproj merge=binary
#*.lsproj merge=binary
#*.wixproj merge=binary
#*.modelproj merge=binary
#*.sqlproj merge=binary
#*.wwaproj merge=binary
###############################################################################
# behavior for image files
#
# image files are treated as binary by default.
###############################################################################
#*.jpg binary
#*.png binary
#*.gif binary
###############################################################################
# diff behavior for common document formats
#
# Convert binary document formats to text before diffing them. This feature
# is only available from the command line. Turn it on by uncommenting the
# entries below.
###############################################################################
#*.doc diff=astextplain
#*.DOC diff=astextplain
#*.docx diff=astextplain
#*.DOCX diff=astextplain
#*.dot diff=astextplain
#*.DOT diff=astextplain
#*.pdf diff=astextplain
#*.PDF diff=astextplain
#*.rtf diff=astextplain
#*.RTF diff=astextplain

71
AbpTemplate.sln Normal file
Просмотреть файл

@ -0,0 +1,71 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
VisualStudioVersion = 15.0.26228.9
MinimumVisualStudioVersion = 10.0.40219.1
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{AFAA0841-BD93-466F-B8F4-FB4EEC86F1FC}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{F10AA149-2626-486E-85BB-9CD5365F3016}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AbpTemplate.Core", "src\AbpTemplate.Core\AbpTemplate.Core.csproj", "{0FA75A5B-AB83-4FD0-B545-279774C01E87}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AbpTemplate.Application", "src\AbpTemplate.Application\AbpTemplate.Application.csproj", "{3870C648-4AEA-4B85-BA3F-F2F63B96136A}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AbpTemplate.Tests", "test\AbpTemplate.Tests\AbpTemplate.Tests.csproj", "{0D4C5D00-C144-4213-A007-4B8944113AB1}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AbpTemplate.Migrator", "src\AbpTemplate.Migrator\AbpTemplate.Migrator.csproj", "{880B3591-E057-46FE-B525-10BD83828B93}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AbpTemplate.Web.Host", "src\AbpTemplate.Web.Host\AbpTemplate.Web.Host.csproj", "{38E184BD-E874-4633-A947-AED4FDB73F40}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AbpTemplate.Web.Core", "src\AbpTemplate.Web.Core\AbpTemplate.Web.Core.csproj", "{22CFE0D2-8DCA-42D7-AD7D-784C3862493F}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AbpTemplate.EntityFrameworkCore", "src\AbpTemplate.EntityFrameworkCore\AbpTemplate.EntityFrameworkCore.csproj", "{E0580562-F8F2-4EBB-B07A-ABFC6F2C314F}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{0FA75A5B-AB83-4FD0-B545-279774C01E87}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{0FA75A5B-AB83-4FD0-B545-279774C01E87}.Debug|Any CPU.Build.0 = Debug|Any CPU
{0FA75A5B-AB83-4FD0-B545-279774C01E87}.Release|Any CPU.ActiveCfg = Release|Any CPU
{0FA75A5B-AB83-4FD0-B545-279774C01E87}.Release|Any CPU.Build.0 = Release|Any CPU
{3870C648-4AEA-4B85-BA3F-F2F63B96136A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{3870C648-4AEA-4B85-BA3F-F2F63B96136A}.Debug|Any CPU.Build.0 = Debug|Any CPU
{3870C648-4AEA-4B85-BA3F-F2F63B96136A}.Release|Any CPU.ActiveCfg = Release|Any CPU
{3870C648-4AEA-4B85-BA3F-F2F63B96136A}.Release|Any CPU.Build.0 = Release|Any CPU
{0D4C5D00-C144-4213-A007-4B8944113AB1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{0D4C5D00-C144-4213-A007-4B8944113AB1}.Debug|Any CPU.Build.0 = Debug|Any CPU
{0D4C5D00-C144-4213-A007-4B8944113AB1}.Release|Any CPU.ActiveCfg = Release|Any CPU
{0D4C5D00-C144-4213-A007-4B8944113AB1}.Release|Any CPU.Build.0 = Release|Any CPU
{880B3591-E057-46FE-B525-10BD83828B93}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{880B3591-E057-46FE-B525-10BD83828B93}.Debug|Any CPU.Build.0 = Debug|Any CPU
{880B3591-E057-46FE-B525-10BD83828B93}.Release|Any CPU.ActiveCfg = Release|Any CPU
{880B3591-E057-46FE-B525-10BD83828B93}.Release|Any CPU.Build.0 = Release|Any CPU
{38E184BD-E874-4633-A947-AED4FDB73F40}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{38E184BD-E874-4633-A947-AED4FDB73F40}.Debug|Any CPU.Build.0 = Debug|Any CPU
{38E184BD-E874-4633-A947-AED4FDB73F40}.Release|Any CPU.ActiveCfg = Release|Any CPU
{38E184BD-E874-4633-A947-AED4FDB73F40}.Release|Any CPU.Build.0 = Release|Any CPU
{22CFE0D2-8DCA-42D7-AD7D-784C3862493F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{22CFE0D2-8DCA-42D7-AD7D-784C3862493F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{22CFE0D2-8DCA-42D7-AD7D-784C3862493F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{22CFE0D2-8DCA-42D7-AD7D-784C3862493F}.Release|Any CPU.Build.0 = Release|Any CPU
{E0580562-F8F2-4EBB-B07A-ABFC6F2C314F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{E0580562-F8F2-4EBB-B07A-ABFC6F2C314F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{E0580562-F8F2-4EBB-B07A-ABFC6F2C314F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{E0580562-F8F2-4EBB-B07A-ABFC6F2C314F}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{0FA75A5B-AB83-4FD0-B545-279774C01E87} = {AFAA0841-BD93-466F-B8F4-FB4EEC86F1FC}
{3870C648-4AEA-4B85-BA3F-F2F63B96136A} = {AFAA0841-BD93-466F-B8F4-FB4EEC86F1FC}
{0D4C5D00-C144-4213-A007-4B8944113AB1} = {F10AA149-2626-486E-85BB-9CD5365F3016}
{880B3591-E057-46FE-B525-10BD83828B93} = {AFAA0841-BD93-466F-B8F4-FB4EEC86F1FC}
{38E184BD-E874-4633-A947-AED4FDB73F40} = {AFAA0841-BD93-466F-B8F4-FB4EEC86F1FC}
{22CFE0D2-8DCA-42D7-AD7D-784C3862493F} = {AFAA0841-BD93-466F-B8F4-FB4EEC86F1FC}
{E0580562-F8F2-4EBB-B07A-ABFC6F2C314F} = {AFAA0841-BD93-466F-B8F4-FB4EEC86F1FC}
EndGlobalSection
EndGlobal

6
NuGet.Config Normal file
Просмотреть файл

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<packageSources>
<add key="aspnetcore-dev" value="https://dotnet.myget.org/F/aspnetcore-dev/api/v3/index.json" />
</packageSources>
</configuration>

Просмотреть файл

@ -1,2 +1,33 @@
# module-zero-core-template-docker
Docker image for [module-zero-core-template](https://github.com/aspnetboilerplate/module-zero-core-template)
# Introduction
This is a template to create **ASP.NET Core MVC / Angular** based startup projects for [ASP.NET Boilerplate](https://aspnetboilerplate.com/Pages/Documents). It has 2 different versions:
1. [ASP.NET Core MVC & jQuery](https://aspnetboilerplate.com/Pages/Documents/Zero/Startup-Template-Core) (server rendered multi-page application).
2. [ASP.NET Core & Angular](https://aspnetboilerplate.com/Pages/Documents/Zero/Startup-Template-Angular) (single page application).
User Interface is based on [BSB Admin theme](https://github.com/gurayyarar/AdminBSBMaterialDesign).
# Download
Create & download your project from https://aspnetboilerplate.com/Templates
# Screenshots
#### Sample Dashboard Page
![](_screenshots/module-zero-core-template-ui-home.png)
#### User Creation Modal
![](_screenshots/module-zero-core-template-ui-user-create-modal.png)
#### Login Page
![](_screenshots/module-zero-core-template-ui-login.png)
# Documentation
* [ASP.NET Core MVC & jQuery version.](https://aspnetboilerplate.com/Pages/Documents/Zero/Startup-Template-Core)
* [ASP.NET Core & Angular version.](https://aspnetboilerplate.com/Pages/Documents/Zero/Startup-Template-Angular)
# License
[MIT](LICENSE).

Двоичные данные
_screenshots/ui-home.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 157 KiB

Двоичные данные
_screenshots/ui-login.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 31 KiB

Двоичные данные
_screenshots/ui-user-create-modal.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 86 KiB

37
build/build-host.ps1 Normal file
Просмотреть файл

@ -0,0 +1,37 @@
# COMMON PATHS
$buildFolder = (Get-Item -Path "./" -Verbose).FullName
$slnFolder = Join-Path $buildFolder "../"
$outputFolder = Join-Path $buildFolder "outputs"
$webHostFolder = Join-Path $slnFolder "src/AbpTemplate.Web.Host"
## CLEAR ######################################################################
Remove-Item $outputFolder -Force -Recurse -ErrorAction Ignore
New-Item -Path $outputFolder -ItemType Directory
## RESTORE NUGET PACKAGES #####################################################
Set-Location $slnFolder
dotnet restore
## PUBLISH WEB Host PROJECT ###################################################
Set-Location $webHostFolder
dotnet publish --output (Join-Path $outputFolder "Host")
## CREATE DOCKER IMAGES #######################################################
# Host
Set-Location (Join-Path $outputFolder "Host")
docker rmi abp/host -f
docker build -t abp/host .
## DOCKER COMPOSE FILES #######################################################
Copy-Item (Join-Path $slnFolder "docker/host/*.*") $outputFolder
## FINALIZE ###################################################################
Set-Location $outputFolder

Просмотреть файл

@ -0,0 +1,12 @@
version: '2'
services:
abp_host:
image: abp/host
environment:
- ASPNETCORE_ENVIRONMENT=Staging
ports:
- "9902:80"
volumes:
- "./Host-Logs:/app/App_Data/Logs"

1
docker/host/down.ps1 Normal file
Просмотреть файл

@ -0,0 +1 @@
docker-compose down -v --rmi local

1
docker/host/up.ps1 Normal file
Просмотреть файл

@ -0,0 +1 @@
docker-compose up -d

Просмотреть файл

@ -0,0 +1,19 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<VersionPrefix>1.0.0.0</VersionPrefix>
<TargetFramework>netcoreapp2.0</TargetFramework>
<AssetTargetFallback>$(AssetTargetFallback);portable-net45+win8+wp8+wpa81;</AssetTargetFallback>
<AssemblyName>AbpTemplate.Application</AssemblyName>
<PackageId>AbpTemplate.Application</PackageId>
<GenerateAssemblyConfigurationAttribute>false</GenerateAssemblyConfigurationAttribute>
<GenerateAssemblyCompanyAttribute>false</GenerateAssemblyCompanyAttribute>
<GenerateAssemblyProductAttribute>false</GenerateAssemblyProductAttribute>
<RootNamespace>AbpTemplate</RootNamespace>
</PropertyGroup>
<PropertyGroup>
<DefineConstants>FEATURE_SIGNALR_ASPNETCORE</DefineConstants>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\AbpTemplate.Core\AbpTemplate.Core.csproj" />
</ItemGroup>
</Project>

Просмотреть файл

@ -0,0 +1,47 @@
using System;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Identity;
using Abp.Application.Services;
using Abp.IdentityFramework;
using Abp.Runtime.Session;
using AbpTemplate.Authorization.Users;
using AbpTemplate.MultiTenancy;
namespace AbpTemplate
{
/// <summary>
/// Derive your application services from this class.
/// </summary>
public abstract class AbpTemplateAppServiceBase : ApplicationService
{
public TenantManager TenantManager { get; set; }
public UserManager UserManager { get; set; }
protected AbpTemplateAppServiceBase()
{
LocalizationSourceName = AbpTemplateConsts.LocalizationSourceName;
}
protected virtual Task<User> GetCurrentUserAsync()
{
var user = UserManager.FindByIdAsync(AbpSession.GetUserId().ToString());
if (user == null)
{
throw new Exception("There is no current user!");
}
return user;
}
protected virtual Task<Tenant> GetCurrentTenantAsync()
{
return TenantManager.GetByIdAsync(AbpSession.GetTenantId());
}
protected virtual void CheckErrors(IdentityResult identityResult)
{
identityResult.CheckErrors(LocalizationManager);
}
}
}

Просмотреть файл

@ -0,0 +1,30 @@
using Abp.AutoMapper;
using Abp.Modules;
using Abp.Reflection.Extensions;
using AbpTemplate.Authorization;
namespace AbpTemplate
{
[DependsOn(
typeof(AbpTemplateCoreModule),
typeof(AbpAutoMapperModule))]
public class AbpTemplateApplicationModule : AbpModule
{
public override void PreInitialize()
{
Configuration.Authorization.Providers.Add<AbpTemplateAuthorizationProvider>();
}
public override void Initialize()
{
var thisAssembly = typeof(AbpTemplateApplicationModule).GetAssembly();
IocManager.RegisterAssemblyByConvention(thisAssembly);
Configuration.Modules.AbpAutoMapper().Configurators.Add(
// Scan the assembly for classes which inherit from AutoMapper.Profile
cfg => cfg.AddProfiles(thisAssembly)
);
}
}
}

Просмотреть файл

@ -0,0 +1,10 @@
namespace AbpTemplate
{
public class AppConsts
{
/// <summary>
/// Default pass phrase for SimpleStringCipher decrypt/encrypt operations
/// </summary>
public const string DefaultPassPhrase = "gsKxGZ012HLL3MI5";
}
}

Просмотреть файл

@ -0,0 +1,64 @@
using System;
using Abp;
using Abp.Authorization;
using Abp.Dependency;
using Abp.UI;
namespace AbpTemplate.Authorization
{
public class AbpLoginResultTypeHelper : AbpServiceBase, ITransientDependency
{
public AbpLoginResultTypeHelper()
{
LocalizationSourceName = AbpTemplateConsts.LocalizationSourceName;
}
public Exception CreateExceptionForFailedLoginAttempt(AbpLoginResultType result, string usernameOrEmailAddress, string tenancyName)
{
switch (result)
{
case AbpLoginResultType.Success:
return new Exception("Don't call this method with a success result!");
case AbpLoginResultType.InvalidUserNameOrEmailAddress:
case AbpLoginResultType.InvalidPassword:
return new UserFriendlyException(L("LoginFailed"), L("InvalidUserNameOrPassword"));
case AbpLoginResultType.InvalidTenancyName:
return new UserFriendlyException(L("LoginFailed"), L("ThereIsNoTenantDefinedWithName{0}", tenancyName));
case AbpLoginResultType.TenantIsNotActive:
return new UserFriendlyException(L("LoginFailed"), L("TenantIsNotActive", tenancyName));
case AbpLoginResultType.UserIsNotActive:
return new UserFriendlyException(L("LoginFailed"), L("UserIsNotActiveAndCanNotLogin", usernameOrEmailAddress));
case AbpLoginResultType.UserEmailIsNotConfirmed:
return new UserFriendlyException(L("LoginFailed"), L("UserEmailIsNotConfirmedAndCanNotLogin"));
case AbpLoginResultType.LockedOut:
return new UserFriendlyException(L("LoginFailed"), L("UserLockedOutMessage"));
default: // Can not fall to default actually. But other result types can be added in the future and we may forget to handle it
Logger.Warn("Unhandled login fail reason: " + result);
return new UserFriendlyException(L("LoginFailed"));
}
}
public string CreateLocalizedMessageForFailedLoginAttempt(AbpLoginResultType result, string usernameOrEmailAddress, string tenancyName)
{
switch (result)
{
case AbpLoginResultType.Success:
throw new Exception("Don't call this method with a success result!");
case AbpLoginResultType.InvalidUserNameOrEmailAddress:
case AbpLoginResultType.InvalidPassword:
return L("InvalidUserNameOrPassword");
case AbpLoginResultType.InvalidTenancyName:
return L("ThereIsNoTenantDefinedWithName{0}", tenancyName);
case AbpLoginResultType.TenantIsNotActive:
return L("TenantIsNotActive", tenancyName);
case AbpLoginResultType.UserIsNotActive:
return L("UserIsNotActiveAndCanNotLogin", usernameOrEmailAddress);
case AbpLoginResultType.UserEmailIsNotConfirmed:
return L("UserEmailIsNotConfirmedAndCanNotLogin");
default: // Can not fall to default actually. But other result types can be added in the future and we may forget to handle it
Logger.Warn("Unhandled login fail reason: " + result);
return L("LoginFailed");
}
}
}
}

Просмотреть файл

@ -0,0 +1,54 @@
using System.Threading.Tasks;
using Abp.Configuration;
using Abp.Zero.Configuration;
using AbpTemplate.Authorization.Accounts.Dto;
using AbpTemplate.Authorization.Users;
namespace AbpTemplate.Authorization.Accounts
{
public class AccountAppService : AbpTemplateAppServiceBase, IAccountAppService
{
private readonly UserRegistrationManager _userRegistrationManager;
public AccountAppService(
UserRegistrationManager userRegistrationManager)
{
_userRegistrationManager = userRegistrationManager;
}
public async Task<IsTenantAvailableOutput> IsTenantAvailable(IsTenantAvailableInput input)
{
var tenant = await TenantManager.FindByTenancyNameAsync(input.TenancyName);
if (tenant == null)
{
return new IsTenantAvailableOutput(TenantAvailabilityState.NotFound);
}
if (!tenant.IsActive)
{
return new IsTenantAvailableOutput(TenantAvailabilityState.InActive);
}
return new IsTenantAvailableOutput(TenantAvailabilityState.Available, tenant.Id);
}
public async Task<RegisterOutput> Register(RegisterInput input)
{
var user = await _userRegistrationManager.RegisterAsync(
input.Name,
input.Surname,
input.EmailAddress,
input.UserName,
input.Password,
true // Assumed email address is always confirmed. Change this if you want to implement email confirmation.
);
var isEmailConfirmationRequiredForLogin = await SettingManager.GetSettingValueAsync<bool>(AbpZeroSettingNames.UserManagement.IsEmailConfirmationRequiredForLogin);
return new RegisterOutput
{
CanLogin = user.IsActive && (user.IsEmailConfirmed || !isEmailConfirmationRequiredForLogin)
};
}
}
}

Просмотреть файл

@ -0,0 +1,12 @@
using System.ComponentModel.DataAnnotations;
using Abp.MultiTenancy;
namespace AbpTemplate.Authorization.Accounts.Dto
{
public class IsTenantAvailableInput
{
[Required]
[StringLength(AbpTenantBase.MaxTenancyNameLength)]
public string TenancyName { get; set; }
}
}

Просмотреть файл

@ -0,0 +1,19 @@
namespace AbpTemplate.Authorization.Accounts.Dto
{
public class IsTenantAvailableOutput
{
public TenantAvailabilityState State { get; set; }
public int? TenantId { get; set; }
public IsTenantAvailableOutput()
{
}
public IsTenantAvailableOutput(TenantAvailabilityState state, int? tenantId = null)
{
State = state;
TenantId = tenantId;
}
}
}

Просмотреть файл

@ -0,0 +1,48 @@
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using Abp.Auditing;
using Abp.Authorization.Users;
using Abp.Extensions;
using AbpTemplate.Validation;
namespace AbpTemplate.Authorization.Accounts.Dto
{
public class RegisterInput : IValidatableObject
{
[Required]
[StringLength(AbpUserBase.MaxNameLength)]
public string Name { get; set; }
[Required]
[StringLength(AbpUserBase.MaxSurnameLength)]
public string Surname { get; set; }
[Required]
[StringLength(AbpUserBase.MaxUserNameLength)]
public string UserName { get; set; }
[Required]
[EmailAddress]
[StringLength(AbpUserBase.MaxEmailAddressLength)]
public string EmailAddress { get; set; }
[Required]
[StringLength(AbpUserBase.MaxPlainPasswordLength)]
[DisableAuditing]
public string Password { get; set; }
[DisableAuditing]
public string CaptchaResponse { get; set; }
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
{
if (!UserName.IsNullOrEmpty())
{
if (!UserName.Equals(EmailAddress) && ValidationHelper.IsEmail(UserName))
{
yield return new ValidationResult("Username cannot be an email address unless it's the same as your email address!");
}
}
}
}
}

Просмотреть файл

@ -0,0 +1,7 @@
namespace AbpTemplate.Authorization.Accounts.Dto
{
public class RegisterOutput
{
public bool CanLogin { get; set; }
}
}

Просмотреть файл

@ -0,0 +1,9 @@
namespace AbpTemplate.Authorization.Accounts.Dto
{
public enum TenantAvailabilityState
{
Available = 1,
InActive,
NotFound
}
}

Просмотреть файл

@ -0,0 +1,13 @@
using System.Threading.Tasks;
using Abp.Application.Services;
using AbpTemplate.Authorization.Accounts.Dto;
namespace AbpTemplate.Authorization.Accounts
{
public interface IAccountAppService : IApplicationService
{
Task<IsTenantAvailableOutput> IsTenantAvailable(IsTenantAvailableInput input);
Task<RegisterOutput> Register(RegisterInput input);
}
}

Просмотреть файл

@ -0,0 +1,16 @@
using System.Threading.Tasks;
using Abp.Authorization;
using Abp.Runtime.Session;
using AbpTemplate.Configuration.Dto;
namespace AbpTemplate.Configuration
{
[AbpAuthorize]
public class ConfigurationAppService : AbpTemplateAppServiceBase, IConfigurationAppService
{
public async Task ChangeUiTheme(ChangeUiThemeInput input)
{
await SettingManager.ChangeSettingForUserAsync(AbpSession.ToUserIdentifier(), AppSettingNames.UiTheme, input.Theme);
}
}
}

Просмотреть файл

@ -0,0 +1,11 @@
using System.ComponentModel.DataAnnotations;
namespace AbpTemplate.Configuration.Dto
{
public class ChangeUiThemeInput
{
[Required]
[StringLength(32)]
public string Theme { get; set; }
}
}

Просмотреть файл

@ -0,0 +1,10 @@
using System.Threading.Tasks;
using AbpTemplate.Configuration.Dto;
namespace AbpTemplate.Configuration
{
public interface IConfigurationAppService
{
Task ChangeUiTheme(ChangeUiThemeInput input);
}
}

Просмотреть файл

@ -0,0 +1,14 @@
namespace AbpTemplate.Configuration.Ui
{
public class UiThemeInfo
{
public string Name { get; }
public string CssClass { get; }
public UiThemeInfo(string name, string cssClass)
{
Name = name;
CssClass = cssClass;
}
}
}

Просмотреть файл

@ -0,0 +1,36 @@
using System.Collections.Generic;
namespace AbpTemplate.Configuration.Ui
{
public static class UiThemes
{
public static List<UiThemeInfo> All { get; }
static UiThemes()
{
All = new List<UiThemeInfo>
{
new UiThemeInfo("Red", "red"),
new UiThemeInfo("Pink", "pink"),
new UiThemeInfo("Purple", "purple"),
new UiThemeInfo("Deep Purple", "deep-purple"),
new UiThemeInfo("Indigo", "indigo"),
new UiThemeInfo("Blue", "blue"),
new UiThemeInfo("Light Blue", "light-blue"),
new UiThemeInfo("Cyan", "cyan"),
new UiThemeInfo("Teal", "teal"),
new UiThemeInfo("Green", "green"),
new UiThemeInfo("Light Green", "light-green"),
new UiThemeInfo("Lime", "lime"),
new UiThemeInfo("Yellow", "yellow"),
new UiThemeInfo("Amber", "amber"),
new UiThemeInfo("Orange", "orange"),
new UiThemeInfo("Deep Orange", "deep-orange"),
new UiThemeInfo("Brown", "brown"),
new UiThemeInfo("Grey", "grey"),
new UiThemeInfo("Blue Grey", "blue-grey"),
new UiThemeInfo("Black", "black")
};
}
}
}

Просмотреть файл

@ -0,0 +1,29 @@
using System.ComponentModel.DataAnnotations;
using Abp.Authorization.Users;
using Abp.AutoMapper;
using Abp.MultiTenancy;
namespace AbpTemplate.MultiTenancy.Dto
{
[AutoMapTo(typeof(Tenant))]
public class CreateTenantDto
{
[Required]
[StringLength(AbpTenantBase.MaxTenancyNameLength)]
[RegularExpression(AbpTenantBase.TenancyNameRegex)]
public string TenancyName { get; set; }
[Required]
[StringLength(AbpTenantBase.MaxNameLength)]
public string Name { get; set; }
[Required]
[StringLength(AbpUserBase.MaxEmailAddressLength)]
public string AdminEmailAddress { get; set; }
[StringLength(AbpTenantBase.MaxConnectionStringLength)]
public string ConnectionString { get; set; }
public bool IsActive {get; set;}
}
}

Просмотреть файл

@ -0,0 +1,22 @@
using System.ComponentModel.DataAnnotations;
using Abp.Application.Services.Dto;
using Abp.AutoMapper;
using Abp.MultiTenancy;
namespace AbpTemplate.MultiTenancy.Dto
{
[AutoMapFrom(typeof(Tenant))]
public class TenantDto : EntityDto
{
[Required]
[StringLength(AbpTenantBase.MaxTenancyNameLength)]
[RegularExpression(AbpTenantBase.TenancyNameRegex)]
public string TenancyName { get; set; }
[Required]
[StringLength(AbpTenantBase.MaxNameLength)]
public string Name { get; set; }
public bool IsActive {get; set;}
}
}

Просмотреть файл

@ -0,0 +1,10 @@
using Abp.Application.Services;
using Abp.Application.Services.Dto;
using AbpTemplate.MultiTenancy.Dto;
namespace AbpTemplate.MultiTenancy
{
public interface ITenantAppService : IAsyncCrudAppService<TenantDto, int, PagedResultRequestDto, CreateTenantDto, TenantDto>
{
}
}

Просмотреть файл

@ -0,0 +1,117 @@
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Identity;
using Abp.Application.Services;
using Abp.Application.Services.Dto;
using Abp.Authorization;
using Abp.Domain.Repositories;
using Abp.Extensions;
using Abp.IdentityFramework;
using Abp.MultiTenancy;
using Abp.Runtime.Security;
using AbpTemplate.Authorization;
using AbpTemplate.Authorization.Roles;
using AbpTemplate.Authorization.Users;
using AbpTemplate.Editions;
using AbpTemplate.MultiTenancy.Dto;
namespace AbpTemplate.MultiTenancy
{
[AbpAuthorize(PermissionNames.Pages_Tenants)]
public class TenantAppService : AsyncCrudAppService<Tenant, TenantDto, int, PagedResultRequestDto, CreateTenantDto, TenantDto>, ITenantAppService
{
private readonly TenantManager _tenantManager;
private readonly EditionManager _editionManager;
private readonly UserManager _userManager;
private readonly RoleManager _roleManager;
private readonly IAbpZeroDbMigrator _abpZeroDbMigrator;
private readonly IPasswordHasher<User> _passwordHasher;
public TenantAppService(
IRepository<Tenant, int> repository,
TenantManager tenantManager,
EditionManager editionManager,
UserManager userManager,
RoleManager roleManager,
IAbpZeroDbMigrator abpZeroDbMigrator,
IPasswordHasher<User> passwordHasher)
: base(repository)
{
_tenantManager = tenantManager;
_editionManager = editionManager;
_userManager = userManager;
_roleManager = roleManager;
_abpZeroDbMigrator = abpZeroDbMigrator;
_passwordHasher = passwordHasher;
}
public override async Task<TenantDto> Create(CreateTenantDto input)
{
CheckCreatePermission();
// Create tenant
var tenant = ObjectMapper.Map<Tenant>(input);
tenant.ConnectionString = input.ConnectionString.IsNullOrEmpty()
? null
: SimpleStringCipher.Instance.Encrypt(input.ConnectionString);
var defaultEdition = await _editionManager.FindByNameAsync(EditionManager.DefaultEditionName);
if (defaultEdition != null)
{
tenant.EditionId = defaultEdition.Id;
}
await _tenantManager.CreateAsync(tenant);
await CurrentUnitOfWork.SaveChangesAsync(); // To get new tenant's id.
// Create tenant database
_abpZeroDbMigrator.CreateOrMigrateForTenant(tenant);
// We are working entities of new tenant, so changing tenant filter
using (CurrentUnitOfWork.SetTenantId(tenant.Id))
{
// Create static roles for new tenant
CheckErrors(await _roleManager.CreateStaticRoles(tenant.Id));
await CurrentUnitOfWork.SaveChangesAsync(); // To get static role ids
// Grant all permissions to admin role
var adminRole = _roleManager.Roles.Single(r => r.Name == StaticRoleNames.Tenants.Admin);
await _roleManager.GrantAllPermissionsAsync(adminRole);
// Create admin user for the tenant
var adminUser = User.CreateTenantAdminUser(tenant.Id, input.AdminEmailAddress);
adminUser.Password = _passwordHasher.HashPassword(adminUser, User.DefaultPassword);
CheckErrors(await _userManager.CreateAsync(adminUser));
await CurrentUnitOfWork.SaveChangesAsync(); // To get admin user's id
// Assign admin user to role!
CheckErrors(await _userManager.AddToRoleAsync(adminUser, adminRole.Name));
await CurrentUnitOfWork.SaveChangesAsync();
}
return MapToEntityDto(tenant);
}
protected override void MapToEntity(TenantDto updateInput, Tenant entity)
{
// Manually mapped since TenantDto contains non-editable properties too.
entity.Name = updateInput.Name;
entity.TenancyName = updateInput.TenancyName;
entity.IsActive = updateInput.IsActive;
}
public override async Task Delete(EntityDto<int> input)
{
CheckDeletePermission();
var tenant = await _tenantManager.GetByIdAsync(input.Id);
await _tenantManager.DeleteAsync(tenant);
}
private void CheckErrors(IdentityResult identityResult)
{
identityResult.CheckErrors(LocalizationManager);
}
}
}

Просмотреть файл

@ -0,0 +1,311 @@
using System;
namespace AbpTemplate.Net.MimeTypes
{
/* Copied from:
* http://stackoverflow.com/questions/10362140/asp-mvc-are-there-any-constants-for-the-default-content-types */
/// <summary>
/// Common mime types.
/// </summary>
public static class MimeTypeNames
{
///<summary>Used to denote the encoding necessary for files containing JavaScript source code. The alternative MIME type for this file type is text/javascript.</summary>
public const string ApplicationXJavascript = "application/x-javascript";
///<summary>24bit Linear PCM audio at 8-48kHz, 1-N channels; Defined in RFC 3190</summary>
public const string AudioL24 = "audio/L24";
///<summary>Adobe Flash files for example with the extension .swf</summary>
public const string ApplicationXShockwaveFlash = "application/x-shockwave-flash";
///<summary>Arbitrary binary data.[5] Generally speaking this type identifies files that are not associated with a specific application. Contrary to past assumptions by software packages such as Apache this is not a type that should be applied to unknown files. In such a case, a server or application should not indicate a content type, as it may be incorrect, but rather, should omit the type in order to allow the recipient to guess the type.[6]</summary>
public const string ApplicationOctetStream = "application/octet-stream";
///<summary>Atom feeds</summary>
public const string ApplicationAtomXml = "application/atom+xml";
///<summary>Cascading Style Sheets; Defined in RFC 2318</summary>
public const string TextCss = "text/css";
///<summary>commands; subtype resident in Gecko browsers like Firefox 3.5</summary>
public const string TextCmd = "text/cmd";
///<summary>Comma-separated values; Defined in RFC 4180</summary>
public const string TextCsv = "text/csv";
///<summary>deb (file format), a software package format used by the Debian project</summary>
public const string ApplicationXDeb = "application/x-deb";
///<summary>Defined in RFC 1847</summary>
public const string MultipartEncrypted = "multipart/encrypted";
///<summary>Defined in RFC 1847</summary>
public const string MultipartSigned = "multipart/signed";
///<summary>Defined in RFC 2616</summary>
public const string MessageHttp = "message/http";
///<summary>Defined in RFC 4735</summary>
public const string ModelExample = "model/example";
///<summary>device-independent document in DVI format</summary>
public const string ApplicationXDvi = "application/x-dvi";
///<summary>DTD files; Defined by RFC 3023</summary>
public const string ApplicationXmlDtd = "application/xml-dtd";
///<summary>ECMAScript/JavaScript; Defined in RFC 4329 (equivalent to application/ecmascript but with looser processing rules) It is not accepted in IE 8 or earlier - text/javascript is accepted but it is defined as obsolete in RFC 4329. The "type" attribute of the <script> tag in HTML5 is optional and in practice omitting the media type of JavaScript programs is the most interoperable solution since all browsers have always assumed the correct default even before HTML5.</summary>
public const string ApplicationJavascript = "application/javascript";
///<summary>ECMAScript/JavaScript; Defined in RFC 4329 (equivalent to application/javascript but with stricter processing rules)</summary>
public const string ApplicationEcmascript = "application/ecmascript";
///<summary>EDI EDIFACT data; Defined in RFC 1767</summary>
public const string ApplicationEdifact = "application/EDIFACT";
///<summary>EDI X12 data; Defined in RFC 1767</summary>
public const string ApplicationEdiX12 = "application/EDI-X12";
///<summary>Email; Defined in RFC 2045 and RFC 2046</summary>
public const string MessagePartial = "message/partial";
///<summary>Email; EML files, MIME files, MHT files, MHTML files; Defined in RFC 2045 and RFC 2046</summary>
public const string MessageRfc822 = "message/rfc822";
///<summary>Extensible Markup Language; Defined in RFC 3023</summary>
public const string TextXml = "text/xml";
///<summary>Flash video (FLV files)</summary>
public const string VideoXFlv = "video/x-flv";
///<summary>GIF image; Defined in RFC 2045 and RFC 2046</summary>
public const string ImageGif = "image/gif";
///<summary>GoogleWebToolkit data</summary>
public const string TextXGwtRpc = "text/x-gwt-rpc";
///<summary>Gzip</summary>
public const string ApplicationXGzip = "application/x-gzip";
///<summary>HTML; Defined in RFC 2854</summary>
public const string TextHtml = "text/html";
///<summary>ICO image; Registered[9]</summary>
public const string ImageVndMicrosoftIcon = "image/vnd.microsoft.icon";
///<summary>IGS files, IGES files; Defined in RFC 2077</summary>
public const string ModelIges = "model/iges";
///<summary>IMDN Instant Message Disposition Notification; Defined in RFC 5438</summary>
public const string MessageImdnXml = "message/imdn+xml";
///<summary>JavaScript Object Notation JSON; Defined in RFC 4627</summary>
public const string ApplicationJson = "application/json";
///<summary>JavaScript Object Notation (JSON) Patch; Defined in RFC 6902</summary>
public const string ApplicationJsonPatch = "application/json-patch+json";
///<summary>JavaScript - Defined in and obsoleted by RFC 4329 in order to discourage its usage in favor of application/javascript. However,text/javascript is allowed in HTML 4 and 5 and, unlike application/javascript, has cross-browser support. The "type" attribute of the <script> tag in HTML5 is optional and there is no need to use it at all since all browsers have always assumed the correct default (even in HTML 4 where it was required by the specification).</summary>
[Obsolete]
public const string TextJavascript = "text/javascript";
///<summary>JPEG JFIF image; Associated with Internet Explorer; Listed in ms775147(v=vs.85) - Progressive JPEG, initiated before global browser support for progressive JPEGs (Microsoft and Firefox).</summary>
public const string ImagePjpeg = "image/pjpeg";
///<summary>JPEG JFIF image; Defined in RFC 2045 and RFC 2046</summary>
public const string ImageJpeg = "image/jpeg";
///<summary>jQuery template data</summary>
public const string TextXJqueryTmpl = "text/x-jquery-tmpl";
///<summary>KML files (e.g. for Google Earth)</summary>
public const string ApplicationVndGoogleEarthKmlXml = "application/vnd.google-earth.kml+xml";
///<summary>LaTeX files</summary>
public const string ApplicationXLatex = "application/x-latex";
///<summary>Matroska open media format</summary>
public const string VideoXMatroska = "video/x-matroska";
///<summary>Microsoft Excel 2007 files</summary>
public const string ApplicationVndOpenxmlformatsOfficedocumentSpreadsheetmlSheet = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
///<summary>Microsoft Excel files</summary>
public const string ApplicationVndMsExcel = "application/vnd.ms-excel";
///<summary>Microsoft Powerpoint 2007 files</summary>
public const string ApplicationVndOpenxmlformatsOfficedocumentPresentationmlPresentation = "application/vnd.openxmlformats-officedocument.presentationml.presentation";
///<summary>Microsoft Powerpoint files</summary>
public const string ApplicationVndMsPowerpoint = "application/vnd.ms-powerpoint";
///<summary>Microsoft Word 2007 files</summary>
public const string ApplicationVndOpenxmlformatsOfficedocumentWordprocessingmlDocument = "application/vnd.openxmlformats-officedocument.wordprocessingml.document";
///<summary>Microsoft Word files[15]</summary>
public const string ApplicationMsword = "application/msword";
///<summary>MIME Email; Defined in RFC 2045 and RFC 2046</summary>
public const string MultipartAlternative = "multipart/alternative";
///<summary>MIME Email; Defined in RFC 2045 and RFC 2046</summary>
public const string MultipartMixed = "multipart/mixed";
///<summary>MIME Email; Defined in RFC 2387 and used by MHTML (HTML mail)</summary>
public const string MultipartRelated = "multipart/related";
///<summary>MIME Webform; Defined in RFC 2388</summary>
public const string MultipartFormData = "multipart/form-data";
///<summary>Mozilla XUL files</summary>
public const string ApplicationVndMozillaXulXml = "application/vnd.mozilla.xul+xml";
///<summary>MP3 or other MPEG audio; Defined in RFC 3003</summary>
public const string AudioMpeg = "audio/mpeg";
///<summary>MP4 audio</summary>
public const string AudioMp4 = "audio/mp4";
///<summary>MP4 video; Defined in RFC 4337</summary>
public const string VideoMp4 = "video/mp4";
///<summary>MPEG-1 video with multiplexed audio; Defined in RFC 2045 and RFC 2046</summary>
public const string VideoMpeg = "video/mpeg";
///<summary>MSH files, MESH files; Defined in RFC 2077, SILO files</summary>
public const string ModelMesh = "model/mesh";
///<summary>mulaw audio at 8 kHz, 1 channel; Defined in RFC 2046</summary>
public const string AudioBasic = "audio/basic";
///<summary>Ogg Theora or other video (with audio); Defined in RFC 5334</summary>
public const string VideoOgg = "video/ogg";
///<summary>Ogg Vorbis, Speex, Flac and other audio; Defined in RFC 5334</summary>
public const string AudioOgg = "audio/ogg";
///<summary>Ogg, a multimedia bitstream container format; Defined in RFC 5334</summary>
public const string ApplicationOgg = "application/ogg";
///<summary>OP</summary>
public const string ApplicationXopXml = "application/xop+xml";
///<summary>OpenDocument Graphics; Registered[14]</summary>
public const string ApplicationVndOasisOpendocumentGraphics = "application/vnd.oasis.opendocument.graphics";
///<summary>OpenDocument Presentation; Registered[13]</summary>
public const string ApplicationVndOasisOpendocumentPresentation = "application/vnd.oasis.opendocument.presentation";
///<summary>OpenDocument Spreadsheet; Registered[12]</summary>
public const string ApplicationVndOasisOpendocumentSpreadsheet = "application/vnd.oasis.opendocument.spreadsheet";
///<summary>OpenDocument Text; Registered[11]</summary>
public const string ApplicationVndOasisOpendocumentText = "application/vnd.oasis.opendocument.text";
///<summary>p12 files</summary>
public const string ApplicationXPkcs12 = "application/x-pkcs12";
///<summary>p7b and spc files</summary>
public const string ApplicationXPkcs7Certificates = "application/x-pkcs7-certificates";
///<summary>p7c files</summary>
public const string ApplicationXPkcs7Mime = "application/x-pkcs7-mime";
///<summary>p7r files</summary>
public const string ApplicationXPkcs7Certreqresp = "application/x-pkcs7-certreqresp";
///<summary>p7s files</summary>
public const string ApplicationXPkcs7Signature = "application/x-pkcs7-signature";
///<summary>Portable Document Format, PDF has been in use for document exchange on the Internet since 1993; Defined in RFC 3778</summary>
public const string ApplicationPdf = "application/pdf";
///<summary>Portable Network Graphics; Registered,[8] Defined in RFC 2083</summary>
public const string ImagePng = "image/png";
///<summary>PostScript; Defined in RFC 2046</summary>
public const string ApplicationPostscript = "application/postscript";
///<summary>QuickTime video; Registered[10]</summary>
public const string VideoQuicktime = "video/quicktime";
///<summary>RAR archive files</summary>
public const string ApplicationXRarCompressed = "application/x-rar-compressed";
///<summary>RealAudio; Documented in RealPlayer Customer Support Answer 2559</summary>
public const string AudioVndRnRealaudio = "audio/vnd.rn-realaudio";
///<summary>Resource Description Framework; Defined by RFC 3870</summary>
public const string ApplicationRdfXml = "application/rdf+xml";
///<summary>RSS feeds</summary>
public const string ApplicationRssXml = "application/rss+xml";
///<summary>SOAP; Defined by RFC 3902</summary>
public const string ApplicationSoapXml = "application/soap+xml";
///<summary>StuffIt archive files</summary>
public const string ApplicationXStuffit = "application/x-stuffit";
///<summary>SVG vector image; Defined in SVG Tiny 1.2 Specification Appendix M</summary>
public const string ImageSvgXml = "image/svg+xml";
///<summary>Tag Image File Format (only for Baseline TIFF); Defined in RFC 3302</summary>
public const string ImageTiff = "image/tiff";
///<summary>Tarball files</summary>
public const string ApplicationXTar = "application/x-tar";
///<summary>Textual data; Defined in RFC 2046 and RFC 3676</summary>
public const string TextPlain = "text/plain";
///<summary>TrueType Font No registered MIME type, but this is the most commonly used</summary>
public const string ApplicationXFontTtf = "application/x-font-ttf";
///<summary>vCard (contact information); Defined in RFC 6350</summary>
public const string TextVcard = "text/vcard";
///<summary>Vorbis encoded audio; Defined in RFC 5215</summary>
public const string AudioVorbis = "audio/vorbis";
///<summary>WAV audio; Defined in RFC 2361</summary>
public const string AudioVndWave = "audio/vnd.wave";
///<summary>Web Open Font Format; (candidate recommendation; use application/x-font-woff until standard is official)</summary>
public const string ApplicationFontWoff = "application/font-woff";
///<summary>WebM Matroska-based open media format</summary>
public const string VideoWebm = "video/webm";
///<summary>WebM open media format</summary>
public const string AudioWebm = "audio/webm";
///<summary>Windows Media Audio Redirector; Documented in Microsoft help page</summary>
public const string AudioXMsWax = "audio/x-ms-wax";
///<summary>Windows Media Audio; Documented in Microsoft KB 288102</summary>
public const string AudioXMsWma = "audio/x-ms-wma";
///<summary>Windows Media Video; Documented in Microsoft KB 288102</summary>
public const string VideoXMsWmv = "video/x-ms-wmv";
///<summary>WRL files, VRML files; Defined in RFC 2077</summary>
public const string ModelVrml = "model/vrml";
///<summary>X3D ISO standard for representing 3D computer graphics, X3D XML files</summary>
public const string ModelX3DXml = "model/x3d+xml";
///<summary>X3D ISO standard for representing 3D computer graphics, X3DB binary files</summary>
public const string ModelX3DBinary = "model/x3d+binary";
///<summary>X3D ISO standard for representing 3D computer graphics, X3DV VRML files</summary>
public const string ModelX3DVrml = "model/x3d+vrml";
///<summary>XHTML; Defined by RFC 3236</summary>
public const string ApplicationXhtmlXml = "application/xhtml+xml";
///<summary>ZIP archive files; Registered[7]</summary>
public const string ApplicationZip = "application/zip";
}
}

Просмотреть файл

@ -0,0 +1,18 @@
using System.Reflection;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("AbpTemplate.Application")]
[assembly: AssemblyTrademark("")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("3870c648-4aea-4b85-ba3f-f2f63b96136a")]

Просмотреть файл

@ -0,0 +1,29 @@
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using Abp.Authorization.Roles;
using Abp.AutoMapper;
using AbpTemplate.Authorization.Roles;
namespace AbpTemplate.Roles.Dto
{
[AutoMapTo(typeof(Role))]
public class CreateRoleDto
{
[Required]
[StringLength(AbpRoleBase.MaxNameLength)]
public string Name { get; set; }
[Required]
[StringLength(AbpRoleBase.MaxDisplayNameLength)]
public string DisplayName { get; set; }
public string NormalizedName { get; set; }
[StringLength(Role.MaxDescriptionLength)]
public string Description { get; set; }
public bool IsStatic { get; set; }
public List<string> Permissions { get; set; }
}
}

Просмотреть файл

@ -0,0 +1,16 @@
using Abp.Application.Services.Dto;
using Abp.AutoMapper;
using Abp.Authorization;
namespace AbpTemplate.Roles.Dto
{
[AutoMapFrom(typeof(Permission))]
public class PermissionDto : EntityDto<long>
{
public string Name { get; set; }
public string DisplayName { get; set; }
public string Description { get; set; }
}
}

Просмотреть файл

@ -0,0 +1,30 @@
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using Abp.Application.Services.Dto;
using Abp.Authorization.Roles;
using Abp.AutoMapper;
using AbpTemplate.Authorization.Roles;
namespace AbpTemplate.Roles.Dto
{
[AutoMap(typeof(Role))]
public class RoleDto : EntityDto<int>
{
[Required]
[StringLength(AbpRoleBase.MaxNameLength)]
public string Name { get; set; }
[Required]
[StringLength(AbpRoleBase.MaxDisplayNameLength)]
public string DisplayName { get; set; }
public string NormalizedName { get; set; }
[StringLength(Role.MaxDescriptionLength)]
public string Description { get; set; }
public bool IsStatic { get; set; }
public List<string> Permissions { get; set; }
}
}

Просмотреть файл

@ -0,0 +1,20 @@
using AutoMapper;
using Abp.Authorization;
using Abp.Authorization.Roles;
using AbpTemplate.Authorization.Roles;
namespace AbpTemplate.Roles.Dto
{
public class RoleMapProfile : Profile
{
public RoleMapProfile()
{
// Role and permission
CreateMap<Permission, string>().ConvertUsing(r => r.Name);
CreateMap<RolePermissionSetting, string>().ConvertUsing(r => r.Name);
CreateMap<CreateRoleDto, Role>().ForMember(x => x.Permissions, opt => opt.Ignore());
CreateMap<RoleDto, Role>().ForMember(x => x.Permissions, opt => opt.Ignore());
}
}
}

Просмотреть файл

@ -0,0 +1,12 @@
using System.Threading.Tasks;
using Abp.Application.Services;
using Abp.Application.Services.Dto;
using AbpTemplate.Roles.Dto;
namespace AbpTemplate.Roles
{
public interface IRoleAppService : IAsyncCrudAppService<RoleDto, int, PagedResultRequestDto, CreateRoleDto, RoleDto>
{
Task<ListResultDto<PermissionDto>> GetAllPermissions();
}
}

Просмотреть файл

@ -0,0 +1,115 @@
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Identity;
using Microsoft.EntityFrameworkCore;
using Abp.Application.Services;
using Abp.Application.Services.Dto;
using Abp.Authorization;
using Abp.Domain.Repositories;
using Abp.IdentityFramework;
using Abp.UI;
using AbpTemplate.Authorization;
using AbpTemplate.Authorization.Roles;
using AbpTemplate.Authorization.Users;
using AbpTemplate.Roles.Dto;
namespace AbpTemplate.Roles
{
[AbpAuthorize(PermissionNames.Pages_Roles)]
public class RoleAppService : AsyncCrudAppService<Role, RoleDto, int, PagedResultRequestDto, CreateRoleDto, RoleDto>, IRoleAppService
{
private readonly RoleManager _roleManager;
private readonly UserManager _userManager;
public RoleAppService(IRepository<Role> repository, RoleManager roleManager, UserManager userManager)
: base(repository)
{
_roleManager = roleManager;
_userManager = userManager;
}
public override async Task<RoleDto> Create(CreateRoleDto input)
{
CheckCreatePermission();
var role = ObjectMapper.Map<Role>(input);
role.SetNormalizedName();
CheckErrors(await _roleManager.CreateAsync(role));
var grantedPermissions = PermissionManager
.GetAllPermissions()
.Where(p => input.Permissions.Contains(p.Name))
.ToList();
await _roleManager.SetGrantedPermissionsAsync(role, grantedPermissions);
return MapToEntityDto(role);
}
public override async Task<RoleDto> Update(RoleDto input)
{
CheckUpdatePermission();
var role = await _roleManager.GetRoleByIdAsync(input.Id);
ObjectMapper.Map(input, role);
CheckErrors(await _roleManager.UpdateAsync(role));
var grantedPermissions = PermissionManager
.GetAllPermissions()
.Where(p => input.Permissions.Contains(p.Name))
.ToList();
await _roleManager.SetGrantedPermissionsAsync(role, grantedPermissions);
return MapToEntityDto(role);
}
public override async Task Delete(EntityDto<int> input)
{
CheckDeletePermission();
var role = await _roleManager.FindByIdAsync(input.Id.ToString());
var users = await _userManager.GetUsersInRoleAsync(role.NormalizedName);
foreach (var user in users)
{
CheckErrors(await _userManager.RemoveFromRoleAsync(user, role.NormalizedName));
}
CheckErrors(await _roleManager.DeleteAsync(role));
}
public Task<ListResultDto<PermissionDto>> GetAllPermissions()
{
var permissions = PermissionManager.GetAllPermissions();
return Task.FromResult(new ListResultDto<PermissionDto>(
ObjectMapper.Map<List<PermissionDto>>(permissions)
));
}
protected override IQueryable<Role> CreateFilteredQuery(PagedResultRequestDto input)
{
return Repository.GetAllIncluding(x => x.Permissions);
}
protected override async Task<Role> GetEntityByIdAsync(int id)
{
return await Repository.GetAllIncluding(x => x.Permissions).FirstOrDefaultAsync(x => x.Id == id);
}
protected override IQueryable<Role> ApplySorting(IQueryable<Role> query, PagedResultRequestDto input)
{
return query.OrderBy(r => r.DisplayName);
}
protected virtual void CheckErrors(IdentityResult identityResult)
{
identityResult.CheckErrors(LocalizationManager);
}
}
}

Просмотреть файл

@ -0,0 +1,14 @@
using System;
using System.Collections.Generic;
namespace AbpTemplate.Sessions.Dto
{
public class ApplicationInfoDto
{
public string Version { get; set; }
public DateTime ReleaseDate { get; set; }
public Dictionary<string, bool> Features { get; set; }
}
}

Просмотреть файл

@ -0,0 +1,11 @@
namespace AbpTemplate.Sessions.Dto
{
public class GetCurrentLoginInformationsOutput
{
public ApplicationInfoDto Application { get; set; }
public UserLoginInfoDto User { get; set; }
public TenantLoginInfoDto Tenant { get; set; }
}
}

Просмотреть файл

@ -0,0 +1,14 @@
using Abp.Application.Services.Dto;
using Abp.AutoMapper;
using AbpTemplate.MultiTenancy;
namespace AbpTemplate.Sessions.Dto
{
[AutoMapFrom(typeof(Tenant))]
public class TenantLoginInfoDto : EntityDto
{
public string TenancyName { get; set; }
public string Name { get; set; }
}
}

Просмотреть файл

@ -0,0 +1,18 @@
using Abp.Application.Services.Dto;
using Abp.AutoMapper;
using AbpTemplate.Authorization.Users;
namespace AbpTemplate.Sessions.Dto
{
[AutoMapFrom(typeof(User))]
public class UserLoginInfoDto : EntityDto<long>
{
public string Name { get; set; }
public string Surname { get; set; }
public string UserName { get; set; }
public string EmailAddress { get; set; }
}
}

Просмотреть файл

@ -0,0 +1,11 @@
using System.Threading.Tasks;
using Abp.Application.Services;
using AbpTemplate.Sessions.Dto;
namespace AbpTemplate.Sessions
{
public interface ISessionAppService : IApplicationService
{
Task<GetCurrentLoginInformationsOutput> GetCurrentLoginInformations();
}
}

Просмотреть файл

@ -0,0 +1,41 @@
using System.Collections.Generic;
using System.Threading.Tasks;
using Abp.Auditing;
using AbpTemplate.Sessions.Dto;
using AbpTemplate.SignalR;
namespace AbpTemplate.Sessions
{
public class SessionAppService : AbpTemplateAppServiceBase, ISessionAppService
{
[DisableAuditing]
public async Task<GetCurrentLoginInformationsOutput> GetCurrentLoginInformations()
{
var output = new GetCurrentLoginInformationsOutput
{
Application = new ApplicationInfoDto
{
Version = AppVersionHelper.Version,
ReleaseDate = AppVersionHelper.ReleaseDate,
Features = new Dictionary<string, bool>
{
{ "SignalR", SignalRFeature.IsAvailable },
{ "SignalR.AspNetCore", SignalRFeature.IsAspNetCore }
}
}
};
if (AbpSession.TenantId.HasValue)
{
output.Tenant = ObjectMapper.Map<TenantLoginInfoDto>(await GetCurrentTenantAsync());
}
if (AbpSession.UserId.HasValue)
{
output.User = ObjectMapper.Map<UserLoginInfoDto>(await GetCurrentUserAsync());
}
return output;
}
}
}

Просмотреть файл

@ -0,0 +1,31 @@
namespace AbpTemplate.SignalR
{
public static class SignalRFeature
{
public static bool IsAvailable
{
get
{
#if FEATURE_SIGNALR
return true;
#elif FEATURE_SIGNALR_ASPNETCORE
return true;
#else
return false;
#endif
}
}
public static bool IsAspNetCore
{
get
{
#if FEATURE_SIGNALR_ASPNETCORE
return true;
#else
return false;
#endif
}
}
}
}

Просмотреть файл

@ -0,0 +1,10 @@
using System.ComponentModel.DataAnnotations;
namespace AbpTemplate.Users.Dto
{
public class ChangeUserLanguageDto
{
[Required]
public string LanguageName { get; set; }
}
}

Просмотреть файл

@ -0,0 +1,47 @@
using System.ComponentModel.DataAnnotations;
using Abp.Auditing;
using Abp.Authorization.Users;
using Abp.AutoMapper;
using Abp.Runtime.Validation;
using AbpTemplate.Authorization.Users;
namespace AbpTemplate.Users.Dto
{
[AutoMapTo(typeof(User))]
public class CreateUserDto : IShouldNormalize
{
[Required]
[StringLength(AbpUserBase.MaxUserNameLength)]
public string UserName { get; set; }
[Required]
[StringLength(AbpUserBase.MaxNameLength)]
public string Name { get; set; }
[Required]
[StringLength(AbpUserBase.MaxSurnameLength)]
public string Surname { get; set; }
[Required]
[EmailAddress]
[StringLength(AbpUserBase.MaxEmailAddressLength)]
public string EmailAddress { get; set; }
public bool IsActive { get; set; }
public string[] RoleNames { get; set; }
[Required]
[StringLength(AbpUserBase.MaxPlainPasswordLength)]
[DisableAuditing]
public string Password { get; set; }
public void Normalize()
{
if (RoleNames == null)
{
RoleNames = new string[0];
}
}
}
}

Просмотреть файл

@ -0,0 +1,40 @@
using System;
using System.ComponentModel.DataAnnotations;
using Abp.Application.Services.Dto;
using Abp.Authorization.Users;
using Abp.AutoMapper;
using AbpTemplate.Authorization.Users;
namespace AbpTemplate.Users.Dto
{
[AutoMapFrom(typeof(User))]
public class UserDto : EntityDto<long>
{
[Required]
[StringLength(AbpUserBase.MaxUserNameLength)]
public string UserName { get; set; }
[Required]
[StringLength(AbpUserBase.MaxNameLength)]
public string Name { get; set; }
[Required]
[StringLength(AbpUserBase.MaxSurnameLength)]
public string Surname { get; set; }
[Required]
[EmailAddress]
[StringLength(AbpUserBase.MaxEmailAddressLength)]
public string EmailAddress { get; set; }
public bool IsActive { get; set; }
public string FullName { get; set; }
public DateTime? LastLoginTime { get; set; }
public DateTime CreationTime { get; set; }
public string[] RoleNames { get; set; }
}
}

Просмотреть файл

@ -0,0 +1,17 @@
using AutoMapper;
using AbpTemplate.Authorization.Users;
namespace AbpTemplate.Users.Dto
{
public class UserMapProfile : Profile
{
public UserMapProfile()
{
CreateMap<UserDto, User>();
CreateMap<UserDto, User>().ForMember(x => x.Roles, opt => opt.Ignore());
CreateMap<CreateUserDto, User>();
CreateMap<CreateUserDto, User>().ForMember(x => x.Roles, opt => opt.Ignore());
}
}
}

Просмотреть файл

@ -0,0 +1,15 @@
using System.Threading.Tasks;
using Abp.Application.Services;
using Abp.Application.Services.Dto;
using AbpTemplate.Roles.Dto;
using AbpTemplate.Users.Dto;
namespace AbpTemplate.Users
{
public interface IUserAppService : IAsyncCrudAppService<UserDto, long, PagedResultRequestDto, CreateUserDto, UserDto>
{
Task<ListResultDto<RoleDto>> GetRoles();
Task ChangeLanguage(ChangeUserLanguageDto input);
}
}

Просмотреть файл

@ -0,0 +1,145 @@
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Identity;
using Microsoft.EntityFrameworkCore;
using Abp.Application.Services;
using Abp.Application.Services.Dto;
using Abp.Authorization;
using Abp.Domain.Repositories;
using Abp.IdentityFramework;
using Abp.Localization;
using Abp.Runtime.Session;
using AbpTemplate.Authorization;
using AbpTemplate.Authorization.Roles;
using AbpTemplate.Authorization.Users;
using AbpTemplate.Roles.Dto;
using AbpTemplate.Users.Dto;
namespace AbpTemplate.Users
{
[AbpAuthorize(PermissionNames.Pages_Users)]
public class UserAppService : AsyncCrudAppService<User, UserDto, long, PagedResultRequestDto, CreateUserDto, UserDto>, IUserAppService
{
private readonly UserManager _userManager;
private readonly RoleManager _roleManager;
private readonly IRepository<Role> _roleRepository;
private readonly IPasswordHasher<User> _passwordHasher;
public UserAppService(
IRepository<User, long> repository,
UserManager userManager,
RoleManager roleManager,
IRepository<Role> roleRepository,
IPasswordHasher<User> passwordHasher)
: base(repository)
{
_userManager = userManager;
_roleManager = roleManager;
_roleRepository = roleRepository;
_passwordHasher = passwordHasher;
}
public override async Task<UserDto> Create(CreateUserDto input)
{
CheckCreatePermission();
var user = ObjectMapper.Map<User>(input);
user.TenantId = AbpSession.TenantId;
user.Password = _passwordHasher.HashPassword(user, input.Password);
user.IsEmailConfirmed = true;
CheckErrors(await _userManager.CreateAsync(user));
if (input.RoleNames != null)
{
CheckErrors(await _userManager.SetRoles(user, input.RoleNames));
}
CurrentUnitOfWork.SaveChanges();
return MapToEntityDto(user);
}
public override async Task<UserDto> Update(UserDto input)
{
CheckUpdatePermission();
var user = await _userManager.GetUserByIdAsync(input.Id);
MapToEntity(input, user);
CheckErrors(await _userManager.UpdateAsync(user));
if (input.RoleNames != null)
{
CheckErrors(await _userManager.SetRoles(user, input.RoleNames));
}
return await Get(input);
}
public override async Task Delete(EntityDto<long> input)
{
var user = await _userManager.GetUserByIdAsync(input.Id);
await _userManager.DeleteAsync(user);
}
public async Task<ListResultDto<RoleDto>> GetRoles()
{
var roles = await _roleRepository.GetAllListAsync();
return new ListResultDto<RoleDto>(ObjectMapper.Map<List<RoleDto>>(roles));
}
public async Task ChangeLanguage(ChangeUserLanguageDto input)
{
await SettingManager.ChangeSettingForUserAsync(
AbpSession.ToUserIdentifier(),
LocalizationSettingNames.DefaultLanguage,
input.LanguageName
);
}
protected override User MapToEntity(CreateUserDto createInput)
{
var user = ObjectMapper.Map<User>(createInput);
user.SetNormalizedNames();
return user;
}
protected override void MapToEntity(UserDto input, User user)
{
ObjectMapper.Map(input, user);
user.SetNormalizedNames();
}
protected override UserDto MapToEntityDto(User user)
{
var roles = _roleManager.Roles.Where(r => user.Roles.Any(ur => ur.RoleId == r.Id)).Select(r => r.NormalizedName);
var userDto = base.MapToEntityDto(user);
userDto.RoleNames = roles.ToArray();
return userDto;
}
protected override IQueryable<User> CreateFilteredQuery(PagedResultRequestDto input)
{
return Repository.GetAllIncluding(x => x.Roles);
}
protected override async Task<User> GetEntityByIdAsync(long id)
{
return await Repository.GetAllIncluding(x => x.Roles).FirstOrDefaultAsync(x => x.Id == id);
}
protected override IQueryable<User> ApplySorting(IQueryable<User> query, PagedResultRequestDto input)
{
return query.OrderBy(r => r.UserName);
}
protected virtual void CheckErrors(IdentityResult identityResult)
{
identityResult.CheckErrors(LocalizationManager);
}
}
}

Просмотреть файл

@ -0,0 +1,25 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<VersionPrefix>1.0.0.0</VersionPrefix>
<TargetFramework>netcoreapp2.0</TargetFramework>
<AssetTargetFallback>$(AssetTargetFallback);portable-net45+win8+wp8+wpa81;</AssetTargetFallback>
<AssemblyName>AbpTemplate.Core</AssemblyName>
<PackageId>AbpTemplate.Core</PackageId>
<GenerateAssemblyConfigurationAttribute>false</GenerateAssemblyConfigurationAttribute>
<GenerateAssemblyCompanyAttribute>false</GenerateAssemblyCompanyAttribute>
<GenerateAssemblyProductAttribute>false</GenerateAssemblyProductAttribute>
<UserSecretsId>AbpCompanyName-AbpTemplate-56C2EF2F-ABD6-4EFC-AAF2-2E81C34E8FB1</UserSecretsId>
<RootNamespace>AbpTemplate</RootNamespace>
</PropertyGroup>
<ItemGroup>
<EmbeddedResource Include="Localization\SourceFiles\*.xml" Exclude="bin\**;obj\**;**\*.xproj;packages\**;@(EmbeddedResource)" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Abp.AutoMapper" Version="3.4.0" />
<PackageReference Include="Abp.ZeroCore.EntityFrameworkCore" Version="3.4.0" />
<PackageReference Include="Microsoft.Extensions.Configuration.EnvironmentVariables" Version="2.0.0" />
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="2.0.0" />
<PackageReference Include="Microsoft.Extensions.Configuration.UserSecrets" Version="2.0.0" />
<PackageReference Include="Castle.Windsor.MsDependencyInjection" Version="3.3.0" />
</ItemGroup>
</Project>

Просмотреть файл

@ -0,0 +1,11 @@
namespace AbpTemplate
{
public class AbpTemplateConsts
{
public const string LocalizationSourceName = "AbpTemplate";
public const string ConnectionStringName = "Default";
public const bool MultiTenancyEnabled = true;
}
}

Просмотреть файл

@ -0,0 +1,48 @@
using Abp.Modules;
using Abp.Reflection.Extensions;
using Abp.Timing;
using Abp.Zero;
using Abp.Zero.Configuration;
using AbpTemplate.Authorization.Roles;
using AbpTemplate.Authorization.Users;
using AbpTemplate.Configuration;
using AbpTemplate.Localization;
using AbpTemplate.MultiTenancy;
using AbpTemplate.Timing;
namespace AbpTemplate
{
[DependsOn(typeof(AbpZeroCoreModule))]
public class AbpTemplateCoreModule : AbpModule
{
public override void PreInitialize()
{
Configuration.Auditing.IsEnabledForAnonymousUsers = true;
// Declare entity types
Configuration.Modules.Zero().EntityTypes.Tenant = typeof(Tenant);
Configuration.Modules.Zero().EntityTypes.Role = typeof(Role);
Configuration.Modules.Zero().EntityTypes.User = typeof(User);
AbpTemplateLocalizationConfigurer.Configure(Configuration.Localization);
// Enable this line to create a multi-tenant application.
Configuration.MultiTenancy.IsEnabled = AbpTemplateConsts.MultiTenancyEnabled;
// Configure roles
AppRoleConfig.Configure(Configuration.Modules.Zero().RoleManagement);
Configuration.Settings.Providers.Add<AppSettingProvider>();
}
public override void Initialize()
{
IocManager.RegisterAssemblyByConvention(typeof(AbpTemplateCoreModule).GetAssembly());
}
public override void PostInitialize()
{
IocManager.Resolve<AppTimes>().StartupTime = Clock.Now;
}
}
}

Просмотреть файл

@ -0,0 +1,27 @@
using System;
using System.IO;
using Abp.Reflection.Extensions;
namespace AbpTemplate
{
/// <summary>
/// Central point for application version.
/// </summary>
public class AppVersionHelper
{
/// <summary>
/// Gets current version of the application.
/// It's also shown in the web page.
/// </summary>
public const string Version = "3.5.0.0";
/// <summary>
/// Gets release (last build) date of the application.
/// It's shown in the web page.
/// </summary>
public static DateTime ReleaseDate
{
get { return new FileInfo(typeof(AppVersionHelper).GetAssembly().Location).LastWriteTime; }
}
}
}

Просмотреть файл

@ -0,0 +1,21 @@
using Abp.Authorization;
using Abp.Localization;
using Abp.MultiTenancy;
namespace AbpTemplate.Authorization
{
public class AbpTemplateAuthorizationProvider : AuthorizationProvider
{
public override void SetPermissions(IPermissionDefinitionContext context)
{
context.CreatePermission(PermissionNames.Pages_Users, L("Users"));
context.CreatePermission(PermissionNames.Pages_Roles, L("Roles"));
context.CreatePermission(PermissionNames.Pages_Tenants, L("Tenants"), multiTenancySides: MultiTenancySides.Host);
}
private static ILocalizableString L(string name)
{
return new LocalizableString(name, AbpTemplateConsts.LocalizationSourceName);
}
}
}

Просмотреть файл

@ -0,0 +1,45 @@
using Microsoft.AspNetCore.Identity;
using Abp.Authorization;
using Abp.Authorization.Users;
using Abp.Configuration;
using Abp.Configuration.Startup;
using Abp.Dependency;
using Abp.Domain.Repositories;
using Abp.Domain.Uow;
using Abp.Zero.Configuration;
using AbpTemplate.Authorization.Roles;
using AbpTemplate.Authorization.Users;
using AbpTemplate.MultiTenancy;
namespace AbpTemplate.Authorization
{
public class LogInManager : AbpLogInManager<Tenant, Role, User>
{
public LogInManager(
UserManager userManager,
IMultiTenancyConfig multiTenancyConfig,
IRepository<Tenant> tenantRepository,
IUnitOfWorkManager unitOfWorkManager,
ISettingManager settingManager,
IRepository<UserLoginAttempt, long> userLoginAttemptRepository,
IUserManagementConfig userManagementConfig,
IIocResolver iocResolver,
IPasswordHasher<User> passwordHasher,
RoleManager roleManager,
UserClaimsPrincipalFactory claimsPrincipalFactory)
: base(
userManager,
multiTenancyConfig,
tenantRepository,
unitOfWorkManager,
settingManager,
userLoginAttemptRepository,
userManagementConfig,
iocResolver,
passwordHasher,
roleManager,
claimsPrincipalFactory)
{
}
}
}

Просмотреть файл

@ -0,0 +1,14 @@
using Abp.Authorization;
using AbpTemplate.Authorization.Roles;
using AbpTemplate.Authorization.Users;
namespace AbpTemplate.Authorization
{
public class PermissionChecker : PermissionChecker<Role, User>
{
public PermissionChecker(UserManager userManager)
: base(userManager)
{
}
}
}

Просмотреть файл

@ -0,0 +1,11 @@
namespace AbpTemplate.Authorization
{
public static class PermissionNames
{
public const string Pages_Tenants = "Pages.Tenants";
public const string Pages_Users = "Pages.Users";
public const string Pages_Roles = "Pages.Roles";
}
}

Просмотреть файл

@ -0,0 +1,29 @@
using Abp.MultiTenancy;
using Abp.Zero.Configuration;
namespace AbpTemplate.Authorization.Roles
{
public static class AppRoleConfig
{
public static void Configure(IRoleManagementConfig roleManagementConfig)
{
// Static host roles
roleManagementConfig.StaticRoles.Add(
new StaticRoleDefinition(
StaticRoleNames.Host.Admin,
MultiTenancySides.Host
)
);
// Static tenant roles
roleManagementConfig.StaticRoles.Add(
new StaticRoleDefinition(
StaticRoleNames.Tenants.Admin,
MultiTenancySides.Tenant
)
);
}
}
}

Просмотреть файл

@ -0,0 +1,28 @@
using System.ComponentModel.DataAnnotations;
using Abp.Authorization.Roles;
using AbpTemplate.Authorization.Users;
namespace AbpTemplate.Authorization.Roles
{
public class Role : AbpRole<User>
{
public const int MaxDescriptionLength = 5000;
public Role()
{
}
public Role(int? tenantId, string displayName)
: base(tenantId, displayName)
{
}
public Role(int? tenantId, string name, string displayName)
: base(tenantId, name, displayName)
{
}
[StringLength(MaxDescriptionLength)]
public string Description {get; set;}
}
}

Просмотреть файл

@ -0,0 +1,37 @@
using System.Collections.Generic;
using Microsoft.AspNetCore.Identity;
using Microsoft.Extensions.Logging;
using Abp.Authorization;
using Abp.Authorization.Roles;
using Abp.Domain.Uow;
using Abp.Runtime.Caching;
using Abp.Zero.Configuration;
using AbpTemplate.Authorization.Users;
namespace AbpTemplate.Authorization.Roles
{
public class RoleManager : AbpRoleManager<Role, User>
{
public RoleManager(
RoleStore store,
IEnumerable<IRoleValidator<Role>> roleValidators,
ILookupNormalizer keyNormalizer,
IdentityErrorDescriber errors,
ILogger<AbpRoleManager<Role, User>> logger,
IPermissionManager permissionManager,
ICacheManager cacheManager,
IUnitOfWorkManager unitOfWorkManager,
IRoleManagementConfig roleManagementConfig)
: base(
store,
roleValidators,
keyNormalizer,
errors, logger,
permissionManager,
cacheManager,
unitOfWorkManager,
roleManagementConfig)
{
}
}
}

Просмотреть файл

@ -0,0 +1,21 @@
using Abp.Authorization.Roles;
using Abp.Domain.Repositories;
using Abp.Domain.Uow;
using AbpTemplate.Authorization.Users;
namespace AbpTemplate.Authorization.Roles
{
public class RoleStore : AbpRoleStore<Role, User>
{
public RoleStore(
IUnitOfWorkManager unitOfWorkManager,
IRepository<Role> roleRepository,
IRepository<RolePermissionSetting, long> rolePermissionSettingRepository)
: base(
unitOfWorkManager,
roleRepository,
rolePermissionSettingRepository)
{
}
}
}

Просмотреть файл

@ -0,0 +1,15 @@
namespace AbpTemplate.Authorization.Roles
{
public static class StaticRoleNames
{
public static class Host
{
public const string Admin = "Admin";
}
public static class Tenants
{
public const string Admin = "Admin";
}
}
}

Просмотреть файл

@ -0,0 +1,32 @@
using System;
using Abp.Authorization.Users;
using Abp.Extensions;
namespace AbpTemplate.Authorization.Users
{
public class User : AbpUser<User>
{
public const string DefaultPassword = "123qwe";
public static string CreateRandomPassword()
{
return Guid.NewGuid().ToString("N").Truncate(16);
}
public static User CreateTenantAdminUser(int tenantId, string emailAddress)
{
var user = new User
{
TenantId = tenantId,
UserName = AdminUserName,
Name = AdminUserName,
Surname = AdminUserName,
EmailAddress = emailAddress
};
user.SetNormalizedNames();
return user;
}
}
}

Просмотреть файл

@ -0,0 +1,21 @@
using Microsoft.AspNetCore.Identity;
using Microsoft.Extensions.Options;
using Abp.Authorization;
using AbpTemplate.Authorization.Roles;
namespace AbpTemplate.Authorization.Users
{
public class UserClaimsPrincipalFactory : AbpUserClaimsPrincipalFactory<User, Role>
{
public UserClaimsPrincipalFactory(
UserManager userManager,
RoleManager roleManager,
IOptions<IdentityOptions> optionsAccessor)
: base(
userManager,
roleManager,
optionsAccessor)
{
}
}
}

Просмотреть файл

@ -0,0 +1,58 @@
using System;
using System.Collections.Generic;
using Microsoft.AspNetCore.Identity;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using Abp.Authorization;
using Abp.Authorization.Users;
using Abp.Configuration;
using Abp.Domain.Repositories;
using Abp.Domain.Uow;
using Abp.Organizations;
using Abp.Runtime.Caching;
using AbpTemplate.Authorization.Roles;
namespace AbpTemplate.Authorization.Users
{
public class UserManager : AbpUserManager<Role, User>
{
public UserManager(
RoleManager roleManager,
UserStore store,
IOptions<IdentityOptions> optionsAccessor,
IPasswordHasher<User> passwordHasher,
IEnumerable<IUserValidator<User>> userValidators,
IEnumerable<IPasswordValidator<User>> passwordValidators,
ILookupNormalizer keyNormalizer,
IdentityErrorDescriber errors,
IServiceProvider services,
ILogger<UserManager<User>> logger,
IPermissionManager permissionManager,
IUnitOfWorkManager unitOfWorkManager,
ICacheManager cacheManager,
IRepository<OrganizationUnit, long> organizationUnitRepository,
IRepository<UserOrganizationUnit, long> userOrganizationUnitRepository,
IOrganizationUnitSettings organizationUnitSettings,
ISettingManager settingManager)
: base(
roleManager,
store,
optionsAccessor,
passwordHasher,
userValidators,
passwordValidators,
keyNormalizer,
errors,
services,
logger,
permissionManager,
unitOfWorkManager,
cacheManager,
organizationUnitRepository,
userOrganizationUnitRepository,
organizationUnitSettings,
settingManager)
{
}
}
}

Просмотреть файл

@ -0,0 +1,112 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Identity;
using Microsoft.EntityFrameworkCore;
using Abp.Authorization.Users;
using Abp.Domain.Services;
using Abp.IdentityFramework;
using Abp.Runtime.Session;
using Abp.UI;
using AbpTemplate.Authorization.Roles;
using AbpTemplate.MultiTenancy;
namespace AbpTemplate.Authorization.Users
{
public class UserRegistrationManager : DomainService
{
public IAbpSession AbpSession { get; set; }
private readonly TenantManager _tenantManager;
private readonly UserManager _userManager;
private readonly RoleManager _roleManager;
private readonly IPasswordHasher<User> _passwordHasher;
public UserRegistrationManager(
TenantManager tenantManager,
UserManager userManager,
RoleManager roleManager,
IPasswordHasher<User> passwordHasher)
{
_tenantManager = tenantManager;
_userManager = userManager;
_roleManager = roleManager;
_passwordHasher = passwordHasher;
AbpSession = NullAbpSession.Instance;
}
public async Task<User> RegisterAsync(string name, string surname, string emailAddress, string userName, string plainPassword, bool isEmailConfirmed)
{
CheckForTenant();
var tenant = await GetActiveTenantAsync();
var user = new User
{
TenantId = tenant.Id,
Name = name,
Surname = surname,
EmailAddress = emailAddress,
IsActive = true,
UserName = userName,
IsEmailConfirmed = isEmailConfirmed,
Roles = new List<UserRole>()
};
user.SetNormalizedNames();
user.Password = _passwordHasher.HashPassword(user, plainPassword);
foreach (var defaultRole in await _roleManager.Roles.Where(r => r.IsDefault).ToListAsync())
{
user.Roles.Add(new UserRole(tenant.Id, user.Id, defaultRole.Id));
}
CheckErrors(await _userManager.CreateAsync(user));
await CurrentUnitOfWork.SaveChangesAsync();
return user;
}
private void CheckForTenant()
{
if (!AbpSession.TenantId.HasValue)
{
throw new InvalidOperationException("Can not register host users!");
}
}
private async Task<Tenant> GetActiveTenantAsync()
{
if (!AbpSession.TenantId.HasValue)
{
return null;
}
return await GetActiveTenantAsync(AbpSession.TenantId.Value);
}
private async Task<Tenant> GetActiveTenantAsync(int tenantId)
{
var tenant = await _tenantManager.FindByIdAsync(tenantId);
if (tenant == null)
{
throw new UserFriendlyException(L("UnknownTenantId{0}", tenantId));
}
if (!tenant.IsActive)
{
throw new UserFriendlyException(L("TenantIdIsNotActive{0}", tenantId));
}
return tenant;
}
protected virtual void CheckErrors(IdentityResult identityResult)
{
identityResult.CheckErrors(LocalizationManager);
}
}
}

Просмотреть файл

@ -0,0 +1,32 @@
using Abp.Authorization.Users;
using Abp.Domain.Repositories;
using Abp.Domain.Uow;
using Abp.Linq;
using AbpTemplate.Authorization.Roles;
namespace AbpTemplate.Authorization.Users
{
public class UserStore : AbpUserStore<Role, User>
{
public UserStore(
IUnitOfWorkManager unitOfWorkManager,
IRepository<User, long> userRepository,
IRepository<Role> roleRepository,
IAsyncQueryableExecuter asyncQueryableExecuter,
IRepository<UserRole, long> userRoleRepository,
IRepository<UserLogin, long> userLoginRepository,
IRepository<UserClaim, long> userClaimRepository,
IRepository<UserPermissionSetting, long> userPermissionSettingRepository)
: base(
unitOfWorkManager,
userRepository,
roleRepository,
asyncQueryableExecuter,
userRoleRepository,
userLoginRepository,
userClaimRepository,
userPermissionSettingRepository)
{
}
}
}

Просмотреть файл

@ -0,0 +1,47 @@
using System.Collections.Concurrent;
using Microsoft.Extensions.Configuration;
using Abp.Extensions;
using Abp.Reflection.Extensions;
namespace AbpTemplate.Configuration
{
public static class AppConfigurations
{
private static readonly ConcurrentDictionary<string, IConfigurationRoot> _configurationCache;
static AppConfigurations()
{
_configurationCache = new ConcurrentDictionary<string, IConfigurationRoot>();
}
public static IConfigurationRoot Get(string path, string environmentName = null, bool addUserSecrets = false)
{
var cacheKey = path + "#" + environmentName + "#" + addUserSecrets;
return _configurationCache.GetOrAdd(
cacheKey,
_ => BuildConfiguration(path, environmentName, addUserSecrets)
);
}
private static IConfigurationRoot BuildConfiguration(string path, string environmentName = null, bool addUserSecrets = false)
{
var builder = new ConfigurationBuilder()
.SetBasePath(path)
.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true);
if (!environmentName.IsNullOrWhiteSpace())
{
builder = builder.AddJsonFile($"appsettings.{environmentName}.json", optional: true);
}
builder = builder.AddEnvironmentVariables();
if (addUserSecrets)
{
builder.AddUserSecrets(typeof(AppConfigurations).GetAssembly());
}
return builder.Build();
}
}
}

Просмотреть файл

@ -0,0 +1,7 @@
namespace AbpTemplate.Configuration
{
public static class AppSettingNames
{
public const string UiTheme = "App.UiTheme";
}
}

Просмотреть файл

@ -0,0 +1,16 @@
using System.Collections.Generic;
using Abp.Configuration;
namespace AbpTemplate.Configuration
{
public class AppSettingProvider : SettingProvider
{
public override IEnumerable<SettingDefinition> GetSettingDefinitions(SettingDefinitionProviderContext context)
{
return new[]
{
new SettingDefinition(AppSettingNames.UiTheme, "red", scopes: SettingScopes.Application | SettingScopes.Tenant | SettingScopes.User, isVisibleToClients: true)
};
}
}
}

Просмотреть файл

@ -0,0 +1,20 @@
using Abp.Application.Editions;
using Abp.Application.Features;
using Abp.Domain.Repositories;
namespace AbpTemplate.Editions
{
public class EditionManager : AbpEditionManager
{
public const string DefaultEditionName = "Standard";
public EditionManager(
IRepository<Edition> editionRepository,
IAbpZeroFeatureValueStore featureValueStore)
: base(
editionRepository,
featureValueStore)
{
}
}
}

Просмотреть файл

@ -0,0 +1,30 @@
using Abp.Application.Features;
using Abp.Domain.Repositories;
using Abp.Domain.Uow;
using Abp.MultiTenancy;
using Abp.Runtime.Caching;
using AbpTemplate.Authorization.Users;
using AbpTemplate.MultiTenancy;
namespace AbpTemplate.Features
{
public class FeatureValueStore : AbpFeatureValueStore<Tenant, User>
{
public FeatureValueStore(
ICacheManager cacheManager,
IRepository<TenantFeatureSetting, long> tenantFeatureRepository,
IRepository<Tenant> tenantRepository,
IRepository<EditionFeatureSetting, long> editionFeatureRepository,
IFeatureManager featureManager,
IUnitOfWorkManager unitOfWorkManager)
: base(
cacheManager,
tenantFeatureRepository,
tenantRepository,
editionFeatureRepository,
featureManager,
unitOfWorkManager)
{
}
}
}

Просмотреть файл

@ -0,0 +1,32 @@
using Microsoft.AspNetCore.Identity;
using Microsoft.Extensions.DependencyInjection;
using AbpTemplate.Authorization;
using AbpTemplate.Authorization.Roles;
using AbpTemplate.Authorization.Users;
using AbpTemplate.Editions;
using AbpTemplate.MultiTenancy;
namespace AbpTemplate.Identity
{
public static class IdentityRegistrar
{
public static IdentityBuilder Register(IServiceCollection services)
{
services.AddLogging();
return services.AddAbpIdentity<Tenant, User, Role>()
.AddAbpTenantManager<TenantManager>()
.AddAbpUserManager<UserManager>()
.AddAbpRoleManager<RoleManager>()
.AddAbpEditionManager<EditionManager>()
.AddAbpUserStore<UserStore>()
.AddAbpRoleStore<RoleStore>()
.AddAbpLogInManager<LogInManager>()
.AddAbpSignInManager<SignInManager>()
.AddAbpSecurityStampValidator<SecurityStampValidator>()
.AddAbpUserClaimsPrincipalFactory<UserClaimsPrincipalFactory>()
.AddPermissionChecker<PermissionChecker>()
.AddDefaultTokenProviders();
}
}
}

Просмотреть файл

@ -0,0 +1,24 @@
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Identity;
using Microsoft.Extensions.Options;
using Abp.Authorization;
using AbpTemplate.Authorization.Roles;
using AbpTemplate.Authorization.Users;
using AbpTemplate.MultiTenancy;
namespace AbpTemplate.Identity
{
public class SecurityStampValidator : AbpSecurityStampValidator<Tenant, Role, User>
{
public SecurityStampValidator(
IOptions<SecurityStampValidatorOptions> options,
SignInManager signInManager,
ISystemClock systemClock)
: base(
options,
signInManager,
systemClock)
{
}
}
}

Просмотреть файл

@ -0,0 +1,38 @@
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Identity;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using Abp.Authorization;
using Abp.Configuration;
using Abp.Domain.Uow;
using AbpTemplate.Authorization.Roles;
using AbpTemplate.Authorization.Users;
using AbpTemplate.MultiTenancy;
namespace AbpTemplate.Identity
{
public class SignInManager : AbpSignInManager<Tenant, Role, User>
{
public SignInManager(
UserManager userManager,
IHttpContextAccessor contextAccessor,
UserClaimsPrincipalFactory claimsFactory,
IOptions<IdentityOptions> optionsAccessor,
ILogger<SignInManager<User>> logger,
IUnitOfWorkManager unitOfWorkManager,
ISettingManager settingManager,
IAuthenticationSchemeProvider schemes)
: base(
userManager,
contextAccessor,
claimsFactory,
optionsAccessor,
logger,
unitOfWorkManager,
settingManager,
schemes)
{
}
}
}

Просмотреть файл

@ -0,0 +1,22 @@
using Abp.Configuration.Startup;
using Abp.Localization.Dictionaries;
using Abp.Localization.Dictionaries.Xml;
using Abp.Reflection.Extensions;
namespace AbpTemplate.Localization
{
public static class AbpTemplateLocalizationConfigurer
{
public static void Configure(ILocalizationConfiguration localizationConfiguration)
{
localizationConfiguration.Sources.Add(
new DictionaryBasedLocalizationSource(AbpTemplateConsts.LocalizationSourceName,
new XmlEmbeddedFileLocalizationDictionaryProvider(
typeof(AbpTemplateLocalizationConfigurer).GetAssembly(),
"AbpTemplate.Localization.SourceFiles"
)
)
);
}
}
}

Просмотреть файл

@ -0,0 +1,47 @@
<?xml version="1.0" encoding="utf-8" ?>
<localizationDictionary culture="es">
<texts>
<text name="HomePage" value="Página de inicio" />
<text name="About" value="Acerca de" />
<text name="WellcomeMessage" value="Bienvenido a WMS!" />
<text name="FormIsNotValidMessage" value="Formulario no es válido. Por favor, compruebe y corrija los errores." />
<text name="TenantNameCanNotBeEmpty" value="Nombre de la empresa no puede estar vacío" />
<text name="InvalidUserNameOrPassword" value="Usuario o contraseña invalido" />
<text name="ThereIsNoTenantDefinedWithName{0}" value="No hay empresa definida con el nombre {0}" />
<text name="TenantIsNotActive" value="La empresa {0} no está activa." />
<text name="UserIsNotActiveAndCanNotLogin" value="El usuario {0} no está activo y no puede conectarse." />
<text name="PleaseEnterLoginInformation" value="Por favor, introduzca la información de inicio de sesión" />
<text name="TenancyName" value="Nombre de la empresa" />
<text name="UserNameOrEmail" value="Nombre de usuario o correo electrónico" />
<text name="Password" value="Contraseña" />
<text name="RememberMe" value="Recuérdame" />
<text name="LogIn" value="Iniciar sesión" />
<text name="LoginFailed" value="¡Error de inicio de sesion!" />
<text name="NameSurname" value="Nombre Apellido" />
<text name="UserName" value="Nombre de usuario" />
<text name="Name" value="Nombre" />
<text name="Surname" value="Apellido" />
<text name="EmailAddress" value="Dirección de correo electrónico" />
<text name="Tenants" value="Empresas" />
<text name="SavedSuccessfully" value="Guardado correctamente" />
<text name="CreateNewTenant" value="Crear nueva empresa" />
<text name="AdminEmailAddress" value="Dirección de correo electrónico del administrador" />
<text name="Save" value="Guardar" />
<text name="Cancel" value="Cancelar" />
<text name="TenantName_Regex_Description" value="El nombre de la empresa debe ser de al menos 2 caracteres, empieza con una letra y continua con una letra, número, guión o un guión bajo." />
<text name="DefaultPasswordIs" value="La contraseña por defecto es {0}" />
<text name="CanBeEmptyToLoginAsHost" value="Puede estar vacía para iniciar la sesión como anfitrión." />
<text name="Register" value="Registro" />
<text name="OrLoginWith" value="o iniciar sesión con" />
<text name="WaitingForActivationMessage" value="Su cuenta está en espera de ser activada por el administrador del sistema." />
<text name="TenantSelection" value="Selección de Empresa" />
<text name="TenantSelection_Detail" value="Por favor seleccione una de las siguientes empresas." />
<text name="Logout" value="Cerrar sesión" />
</texts>
</localizationDictionary>

Просмотреть файл

@ -0,0 +1,47 @@
<?xml version="1.0" encoding="utf-8" ?>
<localizationDictionary culture="fr">
<texts>
<text name="HomePage" value="Accueil" />
<text name="About" value="A propos" />
<text name="WellcomeMessage" value="Bienvenue sur AbpTemplate !" />
<text name="FormIsNotValidMessage" value="Le formulaire n'est pas valide. Veuillez le corriger." />
<text name="TenantNameCanNotBeEmpty" value="Le nom de client (tenant) doit être renseigné." />
<text name="InvalidUserNameOrPassword" value="Nom d'utilisateur ou mot de passe non valide." />
<text name="ThereIsNoTenantDefinedWithName{0}" value="Il n'y a aucun nom de client (tenant) correspondant à {0}" />
<text name="TenantIsNotActive" value="Le client (tenant) {0} n'est pas actif." />
<text name="UserIsNotActiveAndCanNotLogin" value="L'utilisateur {0} n'est pas actif ou ne peut pas s'authentifier." />
<text name="PleaseEnterLoginInformation" value="Veuillez entrer vos informations d'authentification" />
<text name="TenancyName" value="Nom du client (tenant)" />
<text name="UserNameOrEmail" value="Nom d'utilisateur ou email" />
<text name="Password" value="Mot de passe" />
<text name="RememberMe" value="Se rappeler de moi" />
<text name="LogIn" value="Se connecter" />
<text name="LoginFailed" value="Echec d'authentification !" />
<text name="NameSurname" value="Nom de famille" />
<text name="UserName" value="Nom d'utilisateur" />
<text name="Name" value="Prénom" />
<text name="Surname" value="Nom de famille" />
<text name="EmailAddress" value="Adresse email" />
<text name="Tenants" value="Clients (tenants)" />
<text name="SavedSuccessfully" value="Enregistrement réussi" />
<text name="CreateNewTenant" value="Créer un nouveau client (tenant)" />
<text name="AdminEmailAddress" value="Adresse email de l'administrateur" />
<text name="Save" value="Valider" />
<text name="Cancel" value="Annuler" />
<text name="TenantName_Regex_Description" value="Le nom de client (tenant) doit comporter au moins 2 caractères et commencer par une lettre suivie d'autres lettres, chiffres ou tirets." />
<text name="DefaultPasswordIs" value="Le mot de passe par défaut est {0}" />
<text name="CanBeEmptyToLoginAsHost" value="Peut être laissé vide pour s'authentifier en tant qu'hébergeur (host)." />
<text name="Register" value="S'enregistrer" />
<text name="OrLoginWith" value="Ou s'authentifier avec" />
<text name="WaitingForActivationMessage" value="Votre compte est en attente d'activation par l'administrateur du système." />
<text name="TenantSelection" value="Sélection du client (tenant)" />
<text name="TenantSelection_Detail" value="Veuillez choisir l'un de ces clients (tenants) suivants." />
<text name="Logout" value="Déconnexion" />
</texts>
</localizationDictionary>

Просмотреть файл

@ -0,0 +1,57 @@
<?xml version="1.0" encoding="utf-8" ?>
<localizationDictionary culture="it">
<texts>
<text name="HomePage" value="Home page" />
<text name="About" value="Chi siamo" />
<text name="WellcomeMessage" value="Benvenuti su My New House!" />
<text name="FormIsNotValidMessage" value="I dati non sono corretti. Verifica gli errori." />
<text name="TenantNameCanNotBeEmpty" value="Il Dominio non può essere vuoto" />
<text name="InvalidUserNameOrPassword" value="Username o password errati" />
<text name="ThereIsNoTenantDefinedWithName{0}" value="Il dominio {0} non esiste" />
<text name="TenantIsNotActive" value="Il dominio {0} non è attivo." />
<text name="UserIsNotActiveAndCanNotLogin" value="L'utente {0} non è attivo e non può fare login." />
<text name="UserEmailIsNotConfirmedAndCanNotLogin">Indirizzo email non registrato. Login non ammesso.</text>
<text name="UserLockedOutMessage">L'account è momentaneamente bloccato. Riprovare più tardi.</text>
<text name="PleaseEnterLoginInformation" value="Inserisci le informazioni di login" />
<text name="TenancyName" value="Dominio" />
<text name="UserNameOrEmail" value="Use name o email" />
<text name="Password" value="Password" />
<text name="RememberMe" value="Ricordati di me" />
<text name="LogIn" value="Log in" />
<text name="LoginFailed" value="Login errato!" />
<text name="NameSurname" value="Nome e Cognome" />
<text name="UserName" value="Username" />
<text name="Name" value="Nome" />
<text name="Surname" value="Cognome" />
<text name="EmailAddress" value="Email" />
<text name="Tenants" value="Dominio" />
<text name="SavedSuccessfully" value="Salvato" />
<text name="CreateNewTenant" value="Crea un nuovo dominio" />
<text name="AdminEmailAddress" value="Indirizzo email Amministratore" />
<text name="Save" value="Salva" />
<text name="Cancel" value="Annulla" />
<text name="TenantName_Regex_Description" value="Il dominio deve essere di almeno 2 caratteri, iniziare con una lettera e continuare con lettere, numeri o trattini." />
<text name="DefaultPasswordIs" value="La password di default è {0}" />
<text name="CanBeEmptyToLoginAsHost" value="Può essere vuoto per entrare come ospite." />
<text name="Register" value="Registrati" />
<text name="OrLoginWith" value="O entra con" />
<text name="WaitingForActivationMessage" value="Il tuo account è in attesa di approvazione." />
<text name="TenantSelection" value="Selezione dominio" />
<text name="TenantSelection_Detail" value="Seleziona uno dei seguenti domini." />
<text name="Logout" value="Logout" />
<text name="DatabaseConnectionString" value="String connession Database" />
<text name="Users" value="Utenti" />
<text name="IsActive" value="Attivo" />
<text name="FullName" value="Nome completo" />
<text name="CreateNewUser" value="Nuovo utente" />
<text name="Yes" value="Sì" />
<text name="No" value="No" />
<text name="Optional" value="Opzionale" />
</texts>
</localizationDictionary>

Просмотреть файл

@ -0,0 +1,57 @@
<?xml version="1.0" encoding="utf-8" ?>
<localizationDictionary culture="ja">
<texts>
<text name="HomePage" value="ホームページ" />
<text name="About" value="我々について" />
<text name="WellcomeMessage" value="ようこそ AbpTemplate へ!" />
<text name="FormIsNotValidMessage" value="フォームは無効です。エラーを修正してください。" />
<text name="TenantNameCanNotBeEmpty" value="テナント名を空にすることはできません" />
<text name="InvalidUserNameOrPassword" value="無効なユーザー名またはパスワードです" />
<text name="ThereIsNoTenantDefinedWithName{0}" value="テナント名前 {0} の定義がありません。" />
<text name="TenantIsNotActive" value="テナント {0} はアクティブではありません。 " />
<text name="UserIsNotActiveAndCanNotLogin" value="ユーザー {0} がアクティブでなくログインできません。" />
<text name="PleaseEnterLoginInformation" value="ログイン情報を入力してください" />
<text name="TenancyName" value="テナント名" />
<text name="UserNameOrEmail" value="ユーザ名 または E-mail" />
<text name="Password" value="パスワード" />
<text name="RememberMe" value="ログイン情報を記憶する" />
<text name="LogIn" value="ログイン" />
<text name="LoginFailed" value="ログイン失敗!" />
<text name="NameSurname" value="名 姓" />
<text name="UserName" value="ユーザ名" />
<text name="Name" value="名前" />
<text name="Surname" value="姓" />
<text name="EmailAddress" value="E-mailアドレス" />
<text name="Tenants" value="テナント" />
<text name="SavedSuccessfully" value="保存成功" />
<text name="CreateNewTenant" value="新規テナント作成" />
<text name="AdminEmailAddress" value="管理者 E-mailアドレス" />
<text name="Save" value="保存" />
<text name="Cancel" value="キャンセル" />
<text name="TenantName_Regex_Description" value="テナント名は少なくとも 2 文字、英字で始まり、文字、数字、ダッシュまたはアンダー スコアである必要があります。" />
<text name="DefaultPasswordIs" value="デフォルトパスワードは {0} です" />
<text name="CanBeEmptyToLoginAsHost" value="ホストでのログインは空とすることができます。" />
<text name="Register" value="登録" />
<text name="OrLoginWith" value="または次でログイン" />
<text name="WaitingForActivationMessage" value="あなたのアカウントがシステム管理者によってアクティブにされるまで待機しています。" />
<text name="TenantSelection" value="テナント選択" />
<text name="TenantSelection_Detail" value="次のテナントの 1 つを選択してください。" />
<text name="Logout" value="ログアウト" />
<text name="RegisterFormUserNameInvalidMessage">ユーザのメールアドレスを入力しないでください。</text>
<text name="DatabaseConnectionString" value="データベース接続文字列" />
<text name="Users" value="ユーザ" />
<text name="IsActive" value="アクティブ" />
<text name="FullName" value="フルネーム" />
<text name="CreateNewUser" value="新規ユーザ作成" />
<text name="Yes" value="はい" />
<text name="No" value="いいえ" />
<text name="Optional" value="オプション" />
</texts>
</localizationDictionary>

Просмотреть файл

@ -0,0 +1,88 @@
<?xml version="1.0" encoding="utf-8" ?>
<localizationDictionary culture="lt">
<texts>
<text name="HomePage" value="Pagrindinis" />
<text name="About" value="Apie" />
<text name="WellcomeMessage" value="Sveiki atvykė į AbpTemplate!" />
<text name="FormIsNotValidMessage" value="Forma blogai užpildyta. Peržiūrėkite ir pataisykite klaidas." />
<text name="TenantNameCanNotBeEmpty" value="Savininko pavadinimas negali būti tuščias" />
<text name="InvalidUserNameOrPassword" value="Blogas vartotojo vardas ar slaptažodis" />
<text name="ThereIsNoTenantDefinedWithName{0}" value="Nėra tokio savininko su pavadinimu {0}" />
<text name="TenantIsNotActive" value="Savininkas {0} nėra aktyvus." />
<text name="UserIsNotActiveAndCanNotLogin" value="Vartotojas {0} nėra aktyvus ir todėl negali prisijungti." />
<text name="UserEmailIsNotConfirmedAndCanNotLogin">Jūsų el. pašto adresas nepatvirtintas. Jūs negalite prisijungti.</text>
<text name="UserLockedOutMessage">Vartotojo paskyra buvo užblokuota. Pabandykite dar kartą vėliau.</text>
<text name="PleaseEnterLoginInformation" value="Įveskite prisijungimo informaciją" />
<text name="TenancyName" value="Savininko pavadinimas" />
<text name="UserNameOrEmail" value="Vartotojo vardas ar slaptažodis" />
<text name="Password" value="Slaptažodis" />
<text name="RememberMe" value="Prisiminti mane" />
<text name="LogIn" value="Prisijungti" />
<text name="LoginFailed" value="Prisijungimas nepavyko!" />
<text name="NameSurname" value="Vardas pavardė" />
<text name="UserName" value="Vartotojo vardas" />
<text name="Name" value="Vardas" />
<text name="Surname" value="Pavardė" />
<text name="EmailAddress" value="El. pašto adresas" />
<text name="Tenants" value="Savininkai" />
<text name="SavedSuccessfully" value="Išsaugota sėkmingai" />
<text name="CreateNewTenant" value="Sukurti naują savininką" />
<text name="AdminEmailAddress" value="Administratoriaus el. pašto adresas" />
<text name="Save" value="Išsaugoti" />
<text name="Cancel" value="Atšaukti" />
<text name="TenantName_Regex_Description" value="Savininko pavadinimas privalo būti bent 2 simboliai, prasidėti su raide, skaičiumi, brūkšneliu ar pabraukimu." />
<text name="DefaultPasswordIs" value="Slaptažodis pagal nutylėjimą yra {0}" />
<text name="CanBeEmptyToLoginAsHost" value="Gali būti tuščia prisijungimui šeimininku." />
<text name="Register" value="Registruotis" />
<text name="OrLoginWith" value="Arba prisijungti su" />
<text name="WaitingForActivationMessage" value="Jūsų paskyra laukia, kol bus aktyvuota sistemos administratoriaus." />
<text name="TenantSelection" value="Savininko Pasirinkimas" />
<text name="TenantSelection_Detail" value="Pasirinkite vieną iš šių savininkų." />
<text name="Logout" value="Atsijungti" />
<text name="RegisterFormUserNameInvalidMessage">Neveskite el. pašto adreso kaip vartotojo vardo.</text>
<text name="DatabaseConnectionString" value="Duomenų bazės prisijungimo eilutė" />
<text name="Users" value="Vartotojai" />
<text name="IsActive" value="Aktyvus" />
<text name="FullName" value="Vardas pavardė" />
<text name="CreateNewUser" value="Sukurti naują vartotoją" />
<text name="Yes" value="Taip" />
<text name="No" value="Ne" />
<text name="Optional" value="Neprivaloma" />
<text name="LeaveEmptyToSwitchToHost">Palikite tuščią, kad perjungtumėte į priimantįjį</text>
<text name="CurrentTenant">Dabartinis savininkas</text>
<text name="NotSelected">Nepasirinkta</text>
<text name="Change">Keisti</text>
<text name="ChangeTenant">Keisti savininką</text>
<text name="MultiLevelMenu">Multi Level Menu</text>
<text name="Back">Atgal</text>
<text name="SuccessfullyRegistered">Sėkmingai užregistruota</text>
<text name="WaitingForEmailActivation">Jūsų el. pašto adresas turi būti aktyvuotas.</text>
<text name="Roles">Rolės</text>
<text name="DisplayName">Rodomas vardas</text>
<text name="Edit">Keisti</text>
<text name="Delete">Trinti</text>
<text name="CreateNewRole">Kurti naują rolę</text>
<text name="RoleName">Rolės pavadinimas</text>
<text name="Actions">Veiksmai</text>
<text name="CouldNotCompleteLoginOperation">Prisijungimo veiksmas nepavyko. Pabandykite vėliau.</text>
<text name="CouldNotValidateExternalUser">Nepavyko patikrinti išorinio vartotojo</text>
<text name="EditRole">Keisti rolę</text>
<text name="EditTenant">Keisti savininką</text>
<text name="EditUser">Keisti vartotoją</text>
<text name="TenantIdIsNotActive{0}">Savininkas su Id {0} yra neaktyvus</text>
<text name="UnknownTenantId{0}">Nežinomas savininko Id {0}</text>
</texts>
</localizationDictionary>

Просмотреть файл

@ -0,0 +1,88 @@
<?xml version="1.0" encoding="utf-8" ?>
<localizationDictionary culture="nl">
<texts>
<text name="HomePage" value="Startpagina" />
<text name="About" value="Over" />
<text name="WellcomeMessage" value="Welkom bij AbpTemplate!" />
<text name="FormIsNotValidMessage" value="Formulier is onjuist ingevuld. Controleer en herstel de fouten." />
<text name="TenantNameCanNotBeEmpty" value="Naam van de huurder mag niet leeg zijn" />
<text name="InvalidUserNameOrPassword" value="Onjuiste gebruikersnaam en/of wachtwoord" />
<text name="ThereIsNoTenantDefinedWithName{0}" value="Er is geen huurder met de naam {0}" />
<text name="TenantIsNotActive" value="Huurder {0} is niet actief." />
<text name="UserIsNotActiveAndCanNotLogin" value="Gebruiker {0} is niet actief en kan niet inloggen." />
<text name="UserEmailIsNotConfirmedAndCanNotLogin">Uw email adres is nog niet bevestigd. U kan niet inloggen.</text>
<text name="UserLockedOutMessage">De gebruikersaccount is geblokkeerd. Gelieve later opnieuw te proberen.</text>
<text name="PleaseEnterLoginInformation" value="Vul gebruikersnaam en wachtwoord in" />
<text name="TenancyName" value="Naam huurder" />
<text name="UserNameOrEmail" value="Gebruikersnaam of e-mail" />
<text name="Password" value="Wachtwoord" />
<text name="RememberMe" value="Onthoud mij" />
<text name="LogIn" value="Log in" />
<text name="LoginFailed" value="Inloggen mislukt!" />
<text name="NameSurname" value="Naam achternaam" />
<text name="UserName" value="Gebruikersnaam" />
<text name="Name" value="Naam" />
<text name="Surname" value="Achternaam" />
<text name="EmailAddress" value="E-mailadres" />
<text name="Tenants" value="Huurders" />
<text name="SavedSuccessfully" value="Correct opgeslagen" />
<text name="CreateNewTenant" value="Huurder aanmaken" />
<text name="AdminEmailAddress" value="E-mailadres beheerder" />
<text name="Save" value="Opslaan" />
<text name="Cancel" value="Annuleer" />
<text name="TenantName_Regex_Description" value="De naam van de huurder dient minimaal 2 tekens te hebben en moet beginnen met een letter en kan daarnaast nog letters, nummers en een (liggend) streepje bevatten." />
<text name="DefaultPasswordIs" value="Standaard wachtwoord is {0}" />
<text name="CanBeEmptyToLoginAsHost" value="Kan leeggelaten worden indien je als host in wilt loggen." />
<text name="Register" value="Registreer" />
<text name="OrLoginWith" value="Of log in met" />
<text name="WaitingForActivationMessage" value="Je account dient nog te worden geactiveerd door de beheerder." />
<text name="TenantSelection" value="Huurder selectie" />
<text name="TenantSelection_Detail" value="Selecteer één van onderstaande huurders." />
<text name="Logout" value="Uitloggen" />
<text name="RegisterFormUserNameInvalidMessage">Voer a.u.b. geen e-mailadres in als gebruikersnaam.</text>
<text name="DatabaseConnectionString" value="Database connectie string" />
<text name="Users" value="Gebruikers" />
<text name="IsActive" value="Is actief" />
<text name="FullName" value="Volledige naam" />
<text name="CreateNewUser" value="Gebruiker aanmaken" />
<text name="Yes" value="Ja" />
<text name="No" value="Nee" />
<text name="Optional" value="Optioneel" />
<text name="LeaveEmptyToSwitchToHost">Laat leeg om naar de host te gaan</text>
<text name="CurrentTenant">Huidige huurder</text>
<text name="NotSelected">Niet geselecteerd</text>
<text name="Change">Wijzig</text>
<text name="ChangeTenant">Wijzig huurder</text>
<text name="MultiLevelMenu">Multi Level Menu</text>
<text name="Back">Terug</text>
<text name="SuccessfullyRegistered">Met success geregistreerd</text>
<text name="WaitingForEmailActivation">Uw email adres moet geactiveerd worden</text>
<text name="Roles">Rollen</text>
<text name="DisplayName">Weergavenaam</text>
<text name="Edit">Bewerk</text>
<text name="Delete">Verwijder</text>
<text name="CreateNewRole">Maak nieuwe rol</text>
<text name="RoleName">Rol Naam</text>
<text name="Actions">Acties</text>
<text name="CouldNotCompleteLoginOperation">De login operatie kon niet afgewerkt worden. Gelieve later opnieuw te proberen.</text>
<text name="CouldNotValidateExternalUser">De externe gebruiker kon niet gevalideerd worden</text>
<text name="EditRole">Bewerk rol</text>
<text name="EditTenant">Bewerk huurder</text>
<text name="EditUser">Bewerk gebruiker</text>
<text name="TenantIdIsNotActive{0}">HuurderId {0} is niet actief</text>
<text name="UnknownTenantId{0}">Onbekend huurderId {0}</text>
</texts>
</localizationDictionary>

Просмотреть файл

@ -0,0 +1,47 @@
<?xml version="1.0" encoding="utf-8" ?>
<localizationDictionary culture="pt-BR">
<texts>
<text name="HomePage" value="Página Inicial" />
<text name="About" value="Sobre" />
<text name="WellcomeMessage" value="Bem Vindo ao AbpTemplate!" />
<text name="FormIsNotValidMessage" value="Formulário não é válido. Por favor, verifique e corrija os erros." />
<text name="TenantNameCanNotBeEmpty" value="Tenant não pode estar vazio" />
<text name="InvalidUserNameOrPassword" value="Nome de usuário ou senha inválida" />
<text name="ThereIsNoTenantDefinedWithName{0}" value="Não há Tenant definido com o nome {0}" />
<text name="TenantIsNotActive" value="Tenant {0} não está ativo." />
<text name="UserIsNotActiveAndCanNotLogin" value="Usuário {0} não está ativo e não pode logar." />
<text name="PleaseEnterLoginInformation" value="Por favor insira as informações de login" />
<text name="TenancyName" value="Nome da Tenancy" />
<text name="UserNameOrEmail" value="Nome de usuário ou email" />
<text name="Password" value="Senha" />
<text name="RememberMe" value="Lembre de mim" />
<text name="LogIn" value="Entrar" />
<text name="LoginFailed" value="Falha no login!" />
<text name="NameSurname" value="Nome sobrenome" />
<text name="UserName" value="Nome de usuário" />
<text name="Name" value="Nome" />
<text name="Surname" value="Sobrenome" />
<text name="EmailAddress" value="Endereço de e-mail" />
<text name="Tenants" value="Tenants" />
<text name="SavedSuccessfully" value="Salvo com sucesso" />
<text name="CreateNewTenant" value="Crie um novo tenant" />
<text name="AdminEmailAddress" value="Endereço de e-mail administrador" />
<text name="Save" value="Salvar" />
<text name="Cancel" value="Cancelar" />
<text name="TenantName_Regex_Description" value="Tenant deve ter no mínimo 2 caracteres, começa com uma letra e continuar com letra, número, traço ou sublinhado." />
<text name="DefaultPasswordIs" value="Senha padrão é {0}" />
<text name="CanBeEmptyToLoginAsHost" value="Pode estar vazio para acessar como Host." />
<text name="Register" value="Registrar" />
<text name="OrLoginWith" value="Ou faça o login com" />
<text name="WaitingForActivationMessage" value="A sua conta está esperando para ser ativado pelo administrador do sistema." />
<text name="TenantSelection" value="Seleção de Tenant" />
<text name="TenantSelection_Detail" value="Por favor selecione um dos seguintes tenants." />
<text name="Logout" value="Sair" />
</texts>
</localizationDictionary>

Просмотреть файл

@ -0,0 +1,79 @@
<?xml version="1.0" encoding="utf-8" ?>
<localizationDictionary culture="tr">
<texts>
<text name="HomePage" value="Ana Sayfa" />
<text name="About" value="Hakkında" />
<text name="WellcomeMessage" value="AbpTemplate projesine hoşgeldiniz!" />
<text name="FormIsNotValidMessage" value="Form geçerli değil. Lütfen kontrol edip hataları düzeltin." />
<text name="TenantNameCanNotBeEmpty" value="Müşteri adı boş bırakılamaz." />
<text name="InvalidUserNameOrPassword" value="Kullanıcı adı ya da şifre hatalı." />
<text name="ThereIsNoTenantDefinedWithName{0}" value="{0} isminde bir müşteri tanımlı değildir." />
<text name="TenantIsNotActive" value="{0} isimli müşteri aktif edilmemiştir." />
<text name="UserIsNotActiveAndCanNotLogin" value="{0} isimli kullanıcı pasife alınmıştır ve sisteme giremez." />
<text name="UserEmailIsNotConfirmedAndCanNotLogin">E-posta adresiniz doğrulanmadı, giriş yapamazsınız.</text>
<text name="UserLockedOutMessage">Kullanıcı hesabı kilitlenmiş. Lütfen bir süre sonra tekrar deneyin.</text>
<text name="PleaseEnterLoginInformation" value="Lütfen giriş bilgilerinizi girin" />
<text name="TenancyName" value="Müşteri adı" />
<text name="UserNameOrEmail" value="Kullanıcı adı ya da e-posta" />
<text name="Password" value="Şifre" />
<text name="RememberMe" value="Beni hatırla" />
<text name="LogIn" value="Giriş" />
<text name="LoginFailed" value="Giriş başarısız!" />
<text name="NameSurname" value="Ad soyad" />
<text name="UserName" value="Kullanıcı adı" />
<text name="Name" value="İsim" />
<text name="Surname" value="Soyisim" />
<text name="EmailAddress" value="E-posta adresi" />
<text name="Tenants" value="Müşteriler" />
<text name="SavedSuccessfully" value="Başarıyla kaydedildi" />
<text name="CreateNewTenant" value="Yeni müşteri oluştur" />
<text name="AdminEmailAddress" value="Yönetici e-posta adresi" />
<text name="Save" value="Kaydet" />
<text name="Cancel" value="İptal" />
<text name="TenantName_Regex_Description" value="Müşteri adı en az 2 karakter olmalı, bir harfle başlamalı ve harf, rakam, tire ya da alt çizgi ile devam etmelidir." />
<text name="DefaultPasswordIs" value="Varsayılan şifre {0}" />
<text name="CanBeEmptyToLoginAsHost" value="Host olarak giriş yapmak için boş bırakılabilir." />
<text name="Register" value="Kayıt ol" />
<text name="OrLoginWith" value="Ya da şununla giriş yap" />
<text name="WaitingForActivationMessage" value="Hesabınız sistem yöneticisi tarafından etkinleştirilmek için bekliyor." />
<text name="TenantSelection" value="Müşteri seçimi" />
<text name="TenantSelection_Detail" value="Lütfen aşağıdaki müşterilerden birisini seçin." />
<text name="Logout" value=ıkış" />
<text name="RegisterFormUserNameInvalidMessage">Lütfen kullanıcı adı alanına e-posta adresi girmeyin.</text>
<text name="DatabaseConnectionString" value="Veritabanı bağlantı cümlesi" />
<text name="Users" value="Kullanıcılar" />
<text name="IsActive" value="Etkin mi" />
<text name="FullName" value="Tam adı" />
<text name="CreateNewUser" value="Yeni kullanıcı oluştur" />
<text name="Yes" value="Evet" />
<text name="No" value="Hayır" />
<text name="Optional" value="Opsiyonel" />
<text name="LeaveEmptyToSwitchToHost">Üst kullanıcıya geçiş için boş değer girin.</text>
<text name="CurrentTenant">Geçerli müşteri</text>
<text name="NotSelected">Seçilmemiş</text>
<text name="Change">Değiştir</text>
<text name="ChangeTenant">Müşteri değiştir</text>
<text name="MultiLevelMenu">Çok Seviyeli Menü</text>
<text name="Back">Geri</text>
<text name="SuccessfullyRegistered">Başarıyla kayıt olundu</text>
<text name="WaitingForEmailActivation">E-posta adresiniz etkinleştirilmeli.</text>
<text name="Roles">Roller</text>
<text name="DisplayName">Görünen ad</text>
<text name="Edit">Düzenle</text>
<text name="Delete">Sil</text>
<text name="CreateNewRole">Yeni rol oluştur</text>
<text name="RoleName">Rol adı</text>
<text name="Actions">İşlemler</text>
</texts>
</localizationDictionary>

Просмотреть файл

@ -0,0 +1,25 @@
<?xml version="1.0" encoding="utf-8" ?>
<localizationDictionary culture="zh-CN">
<texts>
<text name="HomePage" value="主页" />
<text name="About" value="关于我们" />
<text name="WellcomeMessage" value="欢迎使用 AbpTemplate!" />
<text name="FormIsNotValidMessage" value="部分输入信息不符合要求,请检查并改正.." />
<text name="TenantNameCanNotBeEmpty" value="租户名不能为空" />
<text name="InvalidUserNameOrPassword" value="用户名或密码无效" />
<text name="ThereIsNoTenantDefinedWithName{0}" value="租户 {0}不存在" />
<text name="TenantIsNotActive" value="租户 {0} 未激活." />
<text name="UserIsNotActiveAndCanNotLogin" value="用户 {0} 未激活,不能登录." />
<text name="PleaseEnterLoginInformation" value="请输入登录信息" />
<text name="TenancyName" value="租户名称" />
<text name="UserNameOrEmail" value="用户名或邮箱地址" />
<text name="Password" value="密码" />
<text name="RememberMe" value="记住我" />
<text name="LogIn" value="登录" />
<text name="LoginFailed" value="登录失败!" />
</texts>
</localizationDictionary>

Просмотреть файл

@ -0,0 +1,88 @@
<?xml version="1.0" encoding="utf-8" ?>
<localizationDictionary culture="en">
<texts>
<text name="HomePage" value="Home page" />
<text name="About" value="About" />
<text name="WellcomeMessage" value="Welcome to AbpTemplate!" />
<text name="FormIsNotValidMessage" value="Form is not valid. Please check and fix errors." />
<text name="TenantNameCanNotBeEmpty" value="Tenant name can not be empty" />
<text name="InvalidUserNameOrPassword" value="Invalid user name or password" />
<text name="ThereIsNoTenantDefinedWithName{0}" value="There is no tenant defined with name {0}" />
<text name="TenantIsNotActive" value="Tenant {0} is not active." />
<text name="UserIsNotActiveAndCanNotLogin" value="User {0} is not active and can not log in." />
<text name="UserEmailIsNotConfirmedAndCanNotLogin">Your email address is not confirmed. You can not login.</text>
<text name="UserLockedOutMessage">The user account has been locked out. Please try again later.</text>
<text name="PleaseEnterLoginInformation" value="Please enter login information" />
<text name="TenancyName" value="Tenancy name" />
<text name="UserNameOrEmail" value="User name or email" />
<text name="Password" value="Password" />
<text name="RememberMe" value="Remember me" />
<text name="LogIn" value="Log in" />
<text name="LoginFailed" value="Login failed!" />
<text name="NameSurname" value="Name surname" />
<text name="UserName" value="User name" />
<text name="Name" value="Name" />
<text name="Surname" value="Surname" />
<text name="EmailAddress" value="Email address" />
<text name="Tenants" value="Tenants" />
<text name="SavedSuccessfully" value="Saved successfully" />
<text name="CreateNewTenant" value="Create new tenant" />
<text name="AdminEmailAddress" value="Admin email address" />
<text name="Save" value="Save" />
<text name="Cancel" value="Cancel" />
<text name="TenantName_Regex_Description" value="Tenant name must be at least 2 chars, starts with a letter and continue with letter, number, dash or underscore." />
<text name="DefaultPasswordIs" value="Default password is {0}" />
<text name="CanBeEmptyToLoginAsHost" value="Can be empty to login as host." />
<text name="Register" value="Register" />
<text name="OrLoginWith" value="Or login with" />
<text name="WaitingForActivationMessage" value="Your account is waiting to be activated by system admin." />
<text name="TenantSelection" value="Tenant Selection" />
<text name="TenantSelection_Detail" value="Please select one of the following tenants." />
<text name="Logout" value="Logout" />
<text name="RegisterFormUserNameInvalidMessage">Please don't enter an email address for username.</text>
<text name="DatabaseConnectionString" value="Database connection string" />
<text name="Users" value="Users" />
<text name="IsActive" value="Is active" />
<text name="FullName" value="Full name" />
<text name="CreateNewUser" value="Create new user" />
<text name="Yes" value="Yes" />
<text name="No" value="No" />
<text name="Optional" value="Optional" />
<text name="LeaveEmptyToSwitchToHost">Leave empty to switch to the host</text>
<text name="CurrentTenant">Current tenant</text>
<text name="NotSelected">Not selected</text>
<text name="Change">Change</text>
<text name="ChangeTenant">Change tenant</text>
<text name="MultiLevelMenu">Multi Level Menu</text>
<text name="Back">Back</text>
<text name="SuccessfullyRegistered">Successfully registered</text>
<text name="WaitingForEmailActivation">Your email address should be activated</text>
<text name="Roles">Roles</text>
<text name="DisplayName">Display Name</text>
<text name="Edit">Edit</text>
<text name="Delete">Delete</text>
<text name="CreateNewRole">Create new role</text>
<text name="RoleName">Role Name</text>
<text name="Actions">Actions</text>
<text name="CouldNotCompleteLoginOperation">Could not complete login operation. Please try again later.</text>
<text name="CouldNotValidateExternalUser">Could not validate external user</text>
<text name="EditRole">Edit role</text>
<text name="EditTenant">Edit tenant</text>
<text name="EditUser">Edit user</text>
<text name="TenantIdIsNotActive{0}">TenantId {0} is not active</text>
<text name="UnknownTenantId{0}">Unknown tenantId {0}</text>
</texts>
</localizationDictionary>

Просмотреть файл

@ -0,0 +1,17 @@
using Abp.MultiTenancy;
using AbpTemplate.Authorization.Users;
namespace AbpTemplate.MultiTenancy
{
public class Tenant : AbpTenant<User>
{
public Tenant()
{
}
public Tenant(string tenancyName, string name)
: base(tenancyName, name)
{
}
}
}

Просмотреть файл

@ -0,0 +1,24 @@
using Abp.Application.Features;
using Abp.Domain.Repositories;
using Abp.MultiTenancy;
using AbpTemplate.Authorization.Users;
using AbpTemplate.Editions;
namespace AbpTemplate.MultiTenancy
{
public class TenantManager : AbpTenantManager<Tenant, User>
{
public TenantManager(
IRepository<Tenant> tenantRepository,
IRepository<TenantFeatureSetting, long> tenantFeatureRepository,
EditionManager editionManager,
IAbpZeroFeatureValueStore featureValueStore)
: base(
tenantRepository,
tenantFeatureRepository,
editionManager,
featureValueStore)
{
}
}
}

Просмотреть файл

@ -0,0 +1,18 @@
using System.Reflection;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("AbpTemplate.Core")]
[assembly: AssemblyTrademark("")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("0fa75a5b-ab83-4fd0-b545-279774c01e87")]

Просмотреть файл

@ -0,0 +1,13 @@
using System;
using Abp.Dependency;
namespace AbpTemplate.Timing
{
public class AppTimes : ISingletonDependency
{
/// <summary>
/// Gets the startup time of the application.
/// </summary>
public DateTime StartupTime { get; set; }
}
}

Просмотреть файл

@ -0,0 +1,21 @@
using System.Text.RegularExpressions;
using Abp.Extensions;
namespace AbpTemplate.Validation
{
public static class ValidationHelper
{
public const string EmailRegex = @"^\w+([-+.']\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$";
public static bool IsEmail(string value)
{
if (value.IsNullOrEmpty())
{
return false;
}
var regex = new Regex(EmailRegex);
return regex.IsMatch(value);
}
}
}

Просмотреть файл

@ -0,0 +1,53 @@
using System;
using System.IO;
using System.Linq;
using Abp.Reflection.Extensions;
namespace AbpTemplate.Web
{
/// <summary>
/// This class is used to find root path of the web project in;
/// unit tests (to find views) and entity framework core command line commands (to find conn string).
/// </summary>
public static class WebContentDirectoryFinder
{
public static string CalculateContentRootFolder()
{
var coreAssemblyDirectoryPath = Path.GetDirectoryName(typeof(AbpTemplateCoreModule).GetAssembly().Location);
if (coreAssemblyDirectoryPath == null)
{
throw new Exception("Could not find location of AbpTemplate.Core assembly!");
}
var directoryInfo = new DirectoryInfo(coreAssemblyDirectoryPath);
while (!DirectoryContains(directoryInfo.FullName, "AbpTemplate.sln"))
{
if (directoryInfo.Parent == null)
{
throw new Exception("Could not find content root folder!");
}
directoryInfo = directoryInfo.Parent;
}
var webMvcFolder = Path.Combine(directoryInfo.FullName, "src", "AbpTemplate.Web.Mvc");
if (Directory.Exists(webMvcFolder))
{
return webMvcFolder;
}
var webHostFolder = Path.Combine(directoryInfo.FullName, "src", "AbpTemplate.Web.Host");
if (Directory.Exists(webHostFolder))
{
return webHostFolder;
}
throw new Exception("Could not find root folder of the web project!");
}
private static bool DirectoryContains(string directory, string fileName)
{
return Directory.GetFiles(directory).Any(filePath => string.Equals(Path.GetFileName(filePath), fileName));
}
}
}

Просмотреть файл

@ -0,0 +1,22 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netcoreapp2.0</TargetFramework>
<AssetTargetFallback>$(AssetTargetFallback);portable-net45+win8+wp8+wpa81;</AssetTargetFallback>
<RootNamespace>AbpTemplate</RootNamespace>
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
<GenerateBindingRedirectsOutputType>true</GenerateBindingRedirectsOutputType>
<GenerateRuntimeConfigurationFiles>true</GenerateRuntimeConfigurationFiles>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="2.0.1" />
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="2.0.1" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="2.0.1" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="2.0.1" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\AbpTemplate.Core\AbpTemplate.Core.csproj" />
</ItemGroup>
<ItemGroup>
<DotNetCliToolReference Include="Microsoft.EntityFrameworkCore.Tools.DotNet" Version="2.0.0" />
</ItemGroup>
</Project>

Просмотреть файл

@ -0,0 +1,18 @@
using Microsoft.EntityFrameworkCore;
using Abp.Zero.EntityFrameworkCore;
using AbpTemplate.Authorization.Roles;
using AbpTemplate.Authorization.Users;
using AbpTemplate.MultiTenancy;
namespace AbpTemplate.EntityFrameworkCore
{
public class AbpTemplateDbContext : AbpZeroDbContext<Tenant, Role, User, AbpTemplateDbContext>
{
/* Define a DbSet for each entity of the application */
public AbpTemplateDbContext(DbContextOptions<AbpTemplateDbContext> options)
: base(options)
{
}
}
}

Просмотреть файл

@ -0,0 +1,18 @@
using System.Data.Common;
using Microsoft.EntityFrameworkCore;
namespace AbpTemplate.EntityFrameworkCore
{
public static class AbpTemplateDbContextConfigurer
{
public static void Configure(DbContextOptionsBuilder<AbpTemplateDbContext> builder, string connectionString)
{
builder.UseSqlite(connectionString);
}
public static void Configure(DbContextOptionsBuilder<AbpTemplateDbContext> builder, DbConnection connection)
{
builder.UseSqlite(connection);
}
}
}

Просмотреть файл

@ -0,0 +1,22 @@
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Design;
using Microsoft.Extensions.Configuration;
using AbpTemplate.Configuration;
using AbpTemplate.Web;
namespace AbpTemplate.EntityFrameworkCore
{
/* This class is needed to run "dotnet ef ..." commands from command line on development. Not used anywhere else */
public class AbpTemplateDbContextFactory : IDesignTimeDbContextFactory<AbpTemplateDbContext>
{
public AbpTemplateDbContext CreateDbContext(string[] args)
{
var builder = new DbContextOptionsBuilder<AbpTemplateDbContext>();
var configuration = AppConfigurations.Get(WebContentDirectoryFinder.CalculateContentRootFolder());
AbpTemplateDbContextConfigurer.Configure(builder, configuration.GetConnectionString(AbpTemplateConsts.ConnectionStringName));
return new AbpTemplateDbContext(builder.Options);
}
}
}

Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше