Example #1
0
def register_blueprints(app):
    """Registers flask blueprints."""
    import crabber_api
    import crabber_rss

    # Rate-limit site
    limiter = Limiter(
        app,
        key_func=get_remote_address,
        default_limits=[
            f"{config.SITE_RATE_LIMIT_MINUTE}/minute",
            f"{config.SITE_RATE_LIMIT_SECOND}/second",
        ],
    )
    # Exempt API from site-limits
    limiter.exempt(crabber_api.API)

    # Rate-limit API
    api_limiter = Limiter(app, key_func=crabber_api.get_api_key)
    api_limiter.limit(f"{config.API_RATE_LIMIT_SECOND}/second;"
                      f"{config.API_RATE_LIMIT_MINUTE}/minute;"
                      f"{config.API_RATE_LIMIT_HOUR}/hour")(crabber_api.API)

    # Register API V1 blueprint
    app.register_blueprint(crabber_api.API, url_prefix="/api/v1")
    # Register RSS blueprint
    app.register_blueprint(crabber_rss.RSS, url_prefix="/rss")

    return limiter
Example #2
0
def create_app(test_config=None):
    """Создаёт и конфигурирует Flask-приложение"""
    app = Flask(__name__)

    app.config.from_mapping(
        SECRET_KEY=os.getenv('APP_SECRET_KEY', str(uuid.uuid4())),
        MONGO_URI=os.getenv('APP_MONGO_URI'),
        RATELIMIT_STORAGE_URL=os.getenv('APP_REDIS_URI'),

        # Для авторизации стороннего сервиса
        LOGIN=os.getenv('APP_LOGIN'),
        PASSWORD=os.getenv('APP_PASSWORD'),
    )

    if test_config is not None:
        app.config.update(test_config)

    app.secret_key = app.config['SECRET_KEY']
    limiter = Limiter(
        app,
        key_func=get_remote_address,
    )

    # Важно: импорт моделей должен идти после вызова connect (особенность pymodm)
    # http://pymodm.readthedocs.io/en/latest/api/index.html#module-pymodm.connection
    from miles import db
    db.init_app(app)

    from miles import v1
    # Чтобы трудно было подобрать код, ставим лимит на запросы
    limiter.limit("10/hour")(v1.login)

    app.register_blueprint(v1.bp)

    return app
Example #3
0
def test_invalid_decorated_static_limit_blueprint(caplog):
    app = Flask(__name__)
    limiter = Limiter(
        app, default_limits=["1/second"], key_func=get_remote_address
    )
    bp = Blueprint("bp1", __name__)

    @bp.route("/t1")
    def t1():
        return "42"

    limiter.limit("2/sec")(bp)
    app.register_blueprint(bp)

    with app.test_client() as cli:
        with hiro.Timeline().freeze():
            assert cli.get("/t1").status_code == 200
            assert cli.get("/t1").status_code == 429
    assert (
        "failed to configure"
        in caplog.records[0].msg
    )
    assert (
        "exceeded at endpoint"
        in caplog.records[1].msg
    )
def create_app():
    app = Flask(__name__)
    app.config['CELERY_BROKER_URL'] = CELERY_BROKER_URL
    app.config['CELERY_RESULT_BACKEND'] = 'redis://localhost:6379/0'

    celery.conf.update(app.config)

    bootstrap = Bootstrap(app)

    app.config['SECRET_KEY'] = 'hard to guess string'
    app.config['UPLOAD_FOLDER'] = '/tmp/submissions/'
    app.config['MAX_CONTENT_LENGTH'] = 3 * 1024 * 1024
    app.config['ALLOWED_EXTENSIONS'] = set(['apk'])

    if not os.path.exists(app.config['UPLOAD_FOLDER']):
        os.makedirs(app.config['UPLOAD_FOLDER'])

    import views
    app.register_blueprint(views.status)
    app.register_blueprint(views.uploadbp)

    models.init_db()

    emu_manager.init_emulators()

    limiter = Limiter(app,
                      default_limits=["1/second"],
                      key_func=get_remote_address)
    limiter.limit("20/hour")(views.uploadbp)

    return app, limiter
Example #5
0
def create_app():
    app = Flask(__name__)
    CSRFProtect(app)
    app.secret_key = os.getenv("SECRET_KEY") or os.urandom(24)
    app.config["SQLALCHEMY_DATABASE_URI"] = "sqlite:///santa.sqlite"
    app.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = False
    db.init_app(app)

    if os.environ.get("RESET_DB") == "1":
        with app.app_context():
            from secret_santa.models import Address, Group, Member, User  # noqa: F811

            logger.debug("Reseting DB")
            meta = db.metadata
            for table in reversed(meta.sorted_tables):
                db.session.execute(table.delete())
                logger.debug(f"truncating table {table}")
            db.create_all()
            db.session.commit()

    # register blueprints
    from secret_santa.templates.views import main as main_blueprint

    app.register_blueprint(main_blueprint)
    from secret_santa.auth.views import auth as auth_blueprint

    app.register_blueprint(auth_blueprint, url_prefix="/auth")
    from secret_santa.users.views import users as users_blueprint

    app.register_blueprint(users_blueprint, url_prefix="/users")
    from secret_santa.groups.views import groups as groups_blueprint

    app.register_blueprint(groups_blueprint, url_prefix="/groups")

    login_manager = LoginManager()
    login_manager.login_view = "auth.login"
    login_manager.init_app(app)

    @login_manager.user_loader
    def load_user(user_id):
        from secret_santa.models import User  # noqa: F811

        return User.query.get(int(user_id))

    limiter = Limiter(app,
                      key_func=get_remote_address,
                      default_limits=["5/second"])
    limiter.limit("60/hour")(auth_blueprint)

    # Redirect all non existent URLsto index.html
    @app.errorhandler(404)
    def page_not_found(e):
        flash("Ooops! The requested page doesn't exist!", "is-danger")

        return redirect(url_for("main.index"))

    return app
