Esempio n. 1
0
        public static JObject ToResponse(this SCIMRepresentation representation, string location, bool isGetRequest = false)
        {
            var meta = new JObject
            {
                { SCIMConstants.StandardSCIMMetaAttributes.ResourceType, representation.ResourceType },
                { SCIMConstants.StandardSCIMMetaAttributes.Created, representation.Created },
                { SCIMConstants.StandardSCIMMetaAttributes.LastModified, representation.LastModified },
                { SCIMConstants.StandardSCIMMetaAttributes.Version, representation.Version },
                { SCIMConstants.StandardSCIMMetaAttributes.Location, location }
            };
            var jObj = new JObject
            {
                { SCIMConstants.StandardSCIMRepresentationAttributes.Id, representation.Id },
                { SCIMConstants.StandardSCIMRepresentationAttributes.Schemas, new JArray(representation.Schemas.Select(s => s.Id)) },
                { SCIMConstants.StandardSCIMRepresentationAttributes.Meta, meta }
            };

            if (!string.IsNullOrWhiteSpace(representation.ExternalId))
            {
                jObj.Add(SCIMConstants.StandardSCIMRepresentationAttributes.ExternalId, representation.ExternalId);
            }

            EnrichResponse(representation.Attributes.AsQueryable(), jObj, isGetRequest);
            return(jObj);
        }
        public static void FilterAttributes(this SCIMRepresentation representation, IEnumerable <SCIMAttributeExpression> includedAttributes, IEnumerable <SCIMAttributeExpression> excludedAttributes)
        {
            var allAttributes = new List <SCIMRepresentationAttribute>();

            allAttributes.AddRange(representation.FlatAttributes);
            allAttributes.AddRange(representation.HierarchicalAttributes);
            var queryableAttributes = representation.FlatAttributes.AsQueryable();

            if (includedAttributes != null && includedAttributes.Any())
            {
                var attrs = queryableAttributes.FilterAttributes(includedAttributes).ToList();
                var includedFullPathLst = (includedAttributes != null && includedAttributes.Any()) ? includedAttributes.Where(i => i is SCIMComplexAttributeExpression).Select(i => i.GetFullPath()) : new List <string>();
                representation.FlatAttributes = attrs.Where(a => a != null).SelectMany(_ =>
                {
                    var lst = new List <SCIMRepresentationAttribute> {
                        _
                    };
                    lst.AddRange(_.Children.Where(c => includedFullPathLst.Any(f => c.FullPath.StartsWith(f))));
                    return(lst);
                }).ToList();
            }
            else if (excludedAttributes != null && excludedAttributes.Any())
            {
                representation.FlatAttributes = queryableAttributes.FilterAttributes(excludedAttributes, false).ToList();
            }
        }
        public static JObject ToResponse(this SCIMRepresentation representation, string location, bool isGetRequest = false, bool includeStandardAttributes = true, bool addEmptyArray = false)
        {
            var jObj = new JObject
            {
                { StandardSCIMRepresentationAttributes.Id, representation.Id }
            };

            if (includeStandardAttributes)
            {
                representation.AddStandardAttributes(location, new List <string> {
                }, ignore: true);
            }

            if (addEmptyArray)
            {
                representation.ApplyEmptyArray();
            }

            var attributes = representation.HierarchicalAttributes.Select(a =>
            {
                var schema = representation.GetSchema(a);
                var order  = 1;
                if (schema != null && schema.IsRootSchema)
                {
                    order = 0;
                }

                return(new EnrichParameter(schema, order, a));
            });

            EnrichResponse(attributes, jObj, isGetRequest);
            return(jObj);
        }
        public static JObject ToResponse(this SCIMRepresentation representation, string location, bool isGetRequest = false)
        {
            var jObj = new JObject
            {
                { SCIMConstants.StandardSCIMRepresentationAttributes.Id, representation.Id },
                { SCIMConstants.StandardSCIMRepresentationAttributes.Schemas, new JArray(representation.Schemas.Select(s => s.Id)) }
            };

            EnrichResponse(representation.Attributes.AsQueryable(), jObj, isGetRequest);
            var metaObj = (JObject)jObj.SelectToken(SCIMConstants.StandardSCIMRepresentationAttributes.Meta);

            if (metaObj == null)
            {
                jObj.Add(SCIMConstants.StandardSCIMRepresentationAttributes.Meta, new JObject
                {
                    { SCIMConstants.StandardSCIMMetaAttributes.Location, location }
                });
            }
            else
            {
                metaObj.Add(SCIMConstants.StandardSCIMMetaAttributes.Location, location);
            }

            return(jObj);
        }
