/// <summary>
        /// Register DbContexts for IdentityServer ConfigurationStore and PersistedGrants, Identity and Logging
        /// Configure the connection strings in AppSettings.json
        /// </summary>
        /// <typeparam name="TConfigurationDbContext"></typeparam>
        /// <typeparam name="TPersistedGrantDbContext"></typeparam>
        /// <typeparam name="TLogDbContext"></typeparam>
        /// <typeparam name="TIdentityDbContext"></typeparam>
        /// <typeparam name="TAuditLoggingDbContext"></typeparam>
        /// <typeparam name="TDataProtectionDbContext"></typeparam>
        /// <typeparam name="TAuditLog"></typeparam>
        /// <param name="services"></param>
        /// <param name="connectionStrings"></param>
        /// <param name="databaseProvider"></param>
        /// <param name="databaseMigrations"></param>
        public static void RegisterDbContexts <TIdentityDbContext, TConfigurationDbContext, TPersistedGrantDbContext,
                                               TLogDbContext, TAuditLoggingDbContext, TDataProtectionDbContext, TAuditLog>(
            this IServiceCollection services,
            ConnectionStringsConfiguration connectionStrings,
            DatabaseProviderConfiguration databaseProvider,
            DatabaseMigrationsConfiguration databaseMigrations)
            where TIdentityDbContext : DbContext
            where TPersistedGrantDbContext : DbContext, IAdminPersistedGrantDbContext
            where TConfigurationDbContext : DbContext, IAdminConfigurationDbContext
            where TLogDbContext : DbContext, IAdminLogDbContext
            where TAuditLoggingDbContext : DbContext, IAuditLoggingDbContext <TAuditLog>
            where TDataProtectionDbContext : DbContext, IDataProtectionKeyContext
            where TAuditLog : AuditLog
        {
            switch (databaseProvider.ProviderType)
            {
            case DatabaseProviderType.SqlServer:
                services.RegisterSqlServerDbContexts <TIdentityDbContext, TConfigurationDbContext, TPersistedGrantDbContext, TLogDbContext, TAuditLoggingDbContext, TDataProtectionDbContext, TAuditLog>(connectionStrings, databaseMigrations);
                break;

            case DatabaseProviderType.PostgreSQL:
                services.RegisterNpgSqlDbContexts <TIdentityDbContext, TConfigurationDbContext, TPersistedGrantDbContext, TLogDbContext, TAuditLoggingDbContext, TDataProtectionDbContext, TAuditLog>(connectionStrings, databaseMigrations);
                break;

            case DatabaseProviderType.MySql:
                services.RegisterMySqlDbContexts <TIdentityDbContext, TConfigurationDbContext, TPersistedGrantDbContext, TLogDbContext, TAuditLoggingDbContext, TDataProtectionDbContext, TAuditLog>(connectionStrings, databaseMigrations);
                break;

            default:
                throw new ArgumentOutOfRangeException(nameof(databaseProvider.ProviderType), $@"The value needs to be one of {string.Join(", ", Enum.GetNames(typeof(DatabaseProviderType)))}.");
            }
        }
Exemple #2
0
        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
            services.AddOptions();
            services.AddSingleton <IHttpContextAccessor, HttpContextAccessor>();

            services.Configure <DataProviderConfiguration>(options => Configuration.GetSection("DataProviders").Bind(options));
            var dataProviders = Configuration.GetSection("DataProviders").Get <DataProviderConfiguration>();
            DatabaseProviderConfiguration apiDataProvider = dataProviders.Databases.SingleOrDefault(db => string.Equals(db.ProviderName, "API"));

            services.RegisterPerpetuumApiTypes(Configuration);
            services.AddSingleton <ICache <Client>, InMemoryCache <Client> >();
            services.AddSingleton <ICache <Resource>, InMemoryCache <Resource> >();

            var identityConnectionString = Configuration.GetConnectionString(apiDataProvider.ConnectionId);
            var migrationsAssembly       = typeof(IdentityStartup).GetTypeInfo().Assembly.GetName().Name; // The migration assembly is where the database update instructions exist

            services.AddIdentityServer()
            .AddConfigurationStore(options =>
            {
                options.ConfigureDbContext = b =>
                                             b.UseSqlServer(identityConnectionString, sql => sql.MigrationsAssembly(migrationsAssembly));
            })
            .AddOperationalStore(options =>
            {
                options.ConfigureDbContext = b =>
                                             b.UseSqlServer(identityConnectionString, sql => sql.MigrationsAssembly(migrationsAssembly));
                options.EnableTokenCleanup = true;
            })
            .AddInMemoryCaching()
            .AddClientStoreCache <IdentityServer4.EntityFramework.Stores.ClientStore>()
            .AddResourceStoreCache <IdentityServer4.EntityFramework.Stores.ResourceStore>()
            .AddConfigurationStoreCache()
