From 03947fdbdc279587bca7a4fb954064c2ef9bcb81 Mon Sep 17 00:00:00 2001 From: Mark Ettema Date: Sun, 9 May 2021 21:20:57 +0700 Subject: [PATCH] Added classes for the Configuration Separated the logic in domains --- src/Domains/Common/HostingConfig.cs | 16 +++++++ .../IdentityServer}/AppInMemoryDbContext.cs | 2 +- .../IdentityServerConfigFactory.cs} | 17 +++---- src/Domains/IdentityServer/OpenIdConfig.cs | 18 ++++++++ src/Domains/Steam/Constants.cs | 14 ++++++ .../Steam}/GetPlayerSummariesResponse.cs | 3 +- .../Models => Domains/Steam}/Player.cs | 0 src/Domains/Steam/SteamConfig.cs | 14 ++++++ .../Steam}/SteamProfileService.cs | 44 +++++++++---------- .../Models => Domains/Steam}/SteamResponse.cs | 2 +- src/Startup.cs | 34 +++++++------- 11 files changed, 113 insertions(+), 51 deletions(-) create mode 100644 src/Domains/Common/HostingConfig.cs rename src/{Database => Domains/IdentityServer}/AppInMemoryDbContext.cs (87%) rename src/{IdentityServerConfig.cs => Domains/IdentityServer/IdentityServerConfigFactory.cs} (64%) create mode 100644 src/Domains/IdentityServer/OpenIdConfig.cs create mode 100644 src/Domains/Steam/Constants.cs rename src/{Profile/Models => Domains/Steam}/GetPlayerSummariesResponse.cs (70%) rename src/{Profile/Models => Domains/Steam}/Player.cs (100%) create mode 100644 src/Domains/Steam/SteamConfig.cs rename src/{Profile => Domains/Steam}/SteamProfileService.cs (79%) rename src/{Profile/Models => Domains/Steam}/SteamResponse.cs (76%) diff --git a/src/Domains/Common/HostingConfig.cs b/src/Domains/Common/HostingConfig.cs new file mode 100644 index 0000000..d63f374 --- /dev/null +++ b/src/Domains/Common/HostingConfig.cs @@ -0,0 +1,16 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; + +namespace SteamOpenIdConnectProvider.Domains.Common +{ + public class HostingConfig + { + public static readonly string Key = "Hosting"; + + public string BasePath { get; set; } + + public string PublicOrigin { get; set; } + } +} diff --git a/src/Database/AppInMemoryDbContext.cs b/src/Domains/IdentityServer/AppInMemoryDbContext.cs similarity index 87% rename from src/Database/AppInMemoryDbContext.cs rename to src/Domains/IdentityServer/AppInMemoryDbContext.cs index 0284829..7450f17 100644 --- a/src/Database/AppInMemoryDbContext.cs +++ b/src/Domains/IdentityServer/AppInMemoryDbContext.cs @@ -2,7 +2,7 @@ using Microsoft.AspNetCore.Identity.EntityFrameworkCore; using Microsoft.EntityFrameworkCore; -namespace SteamOpenIdConnectProvider.Database +namespace SteamOpenIdConnectProvider.Domains.IdentityServer { // This is completely in-memory, we do not need a persistent store. public class AppInMemoryDbContext : IdentityDbContext diff --git a/src/IdentityServerConfig.cs b/src/Domains/IdentityServer/IdentityServerConfigFactory.cs similarity index 64% rename from src/IdentityServerConfig.cs rename to src/Domains/IdentityServer/IdentityServerConfigFactory.cs index 16f80f1..8a95f5f 100644 --- a/src/IdentityServerConfig.cs +++ b/src/Domains/IdentityServer/IdentityServerConfigFactory.cs @@ -3,29 +3,30 @@ using System.Collections.Generic; using System.Linq; using IdentityServer4; using IdentityServer4.Models; +using SteamOpenIdConnectProvider.Domains.IdentityServer; -namespace SteamOpenIdConnectProvider +namespace SteamOpenIdConnectProvider.Models.IdentityServer { - public class IdentityServerConfig + public static class IdentityServerConfigFactory { - public static IEnumerable GetClients(string clientId, string secret, string redirectUri, string logoutRedirectUri) + public static IEnumerable GetClients(OpenIdConfig config) { yield return new Client { - ClientId = clientId, - ClientName = "Proxy Client", + ClientId = config.ClientID, + ClientName = config.ClientName, AllowedGrantTypes = GrantTypes.Code, RequireConsent = false, ClientSecrets = { - new Secret(secret.Sha256()) + new Secret(config.ClientSecret.Sha256()) }, // where to redirect to after login - RedirectUris = redirectUri.Split(",").Select(x => x.Trim()).ToArray(), + RedirectUris = config.RedirectUri.Split(",").Select(x => x.Trim()).ToArray(), // where to redirect to after logout - PostLogoutRedirectUris = { logoutRedirectUri }, + PostLogoutRedirectUris = { config.PostLogoutRedirectUri }, RequirePkce = false, AllowedScopes = new List { diff --git a/src/Domains/IdentityServer/OpenIdConfig.cs b/src/Domains/IdentityServer/OpenIdConfig.cs new file mode 100644 index 0000000..8bf8f2f --- /dev/null +++ b/src/Domains/IdentityServer/OpenIdConfig.cs @@ -0,0 +1,18 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; + +namespace SteamOpenIdConnectProvider.Domains.IdentityServer +{ + public class OpenIdConfig + { + public static readonly string Key = "OpenID"; + + public string ClientID { get; set; } + public string ClientSecret { get; set; } + public string RedirectUri { get; set; } + public string PostLogoutRedirectUri { get; set; } + public string ClientName { get; set; } = "Proxy Client"; + } +} diff --git a/src/Domains/Steam/Constants.cs b/src/Domains/Steam/Constants.cs new file mode 100644 index 0000000..4863d1b --- /dev/null +++ b/src/Domains/Steam/Constants.cs @@ -0,0 +1,14 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; + +namespace SteamOpenIdConnectProvider.Domains.Steam +{ + public static class Constants + { + public static readonly string OpenIdUrl = "https://steamcommunity.com/openid/id/"; + public static readonly string ApiUrl = "https://api.steampowered.com/"; + public static readonly string GetPlayerSummariesUrl = ApiUrl + "ISteamUser/GetPlayerSummaries/v0002"; + } +} diff --git a/src/Profile/Models/GetPlayerSummariesResponse.cs b/src/Domains/Steam/GetPlayerSummariesResponse.cs similarity index 70% rename from src/Profile/Models/GetPlayerSummariesResponse.cs rename to src/Domains/Steam/GetPlayerSummariesResponse.cs index 5cb0846..0cf516a 100644 --- a/src/Profile/Models/GetPlayerSummariesResponse.cs +++ b/src/Domains/Steam/GetPlayerSummariesResponse.cs @@ -1,7 +1,8 @@ using System.Collections.Generic; using System.Text.Json.Serialization; +using SteamOpenIdConnectProvider.Profile.Models; -namespace SteamOpenIdConnectProvider.Profile.Models +namespace SteamOpenIdConnectProvider.Domains.Steam { public sealed class GetPlayerSummariesResponse { diff --git a/src/Profile/Models/Player.cs b/src/Domains/Steam/Player.cs similarity index 100% rename from src/Profile/Models/Player.cs rename to src/Domains/Steam/Player.cs diff --git a/src/Domains/Steam/SteamConfig.cs b/src/Domains/Steam/SteamConfig.cs new file mode 100644 index 0000000..150d484 --- /dev/null +++ b/src/Domains/Steam/SteamConfig.cs @@ -0,0 +1,14 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; + +namespace SteamOpenIdConnectProvider.Domains.Steam +{ + public class SteamConfig + { + public static readonly string Key = "Steam"; + + public string ApplicationKey { get; internal set; } + } +} diff --git a/src/Profile/SteamProfileService.cs b/src/Domains/Steam/SteamProfileService.cs similarity index 79% rename from src/Profile/SteamProfileService.cs rename to src/Domains/Steam/SteamProfileService.cs index 72195c8..9592945 100644 --- a/src/Profile/SteamProfileService.cs +++ b/src/Domains/Steam/SteamProfileService.cs @@ -8,39 +8,28 @@ using IdentityServer4.Extensions; using IdentityServer4.Models; using IdentityServer4.Services; using Microsoft.AspNetCore.Identity; -using Microsoft.Extensions.Configuration; -using SteamOpenIdConnectProvider.Profile.Models; +using Microsoft.Extensions.Options; +using SteamOpenIdConnectProvider.Domains.Steam; +using SteamOpenIdConnectProvider.Models.Steam; -namespace SteamOpenIdConnectProvider.Profile +namespace SteamOpenIdConnectProvider.Services { public class SteamProfileService : IProfileService { private readonly HttpClient _httpClient; - private readonly IConfiguration _configuration; + private readonly SteamConfig _config; private readonly IUserClaimsPrincipalFactory _claimsFactory; private readonly UserManager _userManager; - private async Task GetPlayerSummariesAsync(IEnumerable steamIds) - { - const string baseurl = "https://api.steampowered.com/ISteamUser/GetPlayerSummaries/v0002"; - - var applicationKey = _configuration["Authentication:Steam:ApplicationKey"]; - var url = $"{baseurl}/?key={applicationKey}&steamids={string.Join(',', steamIds)}"; - - var res = await _httpClient.GetStringAsync(url); - var response = JsonSerializer.Deserialize>(res); - return response.Response; - } - public SteamProfileService( UserManager userManager, IUserClaimsPrincipalFactory claimsFactory, - IConfiguration configuration, + IOptions config, HttpClient httpClient) { _userManager = userManager; _claimsFactory = claimsFactory; - _configuration = configuration; + _config = config.Value; _httpClient = httpClient; } @@ -53,8 +42,7 @@ namespace SteamOpenIdConnectProvider.Profile var claims = principal.Claims.ToList(); claims = claims.Where(claim => context.RequestedClaimTypes.Contains(claim.Type)).ToList(); - const string steamUrl = "https://steamcommunity.com/openid/id/"; - var steamId = sub.Substring(steamUrl.Length); + var steamId = sub.Substring(Constants.OpenIdUrl.Length); var userSummary = await GetPlayerSummariesAsync(new[] { steamId }); var player = userSummary.Players.FirstOrDefault(); @@ -70,6 +58,13 @@ namespace SteamOpenIdConnectProvider.Profile context.IssuedClaims = claims; } + public async Task IsActiveAsync(IsActiveContext context) + { + var sub = context.Subject.GetSubjectId(); + var user = await _userManager.FindByIdAsync(sub); + context.IsActive = user != null; + } + private void AddClaim(List claims, string type, string value) { if (!string.IsNullOrEmpty(value)) @@ -78,11 +73,12 @@ namespace SteamOpenIdConnectProvider.Profile } } - public async Task IsActiveAsync(IsActiveContext context) + private async Task GetPlayerSummariesAsync(IEnumerable steamIds) { - var sub = context.Subject.GetSubjectId(); - var user = await _userManager.FindByIdAsync(sub); - context.IsActive = user != null; + var url = $"{Constants.GetPlayerSummariesUrl}/?key={_config.ApplicationKey}&steamids={string.Join(',', steamIds)}"; + var res = await _httpClient.GetStringAsync(url); + var response = JsonSerializer.Deserialize>(res); + return response.Response; } } } \ No newline at end of file diff --git a/src/Profile/Models/SteamResponse.cs b/src/Domains/Steam/SteamResponse.cs similarity index 76% rename from src/Profile/Models/SteamResponse.cs rename to src/Domains/Steam/SteamResponse.cs index 7799ea6..f6647fb 100644 --- a/src/Profile/Models/SteamResponse.cs +++ b/src/Domains/Steam/SteamResponse.cs @@ -1,6 +1,6 @@ using System.Text.Json.Serialization; -namespace SteamOpenIdConnectProvider.Profile.Models +namespace SteamOpenIdConnectProvider.Models.Steam { public sealed class SteamResponse { diff --git a/src/Startup.cs b/src/Startup.cs index f056b07..4cd0cb4 100644 --- a/src/Startup.cs +++ b/src/Startup.cs @@ -12,8 +12,11 @@ using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; using IdentityServer4.Services; using Microsoft.AspNetCore.HttpOverrides; -using SteamOpenIdConnectProvider.Database; -using SteamOpenIdConnectProvider.Profile; +using SteamOpenIdConnectProvider.Services; +using SteamOpenIdConnectProvider.Models.IdentityServer; +using SteamOpenIdConnectProvider.Domains.Common; +using SteamOpenIdConnectProvider.Domains.IdentityServer; +using SteamOpenIdConnectProvider.Domains.Steam; namespace SteamOpenIdConnectProvider { @@ -31,7 +34,6 @@ namespace SteamOpenIdConnectProvider services.AddControllers() .SetCompatibilityVersion(CompatibilityVersion.Version_3_0); - services.AddSingleton(Configuration); services.AddDbContext(options => options.UseInMemoryDatabase("default")); @@ -42,21 +44,21 @@ namespace SteamOpenIdConnectProvider .AddEntityFrameworkStores() .AddDefaultTokenProviders(); + var openIdConfig = Configuration.GetSection(OpenIdConfig.Key).Get(); services.AddIdentityServer(options => { options.UserInteraction.LoginUrl = "/ExternalLogin"; }) .AddAspNetIdentity() - .AddInMemoryClients(IdentityServerConfig.GetClients( - Configuration["OpenID:ClientID"], - Configuration["OpenID:ClientSecret"], - Configuration["OpenID:RedirectUri"], - Configuration["OpenID:PostLogoutRedirectUri"])) + .AddInMemoryClients(IdentityServerConfigFactory.GetClients(openIdConfig)) .AddInMemoryPersistedGrants() .AddDeveloperSigningCredential(true) - .AddInMemoryIdentityResources(IdentityServerConfig.GetIdentityResources()); + .AddInMemoryIdentityResources(IdentityServerConfigFactory.GetIdentityResources()); - services.AddHttpClient(); + var steamConfig = Configuration.GetSection(SteamConfig.Key).Get(); + services + .Configure(Configuration.GetSection(SteamConfig.Key)) + .AddHttpClient(); services.AddAuthentication() .AddCookie(options => @@ -66,7 +68,7 @@ namespace SteamOpenIdConnectProvider }) .AddSteam(options => { - options.ApplicationKey = Configuration["Authentication:Steam:ApplicationKey"]; + options.ApplicationKey = steamConfig.ApplicationKey; }); services.AddHealthChecks() @@ -80,18 +82,18 @@ namespace SteamOpenIdConnectProvider app.UseDeveloperExceptionPage(); } - if (!string.IsNullOrEmpty(Configuration["Hosting:PathBase"])) + var hostingConfig = Configuration.GetSection(HostingConfig.Key).Get(); + if (!string.IsNullOrEmpty(hostingConfig.BasePath)) { - app.UsePathBase(Configuration["Hosting:PathBase"]); + app.UsePathBase(hostingConfig.BasePath); } app.UseCookiePolicy(); app.Use(async (ctx, next) => { - var origin = Configuration["Hosting:PublicOrigin"]; - if (!string.IsNullOrEmpty(origin)) + if (!string.IsNullOrEmpty(hostingConfig.PublicOrigin)) { - ctx.SetIdentityServerOrigin(origin); + ctx.SetIdentityServerOrigin(hostingConfig.PublicOrigin); } await next();