Skip to content

Commit e76fbca

Browse files
committed
Add KeycloakRealmResource and AddRealm method
This commit introduces a new `AddRealm` method in the `KeycloakResourceBuilderExtensions` class, enabling the addition of Keycloak Realm resources to the application model. The method constructs a `KeycloakRealmResource` using an `IResourceBuilder<KeycloakResource>`, a realm name, and an optional realm name parameter. Additionally, a new `KeycloakRealmResource` class is defined, which includes properties for various Keycloak endpoints and their expressions, along with a constructor and detailed XML documentation. Changes to `PublicAPI.Unshipped.txt` reflect the inclusion of the new method and class in the public API.
1 parent d343a80 commit e76fbca

File tree

2 files changed

+127
-0
lines changed

2 files changed

+127
-0
lines changed
Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
// Licensed to the .NET Foundation under one or more agreements.
2+
// The .NET Foundation licenses this file to you under the MIT license.
3+
4+
using Aspire.Hosting.ApplicationModel;
5+
6+
namespace Aspire.Hosting.Keycloak;
7+
8+
/// <summary>
9+
/// Represents a Keycloak Realm resource.
10+
/// </summary>
11+
/// <param name="name">The name of the realm resource.</param>
12+
/// <param name="realmName">The name of the realm.</param>
13+
/// <param name="parent">The Keycloak server resource associated with this database.</param>
14+
public sealed class KeycloakRealmResource(string name, string realmName, KeycloakResource parent) : Resource(name), IResourceWithParent<KeycloakResource>, IResourceWithConnectionString
15+
{
16+
private EndpointReference? _parentEndpoint;
17+
private EndpointReference ParentEndpoint => _parentEndpoint ??= new(Parent, "http");
18+
19+
/// <inheritdoc/>
20+
public ReferenceExpression ConnectionStringExpression => ReferenceExpression.Create($"{ParentEndpoint.Property(EndpointProperty.Url)}/realms/{RealmName}/");
21+
22+
/// <summary>
23+
/// Gets the issuer expression for the Keycloak realm.
24+
/// </summary>
25+
public ReferenceExpression IssuerExpression => ReferenceExpression.Create(
26+
$"{ParentEndpoint.Property(EndpointProperty.Url)}/realms/{RealmName}");
27+
28+
/// <summary>
29+
/// Gets or sets the metadata address for the Keycloak realm.
30+
/// </summary>
31+
public string MetadataAddress { get; set; } = ".well-known/openid-configuration";
32+
33+
/// <summary>
34+
/// Gets the metadata address expression for the Keycloak realm.
35+
/// </summary>
36+
public ReferenceExpression MetadataAddressExpression => ReferenceExpression.Create($"{ConnectionStringExpression}{MetadataAddress}");
37+
38+
/// <summary>
39+
/// Gets or sets the 'authorization_endpoint' for the Keycloak realm.
40+
/// </summary>
41+
public string AuthorizationEndpoint { get; set; } = "protocol/openid-connect/auth";
42+
43+
/// <summary>
44+
/// Gets the 'authorization_endpoint' expression for the Keycloak realm.
45+
/// </summary>
46+
public ReferenceExpression AuthorizationEndpointExpression => ReferenceExpression.Create($"{ConnectionStringExpression}{AuthorizationEndpoint}");
47+
48+
/// <summary>
49+
/// Gets or sets the 'token_endpoint' for the Keycloak realm.
50+
/// </summary>
51+
public string TokenEndpoint { get; set; } = "protocol/openid-connect/token";
52+
53+
/// <summary>
54+
/// Gets the 'token_endpoint' expression for the Keycloak realm.
55+
/// </summary>
56+
public ReferenceExpression TokenEndpointExpression => ReferenceExpression.Create($"{ConnectionStringExpression}{TokenEndpoint}");
57+
58+
/// <summary>
59+
/// Gets or sets the 'introspection_endpoint' for the Keycloak realm.
60+
/// </summary>
61+
public string IntrospectionEndpoint { get; set; } = "protocol/openid-connect/token/introspect";
62+
63+
/// <summary>
64+
/// Gets the 'introspection_endpoint' expression for the Keycloak realm.
65+
/// </summary>
66+
public ReferenceExpression IntrospectionEndpointExpression => ReferenceExpression.Create($"{ConnectionStringExpression}{IntrospectionEndpoint}");
67+
68+
/// <summary>
69+
/// Gets or sets 'user_info_endpoint' for the Keycloak realm.
70+
/// </summary>
71+
public string UserInfoEndpoint { get; set; } = "protocol/openid-connect/userinfo";
72+
73+
/// <summary>
74+
/// Gets 'user_info_endpoint' expression for the Keycloak realm.
75+
/// </summary>
76+
public ReferenceExpression UserInfoEndpointExpression => ReferenceExpression.Create($"{ConnectionStringExpression}{UserInfoEndpoint}");
77+
78+
/// <summary>
79+
/// Gets or sets the 'end_session_endpoint' for the Keycloak realm.
80+
/// </summary>
81+
public string EndSessionEndpoint { get; set; } = "protocol/openid-connect/logout";
82+
83+
/// <summary>
84+
/// Gets the 'end_session_endpoint' expression for the Keycloak realm.
85+
/// </summary>
86+
public ReferenceExpression EndSessionEndpointExpression => ReferenceExpression.Create($"{ConnectionStringExpression}{EndSessionEndpoint}");
87+
88+
/// <summary>
89+
/// Gets or sets the 'registration_endpoint' for the Keycloak realm.
90+
/// </summary>
91+
public string RegistrationEndpoint { get; set; } = "clients-registrations/openid-connect";
92+
93+
/// <summary>
94+
/// Gets the 'registration_endpoint' expression for the Keycloak realm.
95+
/// </summary>
96+
public ReferenceExpression RegistrationEndpointExpression => ReferenceExpression.Create($"{ConnectionStringExpression}{RegistrationEndpoint}");
97+
98+
/// <inheritdoc/>
99+
public KeycloakResource Parent { get; } = parent;
100+
101+
/// <summary>
102+
/// Gets the name of the realm.
103+
/// </summary>
104+
public string RealmName { get; } = realmName;
105+
}

src/Aspire.Hosting.Keycloak/KeycloakResourceBuilderExtensions.cs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -175,4 +175,26 @@ public static IResourceBuilder<KeycloakResource> WithRealmImport(
175175

176176
throw new InvalidOperationException($"The realm import file or directory '{importFullPath}' does not exist.");
177177
}
178+
179+
/// <summary>
180+
/// Adds a Keycloak Realm to the application model from a <see cref="IResourceBuilder{KeycloakRealmResource}"/>.
181+
/// </summary>
182+
/// <param name="builder">The Keycloak server resource builder.</param>
183+
/// <param name="name">The name of the realm.</param>
184+
/// <param name="realmName">The name of the realm. If not provided, the resource name will be used.</param>
185+
/// <returns>A reference to the <see cref="IResourceBuilder{KeycloakRealmResource}"/>.</returns>
186+
public static IResourceBuilder<KeycloakRealmResource> AddRealm(
187+
this IResourceBuilder<KeycloakResource> builder,
188+
string name,
189+
string? realmName = null)
190+
{
191+
ArgumentNullException.ThrowIfNull(builder);
192+
193+
// Use the resource name as the realm name if it's not provided
194+
realmName ??= name;
195+
196+
var keycloakRealm = new KeycloakRealmResource(name, realmName, builder.Resource);
197+
198+
return builder.ApplicationBuilder.AddResource(keycloakRealm);
199+
}
178200
}

0 commit comments

Comments
 (0)