How do I password protect an entire page?

Hey @luke2, you’re not missing anything. Privacy roles have their own rules in terms of what expression you can build for them. (I’m not sure if those rules are entirely documented, but they may be.)

In another thread I had mused about Privacy Roles as a way of potentially limiting which objects might be downloaded to the page, based on more temporary comparisons. And I noted that there are expressions that cannot be built directly there, but that one can build elsewhere and paste in.

It was explained by the Bubble team that this is a bad idea and prone to breakage. (So, “don’t do that.”)

It’s true that it seems you cannot do comparisons here to the unique identification fields of the User type (User’s email, User’s unique ID). I suspect this is because those may be subject to change and hard coding them is a bad idea.

There is another reason that this is a bad idea: It holds the potential to be VERY confusing to you as you build your app further. Having a superuser role like this will break all sorts of business logic when you are using the app as that user.

You can achieve what you want though if you create that Administrator type exactly as I describe above (do it first) and take one extra step: put the Administrator object on the User. (User must have a field “Administrator” of type Administrator. Set that field to be the Administrator created by clicking the magic button. That is, create the new Administrator and immediately attach that administrator to User.)

Set up the privacy rule for Administrator as I describe.

Now on some other data type, you can evaluate:

This may seem like a strange and insecure thing (but I’ll explain why this works below). Now YOU can view any Task, even if you would normally have no right that Task. (Imagine that Tasks have a privacy rule such that they are only visible to the Task’s Creator. You will not pass that condition, but you will pass this one.)

To understand why this works (and why this might be a bad idea), imagine what happens when you are logged into your app as this superuser/Administrator:

Let’s say you now go and visit some page that shows us the detail of some Task. Let’s say it is Task 123x456 (I’m abbreviating the unique ID here obviously for sake of argument). This task was created by User “jenny” and should only be visible to her as Tasks are only visible to their Creator (and the superuser):

https://myappexample.com/view_task/123x456

You will not pass the test Current User is this Task’s Creator. But what happens when the Administrator test is applied:

Bubble goes to evaluate Current User’s Administrator. You do have a value there. It is that Administrator object created by the magic button. Can you retrieve that value? Yes you can as you are that Administrator’s Creator (remember that that’s the only rule on the Administrator object). So, Current User’s Administrator is not empty and you pass the test.

The page renders for you with all of the detail of the Task.

Let us now imagine that User “bob” comes along and tries to view this page. Bob has never been given the ability to create an Administrator and so the Administrator field on his User object will be empty. He will not pass the Administrator test. He will also not pass the Task Creator test.

The detail of this page’s task will not render for Bob.

Let us now imagine that you made a screw up somewhere. That you accidentally in some workflow DID populate Bob’s Administrator field. You accidentally attached YOUR Administrator object to Bob’s Administrator field. Can Bob now see this task?

Here’s what will happen:

Bob will not pass the test Current User is this Task’s Creator (only Jenny can pass that test). Will he pass the Administrator test?

Bubble goes to evaluate Current User’s Administrator. Bob does have a value there. It is that Administrator object created by you. Can Bob retrieve that value? NO, he cannot, as he is NOT that Administrator’s Creator. So, Current User’s Administrator WILL COME UP EMPTY and Bob does not pass the test.

So again we see how the Administrator approach I describe previously is somewhat doofus-proof.

However, can you see why this might be a bad idea now? Let’s say you are visiting this page because Jenny has reported a problem. It just doesn’t work right for her and it’s not due to the Task Creator test, but something else down the line that does relate to some privacy rule being configured incorrectly. If YOUR User object has this magic Administrator property and all of your data objects allow you this magic permission, you’ll have a devil of a time debugging Jenny’s problem – when logged in as YOU. Things behave very differently for you.

So you really, really, really have to be cognizant of that.

In the scenario that a user reports something is not working for them, you really have to test your app logged in as them (use “run as…” from the data tab). Which is what you should do anyway, regardless of whether you have a superuser mode or not.

So, I’d advise being judicious with this sort of privacy rule. It’s very useful of course for the User data type.

(You want an admin page where you can view all users of course and you might also want to view everything about them without having to visit the Data tab. But you still have to be mindful of how this might affect core business logic as you are testing your app in your own user context. It’s easy to build stuff that works just fine for you and forget to test it as a not-logged-in user and also for a non-superuser and just deploy away and “whoops, none of that shit works right for anybody else.”)

2 Likes