X-Git-Url: https://osm.etsi.org/gitweb/?p=osm%2FNBI.git;a=blobdiff_plain;f=osm_nbi%2Fbase_topic.py;h=daa7a6b2104efcadc7816ed76f01e920698611b1;hp=e849bb843ee8c4dcb5a9f8cb1a0562db72abccc3;hb=20e74d260242c91c9836efba6a9436a159c4decc;hpb=f5f2e3f9cecc38647a437af7812323a1da7d3f60 diff --git a/osm_nbi/base_topic.py b/osm_nbi/base_topic.py index e849bb8..daa7a6b 100644 --- a/osm_nbi/base_topic.py +++ b/osm_nbi/base_topic.py @@ -69,6 +69,7 @@ class BaseTopic: # static variables for all instance classes topic = None # to_override topic_msg = None # to_override + quota_name = None # to_override. If not provided topic will be used for quota_name schema_new = None # to_override schema_edit = None # to_override multiproject = True # True if this Topic can be shared by several projects. Then it contains _admin.projects_read @@ -107,24 +108,26 @@ class BaseTopic: """ Check whether topic quota is exceeded by the given project Used by relevant topics' 'new' function to decide whether or not creation of the new item should be allowed - :param projects: projects (tuple) for which quota should be checked - :param override: boolean. If true, don't raise ValidationError even though quota be exceeded + :param session[project_id]: projects (tuple) for which quota should be checked + :param session[force]: boolean. If true, skip quota checking :return: None :raise: DbException if project not found - ValidationError if quota exceeded and not overridden + ValidationError if quota exceeded in one of the projects """ - if session["force"] or session["admin"]: + if session["force"]: return projects = session["project_id"] for project in projects: proj = self.auth.get_project(project) pid = proj["_id"] - quota = proj.get("quotas", {}).get(self.topic, self.default_quota) + quota_name = self.quota_name or self.topic + quota = proj.get("quotas", {}).get(quota_name, self.default_quota) count = self.db.count(self.topic, {"_admin.projects_read": pid}) if count >= quota: name = proj["name"] - raise ValidationError("{} quota ({}) exceeded for project {} ({})".format(self.topic, quota, name, pid)) + raise ValidationError("quota ({}={}) exceeded for project {} ({})".format(quota_name, quota, name, pid), + http_code=HTTPStatus.UNAUTHORIZED) def _validate_input_new(self, input, force=False): """ @@ -322,12 +325,23 @@ class BaseTopic: update_content = update_content[kitem_old] if isinstance(update_content, dict): kitem_old = kitem + if not isinstance(update_content.get(kitem_old), (dict, list)): + update_content[kitem_old] = {} elif isinstance(update_content, list): + # key must be an index of the list, must be integer kitem_old = int(kitem) + # if index greater than list, extend the list + if kitem_old >= len(update_content): + update_content += [None] * (kitem_old - len(update_content) + 1) + if not isinstance(update_content[kitem_old], (dict, list)): + update_content[kitem_old] = {} else: raise EngineException( "Invalid query string '{}'. Descriptor is not a list nor dict at '{}'".format(k, kitem)) - update_content[kitem_old] = v if not yaml_format else safe_load(v) + if v is None: + del update_content[kitem_old] + else: + update_content[kitem_old] = v if not yaml_format else safe_load(v) except KeyError: raise EngineException( "Invalid query string '{}'. Descriptor does not contain '{}'".format(k, kitem_old)) @@ -483,14 +497,14 @@ class BaseTopic: # remove reference from project_read if there are more projects referencing it. If it last one, # do not remove reference, but delete other_projects_referencing = next((p for p in item_content["_admin"]["projects_read"] - if p not in session["project_id"]), None) + if p not in session["project_id"] and p != "ANY"), None) # check if there are projects referencing it (apart from ANY, that means, public).... if other_projects_referencing: # remove references but not delete - update_dict_pull = {"_admin.projects_read.{}".format(p): None for p in session["project_id"]} - update_dict_pull.update({"_admin.projects_write.{}".format(p): None for p in session["project_id"]}) - self.db.set_one(self.topic, filter_q, update_dict=None, pull=update_dict_pull) + update_dict_pull = {"_admin.projects_read": session["project_id"], + "_admin.projects_write": session["project_id"]} + self.db.set_one(self.topic, filter_q, update_dict=None, pull_list=update_dict_pull) return None else: can_write = next((p for p in item_content["_admin"]["projects_write"] if p == "ANY" or