Example #6
0
def register_blueprints(_app):
    """ register blueprints to the app """
    # Limit authentication blueprint requests to 30 per minute
    limiter = Limiter(_app, key_func=get_remote_address)
    limiter.limit("30/minute")(authentication_routes.blueprint)

    _app.register_blueprint(static_routes.blueprint)  # register static routes
    _app.register_blueprint(admin_routes.blueprint)  # register admin views
    _app.register_blueprint(authentication_routes.blueprint)  # register login/logout views
    _app.register_blueprint(calibration_routes.blueprint)  # register calibration views
    _app.register_blueprint(general_routes.blueprint)  # register general routes
    _app.register_blueprint(method_routes.blueprint)  # register method views
    _app.register_blueprint(page_routes.blueprint)  # register page views
    _app.register_blueprint(remote_admin_routes.blueprint)  # register remote admin views
    _app.register_blueprint(settings_routes.blueprint)  # register settings views
Example #7
0
def create_app(test_config=None):
    app = Flask(__name__, instance_relative_config=True)

    CORS(app, resources={r"/*": {"origins": "*"}})

    app.config.from_mapping(
        SECRET_KEY='dev',
        DATABASE=os.path.join(app.instance_path, 'flaskr.sqlite'),
    )

    if test_config is None:
        # load the instance config, if it exists, when not testing
        app.config.from_pyfile('config.py', silent=True)
    else:
        # load the test config if passed in
        app.config.from_mapping(test_config)

    # ensure the instance folder exists
    try:
        os.makedirs(app.instance_path)
    except OSError:
        pass

    @app.errorhandler(404)
    def not_found_error(error):
        return 'Page not found', 404

    from . import db
    db.init_app(app)

    from . import post

    limiter = Limiter(app, key_func=get_remote_address)
    limiter.limit("5/minute", methods=['POST'])(post.bp)
    limiter.limit("10/second", methods=['GET'])(post.bp)

    app.register_blueprint(post.bp)

    return app
Example #8
0
def test_invalid_decorated_dynamic_limits_blueprint(caplog):
    app = Flask(__name__)
    app.config.setdefault("X", "2 per sec")
    limiter = Limiter(
        app, default_limits=["1/second"], key_func=get_remote_address
    )
    bp = Blueprint("bp1", __name__)

    @bp.route("/t1")
    def t1():
        return "42"

    limiter.limit(lambda: current_app.config.get("X"))(bp)
    app.register_blueprint(bp)

    with app.test_client() as cli:
        with hiro.Timeline().freeze():
            assert cli.get("/t1").status_code == 200
            assert cli.get("/t1").status_code == 429

    assert len(caplog.records) == 3
    assert "failed to load ratelimit" in caplog.records[0].msg
    assert "failed to load ratelimit" in caplog.records[1].msg
    assert "exceeded at endpoint" in caplog.records[2].msg
from api.indass_select import SelectView

app = Flask(__name__,
            static_folder=config.Config.STATIC_PATH,
            static_url_path='')
manager = Manager(app)

app.config['SECRET_KEY'] = config.Config.SECRET_KEY
csrf = CSRFProtect(app)
app.config.from_object(config.config["development"])
limiter = Limiter(app,
                  key_func=get_remote_address,
                  default_limits=["200 per minute"])

app.add_url_rule("/", view_func=HomeView.as_view("homeview"))
login_view = limiter.limit("12 per minute")(LoginView.as_view("loginview"))
app.add_url_rule("/login", view_func=login_view)
app.add_url_rule("/logout", view_func=LogoutView.as_view("logoutview"))
app.add_url_rule("/select/<username>",
                 view_func=SelectView.as_view("selectview"))
app.add_url_rule("/<username>/<project_id>/<data_marker>",
                 view_func=AnalyzeView.as_view("analyzeview"))
data_view = limiter.limit("12 per minute")(DataView.as_view("dataview"))
app.add_url_rule("/api/v1.0/<username>/<project_id>/<data_marker>",
                 view_func=data_view)


@app.errorhandler(404)
def error(e):
    return render_template("404.html")
Example #10
0
import config
import models
from resources.courses import courses_api
from resources.reviews import reviews_api
from resources.users import users_api

app = Flask(__name__)

app.register_blueprint(courses_api, url_prefix='/api/v1')
app.register_blueprint(reviews_api, url_prefix='/api/v1')
app.register_blueprint(users_api, url_prefix='/api/v1')

limiter = Limiter(app,
                  global_limits=[config.DEFAULT_RATE],
                  key_func=get_ipaddr)
limiter.limit('10/day')(users_api)
limiter.limit(config.DEFAULT_RATE,
              per_method=True,
              methods=['post', 'put', 'delete'])(courses_api)
limiter.limit(config.DEFAULT_RATE,
              per_method=True,
              methods=['post', 'put', 'delete'])(reviews_api)
# limiter.exempt(courses_api)
# limiter.exempt(reviews_api)


@app.route('/')
def hello_world():
    return 'Hello World!'

Example #11
0
from auth import auth
import config
import models
from resources.courses import courses_api
from resources.reviews import reviews_api
from resources.users import users_api


app = Flask(__name__)
app.register_blueprint(courses_api)
app.register_blueprint(reviews_api, url_prefix='/api/v1')
app.register_blueprint(users_api, url_prefix='/api/v1')

