plone / guillotina

Python AsyncIO data API to manage billions of resources
https://guillotina.readthedocs.io/en/latest/
Other
187 stars 51 forks source link

Subscriber to prevent overriding values with outdated content #1110

Open masipcat opened 3 years ago

masipcat commented 3 years ago

The following code is something we use in conjunction with https://github.com/plone/guillotina/issues/1025 to prevent patching an object with outdated info:

from dateutil.parser import isoparse
from guillotina import configure
from guillotina.events import IBeforeObjectModifiedEvent
from guillotina.interfaces import IResource
from guillotina.response import HTTPForbidden
from guillotina.utils import get_current_request

@configure.subscriber(for_=(IResource, IBeforeObjectModifiedEvent), priority=1)
async def check_modifing_latest_version(obj, event):
    request = get_current_request()

    if last_mod_date := request.headers.get("last-mod-date"):
        last_mod_date = isoparse(last_mod_date)
        if last_mod_date != obj.modification_date:
            raise HTTPForbidden(
                content={
                    "error": f"Provided version {last_mod_date} is behind {obj.modification_date}"
                }
            )

@bloodbare @vangheem do we want to add this to guillotina in a contrib like the linked issue https://github.com/plone/guillotina/issues/1025? I'm asking because @aralroca would like to move our implementation to Guillotina React.

runyaga commented 3 years ago

would etag's work?

masipcat commented 3 years ago

Ohh, I didn't know ETag could be used to avoid collisions! We need to add ETag support to Guillotina first but I like the idea of using the ETag header instead of a custom one