Exemplo n.º 1
0
def handle_filter_message(message, session=None):
    """A client updating its streamer filter."""
    if "filter" not in message.payload:
        message.reply(
            {
                "type": "error",
                "error": {
                    "type": "invalid_data",
                    "description": '"filter" is missing'
                },
            },
            ok=False,
        )
        return

    filter_ = message.payload["filter"]
    try:
        jsonschema.validate(filter_, FILTER_SCHEMA)
    except jsonschema.ValidationError:
        message.reply(
            {
                "type": "error",
                "error": {
                    "type": "invalid_data",
                    "description": "failed to parse filter",
                },
            },
            ok=False,
        )
        return

    SocketFilter.set_filter(message.socket, filter_)
Exemplo n.º 2
0
    def test_speed(self, factories, db_session):  # pragma: no cover
        # I think the max number connected at once is 4096
        sockets = [FakeSocket() for _ in range(4096)]

        for socket in sockets:
            SocketFilter.set_filter(socket, self.get_randomized_filter())

        ann = factories.Annotation(target_uri="https://example.org")

        start = datetime.utcnow()
        # This returns a generator, we need to force it to produce answers
        tuple(SocketFilter.matching(sockets, ann, db_session))

        diff = datetime.utcnow() - start
        ms = diff.seconds * 1000 + diff.microseconds / 1000
        print(ms, "ms")
Exemplo n.º 3
0
    def test_set_filter(self, field, value, expected):
        socket = FakeSocket()

        filter_ = {
            "match_policy": "include_any",
            "actions": {},
            "clauses": [{
                "field": field,
                "operator": "one_of",
                "value": value
            }],
        }

        SocketFilter.set_filter(socket, filter_)

        assert socket.filter_rows == Any.iterable.containing(expected).only()
Exemplo n.º 4
0
    def test_it_does_not_crash_with_unexpected_fields(self, annotation,
                                                      db_session):
        socket = FakeSocket()
        socket.filter_rows = (("/not_a_thing", "value"), )

        result = tuple(SocketFilter.matching([socket], annotation, db_session))
        assert not result
Exemplo n.º 5
0
    def test_it_does_not_crash_without_filter_rows(self, annotation,
                                                   db_session):
        socket_no_rows = FakeSocket()

        result = tuple(
            SocketFilter.matching([socket_no_rows], annotation, db_session))
        assert not result
Exemplo n.º 6
0
    def test_it_does_not_crash_with_unexpected_fields(self, annotation,
                                                      db_session):
        socket = FakeSocket()
        socket.filter_rows = (  # pylint:disable=attribute-defined-outside-init
            ("/not_a_thing", "value"), )

        result = tuple(SocketFilter.matching([socket], annotation, db_session))
        assert not result
Exemplo n.º 7
0
def handle_annotation_event(message, sockets, request, session):
    id_ = message["annotation_id"]
    annotation = storage.fetch_annotation(session, id_)

    if annotation is None:
        log.warning("received annotation event for missing annotation: %s",
                    id_)
        return

    # Find connected clients which are interested in this annotation.
    matching_sockets = SocketFilter.matching(sockets, annotation, session)

    try:
        # Check to see if the generator has any items
        first_socket = next(matching_sockets)
    except StopIteration:
        # Nothing matched
        return

    # Create a generator which has the first socket back again
    matching_sockets = chain(  # pylint: disable=redefined-variable-type
        (first_socket, ), matching_sockets)

    resource = AnnotationNotificationContext(
        annotation,
        group_service=request.find_service(IGroupService),
        links_service=request.find_service(name="links"),
    )
    read_principals = principals_allowed_by_permission(resource, "read")
    reply = _generate_annotation_event(session, request, message, resource)

    annotator_nipsad = request.find_service(name="nipsa").is_flagged(
        annotation.userid)

    for socket in matching_sockets:
        # Don't send notifications back to the person who sent them
        if message["src_client_id"] == socket.client_id:
            continue

        # Only send NIPSA'd annotations to the author
        if annotator_nipsad and socket.authenticated_userid != annotation.userid:
            continue

        # Check whether client is authorized to read this annotation.
        if not set(read_principals).intersection(socket.effective_principals):
            continue

        socket.send_json(reply)
Exemplo n.º 8
0
Arquivo: messages.py Projeto: kaydoh/h
def handle_annotation_event(message, sockets, request, session):
    id_ = message["annotation_id"]
    annotation = storage.fetch_annotation(session, id_)

    if annotation is None:
        log.warning("received annotation event for missing annotation: %s",
                    id_)
        return

    # Find connected clients which are interested in this annotation.
    matching_sockets = SocketFilter.matching(sockets, annotation, session)

    try:
        # Check to see if the generator has any items
        first_socket = next(matching_sockets)
    except StopIteration:
        # Nothing matched
        return

    # Create a generator which has the first socket back again
    matching_sockets = chain(  # pylint: disable=redefined-variable-type
        (first_socket, ), matching_sockets)

    reply = _generate_annotation_event(request, message, annotation)

    annotator_nipsad = request.find_service(name="nipsa").is_flagged(
        annotation.userid)
    annotation_context = AnnotationContext(annotation)

    for socket in matching_sockets:
        # Don't send notifications back to the person who sent them
        if message["src_client_id"] == socket.client_id:
            continue

        # Only send NIPSA'd annotations to the author
        if (annotator_nipsad and socket.identity
                and socket.identity.user.userid != annotation.userid):
            continue

        # Check whether client is authorized to read this annotation.
        if not identity_permits(
                socket.identity,
                annotation_context,
                Permission.Annotation.READ_REALTIME_UPDATES,
        ):
            continue

        socket.send_json(reply)
Exemplo n.º 9
0
def handle_annotation_event(message, sockets, settings, session):
    id_ = message["annotation_id"]
    annotation = storage.fetch_annotation(session, id_)

    if annotation is None:
        log.warning("received annotation event for missing annotation: %s",
                    id_)
        return

    # Find connected clients which are interested in this annotation.
    matching_sockets = SocketFilter.matching(sockets, annotation)

    try:
        # Check to see if the generator has any items
        first_socket = next(matching_sockets)
    except StopIteration:
        # Nothing matched
        return

    # Create a generator which has the first socket back again
    matching_sockets = chain((first_socket, ), matching_sockets)

    nipsa_service = NipsaService(session)
    user_nipsad = nipsa_service.is_flagged(annotation.userid)

    authority = settings.get("h.authority", "localhost")
    group_service = GroupfinderService(session, authority)
    user_service = UserService(authority, session)
    formatters = [AnnotationUserInfoFormatter(session, user_service)]

    for socket in matching_sockets:
        reply = _generate_annotation_event(message, socket, annotation,
                                           user_nipsad, group_service,
                                           formatters)
        if reply is None:
            continue
        socket.send_json(reply)
Exemplo n.º 10
0
        def filter_matches(filter, annotation):
            socket = FakeSocket()
            SocketFilter.set_filter(socket, filter)

            return bool(
                tuple(SocketFilter.matching([socket], annotation, db_session)))