Ejemplo n.º 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
Ejemplo n.º 2
0
def heartbeat(request):
    """Test that signer is operationnal.

    :param request: current request object
    :type request: :class:`~pyramid:pyramid.request.Request`
    :returns: ``True`` is everything is ok, ``False`` otherwise.
    :rtype: bool
    """
    for signer in request.registry.signers.values():
        try:
            signer.sign("This is a heartbeat test.")
        except Exception as e:
            logger.exception(e)
            return False
    return True
Ejemplo n.º 3
0
def heartbeat(request):
    """Test that signer is operationnal.

    :param request: current request object
    :type request: :class:`~pyramid:pyramid.request.Request`
    :returns: ``True`` is everything is ok, ``False`` otherwise.
    :rtype: bool
    """
    for signer in request.registry.signers.values():
        try:
            result = signer.sign("This is an heartbeat tests.")
            expected = set(EXPECTED_FIELDS)
            obtained = result.keys()
            if len(expected.intersection(obtained)) != len(EXPECTED_FIELDS):
                raise ValueError("Invalid response content: %s" % result)
        except Exception as e:
            logger.exception(e)
            return False
    return True
Ejemplo n.º 4
0
def heartbeat(request):
    """Test that signer is operationnal.

    :param request: current request object
    :type request: :class:`~pyramid:pyramid.request.Request`
    :returns: ``True`` is everything is ok, ``False`` otherwise.
    :rtype: bool
    """
    for signer in request.registry.signers.values():
        try:
            result = signer.sign("This is an heartbeat tests.")
            expected = set(EXPECTED_FIELDS)
            obtained = result.keys()
            if len(expected.intersection(obtained)) != len(EXPECTED_FIELDS):
                raise ValueError("Invalid response content: %s" % result)
        except Exception as e:
            logger.exception(e)
            return False
    return True
Ejemplo n.º 5
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

    # 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)
Ejemplo n.º 6
0
def sign_collection_data(event, resources, to_review_enabled, **kwargs):
    """
    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

    is_new_collection = payload['action'] == ACTIONS.CREATE.value

    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', {})

        # Only sign the configured resources.
        resource, signer = pick_resource_and_signer(event.request, resources,
                                                    bucket_id=payload['bucket_id'],
                                                    collection_id=new_collection['id'])
        if resource is None:
            continue

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

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

        has_review_enabled = ('preview' in resource and
                              resource.get('to_review_enabled', to_review_enabled))

        review_event_cls = None

        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

        try:
            if is_new_collection:
                if has_review_enabled:
                    updater.destination = resource['preview']
                    updater.sign_and_update_destination(event.request,
                                                        source_attributes=new_collection,
                                                        next_source_status=None)
                updater.destination = resource['destination']
                updater.sign_and_update_destination(event.request,
                                                    source_attributes=new_collection,
                                                    next_source_status=None)

            if old_status == new_status:
                continue

            if new_status == STATUS.TO_SIGN:
                # Run signature process (will set `last_reviewer` field).
                updater.destination = resource['destination']
                updater.sign_and_update_destination(event.request,
                                                    source_attributes=new_collection,
                                                    previous_source_status=old_status)

                if old_status == STATUS.SIGNED:
                    # When we refresh the signature, it is mainly in order to make sure that
                    # the latest signer certificate was used. When a preview collection
                    # is configured, we also want to refresh its signature.
                    if has_review_enabled:
                        updater.destination = resource['preview']
                        updater.sign_and_update_destination(event.request,
                                                            source_attributes=new_collection,
                                                            previous_source_status=old_status)
                else:
                    review_event_cls = signer_events.ReviewApproved

            elif new_status == STATUS.TO_REVIEW:
                if has_review_enabled:
                    # If preview collection: update and sign preview collection
                    updater.destination = resource['preview']
                    updater.sign_and_update_destination(event.request,
                                                        source_attributes=new_collection,
                                                        next_source_status=STATUS.TO_REVIEW)
                else:
                    # If no preview collection: just track `last_editor`
                    updater.update_source_review_request_by(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

            elif new_status == STATUS.TO_REFRESH:
                updater.refresh_signature(event.request, next_source_status=old_status)
                if has_review_enabled:
                    updater.destination = resource['preview']
                    updater.refresh_signature(event.request, next_source_status=old_status)

        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)