Skip to content

Commit e5827a4

Browse files
Access: rework auto config including default hub managed instance sp
1 parent 650c12b commit e5827a4

File tree

5 files changed

+280
-83
lines changed

5 files changed

+280
-83
lines changed

src/Certify.Core/Management/Access/AccessControl.cs

Lines changed: 50 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -63,9 +63,17 @@ public async Task<List<Role>> GetRoles(string contextUserId)
6363
return await _store.GetItems<Role>(nameof(Role));
6464
}
6565

66-
public async Task<List<SecurityPrinciple>> GetSecurityPrinciples(string contextUserId)
66+
public async Task<List<SecurityPrinciple>> GetSecurityPrinciples(string contextUserId, bool includePassword = false)
6767
{
68-
return await _store.GetItems<SecurityPrinciple>(nameof(SecurityPrinciple));
68+
var results = await _store.GetItems<SecurityPrinciple>(nameof(SecurityPrinciple));
69+
70+
if (!includePassword)
71+
{
72+
// remove password hash from results
73+
results.ForEach(sp => sp.Password = null);
74+
}
75+
76+
return results;
6977
}
7078

7179
public async Task<bool> AddSecurityPrinciple(string contextUserId, SecurityPrinciple principle, bool bypassIntegrityCheck = false)
@@ -157,6 +165,15 @@ public async Task<bool> DeleteSecurityPrinciple(string contextUserId, string id,
157165

158166
var existing = await GetSecurityPrinciple(contextUserId, id);
159167

168+
if (existing.IsBuiltIn)
169+
{
170+
if (!allowSelfDelete && id == contextUserId)
171+
{
172+
await AuditWarning("User {contextUserId} tried to delete built-in user [{id}].", contextUserId, id);
173+
return false;
174+
}
175+
}
176+
160177
var deleted = await _store.Delete<SecurityPrinciple>(nameof(SecurityPrinciple), id);
161178

162179
if (deleted != true)
@@ -176,11 +193,18 @@ public async Task<bool> DeleteSecurityPrinciple(string contextUserId, string id,
176193
return true;
177194
}
178195

179-
public async Task<SecurityPrinciple> GetSecurityPrinciple(string contextUserId, string id)
196+
public async Task<SecurityPrinciple> GetSecurityPrinciple(string contextUserId, string id, bool includePassword = false)
180197
{
181198
try
182199
{
183-
return await _store.Get<SecurityPrinciple>(nameof(SecurityPrinciple), id);
200+
var result = await _store.Get<SecurityPrinciple>(nameof(SecurityPrinciple), id);
201+
202+
if (!includePassword && result != null)
203+
{
204+
result.Password = null;
205+
}
206+
207+
return result;
184208
}
185209
catch (Exception exp)
186210
{
@@ -190,16 +214,23 @@ public async Task<SecurityPrinciple> GetSecurityPrinciple(string contextUserId,
190214
}
191215
}
192216

193-
public async Task<SecurityPrinciple> GetSecurityPrincipleByUsername(string contextUserId, string username)
217+
public async Task<SecurityPrinciple> GetSecurityPrincipleByUsername(string contextUserId, string username, bool includePassword = false)
194218
{
195219
if (string.IsNullOrWhiteSpace(username))
196220
{
197221
return default;
198222
}
199223

200-
var list = await GetSecurityPrinciples(contextUserId);
224+
var list = await GetSecurityPrinciples(contextUserId, includePassword);
225+
226+
var result = list?.SingleOrDefault(sp => sp.Username?.ToLowerInvariant() == username.ToLowerInvariant());
201227

202-
return list?.SingleOrDefault(sp => sp.Username?.ToLowerInvariant() == username.ToLowerInvariant());
228+
if (!includePassword && result != null)
229+
{
230+
result.Password = null;
231+
}
232+
233+
return result;
203234
}
204235

205236
/// <summary>
@@ -234,7 +265,7 @@ public async Task<bool> IsSecurityPrincipleAuthorised(string contextUserId, Acce
234265
// if scoped assigned role ID specified (access token check etc), reduce scope of assigned roles to check
235266
if (check.ScopedAssignedRoles?.Any() == true)
236267
{
237-
spAssignedRoles = spAssignedRoles.Where(a => check.ScopedAssignedRoles.Contains(a.Id));
268+
spAssignedRoles = spAssignedRoles.Where(a => check.ScopedAssignedRoles.Contains(a.RoleId));
238269
}
239270

240271
// get all role definitions included in the principles assigned roles
@@ -352,17 +383,17 @@ public async Task<bool> IsPrincipleInRole(string contextUserId, string id, strin
352383
}
353384
}
354385

355-
public async Task<bool> AddResourcePolicy(string contextUserId, ResourcePolicy resourceProfile, bool bypassIntegrityCheck = false)
386+
public async Task<bool> AddResourcePolicy(string contextUserId, ResourcePolicy resourcePolicy, bool bypassIntegrityCheck = false)
356387
{
357388
if (!bypassIntegrityCheck && !await IsPrincipleInRole(contextUserId, contextUserId, StandardRoles.Administrator.Id))
358389
{
359-
await AuditWarning("User {contextUserId} attempted to use AddResourcePolicy [{resourceProfileId}] without being in required role.", contextUserId, resourceProfile?.Id);
390+
await AuditWarning("User {contextUserId} attempted to use AddResourcePolicy [{resourcePolicyId}] without being in required role.", contextUserId, resourcePolicy?.Id);
360391
return false;
361392
}
362393

363-
await _store.Add(nameof(ResourcePolicy), resourceProfile);
394+
await _store.Add(nameof(ResourcePolicy), resourcePolicy);
364395

365-
await AuditInformation("User {contextUserId} added resource policy [{resourceProfile.Id}]", contextUserId, resourceProfile?.Id);
396+
await AuditInformation("User {contextUserId} added resource policy [{resourcePolicy.Id}]", contextUserId, resourcePolicy?.Id);
366397
return true;
367398
}
368399

@@ -569,10 +600,10 @@ public async Task<bool> UpdateAssignedRoles(string contextUserId, SecurityPrinci
569600
public async Task<SecurityPrincipleCheckResponse> CheckSecurityPrinciplePassword(string contextUserId, SecurityPrinciplePasswordCheck passwordCheck)
570601
{
571602
var principle = string.IsNullOrWhiteSpace(passwordCheck.SecurityPrincipleId) ?
572-
await GetSecurityPrincipleByUsername(contextUserId, passwordCheck.Username) :
573-
await GetSecurityPrinciple(contextUserId, passwordCheck.SecurityPrincipleId);
603+
await GetSecurityPrincipleByUsername(contextUserId, passwordCheck.Username, includePassword: true) :
604+
await GetSecurityPrinciple(contextUserId, passwordCheck.SecurityPrincipleId, includePassword: true);
574605

575-
if (principle != null && IsPasswordValid(passwordCheck.Password, principle.Password))
606+
if (principle != null && principle.PrincipleType == SecurityPrincipleType.User && IsPasswordValid(passwordCheck.Password, principle.Password))
576607
{
577608
return new SecurityPrincipleCheckResponse { IsSuccess = true, SecurityPrinciple = principle };
578609
}
@@ -582,6 +613,10 @@ await GetSecurityPrincipleByUsername(contextUserId, passwordCheck.Username) :
582613
{
583614
return new SecurityPrincipleCheckResponse { IsSuccess = false, Message = "Invalid security principle" };
584615
}
616+
else if (principle.PrincipleType != SecurityPrincipleType.User)
617+
{
618+
return new SecurityPrincipleCheckResponse { IsSuccess = false, Message = "Invalid security principle for password based login" };
619+
}
585620
else
586621
{
587622
return new SecurityPrincipleCheckResponse { IsSuccess = false, Message = "Invalid password" };

src/Certify.Models/Hub/AccessControl.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ public enum SecurityPrincipleType
77
{
88
User = 1,
99
Application = 2,
10-
Group
10+
Group = 3
1111
}
1212

1313
public enum SecurityPermissionType
@@ -40,6 +40,7 @@ public class SecurityPrinciple : ConfigurationStoreItem
4040
public string? AuthKey { get; set; }
4141

4242
public string AvatarUrl { get; set; } = string.Empty;
43+
public bool IsBuiltIn { get; set; } = false;
4344
}
4445

4546
/// <summary>

0 commit comments

Comments
 (0)