コード例 #1
0
        public override bool UpdateField(CSEntryChange csentry, object obj)
        {
            if (this.IsReadOnly)
            {
                return(false);
            }

            if (!csentry.HasAttributeChange(this.MmsAttributeName))
            {
                return(false);
            }

            AttributeModificationType modType = csentry.AttributeChanges[this.MmsAttributeName].ModificationType;
            object value = csentry.GetValueAdd <object>(this.MmsAttributeName);

            User user = obj as User;

            if (user == null)
            {
                throw new NotSupportedException("The provided object was not of a 'user' type");
            }

            if (value == null && !this.HasSchemaField(user))
            {
                return(false);
            }

            IDictionary <string, object> schema = this.GetOrCreateSchema(user, out bool created);

            if (modType == AttributeModificationType.Delete)
            {
                if (this.HasSchemaField(user))
                {
                    schema[this.FieldName] = Utilities.GetNullRepresentation(this.NullValueRepresentation);
                    Logger.WriteLine($"Deleting {this.MmsAttributeName}");
                    return(true);
                }

                return(false);
            }

            if (value == null)
            {
                value = Utilities.GetNullRepresentation(this.NullValueRepresentation);
            }
            else
            {
                value = this.ConvertToNativeGoogleFormat(value);
            }

            schema[this.FieldName] = value;
            Logger.WriteLine($"Set {this.MmsAttributeName} -> {value ?? "<null>"}");

            return(true);
        }
コード例 #2
0
        private void AddAttributeChange(AttributeModificationType type, AcmaSchemaAttribute attribute)
        {
            this.ValidateAttributeChangeType(type);

            switch (type)
            {
            case AttributeModificationType.Replace:
            case AttributeModificationType.Update:
            case AttributeModificationType.Delete:
            case AttributeModificationType.Add:
                this.AttributeChanges.Add(Utils.CreateAttributeChange(attribute.Name, type));
                break;

            case AttributeModificationType.Unconfigured:
            default:
                throw new UnknownOrUnsupportedModificationTypeException(type);
            }
        }
コード例 #3
0
        /// <summary>
        /// Creates a CSEntryChange of the specified modification type for the supplied MAObjectHologram
        /// </summary>
        /// <param name="maObject">The MAObjectHologram to create the CSEntryChange from</param>
        /// <param name="objectModificationType">The object modification type to apply</param>
        /// <returns>A new CSEntryChange object representing the current state of the specified MAObjectHologram </returns>
        public static AcmaCSEntryChange CreateCSEntryChangeFromMAObjectHologram(this MAObjectHologram maObject, ObjectModificationType objectModificationType)
        {
            AcmaCSEntryChange csentry = new AcmaCSEntryChange();

            csentry.ObjectModificationType = objectModificationType;
            csentry.DN         = maObject.ObjectID.ToString();
            csentry.ObjectType = maObject.ObjectClass.Name;

            if (objectModificationType != ObjectModificationType.Delete)
            {
                AttributeModificationType attributeModificationType = objectModificationType == ObjectModificationType.Update ? AttributeModificationType.Replace : AttributeModificationType.Add;

                foreach (AcmaSchemaAttribute attribute in maObject.ObjectClass.Attributes.Where(t => t.Name != "objectId" && t.Name != "objectClass"))
                {
                    AttributeValues values = maObject.GetAttributeValues(attribute);

                    if (values.IsEmptyOrNull)
                    {
                        continue;
                    }

                    if (attributeModificationType == AttributeModificationType.Add)
                    {
                        AttributeChange change = AttributeChange.CreateAttributeAdd(attribute.Name, values.ToObjectList());
                        csentry.AttributeChanges.Add(AttributeChange.CreateAttributeAdd(attribute.Name, values.ToObjectList()));
                    }
                    else
                    {
                        csentry.AttributeChanges.Add(AttributeChange.CreateAttributeReplace(attribute.Name, values.ToObjectList()));
                    }
                }
            }

            if (csentry.ErrorCodeImport == MAImportError.Success)
            {
                MAStatistics.AddImportOperation();
            }
            else
            {
                MAStatistics.AddImportError();
            }

            return(csentry);
        }
コード例 #4
0
 /// <summary>
 /// Creates an AttributeChange of the specified type, provided that the attribute is present in the provided schema type
 /// </summary>
 /// <param name="csentry">The CSEntryChange to add the AttributeChange to</param>
 /// <param name="type">The schema type of the object class of the CSEntryChange</param>
 /// <param name="attributeName">The name of the attribute</param>
 /// <param name="modificationType">The type of modification to apply to the attribute</param>
 /// <param name="value">The value to apply to the modification operation</param>
 public static void CreateAttributeChangeIfInSchema(this CSEntryChange csentry, SchemaType type, string attributeName, AttributeModificationType modificationType, byte[] value)
 {
     csentry.CreateAttributeChangeIfInSchemaInternal(type, attributeName, modificationType, value);
 }