Esempio n. 5
0
        public static JObject ToResponseWithExcludedAttributes(this SCIMRepresentation representation, ICollection <SCIMExpression> excludedAttributes, string location)
        {
            var result = (SCIMRepresentation)representation.Clone();

            foreach (var excludedAttribute in excludedAttributes)
            {
                var attributes = GetRepresentationAttributeFromPath(result.Attributes.AsQueryable(), excludedAttribute).ToList();
                foreach (var attr in attributes)
                {
                    if (attr.Parent != null)
                    {
                        attr.Parent.Values.Remove(attr);
                    }
                    else
                    {
                        result.Attributes.Remove(attr);
                    }
                }
            }

            var jObj = result.ToResponse(location, true);

            foreach (var excludedAttribute in excludedAttributes)
            {
                var fullPath = (excludedAttribute as SCIMAttributeExpression).GetFullPath();
                if (COMMNON_PROPERTY_NAMES.Contains(fullPath))
                {
                    jObj.SelectToken(fullPath).Parent.Remove();
                }
            }

            return(jObj);
        }
        public static JObject ToResponseWithIncludedAttributes(this SCIMRepresentation representation, ICollection <SCIMExpression> includedAttributes)
        {
            var result = new JObject();

            foreach (var includedAttribute in includedAttributes)
            {
                representation.IncludeAttribute(includedAttribute, result);
            }

            return(result);
        }
