How can I organize Role Based Access Control (?) in my scenario? - mysql

I have a database where there are products grouped by categories.
When a user registers, he selects a category, which cannot be changed. The user will be able to perform some actions only on the products of that category, and some other actions on products of other categories as well. E.g. a user can comment on a product only in his category, or put a like on a product in another category.
A user with "superpowers" becomes a Moderator. He can do everything a user does, plus the ability to change something made by another user. E.g. he can modify a comment written by another user but always in reference to a product of the category he belongs to.
Then there are the Admins, who are Moderators who, however, can work independently of the category.
How can I set up the tables for this scenario?

Related

Database: How to make my shopping database to have products with various sizes, specs, categories, grades etc?

I am designing an online shopping database, however for a specific set of products. The products has the following.
Product Species
Product Category
Product Type
Product Grade
Product Size
Below is my database diagram
In the application, when we select the Product Species, we will be taken to a page where we have to do other selections. In this page there is a dropdown, where we have to select the Product Category. Then the relevant list of Product Types will get loaded. Then select the Product Type, the relevant list of Product Grades will get loaded. Now you can select the product size.
Below is the UI of the applications selection page
HERE THE "C/T" MEANS "CATEGORY AND TYPE"
With my database design, I find it difficult to perform the "selection operation" in the app itself. To load the fresh products after selecting the product species I can simply call select * from fresh_products where idproduct_species=1. But then, how can I find the Product Grades by selecting a C/T? How can I find the Product Spec by selecting the Product Grade?
I know I can run some quarries in the fresh_products table and get this done, even though it won't be easy as a select statement.
If you are interested, below I have shared the product sheet, with dummy information.
To achieve what I need, is my database design a good one or is there a better model?

SQL Database Structure for Users + Memberships + Groups

I'm developing an e-commerce site and I wanted to get this community's thoughts on a database structure for groups, users, and their memberships.
THE GOAL: Determine a user's group membership(s) and access privilege at login. A user could be a seller on this site, an admin, a site support, or ANYTHING. Must be scalable.
INITIAL THOUGHT: Three separate tables: users, groups, and memberships. At a successful login, search the membership table for the user's ID and get group ID's from that same row in the membership table. From there, another query to get group information from the groups table (like name of group, description, etc). Store the memberships in the user's session and call it a day.
THE CONCERN: At log in, I don't want to unnecessarily perform additional queries. The above "initial thought" consists of 3 separate queries at login.
THE QUESTIONS:
Is this the right approach?
Any better design solution(s)?
Better to break admins into their own table, or toss 'em into the same groups table?
The database design is reasonable. As a user can belong to multiple groups and can have multiple memberships, two additional tables USER_GROUP and USER_MEMBERSHIPto hold the relations between users and groups and between users and memberships will be necessary.

Better structure for database information

I have a list of users with information, currently at like 60+ and a list of products that users could have, which contains like 15 products as of right now. Both lists will grow with the users one growing at a greater speed than the products one.
Is it better to add a products field to the users table and just keep the products there or should I make a separate table for products and under each one, add the users that own that product.
Or does it just not even matter.
One user might have more than one product, so a join table is a good option.

How to handle a user's profile fields privacy?

I have a user table which has all details like username, email id, birth date, contact no. A user has friends and these friends may belong to certain groups like for e.g close friends, family, colleagues which user has created. A friend may belong to one group or many groups or none of the groups at all.
I need to set a certain privacy related to the attributes of the user table for friends or group of friends. Like for e.g. my group of family can only view my birth date or colleagues can view only my email id but no other details like birth date or contact number.
How can I achieve this privacy?
Thanks.
Having a separate table for every "special" attribute, could lead you to have a lot of tables. On the other hand, you can use the entity-attribute-value model. This way you will have one table for users, one table for all the user's attributes, and one table for the values associated to an specific user and his attributes.
User
id
idGroup
Attribute
id
description
Value (User-Atribute)
idUser
idAttribute
value
In addition, you can relate the attribute table and the group table. By relating these two tables you can specify which attributes will be visible for each group. Don't forget to relate the user table and the group table.
Group
id
description
Access (Group-Attribute)
idGroup
idAttribute
Shouldn't you try to handle that logic on the code, instead of the database? It seems that this is related to business logic instead of the actual data model.
If you want to go forward with this approach have you considered having the private data in a separate table?

Permissions for web site users

I'm working on a web site where each user can have multiple roles/permissions such as basic logging in, ordering products, administrating other users, and so on. On top of this, there are stores, and each store can have multiple users administrating it. Each store also has it's own set of permissions.
I've confused myself and am not sure how best to represent this in a db. Right now I'm thinking:
users
roles
users_roles
stores
stores_users
But, should I also have stores_roles and stores_users_roles tables to keep track of separate permissions for the stores or should I keep the roles limited to a single 'roles' table?
I originally thought of having only a single roles table, but then what about users who have roles in multiple stores? I.e., if a user is given a role of let's say 'store product updating' there would need to be some method of determining which store this is referring to. A stores_users_roles table could fix this by having a store_id field, thus a user could have 'store product updating' and 'store product deletion' for store #42 and only 'store product updating' for store #84.
I hope I'm making sense here.
Edit
Thanks for the info everyone. Apparently I have some thinking to do. This is simply a fun project I'm working on, but RBAC has always been something that I wanted to understand better.
This is probably obvious to you by now, but role based access control is hard. My suggestion is, don't try to write your own unless you want that one part to take up all the time you were hoping to spend on the 'cool stuff'.
There are plenty of flexible, thoroughly-tested authorization libraries out there implementing RBAC (sometimes mislabeled as ACL), and my suggestion would be to find one that suits your needs and use it. Don't reinvent the wheel unless you are a wheel geek.
It seems likely to me that if I have permission to do certain roles in a set of stores, then I would probably have the same permissions in each store. So having a single roles table would probably be sufficient. So "joe" can do "store product updating" and "store product deletion", then have a user_stores table to list which stores he has access to. The assumption is for that entire list, he would have the same permissions in all stores.
If the business rules are such that he could update and delete in one store, but only update, no delete, in another store, well then you'll have to get more complex.
In my experience you'll usually be told that you need a lot of flexibility, then once implemented, no one uses it. And the GUI gets very complex and makes it hard to administer.
If the GUI does get complex, I suggest you look at it from the point of view of the store as well as the point of view of the user. In other words, instead of selecting a user, then selecting what permissions they have, and what stores they can access, it may be simpler to first select a store, then select which users have access to which roles in that store. Depends I guess on how many users and how many stores. In a past project I found it far easier to do it one way than the other.
Your model looks ok to me. The only modification I think you need is as to the granularity of the Role. Right now, your role is just an operation.
But first, you need a store_role table, a joint table resolving the Many-to-many relationship b/w a role and a store. ie, one store can have many roles and one role can be done in many stores.
Eg: StoreA can CREATE, UPDATE, DELETE customer. and DELETE customer can be done in StoreA, StoreB and StoreC.
Next, you can freely associate users to store_role_id in the user_store_roles table.
Now, a user_store_role record will have a user_id and a store_role_id:
A collection of
SELECT * FROM USER_STORE_ROLE WHERE user_id = #userID
returns all permitted operations of the user in all the stores.
For a collection of users's roles in a particular store, do an inner join of the above to user_store table adding a WHERE part of like
where STORE_ROLE.store_id = #storeID
Put a store_id in the user_roles table.
If this is Rails, the user model would have_many :stores, :through => :roles