Exemplo n.º 1
0
        /// <summary>
        /// Queries AD for all Groupwise connector contacts and returns
        /// a dictionary of GWiseContacts. The key is the UID of the contact.
        /// If no contacts are found an empty dictionary will be returned,
        /// no null.
        /// The root path, user name and password are optional.
        /// If they are given they will be used, otherwise RootDSE
        /// and the current user will be used instead.
        /// In addition to all contacts function returns the
        /// URL for the folder that contains the free busy message for
        /// the accounts.
        /// </summary>
        /// <param name="searchRootPath">The LDAP root to search,
        /// null will search the default domain</param>
        /// <param name="userName">User to use to make the query,
        /// null will use the default credentials</param>
        /// <param name="password">Password for the user</param>
        /// <param name="filter">The LDAP filter for the query</param>
        /// <param name="freeBusyUrl">
        /// Will be set to the free busy folder URL</param>
        /// <returns>Dictionary of all contacts keyed by the UID</returns>
        private static Dictionary <string, GWiseContact> GetGWiseContactsFromAD(
            string searchRootPath,
            string userName,
            string password,
            out string freeBusyUrl)
        {
            freeBusyUrl = null;
            Dictionary <string, GWiseContact> gwise_contacts =
                new Dictionary <string, GWiseContact>();

            SearchResultCollection adContacts = FindGWiseContacts(
                searchRootPath,
                userName,
                password,
                GWISE_CONTACTS_QUERY, PROPERTIES_TO_LOAD);

            foreach (SearchResult adContact in adContacts)
            {
                ResultPropertyCollection contactProps = adContact.Properties;
                GWiseContact             gwiseContact =
                    ParseGWiseContactsFromADProperties(
                        contactProps, ref freeBusyUrl);

                if (gwiseContact != null)
                {
                    gwise_contacts.Add(
                        gwiseContact.GwiseUid, gwiseContact);
                }
            }

            return(gwise_contacts);
        }