Esempio n. 7
0
        private static void IncludeAttribute(this SCIMRepresentation scimRepresentation, SCIMExpression scimExpression, JObject result)
        {
            var scimAttributeExpression = scimExpression as SCIMAttributeExpression;

            if (scimAttributeExpression == null)
            {
                throw new SCIMAttributeException(Global.InvalidAttributeExpression);
            }

            IncludeAttribute(scimAttributeExpression, scimRepresentation.Attributes.AsQueryable(), result);
            var fullPath = scimAttributeExpression.GetFullPath();

            if (!COMMNON_PROPERTY_NAMES.Contains(fullPath))
            {
                return;
            }

            if (fullPath == SCIMConstants.StandardSCIMRepresentationAttributes.Id)
            {
                result.Add(SCIMConstants.StandardSCIMRepresentationAttributes.Id, scimRepresentation.Id);
            }
            else if (fullPath == SCIMConstants.StandardSCIMRepresentationAttributes.ExternalId)
            {
                result.Add(SCIMConstants.StandardSCIMRepresentationAttributes.ExternalId, scimRepresentation.ExternalId);
            }
            else if (fullPath == $"{SCIMConstants.StandardSCIMRepresentationAttributes.Meta}.{SCIMConstants.StandardSCIMMetaAttributes.ResourceType}")
            {
                result.Add(SCIMConstants.StandardSCIMRepresentationAttributes.Meta, new JObject
                {
                    { SCIMConstants.StandardSCIMMetaAttributes.ResourceType, scimRepresentation.ResourceType }
                });
            }
            else if (fullPath == $"{SCIMConstants.StandardSCIMRepresentationAttributes.Meta}.{SCIMConstants.StandardSCIMMetaAttributes.Created}")
            {
                result.Add(SCIMConstants.StandardSCIMRepresentationAttributes.Meta, new JObject
                {
                    { SCIMConstants.StandardSCIMMetaAttributes.Created, scimRepresentation.Created }
                });
            }
            else if (fullPath == $"{SCIMConstants.StandardSCIMRepresentationAttributes.Meta}.{SCIMConstants.StandardSCIMMetaAttributes.LastModified}")
            {
                result.Add(SCIMConstants.StandardSCIMRepresentationAttributes.Meta, new JObject
                {
                    { SCIMConstants.StandardSCIMMetaAttributes.LastModified, scimRepresentation.LastModified }
                });
            }
            else if (fullPath == $"{SCIMConstants.StandardSCIMRepresentationAttributes.Meta}.{SCIMConstants.StandardSCIMMetaAttributes.Version}")
            {
                result.Add(SCIMConstants.StandardSCIMRepresentationAttributes.Meta, new JObject
                {
                    { SCIMConstants.StandardSCIMMetaAttributes.Version, scimRepresentation.Version }
                });
            }
        }
        private static void IncludeAttribute(this SCIMRepresentation scimRepresentation, SCIMExpression scimExpression, JObject result)
        {
            var scimAttributeExpression = scimExpression as SCIMAttributeExpression;

            if (scimAttributeExpression == null)
            {
                throw new SCIMAttributeException("not a valid attribute expression");
            }

            IncludeAttribute(scimAttributeExpression, scimRepresentation.Attributes.AsQueryable(), result);
        }
        public static void ApplyPatches(this SCIMRepresentation representation, ICollection <SCIMPatchOperationRequest> patches)
        {
            var queryableRepresentationAttributes = representation.Attributes.AsQueryable();

            foreach (var patch in patches)
            {
                var attributes = GetRepresentationAttributeFromPath(queryableRepresentationAttributes, SCIMFilterParser.Parse(patch.Path, representation.Schemas)).ToList();
                if (!attributes.Any())
                {
                    throw new SCIMAttributeException("PATCH can be applied only on existing attributes");
                }

                var removeCallback = new Action <ICollection <SCIMRepresentationAttribute> >((attrs) =>
                {
                    foreach (var a in attrs)
                    {
                        if (a.Parent != null)
                        {
                            a.Parent.Values.Remove(a);
                        }
                        else
                        {
                            representation.Attributes.Remove(a);
                        }
                    }
                });
                if (patch.Operation == SCIMPatchOperations.REMOVE || patch.Operation == SCIMPatchOperations.REPLACE)
                {
                    removeCallback(attributes);
                }

                if (patch.Operation == SCIMPatchOperations.ADD)
                {
                    removeCallback(attributes.Where(a => !a.SchemaAttribute.MultiValued).ToList());
                }

                if (patch.Operation == SCIMPatchOperations.ADD || patch.Operation == SCIMPatchOperations.REPLACE)
                {
                    var firstAttribute = attributes.First();
                    var newAttributes  = ExtractRepresentationAttributesFromJSON(firstAttribute.SchemaAttribute, patch.Value);
                    foreach (var newAttribute in newAttributes)
                    {
                        if (firstAttribute.Parent != null)
                        {
                            firstAttribute.Parent.Values.Add(newAttribute);
                        }
                        else
                        {
                            representation.Attributes.Add(newAttribute);
                        }
                    }
                }
            }
        }
        private static void CheckDuplicate(IEnumerable <SCIMRepresentationAttribute> existingAttributes, ICollection <SCIMRepresentationAttribute> newFlatAttributes)
        {
            var rootAttributes = SCIMRepresentation.BuildHierarchicalAttributes(newFlatAttributes);

            foreach (var newAttribute in rootAttributes)
            {
                if (existingAttributes.Any(a => a.IsSimilar(newAttribute, true)))
                {
                    throw new SCIMDuplicateAttributeException(string.Format(Global.AttributeMustBeUnique, newAttribute.FullPath));
                }
            }
        }
        public static void ApplyEmptyArray(this SCIMRepresentation representation)
        {
            var attrs = representation.Schemas.SelectMany(s => s.Attributes.Where(a => a.MultiValued));

            foreach (var attr in attrs)
            {
                if (!representation.Attributes.Any(a => a.SchemaAttribute.Name == attr.Name))
                {
                    representation.Attributes.Add(new SCIMRepresentationAttribute {
                        SchemaAttribute = attr
                    });
                }
            }
        }
 public static void ApplyEmptyArray(this SCIMRepresentation representation)
 {
     foreach (var schema in representation.Schemas)
     {
         var attrs = schema.HierarchicalAttributes.Select(a => a.Leaf).Where(a => a.MultiValued);
         foreach (var attr in attrs)
         {
             if (!representation.FlatAttributes.Any(a => a.SchemaAttribute.Name == attr.Name))
             {
                 representation.FlatAttributes.Add(new SCIMRepresentationAttribute(Guid.NewGuid().ToString(), Guid.NewGuid().ToString(), attr, schema.Id));
             }
         }
     }
 }
        public static JObject ToResponse(this SCIMRepresentation representation, string location, bool isGetRequest = false)
        {
            var meta = new JObject
            {
                { SCIMConstants.StandardSCIMMetaAttributes.ResourceType, representation.ResourceType },
                { SCIMConstants.StandardSCIMMetaAttributes.Created, representation.Created },
                { SCIMConstants.StandardSCIMMetaAttributes.LastModified, representation.LastModified },
                { SCIMConstants.StandardSCIMMetaAttributes.Version, representation.Version }
            };

            if (!string.IsNullOrWhiteSpace(location))
            {
                meta.Add(SCIMConstants.StandardSCIMMetaAttributes.Location, location);
            }

            var jObj = new JObject
            {
                { SCIMConstants.StandardSCIMRepresentationAttributes.Id, representation.Id },
                { SCIMConstants.StandardSCIMRepresentationAttributes.Schemas, new JArray(representation.Schemas.Select(s => s.Id)) },
                { SCIMConstants.StandardSCIMRepresentationAttributes.Meta, meta }
            };

            if (!string.IsNullOrWhiteSpace(representation.ExternalId))
            {
                jObj.Add(SCIMConstants.StandardSCIMRepresentationAttributes.ExternalId, representation.ExternalId);
            }

            var attributes = representation.Attributes.Select(a =>
            {
                var schema = representation.GetSchema(a);
                int order  = 1;
                if (schema != null && schema.IsRootSchema)
                {
                    order = 0;
                }

                return(new EnrichParameter(schema, order, a));
            });

            EnrichResponse(attributes, jObj, isGetRequest);
            return(jObj);
        }
        private static void IncludeAttribute(SCIMRepresentation scimRepresentation, SCIMAttributeExpression scimExpression, IQueryable <SCIMRepresentationAttribute> attributes, JObject result)
        {
            var filteredAttributes = GetAttributes(scimExpression, attributes);

            if (!filteredAttributes.Any())
            {
                return;
            }

            if (scimExpression.Child != null)
            {
                foreach (var kvp in filteredAttributes.GroupBy(f => f.SchemaAttribute.Name))
                {
                    var representationAttr = kvp.First();
                    if (representationAttr.SchemaAttribute.MultiValued == false)
                    {
                        var jObjVal = new JObject();
                        IncludeAttribute(scimRepresentation, scimExpression.Child, representationAttr.Values.AsQueryable(), jObjVal);
                        result.Add(representationAttr.SchemaAttribute.Name, jObjVal);
                    }
                    else
                    {
                        var jArr = new JArray();
                        foreach (var attr in kvp)
                        {
                            var jObjVal = new JObject();
                            IncludeAttribute(scimRepresentation, scimExpression.Child, attr.Values.AsQueryable(), jObjVal);
                            jArr.Add(jObjVal);
                        }

                        result.Add(representationAttr.SchemaAttribute.Name, jArr);
                    }
                }

                return;
            }

            var enrichParameters = filteredAttributes.Select(at => new EnrichParameter(scimRepresentation.GetSchema(at), 0, at));

            EnrichResponse(enrichParameters, result);
        }
        public static JObject ToResponseWithExcludedAttributes(this SCIMRepresentation representation, ICollection <SCIMExpression> excludedAttributes, string location)
        {
            var result = (SCIMRepresentation)representation.Clone();

            foreach (var excludedAttribute in excludedAttributes)
            {
                var attributes = GetRepresentationAttributeFromPath(result.Attributes.AsQueryable(), excludedAttribute).ToList();
                foreach (var attr in attributes)
                {
                    if (attr.Parent != null)
                    {
                        attr.Parent.Values.Remove(attr);
                    }
                    else
                    {
                        result.Attributes.Remove(attr);
                    }
                }
            }

            return(result.ToResponse(location, true));
        }
        public static List <SCIMPatchResult> ApplyPatches(this SCIMRepresentation representation, ICollection <PatchOperationParameter> patches, bool ignoreUnsupportedCanonicalValues)
        {
            var result = new List <SCIMPatchResult>();

            foreach (var patch in patches)
            {
                var scimFilter       = SCIMFilterParser.Parse(patch.Path, representation.Schemas);
                var schemaAttributes = representation.Schemas.SelectMany(_ => _.Attributes);
                List <SCIMRepresentationAttribute> attributes = null;
                string fullPath = null;
                if (scimFilter != null)
                {
                    var scimAttributeExpression = scimFilter as SCIMAttributeExpression;
                    if (scimAttributeExpression == null)
                    {
                        throw new SCIMAttributeException(Global.InvalidAttributeExpression);
                    }

                    fullPath         = scimAttributeExpression.GetFullPath();
                    schemaAttributes = representation.Schemas
                                       .Select(s => s.GetAttribute(fullPath))
                                       .Where(s => s != null);

                    attributes = scimAttributeExpression.EvaluateAttributes(representation.HierarchicalAttributes.AsQueryable(), true).ToList();
                }
                else
                {
                    attributes = representation.FlatAttributes.Where(h => h.IsLeaf()).ToList();
                }

                var removeCallback = new Action <ICollection <SCIMRepresentationAttribute> >((attrs) =>
                {
                    foreach (var a in attrs)
                    {
                        var removedAttrs = representation.RemoveAttributeById(a);
                        foreach (var removedAttr in removedAttrs)
                        {
                            result.Add(new SCIMPatchResult {
                                Attr = removedAttr, Operation = SCIMPatchOperations.REMOVE, Path = removedAttr.FullPath
                            });
                        }
                    }
                });
                switch (patch.Operation)
                {
                case SCIMPatchOperations.ADD:
                    try
                    {
                        if (schemaAttributes == null || !schemaAttributes.Any())
                        {
                            throw new SCIMNoTargetException(string.Format(Global.AttributeIsNotRecognirzed, patch.Path));
                        }

                        var newAttributes = ExtractRepresentationAttributesFromJSON(representation.Schemas, schemaAttributes.ToList(), patch.Value, ignoreUnsupportedCanonicalValues);
                        CheckDuplicate(attributes, newAttributes);
                        removeCallback(attributes.Where(a => !a.SchemaAttribute.MultiValued && a.FullPath == fullPath).ToList());
                        var isAttributeExits = !string.IsNullOrWhiteSpace(fullPath) && attributes.Any(a => a.FullPath == fullPath);
                        foreach (var newAttribute in newAttributes.OrderBy(a => a.GetLevel()))
                        {
                            var path       = newAttribute.FullPath;
                            var schemaAttr = newAttribute.SchemaAttribute;
                            IEnumerable <SCIMRepresentationAttribute> parentAttributes = null;
                            if (fullPath == path)
                            {
                                var attr = attributes.FirstOrDefault(a => a.FullPath == fullPath);
                                if (attr != null)
                                {
                                    var parent = representation.GetParentAttribute(attr);
                                    if (parent != null)
                                    {
                                        parentAttributes = new[] { parent };
                                    }
                                }
                                else
                                {
                                    parentAttributes = representation.GetParentAttributesByPath(fullPath).ToList();
                                }
                            }

                            if (schemaAttr.MultiValued && schemaAttr.Type != SCIMSchemaAttributeTypes.COMPLEX)
                            {
                                var filteredAttribute = attributes.FirstOrDefault(_ => _.FullPath == path);
                                if (filteredAttribute != null)
                                {
                                    newAttribute.AttributeId = filteredAttribute.AttributeId;
                                }

                                representation.AddAttribute(newAttribute);
                            }
                            else if (parentAttributes != null && parentAttributes.Any())
                            {
                                foreach (var parentAttribute in parentAttributes)
                                {
                                    representation.AddAttribute(parentAttribute, newAttribute);
                                }
                            }
                            else
                            {
                                representation.FlatAttributes.Add(newAttribute);
                            }

                            attributes.Add(newAttribute);
                            result.Add(new SCIMPatchResult {
                                Attr = newAttribute, Operation = SCIMPatchOperations.ADD, Path = fullPath
                            });
                        }

                        if (TryGetExternalId(patch, out string externalId))
                        {
                            representation.ExternalId = externalId;
                        }
                    }
                    catch (SCIMSchemaViolatedException)
                    {
                        continue;
                    }
                    break;

                case SCIMPatchOperations.REMOVE:
                {
                    if (scimFilter == null)
                    {
                        throw new SCIMNoTargetException(string.Format(Global.InvalidPath, patch.Path));
                    }

                    if (SCIMFilterParser.DontContainsFilter(patch.Path) && patch.Value != null)
                    {
                        var excludedAttributes = ExtractRepresentationAttributesFromJSON(representation.Schemas, schemaAttributes.ToList(), patch.Value, ignoreUnsupportedCanonicalValues);
                        excludedAttributes = SCIMRepresentation.BuildHierarchicalAttributes(excludedAttributes);
                        attributes         = attributes.Where(a => excludedAttributes.Any(ea => ea.IsSimilar(a, true))).ToList();
                    }

                    removeCallback(attributes);
                }
                break;

                case SCIMPatchOperations.REPLACE:
                {
                    if (TryGetExternalId(patch, out string externalId))
                    {
                        representation.ExternalId = externalId;
                        continue;
                    }

                    if (schemaAttributes == null || !schemaAttributes.Any())
                    {
                        throw new SCIMNoTargetException(string.Format(Global.AttributeIsNotRecognirzed, patch.Path));
                    }

                    var complexAttr = scimFilter as SCIMComplexAttributeExpression;
                    if (complexAttr != null && !attributes.Any() && complexAttr.GroupingFilter != null)
                    {
                        throw new SCIMNoTargetException(Global.PatchMissingAttribute);
                    }

                    try
                    {
                        List <SCIMRepresentationAttribute> parents = new List <SCIMRepresentationAttribute>();
                        if (complexAttr != null)
                        {
                            var attr   = attributes.First(a => a.FullPath == fullPath);
                            var parent = string.IsNullOrWhiteSpace(attr.ParentAttributeId) ? attr : representation.GetParentAttribute(attributes.First(a => a.FullPath == fullPath));
                            if (parent != null)
                            {
                                parents = new List <SCIMRepresentationAttribute> {
                                    parent
                                };
                            }
                        }
                        else
                        {
                            parents = representation.GetParentAttributesByPath(fullPath).ToList();
                        }

                        if (scimFilter != null && parents.Any())
                        {
                            foreach (var parent in parents)
                            {
                                var flatHiearchy            = representation.GetFlatHierarchicalChildren(parent).ToList();
                                var scimAttributeExpression = scimFilter as SCIMAttributeExpression;
                                var newAttributes           = ExtractRepresentationAttributesFromJSON(representation.Schemas, schemaAttributes.ToList(), patch.Value, ignoreUnsupportedCanonicalValues);
                                foreach (var newAttribute in newAttributes.OrderBy(l => l.GetLevel()))
                                {
                                    if (!flatHiearchy.Any(a => a.FullPath == newAttribute.FullPath))
                                    {
                                        var parentPath = SCIMRepresentation.GetParentPath(newAttribute.FullPath);
                                        var p          = flatHiearchy.FirstOrDefault(a => a.FullPath == parentPath);
                                        if (p != null)
                                        {
                                            representation.AddAttribute(p, newAttribute);
                                        }
                                        else
                                        {
                                            representation.AddAttribute(newAttribute);
                                        }

                                        result.Add(new SCIMPatchResult {
                                                Attr = newAttribute, Operation = SCIMPatchOperations.ADD, Path = fullPath
                                            });
                                    }
                                }

                                result.AddRange(Merge(flatHiearchy, newAttributes, fullPath));
                            }
                        }
                        else
                        {
                            var newAttributes     = ExtractRepresentationAttributesFromJSON(representation.Schemas, schemaAttributes.ToList(), patch.Value, ignoreUnsupportedCanonicalValues);
                            var flatHiearchy      = representation.FlatAttributes.ToList();
                            var missingAttributes = newAttributes.Where(na => string.IsNullOrEmpty(na.ParentAttributeId) && !flatHiearchy.Any(fh => string.IsNullOrWhiteSpace(fh.ParentAttributeId) && fh.SchemaAttributeId == na.SchemaAttributeId)).ToList();
                            missingAttributes.ForEach((ma) =>
                                {
                                    representation.AddAttribute(ma);
                                    result.Add(new SCIMPatchResult {
                                        Attr = ma, Operation = SCIMPatchOperations.ADD, Path = ma.FullPath
                                    });
                                });
                            result.AddRange(Merge(flatHiearchy, newAttributes, fullPath));
                        }
                    }
                    catch (SCIMSchemaViolatedException)
                    {
                        continue;
                    }
                }
                break;
                }
            }

            var displayNameAttr = representation.FlatAttributes.FirstOrDefault(a => a.FullPath == "displayName");

            if (displayNameAttr != null)
            {
                representation.SetDisplayName(displayNameAttr.ValueString);
            }

            return(result);
        }
        public static void ApplyPatches(this SCIMRepresentation representation, ICollection <PatchOperationParameter> patches, bool ignoreUnsupportedCanonicalValues)
        {
            var queryableRepresentationAttributes = representation.Attributes.AsQueryable();

            foreach (var patch in patches)
            {
                var scimFilter          = SCIMFilterParser.Parse(patch.Path, representation.Schemas);
                var attributeExpression = scimFilter as SCIMAttributeExpression;
                var schemaAttributes    = representation.Schemas.SelectMany(_ => _.Attributes);
                List <SCIMRepresentationAttribute> attributes = null;
                string fullPath = null;
                if (attributeExpression != null)
                {
                    fullPath         = attributeExpression.GetFullPath();
                    schemaAttributes = representation.Schemas
                                       .Select(s => s.GetAttribute(fullPath))
                                       .Where(s => s != null);
                    attributes = GetRepresentationAttributeFromPath(queryableRepresentationAttributes, scimFilter).ToList();
                }
                else
                {
                    attributes = queryableRepresentationAttributes.ToList();
                }

                var removeCallback = new Func <ICollection <SCIMRepresentationAttribute>, List <SCIMRepresentationAttribute> >((attrs) =>
                {
                    var result = new List <SCIMRepresentationAttribute>();
                    foreach (var a in attrs)
                    {
                        if (a.Parent != null)
                        {
                            a.Parent.Values.Remove(a);
                            result.Add(a.Parent);
                        }
                        else
                        {
                            representation.Attributes.Remove(a);
                        }
                    }

                    return(result);
                });



                switch (patch.Operation)
                {
                case SCIMPatchOperations.ADD:
                    try
                    {
                        // If the target location already contains the value then do nothing ...
                        if (schemaAttributes == null || !schemaAttributes.Any())
                        {
                            throw new SCIMNoTargetException(string.Format(Global.AttributeIsNotRecognirzed, patch.Path));
                        }

                        var newAttributes = ExtractRepresentationAttributesFromJSON(representation.Schemas, schemaAttributes.ToList(), patch.Value, ignoreUnsupportedCanonicalValues);
                        var parentAttrs   = removeCallback(attributes.Where(a => !a.SchemaAttribute.MultiValued && newAttributes.Any(_ => _.SchemaAttribute.Name == a.SchemaAttribute.Name)).ToList());
                        foreach (var newAttribute in newAttributes.Where(x => x.HasValue))
                        {
                            var path            = string.IsNullOrWhiteSpace(fullPath) ? newAttribute.SchemaAttribute.Name : fullPath;
                            var schemaAttr      = newAttribute.SchemaAttribute;
                            var parentAttribute = representation.GetParentAttribute(path);
                            if (schemaAttr.MultiValued && schemaAttr.Type != SCIMSchemaAttributeTypes.COMPLEX)
                            {
                                var filteredAttributes = attributes.Where(_ => _.GetFullPath() == path);
                                foreach (var attribute in filteredAttributes)
                                {
                                    if (schemaAttr.Type == SCIMSchemaAttributeTypes.BOOLEAN)
                                    {
                                        foreach (var b in newAttribute.ValuesBoolean)
                                        {
                                            attribute.ValuesBoolean.Add(b);
                                        }
                                    }
                                    else if (schemaAttr.Type == SCIMSchemaAttributeTypes.DATETIME)
                                    {
                                        foreach (var d in newAttribute.ValuesDateTime)
                                        {
                                            attribute.ValuesDateTime.Add(d);
                                        }
                                    }
                                    else if (schemaAttr.Type == SCIMSchemaAttributeTypes.INTEGER)
                                    {
                                        foreach (var i in newAttribute.ValuesInteger)
                                        {
                                            attribute.ValuesInteger.Add(i);
                                        }
                                    }
                                    else if (schemaAttr.Type == SCIMSchemaAttributeTypes.REFERENCE)
                                    {
                                        foreach (var r in newAttribute.ValuesReference)
                                        {
                                            attribute.ValuesReference.Add(r);
                                        }
                                    }
                                    else if (schemaAttr.Type == SCIMSchemaAttributeTypes.STRING)
                                    {
                                        foreach (var s in newAttribute.ValuesString)
                                        {
                                            attribute.ValuesString.Add(s);
                                        }
                                    }
                                    else if (schemaAttr.Type == SCIMSchemaAttributeTypes.DECIMAL)
                                    {
                                        foreach (var d in newAttribute.ValuesDecimal)
                                        {
                                            attribute.ValuesDecimal.Add(d);
                                        }
                                    }
                                    else if (schemaAttr.Type == SCIMSchemaAttributeTypes.BINARY)
                                    {
                                        foreach (var b in newAttribute.ValuesBinary)
                                        {
                                            attribute.ValuesBinary.Add(b);
                                        }
                                    }
                                }
                            }
                            else if (parentAttribute != null)
                            {
                                if (parentAttrs.Any())
                                {
                                    foreach (var parentAttr in parentAttrs)
                                    {
                                        parentAttr.Add(newAttribute);
                                    }
                                }
                                else
                                {
                                    parentAttribute.Add(newAttribute);
                                }
                            }
                            else
                            {
                                if (!representation.ContainsAttribute(newAttribute))
                                {
                                    representation.Attributes.Add(newAttribute);
                                }
                            }
                        }
                    }
                    catch (SCIMSchemaViolatedException)
                    {
                        continue;
                    }
                    break;

                case SCIMPatchOperations.REMOVE:
                {
                    if (attributeExpression == null)
                    {
                        throw new SCIMNoTargetException(string.Format(Global.InvalidPath, patch.Path));
                    }

                    removeCallback(attributes);
                }
                break;

                case SCIMPatchOperations.REPLACE:
                {
                    if (schemaAttributes == null || !schemaAttributes.Any())
                    {
                        throw new SCIMNoTargetException(string.Format(Global.AttributeIsNotRecognirzed, patch.Path));
                    }

                    var complexAttr = attributeExpression as SCIMComplexAttributeExpression;
                    if (complexAttr != null && !attributes.Any() && complexAttr.GroupingFilter != null)
                    {
                        throw new SCIMNoTargetException(Global.PatchMissingAttribute);
                    }

                    try
                    {
                        var newAttributes  = ExtractRepresentationAttributesFromJSON(representation.Schemas, schemaAttributes.ToList(), patch.Value, ignoreUnsupportedCanonicalValues);
                        var parentFullPath = attributes.First().Parent?.GetFullPath();
                        if (!string.IsNullOrWhiteSpace(parentFullPath))
                        {
                            scimFilter = SCIMFilterParser.Parse(parentFullPath, representation.Schemas);
                            var allAttrs = GetRepresentationAttributeFromPath(queryableRepresentationAttributes, scimFilter);
                            foreach (var attr in allAttrs)
                            {
                                if (!attr.Values.Any(_ => attributes.Any(a => a.SchemaAttribute.Name == _.SchemaAttribute.Name)))
                                {
                                    attr.Add(attributes.First());
                                }
                            }
                        }

                        Merge(attributes, newAttributes);
                    }
                    catch (SCIMSchemaViolatedException)
                    {
                        continue;
                    }
                }
                break;
                }
            }
        }