limiter = Limiter(app, global_limits=[config.DEFAULT_RATE], key_func=get_ipaddr)
limiter.limit("40/day")(users_api)
limiter.limit(config.DEFAULT_RATE, per_method=True, methods=["post", "put", "delete"])(courses_api)
limiter.limit(config.DEFAULT_RATE, per_method=True, methods=["post", "put", "delete"])(reviews_api)
#limiter.exempt(courses_api)
#limiter.exempt(reviews_api)

@app.route('/')
def hello_world():
    return 'Hello World'

@app.route('/api/v1/users/token', methods=['GET'])
@auth.login_required
def get_auth_token():
    token = g.user.generate_auth_token()
    return jsonify({'token': token.decode('ascii')})
  
Example #12
0
app.config['ALLOWED_TOKENS'] = environ.get('ALLOWED_TOKENS')
app.config['CHANNEL'] = environ.get('CHANNEL')
redis_client = FlaskRedis(app)

limiter = Limiter(app,
                  key_func=get_remote_address,
                  default_limits=[],
                  headers_enabled=True,
                  strategy='fixed-window-elastic-expiry')


@limiter.request_filter
def ip_whitelist():
    return request.remote_addr == "127.0.0.1"


from app.api import email
from app.api import telegram

limiter.limit("10 per second")(email.bp)
limiter.limit("10 per second")(telegram.bp)

app.register_blueprint(email.bp)
app.register_blueprint(telegram.bp)


@app.route("/ping")
@limiter.limit("5 per minute", override_defaults=False)
def ping():
    return "PONG"
Example #13
0
from auth import auth
import config
import models
from resources.courses import courses_api
from resources.reviews import reviews_api
from resources.users import users_api

app = Flask(__name__)
app.register_blueprint(courses_api)
app.register_blueprint(reviews_api, url_prefix='/api/v1')
app.register_blueprint(users_api, url_prefix='/api/v1')

limiter = Limiter(app,
                  global_limits=[config.DEFAULT_RATE],
                  key_func=get_ipaddr)
limiter.limit("40/day")(users_api)
limiter.limit(config.DEFAULT_RATE,
              per_method=True,
              methods=["post", "put", "delete"])(courses_api)
limiter.limit(config.DEFAULT_RATE,
              per_method=True,
              methods=["post", "put", "delete"])(reviews_api)
#Limiter.exempt(courses_api)
#Limiter.exempt(reviews_api)


@app.route('/')
def hello_world():
    return 'Hello World'

Example #14
0
def register_extensions(app):
    """ register extensions to the app """
    app.jinja_env.add_extension('jinja2.ext.do')  # Global values in jinja

    # Uncomment to enable profiler
    # See scripts/profile_analyzer.py to analyze output
    # app = setup_profiler(app)

    # Compress app responses with gzip
    compress = Compress()
    compress.init_app(app)

    # Influx db time-series database
    db.init_app(app)
    influx_db.init_app(app)

    # Limit authentication blueprint requests to 200 per minute
    limiter = Limiter(app, key_func=get_ip_address)
    limiter.limit("200/minute")(routes_authentication.blueprint)

    # Language translations
    babel = Babel(app)

    @babel.localeselector
    def get_locale():
        try:
            user = User.query.filter(
                User.id == flask_login.current_user.id).first()
            if user and user.language != '':
                for key in LANGUAGES:
                    if key == user.language:
                        return key
        # Bypass endpoint test error "'AnonymousUserMixin' object has no attribute 'id'"
        except AttributeError:
            pass
        return request.accept_languages.best_match(LANGUAGES.keys())

    # User login management
    login_manager = flask_login.LoginManager()
    login_manager.init_app(app)

    @login_manager.user_loader
    def user_loader(user_id):
        user = User.query.filter(User.id == user_id).first()
        if not user:
            return
        return user

    @login_manager.unauthorized_handler
    def unauthorized():
        flash(gettext('Please log in to access this page'), "error")
        return redirect(url_for('routes_authentication.do_login'))

    # Create and populate database if it doesn't exist
    with app.app_context():
        db.create_all()
        populate_db()

        # This is disabled because there's a bug that messes up user databases
        # The upgrade script will execute alembic to upgrade the database
        # alembic_upgrade_db()

    # Check user option to force all web connections to use SSL
    # Fail if the URI is empty (pytest is running)
    if app.config['SQLALCHEMY_DATABASE_URI'] != 'sqlite://':
        with session_scope(
                app.config['SQLALCHEMY_DATABASE_URI']) as new_session:
            misc = new_session.query(Misc).first()
            if misc and misc.force_https:
                SSLify(app)