コード例 #5
0
 /// <summary>
 /// Creates an AttributeChange of the specified type, provided that the attribute is present in the provided schema type
 /// </summary>
 /// <param name="csentry">The CSEntryChange to add the AttributeChange to</param>
 /// <param name="type">The schema type of the object class of the CSEntryChange</param>
 /// <param name="attributeName">The name of the attribute</param>
 /// <param name="modificationType">The type of modification to apply to the attribute</param>
 /// <param name="value">The value to apply to the modification operation</param>
 public static void CreateAttributeChangeIfInSchema(this CSEntryChange csentry, SchemaType type, string attributeName, AttributeModificationType modificationType, string value)
 {
     if (!string.IsNullOrWhiteSpace(value))
     {
         csentry.CreateAttributeChangeIfInSchemaInternal(type, attributeName, modificationType, value);
     }
 }
コード例 #6
0
 /// <summary>
 /// Creates an AttributeChange of the specified type, provided that the attribute is present in the provided schema type
 /// </summary>
 /// <param name="csentry">The CSEntryChange to add the AttributeChange to</param>
 /// <param name="type">The schema type of the object class of the CSEntryChange</param>
 /// <param name="attributeName">The name of the attribute</param>
 /// <param name="modificationType">The type of modification to apply to the attribute</param>
 /// <param name="value">The value to apply to the modification operation</param>
 public static void CreateAttributeChangeIfInSchema(this CSEntryChange csentry, SchemaType type, string attributeName, AttributeModificationType modificationType, long?value)
 {
     if (value != null && value.HasValue)
     {
         csentry.CreateAttributeChangeIfInSchemaInternal(type, attributeName, modificationType, value);
     }
 }
コード例 #7
0
 /// <summary>
 /// Creates an AttributeChange of the specified type, provided that the attribute is present in the provided schema type
 /// </summary>
 /// <param name="csentry">The CSEntryChange to add the AttributeChange to</param>
 /// <param name="type">The schema type of the object class of the CSEntryChange</param>
 /// <param name="attributeName">The name of the attribute</param>
 /// <param name="modificationType">The type of modification to apply to the attribute</param>
 /// <param name="valueChanges">The value changes to apply to the modification operation</param>
 public static void CreateAttributeChangeIfInSchema(this CSEntryChange csentry, SchemaType type, string attributeName, AttributeModificationType modificationType, IList <ValueChange> valueChanges)
 {
     if (type.HasAttribute(attributeName) && valueChanges != null && valueChanges.Count > 0)
     {
         csentry.CreateAttributeChange(attributeName, modificationType, valueChanges);
     }
 }
コード例 #8
0
        /// <summary>
        /// Creates an AttributeChange of the specified type
        /// </summary>
        /// <param name="csentry">The CSEntryChange to add the AttributeChange to</param>
        /// <param name="attributeName">The name of the attribute</param>
        /// <param name="modificationType">The type of modification to apply to the attribute</param>
        /// <param name="value">The value to apply to the modification operation</param>
        /// <typeparam name="T">The type of data</typeparam>
        public static void CreateAttributeChange <T>(this CSEntryChange csentry, string attributeName, AttributeModificationType modificationType, Nullable <T> value) where T : struct
        {
            switch (modificationType)
            {
            case AttributeModificationType.Add:
                if (value != null)
                {
                    csentry.AttributeChanges.Add(AttributeChange.CreateAttributeAdd(attributeName, value.Value));
                }
                break;

            case AttributeModificationType.Delete:
                csentry.AttributeChanges.Add(AttributeChange.CreateAttributeDelete(attributeName));
                break;

            case AttributeModificationType.Replace:
                if (value == null)
                {
                    csentry.AttributeChanges.Add(AttributeChange.CreateAttributeReplace(attributeName, value));
                }
                else
                {
                    csentry.AttributeChanges.Add(AttributeChange.CreateAttributeDelete(attributeName));
                }
                break;

            case AttributeModificationType.Update:
                if (value != null)
                {
                    csentry.AttributeChanges.Add(AttributeChange.CreateAttributeUpdate(attributeName, value));
                }
                break;

            case AttributeModificationType.Unconfigured:
            default:
                throw new InvalidOperationException("Unknown modification type");
            }
        }
