Skip to content

Commit

Permalink
Ticket #765 : Add RealmRouter and inject the realm into "CurrentRealm…
Browse files Browse the repository at this point in the history
…" object
  • Loading branch information
thabart committed Jul 25, 2024
1 parent 528636d commit 652c6ab
Show file tree
Hide file tree
Showing 12 changed files with 149 additions and 9 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"Authorization": {
"ClientId": "CredentialIssuer",
"ClientSecret": "password",
"Issuer": "https://e353-81-246-134-116.ngrok-free.app/master",
"Issuer": "https://3bda-81-246-134-116.ngrok-free.app/master",
"IgnoreCertificateError": true
},
"PublicDid": "did:key:z2dmzD81cgPx8Vki7JbuuMmFYrWPgYoytykUZ3eyqht1j9KbpMAoXtZtunruYnM4gCV65AKAUX2AwEReRhEaf3BRQNJArZPwQdmf9ENZcF8VT13a58WsHeVjJtvAKKPYEibaEfdUxvU7sgxEUTJpjEkq6BJKrRV1JQ1CqhYvGbmJ1WyoUQ"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
"forceHttps": false,
"CredentialIssuerUrl": "https://localhost:5005",
"DefaultSecurityOptions": {
"Issuer": "https://e353-81-246-134-116.ngrok-free.app/master",
"Issuer": "https://3bda-81-246-134-116.ngrok-free.app/master",
"ClientId": "CredentialIssuer-manager",
"ClientSecret": "password",
"Scope": "openid profile",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ public class IdServerConfiguration
ClientBuilder.BuildWalletClient("walletClient", "password")
.SetClientName("Wallet")
.Build(),
ClientBuilder.BuildCredentialIssuer("CredentialIssuer", "password", null, "https://8028-81-246-134-116.ngrok-free.app/signin-oidc", "https://localhost:5005/*", "http://localhost:5005/*", "https://credentialissuer.simpleidserver.com/*", "https://credentialissuer.localhost.com/*", "https://credentialissuer.sid.svc.cluster.local/*")
ClientBuilder.BuildCredentialIssuer("CredentialIssuer", "password", null, "https://6991-81-246-134-116.ngrok-free.app/signin-oidc", "https://localhost:5005/*", "http://localhost:5005/*", "https://credentialissuer.simpleidserver.com/*", "https://credentialissuer.localhost.com/*", "https://credentialissuer.sid.svc.cluster.local/*")
.SetClientName("Credential issuer")
.AddScope(
SimpleIdServer.IdServer.Constants.StandardScopes.OpenIdScope,
Expand All @@ -144,6 +144,7 @@ public class IdServerConfiguration
.SetBackChannelLogoutUrl("https://localhost:5002/bc-logout")
.SetClientLogoUri("https://cdn.logo.com/hotlink-ok/logo-social.png")
.AddScope(
SimpleIdServer.IdServer.Constants.StandardScopes.Role,
SimpleIdServer.IdServer.Constants.StandardScopes.OpenIdScope,
SimpleIdServer.IdServer.Constants.StandardScopes.Profile,
SimpleIdServer.IdServer.Constants.StandardScopes.Provisioning,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
app.UseExceptionHandler("/Error");
}

app.Services.AddSIDWebsite();
app.UseStaticFiles();
app.UseRequestLocalization(e =>
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
"Issuer": "https://localhost:5001/master",
"ClientId": "SIDS-manager",
"ClientSecret": "password",
"Scope": "openid profile",
"Scope": "openid profile role",
"IgnoreCertificateError": false
},
"DetailedErrors": true
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
<Fluxor.Blazor.Web.StoreInitializer />
@using SimpleIdServer.IdServer.Website.Infrastructures;

<Router AppAssembly="@typeof(IdServerRouter).Assembly">
<Fluxor.Blazor.Web.StoreInitializer />

<RealmRouter AppAssembly="@typeof(IdServerRouter).Assembly">
<Found Context="routeData">
<RouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)" />
<FocusOnNavigate RouteData="@routeData" Selector="h1" />
Expand All @@ -11,4 +13,4 @@
<p role="alert">Sorry, there's nothing at this address.</p>
</LayoutView>
</NotFound>
</Router>
</RealmRouter>
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// Copyright (c) SimpleIdServer. All rights reserved.
// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.

namespace SimpleIdServer.IdServer.Website.Infrastructures;

public class CurrentRealm
{
public string Identifier { get; set; }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
// Copyright (c) SimpleIdServer. All rights reserved.
// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.

using Microsoft.AspNetCore.Components;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;
using SimpleIdServer.IdServer.Domains;
using System.Reflection;
using System.Text.RegularExpressions;

namespace SimpleIdServer.IdServer.Website.Infrastructures;

public class RealmRouter : IComponent, IHandleAfterRender, IDisposable
{
private RenderHandle _renderHandle;
internal static IServiceProvider _serviceProvider;
[Inject] private NavigationManager NavigationManager { get; set; }
[Parameter] public Assembly AppAssembly { get; set; }
[Parameter] public RenderFragment<RouteData> Found { get; set; }
[Parameter] public RenderFragment NotFound { get; set; }

public void Attach(RenderHandle renderHandle)
{
_renderHandle = renderHandle;
}

public async Task SetParametersAsync(ParameterView parameters)
{
parameters.SetParameterProperties(this);
var options = _serviceProvider.GetRequiredService<IOptions<IdServerWebsiteOptions>>();
var components = GetRouteableComponents();
if (!options.Value.IsReamEnabled)
{
var locationPath = NavigationManager.ToBaseRelativePath(NavigationManager.Uri);
var context = components.FirstOrDefault(c => c.Value.Any(r => Regex.IsMatch(locationPath, r)));
if(context.Key == null)
{
_renderHandle.Render(NotFound);
return;
}

var routeData = new RouteData(context.Key, new Dictionary<string, object>());
_renderHandle.Render(Found(routeData));
return;
}
else
{
var realms = await GetRealms(options);
var locationPath = NavigationManager.ToBaseRelativePath(NavigationManager.Uri);
var realm = string.IsNullOrWhiteSpace(locationPath) ? Constants.DefaultRealm : locationPath.Split("/").First();
_serviceProvider.GetRequiredService<CurrentRealm>().Identifier = realm;
var pathWithoutRealm = locationPath.Replace(realm, string.Empty);
var context = components.FirstOrDefault(c => c.Value.Any(r => Regex.IsMatch(pathWithoutRealm, r)));
if (!realms.Any(r => r.Name == realm) || context.Key == null)
{
_renderHandle.Render(NotFound);
return;
}

var routeData = new RouteData(context.Key, new Dictionary<string, object>());
_renderHandle.Render(Found(routeData));
}
}

public void Dispose()
{
}

public Task OnAfterRenderAsync()
{
return Task.CompletedTask;
}

private async Task<IEnumerable<Realm>> GetRealms(IOptions<IdServerWebsiteOptions> options)
{
var httpClientFactory = _serviceProvider.GetRequiredService<IWebsiteHttpClientFactory>();
var url = $"{options.Value.IdServerBaseUrl}/realms";
var httpClient = await httpClientFactory.Build();
var requestMessage = new HttpRequestMessage
{
RequestUri = new Uri(url),
Method = HttpMethod.Get
};
var httpResult = await httpClient.SendAsync(requestMessage);
var json = await httpResult.Content.ReadAsStringAsync();
var realms = SidJsonSerializer.Deserialize<IEnumerable<Realm>>(json);
return realms;
}

private Dictionary<Type, List<string>> GetRouteableComponents()
{
var assembly = typeof(RealmRouter).Assembly;
var components = new List<Type>();
var dic = new Dictionary<Type, List<string>>();
foreach(var type in assembly.ExportedTypes)
{
if(typeof(IComponent).IsAssignableFrom(type) && type.IsDefined(typeof(RouteAttribute)))
{
var routeAttributes = type.GetCustomAttributes<RouteAttribute>(inherit: false);
var templates = routeAttributes.Select(r => Regex.Replace(r.Template, "{\\w*}", "\\w*")).ToList();
dic.Add(type, templates);
}
}

return dic;
}
}
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
@page "/clients"
@inject CurrentRealm currentRealm
@inject IState<SearchClientsState> clientState
@inject IDispatcher dispatcher
@inject NotificationService notificationService
@inject ContextMenuService contextMenuService
@inject DialogService dialogService
@inherits Fluxor.Blazor.Web.Components.FluxorComponent
@using SimpleIdServer.IdServer.Website.Infrastructures
@using SimpleIdServer.IdServer.Website.Resources;
@using SimpleIdServer.IdServer.Website.Stores.ClientStore;
@using SimpleIdServer.IdServer.Website.Stores.RealmStore;
Expand Down Expand Up @@ -69,6 +71,8 @@
@code {
bool selectAll = false;
RadzenDataGrid<SelectableClient> clientsGrid;
[Parameter]
public string? realm { get; set; } = null;

protected override void OnAfterRender(bool firstRender)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
using Radzen;
using SimpleIdServer.IdServer.UI;
using SimpleIdServer.IdServer.Website;
using SimpleIdServer.IdServer.Website.Infrastructures;
using SimpleIdServer.IdServer.Website.Stores.GroupStore;
using System.Security.Claims;

Expand All @@ -34,6 +35,7 @@ public static IServiceCollection AddSIDWebsite(this IServiceCollection services,
services.AddScoped<NotificationService>();
services.AddScoped<ContextMenuService>();
services.AddScoped<TooltipService>();
services.AddSingleton<CurrentRealm>();
services.AddSingleton<IWebsiteHttpClientFactory, WebsiteHttpClientFactory>();
if (callbackOptions == null) services.Configure<IdServerWebsiteOptions>((o) => { });
else services.Configure(callbackOptions);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// Copyright (c) SimpleIdServer. All rights reserved.
// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.

using SimpleIdServer.IdServer.Website.Infrastructures;

namespace System;

public static class ServiceProviderExtensions
{
public static IServiceProvider AddSIDWebsite(this IServiceProvider serviceProvider)
{
RealmRouter._serviceProvider = serviceProvider;
return serviceProvider;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@

void SubmitSelectRealm(RealmForm realm)
{
dispatcher.Dispatch(new SelectRealmAction { Realm = realm.Name });
this.dialogService.Close();
navigationManager.NavigateTo($"/{realm.Name}");
}
}

0 comments on commit 652c6ab

Please sign in to comment.