Example #15
0
def create_app(env: str = "development"):
    app = Flask(__name__)
    app.config.from_object(settings.app_config[env])

    db.init_app(app)
    migrate.init_app(app, db)
    jwt.init_app(app)
    json_schema_manager.init_app(app)
    Q.init_app(app)
    redis_client.init_app(app)
    CORS(app)
    stripe.api_key = app.config["STRIPE_KEY"]
    stripe.api_base = app.config["STRIPE_ENDPOINT"]
    from app.jobs.nomad_cleanup import check_all_boxes, find_unused_boxes

    # queue job every day at noon (UTC!)
    find_unused_boxes.cron("*/15 * * * *", "Finding unused tunnels")
    check_all_boxes.cron("0 0 12 * *", "Check running tunnels")
    from app.routes.tunnels import tunnel_blueprint
    from app.routes.subdomains import subdomain_blueprint
    from app.routes.authentication import auth_blueprint
    from app.routes.account import account_blueprint
    from app.routes.admin import admin_blueprint
    from app.routes.root import root_blueprint
    from app.commands import plan, redis

    from querystring_parser.parser import parse as qs_parse

    # This is required for route limits to be effective while behind Fabio.
    app.wsgi_app = ProxyFix(app.wsgi_app, num_proxies=1)  # type: ignore
    if env != "test":
        limiter = Limiter(app, key_func=get_remote_address)
        limiter.limit("3/second")(auth_blueprint)

    app.register_blueprint(auth_blueprint)
    app.register_blueprint(tunnel_blueprint)
    app.register_blueprint(subdomain_blueprint)
    app.register_blueprint(account_blueprint)
    app.register_blueprint(admin_blueprint)
    app.register_blueprint(root_blueprint)
    app.cli.add_command(plan)
    app.cli.add_command(redis)

    from app.serializers import ErrorSchema
    from app.utils.errors import (
        OldAPIVersion,
        MalformedAPIHeader,
        TooManyRequestsError,
        NotFoundError,
        InternalServerError,
    )
    import re

    @app.shell_context_processor
    def ctx():
        return {"app": app, "db": db}

    @app.before_first_request
    def init_rollbar():
        if env == "production":
            rollbar.init(
                app.config["ROLLBAR_TOKEN"],
                app.config["ROLLBAR_ENV"],
                # server root directory, makes tracebacks prettier
                root=os.path.dirname(os.path.realpath(__file__)),
                # flask already sets up logging
                allow_logging_basic_config=False,
            )

            # send exceptions from `app` to rollbar, using flask's signal system.
            got_request_exception.connect(rollbar.contrib.flask.report_exception, app)

    @app.errorhandler(429)
    def too_many_requests(_):
        return json_api(TooManyRequestsError, ErrorSchema), 429

    @app.errorhandler(500)
    def debug_error_handler(e):
        if env == "production":
            rollbar.report_exc_info()
            return json_api(InternalServerError, ErrorSchema), 500
        else:
            return (
                json_api(
                    InternalServerError(
                        detail=str(e), backtrace=traceback.format_exc().split("\n")
                    ),
                    ErrorSchema,
                ),
                500,
            )

    @app.errorhandler(404)
    def page_not_found(e):
        return json_api(NotFoundError(detail=e.description), ErrorSchema), 404

    @app.before_request
    def parse_query_params():
        if request.query_string:
            request.query_params = qs_parse(request.query_string)
        else:
            request.query_params = dict()

    def check_version(date):
        return version.parse(date) >= version.parse(app.config["MIN_CALVER"])

    @app.before_request
    def check_api_version():
        if "Api-Version" in request.headers:
            if not re.match(r"^\d+\.\d+\.\d+\.\d+$", request.headers["Api-Version"]):
                return json_api(MalformedAPIHeader, ErrorSchema), 403
            if check_version(request.headers["Api-Version"]):
                return
            else:
                return json_api(OldAPIVersion, ErrorSchema), 400

    @app.after_request
    def session_commit(response):
        if response.status_code >= 400:
            return response
        try:
            db.session.commit()
        except DatabaseError:
            db.session.rollback()
            raise

        return response

    return app
Example #16
0
def get_limiter(app):
    from limits.storage import RedisInteractor, Storage

    class redisclient_storage(RedisInteractor, Storage):
        """ Storage backend for flask-limiters backend (limiter).

        This is essentially a copy of limiter.storage.RedisStorage, if we
        disregard the usage of ..redisclient and the merging of
        initialize_storage and __init__.

        However, this is not a verbatim copy, as we'd rarther refer to
        RedisInteractor instead of self/RedisClient.
        """
        STORAGE_SCHEME = "rcs"

        def __init__(self, *args, **kwargs):
            self.storage = None

        def _maybee_do_init(f):
            @functools.wraps(f)
            def wrapper(self, *args, **kwargs):
                if self.storage is None:
                    from ..redisclient import store
                    self.storage = store
                    self.lua_moving_window = self.storage.register_script(
                        RedisInteractor.SCRIPT_MOVING_WINDOW)
                    self.lua_acquire_window = self.storage.register_script(
                        RedisInteractor.SCRIPT_ACQUIRE_MOVING_WINDOW)
                    self.lua_clear_keys = self.storage.register_script(
                        RedisInteractor.SCRIPT_CLEAR_KEYS)
                    self.lua_incr_expire = self.storage.register_script(
                        RedisInteractor.SCRIPT_INCR_EXPIRE)
                return f(self, *args, **kwargs)

            return wrapper

        @_maybee_do_init
        def incr(self, key, expiry, elastic_expiry=False):
            if elastic_expiry:
                return super(redisclient_storage,
                             self).incr(key, expiry, self.storage,
                                        elastic_expiry)
            else:
                return self.lua_incr_expire([key], [expiry])

        @_maybee_do_init
        def get(self, key):
            return super(redisclient_storage, self).get(key, self.storage)

        @_maybee_do_init
        def acquire_entry(self, key, limit, expiry, no_add=False):
            return super(redisclient_storage,
                         self).acquire_entry(key,
                                             limit,
                                             expiry,
                                             self.storage,
                                             no_add=no_add)

        @_maybee_do_init
        def get_expiry(self, key):
            return super(redisclient_storage,
                         self).get_expiry(key, self.storage)

        @_maybee_do_init
        def check(self):
            return super(redisclient_storage, self).check(self.storage)

        @_maybee_do_init
        def reset(self):
            cleared = self.lua_clear_keys(['LIMITER*'])
            return cleared

    redis_url = "rcs://"
    limiter = Limiter(app,
                      key_func=get_remote_address,
                      storage_uri=redis_url,
                      strategy='moving-window')
    for handler in app.logger.handlers:
        limiter.logger.addHandler(handler)

    def e():
        raise RateLimitError()

    limiter.limit = functools.partial(limiter.limit, error_message=e)

    return limiter
