def _generate_node_event_skeleton(_user_id, _occurred_when, _node_id): """ Generate a skeleton for a event item :param _user_id: The userId :param _occurred_when: When the event occured :param _node_id: The affected nodeId """ # TODO: Decide on how to make user ID reach the logger. return { "user_id": of_object_id(_user_id), "occurredWhen": _occurred_when, "node_id": of_object_id(_node_id) }
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 logout(self, _session_id): _remove_cond = { "conditions": {"_id": of_object_id(_session_id)}, "collection": "session" } self.db_access.remove_condition(_remove_cond, None)
def step_impl(context, event_category, prefix): """ :type context behave.runner.Context :param security_event_type The type of event :param prefix The prefix to look for """ _result = context.node.database_access.find( {"conditions": {"node_id": of_object_id("000000010000010001e64d01"), "user_id": of_object_id("000000010000010001e64d13"), "category": event_category}, "collection": "log"}) for _curr_error in _result: if _curr_error["data"][0:len(prefix)] == prefix: ok_(True) return ok_(False, context.scenario.name + ": Missing security event")
def step_impl(context): """ :type context behave.runner.Context """ _result = context.node.find({"_id": of_object_id(context.curr_id)}, context.user) if len(_result) == 0: ok_(True) else: ok_(False, "Test log item wasn't remove, result:" + str(_result))
def get_user(self, _user_id): _user_condition = { "conditions": {"_id": of_object_id(_user_id), "schemaRef": "ref://of.node.user"}, "collection": "node" } _users = list(self.db_access.find(_user_condition)) if len(_users) > 0: if len(_users) > 1: raise Exception("get user: Multiple users returned by user query for " + _user_id) return _users[0] else: return None
def get_session(self, _session_id): _session_cond = { "conditions": {"_id": of_object_id(_session_id)}, "collection": "session" } _sessions = self.db_access.find(_session_cond) if len(_sessions) > 0: if len(_sessions) > 1: raise Exception("session check: Multiple users returned by user query for " + _session_id) return _sessions[0] else: return None
def step_impl(context): """ :type context behave.runner.Context """ _result = context.node.lookup( {"conditions": {"parent_id": of_object_id("000000010000010001e64c24")}, "collection": "node"}, context.user) for _curr_select in _result: if _curr_select["value"] == "000000010000010001e64c28" and _curr_select["text"] == "Administrators": ok_(True) return ok_(False)
def step_impl(context): """ :type context behave.runner.Context """ _result = context.node.database_access.find( {"conditions": {"node_id": None, "user_id": of_object_id("000000010000010001e64d15"), "category": "right"}, "collection": "log"}) if len(_result) == 1: ok_(True) else: ok_(False)
def step_impl(context): """ :type context behave.runner.Context """ try: context.node.find({"_id": of_object_id("000000010000010001e64d01")}, context.user) except RightCheckError: ok_(True) return ok_(False)
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 filter_by_group(_nodes, _permission, _user, _database_access, _error_prefix_if_not_allowed=None, _use_object_id=False): """This function filters a list of nodes based on what groups a user belong to and its right :param _nodes: A list of node :param _permission: The permission to check. For example "canRead" or "canWrite". :param _user: The user to check :param _database_access: A database access instance. :param _error_prefix_if_not_allowed: If set, the supplied error message is raised. Normally used when testing for\ write access. :param _use_object_id: If true, the node has ObjectId instances and not strings. :return: A list of nodes any of the users' groups have the permission defined in _permission for """ _result = [] _groups = _user["groups"] # Loop nodes for _curr_row in _nodes: _has_permission = False # Check if any of the group the user belongs to.. for _curr_group in _groups: # ..is among those the node has listed having the requested permission if _use_object_id: if of_object_id(_curr_group) in _curr_row[_permission]: _has_permission = True break elif _curr_group in _curr_row[_permission]: _has_permission = True break if _has_permission: _result.append(_curr_row) elif _error_prefix_if_not_allowed: # Raise an error if a user lacks the _permission for. _error = _error_prefix_if_not_allowed + ":" + _user["name"] + " doesn't have the " + _permission + \ " for the " + _curr_row["name"] + "(" + str(_curr_row["_id"]) + ")-node." _database_access.logging.log_security("permission", _error, _user["_id"], str(_curr_row["_id"])) raise PermissionError(_error) return _result
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 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"})