How to manage user access and user permissions - php

I am working on an application with PHP + MySql. In my application I have a table for users, a table for relationships (friends, following, subscribed) and a table for posts. The main actions for users are:
A user has friends
A user can make post entries
A user can see the friends entries
And finally a user can block entries viewing for specific friends
If user A is friends with user B, then user A can see all entries from user B. But user B can restrict access to only a few friends for example. Now the query is: how can I manage these permissions? I was thinking of a table that stores each user that is blocked for viewing an specific entry, but this would't be a good idea once a single user can have several friends. So, how can I solve this? Can someone show me how to start? Maybe the right terms for searching on Google or a link for something similar.

You are on the right track. You are going to want to use linked tables. You would start with a table users. Each user has an id. Then create a table users_friends. This table would consist of two ids, user_id and friend_id. The last table would be users_restricted which would also consist of two ids, user_id and restricted_id.
For example
users
user_id name
1 user1
2 user2
3 user3
users_friends
friend1_id friend2_id
1 2
2 3
This says user 1 and 2 are friends and users 2 and 3 are friends. (This assumes that if user 1 is friends with user 2 then user 2 is also friends with user 1)
users_restricted
user_id restricted_id
1 2
Now even though user 1 and user 2 are friends, user 2 is in the restricted list meaning don't allow user 2 to view user 1's entries.
You can see that tables are linked via ids and all the ids come from the users table. This can be expanded to relate to entries as well. Just refer to entries by their id.
To have users blocked for specific entries you would have the following tables.
entries
entry_id user_id ... other columns holding entry information
1 1
2 1
3 2
4 2
Now user 1 has made 2 entries (entry 1 and entry 2) and user 2 has made 2 entries (entry 3 and entry 4). Another table would hold the restrictions.
entries_restricted
entry_id restricted_user_id
1 2
This would say user 2 cannot view entry 1.
To get the entries visible to user 2 your statement would look something like this.
SELECT e.*, er.entry_id FROM entries e JOIN entries_restricted er ON e.entry_id=er.entry_id WHERE er.restricted_user_id != 2;
The statement selects all the entry information excluding entries restricted to user 2.

You can start using following tables.
The first table is users table (as Jason.Wolfsmith suggested)
users
u_user_id u_name
1 user1
2 user2
3 user3
The second table can be like this.
friends_permissions
f_user_id f_friend_id permission entries
1 2 1 entry1
2 3 0
1 3 1 entry3
This table will contain permission and name of entries that should be allow for view. 1 - restrict some entries; 0 - allow all.
In the column permission data type might be set as SET('1','0') and data type in entries NULL.
Thus, user1 don't allow to view entry1 to user2. (entry1 and entry3 are from entries table).

Related

MySqli php Make Table only view-able to SESSION user or those at his level

beginner here.. this one is a bit complicated.
I created 2 tables, 1 table is for data a user can submit, the other table is for user names passwords and user levels.
ive created user log in levels,
each user can submit a record to the database.
I want to make it so the Active user can only see what he has submitted AND what other users at his level and below have submitted.
ex.
level 4 user can see all submitted by level 1 2 3 and 4
level 3 can see all submitted by level 1 2 3
etc
$query = "SELECT * FROM `employeeinfo` WHERE CONCAT(`posted`) LIKE '%".$_SESSION['sess_user']."%' OR (`id`) LIKE '29'";
The OR id is just a current place holder.
But i guess i want IF (sess user)Mike = (level)3
Then Show 'Posted by' Sess user (which i already did) OR show all where 'Posted By' (which is a name field) is level 3, 2, 1 (in the level field)
Join with the credentials table twice. Once to get the level of the logged in user, and then to get the names of all the users with the same or lower level.
$query = "
SELECT e.*
FROM employeeinfo AS e
JOIN credentials AS c1 ON e.posted_by = c1.username
JOIN credentials AS c2 ON c1.user_level <= c2.user_level
WHERE c2.username = '{$_SESSION['sess_user']}'";

