def delete(self, path): config = self.instance() url = config.get('cenit_url') + API_PATH + path headers = self.headers(config) try: _logger.info("[DEL] %s ? {%s}", url, headers) r = requests.delete(url, headers=headers) except Exception as e: _logger.error(e) raise exceptions.AccessError("Error trying to connect to Cenit.") if 200 <= r.status_code < 300: return True try: error = r.json() _logger.error(error) except Exception as e: _logger.error(e) raise exceptions.ValidationError("Cenit returned with errors") if 400 <= error.get('code', 400) < 500: raise exceptions.AccessError("Error trying to connect to Cenit.") raise exceptions.ValidationError("Cenit returned with errors")
def get(self, path, params=None): config = self.instance() url = config.get('cenit_url') + API_PATH + path headers = self.headers(config) try: _logger.info("[GET] %s ? %s {%s}", url, params, headers) r = requests.get(url, params=params, headers=self.headers(config)) except Exception as e: _logger.error(e) raise exceptions.AccessError("Error trying to connect to Cenit.") if 200 <= r.status_code < 300: return r.json() try: error = r.json() _logger.error(error) except Exception as e: _logger.error(e) _logger.info("\n\n%s\n", r.content) raise exceptions.ValidationError("Cenit returned with errors") if 400 <= error.get('code', 400) < 500: raise exceptions.AccessError("Error trying to connect to Cenit.") raise exceptions.ValidationError("Cenit returned with errors")
def post(self, path, vals): config = self.instance() payload = json.dumps(vals) url = config.get('cenit_url') + API_PATH + path headers = self.headers(config) try: _logger.info("[POST] %s ? %s {%s}", url, payload, headers) r = requests.post(url, data=payload, headers=headers) except Exception as e: _logger.error(e) raise exceptions.AccessError("Error trying to connect to Cenit.") if 200 <= r.status_code < 300: return r.json() try: error = r.json() _logger.error(error) except Exception as e: _logger.error(e) raise exceptions.ValidationError("Cenit returned with errors") if 400 <= error.get('code', 400) < 500: raise exceptions.AccessError("Error trying to connect to Cenit.") raise exceptions.ValidationError("Cenit returned with errors")
def get(self, path, params={}): payload = self._sign_request(path, params) config = self.get_config() try: _logger.info("[GET] %s ? %s ", '%s/%s' % (config['omna_api_url'], path), payload) r = requests.get('%s/%s' % (config['omna_api_url'], path), payload) except Exception as e: _logger.error(e) raise exceptions.AccessError( _("Error trying to connect to Omna's API.")) if 200 <= r.status_code < 300: return r.json() try: error = r.json() _logger.error(error) except Exception as e: _logger.error(e) raise exceptions.ValidationError( _("Omna's API returned with errors")) if 400 <= error.get('code', 400) < 500: raise exceptions.AccessError( error.get('message', _("Error trying to connect to Omna's API."))) raise exceptions.ValidationError( error.get('message', _("Omna's API returned with errors")))
def post(self, path, params={}): payload = self._sign_request(path, params) config = self.get_config() try: _logger.info("[POST] %s ? %s", '%s/%s' % (config['omna_api_url'], path), payload) r = requests.post('%s/%s' % (config['omna_api_url'], path), json=payload, headers={'Content-Type': 'application/json'}) except Exception as e: _logger.error(e) raise exceptions.AccessError( "Error trying to connect to Omna's API.") if 200 <= r.status_code < 300: return r.json() try: error = r.json() _logger.error(error) except Exception as e: _logger.error(e) raise exceptions.ValidationError("Omna's API returned with errors") if 400 <= error.get('code', 400) < 500: raise exceptions.AccessError( error.get('message', "Error trying to connect to Omna's API.")) raise exceptions.ValidationError( error.get('message', "Omna's API returned with errors"))
def write(self, vals): if not self._context.get('synchronizing'): for record in self: if 'name' in vals or 'list_price' in vals or 'description' in vals: data = { 'name': vals['name'] if 'name' in vals else record.name, 'price': vals['list_price'] if 'list_price' in vals else record.list_price, 'description': vals['description'] if 'description' in vals else (record.description or '') } # TODO Send image as data url to OMNA when supported # if 'image' in vals: # data['images'] = [image_data_uri(str(vals['image']).encode('utf-8'))] response = self.post( 'products/%s' % record.omna_product_id, {'data': data}) if not response.get('data').get('id'): raise exceptions.AccessError( _("Error trying to update products in Omna's API.") ) if 'integrations_data' in vals: old_data = json.loads(record.integrations_data) new_data = json.loads(vals['integrations_data']) if old_data != new_data: for integration in old_data: integration_new_data = False for integration_new in new_data: if integration_new['id'] == integration['id']: integration_new_data = integration_new break if integration_new_data and integration_new_data != integration: integration_data = {'properties': []} for field in integration_new_data['product'][ 'properties']: integration_data['properties'].append({ 'id': field['id'], 'value': field['value'] }) response = self.post( 'integrations/%s/products/%s' % (integration['id'], integration['product'] ['remote_product_id']), {'data': integration_data}) if not response.get('data').get('id'): raise exceptions.AccessError( _("Error trying to update products in Omna's API." )) return super(ProductTemplate, self).write(vals) else: return super(ProductTemplate, self).write(vals)
def dpd_be_send_shipping(self, pickings): ''' :param pickings: :return list: A list of dictionaries (one per picking) containing of the form:: { 'exact_price': price, 'tracking_number': number } # TODO missing labels per package # TODO missing currency # TODO missing success, error, warnings ''' successfull, error = self.login() if not successfull: raise exceptions.AccessError(error) res = [] for picking in pickings: shipping_data = {'tracking_number': "", 'exact_price': 0.0} try: order = self.get_order(picking=picking) action = 'storeOrders' client = Client(self.dpd_get_url(action=action)) request = client.service._binding.create_message( action, printOptions=self.get_print_options(), order=order, _soapheaders=self.get_soap_headers()) error, response = self.dpd_send_message(action=action, request=request) if error: raise exceptions.AccessError(error) node = etree.fromstring(response.content) pl_pdf = node.xpath('//parcellabelsPDF')[0].text pl_num = node.xpath('//parcelLabelNumber')[0].text picking.dpd_label_bin = pl_pdf picking.dpd_label_name = '%s.pdf' % picking.name shipping_data.update({'tracking_number': pl_num}) except zeep_exceptions.Fault as zeep_exception: errorcode = zeep_exception.detail[0][0].text errormessage = zeep_exception.detail[0][1].text if errorcode: logmessage = "An error occured." logmessage += "\nFull Response:%s\n" % errormessage else: logmessage = "An error occured." logmessage += "\nCode:%s\n" % zeep_exception.code logmessage += "\nMessage:%s\n" % zeep_exception.message raise exceptions.ValidationError(logmessage) res = res + [shipping_data] return res
def _get_report_values(self, docids, data=None): docs = self.env['test.report.mo'].browse(docids) if not docs.production_id.finished_move_line_ids: raise exceptions.AccessError(_('You Cannot Download Test Certificate as there is no Quantity Produced !')) if docs.production_id.state == 'cancel': raise exceptions.AccessError(_('You can not download Test Report for a Cancelled Manufacturing Order !')) return { 'doc_ids': docs.ids, 'doc_model': 'test.report.mo', 'docs': docs, }
def create(self, vals): res = super(VmFeesTerms, self).create(vals) if not res.line_ids: raise exceptions.AccessError(_("Fees Terms must be Required!")) total = 0.0 for line in res.line_ids: if line.value: total += line.value if total != 100.0: raise exceptions.AccessError( _("Fees terms must be divided as such sum up in 100%")) return res
def _get_report_values(self, docids, data=None): docs = self.env['mrp.production'].browse(docids) if not docs.finished_move_line_ids: raise exceptions.AccessError(_('You Cannot print Test Certificate as there is no Quantity Produced !')) if docs.state == 'cancel': raise exceptions.AccessError(_('You can not print a Test Certificate for a cancelled Manufacturing Order!')) if not docs.test_report_ids: raise exceptions.AccessError(_('Test Certificate has not been generated yet!')) return { 'doc_ids': docs.ids, 'doc_model': 'mrp.production', 'docs': docs, }
def _get_report_values(self, docids, data=None): docs = self.env['stock.picking'].browse(docids) if not docs.move_line_ids_without_package: raise exceptions.AccessError(_('You Cannot print Test Certificate as there is no Quantity Produced !')) if docs.state == 'cancel': raise exceptions.AccessError(_('You can not print a Test Certificate for a cancelled Delivery Order!')) if not docs.production_ids: raise exceptions.AccessError(_('Test Certificate has not been generated yet!')) return { 'doc_ids': docs.ids, 'doc_model': 'stock.picking', 'docs': docs, }
def _get_report_values(self, docids, data=None): docs = self.env['mrp.production'].browse(docids) if not docs.finished_move_line_ids: raise exceptions.AccessError(_('You Cannot print QR Code as there is no Quantity Produced !')) if docs.state == 'cancel': raise exceptions.AccessError(_('You can not print QR Report for a Cancelled Manufacturing Order !')) for data in docs.finished_move_line_ids: if not data.lot_id: raise exceptions.AccessError(_('You can not print QR Code as no Serial Number has been provided!')) return { 'doc_ids': docs.ids, 'doc_model': 'mrp.production', 'docs': docs, }
def _get_report_values(self, docids, data=None): docs = self.env['stock.picking'].browse(docids) if not docs.move_line_ids_without_package: raise exceptions.AccessError(_('You can not print QR Report as no quantity is reserved !')) if docs.state == 'cancel': raise exceptions.AccessError(_('You can not print QR Report for a Cancelled Delivery Order !')) for data in docs.move_line_ids_without_package: if not data.lot_id: raise exceptions.AccessError(_('You can not print QR Code as no Serial Number has been provided!')) return { 'doc_ids': docs.ids, 'doc_model': 'stock.picking', 'docs': docs, }
def check_is_in_group(self, name, name_desc, action_desc): grp = self.env.ref(name) user_grp_ids = self.env.user.groups_id.ids if grp.id not in user_grp_ids: raise exceptions.AccessError( _("Only users in group %s may %s." % (name_desc, action_desc)))
def write(self, vals): if self.env.context.get( "_job_edit_sentinel") is not self.EDIT_SENTINEL: write_on_protected_fields = [ fieldname for fieldname in vals if fieldname in self._protected_fields ] if write_on_protected_fields: raise exceptions.AccessError( _("Not allowed to change field(s): {}").format( write_on_protected_fields)) different_user_jobs = self.browse() if vals.get("user_id"): different_user_jobs = self.filtered( lambda records: records.env.user.id != vals["user_id"]) if vals.get("state") == "failed": self._message_post_on_failure() result = super().write(vals) for record in different_user_jobs: # the user is stored in the env of the record, but we still want to # have a stored user_id field to be able to search/groupby, so # synchronize the env of records with user_id super(QueueJob, record).write( {"records": record.records.with_user(vals["user_id"])}) return result
def check(self, model, mode='read', raise_exception=True): if isinstance(model, models.BaseModel): assert model._name == 'ir.model', 'Invalid model object' model_name = model.model else: model_name = model if mode != 'read' and model_name in [ 'product.template', 'product.product' ]: if self.env['res.users'].has_group( 'product_management_group.group_products_management'): return True elif raise_exception: raise exceptions.AccessError( _("Sorry, you are not allowed to manage products." "Only users with 'Products Management' level are currently" " allowed to do that")) else: return False return super(IrModelAccess, self).check(model, mode=mode, raise_exception=raise_exception)
def form_check_permission(self, raise_exception=True): """Check permission on current model and main object if any.""" res = True msg = '' if self.main_object: if hasattr(self.main_object, 'cms_can_edit'): res = self.main_object.cms_can_edit() else: # not `website.published.mixin` model # TODO: probably is better to move such methods # defined in `cms_info` to `base` model instead. # You might want to use a form on an a non-website model. # This should be considered if we move away from `website` # as a base and rely only on `portal` features. res = self._can_edit(raise_exception=False) msg = _('You cannot edit this record. Model: %s, ID: %s.') % ( self.main_object._name, self.main_object.id) else: if self._form_model: if hasattr(self.form_model, 'cms_can_create'): res = self.form_model.cms_can_create() else: # not `website.published.mixin` model res = self._can_create(raise_exception=False) msg = _('You are not allowed to create any record ' 'for the model `%s`.') % self._form_model if raise_exception and not res: raise exceptions.AccessError(msg) return res
def invite_partner_to_application(self, application_id, invitation_id, secure_hash, **params): salt = invitation_id.salt to_email = request.env.user.email text_to_hash = '%s%i-%s' % (salt, application_id, to_email) hash_to_compare = hashlib.sha256( text_to_hash.encode('utf-8')).hexdigest() if hash_to_compare != secure_hash: raise exceptions.AccessError( _("Ensure to copy the url as you get it")) # family = invitation_id.access_family_id parent = request.env.user.partner_id if not parent.family_ids: family_name = "Family of %s" % parent.name family = request.env['res.partner'].sudo().create({ 'name': family_name, 'is_family': True, 'is_company': True, 'member_ids': [(4, parent.id, False)] }) parent.write({'family_ids': [(4, family.id, False)]}) return http.request.render( 'adm.template_application_invite_partner', { "application_id": application_id, "request": request, "invitation_id": invitation_id.sudo(), "user": http.request.env.user, })
def _contact_iap(local_endpoint, params): sim_result = { 'name': 'Simulator INC', 'location': 'Simulator Street', 'city': 'SimCity', 'postal_code': '9876', 'country_code': 'BE', 'clearbit_id': 'idontknow', 'phone_numbers': ['+3269001122', '+32456001122'], 'twitter': 'testtwitter', 'facebook': 'testfacebook', } if default_data: sim_result.update(default_data) # mock single sms sending if local_endpoint == '/iap/clearbit/1/lead_enrichment_email': result = {} for lead_id, email in params['domains'].items(): if sim_error and sim_error == 'credit': raise iap_tools.InsufficientCreditError( 'InsufficientCreditError') elif sim_error and sim_error == 'jsonrpc_exception': raise exceptions.AccessError( 'The url that this service requested returned an error. Please contact the author of the app. The url it tried to contact was ' + local_endpoint) result[str(lead_id)] = dict(sim_result) if email_data and email_data.get(email): result[str(lead_id)].update(email_data[email]) return result
def get_tracking_information(self, picking): # Try to login to DPD successfull, error = self.login() if not successfull: raise exceptions.AccessError(error) try: action = 'getTrackingData' client = Client(self.dpd_get_url(action=action)) request = client.service._binding.create_message( action, parcelLabelNumber=picking.carrier_tracking_ref, _soapheaders=self.get_soap_headers()) error, response = self.dpd_send_message(action=action, request=request) if response.status_code == 200: node = etree.fromstring(response.content) states = [] for status_info in node.xpath('//statusInfo'): reached = get_data(status_info, 'statusHasBeenReached') status = get_data(status_info, 'status') current = get_data(status_info, 'isCurrentStatus') location = get_data(status_info, 'location/content') date = get_data(status_info, 'date/content') info = get_data(status_info, 'description/content/content') state = { 'state': status, 'reached': reached == 'true', 'current': current == 'true', 'location': location, 'date': date, 'extra_info': '' } infos = [info] for extra_info in status_info.xpath( 'importantItems/content'): infos.append(get_data(extra_info, 'content')) state['extra_info'] = '/'.join(infos) states.append(state) picking.update_tracking_information(data=states) if error: return error except zeep_exceptions.Fault as zeep_exception: errorcode = zeep_exception.detail[0][0].text errormessage = zeep_exception.detail[0][1].text if errorcode: logmessage = "An error occured." logmessage += "\nFull Response:%s\n" % errormessage else: logmessage = "An error occured." logmessage += "\nCode:%s\n" % zeep_exception.code logmessage += "\nMessage:%s\n" % zeep_exception.message raise exceptions.ValidationError(logmessage) return True
def schedule_exam(self): for exam in self: if exam.total_student > exam.room_capacity: raise exceptions.AccessError( _("Room capacity must be greater than total number \ of student")) student_ids = [] for student in exam.student_ids: student_ids.append(student.id) for room in exam.room_ids: for i in range(room.capacity): if not student_ids: continue self.env['op.exam.attendees'].create({ 'exam_id': exam.exam_id.id, 'student_id': student_ids[0], 'status': 'present', 'course_id': exam.course_id.id, 'batch_id': exam.batch_id.id, 'room_id': room.id }) student_ids.remove(student_ids[0]) exam.exam_id.state = 'schedule' return True
def create(self, vals_list): if 'image' not in vals_list: logo = self._get_logo(vals_list['channel']) path = os.path.join( os.path.abspath( os.path.dirname(os.path.abspath(__file__)) + os.path.sep + '..'), logo) with open(path, 'r+b') as fd: res = fd.read() if res: image = base64.b64encode(res).replace(b'\n', b'') vals_list['image'] = image tools.image_resize_images(vals_list) if not self._context.get('synchronizing'): self.check_access_rights('create') data = {'name': vals_list['name'], 'channel': vals_list['channel']} response = self.post('integrations', {'data': data}) if response.get('data').get('id'): vals_list['integration_id'] = response.get('data').get('id') return super(OmnaIntegration, self).create(vals_list) else: raise exceptions.AccessError( _("Error trying to push integration to Omna's API.")) else: return super(OmnaIntegration, self).create(vals_list)
def write(self, vals): self.ensure_one() if not self._context.get('synchronizing'): if 'integration_id' in vals: integration = self.env['omna.integration'].search( [('id', '=', vals['integration_id'])], limit=1) else: integration = self.env['omna.integration'].search( [('id', '=', self.integration_id.id)], limit=1) data = { 'address': vals['address'] if 'address' in vals else self.address, 'integration_id': integration.integration_id, 'topic': vals['topic'] if 'topic' in vals else self.topic } response = self.post('webhooks/%s' % self.omna_webhook_id, {'data': data}) if response.get('data').get('id'): vals['omna_webhook_id'] = response.get('data').get('id') return super(OmnaWebhook, self).write(vals) else: raise exceptions.AccessError( _("Error trying to update webhook in Omna's API.")) else: return super(OmnaWebhook, self).write(vals)
def write(self, vals): self.ensure_one() if not self._context.get('synchronizing'): if 'type' in vals: raise UserError( "You cannot change the type of a worflow. Instead you should delete the current workflow and create a new one of the proper type." ) if 'integration_id' in vals: raise UserError( "You cannot change the integration of a worflow. Instead you should delete the current workflow and create a new one of the proper type." ) data = {"scheduler": {}} if 'start_date' in vals: start_date = datetime.datetime.strptime( vals.get('start_date'), "%Y-%m-%d %H:%M:%S") data['scheduler']['start_date'] = start_date.date().strftime( "%Y-%m-%d") data['scheduler']['time'] = start_date.time().strftime("%H:%M") if 'end_date' in vals: end_date = datetime.datetime.strptime(vals.get('end_date'), "%Y-%m-%d") data['scheduler']['end_date'] = end_date.strftime("%Y-%m-%d") if 'days_of_week' in vals: dow = [] days = self.env['omna.filters'].search([ ('type', '=', 'dow'), ('id', 'in', vals.get('days_of_week')[0][2]) ]) for day in days: dow.append(day.name) data['scheduler']['days_of_week'] = dow if 'weeks_of_month' in vals: wom = [] weeks = self.env['omna.filters'].search([ ('type', '=', 'wom'), ('id', 'in', vals.get('weeks_of_month')[0][2]) ]) for week in weeks: wom.append(week.name) data['scheduler']['weeks_of_month'] = wom if 'months_of_year' in vals: moy = [] months = self.env['omna.filters'].search([ ('type', '=', 'moy'), ('id', 'in', vals.get('months_of_year')[0][2]) ]) for month in months: moy.append(month.name) data['scheduler']['months_of_year'] = moy response = self.post('flows/%s' % self.omna_id, {'data': data}) if 'id' in response.get('data'): return super(OmnaFlow, self).write(vals) else: raise exceptions.AccessError( _("Error trying to update the workflow in Omna.")) else: return super(OmnaFlow, self).write(vals)
def action_test_connection(self): successfull, error = self.login(force=True) if not successfull: raise exceptions.AccessError(error) return self.env.ref('delivery_dpd_be.' 'action_wizard_test_connection').read()[0]
def _contact_iap(local_endpoint, params): # mock single sms sending if local_endpoint == '/iap/message_send': self._sms += [{ 'number': number, 'body': params['message'], } for number in params['numbers']] return True # send_message v0 API returns always True # mock batch sending if local_endpoint == '/iap/sms/1/send': result = [] for to_send in params['messages']: res = { 'res_id': to_send['res_id'], 'state': 'success', 'credit': 1 } error = sim_error or (nbr_t_error and nbr_t_error.get( to_send['number'])) if error and error == 'credit': res.update(credit=0, state='insufficient_credit') elif error and error == 'wrong_format_number': res.update(state='wrong_format_number') elif error and error == 'jsonrpc_exception': raise exceptions.AccessError( 'The url that this service requested returned an error. Please contact the author of the app. The url it tried to contact was ' + local_endpoint) result.append(res) if res['state'] == 'success': self._sms.append({ 'number': to_send['number'], 'body': to_send['content'], }) return result
def _employee_crash(*args, **kwargs): """ If employee is test employee, consider he has no access on document """ recordset = args[0] if recordset.env.uid == self.user_employee.id: raise exceptions.AccessError( 'Hop hop hop Ernest, please step back.') return DEFAULT
def wrapped(*args, **kwargs): service = args[0] user = service.invader_partner_user if user is None: raise exceptions.AccessError(_("User not authenticated")) if checker_name in user._fields: checker = user[checker_name] elif hasattr(user, checker_name): checker = getattr(user, checker_name) else: # let if fail badly if not found checker = getattr(service, checker_name) result = checker() if callable(checker) else checker if not result: raise exceptions.AccessError(_("User not allowed")) return func(*args, **kwargs)
def _check_access(self, operation): """ Rule to access activities * create: check write rights on related document; * write: rule OR write rights on document; * unlink: rule OR write rights on document; """ self.check_access_rights( operation, raise_exception=True) # will raise an AccessError if operation in ('write', 'unlink'): try: self.check_access_rule(operation) except exceptions.AccessError: pass else: return doc_operation = 'read' if operation == 'read' else 'write' activity_to_documents = dict() for activity in self.sudo(): activity_to_documents.setdefault(activity.res_model, list()).append(activity.res_id) for model, res_ids in activity_to_documents.items(): self.env[model].check_access_rights(doc_operation, raise_exception=True) try: self.env[model].browse(res_ids).check_access_rule( doc_operation) except exceptions.AccessError: raise exceptions.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))
def jsonrpc(url, method='call', params=None): """ Calls the provided JSON-RPC endpoint, unwraps the result and returns JSON-RPC errors as exceptions. """ payload = { 'jsonrpc': '2.0', 'method': method, 'params': params, 'id': uuid.uuid4().hex, } _logger.info('iap jsonrpc %s', url) try: req = requests.post(url, json=payload) response = req.json() if 'error' in response: name = response['error']['data'].get('name').rpartition('.')[-1] message = response['error']['data'].get('message') if name == 'InsufficientCreditError': e_class = InsufficientCreditError elif name == 'AccessError': e_class = exceptions.AccessError elif name == 'UserError': e_class = exceptions.UserError else: raise requests.exceptions.ConnectionError() e = e_class(message) e.data = response['error']['data'] raise e return response.get('result') except (ValueError, requests.exceptions.ConnectionError, requests.exceptions.MissingSchema) as e: raise exceptions.AccessError('The url that this service requested returned an error. Please contact the author the app. The url it tried to contact was ' + url)