def save(self, _document, _user): """save(self, _document, _user) Saves an of-node descendant to the database. :param _document: The node document to save. :param _user: The current user :return: A structure detailing the save result """ # The data must have a schema id key and it must say that the collection is "node". self.database_access.verify_document(_document, "node", "Node.save") if "_id" in _document: # It is an existing node, check if user can write to it. _old_document_result = filter_by_group( self.database_access.find( {"conditions": {"_id": of_object_id(_document["_id"])}, "collection": "node"} ), "canWrite", _user, "Node.save(existing node)", ) if len(_old_document_result) == 1: _old_document = _old_document_result[0] else: raise Exception( "Needed exactly one(1) existing node, found " + str(len(_old_document_result)) + ". _id: " + _document["_id"] ) elif "parent_id" in _document: # It is a new node, check if the parent allows user to create it filter_by_group( self.database_access.find( {"conditions": {"_id": of_object_id(_document["parent_id"])}, "collection": "node"} ), "canWrite", _user, "Node.save(new node)", ) _old_document = None else: raise Exception("Node.save: Data must have a parentId or an _id.") # TODO: Specify how the result actually looks return self.database_access.save(_document, _user, _old_document)
def lookup(self, _conditions, _user): """ Returns a list of value-name objects for use in drop downs. As find, handles the ObjectId(000000010000010001ee3214) string format. (no quotes) :param _conditions: An MBE condition :param _user: A user object :return: A list of lookup objects. """ # Only allow node collection, but allow not specifying schema in conditions. self.database_access.verify_condition(_conditions, "node", "Node.find") print(str(_conditions)) # Filter result by canRead groups return [ {"value": _row["_id"], "text": _row["name"]} for _row in filter_by_group( self.database_access.find(self._string_to_object_ids(_conditions)), "canRead", _user, self.database_access, ) ]
def history(self, _id, _user): """ Return the change history for the specified node. :param _id: An object with a node _id field :param _user: A user object :return: """ object_id = of_object_id(_id["_id"]) # Filter result by canRead filter_by_group( self.database_access.find({"conditions": {"_id": object_id}, "collection": "node"}), "canRead", _user, self.database_access, _error_prefix_if_not_allowed="Node.history: No permissions to view details of this node. _id: " + _id["_id"], ) return self.database_access.find({"conditions": {"node_id": object_id}, "collection": "log"})
def load_children(self, _parent_id, _user): """ Returns a list of child nodes whose _parent_ids match _parent_id :param _parent_id: A parent Id :param _user: A user object :return: A list of nodes """ # Filter result by canRead groups return filter_by_group( self.database_access.find({"conditions": {"parent_id": of_object_id(_parent_id)}, "collection": "node"}), "canRead", _user, self.database_access, )
def load_node(self, _id, _user): """ Returns the child with _id. :param _id: An object with a id property :param _user: A user object :return: A list of nodes """ # Filter result by canRead groups return filter_by_group( self.database_access.find({"conditions": {"_id": of_object_id(_id["_id"])}, "collection": "node"}), "canRead", _user, self.database_access, _error_prefix_if_not_allowed="Node.load_node: Not permissioned to load this node. _id: " + _id["_id"], )[0]
def remove(self, _id, _user): """ Remove the specified node :param _id: An object with a node _id field :param _user: A user object :return: Result of removal """ # Recurse and gather all children def _recurse_children(_parent_node): _result = [_parent_node] _child_nodes = self.database_access.find( {"conditions": {"parent_id": _parent_node["_id"]}, "collection": "node"}, _do_not_fix_object_ids=True ) for _curr_child in _child_nodes: _result += _recurse_children(_curr_child) return _result # Load the current node _node = self.database_access.find( {"conditions": {"_id": of_object_id(_id["_id"])}, "collection": "node"}, _do_not_fix_object_ids=True )[0] _all_nodes = _recurse_children(_node) # Check permissions, as the remove_documents function works with documents directly the from database, # use objectIds. _documents = filter_by_group( _all_nodes, "canWrite", _user, self.database_access, _error_prefix_if_not_allowed="Node.remove: Missing permissions to remove node or sub nodes.", _use_object_id=True, ) # TODO: Specify removal result structure return self.database_access.remove_documents(_documents, _user, "node")
def get_templates(self, _schema_ref, _user): """ Returns a template. :param _schema_ref: The schemaRef if the wanted templates :return: A list of nodes matching the schema that the user have rights to """ # Filter result by canRead groups return filter_by_group( self.database_access.find( { "conditions": {"parent_id": of_object_id(id_templates), "schemaRef": _schema_ref}, "collection": "node", } ), "canRead", _user, self.database_access, )
def find(self, _conditions, _user, _error_prefix_if_not_allowed=None): """find(_conditions,_user) Returns a list of nodes matching the condition. Note: This method is literate, it takes ObjectId instances when comparing to ObjectId instances. But JSON doesn't handle ObjectId. So instead it supports an ObjectId(000000010000010001ee3214)-syntax and when it encounters those values, it converts them into ObjectId instances. :param _conditions: A condition :param _user: A user object :return: A list of nodes """ # Filter result by canRead groups return filter_by_group( self.database_access.find({"conditions": self._string_to_object_ids(_conditions), "collection": "node"}), "canRead", _user, self.database_access, _error_prefix_if_not_allowed=_error_prefix_if_not_allowed, )