예제 #1
0
 def wrapper(*args, **kwargs):
     if not current_user.is_authenticated:
         api_errors = ApiErrors()
         api_errors.status_code = 403
         api_errors.add_error('global', "API key or login required")
         raise api_errors
     return f(*args, **kwargs)
예제 #2
0
def check_has_role(user, role_type):
    try:
        Role.query.filter_by(user=user, type=role_type).one()
        return True
    except NoResultFound:
        api_errors = ApiErrors()
        api_errors.add_error('global', "You don't have the rights for this")
        raise api_errors
예제 #3
0
def get_scrap():
    try:
        content = content_from_url(request.args.get('url'))
    except ArticleException:
        api_errors = ApiErrors()
        api_errors.add_error('url', 'url is invalid')
        raise api_errors

    return jsonify(as_dict(content))
예제 #4
0
def internal_error(exception):
    tb = traceback.format_exc()
    oneline_stack = ''.join(tb).replace('\n', ' ### ')
    app.logger.error('500 on %s %s — %s', request.method, request.url,
                     oneline_stack)
    api_errors = ApiErrors()
    api_errors.add_error(
        'global', "Il semble que nous ayons des problèmes techniques :(" +
        " On répare ça au plus vite.")
    return jsonify([api_errors.errors]), 500
예제 #5
0
def check_allowed_changes_for_user(data):
    changes_allowed = {'email'}
    changes_asked = set(data)
    api_errors = ApiErrors()
    changes_not_allowed = changes_asked.difference(changes_allowed)
    if changes_not_allowed:
        for change in changes_not_allowed:
            api_errors.add_error(
                change, 'Vous ne pouvez pas changer cette information')
        raise api_errors
