def whoami_keycloak(self): """To use with the demo_keycloak validator. You can play with this using the browser app in tests/spa and the identity provider in tests/keycloak. """ data = {} if request.jwt_partner_id: partner = request.env["res.partner"].browse(request.jwt_partner_id) data.update(name=partner.name, email=partner.email) return Response(json.dumps(data), content_type="application/json", status=200)
def _json_response(self, result=None, error=None): response = {'jsonrpc': '2.0', 'id': self.jsonrequest.get('id')} # 修复钉钉注册回调事件时报错 if isinstance(result, dict) and result is not None and result.get('json'): mime = 'application/json' body = json.dumps(result.get('data')) return Response(body, status=200, headers=[('Content-Type', mime), ('Content-Length', len(body))]) if error is not None: response['error'] = error if result is not None: response['result'] = result mime = 'application/json' body = json.dumps(response, default=date_utils.json_default) return Response(body, status=error and error.pop('http_status', 200) or 200, headers=[('Content-Type', mime), ('Content-Length', len(body))])
def database_list(self, **kw): databases = [] incompatible_databases = [] try: databases = http.db_list() incompatible_databases = service.db.list_db_incompatible(databases) except AccessDenied: monodb = http.db_monodb() if monodb: databases = [monodb] result = {'databases': databases, 'incompatible_databases': incompatible_databases} content = json.dumps(result, sort_keys=True, indent=4, cls=ResponseEncoder) return Response(content, content_type='application/json;charset=utf-8', status=200)
def product_list(self): products = request.env['product.template'].sudo().search([]) rows = [] for p in products: data = { 'code': p.default_code, 'name': p.name, 'barcode': p.barcode, 'sale_price': p.list_price, 'cost_price': p.standard_price, } rows.append(data) return Response(json.dumps({'ok': True, 'rows': rows}), content_type='application/json')
def _get_jobs(self, **kw): domain = [('active', '=', True)] env = api.Environment(request.cr, SUPERUSER_ID, request.context) if 'limit' in kw.keys(): limit = int(kw['limit']) else: limit = DEFAULT_LIMIT jobs = env['controller.job'].search(domain, limit=limit) if not jobs: body = json.dumps({'msg': "Job not existed"}) headers = [('Content-Type', 'application/json'), ('Content-Length', len(body))] return Response(body, status=404, headers=headers) vals = [{ 'name': job.name, 'code': job.code, } for job in jobs] body = json.dumps(vals) return Response(body, headers=[('Content-Type', 'application/json'), ('Content-Length', len(body))], status=200)
def metadata(self, model, ids, context=None, **kw): ctx = request.session.context.copy() ctx.update(context and parse_value(context) or {}) ids = ids and parse_value(ids) or [] records = request.env[model].with_context(ctx).browse(ids) result = records.get_metadata() content = json.dumps(result, sort_keys=True, indent=4, cls=ResponseEncoder) return Response(content, content_type='application/json;charset=utf-8', status=200)
def test_mfa_login_post_firefox_response_returned(self, val_mock, gen_mock, redirect_mock, request_mock): '''Should behave well if redirect returns Response (Firefox case)''' request_mock.env = self.env request_mock.db = self.registry.db_name redirect_mock.return_value = Response('Test Response') test_token = self.test_user.mfa_login_token request_mock.params = {'mfa_login_token': test_token} val_mock.return_value = True test_result = self.test_controller.mfa_login_post() self.assertIn('Test Response', test_result.response)
def _json_response(self, result=None, error=None): response = {} if error is not None: response['error'] = error if result is not None: response['result'] = result mime = 'application/json' body = json.dumps(response) return Response(body, headers=[('Content-Type', mime), ('Content-Length', len(body))])
def create(self, model, values=None, context=None, **kw): ctx = request.session.context.copy() ctx.update(context and parse_value(context) or {}) values = values and parse_value(values) or {} model = request.env[model].with_context(ctx) result = model.create(values).ids content = json.dumps(result, sort_keys=True, indent=4, cls=ResponseEncoder) return Response(content, content_type='application/json;charset=utf-8', status=200)
def get_events(self, **kw): query = """ select ee.id, ee.state, ee.name, ee.date_begin, ee.date_end, ee.organizer_id, rp.name organizer_name, rp.street, rp.zip, rp.city, st.name statename, coalesce(rp.partner_current_latitude, 0) partner_current_latitude, coalesce(rp.partner_current_longitude, 0) partner_current_longitude from event_event ee, res_partner rp left join res_country_state st on (st.id = rp.state_id) where rp.id = ee.address_id and ee.state = 'confirm' """ eventsJson = [] request.env.cr.execute(query) events = request.env.cr.fetchall() for event in events: event_event = request.env['event.event'].search([('id', '=', event[0])]) eventsJson.append({ 'id': event[0], 'state': event[1], 'name': event[2], 'date_begin': str(event[3]), 'date_end': str(event[4]), 'organizer_id': event[5], 'organizer_name': event[6], 'street': event[7], 'zip': event[8], 'city': event[9], 'statename': event[10], 'partner_current_latitude': event[11], 'partner_current_longitude': event[12], 'website_url': event_event.website_url }) data = {'status': 200, 'response': eventsJson} return Response(json.dumps({'data': data}), status=200, content_type="application/json")
def create_temporary_login_data(self, db=None, ttl=DEFAULT_TIME_TO_LOGIN, user_uuid=None, user_id=None, **params): admin_access_credentials = config.get('admin_access_credentials', True) if not admin_access_credentials: _logger.warning("Attempt to get temporary login/password, " "but this operation is disabled in Odoo config") raise werkzeug.exceptions.Forbidden(description='Feature disabled') token = config.get(SAAS_TOKEN_FIELD, False) token_hash = hashlib.sha256(token.encode('utf8')).hexdigest() random_token = generate_random_password(DEFAULT_LEN_TOKEN) uri_token = '%s:%s:%s' % (db, random_token, token_hash) uri_token = base64.b64encode(uri_token.encode("utf-8")).decode() data = { 'token_user': str(uuid.uuid4()), 'token_password': str(uuid.uuid4()), 'temp_url': '/saas/client/auth/%s' % uri_token, 'expire': fields.Datetime.to_string(datetime.now() + timedelta(seconds=int(ttl))), 'token_temp': random_token, 'user_uuid': user_uuid, 'user_id': user_id if user_id else SUPERUSER_ID, } with registry(db).cursor() as cr: cr.execute( """ INSERT INTO odoo_infrastructure_client_auth (token_user, token_password, expire, token_temp, user_uuid, user_id) VALUES ( %(token_user)s, %(token_password)s, %(expire)s, %(token_temp)s, %(user_uuid)s, %(user_id)s ); """, data) return Response(json.dumps(data), status=200)
def access_fields(self, model, operation='read', fields=None, **kw): fields = fields and parse_value(fields) or None try: result = request.env[model].check_field_access_rights( operation, fields=fields) except (AccessError, UserError): result = False content = json.dumps(result, sort_keys=True, indent=4, cls=ResponseEncoder) return Response(content, content_type='application/json;charset=utf-8', status=200)
def access_rules(self, model, ids, operation='read', **kw): ids = ids and parse_value(ids) or [] try: result = request.env[model].browse(ids).check_access_rule( operation) is None except (AccessError, UserError): result = False content = json.dumps(result, sort_keys=True, indent=4, cls=ResponseEncoder) return Response(content, content_type='application/json;charset=utf-8', status=200)
def _bach_patch_user_archived(self): uuids = request.jsonrequest user_ids = request.env['res.users'].sudo().search([('uuid', 'in', uuids)]) if not user_ids: return Response(json.dumps({'msg': 'User not found'}), headers={'content-type': 'application/json'}, status=404) ret = user_ids.sudo().write({'active': False}) if not ret: return Response(json.dumps({'msg': 'Batch Archived fail'}), headers={'content-type': 'application/json'}, status=405) ret = user_ids.sudo().read(fields=NORMAL_USER_FIELDS_READ)[0] if 'active' in ret: ret.update({'status': 'active' if ret['active'] else 'archived'}) ret.pop('active') return Response(json.dumps(ret), headers={'content-type': 'application/json'}, status=200)
def search(self, model, domain=None, context=None, count=False, limit=80, offset=0, order=None, **kw): ctx = request.session.context.copy() ctx.update({'prefetch_fields': False}) ctx.update(context and parse_value(context) or {}) domain = domain and parse_value(domain) or [] count = count and misc.str2bool(count) or None limit = limit and int(limit) or None offset = offset and int(offset) or None model = request.env[model].with_context(ctx) result = model.search(domain, offset=offset, limit=limit, order=order, count=count) if not count: result = result.ids content = json.dumps(result, sort_keys=True, indent=4, cls=ResponseEncoder) return Response(content, content_type='application/json;charset=utf-8', status=200)
def setUp(self): super(TestWebsiteSaleSelectQty, self).setUp() self.test_controller = WebsiteSaleSelectQty() # Needed when tests are run with no prior requests (e.g. on install) base_request_patcher = patch('odoo.http.request') self.addCleanup(base_request_patcher.stop) base_request_patcher.start() super_patcher = patch(SUPER_PATH) self.addCleanup(super_patcher.stop) super_mock = super_patcher.start() super_mock.return_value = Response(qcontext={})
def get_variants(self, product_id, **kw): product_id = int(product_id) products = None total_valid =[] prod = request.env['product.template'].sudo().browse(product_id) not_id = prod.product_variant_ids.ids user_exists = request.env['quick.order'].search([('user_id', '=', request._uid),('state', '=', 'draft')]) if len(prod.product_variant_ids) == 1: if user_exists: products_exists = self.variants_availability() if prod.product_variant_ids.id not in products_exists: user_exists.quick_order_line = [(0, 0, {"product_id" : prod.product_variant_ids.id})] elif not user_exists: user_exists = request.env['quick.order'].create({ "quick_order_line": [(0, 0, {"product_id" : prod.product_variant_ids.id})] }) products = prod.product_variant_ids.ids return Response(request.env['ir.ui.view'].render_template('quick_order.add_to_cart_mutliple_body',{'order_quicks' : user_exists.quick_order_line, 'id':user_exists.id, 'compute_currency' : self.compute_currency, 'product_r': products}),content_type='text/html;charset=utf-8',status=211) if not prod.product_variant_ids: return Response({'error' : "No variants found"}, content_type='application/json',status=500) if user_exists: not_id = list(set(prod.product_variant_ids.filtered(lambda x: x.product_tmpl_id._is_combination_possible(x.product_template_attribute_value_ids)).ids)-set(self.variants_availability())) return request.render("quick_order.row_select_model", {"docs" : prod, "not_id" : not_id})
def database_backup(self, database_name, master_password="******", backup_format='zip', **kw): service.db.check_super(master_password) ts = datetime.datetime.utcnow().strftime("%Y-%m-%d_%H-%M-%S") filename = "%s_%s.%s" % (database_name, ts, backup_format) headers = [ ('Content-Type', 'application/octet-stream; charset=binary'), ('Content-Disposition', http.content_disposition(filename)), ] dump_stream = service.db.dump_db(database_name, None, backup_format) return Response(dump_stream, headers=headers, direct_passthrough=True)
def custom(self, context=None, **kw): endpoint = kw.get('custom', False) if endpoint and endpoint.exists(): ctx = request.session.context.copy() ctx.update(context and parse_value(context) or {}) result = endpoint.with_context(ctx).evaluate(request.params) content = json.dumps(result, sort_keys=True, indent=4, cls=RecordEncoder) return Response(content, content_type='application/json;charset=utf-8', status=200) return exceptions.NotFound()
def upload_extra_file(self, product_id='', doc_name='', doc_rev='0', related_attachment_id='', **kw): logging.info('Start upload extra file %r' % (product_id)) product_id = eval(product_id) doc_rev = eval(doc_rev) related_attachment_id = eval(related_attachment_id) if doc_name: value1 = kw.get('file_stream').stream.read() ir_attachment_id = request.env['ir.attachment'].search([('engineering_document_name', '=', doc_name), ('revisionid', '=', doc_rev)]) to_write = {'datas': base64.b64encode(value1), 'name': doc_name, 'engineering_document_name': doc_name, 'revisionid': ir_attachment_id.revisionid} link_id = request.env['ir.attachment.relation'] new_context = request.env.context.copy() new_context['backup'] = False new_context['check'] = False # Or zip file will not be updated if in check-in contex_brw = request.env['ir.attachment'].with_context(new_context) to_write['is_plm'] = True if not ir_attachment_id: ir_attachment_id = contex_brw.create(to_write) else: ir_attachment_id.with_context(new_context).write(to_write) if ir_attachment_id and related_attachment_id: link_id = link_id.search([('parent_id', '=', related_attachment_id), ('child_id', '=', ir_attachment_id.id), ('link_kind', '=', 'ExtraTree')]) if not link_id: request.env['ir.attachment.relation'].create({'parent_id': related_attachment_id, 'child_id': ir_attachment_id.id, 'link_kind': 'ExtraTree'}) if product_id: product_id = request.env['product.product'].browse(product_id) request.env['plm.component.document.rel'].createFromIds(product_id, ir_attachment_id) return Response('Extra file Upload succeeded', status=200) logging.info('Extra file no upload %r' % (ir_attachment_id)) return Response('Extra file Failed upload', status=400)
def _json_response(self, result=None, error=None): response = {} if error is not None: response['error'] = error mime = 'application/json' body = json.dumps(response, default=date_utils.json_default) status = error and error.pop('code') or result.status_code body = response and json.dumps(response) or result.data return Response(body, status=status, headers=[('Content-Type', mime), ('Content-Length', len(body))])
def transfer_cash(self, **post): account_transfer = request.env['account.money.transfer'] account_transfer_id = account_transfer.create({ 'name': post.get('note', False), 'date': post.get('date', False), 'source_journal_id': post.get('source_account', False), 'dest_journal_id': post.get('destination_account', False), 'amount': post.get('amount', False), }) return Response("success", status=200)
def content_common(self, xmlid=None, model='ir.attachment', id=None, field='datas', filename=None, filename_field='datas_fname', unique=None, mimetype=None, download=None, data=None, token=None, **kw): status, headers, content = binary_content( xmlid=xmlid, model=model, id=id, field=field, unique=unique, filename=filename, filename_field=filename_field, download=download, mimetype=mimetype) if status == 304: response = werkzeug.wrappers.Response(status=status, headers=headers) elif status == 301: return werkzeug.utils.redirect(content, code=301) # Add HTTP 206 Partial Content Header Support elif status == 206: if content: image_base64 = base64.b64decode(content) else: image_base64 = self.placeholder( image='placeholder.png' ) # could return (contenttype, content) in master headers = self.force_contenttype(headers, contenttype='image/png') response = Response(headers=headers, status=status) response.automatically_set_content_length = False response.set_data(image_base64) elif status != 200: response = request.not_found() else: content_base64 = base64.b64decode(content) headers.append(('Content-Length', len(content_base64))) response = request.make_response(content_base64, headers) if token: response.set_cookie('fileToken', token) return response
def modules(self): loadable = list(http.addons_manifest) env = api.Environment(http.request.cr, SUPERUSER_ID, {}) records = env['ir.module.module'].search([('state', '=', 'installed'), ('name', 'in', loadable)]) result = OrderedDict( (record.name, record.dependencies_id.mapped('name')) for record in records) content = json.dumps(topological_sort(result), sort_keys=True, indent=4, cls=ResponseEncoder) return Response(content, content_type='application/json;charset=utf-8', status=200)
def reports(self, name=None, model=None, **kw): domain = [] if name: domain.append(['name', 'ilike', name]) if model: domain.append(['model', '=', model]) result = request.env['ir.actions.report'].search_read( domain, ['name', 'model', 'report_name']) content = json.dumps(result, sort_keys=True, indent=4, cls=ResponseEncoder) return Response(content, content_type='application/json;charset=utf-8', status=200)
def evaluate(self, params): self.ensure_one() if self.state == 'domain': model = self.env[self.model.sudo().model] fields = self.domain_fields.mapped('name') or None domain = safe_eval(self.domain or "[]", self._get_eval_domain_context(self, params)) result = { 'endpoint': self.route, 'model': model._name, 'domain': domain, 'fields': self.domain_fields.mapped('name'), 'result': model.search_read(domain, fields=fields), } content = json.dumps(result, sort_keys=True, indent=4, cls=RecordEncoder) return Response(content, content_type='application/json;charset=utf-8', status=200) elif self.state == 'action': result = { 'endpoint': self.route, 'action': self.action.name, 'result': self.action.with_context(**self._get_eval_action_context(self, params)).run(), } content = json.dumps(result, sort_keys=True, indent=4, cls=RecordEncoder) return Response(content, content_type='application/json;charset=utf-8', status=200) elif self.state == 'code': content = _("No result was found for this endpoint!") context = self._get_eval_code_context(self, params) safe_eval(self.code.strip(), context, mode="exec", nocopy=True) if 'result' in context and context.get('result'): result = {'endpoint': self.route, 'result': context['result']} content = json.dumps(result, sort_keys=True, indent=4, cls=RecordEncoder) elif 'payload' in context and context.get('payload'): content = context['payload'] if 'headers' in context and context.get('headers'): return Response(content, headers=context['headers'], status=200) return Response(content, content_type='application/json;charset=utf-8', status=200) return Response(_("Invalid endpoint!"), content_type='application/json;charset=utf-8', status=200)
def authenticate(self, db=None, login=None, password=None, **kw): check_params({'db': db, 'login': login, 'password': password}) ensure_db() uid = request.session.authenticate(db, login, password) if uid: env = api.Environment(request.cr, odoo.SUPERUSER_ID, {}) token = env['muk_rest.token'].generate_token(uid) return Response(json.dumps({'token': token.token}, sort_keys=True, indent=4, cls=ObjectEncoder), content_type='application/json;charset=utf-8', status=200) else: abort(LOGIN_INVALID, status=401)
def _get_user_info(self, uuid): user_id = request.env['res.users'].sudo().search([('uuid', '=', uuid)], limit=1) if not user_id: return Response(json.dumps({'msg': 'User not found'}), headers={'content-type': 'application/json'}, status=404) ret = user_id.sudo().read(fields=NORMAL_USER_FIELDS_READ)[0] if 'active' in ret: ret.update({'status': 'active' if ret['active'] else 'archived'}) ret.pop('active') if 'image_small' in ret: ret.update({ 'image_small': u'data:{0};base64,{1}'.format('image/png', ret['image_small']) if ret['image_small'] else "" }) return Response(json.dumps(ret), headers={'content-type': 'application/json'}, status=200)
def _form_redirect(self, response): """ Utility for payment form that are called by AJAX and can send back a redirection. Instead of pushing back the redirection which will fail over HTTPS, we wrap it inside JSON respsonse and let the client perform the redirection. :return: Response """ if response.status_code == 303: # Prepend with lang, to avoid 302 redirection location = '/' + request.env.lang + response.location return Response(json.dumps({'redirect': location}), status=200, mimetype='application/json') return response
def add_expense(self, **post): """ Add new expense """ expense_summary = request.env['expense.summary'] expense_id = expense_summary.create({ 'name':post.get('name', False), 'date':post.get('date', False), 'exp_category_id':post.get('category', False), 'account_journal_id':post.get('account', False), 'amount':post.get('expense_amount', False), 'location':post.get('location', False), 'user_id': request.env.user.id or False }) return Response("success", status=200)