Creating a SQL friends table to store [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 8 years ago.
Improve this question
I have taken it on myself to create a site that allows users to add each other as friends and comment on each others posts. After looking into this I'm not sure exactly how to start. I have a posts and a users table.
My question is how would I relate the databases to
1.Check if user A has sent a friend request to user B?
2.Store a value to indicate that they are friends?
I've browsed around this site before posting but can't seem to understand how to carry this out. Pretty sure I'm just over complicating it. Could anyone explain the concept or how this works?
This could be done with a relational database, and it would be worth reading up on how relational databases work e.g. https://www.youtube.com/watch?v=NvrpuBAMddw
But - to give some pointers, it looks like yor want your relational database to allow for the following functions:
a number of users
a series of posts, by certain users
a number of relationships between users
an ability to verify a relationship before it is confirmed
a series of posts, by certain users
a number of 'sub-post' comments on posts
1) Let's start with the 'friend request' section.
This would need you to have a) a whole load of different users, and b) a load of relationships between those users.
You'd need to represent that in 2 different tables - so create a users table with the following fields:
UserID, name, age, [details, password, address etc etc]
and then a friends table which has these fields:
friendID, userID1, userID2, [date, confirmed]
Your user table might look like this:
UserID, name, age,
1 Fred 18
2 George 24
3 Michael 20
4 Alice 24
5 Sophie 20
6 George 19
Let's say that Michael wants to become friends with Alice and Fred, and Alice wants to befriend Sophie - you'd want to create records in your friends table that looked like this:
FriendID, userID1, userID2,
1 3 (this refers to Michael) 4 (this refers to Alice)
2 3 (this refers to Michael) 1 (this refers to Fred)
3 4 (this refers to Alice) 5 (this refers to Sophie)
So if you then looked for Michael's friends - you'd do a query which looked for:
every record from the friend table where userID1 = Michael's userID.
From the userID2 field, you'd get userID 4 and userID 1
By looking up those userids in the user table, you'd find more details for Alice and Fred.
You should make this query check whether userID1 OR userid2 = the userID you need, so that you get the same results if e.g. the table looked slightly differently:
FriendID, userID1, userID2,
1 3 (this refers to Michael) 4 (this refers to Alice)
2 1 (this refers to Fred) 3 (this refers to Michael)
3 4 (this refers to Alice) 5 (this refers to Sophie)
Otherwise you'd only know about Alice.. but you want to know about Fred too.
2) If you want to confirm a relationship, you could add a 'confirmed' field to the friends table - set it to binary 0 = not confirmed / 1 = confirmed.
When the friendship is requested, you add the record to the table, but when it is confirmed, you would update the 'confirmed' field for that record to 1.
Let's update our friends table accordingly:
FriendID, userID1, userID2, confirmed
1 3 (Michael) 4 (Alice) 0
2 3 (Michael) 1 (Fred) 1
3 4 (Alice) 5 (Sophie) 1
If you want to see all friends that are pending Michael's acceptance, you'd search for:
any records from the friends table where userid1 = 3
AND confirmed = 0 ... which means it hasn't been accepted yet.
This would show that alice hasn't yet been accepted as a friend by Michael.
If you want to see all friends a user had requested but which haven't been accepted you'd look for:
any records from the friends table where userid2 = the user you're looking for
AND confirmed = 0 ... which means it hasn't been accepted yet.
If you want to see all accepted friends, switch 'confirmed' to 1.
3) You also wanted to have posts for each user... so you'll need a posts table with fields for:
postid, userid, date, content
We've already got your user table, so let's say that Michael wanted to post some stuff. The posts table might look like this:
postid, userid, date content
1 3 (Michael) [auto datetime] Hi everyone
2 3 (Michael) [auto datetime] This is my second post
You've now got a relationship between Michael and the posts table. If another user posted something, they'd add another line with a different userid. You can then retrieve all the posts from the posts table where the userid = 3, which is Michael's userid.
4) To add comments on posts you would need a comments table that might look like this:
commentid, postid, userid content
1 1 3 (Michael) Michael is commenting on his own first post...
2 2 4 (Alice) Alice is saying something on Michael's second post

Simple MYSQL data query?

