public void TestSchema()
        {
            OperationOptionInfo opInfo =
                new OperationOptionInfo("name", typeof(int?));
            ObjectClassInfoBuilder bld = new ObjectClassInfoBuilder();

            bld.ObjectType = ObjectClass.ACCOUNT_NAME;
            ObjectClassInfo info = bld.Build();
            ICollection <ObjectClassInfo> temp = CollectionUtil.NewSet(info);
            IDictionary <SafeType <APIOperation>, ICollection <ObjectClassInfo> > map =
                new Dictionary <SafeType <APIOperation>, ICollection <ObjectClassInfo> >();

            map[SafeType <APIOperation> .Get <CreateApiOp>()] = temp;
            ICollection <OperationOptionInfo> temp2 = CollectionUtil.NewSet(opInfo);
            IDictionary <SafeType <APIOperation>, ICollection <OperationOptionInfo> > map2 =
                new Dictionary <SafeType <APIOperation>, ICollection <OperationOptionInfo> >();

            map2[SafeType <APIOperation> .Get <CreateApiOp>()] = temp2;
            Schema v1 = new Schema(CollectionUtil.NewSet(info),
                                   CollectionUtil.NewSet(opInfo),
                                   map,
                                   map2);
            Schema v2 = (Schema)CloneObject(v1);

            Assert.AreEqual(v1, v2);
            Assert.AreEqual(info, v2.ObjectClassInfo.First());
            Assert.AreEqual(1, v2.SupportedObjectClassesByOperation.Count);
            Assert.AreEqual(1, v2.SupportedOptionsByOperation.Count);
            Assert.AreEqual(1, v2.OperationOptionInfo.Count);
        }
Esempio n. 2
0
        internal ConnectorObject CreateConnectorObject(ExchangeConnector connector, PSObject psobject, ObjectClass objectClass)
        {
            ConnectorObjectBuilder builder = new ConnectorObjectBuilder();

            string guid = (string)psobject.Properties["guid"].Value.ToString();
            string name = (string)psobject.Properties["name"].Value;

            builder.SetUid(new Uid(guid));
            builder.SetName(new Name(name));

            ObjectClassInfo ocinfo = connector.GetSchema().FindObjectClassInfo(objectClass.GetObjectClassValue());

            IDictionary <string, PSPropertyInfo> properties = psobject.Properties.ToDictionary(psinfo => psinfo.Name);

            LOG.Trace("Building connector object with UID = {0} and Name = {1}", guid, name);
            foreach (ConnectorAttributeInfo cai in ocinfo.ConnectorAttributeInfos)
            {
                if (cai.IsReadable && properties.ContainsKey(cai.Name))
                {
                    object value = properties[cai.Name].Value;
                    LOG.Trace(" - attribute {0} = {1}", cai.Name, value);

                    if (value is PSObject)
                    {
                        var ps = value as PSObject;
                        value = ps.BaseObject;
                        LOG.Trace(" - attribute {0} UNWRAPPED = {1} ({2})", cai.Name, value, value.GetType());
                    }
                    builder.AddAttribute(cai.Name, CommonUtils.ConvertToSupportedForm(cai, value));
                }
            }
            return(builder.Build());
        }
        /// <summary>
        /// Gets the object class info for specified object class, used for schema building
        /// </summary>
        /// <param name="oc">ObjectClass to get info for</param>
        /// <returns>ObjectClass' ObjectClassInfo</returns>
        protected override ObjectClassInfo GetObjectClassInfo(ObjectClass oc)
        {
            ObjectClassInfo ret = CollectionUtil.GetValue(this.mapOcInfo, oc, null) ?? base.GetObjectClassInfo(oc);

            Assertions.NullCheck(ret, "ret");
            return(ret);
        }
