app_id=app.config['ONESIGNAL_CSH_APP_ID']) intro_onesignal_client = onesignal.Client(user_auth_key=app.config['ONESIGNAL_USER_AUTH_KEY'], app_auth_key=app.config['ONESIGNAL_INTRO_APP_AUTH_KEY'], app_id=app.config['ONESIGNAL_INTRO_APP_ID']) # OIDC Auth auth = OIDCAuthentication({'app': APP_CONFIG}, app) # LDAP _ldap = csh_ldap.CSHLDAP(app.config['LDAP_BIND_DN'], app.config['LDAP_BIND_PASS']) # Sentry sentry_sdk.init( dsn=app.config['SENTRY_DSN'], integrations=[FlaskIntegration(), SqlalchemyIntegration()] ) app.logger.info('OIDCAuth and LDAP configured') # pylint: disable=wrong-import-position from . import models from . import context_processors from . import commands from .routes import api, shared if app.config['REALM'] == 'csh': from .routes import upperclassmen from .routes import admin else: from .routes import freshmen
import os from flask import Flask import sentry_sdk from sentry_sdk.integrations.flask import FlaskIntegration from instance.config import app_config # Sentry integration with flask app if os.environ.get('SENTRY_DSN'): sentry_sdk.init( dsn=os.environ.get('SENTRY_DSN'), integrations=[FlaskIntegration()] ) def create_app(config_name): app = Flask(__name__) app.config.from_object(app_config[config_name]) # Init all extensions init_extensions(app) # Register API Endpoints init_blueprint(app) return app
def create_app() -> Flask: """This function creates application with predefined settings that depends on environment variable of a system. """ application = Flask(__name__, template_folder=settings.TEMPLATE_DIR, static_folder=settings.STATIC_DIR) # Load configuration. environment = os.environ.get('APP_ENV', 'dev') environments = { 'dev': settings.Dev, 'prod': settings.Prod, 'testing': settings.Testing } if environment in environments: application.config.from_object(environments[environment]) else: raise EnvironmentError('Application variable has not been specified.') # Initialize third-party libs. babel.init_app(application) db.init_app(application) migration.init_app(application, db) # Initialize sentry integration. sentry_sdk.init(environment=environment, integrations=[FlaskIntegration()]) @babel.localeselector def get_locale(): return g.get('lang', application.config['BABEL_DEFAULT_LOCALE']) @application.url_defaults def set_language_code(endpoint, values): if 'lang' in values or not g.get('lang', None): return if application.url_map.is_endpoint_expecting(endpoint, 'lang'): values['lang'] = g.lang @application.url_value_preprocessor def get_language_code(endpoint, values): if values is not None: g.lang = values.pop('lang', None) @application.before_request def ensure_language_support(): lang = g.get('lang', None) if lang and lang not in application.config['LANGUAGES'].keys(): return abort(404) @application.errorhandler(404) def not_found(error): lang = request.path.split('/')[1].lower() if lang and lang in application.config['LANGUAGES'].keys(): g.lang = lang else: g.lang = 'uk' return render_template('404.html'), 404 # Register blueprints from admin.views import admin_bp from app.views import app_bp application.register_blueprint(admin_bp) application.register_blueprint(app_bp) application.register_blueprint(app_bp, url_prefix='/<lang>') return application
import sentry_sdk from flask import Flask from sentry_sdk.integrations.flask import FlaskIntegration from app import create_app sentry_sdk.init(integrations=[FlaskIntegration()], traces_sample_rate=1.0) application = Flask('app') create_app(application)
def printLog(*args, **kwargs): print(*args, **kwargs) with open('output.out', 'a') as file: print(*args, **kwargs, file=file) printLog('Codename server start') logging.warning( 'Watch out! Codename server start') # will print a message to the console logging.info('I told you so Codename server start') # will not print anything # init sentry sentry_dsn = os.getenv("SENTRY_DSN") if sentry_dsn: sentry_sdk.init(dsn=sentry_dsn, integrations=[FlaskIntegration()]) app = Flask(__name__) socketio = SocketIO(app) app.secret_key = os.getenv("SECRET_KEY", "") # set up logging if not app.debug: gunicorn_logger = logging.getLogger('gunicorn.error') app.logger.handlers = gunicorn_logger.handlers app.logger.setLevel(gunicorn_logger.level) ROOMS = {} @app.route('/prune')
from flask import Flask, request, jsonify from waitress import serve import os import logging import sentry_sdk from sentry_sdk.integrations.flask import FlaskIntegration from function import handler app = Flask(__name__) logging.basicConfig(level=logging.DEBUG) dns = "https://8f22032536a641d5b017e888e28073fd" "@o71452.ingest.sentry.io/5278583" env = os.environ.get("APP_ENV", "development") sentry_sdk.init(dns, integrations=[FlaskIntegration()], environment=env) class Event: def __init__(self): if request.is_json: self.body = request.get_json() else: self.body = request.get_data() self.headers = request.headers self.method = request.method self.query = request.args self.path = request.path class Context:
def create_app(): import config import logging.config import os from flask_jwt_extended import JWTManager from . import api, models from file_management import helpers from file_management import services def load_app_config(app): """ Load app's configurations :param flask.Flask app: :return: """ app.config.from_object(config) app.config.from_pyfile('config.py', silent=True) app = flask.Flask(__name__, instance_relative_config=True, instance_path=os.path.join(config.ROOT_DIR, 'instance')) load_app_config(app) # Register new flask project here and get new dsn: https://sentry.io dns = SENTRY_DSN if os.environ.get('SEND_REPORT') == 'true' else None app.config['SENTRY_CONFIG'] = { 'ignore_exceptions': [ NotFoundException, UnAuthorizedException, BadRequestException, ForbiddenException ], 'level': logging.ERROR, } sentry_sdk.init(dsn=dns, integrations=[FlaskIntegration()], environment=app.config['ENV_MODE'], in_app_exclude=['app.extensions.exceptions'], before_send=before_send) # setup jwt extended app.config['JWT_SECRET_KEY'] = os.environ['SECRET_KEY'] app.config['JWT_TOKEN_LOCATION'] = ['cookies'] # How long an access token should live before it expires. Set by minutes (int) app.config['JWT_ACCESS_TOKEN_EXPIRES'] = int( os.environ['TOKEN_UPTIME']) * 60 # app.config['JWT_REFRESH_COOKIE_PATH'] = '/token/refresh' # app.config['JWT_ACCESS_COOKIE_PATH'] = '/api/' # should not, but i will use it in this app. app.config['JWT_COOKIE_CSRF_PROTECT'] = False jwt = JWTManager(app) app.config['CORS_SUPPORTS_CREDENTIALS'] = True # setup logging logging.config.fileConfig(app.config['LOGGING_CONFIG_FILE'], disable_existing_loggers=False) app.secret_key = config.FLASK_APP_SECRET_KEY models.init_app(app) api.init_app(app) services.init_app(app) CORS(app) return app
def create_app(config_name): from app.models import Exam, Visit, User, Metric, Category sentry_sdk.init(dsn=app_config[config_name].SENTRY_URL, integrations=[FlaskIntegration()]) app = FlaskAPI(__name__, instance_relative_config=True) cors = CORS(app, resources={r"/*": {"origins": "*"}}) app.config.from_object(app_config[config_name]) app.config.from_pyfile('config.py') app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False db.init_app(app) def token_required(f): @wraps(f) def decorated(*args, **kwargs): if 'Authorization' not in request.headers: return jsonify({'message': 'Token is missing!'}), 401 token = request.headers['Authorization'] try: data = jwt.decode(token, app.config['SECRET']) current_user = User.query.filter_by(id=data['id']).first() except DecodeError: return jsonify({'message': 'Token is invalid!'}), 401 except NoResultFound: return jsonify({'message': 'Token is invalid!'}), 401 except ExpiredSignatureError: return jsonify({'message': 'Token is invalid!'}), 401 return f(current_user, *args, **kwargs) return decorated @app.route('/exams', methods=['POST', 'GET']) @token_required def exam(user): if request.method == 'POST': try: metric_id = request.data['metricId'] visit_id = request.data['visitId'] value = request.data['value'] except KeyError: return {}, 400 metric = Metric.query.filter_by(id=metric_id) visit = Visit.query.filter_by(id=visit_id) if not user.admin: metric = metric.filter_by(gender=user.gender) visit = visit.filter_by(user=user) metric = metric.first() visit = visit.first() if visit is None or metric is None: return {}, 400 exam = Exam(value=value, metric=metric, visit=visit) exam.save() visit.date_modified = exam.date_modified visit.save() response = jsonify({ 'id': exam.id, 'value': exam.value, 'dateCreated': exam.date_created, 'dateModified': exam.date_modified, 'visitId': exam.visit.id, 'metricId': exam.metric.id, 'metricName': exam.metric.name }) response.status_code = 201 return response else: try: visit_id = request.values['visitId'] except KeyError: if user.admin: exams = Exam.get_all() else: visit_ids = Visit.query.filter_by(user=user).with_entities( Visit.id) exams = Exam.query.filter(Exam.visit_id.in_(visit_ids)) else: visit = Visit.query.filter_by(id=visit_id) if not user.admin: visit = visit.filter_by(user=user) visit = visit.first() exams = Exam.query.filter_by(visit=visit).order_by( Exam.metric_id) results = [] for exam in exams: obj = { 'id': exam.id, 'value': exam.value, 'dateCreated': exam.date_created, 'dateModified': exam.date_modified, 'visitId': exam.visit.id, 'metricId': exam.metric.id, 'metricName': exam.metric.name } results.append(obj) response = jsonify(results) response.status_code = 200 return response @app.route('/exams/<int:id>', methods=['GET', 'PUT', 'DELETE']) @token_required def exam_details(user, id, **kwargs): if user.admin: exam = Exam.query.get_or_404(id) else: visit_ids = Visit.query.filter_by(user=user).with_entities( Visit.id) exam = Exam.query.filter(Exam.visit_id.in_(visit_ids)).filter_by( id=id, ).first() if not exam: abort(404) if request.method == 'DELETE': visit = exam.visit visit.date_modified = datetime.datetime.now() visit.save() exam.delete() return { "message": "exam {} deleted successfully".format(exam.id) }, 200 elif request.method == 'PUT': exam.value = request.data.get('value', exam.value) # No control for authorization # metric_id = request.data.get('metricId', exam.metric.id) # visit_id = request.data.get('visitId', exam.visit.id) # exam.metric = Metric.query.get(metric_id) # exam.visit = Visit.query.get(visit_id) exam.save() response = jsonify({ 'id': exam.id, 'value': exam.value, 'dateCreated': exam.date_created, 'dateModified': exam.date_modified, 'metricId': exam.metric.id, 'visitId': exam.visit.id }) visit = exam.visit visit.date_modified = exam.date_modified visit.save() response.status_code = 200 return response else: # GET response = jsonify({ 'id': exam.id, 'value': exam.value, 'dateCreated': exam.date_created, 'dateModified': exam.date_modified, 'metricId': exam.metric.id, 'visitId': exam.visit.id }) response.status_code = 200 return response @app.route('/exams/statistics', methods=['GET']) @token_required def exam_statistics(user): if user.admin: visit_id = request.args.getlist('visits[]', type=int) if not len(visit_id): params = request.values.to_dict() gender = params.pop('gender') filter_age = params.pop('age').split(',') visits = Visit.get_all() visit_id = [] for visit in visits: age = (datetime.datetime.now() - visit.user.birth_date).days // 365.2425 if visit.user.gender != gender: continue if age < int(filter_age[0]) or age > int(filter_age[1]): continue exams = visit.exams good_visit = True for key, value in params.items(): values = value.split(',') for exam in exams: if exam.metric.name == key: if exam.value < int( values[0]) or exam.value > int( values[1]): good_visit = False break if good_visit: visit_id.append(visit.id) if not params: visit_id.append(visit.id) else: visit_id = [] visits = Visit.query.filter_by(user=user) for visit in visits: visit_id.append(visit.id) avgs = Exam.query.with_entities( Exam.metric_id, func.avg(Exam.value).label('avg')).filter( Exam.visit_id.in_(visit_id)).group_by(Exam.metric_id).all() results = [] for avg in avgs: metric = Metric.query.filter_by(id=avg[0]).first() obj = {'metricName': metric.name, 'value': int(avg[1])} results.append(obj) response = jsonify(results) response.status_code = 200 return response @app.route('/visits', methods=['POST', 'GET']) @token_required def visit(user): if request.method == 'POST': try: name = str(request.data['name']) except KeyError: return {}, 400 visit = Visit(name=name, user=user) visit.save() response = jsonify({ 'id': visit.id, 'name': visit.name, 'dateCreated': visit.date_created, 'dateModified': visit.date_modified, 'userUsername': visit.user.username }) response.status_code = 201 return response else: if user.admin: filter_user = request.values.get('user') if filter_user is None: visits = Visit.query.filter_by() else: visits = Visit.query.filter_by(user_id=filter_user) else: visits = Visit.query.filter_by(user=user) visits = visits.order_by(Visit.date_created) results = [] for visit in visits: obj = { 'id': visit.id, 'name': visit.name, 'dateCreated': visit.date_created, 'dateModified': visit.date_modified, 'userUsername': visit.user.username, 'userGender': visit.user.gender } results.append(obj) response = jsonify(results) response.status_code = 200 return response @app.route('/visits/<int:id>', methods=['GET', 'PUT', 'DELETE']) @token_required def visit_details(user, id, **kwargs): visit = Visit.query.filter_by(id=id) if not user.admin: visit = visit.filter_by(user=user) visit = visit.first() if not visit: return {}, 404 if request.method == 'DELETE': visit.delete() return { "message": "visit {} deleted successfully".format(visit.id) }, 200 elif request.method == 'PUT': visit.name = str(request.data.get('name', visit.name)) visit.save() response = jsonify({ 'id': visit.id, 'name': visit.name, 'dateCreated': visit.date_created, 'dateModified': visit.date_modified, 'userUsername': visit.user.username, 'userGender': visit.user.gender }) response.status_code = 200 return response else: # GET response = jsonify({ 'id': visit.id, 'name': visit.name, 'dateCreated': visit.date_created, 'dateModified': visit.date_modified, 'userUsername': visit.user.username, 'userGender': visit.user.gender }) response.status_code = 200 return response @app.route('/visits/exams', methods=['POST', 'GET']) @token_required def exam_group(user): if not user.admin: return {}, 403 user_id = request.values.get('userId', user.id) visits = Visit.query.filter_by(user_id=user_id).order_by( Visit.date_modified) results = [] for visit in visits: result = { 'id': visit.id, 'name': visit.name, 'dateCreated': visit.date_created, 'dateModified': visit.date_modified, 'userUsername': visit.user.username, 'userGender': visit.user.gender, 'exams': [] } for exam in visit.exams: obj = { 'id': exam.id, 'value': exam.value, 'dateCreated': exam.date_created, 'dateModified': exam.date_modified, 'visitId': exam.visit.id, 'metricId': exam.metric.id, 'metricName': exam.metric.name } result['exams'].append(obj) results.append(result) response = jsonify(results) response.status_code = 200 return response @app.route('/metrics', methods=['POST', 'GET']) @token_required def metric(user): if request.method == 'POST': if not user.admin: return {}, 403 category_id = request.data.get('categoryId', None) metric = Metric( name=str(request.data['name']), weight=request.data['weight'], unit_label=str(request.data['unitLabel']), total_range_min=request.data['totalRangeMin'], total_range_max=request.data['totalRangeMax'], healthy_range_min=request.data['healthyRangeMin'], healthy_range_max=request.data['healthyRangeMax'], gender=str(request.data['gender']), ) try: category = Category.query.get(category_id) metric.category = category except: db.session.rollback() metric.save() response = jsonify({ 'id': metric.id, 'name': metric.name, 'weight': metric.weight, 'unitLabel': metric.unit_label, 'totalRangeMin': metric.total_range_min, 'totalRangeMax': metric.total_range_max, 'healthyRangeMin': metric.healthy_range_min, 'healthyRangeMax': metric.healthy_range_max, 'gender': metric.gender, 'categoryId': None if metric.category is None else metric.category.id, 'categoryName': None if metric.category is None else metric.category.name }) response.status_code = 201 return response else: gender = request.values.get('gender', None) if gender is None: metrics = Metric.get_all() else: metrics = Metric.query.filter_by(gender=gender) results = [] for metric in metrics: obj = { 'id': metric.id, 'name': metric.name, 'weight': metric.weight, 'unitLabel': metric.unit_label, 'totalRangeMin': metric.total_range_min, 'totalRangeMax': metric.total_range_max, 'healthyRangeMin': metric.healthy_range_min, 'healthyRangeMax': metric.healthy_range_max, 'gender': metric.gender, 'categoryId': None if metric.category is None else metric.category.id, 'categoryName': None if metric.category is None else metric.category.name } results.append(obj) response = jsonify(results) response.status_code = 200 return response @app.route('/metrics/<int:id>', methods=['GET', 'PUT', 'DELETE']) @token_required def metric_details(user, id, **kwargs): if not user.admin: return {}, 403 metric = Metric.query.get_or_404(id) if request.method == 'DELETE': metric.delete() return { "message": "metric {} deleted successfully".format(metric.id) }, 200 elif request.method == 'PUT': metric.name = str(request.data.get('name', metric.name)) metric.weight = request.data.get('weight', metric.weight) metric.unit_label = str( request.data.get('unitLabel', metric.unit_label)) metric.total_range_min = request.data.get('totalRangeMin', metric.total_range_min) metric.total_range_max = request.data.get('totalRangeMax', metric.total_range_max) metric.healthy_range_min = request.data.get( 'healthyRangeMin', metric.healthy_range_min) metric.healthy_range_max = request.data.get( 'healthyRangeMax', metric.healthy_range_max) metric.gender = request.data.get('gender', metric.gender) metric.save() response = jsonify({ 'id': metric.id, 'name': metric.name, 'weight': metric.weight, 'unitLabel': metric.unit_label, 'totalRangeMin': metric.total_range_min, 'totalRangeMax': metric.total_range_max, 'healthyRangeMin': metric.healthy_range_min, 'healthyRangeMax': metric.healthy_range_max, 'gender': metric.gender, 'categoryId': None if metric.category is None else metric.category.id, 'categoryName': None if metric.category is None else metric.category.name }) response.status_code = 200 return response else: response = jsonify({ 'id': metric.id, 'name': metric.name, 'weight': metric.weight, 'unitLabel': metric.unit_label, 'totalRangeMin': metric.total_range_min, 'totalRangeMax': metric.total_range_max, 'healthyRangeMin': metric.healthy_range_min, 'healthyRangeMax': metric.healthy_range_max, 'gender': metric.gender, 'categoryId': None if metric.category is None else metric.category.id, 'categoryName': None if metric.category is None else metric.category.name }) response.status_code = 200 return response @app.route('/metrics/data', methods=['GET']) @token_required def metric_data(user): results = [] gender = request.values.get('gender', user.gender) categories = Category.get_all() for category in categories: obj_category = {'name': category.name, 'details': []} for metric in category.metrics: if metric.gender == gender: obj = { 'name': metric.name, 'weight': metric.weight, 'unit_label': metric.unit_label, 'features': { 'totalrange': [metric.total_range_min, metric.total_range_max], 'healthyrange': [ metric.healthy_range_min, metric.healthy_range_max ] } } obj_category['details'].append(obj) if obj_category['details']: results.append(obj_category) metrics = Metric.query.filter_by(gender=gender, category=None) for metric in metrics: obj = { 'name': metric.name, 'weight': metric.weight, 'unit_label': metric.unit_label, 'features': { 'totalrange': [metric.total_range_min, metric.total_range_max], 'healthyrange': [metric.healthy_range_min, metric.healthy_range_max] } } results.append(obj) response = jsonify(results) response.status_code = 200 return response @app.route('/categories', methods=['POST', 'GET']) @token_required def category(user): if not user.admin: return {}, 403 if request.method == 'POST': try: name = str(request.data['name']) except KeyError: return {}, 400 category = Category(name=name) category.save() response = jsonify({'id': category.id, 'name': category.name}) response.status_code = 201 return response else: categories = Category.get_all() results = [] for category in categories: obj = {'id': category.id, 'name': category.name} results.append(obj) response = jsonify(results) response.status_code = 200 return response @app.route('/categories/<int:id>', methods=['GET', 'PUT', 'DELETE']) @token_required def category_details(user, id, **kwargs): if not user.admin: return {}, 403 category = Category.query.get_or_404(id) if request.method == 'DELETE': category.delete() return { "message": "category {} deleted successfully".format(category.id) }, 200 elif request.method == 'PUT': category.name = str(request.data.get('name', category.name)) category.save() response = jsonify({'id': category.id, 'name': category.name}) response.status_code = 200 return response else: response = jsonify({ 'id': category.id, 'name': category.name, }) response.status_code = 200 return response @app.route('/users', methods=['POST', 'GET']) def user(): if request.method == 'POST': try: username = request.json['username'] email = request.json['email'] password = request.json['password'] gender = request.json['gender'] birth_date = request.json['birthDate'] except BadRequest: return {}, 400 username = username.lower() email = email.lower() if User.query.filter_by(username=username).first() is not None: return {}, 400 if User.query.filter_by(email=email).first() is not None: return {}, 400 user = User(username=username, gender=gender, birth_date=birth_date, email=email) user.hash_password(password) user.save() return jsonify({ 'username': user.username, 'email': user.email, 'gender': user.gender, 'birthDate': user.birth_date, 'dateCreated': user.date_created, 'dateModified': user.date_modified }), 201 else: users = User.get_all() results = [] for user in users: obj = { 'id': user.id, 'username': user.username, 'gender': user.gender, 'birthDate': user.birth_date, 'dateCreated': user.date_created } results.append(obj) response = jsonify(results) response.status_code = 200 return response @app.route('/login', methods=['POST']) def login(): try: username = request.json['username'] password = request.json['password'] except BadRequest: return {}, 400 user = User.query.filter_by(username=username.lower()).first() if not user: return {}, 400 if user.check_password(password): token = jwt.encode(payload={ 'id': user.id, 'exp': datetime.datetime.utcnow() + datetime.timedelta(minutes=60), 'admin': user.admin }, key=app.config['SECRET']) return jsonify({'access_token': token.decode('UTF-8')}) return {}, 403 return app
import sentry_sdk from flask import Flask from sentry_sdk.integrations.flask import FlaskIntegration from .common import get_parameters AWS_REGION = "us-east-1" AWS_PARAMETER_PATH = "/prod/kusama/" params = get_parameters(AWS_REGION, AWS_PARAMETER_PATH) sentry_sdk.init( dsn=params["SENTRY_DSN"], integrations=[FlaskIntegration()], traces_sample_rate=0 ) app = Flask(__name__) UNIFIED_LOGGING = False DEBUG_STATUS = True LOGSTASH = {"host": "localhost", "port": 9601, "name": "kusama_api_logger"} INTERNAL_ONLY = False PORT = 443 HOST = "0.0.0.0" ARBITRATOR_KEY = params["ARBITRATOR_HEX_SEED"] KUSAMA_NODE_PROVIDER = "ws://ksmnode.lcs.internal/" POLKADOT_NODE_PROVIDER = "ws://ksmnode.lcs.internal:81/"
def _metric(self, name): return f"{self.PREFIX}.{name}" def increment(self, name, value=1, tags=None, sample_rate=None): statsd.increment( self._metric(name), value=value, tags=self.tags_from_request() + (tags or []), sample_rate=sample_rate, ) metrics = Metrics().initialize() # SENTRY_DSN will be taken from env sentry_sdk.init(integrations=[FlaskIntegration()]) CACHE_TIMEOUT = 3600 cache = SimpleCache(threshold=200, default_timeout=CACHE_TIMEOUT) class InvalidPathComponent(ValueError): pass class RegistryJsonEncoder(json.JSONEncoder): def default(self, o): if hasattr(o, 'to_json'): return o.to_json() return json.JSONEncoder.default(self, o)
def create_app(conf=None, verbose=0, logfile=None, **kwargs): """Initialize the whole application. :param conf: Configuration file to use :type conf: str :param verbose: Set the verbosity level :type verbose: int :param logfile: Store the logs in the given file :type logfile: str :param kwargs: Extra options: - gunicorn (bool): Enable gunicorn engine instead of flask's default. Default is True. - unittest (bool): Are we running tests (used for test only). Default is False. - debug (bool): Enable debug mode. Default is False. - cli (bool): Are we running the CLI. Default is False. - reverse_proxy (bool): Are we behind a reverse-proxy. Default is True if gunicorn is True - websocket_server (bool): Are we running the websocket server. Default is False :type kwargs: dict :returns: A :class:`burpui.engines.server.BUIServer` object """ from flask import g, request, session from flask_login import LoginManager from flask_bower import Bower from flask_babel import gettext from .utils import ReverseProxied, lookup_file, is_uuid from .tools.logging import logger from .security import basic_login_from_request from .engines.server import BUIServer as BurpUI from .sessions import session_manager from .filter import mask from .ext.cache import cache from .ext.i18n import babel, get_locale from .misc.auth.handler import BUIanon gunicorn = kwargs.get('gunicorn', True) unittest = kwargs.get('unittest', False) debug = kwargs.get('debug', False) cli = kwargs.get('cli', False) reverse_proxy = kwargs.get('reverse_proxy', gunicorn) celery_worker = kwargs.get('celery_worker', False) websocket_server = kwargs.get('websocket_server', False) # We initialize the core app = BurpUI() app.config['CFG'] = None app.config['LOG_FILE'] = logfile app.config['LOG_LEVEL'] = verbose logger.init_app(app) if verbose: app.enable_logger() app.gunicorn = gunicorn logger.debug('conf: {}\n'.format(conf) + 'verbose: {}\n'.format(logging.getLevelName(verbose)) + 'logfile: {}\n'.format(logfile) + 'gunicorn: {}\n'.format(gunicorn) + 'debug: {}\n'.format(debug) + 'unittest: {}\n'.format(unittest) + 'cli: {}\n'.format(cli) + 'reverse_proxy: {}\n'.format(reverse_proxy) + 'celery_worker: {}\n'.format(celery_worker) + 'websocket_server: {}'.format(websocket_server)) # Some config app.config['BUI_CLI'] = cli # FIXME: strange behavior when bundling errors # app.config['BUNDLE_ERRORS'] = True app.config['REMEMBER_COOKIE_HTTPONLY'] = True if debug and not gunicorn: # pragma: no cover app.config['DEBUG'] = True and not unittest app.config['TESTING'] = True and not unittest # Still need to test conf file here because the init function can be called # by gunicorn directly if conf: app.config['CFG'] = lookup_file(conf, guess=False) else: app.config['CFG'] = lookup_file() logger.info('Using configuration: {}'.format(app.config['CFG'])) app.setup(app.config['CFG'], unittest, cli) if cli and not websocket_server and 'shell' not in sys.argv: return app if debug: app.config.setdefault('TEMPLATES_AUTO_RELOAD', True) app.config['TEMPLATES_AUTO_RELOAD'] = True app.config['DEBUG'] = True if app.demo: try: import sentry_sdk from sentry_sdk.integrations.flask import FlaskIntegration sentry_sdk.init(dsn=app.config['BUI_DSN'], integrations=[FlaskIntegration()]) except ImportError: pass # manage application secret key if app.secret_key and \ (app.secret_key.lower() == 'none' or (app.secret_key.lower() == 'random' and gunicorn)): # pragma: no cover logger.critical('Your setup is not secure! Please consider setting a' ' secret key in your configuration file') app.secret_key = 'Burp-UI' if not app.secret_key or app.secret_key.lower() == 'random': from base64 import b64encode app.secret_key = b64encode(os.urandom(256)) app.wsgi_app = ReverseProxied(app.wsgi_app, app) # Manage reverse_proxy special tricks & improvements if reverse_proxy: # pragma: no cover from werkzeug.middleware.proxy_fix import ProxyFix kwargs = {} if app.config['NUM_PROXIES'] > 0: kwargs = app.config['PROXY_FIX_ARGS'].format( num_proxies=app.config['NUM_PROXIES']) kwargs = json.loads(kwargs) logger.debug(f"Using {kwargs} as ProxyFix parameters") app.wsgi_app = ProxyFix(app.wsgi_app, **kwargs) if app.storage and app.storage.lower() == 'redis': try: # Session setup if not app.session_db or \ str(app.session_db).lower() not in ['none', 'false']: from redis import Redis from .ext.session import sess host, port, pwd = get_redis_server(app) db = 0 if app.session_db and \ str(app.session_db).lower() not \ in ['redis', 'default', 'true']: try: # pragma: no cover (_, _, pwd, host, port, db) = \ parse_db_setting(app.session_db) except ValueError as exp: logger.warning(str(exp)) try: db = int(db) except ValueError: db = 0 logger.debug( 'SESSION: Using redis://guest:****@{}:{}/{}'.format( host, port, db)) red = Redis(host=host, port=port, db=db, password=pwd) app.config['WITH_SRV_SESSION'] = True app.config['SESSION_TYPE'] = 'redis' app.config['SESSION_REDIS'] = red app.config['SESSION_USE_SIGNER'] = app.secret_key is not None app.config['SESSION_PERMANENT'] = False sess.init_app(app) session_manager.backend = red except Exception as exp: # pragma: no cover logger.warning('Unable to initialize session: {}'.format(str(exp))) app.config['WITH_SRV_SESSION'] = False try: # Cache setup if not app.cache_db or \ str(app.cache_db).lower() not in ['none', 'false']: host, port, pwd = get_redis_server(app) db = 1 if app.cache_db and \ str(app.cache_db).lower() not \ in ['redis', 'default', 'true']: try: # pragma: no cover (_, _, pwd, host, port, db) = \ parse_db_setting(app.cache_db) except ValueError as exp: logger.warning(str(exp)) try: db = int(db) except ValueError: db = 1 logger.debug('CACHE: Using redis://guest:****@{}:{}/{}'.format( host, port, db)) cache.init_app(app, config={ 'CACHE_TYPE': 'redis', 'CACHE_REDIS_HOST': host, 'CACHE_REDIS_PORT': port, 'CACHE_REDIS_PASSWORD': pwd, 'CACHE_REDIS_DB': db }) # clear cache at startup in case we removed or added servers with app.app_context(): cache.clear() else: # pragma: no cover cache.init_app(app) except Exception as exp: # pragma: no cover logger.warning('Unable to initialize cache: {}'.format(str(exp))) cache.init_app(app) try: # Limiter setup if app.limiter and str(app.limiter).lower() not \ in ['none', 'false']: # pragma: no cover from .ext.limit import limiter app.config['RATELIMIT_HEADERS_ENABLED'] = True if app.limiter and str(app.limiter).lower() not \ in ['default', 'redis', 'true']: app.config['RATELIMIT_STORAGE_URL'] = app.limiter else: db = 3 host, port, pwd = get_redis_server(app) if pwd: conn = 'redis://*****:*****@{}:{}/{}'.format( pwd, host, port, db) else: conn = 'redis://{}:{}/{}'.format(host, port, db) app.config['RATELIMIT_STORAGE_URL'] = conn (_, _, pwd, host, port, db) = parse_db_setting(app.config['RATELIMIT_STORAGE_URL']) logger.debug( 'LIMITER: Using redis://guest:****@{}:{}/{}'.format( host, port, db)) limiter.init_app(app) app.config['WITH_LIMIT'] = True except ImportError: # pragma: no cover logger.warning('Unable to load limiter. Did you run \'pip install ' 'flask-limiter\'?') except Exception as exp: # pragma: no cover logger.warning('Unable to initialize limiter: {}'.format(str(exp))) else: cache.init_app(app) # Initialize i18n babel.init_app(app) # Create SQLAlchemy if enabled create_db(app, cli, unittest, celery_worker=celery_worker) if not celery_worker: from .api import api, apibp from .routes import view, mypad app.jinja_env.globals.update( isinstance=isinstance, list=list, mypad=mypad, version_id='{}-{}'.format(__version__, __release__), ) # We initialize the API api.load_all() app.register_blueprint(apibp) # Then we load our routes app.register_blueprint(view) # Initialize Bower ext app.config.setdefault('BOWER_COMPONENTS_ROOT', os.path.join('static', 'vendor')) app.config.setdefault('BOWER_REPLACE_URL_FOR', True) bower = Bower() bower.init_app(app) # Order of the initialization matters! # The websocket must be configured prior to the celery worker for instance # Initialize Session Manager session_manager.init_app(app) # Initialize filter mask.init_app(app) # And the login_manager app.login_manager = LoginManager() app.login_manager.anonymous_user = BUIanon app.login_manager.login_view = 'view.login' app.login_manager.login_message_category = 'info' app.login_manager.session_protection = 'strong' # This is just to have the strings in the .po files app.login_manager.login_message = gettext( 'Please log in to access this page.') app.login_manager.needs_refresh_message = gettext( 'Please reauthenticate to access this page.') # This will be called at runtime and will then translate the strings app.login_manager.localize_callback = gettext app.login_manager.init_app(app) # Create WebSocket server if create_websocket(app, websocket_server, celery_worker, cli): return app # Create celery app if enabled create_celery(app, warn=False) def _check_session(user, request, api=False): """Check if the session is in the db""" if user and not session_manager.session_in_db(): # pragma: no cover login = getattr(user, 'name', None) if login and not is_uuid(login): remember = session.get('persistent', False) if not remember: from flask_login import decode_cookie remember_cookie = request.cookies.get( app.config.get('REMEMBER_COOKIE_NAME'), False) # check if the remember_cookie is legit if remember_cookie and decode_cookie(remember_cookie): remember = True session_manager.store_session( login, request.remote_addr, request.headers.get('User-Agent'), remember, api) elif login: app.uhandler.remove(login) @app.before_request def setup_request(): g.version = '{}-{}'.format(__version__, __release__) g.locale = get_locale() g.now = round(time.time()) g.date_format = session.get('dateFormat', 'llll') g.timezone = session.get('timezone') # make sure to store secure cookie if required if app.config['BUI_SCOOKIE']: criteria = (request.is_secure, request.headers.get('X-Forwarded-Proto', 'http') == 'https') app.config['SESSION_COOKIE_SECURE'] = \ app.config['REMEMBER_COOKIE_SECURE'] = any(criteria) if '_extra' in request.args: session['_extra'] = request.args.get('_extra') g._extra = session.get('_extra', '') @app.login_manager.user_loader def load_user(userid): """User loader callback""" if app.auth != 'none': user = app.uhandler.user(userid) if not user: return None if 'X-Language' in request.headers: language = request.headers.get('X-Language') user.language = language session['language'] = language if '_id' not in session: from flask_login import login_user # if _id is not in session, it means we loaded the user from # cache/db using the remember cookie so we need to login it login_user(user, remember=user.is_authenticated, fresh=False) _check_session(user, request) return user return None @app.login_manager.request_loader def load_user_from_request(request): """User loader from request callback""" if app.auth != 'none': user = basic_login_from_request(request, app) _check_session(user, request, True) return user @app.after_request def after_request(response): if getattr(g, 'basic_session', False): if session_manager.invalidate_current_session(): session_manager.delete_session() return response return app
TILE_DOMAIN = 'http://tile.yourdomain.tld' # Update this line ## Sentry is optional - Set it up and receive notifications if an exception on the website occours SENTRY_API_KEY = None # Update this line # Spontit is optional - Create an account and fill in the information below to receive push notifications on your smartphone SPONTIT_API_KEY = None # Update this line SPONTIT_USER_ID = None # Update this line # MD5 salt is required - Protects you from unauthorized uploads of data MD5_SALT = b'2J5Pq1lFga' # Update this line, you can use https://www.random.org/strings/?num=1&len=10&digits=on&upperalpha=on&loweralpha=on&unique=on&format=html&rnd=new if SENTRY_API_KEY is not None: import sentry_sdk from sentry_sdk.integrations.flask import FlaskIntegration sentry_sdk.init(dsn=SENTRY_API_KEY, integrations=[FlaskIntegration()]) if SPONTIT_API_KEY is not None and SPONTIT_USER_ID is not None: import requests spontit_headers = { 'X-Authorization': SPONTIT_API_KEY, 'X-UserId': SPONTIT_USER_ID } # --- def hms_to_s(h, m, s): '''Convert hours, minutes and seconds into seconds.''' h, m, s = int(h), int(m), int(s) return h * 60**2 + m * 60 + s
def configure_logging(debug: bool, testing: bool, sentry_dsn: t.Optional[str], cur_commit: t.Optional[str]) -> None: """Configure the structlog logger. :param debug: Are we in a debug environment. :param testing: Are we in a testing environment. """ json_renderer = structlog.processors.JSONRenderer() processors = [ structlog.stdlib.add_logger_name, _add_log_level, _add_thread_name, _maybe_add_stacktrace, structlog.stdlib.PositionalArgumentsFormatter(), structlog.processors.format_exc_info, structlog.processors.TimeStamper(fmt="iso"), structlog.processors.StackInfoRenderer(), structlog.processors.format_exc_info, structlog.processors.UnicodeDecoder(), _add_log_as_breadcrumb, _maybe_report_error_to_sentry, _call_log_callbacks, json_renderer, ] if debug and not testing: processors[-1] = structlog.dev.ConsoleRenderer(colors=True) structlog.configure( processors=processors, context_class=structlog.threadlocal.wrap_dict(dict), logger_factory=PrintLogger, wrapper_class=structlog.stdlib.BoundLogger, cache_logger_on_first_use=True, ) system_logging.basicConfig( format='%(message)s', stream=sys.stdout, ) system_logging.getLogger('psef').setLevel(system_logging.DEBUG) system_logging.getLogger('werkzeug').setLevel(system_logging.ERROR) # Let the celery logger shut up # system_logging.getLogger('celery').propagate = False if sentry_dsn is not None: logger.info('Setting up sentry') release = None if cur_commit is not None: release = f'CodeGra.de@{cur_commit}' sentry_sdk.init( release=release, dsn=sentry_dsn, integrations=[ FlaskIntegration(transaction_style='url'), SqlalchemyIntegration(), CeleryIntegration(), ], before_send=_sentry_before_send, )
def configure_sentry(environment, sentry_dsn): sentry_sdk.init(dsn=sentry_dsn, environment=environment, integrations=[LoggingIntegration(), FlaskIntegration()])
def init(): if config.SENTRY_DSN: sentry_sdk.init(dsn=config.SENTRY_DSN, release=__version__, before_send=before_send, integrations=[FlaskIntegration()])
if app.config['TRUST_PROXY_HEADERS']: from werkzeug.middleware.proxy_fix import ProxyFix app.wsgi_app = ProxyFix(app.wsgi_app, x_proto=1, x_host=1) if app.config['SENTRY_DSN']: import sentry_sdk from sentry_sdk.integrations.flask import FlaskIntegration sentry_logging = LoggingIntegration( level=logging.INFO, # Capture info and above as breadcrumbs event_level=logging.FATAL # Only send fatal errors as events ) sentry_sdk.init(dsn=app.config['SENTRY_DSN'], integrations=[ FlaskIntegration(), sentry_logging, SqlalchemyIntegration() ]) db = SQLAlchemy(metadata=metadata) migrate = Migrate(app, db) db.init_app(app) oauth = OAuth(app) if app.config.get('TWITTER_CONSUMER_KEY', None): oauth.register( name='twitter', client_id=app.config['TWITTER_CONSUMER_KEY'], client_secret=app.config['TWITTER_CONSUMER_SECRET'], request_token_url='https://api.twitter.com/oauth/request_token',
def create_app(config_name): app = Flask(__name__, instance_relative_config=True) app.config.from_object(app_config[config_name]) app.config.from_pyfile('config.py') db.init_app(app) migrate.init_app(app, db) register_blueprints(app) register_jinja_templte_filters(app) login_manager.init_app(app) login_manager.login_view = 'userpanel.login_view' compress.init_app(app) htmlmin.init_app(app) sentry_sdk.init(dsn=os.environ.get('SENTRY_DSN'), integrations=[FlaskIntegration()]) @app.route('/robots.txt') @app.route('/sitemap.xml') def serve_static_seo_files(): return send_from_directory(app.static_folder, request.path[1:]) @app.route('/generate-pdf', methods=['POST']) def generate_pdf(): try: data = request.get_json() template = render_template('utils/pdf_template.html', content=data['content']) css = [ 'app/static/css/vendors/bootstrap.min.css', 'app/static/css/style.css', 'app/static/css/pdf-style.css', ] try: pdf = base64.b64encode(pdfkit.from_string(template, False, css=css)) except FileNotFoundError: pdf = base64.b64encode(pdfkit.from_string(template, False)) response = make_response(pdf) response.headers['Content-Type'] = 'application/pdf' response.mimetype = 'application/pdf' return response, 200 except Exception as e: abort(Response(str(e)), 400) @app.route('/hardy-weinber-page') def redirection(): return redirect(url_for('hardy_weinberg.hardy_weinberg_page')) @app.errorhandler(404) def page_not_found(e): return render_template("error_pages/404.html", title="404 Page not found!") @app.errorhandler(403) def page_forbidden(e): return render_template("error_pages/403.html", title="403 Page forbidden") @app.context_processor def inject_now(): return {'now': datetime.utcnow(), 'css_js_ver': 1.15} @app.after_request def add_header(response): if "text/html" in response.content_type: response.headers["Cache-Control"] = "no-cache, no-store, must-revalidate" response.headers["Pragma"] = "no-cache" response.headers["Expires"] = "0" response.headers['Cache-Control'] = 'public, max-age=0' return response response.cache_control.max_age = 31536000 return response return app
from flask_assets import Environment, Bundle from flask_moment import Moment from flaskext.markdown import Markdown from werkzeug.middleware.proxy_fix import ProxyFix from flask_limiter import Limiter from flask_limiter.util import get_remote_address from flask_mail import Mail import sentry_sdk from sentry_sdk.integrations.flask import FlaskIntegration from elasticsearch import Elasticsearch sentry_sdk.init( dsn="https://[email protected]/5549957", integrations=[FlaskIntegration(transaction_style = "url")], traces_sample_rate=0.2, ) app = Flask(__name__) app.wsgi_app = ProxyFix(app.wsgi_app, x_proto=1, x_host=1) app.config.from_object(Config) app.jinja_options['extensions'].append('jinja2.ext.do') if app.config['DEBUG'] != 'False': from flask_debugtoolbar import DebugToolbarExtension toolbar = DebugToolbarExtension(app) Markdown(app) mail = Mail(app)
def create_app(): global app_created if not app_created: BlueprintsManager.register(app) Migrate(app, db) app.config.from_object(env('APP_CONFIG', default='config.ProductionConfig')) db.init_app(app) _manager = Manager(app) _manager.add_command('db', MigrateCommand) if app.config['CACHING']: cache.init_app(app, config={'CACHE_TYPE': 'simple'}) else: cache.init_app(app, config={'CACHE_TYPE': 'null'}) stripe.api_key = 'SomeStripeKey' app.secret_key = 'super secret key' app.config['JSONIFY_PRETTYPRINT_REGULAR'] = False app.config['FILE_SYSTEM_STORAGE_FILE_VIEW'] = 'static' app.logger.addHandler(logging.StreamHandler(sys.stdout)) app.logger.setLevel(logging.ERROR) # set up jwt app.config['JWT_AUTH_USERNAME_KEY'] = 'email' app.config['JWT_EXPIRATION_DELTA'] = timedelta(seconds=24 * 60 * 60) app.config['JWT_AUTH_URL_RULE'] = '/auth/session' _jwt = JWT(app, jwt_authenticate, jwt_identity) # setup celery app.config['CELERY_BROKER_URL'] = app.config['REDIS_URL'] app.config['CELERY_RESULT_BACKEND'] = app.config['CELERY_BROKER_URL'] app.config['CELERY_ACCEPT_CONTENT'] = ['json', 'application/text'] CORS(app, resources={r"/*": {"origins": "*"}}) AuthManager.init_login(app) if app.config['TESTING'] and app.config['PROFILE']: # Profiling app.wsgi_app = ProfilerMiddleware(app.wsgi_app, restrictions=[30]) # development api with app.app_context(): from app.api.admin_statistics_api.events import event_statistics from app.api.auth import auth_routes from app.api.attendees import attendee_misc_routes from app.api.bootstrap import api_v1 from app.api.celery_tasks import celery_routes from app.api.event_copy import event_copy from app.api.exports import export_routes from app.api.imports import import_routes from app.api.uploads import upload_routes from app.api.users import user_misc_routes from app.api.orders import order_misc_routes from app.api.role_invites import role_invites_misc_routes from app.api.auth import ticket_blueprint, authorised_blueprint from app.api.admin_translations import admin_blueprint from app.api.orders import alipay_blueprint from app.api.settings import admin_misc_routes app.register_blueprint(api_v1) app.register_blueprint(event_copy) app.register_blueprint(upload_routes) app.register_blueprint(export_routes) app.register_blueprint(import_routes) app.register_blueprint(celery_routes) app.register_blueprint(auth_routes) app.register_blueprint(event_statistics) app.register_blueprint(user_misc_routes) app.register_blueprint(attendee_misc_routes) app.register_blueprint(order_misc_routes) app.register_blueprint(role_invites_misc_routes) app.register_blueprint(ticket_blueprint) app.register_blueprint(authorised_blueprint) app.register_blueprint(admin_blueprint) app.register_blueprint(alipay_blueprint) app.register_blueprint(admin_misc_routes) sa.orm.configure_mappers() if app.config['SERVE_STATIC']: app.add_url_rule('/static/<path:filename>', endpoint='static', view_func=app.send_static_file) # sentry if not app_created and 'SENTRY_DSN' in app.config: sentry_sdk.init(app.config['SENTRY_DSN'], integrations=[FlaskIntegration()]) # redis redis_store.init_app(app) # elasticsearch if app.config['ENABLE_ELASTICSEARCH']: client.init_app(app) connections.add_connection('default', client.elasticsearch) with app.app_context(): try: cron_rebuild_events_elasticsearch.delay() except Exception: pass app_created = True return app, _manager, db, _jwt
import os from flask import Flask from flask_cors import CORS from flask_sacore import SACore import sentry_sdk from sentry_sdk.integrations.flask import FlaskIntegration dsn = os.getenv("DATABASE_URL") SENTRY_DSN = os.getenv("SENTRY_DSN") if SENTRY_DSN is not None: sentry_sdk.init(dsn=SENTRY_DSN, integrations=[FlaskIntegration()]) class DynAPI(Flask): def __init__(self, import_name, **kwargs): super().__init__(import_name, **kwargs) self.db = self.fetch_db(self) def fetch_db(self, app): return SACore(dsn, app) def create_app(): from .api import api # NoQA from .status import status # NoQA app = DynAPI(__name__) CORS(app) app.register_blueprint(api, url_prefix="/api") app.register_blueprint(status, url_prefix="/status")
def create_app(): global app_created if not app_created: BlueprintsManager.register(app) Migrate(app, db) app.config.from_object(env('APP_CONFIG', default='config.ProductionConfig')) db.init_app(app) _manager = Manager(app) _manager.add_command('db', MigrateCommand) if app.config['CACHING']: cache.init_app(app, config={'CACHE_TYPE': 'simple'}) else: cache.init_app(app, config={'CACHE_TYPE': 'null'}) stripe.api_key = 'SomeStripeKey' app.secret_key = 'super secret key' app.config['JSONIFY_PRETTYPRINT_REGULAR'] = False app.config['FILE_SYSTEM_STORAGE_FILE_VIEW'] = 'static' app.logger.addHandler(logging.StreamHandler(sys.stdout)) app.logger.setLevel(logging.ERROR) # set up jwt app.config['JWT_HEADER_TYPE'] = 'JWT' app.config['JWT_ACCESS_TOKEN_EXPIRES'] = timedelta(days=1) app.config['JWT_REFRESH_TOKEN_EXPIRES'] = timedelta(days=365) app.config['JWT_ERROR_MESSAGE_KEY'] = 'error' app.config['JWT_TOKEN_LOCATION'] = ['cookies', 'headers'] app.config['JWT_REFRESH_COOKIE_PATH'] = '/v1/auth/token/refresh' app.config['JWT_SESSION_COOKIE'] = False app.config['JWT_BLACKLIST_ENABLED'] = True app.config['JWT_BLACKLIST_TOKEN_CHECKS'] = ['refresh'] _jwt = JWTManager(app) _jwt.user_loader_callback_loader(jwt_user_loader) _jwt.token_in_blacklist_loader(is_token_blacklisted) # setup celery app.config['CELERY_BROKER_URL'] = app.config['REDIS_URL'] app.config['CELERY_RESULT_BACKEND'] = app.config['CELERY_BROKER_URL'] app.config['CELERY_ACCEPT_CONTENT'] = ['json', 'application/text'] CORS(app, resources={r"/*": {"origins": "*"}}) AuthManager.init_login(app) if app.config['TESTING'] and app.config['PROFILE']: # Profiling app.wsgi_app = ProfilerMiddleware(app.wsgi_app, restrictions=[30]) # development api with app.app_context(): from app.api.admin_statistics_api.events import event_statistics from app.api.auth import auth_routes from app.api.attendees import attendee_misc_routes from app.api.bootstrap import api_v1 from app.api.celery_tasks import celery_routes from app.api.event_copy import event_copy from app.api.exports import export_routes from app.api.imports import import_routes from app.api.uploads import upload_routes from app.api.users import user_misc_routes from app.api.orders import order_misc_routes from app.api.role_invites import role_invites_misc_routes from app.api.auth import ticket_blueprint, authorised_blueprint from app.api.admin_translations import admin_blueprint from app.api.orders import alipay_blueprint from app.api.settings import admin_misc_routes from app.api.server_version import info_route app.register_blueprint(api_v1) app.register_blueprint(event_copy) app.register_blueprint(upload_routes) app.register_blueprint(export_routes) app.register_blueprint(import_routes) app.register_blueprint(celery_routes) app.register_blueprint(auth_routes) app.register_blueprint(event_statistics) app.register_blueprint(user_misc_routes) app.register_blueprint(attendee_misc_routes) app.register_blueprint(order_misc_routes) app.register_blueprint(role_invites_misc_routes) app.register_blueprint(ticket_blueprint) app.register_blueprint(authorised_blueprint) app.register_blueprint(admin_blueprint) app.register_blueprint(alipay_blueprint) app.register_blueprint(admin_misc_routes) app.register_blueprint(info_route) add_engine_pidguard(db.engine) if app.config['SQLALCHEMY_DATABASE_URI'].startswith("sqlite://"): sqlite_datetime_fix() sa.orm.configure_mappers() if app.config['SERVE_STATIC']: app.add_url_rule('/static/<path:filename>', endpoint='static', view_func=app.send_static_file) # sentry if not app_created and 'SENTRY_DSN' in app.config: sentry_sdk.init(app.config['SENTRY_DSN'], integrations=[ FlaskIntegration(), RedisIntegration(), CeleryIntegration(), SqlalchemyIntegration() ]) # redis redis_store.init_app(app) # elasticsearch if app.config['ENABLE_ELASTICSEARCH']: client.init_app(app) connections.add_connection('default', client.elasticsearch) with app.app_context(): try: cron_rebuild_events_elasticsearch.delay() except Exception: pass app_created = True return app, _manager, db, _jwt
import os import json import sentry_sdk from woocommerce import API import klaviyo from dotenv import load_dotenv from flask import Flask, request, Response from sentry_sdk.integrations.flask import FlaskIntegration load_dotenv() sentry_sdk.init(dsn=os.getenv('SENTRY_DSN'), integrations=[FlaskIntegration()]) WCAPI = API(url=os.getenv('WC_URL'), consumer_key=os.getenv('WC_K'), consumer_secret=os.getenv('WC_S'), version="wc/v3") APP = Flask(__name__) CLIENT = klaviyo.Klaviyo(public_token=os.getenv('KLAVIYO_PUBLIC_TOKEN'), private_token=os.getenv('KLAVIYO_PRIVATE_TOKEN')) IP_LISTS = json.loads(os.environ['ALLOWED_IP_ADDRESSES']) def lookup(json_object, search_term): return [obj['value'] for obj in json_object if obj['key'] == search_term] @APP.route('/order/<action>', methods=['POST'])
def create_app(test_config=None): app = Flask(__name__, instance_relative_config=True) app.config.from_mapping( SECRET_KEY='dev', DATABASE=os.path.join(app.instance_path, 'meetyournextmsp.sqlite'), DATABASE_POSTCODES=os.path.join(app.instance_path, 'postcodes.sqlite'), CONTRIBUTIONS_DIRECTORY='', SENTRY_DSN='', ) if test_config is None: app.config.from_pyfile('config.py', silent=True) else: app.config.from_mapping(test_config) try: os.makedirs(app.instance_path) except OSError: pass if app.config['SENTRY_DSN']: sentry_sdk.init( dsn=app.config['SENTRY_DSN'], integrations=[FlaskIntegration()], ) @app.route("/", methods = ['POST', 'GET'] ) def index(): if request.method == 'POST' and request.form['postcode']: postcode = request.form['postcode'].replace(' ','').lower() with closing(sqlite3.connect(app.config['DATABASE_POSTCODES'])) as database: database.row_factory = sqlite3.Row with closing(database.cursor()) as cur: # Try and find an exact match. cur.execute( 'SELECT ScottishParliamentaryConstituency2014Name FROM lookup WHERE Postcode=?', [postcode] ) data = cur.fetchone() if data: return redirect('/constituency/'+data['ScottishParliamentaryConstituency2014Name']) # Does a partial match work? cur.execute( 'SELECT ScottishParliamentaryConstituency2014Name FROM lookup WHERE Postcode LIKE ? GROUP BY ScottishParliamentaryConstituency2014Name', [postcode+"%"] ) data = cur.fetchall() if data and len(data) == 1: return redirect('/constituency/'+data[0]['ScottishParliamentaryConstituency2014Name']) # Give up return render_template('index-postcode-error.html') else: return render_template('index.html') @app.route("/contribute", methods = ['POST', 'GET'] ) def contribute(): if request.method == 'POST': event_data = { 'title': request.form['title'], 'description': request.form['description'], 'url': request.form['url'], 'cancelled': False, 'deleted': False, 'tags': [], } if 'tag-national' in request.form: event_data['tags'].append('national') else: for k,v in request.form.items(): if v and k.startswith('tag-'): event_data['tags'].append(k[4:]) date = request.form['start-date'] event_data['start'] = date + " " + request.form['start-time-hour'] + ":" + request.form['start-time-minute'] event_data['end'] = date + " " + request.form['end-time-hour'] + ":" + request.form['end-time-minute'] meta_data = { 'email': request.form['email'] } dir_name = datetime.datetime.now().strftime('%Y-%m-%d-%H-%M-%S') + str(uuid.uuid4()) os.makedirs(os.path.join(app.config['CONTRIBUTIONS_DIRECTORY'], dir_name)) with open(os.path.join(app.config['CONTRIBUTIONS_DIRECTORY'], dir_name, 'event.yaml'), "w") as fp: yaml.dump(event_data, fp) with open(os.path.join(app.config['CONTRIBUTIONS_DIRECTORY'], dir_name, 'meta.yml'), "w") as fp: yaml.dump(meta_data, fp) return render_template('contribute-thankyou.html') else: with closing(sqlite3.connect(app.config['DATABASE'])) as database: database.row_factory = sqlite3.Row with closing(database.cursor()) as cur: cur.execute('SELECT * FROM tag WHERE extra_is_constituency=1 ORDER by title ASC', []) constituencies = cur.fetchall() cur.execute('SELECT * FROM tag WHERE extra_is_region=1 ORDER by title ASC', []) regions = cur.fetchall() return render_template('contribute.html', constituencies=constituencies, regions=regions ) @app.route("/event/<id>") def event(id): with closing(sqlite3.connect(app.config['DATABASE'])) as database: database.row_factory = sqlite3.Row with closing(database.cursor()) as cur: cur.execute('SELECT * FROM event WHERE id=?', [id]) event = cur.fetchone() if not event: abort(404) return render_template('event.html', event=Event(event)) @app.route("/constituencies") def constituencies(): with closing(sqlite3.connect(app.config['DATABASE'])) as database: database.row_factory = sqlite3.Row with closing(database.cursor()) as cur: cur.execute('SELECT * FROM tag WHERE extra_is_constituency=1 ORDER by title ASC', []) constituencies = cur.fetchall() return render_template('constituencies.html', constituencies=constituencies) @app.route("/constituency/<id>") def constituency(id): with closing(sqlite3.connect(app.config['DATABASE'])) as database: database.row_factory = sqlite3.Row with closing(database.cursor()) as cur: cur.execute('SELECT * FROM tag WHERE extra_is_constituency=1 AND id=?', [id]) tag = cur.fetchone() if not tag: abort(404) cur.execute('SELECT * FROM tag WHERE extra_is_region=1 AND id=?', [tag['extra_region']]) region_tag = cur.fetchone() cur.execute( 'SELECT event.* FROM event JOIN event_has_tag ON event_has_tag.event_id = event.id WHERE event.start_epoch > ? AND event.deleted = 0 AND event_has_tag.tag_id=? ORDER BY event.start_epoch ASC', [time.time(), 'national'] ) national_events = [Event(i) for i in cur.fetchall()] # TODO need a group by so if an event is in both region and constituency it won't appear twice cur.execute( 'SELECT event.* FROM event JOIN event_has_tag ON event_has_tag.event_id = event.id WHERE event.start_epoch > ? AND event.deleted = 0 AND (event_has_tag.tag_id=? OR event_has_tag.tag_id=?) ORDER BY event.start_epoch ASC', [time.time(), tag['id'], tag['extra_region']] ) events = [Event(i) for i in cur.fetchall()] # TODO need a group by so if an event is in both region and constituency it won't appear twice cur.execute( 'SELECT COUNT(event.id) AS c FROM event JOIN event_has_tag ON event_has_tag.event_id = event.id WHERE event.start_epoch <= ? AND event.deleted = 0 AND (event_has_tag.tag_id=? OR event_has_tag.tag_id=?) ORDER BY event.start_epoch ASC', [time.time(), tag['id'], tag['extra_region']] ) past_events_count = cur.fetchone()['c'] return render_template( 'constituency.html', constituency_id=tag['id'], constituency_title=tag['title'], national_events=national_events, events=events, region_title=region_tag['title'], past_events_count=past_events_count ) @app.route("/constituency/<id>/plus_past") def constituency_plus_past(id): with closing(sqlite3.connect(app.config['DATABASE'])) as database: database.row_factory = sqlite3.Row with closing(database.cursor()) as cur: cur.execute('SELECT * FROM tag WHERE extra_is_constituency=1 AND id=?', [id]) tag = cur.fetchone() if not tag: abort(404) cur.execute('SELECT * FROM tag WHERE extra_is_region=1 AND id=?', [tag['extra_region']]) region_tag = cur.fetchone() cur.execute( 'SELECT event.* FROM event JOIN event_has_tag ON event_has_tag.event_id = event.id WHERE event.deleted = 0 AND event_has_tag.tag_id=? ORDER BY event.start_epoch ASC', ['national'] ) national_events = [Event(i) for i in cur.fetchall()] # TODO need a group by so if an event is in both region and constituency it won't appear twice cur.execute( 'SELECT event.* FROM event JOIN event_has_tag ON event_has_tag.event_id = event.id WHERE event.deleted = 0 AND (event_has_tag.tag_id=? OR event_has_tag.tag_id=?) ORDER BY event.start_epoch ASC', [tag['id'], tag['extra_region']] ) events = [Event(i) for i in cur.fetchall()] return render_template( 'constituency_plus_past.html', constituency_id=tag['id'], constituency_title=tag['title'], national_events_plus_past=national_events, events_plus_past=events, region_title=region_tag['title'], ) @app.route("/about") def about(): return render_template('about.html') @app.route("/all_events") def all_events(): with closing(sqlite3.connect(app.config['DATABASE'])) as database: database.row_factory = sqlite3.Row with closing(database.cursor()) as cur: cur.execute( 'SELECT event.* FROM event WHERE event.start_epoch > ? AND event.deleted = 0 ORDER BY event.start_epoch ASC', [time.time()] ) all_events = [Event(i) for i in cur.fetchall()] return render_template('all_events.html', all_events=all_events) @app.route("/all_events_plus_past") def all_events_plus_past(): with closing(sqlite3.connect(app.config['DATABASE'])) as database: database.row_factory = sqlite3.Row with closing(database.cursor()) as cur: cur.execute( 'SELECT event.* FROM event WHERE event.deleted = 0 ORDER BY event.start_epoch ASC', [] ) all_events_plus_past = [Event(i) for i in cur.fetchall()] return render_template('all_events_plus_past.html', all_events_plus_past=all_events_plus_past) @app.route("/stats") def stats(): with closing(sqlite3.connect(app.config['DATABASE'])) as database: database.row_factory = sqlite3.Row with closing(database.cursor()) as cur: cur.execute( 'SELECT COUNT(event.id) AS c FROM event WHERE event.deleted = 0', ) total_events = cur.fetchone()['c'] cur.execute( 'SELECT COUNT(event.id) AS c FROM event JOIN event_has_tag ON event_has_tag.event_id = event.id WHERE event.deleted = 0 AND event_has_tag.tag_id=?', ['national'] ) count_national_events = cur.fetchone()['c'] cur.execute( 'SELECT COUNT(event.id) AS c FROM event JOIN event_has_tag ON event_has_tag.event_id = event.id WHERE event.start_epoch > ? AND event.deleted = 0 AND event_has_tag.tag_id=? ', [time.time(), 'national'] ) count_national_events_in_future = cur.fetchone()['c'] cur.execute( 'SELECT COUNT(event.id) AS c, tag.id AS tag_id, tag.title AS tag_title FROM event ' + 'JOIN event_has_tag ON event_has_tag.event_id = event.id ' + 'JOIN tag ON event_has_tag.tag_id = tag.id ' + 'WHERE event.deleted = 0 AND tag.extra_is_region = 1 GROUP BY tag.id ORDER BY c DESC' ) regions = cur.fetchall() cur.execute( 'SELECT COUNT(event.id) AS c, tag.id AS tag_id, tag.title AS tag_title FROM event ' + 'JOIN event_has_tag ON event_has_tag.event_id = event.id ' + 'JOIN tag ON event_has_tag.tag_id = tag.id ' + 'WHERE event.deleted = 0 AND tag.extra_is_constituency = 1 GROUP BY tag.id ORDER BY c DESC' ) constituencies = cur.fetchall() return render_template( 'stats.html', total_events=total_events, count_national_events=count_national_events, count_national_events_in_future=count_national_events_in_future, regions=regions, constituencies=constituencies, ) return app
def create_app(): global app_created if not app_created: BlueprintsManager.register(app) graphql_views.init_app(app) Migrate(app, db) app.config.from_object(env('APP_CONFIG', default='config.ProductionConfig')) if not app.config['SECRET_KEY']: if app.config['PRODUCTION']: app.logger.error( 'SECRET_KEY must be set in .env or environment variables in production' ) exit(1) else: random_secret = secrets.token_hex() app.logger.warning( f'Using random secret "{ random_secret }" for development server. ' 'This is NOT recommended. Set proper SECRET_KEY in .env or environment variables' ) app.config['SECRET_KEY'] = random_secret db.init_app(app) if app.config['CACHING']: cache.init_app(app, config={'CACHE_TYPE': 'simple'}) else: cache.init_app(app, config={'CACHE_TYPE': 'null'}) stripe.api_key = 'SomeStripeKey' app.config['JSONIFY_PRETTYPRINT_REGULAR'] = False app.config['FILE_SYSTEM_STORAGE_FILE_VIEW'] = 'static' app.logger.addHandler(logging.StreamHandler(sys.stdout)) app.logger.setLevel(logging.ERROR) # set up jwt app.config['JWT_HEADER_TYPE'] = 'JWT' app.config['JWT_ACCESS_TOKEN_EXPIRES'] = timedelta(days=1) app.config['JWT_REFRESH_TOKEN_EXPIRES'] = timedelta(days=365) app.config['JWT_ERROR_MESSAGE_KEY'] = 'error' app.config['JWT_TOKEN_LOCATION'] = ['cookies', 'headers'] app.config['JWT_REFRESH_COOKIE_PATH'] = '/v1/auth/token/refresh' app.config['JWT_SESSION_COOKIE'] = False app.config['JWT_BLACKLIST_ENABLED'] = True app.config['JWT_BLACKLIST_TOKEN_CHECKS'] = ['refresh'] _jwt = JWTManager(app) _jwt.user_loader_callback_loader(jwt_user_loader) _jwt.token_in_blacklist_loader(is_token_blacklisted) # setup celery app.config['CELERY_BROKER_URL'] = app.config['REDIS_URL'] app.config['CELERY_RESULT_BACKEND'] = app.config['CELERY_BROKER_URL'] app.config['CELERY_ACCEPT_CONTENT'] = ['json', 'application/text'] app.config['MAIL_RECORDER'] = MailRecorder(use_env=True) CORS(app, resources={r"/*": {"origins": "*"}}) AuthManager.init_login(app) if app.config['TESTING'] and app.config['PROFILE']: # Profiling app.wsgi_app = ProfilerMiddleware(app.wsgi_app, restrictions=[30]) # development api with app.app_context(): from app.api.admin_statistics_api.events import event_statistics from app.api.auth import auth_routes from app.api.custom.attendees import attendee_blueprint from app.api.bootstrap import api_v1 from app.api.celery_tasks import celery_routes from app.api.event_copy import event_copy from app.api.exports import export_routes from app.api.imports import import_routes from app.api.uploads import upload_routes from app.api.users import user_misc_routes from app.api.orders import order_misc_routes from app.api.role_invites import role_invites_misc_routes from app.api.auth import authorised_blueprint from app.api.admin_translations import admin_blueprint from app.api.orders import alipay_blueprint from app.api.sessions import sessions_blueprint from app.api.settings import admin_misc_routes from app.api.server_version import info_route from app.api.custom.orders import ticket_blueprint from app.api.custom.orders import order_blueprint from app.api.custom.invoices import event_blueprint from app.api.custom.calendars import calendar_routes app.register_blueprint(api_v1) app.register_blueprint(event_copy) app.register_blueprint(upload_routes) app.register_blueprint(export_routes) app.register_blueprint(import_routes) app.register_blueprint(celery_routes) app.register_blueprint(auth_routes) app.register_blueprint(event_statistics) app.register_blueprint(user_misc_routes) app.register_blueprint(attendee_blueprint) app.register_blueprint(order_misc_routes) app.register_blueprint(role_invites_misc_routes) app.register_blueprint(authorised_blueprint) app.register_blueprint(admin_blueprint) app.register_blueprint(alipay_blueprint) app.register_blueprint(admin_misc_routes) app.register_blueprint(info_route) app.register_blueprint(ticket_blueprint) app.register_blueprint(order_blueprint) app.register_blueprint(event_blueprint) app.register_blueprint(sessions_blueprint) app.register_blueprint(calendar_routes) add_engine_pidguard(db.engine) if app.config['SQLALCHEMY_DATABASE_URI' # pytype: disable=attribute-error ].startswith("sqlite://"): sqlite_datetime_fix() sa.orm.configure_mappers() if app.config['SERVE_STATIC']: app.add_url_rule('/static/<path:filename>', endpoint='static', view_func=app.send_static_file) # sentry if not app_created and 'SENTRY_DSN' in app.config: sentry_sdk.init( app.config['SENTRY_DSN'], integrations=[ FlaskIntegration(), RedisIntegration(), CeleryIntegration(), SqlalchemyIntegration(), ], release=app.config['SENTRY_RELEASE_NAME'], traces_sample_rate=app.config['SENTRY_TRACES_SAMPLE_RATE'], ) # redis redis_store.init_app(app) # Initialize Extensions shell.init_app(app) limiter.init_app(app) app_created = True return app
def init(): global initialized if initialized: return initialized = True global db global app global alembic_config if config.sentry_dsn: sentry_sdk.init( dsn=config.sentry_dsn, integrations=[FlaskIntegration(), SqlalchemyIntegration(), RedisIntegration()] ) app = Flask(__name__) if config.flask_env == "production": csp = config.csp_directives if not csp: csp = { 'default-src': '\'self\'', 'style-src': [ '\'unsafe-inline\' \'self\'', 'fonts.googleapis.com', 'use.fontawesome.com', ], 'font-src': [ 'fonts.gstatic.com', 'use.fontawesome.com', ], 'worker-src': [ 'blob:', ], 'img-src': [ 'https:', ], } if config.force_https: talisman = Talisman(app, content_security_policy=csp) app.static_folder = config.static_path oneshot_db_create = False if config.database_url.startswith("sqlite://"): db_path = config.database_url.split("sqlite://")[1] if not os.path.isabs(db_path): db_path = os.path.join(os.path.dirname(__file__), "../../", db_path) config.database_url = "sqlite://" + db_path if not os.path.exists(db_path): oneshot_db_create = True app.config['SQLALCHEMY_DATABASE_URI'] = config.database_url print("Connecting to database {}".format(config.database_url)) app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False alembic_config = AlembicConfig(config.alembic_ini) db = SQLAlchemy(app) import tuber.csrf import tuber.models import tuber.static import tuber.api if oneshot_db_create: # To avoid running migrations on sqlite dev databases just create the current # tables and stamp them as being up to date so that migrations won't run. # This should only run if there is not an existing db. db.create_all() alembic.command.stamp(alembic_config, "head")
app.permanent_session_lifetime = timedelta(days=config.epoch_days) app.config.update( USE_MATOMO=config.use_matomo, MATOMO_URL=config.matomo_url, MATOMO_SITE_ID=config.matomo_site_id, SITE_DOMAIN=config.first_party_trackers[0], ) @app.errorhandler(404) def page_not_found(error): return render_template('404.html'), 404 if config.sentry_dsn: sentry_sdk.init(config.sentry_dsn, integrations=[FlaskIntegration()]) def read_keyfile(): global key with open( config.keyfile, 'rb', ) as fp: key = fp.read(16) read_keyfile() def require_admin_pass(route):
File, Contact, RefusedEmail, ManualSubscription, ) from app.monitor.base import monitor_bp from app.oauth.base import oauth_bp from app.pgp_utils import load_public_key if SENTRY_DSN: LOG.d("enable sentry") sentry_sdk.init( dsn=SENTRY_DSN, release=f"app@{SHA1}", integrations=[ FlaskIntegration(), SqlalchemyIntegration(), ], ) # the app is served behind nginx which uses http and not https os.environ["OAUTHLIB_INSECURE_TRANSPORT"] = "1" def create_light_app() -> Flask: app = Flask(__name__) app.config["SQLALCHEMY_DATABASE_URI"] = DB_URI app.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = False db.init_app(app)
from flask import Flask, request from flask_restful import Api, Resource from .flask_celery import make_celery import sentry_sdk from sentry_sdk.integrations.flask import FlaskIntegration from sentry_sdk.integrations.celery import CeleryIntegration from .enduhub_fetcher import EnduhubFetcher from .enduhub_result_sender import EnduhubResultSender sentry_sdk.init( dsn="https://[email protected]/1472203", integrations=[FlaskIntegration(), CeleryIntegration()], ) flask_app = Flask(__name__) api = Api(flask_app) flask_app.config.update( CELERY_BROKER_URL="redis://endu_redis_cache:6379", CELERY_RESULT_BACKEND="redis://endu_redis_cache:6379", ) celery = make_celery(flask_app) class EnduFetcher(Resource): def post(self): req_json = request.get_json() name = req_json["name"] birth = req_json["birth"]
from secrets import get_secret from helpers import get_timetable, display_date, is_night from flask import Flask, render_template import sentry_sdk from sentry_sdk.integrations.flask import FlaskIntegration sentry_url = get_secret('SENTRY_URL') sentry_sdk.init(sentry_url, integrations=[FlaskIntegration()]) with sentry_sdk.configure_scope() as scope: scope.set_tag('service', 'front') app = Flask(__name__) @app.route('/') def root(): response = get_timetable() date = response['date'] timetable = response['timetable'] classes = [] time = 'Nie ma lekcji 👍' if timetable and timetable['beginning']: classes = timetable['classes'] time = f'{timetable["beginning"]} – {timetable["end"]}' dark = is_night() return render_template('index.html',
def sentry_init(): log.error('clach04 entry') sentry_sdk.init(integrations=[FlaskIntegration()]) sentry_sdk.capture_message('Starting')