Skip to content

Commit ae40dc9

Browse files
committed
Bulk roles/permissions.
1 parent 758dddf commit ae40dc9

File tree

27 files changed

+401
-78
lines changed

27 files changed

+401
-78
lines changed

README.md

Lines changed: 0 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -5,30 +5,3 @@ An Identity and Access Management (IAM) platform.
55
# Documentation
66

77
Please visit the [Shuttle.Access documentation](https://www.pendel.co.za/shuttle-access/home.html) for more information
8-
9-
- move "allow identity/password" setting to back-end
10-
- add description to identity (for OID scenarios)
11-
- logging of tokens as option
12-
- configuration.json:
13-
14-
```json
15-
{
16-
"Roles": [
17-
{
18-
"Name": "Admin",
19-
"Description": "Administrator role",
20-
"Permissions": [
21-
"system://name/permission-a"
22-
]
23-
},
24-
{
25-
"Name": "User",
26-
"Description": "User role"
27-
}
28-
],
29-
"Permissions": [
30-
"system://name/permission-a",
31-
"system://name/permission-b",
32-
]
33-
}
34-
```

Shuttle.Access.Application/.package/package.nuspec

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
<tags>iam identity authorization authentication security permissions</tags>
1818
<dependencies>
1919
<dependency id="Microsoft.CSharp" version="4.7.0" />
20+
<dependency id="Shuttle.Access" version="7.3.0" />
2021
<dependency id="Shuttle.Core.Contract" version="20.0.1" />
2122
<dependency id="Shuttle.Core.Mediator" version="20.0.0" />
2223
<dependency id="Shuttle.Esb" version="20.0.0" />

Shuttle.Access.Application/ConfigureApplicationParticipant.cs

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -84,10 +84,7 @@ public async Task ProcessMessageAsync(IParticipantContext<ConfigureApplication>
8484
{
8585
_logger.LogDebug("[role/registration] : name = 'Administrator'");
8686

87-
var registerRoleMessage = new RequestResponseMessage<RegisterRole, RoleRegistered>(new()
88-
{
89-
Name = "Administrator"
90-
});
87+
var registerRoleMessage = new RequestResponseMessage<RegisterRole, RoleRegistered>(new("Administrator"));
9188

9289
await _mediator.SendAsync(registerRoleMessage);
9390

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
using System.Collections.Generic;
2+
using Shuttle.Core.Contract;
3+
4+
namespace Shuttle.Access.Application;
5+
6+
public class RegisterRole
7+
{
8+
private readonly List<string> _permissions = [];
9+
10+
public string Name { get; }
11+
public bool HasMissingPermissions { get; private set; }
12+
13+
public RegisterRole(string name)
14+
{
15+
Name = Guard.AgainstEmpty(name);
16+
}
17+
18+
public RegisterRole AddPermissions(IEnumerable<string> permissions)
19+
{
20+
Guard.AgainstNull(permissions);
21+
22+
foreach (var permission in permissions)
23+
{
24+
if (!_permissions.Contains(permission))
25+
{
26+
_permissions.Add(permission);
27+
}
28+
}
29+
30+
return this;
31+
}
32+
33+
public IEnumerable<string> GetPermissions() => _permissions.AsReadOnly();
34+
35+
public RegisterRole MissingPermissions()
36+
{
37+
HasMissingPermissions = true;
38+
return this;
39+
}
40+
}

Shuttle.Access.Application/RegisterRoleParticipant.cs

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
24
using System.Threading.Tasks;
5+
using Shuttle.Access.DataAccess;
36
using Shuttle.Access.Messages.v1;
47
using Shuttle.Core.Contract;
58
using Shuttle.Core.Mediator;
@@ -10,13 +13,15 @@ namespace Shuttle.Access.Application;
1013

1114
public class RegisterRoleParticipant : IParticipant<RequestResponseMessage<RegisterRole, RoleRegistered>>
1215
{
16+
private readonly IPermissionQuery _permissionQuery;
1317
private readonly IEventStore _eventStore;
1418
private readonly IIdKeyRepository _idKeyRepository;
1519

16-
public RegisterRoleParticipant(IEventStore eventStore, IIdKeyRepository idKeyRepository)
20+
public RegisterRoleParticipant(IEventStore eventStore, IIdKeyRepository idKeyRepository, IPermissionQuery permissionQuery)
1721
{
1822
_eventStore = Guard.AgainstNull(eventStore);
1923
_idKeyRepository = Guard.AgainstNull(idKeyRepository);
24+
_permissionQuery = Guard.AgainstNull(permissionQuery);
2025
}
2126

2227
public async Task ProcessMessageAsync(IParticipantContext<RequestResponseMessage<RegisterRole, RoleRegistered>> context)
@@ -25,6 +30,24 @@ public async Task ProcessMessageAsync(IParticipantContext<RequestResponseMessage
2530

2631
var message = context.Message.Request;
2732

33+
var permissionIds = new List<Guid>();
34+
35+
foreach (var permission in message.GetPermissions())
36+
{
37+
var permissionId = (await _permissionQuery.SearchAsync(new DataAccess.Permission.Specification().AddName(permission))).FirstOrDefault()?.Id;
38+
39+
if (permissionId.HasValue)
40+
{
41+
permissionIds.Add(permissionId.Value);
42+
}
43+
else
44+
{
45+
46+
message.MissingPermissions();
47+
return;
48+
}
49+
}
50+
2851
var key = Role.Key(message.Name);
2952

3053
if (await _idKeyRepository.ContainsAsync(key))
@@ -41,6 +64,14 @@ public async Task ProcessMessageAsync(IParticipantContext<RequestResponseMessage
4164

4265
stream.Add(role.Register(message.Name));
4366

67+
foreach (var permissionId in permissionIds)
68+
{
69+
if (!role.HasPermission(permissionId))
70+
{
71+
stream.Add(role.AddPermission(permissionId));
72+
}
73+
}
74+
4475
context.Message.WithResponse(new()
4576
{
4677
Id = id,

Shuttle.Access.Application/Shuttle.Access.Application.csproj

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,17 +16,14 @@
1616

1717
<ItemGroup>
1818
<PackageReference Include="Microsoft.CSharp" Version="4.7.0" />
19+
<PackageReference Include="Shuttle.Access" Version="7.3.0" />
1920
<PackageReference Include="Shuttle.Core.Contract" Version="20.0.1" />
2021
<PackageReference Include="Shuttle.Core.Mediator" Version="20.0.0" />
2122
<PackageReference Include="Shuttle.Esb" Version="20.0.0" />
2223
<PackageReference Include="Shuttle.Recall" Version="20.0.0" />
2324
<PackageReference Include="Shuttle.Recall.Sql.Storage" Version="20.0.0" />
2425
</ItemGroup>
2526

26-
<ItemGroup>
27-
<ProjectReference Include="..\Shuttle.Access\Shuttle.Access.csproj" />
28-
</ItemGroup>
29-
3027
<ItemGroup>
3128
<Compile Update="Resources.Designer.cs">
3229
<DesignTime>True</DesignTime>

Shuttle.Access.AspNetCore/.package/package.nuspec

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
<tags>iam middleware authorization permissions</tags>
1818
<dependencies>
1919
<dependency id="Microsoft.IdentityModel.JsonWebTokens" version="8.7.0" />
20-
<dependency id="Shuttle.Access" version="7.2.3" />
20+
<dependency id="Shuttle.Access" version="7.3.0" />
2121
<dependency id="Shuttle.Core.Contract" version="20.0.1" />
2222
</dependencies>
2323
</metadata>

Shuttle.Access.AspNetCore/Authentication/RoutingAuthenticationHandler.cs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,20 @@
22
using Microsoft.AspNetCore.Authentication;
33
using Microsoft.Extensions.Logging;
44
using Microsoft.Extensions.Options;
5+
using Shuttle.Core.Contract;
56

67
namespace Shuttle.Access.AspNetCore.Authentication;
78

89
public class RoutingAuthenticationHandler : AuthenticationHandler<AuthenticationSchemeOptions>
910
{
11+
private readonly ILogger _logger;
12+
private readonly AccessOptions _accessOptions;
1013
public const string AuthenticationScheme = "Routing";
1114

12-
public RoutingAuthenticationHandler(IOptionsMonitor<AuthenticationSchemeOptions> options, ILoggerFactory logger, UrlEncoder encoder) : base(options, logger, encoder)
15+
public RoutingAuthenticationHandler(IOptions<AccessOptions> accessOptions, IOptionsMonitor<AuthenticationSchemeOptions> options, ILoggerFactory logger, UrlEncoder encoder) : base(options, logger, encoder)
1316
{
17+
_accessOptions = Guard.AgainstNull(Guard.AgainstNull(accessOptions).Value);
18+
_logger = logger.CreateLogger(GetType());
1419
}
1520

1621
protected override async Task<AuthenticateResult> HandleAuthenticateAsync()

Shuttle.Access.Messages/v1/RegisterIdentity.cs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,4 @@
1-
using System;
2-
3-
namespace Shuttle.Access.Messages.v1;
1+
namespace Shuttle.Access.Messages.v1;
42

53
public class RegisterIdentity
64
{
Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
1-
namespace Shuttle.Access.Messages.v1;
1+
using System.Collections.Generic;
2+
3+
namespace Shuttle.Access.Messages.v1;
24

35
public class RegisterRole
46
{
57
public string Name { get; set; } = default!;
8+
public List<string> Permissions { get; set; } = [];
9+
public int WaitCount { get; set; }
610
}

0 commit comments

Comments
 (0)