Created
November 7, 2023 07:53
-
-
Save ebicoglu/f1bafc8f339924c0fe2baac679353077 to your computer and use it in GitHub Desktop.
This is a sample ABP class that seeds your DB with dummy editions, tenants, roles, users and organizations. This class implements `IDataSeedContributor`, therefore, `DbMigrator` will add the specified data to your DB.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Generic; | |
using System.Linq; | |
using System.Threading.Tasks; | |
using Bogus; | |
using Volo.Abp; | |
using Volo.Abp.Auditing; | |
using Volo.Abp.AuditLogging; | |
using Volo.Abp.Data; | |
using Volo.Abp.DependencyInjection; | |
using Volo.Abp.Guids; | |
using Volo.Abp.Identity; | |
using Microsoft.AspNetCore.Identity; | |
using Microsoft.Extensions.Options; | |
using Volo.Abp.MultiTenancy; | |
using Volo.Abp.PermissionManagement; | |
using Volo.Abp.SettingManagement; | |
using Volo.Abp.Settings; | |
using Volo.Abp.Timing; | |
using Volo.Abp.Uow; | |
using Volo.Saas.Editions; | |
using Volo.Saas.Tenants; | |
using IdentityUser = Volo.Abp.Identity.IdentityUser; | |
using IdentityRole = Volo.Abp.Identity.IdentityRole; | |
namespace Volo.AbpCommercialDemo.Data | |
{ | |
public class DemoDataSeedContributor : IDataSeedContributor, ITransientDependency | |
{ | |
private readonly ITenantRepository _tenantRepository; | |
private readonly ITenantManager _tenantManager; | |
private readonly IEditionRepository _editionRepository; | |
private readonly IGuidGenerator _guidGenerator; | |
private readonly IAuditLogRepository _auditLogRepository; | |
private readonly IClock _clock; | |
private readonly IdentityUserManager _userManager; | |
private readonly IdentityRoleManager _roleManager; | |
private readonly OrganizationUnitManager _organizationUnitManager; | |
private readonly IUnitOfWorkManager _unitOfWorkManager; | |
private readonly IdentityDataSeedContributor _identityDataSeedContributor; | |
private readonly PermissionDataSeedContributor _permissionDataSeedContributor; | |
private readonly ICurrentTenant _currentTenant; | |
private readonly IOptions<IdentityOptions> _identityOptions; | |
private readonly IAuditLogInfoToAuditLogConverter _auditLogInfoToAuditLogConverter; | |
private readonly ISettingManager _settingManager; | |
public DemoDataSeedContributor( | |
ITenantRepository tenantRepository, | |
ITenantManager tenantManager, | |
IEditionRepository editionRepository, | |
IGuidGenerator guidGenerator, | |
IAuditLogRepository auditLogRepository, | |
IClock clock, | |
IdentityUserManager userManager, | |
IdentityDataSeedContributor identityDataSeedContributor, | |
PermissionDataSeedContributor permissionDataSeedContributor, | |
ICurrentTenant currentTenant, | |
IdentityRoleManager roleManager, | |
OrganizationUnitManager organizationUnitManager, | |
IUnitOfWorkManager unitOfWorkManager, | |
IOptions<IdentityOptions> identityOptions, | |
IAuditLogInfoToAuditLogConverter auditLogInfoToAuditLogConverter, | |
ISettingManager settingManager) | |
{ | |
_tenantRepository = tenantRepository; | |
_tenantManager = tenantManager; | |
_editionRepository = editionRepository; | |
_guidGenerator = guidGenerator; | |
_auditLogRepository = auditLogRepository; | |
_clock = clock; | |
_userManager = userManager; | |
_identityDataSeedContributor = identityDataSeedContributor; | |
_permissionDataSeedContributor = permissionDataSeedContributor; | |
_currentTenant = currentTenant; | |
_roleManager = roleManager; | |
_organizationUnitManager = organizationUnitManager; | |
_unitOfWorkManager = unitOfWorkManager; | |
_identityOptions = identityOptions; | |
_auditLogInfoToAuditLogConverter = auditLogInfoToAuditLogConverter; | |
_settingManager = settingManager; | |
} | |
[UnitOfWork] | |
public virtual async Task SeedAsync(DataSeedContext context) | |
{ | |
if (_currentTenant.Id.HasValue) | |
{ | |
return; | |
} | |
var editionIds = await CreateEditionsAsync(); | |
await CreateTenantsAsync(editionIds); | |
await CreateAuditLogs(); | |
var roles = await CreateRolesAsync(); | |
var users = await CreateUsersAsync(roles); | |
await CreateOrganizationUnitsAsync(users, roles); | |
await SetDefaultSettingsAsync(); | |
} | |
private async Task SetDefaultSettingsAsync() | |
{ | |
await _settingManager.SetAsync( | |
"Abp.Identity.SignIn.RequireConfirmedEmail", | |
bool.FalseString, | |
GlobalSettingValueProvider.ProviderName, | |
null | |
); | |
} | |
private async Task<List<IdentityRole>> CreateRolesAsync() | |
{ | |
var roles = new List<IdentityRole> | |
{ | |
new IdentityRole(_guidGenerator.Create(), "Manager", _currentTenant.Id), | |
new IdentityRole(_guidGenerator.Create(), "Moderator", _currentTenant.Id), | |
new IdentityRole(_guidGenerator.Create(), "Supporter", _currentTenant.Id) | |
}; | |
using (var uow = _unitOfWorkManager.Begin()) // OrganizationUnitManager requires this. | |
{ | |
foreach (var role in roles) | |
{ | |
if (!await _roleManager.RoleExistsAsync(role.Name)) | |
{ | |
await _roleManager.CreateAsync(role); | |
} | |
} | |
await uow.SaveChangesAsync(); | |
} | |
return roles; | |
} | |
private async Task<List<IdentityUser>> CreateUsersAsync(List<IdentityRole> roles = null) | |
{ | |
await _identityOptions.SetAsync(); | |
var faker = new Faker(); | |
var rnd = new Random(); | |
var emailList = new List<string>(); | |
var userList = new List<IdentityUser>(); | |
for (int i = 0; i < rnd.Next(20, 30); i++) | |
{ | |
var email = faker.Internet.ExampleEmail(); | |
if (emailList.Contains(email)) | |
{ | |
continue; | |
} | |
emailList.Add(email); | |
userList.Add( | |
new IdentityUser( | |
_guidGenerator.Create(), | |
email.Split('@').First(), | |
email, | |
_currentTenant.Id | |
) | |
); | |
} | |
using (var uow = _unitOfWorkManager.Begin()) // OrganizationUnitManager requires this. | |
{ | |
foreach (var user in userList) | |
{ | |
(await _userManager.CreateAsync(user, "123456")).CheckErrors(); | |
if (roles != null) | |
{ | |
if (rnd.Next(0, 4) <= 2) // 3/4 ratio for true | |
{ | |
var assignedRoles = faker.PickRandom(roles, rnd.Next(1, roles.Count + 1)) | |
.Select(x => x.Name) | |
.ToArray(); | |
await _userManager.AddToRolesAsync(user, assignedRoles); | |
} | |
} | |
} | |
await uow.SaveChangesAsync(); | |
} | |
return userList; | |
} | |
private async Task<List<OrganizationUnit>> CreateOrganizationUnitsAsync(List<IdentityUser> users = null, | |
List<IdentityRole> roles = null) | |
{ | |
var sellingId = _guidGenerator.Create(); | |
var supportingId = _guidGenerator.Create(); | |
var oUnits = new List<OrganizationUnit> | |
{ | |
new OrganizationUnit(sellingId, "Selling", tenantId: _currentTenant.Id), | |
new OrganizationUnit(_guidGenerator.Create(), "Marketing", sellingId, tenantId: _currentTenant.Id), | |
new OrganizationUnit(_guidGenerator.Create(), "Customer Relations", sellingId, tenantId: _currentTenant.Id), | |
new OrganizationUnit(supportingId, "Supporting", tenantId: _currentTenant.Id), | |
new OrganizationUnit(_guidGenerator.Create(), "Buying", supportingId, tenantId: _currentTenant.Id), | |
new OrganizationUnit(_guidGenerator.Create(), "Human Resources", supportingId, tenantId: _currentTenant.Id), | |
new OrganizationUnit(_guidGenerator.Create(), "Sales", tenantId: _currentTenant.Id) | |
}; | |
var rnd = new Random(); | |
var faker = new Faker(); | |
foreach (var organizationUnit in oUnits) | |
{ | |
using (var uow = _unitOfWorkManager.Begin()) // OrganizationUnitManager requires this. | |
{ | |
await _organizationUnitManager.CreateAsync(organizationUnit); | |
await uow.SaveChangesAsync(); | |
} | |
if (roles != null) | |
{ | |
var assignedRoles = faker.PickRandom(roles, rnd.Next(0, roles.Count + 1)); | |
foreach (var assignedRole in assignedRoles) | |
{ | |
await _organizationUnitManager.AddRoleToOrganizationUnitAsync(assignedRole.Id, | |
organizationUnit.Id); | |
} | |
} | |
if (users != null) | |
{ | |
var ouListId = oUnits.IndexOf(organizationUnit); | |
var pageSize = (int) (users.Count / oUnits.Count); | |
var pagedUsers = users.Skip(ouListId * pageSize); | |
if (ouListId != oUnits.Count - 1) | |
{ | |
pagedUsers = pagedUsers.Take(pageSize); | |
} | |
foreach (var user in pagedUsers) | |
{ | |
await _userManager.AddToOrganizationUnitAsync(user.Id, organizationUnit.Id); | |
} | |
} | |
} | |
return oUnits; | |
} | |
private async Task CreateAuditLogs() | |
{ | |
var services = new List<string> {"UserAppService", "TenantAppService", "CompanyAppService"}; | |
var methods = new List<string> {"GetAsync", "CreateAsync", "DeleteAsync"}; | |
var httpStatusCodes = new List<int> {400, 401, 403, 404, 500}; | |
var ipAddresses = new List<string> | |
{ | |
"127.0.0.1", | |
"10.0.0.42" | |
}; | |
var urls = new List<string> | |
{ | |
"/identity/claim-types", | |
"/identity/users", | |
"/setting-management", | |
"/saas/tenants", | |
"/file-management", | |
"/identity/roles" | |
}; | |
var admin = await _userManager.FindByNameAsync("admin"); | |
for (var i = 0; i < 100; i++) | |
{ | |
var method = RandomHelper.GetRandomOfList(methods); | |
await CreateAuditLog( | |
admin, | |
RandomHelper.GetRandomOfList(services), | |
method, | |
GetHttpMethodFromMethodName(method), | |
RandomHelper.GetRandomOfList(httpStatusCodes), | |
RandomHelper.GetRandomOfList(ipAddresses), | |
RandomHelper.GetRandomOfList(urls) | |
); | |
} | |
} | |
private string GetHttpMethodFromMethodName(string method) | |
{ | |
if (method.StartsWith("Create")) | |
{ | |
return "POST"; | |
} | |
if (method.StartsWith("Delete")) | |
{ | |
return "DELETE"; | |
} | |
return "GET"; | |
} | |
private async Task CreateAuditLog(IdentityUser user, string serviceName, string methodName, string httpMethod, | |
int? httpStatusCode, string ipAddress, string url) | |
{ | |
await _auditLogRepository.InsertAsync(await _auditLogInfoToAuditLogConverter.ConvertAsync(new AuditLogInfo | |
{ | |
ApplicationName = "AbpCommercialDemo", | |
HttpMethod = httpMethod, | |
HttpStatusCode = httpStatusCode, | |
TenantId = _currentTenant.Id, | |
UserId = user.Id, | |
Url = url, | |
UserName = user.UserName, | |
ClientIpAddress = ipAddress, | |
ExecutionDuration = RandomHelper.GetRandom(1000, 10000), | |
ExecutionTime = _clock.Now.AddMinutes(-1 * RandomHelper.GetRandom(100)), | |
Actions = new List<AuditLogActionInfo> | |
{ | |
new AuditLogActionInfo | |
{ | |
ServiceName = serviceName, | |
MethodName = methodName, | |
ExecutionDuration = RandomHelper.GetRandom(1000, 10000), | |
ExecutionTime = _clock.Now.AddMinutes(-1 * RandomHelper.GetRandom(100)), | |
Parameters = "" | |
} | |
} | |
})); | |
} | |
private async Task CreateTenantsAsync(List<Guid> editionIds) | |
{ | |
if ((await _tenantRepository.FindByNameAsync("Volosoft")) == null) | |
{ | |
await CreateTenantAsync("Volosoft", editionIds); | |
} | |
if ((await _tenantRepository.FindByNameAsync("Microsoft")) == null) | |
{ | |
await CreateTenantAsync("Microsoft", editionIds); | |
} | |
if ((await _tenantRepository.FindByNameAsync("Apple")) == null) | |
{ | |
await CreateTenantAsync("Apple", editionIds); | |
} | |
if ((await _tenantRepository.FindByNameAsync("Samsung")) == null) | |
{ | |
await CreateTenantAsync("Samsung", editionIds); | |
} | |
if (await _tenantRepository.FindByNameAsync("Amazon") == null) | |
{ | |
await CreateTenantAsync("Amazon", editionIds); | |
} | |
if (await _tenantRepository.FindByNameAsync("Intel") == null) | |
{ | |
await CreateTenantAsync("Intel", editionIds); | |
} | |
if ((await _tenantRepository.FindByNameAsync("IBM")) == null) | |
{ | |
await CreateTenantAsync("IBM", editionIds); | |
} | |
if ((await _tenantRepository.FindByNameAsync("Oracle")) == null) | |
{ | |
await CreateTenantAsync("Oracle", editionIds); | |
} | |
} | |
private async Task CreateTenantAsync(string name, List<Guid> editionIds) | |
{ | |
var tenant = await _tenantManager.CreateAsync(name, GetRandomEditionId(editionIds)); | |
await _tenantRepository.InsertAsync(tenant); | |
using (_currentTenant.Change(tenant.Id)) | |
{ | |
await _identityDataSeedContributor.SeedAsync(new DataSeedContext(tenant.Id)); | |
await _permissionDataSeedContributor.SeedAsync(new DataSeedContext(tenant.Id)); | |
} | |
} | |
private Guid? GetRandomEditionId(List<Guid> editionIds) | |
{ | |
if (editionIds.Count == 0) | |
{ | |
return null; | |
} | |
return RandomHelper.GetRandomOfList(editionIds); | |
} | |
private async Task<List<Guid>> CreateEditionsAsync() | |
{ | |
var editions = await _editionRepository.GetListAsync(false); | |
var editionIds = new List<Guid>(); | |
if (editions.All(e => e.DisplayName != "Standard")) | |
{ | |
var id = await CreateEditionAsync("Standard"); | |
editionIds.Add(id); | |
} | |
if (editions.All(e => e.DisplayName != "Professional")) | |
{ | |
var id = await CreateEditionAsync("Professional"); | |
editionIds.Add(id); | |
} | |
if (editions.All(e => e.DisplayName != "Business")) | |
{ | |
var id = await CreateEditionAsync("Business"); | |
editionIds.Add(id); | |
} | |
if (editions.All(e => e.DisplayName != "Enterprise")) | |
{ | |
var id = await CreateEditionAsync("Enterprise"); | |
editionIds.Add(id); | |
} | |
return editionIds; | |
} | |
private async Task<Guid> CreateEditionAsync(string name) | |
{ | |
var id = _guidGenerator.Create(); | |
await _editionRepository.InsertAsync( | |
new Edition(id, name) | |
); | |
return id; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment