Skip to content

More robust Singleton form constraint checking #6902

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
ebruchez opened this issue Mar 26, 2025 · 3 comments
Open

More robust Singleton form constraint checking #6902

ebruchez opened this issue Mar 26, 2025 · 3 comments

Comments

@ebruchez
Copy link
Collaborator

ebruchez commented Mar 26, 2025

We'd like more robust singleton checking at the database label in order to ensure atomicity. The function would be:

Create new form data with this document id if there is no existing form data yet for this app/form/version, given optional username/group permissions.

Checking this requires:

  • performing operations in a single database transaction
  • searching for existing data, including checking for username/group permissions if needed
  • create new data
  • return whether this succeeded

This would be enabled for a REST PUT by passing a new parameter to the call.

One issue is that the persistence proxy is not transaction-aware (it doesn't have a transaction manager, and doesn't know about persistence providers are relational or not.

The simplest way might be to do this in the provider implementation:

  • support an extra parameter
  • in that case, perform the very limited search
    • it's in the same orbeon_form_data table
    • only extra WHERE would be for username/group permission checking
@ebruchez ebruchez changed the title Improved Singleton form checking More robust Singleton form constraint checking Mar 26, 2025
@avernet
Copy link
Collaborator

avernet commented Mar 26, 2025

We want to prevent a user from creating data if they already have access to data. We need to do this given the constraint the only operations available to us are: search (to find what data the user has access to), create, and delete. Moreover, we can't have a transaction span multiple operations. We've discussed the possibility of always doing the following steps:

  1. search
  2. create
  3. search
  4. delete

The first "search" isn't strictly necessary, but in most cases avoids performing a "delete".
However, we found that this could lead to the problematic scenario described below.
The number of each line is denotes a thread id.

  • 1 search ∅
  • 2 search ∅
  • 3 search ∅
  • 1 create a
  • 2 create b
  • 3 create c
  • 3 search a, b, c
  • 3 delete c

At this point, thread 3 will take the user to the summary page to choose between a and b, not knowing that b will be deleted by 2. The impact is that if the user selects b, they will most likely encounter an error. However, if they are able to open the documents before it is deleted, they might be able to save it and violate the constraints we have set. This seems extremely unlikely and very difficult to exploit, but it is nonetheless a situation we need to consider.

@avernet
Copy link
Collaborator

avernet commented Apr 3, 2025

Extension of the current PUT API to support a search then create of search didn't return anything:

  • Endpoint: /fr/service/crud/$app/$form/data/$document/data.xml
  • Request:
    • Method: PUT
    • Create-If: search-empty
    • Body: form data
  • Response:
    • If created, 201, no body
    • If not created, 200 (TBD), no body

@avernet
Copy link
Collaborator

avernet commented Apr 4, 2025

Possibilities for the response code if not created:

  • 200 OK
  • 204 No Content
  • 409 Conflict

I think I prefer 409 because it indicates that the request document wasn't created (remember, we provided a document id in the path) and gives us a hint as to why it wasn't created.

avernet added a commit that referenced this issue Apr 24, 2025
- Favor objects over traits
- Avoid duplicate names
- Choose more descriptive names
avernet added a commit that referenced this issue Apr 25, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants