예제 #1
0
 def test_group(self):
     annotation = models.Annotation()
     annotation['permissions'] = {
         'read': ['group:lulapalooza'],
     }
     actual = annotation.__acl__()
     expect = [(security.Allow, 'group:lulapalooza', 'read')]
예제 #2
0
def test_uri_mapping():
    permissions = {
        'read': ['group:__world__'],
    }
    a1 = models.Annotation(uri='http://example.com/page#hashtag',
                           permissions=permissions)
    a1.save()
    a2 = models.Annotation(uri='http://example.com/page',
                           permissions=permissions)
    a2.save()
    a3 = models.Annotation(uri='http://totallydifferent.domain.com/',
                           permissions=permissions)
    a3.save()

    res = models.Annotation.search(query={'uri': 'example.com/page'})
    assert len(res) == 2
예제 #3
0
 def test_deny_system_role(self):
     annotation = models.Annotation()
     annotation['permissions'] = {
         'read': [security.Everyone],
     }
     with raises(ValueError):
         annotation.__acl__()
예제 #4
0
파일: storage.py 프로젝트: truthadjustr/h
def create_annotation(request, data, group_service):
    """
    Create an annotation from passed data.

    :param request: the request object
    :type request: pyramid.request.Request

    :param data: a dictionary of annotation properties
    :type data: dict

    :param group_service: a service object that adheres to ``h.interfaces.IGroupService``
    :type group_service: h.interfaces.IGroupService

    :returns: the created and flushed annotation
    :rtype: dict
    """
    created = updated = datetime.utcnow()

    document_uri_dicts = data['document']['document_uri_dicts']
    document_meta_dicts = data['document']['document_meta_dicts']
    del data['document']

    # Replies must have the same group as their parent.
    if data['references']:
        top_level_annotation_id = data['references'][0]
        top_level_annotation = fetch_annotation(request.db,
                                                top_level_annotation_id)
        if top_level_annotation:
            data['groupid'] = top_level_annotation.groupid
        else:
            raise schemas.ValidationError(
                'references.0: ' + _('Annotation {id} does not exist').format(
                    id=top_level_annotation_id))

    # The user must have permission to create an annotation in the group
    # they've asked to create one in. If the application didn't configure
    # a groupfinder we will allow writing this annotation without any
    # further checks.
    group = group_service.find(data['groupid'])
    if group is None or not request.has_permission('write', context=group):
        raise schemas.ValidationError('group: ' +
                                      _('You may not create annotations '
                                        'in the specified group!'))

    annotation = models.Annotation(**data)
    annotation.created = created
    annotation.updated = updated

    document = update_document_metadata(request.db,
                                        annotation.target_uri,
                                        document_meta_dicts,
                                        document_uri_dicts,
                                        created=created,
                                        updated=updated)
    annotation.document = document

    request.db.add(annotation)
    request.db.flush()

    return annotation
예제 #5
0
 def test_principal(self):
     annotation = models.Annotation()
     annotation['permissions'] = {
         'read': ['saoirse'],
     }
     actual = annotation.__acl__()
     expect = [(security.Allow, 'saiorse', 'read')]
예제 #6
0
 def test_group_world(self):
     annotation = models.Annotation()
     annotation['permissions'] = {
         'read': ['group:__world__'],
     }
     actual = annotation.__acl__()
     expect = [(security.Allow, security.Everyone, 'read')]
     assert actual == expect
예제 #7
0
 def test_group_authenticated(self):
     annotation = models.Annotation()
     annotation['permissions'] = {
         'read': ['group:__authenticated__'],
     }
     actual = annotation.__acl__()
     expect = [(security.Allow, security.Authenticated, 'read')]
     assert actual == expect
예제 #8
0
def annotation(session, document_, groupid, shared):
    """Add a new annotation of the given document to the db and return it."""
    annotation_ = models.Annotation(
        userid=u'fred', groupid=groupid, shared=shared,
        target_uri=document_.document_uris[0].uri,
        document_id=document_.id)
    session.add(annotation_)
    return annotation_
