def client_db_restore(self, db=None, backup_file=None, copy=False, **params): if not db: raise werkzeug.exceptions.BadRequest("Database not specified") if service_db.exp_db_exist(db): raise werkzeug.exceptions.Conflict( description="Database %s already exists" % db) try: with tempfile.NamedTemporaryFile(delete=False) as data_file: backup_file.save(data_file) service_db.restore_db(db, data_file.name, str2bool(copy)) except exceptions.AccessDenied as e: raise werkzeug.exceptions.Forbidden(description=str(e)) except Exception as e: _logger.error("Cannot restore db %s", db, exc_info=True) raise werkzeug.exceptions.InternalServerError( "Cannot restore db (%s): %s" % (db, str(e))) else: self._postprocess_restored_db(db) return http.Response('OK', status=200) finally: os.unlink(data_file.name)
def read_group(self, model, domain, fields, groupby, context=None, offset=0, limit=None, orderby=False, lazy=True, **kw): ctx = request.session.context.copy() ctx.update(context and parse_value(context) or {}) domain = domain and parse_value(domain) or [] fields = fields and parse_value(fields) or [] groupby = groupby and parse_value(groupby) or [] limit = limit and int(limit) or None offset = offset and int(offset) or None lazy = misc.str2bool(lazy) model = request.env[model].with_context(ctx) result = model.read_group(domain, fields, groupby, offset=offset, limit=limit, orderby=orderby, lazy=lazy) content = json.dumps(result, sort_keys=True, indent=4, cls=ResponseEncoder) return Response(content, content_type='application/json;charset=utf-8', status=200)
def binary(self, xmlid=None, model='ir.attachment', id=None, field='datas', unique=None, filename=None, filename_field='datas_fname', mimetype=None, access_token=None, file_response=False, **kw): status, headers, content = request.env['ir.http'].binary_content(xmlid=xmlid, model=model, id=id, field=field, unique=unique, filename=filename, filename_field=filename_field, mimetype=mimetype, access_token=access_token, download=True, default_mimetype='application/octet-stream') if status != 200: exceptions.abort(status) if file_response and misc.str2bool(file_response): decoded_content = base64.b64decode(content) headers.append(('Content-Length', len(decoded_content))) response = request.make_response(decoded_content, headers) else: if not filename: record = request.env.ref(xmlid, False) if xmlid else None if not record and id and model in request.env.registry: record = request.env[model].browse(int(id)) if record and filename_field in record: filename = record[filename_field] else: filename = "%s-%s-%s" % (record._name, record.id, field) headers = dict(headers) result = { 'content': content, 'filename': filename, 'content_disposition': headers.get('Content-Disposition'), 'content_type': headers.get('Content-Type'), 'content_length': len(base64.b64decode(content))} content = json.dumps(result, sort_keys=True, indent=4, cls=ResponseEncoder) response = Response(content, content_type='application/json;charset=utf-8', status=200) return response
def add_attachment(self, ufile, temporary=False, **kw): tmp = temporary and str2bool(temporary) or False name = "Access Attachment: %s" % ufile.filename attachment = request.env['ir.attachment'].create({ 'name': tmp and "%s (Temporary)" % name or name, 'datas': base64.b64encode(ufile.read()), 'datas_fname': ufile.filename, 'type': 'binary', 'public': False, 'temporary': tmp, }) attachment.generate_access_token() if ufile.mimetype and ufile.mimetype != 'application/octet-stream': attachment.sudo().write({ 'mimetype': ufile.mimetype, }) base_url = request.env['ir.config_parameter'].sudo().get_param( 'web.base.url') result = attachment.read( ['name', 'datas_fname', 'mimetype', 'checksum', 'access_token'])[0] result['url'] = '%s/web/content/%s?access_token=%s' % ( base_url, attachment.id, attachment.access_token) return json.dumps(result)
def _handle_debug(cls): debug = request.httprequest.args.get('debug') if debug is not None: request.session.debug = ','.join( mode if mode in ALLOWED_DEBUG_MODES else '1' if str2bool(mode, mode) else '' for mode in (debug or '').split(','))
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 restore_via_odoo_backup_sh(self, master_pwd, backup_file_name, name, encryption_password, copy=False): if config['admin_passwd'] != master_pwd: return env.get_template("backup_list.html").render( error="Incorrect master password") if os.path.exists(config.filestore(name)): return env.get_template("backup_list.html").render( error= 'Filestore for database "{}" already exists. Please choose another database name' .format(name)) cloud_params = self.get_cloud_params(request.httprequest.url, call_from='frontend') backup_object = BackupCloudStorage.get_object( cloud_params, filename=backup_file_name) backup_file = tempfile.NamedTemporaryFile() backup_file.write(backup_object['Body'].read()) if backup_file_name.split('|')[0][-4:] == '.enc': if not encryption_password: raise UserError( _('The backup are encrypted. But encryption password is not found. Please check your module settings.' )) # GnuPG ignores the --output parameter with an existing file object as value decrypted_backup_file = tempfile.NamedTemporaryFile() decrypted_backup_file_name = decrypted_backup_file.name os.unlink(decrypted_backup_file_name) backup_file.seek(0) r = gnupg.GPG().decrypt_file(backup_file, passphrase=encryption_password, output=decrypted_backup_file_name) if not r.ok: error = 'gpg: {0}'.format(r.status) if not r.valid: error += ". Maybe wrong password?" return env.get_template("backup_list.html").render(error=error) backup_file = open(decrypted_backup_file_name, 'rb') try: db.restore_db(name, backup_file.name, str2bool(copy)) # Make all auto backup cron records inactive with closing(db_connect(name).cursor()) as cr: cr.autocommit(True) try: cr.execute(""" UPDATE ir_cron SET active=false WHERE active=true AND id IN (SELECT ir_cron_id FROM odoo_backup_sh_config_cron); UPDATE odoo_backup_sh_config SET active=false WHERE active=true; """) except Exception: pass return http.local_redirect('/web/database/manager') except Exception as e: error = "Database restore error: %s" % (str(e) or repr(e)) return env.get_template("backup_list.html").render(error=error) finally: os.unlink(backup_file.name)
def _is_partner_duplicate_allowed(self): """Check if partner duplication is allowed This parameter is configured through res.config.settings """ get_param = self.env["ir.config_parameter"].sudo().get_param param = get_param("commerce.no_partner_duplicate") return not str2bool(param, True)
def restore(self, master_pwd, backup_file, name, copy=False): try: data = base64.b64encode(backup_file.read()) dispatch_rpc('db', 'restore', [master_pwd, name, data, str2bool(copy)]) return http.local_redirect('/web/database/manager') except Exception, e: error = "Database restore error: %s" % e return self._render_template(error=error)
def restore(self, backup_file, database_name, master_password="******", copy=False, **kw): service.db.check_super(master_password) try: with tempfile.NamedTemporaryFile(delete=False) as file: backup_file.save(file) service.db.restore_db(database_name, file.name, misc.str2bool(copy)) return Response(json.dumps(True), content_type='application/json;charset=utf-8', status=200) except Exception: raise finally: os.unlink(file.name)
def report(self, report, ids, type='PDF', context=None, options=None, file_response=False, **kw): ctx = request.session.context.copy() ctx.update(context and parse_value(context) or {}) ids = ids and parse_value(ids) or [] options = options and parse_value(options) or {} result = {'report': report, 'type': type} report = request.env['ir.actions.report']._get_report_from_name(report) if type.lower() == "html": data = report.with_context(ctx).render_qweb_html(ids, data=options)[0] result.update({ 'content': base64.b64encode(data), 'content_type': 'text/html', 'content_length': len(data) }) elif type.lower() == "pdf": data = report.with_context(ctx).render_qweb_pdf(ids, data=options)[0] result.update({ 'content': base64.b64encode(data), 'content_type': 'application/pdf', 'content_length': len(data) }) elif type.lower() == "text": data = report.with_context(ctx).render_qweb_text(ids, data=options)[0] result.update({ 'content': base64.b64encode(data), 'content_type': 'text/plain', 'content_length': len(data) }) else: return exceptions.NotFound() if file_response and misc.str2bool(file_response): headers = [('Content-Type', result.get('content_type')), ('Content-Length', result.get('content_length'))] response = request.make_response(data, headers) else: content = json.dumps(result, sort_keys=True, indent=4, cls=ResponseEncoder) response = Response(content, content_type='application/json;charset=utf-8', status=200) return response
def _handle_debug(cls): # Store URL debug mode (might be empty) into session if 'debug' in request.httprequest.args: debug_mode = [] for debug in request.httprequest.args['debug'].split(','): if debug not in ALLOWED_DEBUG_MODES: debug = '1' if str2bool(debug, debug) else '' debug_mode.append(debug) debug_mode = ','.join(debug_mode) # Write on session only when needed if debug_mode != request.session.debug: request.session.debug = debug_mode
def restore(self, master_pwd, backup_file, name, copy=False): try: data_file = None db.check_super(master_pwd) with tempfile.NamedTemporaryFile(delete=False) as data_file: backup_file.save(data_file) db.restore_db(name, data_file.name, str2bool(copy)) return http.local_redirect('/web/v2/manager') except Exception as e: error = "Database restore error: %s" % (str(e) or repr(e)) return self._render_template(error=error) finally: if data_file: os.unlink(data_file.name)
def restore(self, master_pwd, backup_file, name, copy=False): insecure = odoo.tools.config.verify_admin_password('admin') if insecure and master_pwd: dispatch_rpc('db', 'change_admin_password', ["admin", master_pwd]) try: data_file = None db.check_super(master_pwd) with tempfile.NamedTemporaryFile(delete=False) as data_file: backup_file.save(data_file) db.restore_db(name, data_file.name, str2bool(copy)) return request.redirect('/web/database/manager') except Exception as e: error = "Database restore error: %s" % (str(e) or repr(e)) return self._render_template(error=error) finally: if data_file: os.unlink(data_file.name)
def _connect(self, conf): """ Connect to an LDAP server specified by an ldap configuration dictionary. :param dict conf: LDAP configuration :return: an LDAP object """ uri = 'ldap://%s:%d' % (conf['ldap_server'], conf['ldap_server_port']) connection = ldap.initialize(uri) ldap_chase_ref_disabled = self.env['ir.config_parameter'].sudo().get_param('auth_ldap.disable_chase_ref') if str2bool(ldap_chase_ref_disabled): connection.set_option(ldap.OPT_REFERRALS, ldap.OPT_OFF) if conf['ldap_tls']: connection.start_tls_s() return connection
def client_db_create(self, dbname=None, demo=False, lang='en_US', user_password='******', user_login='******', country_code=None, phone=None, template_dbname=None, **params): demo = str2bool(demo, False) if not dbname: raise werkzeug.exceptions.BadRequest( description='Missing parameter: dbname') _logger.info("Create database: %s (demo=%r)", dbname, demo) try: service_db._create_empty_database(dbname) except service_db.DatabaseExists as bd_ex: raise werkzeug.exceptions.Conflict(description=str(bd_ex)) service_db._initialize_db( id, dbname, demo, lang, user_password, user_login, country_code=str_filter_falsy(country_code), phone=str_filter_falsy(phone), ) db = db_connect(dbname) with closing(db.cursor()) as cr: db_init = modules_db.is_initialized(cr) if not db_init: raise werkzeug.exceptions.InternalServerError( description='Database not initialized.') return Response('OK', status=200)
def client_db_configure_mail(self, incoming, outgoing, db=None, test_and_confirm=False, **params): # pylint: disable=too-many-locals, too-many-branches """ Configure mail servers for database :param dict incoming: dict with config of incoming mail server :param dict outgoing: dict with config of outgoing mail server :param bool test_and_confirm: if set to True, test if odoo can use specified mail servers :return: 200 OK if everythning is ok. in case of errors, 500 code will be returned Required params for incoming mail server: - host - user - password Required params for outgoing mail server: - host - user - password """ test_and_confirm = str2bool(test_and_confirm) incoming = json.loads(incoming) outgoing = json.loads(outgoing) incoming_data = { 'name': 'Yodoo Incoming Mail', 'server_type': 'imap', 'is_ssl': True, 'port': 993, 'server': incoming['host'], 'user': incoming['user'], 'password': incoming['password'], 'active': incoming.get('active', True), 'state': 'draft', } outgoing_data = { 'name': 'Yodoo Outgoing Mail', 'smtp_encryption': 'starttls', 'smtp_port': 587, 'smtp_host': outgoing['host'], 'smtp_user': outgoing['user'], 'smtp_pass': outgoing['password'], 'active': outgoing.get('active', True), } with registry(db).cursor() as cr: env = api.Environment(cr, SUPERUSER_ID, context={}) incoming_srv = env.ref('yodoo_client.yodoo_incoming_mail', raise_if_not_found=False) if incoming_srv: incoming_srv.write(incoming_data) else: incoming_srv = env['fetchmail.server'].create(incoming_data) env['ir.model.data'].create({ 'name': 'yodoo_incoming_mail', 'module': 'yodoo_client', 'model': incoming_srv._name, 'res_id': incoming_srv.id, 'noupdate': True, }) if test_and_confirm: incoming_srv.button_confirm_login() if incoming_srv.state != 'done': raise werkzeug.exceptions.InternalServerError( "Cannot configure incoming mail server") outgoing_srv = env.ref('yodoo_client.yodoo_outgoing_mail', raise_if_not_found=False) if outgoing_srv: outgoing_srv.write(outgoing_data) else: catchall_domain = outgoing['user'].split('@') if len(catchall_domain) > 1: catchall_domain = catchall_domain[1] res_users = env['res.users'].sudo().with_context( active_test=False) res_users.browse(SUPERUSER_ID).partner_id.write( {'email': 'odoobot@%s' % catchall_domain}) env['ir.config_parameter'].sudo().set_param( 'mail.catchall.domain', catchall_domain) env['ir.mail_server'].search([('active', '=', True) ]).write({'active': False}) outgoing_srv = env['ir.mail_server'].create(outgoing_data) env['ir.model.data'].create({ 'name': 'yodoo_outgoing_mail', 'module': 'yodoo_client', 'model': outgoing_srv._name, 'res_id': outgoing_srv.id, 'noupdate': True, }) if test_and_confirm: try: smtp = outgoing_srv.connect(mail_server_id=outgoing_srv.id) except Exception: _logger.error("Cannot configure outgoing mail server", exc_info=True) raise werkzeug.exceptions.InternalServerError( "Cannot configure outgoing mail server") finally: try: if smtp: smtp.quit() except Exception: # pylint: disable=except-pass # ignored, just a consequence of the previous exception pass return http.Response('OK', status=200)
def _is_partner_duplicate_prevented(self): get_param = self.env["ir.config_parameter"].sudo().get_param return str2bool(get_param("shopinvader.no_partner_duplicate"))