Example #17
0
from flask_limiter import Limiter
from decorators import admins_only, redirect_if_not_logged_in

app = Flask(__name__)
limiter = Limiter(app)

@app.errorhandler(429)
def error_handler(optional_argument=""):
    if "tid" in session:
        logger.log("spam", logger.CRITICAL, "%s is using the api too quickly!", session["tid"])
    return make_response(jsonify(message="Slow down!"), 200)

app.debug = True
app.secret_key = open(".secret_key", "r").read()
app.jinja_env.trim_blocks = True
limiter.limit("10/minute", error_message=error_handler, exempt_when=lambda: is_admin())(api)
app.register_blueprint(api)

conn = sqlite3.connect("introctf.db", check_same_thread=False)
conn.text_factory = str

@app.route('/')
def index():
    return render_template("index.html", logged_in=is_logged_in(), admin=is_admin())

@app.route("/scoreboard")
def scoreboard():
    scoreboard = teamdb.get_scoreboard_data()
    return render_template("scoreboard.html", logged_in=is_logged_in(), admin=is_admin(), scoreboard=scoreboard)

@app.route("/problems")
Example #18
0
    #connection to db
    dbLogin = ''
    dbPassword = ''
    try:
        dbLogin = os.environ['DatabaseLogin']
        dbPassword = os.environ['DatabasePassword']
    except KeyError:
        print(
            'Please define environment variable DatabaseLogin and DatabasePassword'
        )
        sys.exit(1)
    db = pymysql.connect(host=dbAddr,
                         port=int(dbPort),
                         user=dbLogin,
                         password=dbPassword,
                         db='fictionalinvention')
    cursor = db.cursor()
    app.config['db'] = db
    app.config["cursor"] = cursor
    #secret key for JWT signing
    secretKey = os.urandom(64).hex()
    app.config["secretKey"] = secretKey

    limiter = Limiter(app,
                      key_func=get_remote_address,
                      default_limits=["100 per minute"])
    limiter.limit("3 per minute")(session)
    app.register_blueprint(static)
    app.register_blueprint(session)
    app.register_blueprint(dbquery)
    app.run(host=appHost, port=int(appPort))
Example #19
0
fh.setLevel(ConfigClass.flask_log_level)
fh.setFormatter(formatter)
logger.addHandler(fh)

sh = logging.StreamHandler()
sh.setLevel(ConfigClass.flask_log_level)
sh.setFormatter(formatter)
logger.addHandler(sh)

# Initialize Flask Limiter extension
limiter = Limiter(app, headers_enabled=ConfigClass.xrate_limit_headers_enabled, 
    strategy='fixed-window-elastic-expiry',
    storage_uri=ConfigClass.redis_cache_uri)

# set rate limits for each module/blueprint
limiter.limit("1/second;5/minute")(api_blueprint)
limiter.limit("1/second;10/minute")(users_blueprint)
limiter.limit("1/second;3/minute")(site_blueprint)

# register blueprints
app.register_blueprint(api_blueprint)
app.register_blueprint(users_blueprint)
app.register_blueprint(site_blueprint)


if __name__ == '__main__':
	if ConfigClass.debug_mode:
	    app.run(host=ConfigClass.debug_host, port=ConfigClass.debug_port, debug=True)
	else:
		app.run(debug=False)
Example #20
0
from auth import auth

DEBUG = True
PORT = 8800
HOST = '0.0.0.0'

SECRET_KEY = 'da;lfkjadlfdsafasdfjfdaopsifdsaifdoisafakldf=jdaff'

app = Flask(__name__)
app.secret_key = SECRET_KEY
app.register_blueprint(courses_api)
app.register_blueprint(reviews_api, url_prefix='/api/v1')
app.register_blueprint(users_api, url_prefix='/api/v1')

limiter = Limiter(app, global_limits=['6/hour'], key_func=get_ipaddr)
limiter.limit("40/day")(users_api)
limiter.limit('100/hour', per_method=True, methods=['post', 'put',
                                                    'delete'])(courses_api)
limiter.limit('100/hour', per_method=True, methods=['post', 'put',
                                                    'delete'])(reviews_api)
# limiter.exempt(courses_api)
# limiter.exempt(reviews_api)


@app.route('/')
def hello_world():
    return 'Hello world'


@app.route('/api/v1/users/token', methods=['GET'])
@auth.login_required
Example #21
0
from flask import Flask, g, jsonify, render_template
from flask_limiter import Limiter
from flask_limiter.util import get_ipaddr

from auth import auth
import config
import models
from resources.tasks import todos_api
from resources.users import users_api

app = Flask(__name__)
app.register_blueprint(todos_api, url_prefix='/api/v1')
app.register_blueprint(users_api, url_prefix='/api/v1')

limiter = Limiter(app,
                  global_limits=[config.DEFAULT_RATE],
                  key_func=get_ipaddr)
limiter.limit("40/day")(users_api)
limiter.limit(config.DEFAULT_RATE,
              per_method=True,
              methods=['post', 'put', 'delete'])(todos_api)


@app.route('/')
def my_todos():
    return render_template('index.html')


if __name__ == '__main__':
    models.initialize()
    app.run(debug=config.DEBUG, host=config.HOST, port=config.PORT)
