Recursively get ActiveDirectiory user groups

The native System.DirectoryService can’t recursively retrieve groups, so I created this enchanced one.


    public class ActiveDirectoryService
    {
        private readonly string _gusetUserid;
        private readonly string _guestPasswd;
        private readonly DirectoryEntry _ldapEntry;

        public enum FilterType
        {
            CN,             // subGroup
            SAMAccountName  // user
        }

        public ActiveDirectoryService(string host, string baseDN, string guestUserId, string guestPasswd)
        {
            _gusetUserid = guestUserId;
            _guestPasswd = guestPasswd;

            _ldapEntry = new DirectoryEntry("LDAP://" + host + "/" + baseDN, _gusetUserid, _guestPasswd);
        }

        public IEnumerable<string> GetADUserGroups(string username)
        {
            return GetADUserGroups(username, true);
        }

        public IEnumerable<string> GetADUserGroups(string username, bool recursive)
        {
            return GetParentGroups(username, new List<string>(), FilterType.SAMAccountName, recursive); 
        }

        private IList<string> GetParentGroups(string childName, 
            IList<string> originalGroups,
            FilterType filterType,
            bool recursive)
        {
            var search = new DirectorySearcher(_ldapEntry)
                             {
                                 Filter = string.Format("({0}={1})", filterType, childName)
                             };
            search.PropertiesToLoad.Add("memberOf");
            SearchResult result = search.FindOne();

            if (result != null)
            {
                int propertyCount = result.Properties["memberOf"].Count;

                string dn;

                for (int i = 0; i < propertyCount; i++)
                {
                    dn = result.Properties&#91;"memberOf"&#93;&#91;i&#93;.ToString();
                    int equalsIndex = dn.IndexOf("=", 1);
                    int commaIndex = dn.IndexOf(",", 1);
                    if (equalsIndex != -1)
                    {
                        string groupName = dn.Substring((equalsIndex + 1), (commaIndex - equalsIndex) - 1);
                        if (!originalGroups.Contains(groupName))
                        {
                            originalGroups.Add(groupName);

                            if (recursive) originalGroups = GetParentGroups(groupName, originalGroups, FilterType.CN, true);
                        }
                    }
                }
            }
           
            return originalGroups;
        }
    }
namespace ActiveDirectoryServiceSpecs
{
    &#91;TestFixture&#93;
    public class ActiveDirectoryServiceSpecs
    {
        const string LDAP_HOST = "Dcxx";
        const string LDAP_BASE_DN = "DC=xxxx,DC=xxx,DC=xx";
        const string LDAP_GUEST_USERID = "guest";
        const string LDAP_GUEST_PASSWD = "hello";

        private ActiveDirectoryService _SUT;
        &#91;SetUp&#93;
        public void Setup()
        {
            _SUT = new ActiveDirectoryService(LDAP_HOST, LDAP_BASE_DN, LDAP_GUEST_USERID, LDAP_GUEST_PASSWD);
        }

        &#91;Test&#93;
        public void should_get_immediate_user_ad_groups()
        {
            IEnumerable<string> adUserGroups = _SUT.GetADUserGroups("fmao", false);
            Assert.That(adUserGroups.Count() > 0);

            Assert.IsFalse(adUserGroups.Contains("Information Systems"));

            foreach (var s in adUserGroups)
            {
                Console.WriteLine(s);
            }
        }   
        
        [Test]
        public void should_get_recursive_user_ad_groups()
        {
            IEnumerable<string> adUserGroups = _SUT.GetADUserGroups("fmao", true);
            Assert.That(adUserGroups.Count() > 20);

            Assert.That(adUserGroups.Contains("Information Systems"));
            foreach (var s in adUserGroups)
            {
                Console.WriteLine(s);
            }
        }
    }
}

Advertisements