I am looking for a database design that can track and manage users with attributes to systems.
Situation:
A user has access to many systems in the organization and within each system, different attributes such as date created, system login name, system user id, etc. Currently, we have a database that is a flat database so for every attribute is in one row and continues to grow as more system attributes are added. The current tool used is an Access database and the current column count is 231 columns (OMG)! This is getting out of hand.
Assumptions:
There are a lot of attributes to track and one specific table in a database shouldn't be so broad to accommodate those attributes. Creating a table for each system becomes a mess in itself because each system may change in terms of columns. We need an interface for the administrators to easily manage this.
Let me give an example:
User Sunny, who works at Google, has access to the DMV, IRS, and Whitehouse.
For the DMV, Sunny has a user name, a pin code, and authorized IP address field. For the IRS, Sunny has a tax ID number, an organization number, a clearance number, and an access expiration date. For the Whitehouse, Sunny has a user name, a password, an access schedule, a portal address, and a user type. As Sunny works at google for years and slowly things change. Sunny gets access to the NRA, HP, Facebook, and Intel. The IRS adds a department clearance information. Whitehouse requires an authorization ID. The administrators need to see what access Sunny has and looks into the system; easily they find what they need.
Conclusion
Modifying tables and adding attributes may change on a regular basis. Developing a single table to handle this seems like a chore. I need a database design that could accommodate changes like this.
Question
How should design a database to accommodate something like this?
Thanks in Advance!
PS. I asked a question that is similar to this but it was a question for a software that actually exists to do this.
Related
Consider the problem bellow:
Every year we provide the best employee survey in our company. We want to automate this process(now we use some papers and a block box). It is easy to build a survey application but the main problem here is the privacy.
There are some requirements:
User should be able to login
User can give a vote for somebody only once
The survey should be completely anonymous even for database administrator
I guess we can achieve this with some form of database encryption. But what should I do with the keys?
A (simple) idea to hide user ID from the DBA is to encode it in the DB using the user password as a cryto key. If the executable used for the survey is somehow protected from reverse-engineering, that would provide a basic level of identity protection.
An even simpler idea:
If you are allowed to keep some paper around, you can create and distribute "voting cards". Cards with a unique ID (say, 8 or 10 characters) are distributed randomly to voters, and instead of login with his/her real name, the voter uses his (secret) ID. That way, anonymity is guaranteed, and you can do the checks you want on the votes.
I have an ASP.NET MVC + SQL Server application with 250 simultaneous users daily which uses AD/NTLM SSO to do all the authorization using a custom authorization security class that control access to controllers & Actions based on users & groups.
A dilemma recently came up where the 50K+ account records of the database are going to be managed by different groups to varying degree's:
All users will be able to view most records certain records can only
be edited by certain users/groups of specific departments There will
be an admin & support groups that will be able to edit any group owned records
etc.
This is not a problem of who has access to what features/forms/etc. in the controllers, but instead a dilemma of data ownership restrictions that must be imposed. I am guessing this means I need some additional layer of security for row level security.
I am looking for a pragmatic & robust way to tackle data ownership within the current application framework with minimal performance hits since it is likely the same thing will need to be imposed on other much larger tables of data. Initially there will be about 5 ownership groups, but creeping up to 25 to 100 in the near future.
Sadly there are no cut and dry business rules that are hard and fast that can be implemented here.. there is no rhyme or reason make sense of who owns what except the record primary key id.
To try to fix it I was thinking of creating a table of owner_roles and map it to the users table then create another table called accounts_ownership that looks something like:
tbl(PK),row(PK),owner(PK),view,create,modify,delete
accounts,1,hr,1,1,1,1
accounts,1,it,1,0,0,0
accounts,2,hr,1,1,1,1
accounts,2,it,1,1,1,1
accounts,3,it,1,0,0,0
But in doing so that would create a table that was 250K lines and could easily get some crappy performance. Looking at sites like Facebook and others this must be a common thing that has to be implemented, but I am hesitant to introduce a table like that since it could create serious performance issues.
The other way I thought this may be implemented is by adding an extra column to the accounts table that is a compound field that is comma separated that would contain the owner(s) with a coded set of rights ie.:
id owners
1 ,hr,
2 ,hr,
3 ,hr,it,
4 ,it,
And then add a custom class to search using the 'like' statement.. provided the logged in users role was "it" and the comma's were reserved and not allowed in owners names:
SELECT * FROM accounts WHERE owners LIKE '%,it,%'
... however this really just feels wrong from a DBA perspective (ugly as hell) and a maintenance nightmare.
Any practical approaches on how I could implement this without destroying my site?
Start with Role-based access control, you can possibly skip the roles from the pure definition but should be able to implement it like this:
Every user can be in one or more groups like admin, support, it, hr
Every data row has an owner like it, hr
On Access, check the access: an admin can see and edit all rows. Support+it sees every row and can edit those from it etc. This way you need only (user-groups + row-access) new rows in your database, not (user-groups * row-access).
User groups in your scenario should be possible to hardcode in your application, in a CMS there is generally a table defining what rights to assign to each user group - complicating the coding but very flexible.
Roles in the original concept allow a user to select what rights he/she wants to use, there would be a "Unlock with admin rights" or the like in your interface.
Primarily for performance reasons, I went with the less elegant approach listed. It took some doing, but there are careful application controls that had to be created to enforce things like no comma's in the id's.
Planing to create Access control system. Keeping an education institution in mind i created the Perimeter Tables like Main Gate, Zones, Building , Levels, Sections, Rooms(each table with foreign key relation).....Now i wish to create department table and employee tables, But how can i define a department to a particular perimeter. Because as the user the department can be a room or an entire building. Giving all the perimeter table foreign Key into the department table is not an apt way i guess. I also want the access to be in a path, don't want to authorized, if the user come to a Checkpoint through different point. I am newbie in database design, there might be a simple way i did not think of.. Please do help with a optimal design idea to create the above.
Thanks in advance..
Since the point of creating a hierarchy of securable locations is to manage who should have access to which locations, you are better off managing all of these locations in a single table with an involuted foreign key (self-referencing relationship).
Consider the following ERD:
Here you have security zones that can contain other security zones. People are granted access to the appropriate zones. Access to a lower level zone implies access to all of the zones that contain the lower level zone.
Using an involuted foreign key implies having to deal with hierarchical data, which can be a nuisance in SQL. To ease hierarchy navigation, I suggest using visitation numbers as I described at length in my answer to this question.
One thing to consider in any kind of access control system is minimizing the amount of data to be maintained by your security administrator. Many people will have the same access rules. For this reason, you may want to expand on the above ERD to use role based security in which groups not individuals are granted access to zones and individuals are granted access to groups. See my answer to this question on dba.se for more about role based security. If it might help, you could use a mixture of role-based and individual access rules.
Another option to consider is that your ACCESS table could include both allow and disallow flags. These could be used to allow access to a larger area while specifically forbidding access to a smaller area that is contained within. This approach could reduce the amount of data that needs to be managed for each person.
My wife works for a medium sized retail chain. Managers from each of the 80 outlets have to fill in one row of performance info for each of their staff (900 in all), but aren't allowed to see the data of other stores' staff.
My wife currently manages this with lots of spreadsheets, because each month the executive change what they want to collect, and their IT team don't have the resources to update their SAS system. She has to manually compile all the data into 1 spreadsheet for analysis which is time consuming and error prone. She's recently gone from having to do this for 20 outlets to 80 outlets and thinks she must be an easier way.
Is there a simple form based system, that can leverage what is already installed (microsoft office and lotus but not MSAccess), or can be run from a network drive. Cloud apps are banned. Excel's security is all wrong. Can word form templates append to a shared data source? Any ideas?
TIA
You could have a single table with all the data, then create 'shadowtables' on this table for each individual store.
in MySQL this would probably be either a 'partition table' (I've never used this so not sure how it works) or the use of temp tables.
You would then need to implement a method whereby when a user logs in at a given location (IP address) a trigger would create the temp table, then populate it with the relevent data for the store at that IP address.
An alternative (probably easier too) would be to have a specied table for each store, then grant users specific priveleges on each table you create. Again you'll need trigers to either populate a single 'master table' with info as it is updated, or you will just send a
select * from outlet1, outlet2... outlet80
again you may decide to create a temp table from the above select, and implement a custom script to create it only when required.
In fact that is probably how I would do it.
Then in you web interface have a button to create the temp table, and display it to the current user (provided they have the required priveleges to view all the tables of course).
I don't know for certain if Lotus is able to implement this, I don't know about its 'database' solution. I know that to do something similar in Access isn't that hard, the only downside would be needing to handle user identification (which Access doesn't do natively), again I don't know about Lotus.
In my experience the 'flat file database systems' don't generally handle user permisions in a native fashion, it is put onto the interface development to hand this.
I'm not sure how helpful the answer is, but it may take you a little way to a solution (even if you end up going for a server/client dbms system)
You can use Lotus for this. A simple start for you:
Create a database with one form and one view
On the form add whatever fields you want but also add a computed-when-composed multi-value field of type "Readers" with formula:
"[Admin]" : #Name( [CANONICALIZE];#userName)
With the exception of those with an Admin role (e.g., your wife), the view will display to each user only the records that the user created. The users will have to create one record per row.
Alternatively you could create an agent in the database that reads the data from an Excel file and builds the documents (records) with the READERS field's value computed as the documents are created.
If that's the route you want to take post a reply here and I'll post some code to (i) prompt a user to select an excel file, (ii) read the excel file data into lotus notes, (iii) implement a READERS field to see that documents are kept confidential between the creator and the Admin role people.
Hope that helps.
I am implementing an authentication system into an existing database system. Currently, the database has a "Person" table that includes things like: First Name, Last Name, Date of Birth, Email (username), etc. This is the primary table for a user.
I need to add the following fields for authentication: Password, IsLocked, LockDate, LastLoginDate.
Would you suggest putting these fields in the Person table or would you put them in a new Authentication table? My original plan was for "Person" to simply contain data about that person, not necessarily about authentication.
The other approach could be to store the password along with the email in Person, but then place the authentication data in a separate table. This way, the username and password would be in the same place, but the meta data would be in its own entity.
Anyone have any thoughts?
Thanks for the help!
Keep them separate so that users can query the system for information about a Person without necessarily having access to their account credentials.
This also has a nice side-effect where not all Person entities may have accounts.
Keep the account information separate. Your current business requirement may be for each person to have only one account, but it could come up in the future that a person needs to have multiple accounts, or even that you need an account that is shared by multiple people. Having a separate table for authentication means that such future changes will have a smaller impact on your code.
Also, from the perspective of protecting authentication information, the fewer people/processes that can access the account data the better off you'll be. It's much easier to implement table-level access than column-level access.
I don't think it makes much sense to create a seperate table for Authentication data. Authentication can't exist independently of the Person, as far as I can tell - and there doesn't seem to be a way one Person could reasonably be associated with two Authentications (or vice versa).
In other words: There's a 1:1 relationship between Person and Authentication, so why split it off?