public static IHost InitializeDatabase( this IHost host ) { using (var scope = host.Services.CreateScope()) { var services = scope.ServiceProvider; IConfiguration config = services.GetRequiredService <IConfiguration>(); IWebHostEnvironment env = services.GetService <IWebHostEnvironment>(); DatabaseOptions options = config.GetSection("Database").Get <DatabaseOptions>() ?? new DatabaseOptions(); var dbContext = services.GetService <TopoMojoDbContext>(); if (!dbContext.Database.IsInMemory()) { dbContext.Database.Migrate(); } string seedFile = Path.Combine(env.ContentRootPath, options.SeedFile); if (File.Exists(seedFile)) { DbSeedModel seedData = JsonSerializer.Deserialize <DbSeedModel>( File.ReadAllText(seedFile) ); foreach (var u in seedData.Users) { if (!dbContext.Users.Any(p => p.GlobalId == u.GlobalId)) { dbContext.Users.Add(new TopoMojo.Data.User { Name = u.Name, GlobalId = u.GlobalId, WhenCreated = DateTime.UtcNow, Role = TopoMojo.Models.UserRole.Administrator }); } } dbContext.SaveChanges(); } return(host); } }
public static IHost InitializeDatabase( this IHost host ) { using (var scope = host.Services.CreateScope()) { var services = scope.ServiceProvider; IConfiguration config = services.GetRequiredService <IConfiguration>(); IWebHostEnvironment env = services.GetService <IWebHostEnvironment>(); var db = services.GetService <GameboardDbContext>(); if (!db.Database.IsInMemory()) { db.Database.Migrate(); } string seedFile = Path.Combine( env.ContentRootPath, config.GetValue <string>("Database:SeedFile", "seed-data.yaml") ); var YamlDeserializer = new DeserializerBuilder() .WithNamingConvention(CamelCaseNamingConvention.Instance) .IgnoreUnmatchedProperties() .Build(); if (File.Exists(seedFile)) { DbSeedModel seedModel = Path.GetExtension(seedFile).ToLower() == "json" ? JsonSerializer.Deserialize <DbSeedModel>(File.ReadAllText(seedFile)) : YamlDeserializer.Deserialize <DbSeedModel>(File.ReadAllText(seedFile)); foreach (var user in seedModel.Users) { if (db.Users.Any(u => u.Id == user.Id)) { continue; } db.Users.Add(user); } db.SaveChanges(); foreach (var game in seedModel.Games) { if (db.Games.Any(u => u.Id == game.Id)) { continue; } db.Games.Add(game); } db.SaveChanges(); foreach (var spec in seedModel.ChallengeSpecs) { if (db.ChallengeSpecs.Any(u => u.Id == spec.Id)) { continue; } db.ChallengeSpecs.Add(spec); } db.SaveChanges(); foreach (var player in seedModel.Players) { if (db.Players.Any(u => u.Id == player.Id)) { continue; } db.Players.Add(player); } db.SaveChanges(); foreach (var challenge in seedModel.Challenges) { if (db.Challenges.Any(u => u.Id == challenge.Id)) { continue; } db.Challenges.Add(challenge); } db.SaveChanges(); foreach (var sponsor in seedModel.Sponsors) { if (db.Sponsors.Any(u => u.Id == sponsor.Id)) { continue; } db.Sponsors.Add(sponsor); } db.SaveChanges(); foreach (var feedback in seedModel.Feedback) { if (db.Feedback.Any(u => u.Id == feedback.Id)) { continue; } db.Feedback.Add(feedback); } db.SaveChanges(); } return(host); } }
public static IHost InitializeDatabase(this IHost appHost) { using (var scope = appHost.Services.CreateScope()) { var services = scope.ServiceProvider; var loggerFactory = services.GetService <Microsoft.Extensions.Logging.ILoggerFactory>(); ILogger logger = loggerFactory.CreateLogger("DatabaseInitialization"); IConfiguration config = services.GetRequiredService <IConfiguration>(); IHostEnvironment env = services.GetService <IHostEnvironment>(); AccountDbContext accountDb = services.GetRequiredService <AccountDbContext>(); ClientDbContext clientDb = services.GetRequiredService <ClientDbContext>(); AccountOptions accountOptions = services.GetService <IOptionsSnapshot <AccountOptions> >().Value; IAccountService accountSvc = services.GetRequiredService <IAccountService>(); var secretOptions = config.GetSection("SeedData").Get <DbSeedKVP[]>() ?? new DbSeedKVP[] { }; if (!accountDb.Database.IsInMemory()) { accountDb.Database.Migrate(); } if (!clientDb.Database.IsInMemory()) { clientDb.Database.Migrate(); } // manual migration foreach (var client in clientDb.Clients .Include(c => c.Resources).ThenInclude(r => r.Resource) .ToArray()) { if (string.IsNullOrEmpty(client.Grants)) { client.Grants = string.Join(" ", client.Resources .Where(r => r.Resource.Type == ResourceType.Grant) .Select(r => r.Resource.Name) .ToArray()); } if (string.IsNullOrEmpty(client.Scopes)) { client.Scopes = string.Join(" ", client.Resources .Where(r => r.Resource.Type != ResourceType.Grant) .Select(r => r.Resource.Name) .ToArray()); } } clientDb.SaveChanges(); var seedGrants = new IdentityResource[] { new IdentityResource { Name = "client_credentials", DisplayName = "Client Credentials", Enabled = true }, new IdentityResource { Name = "authorization_code", DisplayName = "Code Grant", Enabled = true }, new IdentityResource { Name = "hybrid", DisplayName = "Hybrid Grant", Enabled = true }, new IdentityResource { Name = "implicit", DisplayName = "Implicit Grant", Enabled = true }, new IdentityResource { Name = "password", DisplayName = "Resource Owner Grant", Enabled = true } }.ToList(); var seedScopes = new IdentityResource[] { new IdentityResources.OpenId() { DisplayName = "User Id" }, new IdentityResources.Email() { DisplayName = "Email Address" }, new IdentityResource { Name = "profile", DisplayName = "Profile Info", Enabled = true, UserClaims = new string[] { "name", "family_name", "given_name", "username", "picture", "updated_at", "affiliate" } }, new IdentityResource { Name = "organization", DisplayName = "Organization", Enabled = true, UserClaims = new string[] { "org", "orgunit", "picture_o", "picture_ou" } }, new IdentityResource { Name = "role", DisplayName = "Role", Enabled = true, UserClaims = new string[] { "role" } } }.ToList(); var seedApi = new DbSeedApi[] { new DbSeedApi { Name = "identity-api" }, new DbSeedApi { Name = "identity-api-privileged" }, }.ToList(); var seedClients = new List <DbSeedClient>(); //[] { // new DbSeedClient { // Name = "IdentityApiSwaggerClient", // DisplayName = "Identity OpenApi", // GlobalId = Guid.NewGuid().ToString(), // Flags = ClientFlag.AllowRememberConsent | ClientFlag.EnableLocalLogin, // SeedGrant = "implicit", // SeedScopes = "openid identity-api", // Enabled = true, // Urls = new ClientUri[] { // new ClientUri { Type = ClientUriType.RedirectUri, Value = "http://localhost:5000/api/oauth2-redirect.html"} // } // } // }.ToList(); var seedUsers = new List <DbSeedUser>(); if ( !string.IsNullOrEmpty(accountOptions.OverrideCode) && !accountDb.OverrideCodes .Where(o => o.Code == accountOptions.OverrideCode) .Any() ) { accountDb.OverrideCodes.Add( new Identity.Accounts.Data.OverrideCode { Code = accountOptions.OverrideCode, Description = "Applied at Startup", WhenCreated = DateTime.UtcNow } ); accountDb.SaveChanges(); } if (!string.IsNullOrEmpty(accountOptions.AdminEmail)) { seedUsers.Add(new DbSeedUser { Username = accountOptions.AdminEmail, GlobalId = accountOptions.AdminGuid, Password = accountOptions.AdminPassword }); } string seedFile = Path.Combine( env.ContentRootPath, config.GetValue <string>("Database:SeedFile", "seed-data.json") ); if (File.Exists(seedFile)) { DbSeedModel seedData = JsonConvert.DeserializeObject <DbSeedModel>(File.ReadAllText(seedFile)); seedGrants.AddRange(seedData.GrantResources); seedScopes.AddRange(seedData.IdentityResources); seedApi.AddRange(seedData.ApiResources); seedClients.AddRange(seedData.Clients); seedUsers.AddRange(seedData.Users); } if (seedUsers.Count() > 0) { foreach (DbSeedUser seedUser in seedUsers) { try { // override seed-data with config data for password string secret = secretOptions .Where(i => i.Key == seedUser.Username || i.Key == seedUser.GlobalId) .FirstOrDefault()?.Value ?? seedUser.Password; accountSvc.RegisterUsername( seedUser.Username, seedUser.Password, seedUser.GlobalId ).Wait(); } catch (Exception ex) { logger.LogError(ex, $"Failed to register {seedUser.Username}"); } } } foreach (var resource in seedGrants) { if (!clientDb.Resources.Any(r => r.Type == ResourceType.Grant && r.Name == resource.Name )) { var entity = new Identity.Clients.Data.Resource { Type = ResourceType.Grant, Name = resource.Name, DisplayName = resource.DisplayName, Description = resource.Description, Scopes = $"{resource.Name} client_credentials" }; clientDb.Resources.Add(entity); } } foreach (var resource in seedApi) { if (!clientDb.Resources.Any(r => r.Type == ResourceType.Api && r.Name == resource.Name )) { var entity = new Identity.Clients.Data.Resource { Type = ResourceType.Api, Name = resource.Name, DisplayName = resource.DisplayName ?? resource.Name, Description = resource.Description, Enabled = true, }; clientDb.Resources.Add(entity); if (String.IsNullOrWhiteSpace(resource.Scopes)) { resource.Scopes = resource.Name; } entity.Scopes = String.Join(' ', resource.Scopes); if (!string.IsNullOrEmpty(resource.SeedSecret)) { entity.Secrets.Add( new ApiSecret { Type = "SharedSecret", Value = resource.SeedSecret.Sha256(), Description = "Added by Admin at " + DateTime.UtcNow.ToString("u") } ); } clientDb.SaveChanges(); } } foreach (var resource in seedScopes) { if (!clientDb.Resources.Any(r => r.Type == ResourceType.Identity && r.Name == resource.Name )) { var entity = new Identity.Clients.Data.Resource { Type = ResourceType.Identity, Name = resource.Name, DisplayName = resource.DisplayName ?? resource.Name, Description = resource.Description, Enabled = resource.Enabled, Emphasize = resource.Emphasize, Required = resource.Required, Default = "openid profile organization".Contains(resource.Name), UserClaims = String.Join(' ', resource.UserClaims), Scopes = resource.Name }; clientDb.Resources.Add(entity); } } clientDb.SaveChanges(); foreach (var client in seedClients) { if (!clientDb.Clients.Any(c => c.Name == client.Name)) { if (Enum.TryParse <ClientFlag>(client.SeedFlags, out ClientFlag flags)) { client.Flags = flags; } client.GlobalId = Guid.NewGuid().ToString("N"); client.EnlistCode = Guid.NewGuid().ToString("N"); //combine any secrets from config and seed-data (as secrets may be provided separately in the config) var clientSecrets = secretOptions.Where(i => i.Key == client.Name) .Select(s => s.Value) .Union(new string[] { client.SeedSecret }) .ToArray(); foreach (var secret in clientSecrets) { if (!String.IsNullOrEmpty(secret)) { client.Secrets.Add( new ClientSecret { Type = "SharedSecret", Value = secret.Sha256(), Description = "Added by Admin at " + DateTime.UtcNow.ToString("u") } ); } } foreach (var item in client.SeedHandlers) { string[] src = item.Key.Split("::"); if (src.Length > 1) { var srcClient = clientDb.Clients .Include(c => c.Events) .Where(c => c.Name == src[0]) .FirstOrDefault(); if (srcClient != null) { var srcEvent = srcClient.Events .Where(e => e.Type == src[1]) .FirstOrDefault(); if (srcEvent != null) { client.EventHandlers.Add( new ClientEventHandler { ClientEventId = srcEvent.Id, Uri = item.Value, Enabled = true } ); } } } } client.Grants = client.SeedGrant; client.Scopes = client.SeedScopes; //convert derived entity to base entity Identity.Clients.Data.Client entity = JsonConvert.DeserializeObject <Identity.Clients.Data.Client>(JsonConvert.SerializeObject(client)); clientDb.Clients.Add(entity); clientDb.SaveChanges(); } } // run any method migrations accountSvc.FixAccounts().Wait(); } return(appHost); }