def check_stat(**args): stats = args['stat_keys'].split('+') view = 'dist' if stats[0] in DIST_STATS else 'num' fmt = filter.xform(stats[0]) if not hasattr(args['userdata'], stats[0]): e = NotFound() e.type = 'stat' e.msg = 'err_invalid_statistics_name' raise e subtitle = ', '.join(map(filter.msg, stats)) return dict(stats=stats, stat_view=view, xfmt=fmt, subtitle=subtitle)
def check_user(**args): if not g.username: user = None g.userdata = None return try: user = database.User.by(alias=g.username) g.userdata = user.userdata(date=g.date) except: user = None g.userdata = None if user is None: error = NotFound() error.type = 'user' error.msg = 'err_url_invalid_username' raise error elif user.userdata_pool.count() == 0: error = InternalServerError error.type = 'user' if not user.raw_main: error.msg = 'err_data_not_collected' elif u'現在システムエラーが発生しております' in user.raw_main: error.msg = 'err_eamusement_system' elif u'プレーヤーデータを公開していません' in user.raw_main: error.msg = 'err_eamusement_nonpublic' else: error.msg = 'err_unknown' raise error return dict(user=user, userdata=g.userdata)
def enroll(): g.info_ver = request.args.get('ver') if not g.info_ver in modules().keys(): flask.abort(404) username = request.args.get('alias') friend_id = request.args.get('friend_id') if not username or not friend_id: error = NotFound() error.type = 'enroll' error.msg = 'err_no_alias' if not username else\ 'err_enroll_friend_id' raise error url = url_for(g.info_ver + '.enroll', username=username, friend_id=friend_id) return redirect(url)
def check_tune(**args): mkey, dkey = args['music_key'], args['dif_key'] if dkey.isnumeric(): dif_id = int(dkey) else: try: dif_id = DIF_TRANS[dkey.lower()] except KeyError: error = NotFound() error.type = 'dif' error.msg = 'err_url_invalid_dif' raise error try: music_id = int(mkey) music = database.Music.by(music_id=music_id) except ValueError: music = database.Music.by_keyword(mkey, g.lang) if music is None: error = NotFound() error.type = 'music' error.msg = 'err_url_invalid_music' raise error subtitle = music.title l10n = music.localization(g.lang) if l10n: subtitle += ' (%s)' % l10n.text subtitle += ' ' + const.DIFFICULTY_NAMES2[dif_id] return dict(music=music, dif_id=dif_id, subtitle=subtitle)
def item_handler(self, request, uid): item = self.data_map.get(uid, None) if item is None: raise NotFound() return self.render_json(item)
def view404(): raise NotFound('not found')
def _process_args(self): self.event = Event.get(int(request.view_args['confId'])) if self.event is None: raise NotFound(_('An event with this ID does not exist.')) elif self.event.is_deleted: raise NotFound(_('This event has been deleted.'))
def get_relationship(db: PartitionedDatabase, model_id_or_name: str, relationship_id: ModelRelationshipId) -> JsonDict: relationship = db.get_model_relationship(relationship_id) if relationship is None: raise NotFound(f"Could not get model relationship [{relationship_id}]") return relationship.to_dict()
def url_mapper(self, path): try: path = path[1:].split('/') return self.routes[path[0]] except StandardError: raise NotFound()
def profile(viewcode): """Patron Profile Page.""" tab = request.args.get('tab', 'loans') allowed_tabs = [ 'loans', 'requests', 'fees', 'history', 'ill_request', 'personal' ] if tab not in allowed_tabs: abort(400) patron = Patron.get_patron_by_user(current_user) if patron is None: raise NotFound() if not patron.is_patron: abort(403) if request.method == 'POST': loan = Loan.get_record_by_pid(request.values.get('loan_pid')) item = Item.get_record_by_pid(loan.get('item_pid', {}).get('value')) if request.form.get('type') == 'cancel': tab = 'requests' cancel_params = { 'pid': loan.pid, 'transaction_location_pid': item.location_pid, 'transaction_user_pid': patron.pid } try: item.cancel_item_request(**cancel_params) flash( _('The request for item %(item_id)s has been canceled.', item_id=item.pid), 'success') except Exception: flash( _('Error during the cancellation of the request of \ item %(item_id)s.', item_id=item.pid), 'danger') elif request.form.get('type') == 'renew': data = { 'item_pid': item.pid, 'pid': request.values.get('loan_pid'), 'transaction_location_pid': item.location_pid, 'transaction_user_pid': patron.pid } try: item.extend_loan(**data) flash( _('The item %(item_id)s has been renewed.', item_id=item.pid), 'success') except Exception: flash( _('Error during the renewal of the item %(item_id)s.', item_id=item.pid), 'danger') return redirect( url_for('patrons.profile', viewcode=viewcode) + '?tab={0}'.format(tab)) loans, requests, fees, history, ill_requests = patron_profile(patron) # patron messages list messages = patron.get_circulation_messages(True) if patron.get_pending_subscriptions(): messages.append({ 'type': 'warning', 'content': _('You have a pending subscription fee.') }) bootstrap_alert_mapping = {'error': 'danger'} for message in messages: msg_type = message['type'] message['type'] = bootstrap_alert_mapping.get(msg_type, msg_type) return render_template('rero_ils/patron_profile.html', record=patron, loans=loans, requests=requests, fees=fees, history=history, ill_requests=ill_requests, messages=messages, viewcode=viewcode, tab=tab)
def get(self, host_uuid): for host in consts.HOSTS["hosts"]: if host["uuid"] == host_uuid: return jsonify(host) raise NotFound("%s not found" % host_uuid)
def portal_my_lead(self, lead, **kw): if lead.type != 'lead': raise NotFound() return request.render("website_crm_partner_assign.portal_my_lead", {'lead': lead})
def _checkParams(self): RHUserBase._checkParams(self) self.identity = Identity.get_one(request.view_args['identity']) if self.identity.user != self.user: raise NotFound()
def api_token(token_id): """ Manipulate a token. GET: Gets the current token data. Return: Object of {id, active, identity} POST: Change one or more of the token's data fields. The id cannot be set, but it can be forced to change, sending any value other than the current id, including null. Return: See GET. Error: If new identity would be a duplicate: 409 "Conflict" DELETE: Delete the token and all links owned by it. *Active session is required.* Returns: True PUT: Make new links owned by this token. Input: Array of strings (URLs) Return: Array of URL ids If a URL is invalid, the returned id will be null. """ token = Token.query.get(token_id) if token is None: raise NotFound('Token not found.') if request.method == 'POST': data = request.get_json() if data is None: raise BadRequest if 'active' in data and token.active != data['active']: token.active = data['active'] if 'identity' in data and token.identity != data['identity']: if Token.query.filter_by(owner=current_user, identity=data['identity']).limit(1).first(): raise Conflict('This identity already exists.') token.identity = data['identity'] if 'id' in data and token.id != data['id']: token.generate_id() db.session.add(token) db.session.commit() elif request.method == 'DELETE': if current_user.is_anonymous: raise Forbidden token.delete() return jsonify(True) elif request.method == 'PUT': data = request.get_json() links = [] for url in data: try: link = Link(token, url) links.append(link.id) db.session.add(link) except: links.append(None) db.session.commit() return jsonify(links) return jsonify({ 'id': token.id, 'active': token.active, 'identity': token.identity, })
def other_profile(user): user = User.query.get(user) if not user: raise NotFound('User not found.') return render_template('profile.html', user=user)
def _get_as_sudo_from_request_or_raise(self, request, channel_id): channel_partner = self._get_as_sudo_from_request(request=request, channel_id=channel_id) if not channel_partner: raise NotFound() return channel_partner
def get_observation_score(): """ .. :quickref: Profiles; Check an observation with the related profile Return alert when the observation do not match the profile """ data = request.get_json() try: cd_ref = data["cd_ref"] except KeyError: raise BadRequest("No cd_ref provided") # Récupération du profil du cd_ref result = {} profile = (DB.session.query(VmValidProfiles).filter( VmValidProfiles.cd_ref == cd_ref).one_or_none()) if not profile: raise NotFound("No profile for this cd_ref") check_life_stage = profile.active_life_stage result = { "valid_distribution": True, "valid_altitude": True, "valid_phenology": True, "valid_life_stage": None, "life_stage_accepted": [], "errors": [], "profil": profile.as_dict(), "check_life_stage": check_life_stage } # Calcul de la période correspondant à la date if data.get("date_min") and data.get("date_max"): date_min = datetime.datetime.strptime(data["date_min"], "%Y-%m-%d") date_max = datetime.datetime.strptime(data["date_max"], "%Y-%m-%d") # Calcul du numéro du jour pour les dates min et max doy_min = date_min.timetuple().tm_yday doy_max = date_max.timetuple().tm_yday else: raise BadRequest("Missing date min or date max") # Récupération des altitudes if data.get("altitude_min") and data.get("altitude_max"): altitude_min = data["altitude_min"] altitude_max = data["altitude_max"] else: raise BadRequest('Missing altitude_min or altitude_max') # Check de la répartition if "geom" in data: query = DB.session.query( func.ST_Contains( func.ST_Transform(profile.valid_distribution, 4326), func.ST_SetSRID( func.ST_GeomFromGeoJSON(json.dumps(data["geom"])), 4326), )) check_geom = query.one_or_none() if not check_geom: result["valid_distribution"] = False result["errors"].append({ "type": "geometry", "value": "Erreur lors du calcul de la géométrie valide" }) if check_geom[0] is False: result["valid_distribution"] = False result["errors"].append({ "type": "geom", "value": f"Le taxon n'a jamais été observé dans cette zone géographique" }) else: result["valid_distribution"] = True # check de la periode q_pheno = DB.session.query( VmCorTaxonPhenology.id_nomenclature_life_stage).distinct() q_pheno = q_pheno.filter(VmCorTaxonPhenology.cd_ref == cd_ref) q_pheno = q_pheno.filter( VmCorTaxonPhenology.doy_min <= doy_min).filter( VmCorTaxonPhenology.doy_max >= doy_max) period_result = q_pheno.all() if len(period_result) == 0: result["valid_phenology"] = False result["errors"].append({ "type": "period", "value": "Le taxon n'a jamais été observé à cette periode" }) # check de l'altitude if altitude_max > profile.altitude_max or altitude_min < profile.altitude_min: result["valid_altitude"] = False result["errors"].append({ "type": "altitude", "value": f"Le taxon n'a jamais été observé à cette altitude ({altitude_min}-{altitude_max}m)" }) # check de l'altitude pour la période donnée if len(period_result) > 0: peridod_and_altitude = q_pheno.filter( VmCorTaxonPhenology.calculated_altitude_min <= altitude_min) peridod_and_altitude = peridod_and_altitude.filter( VmCorTaxonPhenology.calculated_altitude_max >= altitude_max) peridod_and_altitude_r = peridod_and_altitude.all() if len(peridod_and_altitude_r) > 0: result["valid_altitude"] = True result["valid_phenology"] = True for row in peridod_and_altitude_r: # Construction de la liste des stade de vie potentielle if row.id_nomenclature_life_stage: result["life_stage_accepted"].append( row.id_nomenclature_life_stage) else: result["valid_altitude"] = False result["valid_phenology"] = False if altitude_max <= profile.altitude_max and altitude_min >= altitude_min: result["errors"].append({ "type": "period", "value": f"Le taxon a déjà été observé à cette altitude ({altitude_min}-{altitude_max}m), mais pas à cette periode de l'année" }) if result["valid_phenology"]: result["errors"].append({ "type": "period", "value": f"Le taxon a déjà été observé à cette periode de l'année, mais pas à cette altitude ({altitude_min}-{altitude_max}m)" }) # check du stade de vie pour la periode donnée if check_life_stage and "life_stages" in data: if type(data["life_stages"]) is not list: raise BadRequest("life_stages must be a list") for life_stage in data["life_stages"]: life_stage_value = TNomenclatures.query.get(life_stage) q = q_pheno.filter(VmCorTaxonPhenology. id_nomenclature_life_stage == life_stage) r_life_stage = q.all() if len(r_life_stage) == 0: result["valid_life_stage"] = False result["valid_phenology"] = False result["errors"].append({ "type": "life_stage", "value": f"Le taxon n'a jamais été observé à cette periode pour le stade de vie {life_stage_value.label_default}" }) # check du stade de vie pour la période et l'altitude else: if altitude_min and altitude_max: q = q.filter(VmCorTaxonPhenology. calculated_altitude_min <= altitude_min) q = q.filter(VmCorTaxonPhenology. calculated_altitude_max >= altitude_max) r_life_stage_altitude = q.all() if len(r_life_stage_altitude) == 0: result["valid_life_stage"] = False result["valid_altitude"] = False result["valid_phenology"] = False result["errors"].append({ "type": "life_stage", "value": f""" Le taxon n'a jamais été observé à cette periode et à cette altitude ({altitude_min}-{altitude_max}m) pour le stade de vie {life_stage_value.label_default}""" }) return result
def ensure_enabled(self) -> None: if not self.is_enabled(): raise NotFound()
def put(self, type, identifier): """ --- summary: Add object tag description: | Add new tag to an object. Requires `adding_tags` capability. security: - bearerAuth: [] tags: - tag parameters: - in: path name: type schema: type: string enum: [file, config, blob, object] description: Type of target object - in: path name: identifier schema: type: string description: Object identifier requestBody: description: Tag value content: application/json: schema: TagRequestSchema responses: 200: description: When tag is successfully added content: application/json: schema: type: array items: $ref: '#/components/schemas/TagItemResponse' 400: description: When tag is invalid 403: description: When user doesn't have `adding_tags` capability. 404: description: | When object doesn't exist or user doesn't have access to this object. """ schema = TagRequestSchema() obj = loads_schema(request.get_data(as_text=True), schema) db_object = access_object(type, identifier) if db_object is None: raise NotFound("Object not found") tag_name = obj["tag"] db_object.add_tag(tag_name) logger.info("Tag added", extra={"tag": tag_name, "dhash": db_object.dhash}) db.session.refresh(db_object) schema = TagItemResponseSchema(many=True) return schema.dump(db_object.tags)
def f(_): time.sleep(delay) # Raise exception so that we proceed to the next middleware raise NotFound()
def delete(self, type, identifier): """ --- summary: Delete object tag description: | Removes tag from object. Requires `removing_tags` capability. security: - bearerAuth: [] tags: - tag parameters: - in: path name: type schema: type: string enum: [file, config, blob, object] description: Type of object - in: path name: identifier schema: type: string description: Object identifier - in: query name: tag schema: type: string description: Tag to be deleted required: true responses: 200: description: When tag is successfully removed content: application/json: schema: type: array items: $ref: '#/components/schemas/TagItemResponse' 400: description: When tag is invalid 403: description: When user doesn't have `removing_tags` capability. 404: description: | When object doesn't exist or user doesn't have access to this object. """ schema = TagRequestSchema() obj = load_schema(request.args, schema) db_object = access_object(type, identifier) if db_object is None: raise NotFound("Object not found") tag_name = obj["tag"] db_object.remove_tag(tag_name) logger.info("Tag removed", extra={"tag": tag_name, "dhash": db_object.dhash}) db.session.refresh(db_object) schema = TagItemResponseSchema(many=True) return schema.dump(db_object.tags)
def is_whitelisted(self, method): fn = getattr(self, method, None) if not fn: raise NotFound("Method {0} not found".format(method)) elif not getattr(fn, "whitelisted", False): raise Forbidden("Method {0} not whitelisted".format(method))
def _process(self): if not self.contrib.is_scheduled: raise NotFound('This contribution is not scheduled') return send_file('contribution.ics', get_contribution_ical_file(self.contrib), 'text/calendar')
def delete(self, type, identifier): """ --- summary: Delete object attribute description: | Deletes attribute from specified object. User must have `removing_attributes` capability. security: - bearerAuth: [] tags: - attribute parameters: - in: path name: type schema: type: string enum: [file, config, blob, object] description: Type of object - in: path name: identifier schema: type: string description: Object identifier - in: query name: key schema: type: string description: Key of attribute object to be deleted required: true - in: query name: value schema: type: string description: Value of attribute key object to be deleted required: true responses: 200: description: When metakey was deleted successfully 404: description: | When object doesn't exist or user doesn't have access to this object. When attribute key is not defined or user doesn't have privileges to set that one. """ schema = MetakeyItemRequestSchema() obj = load_schema(request.args, schema) db_object = access_object(type, identifier) if db_object is None: raise NotFound("Object not found") key = obj["key"] value = obj["value"] deleted_object = db_object.remove_metakey(key, value) if deleted_object is False: raise NotFound(f"Metakey '{key}' is not defined or you have " f"insufficient permissions to delete it") db.session.commit()
def get(self, host_uuid): if consts.USE_STATIC == True: return jsonify(consts.COMPONENTS) try: for host in consts.HOSTS["hosts"]: if host["uuid"] == host_uuid: bmc_ip = host["ipmi_ip"] cred_url = "http://localhost:8005/credentials" response = requests.get(cred_url) creds = response.json()["credentials"] for cred in creds: if cred["bmc_ip"] == bmc_ip: username = cred["username"] password = cred["password"] bmc_info = bmc.get_info(ipmi_ip=bmc_ip, userid=username, pswd=password) bmc_list = [] for bmc_i in bmc_info: bmc_list.append({ "version": bmc_i["Version"], "model": bmc_i["Model"], "health": bmc_i["Status"]["Health"], "state": bmc_i["Status"]["State"] }) log.info(bmc_list) bios_info = bios.get_info(ipmi_ip=bmc_ip, userid=username, pswd=password) bios_list = [] for bios_i in bios_info: bios_list.append({ "version": bios_i["Version"], "model": bios_i["Model"], "serial": bios_i["SerialNumber"], "manufacturer": bios_i["Manufacturer"] }) cpu_info = cpu.get_info(ipmi_ip=bmc_ip, userid=username, pswd=password) cpu_list = [] for cpu_i in cpu_info: cpu_list.append({ "manufacturer": cpu_i["Manufacturer"], "name": cpu_i["Name"].split()[0], "model": cpu_i["Model"], "cores": cpu_i["TotalCores"], "threads": cpu_i["TotalThreads"], "temperature": cpu_i["ReadingCelsius"], "health": cpu_i["Status"]["Health"], "state": cpu_i["Status"]["State"] }) fan_info = fan.get_info(ipmi_ip=bmc_ip, userid=username, pswd=password) fan_list = [] for fan_i in fan_info: fan_list.append({ "name": fan_i["Name"], "rpm": fan_i["Reading"], "health": fan_i["Status"]["Health"], "state": fan_i["Status"]["State"] }) return jsonify({ "components": { "fan": fan_list, "cpu": cpu_list, "bmc": bmc_list, "bios": bios_list } }) raise NotFound("Credentials not found for %s" % bmc_ip) raise NotFound("%s not found" % host_uuid) except Exception as ex: log.error(str(traceback.format_exc())) return {"error": str(traceback.format_exc())}
def redirect_to_entity(review_id, revision_id): try: revision_number = db_revision.get_revision_number(review_id, revision_id) except db_exceptions.NoDataFoundException: raise NotFound(gettext("The revision you are looking for does not exist.")) return redirect(url_for('.entity', id=review_id, rev=revision_number))
def normalize_url(self): """Perform URL normalization. This uses the :attr:`normalize_url_spec` to check if the URL params are what they should be and redirects or fails depending on the HTTP method used if it's not the case. :return: ``None`` or a redirect response """ if current_app.debug and self.normalize_url_spec is RH.normalize_url_spec: # in case of ``class SomeRH(RH, MixinWithNormalization)`` # the default value from `RH` overwrites the normalization # rule from ``MixinWithNormalization``. this is never what # the developer wants so we fail if it happens. the proper # solution is ``class SomeRH(MixinWithNormalization, RH)`` cls = next((x for x in inspect.getmro(self.__class__) if (x is not RH and x is not self.__class__ and hasattr(x, 'normalize_url_spec') and getattr(x, 'normalize_url_spec', None) is not RH.normalize_url_spec)), None) if cls is not None: raise Exception( 'Normalization rule of {} in {} is overwritten by base RH. Put mixins with class-level ' 'attributes on the left of the base class'.format( cls, self.__class__)) if not self.normalize_url_spec or not any( self.normalize_url_spec.itervalues()): return spec = { 'args': self.normalize_url_spec.get('args', {}), 'locators': self.normalize_url_spec.get('locators', set()), 'preserved_args': self.normalize_url_spec.get('preserved_args', set()), 'endpoint': self.normalize_url_spec.get('endpoint', None) } # Initialize the new view args with preserved arguments (since those would be lost otherwise) new_view_args = { k: v for k, v in request.view_args.iteritems() if k in spec['preserved_args'] } # Retrieve the expected values for all simple arguments (if they are currently present) for key, getter in spec['args'].iteritems(): if key in request.view_args: new_view_args[key] = getter(self) # Retrieve the expected values from locators prev_locator_args = {} for getter in spec['locators']: value = getter(self) if value is None: raise NotFound( 'The URL contains invalid data. Please go to the previous page and refresh it.' ) locator_args = get_locator(value) reused_keys = set(locator_args) & prev_locator_args.viewkeys() if any(locator_args[k] != prev_locator_args[k] for k in reused_keys): raise NotFound( 'The URL contains invalid data. Please go to the previous page and refresh it.' ) new_view_args.update(locator_args) prev_locator_args.update(locator_args) # Get all default values provided by the url map for the endpoint defaults = set( itertools.chain.from_iterable( r.defaults for r in current_app.url_map.iter_rules(request.endpoint) if r.defaults)) def _convert(v): # some legacy code has numeric ids in the locator data, but still takes # string ids in the url rule (usually for confId) return unicode(v) if isinstance(v, (int, long)) else v provided = { k: _convert(v) for k, v in request.view_args.iteritems() if k not in defaults } new_view_args = { k: _convert(v) for k, v in new_view_args.iteritems() if v is not None } if new_view_args != provided: if request.method in {'GET', 'HEAD'}: endpoint = spec['endpoint'] or request.endpoint try: return redirect( url_for( endpoint, **dict(request.args.to_dict(), **new_view_args))) except BuildError as e: if current_app.debug: raise logger.warn('BuildError during normalization: %s', e) raise NotFound else: raise NotFound( 'The URL contains invalid data. Please go to the previous page and refresh it.' )
def _validate_update(self, session, obj, existing_obj): # pylint: disable=unused-argument """Participant summaries don't have a version value; drop it from validation logic.""" if not existing_obj: raise NotFound('%s with id %s does not exist' % (self.model_type.__name__, id))
def shop(self, page=0, category=None, search='', ppg=False, **post): if ppg: try: ppg = int(ppg) except ValueError: ppg = PPG post["ppg"] = ppg else: ppg = PPG if category: category = request.env['product.public.category'].search([('id', '=', int(category))], limit=1) if not category: raise NotFound() attrib_list = request.httprequest.args.getlist('attrib') attrib_values = [[int(x) for x in v.split("-")] for v in attrib_list if v] attributes_ids = {v[0] for v in attrib_values} attrib_set = {v[1] for v in attrib_values} domain = self._get_search_domain(search, category, attrib_values) keep = QueryURL('/shop', category=category and int(category), search=search, attrib=attrib_list, order=post.get('order')) compute_currency, pricelist_context, pricelist = self._get_compute_currency_and_context() request.context = dict(request.context, pricelist=pricelist.id, partner=request.env.user.partner_id) url = "/shop" if search: post["search"] = search if attrib_list: post['attrib'] = attrib_list categs = request.env['product.public.category'].search([('parent_id', '=', False)]) Product = request.env['product.template'] parent_category_ids = [] if category: url = "/shop/category/%s" % slug(category) parent_category_ids = [category.id] current_category = category while current_category.parent_id: parent_category_ids.append(current_category.parent_id.id) current_category = current_category.parent_id product_count = Product.search_count(domain) pager = request.website.pager(url=url, total=product_count, page=page, step=ppg, scope=7, url_args=post) products = Product.search(domain, limit=ppg, offset=pager['offset'], order=self._get_search_order(post)) ProductAttribute = request.env['product.attribute'] if products: # get all products without limit selected_products = Product.search(domain, limit=False) attributes = ProductAttribute.search([('attribute_line_ids.product_tmpl_id', 'in', selected_products.ids)]) else: attributes = ProductAttribute.browse(attributes_ids) values = { 'search': search, 'category': category, 'attrib_values': attrib_values, 'attrib_set': attrib_set, 'pager': pager, 'pricelist': pricelist, 'products': products, 'search_count': product_count, # common for all searchbox 'bins': TableCompute().process(products, ppg), 'rows': PPR, 'categories': categs, 'attributes': attributes, 'compute_currency': compute_currency, 'keep': keep, 'parent_category_ids': parent_category_ids, } if category: values['main_object'] = category return request.render("website_sale.products", values)
def handle_request(self, request): raise NotFound()
def put(self, key, group_name): """ --- summary: Add/modify attribute key permission description: | Adds or modifies attribute key group permission for specified key and group name. Requires `managing_attributes` capability. security: - bearerAuth: [] tags: - attribute parameters: - in: path name: key schema: type: string description: Attribute key - in: path name: group_name schema: type: string description: Group name to add/modify requestBody: description: Attribute key permission definition content: application/json: schema: MetakeyPermissionSetRequestBodySchema responses: 200: description: When group permission has been successfully changed content: application/json: schema: MetakeyDefinitionManageItemResponseSchema 400: description: | When one of attribute permission fields is missing or incorrect. 403: description: When user doesn't have `managing_attributes` capability. 404: description: When attribute key or group doesn't exist """ schema = MetakeyPermissionSetRequestArgsSchema() args_obj = load_schema({"key": key, "group_name": group_name}, schema) schema = MetakeyPermissionSetRequestBodySchema() obj = loads_schema(request.get_data(as_text=True), schema) metakey_definition = (db.session.query(MetakeyDefinition).filter( MetakeyDefinition.key == args_obj["key"]).first()) if metakey_definition is None: raise NotFound("No such metakey") group = (db.session.query(Group).filter( Group.name == args_obj["group_name"]).first()) if group is None: raise NotFound("No such group") permission = MetakeyPermission( key=args_obj["key"], group_id=group.id, can_read=obj["can_read"], can_set=obj["can_set"], ) db.session.merge(permission) db.session.commit() db.session.refresh(metakey_definition) schema = MetakeyDefinitionManageItemResponseSchema() return schema.dump(metakey_definition)
def _message_post_helper(res_model, res_id, message, token='', _hash=False, pid=False, nosubscribe=True, **kw): """ Generic chatter function, allowing to write on *any* object that inherits mail.thread. We distinguish 2 cases: 1/ If a token is specified, all logged in users will be able to write a message regardless of access rights; if the user is the public user, the message will be posted under the name of the partner_id of the object (or the public user if there is no partner_id on the object). 2/ If a signed token is specified (`hash`) and also a partner_id (`pid`), all post message will be done under the name of the partner_id (as it is signed). This should be used to avoid leaking token to all users. Required parameters :param string res_model: model name of the object :param int res_id: id of the object :param string message: content of the message Optional keywords arguments: :param string token: access token if the object's model uses some kind of public access using tokens (usually a uuid4) to bypass access rules :param string hash: signed token by a partner if model uses some token field to bypass access right post messages. :param string pid: identifier of the res.partner used to sign the hash :param bool nosubscribe: set False if you want the partner to be set as follower of the object when posting (default to True) The rest of the kwargs are passed on to message_post() """ record = request.env[res_model].browse(res_id) # check if user can post with special token/signed token. The "else" will try to post message with the # current user access rights (_mail_post_access use case). if token or (_hash and pid): pid = int(pid) if pid else False if _check_special_access(res_model, res_id, token=token, _hash=_hash, pid=pid): record = record.sudo() else: raise Forbidden() # deduce author of message author_id = request.env.user.partner_id.id if request.env.user.partner_id else False # Token Case: author is document customer (if not logged) or itself even if user has not the access if token: if request.env.user._is_public(): # TODO : After adding the pid and sign_token in access_url when send invoice by email, remove this line # TODO : Author must be Public User (to rename to 'Anonymous') author_id = record.partner_id.id if hasattr(record, 'partner_id') and record.partner_id.id else author_id else: if not author_id: raise NotFound() # Signed Token Case: author_id is forced elif _hash and pid: author_id = pid email_from = None if author_id and 'email_from' not in kw: partner = request.env['res.partner'].sudo().browse(author_id) email_from = partner.email_formatted if partner.email else None message_post_args = dict( body=message, message_type=kw.pop('message_type', "comment"), subtype_xmlid=kw.pop('subtype_xmlid', "mail.mt_comment"), author_id=author_id, **kw ) # This is necessary as mail.message checks the presence # of the key to compute its default email from if email_from: message_post_args['email_from'] = email_from return record.with_context(mail_create_nosubscribe=nosubscribe).message_post(**message_post_args)
def post(self, type, identifier): """ --- summary: Add object attribute description: | Adds attribute to specified object. User must have `set` access to the attribute key or `adding_all_attributes` capability. security: - bearerAuth: [] tags: - attribute parameters: - in: path name: type schema: type: string enum: [file, config, blob, object] description: Type of object - in: path name: identifier schema: type: string description: Object identifier requestBody: description: Attribute key and value content: application/json: schema: MetakeyItemRequestSchema responses: 200: description: When metakey was added successfully content: application/json: schema: MetakeyListResponseSchema 404: description: | When object doesn't exist or user doesn't have access to this object. When attribute key is not defined or user doesn't have privileges to set that one. """ schema = MetakeyItemRequestSchema() obj = loads_schema(request.get_data(as_text=True), schema) db_object = access_object(type, identifier) if db_object is None: raise NotFound("Object not found") key = obj["key"] value = obj["value"] is_new = db_object.add_metakey(key, value) if is_new is None: raise NotFound(f"Metakey '{key}' is not defined or you have " f"insufficient permissions to set it") db.session.commit() db.session.refresh(db_object) metakeys = db_object.get_metakeys() schema = MetakeyListResponseSchema() return schema.dump({"metakeys": metakeys})
def get_metadata_list(train_ids, tag): raise NotFound("%s" % text)