Django--Model Construction (User Profile or Seperate Model) - mysql

The phrasing of the title may be a little confusing. I have an app that has users with varying permission levels (admin and non-admin).
I was unsure which of the following constructs was preferable: just go with User_Profile and add an admin field or create two models (one for admin and one for )
class User_Profile(models.Model):
user=models.ForeignKey(User, unique=True)
employer=models.ForeignKey(Company,blank=True)
admin=models.BooleanField(default=False)
phone=models.CharField(blank=True)
Is this preferable to creating a separate table for Admins that just links to User and Employer through ForeignKeys? My views will be checking each user for Admin status, so I was concerned that querying a large User_Profile table over and over again might become expensive.
Probably not at the stage to optimize this, but I'm just curious about best practice.

I'd actually recommend Django's built in user permissions over either of those options:
https://docs.djangoproject.com/en/dev/topics/auth/#methods
Here's a quick tutorial to help you get started:
http://parand.com/say/index.php/2010/02/19/django-using-the-permission-system/

Related

Zend 2 Individual Access Control with Database

I understand the concept of RBAC in ZF2, even with the ACL defined in config-files. But now I want to make some of my application modules available to individual users. E.g. user "foo#bar.com" may use modules A and C, user "bar#foo.net" has A and B available and so on. I can realize this in a MySQL database, but how could I do this in ZF2? I got an ACLService class with an "isAllowed" function where roles are compared, is this the right place to introduce some database?
In a few words a solution could be:
You introduce a user_role table and a role_privileges table.
In your user_role table you link user_id, email or username (a unique user identifier) to a role.
In your role_privileges table you link the role to one or more privileges (in your case a module, but it could also be a controller name or a route or whatever you want to manage).
You could also skip the role_privileges table and define the privileges in a config. That is decision is up to you...
If you don't want to write all the code then there are several ZF2 modules available that make this possible.

Efficient way to handle user roles

I am working on one portal where will be few user roles. I have been wondering what is the best way to handle them. I have created separated tables for users and clients, but clients will want the functionality as users and users can become clients easy too.
I also don't want to make many joints, so what I as thinking is this:
I will have 4 different user roles (at least for now) as follow:
user
client
reviewer
admin
I will assing "id" to each role. At the same time I will keep table in mysql with these roles. It will be something like:
1 - admin
2 - reviewer
3 - client
4 - user
This table will be used only upon creation of user, to get the code of user "permissions". So Let's say that there will be a guy who is a user and reviewer. His role would be 24.
login password email role created
----------------------------------------------------------
guy password guy#gmail.com 24 2012-12-08 23:12:30
I think this could work pretty well, but still want to ask if you guys think this is good and effective solution.
Thanks
The other way to do this would be to have a many to many USER_ROLE table where for your example guy would have the following entires.
login role
guy 2
guy 4
I generally prefer this method of tracking roles. A join against this table in a situation like this should be fast and painless, especially if you move to using a user_id instead of a login, and index appropriately.
What you're defining is a Role Based Access Control System (I would suggest looking up resources on this). An RBAC system will have a separate table for users and another table for roles. There will be a many to many relationship between users and roles. Also, you will connect a permissions table to roles in another many to many relationship. The image attached represents how to implement this system:RBAC SYSTEM IN MYSQL
A similar question was asked before: How to design a hierarchical role based access control system

What is a better data model to use to store user profiles?

I am working on the data model for a relational database where I have to store User Information as well as User's profile such as Education Level, personal interests, hobbies, and etc. Similar to what most of the social networking sites have or any other systems that allow you to build a profile.
I cannot decide if it would be better to store all this information in one Users table, or break it into 2 tables.
If I would break it into two tables I would have Users table that would just store UserID, Name, e-mail, DOB, gender.
UserProfiles would store the rest of the stuff pertaining to a profile, sharing the same UserID with Users table
If there are multiple profiles of a single user means one to many relation then i would recommend you to create 2 tables one is user and other is user-profile.
If one user have only one profile then your should create only one table with both attributes on User as well as profile.
Go for the more modular design, this will allow for more flexibility and control. The only time I would recommend keeping the data in a single table is if you plan to query the same data frequently.
There is a great article here which goes into depth as to why joins are expensive. You should ultimately base your decision off the information provided in the link, however as I mentioned before if you plan to query the two tables together frequently then keep the data in a single table.
I think,in order to decide which data model to chose, just look at some of the similar requirement Datamodels, which are presented in this Datamodel Library.
Specific to your User-profiles Datamodel Requirement, this link may be useful.
Hope those links will be useful. OR I got this Data model image depicting facebook type data model:

MySQL database model for signups with and without addresses

I've been thinking about this all evening (GMT) but I can't seem to figure out a good solution for this one. Here's the case...
I have to create a signup system which distinguishes 4 kinds of "users":
Individual sign ups (require address info)
Group sign ups (don't require address info)
Group contact (require address info)
Application users (don't require address info)
I really cannot come up with a decent way of modeling this into something that makes sense. I'd greatly appreciate it if you could share your ideas.
Thanks in advance!
Sounds like good case for single table inheritance
Requiring certain data is more a function of your application logic than your database. You can definitely define database columns that don't allow NULL values, but they can be set to "" (empty string) without any errors.
As far as how to structure your database, have two separate tables:
User
UserAddress
When you have a new signup that requires contact info, your application will create records in both tables. When a new signup doesn't require address info, your application will only create a record in the User table.
There are a couple considerations here: first, I like to look at User/Group as a case of a Composite pattern. It clearly meets the requirement: you often have to treat the aggregate and individual versions of the entity interchangeably (as you note). Implementing a composite in a database is not that hard. If you are using an ORM, it is pretty simple (inheritance).
On the other part of the question, you always have the ability to create data structures that are mostly empty. Generally, that's a bad idea. So you can say 'well, in the beginning, we don't have any information about the User so we will just leave all the other fields blank.' A better approach is to try and model the phases as if they were part of an FSM. One of the clearest ways to do this in this particular case is to distinguish between Users, Accounts and some other more domain-specific entity, e.g. Subscriber or Customer. Then, I can come and browse using User, sign up and make an Account, then later when you want address and other personal information, become a subscriber. This would also imply inheritance, and you have the added benefit of being able to have a true representation of the population at any time that doesn't require stupid shenanigans like 'SELECT COUNT(*) WHERE _ not null,' etc.
Here's a suggestion from my end after weighing pro's and con's on this model. As I think the ideal setup is to have all users be a user entity that belong to a group without differentiating groups from individuals (except of course flag a group contact person and creating a link with a groups table) we came up with the alternative to copy the group contact user details to the group members when they group is created.
This way all entities that actually are a person will get their own table.
Could this be a good idea? Awaiting your comments :)
I've decided to go with a construction where group members are separated from the user pool anyway. The group members eventually have no relation with a user since they don't require access to mutating their personal data, that's what a group contact person is for. Eventually I could add a possibility for groups to have multiple contact persons, even distinguishing persons that are or are not allowed to edit any member data.
That's my answer on this one.

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