@@ -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" } ;
0 commit comments