コード例 #9
0
        /// <summary>
        /// Reads the <![CDATA[<attribute-change]]> node of the XML representation of the <see cref="Microsoft.MetadirectoryServices.CSEntryChange">CSEntryChange</see>
        /// </summary>
        /// <param name="element">An <c ref="System.Linq.Xml.XElement">XElement</c> containing an <![CDATA[<attribute-change>]]> element</param>
        /// <param name="csentry">The <see cref="Microsoft.MetadirectoryServices.CSEntryChange">CSEntryChange</see> to populate</param>
        private static void XmlReadAttributeChangeNode(XElement element, CSEntryChange csentry)
        {
            string name = null;
            AttributeModificationType modificationType = AttributeModificationType.Unconfigured;
            AttributeType             dataType         = AttributeType.Undefined;
            List <ValueChange>        valueChanges     = null;
            AttributeChange           attributeChange  = null;

            foreach (XElement child in element.Elements())
            {
                if (child.Name.LocalName == "name")
                {
                    name = (string)child;
                }
                else if (child.Name.LocalName == "modification-type")
                {
                    string modificationTypeString = (string)child;

                    if (!Enum.TryParse <AttributeModificationType>(modificationTypeString, out modificationType))
                    {
                        throw new InvalidCastException(string.Format("Cannot convert '{0}' to type {1}", modificationTypeString, typeof(AttributeModificationType).Name));
                    }
                }
                else if (child.Name.LocalName == "data-type")
                {
                    string dataTypeString = (string)child;

                    if (!Enum.TryParse <AttributeType>(dataTypeString, out dataType))
                    {
                        throw new InvalidCastException(string.Format("Cannot convert '{0}' to type '{1}'", dataTypeString, typeof(AttributeType).Name));
                    }
                }
                else if (child.Name.LocalName == "value-changes")
                {
                    if (string.IsNullOrWhiteSpace(name))
                    {
                        throw new ArgumentException("The attribute name must appear first in the list of <attribute-change> elements");
                    }

                    if (dataType == AttributeType.Undefined)
                    {
                        dataType = AttributeType.String;
                    }

                    valueChanges = CSEntryChangeDeserializer.XmlReadValueChangesNode(child, dataType);
                }
            }

            if (valueChanges == null)
            {
                return;
            }

            switch (modificationType)
            {
            case AttributeModificationType.Add:
                if (valueChanges.Count == 0)
                {
                    // discard attribute change with no values
                    return;
                }

                attributeChange = AttributeChange.CreateAttributeAdd(name, (valueChanges.Where(t => t.ModificationType == ValueModificationType.Add)).Select(t => t.Value).ToList());
                break;

            case AttributeModificationType.Replace:
                if (valueChanges.Count == 0)
                {
                    // discard attribute change with no values
                    return;
                    //throw new ArgumentException("The attribute replace in the CSEntry provided no values");
                }

                attributeChange = AttributeChange.CreateAttributeReplace(name, (valueChanges.Where(t => t.ModificationType == ValueModificationType.Add)).Select(t => t.Value).ToList());
                break;

            case AttributeModificationType.Delete:
                attributeChange = AttributeChange.CreateAttributeDelete(name);
                break;

            case AttributeModificationType.Update:
                if (valueChanges.Count == 0)
                {
                    // discard attribute change with no values
                    return;
                    //throw new ArgumentException("The attribute update in the CSEntry provided no values");
                }

                attributeChange = AttributeChange.CreateAttributeUpdate(name, valueChanges);

                break;

            case AttributeModificationType.Unconfigured:
            default:
                throw new NotSupportedException($"The modification type is not supported {modificationType}");
            }

            csentry.AttributeChanges.Add(attributeChange);
        }
コード例 #10
0
 public AcmaInheritedAttributeChange(AcmaSchemaAttribute attribute, AttributeModificationType modificationType, IList <ValueChange> valueChanges)
     : base(attribute.Name, modificationType, valueChanges)
 {
 }
コード例 #11
0
 private void ValidateAttributeChangeType(AttributeModificationType type)
 {
     DetachedUtils.ValidateAttributeModificationType(this.ModificationType, type);
 }
コード例 #12
0
ファイル: AcmaService.cs プロジェクト: ryannewington/acma
        private AttributeChange AvpToAttributeChange(KeyValuePair <string, IList <string> > kvp, AttributeModificationType modificationType)
        {
            ExtendedAttributeType type = ActiveConfig.DB.GetAttribute(kvp.Key).Type;

            switch (modificationType)
            {
            case AttributeModificationType.Replace:
                if (kvp.Value == null)
                {
                    return(AttributeChangeDetached.CreateAttributeDelete(kvp.Key));
                }
                else
                {
                    return(AttributeChangeDetached.CreateAttributeReplace(kvp.Key, kvp.Value.Select(t => TypeConverter.ConvertData(t, type)).ToList <object>()));
                }

            case AttributeModificationType.Add:
                return(AttributeChangeDetached.CreateAttributeAdd(kvp.Key, kvp.Value.Select(t => TypeConverter.ConvertData(t, type)).ToList <object>()));

            case AttributeModificationType.Delete:
                return(AttributeChangeDetached.CreateAttributeDelete(kvp.Key));

            default:
            case AttributeModificationType.Update:
            case AttributeModificationType.Unconfigured:
                throw new InvalidOperationException();
            }
        }
