def test_dataset_elements_info_by_pages(self): """ Factory can retrieve multiple elements at once by pages. """ editor = TokenDAO("normal user privileged with link", 1, 5, "user1", privileges=Privileges.RO_WATCH_DATASET ) dataset = DatasetDAO("user1/dataset1", "example_dataset", "dataset for testing purposes", "none", tags=["example", "0"]) self.session.flush() editor = editor.link_dataset(dataset) elements = [DatasetElementDAO("example{}".format(x), "none", None, dataset=dataset).title for x in range(5)] self.session.flush() dataset = dataset.update() page_size = global_config.get_page_size() for page in range(len(elements) // page_size + int(len(elements) % page_size > 0)): retrieved_elements = DatasetElementFactory(editor, dataset).get_elements_info(page) for x in retrieved_elements: self.assertIn(x.title, elements)
def test_dataset_elements_creation(self): """ Factory can create multiple dataset's elements at once. """ creator = TokenDAO("normal user privileged with link", 1, 3, "user1", privileges=Privileges.CREATE_DATASET + Privileges.ADD_ELEMENTS ) dataset = DatasetDAO("user1/dataset1", "example_dataset", "dataset for testing purposes", "none", tags=["example", "0"]) self.session.flush() creator = creator.link_dataset(dataset) # Creator can create elements into the dataset elements_kwargs = [ dict(title="New element", description="Description unknown", tags=["example_tag"], content=b"hello"), dict(title="New element2", description="Description unknown2", tags=["example_tag2"], content=b"hello2"), dict(title="New element3", description="Description unknown3", tags=["example_tag3"], content=b"hello3"), ] elements = DatasetElementFactory(creator, dataset).create_elements(elements_kwargs) self.assertEqual(len(elements), 3) content = storage.get_file(elements[0].file_ref_id).content self.assertEqual(content, b"hello") content = storage.get_file(elements[1].file_ref_id).content self.assertEqual(content, b"hello2") content = storage.get_file(elements[2].file_ref_id).content self.assertEqual(content, b"hello3") dataset = dataset.update() self.assertEqual(len(dataset.elements), 3)
def test_dataset_multiple_elements_content_retrieval(self): """ Factory can retrieve content of multiple elements at once. """ editor = TokenDAO("normal user privileged with link", 1, 1, "user1", privileges=Privileges.RO_WATCH_DATASET ) dataset = DatasetDAO("user1/dataset1", "example_dataset", "dataset for testing purposes", "none", tags=["example", "0"]) self.session.flush() editor = editor.link_dataset(dataset) file_id1 = storage.put_file_content(b"content1") file_id2 = storage.put_file_content(b"content2") element = DatasetElementDAO("example1", "none", file_id1, dataset=dataset) element2 = DatasetElementDAO("example2", "none", file_id1, dataset=dataset) element3 = DatasetElementDAO("example3", "none", file_id2, dataset=dataset) self.session.flush() dataset = dataset.update() with self.assertRaises(RequestedRangeNotSatisfiable) as ex: contents = DatasetElementFactory(editor, dataset).get_elements_content([element._id, element2._id, element3._id]) contents = DatasetElementFactory(editor, dataset).get_elements_content([element._id, element3._id]) self.assertEqual(contents[element._id], b"content1") self.assertEqual(contents[element3._id], b"content2")
def test_url_prefix_duplication_error(self): """ Tests that a duplicated url prefix cannot be retrieved. :return: """ dataset = DatasetDAO("ip/asd5", "example5", "desc", "none") self.session.flush() with self.assertRaises(Exception) as ex: dataset2 = DatasetDAO("ip/asd5", "example5", "desc", "none")
def test_dataset_fork(self): """ Factory can fork a dataset :return: """ viewer = TokenDAO("normal user only view dataset", 2, 10, "viewer", privileges=Privileges.RO_WATCH_DATASET) creator = TokenDAO("normal user privileged", 2, 10, "creator", privileges=Privileges.CREATE_DATASET) d = DatasetDAO("viewer/dataset", "dataset", "description for dataset", "none", ["d1", "d2"]) self.session.flush() element1 = DatasetElementDAO("a", "a", None, "noneaa", ["taga"], dataset=d) element2 = DatasetElementDAO("b", "b", None, "nonebb", ["tagb"], dataset=d) self.session.flush() d = d.update() self.assertEqual(len(d.elements), 2) viewer = viewer.link_dataset(d) d.update() # Creator can clone it from viewer. forked_dataset = DatasetFactory(creator).fork_dataset(d.url_prefix, viewer, title="dataset_cloned", url_prefix="dataset", description="desc", reference="none", tags=["d2", "d1"]) self.assertEqual(forked_dataset.url_prefix, "creator/dataset") self.assertEqual(forked_dataset.title, "dataset_cloned") self.assertEqual(forked_dataset.description, "desc") self.assertEqual(forked_dataset.tags, ["d2", "d1"]) self.assertEqual(len(forked_dataset.elements), 2) elements_titles = [element1.title, element2.title] self.assertIn(forked_dataset.elements[0].title, elements_titles) self.assertIn(forked_dataset.elements[1].title, elements_titles) # viewer can NOT clone it from creator. with self.assertRaises(Unauthorized) as ex: forked_dataset = DatasetFactory(viewer).fork_dataset(forked_dataset.url_prefix, creator, title="dataset_cloned", url_prefix="dataset", description="desc", reference="none", tags=["d2", "d1"]) # Dataset can be forked omitting some options forked_dataset2 = DatasetFactory(creator).fork_dataset(d.url_prefix, viewer, url_prefix="dataset2") self.assertEqual(forked_dataset2.title, d.title) self.assertEqual(forked_dataset2.description, d.description) self.assertEqual(forked_dataset2.tags, d.tags) self.assertEqual(forked_dataset2.reference, d.reference)
def test_url_prefix_can_be_reutilized_on_delete(self): """ Tests that a url prefix can be reutilized. :return: """ dataset = DatasetDAO("ip/asd5", "example6", "desc", "none") dataset.delete() dataset2 = DatasetDAO("ip/asd5", "example6", "desc", "none") self.assertEqual(dataset2.url_prefix, "ip/asd5")
def test_create_dataset_add_remove_element(self): """ Dataset creation and removal of elements works successfully. :return: """ dataset = DatasetDAO("ip/asd3", "example3", "for content", "unknown") dataset.add_element("ele1", "description of the element.", None, tags=["tag1", "tag2"]) dataset.add_element("ele2", "description of the element.", None, tags=["tag1"]) self.session.flush() self.assertEqual(len(dataset.elements), 2) element = DatasetElementDAO.query.get(tags="tag2") self.assertEqual(element.title, "ele1") element.delete() self.session.flush() element = DatasetElementDAO.query.get(tags="tag2") self.assertIsNone(element) element = DatasetElementDAO.query.get(tags="tag1") self.assertEqual(element.title, "ele2") dataset.delete() element = DatasetElementDAO.query.get(tags="tag1") self.assertIsNone(element)
def test_dataset_element_tags_allow_dicts(self): """ Dataset elements tags allow dictionaries as elements. :return: """ dataset = DatasetDAO("ip/asd4", "example4", "desc", "none") element = dataset.add_element("ele1", "description of the element.", None, tags=["tag1", {"tag2":"tag example"}]) self.session.flush() element = dataset.elements[0] self.assertTrue(element.tags[0], "tag1") self.assertTrue(element.tags[1], {"tag2":"tag example"})
def test_dataset_modification(self): """ Factory can modify datasets :return: """ dataset = DatasetDAO("foo/hello", "notitle", "desc", "ref") dataset2 = DatasetDAO("bar/hello", "notitle", "desc", "ref") token_unprivileged = TokenDAO("unprivileged", 0, 0, "bar") token_privileged = TokenDAO("privileged", 0, 0, "bar", privileges=Privileges.EDIT_DATASET) token_admin = TokenDAO("admin", 0, 0, "bar", privileges=Privileges.ADMIN_EDIT_TOKEN) self.session.flush() # Unprivileged token cannot modify dataset with self.assertRaises(Unauthorized) as ex: DatasetFactory(token_unprivileged).edit_dataset(dataset.url_prefix, title="hello") # Privileged token cannot modify dataset if not in same url prefix with self.assertRaises(Unauthorized) as ex: DatasetFactory(token_privileged).edit_dataset(dataset.url_prefix, title="hello") # Privileged token can modify dataset if in same url prefix # NOT: Because dataset is not linked with the token. with self.assertRaises(Unauthorized) as ex: dataset2 = DatasetFactory(token_privileged).edit_dataset(dataset2.url_prefix, title="hello") # If we link it, then it does: token_privileged = token_privileged.link_dataset(dataset2) dataset2 = DatasetFactory(token_privileged).edit_dataset(dataset2.url_prefix, title="hello") self.assertEqual(dataset2.title, "hello") # Admin token can modify any dataset dataset = DatasetFactory(token_admin).edit_dataset(dataset.url_prefix, title="hello2") self.assertEqual(dataset.title, "hello2") # Privileged can partially modify url prefix dataset2 = DatasetFactory(token_privileged).edit_dataset(dataset2.url_prefix, url_prefix="new_prefix") self.assertEqual(dataset2.url_prefix, "bar/new_prefix") with self.assertRaises(BadRequest) as ex: dataset2 = DatasetFactory(token_privileged).edit_dataset(dataset2.url_prefix, url_prefix="bar2/new_prefix") # Admin can modify url prefix without problems dataset2 = DatasetFactory(token_admin).edit_dataset(dataset2.url_prefix, url_prefix="bar2/new_prefix") self.assertEqual(dataset2.url_prefix, "bar2/new_prefix")
def test_dataset_elements_removal(self): """ Factory can remove mutliple elements from datasets at once. """ destructor = TokenDAO("normal user privileged with link", 1, 1, "user1", privileges=Privileges.DESTROY_DATASET + Privileges.DESTROY_ELEMENTS ) dataset = DatasetDAO("user1/dataset1", "example_dataset", "dataset for testing purposes", "none", tags=["example", "0"]) self.session.flush() destructor = destructor.link_dataset(dataset) file_id1 = storage.put_file_content(b"content1") file_id2 = storage.put_file_content(b"content2") element = DatasetElementDAO("example1", "none", file_id1, dataset=dataset) element2 = DatasetElementDAO("example2", "none", file_id1, dataset=dataset) element3 = DatasetElementDAO("example3", "none", file_id2, dataset=dataset) self.session.flush() dataset = dataset.update() self.assertEqual(len(dataset.elements), 3) with self.assertRaises(RequestedRangeNotSatisfiable) as ex: DatasetElementFactory(destructor, dataset).destroy_elements([element._id, element2._id, element3._id]) DatasetElementFactory(destructor, dataset).destroy_elements([element._id, element2._id]) dataset = dataset.update() self.assertEqual(len(dataset.elements), 1) self.assertEqual(dataset.elements[0]._id, element3._id) element = DatasetElementDAO("example1", "none", file_id1, dataset=dataset) element2 = DatasetElementDAO("example2", "none", file_id1, dataset=dataset) self.session.flush() dataset = dataset.update() DatasetElementFactory(destructor, dataset).destroy_elements()
def test_dataset_specific_elements_info(self): """ Factory can retrieve multiple elements at once by specific sets. """ editor = TokenDAO("normal user privileged with link", 1, 1, "user1", privileges=Privileges.RO_WATCH_DATASET ) dataset = DatasetDAO("user1/dataset1", "example_dataset", "dataset for testing purposes", "none", tags=["example", "0"]) self.session.flush() editor = editor.link_dataset(dataset) elements = [DatasetElementDAO("example{}".format(x), "none", None, dataset=dataset) for x in range(5)] titles = [element.title for element in elements] ids = [element._id for element in elements] self.session.flush() dataset = dataset.update() # Can't retrieve more elements than the page size at once. with self.assertRaises(RequestedRangeNotSatisfiable) as ex: retrieved_elements = [x for x in DatasetElementFactory(editor, dataset).get_specific_elements_info(ids)] request1 = ids[0:2] retrieved_elements = [x for x in DatasetElementFactory(editor, dataset).get_specific_elements_info(request1)] self.assertEqual(len(retrieved_elements), 2) self.assertIn(retrieved_elements[0].title, titles) self.assertIn(retrieved_elements[1].title, titles) request2 = ids[1:3] retrieved_elements2 = [x for x in DatasetElementFactory(editor, dataset).get_specific_elements_info(request2)] self.assertEqual(len(retrieved_elements2), 2) self.assertIn(retrieved_elements2[0].title, titles) self.assertIn(retrieved_elements2[1].title, titles) self.assertNotEqual(retrieved_elements[0].title, retrieved_elements2[0].title) self.assertNotEqual(retrieved_elements[1].title, retrieved_elements2[1].title) self.assertEqual(retrieved_elements[1].title, retrieved_elements2[0].title)
def test_dataset_elements_edit(self): """ Factory can edit multiple elements from datasets at once. """ editor = TokenDAO("normal user privileged with link", 1, 1, "user1", privileges=Privileges.EDIT_DATASET + Privileges.EDIT_ELEMENTS ) dataset = DatasetDAO("user1/dataset1", "example_dataset", "dataset for testing purposes", "none", tags=["example", "0"]) self.session.flush() editor = editor.link_dataset(dataset) file_id1 = storage.put_file_content(b"content1") file_id2 = storage.put_file_content(b"content2") element = DatasetElementDAO("example1", "none", file_id1, dataset=dataset) element2 = DatasetElementDAO("example2", "none", file_id1, dataset=dataset) element3 = DatasetElementDAO("example3", "none", file_id2, dataset=dataset) self.session.flush() dataset = dataset.update() self.assertEqual(len(dataset.elements), 3) modifications = { element._id: dict(title="asd6", content=b"content4"), element3._id: dict(description="ffff", content=b"New Content!") } DatasetElementFactory(editor, dataset).edit_elements(modifications) self.session.flush() dataset = dataset.update() element = element.update() element3 = element3.update() self.assertEqual(element.title, "asd6") self.assertEqual(storage.get_file(element.file_ref_id).content, b"content4") self.assertEqual(element3.description, "ffff") self.assertEqual(storage.get_file(element3.file_ref_id).content, b"New Content!")
def test_dataset_tags_allow_dicts(self): """ Dataset elements tags allow dictionaries as elements. :return: """ dataset = DatasetDAO("ip/asd4", "example4", "desc", "none", tags=["tag1", {"tag2":"tag example"}]) self.session.flush() self.assertTrue(dataset.tags[0], "tag1") self.assertTrue(dataset.tags[1], {"tag2":"tag example"})
def test_token_can_link_datasets(self): """ Tests that tokens can be associated to multiple datasets and disassociated. :return: """ token1 = TokenDAO("example_token", 2, 5, "dalap") token2 = TokenDAO("example_token2", 2, 5, "dalap") dataset1 = DatasetDAO("ex/ivan", "example1", "lalala", "none") dataset2 = DatasetDAO("ex/ivan2", "example2", "lalala", "none") token1 = token1.link_datasets([dataset1, dataset2]) token2 = token2.link_dataset(dataset2) self.session.flush() self.assertEqual(len(token1.datasets), 2) self.assertEqual(len(token2.datasets), 1) token1 = token1.unlink_dataset(dataset2) self.assertEqual(len(token1.datasets), 1)
def test_dataset_elements_info_by_different_pages_size(self): """ Factory can retrieve multiple elements with different page sizes. """ initial_page_size = global_config.get_page_size() global_config.set_page_size(10) editor = TokenDAO("normal user privileged with link", 1, 5, "user1", privileges=Privileges.RO_WATCH_DATASET ) dataset = DatasetDAO("user1/dataset1", "example_dataset", "dataset for testing purposes", "none", tags=["example", "0"]) self.session.flush() editor = editor.link_dataset(dataset) elements = [DatasetElementDAO("example{}".format(x), "none", None, dataset=dataset).title for x in range(5)] self.session.flush() dataset = dataset.update() # We need to know the order of the elements ordered_elements = [l for l in DatasetElementFactory(editor, dataset).get_elements_info(page_size=len(elements))] pages_size = [1, 2, 3, 4, 5] for page_size in pages_size: num_pages = len(elements) // page_size + int(len(elements) % page_size > 0) for page in range(num_pages): retrieved_elements = [l for l in DatasetElementFactory(editor, dataset).get_elements_info(page, page_size=page_size)] for retrieved_element, ordered_element in zip(retrieved_elements, ordered_elements[page*page_size:(page+1)*page_size]): self.assertEqual(retrieved_element._id, ordered_element._id) with self.assertRaises(Conflict): retrieved_elements = DatasetElementFactory(editor, dataset).get_elements_info(page_size=global_config.get_page_size()+1) global_config.set_page_size(initial_page_size)
def create_dataset(self, *args, **kwargs) -> DatasetDAO: can_create_inner_dataset = bool(self.token.privileges & Privileges.CREATE_DATASET) can_create_others_dataset = bool(self.token.privileges & Privileges.ADMIN_CREATE_TOKEN) illegal_chars = self.illegal_chars if not any([can_create_inner_dataset, can_create_others_dataset]): abort(401, message="Your token does not have privileges enough to create dataset.") if not can_create_others_dataset and self._dataset_limit_reached(): abort(401, message="Your token has reached the limit in the creation of datasets.") try: url_prefix = kwargs["url_prefix"] del kwargs["url_prefix"] except KeyError as ex: url_prefix = "" abort(400, message="An URL-Prefix is required for the creation of the dataset.") if 'elements' in kwargs: abort(400, message="There is a field not allowed in the create request.") if 'comments' in kwargs: abort(400, message="There is a field not allowed in the create request.") # Limit arguments. kwargs['fork_count'] = 0 if 'forked_from' in kwargs: del kwargs['forked_from'] if 'forked_from_id' in kwargs: del kwargs['forked_from_id'] if can_create_others_dataset: illegal_chars = illegal_chars[1:] # "/" is allowed for admin if any([illegal_char in url_prefix for illegal_char in illegal_chars]): abort(400, message="The following chars are not allowed in the url-prefix: {}".format(illegal_chars)) if "/" not in url_prefix: url_prefix="{}/{}".format(self.token.url_prefix, url_prefix) kwargs['url_prefix'] = url_prefix try: dataset = DatasetDAO(*args, **kwargs) except Exception as ex: dataset = None abort(400, message=str(ex)) self.session.flush() return dataset
def test_create_dataset_element_link_datasets_remove(self): """ Dataset element clones itself correctly when it is linked to multiple datasets and removed. :return: """ dataset = DatasetDAO("ip/asd3", "example3", "for content", "unknown") dataset2 = DatasetDAO("ip/asd4", "example4", "for content", "unknown") element = dataset.add_element("ele1", "description of the element.", None, tags=["tag1", "tag2"]) self.session.flush() self.assertEqual(len(dataset.elements), 1) self.assertEqual(len(dataset2.elements), 0) element.link_dataset(dataset2) self.session.flush() self.assertEqual(len(dataset.elements), 1) self.assertEqual(len(dataset2.elements), 1) self.assertEqual(dataset2.elements[0], element) element.delete() self.session.flush() self.assertEqual(len(dataset.elements), 0) self.assertEqual(len(dataset2.elements), 1) self.assertNotEqual(element, dataset2.elements[0]) self.assertEqual(element.title, dataset2.elements[0].title) element = dataset2.elements[0] element.link_dataset(dataset) self.session.flush() self.assertEqual(len(dataset.elements), 1) self.assertEqual(len(dataset2.elements), 1) element.delete(owner_id=dataset._id) self.session.flush() self.assertEqual(len(dataset.elements), 0) self.assertEqual(len(dataset2.elements), 1) self.assertEqual(element.title, dataset2.elements[0].title)
def test_dataset_element_creation_limit(self): """ Factory limits creation of dataset's elements depending on the token used to create it. """ creator = TokenDAO("normal user privileged", 1, 1, "user1", privileges=Privileges.CREATE_DATASET+Privileges.ADD_ELEMENTS) dataset = DatasetDAO("user1/dataset1", "example_dataset", "dataset for testing purposes", "none", tags=["example", "0"]) self.session.flush() # Creator should not be able to create more than 1 element in any dataset creator = creator.link_dataset(dataset) element1 = DatasetElementFactory(creator, dataset).create_element(title="New element1", description="Description unknown", tags=["example_tag"], content=b"hello") dataset = dataset.update() with self.assertRaises(Unauthorized) as ex: element2 = DatasetElementFactory(creator, dataset).create_element(title="New element2", description="Description unknown", tags=["example_tag"], content=b"hello")
def test_clone_element(self): """ Factory can clone elements. """ editor = TokenDAO("normal user privileged with link", 2, 1, "user1", privileges=Privileges.RO_WATCH_DATASET + Privileges.EDIT_DATASET + Privileges.ADD_ELEMENTS ) dataset = DatasetDAO("user1/dataset1", "example_dataset", "dataset for testing purposes", "none", tags=["example", "0"]) dataset2 = DatasetDAO("user1/dataset2", "example_dataset2", "dataset2 for testing purposes", "none", tags=["example", "1"]) self.session.flush() editor = editor.link_dataset(dataset) file_id1 = storage.put_file_content(b"content1") file_id2 = storage.put_file_content(b"content2") element = DatasetElementDAO("example1", "none", file_id1, dataset=dataset) element2 = DatasetElementDAO("example2", "none", file_id1, dataset=dataset) element3 = DatasetElementDAO("example3", "none", file_id2, dataset=dataset) self.session.flush() dataset = dataset.update() dataset2 = dataset2.update() self.assertEqual(len(dataset.elements), 3) self.assertEqual(len(dataset2.elements), 0) with self.assertRaises(Unauthorized) as ex: new_element = DatasetElementFactory(editor, dataset).clone_element(element._id, dataset2.url_prefix) editor = editor.link_dataset(dataset2) self.assertEqual(len(element.dataset_id), 1) new_element = DatasetElementFactory(editor, dataset).clone_element(element._id, dataset2.url_prefix) dataset2 = dataset2.update() self.assertEqual(len(dataset2.elements), 1) self.assertEqual(new_element.file_ref_id, element.file_ref_id) self.assertEqual(new_element.title, element.title) self.assertEqual(new_element.description, element.description) self.assertEqual(new_element.tags, element.tags) self.assertEqual(new_element._id, element._id) self.assertEqual(len(new_element.dataset_id), 2) self.assertEqual(len(element.dataset_id), 2) with self.assertRaises(Unauthorized) as ex: new_element = DatasetElementFactory(editor, dataset).clone_element(element2._id, dataset2.url_prefix)
def test_create_remove_dataset(self): """ Dataset creation and removal works successfully. :return: """ dataset = DatasetDAO("ip/asd", "example1", "desc", "none") self.assertTrue(dataset.title, "example") self.assertTrue(dataset.description, "desc") self.assertTrue(dataset.reference, "none") self.session.flush() dataset2 = DatasetDAO.query.get(title="example1") self.assertEqual(dataset.title, dataset2.title) self.assertEqual(dataset.description, dataset2.description) self.assertEqual(dataset.reference, dataset2.reference) dataset.delete() self.session.flush() dataset3 = DatasetDAO.query.get(title='example1') self.assertIsNone(dataset3)
def test_create_dataset_element_add_remove_comment(self): """ Dataset creation and removal of comments from elements works successfully. :return: """ dataset = DatasetDAO("ip/asd4", "example4", "desc", "none") element = dataset.add_element("ele1", "description of the element.", None, tags=["tag1", "tag2"]) element2 = dataset.add_element("ele2", "description of the element2.", None, tags=["tag1", "tag2"]) element.add_comment("ivan", "1", "11") element.add_comment("ivan", "1", "21") element.add_comment("ivan", "1", "11") self.session.flush() self.assertEqual(len(element.comments), 3) self.assertEqual(len(element2.comments), 0) self.assertEqual(element.comments[0].author_name, "ivan") self.assertEqual(element.comments[1].author_name, "ivan") self.assertEqual(element.comments[2].author_name, "ivan") comment = element.comments[0] comment.delete() self.session.flush() self.session.clear() element = DatasetElementDAO.query.get(title="ele1") self.session.refresh(element) self.assertEqual(len(element.comments), 2) comment = DatasetElementCommentDAO.query.get(author_name="ivan") self.assertEqual(comment.element_id, element._id) element.delete() self.session.flush() comment = DatasetElementCommentDAO.query.get(author_name="ivan") self.assertIsNone(comment) dataset.delete()
def test_create_dataset_add_remove_comment(self): """ Dataset creation and removal of comments works successfully. :return: """ dataset = DatasetDAO("ip/asd2", "example2", "desc", "none") c1 = dataset.add_comment("ivan", "1", "11") c2 = dataset.add_comment("ivan", "1", "21") c3 = dataset.add_comment("ivan", "1", "11") self.session.flush() dataset2 = DatasetDAO.query.get(title="example2") self.session.refresh(dataset2) self.assertEqual(len(dataset2.comments), 3) self.assertEqual(dataset2.comments[0].author_name, "ivan") self.assertEqual(dataset2.comments[1].author_name, "ivan") self.assertEqual(dataset2.comments[2].author_name, "ivan") dataset.comments[0].delete() self.session.flush() dataset3 = DatasetDAO.query.get(title="example2") self.assertEqual(len(dataset3.comments), 2) comment = DatasetCommentDAO.query.get(author_name="ivan") self.assertEqual(comment.dataset_id, dataset._id) dataset.delete() self.session.flush() comment = DatasetCommentDAO.query.get(author_name="ivan") self.assertIsNone(comment)
def test_dataset_element_removal(self): """ Factory can remove elements from datasets. """ anonymous = TokenDAO("Anonymous", 1, 1, "anonymous") destructor = TokenDAO("normal user privileged with link", 1, 1, "user1", privileges=Privileges.DESTROY_DATASET + Privileges.DESTROY_ELEMENTS ) destructor2 = TokenDAO("normal user unprivileged", 1, 1, "user1", privileges=Privileges.DESTROY_DATASET ) admin = TokenDAO("admin user", 1, 1, "admin", privileges=Privileges.ADMIN_CREATE_TOKEN + Privileges.ADMIN_EDIT_TOKEN + Privileges.ADMIN_DESTROY_TOKEN) dataset = DatasetDAO("user1/dataset1", "example_dataset", "dataset for testing purposes", "none", tags=["example", "0"]) dataset2 = DatasetDAO("user1/dataset2", "example_dataset2", "dataset2 for testing purposes", "none", tags=["example", "1"]) self.session.flush() destructor = destructor.link_dataset(dataset) destructor2 = destructor2.link_dataset(dataset2) file_id1 = storage.put_file_content(b"content1") file_id2 = storage.put_file_content(b"content2") element = DatasetElementDAO("example1", "none", file_id1, dataset=dataset) element2 = DatasetElementDAO("example2", "none", file_id1, dataset=dataset) element3 = DatasetElementDAO("example3", "none", file_id2, dataset=dataset2) self.session.flush() dataset = dataset.update() dataset2 = dataset2.update() self.assertEqual(len(dataset.elements), 2) self.assertEqual(len(dataset2.elements), 1) # Destructor can not destroy elements from a dataset that is not linked to with self.assertRaises(Unauthorized) as ex: DatasetElementFactory(destructor, dataset2).destroy_element(element._id) with self.assertRaises(Unauthorized) as ex: DatasetElementFactory(destructor, dataset2).destroy_element(element2._id) with self.assertRaises(Unauthorized) as ex: DatasetElementFactory(destructor, dataset2).destroy_element(element3._id) # Destructor can not destroy elements if they exist but are not inside his dataset with self.assertRaises(Unauthorized) as ex: DatasetElementFactory(destructor, dataset).destroy_element(element3._id) # Destructor can not destroy elements if they don't exist with self.assertRaises(Unauthorized) as ex: DatasetElementFactory(destructor, dataset).destroy_element("randomID") # Destructor can destroy elements if they exist and are inside his dataset DatasetElementFactory(destructor, dataset).destroy_element(element._id) # Even though element is destroyed, file referenced should still exist self.assertEqual(storage.get_file(file_id1).content, b"content1") dataset = dataset.update() self.assertEqual(len(dataset.elements), 1) # Admin can remove elements form any source DatasetElementFactory(admin, dataset).destroy_element(element2._id) DatasetElementFactory(admin, dataset2).destroy_element(element3._id) self.session.flush() dataset = dataset.update() dataset2 = dataset2.update() self.assertEqual(len(dataset.elements), 0) self.assertEqual(len(dataset2.elements), 0)
def test_dataset_element_edit(self): """ Factory can edit elements from datasets. """ editor = TokenDAO("normal user privileged with link", 1, 1, "user1", privileges=Privileges.EDIT_DATASET + Privileges.EDIT_ELEMENTS ) editor2 = TokenDAO("normal user unprivileged", 1, 1, "user1", privileges=Privileges.EDIT_DATASET ) admin = TokenDAO("admin user", 1, 1, "admin", privileges=Privileges.ADMIN_CREATE_TOKEN + Privileges.ADMIN_EDIT_TOKEN + Privileges.ADMIN_DESTROY_TOKEN) dataset = DatasetDAO("user1/dataset1", "example_dataset", "dataset for testing purposes", "none", tags=["example", "0"]) dataset2 = DatasetDAO("user1/dataset2", "example_dataset2", "dataset2 for testing purposes", "none", tags=["example", "1"]) self.session.flush() editor = editor.link_dataset(dataset) editor2 = editor2.link_dataset(dataset2) file_id1 = storage.put_file_content(b"content1") file_id2 = storage.put_file_content(b"content2") element = DatasetElementDAO("example1", "none", file_id1, dataset=dataset) element2 = DatasetElementDAO("example2", "none", file_id1, dataset=dataset) element3 = DatasetElementDAO("example3", "none", file_id2, dataset=dataset2) self.session.flush() dataset = dataset.update() dataset2 = dataset2.update() self.assertEqual(len(dataset.elements), 2) self.assertEqual(len(dataset2.elements), 1) # editor can not edit elements from a dataset that is not linked to with self.assertRaises(Unauthorized) as ex: DatasetElementFactory(editor, dataset2).edit_element(element._id, title="asd") with self.assertRaises(Unauthorized) as ex: DatasetElementFactory(editor, dataset2).edit_element(element2._id, title="asd2") with self.assertRaises(Unauthorized) as ex: DatasetElementFactory(editor, dataset2).edit_element(element3._id, title="asd3") # editor can not edit elements if they exist but are not inside his dataset with self.assertRaises(Unauthorized) as ex: DatasetElementFactory(editor, dataset).edit_element(element3._id, title="asd4") # editor can not edit elements if they don't exist with self.assertRaises(NotFound) as ex: DatasetElementFactory(editor, dataset).edit_element("randomID", title="asd5") # Editor can edit elements if they exist and are inside his dataset DatasetElementFactory(editor, dataset).edit_element(element._id, title="asd6") self.session.flush() dataset = dataset.update() element = element.update() # Editor can not change references to files with self.assertRaises(Unauthorized) as ex: DatasetElementFactory(editor, dataset).edit_element(element._id, file_ref_id="other_reference") # BUT he can change the content DatasetElementFactory(editor, dataset).edit_element(element._id, content=b"other_content") element = element.update() self.assertEqual(storage.get_file(element.file_ref_id).content, b"other_content") # Admin can do whatever he wants DatasetElementFactory(admin, dataset).edit_element(element2._id, title="changed by admin") element2 = element2.update() self.assertEqual(element2.title, "changed by admin") DatasetElementFactory(admin, dataset2).edit_element(element3._id, file_ref_id=element.file_ref_id) element3 = element3.update() self.assertEqual(storage.get_file(element3.file_ref_id).content, storage.get_file(element.file_ref_id).content) self.session.flush()
def test_dataset_element_creation(self): """ Factory can create dataset's elements. """ anonymous = TokenDAO("Anonymous", 1, 1, "anonymous") creator = TokenDAO("normal user privileged with link", 1, 1, "user1", privileges=Privileges.CREATE_DATASET + Privileges.ADD_ELEMENTS ) creator2 = TokenDAO("normal user unprivileged", 1, 1, "user1", privileges=Privileges.CREATE_DATASET ) admin = TokenDAO("admin user", 1, 1, "admin", privileges=Privileges.ADMIN_CREATE_TOKEN + Privileges.ADMIN_EDIT_TOKEN + Privileges.ADMIN_DESTROY_TOKEN) dataset = DatasetDAO("user1/dataset1", "example_dataset", "dataset for testing purposes", "none", tags=["example", "0"]) dataset2 = DatasetDAO("user1/dataset2", "example_dataset2", "dataset2 for testing purposes", "none", tags=["example", "1"]) self.session.flush() creator = creator.link_dataset(dataset) creator2 = creator2.link_dataset(dataset) # Creator can create elements into the dataset element = DatasetElementFactory(creator, dataset).create_element(title="New element", description="Description unknown", tags=["example_tag"], content=b"hello") self.assertEqual(element.tags, ["example_tag"]) content = storage.get_file(element.file_ref_id).content self.assertEqual(content, b"hello") self.session.flush() # Creator can't create elements referencing existing files directly (Exploit fix) with self.assertRaises(Unauthorized) as ex: element = DatasetElementFactory(creator, dataset).create_element(title="New element2", description="Description unknown2", tags=["example_tag"], file_ref_id=element.file_ref_id) # Creator can't create elements on other's datasets if not linked with them with self.assertRaises(Unauthorized) as ex: element = DatasetElementFactory(creator, dataset2).create_element(title="New element2", description="Description unknown2", tags=["example_tag"], content=b"hello2") # Anonymous can't create elements with self.assertRaises(Unauthorized) as ex: element = DatasetElementFactory(anonymous, dataset).create_element(title="New element3", description="Description unknown", tags=["example_tag"], content=b"hello3") # Creator2, even linked to the dataset, can't create elements as it is not privileged with self.assertRaises(Unauthorized) as ex: element = DatasetElementFactory(creator2, dataset).create_element(title="New element4", description="Description unknown4", tags=["example_tag"], content=b"hello4") # Admin can do any of the previous actions. element = DatasetElementFactory(admin, dataset).create_element(title="New element5", description="Description unknown5", tags=["example_tag"], content=b"hello5") self.session.flush_all() self.session.refresh(dataset) dataset = DatasetDAO.query.get(_id=dataset._id) self.assertIn(dataset._id, element.dataset_id) self.assertEqual(len(dataset.elements), 2) new_element = DatasetElementFactory(admin, dataset2).create_element(title="New element6", description="Description unknown5", tags=["example_tag"], file_ref_id=element.file_ref_id) self.assertEqual(element.file_ref_id, new_element.file_ref_id)
def test_dataset_can_be_unlinked_with_token(self): """ Factory can unlink datasets. :return: """ token = TokenDAO("linker", 1, 1, "testinglink", privileges=Privileges.RO_WATCH_DATASET + Privileges.CREATE_DATASET) token2 = TokenDAO("linker", 1, 1, "testinglink2", privileges=Privileges.RO_WATCH_DATASET + Privileges.USER_EDIT_TOKEN) token21 = TokenDAO("linker", 1, 1, "testinglink2", privileges=Privileges.RO_WATCH_DATASET + Privileges.USER_EDIT_TOKEN) dataset = DatasetDAO("{}/{}".format(token.url_prefix, "dataset"), "dataset1", "dataset example", "none") dataset2 = DatasetDAO("{}/{}".format(token2.url_prefix, "dataset2"), "dataset2", "dataset example2", "none") token3 = TokenDAO("linked", 1, 1, "testinglink2", privileges=Privileges.RO_WATCH_DATASET + Privileges.ADMIN_EDIT_TOKEN) self.session.flush() token = token.link_datasets([dataset, dataset2]) token21 = token21.link_datasets([dataset2]) # Not privileged token can't link a dataset. with self.assertRaises(Unauthorized) as ex: token21 = TokenFactory(token).unlink_datasets( token21.token_gui, [dataset2.url_prefix]) with self.assertRaises(Unauthorized) as ex: token = TokenFactory(token).unlink_datasets( token.token_gui, [dataset.url_prefix]) # Privileged token can unlink a dataset. token21 = TokenFactory(token2).unlink_datasets(token21.token_gui, [dataset2.url_prefix]) self.assertEqual(len(token21.datasets), 0) token21 = token21.link_datasets([dataset]) # Privileged token can NOT unlink a dataset of other url prefix with self.assertRaises(Unauthorized) as ex: token21 = TokenFactory(token2).unlink_datasets( token21.token_gui, [dataset.url_prefix]) # Privileged token can NOT unlink a dataset from a token of other url prefix with self.assertRaises(Unauthorized) as ex: token = TokenFactory(token2).unlink_datasets( token.token_gui, [dataset.url_prefix]) # Admin can do all of the above cases. token21 = TokenFactory(token3).unlink_datasets(token21.token_gui, [dataset.url_prefix]) token = TokenFactory(token3).unlink_datasets(token.token_gui, [dataset.url_prefix]) self.assertEqual(len(token21.datasets), 0) self.assertEqual(len(token.datasets), 1)
def test_dataset_element_content_retrieval(self): """ Factory can retrieve content of an element. """ editor = TokenDAO("normal user privileged with link", 1, 1, "user1", privileges=Privileges.RO_WATCH_DATASET ) editor2 = TokenDAO("normal user unprivileged", 1, 1, "user1", privileges=0 ) admin = TokenDAO("admin user", 1, 1, "admin", privileges=Privileges.ADMIN_CREATE_TOKEN + Privileges.ADMIN_EDIT_TOKEN + Privileges.ADMIN_DESTROY_TOKEN) dataset = DatasetDAO("user1/dataset1", "example_dataset", "dataset for testing purposes", "none", tags=["example", "0"]) dataset2 = DatasetDAO("user1/dataset2", "example_dataset2", "dataset2 for testing purposes", "none", tags=["example", "1"]) self.session.flush() editor = editor.link_dataset(dataset) editor2 = editor2.link_dataset(dataset2) file_id1 = storage.put_file_content(b"content1") file_id2 = storage.put_file_content(b"content2") element = DatasetElementDAO("example1", "none", file_id1, dataset=dataset) element2 = DatasetElementDAO("example2", "none", file_id1, dataset=dataset) element3 = DatasetElementDAO("example3", "none", file_id2, dataset=dataset2) self.session.flush() dataset = dataset.update() dataset2 = dataset2.update() self.assertEqual(len(dataset.elements), 2) self.assertEqual(len(dataset2.elements), 1) # editor can see elements from his dataset element_content = DatasetElementFactory(editor, dataset).get_element_content(element._id) self.assertEqual(element_content, b"content1") # editor can not see elements from other's datasets with self.assertRaises(Unauthorized) as ex: element_content = DatasetElementFactory(editor, dataset2).get_element_content(element3._id) # editor can not see external elements within his dataset with self.assertRaises(Unauthorized) as ex: element_content = DatasetElementFactory(editor, dataset).get_element_content(element3._id) # editor2 is not privileged and can not see any elements of his own dataset with self.assertRaises(Unauthorized) as ex: element_content = DatasetElementFactory(editor2, dataset2).get_element_content(element3._id) # Or external elements with self.assertRaises(Unauthorized) as ex: element_content = DatasetElementFactory(editor2, dataset2).get_element_content(element2._id) # Or other datasets with self.assertRaises(Unauthorized) as ex: element_content = DatasetElementFactory(editor2, dataset).get_element_content(element2._id) # Admin can do anything element_content = DatasetElementFactory(admin, dataset).get_element_content(element._id) self.assertEqual(element_content, b"content1") # But not this: dataset2 does not have element with self.assertRaises(Unauthorized) as ex: element_content = DatasetElementFactory(admin, dataset2).get_element_content(element._id) element_content = DatasetElementFactory(admin, dataset2).get_element_content(element3._id) self.assertEqual(element_content, b"content2")