public async Task <SCIMRepresentation> Handle(ReplaceRepresentationCommand replaceRepresentationCommand) { var requestedSchemas = replaceRepresentationCommand.Representation.GetSchemas(); if (!requestedSchemas.Any()) { throw new SCIMBadRequestException("invalidRequest", $"{SCIMConstants.StandardSCIMRepresentationAttributes.Schemas} attribute is missing"); } if (!replaceRepresentationCommand.SchemaIds.Any(s => requestedSchemas.Contains(s))) { throw new SCIMBadRequestException("invalidRequest", $"some schemas are not recognized by the endpoint"); } var schemas = await _scimSchemaQueryRepository.FindSCIMSchemaByIdentifiers(requestedSchemas); var unsupportedSchemas = requestedSchemas.Where(s => !schemas.Any(sh => sh.Id == s)); if (unsupportedSchemas.Any()) { throw new SCIMBadRequestException("invalidRequest", $"{string.Join(",", unsupportedSchemas)} schemas are unknown"); } var existingRepresentation = await _scimRepresentationQueryRepository.FindSCIMRepresentationById(replaceRepresentationCommand.Id); if (existingRepresentation == null) { throw new SCIMNotFoundException("notFound", "Resource does not exist"); } var updatedRepresentation = _scimRepresentationHelper.ExtractSCIMRepresentationFromJSON(replaceRepresentationCommand.Representation, schemas.ToList()); foreach (var updatedAttribute in updatedRepresentation.Attributes) { if (updatedAttribute.SchemaAttribute.Mutability == SCIMSchemaAttributeMutabilities.IMMUTABLE) { throw new SCIMImmutableAttributeException($"attribute {updatedAttribute.Id} is immutable"); } if (updatedAttribute.SchemaAttribute.Mutability == SCIMSchemaAttributeMutabilities.WRITEONLY || updatedAttribute.SchemaAttribute.Mutability == SCIMSchemaAttributeMutabilities.READWRITE) { var existingAttribute = existingRepresentation.Attributes.FirstOrDefault(a => a.SchemaAttribute.Id == updatedAttribute.SchemaAttribute.Id); if (existingAttribute == null) { existingRepresentation.AddAttribute(updatedAttribute); } else { existingRepresentation.Attributes.Remove(existingAttribute); existingRepresentation.AddAttribute(updatedAttribute); } } } existingRepresentation.SetUpdated(DateTime.UtcNow); _scimRepresentationCommandRepository.Update(existingRepresentation); await _scimRepresentationCommandRepository.SaveChanges(); return(existingRepresentation); }
public async Task <SCIMRepresentation> Handle(AddRepresentationCommand addRepresentationCommand) { var requestedSchemas = addRepresentationCommand.Representation.Schemas; if (!requestedSchemas.Any()) { throw new SCIMBadSyntaxException(string.Format(Global.AttributeMissing, SCIMConstants.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 version = Guid.NewGuid().ToString(); 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(version); scimRepresentation.SetResourceType(addRepresentationCommand.ResourceType); var uniqueServerAttributeIds = scimRepresentation.Attributes.Where(a => a.SchemaAttribute.MultiValued == false && a.SchemaAttribute.Uniqueness == SCIMSchemaAttributeUniqueness.SERVER); var uniqueGlobalAttributes = scimRepresentation.Attributes.Where(a => a.SchemaAttribute.MultiValued == false && a.SchemaAttribute.Uniqueness == SCIMSchemaAttributeUniqueness.GLOBAL); await CheckSCIMRepresentationExistsForGivenUniqueAttributes(uniqueServerAttributeIds, addRepresentationCommand.ResourceType); await CheckSCIMRepresentationExistsForGivenUniqueAttributes(uniqueGlobalAttributes); using (var transaction = await _scimRepresentationCommandRepository.StartTransaction()) { await _scimRepresentationCommandRepository.Add(scimRepresentation); await transaction.Commit(); } scimRepresentation.ApplyEmptyArray(); return(scimRepresentation); }
public async Task <SCIMRepresentation> Handle(ReplaceRepresentationCommand replaceRepresentationCommand) { var requestedSchemas = replaceRepresentationCommand.Representation.GetSchemas(); if (!requestedSchemas.Any()) { throw new SCIMBadSyntaxException(string.Format(Global.AttributeMissing, SCIMConstants.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 existingRepresentation = await _scimRepresentationQueryRepository.FindSCIMRepresentationById(replaceRepresentationCommand.Id); if (existingRepresentation == null) { throw new SCIMNotFoundException(string.Format(Global.ResourceNotFound, replaceRepresentationCommand.Id)); } var updatedRepresentation = _scimRepresentationHelper.ExtractSCIMRepresentationFromJSON(replaceRepresentationCommand.Representation, schemas.ToList()); existingRepresentation.RemoveAttributes(updatedRepresentation.Attributes.Select(_ => _.SchemaAttribute.Id)); foreach (var updatedAttribute in updatedRepresentation.Attributes) { if (updatedAttribute.SchemaAttribute.Mutability == SCIMSchemaAttributeMutabilities.IMMUTABLE) { throw new SCIMImmutableAttributeException(string.Format(Global.AttributeImmutable, updatedAttribute.Id)); } if (updatedAttribute.SchemaAttribute.Mutability == SCIMSchemaAttributeMutabilities.WRITEONLY || updatedAttribute.SchemaAttribute.Mutability == SCIMSchemaAttributeMutabilities.READWRITE) { existingRepresentation.AddAttribute(updatedAttribute); } } existingRepresentation.SetUpdated(DateTime.UtcNow); using (var transaction = await _scimRepresentationCommandRepository.StartTransaction()) { await _scimRepresentationCommandRepository.Update(existingRepresentation); await transaction.Commit(); } return(existingRepresentation); }
public async Task <SCIMRepresentation> Handle(AddRepresentationCommand addRepresentationCommand) { var requestedSchemas = addRepresentationCommand.Representation.GetSchemas(); if (!requestedSchemas.Any()) { throw new SCIMBadRequestException("invalidRequest", $"{SCIMConstants.StandardSCIMRepresentationAttributes.Schemas} attribute is missing"); } if (!addRepresentationCommand.SchemaIds.Any(s => requestedSchemas.Contains(s))) { throw new SCIMBadRequestException("invalidRequest", $"some schemas are not recognized by the endpoint"); } var schemas = await _scimSchemaQueryRepository.FindSCIMSchemaByIdentifiers(requestedSchemas); var unsupportedSchemas = requestedSchemas.Where(s => !schemas.Any(sh => sh.Id == s)); if (unsupportedSchemas.Any()) { throw new SCIMBadRequestException("invalidRequest", $"{string.Join(",", unsupportedSchemas)} schemas are unknown"); } var version = Guid.NewGuid().ToString(); var scimRepresentation = _scimRepresentationHelper.ExtractSCIMRepresentationFromJSON(addRepresentationCommand.Representation, schemas.ToList()); scimRepresentation.Id = Guid.NewGuid().ToString(); scimRepresentation.SetCreated(DateTime.UtcNow); scimRepresentation.SetUpdated(DateTime.UtcNow); scimRepresentation.SetVersion(version); scimRepresentation.SetResourceType(addRepresentationCommand.ResourceType); var uniqueServerAttributeIds = scimRepresentation.Attributes.Where(a => a.SchemaAttribute.MultiValued == false && a.SchemaAttribute.Uniqueness == SCIMSchemaAttributeUniqueness.SERVER); var uniqueGlobalAttributes = scimRepresentation.Attributes.Where(a => a.SchemaAttribute.MultiValued == false && a.SchemaAttribute.Uniqueness == SCIMSchemaAttributeUniqueness.GLOBAL); await CheckSCIMRepresentationExistsForGivenUniqueAttributes(uniqueServerAttributeIds, addRepresentationCommand.ResourceType); await CheckSCIMRepresentationExistsForGivenUniqueAttributes(uniqueGlobalAttributes); _scimRepresentationCommandRepository.Add(scimRepresentation); await _scimRepresentationCommandRepository.SaveChanges(); 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); } }