예제 #6
0
def internal_error(exception):
    tb = traceback.format_exc()
    oneline_stack = ''.join(tb).replace('\n', ' ### ')
    app.logger.error('500 on %s %s — %s',
                     request.method, request.url, oneline_stack)
    api_errors = ApiErrors()
    api_errors.add_error(
        'global',
        'It seems whe have troubles with our server... We will fix soon as we can !'
    )
    return jsonify([api_errors.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
예제 #8
0
def get_trending(source_id):
    trending_type = request.args.get('type', 'article')

    trending = trending_from(trending_type, source_id)

    if not trending:
        api_errors = ApiErrors()
        api_errors.add_error(
            'sourceId', '{} {} not found'.format(trending_type, source_id))
        raise api_errors

    return jsonify(trending), 200
예제 #9
0
def get_sandbox(getter_name):
    for key in dir(getters):
        module = getattr(getters, key)
        if hasattr(module, getter_name):
            getter = getattr(module, getter_name)
            obj = getter()
            return jsonify(obj)

    errors = ApiErrors()
    errors.add_error(
        'getter',
        'Il n\'existe pas de tel \"{}\" getter pour la sandbox'.format(
            getter_name))
    raise errors
예제 #10
0
def post_new_password():
    validate_new_password_request(request)
    token = request.get_json()['token']
    new_password = request.get_json()['newPassword']
    user = find_user_by_reset_password_token(token)

    if not user:
        api_errors = ApiErrors()
        api_errors.add_error('token', 'Votre lien de changement de mot de passe est invalide.')
        raise api_errors

    check_reset_token_validity(user)
    check_password_strength('newPassword', new_password)
    user.set_password(new_password)
    ApiHandler.save(user)
    return '', 204
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
예제 #12
0
def get_credentials_from_service_account_string(service_account_string):
    if service_account_string is None:
        errors = ApiErrors()
        errors.add_error('file', 'Bad google credentials.')
        raise errors

    json_payload = json.loads(service_account_string)
    json_path = '{}/{}_client_secret.json'.format(
        GOOGLE_TMP_PATH,
        json_payload['client_email'].split('@')[0].replace('-', '_'))
    with open(json_path, 'w') as outfile:
        json.dump(json_payload, outfile)

    credentials = service_account.Credentials.from_service_account_file(
        json_path, scopes=SCOPES)

    return credentials
예제 #13
0
def find_file_from_name(name,
                        drive_id=None,
                        parent_folder_id=None,
                        service_account_string=None):
    files = find_files_from_name(name,
                                 drive_id=drive_id,
                                 parent_folder_id=parent_folder_id,
                                 service_account_string=service_account_string)

    files_count = len(files)
    if files_count == 1:
        return files[0]

    if files_count > 1:
        errors = ApiErrors()
        errors.add_error('file', 'Found several files for this name')
        raise errors
예제 #14
0
def validate_reset_request(request):
    if 'email' not in request.get_json():
        errors = ApiErrors()
        errors.add_error('email', 'Email is missing.')
        raise errors

    if not request.get_json()['email']:
        errors = ApiErrors()
        errors.add_error('email', 'This Email is empty.')
        raise errors
예제 #15
0
def validate_new_password_request(request):
    if 'token' not in request.get_json():
        errors = ApiErrors()
        errors.add_error('token', 'Your token link is invalid.')
        raise errors

    if 'newPassword' not in request.get_json():
        errors = ApiErrors()
        errors.add_error('newPassword', 'You need to enter a new password.')
        raise errors
예제 #16
0
def get_credentials_from_service_account_string(service_account_string):

    if service_account_string is None:
        errors = ApiErrors()
        errors.add_error('file', 'Bad google credentials.')
        raise errors

    json_payload = json.loads(service_account_string)
    json_path = '/tmp/client_secret.json'
    with open(json_path, 'w') as outfile:
        json.dump(json_payload, outfile)

    credentials = service_account.Credentials.from_service_account_file(
        json_path, scopes=SCOPES)

    os.remove(json_path)

    return credentials
예제 #17
0
def check_thumb_in_request(files, form):
    missing_image_error = ApiErrors({'thumb': ["This field is obligatory"]})

    if 'thumb' in files:
        if files['thumb'].filename == '':
            raise missing_image_error

    elif 'thumbUrl' not in form:
        raise missing_image_error
예제 #18
0
def read_thumb(files=None, form=None):
    if 'thumb' in files:
        thumb = files['thumb']
        filename_parts = thumb.filename.rsplit('.', 1)
        if len(filename_parts) < 2 \
                or filename_parts[1].lower() not in ALLOWED_EXTENSIONS:
            raise ApiErrors({
                'thumb': [
                    f"Cette image manque d'une extension {READABLE_EXTENSIONS} ou son format n'est pas autorisé"
                ]
            })
        return thumb.read()

    if 'thumbUrl' in form:
        try:
            return _fetch_image(form['thumbUrl'])
        except ValueError as e:
            logger.error(e)
            raise ApiErrors(
                {'thumbUrl': ["Th L'adresse saisie n'est pas valide"]})
예제 #19
0
def check_password_strength(field_name, field_value):
    at_least_one_uppercase = '(?=.*?[A-Z])'
    at_least_one_lowercase = '(?=.*?[a-z])'
    at_least_one_digit = '(?=.*?[0-9])'
    min_length = '.{12,}'
    at_least_one_special_char = '(?=.*?[#~|=;:,+><?!@$%^&*_.-])'

    regex = '^' \
            + at_least_one_uppercase \
            + at_least_one_lowercase \
            + at_least_one_digit \
            + at_least_one_special_char \
            + min_length \
            + '$'

    if not re.match(regex, field_value):
        errors = ApiErrors()
        errors.add_error(
            field_name,
            'Le mot de passe doit faire au moins 12 caractères et contenir à minima '
            '1 majuscule, 1 minuscule, 1 chiffre et 1 caractère spécial parmi _-&?~#|^@=+.$,<>%*!:;'
        )
        raise errors
예제 #20
0
def check_thumb_quality(thumb: bytes):
    errors = []

    if len(thumb) < MINIMUM_FILE_SIZE:
        errors.append("L'image doit faire 100 ko minimum")

    image = Image.open(BytesIO(thumb))
    if image.width < 400 or image.height < 400:
        errors.append("L'image doit faire 400 * 400 px minimum")

    if len(errors) > 1:
        errors = ["L'image doit faire 100 ko minimum et 400 * 400 px minimum"]

    if errors:
        raise ApiErrors({'thumb': errors})
예제 #21
0
def validate_change_password_request(json):
    errors = ApiErrors()

    if 'oldPassword' not in json:
        errors.add_error('oldPassword', 'Old password is missing.')
        raise errors

    if 'newPassword' not in json:
        errors.add_error('newPassword', 'New password is missing.')
        raise errors
예제 #22
0
def check_new_password_validity(user, old_password, new_password):
    errors = ApiErrors()

    if not user.check_password(old_password):
        errors.add_error('oldPassword', 'Your old password is incorrect.')
        raise errors

    if user.check_password(new_password):
        errors.add_error('newPassword', 'You new password is the same as the old one.')
        raise errors
예제 #23
0
def _fetch_image(thumb_url: str) -> bytes:
    if not thumb_url[0:4] == 'http':
        raise ValueError('Invalid thumb URL : %s' % thumb_url)

    try:
        response = requests.get(thumb_url)
    except Exception as e:
        logger.error(e)
        raise ApiErrors({
            'thumbUrl': ["Impossible de télécharger l'image à cette adresse"]
        })
    content_type = response.headers['Content-type']
    is_an_image = content_type.split('/')[0] == 'image'

    if response.status_code == 200 and is_an_image:
        return response.content
    else:
        raise ValueError(
            'Error downloading thumb from url %s (status_code : %s)' %
            (thumb_url, str(response.status_code)))
예제 #24
0
def _find_folder_from_name(name,
                           drive_id=None,
                           force_create=False,
                           parent_folder_id=None,
                           service_account_string=None):
    body = {'mimeType': 'application/vnd.google-apps.folder', 'name': name}

    if not parent_folder_id:
        parent_folder_id = drive_id

    body['parents'] = [parent_folder_id]

    folders = find_folders_from_name(
        name,
        drive_id=drive_id,
        parent_folder_id=parent_folder_id,
        service_account_string=service_account_string)

    folders_count = len(folders)
    if folders_count == 1:
        return folders[0]

    if folders_count > 1:
        errors = ApiErrors()
        errors.add_error('name', 'Found several folders for this name')
        raise errors

    if force_create:
        return create_google_service('drive', service_account_string).files() \
                .create(
                    body=body,
                    fields='id',
                    supportsAllDrives=True) \
                .execute()

    errors = ApiErrors()
    errors.add_error('folder', '{} folder was not found.'.format(name))
    raise errors
예제 #25
0
def check_thumb_quality(thumb: bytes):
    errors = []

    if len(thumb) < MINIMUM_FILE_SIZE:
        errors.append('Picture must have a minimal size of {} ko.'.format(
            MINIMUM_FILE_SIZE))

    image = Image.open(BytesIO(thumb))
    print(image.width, image.height)
    if image.width < MINIMUM_HEIGHT_SIZE or image.height < MINIMUM_WIDTH_SIZE:
        errors.append('Picture must be at least {} * {} px.'.format(
            MINIMUM_WIDTH_SIZE, MINIMUM_HEIGHT_SIZE))

    if len(errors) > 1:
        errors = [
            'Picture must have a minimal size of {} ko and at least {} * {} px.'
            .format(MINIMUM_FILE_SIZE, MINIMUM_WIDTH_SIZE, MINIMUM_HEIGHT_SIZE)
        ]

    if errors:
        raise ApiErrors({'thumb': errors})
예제 #26
0
def restize_not_found_route_errors(exception):
    api_errors = ApiErrors()
    api_errors.add_error('data', 'Not Found')
    return jsonify([api_errors.errors]), 404
예제 #27
0
def check_reset_token_validity(user):
    if datetime.utcnow() > user.resetPasswordTokenValidityLimit:
        errors = ApiErrors()
        errors.add_error('token',
                        'Votre lien de changement de mot de passe est périmé. Veuillez effecture une nouvelle demande.')
        raise errors
예제 #28
0
def check_and_read_files_thumb(files=None):
    if 'thumb' in files:
        thumb = files['thumb']
        if files['thumb'].filename == '':
            api_errors = ApiErrors()
            api_errors.add_error('thumb',
                                 "You need a name for your thumb file")
            raise api_errors
        filename_parts = thumb.filename.rsplit('.', 1)
        if len(filename_parts) < 2 \
           or filename_parts[1].lower() not in ALLOWED_EXTENSIONS:
            api_errors = ApiErrors()
            api_errors.add_error(
                'thumb',
                "This thumb needs a (.png, .jpg...) like or its format is not authorized"
            )
            raise api_errors
        return thumb.read()

    api_errors = ApiErrors()
    api_errors.add_error('thumb',
                         "You need to provide a thumb in your request")
    raise api_errors
예제 #29
0
def send_401():
    api_errors = ApiErrors()
    api_errors.add_error('global', 'Authentification nécessaire')
    return jsonify([api_errors.errors]), 401
예제 #30
0
def invalid_id_for_dehumanize_error(exception):
    api_errors = ApiErrors()
    api_errors.add_error('global', 'La page que vous recherchez n\'existe pas')
    app.logger.error('404 %s' % str(exception))
    return jsonify([api_errors.errors]), 404