Exemplo n.º 2
0
        /// <summary>
        /// The function gets a stream, which is the result of WebDAV query
        /// for free busy emails. It parses the contacts UIDs from the XML
        /// response and marks the contacts, which have free buys emails.
        /// If the subject is mallformed the function will return null.
        /// I am not perfectly happy about mixing the response and
        /// the dictionary in a single function. It will be cleaner to parse
        /// the response and have this function work on a list.
        /// the problem with that is the number of additional allocations that
        /// are going to be made, just to be thrown away. So the current design
        /// is a compromise for better performance.
        /// </summary>
        /// <param name="gwiseContacts">Dictionary of contacts</param>
        /// <param name="stream">Http response from Exchange</param>
        private static void MarkWorkingContacts(
            Dictionary <string, GWiseContact> gwiseContacts,
            Stream stream)
        {
            XmlReaderSettings settings = new XmlReaderSettings();

            settings.XmlResolver      = null;
            settings.IgnoreComments   = true;
            settings.IgnoreWhitespace = true;
            settings.ValidationType   = ValidationType.None;
            settings.ValidationFlags  = XmlSchemaValidationFlags.None;

            XmlReader reader = XmlReader.Create(stream, settings);

            reader.MoveToContent();
            while (reader.Read())
            {
                if ((reader.NodeType == XmlNodeType.Element) &&
                    (reader.Name.IndexOf(COLON_SUBJECT) != -1))
                {
                    string element = reader.ReadElementString();
                    string uid     = GetGWiseUidFromFreeBusySubject(element);

                    if (uid != null)
                    {
                        GWiseContact gwiseContact = null;

                        if (gwiseContacts.TryGetValue(uid, out gwiseContact))
                        {
                            gwiseContact.Marked = true;
                        }
                    }

                    reader.ReadEndElement();
                }
            }
        }
        /// <summary>
        /// The function creates a free busy email for the given GWise contact
        /// under the public folder specified in free_busy_url.
        /// The credentials are optional.
        /// If they are given they will be used, otherwise
        /// the current user will be used to make the WebDAV call.
        /// </summary>
        /// <param name="userName">User to authenticate as or
        /// null will use the default credentials</param>
        /// <param name="password">Password for the user</param>
        /// <param name="freeBusyUrl">The Url of the free busy folder,
        /// where the free busy email should be created</param>
        /// <param name="gwiseContact">The contact for 
        /// which to create the free busy email</param>
        private static void CreateGWiseFreeBusyEmail(
            ICredentials credentials,
            string freeBusyUrl,
            GWiseContact gwiseContact)
        {
            string gwiseUid = gwiseContact.GwiseUid;
            string gwiseAddress = gwiseContact.GwiseAddress;
            string commonGroup = gwiseContact.CommonGroup;

            string freeBusyMessageUrl =
                string.Format(FREE_BUSY_EML_TEMPLATE,
                    freeBusyUrl, commonGroup, gwiseUid);

            HttpWebRequest request =
                (HttpWebRequest)HttpWebRequest.Create(freeBusyMessageUrl);

            if (credentials != null)
            {
                request.Credentials = credentials;
                request.ConnectionGroupName = "CustomCredentials";
            }
            else
            {
                request.UseDefaultCredentials = true;
                request.ConnectionGroupName = "DefaultNetworkCredentials";
            }
            request.Method = PROPPATCH;
            // This is necesssary to make Windows Auth use keep alive.
            // Due to the large number of connections we may make to Exchange,
            // if we don't do this, the process may exhaust the supply of 
            // available ports.
            // To keep this "safe", requests are isolated by connection pool.
            // See UnsafeAuthenticatedConnectionSharing on MSDN.
            request.UnsafeAuthenticatedConnectionSharing = true;
            request.PreAuthenticate = true;
            request.AllowAutoRedirect = false;
            request.KeepAlive = true;
            request.UserAgent = USER_AGENT;
            request.Accept = SLASH_START_SLASH;
            request.ContentType = TEXT_SLASH_XML;
            request.Headers.Add("Translate", "F");
            request.Headers.Add("Brief", "t");

            string propPatchRequest =
                string.Format(PROPPATCH_REQUEST,
                    commonGroup, gwiseUid, gwiseAddress);

            byte[] encodedBody = Encoding.UTF8.GetBytes(propPatchRequest);
            request.ContentLength = encodedBody.Length;
            Stream requestStream = request.GetRequestStream();
            requestStream.Write(encodedBody, 0, encodedBody.Length);
            requestStream.Close();

            WebResponse response = (HttpWebResponse)request.GetResponse();

            Stream responseStream = response.GetResponseStream();

            responseStream.Close();
            response.Close();
        }
        /// <summary>
        /// Parses the properties for a contact that came from AD
        /// and return GWiseContact object created from those properties.
        /// If some of the properties are misisng or mallformed
        /// the function will return null.
        /// In addition to parsing the contact the function returns the
        /// URL for the folder that contains the free busy message for
        /// the account, if it wasn't computed yet.
        /// </summary>
        /// <param name="contactProps">The properties of the contact</param>
        /// <param name="freeBusyUrl">If not already computed,
        /// it will be set to the free busy folder URL</param>
        /// <returns>A contact object or null</returns>
        private static GWiseContact ParseGWiseContactsFromADProperties(
            ResultPropertyCollection contactProps,
            ref string freeBusyUrl)
        {
            string gwiseUid = null;
            string gwiseAddress = null;
            string commonGroup = null;
            string freeBusyUrlTemp = null;
            GWiseContact gwiseContact = null;

            foreach (string propName in contactProps.PropertyNames)
            {
                foreach (Object propObject in contactProps[propName])
                {
                    string propValue = propObject.ToString();

                    if ((freeBusyUrl == null) &&
                        (freeBusyUrlTemp == null))
                    {
                        freeBusyUrlTemp =
                            GenerateParentFreeBusyFolderUrl(
                                propName, propValue);
                    }

                    if (gwiseUid == null)
                    {
                        gwiseUid =
                            GetGWiseUidFromLegacyExchangeDN(
                                propName, propValue);
                    }

                    if (commonGroup == null)
                    {
                        commonGroup =
                            GetCommonGroupFromLegacyExchangeDN(
                                propName, propValue);
                    }

                    if (gwiseAddress == null)
                    {
                        gwiseAddress =
                            GetGWiseAddressFromProxyAddresses(
                                propName, propValue);
                    }
                }
            }

            if ((gwiseAddress != null) &&
                (gwiseUid != null) &&
                (commonGroup != null))
            {
                gwiseContact =
                    new GWiseContact(gwiseUid, gwiseAddress, commonGroup);
            }

            if ((freeBusyUrl == null) &&
                (gwiseContact != null) &&
                (freeBusyUrlTemp != null))
            {
                // Return the free busy URL if not set already,
                // but do that only for well formed accounts.
                freeBusyUrl = freeBusyUrlTemp;
            }

            return gwiseContact;
        }
