Reputation: 371
I'm trying to figure out if this is possible with baqend, or even the correct approach to begin with.
I have a bunch of users, using the default user account system that comes with Baqend.
Some of these users will be administrators of a company. A company will have somewhere between 1 and 5 users who are administrators.
There is a separate data class that contains a record for the company and an array of users who are the administrators.
Like this:
{
id: "/db/Companies/123-456-789",
name: "Test Co",
admins: [
{ id: "/db/Users/10", name: "Joe Schmo" },
{ id: "/db/Users/11", name: "Kate Skate" },
{ id: "/db/Users/12", name: "Johny Begood" }
]
}
What is the approach to ensure that only users 10, 11, and 12 can modify the contents of the admins array and whatever else is contained in /db/Companies/123-456-789 ?
Is it as simple as inserting the additional admin's info into the array and also adding that person to the ACL of /db/Companies/123-456-789 at the same time or right after?
Also what is the way to remove a persons ACL? I see how to set it here: https://www.baqend.com/guide/topics/user-management/#permissions but how do we do remove or delete? And what is the difference between explicitly denying that user in the ACL vs that user simply not existing (and I guess by default being denied? Assuming the entire collection is set to NOT be public in the first place).
For our use, just because an administrator leaves does not mean he leaves OUR APP, he might go work for another customer who uses our app and his user account should remain valid, but with no more access to the company record.
Upvotes: 2
Views: 178
Reputation: 19
I think you already have it quite right: you can add administrators to a company by adding them to the admins
array and by explicitly allowing them read and write access in the ACLs. To remove admin rights, you can simply remove the explicit allow
rules for the soon-to-be-ex admin.
In Baqend, permissions are enforced like this:
Since every record is public unless there is at least one allow
rule, your record will be protected when you allow access to the administrators. However, it will be public again as soon as you remove the last administrator from the access ruleset. Therefore, it's probably a good idea to always explicitly allow write access to your Baqend app admin, so that there is always at least one allow
rule.
Upvotes: 2
Reputation: 3048
let me try to explain how exactly ACLs in Baqend work.
To secure your object /db/Companies/123-456-789
you can simply add an allow rule for each of your three user ids (/db/Users/10
. /db/Users/11
, /db/Users/12
) to the object acls of your company object like this:
db.Companies.load("/db/Companies/123-456-789").then(function(company) {
company.allowWriteAccess("/db/Users/10");
company.allowWriteAccess("/db/Users/11");
company.allowWriteAccess("/db/Users/12");
return company.save();
})
This ensures that only these users can edit the company object. Notably, this list of rules is independent of the list of admins contained in your company object. To revoke the write access of a user, you can use deleteWriteAccess
in the same way we used allowWriteAccess
before.
This means your users can leave a Company easily without leaving your app.
I hope this answers your question. Because ACLs are complex I will try to explain the general approach in more detail now.
There are two levels to control access to your data:
Schema ACLs define who is allowed access to the table in general. For example, you could define that the User table is not readable for the public by granting read access only to the admin:
allowReadAccess("/db/Role/admin") // Schema ACLs can only be set by the admin
You can define rules for reading, updating, inserting and querying on the table separately.
Object ACLs defines access on the lower level. You can use it to deny access to a specific object. For example, you could define that only the user itself can update its own User object, like this:
allowWriteAccess("<userId>")
For objects, you can define rules for reading and writing separately.
In order to access an object, a user needs to have general permission to access the table (Schema ACLs) and also permission to access the object itself (Object ACLs). This means the Schema ACLs are evaluated first if they grant you access, the Object ACLs are evaluated as well.
There are two types of rules that can be defined to allow or deny access:
Take a look at the JS API for ACLs for the actual method documentation.
These separate rules can be tricky at the start but they are really powerful. Let's do some examples. How can I use these rules to ...
loggedin
role and a deny rule for Peter.node
role (see below for the explanation of Roles).There are two entities you can use in your allow and deny rules:
admin
, loggedin
(represents all logged-in users) and node
(represents backend code modules that access the database)Tables and objects are publically accessible by default if not configured otherwise.
There are no attribute level ACLs in Baqend. This means when you have a User object with a private email address and a public name you can only make the object private or public.
The solution for this is to use two objects, one for the private information and one for the public information and then link the two. For the User, this would mean you make the actual User object private and define a new Profile table where you keep the public user information.
While this solution is more work when defining your schema, there are good reasons why Baqend does not support attribute-level ACLs. Without going into too much detail:
I hope these explanations help to understand the ACL system better. If there is something missing here, just comment and I will add it.
Upvotes: 1