.Net and Active Directory - An OO solution to authority structure - Part 7

Ok, now that we have walked from our Owner down the organizational tree, lets climb up and create a lineage of Manager objects.

The Manager object is a bit different.  Since our Owner could be a Group, our Manager could also.  Also at some point there is no higher to go on the tree and we find ourself looking at a Manager object who is invariably playing golf. So we have to build flexibility into this object and a way to dead end the recursion.  So lets just look at the Manager object in it's entirety:

using System;
using System.DirectoryServices;
 
namespace ActiveDirectory_Demo1.GlobalObjects.AuthorityObjects
{
    /// <summary>
    /// Summary description for ManagerObject.
    /// </summary>
    public class ManagerObject : BaseObject
    {
        private string managername;
        private string id;
        private string login;
        private string homepage;
        private ManagerObject manager;
        private DirectoryEntry originaldirectoryentry;
        private string objecttype;
        private string path;
 
        /// <summary>
        /// The Manager Object is a user or group which represents the entity that manages the object below it.
        /// </summary>
        /// <param name="de">DirectoryEntry object (user/group) to derrive the Manager from</param>
        public ManagerObject(DirectoryEntry de)
        {
            if(de.SchemaClassName.ToLower() == "group" && de.Properties["managedBy"].Value != null)
            {
                originaldirectoryentry = new DirectoryEntry(DEFAULTDOMAIN +"/"+ de.Properties["managedBy"].Value.ToString(), DEFAULTUSERNAME, DEFAULTPASSWORD, AuthenticationTypes.Secure);
                Path = originaldirectoryentry.Path;
            }
            else if(de.SchemaClassName.ToLower() == "user" && de.Properties["manager"].Value != null)
            {
                originaldirectoryentry = new DirectoryEntry(DEFAULTDOMAIN +"/"+ de.Properties["manager"].Value.ToString(), DEFAULTUSERNAME, DEFAULTPASSWORD, AuthenticationTypes.Secure);
                Path = originaldirectoryentry.Path;
                HomePage = GetHomePage();
            }
            else
            {
                ObjectType = null;
                ManagerName = null;
                HomePage = null;
            }
 
            if(originaldirectoryentry != null)
            {
                ID = de.NativeGuid;
                Login = originaldirectoryentry.Properties["sAMAccountName"].Value.ToString();
                ObjectType = originaldirectoryentry.SchemaClassName.ToLower();
                ManagerName = this.originaldirectoryentry.Name.Replace("CN=","");
                Manager = GetManager(this.originaldirectoryentry);
            }
        }
 
        /// <summary>
        /// Name of the user.
        /// </summary>
        public string ManagerName
        {
            get {  return managername; }
            set { managername = value; }    
        }
 
        /// <summary>
        /// NativeGuid of the DirectoryEntry
        /// </summary>
        public string ID
        {
            get { return id; }
            set { id = value; }
        }
 
        /// <summary>
        /// Login used to authenticate
        /// </summary>
        public string Login
        {
            get{ return login; }
            set{ login = value; }
        }
 
        /// <summary>
        /// HomePage
        /// </summary>
        public string HomePage
        {
            get { return homepage; }
            set { homepage = value;}
        }
 
        /// <summary>
        /// Manager Object who is the manager of this Object
        /// </summary>
        public ManagerObject Manager
        {
            get {  return manager; }
            set { manager = value; }  
        }
 
        /// <summary>
        /// Type of object (user/group)
        /// </summary>
        public string ObjectType
        {
            get { return objecttype; }
            set { objecttype = value; }
        }
 
        /// <summary>
        /// Path from the oringinal DirectoryEntry
        /// </summary>
        public string Path
        {
            get{ return path; }
            set{ path = value; }
        }
 
        private ManagerObject GetManager(DirectoryEntry de)
        {
            Object mngrObj = null;
 
            if(de.SchemaClassName.ToLower() == "group")
            {mngrObj = de.Properties["managedBy"].Value;}
            else if(de.SchemaClassName.ToLower() == "user")
            {mngrObj = de.Properties["manager"].Value;}
            
            if(mngrObj != null)
            {
                return new ManagerObject(de);
            }
            else
            {return null;}
        }
 
        private string GetHomePage()
        {
            string rtn = "";
            if(this.originaldirectoryentry.Properties["wWWHomePage"].Value != null)
            {rtn = this.originaldirectoryentry.Properties["wWWHomePage"].Value.ToString();}
            return rtn;
        }
    }
}

And add a Manager to our Owner and call into this class to populate it:

private ManagerObject manager;
 
/// <summary>
/// User or Group which manages this object
/// </summary>
public ManagerObject Manager
{
    get 
    { return manager;    }
    set 
    { manager = value; }  
}
public Owner(DirectoryEntry de)
{
    .
    .
    .
    if(HasManager(de))
    {Manager = new ManagerObject(de);}
    .
    .
    .
}

*Note that the HasManager method is in the BaseObject our Owner inherits.

Rather than starting at the constructor lets take a quick peek at the GetManager method.  Here we see how the DirectoryEntry passed into this method could be a "user" or "group".  And depending on which type we find, we instantiate the correct ManagerObject using the appropriate DirectoryEntry.  Here also we see that if we find neither a User nor Group above our current Manager, we return null and don't try and climb any higher.

Looking at the constructor we likewise see handling for both a Group or User. We also see that if we find insufficient information to construct a DirectoryEntry, our last IF statement terminates if the originaldirectoryentry (not the DirectoryEntry passed in) is NULL.  In all likelihood when this condition is met we are looking at the President or CEO (depending on how your organization is constructed) and walking any higher would simply place us at the Root Node for Active Directory.

Whew!  What a journey, but if you've been following the solution provided you should now have a firm grasp on interacting with Active Directory through .Net to produce a chain of authority.  As stated in the Intro post, this is a project with a purpose.  Knowing who has authority over whom is academic, doing something useful with it should be the ultimate goal (unless you just like reading about this stuff in your spare time without any practical application for it which in that case you should go outside and get some fresh air).

Anyhoo, in the next post we will create a custom serialization method for the Owner object, the purpose of which will be storage, extending our object with permissions related information and to compare it upon regeneration.  Why is that important?  Read on....

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Posted by: AaronZalewski
Posted on: 1/23/2008 at 12:07 PM
Tags: , ,
Categories: Active Directory
Actions: E-mail | Kick it! | DZone it! | del.icio.us
Post Information: Permalink | Comments (0) | Post RSSRSS comment feed

Related posts

Comments are closed