need help w/inheritance scheme

This is a discussion on need help w/inheritance scheme within the C++ Programming forums, part of the General Programming Boards category; My program has three different types of users: 1. Basic User 2. System Administrator (There are multiple "systems" in my ...

  1. #1
    Use this: dudeomanodude's Avatar
    Join Date
    Jan 2008
    Location
    Hampton, VA
    Posts
    391

    need help w/inheritance scheme

    My program has three different types of users:

    1. Basic User
    2. System Administrator (There are multiple "systems" in my program)
    3. Overall Site Administrator (A "super user" who can do everything a SysAdmin does, and creates other users)

    My inheritance scheme thus far is (with relevant functionality included):
    Code:
    class BasicUser{
    
        // ...
        protected:
            unsigned char key;
    };
    
    class SysAdmin : public BasicUser{
    
        // ....
        void setUserKey( BasicUser& basicUser );
    
        protected:
            unsigned char mySystemKey;
    };
    
    class SiteAdmin : public SysAdmin{
    
        // ...
        BasicUser* makeBasicUser( int id, string name );
        SysAdmin* makeSysAdmin( int id, string name, unsigned char sysKey );
    }:
    A basic user can navigate the program and do things granted their key allows them to (I'm setting their key with a bitwise OR and checking their key with a bitwise AND).

    A SysAdmin has "mySystemKey" which they use to grant a user access to their system.

    A SiteAdmin and only a SiteAdmin creates both BasicUsers and SysAdmins.

    Here's the problem:

    I will need to group all 3 kinds of users together (which I can becasuse they are all BasicUsers). However, it is possible that a user can be a BasicUser in one system, AND a SysAdmin in another system. I'd really like to avoid duplicating a user who has different roles on different systems without giving a BasicUser all the functionality of SysAdmin and saying they can only use that functionality if they have "permission" to do so.

    In other words, I don't want to eliminate the "SysAdmin" role by giving "mySystemKey" and "setUserKey()" to a BasicUser and then check to see if they can actually "use" those functions. I'd like to keep the roles as separate classes, but I also don't want to duplicate any user who might belong to multiple systems.

    Is this possible?

    Any ideas?

    Thank you all in advance.
    Ubuntu Desktop
    GCC/G++
    Geany (for quick projects)
    Anjuta (for larger things)

  2. #2
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    20,975
    How are you modeling the systems?
    C + C++ Compiler: MinGW port of GCC
    Version Control System: Bazaar

    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  3. #3
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,892
    I had a very similar situation. After modelling the entire thing several times, I finally threw the entire idea away, made a single User class, and made a powerful permissions system that decides who can do what. My lesson learned: never distinguish user types by their class.
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  4. #4
    Use this: dudeomanodude's Avatar
    Join Date
    Jan 2008
    Location
    Hampton, VA
    Posts
    391
    The systems are really just a bunch of parts in a database. We have to keep them separate since the information is sensative (i.e. a user who belongs to one system shouldn't be able to see parts/info in another system unless they've explicitly been given access).

    So the simple idea here is that a SysAdmin has a "mySystemKey" which they will use to give a BasicUser access like this:
    Code:
    void SysAdmin::setUserKey( User& user ){
    
        user.setMyKey = user.setMyKey | mySystemKey;
    }
    where mySystemKey has the possible values: 0x01, 0x02, 0x04, etc.

    The problem is, I need to group all users (regardless of thier role) together, perhaps in a list, or map, whatever. And I want to avoid duplicating a user if they happen to be a BasicUser in one system and a SysAdmin in another.

    I could possibly do the following, but it's exactly what I'm trying to avoid:
    Code:
    class BasicUser{
    
        // BasicUser now contains all BasicUser and SysAdmin functionality
    
        void setSystemKey( User& user );
    
        protected:
            uchar mySystemKey;
    };
    
    // No more SysAdmin class
    
    class SiteAdmin : public BasicUser{
    
        BasicUser* createBasicUser();
    };
    In the above scheme, a BasicUser has the functionality of a SysAdmin, but in order to "setSystemKey()" their private key would have to reflect the permission to use that functionality. That's why it seems better to separate the classes, while still retaining the ability to group all types of users together.
    Ubuntu Desktop
    GCC/G++
    Geany (for quick projects)
    Anjuta (for larger things)

  5. #5
    Use this: dudeomanodude's Avatar
    Join Date
    Jan 2008
    Location
    Hampton, VA
    Posts
    391
    Thanks CornedBee, so I guess just grant all access through the permissions and forget the whole thing, huh?

    That definately simplifies things quite a bit for me, esp. the problem of grouping all types of users together when needed.
    Ubuntu Desktop
    GCC/G++
    Geany (for quick projects)
    Anjuta (for larger things)

  6. #6
    The larch
    Join Date
    May 2006
    Posts
    3,573
    Perhaps it shouldn't be the task of UserTypes to create accounts and give out keys? Perhaps whichever class does that could use the user type to decide whether this functionality is available?
    I might be wrong.

    Thank you, anon. You sure know how to recognize different types of trees from quite a long way away.
    Quoted more than 1000 times (I hope).

  7. #7
    Use this: dudeomanodude's Avatar
    Join Date
    Jan 2008
    Location
    Hampton, VA
    Posts
    391
    Quote Originally Posted by anon View Post
    Perhaps it shouldn't be the task of UserTypes to create accounts and give out keys? Perhaps whichever class does that could use the user type to decide whether this functionality is available?
    So introduce a GrantAccess class? But I would think that CornedBee's suggestion still stands here...

    Example:

    A user is logged on, user tries to "grant access" to another user. If their "key" allows them to, they do, if they can't, they can't.

    But what I'm still struggling with is if all users are fundamentally the same class, I now have to have a vector or lilst of "mySystemKeys" to keep track of if the user is a SysAdmin on multiple systems?

    This program is utterly obfuscated at this point, but hey, I don't set the requirements...
    Ubuntu Desktop
    GCC/G++
    Geany (for quick projects)
    Anjuta (for larger things)

  8. #8
    Use this: dudeomanodude's Avatar
    Join Date
    Jan 2008
    Location
    Hampton, VA
    Posts
    391
    Would a wrapper class around the idea of a key be a good choice then?

    One goal of mine is to allow other developers to easily implement the access/permissions controls. I don't want other developers to have to enter in hex codes so when they use this stuff it will look something like:

    Code:
    if( checkUser( 12345, access("CostInfo") ) // Where 12345 is a user id and "CostInfo" is some controlled functionality
    {
        // allow user to do whatever
    }
    
    else
    {
        // disallow user to do whatever
    }
    Ubuntu Desktop
    GCC/G++
    Geany (for quick projects)
    Anjuta (for larger things)

  9. #9
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,892
    I store that stuff in a database.

    But how about named constants?

    Code:
    // Does the user have permission to do "CostInfo" in a given system?
    if(getUser(userId).hasPermission(CostInfo, systemId))
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  10. #10
    Use this: dudeomanodude's Avatar
    Join Date
    Jan 2008
    Location
    Hampton, VA
    Posts
    391
    So "userId", "CostInfo" and "SystemId" are database entries?
    Ubuntu Desktop
    GCC/G++
    Geany (for quick projects)
    Anjuta (for larger things)

  11. #11
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,892
    In my system, I have the tables "Users", "Permissions", and "PermissionProperties". A user has multiple permissions, each of which has a name and multiple properties, which are name-value pairs.

    So basically, to say that User #1 can do CostInfo in system A, I'd have an entry in Permissions with UID #1 and name "CostInfo", and in PermissionProperties there'd be a property called "System" with value A which belongs to this permission.
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Apple's music protection scheme is hacked
    By joeprogrammer in forum A Brief History of Cprogramming.com
    Replies: 3
    Last Post: 10-27-2006, 04:33 PM
  2. Using XML? My own binary system? A paint by number scheme?
    By Shamino in forum Game Programming
    Replies: 25
    Last Post: 03-10-2006, 12:08 AM
  3. Scheme
    By YankeePride13 in forum A Brief History of Cprogramming.com
    Replies: 23
    Last Post: 12-18-2005, 03:16 AM
  4. ping pong buffering scheme
    By cblix in forum Tech Board
    Replies: 0
    Last Post: 11-23-2005, 04:26 PM
  5. Post your IDE scheme!
    By nickname_changed in forum A Brief History of Cprogramming.com
    Replies: 3
    Last Post: 05-09-2005, 05:47 AM

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21