예제 #9
0
파일: rss_test.py 프로젝트: zermelozf/h
def _annotation(**kwargs):
    args = {
        'userid': 'acct:[email protected]',
        'target_selectors': [],
        'created': datetime.datetime.utcnow(),
        'updated': datetime.datetime.utcnow(),
        'document': models.Document(),
    }
    args.update(**kwargs)
    return models.Annotation(**args)
예제 #10
0
def _annotation(**kwargs):
    args = {
        "userid": "acct:[email protected]",
        "target_selectors": [],
        "created": datetime.datetime.utcnow(),
        "updated": datetime.datetime.utcnow(),
        "document": models.Document(),
    }
    args.update(**kwargs)
    return models.Annotation(**args)
예제 #11
0
    def merge_data(self, db_session, request):
        master = document.Document(
            document_uris=[
                document.DocumentURI(
                    claimant='https://en.wikipedia.org/wiki/Main_Page',
                    uri='https://en.wikipedia.org/wiki/Main_Page',
                    type='self-claim')
            ],
            meta=[
                document.DocumentMeta(
                    claimant='https://en.wikipedia.org/wiki/Main_Page',
                    type='title',
                    value='Wikipedia, the free encyclopedia')
            ])
        duplicate_1 = document.Document(
            document_uris=[
                document.DocumentURI(
                    claimant='https://m.en.wikipedia.org/wiki/Main_Page',
                    uri='https://en.wikipedia.org/wiki/Main_Page',
                    type='rel-canonical')
            ],
            meta=[
                document.DocumentMeta(
                    claimant='https://m.en.wikipedia.org/wiki/Main_Page',
                    type='title',
                    value='Wikipedia, the free encyclopedia')
            ])
        duplicate_2 = document.Document(
            document_uris=[
                document.DocumentURI(
                    claimant='https://en.wikipedia.org/wiki/Home',
                    uri='https://en.wikipedia.org/wiki/Main_Page',
                    type='rel-canonical')
            ],
            meta=[
                document.DocumentMeta(
                    claimant='https://en.wikipedia.org/wiki/Home',
                    type='title',
                    value='Wikipedia, the free encyclopedia')
            ])

        db_session.add_all([master, duplicate_1, duplicate_2])
        db_session.flush()

        master_ann_1 = models.Annotation(userid='luke', document_id=master.id)
        master_ann_2 = models.Annotation(userid='alice', document_id=master.id)
        duplicate_1_ann_1 = models.Annotation(userid='lucy',
                                              document_id=duplicate_1.id)
        duplicate_1_ann_2 = models.Annotation(userid='bob',
                                              document_id=duplicate_1.id)
        duplicate_2_ann_1 = models.Annotation(userid='amy',
                                              document_id=duplicate_2.id)
        duplicate_2_ann_2 = models.Annotation(userid='dan',
                                              document_id=duplicate_2.id)
        db_session.add_all([
            master_ann_1, master_ann_2, duplicate_1_ann_1, duplicate_1_ann_2,
            duplicate_2_ann_1, duplicate_2_ann_2
        ])
        return (master, duplicate_1, duplicate_2)
예제 #12
0
    def duplicate_docs(self, db_session, factories):
        uri = "http://example.com/master"

        documents = []
        for _ in range(3):
            meta = factories.DocumentMeta()

            documents.append(
                factories.Document(
                    document_uris=[
                        factories.DocumentURI(claimant=meta.claimant, uri=uri)
                    ],
                    meta=[meta],
                ))

        db_session.flush()

        for doc in documents:
            db_session.add(
                models.Annotation(userid="userid", document_id=doc.id))

        return documents
