Skip to content

Instantly share code, notes, and snippets.

@ebicoglu
Created November 7, 2023 07:53
Show Gist options
  • Save ebicoglu/f1bafc8f339924c0fe2baac679353077 to your computer and use it in GitHub Desktop.
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.
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