I need a little help architecting a process that is a little beyond my skill set so if I could get a little help in how to approach this, I would appreciate it.

Basically:

BigBox Corporation has 15,000 employees in multiple countries. They want to build a communications system consisting of two types of channels:

  1. Read-Only (by recipient)
  2. Read/Write (by recipient)

Each channel will have a set of properties:

Name:

  • security
  • hr
  • LA widget sales
  • NY widget sales

Send/Receive Method (how the creator will write to and read from the channel):

  • email (email address)
  • im (screen name)
  • rss
  • sms (phone number)
  • etc.

Security:
The Creator assigns the access rights based on their own security level.

Employees can create with access rights for:

  • Other employees within their workgroup/department
  • Open to all empolyees

Managers can create with access rights for:

  • His employees / direct reports
  • Other managers within his department (his peers)

Directors can create with access rights for:

  • His employees and their managers
  • His managers only
  • Other Directors (his peers)

VP’s can create with access rights for:

  • His employees and their managers and directors
  • His directors only
  • His directors and managers
  • Other VPs (his peers)

Certain departments would be able to create companywide channels such as:
HR could create a companywide, broadcast only (read only) channel for disseminating information to all employees at all levels

Security could create a companywide read/write channel to accept reports of theft or viruses etc.

Once implemented, a user would "subscribe" to various channels. The Creator will send information using their "Method" and it will end up in this system and then sent to the user via the method they defined when they subscribed. The Creator may send via email and the recipient may receive via IM. You can have a one-to-many or a many-to-one relationship.

Any suggestions, guidance, ideas would be appreciated!

Pete

So essentially this is more of a permissions issue?

If that's the case having your database store permissions is probably the best way to go. Have a database table for users and roles. The roles table will most likely contain the permission's level and will be the reference table for other tables like users. if each user can have multiple permissions you could store a serialize array in the user table containing the role IDs.

Member Avatar for diafol

I agree that you need a permissions type table.
It could also be set up in a class with default config data, obviating the need for making multiple calls to the DB. However, I'm still a noob at OOP, so I'm probably not the best person to suggest an approach via this method.

So essentially this is more of a permissions issue?

If that's the case having your database store permissions is probably the best way to go. Have a database table for users and roles. The roles table will most likely contain the permission's level and will be the reference table for other tables like users. if each user can have multiple permissions you could store a serialize array in the user table containing the role IDs.

That's a really good way of verbalizing it... permissions issue... and that's what I'm having trouble wrapping my head around.

There are international permissions, national permissions, divisional permissions, operating unit permissions (and those can be broken up by region), workgroup permissions, individual user permissions... and I can see how some of these would look and cross over one another.

The main thing is to have a good database structure designed before starting on any kind of framework. Permissions always seem to add a bunch of complexity to your app/site etc. so try to keep it as simplified as possible.

you should start by drawing out the relationship between your tables. If you have a permissions/role table containing the name and level of access, it should have a foreign key in the users table as well as any other tables that require permissions. This is a one to many relationship. one type of permissions to several users etc...

If you need a many to many relationship (one or more users can have one or more permissions) than it gets a bit more complex. you will need another table to contain the permissions and users and other stuff that require permissions ex:

permissionsM2M table
ID //primary key
type //str probably containing is it's a user page or form etc...
permissionID //FK to permissions talbe
type_ID //the user ID or page ID etc...

probably something like that. this method could potentially bloat your database if there are ALOT of data so be sure to add index on all the foreign keys.

Another method would be to store a serialize array of permissions ID in user table or page table etc.

The main thing is to have a good database structure designed before starting on any kind of framework. Permissions always seem to add a bunch of complexity to your app/site etc. so try to keep it as simplified as possible.

Yeah, I learned a long time ago to make sure your ducks are all in a row before writing the first line of code. If you can't define it, you certainly cant write it... at least not anything reliable and maintainable!

I get that I need one table for users, one with channel definitions and one for channels the user has subscribed to.

What I'm still unclear on is how to actually define those permission levels...

HR defines a company wide channel with all access: easy.

Department Manager defines a department channel for just his direct reports: This needs a security level allowing his employees to see the channel but higher ups, his peers and employees from other departments can't see the channel.

As I've worked through documenting this, I have come to realisze this is the part that I don't understand...

could just name those permission levels anything you want and document it well or you could have a name and level for each permission. ex: name = 'Department Manager' level = '4' | name = 'admin', level = '1' and on each channel have a way to specify levels of access. if you have a channel's table you could store it in there.

Just have a class that checks for the permissions before each channel renders.

One possible way to do it would be to define a table of groups where each group has specific access rights, a table of users, and a userGroup table where a user can belong to more than one group. Then before allowing access to a 'channel', the program queries userGroup to see if the user is a member of a group that is allowed to access/use that channel.

Member Avatar for diafol

On Fest3er's idea, you could store info as bits:

user table:
userlevel field
employees 1
managers 2
directors 4
VPs 8
siteadmin 16

a user could have multiple roles, e.g. siteadmin and director = 20

permissions table
permission | levels (sum of all userlevels with rights to do)
createmanager 28
createdirector 24
createemployee 30
createVP 16

So if an user's userlevel was 6 (director and manager), s/he could create other managers and employees. These rights could be tested:

if testing whether to create a manager (28)

if($levels & $userlevel){
  //this will return a number > 0  or 0
  //if 0 - no right, otherwise right
}

anyway, just a thought

Ardav presents a great and very valid idea, with one provision to bear in mind: that one is sure she will never run out of bits in the bitfield. If the likelihood of growth cannot reasonably be foreseen to exceed 32/64/128 bits of field, use the bitfield concept. But if there's any reasonable probability that an organization is large enough to need more than 32/64/128 groups, go right to the userGroup table concept: 2^32 groups probably counts as 'unlimited'.

Of course, if bitfields are 'dynamic' and 'unlimited' in size and/or are easily changed and the code to set/get them is efficient, then a bitfield is the way to go: one less DB query.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.