I am developing a webapp where each user will access his own data.
Think about pivotal tracker and the such as an example, and assume each user will store 2 different data types like so:
table project
id | name
0 | foo
1 | bar
table story
id | name | effort
1 | baz | 5
2 | ex | 2
I can think of 2 solutions.
1) Provide each table with an additional user_id column so that each data is bound to his owner
2) Setup a new database schema for each new user
Personally, i am more on 2) because it would grant a higher security rate (not bound to the application level).
What would be the recommended way, and why?
Solution 2 appears rather exotic to me. It means creating new database schemas each time a user is added. Now, if you have very few users, and new users only get added very rarely, this may be feasible. But if you have lots of users to accomodate, you will need an automatism to create those schemas on the fly. Sure this is possible, but you will leave the grounds of existing tools and frameworks that support your development. E.g., Java Persistency API links a Java class to a table and won't support dynamic data base definition.
Also, I have doubts concerning the security level. In a web app, the database "user" is not the actual human user behind the browser, but the application server, which owns a database connection for its entire runtime. Therefore, individual human user's access rights aren't handled by the database, but by the application.
Related
I have a Role Hierarchy Setup with the following
CEO
-- Finance
----Department A Managers
------ Department A Users
----Department B Managers
------ Department B Users
I then only have 2 objects configured to Private
The problem is, we have certain people (Project Managers) that need to be able to view data from these two objects from different users in both Department A Users or Department B Users.
They should not be able to view data from either Department A Managers or Department B Managers.
Does anyone know how I can set this up to work with the above scenario ?
I've spent a lot of time on this and I am not sure the best approach.
Not sure if it possible, perhaps a trigger can be created (or workflow) to update the sharing rules of the record with the Project Manger? If that is the only solution then it might work.
Also I looked at creating a Sharing Rule but you can only share with a Role or Public Group, not an individual user.
Thank you
I think grouping and sharing is prob your best bet. So group dept.A&B users and group the PMs then share. Or you could add a field to your custom objects and share based on criteria, using the field as a flag, and share to the group of PMs. Maybe I've missed something.
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.
I have an application that creates its own users and then these users log in to the application and access the database. How should the users be created, should I have a users table or should I create database level user?
That's a pretty open ended question, you left out if it's web based or a desktop based application for example - but here are some thoughts.
How many users are you talking and what kind of turnover. Thousands? Millions? Ten? As the number and/or turnover gets larger and larger the user table looks better and better. Amazon, for example allows us to create our own shopping cart, be we aren't users on their database server.
For a database internal to a company having database level users usually makes more sense. It keeps you from having to define a whole security sub-system in your application and ensures that any vulnerabilities have already been addressed by Microsoft and millions of users around the world.
Creating a user table within the database is much simpler up front. But, it puts a lot of work on the business rules and security sub-system that you'll have to build. (in addition to mentioned vulnerabilities that it creates)
Meanwhile leveraging database users and roles can be more complex up front (if your doing it from within an application). You need someone comfortable with tsql, system stored procedures, SMO etc. But makes managing roles, users, groups, rights etc. a lot easier in the long run with the added benefit that you can manage it all outside of the application if necessary.
Either way your application is going to have to figure out how it uses connection strings. The database level user route requires connection strings to be specific to each user. Unless you're planning on using domain accounts with Windows authentication - which is the way to go whenever possible in my opinion.
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 a part of a student programming group an we are programming a social networking site.
I have a Session bean and for every User i create a UserInfoHolder Class and my Session bean has an Instance of it. So 1 User = 1 UserHolder Instace = 1 Big Database query .. when logging in.
Another Design Approach would be :
No Holders. Direct Connection to Database in every Session Bean Method => 1 User = 40 Database queries, no JavaClasses in Backgroud
My Question is :
Which One is the better Choice ?
I think .. having 5000 InfoHolder(5000 Users simultanously logged in) Classes might be a little bit too much. :/
What do you think ?
Your design should always aim to minimize the number of database queries since database is the a bottleneck whereas users session, so your UserInfoHolders, can be easily distribuited along many servers.