public async Task <SCIMRepresentation> Handle(DeleteRepresentationCommand request) { var representation = await _scimRepresentationQueryRepository.FindSCIMRepresentationById(request.Id, request.ResourceType); if (representation == null) { throw new SCIMNotFoundException(string.Format(Global.ResourceNotFound, request.Id)); } var references = await _representationReferenceSync.Sync(request.ResourceType, representation, representation, request.Location, true, true); using (var transaction = await _scimRepresentationCommandRepository.StartTransaction()) { await _scimRepresentationCommandRepository.Delete(representation); foreach (var reference in references.Representations) { await _scimRepresentationCommandRepository.Update(reference); } await transaction.Commit(); } await Notify(references); return(representation); }
public async Task <SCIMRepresentation> Handle(PatchRepresentationCommand patchRepresentationCommand) { CheckParameter(patchRepresentationCommand.PatchRepresentation); var lockName = $"representation-{patchRepresentationCommand.Id}"; await _distributedLock.WaitLock(lockName, CancellationToken.None); try { var existingRepresentation = await _scimRepresentationQueryRepository.FindSCIMRepresentationById(patchRepresentationCommand.Id); if (existingRepresentation == null) { throw new SCIMNotFoundException(string.Format(Global.ResourceNotFound, patchRepresentationCommand.Id)); } var oldRepresentation = existingRepresentation.Clone() as SCIMRepresentation; var patchResult = existingRepresentation.ApplyPatches(patchRepresentationCommand.PatchRepresentation.Operations, _options.IgnoreUnsupportedCanonicalValues); existingRepresentation.SetUpdated(DateTime.UtcNow); var references = await _representationReferenceSync.Sync(patchRepresentationCommand.ResourceType, existingRepresentation, patchResult, patchRepresentationCommand.Location); using (var transaction = await _scimRepresentationCommandRepository.StartTransaction()) { await _scimRepresentationCommandRepository.Update(existingRepresentation); foreach (var reference in references.Representations) { await _scimRepresentationCommandRepository.Update(reference); } await transaction.Commit(); } await Notify(references); existingRepresentation.ApplyEmptyArray(); return(existingRepresentation); } finally { await _distributedLock.ReleaseLock(lockName, CancellationToken.None); } }
public async Task <SCIMRepresentation> Handle(AddRepresentationCommand addRepresentationCommand) { var requestedSchemas = addRepresentationCommand.Representation.Schemas; if (!requestedSchemas.Any()) { throw new SCIMBadSyntaxException(string.Format(Global.AttributeMissing, StandardSCIMRepresentationAttributes.Schemas)); } var schema = await _scimSchemaQueryRepository.FindRootSCIMSchemaByResourceType(addRepresentationCommand.ResourceType); var allSchemas = new List <string> { schema.Id }; var requiredSchemas = new List <string> { schema.Id }; allSchemas.AddRange(schema.SchemaExtensions.Select(s => s.Schema)); requiredSchemas.AddRange(schema.SchemaExtensions.Where(s => s.Required).Select(s => s.Schema)); var missingRequiredSchemas = requiredSchemas.Where(s => !requestedSchemas.Contains(s)); if (missingRequiredSchemas.Any()) { throw new SCIMBadSyntaxException(string.Format(Global.RequiredSchemasAreMissing, string.Join(",", missingRequiredSchemas))); } var unsupportedSchemas = requestedSchemas.Where(s => !allSchemas.Contains(s)); if (unsupportedSchemas.Any()) { throw new SCIMBadSyntaxException(string.Format(Global.SchemasAreUnknown, string.Join(",", unsupportedSchemas))); } var schemas = await _scimSchemaQueryRepository.FindSCIMSchemaByIdentifiers(requestedSchemas); var scimRepresentation = _scimRepresentationHelper.ExtractSCIMRepresentationFromJSON(addRepresentationCommand.Representation.Attributes, addRepresentationCommand.Representation.ExternalId, schema, schemas.Where(s => s.Id != schema.Id).ToList()); scimRepresentation.Id = Guid.NewGuid().ToString(); scimRepresentation.SetCreated(DateTime.UtcNow); scimRepresentation.SetUpdated(DateTime.UtcNow); scimRepresentation.SetVersion(0); scimRepresentation.SetResourceType(addRepresentationCommand.ResourceType); var uniqueServerAttributeIds = scimRepresentation.FlatAttributes.Where(s => s.IsLeaf()).Where(a => a.SchemaAttribute.MultiValued == false && a.SchemaAttribute.Uniqueness == SCIMSchemaAttributeUniqueness.SERVER); var uniqueGlobalAttributes = scimRepresentation.FlatAttributes.Where(s => s.IsLeaf()).Where(a => a.SchemaAttribute.MultiValued == false && a.SchemaAttribute.Uniqueness == SCIMSchemaAttributeUniqueness.GLOBAL); await CheckSCIMRepresentationExistsForGivenUniqueAttributes(uniqueServerAttributeIds, addRepresentationCommand.ResourceType); await CheckSCIMRepresentationExistsForGivenUniqueAttributes(uniqueGlobalAttributes); var references = await _representationReferenceSync.Sync(addRepresentationCommand.ResourceType, new SCIMRepresentation(), scimRepresentation, addRepresentationCommand.Location); using (var transaction = await _scimRepresentationCommandRepository.StartTransaction()) { await _scimRepresentationCommandRepository.Add(scimRepresentation); foreach (var reference in references.Representations) { await _scimRepresentationCommandRepository.Update(reference); } await transaction.Commit(); } await Notify(references); scimRepresentation.ApplyEmptyArray(); return(scimRepresentation); }
public async Task <SCIMRepresentation> Handle(ReplaceRepresentationCommand replaceRepresentationCommand) { var requestedSchemas = replaceRepresentationCommand.Representation.Schemas; if (!requestedSchemas.Any()) { throw new SCIMBadSyntaxException(string.Format(Global.AttributeMissing, StandardSCIMRepresentationAttributes.Schemas)); } var schema = await _scimSchemaQueryRepository.FindRootSCIMSchemaByResourceType(replaceRepresentationCommand.ResourceType); var allSchemas = new List <string> { schema.Id }; allSchemas.AddRange(schema.SchemaExtensions.Select(s => s.Schema)); var unsupportedSchemas = requestedSchemas.Where(s => !allSchemas.Contains(s)); if (unsupportedSchemas.Any()) { throw new SCIMBadSyntaxException(string.Format(Global.SchemasAreUnknown, string.Join(",", unsupportedSchemas))); } var schemas = await _scimSchemaQueryRepository.FindSCIMSchemaByIdentifiers(requestedSchemas); var lockName = $"representation-{replaceRepresentationCommand.Id}"; await _distributedLock.WaitLock(lockName, CancellationToken.None); try { var existingRepresentation = await _scimRepresentationQueryRepository.FindSCIMRepresentationById(replaceRepresentationCommand.Id); if (existingRepresentation == null) { throw new SCIMNotFoundException(string.Format(Global.ResourceNotFound, replaceRepresentationCommand.Id)); } var oldRepresentation = (SCIMRepresentation)existingRepresentation.Clone(); var mainSchema = schemas.First(s => s.Id == schema.Id); var extensionSchemas = schemas.Where(s => s.Id != schema.Id).ToList(); var updatedRepresentation = _scimRepresentationHelper.ExtractSCIMRepresentationFromJSON( replaceRepresentationCommand.Representation.Attributes, replaceRepresentationCommand.Representation.ExternalId, mainSchema, extensionSchemas); var allExistingAttributes = existingRepresentation.HierarchicalAttributes; existingRepresentation.RemoveAttributesBySchemaAttrId(updatedRepresentation.FlatAttributes.Select(_ => _.SchemaAttribute.Id)); foreach (var kvp in updatedRepresentation.HierarchicalAttributes.GroupBy(h => h.FullPath)) { var fullPath = kvp.Key; var filteredExistingAttributes = allExistingAttributes.Where(a => a.FullPath == fullPath); var invalidAttrs = filteredExistingAttributes.Where(fa => !kvp.Any(a => a.IsMutabilityValid(fa))); if (invalidAttrs.Any()) { throw new SCIMImmutableAttributeException(string.Format(Global.AttributeImmutable, string.Join(",", invalidAttrs.Select(a => a.FullPath)))); } foreach (var rootAttr in kvp) { if (rootAttr.SchemaAttribute.Mutability == SCIMSchemaAttributeMutabilities.WRITEONLY || rootAttr.SchemaAttribute.Mutability == SCIMSchemaAttributeMutabilities.READWRITE || rootAttr.SchemaAttribute.Mutability == SCIMSchemaAttributeMutabilities.IMMUTABLE) { var flatAttrs = rootAttr.ToFlat(); foreach (var attr in flatAttrs) { existingRepresentation.AddAttribute(attr); } } } } existingRepresentation.SetDisplayName(updatedRepresentation.DisplayName); existingRepresentation.SetExternalId(updatedRepresentation.ExternalId); existingRepresentation.SetUpdated(DateTime.UtcNow); var isReferenceProperty = await _representationReferenceSync.IsReferenceProperty(replaceRepresentationCommand.Representation.Attributes.GetKeys()); var references = await _representationReferenceSync.Sync(replaceRepresentationCommand.ResourceType, oldRepresentation, existingRepresentation, replaceRepresentationCommand.Location, !isReferenceProperty); using (var transaction = await _scimRepresentationCommandRepository.StartTransaction()) { await _scimRepresentationCommandRepository.Update(existingRepresentation); foreach (var reference in references.Representations) { await _scimRepresentationCommandRepository.Update(reference); } await transaction.Commit(); } await Notify(references); existingRepresentation.ApplyEmptyArray(); return(existingRepresentation); } finally { await _distributedLock.ReleaseLock(lockName, CancellationToken.None); } }