Example #22
0
def register_extensions(app):
    """ register extensions to the app """
    app.jinja_env.add_extension('jinja2.ext.do')  # Global values in jinja

    # Uncomment to enable profiler
    # See scripts/profile_analyzer.py to analyze output
    # app = setup_profiler(app)

    # Compress app responses with gzip
    compress = Compress()
    compress.init_app(app)

    # Influx db time-series database
    db.init_app(app)
    influx_db.init_app(app)

    # Limit authentication blueprint requests to 200 per minute
    limiter = Limiter(app, key_func=get_ip_address)
    limiter.limit("200/minute")(routes_authentication.blueprint)

    # Language translations
    babel = Babel(app)

    @babel.localeselector
    def get_locale():
        try:
            user = User.query.filter(
                User.id == flask_login.current_user.id).first()
            if user and user.language != '':
                for key in LANGUAGES:
                    if key == user.language:
                        return key
        # Bypass endpoint test error "'AnonymousUserMixin' object has no attribute 'id'"
        except AttributeError:
            pass
        return request.accept_languages.best_match(LANGUAGES.keys())

    # User login management
    login_manager = flask_login.LoginManager()
    login_manager.init_app(app)

    @login_manager.user_loader
    def user_loader(user_id):
        user = User.query.filter(User.id == user_id).first()
        if not user:
            return
        return user

    @login_manager.unauthorized_handler
    def unauthorized():
        flash(gettext('Please log in to access this page'), "error")
        return redirect(url_for('routes_authentication.do_login'))

    # Create and populate database if it doesn't exist
    with app.app_context():
        db.create_all()
        populate_db()

        # This is disabled because there's a bug that messes up user databases
        # The upgrade script will execute alembic to upgrade the database
        # alembic_upgrade_db()

    # Check user option to force all web connections to use SSL
    # Fail if the URI is empty (pytest is running)
    if app.config['SQLALCHEMY_DATABASE_URI'] != 'sqlite://':
        with session_scope(app.config['SQLALCHEMY_DATABASE_URI']) as new_session:
            misc = new_session.query(Misc).first()
            if misc and misc.force_https:
                SSLify(app)
Example #23
0
def extension_limiter(app):
    limiter = Limiter(app, key_func=get_key_func, headers_enabled=True)
    limiter.limit("300/hour")(routes_authentication.blueprint)
    limiter.limit("20/hour")(routes_password_reset.blueprint)
    limiter.limit("200/minute")(api_blueprint)
    return app
Example #24
0
from flask import Flask, request
from api.resources import search
from flask_restful import Api
from flask_limiter import Limiter
from flask_limiter.util import get_remote_address

app = Flask(__name__)
api = Api(app)


# Rate Limiting
limiter = Limiter(app, key_func=get_remote_address, default_limits=[
          '50/hour', '200/day'])

rate = limiter.limit('1/second, 5/minute', error_message={
       'Rate Limit Exceeded': '1/second, 5/minutes, 50/hour, 200/day'})

@limiter.request_filter
def ip_whitelist():
    return request.remote_addr == "127.0.0.1"

search.CVE.decorators.append(rate)
search.CVE_Year.decorators.append(rate)
search.CVE_Modified.decorators.append(rate)
search.CVE_Recent.decorators.append(rate)
search.CVE_All.decorators.append(rate)
search.Schema.decorators.append(rate)


# API endpoints
api.add_resource(search.CVE, '/nvd-api/v1/<cve_id>')
Example #25
0
from flask import Flask, render_template

from flask_limiter import Limiter
from flask_limiter.util import get_ipaddr

import config
import models
from resources.todos import todos_api

app = Flask(__name__)
app.register_blueprint(todos_api, url_prefix='/api/v1')

limiter = Limiter(app,
                  default_limits=[config.DEFAULT_RATE],
                  key_func=get_ipaddr)
limiter.limit('100/day', per_method=True, methods=['post', 'put',
                                                   'delete'])(todos_api)


@app.route('/')
def my_todos():
    return render_template('index.html')


if __name__ == '__main__':
    models.initialize()
    app.run(debug=config.DEBUG, host=config.HOST, port=config.PORT)
Example #26
0
from resources.todo import tasks_api
from resources.user import users_api
from auth import auth

import config
import models

app = Flask(__name__)
app.register_blueprint(tasks_api, url_prefix='/api/v1')
app.register_blueprint(users_api, url_prefix='/api/v1')

limiter = Limiter(app,
                  default_limits=[config.DEFAULT_RATE],
                  key_func=get_ipaddr)

limiter.limit("40/day;10/hour;1/min")(users_api)
limiter.limit(config.DEFAULT_RATE,
              per_method=True,
              methods=['post', 'put', 'delete'])(tasks_api)


@app.route('/')
def my_todos():
    return render_template('index.html')


@app.route('/api/v1/users/token', methods=['GET'])
@auth.login_required
def get_auth_token():
    token = g.user.generate_token()
    return jsonify({'token': token.decode('ascii')})
Example #27
0
    'MAILGUN_DOMAIN') or os.environ.get('SERVER_NAME')
app.config['SECRET_KEY'] = os.environ.get('SECRET_KEY')
app.config['SQLALCHEMY_DATABASE_URI'] = db_url

db.app = app
db.init_app(app)


# CSS directives must be inlined in HTML emails.
@app.template_filter('inline_styles')
def inline_styles(html):
    return premailer.transform(html)


limiter = Limiter(app, global_limits=['5/second'])
limiter.limit('100/hour')(ui)
limiter.limit('10/minute')(api)
limiter.limit('100/day')(api)

app.register_blueprint(ui)
app.register_blueprint(api)

if __name__ == '__main__':
    print "Running in debug mode"
    app.debug = True
    app.run()
else:
    handler = logging.StreamHandler()
    handler.setLevel(logging.INFO)
    app.logger.setLevel(logging.INFO)
    app.logger.addHandler(handler)
Example #28
0
import models
from resources.courses import courses_api
from resources.reviews import reviews_api
from resources.users import users_api

