Permission based on one column - secure? - asp.net

I am developing an early version of my site and before I create the production version, I'd like people's opinions on whether I'm going about things the right way. The main objective is to allow users to share playlists. I have the User table (ASP.NET Membership), Playlist table and a permission table. I'd like a user to create a playlist and grant/deny access to it for a given user. My approach to this is to have the permission table contain a "pStatus" column where 0/null = deny, 1 = read.
When a user requests permission to access a playlist, the creator chooses the pStatus enumeration. The column is then changed accordingly for the recipient. When accessing the recipient's profile page, a scan of the column is done to check all playlists the recipient has access to and the relevant playlists are displayed.
Is this an efficient and secure way of doing things? Or is relying on one column not enough?
(nb - playlists can be considered to be similar to Facebook groups)
Thanks for any advice

I would use some sort of bitmask in the n-m relation table I'm guessing is in between User and PlayList (i.e. a table named UserPlaylist, because 1 user can have access to more than 1 playlist and vice versa 1 playlist can be accessed by more than 1 user).
If you define the needed permission levels up front (i.e. 0 = no access, 1 = read, 2 = write, etc.), you can just add a column to the UserPlayList table, that represents the access level.
So the UserPlaylist table will have 2 foreign key columns of which the combination should be unique (i.e. define the primary key to be the 2 foreign key columns) and a column that holds the level of access in the form of a bit / integer.

So Permission has foreign keys to User and Playlist. Is there any reason for the third column specifying permission level? It sounds like it should be: If a row exists in Permission, the user is allowed to access the playlist.
Otherwise, that sounds good to me.

Related

What's the best way to store users in DynamoDB so I can get one efficiently, and a related group as well?

I have users for my website that need to log in. In order to do that, I have to check the database for them, by email address or a hash of their email.
Some of my users have an online course in common.
Others are all on the same project.
There are multiple projects and courses.
How might I set up my table so that I can grab individual users, and efficiently query related groups of users?
I'm thinking...
PK = user#mysite
SK = user#email.com
projects = [1,2,3]
courses = [101,202,303]
I can get any user user with a get PK = user#mysite, SK = user#email.com.
But if I query, I have to filter two attributes, and I feel like I'm no longer very efficient.
If I set up users like this on the other hand:
PK = user#email.com
SK = 1#2#3#101#202#303
projects = [1,2,3]
courses = [101,202,303]
Then I can get PK = user#gmail.com and that's unique on its own.
And I can query SK contains 101 for example if I want all the 101 course students.
But I have to maintain this weird # deliminated list of things in the SK string.
Am I thinking about this the right way?
You want to find items which possess a value in an attribute holding a list of values. So do I sometimes! But there is not an index for that.
You can, however, solve this by adding new items to the table.
Your main item would have the email address as both the PK and the SK. It includes attributes listing the courses and projects, and all the other metadata about that user.
For each course, you insert additional items where the course id is the PK and the member emails are the various SKs in that item collection. Same for projects.
Given an email, you can find all about them with a get item. Given a course or project you can find all matching emails with a query against the course or project id. Do a batch get items then if you need all the data about each email.
When someone adds or drops a course or project, you update the main item as well as add/remove the additional indexed items.
Should you want to query by course X and project Y you can pull the matching results to the client and join in the client on email address.
In one of your designs you're proposing a contains against the SK, which is not a supported operator against SKs so that design wouldn't work.

How to obtain list of common users from different groups in firebase DB

Is there any way I can find if users is present in both the groups here: user 1 so that notification/data can be sent to only that set of common users only?
As DB grows I think it will be inefficient to check if every user in one group is present in another or not.
Yes there is. You can create a list of users from GroupA, then create another list of users from GroupsB and then just simply use this line of code using Java8:
!Collections.disjoint(list1, list2);

how to generate unique id per user?

I have a webpage Default.aspx which generate the id for each new user after that the id will be subbmitted to database on button click on Default.aspx...
if onother user is also entering the same time the id will be the same ... till they press button on default.aspx
How to get rid of this issue...so that ... each user will be alloted the unique id ...
i m using the read write code to generate unique id ..
You could use a Guid as ids. And to generate an unique id:
Guid id = Guid.NewGuid();
Another possibility is to use an automatically incremented primary column in the database so that it is the database that generates the unique identifiers.
Three options
Use a GUID: Guid.NewGuid() will generate unique GUIDs. GUIDs are, of course, much longer than an integer.
Use intelocked operations to increment a shared counter. Interlocked.Increment is thread safe. This will only work if all the requests happen in the same AppDomain: either process cycling on a refresh of the code will create a new AppDomain and restart the count.
Use an IDENTITY column in the database. The database is designed to handle this, within the request that inserts the new row, use SCOPE_IDENTITY to select the value of the identity to update in memory data (ORMs should handle this for you). (This is SQL Server, other databases have equivalent functionality.)
Of there #3 is almost certainly best.
You could generate a Guid:
Guid.NewGuid()
Or you could let the database generate it for you upon insert. One way to do this is via a Sequence. See the wikipedia article for Surrogate Keys
From the article:
A surrogate key in a database is a unique identifier for either an entity in the modeled world or an object in the database. The surrogate key is not derived from application data.
The Sequence/auto-incremented column option is going to be simpler, and easier to remember when manually querying your DB (during debugging), but the DBA at my work says he's gotten 20% increases in performance by switching to Guids. He was using Oracle, and his database was huge, though :)
I use a utility static method to generate id's, basically use the full datetime(including seconds) and generate a random number of say 3 or 4 characters and return the whole thing, then you can save it to the database.

Adding an integer ID to ASP.NET Forms Authentication

In the standard forms authentication, users are identified by a Guid. I want to give my users an UserId of type int (doesn't have to be the primary key, just something to do lookup's on).
Is it safe to add an additional column to the aspnet_users table, or should I create a new table which FKs to the UserId column and has a Unique column which generates the integer ID?
The later sounds like a bad performance hit to take just for the sake of an int!
EDIT
I want to create URLs like those on stackoverflow. eg. https://stackoverflow.com/users/23590/greg-b where the User ID is an int. For that reason I don't want to use Guids.
I'd create profiles and store the associated urlID there. Web Forms don't have Profiles available out of the box, but you can see a workaround here:
http://www.codersbarn.com/post/2008/06/01/ASPNET-Web-Site-versus-Web-Application-Project.aspx
The advantage of using Profiles is that you can tap into all the existing logic and won't have to write as much custom code yourself, aside from constructing the URL.
You could combine this with Routing for friendly URLs, if you're using ASP.NET 3.5 or up.
UPDATE: kinda similar question:
Shorter GUID using CRC

Using IPrinciple.Identity.Name as a key in a dataBase to identify user's rows

I'm writing a small intranet app that uses Windows Authentication and Asp.Net MVC.
I need to store various bits of data in a db against each user.
As far as I can tell the IPrinciple object does not seem to have something like a unique id. So I was thinking I could just use User.Identity.Name as a unique value to identify rows in my db.
Is this a bad idea? Is there an alternative to this approach?
Thanks for any help.
I would create a User table that included an identity column as the id. When a person accesses the site, I would check the user table for that individuals unique id, and read it if it exists, or insert a new row if the user is new.
Login names can be long, and that could affect your indexes depending on the expected size of your data.

Resources