def oea(self, **kw): """login user via actpy Account provider""" dbname = kw.pop('db', None) if not dbname: dbname = db_monodb() if not dbname: return BadRequest() registry = registry_get(dbname) with registry.cursor() as cr: try: env = api.Environment(cr, SUPERUSER_ID, {}) provider = env.ref('auth_oauth.provider_openerp') except ValueError: return set_cookie_and_redirect('/web?db=%s' % dbname) assert provider._name == 'auth.oauth.provider' state = { 'd': dbname, 'p': provider.id, 'c': { 'no_user_creation': True }, } kw['state'] = json.dumps(state) return self.signin(**kw)
def update_dashboard_graph_model(dbname): db_registry = actpy.modules.registry.Registry.new(dbname) with api.Environment.manage(), db_registry.cursor() as cr: env = api.Environment(cr, SUPERUSER_ID, {}) if 'crm.team' in env: recs = env['crm.team'].search([]) for rec in recs: rec._onchange_team_type()
def environment(): """ Return an environment with a new cursor for the current database; the cursor is committed and closed after the context block. """ reg = registry(common.get_db_name()) with reg.cursor() as cr: yield api.Environment(cr, SUPERUSER_ID, {}) cr.commit()
def _setup_inalterability(cr, registry): env = api.Environment(cr, SUPERUSER_ID, {}) # enable ping for this module env['publisher_warranty.contract'].update_notification(cron_mode=True) fr_companies = env['res.company'].search([('partner_id.country_id.code', 'in', UNALTERABLE_COUNTRIES)]) if fr_companies: # create the securisation sequence per company fr_companies._create_secure_sequence(['l10n_fr_pos_cert_sequence_id'])
def poll(self, dbname, channels, last, options=None, timeout=TIMEOUT): if options is None: options = {} # Dont hang ctrl-c for a poll request, we need to bypass private # attribute access because we dont know before starting the thread that # it will handle a longpolling request if not actpy.evented: current = threading.current_thread() current._Thread__daemonic = True # PY2 current._daemonic = True # PY3 # rename the thread to avoid tests waiting for a longpolling current.setName("actpy.longpolling.request.%s" % current.ident) registry = actpy.registry(dbname) # immediatly returns if past notifications exist with registry.cursor() as cr: env = api.Environment(cr, SUPERUSER_ID, {}) notifications = env['bus.bus'].poll(channels, last, options) # immediatly returns in peek mode if options.get('peek'): return dict(notifications=notifications, channels=channels) # or wait for future ones if not notifications: if not self.started: # Lazy start of events listener self.start() event = self.Event() for channel in channels: self.channels.setdefault(hashable(channel), []).append(event) try: event.wait(timeout=timeout) with registry.cursor() as cr: env = api.Environment(cr, SUPERUSER_ID, {}) notifications = env['bus.bus'].poll(channels, last, options, force_status=True) except Exception: # timeout pass return notifications
def _auth_method_public(cls): """ If no user logged, set the public user of current website, or default public user as request uid. After this method `request.env` can be called, since the `request.uid` is set. The `env` lazy property of `request` will be correct. """ if not request.session.uid: env = api.Environment(request.cr, SUPERUSER_ID, request.context) website = env['website'].get_current_website() if website and website.user_id: request.uid = website.user_id.id if not request.uid: super(Http, cls)._auth_method_public()
def _set_accounts(cr, registry): #write the default debit account on salary rule having xml_id like 'l10n_be_hr_payroll.1' up to 'l10n_be_hr_payroll.1409' env = api.Environment(cr, SUPERUSER_ID, {}) names = [str(x) for x in range(1, 1410)] data = env['ir.model.data'].search([('model', '=', 'hr.salary.rule'), ('module', '=', 'l10n_be_hr_payroll'), ('name', 'in', names)]) account = env['account.account'].search([('code', 'like', '4530%')], limit=1) if account and data: rule_ids = [x['res_id'] for x in data.read(['res_id'])] env['hr.salary.rule'].browse(rule_ids).write( {'account_debit': account.id})
def receive(self, req): """ End-point to receive mail from an external SMTP server. """ dbs = req.jsonrequest.get('databases') for db in dbs: message = base64.b64decode(dbs[db]) try: db_registry = registry(db) with db_registry.cursor() as cr: env = api.Environment(cr, SUPERUSER_ID, {}) env['mail.thread'].message_process(None, message) except psycopg2.Error: pass return True
def signin(self, **kw): state = json.loads(kw['state']) dbname = state['d'] provider = state['p'] context = state.get('c', {}) registry = registry_get(dbname) with registry.cursor() as cr: try: env = api.Environment(cr, SUPERUSER_ID, context) credentials = env['res.users'].sudo().auth_oauth(provider, kw) cr.commit() action = state.get('a') menu = state.get('m') redirect = werkzeug.url_unquote_plus( state['r']) if state.get('r') else False url = '/web' if redirect: url = redirect elif action: url = '/web#action=%s' % action elif menu: url = '/web#menu_id=%s' % menu resp = login_and_redirect(*credentials, redirect_url=url) # Since /web is hardcoded, verify user has right to land on it if werkzeug.urls.url_parse( resp.location ).path == '/web' and not request.env.user.has_group( 'base.group_user'): resp.location = '/' return resp except AttributeError: # auth_signup is not installed _logger.error( "auth_signup not installed on database %s: oauth sign up cancelled." % (dbname, )) url = "/web/login?oauth_error=1" except AccessDenied: # oauth credentials not valid, user could be on a temporary session _logger.info( 'OAuth2: access denied, redirect to main page in case a valid session exists, without setting cookies' ) url = "/web/login?oauth_error=3" redirect = werkzeug.utils.redirect(url, 303) redirect.autocorrect_location_header = False return redirect except Exception as e: # signup error _logger.exception("OAuth2: %s" % str(e)) url = "/web/login?oauth_error=2" return set_cookie_and_redirect(url)
def _setup_inalterability(cr, registry): env = api.Environment(cr, SUPERUSER_ID, {}) # enable ping for this module env['publisher_warranty.contract'].update_notification(cron_mode=True) fr_companies = env['res.company'].search([('partner_id.country_id.code', 'in', UNALTERABLE_COUNTRIES)]) if fr_companies: # create the securisation sequence per company fr_companies._create_secure_sequence(['l10n_fr_secure_sequence_id']) #reset the update_posted field on journals journals = env['account.journal'].search([('company_id', 'in', fr_companies.ids)]) journals.write({'update_posted': False})
def _login(cls, db, login, password): if not password: return False user_id = False try: with cls.pool.cursor() as cr: self = api.Environment(cr, SUPERUSER_ID, {})[cls._name] user = self.search([('login', '=', login)]) if user: user_id = user.id user.sudo(user_id).check_credentials(password) user.sudo(user_id)._update_last_login() except AccessDenied: _logger.info("Login failed for db:%s login:%s", db, login) user_id = False return user_id
def check(cls, db, uid, passwd): """Verifies that the given (uid, password) is authorized for the database ``db`` and raise an exception if it is not.""" if not passwd: # empty passwords disallowed for obvious security reasons raise AccessDenied() db = cls.pool.db_name if cls.__uid_cache[db].get(uid) == passwd: return cr = cls.pool.cursor() try: self = api.Environment(cr, uid, {})[cls._name] self.check_credentials(passwd) cls.__uid_cache[db][uid] = passwd finally: cr.close()
def post_init(cr, registry): """ Set the timesheet project and task on existing leave type. Do it in post_init to be sure the internal project/task of res.company are set. (Since timesheet_generate field is true by default, those 2 fields are required on the leave type). """ from actpy import api, SUPERUSER_ID env = api.Environment(cr, SUPERUSER_ID, {}) for leave_type in env['hr.holidays.status'].search([ ('timesheet_generate', '=', True), ('timesheet_project_id', '=', False) ]): company = leave_type.company_id or env.user.company_id leave_type.write({ 'timesheet_project_id': company.leave_timesheet_project_id.id, 'timesheet_task_id': company.leave_timesheet_task_id.id, })
def setUp(self): self.registry = actpy.registry(get_db_name()) #: current transaction's cursor self.cr = self.cursor() self.uid = actpy.SUPERUSER_ID #: :class:`~actpy.api.Environment` for the current test case self.env = api.Environment(self.cr, self.uid, {}) @self.addCleanup def reset(): # rollback and close the cursor, and reset the environments self.registry.clear_caches() self.registry.reset_changes() self.env.reset() self.cr.rollback() self.cr.close() self.patch(type(self.env['res.partner']), '_get_gravatar_image', lambda *a: False)
def _login(cls, db, login, password): user_id = super(Users, cls)._login(db, login, password) if user_id: return user_id with registry(db).cursor() as cr: cr.execute("SELECT id FROM res_users WHERE lower(login)=%s", (login, )) res = cr.fetchone() if res: return False env = api.Environment(cr, SUPERUSER_ID, {}) Ldap = env['res.company.ldap'] for conf in Ldap.get_ldap_dicts(): entry = Ldap.authenticate(conf, login, password) if entry: user_id = Ldap.get_or_create_user(conf, login, entry) if user_id: break return user_id
def _process_job(cls, job_cr, job, cron_cr): """ Run a given job taking care of the repetition. :param job_cr: cursor to use to execute the job, safe to commit/rollback :param job: job to be run (as a dictionary). :param cron_cr: cursor holding lock on the cron job row, to use to update the next exec date, must not be committed/rolled back! """ try: with api.Environment.manage(): cron = api.Environment(job_cr, job['user_id'], {})[cls._name] # Use the user's timezone to compare and compute datetimes, # otherwise unexpected results may appear. For instance, adding # 1 month in UTC to July 1st at midnight in GMT+2 gives July 30 # instead of August 1st! now = fields.Datetime.context_timestamp(cron, datetime.now()) nextcall = fields.Datetime.context_timestamp( cron, fields.Datetime.from_string(job['nextcall'])) numbercall = job['numbercall'] ok = False while nextcall < now and numbercall: if numbercall > 0: numbercall -= 1 if not ok or job['doall']: cron._callback(job['cron_name'], job['ir_actions_server_id'], job['id']) if numbercall: nextcall += _intervalTypes[job['interval_type']]( job['interval_number']) ok = True addsql = '' if not numbercall: addsql = ', active=False' cron_cr.execute( "UPDATE ir_cron SET nextcall=%s, numbercall=%s" + addsql + " WHERE id=%s", (fields.Datetime.to_string( nextcall.astimezone(pytz.UTC)), numbercall, job['id'])) cron.invalidate_cache() finally: job_cr.commit() cron_cr.commit()
def _button_immediate_function(self, function): function(self) self._cr.commit() api.Environment.reset() modules.registry.Registry.new(self._cr.dbname, update_module=True) self._cr.commit() env = api.Environment(self._cr, self._uid, self._context) # pylint: disable=next-method-called config = env['ir.module.module'].next() or {} if config.get('type') not in ('ir.actions.act_window_close',): return config # reload the client; open the first available root menu menu = env['ir.ui.menu'].search([('parent_id', '=', False)])[:1] return { 'type': 'ir.actions.client', 'tag': 'reload', 'params': {'menu_id': menu.id}, }
def log_xml(self, xml_string, func): self.ensure_one() if self.debug_logging: db_name = self._cr.dbname # Use a new cursor to avoid rollback that could be caused by an upper method try: db_registry = registry(db_name) with db_registry.cursor() as cr: env = api.Environment(cr, SUPERUSER_ID, {}) IrLogging = env['ir.logging'] IrLogging.sudo().create({'name': 'delivery.carrier', 'type': 'server', 'dbname': db_name, 'level': 'DEBUG', 'message': xml_string, 'path': self.delivery_type, 'func': func, 'line': 1}) except psycopg2.Error: pass
def _auto_install_l10n(cr, registry): #check the country of the main company (only) and eventually load some module needed in that country env = api.Environment(cr, SUPERUSER_ID, {}) country_code = env.user.company_id.country_id.code if country_code: #auto install localization module(s) if available module_list = [] if country_code in SYSCOHADA_LIST: #countries using OHADA Chart of Accounts module_list.append('l10n_syscohada') elif country_code == 'GB': module_list.append('l10n_uk') elif country_code == 'DE': module_list.append('l10n_de_skr03') module_list.append('l10n_de_skr04') else: if env['ir.module.module'].search([('name', '=', 'l10n_' + country_code.lower())]): module_list.append('l10n_' + country_code.lower()) else: module_list.append('l10n_generic_coa') if country_code == 'US': module_list.append('account_plaid') module_list.append('account_check_printing') if country_code in ['US', 'AU', 'NZ', 'CA', 'CO', 'EC', 'ES', 'FR', 'IN', 'MX', 'UK']: module_list.append('account_yodlee') if country_code in SYSCOHADA_LIST + [ 'AT', 'BE', 'CA', 'CO', 'DE', 'EC', 'ES', 'ET', 'FR', 'GR', 'IT', 'LU', 'MX', 'NL', 'NO', 'PL', 'PT', 'RO', 'SI', 'TR', 'UK', 'VE', 'VN' ]: module_list.append('base_vat') #european countries will be using SEPA europe = env.ref('base.europe', raise_if_not_found=False) if europe: europe_country_codes = [x.code for x in europe.country_ids] if country_code in europe_country_codes: module_list.append('account_sepa') module_ids = env['ir.module.module'].search([('name', 'in', module_list), ('state', '=', 'uninstalled')]) module_ids.sudo().button_install()
def authenticate(self, user, password): # stay non-authenticated if user is None: return db = get_db_name() uid = self.registry['res.users'].authenticate(db, user, password, None) env = api.Environment(self.cr, uid, {}) # self.session.authenticate(db, user, password, uid=uid) # OpenERPSession.authenticate accesses the current request, which we # don't have, so reimplement it manually... session = self.session session.db = db session.uid = uid session.login = user session.session_token = uid and security.compute_session_token(session) session.context = env['res.users'].context_get() or {} session.context['uid'] = uid session._fix_lang(session.context) actpy.http.root.session_store.save(session)
def _serve_attachment(cls): env = api.Environment(request.cr, SUPERUSER_ID, request.context) domain = [('type', '=', 'binary'), ('url', '=', request.httprequest.path)] fields = ['__last_update', 'datas', 'name', 'mimetype', 'checksum'] attach = env['ir.attachment'].search_read(domain, fields) if attach: wdate = attach[0]['__last_update'] datas = attach[0]['datas'] or b'' name = attach[0]['name'] checksum = attach[0]['checksum'] or hashlib.sha1(datas).hexdigest() if (not datas and name != request.httprequest.path and name.startswith(('http://', 'https://', '/'))): return werkzeug.utils.redirect(name, 301) response = werkzeug.wrappers.Response() server_format = tools.DEFAULT_SERVER_DATETIME_FORMAT try: response.last_modified = datetime.datetime.strptime( wdate, server_format + '.%f') except ValueError: # just in case we have a timestamp without microseconds response.last_modified = datetime.datetime.strptime( wdate, server_format) response.set_etag(checksum) response.make_conditional(request.httprequest) if response.status_code == 304: return response response.mimetype = attach[0][ 'mimetype'] or 'application/octet-stream' response.data = base64.b64decode(datas) return response
def authenticate(cls, db, login, password, user_agent_env): """Verifies and returns the user ID corresponding to the given ``login`` and ``password`` combination, or False if there was no matching user. :param str db: the database on which user is trying to authenticate :param str login: username :param str password: user password :param dict user_agent_env: environment dictionary describing any relevant environment attributes """ uid = cls._login(db, login, password) if uid == SUPERUSER_ID: # Successfully logged in as admin! # Attempt to guess the web base url... if user_agent_env and user_agent_env.get('base_location'): try: with cls.pool.cursor() as cr: base = user_agent_env['base_location'] ICP = api.Environment(cr, uid, {})['ir.config_parameter'] if not ICP.get_param('web.base.url.freeze'): ICP.set_param('web.base.url', base) except Exception: _logger.exception("Failed to update web.base.url configuration parameter") return uid
def recreate_view(dbname): db_registry = openerp.modules.registry.Registry.new(dbname) with api.Environment.manage(), db_registry.cursor() as cr: env = api.Environment(cr, SUPERUSER_ID, {}) if 'sale.report' in env: env['sale.report'].init()
def send_notifications(): db_registry = registry(dbname) with api.Environment.manage(), db_registry.cursor() as cr: env = api.Environment(cr, SUPERUSER_ID, _context) env['mail.mail'].browse(email_ids).send()
def post_init(cr, registry): from actpy import api, SUPERUSER_ID env = api.Environment(cr, SUPERUSER_ID, {}) env['publisher_warranty.contract'].update_notification()
def post_init(cr, registry): """Rewrite ICP's to force groups""" from actpy import api, SUPERUSER_ID env = api.Environment(cr, SUPERUSER_ID, {}) env['ir.config_parameter'].init(force=True)
def finish(self): """ Transfer the data from the temp table to ir.translation """ cr = self._cr if self._debug: cr.execute("SELECT count(*) FROM %s" % self._table) count = cr.fetchone()[0] _logger.debug( "ir.translation.cursor: We have %d entries to process", count) # Step 1: resolve ir.model.data references to res_ids cr.execute(""" UPDATE %s AS ti SET res_id = imd.res_id, noupdate = imd.noupdate FROM ir_model_data AS imd WHERE ti.res_id IS NULL AND ti.module IS NOT NULL AND ti.imd_name IS NOT NULL AND ti.module = imd.module AND ti.imd_name = imd.name AND ti.imd_model = imd.model; """ % self._table) if self._debug: cr.execute(""" SELECT module, imd_name, imd_model FROM %s WHERE res_id IS NULL AND module IS NOT NULL """ % self._table) for row in cr.fetchall(): _logger.info( "ir.translation.cursor: missing res_id for %s.%s <%s> ", *row) # Records w/o res_id must _not_ be inserted into our db, because they are # referencing non-existent data. cr.execute( "DELETE FROM %s WHERE res_id IS NULL AND module IS NOT NULL" % self._table) # detect the xml_translate fields, where the src must be the same env = api.Environment(cr, SUPERUSER_ID, {}) src_relevant_fields = [] for model in env: for field_name, field in env[model]._fields.items(): if hasattr(field, 'translate') and callable(field.translate): src_relevant_fields.append("%s,%s" % (model, field_name)) find_expr = """ irt.lang = ti.lang AND irt.type = ti.type AND irt.name = ti.name AND ( (ti.type = 'model' AND ti.res_id = irt.res_id AND ti.name IN %s AND irt.src = ti.src) OR (ti.type = 'model' AND ti.res_id = irt.res_id AND ti.name NOT IN %s) OR (ti.type = 'view' AND (irt.res_id IS NULL OR ti.res_id = irt.res_id) AND irt.src = ti.src) OR (ti.type = 'field') OR (ti.type = 'help') OR (ti.type NOT IN ('model', 'view', 'field', 'help') AND irt.src = ti.src) ) """ # Step 2: update existing (matching) translations if self._overwrite: cr.execute( """ UPDATE ONLY %s AS irt SET value = ti.value, src = ti.src, state = 'translated' FROM %s AS ti WHERE %s AND ti.value IS NOT NULL AND ti.value != '' AND noupdate IS NOT TRUE """ % (self._model_table, self._table, find_expr), (tuple(src_relevant_fields), tuple(src_relevant_fields))) # Step 3: insert new translations cr.execute( """ INSERT INTO %s(name, lang, res_id, src, type, value, module, state, comments) SELECT name, lang, res_id, src, type, value, module, state, comments FROM %s AS ti WHERE NOT EXISTS(SELECT 1 FROM ONLY %s AS irt WHERE %s); """ % (self._model_table, self._table, self._model_table, find_expr), (tuple(src_relevant_fields), tuple(src_relevant_fields))) if self._debug: cr.execute("SELECT COUNT(*) FROM ONLY %s" % self._model_table) total = cr.fetchone()[0] cr.execute("SELECT COUNT(*) FROM ONLY %s AS irt, %s AS ti WHERE %s" % \ (self._model_table, self._table, find_expr), (tuple(src_relevant_fields), tuple(src_relevant_fields))) count = cr.fetchone()[0] _logger.debug( "ir.translation.cursor: %d entries now in ir.translation, %d common entries with tmp", total, count) # Step 4: cleanup cr.execute("DROP TABLE %s" % self._table) return True
def load_translations(cr, registry): env = api.Environment(cr, SUPERUSER_ID, {}) env.ref('l10n_be.l10nbe_chart_template').process_coa_translations()
def change_digit(cr): env = api.Environment(cr, SUPERUSER_ID, {}) precision = env['decimal.precision'].precision_get(application) return 16, precision
def setUpClass(cls): cls.registry = actpy.registry(get_db_name()) cls.cr = cls.registry.cursor() cls.uid = actpy.SUPERUSER_ID cls.env = api.Environment(cls.cr, cls.uid, {})