public async Task <RepresentationSyncResult> Sync(string resourceType, SCIMRepresentation newSourceScimRepresentation, ICollection <SCIMPatchResult> patchOperations, string location) { var stopWatch = new Stopwatch(); var result = new RepresentationSyncResult(_resourceTypeResolver); var attributeMappingLst = await _scimAttributeMappingQueryRepository.GetBySourceResourceType(resourceType); if (!attributeMappingLst.Any()) { return(result); } foreach (var attributeMapping in attributeMappingLst) { var existingIds = newSourceScimRepresentation.GetAttributesByAttrSchemaId(attributeMapping.SourceAttributeId).SelectMany(a => newSourceScimRepresentation.GetChildren(a).Where(v => v.SchemaAttribute.Name == "value")).Select(v => v.ValueString); var newIds = patchOperations .Where(p => p.Operation == DTOs.SCIMPatchOperations.ADD && p.Attr.SchemaAttributeId == attributeMapping.SourceAttributeId) .SelectMany(p => patchOperations.Where(po => po.Attr.ParentAttributeId == p.Attr.Id && po.Attr.SchemaAttribute.Name == "value").Select(po => po.Attr.ValueString)); var idsToBeRemoved = patchOperations .Where(p => p.Operation == DTOs.SCIMPatchOperations.REMOVE && p.Attr.SchemaAttributeId == attributeMapping.SourceAttributeId) .SelectMany(p => patchOperations.Where(po => po.Attr.ParentAttributeId == p.Attr.Id && po.Attr.SchemaAttribute.Name == "value").Select(po => po.Attr.ValueString)); var duplicateIds = existingIds.GroupBy(i => i).Where(i => i.Count() > 1); if (duplicateIds.Any()) { throw new SCIMUniquenessAttributeException(string.Format(Global.DuplicateReference, string.Join(",", duplicateIds.Select(_ => _.Key).Distinct()))); } await RemoveReferenceAttributes(result, idsToBeRemoved, attributeMapping, newSourceScimRepresentation, location); await UpdateReferenceAttributes(result, newIds, attributeMapping, newSourceScimRepresentation, location); } return(result); }
protected virtual async Task UpdateReferenceAttributes(RepresentationSyncResult result, IEnumerable <string> ids, SCIMAttributeMapping attributeMapping, SCIMRepresentation sourceScimRepresentation, string location) { var targetRepresentations = await _scimRepresentationQueryRepository.FindSCIMRepresentationByIds(ids, attributeMapping.TargetResourceType); var missingIds = ids.Where(i => !targetRepresentations.Any(r => r.Id == i)); if (missingIds.Any()) { throw new SCIMNotFoundException(string.Format(Global.ReferencesDontExist, string.Join(",", missingIds))); } if (targetRepresentations.Any()) { foreach (var targetRepresentation in targetRepresentations) { bool isAttrUpdated; UpdateScimRepresentation(targetRepresentation, sourceScimRepresentation, attributeMapping.TargetAttributeId, attributeMapping.SourceResourceType, out isAttrUpdated); UpdateScimRepresentation(sourceScimRepresentation, targetRepresentation, attributeMapping.SourceAttributeId, attributeMapping.TargetResourceType, out bool b); if (!isAttrUpdated) { result.AddReferenceAttr(targetRepresentation, attributeMapping.TargetAttributeId, targetRepresentation.GetSchemaAttributeById(attributeMapping.TargetAttributeId).FullPath, sourceScimRepresentation.Id, location); } result.AddRepresentation(targetRepresentation); } } }
protected virtual async Task RemoveReferenceAttributes(RepresentationSyncResult result, IEnumerable <string> ids, SCIMAttributeMapping attributeMapping, SCIMRepresentation sourceScimRepresentation, string location) { var targetRepresentations = await _scimRepresentationQueryRepository.FindSCIMRepresentationByIds(ids, attributeMapping.TargetResourceType); if (targetRepresentations.Any()) { var firstTargetRepresentation = targetRepresentations.First(); var targetSchemaAttribute = firstTargetRepresentation.GetRootSchema().GetAttributeById(attributeMapping.TargetAttributeId); foreach (var targetRepresentation in targetRepresentations) { var attr = targetRepresentation.GetAttributesByAttrSchemaId(targetSchemaAttribute.Id).FirstOrDefault(v => targetRepresentation.GetChildren(v).Any(c => c.ValueString == sourceScimRepresentation.Id)); if (attr != null) { targetRepresentation.RemoveAttributeById(attr); result.RemoveReferenceAttr(targetRepresentation, attr.SchemaAttribute.Id, attr.SchemaAttribute.FullPath, sourceScimRepresentation.Id, location); } result.AddRepresentation(targetRepresentation); } } }
public async virtual Task <RepresentationSyncResult> Sync(string resourceType, SCIMRepresentation oldScimRepresentation, SCIMRepresentation newSourceScimRepresentation, string location, bool updateAllReferences = false, bool isScimRepresentationRemoved = false) { var stopWatch = new Stopwatch(); var result = new RepresentationSyncResult(_resourceTypeResolver); var attributeMappingLst = await _scimAttributeMappingQueryRepository.GetBySourceResourceType(resourceType); if (!attributeMappingLst.Any()) { return(result); } foreach (var attributeMapping in attributeMappingLst) { var newIds = newSourceScimRepresentation.GetAttributesByAttrSchemaId(attributeMapping.SourceAttributeId).SelectMany(a => newSourceScimRepresentation.GetChildren(a).Where(v => v.SchemaAttribute.Name == "value")).Select(v => v.ValueString); if (isScimRepresentationRemoved) { await RemoveReferenceAttributes(result, newIds, attributeMapping, newSourceScimRepresentation, location); } else { var oldIds = oldScimRepresentation.GetAttributesByAttrSchemaId(attributeMapping.SourceAttributeId).SelectMany(a => oldScimRepresentation.GetChildren(a).Where(v => v.SchemaAttribute.Name == "value")).Select(v => v.ValueString); var idsToBeRemoved = oldIds.Except(newIds); var duplicateIds = newIds.GroupBy(i => i).Where(i => i.Count() > 1); if (duplicateIds.Any()) { throw new SCIMUniquenessAttributeException(string.Format(Global.DuplicateReference, string.Join(",", duplicateIds.Select(_ => _.Key).Distinct()))); } if (!updateAllReferences) { newIds = newIds.Except(oldIds).ToList(); } await RemoveReferenceAttributes(result, idsToBeRemoved, attributeMapping, newSourceScimRepresentation, location); await UpdateReferenceAttributes(result, newIds, attributeMapping, newSourceScimRepresentation, location); } } return(result); }