I am attempting to model account access in a graph DB.
The account can have multiple users and multiple features. A user can have access to many accounts. Each account can give access to only part of the features for each user.
One way I see it is to represent access for each user through relationship attributes, this allows having a shared feature node.
user_1 has access to account_1-feature_1 and account_2-feature-2. user_1 does not have access to account_1-feature_2 even though it is enabled for the account.
Another way to model the same access, but without relationship attribute is to create account specific feature nodes.
Question 1: which of these 2 ways is a more 'proper' modeling in the graph DB world?
Now to make things more interesting the account can also have parts which can be accessed by multiple accounts and a certain feature should be able to be scoped down to only be accessible for specific part by user.
In this example user_1 can access account_1 only for part_a feature_1.
To me it seems like defining an attribute on relationship is the way to go for being able to scope down user access by feature & by part of the account. However, reading neo4j powerpoints this would be one of the code smells of relationships having "Lots of attribute-like properties". Is there a better way to approach such problem in a graph?
I could be wrong here, but here are my thoughts. Option 1 definitely sounds the better way from a modeling perspective, however, I don't see how you can keep the data consistent without building heavy machinery to do it. For example, If someone deletes Account1.Feature1, and does not update the edge from User1 -> Account1, then you end up having stale RBAC rules in the system. You think you have access to something, but in reality that "thing" does not exist anymore. Option 2 may not seem very attractive from a data model perspective, but it does keep your data consistent. If you delete Account1.Feature1, the edge is automatically deleted in the same transaction.
The only con is that, you need to incur additional cost at insertion where you need to insert a lot more nodes than Option 1. For an RBAC system, I think its a fair compromise.
The same comment applies to the second half of your question as well.
Related
I am trying to create a basic app for my small educational business.
We supply English teachers to schools and I want a way for parents to access the progress reports and other data about their children.
I'm using Android Studio and Flutter as well as Firebase to store the data. I don't want parents to be able to access the data of every child, obviously, but they may have more than one child at the school.
So I need to limit their read privileges to just the records that relate to their children. I'd like to do that by giving them some sort of registration code that they could use the first time they access the app so that we can ensure that they are only being given access to the correct records. Subsequent logins would then be via email and password.
Is there a way to do this with Firebase?
Your use-case sounds feasible, but it is really broad which makes it impossible to answer it completely-yet-succinctly.
Specific on what to do with the registration code that associates a parent with their children, when you generate the registration code, you write that code and the associated children to a database. Then when the parent registers with that code, you associate their account (UID) with the code. You'll just have to ensure that the code is sufficiently long and random that it can't be reasonably guessed by another user.
I am building a community-type app based on Firestore where users should have granual control over what kind of information they share with whom.
Users can have properties such as name, birthdate, etc. and for each of them they can decide to share it with the one of the following groups/roles:
Private
Contacts
Admin (Admins of organizations that user is a member of)
Organization (Members of organizations that a users is a member of)
Public (All users of the app)
As documents in Firestore will always be retrieved as a whole, I already know that I somehow will have to segregate my user properties by access level.
I've got two approaches so far:
Approach 1
Store each user property in a separate document that contains a field access level
Store some metadata in, for example /user/12345/meta/roles, so that I can point the security rules to those documents to validate access
Benefits:
Easy structure
Flexibly
(Almost) no data duplication
Drawbacks:
Lots of document reads for getting a user's profile
Approach 2
Store user profile in, for example /user/12345/profile/private and duplicate the public information into /user/12345/profile/public, and do the same for each access level
Benefits:
Reduced document reads
Drawbacks:
Complexity
It feels wrong to duplicate that much data
Does anyone have any experience with this and any suggestions or alternative approaches they can share?
Follow-up question:
Let’s say I store the list of members of an organization in a subcollection, that is only accessible for members of the organization (for privacy reasons). Doesn’t that mean that when querying that list of members from client side, I have to do it „blindly“, meaning I can’t know if the user can access that document until I actually try? The fact that the query might fail would tell me that the user is not actually a member of that organization.
Would you consider this kind of query that is set up for failure bad practice? Are there any alternatives that still allow to keep the memberlist private?
I think you are moving from a SQL environment to NoSql now which is why you are finding the Approach 2 as not the right way to proceed.
Actually approach 2 is the right way to proceed there are couple of advantages
1.) Reduced Document Reads - More cost savings. Firestore charges by number of reads and writes if you are reducing no of reads and writes optimally its always the way to go for. Also the cost of storage due is increased reads will always be less than the actual cost of reads if you are scaling up your application.
2.) In NoSql database your are allowed to duplicate data provided it is going to increase the read / search speed from the database.
I am not seeing the second approach as complex because that's the tradeoff you are making when Choosing a NoSql over Sql
This is mobile app which can have different kind of users. I'm using realm only for the offline storage. Say I have two users A and B and a have a List Class. This class wont ever be shared, so different data for each user. How would i go in designing the schema? Considering versioning and migration.
A. Add a primary key for the List and assign it differently to user A and B.
B. Use two different realms
There is no one good way of defining your Realm schema and the solution to choose completely depends on the exact scenario.
If you want your users data to be completely independent of each other and you will never need to use a single query to retrieve both users data or to access some common data, then using separate Realm instances for each use seems like a good approach. It provides complete separation between your users data.
However, if your users might have some shared data or if you might end up making some statistics about all of your users even though their data is independent, using a single Realm instance is the way to go. In this case you should just create a one-to-many relationship between each of your users and whatever objects you want to store in your lists like this:
class User:Object {
let stuff = List<Stuff>()
}
I am making an app that my company is going to use and I want the one account for each department, thus every employee from a certain department can log in and use that joint account. Can I just create an account with Meteor's account system or is it anything else I should think about?
if you mean you are going to have multiple humans share a password for an account, technically, yes that should work. Meteor supports multiple logins for a single account.
where you might run into trouble is multiple writes, e.g. if 2 people both decide to change the password.
however, just because it is technically possible, you might consider finding a way to fulfill your requirements but still allowing each human to have their own account.
for example, you could handle that with groups. each account is assigned to one or more groups, and each group shares data and functionality. if it is at all important to track who made a data change, this is a better approach.
the Meteor roles package (https://github.com/alanning/meteor-roles) could help in this regard.
Is it possible to assign a person or a group of people as reviewers in a certain state of a workflow in Plone?
I have been looking at AutoRole en the IRolesplugin, but do not seem to find what I need?
In our case, users need a multiple review step workflow, yet the first reviewer should have control over which reviewers come afterwards...
Workflows can trigger scripts. Scripts can do things like grant roles to users. You'd have to come up with an approach to letting your first specify additional users. There are probably multiple ways to do it, but I could imagine using archetypes.schemextender or a custom content type to provide a field for choosing additional reviewers, only visible to initial reviewers. Then use those values in the workflow script. http://plone.org/documentation/kb/creating-workflows-in-plone/tutorial-all-pages provides a good overview of how DCWorkflow works.