Exemple #1
0
def sign_collection_data(event, resources):
    """
    Listen to resource change events, to check if a new signature is
    requested.

    When a source collection specified in settings is modified, and its
    new metadata ``status`` is set to ``"to-sign"``, then sign the data
    and update the destination.
    """
    payload = event.payload

    current_user_id = event.request.prefixed_userid
    if current_user_id == _PLUGIN_USERID:
        # Ignore changes made by plugin.
        return

    for impacted in event.impacted_records:
        new_collection = impacted['new']

        key = instance_uri(event.request, "collection",
                           bucket_id=payload['bucket_id'],
                           id=new_collection['id'])
        resource = resources.get(key)

        # Only sign the configured resources.
        if resource is None:
            continue

        registry = event.request.registry
        updater = LocalUpdater(signer=registry.signers[key],
                               storage=registry.storage,
                               permission=registry.permission,
                               source=resource['source'],
                               destination=resource['destination'])

        try:
            new_status = new_collection.get("status")
            if new_status == STATUS.TO_SIGN:
                # Run signature process (will set `last_reviewer` field).
                updater.sign_and_update_destination(event.request)

            elif new_status == STATUS.TO_REVIEW:
                if 'preview' in resource:
                    # If preview collection: update and sign preview collection
                    updater.destination = resource['preview']
                    updater.sign_and_update_destination(event.request,
                                                        next_source_status=STATUS.TO_REVIEW)
                else:
                    # If no preview collection: just track `last_editor`
                    updater.update_source_editor(event.request)

        except Exception:
            logger.exception("Could not sign '{0}'".format(key))
            event.request.response.status = 503
def sign_collection_data(event, resources):
    """
    Listen to resource change events, to check if a new signature is
    requested.

    When a source collection specified in settings is modified, and its
    new metadata ``status`` is set to ``"to-sign"``, then sign the data
    and update the destination.
    """
    payload = event.payload

    current_user_id = event.request.prefixed_userid
    if current_user_id == _PLUGIN_USERID:
        # Ignore changes made by plugin.
        return

    # Prevent recursivity, since the following operations will alter the current collection.
    impacted_records = list(event.impacted_records)

    for impacted in impacted_records:
        new_collection = impacted['new']
        old_collection = impacted.get('old', {})

        uri = instance_uri(event.request,
                           "collection",
                           bucket_id=payload['bucket_id'],
                           id=new_collection['id'])
        resource = resources.get(uri)

        # Only sign the configured resources.
        if resource is None:
            continue

        registry = event.request.registry
        updater = LocalUpdater(signer=registry.signers[uri],
                               storage=registry.storage,
                               permission=registry.permission,
                               source=resource['source'],
                               destination=resource['destination'])

        review_event_cls = None
        try:
            new_status = new_collection.get("status")
            old_status = old_collection.get("status")

            # Autorize kinto-attachment metadata write access. #190
            event.request._attachment_auto_save = True

            if new_status == STATUS.TO_SIGN:
                # Run signature process (will set `last_reviewer` field).
                updater.sign_and_update_destination(event.request,
                                                    source=new_collection)
                if old_status != STATUS.SIGNED:
                    review_event_cls = signer_events.ReviewApproved

            elif new_status == STATUS.TO_REVIEW:
                if 'preview' in resource:
                    # If preview collection: update and sign preview collection
                    updater.destination = resource['preview']
                    updater.sign_and_update_destination(
                        event.request,
                        source=new_collection,
                        next_source_status=STATUS.TO_REVIEW)
                else:
                    # If no preview collection: just track `last_editor`
                    with updater.send_events(event.request):
                        updater.update_source_editor(event.request)
                review_event_cls = signer_events.ReviewRequested

            elif old_status == STATUS.TO_REVIEW and new_status == STATUS.WORK_IN_PROGRESS:
                review_event_cls = signer_events.ReviewRejected

        except Exception:
            logger.exception("Could not sign '{0}'".format(uri))
            event.request.response.status = 503

        # Notify request of review.
        if review_event_cls:
            payload = payload.copy()
            payload["uri"] = uri
            payload["collection_id"] = new_collection['id']
            review_event = review_event_cls(request=event.request,
                                            payload=payload,
                                            impacted_records=[impacted],
                                            resource=resource,
                                            original_event=event)
            event.request.bound_data.setdefault('kinto_signer.events',
                                                []).append(review_event)