コード例 #13
0
        public override bool UpdateField(CSEntryChange csentry, object obj)
        {
            if (this.IsReadOnly)
            {
                return(false);
            }

            if (!csentry.HasAttributeChange(this.MmsAttributeName))
            {
                return(false);
            }

            AttributeModificationType modType      = csentry.AttributeChanges[this.MmsAttributeName].ModificationType;
            IList <object>            valueAdds    = csentry.GetValueAdds <object>(this.MmsAttributeName);
            IList <object>            valueDeletes = csentry.GetValueDeletes <object>(this.MmsAttributeName);

            valueAdds    = this.ConvertToNativeGoogleFormat(valueAdds);
            valueDeletes = this.ConvertToNativeGoogleFormat(valueDeletes);

            User user = obj as User;

            if (user == null)
            {
                throw new NotSupportedException("The provided object was not of a 'user' type");
            }

            if (valueAdds.Count == 0 && !this.HasSchemaField(user))
            {
                return(false);
            }

            IDictionary <string, object> schema = this.GetOrCreateSchema(user, out bool created);

            if (modType == AttributeModificationType.Delete)
            {
                if (this.HasSchemaField(user))
                {
                    schema[this.FieldName] = Utilities.GetNullRepresentation(this.NullValueRepresentation);
                    Logger.WriteLine($"Deleting {this.MmsAttributeName}");
                    return(true);
                }

                return(false);
            }

            IList <object> list = null;

            if (!this.HasSchemaField(user) || modType == AttributeModificationType.Replace || modType == AttributeModificationType.Add)
            {
                list = new List <object>();
            }
            else
            {
                list = this.GetValuesFromArray(schema[this.FieldName], "value");
                list = this.ConvertToNativeGoogleFormat(list);
            }

            if (modType == AttributeModificationType.Update)
            {
                foreach (object value in valueDeletes)
                {
                    list.Remove(value);
                    Logger.WriteLine($"Removing value {this.MmsAttributeName} -> {value}");
                }
            }

            foreach (object value in valueAdds)
            {
                list.Add(value);
                Logger.WriteLine($"Adding value {this.MmsAttributeName} -> {value}");
            }

            if (list.Count > 0)
            {
                List <Dictionary <string, object> > items = new List <Dictionary <string, object> >();

                foreach (object value in list)
                {
                    Dictionary <string, object> item = new Dictionary <string, object>();
                    item.Add("value", value);
                    items.Add(item);
                }

                schema[this.FieldName] = items;
            }
            else
            {
                object value = null;

                value = Utilities.GetNullRepresentation(this.NullValueRepresentation);
                Logger.WriteLine($"Set {this.MmsAttributeName} -> {value ?? "<null>"}");

                schema[this.FieldName] = value;
            }

            return(true);
        }
        public IList<AttributeChange> ApplyChanges(CSEntryChange csentry, SchemaType type, ref object target, bool patch = false)
        {
            Logger.WriteLine($"Processing students for course {csentry.DN}");
            List<AttributeChange> changes = new List<AttributeChange>();

            this.GetStudentChangesFromCSEntryChange(csentry, out CourseStudents studentsToAdd, out CourseStudents studentsToDelete, out CourseStudents reportedAdds, out CourseStudents reportedDeletes, csentry.ObjectModificationType == ObjectModificationType.Replace);

            HashSet<string> allStudentsToDelete = studentsToDelete.GetAllStudents();
            List<Student> allStudentsToAdd = studentsToAdd.ToStudentList();

            AttributeModificationType modificationType = csentry.ObjectModificationType == ObjectModificationType.Update ? AttributeModificationType.Update : AttributeModificationType.Add;
            try
            {
                if (csentry.ObjectModificationType != ObjectModificationType.Add && allStudentsToDelete.Count > 0)
                {
                    try
                    {
                        this.config.ClassroomService.StudentFactory.RemoveStudents(csentry.DN, allStudentsToDelete.ToList(), false);

                        foreach (string student in allStudentsToDelete)
                        {
                            Logger.WriteLine($"Deleted student {student} from course {csentry.DN}", LogLevel.Debug);
                        }

                        if (allStudentsToDelete.Count == 1)
                        {
                            Logger.WriteLine($"Deleted {allStudentsToDelete.Count} student from course {csentry.DN}");
                        }
                        else
                        {
                            Logger.WriteLine($"Deleted {allStudentsToDelete.Count} students from course {csentry.DN}");
                        }
                    }
                    catch (AggregateCourseStudentException ex)
                    {
                        Logger.WriteLine("The following students removals failed");
                        foreach (Exception e in ex.Exceptions)
                        {
                            Logger.WriteException(e);
                        }

                        reportedDeletes.RemoveStudents(ex.FailedStudents);
                        throw;
                    }
                }

                if (allStudentsToAdd.Count > 0)
                {
                    try
                    {
                        this.config.ClassroomService.StudentFactory.AddStudents(csentry.DN, allStudentsToAdd, false);

                        foreach (Student student in allStudentsToAdd)
                        {
                            Logger.WriteLine($"Added student {student.UserId} to {csentry.DN}", LogLevel.Debug);
                        }

                        if (allStudentsToAdd.Count == 1)
                        {
                            Logger.WriteLine($"Added {allStudentsToAdd.Count} student to {csentry.DN}");
                        }
                        else
                        {
                            Logger.WriteLine($"Added {allStudentsToAdd.Count} students to {csentry.DN}");
                        }
                    }
                    catch (AggregateCourseStudentException ex)
                    {
                        Logger.WriteLine("The following student additions failed");
                        foreach (Exception e in ex.Exceptions)
                        {
                            Logger.WriteException(e);
                        }

                        reportedAdds.RemoveStudents(ex.FailedStudents);
                        throw;
                    }
                }
            }
            finally
            {
                ApiInterfaceCourseStudents.AddAttributeChange(SchemaConstants.Students, modificationType, reportedDeletes.Students.ToValueChange(ValueModificationType.Delete), changes);
                ApiInterfaceCourseStudents.AddAttributeChange(SchemaConstants.Students, modificationType, reportedAdds.Students.ToValueChange(ValueModificationType.Add), changes);
            }

            Logger.WriteLine($"Processed students for course {csentry.DN}");
            return changes;
        }
        private static void AddAttributeChange(string attributeName, AttributeModificationType modificationType, IList<ValueChange> changes, IList<AttributeChange> attributeChanges)
        {
            AttributeChange existingChange = attributeChanges.FirstOrDefault(t => t.Name == attributeName);

            if (modificationType == AttributeModificationType.Delete)
            {
                if (existingChange != null)
                {
                    attributeChanges.Remove(existingChange);
                }

                attributeChanges.Add(AttributeChange.CreateAttributeDelete(attributeName));
                return;
            }

            if (changes == null || changes.Count == 0)
            {
                return;
            }

            IList<object> adds;
            switch (modificationType)
            {
                case AttributeModificationType.Add:
                    if (existingChange != null)
                    {
                        foreach (ValueChange valueChange in changes.Where(t => t.ModificationType == ValueModificationType.Add))
                        {
                            existingChange.ValueChanges.Add(valueChange);
                        }
                    }
                    else
                    {
                        adds = changes.Where(t => t.ModificationType == ValueModificationType.Add).Select(t => t.Value).ToList();

                        if (adds.Count > 0)
                        {
                            attributeChanges.Add(AttributeChange.CreateAttributeAdd(attributeName, adds));
                        }
                    }
                    break;

                case AttributeModificationType.Replace:
                    if (existingChange != null)
                    {
                        attributeChanges.Remove(existingChange);
                    }

                    adds = changes.Where(t => t.ModificationType == ValueModificationType.Add).Select(t => t.Value).ToList();
                    if (adds.Count > 0)
                    {
                        attributeChanges.Add(AttributeChange.CreateAttributeReplace(attributeName, adds));
                    }

                    break;

                case AttributeModificationType.Update:
                    if (existingChange != null)
                    {
                        if (existingChange.ModificationType != AttributeModificationType.Update)
                        {
                            throw new InvalidOperationException();
                        }

                        foreach (ValueChange valueChange in changes)
                        {
                            existingChange.ValueChanges.Add(valueChange);
                        }
                    }
                    else
                    {
                        if (changes.Count > 0)
                        {
                            attributeChanges.Add(AttributeChange.CreateAttributeUpdate(attributeName, changes));
                        }
                    }

                    break;

                case AttributeModificationType.Delete:
                case AttributeModificationType.Unconfigured:
                default:
                    throw new InvalidOperationException();
            }
        }
