using System; using System.Collections.Generic; using AyaNova.Models; using AyaNova.Biz; using Microsoft.Extensions.Logging; using Microsoft.EntityFrameworkCore; using Bogus; using AyaNova.Api.ControllerHelpers; namespace AyaNova.Util { public static class Seeder { public enum SeedLevel { SmallOneManShopTrialDataSet, MediumLocalServiceCompanyTrialDataSet, LargeCorporateMultiRegionalTrialDataSet }; // ////////////////////////////////////////////////////// // //Seed database with default manager account // // // public static User GenerateDefaultManagerAccountUser() // { // User u = new User(); // u.Name = "AyaNova Administrator"; // u.Salt = Hasher.GenerateSalt(); // u.Login = "manager"; // u.Password = Hasher.hash(u.Salt, "l3tm3in"); // u.Roles = AuthorizationRoles.BizAdminFull | AuthorizationRoles.OpsAdminFull | AuthorizationRoles.DispatchFull | AuthorizationRoles.InventoryFull; // u.OwnerId = 1; // return u; // } ////////////////////////////////////////////////////// //Seed database for trial and testing purposes // public static void SeedDatabase(SeedLevel slevel) { ILogger log = AyaNova.Util.ApplicationLogging.CreateLogger("Seeder"); ApiServerState apiServerState = (ApiServerState)ServiceProviderProvider.Provider.GetService(typeof(ApiServerState)); //get the current server state so can set back to it later ApiServerState.ServerState wasServerState = apiServerState.GetState(); string wasReason = apiServerState.Reason; try { log.LogInformation("SEEDER: SeedDatabase, level is: " + slevel.ToString()); //Only allow this in a trial database if (!AyaNova.Core.License.ActiveKey.TrialLicense) { throw new System.NotSupportedException("This database has a registered license key and can't be seeded."); } log.LogInformation("Setting server state to OpsOnly"); apiServerState.SetOpsOnly("Seeding database"); //Erase all the data except for the license, schema and the manager user DbUtil.PrepareDatabaseForSeeding(log); //Seed special test data for integration testing SeedKnownUsers(); switch (slevel) { //This is for a busy but one man shop with a single office person handling stuff back at the shop case SeedLevel.SmallOneManShopTrialDataSet: //Generate owner and lead tech GenSeedUser(1, AuthorizationRoles.BizAdminFull | AuthorizationRoles.DispatchFull | AuthorizationRoles.InventoryFull | AuthorizationRoles.OpsAdminFull); //Generate one office person / secretary GenSeedUser(1, AuthorizationRoles.DispatchFull | AuthorizationRoles.InventoryFull | AuthorizationRoles.AccountingFull); //200 widgets GenSeedWidget(200); break; //This is for a typical AyaNova medium busy shop //has one location, many techs and full staff for each department case SeedLevel.MediumLocalServiceCompanyTrialDataSet: //One IT administrator, can change ops but nothing else GenSeedUser(1, AuthorizationRoles.OpsAdminFull); //One business administrator, can view ops issues GenSeedUser(1, AuthorizationRoles.BizAdminFull | AuthorizationRoles.OpsAdminLimited); //One owner who doesn't control anything but views stuff GenSeedUser(1, AuthorizationRoles.DispatchLimited | AuthorizationRoles.InventoryLimited | AuthorizationRoles.OpsAdminLimited); //20 techs GenSeedUser(20, AuthorizationRoles.TechFull | AuthorizationRoles.DispatchLimited); //2 subcontractors GenSeedUser(2, AuthorizationRoles.SubContractorFull); //3 sales / generic office people people GenSeedUser(3, AuthorizationRoles.DispatchLimited | AuthorizationRoles.InventoryLimited); //1 dispatch manager GenSeedUser(1, AuthorizationRoles.DispatchFull | AuthorizationRoles.InventoryLimited); //1 Inventory manager GenSeedUser(1, AuthorizationRoles.InventoryFull | AuthorizationRoles.DispatchLimited); //1 accountant / bookkeeper GenSeedUser(1, AuthorizationRoles.AccountingFull | AuthorizationRoles.BizAdminLimited); //10 full on client users GenSeedUser(10, AuthorizationRoles.ClientLimited); //10 limited client users GenSeedUser(10, AuthorizationRoles.ClientLimited); //2000 widgets GenSeedWidget(2000); break; //this is a large corporation with multiple branches in multiple locations all in the same country //Each location has a full staff and corporate head office has an overarching staff member in charge of each location case SeedLevel.LargeCorporateMultiRegionalTrialDataSet: //IT administrator, can change ops but nothing else GenSeedUser(2, AuthorizationRoles.OpsAdminFull); //business administrator, can view ops issues GenSeedUser(2, AuthorizationRoles.BizAdminFull | AuthorizationRoles.OpsAdminLimited); //owner / upper management who doesn't control anything but views stuff GenSeedUser(5, AuthorizationRoles.DispatchLimited | AuthorizationRoles.InventoryLimited | AuthorizationRoles.OpsAdminLimited); //techs GenSeedUser(100, AuthorizationRoles.TechFull | AuthorizationRoles.DispatchLimited); //limited techs GenSeedUser(50, AuthorizationRoles.TechLimited | AuthorizationRoles.DispatchLimited); //20 subcontractors GenSeedUser(20, AuthorizationRoles.SubContractorFull); //10 limited subcontractors GenSeedUser(10, AuthorizationRoles.SubContractorLimited); //30 sales / generic office people people GenSeedUser(30, AuthorizationRoles.DispatchLimited | AuthorizationRoles.InventoryLimited); //5 dispatch manager GenSeedUser(5, AuthorizationRoles.DispatchFull | AuthorizationRoles.InventoryLimited); //5 Inventory manager GenSeedUser(5, AuthorizationRoles.InventoryFull | AuthorizationRoles.DispatchLimited); //10 Inventory manager assistants GenSeedUser(5, AuthorizationRoles.InventoryLimited); //5 accountant / bookkeeper GenSeedUser(5, AuthorizationRoles.AccountingFull | AuthorizationRoles.BizAdminLimited); //100 full on client users GenSeedUser(100, AuthorizationRoles.ClientFull); //100 limited client users GenSeedUser(100, AuthorizationRoles.ClientLimited); //20000 widgets GenSeedWidget(20000); break; } log.LogInformation("Seeding completed successfully"); } catch { throw; } finally { log.LogInformation($"Seeder: setting server state back to {wasServerState.ToString()}"); apiServerState.SetState(wasServerState, wasReason); } } ////////////////////////////////////////////////////// //Seed test data for integration tests // public static void SeedKnownUsers() { //TEST USERS //one of each role type GenSeedUser(1, AuthorizationRoles.BizAdminLimited, "BizAdminLimited", "BizAdminLimited"); GenSeedUser(1, AuthorizationRoles.BizAdminFull, "BizAdminFull", "BizAdminFull"); GenSeedUser(1, AuthorizationRoles.DispatchLimited, "DispatchLimited", "DispatchLimited"); GenSeedUser(1, AuthorizationRoles.DispatchFull, "DispatchFull", "DispatchFull"); GenSeedUser(1, AuthorizationRoles.InventoryLimited, "InventoryLimited", "InventoryLimited"); GenSeedUser(1, AuthorizationRoles.InventoryFull, "InventoryFull", "InventoryFull"); GenSeedUser(1, AuthorizationRoles.AccountingFull, "Accounting", "Accounting"); GenSeedUser(1, AuthorizationRoles.TechLimited, "TechLimited", "TechLimited"); GenSeedUser(1, AuthorizationRoles.TechFull, "TechFull", "TechFull"); GenSeedUser(1, AuthorizationRoles.SubContractorLimited, "SubContractorLimited", "SubContractorLimited"); GenSeedUser(1, AuthorizationRoles.SubContractorFull, "SubContractorFull", "SubContractorFull"); GenSeedUser(1, AuthorizationRoles.ClientLimited, "ClientLimited", "ClientLimited"); GenSeedUser(1, AuthorizationRoles.ClientFull, "ClientFull", "ClientFull"); GenSeedUser(1, AuthorizationRoles.OpsAdminLimited, "OpsAdminLimited", "OpsAdminLimited"); GenSeedUser(1, AuthorizationRoles.OpsAdminFull, "OpsAdminFull", "OpsAdminFull"); //PRIVACY TEST USER - this is used for a test to see if user info leaks into the logs GenSeedUser(1, AuthorizationRoles.OpsAdminLimited, "TEST_PRIVACY_USER_ACCOUNT", "TEST_PRIVACY_USER_ACCOUNT"); } ////////////////////////////////////////////////////// //Seed user - default login / pw is first name // public static void GenSeedUser(int count, AuthorizationRoles roles, string login = null, string password = null) { AyContext ct = ServiceProviderProvider.DBContext; for (int x = 0; x < count; x++) { User u = new User(); var p = new Bogus.Person(); u.Name = p.FullName; u.Salt = Hasher.GenerateSalt(); if (login != null) { u.Login = login; u.Name += " - " + login; } else u.Login = p.FirstName; if (password != null) u.Password = Hasher.hash(u.Salt, password); else u.Password = Hasher.hash(u.Salt, u.Login); u.Roles = roles; u.LocaleId = ServerBootConfig.AYANOVA_DEFAULT_LANGUAGE_ID; ct.User.Add(u); } //save to get id values ct.SaveChanges(); //Now that we have the ID values bulk add the event log entries //To save a db call iterate the local collection in the context, but... //can't modify the context in the foreach, even if it's another collection entirely, so need to save the id's in a temporary list List ItemsAdded = new List(); foreach (User o in ct.User.Local) { ItemsAdded.Add(o.Id); } //Now we have all the id's can actually add them to the context foreach (long l in ItemsAdded) { EventLogProcessor.AddEntry(new Event(1, l, AyaType.User, AyaEvent.Created), ct); } //Now save the Event Log entries ct.SaveChanges(); } ////////////////////////////////////////////////////// //Seed widget for testing // public static void GenSeedWidget(int count) { //get a context just for this op to save memory on changetracking AyContext ct = ServiceProviderProvider.DBContext; var f = new Bogus.Faker(); for (int x = 0; x < count; x++) { Widget o = new Widget(); o.Name = f.Commerce.ProductName(); o.Active = f.Random.Bool(); o.StartDate = f.Date.Between(DateTime.Now, DateTime.Now.AddMinutes(60)); o.EndDate = f.Date.Between(DateTime.Now.AddMinutes(90), DateTime.Now.AddHours(5)); o.DollarAmount = Convert.ToDecimal(f.Commerce.Price()); o.OwnerId = 1; //this is nonsense but just to test an enum o.Roles = AuthorizationRoles.DispatchLimited | AuthorizationRoles.InventoryLimited | AuthorizationRoles.OpsAdminLimited; ct.Widget.Add(o); } //Save the changes to get the ID values ct.SaveChanges(); //Now that we have the ID values bulk add the event log entries //To save a db call iterate the local collection in the context, but... //can't modify the context in the foreach, even if it's another collection entirely, so need to save the id's in a temporary list List WidgetsAdded = new List(); foreach (Widget w in ct.Widget.Local) { WidgetsAdded.Add(w.Id); } //Now we have all the id's can actually add them to the context foreach (long l in WidgetsAdded) { EventLogProcessor.AddEntry(new Event(1, l, AyaType.Widget, AyaEvent.Created), ct); } //Now save the Event Log entries ct.SaveChanges(); } }//eoc }//eons