app = Flask(__name__)

app.register_blueprint(courses_api, url_prefix='/api/v1')
app.register_blueprint(reviews_api, url_prefix='/api/v1')
app.register_blueprint(users_api, url_prefix='/api/v1')

limiter = Limiter(app,
                  default_limits=[config.DEFAULT_RATE],
                  key_func=get_ipaddr
                  )  # sets the limit and uses ip address to identifyy a user
limiter.limit("40/day")(users_api)  # add an additional limit to a resource
# per_method makes it sensitive to the method involved
# we make an exception to limiting GET requests but limit the other methods
limiter.limit(config.DEFAULT_RATE,
              per_method=True,
              methods=['POST', 'PUT', 'DELETE'])(courses_api)
limiter.limit(config.DEFAULT_RATE,
              per_method=True,
              methods=['POST', 'PUT', 'DELETE'])(reviews_api)
# limiter.exempt(courses_api)
# limiter.exempt(reviews_api)


@app.route('/')
def hello_world():
    return 'Hello World'
Example #29
0
    datefmt='%Y-%m-%d %H:%M:%S')
ch_console.setFormatter(formatter)
logger.addHandler(ch_console)

limiter = Limiter(app,
                  key_func=get_remote_address,
                  default_limits=[],
                  headers_enabled=True,
                  strategy='fixed-window-elastic-expiry')
limiter.logger.addHandler(ch_console)


@limiter.request_filter
def ip_whitelist():
    return request.remote_addr == "127.0.0.1"


from app.api import v1, v2

limiter.limit("5 per second")(v1.bp)
limiter.limit("5 per second")(v2.bp)

app.register_blueprint(v1.bp)
app.register_blueprint(v2.bp)


@app.route("/ping")
@limiter.limit("2 per minute", override_defaults=False)
def ping():
    return "PONG"
Example #30
0
import forms
import models
from auth import auth
from resources.todos import todos_api
from resources.users import users_api

app = Flask(__name__)
app.secret_key = config.SECRET_KEY

app.register_blueprint(users_api, url_prefix='/api/v1')
app.register_blueprint(todos_api, url_prefix='/api/v1')

limiter = Limiter(app,
                  default_limits=[config.DEFAULT_RATE],
                  key_func=get_ipaddr)
limiter.limit("40/day")(users_api)

login_manager = LoginManager()
login_manager.init_app(app)
login_manager.login_view = 'login'


@login_manager.user_loader
def load_user(userid):
    try:
        return models.User.get(models.User.id == userid)
    except models.DoesNotExist:
        return None


@app.before_request
Example #31
0
from flask_limiter import Limiter
from flask_limiter.util import get_ipaddr

import config
import models
from resources.companies import companies_api
from resources.marinas import marinas_api
from resources.users import users_api

app = Flask(__name__)
app.register_blueprint(companies_api, url_prefix='/api/v1')
app.register_blueprint(marinas_api, url_prefix='/api/v1')
app.register_blueprint(users_api, url_prefix='/api/v1')