Esempio n. 18
0
        public static void ApplyPatches(this SCIMRepresentation representation, ICollection <PatchOperationParameter> patches, bool ignoreUnsupportedCanonicalValues)
        {
            var queryableRepresentationAttributes = representation.Attributes.AsQueryable();

            foreach (var patch in patches)
            {
                var scimFilter          = SCIMFilterParser.Parse(patch.Path, representation.Schemas);
                var attributeExpression = scimFilter as SCIMAttributeExpression;
                if (attributeExpression == null)
                {
                    throw new SCIMAttributeException(string.Format(Global.InvalidPath, patch.Path));
                }

                var fullPath         = attributeExpression.GetFullPath();
                var schemaAttributes = representation.Schemas.Select(s => s.GetAttribute(fullPath)).Where(s => s != null);
                if (!schemaAttributes.Any())
                {
                    throw new SCIMAttributeException(string.Format(Global.UnknownPath, patch.Path));
                }

                var schemaAttribute = schemaAttributes.First();
                var attributes      = GetRepresentationAttributeFromPath(queryableRepresentationAttributes, scimFilter).ToList();
                if (!attributes.Any() && schemaAttribute.Type != SCIMSchemaAttributeTypes.COMPLEX && !schemaAttribute.MultiValued)
                {
                    throw new SCIMAttributeException(Global.PatchMissingAttribute);
                }

                var removeCallback = new Action <ICollection <SCIMRepresentationAttribute> >((attrs) =>
                {
                    foreach (var a in attrs)
                    {
                        if (a.Parent != null)
                        {
                            a.Parent.Values.Remove(a);
                        }
                        else
                        {
                            representation.Attributes.Remove(a);
                        }
                    }
                });
                if (patch.Operation == SCIMPatchOperations.REMOVE || patch.Operation == SCIMPatchOperations.REPLACE)
                {
                    removeCallback(attributes);
                }

                if (patch.Operation == SCIMPatchOperations.ADD)
                {
                    removeCallback(attributes.Where(a => !a.SchemaAttribute.MultiValued).ToList());
                }

                if (patch.Operation == SCIMPatchOperations.ADD || patch.Operation == SCIMPatchOperations.REPLACE)
                {
                    var newAttributes = ExtractRepresentationAttributesFromJSON(schemaAttribute, patch.Value, ignoreUnsupportedCanonicalValues);
                    foreach (var newAttribute in newAttributes)
                    {
                        var parentAttribute = representation.GetParentAttribute(fullPath);
                        var attribute       = representation.GetAttribute(fullPath);
                        if (schemaAttribute.Type == SCIMSchemaAttributeTypes.COMPLEX && parentAttribute != null)
                        {
                            parentAttribute.Values.Add(newAttribute);
                            continue;
                        }

                        if (attribute != null && schemaAttribute.Type != SCIMSchemaAttributeTypes.COMPLEX)
                        {
                            if (schemaAttribute.Type == SCIMSchemaAttributeTypes.BOOLEAN)
                            {
                                foreach (var b in newAttribute.ValuesBoolean)
                                {
                                    attribute.ValuesBoolean.Add(b);
                                }
                            }
                            else if (schemaAttribute.Type == SCIMSchemaAttributeTypes.DATETIME)
                            {
                                foreach (var d in newAttribute.ValuesDateTime)
                                {
                                    attribute.ValuesDateTime.Add(d);
                                }
                            }
                            else if (schemaAttribute.Type == SCIMSchemaAttributeTypes.INTEGER)
                            {
                                foreach (var i in newAttribute.ValuesInteger)
                                {
                                    attribute.ValuesInteger.Add(i);
                                }
                            }
                            else if (schemaAttribute.Type == SCIMSchemaAttributeTypes.REFERENCE)
                            {
                                foreach (var r in newAttribute.ValuesReference)
                                {
                                    attribute.ValuesReference.Add(r);
                                }
                            }
                            else if (schemaAttribute.Type == SCIMSchemaAttributeTypes.STRING)
                            {
                                foreach (var s in newAttribute.ValuesString)
                                {
                                    attribute.ValuesString.Add(s);
                                }
                            }
                            else if (schemaAttribute.Type == SCIMSchemaAttributeTypes.DECIMAL)
                            {
                                foreach (var d in newAttribute.ValuesDecimal)
                                {
                                    attribute.ValuesDecimal.Add(d);
                                }
                            }
                            else if (schemaAttribute.Type == SCIMSchemaAttributeTypes.BINARY)
                            {
                                foreach (var b in newAttribute.ValuesBinary)
                                {
                                    attribute.ValuesBinary.Add(b);
                                }
                            }
                        }
                        else
                        {
                            representation.Attributes.Add(newAttribute);
                        }
                    }
                }
            }
        }