Skip to content

Commit

Permalink
Extract UI project for use in existing setups (v1) (#780)
Browse files Browse the repository at this point in the history
* Moved UI folders and files to new Admin.UI project

* Fixed application version page can no longer refer to Startup type for detecting assembly version

* Fixed build of Admin project that now depends on UI project

* Extracted UI-specific startup helpers and classes into UI project

* Removed bogus project dependency

* Removed now unused namespace imports in map app startup helpers

* Moved styles and scripts and more helpers to UI project

* Moved back root configuration to Admin app because database migration and seeding is probably out of scope of UI

* Moved startup service configuration to UI project through dependency injection helpers

* Moved back one constant unrelated to UI into main project

* Refactored UI project namespaces for consistency

* Fixed some build issues

* Stub for app builder extensions for UI project

* Fixed test project build

* Moved security headers feature to UI project

* Moved startup app building to UI project

* Fixed authorization middleware setup

* Fixed UI view build

* Fixed views cannot be resolved

* Fixed static assets not accessible from root URL (e.g. ~/)

* Cleaned up startup

* Added convenience DI extensions for setting up UI

* Cleaned up startup test

* Moved migration helpers to UI project

* Support for custom migration assemblies

* Moved migration helpers and config down to EntityFramework.Shared

* Fixed build and tests

* Fixed DI UI helper not using custom entity types completely

* Moved UI config json files to UI project

* Disabled unused code in startup

* Minor code style

* Fixed view localization of UI failing when used in custom web app project

* Refactored middleware configuration to simplify usage of Use* methods in Startup

* Added configuration of health checks middleware

* Options to further configure the auth pipelines, and better separation of endpoint routing

* Ported UI to area

* Fixed test build

* Fixed seeding not working due to missing configuration bind

(backported from 93d5e3a and 01646fd)
  • Loading branch information
Brice-xCIT authored Feb 13, 2021
1 parent 4993559 commit 91a8ff9
Show file tree
Hide file tree
Showing 1,048 changed files with 1,250 additions and 704 deletions.
4 changes: 2 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -275,9 +275,9 @@ __pycache__/
/src/Skoruba.IdentityServer4.Admin/Data/Migrations/

# Don't ignore these log folders
!/src/Skoruba.IdentityServer4.Admin/Resources/Views/Log/
!/src/Skoruba.IdentityServer4.Admin.UI/Resources/Views/Log/
!/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Dtos/Log/
!/src/Skoruba.IdentityServer4.Admin/Views/Log/
!**/Views/Log/
!/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/Log/
/src/Skoruba.IdentityServer4.Admin.Api/appsettings.Production.json

Expand Down
7 changes: 7 additions & 0 deletions Skoruba.IdentityServer4.Admin.sln
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Skoruba.IdentityServer4.Adm
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Skoruba.IdentityServer4.Shared", "src\Skoruba.IdentityServer4.Shared\Skoruba.IdentityServer4.Shared.csproj", "{61B285F0-EE06-4AEE-AAF3-71492CBD11C5}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Skoruba.IdentityServer4.Admin.UI", "src\Skoruba.IdentityServer4.Admin.UI\Skoruba.IdentityServer4.Admin.UI.csproj", "{6DD24C2C-0FB5-4C37-8B42-5DACA0FDE4EC}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand Down Expand Up @@ -133,6 +135,10 @@ Global
{61B285F0-EE06-4AEE-AAF3-71492CBD11C5}.Debug|Any CPU.Build.0 = Debug|Any CPU
{61B285F0-EE06-4AEE-AAF3-71492CBD11C5}.Release|Any CPU.ActiveCfg = Release|Any CPU
{61B285F0-EE06-4AEE-AAF3-71492CBD11C5}.Release|Any CPU.Build.0 = Release|Any CPU
{6DD24C2C-0FB5-4C37-8B42-5DACA0FDE4EC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{6DD24C2C-0FB5-4C37-8B42-5DACA0FDE4EC}.Debug|Any CPU.Build.0 = Debug|Any CPU
{6DD24C2C-0FB5-4C37-8B42-5DACA0FDE4EC}.Release|Any CPU.ActiveCfg = Release|Any CPU
{6DD24C2C-0FB5-4C37-8B42-5DACA0FDE4EC}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand All @@ -156,6 +162,7 @@ Global
{0A8A0DB7-0509-4DFB-9201-74398511B481} = {2A514C8F-6A53-41CA-AB41-B644E7BC92A7}
{4D123ACB-ACBD-4E40-AE6B-1B0F79D703B0} = {0BC0CC4E-A0F1-45E8-B41A-AE0FA76BF3E5}
{61B285F0-EE06-4AEE-AAF3-71492CBD11C5} = {EE588CE5-51D0-4E98-A2B3-40EC8E655931}
{6DD24C2C-0FB5-4C37-8B42-5DACA0FDE4EC} = {588205D4-3A30-4DA4-849D-C7422C396DAA}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {B3166EDE-037B-4C68-BEBA-5DE9C5E3DB82}
Expand Down
15 changes: 5 additions & 10 deletions src/Skoruba.IdentityServer4.Admin.Api/Helpers/StartupHelpers.cs
Original file line number Diff line number Diff line change
Expand Up @@ -145,24 +145,19 @@ public static IServiceCollection AddAdminApiCors(this IServiceCollection service
where TDataProtectionDbContext : DbContext, IDataProtectionKeyContext
{
var databaseProvider = configuration.GetSection(nameof(DatabaseProviderConfiguration)).Get<DatabaseProviderConfiguration>();

var identityConnectionString = configuration.GetConnectionString(ConfigurationConsts.IdentityDbConnectionStringKey);
var configurationConnectionString = configuration.GetConnectionString(ConfigurationConsts.ConfigurationDbConnectionStringKey);
var persistedGrantsConnectionString = configuration.GetConnectionString(ConfigurationConsts.PersistedGrantDbConnectionStringKey);
var errorLoggingConnectionString = configuration.GetConnectionString(ConfigurationConsts.AdminLogDbConnectionStringKey);
var auditLoggingConnectionString = configuration.GetConnectionString(ConfigurationConsts.AdminAuditLogDbConnectionStringKey);
var dataProtectionConnectionString = configuration.GetConnectionString(ConfigurationConsts.DataProtectionDbConnectionStringKey);
var databaseMigrations = configuration.GetSection(nameof(DatabaseMigrationsConfiguration)).Get<DatabaseMigrationsConfiguration>() ?? new DatabaseMigrationsConfiguration();
var connectionStrings = configuration.GetSection("ConnectionStrings").Get<ConnectionStringsConfiguration>();

switch (databaseProvider.ProviderType)
{
case DatabaseProviderType.SqlServer:
services.RegisterSqlServerDbContexts<TIdentityDbContext, TConfigurationDbContext, TPersistedGrantDbContext, TLogDbContext, TAuditLoggingDbContext, TDataProtectionDbContext>(identityConnectionString, configurationConnectionString, persistedGrantsConnectionString, errorLoggingConnectionString, auditLoggingConnectionString, dataProtectionConnectionString);
services.RegisterSqlServerDbContexts<TIdentityDbContext, TConfigurationDbContext, TPersistedGrantDbContext, TLogDbContext, TAuditLoggingDbContext, TDataProtectionDbContext>(connectionStrings, databaseMigrations);
break;
case DatabaseProviderType.PostgreSQL:
services.RegisterNpgSqlDbContexts<TIdentityDbContext, TConfigurationDbContext, TPersistedGrantDbContext, TLogDbContext, TAuditLoggingDbContext, TDataProtectionDbContext>(identityConnectionString, configurationConnectionString, persistedGrantsConnectionString, errorLoggingConnectionString, auditLoggingConnectionString, dataProtectionConnectionString);
services.RegisterNpgSqlDbContexts<TIdentityDbContext, TConfigurationDbContext, TPersistedGrantDbContext, TLogDbContext, TAuditLoggingDbContext, TDataProtectionDbContext>(connectionStrings, databaseMigrations);
break;
case DatabaseProviderType.MySql:
services.RegisterMySqlDbContexts<TIdentityDbContext, TConfigurationDbContext, TPersistedGrantDbContext, TLogDbContext, TAuditLoggingDbContext, TDataProtectionDbContext>(identityConnectionString, configurationConnectionString, persistedGrantsConnectionString, errorLoggingConnectionString, auditLoggingConnectionString, dataProtectionConnectionString);
services.RegisterMySqlDbContexts<TIdentityDbContext, TConfigurationDbContext, TPersistedGrantDbContext, TLogDbContext, TAuditLoggingDbContext, TDataProtectionDbContext>(connectionStrings, databaseMigrations);
break;
default:
throw new ArgumentOutOfRangeException(nameof(databaseProvider.ProviderType), $@"The value needs to be one of {string.Join(", ", Enum.GetNames(typeof(DatabaseProviderType)))}.");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
using Skoruba.AuditLogging.EntityFramework.DbContexts;
using Skoruba.AuditLogging.EntityFramework.Entities;
using Skoruba.IdentityServer4.Admin.EntityFramework.Interfaces;
using Skoruba.IdentityServer4.Admin.EntityFramework.Shared.Configuration;

namespace Skoruba.IdentityServer4.Admin.EntityFramework.MySql.Extensions
{
Expand All @@ -28,9 +29,8 @@ public static class DatabaseExtensions
/// <param name="auditLoggingConnectionString"></param>
public static void RegisterMySqlDbContexts<TIdentityDbContext, TConfigurationDbContext,
TPersistedGrantDbContext, TLogDbContext, TAuditLoggingDbContext, TDataProtectionDbContext>(this IServiceCollection services,
string identityConnectionString, string configurationConnectionString,
string persistedGrantConnectionString, string errorLoggingConnectionString,
string auditLoggingConnectionString, string dataProtectionConnectionString = null)
ConnectionStringsConfiguration connectionStrings,
DatabaseMigrationsConfiguration databaseMigrations)
where TIdentityDbContext : DbContext
where TPersistedGrantDbContext : DbContext, IAdminPersistedGrantDbContext
where TConfigurationDbContext : DbContext, IAdminConfigurationDbContext
Expand All @@ -42,29 +42,29 @@ public static class DatabaseExtensions

// Config DB for identity
services.AddDbContext<TIdentityDbContext>(options =>
options.UseMySql(identityConnectionString, sql => sql.MigrationsAssembly(migrationsAssembly)));
options.UseMySql(connectionStrings.IdentityDbConnection, sql => sql.MigrationsAssembly(databaseMigrations.IdentityDbMigrationsAssembly ?? migrationsAssembly)));

// Config DB from existing connection
services.AddConfigurationDbContext<TConfigurationDbContext>(options =>
options.ConfigureDbContext = b =>
b.UseMySql(configurationConnectionString, sql => sql.MigrationsAssembly(migrationsAssembly)));
b.UseMySql(connectionStrings.ConfigurationDbConnection, sql => sql.MigrationsAssembly(databaseMigrations.ConfigurationDbMigrationsAssembly ?? migrationsAssembly)));

// Operational DB from existing connection
services.AddOperationalDbContext<TPersistedGrantDbContext>(options => options.ConfigureDbContext = b =>
b.UseMySql(persistedGrantConnectionString, sql => sql.MigrationsAssembly(migrationsAssembly)));
b.UseMySql(connectionStrings.PersistedGrantDbConnection, sql => sql.MigrationsAssembly(databaseMigrations.PersistedGrantDbMigrationsAssembly ?? migrationsAssembly)));

// Log DB from existing connection
services.AddDbContext<TLogDbContext>(options => options.UseMySql(errorLoggingConnectionString,
optionsSql => optionsSql.MigrationsAssembly(migrationsAssembly)));
services.AddDbContext<TLogDbContext>(options => options.UseMySql(connectionStrings.AdminLogDbConnection,
optionsSql => optionsSql.MigrationsAssembly(databaseMigrations.AdminLogDbMigrationsAssembly ?? migrationsAssembly)));

// Audit logging connection
services.AddDbContext<TAuditLoggingDbContext>(options => options.UseMySql(auditLoggingConnectionString,
optionsSql => optionsSql.MigrationsAssembly(migrationsAssembly)));
services.AddDbContext<TAuditLoggingDbContext>(options => options.UseMySql(connectionStrings.AdminAuditLogDbConnection,
optionsSql => optionsSql.MigrationsAssembly(databaseMigrations.AdminAuditLogDbMigrationsAssembly ?? migrationsAssembly)));

// DataProtectionKey DB from existing connection
if(!string.IsNullOrEmpty(dataProtectionConnectionString))
services.AddDbContext<TDataProtectionDbContext>(options => options.UseMySql(dataProtectionConnectionString,
optionsSql => optionsSql.MigrationsAssembly(migrationsAssembly)));
if(!string.IsNullOrEmpty(connectionStrings.DataProtectionDbConnection))
services.AddDbContext<TDataProtectionDbContext>(options => options.UseMySql(connectionStrings.DataProtectionDbConnection,
optionsSql => optionsSql.MigrationsAssembly(databaseMigrations.DataProtectionDbMigrationsAssembly ?? migrationsAssembly)));
}

/// <summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
using Skoruba.AuditLogging.EntityFramework.DbContexts;
using Skoruba.AuditLogging.EntityFramework.Entities;
using Skoruba.IdentityServer4.Admin.EntityFramework.Interfaces;
using Skoruba.IdentityServer4.Admin.EntityFramework.Shared.Configuration;

namespace Skoruba.IdentityServer4.Admin.EntityFramework.PostgreSQL.Extensions
{
Expand All @@ -29,9 +30,8 @@ public static class DatabaseExtensions
/// <param name="auditLoggingConnectionString"></param>
public static void RegisterNpgSqlDbContexts<TIdentityDbContext, TConfigurationDbContext,
TPersistedGrantDbContext, TLogDbContext, TAuditLoggingDbContext, TDataProtectionDbContext>(this IServiceCollection services,
string identityConnectionString, string configurationConnectionString,
string persistedGrantConnectionString, string errorLoggingConnectionString,
string auditLoggingConnectionString, string dataProtectionConnectionString = null)
ConnectionStringsConfiguration connectionStrings,
DatabaseMigrationsConfiguration databaseMigrations)
where TIdentityDbContext : DbContext
where TPersistedGrantDbContext : DbContext, IAdminPersistedGrantDbContext
where TConfigurationDbContext : DbContext, IAdminConfigurationDbContext
Expand All @@ -43,28 +43,28 @@ public static class DatabaseExtensions

// Config DB for identity
services.AddDbContext<TIdentityDbContext>(options =>
options.UseNpgsql(identityConnectionString, sql => sql.MigrationsAssembly(migrationsAssembly)));
options.UseNpgsql(connectionStrings.IdentityDbConnection, sql => sql.MigrationsAssembly(databaseMigrations.IdentityDbMigrationsAssembly ?? migrationsAssembly)));