Esempio n. 4
0
        private static void Merge(IDictionary <ObjectClass, ObjectClassInfo> target, IDictionary <ObjectClass, ObjectClassInfo> source)
        {
            foreach (ObjectClass oc in source.Keys)
            {
                ObjectClassInfo sourceOCI = source[oc];
                if (!target.ContainsKey(oc))
                {
                    ObjectClassInfoBuilder builder = new ObjectClassInfoBuilder();
                    builder.ObjectType  = sourceOCI.ObjectType;
                    builder.IsContainer = sourceOCI.IsContainer;
                    builder.AddAllAttributeInfo(sourceOCI.ConnectorAttributeInfos);
                    ObjectClassInfo targetOCI = builder.Build();
                    LOGGER.TraceEvent(TraceEventType.Information, CAT_DEFAULT, "Adding object class info {0}", targetOCI.ObjectType);
                    target.Add(oc, targetOCI);
                }
                else
                {
                    ObjectClassInfo targetOCI = target[oc];
                    if (!targetOCI.ObjectType.Equals(sourceOCI.ObjectType))
                    {
                        throw new ArgumentException("Incompatible ObjectType for object class " + oc);
                    }
                    if (targetOCI.IsContainer != sourceOCI.IsContainer)
                    {
                        throw new ArgumentException("Incompatible Container flag for object class " + oc);
                    }
                    ObjectClassInfoBuilder builder = new ObjectClassInfoBuilder();
                    builder.ObjectType  = targetOCI.ObjectType;
                    builder.IsContainer = targetOCI.IsContainer;
                    builder.AddAllAttributeInfo(targetOCI.ConnectorAttributeInfos);
                    foreach (ConnectorAttributeInfo info in sourceOCI.ConnectorAttributeInfos)
                    {
                        if (info.Is(Name.NAME))
                        {
                            // The __NAME__ attribute is a special one and has to be provided on each object class.
                            // So, even if we just want to extend an object class with a few attributes, we have to provide
                            // artificial __NAME__ attribute there. When merging, we simply skip it.
                            continue;
                        }

                        foreach (ConnectorAttributeInfo existingInfo in targetOCI.ConnectorAttributeInfos)
                        {
                            if (existingInfo.Is(info.Name))
                            {
                                throw new ArgumentException("Attempted to redefine attribute " + info.Name);
                            }
                        }
                        LOGGER.TraceEvent(TraceEventType.Verbose, CAT_DEFAULT, "Adding connector attribute info {0}:{1}", info.Name, info.ValueType);
                        builder.AddAttributeInfo(info);
                    }
                    ObjectClassInfo targetRebuilt = builder.Build();
                    LOGGER.TraceEvent(TraceEventType.Information, CAT_DEFAULT, "Replacing object class info {0}", targetOCI.ObjectType);
                    target.Remove(oc);
                    target.Add(oc, targetRebuilt);
                }
            }
        }
        /// <summary>
        /// Gets the object class info for specified object class, used for schema building
        /// </summary>
        /// <param name="oc">ObjectClass to get info for</param>
        /// <returns>ObjectClass' ObjectClassInfo</returns>
        protected override ObjectClassInfo GetObjectClassInfo(ObjectClass oc)
        {
            // get the object class from base
            ObjectClassInfo oinfo = base.GetObjectClassInfo(oc);

            // add additional attributes for ACCOUNT
            if (oc.Is(ObjectClass.ACCOUNT_NAME))
            {
                var classInfoBuilder = new ObjectClassInfoBuilder {
                    IsContainer = oinfo.IsContainer, ObjectType = oinfo.ObjectType
                };
                classInfoBuilder.AddAllAttributeInfo(oinfo.ConnectorAttributeInfos);
                classInfoBuilder.AddAttributeInfo(AttInfoDatabase);
                classInfoBuilder.AddAttributeInfo(AttInfoRecipientType);
                classInfoBuilder.AddAttributeInfo(AttInfoExternalMail);
                oinfo = classInfoBuilder.Build();
            }

            // return
            return(oinfo);
        }
        public void TestObjectClassInfo()
        {
            ConnectorAttributeInfoBuilder builder = new ConnectorAttributeInfoBuilder();

            builder.Name        = ("foo");
            builder.ValueType   = (typeof(String));
            builder.Required    = (true);
            builder.Readable    = (true);
            builder.Updateable  = (true);
            builder.MultiValued = (true);
            ObjectClassInfoBuilder obld = new ObjectClassInfoBuilder();

            obld.ObjectType  = ObjectClass.ACCOUNT_NAME;
            obld.IsContainer = true;
            obld.AddAttributeInfo(builder.Build());
            ObjectClassInfo v1 = obld.Build();
            ObjectClassInfo v2 = (ObjectClassInfo)CloneObject(v1);

            Assert.AreEqual(v1, v2);
            Assert.IsTrue(v2.IsContainer);
        }
Esempio n. 7
0
        public static Schema BuildSchema(Connector connector,
                                         GetSupportedObjectClassesDelegate getSupportedObjectClassesDelegate,
                                         GetObjectClassInfoDelegate getObjectClassInfoDelegate,
                                         GetSupportedOperationsDelegate getSupportedOperationsDelegate,
                                         GetUnSupportedOperationsDelegate getUnSupportedOperationsDelegate)
        {
            SchemaBuilder schemaBuilder = new SchemaBuilder(SafeType <Connector> .Get(connector));

            //iterate through supported object classes
            foreach (ObjectClass oc in getSupportedObjectClassesDelegate())
            {
                ObjectClassInfo ocInfo = getObjectClassInfoDelegate(oc);
                Assertions.NullCheck(ocInfo, "ocInfo");

                //add object class to schema
                schemaBuilder.DefineObjectClass(ocInfo);

                //add supported operations
                IList <SafeType <SPIOperation> > supportedOps = getSupportedOperationsDelegate(oc);
                if (supportedOps != null)
                {
                    foreach (SafeType <SPIOperation> op in supportedOps)
                    {
                        schemaBuilder.AddSupportedObjectClass(op, ocInfo);
                    }
                }

                //remove unsupported operatons
                IList <SafeType <SPIOperation> > unSupportedOps = getUnSupportedOperationsDelegate(oc);
                if (unSupportedOps != null)
                {
                    foreach (SafeType <SPIOperation> op in unSupportedOps)
                    {
                        schemaBuilder.RemoveSupportedObjectClass(op, ocInfo);
                    }
                }
            }
            LOG.Debug("Finished retrieving schema");
            return(schemaBuilder.Build());
        }