#if DEBUG
            .AddDeveloperSigningCredential();
 public static string GetMigrationAssemblyByProvider(DatabaseProviderConfiguration databaseProvider)
 {
     return(databaseProvider.ProviderType switch
     {
         DatabaseProviderType.SqlServer => typeof(SqlMigrationAssembly).GetTypeInfo().Assembly.GetName().Name,
         DatabaseProviderType.PostgreSQL => typeof(PostgreSQLMigrationAssembly).GetTypeInfo()
         .Assembly.GetName()
         .Name,
         DatabaseProviderType.MySql => typeof(MySqlMigrationAssembly).GetTypeInfo().Assembly.GetName().Name,
         _ => throw new ArgumentOutOfRangeException()
     });
Exemple #4
0
        public IHttpActionResult Put(
            [FromUri] int id,
            [FromBody] CreateTenantModel command)
        {
            if (command == null || !ModelState.IsValid)
            {
                return(this.Error().InvalidParameters("Tenant body parameters missing"));
            }
            if (command.TenantDbProvider == null || command.TenantDbConfiguration == null)
            {
                return(this.Error().InvalidParameters("Tenant Db information missing"));
            }

            var tenant = _tenantsRepository.GetById(id);

            tenant.Change(command.Name,
                          command.DefaultTheme,
                          DatabaseProviderConfiguration.Create(command.TenantDbProvider, command.TenantDbConfiguration));
            _tenantsRepository.Update(tenant);
            _tenantsRepository.SaveChanges();
            var tenantModel = _mapper.Map <TenantModel>(tenant);

            return(Ok(tenantModel));
        }
Exemple #5
0
        protected override void AdjustModel(Tenant model)
        {
            var dbProviderConfig = DatabaseProviderConfiguration.CreateFromConfiguration(model.TenantDb.Provider, model.TenantDb.ConfigurationJson);

            model.Change(model.Name, model.DefaultTheme, dbProviderConfig);
        }
        public static void AddIdSHealthChecks <TConfigurationDbContext, TPersistedGrantDbContext, TIdentityDbContext,
                                               TLogDbContext, TAuditLoggingDbContext, TDataProtectionDbContext, TAuditLog>
            (this IHealthChecksBuilder healthChecksBuilder, AdminConfiguration adminConfiguration,
            ConnectionStringsConfiguration connectionStringsConfiguration, DatabaseProviderConfiguration databaseProviderConfiguration)
            where TConfigurationDbContext : DbContext, IAdminConfigurationDbContext
            where TPersistedGrantDbContext : DbContext, IAdminPersistedGrantDbContext
            where TIdentityDbContext : DbContext
            where TLogDbContext : DbContext, IAdminLogDbContext
            where TAuditLoggingDbContext : DbContext, IAuditLoggingDbContext <TAuditLog>
            where TDataProtectionDbContext : DbContext, IDataProtectionKeyContext
            where TAuditLog : AuditLog
        {
            var configurationDbConnectionString   = connectionStringsConfiguration.ConfigurationDbConnection;
            var persistedGrantsDbConnectionString = connectionStringsConfiguration.PersistedGrantDbConnection;
            var identityDbConnectionString        = connectionStringsConfiguration.IdentityDbConnection;
            var logDbConnectionString             = connectionStringsConfiguration.AdminLogDbConnection;
            var auditLogDbConnectionString        = connectionStringsConfiguration.AdminAuditLogDbConnection;
            var dataProtectionDbConnectionString  = connectionStringsConfiguration.DataProtectionDbConnection;

            var identityServerUri = adminConfiguration.IdentityServerBaseUrl;

            healthChecksBuilder = healthChecksBuilder
                                  .AddDbContextCheck <TConfigurationDbContext>("ConfigurationDbContext")
                                  .AddDbContextCheck <TPersistedGrantDbContext>("PersistedGrantsDbContext")
                                  .AddDbContextCheck <TIdentityDbContext>("IdentityDbContext")
                                  .AddDbContextCheck <TLogDbContext>("LogDbContext")
                                  .AddDbContextCheck <TAuditLoggingDbContext>("AuditLogDbContext")
                                  .AddDbContextCheck <TDataProtectionDbContext>("DataProtectionDbContext")

                                  .AddIdentityServer(new Uri(identityServerUri), "Identity Server");

            var serviceProvider = healthChecksBuilder.Services.BuildServiceProvider();
            var scopeFactory    = serviceProvider.GetRequiredService <IServiceScopeFactory>();

            using (var scope = scopeFactory.CreateScope())
            {
                var configurationTableName  = DbContextHelpers.GetEntityTable <TConfigurationDbContext>(scope.ServiceProvider);
                var persistedGrantTableName = DbContextHelpers.GetEntityTable <TPersistedGrantDbContext>(scope.ServiceProvider);
                var identityTableName       = DbContextHelpers.GetEntityTable <TIdentityDbContext>(scope.ServiceProvider);
                var logTableName            = DbContextHelpers.GetEntityTable <TLogDbContext>(scope.ServiceProvider);
                var auditLogTableName       = DbContextHelpers.GetEntityTable <TAuditLoggingDbContext>(scope.ServiceProvider);
                var dataProtectionTableName = DbContextHelpers.GetEntityTable <TDataProtectionDbContext>(scope.ServiceProvider);

                switch (databaseProviderConfiguration.ProviderType)
                {
                case DatabaseProviderType.SqlServer:
                    healthChecksBuilder
                    .AddSqlServer(configurationDbConnectionString, name: "ConfigurationDb",
                                  healthQuery: $"SELECT TOP 1 * FROM dbo.[{configurationTableName}]")
                    .AddSqlServer(persistedGrantsDbConnectionString, name: "PersistentGrantsDb",
                                  healthQuery: $"SELECT TOP 1 * FROM dbo.[{persistedGrantTableName}]")
                    .AddSqlServer(identityDbConnectionString, name: "IdentityDb",
                                  healthQuery: $"SELECT TOP 1 * FROM dbo.[{identityTableName}]")
                    .AddSqlServer(logDbConnectionString, name: "LogDb",
                                  healthQuery: $"SELECT TOP 1 * FROM dbo.[{logTableName}]")
                    .AddSqlServer(auditLogDbConnectionString, name: "AuditLogDb",
                                  healthQuery: $"SELECT TOP 1 * FROM dbo.[{auditLogTableName}]")
                    .AddSqlServer(dataProtectionDbConnectionString, name: "DataProtectionDb",
                                  healthQuery: $"SELECT TOP 1 * FROM dbo.[{dataProtectionTableName}]");
                    break;

                case DatabaseProviderType.PostgreSQL:
                    healthChecksBuilder
                    .AddNpgSql(configurationDbConnectionString, name: "ConfigurationDb",
                               healthQuery: $"SELECT * FROM \"{configurationTableName}\" LIMIT 1")
                    .AddNpgSql(persistedGrantsDbConnectionString, name: "PersistentGrantsDb",
                               healthQuery: $"SELECT * FROM \"{persistedGrantTableName}\" LIMIT 1")
                    .AddNpgSql(identityDbConnectionString, name: "IdentityDb",
                               healthQuery: $"SELECT * FROM \"{identityTableName}\" LIMIT 1")
                    .AddNpgSql(logDbConnectionString, name: "LogDb",
                               healthQuery: $"SELECT * FROM \"{logTableName}\" LIMIT 1")
                    .AddNpgSql(auditLogDbConnectionString, name: "AuditLogDb",
                               healthQuery: $"SELECT * FROM \"{auditLogTableName}\"  LIMIT 1")
                    .AddNpgSql(dataProtectionDbConnectionString, name: "DataProtectionDb",
                               healthQuery: $"SELECT * FROM \"{dataProtectionTableName}\"  LIMIT 1");
                    break;

                case DatabaseProviderType.MySql:
                    healthChecksBuilder
                    .AddMySql(configurationDbConnectionString, name: "ConfigurationDb")
                    .AddMySql(persistedGrantsDbConnectionString, name: "PersistentGrantsDb")
                    .AddMySql(identityDbConnectionString, name: "IdentityDb")
                    .AddMySql(logDbConnectionString, name: "LogDb")
                    .AddMySql(auditLogDbConnectionString, name: "AuditLogDb")
                    .AddMySql(dataProtectionDbConnectionString, name: "DataProtectionDb");
                    break;

                default:
                    throw new NotImplementedException($"Health checks not defined for database provider {databaseProviderConfiguration.ProviderType}");
                }
            }
        }
Exemple #7
0
 private DatabaseProviderConfiguration CreateDBProviderConfiguration(CreateTenantModel command)
 => String.IsNullOrEmpty(command.TenantDbConnectionString)
             ? DatabaseProviderConfiguration.CreateFromConfiguration(command.TenantDbProvider, command.TenantDbConfiguration)
             : DatabaseProviderConfiguration.Create(command.TenantDbProvider, command.TenantDbConnectionString);
Exemple #8
0
 public TenantTestModel()
 {
     TenantDb = DatabaseProviderConfiguration.CreateFromConfiguration(DbProviderType.SqlServer, "{\"connectionString\": \"Database=Test\"}");
 }