API - remove intermediate directory and rename api directory

This commit is contained in:
Sam
2020-09-16 15:41:02 +02:00
parent 640385cdb7
commit af301b437e
148 changed files with 1953 additions and 1967 deletions

View File

View File

@ -0,0 +1,171 @@
from fittrackee import appLog, db
from flask import Blueprint, current_app, jsonify, request
from sqlalchemy.orm.exc import MultipleResultsFound, NoResultFound
from ..users.utils import authenticate_as_admin
from .models import AppConfig
from .utils import update_app_config_from_database
config_blueprint = Blueprint('config', __name__)
@config_blueprint.route('/config', methods=['GET'])
def get_application_config():
"""
Get Application config
**Example request**:
.. sourcecode:: http
GET /api/config HTTP/1.1
Content-Type: application/json
**Example response**:
.. sourcecode:: http
HTTP/1.1 200 OK
Content-Type: application/json
{
"data": {
"gpx_limit_import": 10,
"is_registration_enabled": false,
"max_single_file_size": 1048576,
"max_zip_file_size": 10485760,
"max_users": 0
},
"status": "success"
}
:statuscode 200: success
:statuscode 500: Error on getting configuration.
"""
try:
config = AppConfig.query.one()
response_object = {'status': 'success', 'data': config.serialize()}
return jsonify(response_object), 200
except (MultipleResultsFound, NoResultFound) as e:
appLog.error(e)
response_object = {
'status': 'error',
'message': 'Error on getting configuration.',
}
return jsonify(response_object), 500
@config_blueprint.route('/config', methods=['PATCH'])
@authenticate_as_admin
def update_application_config(auth_user_id):
"""
Update Application config
Authenticated user must be an admin
**Example request**:
.. sourcecode:: http
GET /api/config HTTP/1.1
Content-Type: application/json
**Example response**:
.. sourcecode:: http
HTTP/1.1 200 OK
Content-Type: application/json
{
"data": {
"gpx_limit_import": 10,
"is_registration_enabled": true,
"max_single_file_size": 1048576,
"max_zip_file_size": 10485760,
"max_users": 10
},
"status": "success"
}
:param integer auth_user_id: authenticate user id (from JSON Web Token)
:<json integrer gpx_limit_import: max number of files in zip archive
:<json boolean is_registration_enabled: is registration enabled ?
:<json integrer max_single_file_size: max size of a single file
:<json integrer max_zip_file_size: max size of a zip archive
:<json integrer max_users: max users allowed to register on instance
:reqheader Authorization: OAuth 2.0 Bearer Token
:statuscode 200: success
:statuscode 400: invalid payload
:statuscode 401:
- Provide a valid auth token.
- Signature expired. Please log in again.
- Invalid token. Please log in again.
:statuscode 403: You do not have permissions.
:statuscode 500: Error on updating configuration.
"""
config_data = request.get_json()
if not config_data:
response_object = {'status': 'error', 'message': 'Invalid payload.'}
return jsonify(response_object), 400
try:
config = AppConfig.query.one()
if 'gpx_limit_import' in config_data:
config.gpx_limit_import = config_data.get('gpx_limit_import')
if 'max_single_file_size' in config_data:
config.max_single_file_size = config_data.get(
'max_single_file_size'
)
if 'max_zip_file_size' in config_data:
config.max_zip_file_size = config_data.get('max_zip_file_size')
if 'max_users' in config_data:
config.max_users = config_data.get('max_users')
db.session.commit()
update_app_config_from_database(current_app, config)
response_object = {'status': 'success', 'data': config.serialize()}
code = 200
except Exception as e:
appLog.error(e)
response_object = {
'status': 'error',
'message': 'Error on updating configuration.',
}
code = 500
return jsonify(response_object), code
@config_blueprint.route('/ping', methods=['GET'])
def health_check():
"""health check endpoint
**Example request**:
.. sourcecode:: http
GET /api/ping HTTP/1.1
Content-Type: application/json
**Example response**:
.. sourcecode:: http
HTTP/1.1 200 OK
Content-Type: application/json
{
"message": "pong!",
"status": "success"
}
:statuscode 200: success
"""
return jsonify({'status': 'success', 'message': 'pong!'})

View File

@ -0,0 +1,57 @@
from fittrackee import db
from flask import current_app
from sqlalchemy.event import listens_for
from ..users.models import User
class AppConfig(db.Model):
__tablename__ = 'app_config'
id = db.Column(db.Integer, primary_key=True, autoincrement=True)
max_users = db.Column(db.Integer, default=0, nullable=False)
gpx_limit_import = db.Column(db.Integer, default=10, nullable=False)
max_single_file_size = db.Column(
db.Integer, default=1048576, nullable=False
)
max_zip_file_size = db.Column(db.Integer, default=10485760, nullable=False)
@property
def is_registration_enabled(self):
nb_users = User.query.count()
return self.max_users == 0 or nb_users < self.max_users
@property
def map_attribution(self):
return current_app.config['TILE_SERVER']['ATTRIBUTION']
def serialize(self):
return {
"gpx_limit_import": self.gpx_limit_import,
"is_registration_enabled": self.is_registration_enabled,
"max_single_file_size": self.max_single_file_size,
"max_zip_file_size": self.max_zip_file_size,
"max_users": self.max_users,
"map_attribution": self.map_attribution,
}
def update_app_config():
config = AppConfig.query.first()
if config:
current_app.config[
'is_registration_enabled'
] = config.is_registration_enabled
@listens_for(User, 'after_insert')
def on_user_insert(mapper, connection, user):
@listens_for(db.Session, 'after_flush', once=True)
def receive_after_flush(session, context):
update_app_config()
@listens_for(User, 'after_delete')
def on_user_delete(mapper, connection, old_user):
@listens_for(db.Session, 'after_flush', once=True)
def receive_after_flush(session, context):
update_app_config()

View File

@ -0,0 +1,46 @@
import os
from fittrackee import db
from fittrackee.users.models import User
from .models import AppConfig
MAX_FILE_SIZE = 1 * 1024 * 1024 # 1MB
def init_config():
"""
init application configuration if not existing in database
Note: get some configuration values from env variables
(for FitTrackee versions prior to v0.3.0)
"""
existing_config = AppConfig.query.one_or_none()
nb_users = User.query.count()
if not existing_config:
config = AppConfig()
config.max_users = (
nb_users
if os.getenv('REACT_APP_ALLOW_REGISTRATION') == "false"
else 0
)
config.max_single_file_size = os.environ.get(
'REACT_APP_MAX_SINGLE_FILE_SIZE', MAX_FILE_SIZE
)
config.max_zip_file_size = os.environ.get(
'REACT_APP_MAX_ZIP_FILE_SIZE', MAX_FILE_SIZE * 10
)
db.session.add(config)
db.session.commit()
return True, config
return False, existing_config
def update_app_config_from_database(current_app, db_config):
current_app.config['gpx_limit_import'] = db_config.gpx_limit_import
current_app.config['max_single_file_size'] = db_config.max_single_file_size
current_app.config['MAX_CONTENT_LENGTH'] = db_config.max_zip_file_size
current_app.config['max_users'] = db_config.max_users
current_app.config[
'is_registration_enabled'
] = db_config.is_registration_enabled