Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

Goal:

I'm trying to figure out the best way to model/design and then implement a "user" feature in a system.

Background:

I am designing an on-line access request system, so our company can use a web-based method for users to request access to various software systems. Since the system is all about the "user", the user is the focal point of the system.

So, a User can request access to a system. Then, the User's Manager will approve/reject the request. After that, the System Owner will approve/reject the request. Then it's the System Admin who approves/rejects, and finally the Security Administrator approves/rejects and adds them to the appropriate Active Directory group so they have access to the target Active Directory-driven application (not this application).

Problem:

I see all entities that represent a User as a core (set of) class(es) in the system. The User object is straight-forward - just pass their Windows login to Active Directory (AD) via an LDAP query and get their info and load it into an object. In an LDAP query, if there are other Users that report to them (a user's manager is stored in our AD), then this "user" is not only a User in this system but also a Manager. If this User is also in the database as a System Owner, they are also a System Owner.

So Far:

(Assume a Manager is someone with at least one direct report assigned to them in AD.)

I've considered a single User object, with properties such as IsManager or IsSystemOwner. However, should I construct an object hierarchy where (for example) a Manager class inherits from User? There are quirks with this, because a System Owner could inherit from User or Manager. Not all system owners are managers. However, Managers, System Owners, System Admins, and Security Admins are all Users, because they can be requesting access to some software system where there role in this system is only as a User. Here is an overview of "is a" for all of the user entities:

  • A User can request access to some other software system in this system.
  • A Manager is a User.
  • A System Owner is a User.
  • A System Admin is a User.
  • A Security Admin is a User (but unlikely to be, due to our organization).
  • A Manager may be a System Owner, but not always.
  • A System Owner may be a Manager, but not always.
  • A System Admin may be a Manager, but not always.
  • A System Admin may be a System Owner, but not likely.
  • A Security Admin may be a Manager, but not always.
  • A Security Admin may be a System Owner, but not likely.

Some additional info:

  • I don't anticipate Security Admins to be using the system as a User to request access, but it's always a possibility.
  • A Manager may create an access request on behalf of one of their employees (to revoke access to a fired employee, for example)
  • All employees in the Windows domain will have access to this site. I assume that I will have some Active Directory groups created for System Admins and Security Admins, as the users in these groups will not be dynamic, rather, users in one team are Sys Admins and users in another team are Security Admins.
  • The System Owner is subject to changed and will be stored in the database, along with the option to designate an alternate approver when on vacation, etc.
  • I may need a Manager to have an alternate approver, but I didn't plan on storing all users on the domain in the database!

This seems like it's so easy to model on paper, but getting it into good, flexible code is stumping me. All suggestions are welcome.

EDIT: Based on Karl's feedback, I have this prototype model. Does it look solid from an OOP perspective, based on my intended use?

Public Class MyCustomUserObject

    Public Property LoginID As String
    Public Property FirstName As String
    Public Property LastName As String
    Public Property EmailAddress As String

    Public Property Roles As List(Of Role)

    Public Function IsManager() As Boolean
        ' If List(Of Role) contains an object of type ManagerRole, then True, else False.
    End Function

    Public Function IsSystemOwner(systemName As String) As Boolean
        ' If List(Of Role) contains an object of type SystemOwnerRole with matching name
        ' in SystemOwnerRole.SoftwareSystems, then True, else False.
    End Function

    Public Function IsSystemAdministrator(systemName As String) As Boolean
        ' If List(Of Role) contains an object of type SystemAdministratorRole with matching name
        ' in SystemAdministratorRole.SoftwareSystems, then True, else False.
    End Function

    Public Function IsSecurityAdministrator() As Boolean
        Return My.User.IsInRole("My Active Directory group name for Security Admins")
    End Function

End Class

Public Class SoftwareSystem

    Public Property ID As String
    Public Property Name As String

End Class

Public MustInherit Class Role

    Public Property DesignatedApproverLoginID As String

End Class

Public Class ManagerRole
    Inherits Role

    Public Property Subordinates As List(Of AafUser)
    ' Or this, with a List of login IDs?
    ' Public Property Subordinates As List(Of String)

End Class

Public Class SystemOwnerRole
    Inherits Role

    Public Property SoftwareSystems As List(Of SoftwareSystem)

End Class

Public Class SystemAdministratorRole
    Inherits Role

    Public Property SoftwareSystems As List(Of SoftwareSystem)

End Class

Public Class SecurityAdministratorRole
    Inherits Role

    ' Explictly a Security Admin for all Software Systems.

End Class
share|improve this question
add comment

1 Answer

My suggestion is rather than making different User classes for different roles, have a single User class that contains a list of Role objects. Role would be a base class, with Manager, SystemOwner, SecurityAdmin, and SystemAdmin being derived classes, with fields specific to their needs. Manager would have a list of subordinates, SystemOwner would have descriptions of the system, etc. Role could have common fields, like an alternate approver, for example.

That architecture opens a lot of possibilities. Someone can easily be the owner of multiple systems, for example. That also makes queries like "list all system owners" easier.

share|improve this answer
    
I've prototyped some classes and put them in my OP. Does it look about right to what you were thinking? I am thinking that a SecurityAdministratorRole might not be needed, since it's target system independent, and will not have a designated approver. –  HardCode May 11 '12 at 19:25
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.