I have a web application that reads data from a DB.
I have different users in my web-app and I'm thinking of delegating the functionality to determine "who can see what" to the DB instead than to the web-app.
Example:
On my DB I'm storing data for different customers. On the same table, I'm storing data for different customers, each row has a "customer" field that identifies the customer to which the row belongs. When the web-app queries the previous table, as the users in the DB are equal to the users in the web-app, the DB will return to the web-app only the rows to which the user has permissions to SELECT.
To implement this I have thought on the following process:
Use ROW-LEVEL SECURITY ACCESS to create a role per each customer. That role will only allow querying rows with Customer='CUSTOMER_NAME'
As the same CUSTOMER could have different types of users (EX: Marketing/Sales users). I want to create a common role for all customers that will filter the data that each type of user could SELECT.
I don't know if I could create a ROLE that will limit the rows that a certain user can select (EX: All the rows with CUSTOMER='CUSTOMER_NAME') and then grant another ROLE to the same user that will limit more the rows that the user can select (EX: All the rows related to a certain department: Marketing/Sales).
Are the roles applied from more restrictive to less? If so, my desired outcome is to have a single "Marketing" role with access to all Marketing-related rows and then to have a single "Customer" role with access to all Customer-related rows. Then the user with those roles will only be able to see Marketing related rows but only for a certain customer.
Is there any other way to do this?
Related
I have 4 tables
Account
Admin
User
Role
The account table contains the email and password to login.
An account can either be an admin or an user.
An user has a registerdate
An admin has an adminnumber, but no registerdate (different attributes)
The role table contains the role name, either admin or user.
An account currently contains foreign-key relationships with all other tables. This isn't ideal, since depending on the role, one of the tables will be left empty.
I need all account to be in the same table, yet depending on the role it should have different links and attributes.
What is the best way to tackle this?
I use MSSQL
I need to create a system that allows both individual users and groups (e.g., a company) to sign up for a subscription service.
The procedure for signing up for a group membership will involve a user paying for as many users as they require (e.g., 5) at sign up. Once they have paid they will be able to create these other users (i.e., have admin functions) that will be associated with this group (e.g., other members of their company). (They will be able to pay for more users for their group at a later date if they wish.) A user cannot be in more than one group. The original person that signed up on behalf of a group can assign admin roles to these newly created members.
For login purposes, I would like to have both individual users and group users in the same table of the database. For example, it could be called and have columns (to keep things simple):
user table:
user_id
username
I then thought that there must be a second table that shows the links between users (i.e., which belong to which group). Let's say that this is:
groups table:
group_id
user_id
I am guessing that this is a one-to-many relationship as many users can be in one group, but each user can be in only one group.
In order to assign the proper roles to the user that signed up on behalf of a group there would be another table called:
roles table:
role_id
user_id
This would allow some users to have permissions of admin rather than just user. I would then just have to lookup the user_id's of the admin role (a specific admin user_id) when they logged in and this would give them access to the correct people in their group.
Before I go ahead designing this database I was wondering if this is an appropriate database design to go about creating these individual and group users or if there is a better setup?
FURTHER INFO: There are two sign up forms: an individual sign up form and a groups sign up form.
For an individual, we will record their "username", their user_type (individual) and assign them a role of "user". They do not need to be assigned a group id and we will not need to convert their membership to a group membership later on.
For the user who signed up as a group using the group sign up form, we will record their "username", their user_type (group), no. of memberships purchased (e.g., 5), a group id (e.g., a unique integer) and assign them a role of "admin". Because they have purchased multiple memberships, they will be able to create/add new users to their group upto the number purchased. They can assign each new user a role of either "user" or "admin". A role of "user" in both individal and group membership has the same permissions, so there are only two types of role.
As such, I had planned a createUser() function that creates:
For an individual: username, user_type(individual), role(user)
For a group: username, user_type(group), group_id, no_purchased, role(admin)
For a new member of a group (created by admin): username, user_type(group), group_id(the same as the admin), role(admin or user)
I had then planned to create a checkUser() function that:
Gets their id, username, etc...
Checks if they are an admin or user.
If admin, then gets the users/admins that are in the same group as them.
Most calls to the database will be to login (i.e., username/password). I was looking to see what the simplest database structure would be for this situation.
I feel like you might make your life simpler if you consider individual users as groups users with only one member. This will also give you flexibility in the future if an individual user would like to expand into a group?
On the other hand you can keep it as you have it but I wouldn't bother specifying the user type. That can be derived based on if they belong to a group or not.
Many ways to tackle this problem...
I have a database and normally users are the central object.
In database I have a tables roles and users in roles so I can give users different permissions on site.
But now I have one doubt.
I saw before one database with structure like this (User is in 1:1 relation to other tables):
User{UserId, Username, Email etc.}
Admin{UserId, some specific columns}
Child{UserId, some specific columns}
Admin{Parent, some specific columns}
and other tables are connected to user not through User table but through Admin, Child and admin.
Because now I design my database I have Users and user can be Admin, CompanyManager and Professor.
I wonder should I design table like I show above or just relied on roles?
What is advantage of the first approach?
And also in my business model User doesn't have to be CompanyManager or Professor so this is actually 1 to 0 or 1 design.
What is a good way to design database with scenario like this?
The advantage of having specific tables for certain types of users is to store information that is only relevant to that class of user.
In your example,
perhaps all users would have a manager - so the manager ID would go in the users column.
managers would have permissions to view certain information, so this would be handled via a role.
only professors would have a Subject, or the "HasTenure" property. So this information would go in a professors table. Using this approach, you avoid the need to have a "Subject" column in the users table, when it is only applicable to a certain subset of users. As such you avoid a functional dependency in the users table, and a violation of 3rd Normal Form.
I prefer this approach:
In this way, you can easily group Roles into categories and assign them to users.
My application has several kinds of users with different sets of properties, for example: customers and employees. One user may be belong to more than one of these roles.
So I decided to have this (simplified example) structure of my database:
users (contains the fields applicable to all different kinds of users)
id
username
email
customers (contains fields applicable to customer role)
id
user_id
shipping_address
employees (contains fields applicable to employee role)
id
user_id
salary
Question 1: Is this a good way of handling user roles with many different properties?
In reality I have six roles with sets of 7-20 properties. Some of the roles are not even conventionar roles, but bore like extra properties. If a user decides to login with a Facebook acoount, then the Facebook_account table is applicable.
Question 2: When using an ORM, in my case Eloquent, would it make sense to have the role model (customers) extend the user model?
When I fetch a customer object I really want all user och customer properties together, without having to merge them manually.
I read this on msdn:
Views let different users to see data in different ways, even when they are using the same
data at the same time. This is especially useful when users who have many different interests and skill levels share the same database.
For example, a view can be created that retrieves only the data for the customers with whom an account manager deals. The view can determine which data to retrieve based on the login ID of the account manager who uses the view.
My question:
For the above example , i would have to have a column named Userid/LoginId on my table on which the view is created so that i can apply a check option in the view for this column. and then if a user with a name not in that column tries to enter data , then he/she is blocked.
Yes, you are right. You should
add a column with the user's login or database user name (say you call it username),
each row should have username populated with the login or database name of the person who is allowed to see that row
you can then build a view where you use the builtin functions SUSER_SNAME() (for logins) or USER_NAME (for database names) in your WHERE clause to filter only the rows the user is allowed to see
See Granting Row-Level Permissions in SQL Server (ADO.NET).
You don't have to add a column to the table: it could be more appropriate to instead add a new table to model the relationship.
There's a deisgn rule of thumb that states a table should model an entity or a relationship but not both. Let's say the table in question models the companies a customer owns (i.e. an entity table) and the business rule states the the account manager can only see companies relating to customers he looks after.
Is account manager an attribute of a company? No, so account_manager should not be a column (attribute) in the Companies table.
Is there a direct relationship between account_manager and a company? No, so a relationship table between is not due here (because the relationship is indirect).
Rather, the direct relationships are between account manager and customer, and between customer and company respectively. There should be two tables whose sole purpose is to model these relationships.