demos-europe / edt

Enables your PHP application to expose its entities as REST resources using the feature rich JSON:API specification as API. How and to whom your entities are exposed is highly customizable while minimizing boilerplate code.
MIT License
2 stars 1 forks source link

Handle entity conditions on creation request consistently #145

Open joorei opened 3 months ago

joorei commented 3 months ago

Creating an entity (executing the "creation behaviors") is done in two steps: first the entity instance is created, second the instance is filled according to the creation request body. The second step is basically the same as executing an update on an existing entity and thus re-uses some of the corresponding interfaces and classes.

However, update behaviors allow to set a list of "entity conditions", which the entity must match the entity to be updated (i.e. before the update is done). Those entity conditions exist in the creation behaviors second step as well, but are currently ignored.

This may lead to a situation where creation behavior entity conditions are intentionally configured, but not executed, thus leading to a security hole.

There seem to be two approaches to solve the unused entity conditions in creation behaviors:

  1. Execute them on the entity just created: the usefulness of this is doubtful, as the entity is already present in the application. I.e. there is no performance advantage by not retrieving the entity from the database if it doesn't match the conditions anyway (like it is implemented in update behaviors). For the using developer being able to configure the conditions may be helpful to implement access restrictions (i.e. if a specific user role is allowed to create an entity with a specific state). However, the approach seems quite limited, as it can only check the entity in the middle of creation. Using developers also need to be aware when/if the entity is persisted/flushed into the database. E.g. in the case of Doctrine, the conditions would be executed in the database, but if the newly created entity instance was (understandably) not yet persisted the conditions will always result in no match.
  2. Split the creation behavior implementation away from the update behavior implementation and remove the entity conditions from the creation behaviors. To allow to check for access restrictions (as explained above) a better approach than entity conditions would be validator constraints that are executed at the very end of the entity creation. This may be a worthwhile addition for the update behaviors as well.

Comparing the approaches, 2. is heavily preferred, though more work to implement.