Ejemplo n.º 1
0
        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);
            }
        }
Ejemplo n.º 2
0
        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);
            }
        }
Ejemplo n.º 3
0
        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);
        }