Skip to content

Commit e5ecf6c

Browse files
committed
User Management Endpoints & Orchestrator Basics
1 parent eef1785 commit e5ecf6c

File tree

46 files changed

+650
-108
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

46 files changed

+650
-108
lines changed

src/CodeBeam.UltimateAuth.Core/Abstractions/Authority/IAccessAuthority.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ namespace CodeBeam.UltimateAuth.Core.Abstractions
44
{
55
public interface IAccessAuthority
66
{
7-
AccessDecision Decide(AccessContext context, IEnumerable<IAccessPolicy> policies);
7+
AccessDecision Decide(AccessContext context, IEnumerable<IAccessPolicy> runtimePolicies);
88
}
99

1010
}

src/CodeBeam.UltimateAuth.Core/Contracts/Authority/AccessContext.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@ namespace CodeBeam.UltimateAuth.Core.Contracts
44
{
55
public sealed class AccessContext
66
{
7-
public UserKey? UserKey { get; init; }
7+
public string? TenantId { get; init; }
8+
public UserKey? ActorUserKey { get; init; }
89
public string Action { get; init; } = default!;
910
public string? Resource { get; init; }
1011
public string? ResourceId { get; init; }
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
namespace CodeBeam.UltimateAuth.Core.Contracts
2+
{
3+
public enum DeleteMode
4+
{
5+
Soft,
6+
Hard
7+
}
8+
}

src/CodeBeam.UltimateAuth.Core/Domain/AuthFlowType.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ public enum AuthFlowType
2121
PermissionQuery,
2222

2323
UserManagement,
24+
UserProfile,
2425
CredentialManagement,
2526
AuthorizationManagement,
2627

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
using CodeBeam.UltimateAuth.Core.Domain;
2+
using Microsoft.AspNetCore.Http;
3+
4+
namespace CodeBeam.UltimateAuth.Server.Endpoints
5+
{
6+
public interface IUserProfileAdminEndpointHandler
7+
{
8+
Task<IResult> GetAsync(UserKey userKey, HttpContext ctx);
9+
Task<IResult> UpdateAsync(UserKey userKey, HttpContext ctx);
10+
}
11+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
using Microsoft.AspNetCore.Http;
2+
3+
namespace CodeBeam.UltimateAuth.Server.Endpoints
4+
{
5+
public interface IUserProfileEndpointHandler
6+
{
7+
Task<IResult> GetAsync(HttpContext ctx);
8+
Task<IResult> UpdateAsync(HttpContext ctx);
9+
}
10+
}

src/CodeBeam.UltimateAuth.Server/Endpoints/UAuthEndpointRegistrar.cs

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ public void MapEndpoints(RouteGroupBuilder rootGroup, UAuthServerOptions options
106106
=> await h.CheckPermissionAsync(ctx)).WithMetadata(new AuthFlowMetadata(AuthFlowType.PermissionQuery));
107107
}
108108

109-
if (options.EnableUsersEndpoints)
109+
if (options.EnableUserLifecycleEndpoints)
110110
{
111111
var users = group.MapGroup("/users");
112112

@@ -116,11 +116,33 @@ public void MapEndpoints(RouteGroupBuilder rootGroup, UAuthServerOptions options
116116
users.MapPost("/status", async ([FromServices] IUserEndpointHandler h, HttpContext ctx)
117117
=> await h.ChangeStatusAsync(ctx)).WithMetadata(new AuthFlowMetadata(AuthFlowType.UserManagement));
118118

119-
// Intended post here
119+
// Post is intended here
120120
users.MapPost("/delete", async ([FromServices] IUserEndpointHandler h, HttpContext ctx)
121121
=> await h.DeleteAsync(ctx)).WithMetadata(new AuthFlowMetadata(AuthFlowType.UserManagement));
122122
}
123123

124+
if (options.EnableUserProfileEndpoints)
125+
{
126+
var userProfile = group.MapGroup("/users");
127+
128+
userProfile.MapGet("/me", async ([FromServices] IUserProfileEndpointHandler h, HttpContext ctx)
129+
=> await h.GetAsync(ctx)).WithMetadata(new AuthFlowMetadata(AuthFlowType.UserProfile));
130+
131+
userProfile.MapPut("/me", async ([FromServices] IUserProfileEndpointHandler h, HttpContext ctx)
132+
=> await h.UpdateAsync(ctx)).WithMetadata(new AuthFlowMetadata(AuthFlowType.UserInfo));
133+
}
134+
135+
if (options.EnableAdminChangeUserProfileEndpoints)
136+
{
137+
var admin = group.MapGroup("/admin/users");
138+
139+
admin.MapGet("/{userKey}/profile", async ([FromServices] IUserProfileAdminEndpointHandler h, UserKey userKey, HttpContext ctx)
140+
=> await h.GetAsync(userKey, ctx)).WithMetadata(new AuthFlowMetadata(AuthFlowType.UserManagement));
141+
142+
admin.MapPut("/{userKey}/profile", async ([FromServices] IUserProfileAdminEndpointHandler h, UserKey userKey, HttpContext ctx)
143+
=> await h.UpdateAsync(userKey, ctx)).WithMetadata(new AuthFlowMetadata(AuthFlowType.UserManagement));
144+
}
145+
124146
if (options.EnableCredentialsEndpoints)
125147
{
126148
var credentials = group.MapGroup("/credentials");

src/CodeBeam.UltimateAuth.Server/Infrastructure/Orchestrator/UAuthAccessOrchestrator.cs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ public async Task ExecuteAsync(AccessContext context, IAccessCommand command, Ca
2121

2222
_executed = true;
2323

24-
var policies = command.GetPolicies(context);
24+
var policies = command.GetPolicies(context) ?? Array.Empty<IAccessPolicy>();
2525
var decision = _authority.Decide(context, policies);
2626

2727
if (!decision.IsAllowed)
@@ -33,5 +33,4 @@ public async Task ExecuteAsync(AccessContext context, IAccessCommand command, Ca
3333
await command.ExecuteAsync(ct);
3434
}
3535
}
36-
3736
}

src/CodeBeam.UltimateAuth.Server/Options/UAuthServerOptions.cs

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -108,10 +108,14 @@ public void ReplaceSessionCookieManager<T>() where T : class, IUAuthCookieManage
108108
public bool? EnableSessionEndpoints { get; set; } = true;
109109
public bool? EnableUserInfoEndpoints { get; set; } = true;
110110

111-
public bool EnableUsersEndpoints { get; set; } = true;
111+
public bool EnableUserLifecycleEndpoints { get; set; } = true;
112+
public bool EnableUserProfileEndpoints { get; set; } = true;
113+
public bool EnableAdminChangeUserProfileEndpoints { get; set; } = false;
112114
public bool EnableCredentialsEndpoints { get; set; } = true;
113115
public bool EnableAuthorizationEndpoints { get; set; } = true;
114116

117+
public UserIdentifierOptions UserIdentifiers { get; set; } = new();
118+
115119
/// <summary>
116120
/// If true, server will add anti-forgery headers
117121
/// and require proper request metadata.
@@ -141,7 +145,7 @@ public void ReplaceSessionCookieManager<T>() where T : class, IUAuthCookieManage
141145
public Action<IServiceCollection>? ConfigureServices { get; set; }
142146

143147

144-
internal Dictionary<UAuthMode, Action<UAuthServerOptions>> ModeConfigurations { get; } = new();
148+
internal Dictionary<UAuthMode, Action<UAuthServerOptions>> ModeConfigurations { get; set; } = new();
145149

146150

147151
internal UAuthServerOptions Clone()
@@ -163,19 +167,23 @@ internal UAuthServerOptions Clone()
163167
AuthResponse = AuthResponse.Clone(),
164168
Hub = Hub.Clone(),
165169
SessionResolution = SessionResolution.Clone(),
170+
UserIdentifiers = UserIdentifiers.Clone(),
166171

167172
EnableLoginEndpoints = EnableLoginEndpoints,
168173
EnablePkceEndpoints = EnablePkceEndpoints,
169174
EnableTokenEndpoints = EnableTokenEndpoints,
170175
EnableSessionEndpoints = EnableSessionEndpoints,
171176
EnableUserInfoEndpoints = EnableUserInfoEndpoints,
172-
EnableUsersEndpoints = EnableUsersEndpoints,
177+
EnableUserLifecycleEndpoints = EnableUserLifecycleEndpoints,
178+
EnableUserProfileEndpoints = EnableUserProfileEndpoints,
179+
EnableAdminChangeUserProfileEndpoints = EnableAdminChangeUserProfileEndpoints,
173180
EnableCredentialsEndpoints = EnableCredentialsEndpoints,
174181
EnableAuthorizationEndpoints = EnableAuthorizationEndpoints,
175182

176183
EnableAntiCsrfProtection = EnableAntiCsrfProtection,
177184
EnableLoginRateLimiting = EnableLoginRateLimiting,
178185

186+
ModeConfigurations = ModeConfigurations,
179187
OnConfigureEndpoints = OnConfigureEndpoints,
180188
ConfigureServices = ConfigureServices,
181189
CustomCookieManagerType = CustomCookieManagerType
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
namespace CodeBeam.UltimateAuth.Server.Options
2+
{
3+
public sealed class UserIdentifierOptions
4+
{
5+
public bool AllowUsernameChange { get; set; } = true;
6+
public bool AllowMultipleUsernames { get; set; } = false;
7+
public bool AllowMultipleEmail { get; set; } = true;
8+
public bool AllowMultiplePhone { get; set; } = true;
9+
10+
public bool RequireEmailVerification { get; set; } = false;
11+
public bool RequirePhoneVerification { get; set; } = false;
12+
13+
public bool AllowAdminOverride { get; set; } = true;
14+
public bool AllowUserOverride { get; set; } = true;
15+
16+
internal UserIdentifierOptions Clone() => new()
17+
{
18+
AllowUsernameChange = AllowUsernameChange,
19+
AllowMultipleUsernames = AllowMultipleUsernames,
20+
AllowMultipleEmail = AllowMultipleEmail,
21+
AllowMultiplePhone = AllowMultiplePhone,
22+
RequireEmailVerification = RequireEmailVerification,
23+
RequirePhoneVerification = RequirePhoneVerification,
24+
AllowAdminOverride = AllowAdminOverride,
25+
AllowUserOverride = AllowUserOverride
26+
};
27+
}
28+
29+
}

0 commit comments

Comments
 (0)