def errors(self): api_errors = ApiErrors() columns = self.__class__.__table__.columns._data for key in columns.keys(): column = columns[key] value = getattr(self, key) if not isinstance(column, Column): continue if not column.nullable \ and not column.foreign_keys \ and not column.primary_key \ and column.default is None \ and value is None: api_errors.add_error(key, 'Cette information est obligatoire') if value is None: continue if (isinstance(column.type, String) or isinstance(column.type, CHAR)) \ and not isinstance(column.type, sqlalchemy.Enum) \ and not isinstance(value, str): api_errors.add_error(key, 'doit être une chaîne de caractères') if (isinstance(column.type, String) or isinstance(column.type, CHAR)) \ and isinstance(value, str) \ and column.type.length \ and len(value) > column.type.length: api_errors.add_error( key, 'Vous devez saisir moins de ' + str(column.type.length) + ' caractères') if isinstance(column.type, Integer) \ and not isinstance(value, int): api_errors.add_error(key, 'doit être un entier') if isinstance(column.type, Float) \ and not isinstance(value, float): api_errors.add_error(key, 'doit être un nombre') return api_errors
def check_offer_is_editable(offer: Offer): if not offer.isEditable: error = ApiErrors() error.status_code = 400 error.add_error('global', "Les offres importées ne sont pas modifiables") raise error
def check_offer_id_is_present_in_request(offer_id: str): if offer_id is None: errors = ApiErrors() errors.status_code = 400 errors.add_error('global', 'Le paramètre offerId est obligatoire') errors.maybe_raise() raise errors
def ensure_can_be_updated(self): if self.lastProvider: errors = ApiErrors() errors.add_error( 'global', 'not allowed because data come from provider ' + element.lastProvider.name ) raise errors
def ensure_current_user_has_rights(rights, offerer_id, user=current_user): if not user.hasRights(rights, offerer_id): errors = ApiErrors() errors.add_error( 'global', "Vous n'avez pas les droits d'accès suffisant pour accéder à cette information." ) errors.status_code = 403 raise errors
def internal_error(error): tb = traceback.format_exc() oneline_stack = ''.join(tb).replace('\n', ' ### ') app.logger.error('500 on %s %s — %s', request.method, request.url, oneline_stack) e = ApiErrors() e.add_error( 'global', "Il semble que nous ayons des problèmes techniques :(" + " On répare ça au plus vite.") return jsonify(e.errors), 500
def check_single_order_by_string(order_by_string): order_by_string = order_by_string.strip(' ') optional_table_prefix = '("?\\w+"?\\.|)' column_identifier = '"?\\w+"?' optional_sorting_order = '(|\\s+desc|\\s+asc)' if not re.match( f'^{optional_table_prefix}{column_identifier}{optional_sorting_order}$', order_by_string, re.IGNORECASE): api_errors = ApiErrors() api_errors.add_error('order_by', 'Invalid order_by field : "%s"' % order_by_string) raise api_errors
def load_or_raise_error(obj_class, human_id): data = obj_class.query.filter_by(id=dehumanize(human_id)).first() if data is None: errors = ApiErrors() errors.add_error( 'global', 'Aucun objet ne correspond à cet identifiant dans notre base de données' ) errors.status_code = 400 raise errors else: return data
def _check_token(): if EXPORT_TOKEN is None or EXPORT_TOKEN == '': raise ValueError("Missing environment variable EXPORT_TOKEN") token = request.args.get('token') api_errors = ApiErrors() if token is None: api_errors.add_error( 'token', 'Vous devez préciser un jeton dans l' 'adresse (token=XXX)') if not token == EXPORT_TOKEN: api_errors.add_error('token', 'Le jeton est invalide') if api_errors.errors: raise api_errors
def list_venue_providers(): venue_id = request.args.get('venueId') if venue_id is None: e = ApiErrors() e.add_error('venueId', 'Vous devez obligatoirement fournir le paramètre venueId') return jsonify(e.errors), 400 vp_query = VenueProvider.query \ .filter_by(venueId=dehumanize(venue_id)) return jsonify([ as_dict(venue_provider, includes=VENUE_PROVIDER_INCLUDES) for venue_provider in vp_query.all() ])
def check_valid_edition(payload: dict): forbidden_keys = { 'idAtProviders', 'dateModifiedAtLastProvider', 'thumbCount', 'firstThumbDominantColor', 'owningOffererId', 'id', 'lastProviderId', 'dateCreated' } all_keys = payload.keys() keys_in_error = forbidden_keys.intersection(all_keys) if keys_in_error: errors = ApiErrors() for key in keys_in_error: errors.add_error(key, 'Vous ne pouvez pas modifier cette information') raise errors
def save(*objects): if not objects: return None # CUMULATE ERRORS IN ONE SINGLE API ERRORS DURING ADD TIME api_errors = ApiErrors() for obj in objects: with db.session.no_autoflush: obj_api_errors = obj.errors() if obj_api_errors.errors.keys(): api_errors.errors.update(obj_api_errors.errors) else: db.session.add(obj) # CHECK BEFORE COMMIT if api_errors.errors.keys(): raise api_errors # COMMIT try: db.session.commit() except DataError as de: api_errors.add_error(*PcObject.restize_data_error(de)) db.session.rollback() raise api_errors except IntegrityError as ie: api_errors.add_error(*PcObject.restize_integrity_error(ie)) db.session.rollback() raise api_errors except InternalError as ie: for obj in objects: api_errors.add_error(*obj.restize_internal_error(ie)) db.session.rollback() raise api_errors except TypeError as te: api_errors.add_error(*PcObject.restize_type_error(te)) db.session.rollback() raise api_errors except ValueError as ve: api_errors.add_error(*PcObject.restize_value_error(ve)) db.session.rollback() raise api_errors if api_errors.errors.keys(): raise api_errors
def query_with_order_by(query, order_by): if order_by: if type(order_by) == str: order_by = text(order_by) try: order_by = [order_by] if not isinstance(order_by, list) \ else order_by query = query.order_by(*order_by) except ProgrammingError as e: field = re.search('column "?(.*?)"? does not exist', e._message, re.IGNORECASE) if field: errors = ApiErrors() errors.add_error( 'order_by', 'order_by value references an unknown field : ' + field.group(1)) raise errors else: raise e return query
def get_sandbox(module_name, getter_name): if not hasattr(getters, module_name): errors = ApiErrors() errors.add_error( 'module', 'Il n\'existe pas de tel \"{}\" module de getters pour la sandbox'. format(module_name)) raise errors testcafes_module = getattr(getters, module_name) if not hasattr(testcafes_module, getter_name): errors = ApiErrors() errors.add_error( 'getter', 'Il n\'existe pas de tel \"{} {}\" getter pour la sandbox'.format( module_name, getter_name)) raise errors getter = getattr(testcafes_module, getter_name) try: obj = getter() return jsonify(obj) except: errors = ApiErrors() errors.add_error( 'query', 'Une erreur s\'est produite lors du calcul de \"{} {}\" pour la sandbox' .format(module_name, getter_name)) raise errors
def get_user_with_credentials(identifier: str, password: str) -> User: with auto_close_db_transaction(): user = find_user_by_email(identifier) errors = ApiErrors() errors.status_code = 401 if not user: errors.add_error('identifier', 'Identifiant incorrect') raise errors if not user.isValidated: errors.add_error('identifier', "Ce compte n'est pas validé.") raise errors if not user.checkPassword(password): errors.add_error('password', 'Mot de passe incorrect') raise errors return user
def export_table(model_name): _check_token() ae = ApiErrors() if model_name not in models.__all__: ae.add_error('global', 'Classe inconnue : ' + model_name) return jsonify(ae.errors), 400 try: model = getattr(models, model_name) except KeyError: ae.add_error('global', 'Nom de classe incorrect : ' + model_name) return jsonify(ae.errors), 400 if not _is_exportable(model_name): ae.add_error('global', 'Classe non exportable : ' + model_name) return jsonify(ae.errors), 400 objects = model.query.all() if len(objects) == 0: return "", 200 csvfile = StringIO() header = _clean_dict_for_export(model_name, as_dict(objects[0])).keys() if model_name == 'User': header = list(filter(lambda h: h != 'id' and h != 'password', header)) writer = csv.DictWriter(csvfile, header, extrasaction='ignore') writer.writeheader() for obj in objects: dct = _clean_dict_for_export(model_name, as_dict(obj)) writer.writerow(dct) csvfile.seek(0) mem = BytesIO() mem.write(csvfile.getvalue().encode('utf-8')) mem.seek(0) csvfile.close() return send_file(mem, attachment_filename='export.csv', as_attachment=True)
def check_offer_type_is_valid(offer_type_name): if not ProductType.is_thing(offer_type_name) and not ProductType.is_event( offer_type_name): api_error = ApiErrors() api_error.add_error('type', 'Le type de cette offre est inconnu') raise api_error
def check_has_venue_id(venue_id): if venue_id is None: api_errors = ApiErrors() api_errors.add_error('venueId', 'Vous devez préciser un identifiant de lieu') raise api_errors
def date_time_cast_error(error): api_errors = ApiErrors() app.logger.warning(json.dumps(error.errors)) for field in error.errors.keys(): api_errors.add_error(field, 'Format de date invalide') return jsonify(api_errors.errors), 400
def errors(self): errors = ApiErrors() if self.postalCode is not None\ and not re.match('^\d[AB0-9]\d{3,4}$', self.postalCode): errors.add_error('postalCode', 'Ce code postal est invalide') return errors
def decimal_cast_error(error): api_errors = ApiErrors() app.logger.warning(json.dumps(error.errors)) for field in error.errors.keys(): api_errors.add_error(field, 'Saisissez un nombre valide') return jsonify(api_errors.errors), 400
def invalid_id_for_dehumanize_error(error): api_errors = ApiErrors() api_errors.add_error('global', 'La page que vous recherchez n\'existe pas') app.logger.error('404 %s' % str(error)) return jsonify(api_errors.errors), 404
def check_validation_request(token): if token is None: error = ApiErrors() error.add_error('token', 'Vous devez fournir un jeton de validation') raise error
def restize_invalid_header_exception(e): e = ApiErrors() e.add_error('global', 'Header non autorisé') return jsonify(e.errors), 400
def send_401(): e = ApiErrors() e.add_error('global', 'Authentification nécessaire') return jsonify(e.errors), 401