コード例 #16
0
 private static void CreateAttributeChangeIfInSchemaInternal(this CSEntryChange csentry, SchemaType type, string attributeName, AttributeModificationType modificationType, object value)
 {
     if (type.HasAttribute(attributeName))
     {
         csentry.CreateAttributeChange(attributeName, modificationType, value);
     }
 }
コード例 #17
0
        private static void TestAttributeChangeResults(CSEntryChange csentry, AcmaSchemaAttribute testAttribute, AttributeModificationType expectedModificationType, IList <object> expectedValues)
        {
            AttributeChange attributeChange = null;

            if (csentry.AttributeChanges.Contains(testAttribute.Name))
            {
                attributeChange = csentry.AttributeChanges[testAttribute.Name];
            }

            if (attributeChange == null && expectedModificationType == AttributeModificationType.Unconfigured)
            {
                return;
            }
            else if (attributeChange == null && expectedModificationType != AttributeModificationType.Unconfigured)
            {
                Assert.Fail("An AttributeChange was found where none were expected");
            }
            else if (attributeChange == null)
            {
                Assert.Fail("An AttributeChange was expected but not found");
            }

            if (attributeChange.ModificationType != expectedModificationType)
            {
                Assert.Fail("The AttributeChange was not of the expected type");
            }

            if (expectedModificationType != AttributeModificationType.Delete)
            {
                List <AttributeValue> comparerValues1 = attributeChange.ValueChanges.Select(t => new AttributeValue(testAttribute, t.Value)).ToList();
                List <AttributeValue> comparerValues2 = expectedValues.Select(t => new AttributeValue(testAttribute, t)).ToList();

                CollectionAssert.AreEquivalent(comparerValues1, comparerValues2);
            }
        }
