Skip to content

Commit 2f244af

Browse files
Ticket #910 : Check attribute uniqueness
1 parent 3f7e4d7 commit 2f244af

3 files changed

Lines changed: 18 additions & 8 deletions

File tree

src/Scim/SimpleIdServer.Scim/Commands/Handlers/AddRepresentationCommandHandler.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ public async virtual Task<GenericResult<SCIMRepresentation>> Handle(AddRepresent
7070
scimRepresentation.RealmName = addRepresentationCommand.Realm;
7171
scimRepresentation.SetResourceType(addRepresentationCommand.ResourceType);
7272
foreach (var attr in scimRepresentation.FlatAttributes) attr.RepresentationId = scimRepresentation.Id;
73-
await _representationHelper.CheckUniqueness(scimRepresentation.FlatAttributes);
73+
await _representationHelper.CheckUniqueness(addRepresentationCommand.Realm, scimRepresentation.FlatAttributes);
7474
var patchOperations = scimRepresentation.FlatAttributes.Select(a => new SCIMPatchResult
7575
{
7676
Attr = a,

src/Scim/SimpleIdServer.Scim/Commands/Handlers/ReplaceRepresentationCommandHandler.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ public async virtual Task<GenericResult<ReplaceRepresentationResult>> Handle(Rep
5858
var patchOperations = patchResult.Patches.Where(p => p.Attr != null).ToList();
5959
var displayNameDifferent = existingRepresentation.DisplayName != oldDisplayName;
6060
var modifiedAttributes = patchOperations.Where(p => p.Operation != SCIMPatchOperations.REMOVE && p.Attr != null && !p.Attr.IsLeaf() && p.Attr.SchemaAttribute.MultiValued == false).Select(p => p.Attr);
61-
await _representationHelper.CheckUniqueness(modifiedAttributes);
61+
await _representationHelper.CheckUniqueness(replaceRepresentationCommand.Realm, modifiedAttributes);
6262
_representationHelper.CheckMutability(patchOperations);
6363
var references = await _representationReferenceSync.Sync(existingRepresentation.ResourceType, existingRepresentation, patchOperations, replaceRepresentationCommand.Location, schema, displayNameDifferent);
6464
await using (var transaction = await _scimRepresentationCommandRepository.StartTransaction().ConfigureAwait(false))

src/Scim/SimpleIdServer.Scim/Helpers/RepresentationHelper.cs

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ namespace SimpleIdServer.Scim.Helpers
2323
public interface IRepresentationHelper
2424
{
2525
Task<SCIMRepresentationPatchResult> Apply(SCIMRepresentation representation, IEnumerable<PatchOperationParameter> patchLst, IEnumerable<SCIMAttributeMapping> attributeMappings, bool ignoreUnsupportedCanonicalValues, CancellationToken cancellationToken);
26-
Task CheckUniqueness(IEnumerable<SCIMRepresentationAttribute> attributes);
26+
Task CheckUniqueness(string realm, IEnumerable<SCIMRepresentationAttribute> attributes);
2727
void CheckMutability(List<SCIMPatchResult> patchOperations);
2828
SCIMRepresentation ExtractSCIMRepresentationFromJSON(JsonObject json, string externalId, SCIMSchema mainSchema, ICollection<SCIMSchema> extensionSchemas, IEnumerable<SCIMAttributeMapping> attributeMappings);
2929
}
@@ -547,15 +547,15 @@ private static List<SCIMRepresentationAttribute> FilterDuplicate(IEnumerable<SCI
547547

548548
#region Check uniqueness
549549

550-
public async Task CheckUniqueness(IEnumerable<SCIMRepresentationAttribute> attributes)
550+
public async Task CheckUniqueness(string realm, IEnumerable<SCIMRepresentationAttribute> attributes)
551551
{
552552
var uniqueServerAttributeIds = attributes.Where(a => a.SchemaAttribute.Uniqueness == SCIMSchemaAttributeUniqueness.SERVER);
553553
var uniqueGlobalAttributes = attributes.Where(a => a.SchemaAttribute.Uniqueness == SCIMSchemaAttributeUniqueness.GLOBAL);
554-
await CheckSCIMRepresentationExistsForGivenUniqueAttributes(uniqueServerAttributeIds);
555-
await CheckSCIMRepresentationExistsForGivenUniqueAttributes(uniqueGlobalAttributes);
554+
await CheckSCIMRepresentationExistsForGivenUniqueAttributes(realm, uniqueServerAttributeIds);
555+
await CheckSCIMRepresentationExistsForGivenUniqueAttributes(realm, uniqueGlobalAttributes);
556556
}
557557

558-
private async Task CheckSCIMRepresentationExistsForGivenUniqueAttributes(IEnumerable<SCIMRepresentationAttribute> attributes)
558+
private async Task CheckSCIMRepresentationExistsForGivenUniqueAttributes(string realm, IEnumerable<SCIMRepresentationAttribute> attributes)
559559
{
560560
foreach (var attribute in attributes)
561561
{
@@ -567,11 +567,21 @@ private async Task CheckSCIMRepresentationExistsForGivenUniqueAttributes(IEnumer
567567
break;
568568
case SCIMSchemaAttributeTypes.INTEGER:
569569
if (attribute.ValueInteger != null)
570+
{
570571
records = await _scimRepresentationCommandRepository.FindAttributesByValue(attribute.SchemaAttribute.Id, attribute.ValueInteger.Value);
572+
}
571573
break;
572574
}
573575

574-
if (records != null && records.Any())
576+
var isUnique = records != null && records.Any();
577+
if(!string.IsNullOrWhiteSpace(realm))
578+
{
579+
var representations = await _scimRepresentationCommandRepository.FindRepresentations(records.Select(r => r.RepresentationId).Distinct().ToList());
580+
var filteredRepresentations = representations.Where(r => r.RealmName == realm);
581+
isUnique = filteredRepresentations != null && filteredRepresentations.Any();
582+
}
583+
584+
if (isUnique)
575585
{
576586
throw new SCIMUniquenessAttributeException(string.Format(Global.AttributeMustBeUnique, attribute.SchemaAttribute.Name));
577587
}

0 commit comments

Comments
 (0)