def write(self, vals): # Se valida que los avances ya calificados no sean modificados es_ejecutor = self.env.user.has_group_v8( 'plan_mejoramiento.ejecutor')[0] if len(vals) == 1 and self.tipo_calificacion_id and es_ejecutor: raise AccessError( 'No se permite modificar un avance que ya ha sido calificado') # Se valida que solo el jefe_dependencia apruebe el avance es_jefe_dependencia = self.accion_id.jefe_dependencia_id.id == self.env.uid if 'aprobacion_jefe_dependencia' in vals and not es_jefe_dependencia: raise AccessError( 'El Campo [Aprobación Jefe Unidad] solo lo puede diligenciar el usuario Jefe de la Unidad' ) # Se valida que el usuario auditor solo pueda realizar la calificación una vez este aprobado el avance por el usuario jefe_dependencia es_auditor = self.env.user.has_group_v8('plan_mejoramiento.auditor')[0] if ('tipo_calificacion_id' in vals or 'porcentaje' in vals ) and es_auditor and self.aprobacion_jefe_dependencia == False: raise AccessError( 'Se podrá calificar este avance hasta que el usuario Jefe Depedencia lo apruebe' ) result = super(plan_mejoramiento_avance, self).write(vals) return result
def write(self, vals): if not self.env.user._is_admin(): if {'channel_id', 'partner_id', 'partner_email'} & set(vals): raise AccessError(_('You can not write on this field')) elif self.mapped('partner_id') != self.env.user.partner_id: raise AccessError(_('You can not write on the record of other users')) return super(ChannelPartner, self).write(vals)
def check_field_access_rights(self, cr, user, operation, fields, context=None): """Just allow to write on specific fields for some groups referenced at _write_fields_whitelist""" res = super(fields_security_mixin, self).check_field_access_rights(cr, user, operation, fields, context) if hasattr(self, '_write_fields_whitelist') and self._write_fields_whitelist: whitelisted_groups = self._write_fields_whitelist.keys() if operation == 'write' and whitelisted_groups and self.user_has_groups( cr, user, groups=','.join(whitelisted_groups), context=context): fields_set = set(fields) for group in whitelisted_groups: fields_allowed = set(self._write_fields_whitelist[group]) is_allowed = fields_allowed.issuperset(fields_set) if self.user_has_groups( cr, user, groups=group, context=context) and not is_allowed: _logger.warning( 'Access Denied by ACLs for operation: %s, uid: %s, model: %s, fields: %s', operation, user, self._name, ', '.join(fields_set - fields_allowed)) raise AccessError( _('The requested operation cannot be completed due to security restrictions. ' 'Please contact your system administrator.\n\n(Document type: %s, Operation: %s)') % \ (self._description, operation) ) if hasattr(self, '_write_fields_blacklist') and self._write_fields_blacklist: blacklisted_groups = self._write_fields_blacklist.keys() if operation == 'write' and blacklisted_groups and self.user_has_groups( cr, user, groups=','.join(blacklisted_groups), context=context): fields_set = set(fields) for group in blacklisted_groups: fields_denied = set(self._write_fields_blacklist[group]) is_denied = fields_denied.issuperset(fields_set) if self.user_has_groups( cr, user, groups=group, context=context) and is_denied: _logger.warning( 'Access Denied by ACLs for operation: %s, uid: %s, model: %s, fields: %s', operation, user, self._name, ', '.join(fields_set - fields_denied)) raise AccessError( _('The requested operation cannot be completed due to security restrictions. ' 'Please contact your system administrator.\n\n(Document type: %s, Operation: %s)') % \ (self._description, operation) ) return res
def _check_alfresco_access(self, cmis_backend, params): token = self._check_provided_token("/", cmis_backend, params) if not token: raise AccessError("Bad request") # check access to object from token model_inst, field_name = self._decode_token( "/", cmis_backend, params, token) if not self._check_cmis_content_access( "/", cmis_backend, params, model_inst, field_name): raise AccessError("Bad request") if not self._check_access_operation(model_inst, "read"): raise AccessError("Bad request") return True
def create(self, cr, uid, values, context=None): """ Override to avoid automatic logging of creation """ if context is None: context = {} employee_id = values.get('employee_id', False) context = dict(context, mail_create_nolog=True) if values.get('state') and values['state'] not in [ 'draft', 'confirm', 'cancel' ] and not self.pool['res.users'].has_group(cr, uid, 'base.group_hr_user'): raise AccessError( _('You cannot set a leave request as \'%s\'. Contact a human resource manager.' ) % values.get('state')) if not values.get('name'): employee_name = self.pool['hr.employee'].browse( cr, uid, employee_id, context=context).name holiday_type = self.pool['hr.holidays.status'].browse( cr, uid, values.get('holiday_status_id'), context=context).name values['name'] = _("%s on %s") % (employee_name, holiday_type) hr_holiday_id = super(hr_holidays, self).create(cr, uid, values, context=context) self.add_follower(cr, uid, [hr_holiday_id], employee_id, context=context) return hr_holiday_id
def force_storage_previous(self, previous_value=None): """Force all attachments to be stored in the currently configured storage""" if not self.env.user._is_admin(): raise AccessError( _('Only administrators can execute this action.')) new_value = self._storage() if LARGE_OBJECT_LOCATION in [previous_value, new_value]: # Update all records if large object is participated domain = [] else: # Switching between file and db. # We can reduce records to be updated. domain = { 'db': [('store_fname', '!=', False)], 'file': [('db_datas', '!=', False)], }.get(new_value, []) # trick to disable addional filtering in ir.attachment's method _search domain += [('id', '!=', -1)] for attach in self.search(domain): # we add url because in some environment mimetype is not computed correctly # see https://github.com/odoo/odoo/issues/11978 attach.write({'datas': attach.datas, 'url': attach.url}) return True
def button_open(self, cr, uid, ids, context=None): """ Changes statement state to Running. @return: True """ obj_seq = self.pool.get('ir.sequence') if context is None: context = {} statement_pool = self.pool.get('account.bank.statement') for statement in statement_pool.browse(cr, uid, ids, context=context): vals = {} if not self._user_allow(cr, uid, statement.id, context=context): raise AccessError( (_('You do not have rights to open this %s journal!') % (statement.journal_id.name, ))) if statement.name and statement.name == '/': c = {'ir_sequence_date': statement.period_id.date_start} if statement.journal_id.sequence_id: st_number = obj_seq.next_by_id( cr, uid, statement.journal_id.sequence_id.id, context=c) else: st_number = obj_seq.next_by_code(cr, uid, 'account.cash.statement', context=c) vals.update({'name': st_number}) vals.update({ 'state': 'open', }) self.write(cr, uid, [statement.id], vals, context=context) return True
def create(self, cr, uid, values, context=None): """ Override to avoid automatic logging of creation """ # print self.pool.get('hr.holidays').browse(cr, uid,values=values) print "create-----------" if context is None: context = {} employee_id = values.get('employee_id', False) context = dict(context, mail_create_nolog=True, mail_create_nosubscribe=True) if not self._check_state_access_right(cr, uid, values, context): raise AccessError( ('您不能分配年休假 \'%s\'. 请联系管理员') % values.get('state')) if not values.get('name'): values['name'] = " " hr_holiday_id = super(dtdream_hr_holidays_extend, self).create(cr, uid, values, context=context) self.add_follower(cr, uid, [hr_holiday_id], employee_id, context=context) damn_this = self.pool.get('hr.holidays').browse(cr, uid, hr_holiday_id, context=context) for this in damn_this: this.message_post(body=u'创建,状态:草稿 ') # print rrrrrrrr return hr_holiday_id
def write(self, cr, uid, ids, vals, context=None): employee_id = vals.get('employee_id', False) if vals.get('state') and vals['state'] not in ['draft', 'confirm', 'cancel'] and not self.pool['res.users'].has_group(cr, uid, 'base.group_hr_user'): raise AccessError(_('You cannot set a leave request as \'%s\'. Contact a human resource manager.') % vals.get('state')) hr_holiday_id = super(hr_holidays, self).write(cr, uid, ids, vals, context=context) self.add_follower(cr, uid, ids, employee_id, context=context) return hr_holiday_id
def force_storage_previous(self, cr, uid, previous_value=None, context=None): """Force all attachments to be stored in the currently configured storage""" if not self.pool['res.users'].has_group(cr, uid, 'base.group_erp_manager'): raise AccessError( _('Only administrators can execute this action.')) new_value = self._storage(cr, uid) if all([v in ['db', 'file'] for v in [new_value, previous_value]]): # Switching between file and db. # We can reduce records to be updated. domain = { 'db': [('store_fname', '!=', False)], 'file': [('db_datas', '!=', False)], }.get(new_value, []) else: # Update all records if it's not standart switching domain = [] ids = self.search(cr, uid, domain, context=context) for attach in self.browse(cr, uid, ids, context=context): attach.write({'datas': attach.datas}) return True
def create(self, cr, uid, values, context=None): """ Override to avoid automatic logging of creation """ if context is None: context = {} employee_id = values.get('employee_id', False) context = dict(context, mail_create_nolog=True, mail_create_nosubscribe=True) if not self._check_state_access_right(cr, uid, values, context): raise AccessError( _('You cannot set a leave request as \'%s\'. Contact a human resource manager.' ) % values.get('state')) if not values.get('name'): employee_name = self.pool['hr.employee'].browse( cr, uid, employee_id, context=context).name holiday_type = self.pool['hr.holidays.status'].browse( cr, uid, values.get('holiday_status_id'), context=context).name values['name'] = _("%s on %s") % (employee_name, holiday_type) hr_holiday_id = super(hr_holidays, self).create(cr, uid, values, context=context) self.add_follower(cr, uid, [hr_holiday_id], employee_id, context=context) return hr_holiday_id
def adjustment_message_error_access(self, model_name, message): model_accesses = self.get_model_accesses(model_name) if model_accesses: message += '\n (Model Access of This Users: %s)' % \ (', '.join(model_accesses)) raise AccessError(message) return True
def write(self, cr, uid, ids, vals, context=None): employee_id = vals.get('employee_id', False) if not self._check_state_access_right(cr, uid, vals, context): raise AccessError(_('You cannot set a leave request as \'%s\'. Contact a human resource manager.') % vals.get('state')) hr_holiday_id = super(hr_holidays, self).write(cr, uid, ids, vals, context=context) self.add_follower(cr, uid, ids, employee_id, context=context) return hr_holiday_id
def order(self): """ The order_line is ordered to the vendor but isn't received yet """ if self.user_has_groups("lunch.group_lunch_manager"): self.state = 'ordered' else: raise AccessError(_("Only your lunch manager processes the orders."))
def execute(self): ''' This function is called at the confirmation of the wizard to generate the COA from the templates. It will read all the provided information to create the accounts, the banks, the journals, the taxes, the accounting properties... accordingly for the chosen company. ''' if len(self.env['account.account'].search([('company_id', '=', self.company_id.id)])) > 0: # We are in a case where we already have some accounts existing, meaning that user has probably # created its own accounts and does not need a coa, so skip installation of coa. _logger.info('Could not install chart of account since some accounts already exists for the company (%s)', (self.company_id.id,)) return {} if not self.env.user._is_admin(): raise AccessError(_("Only administrators can change the settings")) ir_values_obj = self.env['ir.values'] company = self.company_id self.company_id.write({'currency_id': self.currency_id.id, 'accounts_code_digits': self.code_digits, 'anglo_saxon_accounting': self.use_anglo_saxon, 'bank_account_code_prefix': self.bank_account_code_prefix, 'cash_account_code_prefix': self.cash_account_code_prefix, 'chart_template_id': self.chart_template_id.id}) #set the coa currency to active self.currency_id.write({'active': True}) # When we install the CoA of first company, set the currency to price types and pricelists if company.id == 1: for reference in ['product.list_price', 'product.standard_price', 'product.list0']: try: tmp2 = self.env.ref(reference).write({'currency_id': self.currency_id.id}) except ValueError: pass # If the floats for sale/purchase rates have been filled, create templates from them self._create_tax_templates_from_rates(company.id) # Install all the templates objects and generate the real objects acc_template_ref, taxes_ref = self.chart_template_id._install_template(company, code_digits=self.code_digits, transfer_account_id=self.transfer_account_id) # write values of default taxes for product as super user if self.sale_tax_id and taxes_ref: ir_values_obj.sudo().set_default('product.template', "taxes_id", [taxes_ref[self.sale_tax_id.id]], for_all_users=True, company_id=company.id) if self.purchase_tax_id and taxes_ref: ir_values_obj.sudo().set_default('product.template', "supplier_taxes_id", [taxes_ref[self.purchase_tax_id.id]], for_all_users=True, company_id=company.id) # Create Bank journals self._create_bank_journals_from_o2m(company, acc_template_ref) # Create the current year earning account if it wasn't present in the CoA account_obj = self.env['account.account'] unaffected_earnings_xml = self.env.ref("account.data_unaffected_earnings") if unaffected_earnings_xml and not account_obj.search([('company_id', '=', company.id), ('user_type_id', '=', unaffected_earnings_xml.id)]): account_obj.create({ 'code': '999999', 'name': _('Undistributed Profits/Losses'), 'user_type_id': unaffected_earnings_xml.id, 'company_id': company.id,}) return {}
def cancel(self): """ cancel one or more order.line, update order status and unlink existing cashmoves """ if self.user_has_groups("lunch.group_lunch_manager"): self.state = 'cancelled' self.cashmove.unlink() else: raise AccessError(_("Only your lunch manager cancels the orders."))
def action_done(self): """ @deprecated use inventory workflow. Material order status follow stock picking status. All products have been received. Mark related picking to done.""" if not self.user_has_groups('stock.group_stock_user'): err_msg = _('You have no access to receive material.') raise AccessError(err_msg) for record in self: record.state = 'done'
def unlink(self, cr, uid, ids, context=None): for categ in self.browse(cr, uid, ids): if categ.code in ('HB', 'TP', 'NVL', 'BTP', 'CCDC', 'NLTH', 'DV'): raise AccessError( _("You're not able to delete default configuration !!!")) return super(product_category, self).unlink(cr, uid, ids, context=context)
def _check_access(self, cmis_path, proxy_info, params): """This method check that the user can access to the requested CMIS content. Security checks applied when the proxy mode is activated,: 1. Requests from the client must provide a token (in the header or as param of the request). If no security token is provided in this case, the access is denied. 2. The Odoo object referenced by the token (the token is build as 'model.name' + '_' + 'instance_id') must exist. 3. The user must have read access to the object referenced by the token 4. If a cmis_path or object_id is provided by the request, the referenced CMIS content must be child of or the node referenced by the Odoo object from the token (or equal) 5. If a cmisaction is provided by the request, a check is done to ensure that the user has the required privileges in Odoo """ # check token conformity token = self._check_provided_token(cmis_path, proxy_info, params) if not token: raise AccessError("Bad request") # check access to object from token model_inst, field_name = self._decode_token(cmis_path, proxy_info, params, token) if not model_inst: raise AccessError("Bad request") # check if the CMIS object in the request is the the one referenced on # model_inst or a child of this one if not cmis_path and 'objectId' not in params: # The request is not for an identified content return model_inst if not self._check_cmis_content_access(cmis_path, proxy_info, params, model_inst, field_name): raise AccessError("Bad request") if not self._check_content_action_access(cmis_path, proxy_info, params, model_inst): raise AccessError("Bad request") return model_inst
def create(self, cr, uid, vals, context=None): #Thanh: Only User has group Product Creation can create a product if uid != SUPERUSER_ID and not self.pool[ 'ir.model.access'].check_groups( cr, uid, "general_product.group_product_creation"): raise AccessError(_("You're not able to create a product!!!")) return super(product_template, self).create(cr, uid, vals, context=context)
def create(self, vals): """ No permitir la creacion de productos a cualquiera. """ if self.env.user.id == SUPERUSER_ID or self.env.user.has_group( 'product_create_restriction.group_product_create_users'): return super(ProductTemplate, self).create(vals) else: raise AccessError(_("You do not have permission to create " "products, if you really need to create a " "product, please contact a user who has " "permissions."))
def set_sale_defaults(self): self.ensure_one() if not self.env.user._is_admin(): raise AccessError(_("Only administrators can change the settings")) default_picking_policy = 'one' if self.default_picking_policy else 'direct' self.env['ir.values'].sudo().set_default('sale.order', 'picking_policy', default_picking_policy) res = super(SaleConfiguration, self).set_sale_defaults() return res
def fix_invalid_sequence(self, cr, uid, ids, context=None): if self.pool['res.users'].has_group(cr, uid, 'base.group_system'): for disw in self.browse(cr, uid, ids, context=context): for diswl in disw.line_ids: if diswl.state == 'invalid': cr.execute("ALTER SEQUENCE %s RESTART WITH %s;" % (diswl.sequence_name, diswl.max_id)) return True else: # We check in this way because TransientModel doesn't accept # ir_model_access definition. raise AccessError(_('You have to belong to administration group.'))
def web_settings_dashboard_data(self, **kw): if not request.env.user.has_group('base.group_erp_manager'): raise AccessError("Access Denied") installed_apps = request.env['ir.module.module'].search_count([ ('application', '=', True), ('state', 'in', ['installed', 'to upgrade', 'to remove']) ]) cr = request.cr cr.execute(""" SELECT exists(SELECT 1 FROM res_users_log WHERE create_uid=u.id), count(1) FROM res_users u WHERE active=true GROUP BY 1 """) counts = dict(cr.fetchall()) cr.execute(""" SELECT id, login FROM res_users u WHERE active=true AND NOT exists(SELECT 1 FROM res_users_log WHERE create_uid=u.id) ORDER BY id desc LIMIT 10 """) pending_users = cr.fetchall() # See update.py for this computation limit_date = datetime.now() - timedelta(15) enterprise_users = request.env['res.users'].search_count([ ("login_date", ">=", limit_date.strftime(DEFAULT_SERVER_DATETIME_FORMAT)), ('share', '=', False) ]) return { 'apps': { 'installed_apps': installed_apps, 'enterprise_users': enterprise_users, }, 'users_info': { 'active_users': counts.get(True, 0), 'pending_count': counts.get(False, 0), 'pending_users': pending_users, 'user_form_view_id': request.env['ir.model.data'].xmlid_to_res_id( "base.view_users_form"), }, }
def check(self, cr, uid, ids, mode, context=None, values=None): """Restricts the access to an ir.attachment, according to referred model In the 'document' module, it is overriden to relax this hard rule, since more complex ones apply there. """ res_ids = {} require_employee = False if ids: if isinstance(ids, (int, long)): ids = [ids] cr.execute( 'SELECT res_model, res_id, create_uid, public FROM ir_attachment WHERE id = ANY (%s)', (ids, )) for rmod, rid, create_uid, public in cr.fetchall(): if public and mode == 'read': continue if not (rmod and rid): if create_uid != uid: require_employee = True continue res_ids.setdefault(rmod, set()).add(rid) if values: if values.get('res_model') and values.get('res_id'): res_ids.setdefault(values['res_model'], set()).add(values['res_id']) ima = self.pool.get('ir.model.access') for model, mids in res_ids.items(): # ignore attachments that are not attached to a resource anymore when checking access rights # (resource was deleted but attachment was not) if not self.pool.get(model): require_employee = True continue existing_ids = self.pool[model].exists(cr, uid, mids) if len(existing_ids) != len(mids): require_employee = True # For related models, check if we can write to the model, as unlinking # and creating attachments can be seen as an update to the model if (mode in ['unlink', 'create']): ima.check(cr, uid, model, 'write') else: ima.check(cr, uid, model, mode) self.pool[model].check_access_rule(cr, uid, existing_ids, mode, context=context) if require_employee: if not uid == SUPERUSER_ID and not self.pool[ 'res.users'].has_group(cr, uid, 'base.group_user'): raise AccessError( _("Sorry, you are not allowed to access this document."))
def action_confirm(self): if not self.user_has_groups('stock.group_stock_assistant'): err_msg = _('You have no access to confirm this record.') raise AccessError(err_msg) # do not confirm empty material line for record in self: if not record.material_ids: err_msg = _('No material requested.') raise ValidationError(err_msg) record.state = 'confirm'
def set_technical_features(self): """ Map boolean field value to group membership, but checking access """ group = self.env.ref( 'base_technical_features.group_technical_features') for user in self: if self.env.ref('base.group_no_one') not in user.groups_id: raise AccessError( _('The user does not have access to technical ' 'features.')) if user.technical_features: self.sudo().write({'groups_id': [(4, group.id)]}) else: self.sudo().write({'groups_id': [(3, group.id)]})
def _improve_error_message_record_rules(self, missing_ids, description, operation): """ The main function to show message error in friendly way. """ self._cr.execute('SELECT id FROM ' + self._table + ' WHERE id IN %s', (tuple(missing_ids), )) forbidden_ids = [x[0] for x in self._cr.fetchall()] # only show message if there are missing_ids and they're forbidden if missing_ids and forbidden_ids: # the missing ids are (at least partially) # hidden by access rules if self._uid == SUPERUSER_ID: return # Trobz: 8625, Improve the error message about "Access Right" in # the user interface and in the log file rule_ids = get_error_rule_ids_with_current_user(self, operation) rules = rule_names_with_rule_ids(self, rule_ids) rule_names = ', '.join([rule['name'] for rule in rules]) missing_objs = self.browse(missing_ids) missings = missing_objs.sudo().name_get() missing_obj = ', '.join( ['%s (id=%s)' % (missed[1], missed[0]) for missed in missings]) user = self.env['res.users'].sudo().browse(self._uid) # log errors _logger.error( 'Access denied by ir_rules for operation: %s, ' 'uid: %s (id=%s), model: %s', operation, user.login, self._uid, self._name) _logger.error("- user try to access to: %s", missings) for rule in rules: _logger.error('- ir_rule implied: %s (id=%s) - %s', rule['name'], rule['id'], rule['domain']) return AccessError(('Some security rules didn\'t allow you ' 'to access to some records:\n' '- Server time: %s\n' '- Security rules: %s\n' '- User: %s (id=%s)\n' '- Profile Group: %s\n' '- Operation: %s\n' '- Model: %s\n' '- Document type: %s\n' '- Access Refused to: %s\n') % (str(datetime.datetime.now()), rule_names, user.login, self._uid, user.group_profile_id.name, operation, self._name, description, missing_obj))
def create(self, cr, uid, vals, context=None): #Thanh: Only User has group Product Creation can create a product if uid != SUPERUSER_ID and not self.pool[ 'ir.model.access'].check_groups( cr, uid, "general_product.group_product_creation"): raise AccessError(_("You're not able to create a product!!!")) system_sequence_obj = self.pool.get('system.sequence') categ_pool = self.pool.get('product.category') template_pool = self.pool.get('product.template') if vals.get('product_tmpl_id', False): template = template_pool.browse(cr, uid, vals['product_tmpl_id']) latest_parent_code = categ_pool.get_latest_parent( template.categ_id) if latest_parent_code == 'HB': code = system_sequence_obj.get_current_sequence( cr, 'product_code') vals.update({'default_code': code}) if latest_parent_code == 'TP': code = system_sequence_obj.get_current_sequence( cr, 'finished_good_code') vals.update({'default_code': code}) if latest_parent_code == 'NVL': code = system_sequence_obj.get_current_sequence( cr, 'material_code') vals.update({'default_code': code}) if latest_parent_code == 'BTP': code = system_sequence_obj.get_current_sequence( cr, 'semi_finished_good_code') vals.update({'default_code': code}) if latest_parent_code == 'CCDC': code = system_sequence_obj.get_current_sequence( cr, 'tools_code') vals.update({'default_code': code}) if latest_parent_code == 'NLTH': code = system_sequence_obj.get_current_sequence( cr, 'consumable_item_code') vals.update({'default_code': code}) return super(product_product, self).create(cr, uid, vals, context=context)
def force_storage(self, cr, uid, context=None): """Force all attachments to be stored in the currently configured storage""" if not self.pool['res.users'].has_group(cr, uid, 'base.group_erp_manager'): raise AccessError(_('Only administrators can execute this action.')) location = self._storage(cr, uid, context) domain = { 'db': [('store_fname', '!=', False)], 'file': [('db_datas', '!=', False)], }[location] ids = self.search(cr, uid, domain, context=context) for attach in self.browse(cr, uid, ids, context=context): attach.write({'datas': attach.datas}) return True