Exemplo n.º 5
0
        /// <summary>
        /// The function creates a free busy email for the given GWise contact
        /// under the public folder specified in free_busy_url.
        /// The credentials are optional.
        /// If they are given they will be used, otherwise
        /// the current user will be used to make the WebDAV call.
        /// </summary>
        /// <param name="userName">User to authenticate as or
        /// null will use the default credentials</param>
        /// <param name="password">Password for the user</param>
        /// <param name="freeBusyUrl">The Url of the free busy folder,
        /// where the free busy email should be created</param>
        /// <param name="gwiseContact">The contact for
        /// which to create the free busy email</param>
        private static void CreateGWiseFreeBusyEmail(
            ICredentials credentials,
            string freeBusyUrl,
            GWiseContact gwiseContact)
        {
            string gwiseUid     = gwiseContact.GwiseUid;
            string gwiseAddress = gwiseContact.GwiseAddress;
            string commonGroup  = gwiseContact.CommonGroup;

            string freeBusyMessageUrl =
                string.Format(FREE_BUSY_EML_TEMPLATE,
                              freeBusyUrl, commonGroup, gwiseUid);

            HttpWebRequest request =
                (HttpWebRequest)HttpWebRequest.Create(freeBusyMessageUrl);

            if (credentials != null)
            {
                request.Credentials         = credentials;
                request.ConnectionGroupName = "CustomCredentials";
            }
            else
            {
                request.UseDefaultCredentials = true;
                request.ConnectionGroupName   = "DefaultNetworkCredentials";
            }
            request.Method = PROPPATCH;
            // This is necesssary to make Windows Auth use keep alive.
            // Due to the large number of connections we may make to Exchange,
            // if we don't do this, the process may exhaust the supply of
            // available ports.
            // To keep this "safe", requests are isolated by connection pool.
            // See UnsafeAuthenticatedConnectionSharing on MSDN.
            request.UnsafeAuthenticatedConnectionSharing = true;
            request.PreAuthenticate   = true;
            request.AllowAutoRedirect = false;
            request.KeepAlive         = true;
            request.UserAgent         = USER_AGENT;
            request.Accept            = SLASH_START_SLASH;
            request.ContentType       = TEXT_SLASH_XML;
            request.Headers.Add("Translate", "F");
            request.Headers.Add("Brief", "t");

            string propPatchRequest =
                string.Format(PROPPATCH_REQUEST,
                              commonGroup, gwiseUid, gwiseAddress);

            byte[] encodedBody = Encoding.UTF8.GetBytes(propPatchRequest);
            request.ContentLength = encodedBody.Length;
            Stream requestStream = request.GetRequestStream();

            requestStream.Write(encodedBody, 0, encodedBody.Length);
            requestStream.Close();

            WebResponse response = (HttpWebResponse)request.GetResponse();

            Stream responseStream = response.GetResponseStream();

            responseStream.Close();
            response.Close();
        }
Exemplo n.º 6
0
        /// <summary>
        /// Parses the properties for a contact that came from AD
        /// and return GWiseContact object created from those properties.
        /// If some of the properties are misisng or mallformed
        /// the function will return null.
        /// In addition to parsing the contact the function returns the
        /// URL for the folder that contains the free busy message for
        /// the account, if it wasn't computed yet.
        /// </summary>
        /// <param name="contactProps">The properties of the contact</param>
        /// <param name="freeBusyUrl">If not already computed,
        /// it will be set to the free busy folder URL</param>
        /// <returns>A contact object or null</returns>
        private static GWiseContact ParseGWiseContactsFromADProperties(
            ResultPropertyCollection contactProps,
            ref string freeBusyUrl)
        {
            string       gwiseUid        = null;
            string       gwiseAddress    = null;
            string       commonGroup     = null;
            string       freeBusyUrlTemp = null;
            GWiseContact gwiseContact    = null;

            foreach (string propName in contactProps.PropertyNames)
            {
                foreach (Object propObject in contactProps[propName])
                {
                    string propValue = propObject.ToString();

                    if ((freeBusyUrl == null) &&
                        (freeBusyUrlTemp == null))
                    {
                        freeBusyUrlTemp =
                            GenerateParentFreeBusyFolderUrl(
                                propName, propValue);
                    }

                    if (gwiseUid == null)
                    {
                        gwiseUid =
                            GetGWiseUidFromLegacyExchangeDN(
                                propName, propValue);
                    }

                    if (commonGroup == null)
                    {
                        commonGroup =
                            GetCommonGroupFromLegacyExchangeDN(
                                propName, propValue);
                    }

                    if (gwiseAddress == null)
                    {
                        gwiseAddress =
                            GetGWiseAddressFromProxyAddresses(
                                propName, propValue);
                    }
                }
            }

            if ((gwiseAddress != null) &&
                (gwiseUid != null) &&
                (commonGroup != null))
            {
                gwiseContact =
                    new GWiseContact(gwiseUid, gwiseAddress, commonGroup);
            }

            if ((freeBusyUrl == null) &&
                (gwiseContact != null) &&
                (freeBusyUrlTemp != null))
            {
                // Return the free busy URL if not set already,
                // but do that only for well formed accounts.
                freeBusyUrl = freeBusyUrlTemp;
            }

            return(gwiseContact);
        }