I have a use case where I want to connect two different user roles, and if they accept and want to connect, new features will open up. It is very similar to how friend requests work at Facebook or LinkedIn, opening up and showing more content. Let's call them role1 and role2.
All users are stored within a "users" collection with an id. Depending on their provided role within the document attached to the "users" collection, they can store additional data in their respective role-collection, i.e., role1 collection or role2 collection.
What is the best approach and structure to connect the two users, i.e., become "friends"? Should I have the connection stored in a new collection, named perhaps connections-collection, or multiple collections?
I'm using Next.js, NextAuth for user authentication, and FaunaDB as a database. I'm using Fauna's query language, FQL.
Have you perhaps seen fireship's video RE: fauna db? I think it covers what you want to do and how you can proceed.
Edit: There are many ways to implement this. Based on my understanding, perhaps you can have "Friends" and "Requests" arrays stored under a user document. That way you can differentiate between confirmed friends or a just request.
Example: When user1 initiates a friend request with user2, you store user1's ref under "Requests" of user2's document. When user2 confirms, you move user1's ref to the "Friends" array.
This is just a overly simplified idea and you may need to consider your options and the implications. You would need to plan and define the predicate in both roles so you would only see what is necessary.
Related
I'm currently working on a project where a user can have many roles, and each role has assigned one or many permissions. Permissions describe the actions that a user can apply to ressources. For example let's consider that I have three ressources that I can interact with using my API : users, books, payments.
I'd like to have all users able to update their personal informations like phone number... etc. This led me to give update permission on user's ressource for all users. But the problem is that I want them to be able to updates their own profiles only. Furthermore, some users have admin permissions and can change other users permissions, therefor they have another kind of update permission on user's resource.
So my question is : what's the best way to design the permission table. Below you can find my schema design. Thank you for your answers in advance.
User(firstName string, lastName string, roles Role[])
Role(name string, description string, permissions Permission[])
Permission(name string, effect 'Allow' | 'Deny', resource string, action string)
Well I am not entirely sure what you meant by resource and action. If you meant URI template and HTTP method, then ok. Otherwise you might need a different solution or somehow add parameters to your design if you want to allow or deny individual resources per id.
If we are talking about a REST API, which I assume, then you can do something like PATCH /api/v1/current-user/profile {...} for updating your profile and PATCH /api/v1/users/{user-id}/profile {...} to update somebody else's profile. If you meant controller classes and their methods, then you can do the same with two different controllers, something like CurrentUser.partialUpdate(params) and User.partialUpdate(params).
As of updating user permissions, I wonder how to do it, because you can update only role permissions and give or take away roles for the users in your model.
Another thing I don't understand that why do you need the allow|deny flags. If roles collide because users can have multiple roles or permissions collide, because you can both allow and deny the same thing, then how do you resolve it without a hierarchy? And if you don't have a hierarchy, then this flag is completely useless and just deny all and allow what is added to the role.
As of the one user multiple roles approach it is not a great idea, at least in places where people take security seriously a single account or at least a single session can have only a single role. Since this would make a lot of repetition I would solve this on a role level and make composite roles or support role inheritance. So for example the Administrator role would be the composite of the OwnProfileEditor and ProfileEditor sub-roles, which I would rather call Features or Capabilities or PermissionGroups rather than Roles.
Usually RBAC is not that flexible, so people tend to add per User Permissions to override Role Permissions. I would not do it, because you will end up with a mess if you follow that approach.
I'm building an application with AWS Amplify, where I have three DynamoDB tables: Users, Posts and Subscriptions.
users can make posts
users subscribe to other users
user A can only see posts by user B if user A is subscribed to user B
Points 1. and 2. are easy to implement with standard graphQL mutations. But I'm stuck at how to implement 3. in an elegant way. Currently what I do is to use a lambda resolver.
Given inputs "user A wants to see user B", the lambda resolver does the following:
Query Subscriptions table to see if there's a document for "user A subscribed to user B"
if such a row exists, query Posts table and return documents. If not, return nothing.
This logic required two round trips, but since dynamo is fast I'm OK with this trade-off. There are other downsides though, so I'm wondering if there's a more Amplify-native way to do this? Some magic DynamoDB and #auth trickery perhaps?
Thank you!
If you are using multiple tables to store the data, the multiple query approach is your only option.
You can use transactions when mutating items across multiple tables, which is useful when you want to perform an operation based on a condition on an item in another table(s). But when it comes to a read operation, you have no such option.
Aside from re-designing your tables to support this access pattern, I don't think two reads is particularly bad.
If you wanted to handle authorization logic outside of DDB, you may want to look into AWS IAM and it's documentation on Fine-Grained Access Control. Among other features, IAM can restrict access to specific items in a table based on certain primary key values.
This questions is more of a higher level question about MongoDB app structure.
I am currently building an App that can do User to User messaging using a MongoDB. Everything works great so far, but I am wondering if my design would lead to security issues.
I have a "UserDB" with a Collection "Users". In the collection, "Users" it stores documents of each Users data (Username, Password, ListOfMessages).
When one user sends a message to another user the structure is like this:
User1 wants to send a message to User2
User1 checks if User2 exists in the Collection
if User2 exists, then add new Message to User2's list of Messages from User1
Add the same message to User1 and mark as sent.
What I am concerned about is, should one user be able to access and modify another users data that way? I am concerned about potential hackers.
Any advice or resources would be appreciated.
Thanks!
It's not security issues that you'll run into, but rather scalability issues. For security, however, you should be encrypting your passwords and looking into security for password management.
But with this implementation you'll run into scalability issues. You don't want documents in your collections (your Users in this case) to be growing arbitrarily large (source: https://www.reddit.com/r/mongodb/comments/573fqr/question_mongodb_terrible_performance_for_a/).
Instead, you should create a new collection: Messages.
Each message will have documents like: {fromUser, toUser, message, date, ...}.
Im using Parse to save data from my social network. So far I have three class: Users, Posts, and Relationships. I want the user to be able to like a post.
Should I create a new table for Likes. If so, then on my storyboard page I would have to query through Relationships to get the user followers, then Posts to get the posts from the followers, and then Likes to get the likes from those posts?
Is it efficient to have three API requests to parse on one page. I feel like this will slow down performance but I'm not sure how else to save likes.
Another thing is, I would like to display a notifications tableView. So all likes and requested follows. So Im guessing I would save likes in Relationships and just query through it twice on the storyboard to first get followers, then likes. And on the notification page, have one class to query though once to get all recent notifications.
What are your suggestions?
Thanks.
This is sort of a broad question so there is no way that I could say for sure, but I do have a couple suggestion that you can do with parse.com.
Use the local datastore: You can save all of the likes that the user has in the local datastore as well as in the cloud of your application. So, for instance, you create the like when the user likes something, save it to the cloud, and then pin it to the local datastore. That way, you can efficiently query all of the likes that your user has created without using an API request. But in the event the user logs into the app somewhere else, you also have the likes in the cloud to retrieve. So, I would create a new table for likes.
You could use a join table to implement the followers, so, you could also pin the followers of the user to the local datastore like you would for a like. This is like is done in the Parse.com anypic tutorial.
I would also have another table for notifications. In cloud code, you could even update how many notifications the user has with an afterSave method, and then get all the notifications through a query when requested by the user.
I have a music based app I'm building using Parse for the back end. I'm wondering how I should structure my data when it comes to user identities:
A user can be a regular user, and also a musician, and also a venue owner, etc.
So the idea is that a user can have different identities.
I would love your help on how to best structure this data.
You can have a role column in your user table, assign the role based on the user. When the user logs in to the app, you will read his role and based on the role, the ui will be populated. Is this what you are looking for?