예제 #13
0
def create_annotation(request, data, group_service):
    """
    Create an annotation from already-validated data.

    :param request: the request object
    :type request: pyramid.request.Request

    :param data: an annotation data dict that has already been validated by
        :py:class:`h.schemas.annotation.CreateAnnotationSchema`
    :type data: dict

    :param group_service: a service object that implements
        :py:class:`h.interfaces.IGroupService`
    :type group_service: :py:class:`h.interfaces.IGroupService`

    :returns: the created and flushed annotation
    :rtype: :py:class:`h.models.Annotation`
    """
    created = updated = datetime.utcnow()

    document_uri_dicts = data["document"]["document_uri_dicts"]
    document_meta_dicts = data["document"]["document_meta_dicts"]
    del data["document"]

    # Replies must have the same group as their parent.
    if data["references"]:
        top_level_annotation_id = data["references"][0]
        top_level_annotation = fetch_annotation(request.db,
                                                top_level_annotation_id)
        if top_level_annotation:
            data["groupid"] = top_level_annotation.groupid
        else:
            raise schemas.ValidationError(
                "references.0: " + _("Annotation {id} does not exist").format(
                    id=top_level_annotation_id))

    # The user must have permission to create an annotation in the group
    # they've asked to create one in. If the application didn't configure
    # a groupfinder we will allow writing this annotation without any
    # further checks.
    group = group_service.find(data["groupid"])
    if group is None or not request.has_permission("write", context=group):
        raise schemas.ValidationError("group: " +
                                      _("You may not create annotations "
                                        "in the specified group!"))

    _validate_group_scope(group, data["target_uri"])

    annotation = models.Annotation(**data)
    annotation.created = created
    annotation.updated = updated

    document = update_document_metadata(
        request.db,
        annotation.target_uri,
        document_meta_dicts,
        document_uri_dicts,
        created=created,
        updated=updated,
    )
    annotation.document = document

    request.db.add(annotation)
    request.db.flush()

    request.find_service(name="search_index")._queue.add_by_id(
        annotation.id, tag="storage.create_annotation", schedule_in=60)

    return annotation
예제 #14
0
    def merge_data(self, db_session, request):
        master = document.Document(
            document_uris=[
                document.DocumentURI(
                    claimant="https://en.wikipedia.org/wiki/Main_Page",
                    uri="https://en.wikipedia.org/wiki/Main_Page",
                    type="self-claim",
                )
            ],
            meta=[
                document.DocumentMeta(
                    claimant="https://en.wikipedia.org/wiki/Main_Page",
                    type="title",
                    value="Wikipedia, the free encyclopedia",
                )
            ],
        )
        duplicate_1 = document.Document(
            document_uris=[
                document.DocumentURI(
                    claimant="https://m.en.wikipedia.org/wiki/Main_Page",
                    uri="https://en.wikipedia.org/wiki/Main_Page",
                    type="rel-canonical",
                )
            ],
            meta=[
                document.DocumentMeta(
                    claimant="https://m.en.wikipedia.org/wiki/Main_Page",
                    type="title",
                    value="Wikipedia, the free encyclopedia",
                )
            ],
        )
        duplicate_2 = document.Document(
            document_uris=[
                document.DocumentURI(
                    claimant="https://en.wikipedia.org/wiki/Home",
                    uri="https://en.wikipedia.org/wiki/Main_Page",
                    type="rel-canonical",
                )
            ],
            meta=[
                document.DocumentMeta(
                    claimant="https://en.wikipedia.org/wiki/Home",
                    type="title",
                    value="Wikipedia, the free encyclopedia",
                )
            ],
        )

        db_session.add_all([master, duplicate_1, duplicate_2])
        db_session.flush()

        master_ann_1 = models.Annotation(userid="luke", document_id=master.id)
        master_ann_2 = models.Annotation(userid="alice", document_id=master.id)
        duplicate_1_ann_1 = models.Annotation(userid="lucy",
                                              document_id=duplicate_1.id)
        duplicate_1_ann_2 = models.Annotation(userid="bob",
                                              document_id=duplicate_1.id)
        duplicate_2_ann_1 = models.Annotation(userid="amy",
                                              document_id=duplicate_2.id)
        duplicate_2_ann_2 = models.Annotation(userid="dan",
                                              document_id=duplicate_2.id)
        db_session.add_all([
            master_ann_1,
            master_ann_2,
            duplicate_1_ann_1,
            duplicate_1_ann_2,
            duplicate_2_ann_1,
            duplicate_2_ann_2,
        ])
        return (master, duplicate_1, duplicate_2)