// Config DB from existing connection
services.AddConfigurationDbContext<TConfigurationDbContext>(options =>
options.ConfigureDbContext = b =>
b.UseNpgsql(configurationConnectionString, sql => sql.MigrationsAssembly(migrationsAssembly)));
b.UseNpgsql(connectionStrings.ConfigurationDbConnection, sql => sql.MigrationsAssembly(databaseMigrations.ConfigurationDbMigrationsAssembly ?? migrationsAssembly)));

// Operational DB from existing connection
services.AddOperationalDbContext<TPersistedGrantDbContext>(options => options.ConfigureDbContext = b =>
b.UseNpgsql(persistedGrantConnectionString, sql => sql.MigrationsAssembly(migrationsAssembly)));
b.UseNpgsql(connectionStrings.PersistedGrantDbConnection, sql => sql.MigrationsAssembly(databaseMigrations.PersistedGrantDbMigrationsAssembly ?? migrationsAssembly)));

// Log DB from existing connection
services.AddDbContext<TLogDbContext>(options => options.UseNpgsql(errorLoggingConnectionString,
optionsSql => optionsSql.MigrationsAssembly(migrationsAssembly)));
services.AddDbContext<TLogDbContext>(options => options.UseNpgsql(connectionStrings.AdminLogDbConnection,
optionsSql => optionsSql.MigrationsAssembly(databaseMigrations.AdminLogDbMigrationsAssembly ?? migrationsAssembly)));