Just a really simple question. In my SQL database I have a column named "friend_count" in table "users" to record all friends the logged in user has. This works with UserID numbers and I am trying to figure out how to record them all. Here's my example:
USER #29 becomes friends with USER #422
In the user database under USER #29's info in the column "friend_count" there will then be the number "422", if he then becomes friends with USER #500, it will show "422, 500" and so on... If he deletes one, that particular number is removed from the box. The script will then search these numbers through the user database to show a list of the people you are friends with.
How can I do this? Any ideas? Thanks!
Any time you have a delimited list of values in a column it's almost always a sign that the data model is incorrect. (Actually, I can't think of an exception to this, but I'll stick with "almost always" just to be safe.)
In this case you have two types of entities:
User
Friendship
A friendship, though not a physical object, is a conceptual entity in and of itself. It connects two users and can add more information related to the friendship itself but not necessarily to the two users.
So you might have tables like this:
User
--------
ID
Name
etc.
Friendship
--------
ID
OriginatingUser
AcceptingUser
BecameFriendsOn
etc.
So OriginatingUser might be the user who sent the friend request, and AcceptingUser might be the user who accepted it. BecameFriendsOn is the date it was accepted. You'd probably want to have statuses and other dates to keep track of pending requests, denied requests, etc. But all of this information is related to the friendship, not necessarily to the users.
The concept you're looking to understand here is called a Foreign Key. The OriginatingUser and AcceptingUser columns are the same data type as the ID column on the User table. You would create the Friendship table such that those columns are foreign keys to the User table, this enforces the integrity of the data so that you can't create a Friendship record without two valid and existing User records.
Then to get the list of friends, you'd join the tables in a query. Perhaps something like this:
SELECT
User.Name
FROM
Friendship
INNER JOIN User ON Friendship.AcceptingUser = User.ID
WHERE
Friendship.OriginatingUser = ?
When supplied with the ID of the originating user, this would get all of the names of users to whom that user sent a friend request. You can further build on the query to also get users who sent this same user a friend request, and so on. By making use of the key foreign key relationships between tables which represent different types of entities in the system, you can construct very robust queries to view that data in lots of different ways.
You are describing a relationship between two entities so you can create a table to store the details of that relationship.
Suppose that you have your user table with a userid column and other columns. You can then create a friends table with two columns that are both foreign keys to the user table.
friends = (user, friend)
Thus, for each friend that user #29 gets you need to add a row into the friends table. For example:
USER
ID NAME ...
29 Sam
30 Henry
32 Jane
Friends
user friend
29 30
29 32
Sam is friends with both Jane and Henry but Jane and Henry are not friends.
I would create a table "friendship" with two cols "user" and "friend", then you start adding pairs of user/friend ids
users table:
id, username, whatever else
friends table:
relationship_id, user_id, user_friend_id
example query to get a list of IDs that belong to the users friends:
SELECT f.user_friend_id FROM users u
LEFT JOIN friends f ON f.user_id = u.id
WHERE u.id = {$user_id}
A very simple approach, assuming that if UserA becomes friends with UserB , then UserB also becomes friends with UserA.
Usually, Comma Separated Lists are not recommended, as they will become a pain when the list is very large. A simpler approach will be, make a table friends with columns user_id and friend_id Where user_id and friend_id are the respective UserIDs .
Now when you want to add a friend to someone's list, use the following :
INSERT INTO users (user_id,friend_id) VALUES(UserA,UserB),(UserB,UserA)
Now when you execute the above query, you will have 2 new rows in your friends table :
user_id friend_id
UserA UserB
UserB UserA
When you want to get the list of a user's friends, use :
SELECT friend_id FROM friends WHERE user_id=(Your user's ID)
This will return a row one by one, and hence will give you all the IDs of friends of a particular user.
Now when you want to delete a friend, use :
DELETE FROM friends WHERE (user_id,friend_id) IN ((user_id,friend_id),(friend_id,user_id))
This removes both the rows from the table, which means that the relationship between UserA and UserB is deleted, and neither of them is friend of each other.

Grouping Users on a virtual roster

I'm trying to come up with the most simple / userful / efficient method to group 3 users together using mysql.
To set the stage:
X number of users in a list (all with int account_id's)
mini groupings need to be created on a per user basis (user 1 wants to group with 220 for instance).
Max 3 people per grouping (user 1 + user 220 + user 9123 = group full)
Need to easily find if a user is in a group or not without looking in a bunch of columns
I'm stumped about how best to create a schema for this (so I can easily query my table to see if user is in a group, or if they can be added, or check for group space availability).
Anyone have any idea? My initial thought is schema like this (but it really seems too rigid):
Schema
GROUP_ID USER1 USER2 USER3 LASTUPDATE
1 1 220 null 5/25/2011 20:00:00
2 300 2 4 5/25/2011 20:00:00
How would you do it to make something this simple very flexible and efficient. I really feel stupid for asking.
Personally I would approach this by using 3 tables.
Users Table
user_id user_name ..... last_update
Groups Table
group_id group_name ......
Users to groups Table
user_to_group_id user_id group_id
This forms a many to many relationship by linking through the "Users to groups" table, obviously you can have more that 3 users linked to one group so you will have to make your PHP logic check for this when adding a new user to a group.
You can simply use SQL joins to retrieve all the data required and filter the results in your PHP code.
I hope this helps
Kind regards
Garry

PHP MySQL. Linking 2 Tables columns together

I've got an small issue, I'm trying to make my own forum, but I am stuck at something.
I have 3 tables, 1 users with a user_level (Authentication level).
forum_section which contains all the sections with a user_level again.
But how can I link forum_section.user_level to forum_topics.user_level.
So if I define: forum_section.user_level = 4 for forum_section.section_id = 1.
For example:
Someone wants to visit the forum_section id 1 then they must have a auth level of 4.
And when they go to the topic it then again checks if the user level is 4, but I do not want to manual set the topic level, topic level must always be the same as the section level.
I've googled for this, but I can't really find a good manual for it. I guess it has something to do with: "foreign keys"?
Okay, let me explain a bit more just to be sure.
I have 3 tables
Table User
username = Wesley
userlevel < for example 4(admin).
Table section
section_id = 3
section_name = News
section_level = 3 <require level to view.
table topics
topic_id = 123
topic_name = I like candy
topic_level = Needs to be the same as section_level so if I change section_level it automatically changes this too.
You should have to manage your database by using master and transaction tables.
Your table format should look like this:
table name: user
user_id user_name
1 abc
2 xyz
3 pqr
4 new
table2 name : forum_section
forum_id user_id forum_name
1 4 abc
2 4 jkl
3 2 cbd
4 3 lmn
Now, you can JOIN these two tables and make a query as you want, like this:
SELECT forum_id FROM forum_section as fs,user as u WHERE fs.user_id = u.user_id AND fs.user_id = 4
This may help you. Please write if you need more help!
You need to either use a SQL JOIN or a NESTED SUB QUERY
The simplest implementation would be to initially establish the users access level, then filter subsequent queries based on this- so in your PHP, pass the access level to subsequent requests for content- if the query returns anything, the user can view the content, if not- they can be redirected.

Categories