Closed xavier268 closed 7 years ago
Solved. See EDIT in the initial question.
Hi glad you managed to find a solution.
There is a trick that could simplify it:
In RESTHeart both PUT and POST have upsert semantic. However there is a way to have them not creating a document if already existing using the checkEtag query parameter.
You can find in the ETag documentation section the following:
An interesting usage of the checkETag query parameter is avoiding the upsert semantic of RESTHeart. If the client wants to make sure that a write request only creates documents without updating them, it can send a random ETag; in case the resource does not exist, the ETag is not checked anyway.
PUT /db/coll/doc?checkEtag (passing the request header If-Match:x)
This request leads either to CREATED if the document with id doc was not existing or to PRECONDITION FAILED if it already exists.
Of course you need to define a security predicate that enforce the presence of the checkETag query parameter and the "wrong" If-Match header
Hi Andrea,
Thanks for taking the time for answering, and so fast.
I suspected you had a trick of that sort in you magic toolbox ... and your suggestion is spot on, and indeed solves exactly my point without a dedicated applicationhandler.
You are bringing a tremendous value to the community with the Restheart ! A big thank you for your efforts and your commitments !
Xavier
I want to allow unauthenticated users to register for authentication, so I let them POST to /db/coll/ Since I use the provided DB Identity Manager, the username they select ends up in the _id field.
When POSTing a new account to /db/col, I provide the _id in the json body. I am using security predicates to only open unautheticated access to POST and no other verbs, and I was planning on filtering away the password field in the returned data. That would have given me a both secure and simple architecture, where, anyone could POST to register a new account, but only the owner could change an existing account, using PUT, protected accordingly with a predicate.
But unfortunately, that does not work, since I realized that POSTing on the collection behaves exactly as PUTing on the document, and just overwrites the document if it exists ! Anyone can recreate an account with a different password, and hijack the previous account !
Is there a way to disable "updates" on POST, both allowing $unauthenticated users to create new accounts, but only authenticated users to modify existing ones ? I have been trying various combinations of PUT and PATCH but without any success. I am currently considering :
Am I missing a simpler way to achieve this use case in a secured way with Restheart out of the box ? Like a &update=false flag somewhere in the query string ?
Thanks for any hints or directions, and many thanks for the great product you've built !
Xavier
EDIT
Actually, I implemented a logic handler. I turned out to be much simpler that what I feared. Pasting the code below in case it can help someone else. (using Restheart 3.x snapshot)