예제 #15
0
 def annotation(self):
     return mock.Mock(spec=models.Annotation())
예제 #16
0
    document_data = data.pop("document", {})

    # Replies must have the same group as their parent.
    if data["references"]:
        root_annotation_id = data["references"][0]

        if root_annotation := fetch_annotation(request.db, root_annotation_id):
            data["groupid"] = root_annotation.groupid
        else:
            raise schemas.ValidationError(
                "references.0: " + _("Annotation {id} does not exist").format(
                    id=root_annotation_id))

    # Create the annotation and enable relationship loading so we can access
    # the group, even though we've not added this to the session yet
    annotation = models.Annotation(**data)
    request.db.enable_relationship_loading(annotation)

    group = annotation.group
    if not group:
        raise schemas.ValidationError(
            "group: " + _(f"Invalid group id {annotation.groupid}"))

    # The user must have permission to create an annotation in the group
    # they've asked to create one in.
    if not request.has_permission(Permission.Group.WRITE,
                                  context=GroupContext(group)):
        raise schemas.ValidationError(
            "group: " +
            _("You may not create annotations in the specified group!"))
예제 #17
0
def create_annotation(request, data, group_service):
    """
    Create an annotation from already-validated data.

    :param request: the request object
    :type request: pyramid.request.Request

    :param data: an annotation data dict that has already been validated by
        :py:class:`h.schemas.annotation.CreateAnnotationSchema`
    :type data: dict

    :param group_service: a service object that implements
        :py:class:`h.interfaces.IGroupService`
    :type group_service: :py:class:`h.interfaces.IGroupService`

    :returns: the created and flushed annotation
    :rtype: :py:class:`h.models.Annotation`
    """
    created = updated = datetime.utcnow()

    document_uri_dicts = data['document']['document_uri_dicts']
    document_meta_dicts = data['document']['document_meta_dicts']
    del data['document']

    # Replies must have the same group as their parent.
    if data['references']:
        top_level_annotation_id = data['references'][0]
        top_level_annotation = fetch_annotation(request.db,
                                                top_level_annotation_id)
        if top_level_annotation:
            data['groupid'] = top_level_annotation.groupid
        else:
            raise schemas.ValidationError(
                'references.0: ' + _('Annotation {id} does not exist').format(
                    id=top_level_annotation_id))

    # The user must have permission to create an annotation in the group
    # they've asked to create one in. If the application didn't configure
    # a groupfinder we will allow writing this annotation without any
    # further checks.
    group = group_service.find(data['groupid'])
    if group is None or not request.has_permission('write', context=group):
        raise schemas.ValidationError('group: ' +
                                      _('You may not create annotations '
                                        'in the specified group!'))

    if request.feature('filter_groups_by_scope') and group.scopes:
        # The scope (origin) of the target URI must match at least one
        # of a group's defined scopes, if the group has any
        group_scopes = [scope.origin for scope in group.scopes]
        if not group_scope_match(data['target_uri'], group_scopes):
            raise schemas.ValidationError('group scope: ' +
                                          _('Annotations for this target URI '
                                            'are not allowed in this group'))

    annotation = models.Annotation(**data)
    annotation.created = created
    annotation.updated = updated

    document = update_document_metadata(request.db,
                                        annotation.target_uri,
                                        document_meta_dicts,
                                        document_uri_dicts,
                                        created=created,
                                        updated=updated)
    annotation.document = document

    request.db.add(annotation)
    request.db.flush()

    return annotation
예제 #18
0
 def test_admin_party(self):
     annotation = models.Annotation()
     actual = annotation.__acl__()
     expect = [(security.Allow, security.Everyone, security.ALL_PERMISSIONS)
               ]
     assert actual == expect