limiter = Limiter(app, global_limits=[config.DEFAULT_RATE], key_func=get_ipaddr)
limiter.limit('40/day')(users_api)
limiter.limit(config.DEFAULT_RATE, per_method=True,
							methods=['post', 'put', 'delete'](companies_api)
# limiter.exempt(companies_api)
# limiter.exempt(marinas_api)

@app.route('/')
@app.route('/index')
def index():
	return render_template('index.html')

@app.route('/api/v1/users/token', methods=['GET'])
@auth.login_required
def get_auth_token():
	token = g.user.generate_auth_token()
	return jsonify({'token': token.decode('ascii')})
Example #32
0
#!/usr/bin/env python

from flask import Flask, render_template
from flask_limiter import Limiter
from flask_limiter.util import get_remote_address

from routes.email_api import email_api
from routes.photos_api import photos_api

application = app = Flask(__name__)
limiter = Limiter(app, key_func=get_remote_address)

limiter.limit('1/second')(email_api)

app.register_blueprint(email_api)
app.register_blueprint(photos_api)


# catch all to redirect all paths to be handled on client-side by react router
@app.route('/', defaults={'path': ''})
@app.route('/<path:path>')
def load_app(path):
    return render_template('index.html')

if __name__ == '__main__':
    app.run(debug=False)
Example #33
0
from flask import Flask, jsonify
from flask_restful import Resource, Api
from flask_limiter import Limiter
from flask_limiter.util import get_remote_address
from flask_caching import Cache
from .course import course
from .invalid import *

app = Flask(__name__)
api = Api(app, prefix="/cutimetable/v1")
limiter = Limiter(app,
                  key_func=get_remote_address,
                  default_limits=["2 per 5 second"])
app.config["JSON_SORT_KEYS"] = False
app.config["JSON_AS_ASCII"] = False
# app.register_blueprint(course.bp, url_prefix="/cutimetable/v1")

course.Course.method_decorators.append(limiter.limit("10 per minute"))
api.add_resource(course.Course, "/course/<string:id>")


@app.errorhandler(InvalidUsage)
def handle_invalid_usage(error):
    response = jsonify(error.to_dict())
    response.status_code = error.status_code
    return response
Example #34
0
app.config['PREFERRED_URL_SCHEME'] = 'https'
app.config['SERVER_NAME'] = os.environ.get('SERVER_NAME')
app.config['SECRET_KEY'] = os.environ.get('SECRET_KEY')
app.config['SQLALCHEMY_DATABASE_URI'] = os.environ.get('DATABASE_URL')

db.app = app
db.init_app(app)

# CSS directives must be inlined in HTML emails.
@app.template_filter('inline_styles')
def inline_styles(html):
    return premailer.transform(html)

limiter = Limiter(app, global_limits=['5/second'])
limiter.limit('100/hour')(ui)
limiter.limit('10/minute')(api)
limiter.limit('100/day')(api)

app.register_blueprint(ui)
app.register_blueprint(api)

if __name__ == '__main__':
    print "Running in debug mode"
    app.debug = True
    app.run()
else:
    handler = logging.StreamHandler()
    handler.setLevel(logging.INFO)
    app.logger.setLevel(logging.INFO)
    app.logger.addHandler(handler)
Example #35
0
formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(module)s %(funcName)s : %(message)s')

fh = logging.FileHandler(ConfigClass.flask_logfile)
fh.setLevel(ConfigClass.flask_log_level)
fh.setFormatter(formatter)
logger.addHandler(fh)

sh = logging.StreamHandler()
sh.setLevel(ConfigClass.flask_log_level)
sh.setFormatter(formatter)
logger.addHandler(sh)

# Initialize Flask Limiter extension
limiter = Limiter(app, headers_enabled=ConfigClass.xrate_limit_headers_enabled, 
    strategy='fixed-window-elastic-expiry',
    storage_uri=ConfigClass.redis_cache_uri)

# set rate limits for each module/blueprint
limiter.limit("1/second;5/minute")(api_blueprint)
limiter.limit("1/second;10/minute")(users_blueprint)

# register blueprints
app.register_blueprint(api_blueprint)
app.register_blueprint(users_blueprint)

if __name__ == '__main__':
	if ConfigClass.debug_mode:
	    app.run(host=ConfigClass.debug_host, port=ConfigClass.debug_port, debug=True)
	else:
		app.run(debug=False)
Example #36
0
def create_app():
    app = Flask(__name__, instance_relative_config=True)
    app.config.from_pyfile('config.py')

    db.init_app(app)
    from briefly.models.users import Users
    from briefly.models.authors import Authors

    redis_client.init_app(app)

    ch_file = handlers.RotatingFileHandler('logs/briefly.log',
                                           maxBytes=1000000,
                                           backupCount=5)
    formatter = logging.Formatter(
        '%(asctime)s - %(name)s - %(levelname)s: %(message)s',
        datefmt='%Y-%m-%d %H:%M:%S')
    ch_file.setFormatter(formatter)

    limiter = Limiter(
        app,
        key_func=get_remote_address,
        default_limits=
        [],  # [count] [per|/] [n (optional)] [second|minute|hour|day|month|year]
        headers_enabled=True,
        strategy='fixed-window-elastic-expiry')
    limiter.logger.addHandler(ch_file)
    limiter.init_app(app)

    @limiter.request_filter
    def ip_whitelist():
        return request.remote_addr == "127.0.0.1"

    from briefly.api.v1 import endpoints as api_v1
    limiter.limit("20 per second")(api_v1.bp)
    app.register_blueprint(api_v1.bp)

    @app.route('/')
    def index():
        return render_template('index.html')

    @app.route('/about')
    def about():
        return render_template('about.html')

    @app.route('/api')
    def api():
        return render_template('api.html')

    @app.route('/reg', methods=['GET'])
    def reg():
        return render_template('reg.html', email=email)

    @app.route('/regme', methods=['POST'])
    @limiter.limit('5 per day')
    def regme():
        if request.method == 'POST' and request.form['emailaddress']:
            token = uuid.uuid4()
            email = request.form['emailaddress']
            ip = request.remote_addr

            if not email:
                message = 'E-mail is required.'
            else:
                is_user_present = Users.query.filter_by(
                    user_email=email).first()
                if is_user_present is None:
                    new_user = Users(user_email=email,
                                     user_token=str(token),
                                     user_reg_ip=ip)
                    db.session.add(new_user)
                    db.session.commit()

                    message = 'Token was sent to your e-mail'
                    text_body = render_template('emails/new_user.txt',
                                                token=token)
                    Thread(target=send_async_email,
                           args=(current_app._get_current_object(), email,
                                 text_body)).start()
                else:
                    message = 'E-mail is already registered.'

            flash(message)
            return redirect(url_for('reg'))

    @app.route('/authors/<letter>', methods=['GET'])
    @limiter.limit('100/second')
    def letter(letter):
        answer = {'status': False, 'number_of_records': 0, 'authors': []}
        letters = [
            'А', 'Б', 'В', 'Г', 'Д', 'Е', 'Ж', 'З', 'И', 'К', 'Л', 'М', 'Н',
            'О', 'П', 'Р', 'С', 'Т', 'У', 'Ф', 'Х', 'Ц', 'Ч', 'Ш', 'Э', 'Ю',
            'Я'
        ]
        if len(letter) == 1 and letter in letters:
            answer['status'] = True
            sql = f'SELECT id, author_fullname, author_url ' \
                f'FROM authors ' \
                f'WHERE author_fullname ' \
                f'REGEXP "[а-яА-Я]+ [а-яА-Я]+ {letter}"'
            authors = Authors.query.from_statement(text(sql)).all()
            if authors:
                answer['number_of_records'] = len(authors)
                for author in authors:
                    answer['authors'].append({
                        'id': author.id,
                        'author_fullname': author.author_fullname,
                        'author_url': author.author_url
                    })

        return jsonify(answer), 200

    @app.errorhandler(429)
    def ratelimit_handler(e):
        return make_response(jsonify(error="Too Many Requests"), 429)

    @app.errorhandler(400)
    def badrequest_handler(e):
        return make_response(jsonify(error="Bad Request"), 400)

    @app.errorhandler(405)
    def method_not_allowd_handler(e):
        return make_response(jsonify(error="Method Not Allowed"), 405)

    return app