Esempio n. 8
0
        public static IDictionary <ObjectClass, ICollection <string> > GetAttributesReturnedByDefault(
            GetSupportedObjectClassesDelegate getSupportedObjectClassesDelegate,
            GetObjectClassInfoDelegate getObjectClassInfoDelegate)
        {
            var attributesReturnedByDefault = new Dictionary <ObjectClass, ICollection <string> >();

            //iterate through supported object classes
            foreach (ObjectClass oc in getSupportedObjectClassesDelegate())
            {
                ObjectClassInfo ocInfo = getObjectClassInfoDelegate(oc);
                Assertions.NullCheck(ocInfo, "ocInfo");

                //populate the list of default attributes to get
                attributesReturnedByDefault.Add(oc, new HashSet <string>());
                foreach (ConnectorAttributeInfo caInfo in ocInfo.ConnectorAttributeInfos)
                {
                    if (caInfo.IsReturnedByDefault)
                    {
                        attributesReturnedByDefault[oc].Add(caInfo.Name);
                    }
                }
            }
            return(attributesReturnedByDefault);
        }
Esempio n. 9
0
        // creates a collection of attributes that correspond to the original ones, but resolves ADD/DELETE using existing values of psuser
        public ICollection <ConnectorAttribute> DetermineNewAttributeValues(UpdateOpContext context, ConnectorObject originalObject)
        {
            if (context.UpdateType == UpdateType.REPLACE)
            {
                // TODO check multivaluedness and updateability (as below)
                return(new List <ConnectorAttribute>(context.Attributes));
            }
            else
            {
                Boolean add;
                if (context.UpdateType == UpdateType.ADD)
                {
                    add = true;
                }
                else if (context.UpdateType == UpdateType.DELETE)
                {
                    add = false;
                }
                else
                {
                    throw new ArgumentException("Unsupported update type: " + context.UpdateType);
                }

                Schema schema = null;
                ICollection <ConnectorAttribute> rv = new List <ConnectorAttribute>(context.Attributes.Count);
                foreach (ConnectorAttribute attribute in context.Attributes)
                {
                    ConnectorAttribute originalAttribute = originalObject.GetAttributeByName(attribute.Name);
                    IList <object>     newValues         = originalAttribute != null && originalAttribute.Value != null ? new List <object>(originalAttribute.Value) : new List <object>();
                    Boolean            changed           = false;
                    if (attribute.Value != null)
                    {
                        foreach (object item in attribute.Value)
                        {
                            if (add)
                            {
                                if (newValues.Contains(item))
                                {
                                    LOG.Warn("Trying to add value from " + attribute.Name + " that is already there: " + item);
                                }
                                else
                                {
                                    newValues.Add(item);
                                    changed = true;
                                }
                            }
                            else
                            {
                                if (!newValues.Contains(item))
                                {
                                    LOG.Warn("Trying to remove value from " + attribute.Name + " that is not there: " + item);
                                }
                                else
                                {
                                    newValues.Remove(item);
                                    changed = true;
                                }
                            }
                        }
                    }
                    if (changed)
                    {
                        ConnectorAttributeBuilder b = new ConnectorAttributeBuilder();
                        b.Name = attribute.Name;
                        b.AddValue(newValues);
                        ConnectorAttribute modified = b.Build();

                        if (schema == null)
                        {
                            ExchangeConnector connector = (ExchangeConnector)context.Connector;
                            schema = connector.Schema();
                        }
                        ObjectClassInfo oci = schema.FindObjectClassInfo(context.ObjectClass.Type);
                        if (oci == null)
                        {
                            throw new InvalidOperationException("No object class info for " + context.ObjectClass.Type + " in the schema");
                        }
                        var cai = ConnectorAttributeInfoUtil.Find(attribute.Name, oci.ConnectorAttributeInfos);
                        if (cai == null)
                        {
                            throw new InvalidOperationException("No connector attribute info for " + context.ObjectClass.Type + " in the schema");
                        }

                        if (!cai.IsUpdateable)
                        {
                            throw new ConnectorSecurityException("Attempt to update a non-updateable attribute (" + attribute.Name + "): " +
                                                                 CollectionUtil.Dump(newValues));
                        }

                        if (newValues.Count > 1 && !cai.IsMultiValued)
                        {
                            throw new InvalidAttributeValueException("More than one value in a single-valued attribute (" + attribute.Name + "): " +
                                                                     CollectionUtil.Dump(newValues));
                        }
                        rv.Add(modified);
                    }
                }
                return(rv);
            }
        }