// Audit logging connection
services.AddDbContext<TAuditLoggingDbContext>(options => options.UseNpgsql(auditLoggingConnectionString,
optionsSql => optionsSql.MigrationsAssembly(migrationsAssembly)));
services.AddDbContext<TAuditLoggingDbContext>(options => options.UseNpgsql(connectionStrings.AdminAuditLogDbConnection,
optionsSql => optionsSql.MigrationsAssembly(databaseMigrations.AdminAuditLogDbMigrationsAssembly ?? migrationsAssembly)));

// DataProtectionKey DB from existing connection
if (!string.IsNullOrEmpty(dataProtectionConnectionString))
services.AddDbContext<TDataProtectionDbContext>(options => options.UseNpgsql(dataProtectionConnectionString, sql => sql.MigrationsAssembly(migrationsAssembly)));
if (!string.IsNullOrEmpty(connectionStrings.DataProtectionDbConnection))
services.AddDbContext<TDataProtectionDbContext>(options => options.UseNpgsql(connectionStrings.DataProtectionDbConnection, sql => sql.MigrationsAssembly(databaseMigrations.DataProtectionDbMigrationsAssembly ?? migrationsAssembly)));
}

/// <summary>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
namespace Skoruba.IdentityServer4.Admin.EntityFramework.Shared.Configuration
{
public class ConnectionStringsConfiguration
{
public string ConfigurationDbConnection { get; set; }

public string PersistedGrantDbConnection { get; set; }

public string AdminLogDbConnection { get; set; }

public string IdentityDbConnection { get; set; }

public string AdminAuditLogDbConnection { get; set; }

public string DataProtectionDbConnection { get; set; }

public void SetConnections(string commonConnectionString)
{
AdminAuditLogDbConnection = commonConnectionString;
AdminLogDbConnection = commonConnectionString;
ConfigurationDbConnection = commonConnectionString;
DataProtectionDbConnection = commonConnectionString;
IdentityDbConnection = commonConnectionString;
PersistedGrantDbConnection = commonConnectionString;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
namespace Skoruba.IdentityServer4.Admin.EntityFramework.Shared.Configuration
{
public class DatabaseMigrationsConfiguration
{
public bool ApplyDatabaseMigrations { get; set; } = false;

public string ConfigurationDbMigrationsAssembly { get; set; }

public string PersistedGrantDbMigrationsAssembly { get; set; }

public string AdminLogDbMigrationsAssembly { get; set; }

public string IdentityDbMigrationsAssembly { get; set; }

public string AdminAuditLogDbMigrationsAssembly { get; set; }

public string DataProtectionDbMigrationsAssembly { get; set; }

public void SetMigrationsAssemblies(string commonMigrationsAssembly)
{
AdminAuditLogDbMigrationsAssembly = commonMigrationsAssembly;
AdminLogDbMigrationsAssembly = commonMigrationsAssembly;
ConfigurationDbMigrationsAssembly = commonMigrationsAssembly;
DataProtectionDbMigrationsAssembly = commonMigrationsAssembly;
IdentityDbMigrationsAssembly = commonMigrationsAssembly;
PersistedGrantDbMigrationsAssembly = commonMigrationsAssembly;
}
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
namespace Skoruba.IdentityServer4.Admin.Configuration.Identity
namespace Skoruba.IdentityServer4.Admin.EntityFramework.Shared.Configuration.Identity
{
public class Claim
{
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
using System.Collections.Generic;

namespace Skoruba.IdentityServer4.Admin.Configuration.Identity
namespace Skoruba.IdentityServer4.Admin.EntityFramework.Shared.Configuration.Identity
{
public class Role
{
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
using System.Collections.Generic;

namespace Skoruba.IdentityServer4.Admin.Configuration.Identity
namespace Skoruba.IdentityServer4.Admin.EntityFramework.Shared.Configuration.Identity
{
public class User
{
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
using Skoruba.IdentityServer4.Admin.EntityFramework.Shared.Configuration.Identity;
using System.Collections.Generic;

namespace Skoruba.IdentityServer4.Admin.EntityFramework.Shared.Configuration
{
public class IdentityData
{
public List<Role> Roles { get; set; }
public List<User> Users { get; set; }
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
using System.Collections.Generic;
using Skoruba.IdentityServer4.Admin.Configuration.Identity;
using Skoruba.IdentityServer4.Admin.EntityFramework.Shared.Configuration.Identity;

namespace Skoruba.IdentityServer4.Admin.Configuration.IdentityServer
namespace Skoruba.IdentityServer4.Admin.EntityFramework.Shared.Configuration.IdentityServer
{
public class Client : global::IdentityServer4.Models.Client
{
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
using IdentityServer4.Models;
using System.Collections.Generic;
using Client = Skoruba.IdentityServer4.Admin.Configuration.IdentityServer.Client;
using Client = Skoruba.IdentityServer4.Admin.EntityFramework.Shared.Configuration.IdentityServer.Client;

namespace Skoruba.IdentityServer4.Admin.Configuration
namespace Skoruba.IdentityServer4.Admin.EntityFramework.Shared.Configuration
{
public class IdentityServerDataConfiguration
public class IdentityServerData
{
public List<Client> Clients { get; set; } = new List<Client>();
public List<IdentityResource> IdentityResources { get; set; } = new List<IdentityResource>();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
namespace Skoruba.IdentityServer4.Admin.Configuration
namespace Skoruba.IdentityServer4.Admin.EntityFramework.Shared.Configuration
{
public class SeedConfiguration
{
Expand Down
Loading

0 comments on commit 91a8ff9

Please sign in to comment.