def test_group(self): annotation = models.Annotation() annotation['permissions'] = { 'read': ['group:lulapalooza'], } actual = annotation.__acl__() expect = [(security.Allow, 'group:lulapalooza', 'read')]
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
def test_deny_system_role(self): annotation = models.Annotation() annotation['permissions'] = { 'read': [security.Everyone], } with raises(ValueError): annotation.__acl__()
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
def test_principal(self): annotation = models.Annotation() annotation['permissions'] = { 'read': ['saoirse'], } actual = annotation.__acl__() expect = [(security.Allow, 'saiorse', 'read')]
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
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
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_
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)
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)
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)
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
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
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)
def annotation(self): return mock.Mock(spec=models.Annotation())
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!"))
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
def test_admin_party(self): annotation = models.Annotation() actual = annotation.__acl__() expect = [(security.Allow, security.Everyone, security.ALL_PERMISSIONS) ] assert actual == expect