コード例 #18
0
        private static void XmlReadAttributeChangeNode(XElement element, CSEntryChange csentry)
        {
            string name = null;
            AttributeModificationType modificationType = AttributeModificationType.Unconfigured;
            AcmaSchemaAttribute       attribute        = null;
            List <ValueChange>        valueChanges     = null;
            AttributeChange           attributeChange  = null;

            foreach (var child in element.Elements())
            {
                if (child.Name.LocalName == "name")
                {
                    name      = (string)child;
                    attribute = ActiveConfig.DB.GetAttribute(name);
                }
                else if (child.Name.LocalName == "modification-type")
                {
                    string modificationTypeString = (string)child;

                    if (!Enum.TryParse <AttributeModificationType>(modificationTypeString, out modificationType))
                    {
                        throw new InvalidCastException(string.Format("Cannot convert '{0}' to type {1}", modificationTypeString, typeof(AttributeModificationType).Name));
                    }
                }
                else if (child.Name.LocalName == "value-changes")
                {
                    if (attribute == null)
                    {
                        throw new ArgumentException("The attribute name must appear first in the list of <attribute-change> elements");
                    }

                    valueChanges = ImportExportEngine.GetValueChanges(child, attribute.Type);
                }
            }

            switch (modificationType)
            {
            case AttributeModificationType.Add:
                if (valueChanges.Count == 0)
                {
                    // discard attribute change with no values
                    return;
                }

                attributeChange = AttributeChange.CreateAttributeAdd(name, valueChanges.Where(t => t.ModificationType == ValueModificationType.Add).Select(t => t.Value).ToList());
                break;

            case AttributeModificationType.Replace:
                if (valueChanges.Count == 0)
                {
                    // discard attribute change with no values
                    return;
                    //throw new ArgumentException("The attribute replace in the CSEntry provided no values");
                }

                attributeChange = AttributeChange.CreateAttributeReplace(name, valueChanges.Where(t => t.ModificationType == ValueModificationType.Add).Select(t => t.Value).ToList());
                break;

            case AttributeModificationType.Delete:
                attributeChange = AttributeChange.CreateAttributeDelete(name);
                break;

            case AttributeModificationType.Update:
                if (valueChanges.Count == 0)
                {
                    // discard attribute change with no values
                    return;
                    //throw new ArgumentException("The attribute update in the CSEntry provided no values");
                }

                attributeChange = AttributeChange.CreateAttributeUpdate(name, valueChanges);

                break;

            case AttributeModificationType.Unconfigured:
            default:
                throw new UnknownOrUnsupportedModificationTypeException(modificationType);
            }

            csentry.AttributeChanges.Add(attributeChange);
        }
 /// <summary>
 /// Initializes a new instance of the UnknownOrUnsupportedModificationTypeException class
 /// </summary>
 /// <param name="modificationType">The modification type that was unknown or supported</param>
 public UnknownOrUnsupportedModificationTypeException(AttributeModificationType modificationType)
     : base(string.Format("An unknown or unsupported attribute modification type was used: {0}", modificationType.ToSmartString()))
 {
 }
コード例 #20
0
        /// <summary>
        /// Creates an AttributeChange of the specified type
        /// </summary>
        /// <param name="csentry">The CSEntryChange to add the AttributeChange to</param>
        /// <param name="attributeName">The name of the attribute</param>
        /// <param name="modificationType">The type of modification to apply to the attribute</param>
        /// <param name="values">The values to apply to the modification operation</param>
        public static void CreateAttributeChange(this CSEntryChange csentry, string attributeName, AttributeModificationType modificationType, IList <object> values)
        {
            switch (modificationType)
            {
            case AttributeModificationType.Add:
                if (values.Count > 0)
                {
                    csentry.AttributeChanges.Add(AttributeChange.CreateAttributeAdd(attributeName, values));
                }

                break;

            case AttributeModificationType.Delete:
                csentry.AttributeChanges.Add(AttributeChange.CreateAttributeDelete(attributeName));
                break;

            case AttributeModificationType.Replace:
                if (values.Count > 0)
                {
                    csentry.AttributeChanges.Add(AttributeChange.CreateAttributeReplace(attributeName, values));
                }
                else
                {
                    csentry.AttributeChanges.Add(AttributeChange.CreateAttributeDelete(attributeName));
                }

                break;

            case AttributeModificationType.Update:
                throw new NotSupportedException("Update operations are not supported by this method");

            case AttributeModificationType.Unconfigured:
            default:
                throw new InvalidOperationException("Unknown modification type");
            }
        }
コード例 #21
0
        /// <summary>
        /// Creates an AttributeChange of the specified type
        /// </summary>
        /// <param name="csentry">The CSEntryChange to add the AttributeChange to</param>
        /// <param name="attributeName">The name of the attribute</param>
        /// <param name="modificationType">The type of modification to apply to the attribute</param>
        /// <param name="values">The value changes to apply to the modification operation</param>
        public static void CreateAttributeChange(this CSEntryChange csentry, string attributeName, AttributeModificationType modificationType, IList <ValueChange> values)
        {
            switch (modificationType)
            {
            case AttributeModificationType.Delete:
                csentry.AttributeChanges.Add(AttributeChange.CreateAttributeDelete(attributeName));
                break;

            case AttributeModificationType.Add:
                csentry.AttributeChanges.Add(AttributeChange.CreateAttributeAdd(attributeName, values));
                break;

            case AttributeModificationType.Replace:
                if (values == null || values.Count == 0)
                {
                    csentry.AttributeChanges.Add(AttributeChange.CreateAttributeDelete(attributeName));
                }
                else
                {
                    csentry.AttributeChanges.Add(AttributeChange.CreateAttributeReplace(attributeName, values));
                }
                break;

            case AttributeModificationType.Update:
                csentry.AttributeChanges.Add(AttributeChange.CreateAttributeUpdate(attributeName, values));
                break;

            case AttributeModificationType.Unconfigured:
            default:
                throw new InvalidOperationException("Unknown modification type");
            }
        }
コード例 #22
0
        private static void XmlReadAttributeChangeNode(XElement element, CSEntryChange csentry, bool throwOnMissingAttribute)
        {
            string name = null;
            AttributeModificationType modificationType = AttributeModificationType.Unconfigured;
            ExtendedAttributeType     dataType         = ExtendedAttributeType.Undefined;
            List <ValueChange>        valueChanges     = null;
            AttributeChange           attributeChange  = null;

            foreach (var child in element.Elements())
            {
                if (child.Name.LocalName == "name")
                {
                    name = (string)child;
                }
                else if (child.Name.LocalName == "modification-type")
                {
                    string modificationTypeString = (string)child;

                    if (!Enum.TryParse <AttributeModificationType>(modificationTypeString, out modificationType))
                    {
                        throw new InvalidCastException(string.Format("Cannot convert '{0}' to type {1}", modificationTypeString, typeof(AttributeModificationType).Name));
                    }
                }
                else if (child.Name.LocalName == "data-type")
                {
                    string dataTypeString = (string)child;

                    if (!Enum.TryParse <ExtendedAttributeType>(dataTypeString, out dataType))
                    {
                        throw new InvalidCastException(string.Format("Cannot convert '{0}' to type '{1}'", dataTypeString, typeof(ExtendedAttributeType).Name));
                    }
                }
                else if (child.Name.LocalName == "value-changes")
                {
                    if (string.IsNullOrWhiteSpace(name))
                    {
                        throw new ArgumentException("The attribute name must appear first in the list of <attribute-change> elements");
                    }

                    if (dataType == ExtendedAttributeType.Undefined)
                    {
                        if (ActiveConfig.DB == null)
                        {
                            throw new NotConnectedException("The CSEntryChange did not specify a data type in the attribute change, and there was no active connection to the database to resolve it internally");
                        }
                        else
                        {
                            AcmaSchemaAttribute attribute = null;

                            try
                            {
                                attribute = ActiveConfig.DB.GetAttribute(name);
                                dataType  = attribute.Type;
                            }
                            catch (NoSuchAttributeException)
                            {
                                if (throwOnMissingAttribute)
                                {
                                    throw;
                                }
                                else
                                {
                                    continue;
                                }
                            }
                        }
                    }

                    valueChanges = CSEntryChangeXmlImport.GetValueChanges(child, dataType);
                }
            }

            switch (modificationType)
            {
            case AttributeModificationType.Add:
                if (valueChanges.Count == 0)
                {
                    // discard attribute change with no values
                    return;
                }

                attributeChange = AttributeChange.CreateAttributeAdd(name, valueChanges.Where(t => t.ModificationType == ValueModificationType.Add).Select(t => t.Value).ToList());
                break;

            case AttributeModificationType.Replace:
                if (valueChanges.Count == 0)
                {
                    // discard attribute change with no values
                    return;
                    //throw new ArgumentException("The attribute replace in the CSEntry provided no values");
                }

                attributeChange = AttributeChange.CreateAttributeReplace(name, valueChanges.Where(t => t.ModificationType == ValueModificationType.Add).Select(t => t.Value).ToList());
                break;

            case AttributeModificationType.Delete:
                attributeChange = AttributeChange.CreateAttributeDelete(name);
                break;

            case AttributeModificationType.Update:
                if (valueChanges.Count == 0)
                {
                    // discard attribute change with no values
                    return;
                    //throw new ArgumentException("The attribute update in the CSEntry provided no values");
                }

                attributeChange = AttributeChange.CreateAttributeUpdate(name, valueChanges);

                break;

            case AttributeModificationType.Unconfigured:
            default:
                throw new UnknownOrUnsupportedModificationTypeException(modificationType);
            }

            csentry.AttributeChanges.Add(attributeChange);
        }
        public IList <AttributeChange> ApplyChanges(CSEntryChange csentry, SchemaType type, ref object target, bool patch = false)
        {
            List <AttributeChange> changes = new List <AttributeChange>();

            this.GetMemberChangesFromCSEntryChange(csentry, out GroupMembership membershipToAdd, out GroupMembership membershipToDelete, out GroupMembership reportedAdds, out GroupMembership reportedDeletes, out IList <Member> roleChanges, csentry.ObjectModificationType == ObjectModificationType.Replace);

            HashSet <string> allMembersToDelete = membershipToDelete.GetAllMembers();
            List <Member>    allMembersToAdd    = membershipToAdd.ToMemberList();

            AttributeModificationType modificationType = csentry.ObjectModificationType == ObjectModificationType.Update ? AttributeModificationType.Update : AttributeModificationType.Add;

            try
            {
                if (csentry.ObjectModificationType != ObjectModificationType.Add && allMembersToDelete.Count > 0)
                {
                    try
                    {
                        this.config.GroupsService.MemberFactory.RemoveMembers(csentry.DN, allMembersToDelete.ToList(), false);

                        foreach (string member in allMembersToDelete)
                        {
                            Logger.WriteLine($"Deleted member {member} from group {csentry.DN}", LogLevel.Debug);
                        }

                        if (allMembersToDelete.Count == 1)
                        {
                            Logger.WriteLine($"Deleted {allMembersToDelete.Count} member from group {csentry.DN}");
                        }
                        else
                        {
                            Logger.WriteLine($"Deleted {allMembersToDelete.Count} members from group {csentry.DN}");
                        }
                    }
                    catch (AggregateGroupUpdateException ex)
                    {
                        Logger.WriteLine("The following member removals failed");
                        foreach (Exception e in ex.Exceptions)
                        {
                            Logger.WriteException(e);
                        }

                        reportedDeletes.RemoveMembers(ex.FailedMembers);
                        throw;
                    }
                }

                if (csentry.ObjectModificationType != ObjectModificationType.Add && roleChanges?.Count > 0)
                {
                    try
                    {
                        foreach (Member change in roleChanges)
                        {
                            try
                            {
                                this.config.GroupsService.MemberFactory.ChangeMemberRole(csentry.DN, change);
                                Logger.WriteLine($"Changed member role {change.Email} to {change.Role}", LogLevel.Debug);
                            }
                            catch (GoogleApiException ex)
                            {
                                if (ex.HttpStatusCode == System.Net.HttpStatusCode.NotFound)
                                {
                                    throw new UnexpectedDataException($"Member {change.Email} cannot be assigned {change.Role} without being made a member", ex);
                                }

                                throw;
                            }
                        }
                    }
                    catch (AggregateGroupUpdateException ex)
                    {
                        Logger.WriteLine("The following member role changes failed");

                        foreach (Exception e in ex.Exceptions)
                        {
                            Logger.WriteException(e);
                        }

                        throw;
                    }
                }

                if (allMembersToAdd.Count > 0)
                {
                    try
                    {
                        this.config.GroupsService.MemberFactory.AddMembers(csentry.DN, this.NormalizeMembershipList(allMembersToAdd), false);

                        foreach (Member member in allMembersToAdd)
                        {
                            Logger.WriteLine($"Added {member.Role} {member.Email}", LogLevel.Debug);
                        }

                        if (allMembersToAdd.Count == 1)
                        {
                            Logger.WriteLine($"Added {allMembersToAdd.Count} member");
                        }
                        else
                        {
                            Logger.WriteLine($"Added {allMembersToAdd.Count} members");
                        }
                    }
                    catch (AggregateGroupUpdateException ex)
                    {
                        Logger.WriteLine("The following member additions failed");
                        foreach (Exception e in ex.Exceptions)
                        {
                            Logger.WriteException(e);
                        }

                        reportedAdds.RemoveMembers(ex.FailedMembers);
                        throw;
                    }
                }
            }
            finally
            {
                ApiInterfaceGroupMembership.AddAttributeChange(this.config.GroupMemberAttributeName, modificationType, reportedDeletes.Members.ToValueChange(ValueModificationType.Delete), changes);
                ApiInterfaceGroupMembership.AddAttributeChange("externalMember", modificationType, reportedDeletes.ExternalMembers.ToValueChange(ValueModificationType.Delete), changes);
                ApiInterfaceGroupMembership.AddAttributeChange(this.config.GroupManagerAttributeName, modificationType, reportedDeletes.Managers.ToValueChange(ValueModificationType.Delete), changes);
                ApiInterfaceGroupMembership.AddAttributeChange("externalManager", modificationType, reportedDeletes.ExternalManagers.ToValueChange(ValueModificationType.Delete), changes);
                ApiInterfaceGroupMembership.AddAttributeChange(this.config.GroupOwnerAttributeName, modificationType, reportedDeletes.Owners.ToValueChange(ValueModificationType.Delete), changes);
                ApiInterfaceGroupMembership.AddAttributeChange("externalOwner", modificationType, reportedDeletes.ExternalOwners.ToValueChange(ValueModificationType.Delete), changes);

                ApiInterfaceGroupMembership.AddAttributeChange(this.config.GroupMemberAttributeName, modificationType, reportedAdds.Members.ToValueChange(ValueModificationType.Add), changes);
                ApiInterfaceGroupMembership.AddAttributeChange("externalMember", modificationType, reportedAdds.ExternalMembers.ToValueChange(ValueModificationType.Add), changes);
                ApiInterfaceGroupMembership.AddAttributeChange(this.config.GroupManagerAttributeName, modificationType, reportedAdds.Managers.ToValueChange(ValueModificationType.Add), changes);
                ApiInterfaceGroupMembership.AddAttributeChange("externalManager", modificationType, reportedAdds.ExternalManagers.ToValueChange(ValueModificationType.Add), changes);
                ApiInterfaceGroupMembership.AddAttributeChange(this.config.GroupOwnerAttributeName, modificationType, reportedAdds.Owners.ToValueChange(ValueModificationType.Add), changes);
                ApiInterfaceGroupMembership.AddAttributeChange("externalOwner", modificationType, reportedAdds.ExternalOwners.ToValueChange(ValueModificationType.Add), changes);
            }

            return(changes);
        }