def create_app(settings_ns): babel = Babel() app = Flask( __name__, static_url_path="/static", static_folder="static", instance_relative_config=False, ) app.config.from_object(settings_ns) app.register_blueprint(main_bp) app.jinja_env.filters["clean_uri"] = clean_uri app.context_processor(utility_processor) babel.init_app(app) if app.config["DEBUG"]: try: from flask_debugtoolbar import DebugToolbarExtension except ImportError: LOGGER.info('cannot import lib "flask_debugtoolbar". ' 'Make sure it is installed and available in the ' 'import path.') else: toolbar = DebugToolbarExtension() toolbar.init_app(app) return app
def register_babel(app): babel = Babel() babel.init_app(app) class CustomJSONEncoder(JSONEncoder): """This class adds support for lazy translation texts to Flask's JSON encoder. This is necessary when flashing translated texts.""" def default(self, obj): from speaklater import is_lazy_string if is_lazy_string(obj): try: return unicode(obj) # python 2 except NameError: return str(obj) # python 3 return super(CustomJSONEncoder, self).default(obj) app.json_encoder = CustomJSONEncoder @babel.localeselector def get_locale(): user = getattr(g, 'user', None) if user is not None: if g.user.is_authenticated: return user.setting.locale or 'zh' return request.accept_languages.best_match(app.config[ 'LANGUAGES'].keys()) @babel.timezoneselector def get_timezone(): user = getattr(g, 'user', None) if user is not None: if g.user.is_authenticated: return user.setting.timezone or 'UTC' return 'UTC'
def register_babel(app): translations = os.path.abspath(os.path.join( os.path.dirname(__file__), os.pardir, 'translations')) domain = Domain(translations) babel = Babel(default_domain=domain) babel.init_app(app) class CustomJSONEncoder(JSONEncoder): """This class adds support for lazy translation texts to Flask's JSON encoder. This is necessary when flashing translated texts.""" def default(self, obj): from speaklater import is_lazy_string if is_lazy_string(obj): try: return unicode(obj) # python 2 except NameError: return str(obj) # python 3 return super(CustomJSONEncoder, self).default(obj) app.json_encoder = CustomJSONEncoder @babel.localeselector def get_locale(): return request.accept_languages.best_match(['zh', 'en']) @babel.timezoneselector def get_timezone(): return 'UTC'
def __init__(self, app=None, date_formats=None, localeselector=None, timezoneselector=None, entry_point_group='invenio_i18n.translations'): """Initialize extension. :param app: Flask application. :param data_formats: Override default date/time formatting. :param localeselector: Callback function used for locale selection. (Default: :func:`invenio_i18n.selectors.get_locale()`) :param timezoneselector: Callback function used for timezone selection. (Default: ``BABEL_DEFAULT_TIMEZONE``) :param entry_point_group: Entrypoint used to load translations from. Set to ``None`` to not load translations from entry points. """ self.domain = MultidirDomain() self.babel = Babel( date_formats=date_formats, configure_jinja=True, default_domain=self.domain, ) self.localeselector = localeselector self.timezoneselector = timezoneselector self.entry_point_group = entry_point_group self._locales_cache = None self._languages_cache = None if app: self.init_app(app)
def __init__(self, app=None, date_formats=None, localeselector=None, timezoneselector=None, entry_point_group='invenio_i18n.translations'): """Initialize extension.""" self.babel = Babel( date_formats=date_formats, configure_jinja=True, default_domain=MultidirDomain()) self.localeselector = localeselector self.timezoneselector = timezoneselector self.entry_point_group = entry_point_group self._locales_cache = None self._languages_cache = None if app: self.init_app(app)
def create_app(config_filename="config.py", app_name=None, register_blueprints=True): # App configuration app = Flask(app_name or __name__) app.config.from_pyfile(config_filename) socketio.init_app(app, message_queue=app.config["SOCKETIO_MESSAGE_QUEUE"]) app.jinja_env.add_extension("jinja2.ext.with_") app.jinja_env.add_extension("jinja2.ext.do") if HAS_SENTRY: app.config["SENTRY_RELEASE"] = raven.fetch_git_sha( os.path.dirname(__file__)) sentry = Sentry(app, dsn=app.config["SENTRY_DSN"]) # noqa: F841 print("Sentry support activated") print("Sentry DSN: %s" % app.config["SENTRY_DSN"]) if app.config["DEBUG"] is True: app.jinja_env.auto_reload = True app.logger.setLevel(logging.DEBUG) # Logging if not app.debug: formatter = logging.Formatter("%(asctime)s %(levelname)s: %(message)s " "[in %(pathname)s:%(lineno)d]") file_handler = RotatingFileHandler("%s/errors_app.log" % os.getcwd(), "a", 1000000, 1) file_handler.setLevel(logging.DEBUG) file_handler.setFormatter(formatter) app.logger.addHandler(file_handler) mail.init_app(app) migrate = Migrate(app, db) # noqa: F841 babel = Babel(app) # noqa: F841 toolbar = DebugToolbarExtension(app) # noqa: F841 db.init_app(app) git_version = "" gitpath = os.path.join(os.getcwd(), ".git") if os.path.isdir(gitpath): git_version = subprocess.check_output( ["git", "rev-parse", "--short", "HEAD"]) if git_version: git_version = git_version.strip().decode("UTF-8") @babel.localeselector def get_locale(): # if a user is logged in, use the locale from the user settings identity = getattr(g, "identity", None) if identity is not None and identity.id: return identity.user.locale # otherwise try to guess the language from the user accept # header the browser transmits. We support fr/en in this # example. The best match wins. return request.accept_languages.best_match(["fr", "en"]) @babel.timezoneselector def get_timezone(): identity = getattr(g, "identity", None) if identity is not None and identity.id: return identity.user.timezone @app.before_request def before_request(): cfg = { "PYAIRWAVES_VERSION_VER": VERSION, "PYAIRWAVES_VERSION_GIT": git_version, "PYAIRWAVES_VERSION": "{0} ({1})".format(VERSION, git_version), } g.cfg = cfg @app.errorhandler(InvalidUsage) def handle_invalid_usage(error): response = jsonify(error.to_dict()) response.status_code = error.status_code return response if register_blueprints: from controllers.main import bp_main app.register_blueprint(bp_main) @app.errorhandler(404) def page_not_found(msg): pcfg = { "title": gettext("Whoops, something failed."), "error": 404, "message": gettext("Page not found"), "e": msg, } return render_template("error_page.jinja2", pcfg=pcfg), 404 @app.errorhandler(403) def err_forbidden(msg): pcfg = { "title": gettext("Whoops, something failed."), "error": 403, "message": gettext("Access forbidden"), "e": msg, } return render_template("error_page.jinja2", pcfg=pcfg), 403 @app.errorhandler(410) def err_gone(msg): pcfg = { "title": gettext("Whoops, something failed."), "error": 410, "message": gettext("Gone"), "e": msg } return render_template("error_page.jinja2", pcfg=pcfg), 410 if not app.debug: @app.errorhandler(500) def err_failed(msg): pcfg = { "title": gettext("Whoops, something failed."), "error": 500, "message": gettext("Something is broken"), "e": msg, } return render_template("error_page.jinja2", pcfg=pcfg), 500 @app.after_request def set_x_powered_by(response): response.headers["X-Powered-By"] = "pyAirwaves" return response # Other commands @app.cli.command() def routes(): """Dump all routes of defined app""" table = texttable.Texttable() table.set_deco(texttable.Texttable().HEADER) table.set_cols_dtype(["t", "t", "t"]) table.set_cols_align(["l", "l", "l"]) table.set_cols_width([50, 30, 80]) table.add_rows([["Prefix", "Verb", "URI Pattern"]]) for rule in sorted(app.url_map.iter_rules(), key=lambda x: str(x)): methods = ",".join(rule.methods) table.add_row([rule.endpoint, methods, rule]) print(table.draw()) @app.cli.command() def config(): """Dump config""" pp(app.config) @app.cli.command() def seed(): """Seed database with default content""" # make_db_seed(db) pass @app.cli.command() def download_and_ingest_faa(): """Downloads and ingest FAA datas""" utils_download_and_ingest_faa() @app.cli.command() def update_db(): """Downloads and ingest various datas""" update_all_db() @app.cli.command() def import_aircrafts(): """Ingest aircrafts""" update_aircrafts() @app.cli.command() def import_registrations(): """Ingest registrations""" update_registrations() return app
webapp.config['MAIL_USE_SSL'] = app.smtp['use_ssl'] webapp.config['MAIL_USE_TLS'] = app.smtp['use_tls'] webapp.config['MAIL_PORT'] = app.smtp['port'] ############################################################################### # Initialize standard Flask extensions db.init_app(webapp) csrf = CSRFProtect(webapp) security = Security(webapp, user_datastore, login_form=CustomLoginForm, register_form=CustomRegisterForm) mail = Mail(webapp) migrate = Migrate(webapp, db) babel = Babel(webapp) ############################################################################### # Hooks @webapp.before_first_request def init_database(): """Initiate database and create admin user""" db.create_all() for role_definition in app.role_definitions: name = role_definition['name'] description = role_definition['description'] permissions = role_definition['permissions'] level = role_definition['level'] user_datastore.find_or_create_role(
def app(request): app = Flask(__name__) app.response_class = Response app.debug = True app.config["SECRET_KEY"] = "secret" app.config["TESTING"] = True app.config["LOGIN_DISABLED"] = False app.config["WTF_CSRF_ENABLED"] = False app.config["SECURITY_TWO_FACTOR_SECRET"] = { "1": "TjQ9Qa31VOrfEzuPy4VHQWPCTmRzCnFzMKLxXYiZu9B" } app.config["SECURITY_TWO_FACTOR_SMS_SERVICE"] = "test" app.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = False app.config["SECURITY_PASSWORD_SALT"] = "salty" # Make this plaintext for most tests - reduces unit test time by 50% app.config["SECURITY_PASSWORD_HASH"] = "plaintext" # Make this hex_md5 for token tests app.config["SECURITY_HASHING_SCHEMES"] = ["hex_md5"] app.config["SECURITY_DEPRECATED_HASHING_SCHEMES"] = [] for opt in [ "changeable", "recoverable", "registerable", "trackable", "passwordless", "confirmable", "two_factor", ]: app.config["SECURITY_" + opt.upper()] = opt in request.keywords pytest_major = int(pytest.__version__.split(".")[0]) if pytest_major >= 4: marker_getter = request.node.get_closest_marker else: marker_getter = request.keywords.get settings = marker_getter("settings") babel = marker_getter("babel") if settings is not None: for key, value in settings.kwargs.items(): app.config["SECURITY_" + key.upper()] = value mail = Mail(app) if babel is None or babel.args[0]: Babel(app) app.json_encoder = JSONEncoder app.mail = mail @app.route("/") def index(): return render_template("index.html", content="Home Page") @app.route("/profile") @login_required def profile(): return render_template("index.html", content="Profile Page") @app.route("/post_login") @login_required def post_login(): return render_template("index.html", content="Post Login") @app.route("/http") @http_auth_required def http(): return "HTTP Authentication" @app.route("/http_custom_realm") @http_auth_required("My Realm") def http_custom_realm(): return render_template("index.html", content="HTTP Authentication") @app.route("/token", methods=["GET", "POST"]) @auth_token_required def token(): return render_template("index.html", content="Token Authentication") @app.route("/multi_auth") @auth_required("session", "token", "basic") def multi_auth(): return render_template("index.html", content="Session, Token, Basic auth") @app.route("/post_logout") def post_logout(): return render_template("index.html", content="Post Logout") @app.route("/post_register") def post_register(): return render_template("index.html", content="Post Register") @app.route("/post_confirm") def post_confirm(): return render_template("index.html", content="Post Confirm") @app.route("/admin") @roles_required("admin") def admin(): return render_template("index.html", content="Admin Page") @app.route("/admin_and_editor") @roles_required("admin", "editor") def admin_and_editor(): return render_template("index.html", content="Admin and Editor Page") @app.route("/admin_or_editor") @roles_accepted("admin", "editor") def admin_or_editor(): return render_template("index.html", content="Admin or Editor Page") @app.route("/simple") @roles_accepted("simple") def simple(): return render_template("index.html", content="SimplePage") @app.route("/admin_perm") @permissions_accepted("full-write", "super") def admin_perm(): return render_template("index.html", content="Admin Page with full-write or super") @app.route("/admin_perm_required") @permissions_required("full-write", "super") def admin_perm_required(): return render_template("index.html", content="Admin Page required") @app.route("/unauthorized") def unauthorized(): return render_template("unauthorized.html") @app.route("/page1") def page_1(): return "Page 1" @app.route("/json", methods=["GET", "POST"]) def echo_json(): return jsonify(flask_request.get_json()) return app
def create_app(config_filename="config.py", app_name=None, register_blueprints=True): # App configuration app = Flask(app_name or __name__) app.config.from_pyfile(config_filename) Bootstrap(app) app.jinja_env.add_extension("jinja2.ext.with_") app.jinja_env.add_extension("jinja2.ext.do") app.jinja_env.globals.update(is_admin=is_admin) app.jinja_env.filters["localize"] = dt_utc_to_user_tz app.jinja_env.filters["show_date_no_offset"] = show_date_no_offset if HAS_SENTRY: app.config["SENTRY_RELEASE"] = raven.fetch_git_sha( os.path.dirname(__file__)) sentry = Sentry(app, dsn=app.config["SENTRY_DSN"]) # noqa: F841 print(" * Sentry support activated") print(" * Sentry DSN: %s" % app.config["SENTRY_DSN"]) if app.config["DEBUG"] is True: app.jinja_env.auto_reload = True app.logger.setLevel(logging.DEBUG) # Logging if not app.debug: formatter = logging.Formatter( "%(asctime)s %(levelname)s: %(message)s [in %(pathname)s:%(lineno)d]" ) file_handler = RotatingFileHandler("%s/errors_app.log" % os.getcwd(), "a", 1000000, 1) file_handler.setLevel(logging.DEBUG) file_handler.setFormatter(formatter) app.logger.addHandler(file_handler) mail.init_app(app) migrate = Migrate(app, db) # noqa: F841 babel = Babel(app) # noqa: F841 toolbar = DebugToolbarExtension(app) # noqa: F841 db.init_app(app) # Setup Flask-Security security = Security( # noqa: F841 app, user_datastore, register_form=ExtendedRegisterForm, confirm_register_form=ExtendedRegisterForm) @FlaskSecuritySignals.password_reset.connect_via(app) @FlaskSecuritySignals.password_changed.connect_via(app) def log_password_reset(sender, user): if not user: return # add_user_log(user.id, user.id, "user", "info", "Your password has been changed !") @FlaskSecuritySignals.reset_password_instructions_sent.connect_via(app) def log_reset_password_instr(sender, user, token): if not user: return # add_user_log(user.id, user.id, "user", "info", "Password reset instructions sent.") git_version = "" gitpath = os.path.join(os.getcwd(), ".git") if os.path.isdir(gitpath): git_version = subprocess.check_output( ["git", "rev-parse", "--short", "HEAD"]) if git_version: git_version = git_version.strip().decode("UTF-8") @babel.localeselector def get_locale(): # if a user is logged in, use the locale from the user settings # FIXME: not implemented yet # identity = getattr(g, "identity", None) # if identity is not None and identity.id: # return identity.user.locale # otherwise try to guess the language from the user accept # header the browser transmits. We support fr/en in this # example. The best match wins. return request.accept_languages.best_match(["fr", "en"]) @babel.timezoneselector def get_timezone(): # identity = getattr(g, "identity", None) # if identity is not None and identity.id: # return identity.user.timezone # FIXME: not implemented yet pass @app.before_request def before_request(): cfg = { "AHRL_VERSION_VER": VERSION, "AHRL_VERSION_GIT": git_version, "AHRL_VERSION": "{0} ({1})".format(VERSION, git_version), } g.cfg = cfg @app.errorhandler(InvalidUsage) def handle_invalid_usage(error): response = jsonify(error.to_dict()) response.status_code = error.status_code return response pictures = UploadSet("pictures", IMAGES) configure_uploads(app, pictures) patch_request_class(app, 5 * 1024 * 1024) # 5m limit if register_blueprints: from controllers.admin import bp_admin app.register_blueprint(bp_admin) from controllers.contacts import bp_contacts app.register_blueprint(bp_contacts) from controllers.logbooks import bp_logbooks app.register_blueprint(bp_logbooks) from controllers.main import bp_main app.register_blueprint(bp_main) from controllers.notes import bp_notes app.register_blueprint(bp_notes) from controllers.qsos import bp_qsos app.register_blueprint(bp_qsos) from controllers.tools import bp_tools app.register_blueprint(bp_tools) from controllers.users import bp_users app.register_blueprint(bp_users) from controllers.extapi import bp_extapi app.register_blueprint(bp_extapi) @app.route("/uploads/<string:thing>/<path:stuff>", methods=["GET"]) def get_uploads_stuff(thing, stuff): if app.debug: directory = safe_join(app.config["UPLOADS_DEFAULT_DEST"], thing) app.logger.debug(f"serving {stuff} from {directory}") return send_from_directory(directory, stuff, as_attachment=True) else: app.logger.debug(f"X-Accel-Redirect serving {stuff}") resp = Response("") resp.headers[ "Content-Disposition"] = f"attachment; filename={stuff}" resp.headers[ "X-Accel-Redirect"] = f"/_protected/media/tracks/{thing}/{stuff}" return resp @app.errorhandler(404) def page_not_found(msg): pcfg = { "title": gettext("Whoops, something failed."), "error": 404, "message": gettext("Page not found"), "e": msg, } return render_template("error_page.jinja2", pcfg=pcfg), 404 @app.errorhandler(403) def err_forbidden(msg): pcfg = { "title": gettext("Whoops, something failed."), "error": 403, "message": gettext("Access forbidden"), "e": msg, } return render_template("error_page.jinja2", pcfg=pcfg), 403 @app.errorhandler(410) def err_gone(msg): pcfg = { "title": gettext("Whoops, something failed."), "error": 410, "message": gettext("Gone"), "e": msg } return render_template("error_page.jinja2", pcfg=pcfg), 410 if not app.debug: @app.errorhandler(500) def err_failed(msg): pcfg = { "title": gettext("Whoops, something failed."), "error": 500, "message": gettext("Something is broken"), "e": msg, } return render_template("error_page.jinja2", pcfg=pcfg), 500 @app.after_request def set_x_powered_by(response): response.headers["X-Powered-By"] = "ahrl" return response # Commands from Flask CLI @app.cli.command() def routes(): """Dump all routes of defined app""" table = texttable.Texttable() table.set_deco(texttable.Texttable().HEADER) table.set_cols_dtype(["t", "t", "t"]) table.set_cols_align(["l", "l", "l"]) table.set_cols_width([50, 30, 80]) table.add_rows([["Prefix", "Verb", "URI Pattern"]]) for rule in sorted(app.url_map.iter_rules(), key=lambda x: str(x)): methods = ",".join(rule.methods) table.add_row([rule.endpoint, methods, rule]) print(table.draw()) @app.cli.command() def config(): """Dump config""" pp(app.config) @app.cli.command() def seed(): """Seed database with default content""" make_db_seed(db) @app.cli.command() def createuser(): """Create an user""" username = click.prompt("Username", type=str) email = click.prompt("Email", type=str) password = click.prompt("Password", type=str, hide_input=True, confirmation_prompt=True) while True: role = click.prompt("Role [admin/user]", type=str) if role == "admin" or role == "user": break if click.confirm("Do you want to continue ?"): role = Role.query.filter(Role.name == role).first() if not role: raise click.UsageError("Roles not present in database") u = user_datastore.create_user(name=username, email=email, password=encrypt_password(password), roles=[role]) db.session.commit() if FSConfirmable.requires_confirmation(u): FSConfirmable.send_confirmation_instructions(u) print("Look at your emails for validation instructions.") @app.cli.group() def cron(): """Commands to be run regullary""" pass @cron.command() @click.option("--file", default=None, help="Local file to import instead of downloading", type=click.Path(exists=True)) def update_dxcc_from_cty(file): """Update DXCC tables from cty.xml""" print("-- STARTED on {0}".format(datetime.datetime.now())) update_dxcc_from_cty_xml(file) print("-- FINISHED on {0}".format(datetime.datetime.now())) @cron.command() def update_qsos_countries(): """Update QSOs with empty country""" print("-- STARTED on {0}".format(datetime.datetime.now())) update_qsos_without_countries() print("-- FINISHED on {0}".format(datetime.datetime.now())) @cron.command() @click.option("--dryrun", default=False, help="Dry run, doesn't commit anything") def sync_to_eqsl(dryrun=False): """Push to eQSL logs with requested eQSL sync""" print("-- STARTED on {0}".format(datetime.datetime.now())) cron_sync_eqsl(dryrun) print("-- FINISHED on {0}".format(datetime.datetime.now())) @cron.command() @click.option("--dryrun", default=False, help="Dry run, doesn't commit anything") def sync_from_eqsl(dryrun=False): """Fetch from eQSL logs """ print("-- STARTED on {0}".format(datetime.datetime.now())) cron_sync_from_eqsl(dryrun) print("-- FINISHED on {0}".format(datetime.datetime.now())) @cron.command() def update_qsos_hamqth(): """Update QSOs with datas from HamQTH""" print("-- STARTED on {0}".format(datetime.datetime.now())) update_qsos_from_hamqth() print("-- FINISHED on {0}".format(datetime.datetime.now())) @cron.command() def populate_logs_gridsquare(): """Update QSOs with empty gridsquare cache""" print("-- STARTED on {0}".format(datetime.datetime.now())) populate_logs_gridsquare_cache() print("-- FINISHED on {0}".format(datetime.datetime.now())) return app
# -*- coding: utf-8 -*- from flask import Flask, request, session from flask_sqlalchemy import SQLAlchemy from flask_babelex import Babel, Domain, lazy_gettext from wtforms import validators from plumbum import Plumbum, ModelView sqla_domain = Domain(domain='sqla-babel', dirname='locales') # Create application app = Flask(__name__) babel = Babel(app, default_domain=sqla_domain) app.config['SECRET_KEY'] = '1234' app.config['DEBUG'] = True app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///sample_data.db' app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False app.config['PLUMBUM_DEBUG_TEMPLATE'] = False db = SQLAlchemy(app) @babel.localeselector def get_locale(): override = request.args.get('lang') if override:
def create_app(): # Create Flask app load app.config app = Flask(__name__) app.config.from_object(__name__+'.ConfigClass') # Initialize Flask-BabelEx babel = Babel(app) # Initialize Flask-SQLAlchemy @babel.localeselector def get_locale(): translations = [str(translation) for translation in babel.list_translations()] # return request.accept_languages.best_match(translations) # @babel.localeselector #def get_locale(): # if request.args.get('lang'): # session['lang'] = request.args.get('lang') # return session.get('lang', 'tr') db = SQLAlchemy(app) # Define the User data-model. # NB: Make sure to add flask_user UserMixin !!! class User(db.Model, UserMixin): __tablename__ = 'users' id = db.Column(db.Integer, primary_key=True) active = db.Column('is_active', db.Boolean(), nullable=False, server_default='1') # User authentication information. The collation='NOCASE' is required # to search case insensitively when USER_IFIND_MODE is 'nocase_collation'. email = db.Column(db.String(255, collation='NOCASE'), nullable=False, unique=True) email_confirmed_at = db.Column(db.DateTime()) password = db.Column(db.String(255), nullable=False, server_default='') # User information first_name = db.Column(db.String(100, collation='NOCASE'), nullable=False, server_default='') last_name = db.Column(db.String(100, collation='NOCASE'), nullable=False, server_default='') # Define the relationship to Role via UserRoles roles = db.relationship('Role', secondary='user_roles') # Define the Role data-model class Role(db.Model): __tablename__ = 'roles' id = db.Column(db.Integer(), primary_key=True) name = db.Column(db.String(50), unique=True) # Define the UserRoles association table class UserRoles(db.Model): __tablename__ = 'user_roles' id = db.Column(db.Integer(), primary_key=True) user_id = db.Column(db.Integer(), db.ForeignKey('users.id', ondelete='CASCADE')) role_id = db.Column(db.Integer(), db.ForeignKey('roles.id', ondelete='CASCADE')) # Setup Flask-User and specify the User data-model user_manager = UserManager(app, db, User) # Create all database tables db.create_all() # Create '*****@*****.**' user with no roles if not User.query.filter(User.email == '*****@*****.**').first(): user = User( email='*****@*****.**', email_confirmed_at=datetime.datetime.utcnow(), password=user_manager.hash_password('Password1'), ) db.session.add(user) db.session.commit() # Create '*****@*****.**' user with 'Admin' and 'Agent' roles if not User.query.filter(User.email == '*****@*****.**').first(): user = User( email='*****@*****.**', email_confirmed_at=datetime.datetime.utcnow(), password=user_manager.hash_password('Password1'), ) user.roles.append(Role(name='Admin')) user.roles.append(Role(name='Agent')) db.session.add(user) db.session.commit() @app.route('/') def home_page(): return render_template_string(""" {% extends "flask_user_layout.html" %} {% block content %} <h2>{%trans%}Ana sayfa{%endtrans%}</h2> <h1>{%trans%}Bu web sitesinin anasayfasıdır{%endtrans%}</h1> <p><a href={{ url_for('user.register') }}>{%trans%}Kayıt ol{%endtrans%}</a></p> <p><a href={{ url_for('user.login') }}>{%trans%}Giriş Yap{%endtrans%}</a></p> <p><a href={{ url_for('home_page') }}>{%trans%}Ana sayfa{%endtrans%}</a> (Herkes erişebilir)</p> <p><a href={{ url_for('member_page') }}>{%trans%}Üye sayfası{%endtrans%}</a> (Giriş gerekli: [email protected] / Password1)</p> <p><a href={{ url_for('admin_page') }}>{%trans%}Admin sayfası{%endtrans%}</a> (Rol gerekli: [email protected] / Password1)</p> <p><a href={{ url_for('user.logout') }}>{%trans%}Çıkış{%endtrans%}</a></p> {% endblock %} """)
def create_app(config_name): app = Flask(config_name) app.config.from_object(config[config_name]) # 全局响应头 @app.after_request def after_request(response): if "Access-Control-Allow-Origin" not in response.headers.keys(): response.headers['Access-Control-Allow-Origin'] = '*' if request.method == 'OPTIONS': response.headers[ 'Access-Control-Allow-Methods'] = 'DELETE, GET, POST, PUT' headers = request.headers.get('Access-Control-Request-Headers') if headers: response.headers['Access-Control-Allow-Headers'] = headers return response # 自定义错误日志 handler = logging.FileHandler('app.log', encoding='UTF-8') logging_format = logging.Formatter( '%(asctime)s - %(levelname)s - %(filename)s - %(funcName)s - %(lineno)s - %(message)s' ) handler.setFormatter(logging_format) app.logger.addHandler(handler) def init_login(): login_manager = login.LoginManager() login_manager.setup_app(app) # Create user loader function @login_manager.user_loader def load_user(user_id): return AdminUser.objects(id=user_id).first() @app.errorhandler(404) def page_not_found(e): return jsonify(msg='404 page not found') # 注册所有蓝图 for bp_name in blueprints: bp = import_string(bp_name) app.register_blueprint(bp) config[config_name].init_app(app) babel = Babel(app) db.init_app(app) docs.init_app(app) admin.init_app(app) init_login() limiter.init_app(app) celery.init_app(app) redis.init_app(app) celery.conf.update(app.config) db.register_connection(db='ultrabear_homework', alias="home", port=PORT, username=NAME, password=PWD) # 跨域 CORS(app, supports_credentials=True) return app
def app(request): """Flask application fixture.""" # Set temporary instance path for sqlite instance_path = tempfile.mkdtemp() app = Flask('testapp', instance_path=instance_path) app.config.update( SQLALCHEMY_DATABASE_URI=os.environ.get( 'SQLALCHEMY_DATABASE_URI', 'sqlite:///test.db' ), TESTING=True, SECRET_KEY='SECRET_KEY', SQLALCHEMY_TRACK_MODIFICATIONS=False, JSONSCHEMAS_ENDPOINT='/schema', JSONSCHEMAS_HOST='ils.test.rero.ch', RECORDS_UI_ENDPOINTS={ "doc": { "pid_type": "doc", "route": "/documents/<pid_value>", "template": "rero_ils/detailed_view_documents_items.html" } } ) InvenioDB(app) InvenioPIDStore(app) InvenioRecords(app) InvenioAccounts(app) REROILSAPP(app) InvenioAccess(app) InvenioJSONSchemas(app) InvenioRecordsUI(app) Menu(app) Babel(app) app.register_blueprint(item_blueprint) @app.route('/test/login') def login(): from flask_security import login_user from flask import request as flask_request role = flask_request.args.get('role') if role: datastore.create_role(name=role) datastore.add_role_to_user(user, role) datastore.commit() login_user(user) return "Logged In" @app.route('/test/login') def logout(): from flask_security import logout_user logout_user() return "Logged Out" from invenio_db import db as db_ with app.app_context(): if not database_exists(str(db_.engine.url)): create_database(str(db_.engine.url)) db_.create_all() security = LocalProxy(lambda: app.extensions['security']) datastore = LocalProxy(lambda: security.datastore) user = datastore.create_user( email='*****@*****.**', active=True, password=hash_password('aafaf4as5fa') ) yield app # Teardown instance path. db_.session.remove() db_.drop_all() shutil.rmtree(instance_path)
def create_app(): """ Flask application factory """ # Create Flask app load app.config app = Flask(__name__) app.config.from_object(__name__ + '.ConfigClass') # Initialize Flask-BabelEx babel = Babel(app) # Initialize Flask-SQLAlchemy @babel.localeselector def get_locale(): translations = [ str(translation) for translation in babel.list_translations() ] # return request.accept_languages.best_match(translations) # @babel.localeselector #def get_locale(): # if request.args.get('lang'): # session['lang'] = request.args.get('lang') # return session.get('lang', 'tr') db = SQLAlchemy(app) # Define the User data-model. # NB: Make sure to add flask_user UserMixin !!! class User(db.Model, UserMixin): __tablename__ = 'users' id = db.Column(db.Integer, primary_key=True) active = db.Column('is_active', db.Boolean(), nullable=False, server_default='1') # User authentication information. The collation='NOCASE' is required # to search case insensitively when USER_IFIND_MODE is 'nocase_collation'. email = db.Column(db.String(255, collation='NOCASE'), nullable=False, unique=True) email_confirmed_at = db.Column(db.DateTime()) password = db.Column(db.String(255), nullable=False, server_default='') # User information first_name = db.Column(db.String(100, collation='NOCASE'), nullable=False, server_default='') last_name = db.Column(db.String(100, collation='NOCASE'), nullable=False, server_default='') # Define the relationship to Role via UserRoles roles = db.relationship('Role', secondary='user_roles') # Define the Role data-model class Role(db.Model): __tablename__ = 'roles' id = db.Column(db.Integer(), primary_key=True) name = db.Column(db.String(50), unique=True) # Define the UserRoles association table class UserRoles(db.Model): __tablename__ = 'user_roles' id = db.Column(db.Integer(), primary_key=True) user_id = db.Column(db.Integer(), db.ForeignKey('users.id', ondelete='CASCADE')) role_id = db.Column(db.Integer(), db.ForeignKey('roles.id', ondelete='CASCADE')) # Setup Flask-User and specify the User data-model user_manager = UserManager(app, db, User) # Create all database tables db.create_all() # The Home page is accessible to anyone @app.route('/') def home(): return render_template('/index.html') @app.route('/üye') def uye(): veriler = User.query.all() return render_template('/üye.html', veriler=veriler) @app.route('/add', methods=["POST"]) def adduser(): email = request.form.get("e-mail") sifre = request.form.get("sifre") email_confirmed_at = datetime.datetime.utcnow() newuser = User(email=email, password=sifre, email_confirmed_at=email_confirmed_at) db.session.add(newuser) db.session.commit() return redirect(url_for("uye")) return app
class InvenioI18N(object): """Invenio I18N extension.""" def __init__(self, app=None, date_formats=None, localeselector=None, timezoneselector=None, entry_point_group='invenio_i18n.translations'): """Initialize extension. :param app: Flask application. :param data_formats: Override default date/time formatting. :param localeselector: Callback function used for locale selection. (Default: :func:`invenio_i18n.selectors.get_locale()`) :param timezoneselector: Callback function used for timezone selection. (Default: ``BABEL_DEFAULT_TIMEZONE``) :param entry_point_group: Entrypoint used to load translations from. Set to ``None`` to not load translations from entry points. """ self.domain = MultidirDomain() self.babel = Babel( date_formats=date_formats, configure_jinja=True, default_domain=self.domain, ) self.localeselector = localeselector self.timezoneselector = timezoneselector self.entry_point_group = entry_point_group self._locales_cache = None self._languages_cache = None if app: self.init_app(app) def init_app(self, app): """Flask application initialization. The initialization will: * Set default values for the configuration variables. * Load translations from paths specified in ``I18N_TRANSLATIONS_PATHS``. * Load translations from ``app.root_path>/translations`` if it exists. * Load translations from a specified entry point. * Add ``toutc`` and ``tousertimezone`` template filters. * Install a custom JSON encoder on app. """ self.init_config(app) # Initialize Flask-BabelEx self.babel.init_app(app) self.babel.localeselector(self.localeselector or get_locale) self.babel.timezoneselector(self.timezoneselector or get_timezone) # 1. Paths listed in I18N_TRANSLATIONS_PATHS for p in app.config.get('I18N_TRANSLATIONS_PATHS', []): self.domain.add_path(p) # 2. <app.root_path>/translations app_translations = os.path.join(app.root_path, 'translations') if os.path.exists(app_translations): self.domain.add_path(app_translations) # 3. Entrypoints if self.entry_point_group: self.domain.add_entrypoint(self.entry_point_group) # Register blueprint if URL is set. if app.config['I18N_SET_LANGUAGE_URL'] \ and app.config['I18N_LANGUAGES']: app.register_blueprint( blueprint, url_prefix=app.config['I18N_SET_LANGUAGE_URL']) # Register Jinja2 template filters for date formatting (Flask-Babel # already installs other filters). app.add_template_filter(filter_to_utc, name='toutc') app.add_template_filter(filter_to_user_timezone, name='tousertimezone') app.add_template_filter(filter_language_name, name='language_name') app.add_template_filter( filter_language_name_local, name='language_name_local') app.context_processor(lambda: dict(current_i18n=current_i18n)) # Lazy string aware JSON encoder. app.json_encoder = get_lazystring_encoder(app) app.extensions['invenio-i18n'] = self def init_config(self, app): """Initialize configuration.""" for k in dir(config): if k.startswith('I18N_'): app.config.setdefault(k, getattr(config, k)) def iter_languages(self): """Iterate over list of languages.""" default_lang = self.babel.default_locale.language default_title = self.babel.default_locale.get_display_name( default_lang) yield (default_lang, default_title) for l, title in current_app.config.get('I18N_LANGUAGES', []): yield l, title def get_languages(self): """Get list of languages.""" if self._languages_cache is None: self._languages_cache = list(self.iter_languages()) return self._languages_cache def get_locales(self): """Get a list of supported locales. Computes the list using ``I18N_LANGUAGES`` configuration variable. """ if self._locales_cache is None: langs = [self.babel.default_locale] for l, dummy_title in current_app.config.get('I18N_LANGUAGES', []): langs.append(self.babel.load_locale(l)) self._locales_cache = langs return self._locales_cache @property def locale(self): """Get current locale.""" return get_current_locale() @property def language(self): """Get current language code.""" return get_current_locale().language @property def timezone(self): """Get current timezone.""" return get_current_timezone()
class InvenioI18N(object): """Invenio I18N module.""" def __init__(self, app=None, date_formats=None, localeselector=None, timezoneselector=None, entrypoint='invenio_i18n.translations'): """Initialize extension.""" self.babel = Babel(date_formats=date_formats, configure_jinja=True, default_domain=MultidirDomain()) self.localeselector = localeselector self.timezoneselector = timezoneselector self.entrypoint = entrypoint self._locales_cache = None if app: self.init_app(app) def init_app(self, app): """Flask application initialization.""" # Initialize Flask-BabelEx app.config.setdefault("I18N_LANGUAGES", []) # TODO: allow to plug custom localeselector and timezoneselector self.babel.init_app(app) self.babel.localeselector(self.localeselector or get_locale) self.babel.timezoneselector(self.timezoneselector or get_timezone) # Add paths to search for message catalogs domain = self.babel._default_domain # 1. Paths listed in I18N_TRANSLATIONS_PATHS for p in app.config.get("I18N_TRANSLATIONS_PATHS", []): domain.add_path(p) # 2. <app.root_path>/translations app_translations = os.path.join(app.root_path, 'translations') if os.path.exists(app_translations): domain.add_path(app_translations) # 3. Entrypoints if self.entrypoint: domain.add_entrypoint(self.entrypoint) # Register Jinja2 template filters for date formatting (Flask-Babel # already installs other filters). app.add_template_filter(filter_to_utc, name="toutc") app.add_template_filter(filter_to_user_timezone, name="tousertimezone") # Lazy string aware JSON encoder. app.json_encoder = get_lazystring_encoder(app) app.extensions['invenio-i18n'] = self def get_locales(self): """Get a list of supported locales.""" if self._locales_cache is None: langs = [self.babel.default_locale] for l in current_app.config.get('I18N_LANGUAGES', []): langs.append(self.babel.load_locale(l)) self._locales_cache = langs return self._locales_cache
def create_app(): """ Flask application factory """ # Create Flask app load app.config app = Flask(__name__) app.config.from_object(__name__ + '.ConfigClass') # Initialize Flask-BabelEx babel = Babel(app) # Initialize Flask-SQLAlchemy @babel.localeselector def get_locale(): translations = [ str(translation) for translation in babel.list_translations() ] # return request.accept_languages.best_match(translations) # @babel.localeselector #def get_locale(): # if request.args.get('lang'): # session['lang'] = request.args.get('lang') # return session.get('lang', 'tr') db = SQLAlchemy(app) # Define the User data-model. # NB: Make sure to add flask_user UserMixin !!! class User(db.Model, UserMixin): __tablename__ = 'users' id = db.Column(db.Integer, primary_key=True) active = db.Column('is_active', db.Boolean(), nullable=False, server_default='1') # User authentication information. The collation='NOCASE' is required # to search case insensitively when USER_IFIND_MODE is 'nocase_collation'. email = db.Column(db.String(255, collation='NOCASE'), nullable=False, unique=True) email_confirmed_at = db.Column(db.DateTime()) password = db.Column(db.String(255), nullable=False, server_default='') # User information first_name = db.Column(db.String(100, collation='NOCASE'), nullable=False, server_default='') last_name = db.Column(db.String(100, collation='NOCASE'), nullable=False, server_default='') # Define the relationship to Role via UserRoles roles = db.relationship('Role', secondary='user_roles') # Define the Role data-model class Role(db.Model): __tablename__ = 'roles' id = db.Column(db.Integer(), primary_key=True) name = db.Column(db.String(50), unique=True) # Define the UserRoles association table class UserRoles(db.Model): __tablename__ = 'user_roles' id = db.Column(db.Integer(), primary_key=True) user_id = db.Column(db.Integer(), db.ForeignKey('users.id', ondelete='CASCADE')) role_id = db.Column(db.Integer(), db.ForeignKey('roles.id', ondelete='CASCADE')) # Setup Flask-User and specify the User data-model user_manager = UserManager(app, db, User) # Create all database tables db.create_all() # The Home page is accessible to anyone @app.route('/') def index(): return render_template("index.html") @app.route('/üye') def uye(): veriler = User.query.all() return render_template("üye.html", veriler=veriler) @app.route('/members') @login_required # Use of @login_required decorator def member_page(): return render_template_string(""" {% extends "flask_user_layout.html" %} {% block content %} <h2>{%trans%}Üyeler sayfası {%endtrans%}</h2> <h1>{%trans%}Sisteme giriş yapanlar bu sayfayı görüntüleyebilir{%endtrans%}</h1> <p><a href={{ url_for('user.register') }}>{%trans%}Kayıt ol{%endtrans%}</a></p> <p><a href={{ url_for('user.login') }}>{%trans%}Giriş Yap{%endtrans%}</a></p> <p><a href={{ url_for('home_page') }}>{%trans%}Ana sayfa{%endtrans%}</a> (Herkes erişebilir)</p> <p><a href={{ url_for('member_page') }}>{%trans%}Üye sayfası{%endtrans%}</a> (Giriş gerekli: [email protected] / Password1)</p> <p><a href={{ url_for('admin_page') }}>{%trans%}Admin sayfası{%endtrans%}</a> (Rol gerekli: [email protected] / Password1)</p> <p><a href={{ url_for('user.logout') }}>{%trans%}Çıkış{%endtrans%}</a></p> {% endblock %} """) @app.route('/admin') @roles_required('Admin') #Use of @roles_required decorator def admin_page(): return render_template_string(""" {% extends "flask_user_layout.html" %} {% block content %} <h2>{%trans%}Admin Sayfası{%endtrans%}</h2> <h1>{%trans%}Bu yalnızca adminlerin giriş yapabildiği bir sayfadır{%endtrans%}</h1> <p><a href={{ url_for('user.register') }}>{%trans%}Kayıt ol{%endtrans%}</a></p> <p><a href={{ url_for('user.login') }}>{%trans%}Giriş Yap{%endtrans%}</a></p> <p><a href={{ url_for('home_page') }}>{%trans%}Ana sayfa{%endtrans%}</a> (Herkes erişebilir)</p> <p><a href={{ url_for('member_page') }}>{%trans%}Üye sayfası{%endtrans%}</a> (Giriş gerekli: [email protected] / Password1)</p> <p><a href={{ url_for('admin_page') }}>{%trans%}Admin sayfası{%endtrans%}</a> (Rol gerekli: [email protected] / Password1)</p> <p><a href={{ url_for('user.logout') }}>{%trans%}Çıkış{%endtrans%}</a></p> {% endblock %} """) @app.route('/add', methods=["POST"]) def adduser(): email = request.form.get("e-mail") sifre = request.form.get("sifre") email_confirmed_at = datetime.datetime.utcnow() newuser = User(email=email, password=sifre, email_confirmed_at=email_confirmed_at) db.session.add(newuser) db.session.commit() return redirect(url_for("uye")) return app
"ck": "ck_%(table_name)s_%(constraint_name)s", "fk": "fk_%(table_name)s_%(column_0_name)s_%(referred_table_name)s", "pk": "pk_%(table_name)s" } metadata = MetaData(naming_convention=convention) else: metadata = MetaData() basedir = os.path.abspath(os.path.dirname(__file__)) load_dotenv(os.path.join(basedir, '.env')) db = SQLAlchemy(metadata=metadata) migrate = Migrate() mail = Mail() security = Security() socketio = SocketIO() babelobject = Babel() moment = Moment() avatars = UploadSet('avatars', IMAGES) # Fixes bug: url_for generates http endpoints instead of https which causes mixed-content-errors class ReverseProxied(object): def __init__(self, app): self.app = app def __call__(self, environ, start_response): scheme = environ.get('HTTP_X_FORWARDED_PROTO') if scheme: environ['wsgi.url_scheme'] = scheme return self.app(environ, start_response)
def create_app(config_filename="config.py", app_name=None, register_blueprints=True): # App configuration app = Flask(app_name or __name__) app.config.from_pyfile(config_filename) Bootstrap(app) app.jinja_env.add_extension("jinja2.ext.with_") app.jinja_env.add_extension("jinja2.ext.do") app.jinja_env.globals.update(is_admin=is_admin) app.jinja_env.globals.update(duration_elapsed_human=duration_elapsed_human) app.jinja_env.globals.update(duration_song_human=duration_song_human) if HAS_SENTRY: sentry_sdk.init( app.config["SENTRY_DSN"], integrations=[SentryFlaskIntegration(), SentryCeleryIntegration()], release=f"{VERSION} ({GIT_VERSION})", ) print(" * Sentry Flask/Celery support activated") print(" * Sentry DSN: %s" % app.config["SENTRY_DSN"]) if app.config["DEBUG"] is True: app.jinja_env.auto_reload = True app.logger.setLevel(logging.DEBUG) # Logging if not app.debug: formatter = logging.Formatter("%(asctime)s %(levelname)s: %(message)s " "[in %(pathname)s:%(lineno)d]") file_handler = RotatingFileHandler("%s/errors_app.log" % os.getcwd(), "a", 1000000, 1) file_handler.setLevel(logging.DEBUG) file_handler.setFormatter(formatter) app.logger.addHandler(file_handler) mail.init_app(app) migrate = Migrate(app, db) # noqa: F841 babel = Babel(app) # noqa: F841 app.babel = babel toolbar = DebugToolbarExtension(app) # noqa: F841 db.init_app(app) # ActivityPub backend back = Reel2BitsBackend() ap.use_backend(back) # Setup Flask-Security security = Security( # noqa: F841 app, user_datastore, register_form=ExtendedRegisterForm, confirm_register_form=ExtendedRegisterForm) @FlaskSecuritySignals.password_reset.connect_via(app) @FlaskSecuritySignals.password_changed.connect_via(app) def log_password_reset(sender, user): if not user: return add_user_log(user.id, user.id, "user", "info", "Your password has been changed !") @FlaskSecuritySignals.reset_password_instructions_sent.connect_via(app) def log_reset_password_instr(sender, user, token): if not user: return add_user_log(user.id, user.id, "user", "info", "Password reset instructions sent.") @FlaskSecuritySignals.user_registered.connect_via(app) def create_actor_for_registered_user(app, user, confirm_token): if not user: return actor = create_actor(user) actor.user = user actor.user_id = user.id db.session.add(actor) db.session.commit() @babel.localeselector def get_locale(): # if a user is logged in, use the locale from the user settings identity = getattr(g, "identity", None) if identity is not None and identity.id: return identity.user.locale # otherwise try to guess the language from the user accept # header the browser transmits. We support fr/en in this # example. The best match wins. return request.accept_languages.best_match(AVAILABLE_LOCALES) @babel.timezoneselector def get_timezone(): identity = getattr(g, "identity", None) if identity is not None and identity.id: return identity.user.timezone @app.before_request def before_request(): _config = Config.query.first() if not _config: flash(gettext("Config not found"), "error") cfg = { "REEL2BITS_VERSION_VER": VERSION, "REEL2BITS_VERSION_GIT": GIT_VERSION, "REEL2BITS_VERSION": "{0} ({1})".format(VERSION, GIT_VERSION), "app_name": _config.app_name, "app_description": _config.app_description, } g.cfg = cfg @app.errorhandler(InvalidUsage) def handle_invalid_usage(error): response = jsonify(error.to_dict()) response.status_code = error.status_code return response sounds = UploadSet("sounds", AUDIO) configure_uploads(app, sounds) patch_request_class(app, 500 * 1024 * 1024) # 500m limit if register_blueprints: from controllers.main import bp_main app.register_blueprint(bp_main) from controllers.users import bp_users app.register_blueprint(bp_users) from controllers.admin import bp_admin app.register_blueprint(bp_admin) from controllers.sound import bp_sound app.register_blueprint(bp_sound) from controllers.albums import bp_albums app.register_blueprint(bp_albums) from controllers.search import bp_search app.register_blueprint(bp_search) from controllers.api.v1.well_known import bp_wellknown app.register_blueprint(bp_wellknown) from controllers.api.v1.nodeinfo import bp_nodeinfo app.register_blueprint(bp_nodeinfo) from controllers.api.v1.activitypub import bp_ap app.register_blueprint(bp_ap) @app.route("/uploads/<string:thing>/<path:stuff>", methods=["GET"]) def get_uploads_stuff(thing, stuff): if app.testing: directory = safe_join(app.config["UPLOADS_DEFAULT_DEST"], thing) app.logger.debug(f"serving {stuff} from {directory}") return send_from_directory(directory, stuff, as_attachment=True) else: app.logger.debug(f"X-Accel-Redirect serving {stuff}") resp = Response("") resp.headers[ "Content-Disposition"] = f"attachment; filename={stuff}" resp.headers[ "X-Accel-Redirect"] = f"/_protected/media/{thing}/{stuff}" resp.headers[ "Content-Type"] = "" # empty it so Nginx will guess it correctly return resp @app.errorhandler(404) def page_not_found(msg): pcfg = { "title": gettext("Whoops, something failed."), "error": 404, "message": gettext("Page not found"), "e": msg, } return render_template("error_page.jinja2", pcfg=pcfg), 404 @app.errorhandler(403) def err_forbidden(msg): pcfg = { "title": gettext("Whoops, something failed."), "error": 403, "message": gettext("Access forbidden"), "e": msg, } return render_template("error_page.jinja2", pcfg=pcfg), 403 @app.errorhandler(410) def err_gone(msg): pcfg = { "title": gettext("Whoops, something failed."), "error": 410, "message": gettext("Gone"), "e": msg } return render_template("error_page.jinja2", pcfg=pcfg), 410 if not app.debug: @app.errorhandler(500) def err_failed(msg): pcfg = { "title": gettext("Whoops, something failed."), "error": 500, "message": gettext("Something is broken"), "e": msg, } return render_template("error_page.jinja2", pcfg=pcfg), 500 @app.after_request def set_x_powered_by(response): response.headers["X-Powered-By"] = "reel2bits" return response # Other commands @app.cli.command() def routes(): """Dump all routes of defined app""" table = texttable.Texttable() table.set_deco(texttable.Texttable().HEADER) table.set_cols_dtype(["t", "t", "t"]) table.set_cols_align(["l", "l", "l"]) table.set_cols_width([50, 30, 80]) table.add_rows([["Prefix", "Verb", "URI Pattern"]]) for rule in sorted(app.url_map.iter_rules(), key=lambda x: str(x)): methods = ",".join(rule.methods) table.add_row([rule.endpoint, methods, rule]) print(table.draw()) @app.cli.command() def config(): """Dump config""" pp(app.config) @app.cli.command() def seed(): """Seed database with default content""" make_db_seed(db) @app.cli.command() def createuser(): """Create an user""" username = click.prompt("Username", type=str) email = click.prompt("Email", type=str) password = click.prompt("Password", type=str, hide_input=True, confirmation_prompt=True) while True: role = click.prompt("Role [admin/user]", type=str) if role == "admin" or role == "user": break if click.confirm("Do you want to continue ?"): role = Role.query.filter(Role.name == role).first() if not role: raise click.UsageError("Roles not present in database") u = user_datastore.create_user(name=username, email=email, password=encrypt_password(password), roles=[role]) actor = create_actor(u) actor.user = u actor.user_id = u.id db.session.add(actor) db.session.commit() if FSConfirmable.requires_confirmation(u): FSConfirmable.send_confirmation_instructions(u) print("Look at your emails for validation instructions.") return app
from opac_schema.v1.models import ( Collection, Sponsor, Journal, Issue, Article, News, Pages, PressRelease, AuditLogEntry) login_manager = LoginManager() dbmongo = MongoEngine() dbsql = SQLAlchemy() mail = Mail() babel = Babel() sentry = Sentry() cache = Cache() from .main import custom_filters # noqa logger = logging.getLogger(__name__) class RegexConverter(BaseConverter): def __init__(self, url_map, *items): super(RegexConverter, self).__init__(url_map) self.regex = items[0]
def create_app(app_name=None): # Configuration settings import config if not app_name: app_name = config.APP_NAME # Only enable password related functionality in server mode. if config.SERVER_MODE is True: # Some times we need to access these config params where application # context is not available (we can't use current_app.config in those # cases even with current_app.app_context()) # So update these params in config itself. # And also these updated config values will picked up by application # since we are updating config before the application instance is # created. config.SECURITY_RECOVERABLE = True config.SECURITY_CHANGEABLE = True # Now we'll open change password page in alertify dialog # we don't want it to redirect to main page after password # change operation so we will open the same password change page again. config.SECURITY_POST_CHANGE_VIEW = 'browser.change_password' """Create the Flask application, startup logging and dynamically load additional modules (blueprints) that are found in this directory.""" app = PgAdmin(__name__, static_url_path='/static') # Removes unwanted whitespace from render_template function app.jinja_env.trim_blocks = True app.config.from_object(config) app.config.update(dict(PROPAGATE_EXCEPTIONS=True)) ########################################################################## # Setup logging and log the application startup ########################################################################## # We won't care about errors in the logging system, we are more # interested in application errors. logging.raiseExceptions = False # Add SQL level logging, and set the base logging level logging.addLevelName(25, 'SQL') app.logger.setLevel(logging.DEBUG) app.logger.handlers = [] # We also need to update the handler on the webserver in order to see # request. Setting the level prevents werkzeug from setting up it's own # stream handler thus ensuring all the logging goes through the pgAdmin # logger. logger = logging.getLogger('werkzeug') logger.setLevel(logging.INFO) # Set SQLITE_PATH to TEST_SQLITE_PATH while running test cases if ('PGADMIN_TESTING_MODE' in os.environ and os.environ['PGADMIN_TESTING_MODE'] == '1'): config.SQLITE_PATH = config.TEST_SQLITE_PATH config.MASTER_PASSWORD_REQUIRED = False config.UPGRADE_CHECK_ENABLED = False # Ensure the various working directories exist from pgadmin.setup import create_app_data_directory, db_upgrade create_app_data_directory(config) # File logging fh = logging.FileHandler(config.LOG_FILE, encoding='utf-8') fh.setLevel(config.FILE_LOG_LEVEL) fh.setFormatter(logging.Formatter(config.FILE_LOG_FORMAT)) app.logger.addHandler(fh) logger.addHandler(fh) # Console logging ch = logging.StreamHandler() ch.setLevel(config.CONSOLE_LOG_LEVEL) ch.setFormatter(logging.Formatter(config.CONSOLE_LOG_FORMAT)) app.logger.addHandler(ch) logger.addHandler(ch) # Log the startup app.logger.info('########################################################') app.logger.info('Starting %s v%s...', config.APP_NAME, config.APP_VERSION) app.logger.info('########################################################') app.logger.debug("Python syspath: %s", sys.path) ########################################################################## # Setup i18n ########################################################################## # Initialise i18n babel = Babel(app) app.logger.debug('Available translations: %s' % babel.list_translations()) @babel.localeselector def get_locale(): """Get the language for the user.""" language = 'en' if config.SERVER_MODE is False: # Get the user language preference from the miscellaneous module if current_user.is_authenticated: user_id = current_user.id else: user = user_datastore.get_user(config.DESKTOP_USER) if user is not None: user_id = user.id user_language = Preferences.raw_value('miscellaneous', 'user_language', None, user_id) if user_language is not None: language = user_language else: # If language is available in get request then return the same # otherwise check the session or cookie data = request.form if 'language' in data: language = data['language'] or language setattr(session, 'PGADMIN_LANGUAGE', language) elif hasattr(session, 'PGADMIN_LANGUAGE'): language = getattr(session, 'PGADMIN_LANGUAGE', language) elif hasattr(request.cookies, 'PGADMIN_LANGUAGE'): language = getattr(request.cookies, 'PGADMIN_LANGUAGE', language) return language ########################################################################## # Setup authentication ########################################################################## app.config['SQLALCHEMY_DATABASE_URI'] = u'sqlite:///{0}?timeout={1}' \ .format(config.SQLITE_PATH.replace(u'\\', u'/'), getattr(config, 'SQLITE_TIMEOUT', 500) ) # Create database connection object and mailer db.init_app(app) ########################################################################## # Upgrade the schema (if required) ########################################################################## with app.app_context(): # Run migration for the first time i.e. create database from config import SQLITE_PATH # If version not available, user must have aborted. Tables are not # created and so its an empty db if not os.path.exists(SQLITE_PATH) or get_version() == -1: db_upgrade(app) else: schema_version = get_version() # Run migration if current schema version is greater than the # schema version stored in version table if CURRENT_SCHEMA_VERSION >= schema_version: db_upgrade(app) # Update schema version to the latest if CURRENT_SCHEMA_VERSION > schema_version: set_version(CURRENT_SCHEMA_VERSION) db.session.commit() if os.name != 'nt': os.chmod(config.SQLITE_PATH, 0o600) Mail(app) import pgadmin.utils.paths as paths paths.init_app(app) # Setup Flask-Security user_datastore = SQLAlchemyUserDatastore(db, User, Role) security = Security(None, user_datastore) ########################################################################## # Setup security ########################################################################## with app.app_context(): config.CSRF_SESSION_KEY = Keys.query.filter_by( name='CSRF_SESSION_KEY').first().value config.SECRET_KEY = Keys.query.filter_by( name='SECRET_KEY').first().value config.SECURITY_PASSWORD_SALT = Keys.query.filter_by( name='SECURITY_PASSWORD_SALT').first().value # Update the app.config with proper security keyes for signing CSRF data, # signing cookies, and the SALT for hashing the passwords. app.config.update( dict({ 'CSRF_SESSION_KEY': config.CSRF_SESSION_KEY, 'SECRET_KEY': config.SECRET_KEY, 'SECURITY_PASSWORD_SALT': config.SECURITY_PASSWORD_SALT, 'SESSION_COOKIE_DOMAIN': config.SESSION_COOKIE_DOMAIN, # CSRF Token expiration till session expires 'WTF_CSRF_TIME_LIMIT': getattr(config, 'CSRF_TIME_LIMIT', None), 'WTF_CSRF_METHODS': ['GET', 'POST', 'PUT', 'DELETE'], })) security.init_app(app, user_datastore) # register custom unauthorised handler. app.login_manager.unauthorized_handler(pga_unauthorised) # Set the permanent session lifetime to the specified value in config file. app.permanent_session_lifetime = timedelta( days=config.SESSION_EXPIRATION_TIME) app.session_interface = create_session_interface(app, config.SESSION_SKIP_PATHS) # Make the Session more secure against XSS & CSRF when running in web mode if config.SERVER_MODE and config.ENHANCED_COOKIE_PROTECTION: paranoid = Paranoid(app) paranoid.redirect_view = 'browser.index' ########################################################################## # Load all available server drivers ########################################################################## driver.init_app(app) ########################################################################## # Register language to the preferences after login ########################################################################## @user_logged_in.connect_via(app) def register_language(sender, user): # After logged in, set the language in the preferences if we get from # the login page data = request.form if 'language' in data: language = data['language'] # Set the user language preference misc_preference = Preferences.module('miscellaneous') user_languages = misc_preference.preference('user_language') if user_languages and language: language = user_languages.set(language) ########################################################################## # Register any local servers we can discover ########################################################################## @user_logged_in.connect_via(app) def on_user_logged_in(sender, user): # Keep hold of the user ID user_id = user.id # Get the first server group for the user servergroup_id = 1 servergroups = ServerGroup.query.filter_by( user_id=user_id).order_by("id") if servergroups.count() > 0: servergroup = servergroups.first() servergroup_id = servergroup.id '''Add a server to the config database''' def add_server(user_id, servergroup_id, name, superuser, port, discovery_id, comment): # Create a server object if needed, and store it. servers = Server.query.filter_by( user_id=user_id, discovery_id=svr_discovery_id).order_by("id") if servers.count() > 0: return svr = Server(user_id=user_id, servergroup_id=servergroup_id, name=name, host='localhost', port=port, maintenance_db='postgres', username=superuser, ssl_mode='prefer', comment=svr_comment, discovery_id=discovery_id) db.session.add(svr) db.session.commit() # Figure out what servers are present if winreg is not None: arch_keys = set() proc_arch = os.environ['PROCESSOR_ARCHITECTURE'].lower() try: proc_arch64 = os.environ['PROCESSOR_ARCHITEW6432'].lower() except Exception as e: proc_arch64 = None if proc_arch == 'x86' and not proc_arch64: arch_keys.add(0) elif proc_arch == 'x86' or proc_arch == 'amd64': arch_keys.add(winreg.KEY_WOW64_32KEY) arch_keys.add(winreg.KEY_WOW64_64KEY) for arch_key in arch_keys: for server_type in ('PostgreSQL', 'EnterpriseDB'): try: root_key = winreg.OpenKey( winreg.HKEY_LOCAL_MACHINE, "SOFTWARE\\" + server_type + "\Services", 0, winreg.KEY_READ | arch_key) for i in xrange(0, winreg.QueryInfoKey(root_key)[0]): inst_id = winreg.EnumKey(root_key, i) inst_key = winreg.OpenKey(root_key, inst_id) svr_name = winreg.QueryValueEx( inst_key, 'Display Name')[0] svr_superuser = winreg.QueryValueEx( inst_key, 'Database Superuser')[0] svr_port = winreg.QueryValueEx(inst_key, 'Port')[0] svr_discovery_id = inst_id svr_comment = gettext( "Auto-detected %s installation with the data " "directory at %s" % (winreg.QueryValueEx(inst_key, 'Display Name')[0], winreg.QueryValueEx(inst_key, 'Data Directory')[0])) add_server(user_id, servergroup_id, svr_name, svr_superuser, svr_port, svr_discovery_id, svr_comment) inst_key.Close() except Exception as e: pass else: # We use the postgres-winreg.ini file on non-Windows try: from configparser import ConfigParser except ImportError: from ConfigParser import ConfigParser # Python 2 registry = ConfigParser() try: registry.read('/etc/postgres-reg.ini') sections = registry.sections() # Loop the sections, and get the data from any that are PG or PPAS for section in sections: if (section.startswith('PostgreSQL/') or section.startswith('EnterpriseDB/')): svr_name = registry.get(section, 'Description') svr_superuser = registry.get(section, 'Superuser') # getint function throws exception if value is blank. # Ex: Port= # In such case we should handle the exception and continue # to read the next section of the config file. try: svr_port = registry.getint(section, 'Port') except ValueError: continue svr_discovery_id = section description = registry.get(section, 'Description') data_directory = registry.get(section, 'DataDirectory') if hasattr(str, 'decode'): description = description.decode('utf-8') data_directory = data_directory.decode('utf-8') svr_comment = gettext(u"Auto-detected %s installation " u"with the data directory at %s" % (description, data_directory)) add_server(user_id, servergroup_id, svr_name, svr_superuser, svr_port, svr_discovery_id, svr_comment) except Exception as e: pass @user_logged_in.connect_via(app) @user_logged_out.connect_via(app) def force_session_write(app, user): session.force_write = True @user_logged_in.connect_via(app) def store_crypt_key(app, user): # in desktop mode, master password is used to encrypt/decrypt # and is stored in the keyManager memory if config.SERVER_MODE: if 'password' in request.form: current_app.keyManager.set(request.form['password']) @user_logged_out.connect_via(app) def current_user_cleanup(app, user): from config import PG_DEFAULT_DRIVER from pgadmin.utils.driver import get_driver from flask import current_app # remove key current_app.keyManager.reset() for mdl in current_app.logout_hooks: try: mdl.on_logout(user) except Exception as e: current_app.logger.exception(e) _driver = get_driver(PG_DEFAULT_DRIVER) _driver.gc_own() ########################################################################## # Load plugin modules ########################################################################## for module in app.find_submodules('pgadmin'): app.logger.info('Registering blueprint module: %s' % module) app.register_blueprint(module) app.register_logout_hook(module) ########################################################################## # Handle the desktop login ########################################################################## @app.before_request def before_request(): """Login the default user if running in desktop mode""" # Check the auth key is valid, if it's set, and we're not in server # mode, and it's not a help file request. if not config.SERVER_MODE and app.PGADMIN_KEY != '': if (('key' not in request.args or request.args['key'] != app.PGADMIN_KEY) and request.cookies.get('PGADMIN_KEY') != app.PGADMIN_KEY and request.endpoint != 'help.static'): abort(401) if not config.SERVER_MODE and not current_user.is_authenticated: user = user_datastore.get_user(config.DESKTOP_USER) # Throw an error if we failed to find the desktop user, to give # the sysadmin a hint. We'll continue to try to login anyway as # that'll through a nice 500 error for us. if user is None: app.logger.error( 'The desktop user %s was not found in the configuration ' 'database.' % config.DESKTOP_USER) abort(401) login_user(user) # if the server is restarted the in memory key will be lost # but the user session may still be active. Logout the user # to get the key again when login if config.SERVER_MODE and current_user.is_authenticated: if current_app.keyManager.get() is None and \ request.endpoint not in ('security.login', 'security.logout'): logout_user() @app.after_request def after_request(response): if 'key' in request.args: domain = dict() if config.COOKIE_DEFAULT_DOMAIN and \ config.COOKIE_DEFAULT_DOMAIN != 'localhost': domain['domain'] = config.COOKIE_DEFAULT_DOMAIN response.set_cookie('PGADMIN_KEY', value=request.args['key'], path=config.COOKIE_DEFAULT_PATH, **domain) # X-Frame-Options for security if config.X_FRAME_OPTIONS != "" and \ config.X_FRAME_OPTIONS.lower() != "deny": response.headers["X-Frame-Options"] = config.X_FRAME_OPTIONS return response ########################################################################## # Cache busting ########################################################################## # Version number to be added to all static file url requests # This is used by url_for function when generating urls # This will solve caching issues when application is upgrading # This is called - Cache Busting @app.url_defaults def add_internal_version(endpoint, values): extensions = config.APP_VERSION_EXTN # Add the internal version only if it is set if config.APP_VERSION_PARAM is not None and \ config.APP_VERSION_PARAM != '': # If there is a filename, add the version if 'filename' in values \ and values['filename'].endswith(extensions): values[config.APP_VERSION_PARAM] = config.APP_VERSION_INT else: # Sometimes there may be direct endpoint for some files # There will be only one rule for such endpoints urls = [url for url in app.url_map.iter_rules(endpoint)] if len(urls) == 1 and urls[0].rule.endswith(extensions): values[config.APP_VERSION_PARAM] = \ config.APP_VERSION_INT # Strip away internal version param before sending further to app as it was # required for cache busting only @app.url_value_preprocessor def strip_version_number(endpoint, values): if values and config.APP_VERSION_PARAM in values: values.pop(config.APP_VERSION_PARAM) ########################################################################## # Minify output ########################################################################## if not config.DEBUG: from flask_htmlmin import HTMLMIN HTMLMIN(app) @app.context_processor def inject_blueprint(): """Inject a reference to the current blueprint, if any.""" return { 'current_app': current_app, 'current_blueprint': current_blueprint } @app.errorhandler(Exception) def all_exception_handler(e): current_app.logger.error(e, exc_info=True) return internal_server_error(errormsg=str(e)) # Exclude HTTPexception from above handler (all_exception_handler) # HTTPException are user defined exceptions and those should be returned # as is @app.errorhandler(HTTPException) def http_exception_handler(e): current_app.logger.error(e, exc_info=True) return e # Intialize the key manager app.keyManager = KeyManager() ########################################################################## # Protection against CSRF attacks ########################################################################## with app.app_context(): pgCSRFProtect.init_app(app) ########################################################################## # All done! ########################################################################## return app
def create_app(): app = Flask(__name__) app.config.from_object(youjiao_config) # flask_sqlalchemy # import ipdb; ipdb.set_trace() db.init_app(app) # flask_redis redis_cli.init_app(app) # flask_debug if app.config.get('DEBUG'): DebugToolbarExtension(app) # flask_login login_manager.user_loader(load_user) login_manager.login_view = 'user_view.login' login_manager.init_app(app) # flask_jwt jwt.init_app(app) # flask_principal Principal(app) identity_loaded.connect_via(app)(_on_identity_loaded) # flask_wtf csrf csrf = CsrfProtect() csrf.init_app(app) app.before_request(check_csrf(csrf)) # flask_babel Babel(app) # flask_limiter limiter.init_app(app) # flask_qiniu flask_qiniu.init_app(app) # flask_admin admin.init_app(app) # register blueprint app.register_blueprint(content_bp) app.register_blueprint(user_bp) app.register_blueprint(user_api_bp) # import ipdb; ipdb.set_trace() app.register_blueprint(book_bp) app.register_blueprint(book_api_bp) app.register_blueprint(user_util_api_bp) app.register_blueprint(media_bp) app.register_blueprint(online_course_bp) # register subscriber user_connect(app) # register home page app.add_url_rule('/', 'index', index) with open(os.path.join(os.getcwd(), 'youjiao/static/assets.json.py'), 'r') as assets: app.assets = json.load(assets) return app
def create_app(app_name=None): # Configuration settings import config if not app_name: app_name = config.APP_NAME # Check if app is created for CLI operations or Web cli_mode = False if app_name.endswith('-cli'): cli_mode = True # Only enable password related functionality in server mode. if config.SERVER_MODE is True: # Some times we need to access these config params where application # context is not available (we can't use current_app.config in those # cases even with current_app.app_context()) # So update these params in config itself. # And also these updated config values will picked up by application # since we are updating config before the application instance is # created. config.SECURITY_RECOVERABLE = True config.SECURITY_CHANGEABLE = True # Now we'll open change password page in alertify dialog # we don't want it to redirect to main page after password # change operation so we will open the same password change page again. config.SECURITY_POST_CHANGE_VIEW = 'browser.change_password' """Create the Flask application, startup logging and dynamically load additional modules (blueprints) that are found in this directory.""" app = PgAdmin(__name__, static_url_path='/static') # Removes unwanted whitespace from render_template function app.jinja_env.trim_blocks = True app.config.from_object(config) app.config.update(dict(PROPAGATE_EXCEPTIONS=True)) ########################################################################## # Setup logging and log the application startup ########################################################################## # We won't care about errors in the logging system, we are more # interested in application errors. logging.raiseExceptions = False # Add SQL level logging, and set the base logging level logging.addLevelName(25, 'SQL') app.logger.setLevel(logging.DEBUG) app.logger.handlers = [] # We also need to update the handler on the webserver in order to see # request. Setting the level prevents werkzeug from setting up it's own # stream handler thus ensuring all the logging goes through the pgAdmin # logger. logger = logging.getLogger('werkzeug') logger.setLevel(config.CONSOLE_LOG_LEVEL) # Set SQLITE_PATH to TEST_SQLITE_PATH while running test cases if ('PGADMIN_TESTING_MODE' in os.environ and os.environ['PGADMIN_TESTING_MODE'] == '1'): config.SQLITE_PATH = config.TEST_SQLITE_PATH config.MASTER_PASSWORD_REQUIRED = False config.UPGRADE_CHECK_ENABLED = False if not cli_mode: # Ensure the various working directories exist from pgadmin.setup import create_app_data_directory create_app_data_directory(config) # File logging from pgadmin.utils.enhanced_log_rotation import \ EnhancedRotatingFileHandler fh = EnhancedRotatingFileHandler(config.LOG_FILE, config.LOG_ROTATION_SIZE, config.LOG_ROTATION_AGE, config.LOG_ROTATION_MAX_LOG_FILES) fh.setLevel(config.FILE_LOG_LEVEL) fh.setFormatter(logging.Formatter(config.FILE_LOG_FORMAT)) app.logger.addHandler(fh) logger.addHandler(fh) # Console logging ch = logging.StreamHandler() ch.setLevel(config.CONSOLE_LOG_LEVEL) ch.setFormatter(logging.Formatter(config.CONSOLE_LOG_FORMAT)) app.logger.addHandler(ch) logger.addHandler(ch) # Log the startup app.logger.info('########################################################') app.logger.info('Starting %s v%s...', config.APP_NAME, config.APP_VERSION) app.logger.info('########################################################') app.logger.debug("Python syspath: %s", sys.path) ########################################################################## # Setup i18n ########################################################################## # Initialise i18n babel = Babel(app) app.logger.debug('Available translations: %s' % babel.list_translations()) @babel.localeselector def get_locale(): """Get the language for the user.""" language = 'en' if config.SERVER_MODE is False: # Get the user language preference from the miscellaneous module user_id = None if current_user.is_authenticated: user_id = current_user.id else: user = user_datastore.find_user(email=config.DESKTOP_USER) if user is not None: user_id = user.id user_language = Preferences.raw_value('misc', 'user_language', 'user_language', user_id) if user_language is not None: language = user_language else: # If language is available in get request then return the same # otherwise check the session or cookie data = request.form if 'language' in data: language = data['language'] or language setattr(session, 'PGADMIN_LANGUAGE', language) elif hasattr(session, 'PGADMIN_LANGUAGE'): language = getattr(session, 'PGADMIN_LANGUAGE', language) elif hasattr(request.cookies, 'PGADMIN_LANGUAGE'): language = getattr(request.cookies, 'PGADMIN_LANGUAGE', language) return language ########################################################################## # Setup authentication ########################################################################## app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///{0}?timeout={1}' \ .format(config.SQLITE_PATH.replace('\\', '/'), getattr(config, 'SQLITE_TIMEOUT', 500) ) # Override USER_DOES_NOT_EXIST and INVALID_PASSWORD messages from flask. app.config['SECURITY_MSG_USER_DOES_NOT_EXIST'] = \ app.config['SECURITY_MSG_INVALID_PASSWORD'] = \ (gettext("Incorrect username or password."), "error") # Create database connection object and mailer db.init_app(app) ########################################################################## # Upgrade the schema (if required) ########################################################################## def backup_db_file(): """ Create a backup of the current database file and create new database file with default settings. """ backup_file_name = "{0}.{1}".format( SQLITE_PATH, datetime.now().strftime('%Y%m%d%H%M%S')) os.rename(SQLITE_PATH, backup_file_name) app.logger.error('Exception in database migration.') app.logger.info('Creating new database file.') try: db_upgrade(app) os.environ['CORRUPTED_DB_BACKUP_FILE'] = backup_file_name app.logger.info('Database migration completed.') except Exception as e: app.logger.error('Database migration failed') app.logger.error(traceback.format_exc()) raise RuntimeError('Migration failed') def upgrade_db(): """ Execute the migrations. """ try: db_upgrade(app) os.environ['CORRUPTED_DB_BACKUP_FILE'] = '' except Exception as e: backup_db_file() # check all tables are present in the db. is_db_error, invalid_tb_names = check_db_tables() if is_db_error: app.logger.error('Table(s) {0} are missing in the' ' database'.format(invalid_tb_names)) backup_db_file() with app.app_context(): # Run migration for the first time i.e. create database from config import SQLITE_PATH from pgadmin.setup import db_upgrade # If version not available, user must have aborted. Tables are not # created and so its an empty db if not os.path.exists(SQLITE_PATH) or get_version() == -1: # If running in cli mode then don't try to upgrade, just raise # the exception if not cli_mode: upgrade_db() else: if not os.path.exists(SQLITE_PATH): raise FileNotFoundError('SQLite database file "' + SQLITE_PATH + '" does not exists.') raise RuntimeError( 'The configuration database file is not valid.') else: schema_version = get_version() # Run migration if current schema version is greater than the # schema version stored in version table if CURRENT_SCHEMA_VERSION >= schema_version: upgrade_db() else: # check all tables are present in the db. is_db_error, invalid_tb_names = check_db_tables() if is_db_error: app.logger.error('Table(s) {0} are missing in the' ' database'.format(invalid_tb_names)) backup_db_file() # Update schema version to the latest if CURRENT_SCHEMA_VERSION > schema_version: set_version(CURRENT_SCHEMA_VERSION) db.session.commit() if os.name != 'nt': os.chmod(config.SQLITE_PATH, 0o600) Mail(app) # Don't bother paths when running in cli mode if not cli_mode: import pgadmin.utils.paths as paths paths.init_app(app) # Setup Flask-Security user_datastore = SQLAlchemyUserDatastore(db, User, Role) security = Security(None, user_datastore) ########################################################################## # Setup security ########################################################################## with app.app_context(): config.CSRF_SESSION_KEY = Keys.query.filter_by( name='CSRF_SESSION_KEY').first().value config.SECRET_KEY = Keys.query.filter_by( name='SECRET_KEY').first().value config.SECURITY_PASSWORD_SALT = Keys.query.filter_by( name='SECURITY_PASSWORD_SALT').first().value # Update the app.config with proper security keyes for signing CSRF data, # signing cookies, and the SALT for hashing the passwords. app.config.update( dict({ 'CSRF_SESSION_KEY': config.CSRF_SESSION_KEY, 'SECRET_KEY': config.SECRET_KEY, 'SECURITY_PASSWORD_SALT': config.SECURITY_PASSWORD_SALT, 'SESSION_COOKIE_DOMAIN': config.SESSION_COOKIE_DOMAIN, # CSRF Token expiration till session expires 'WTF_CSRF_TIME_LIMIT': getattr(config, 'CSRF_TIME_LIMIT', None), 'WTF_CSRF_METHODS': ['GET', 'POST', 'PUT', 'DELETE'], # Disable deliverable check for email addresss 'SECURITY_EMAIL_VALIDATOR_ARGS': config.SECURITY_EMAIL_VALIDATOR_ARGS })) if 'SCRIPT_NAME' in os.environ and os.environ["SCRIPT_NAME"]: app.config.update(dict({'APPLICATION_ROOT': os.environ["SCRIPT_NAME"]})) app.config.update( dict({ 'INTERNAL': INTERNAL, 'LDAP': LDAP, 'KERBEROS': KERBEROS, 'OAUTH2': OAUTH2, 'WEBSERVER': WEBSERVER })) security.init_app(app, user_datastore) # register custom unauthorised handler. app.login_manager.unauthorized_handler(pga_unauthorised) # Set the permanent session lifetime to the specified value in config file. app.permanent_session_lifetime = timedelta( days=config.SESSION_EXPIRATION_TIME) if not cli_mode: app.session_interface = create_session_interface( app, config.SESSION_SKIP_PATHS) # Make the Session more secure against XSS & CSRF when running in web mode if config.SERVER_MODE and config.ENHANCED_COOKIE_PROTECTION: paranoid = Paranoid(app) paranoid.redirect_view = 'browser.index' ########################################################################## # Load all available server drivers ########################################################################## driver.init_app(app) authenticate.init_app(app) ########################################################################## # Register language to the preferences after login ########################################################################## @user_logged_in.connect_via(app) def register_language(sender, user): # After logged in, set the language in the preferences if we get from # the login page data = request.form if 'language' in data: language = data['language'] # Set the user language preference misc_preference = Preferences.module('misc') user_languages = misc_preference.preference('user_language') if user_languages and language: language = user_languages.set(language) ########################################################################## # Register any local servers we can discover ########################################################################## @user_logged_in.connect_via(app) def on_user_logged_in(sender, user): # Keep hold of the user ID user_id = user.id # Get the first server group for the user servergroup_id = 1 servergroups = ServerGroup.query.filter_by( user_id=user_id).order_by("id") if servergroups.count() > 0: servergroup = servergroups.first() servergroup_id = servergroup.id '''Add a server to the config database''' def add_server(user_id, servergroup_id, name, superuser, port, discovery_id, comment): # Create a server object if needed, and store it. servers = Server.query.filter_by( user_id=user_id, discovery_id=svr_discovery_id).order_by("id") if servers.count() > 0: return svr = Server(user_id=user_id, servergroup_id=servergroup_id, name=name, host='localhost', port=port, maintenance_db='postgres', username=superuser, ssl_mode='prefer', comment=svr_comment, discovery_id=discovery_id) db.session.add(svr) db.session.commit() # Figure out what servers are present if winreg is not None: arch_keys = set() proc_arch = os.environ['PROCESSOR_ARCHITECTURE'].lower() try: proc_arch64 = os.environ['PROCESSOR_ARCHITEW6432'].lower() except Exception: proc_arch64 = None if proc_arch == 'x86' and not proc_arch64: arch_keys.add(0) elif proc_arch == 'x86' or proc_arch == 'amd64': arch_keys.add(winreg.KEY_WOW64_32KEY) arch_keys.add(winreg.KEY_WOW64_64KEY) for arch_key in arch_keys: for server_type in ('PostgreSQL', 'EnterpriseDB'): try: root_key = winreg.OpenKey( winreg.HKEY_LOCAL_MACHINE, "SOFTWARE\\" + server_type + "\\Services", 0, winreg.KEY_READ | arch_key) for i in range(0, winreg.QueryInfoKey(root_key)[0]): inst_id = winreg.EnumKey(root_key, i) inst_key = winreg.OpenKey(root_key, inst_id) svr_name = winreg.QueryValueEx( inst_key, 'Display Name')[0] svr_superuser = winreg.QueryValueEx( inst_key, 'Database Superuser')[0] svr_port = winreg.QueryValueEx(inst_key, 'Port')[0] svr_discovery_id = inst_id svr_comment = gettext( "Auto-detected {0} installation with the data " "directory at {1}").format( winreg.QueryValueEx( inst_key, 'Display Name')[0], winreg.QueryValueEx( inst_key, 'Data Directory')[0]) add_server(user_id, servergroup_id, svr_name, svr_superuser, svr_port, svr_discovery_id, svr_comment) inst_key.Close() except Exception: pass else: # We use the postgres-winreg.ini file on non-Windows from configparser import ConfigParser registry = ConfigParser() try: registry.read('/etc/postgres-reg.ini') sections = registry.sections() # Loop the sections, and get the data from any that are PG or PPAS for section in sections: if (section.startswith('PostgreSQL/') or section.startswith('EnterpriseDB/')): svr_name = registry.get(section, 'Description') svr_superuser = registry.get(section, 'Superuser') # getint function throws exception if value is blank. # Ex: Port= # In such case we should handle the exception and continue # to read the next section of the config file. try: svr_port = registry.getint(section, 'Port') except ValueError: continue svr_discovery_id = section description = registry.get(section, 'Description') data_directory = registry.get(section, 'DataDirectory') svr_comment = gettext( "Auto-detected {0} installation " "with the data directory at {1}").format( description, data_directory) add_server(user_id, servergroup_id, svr_name, svr_superuser, svr_port, svr_discovery_id, svr_comment) except Exception: pass @user_logged_in.connect_via(app) @user_logged_out.connect_via(app) def force_session_write(app, user): session.force_write = True @user_logged_in.connect_via(app) def store_crypt_key(app, user): # in desktop mode, master password is used to encrypt/decrypt # and is stored in the keyManager memory if config.SERVER_MODE and 'password' in request.form: current_app.keyManager.set(request.form['password']) @user_logged_out.connect_via(app) def current_user_cleanup(app, user): from config import PG_DEFAULT_DRIVER from pgadmin.utils.driver import get_driver from flask import current_app for mdl in current_app.logout_hooks: try: mdl.on_logout(user) except Exception as e: current_app.logger.exception(e) # remove key current_app.keyManager.reset() _driver = get_driver(PG_DEFAULT_DRIVER) _driver.gc_own() ########################################################################## # Load plugin modules ########################################################################## for module in app.find_submodules('pgadmin'): app.logger.info('Registering blueprint module: %s' % module) app.register_blueprint(module) app.register_logout_hook(module) @app.before_request def limit_host_addr(): """ This function validate the hosts from ALLOWED_HOSTS before allowing HTTP request to avoid Host Header Injection attack :return: None/JSON response with 403 HTTP status code """ client_host = str(request.host).split(':')[0] valid = True allowed_hosts = config.ALLOWED_HOSTS if len(allowed_hosts) != 0: regex = re.compile( r'\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}(?:/\d{1,2}|)') # Create separate list for ip addresses and host names ip_set = list(filter(lambda ip: regex.match(ip), allowed_hosts)) host_set = list( filter(lambda ip: not regex.match(ip), allowed_hosts)) is_ip = regex.match(client_host) if is_ip: ip_address = [] for ip in ip_set: ip_address.extend(list(ipaddress.ip_network(ip))) valid = ip_address.__contains__( ipaddress.ip_address(client_host)) else: valid = host_set.__contains__(client_host) if not valid: return make_json_response(status=403, success=0, errormsg=_("403 FORBIDDEN")) ########################################################################## # Handle the desktop login ########################################################################## @app.before_request def before_request(): """Login the default user if running in desktop mode""" # Check the auth key is valid, if it's set, and we're not in server # mode, and it's not a help file request. if not config.SERVER_MODE and app.PGADMIN_INT_KEY != '' and ( ('key' not in request.args or request.args['key'] != app.PGADMIN_INT_KEY) and request.cookies.get('PGADMIN_INT_KEY') != app.PGADMIN_INT_KEY and request.endpoint != 'help.static'): abort(401) if not config.SERVER_MODE and not current_user.is_authenticated: user = user_datastore.find_user(email=config.DESKTOP_USER) # Throw an error if we failed to find the desktop user, to give # the sysadmin a hint. We'll continue to try to login anyway as # that'll through a nice 500 error for us. if user is None: app.logger.error( 'The desktop user %s was not found in the configuration ' 'database.' % config.DESKTOP_USER) abort(401) login_user(user) elif config.SERVER_MODE and \ not current_user.is_authenticated and \ request.endpoint in ('redirects.index', 'security.login'): if app.PGADMIN_EXTERNAL_AUTH_SOURCE in [KERBEROS, WEBSERVER]: return authenticate.login() # if the server is restarted the in memory key will be lost # but the user session may still be active. Logout the user # to get the key again when login if config.SERVER_MODE and current_user.is_authenticated and \ app.PGADMIN_EXTERNAL_AUTH_SOURCE not in [ KERBEROS, OAUTH2, WEBSERVER] and \ current_app.keyManager.get() is None and \ request.endpoint not in ('security.login', 'security.logout'): logout_user() @app.after_request def after_request(response): if 'key' in request.args: domain = dict() if config.COOKIE_DEFAULT_DOMAIN and \ config.COOKIE_DEFAULT_DOMAIN != 'localhost': domain['domain'] = config.COOKIE_DEFAULT_DOMAIN response.set_cookie('PGADMIN_INT_KEY', value=request.args['key'], path=config.COOKIE_DEFAULT_PATH, secure=config.SESSION_COOKIE_SECURE, httponly=config.SESSION_COOKIE_HTTPONLY, samesite=config.SESSION_COOKIE_SAMESITE, **domain) SecurityHeaders.set_response_headers(response) return response ########################################################################## # Cache busting ########################################################################## # Version number to be added to all static file url requests # This is used by url_for function when generating urls # This will solve caching issues when application is upgrading # This is called - Cache Busting @app.url_defaults def add_internal_version(endpoint, values): extensions = config.APP_VERSION_EXTN # Add the internal version only if it is set if config.APP_VERSION_PARAM is not None and \ config.APP_VERSION_PARAM != '': # If there is a filename, add the version if 'filename' in values \ and values['filename'].endswith(extensions): values[config.APP_VERSION_PARAM] = config.APP_VERSION_INT else: # Sometimes there may be direct endpoint for some files # There will be only one rule for such endpoints urls = [url for url in app.url_map.iter_rules(endpoint)] if len(urls) == 1 and urls[0].rule.endswith(extensions): values[config.APP_VERSION_PARAM] = \ config.APP_VERSION_INT # Strip away internal version param before sending further to app as it was # required for cache busting only @app.url_value_preprocessor def strip_version_number(endpoint, values): if values and config.APP_VERSION_PARAM in values: values.pop(config.APP_VERSION_PARAM) ########################################################################## # Minify output. Not required in desktop mode ########################################################################## if not config.DEBUG and config.SERVER_MODE: from flask_compress import Compress Compress(app) from pgadmin.misc.themes import themes themes(app) @app.context_processor def inject_blueprint(): """ Inject a reference to the current blueprint, if any. """ return { 'current_app': current_app, 'current_blueprint': current_blueprint, } @app.errorhandler(Exception) def all_exception_handler(e): current_app.logger.error(e, exc_info=True) return internal_server_error(errormsg=str(e)) # Exclude HTTPexception from above handler (all_exception_handler) # HTTPException are user defined exceptions and those should be returned # as is @app.errorhandler(HTTPException) def http_exception_handler(e): current_app.logger.error(e, exc_info=True) return e # Intialize the key manager app.keyManager = KeyManager() ########################################################################## # Protection against CSRF attacks ########################################################################## with app.app_context(): pgCSRFProtect.init_app(app) ########################################################################## # All done! ########################################################################## socketio.init_app(app) return app
import sys from flask import Flask from flask_sqlalchemy import SQLAlchemy from flask_babelex import Babel app = Flask(__name__) babel = Babel(app) # 国际化 app.config.from_object('config') db = SQLAlchemy(app) from app import routers
def create_app(): """ Flask application factory """ # Create Flask app load app.config app = Flask(__name__) app.config.from_object(__name__ + '.ConfigClass') # Initialize Flask-BabelEx babel = Babel(app) # Initialize Flask-SQLAlchemy @babel.localeselector def get_locale(): translations = [ str(translation) for translation in babel.list_translations() ] # return request.accept_languages.best_match(translations) # @babel.localeselector #def get_locale(): # if request.args.get('lang'): # session['lang'] = request.args.get('lang') # return session.get('lang', 'tr') db = SQLAlchemy(app) # Define the User data-model. # NB: Make sure to add flask_user UserMixin !!! class User(db.Model, UserMixin): __tablename__ = 'users' id = db.Column(db.Integer, primary_key=True) active = db.Column('is_active', db.Boolean(), nullable=False, server_default='1') # User authentication information. The collation='NOCASE' is required # to search case insensitively when USER_IFIND_MODE is 'nocase_collation'. email = db.Column(db.String(255, collation='NOCASE'), nullable=False, unique=True) email_confirmed_at = db.Column(db.DateTime()) password = db.Column(db.String(255), nullable=False, server_default='') # User information first_name = db.Column(db.String(100, collation='NOCASE'), nullable=False, server_default='') last_name = db.Column(db.String(100, collation='NOCASE'), nullable=False, server_default='') # Define the relationship to Role via UserRoles roles = db.relationship('Role', secondary='user_roles') # Define the Role data-model class Role(db.Model): __tablename__ = 'roles' id = db.Column(db.Integer(), primary_key=True) name = db.Column(db.String(50), unique=True) # Define the UserRoles association table class UserRoles(db.Model): __tablename__ = 'user_roles' id = db.Column(db.Integer(), primary_key=True) user_id = db.Column(db.Integer(), db.ForeignKey('users.id', ondelete='CASCADE')) role_id = db.Column(db.Integer(), db.ForeignKey('roles.id', ondelete='CASCADE')) # Setup Flask-User and specify the User data-model user_manager = UserManager(app, db, User) # Create all database tables db.create_all() # Create '*****@*****.**' user with no roles if not User.query.filter(User.email == '*****@*****.**').first(): user = User( email='*****@*****.**', email_confirmed_at=datetime.datetime.utcnow(), password=user_manager.hash_password('Password1'), ) db.session.add(user) db.session.commit() # Create '*****@*****.**' user with 'Admin' and 'Agent' roles if not User.query.filter(User.email == '*****@*****.**').first(): user = User( email='*****@*****.**', email_confirmed_at=datetime.datetime.utcnow(), password=user_manager.hash_password('Password1'), ) user.roles.append(Role(name='Admin')) user.roles.append(Role(name='Agent')) db.session.add(user) db.session.commit()
def base_app(request): """Flask application fixture without OAuthClient initialized.""" # allow HTTP for keycloak tests, and create the KEYCLOAK_REMOTE_APP os.environ["OAUTHLIB_INSECURE_TRANSPORT"] = "1" base_url, realm = "http://localhost:8080", "test" helper = KeycloakSettingsHelper(title="Keycloak", description="", base_url=base_url, realm=realm) KEYCLOAK_REMOTE_APP = helper.remote_app instance_path = tempfile.mkdtemp() base_app = Flask('testapp') base_app.config.update( ACCOUNTS_LOCAL_LOGIN_ENABLED=True, TESTING=True, WTF_CSRF_ENABLED=False, LOGIN_DISABLED=False, CACHE_TYPE='simple', OAUTHCLIENT_SIGNUP_FORM=_create_registrationform, OAUTHCLIENT_REMOTE_APPS=dict( cern=CERN_REMOTE_APP, cern_openid=CERN_OPENID_REMOTE_APP, orcid=ORCID_REMOTE_APP, github=GITHUB_REMOTE_APP, globus=GLOBUS_REMOTE_APP, keycloak=KEYCLOAK_REMOTE_APP, ), OAUTHCLIENT_REST_REMOTE_APPS=dict( cern=CERN_REMOTE_REST_APP, cern_openid=CERN_OPENID_REMOTE_REST_APP, orcid=ORCID_REMOTE_REST_APP, github=GITHUB_REMOTE_REST_APP, globus=GLOBUS_REMOTE_REST_APP, ), OAUTHCLIENT_STATE_EXPIRES=300, GITHUB_APP_CREDENTIALS=dict( consumer_key='github_key_changeme', consumer_secret='github_secret_changeme', ), ORCID_APP_CREDENTIALS=dict( consumer_key='orcid_key_changeme', consumer_secret='orcid_secret_changeme', ), CERN_APP_CREDENTIALS=dict( consumer_key='cern_key_changeme', consumer_secret='cern_secret_changeme', ), CERN_APP_OPENID_CREDENTIALS=dict( consumer_key='cern_key_changeme', consumer_secret='cern_secret_changeme', ), GLOBUS_APP_CREDENTIALS=dict( consumer_key='globus_key_changeme', consumer_secret='globus_secret_changeme', ), TEST_APP_CREDENTIALS=dict( consumer_key='test_key_changeme', consumer_secret='test_secret_changeme', ), OAUTHCLIENT_KEYCLOAK_USER_INFO_URL=helper.user_info_url, OAUTHCLIENT_KEYCLOAK_REALM_URL=helper.realm_url, OAUTHCLIENT_KEYCLOAK_VERIFY_AUD=True, OAUTHCLIENT_KEYCLOAK_VERIFY_EXP=False, OAUTHCLIENT_KEYCLOAK_AUD="invenio", KEYCLOAK_APP_CREDENTIALS=dict( consumer_key="keycloak_key_changeme", consumer_secret="keycloak_secret_changeme", ), # use local memory mailbox EMAIL_BACKEND='flask_email.backends.locmem.Mail', SQLALCHEMY_DATABASE_URI=os.getenv('SQLALCHEMY_DATABASE_URI', 'sqlite://'), # Alembic runs all migrations in a single transaction, and in # oauthclient the useridentity table can be in state where it's created # and then deleted in the same transaction. On PostgreSQL which # supports transactional DDL therefore fails if we don't run each # migration in its own migration. ALEMBIC_CONTEXT={ 'transaction_per_migration': True, }, SERVER_NAME='localhost', DEBUG=False, SECRET_KEY='TEST', SECURITY_DEPRECATED_PASSWORD_SCHEMES=[], SQLALCHEMY_TRACK_MODIFICATIONS=False, SECURITY_PASSWORD_HASH='plaintext', SECURITY_PASSWORD_SCHEMES=['plaintext'], APP_ALLOWED_HOSTS=['localhost'], APP_THEME=['semantic-ui'], THEME_ICONS={'semantic-ui': dict(link='linkify icon')}) FlaskMenu(base_app) Babel(base_app) Mail(base_app) InvenioDB(base_app) InvenioAccounts(base_app) with base_app.app_context(): if str(db.engine.url) != 'sqlite://' and \ not database_exists(str(db.engine.url)): create_database(str(db.engine.url)) db.create_all() def teardown(): with base_app.app_context(): db.session.close() if str(db.engine.url) != 'sqlite://': drop_database(str(db.engine.url)) shutil.rmtree(instance_path) db.engine.dispose() request.addfinalizer(teardown) base_app.test_request_context().push() return base_app
def create_app(test_config=None): # For automated tests # Setup Flask and read config from ConfigClass defined above app = Flask(__name__) app.config.from_object(__name__ + '.ConfigClass') # Load local_settings.py if file exists # For automated tests try: app.config.from_object('local_settings') except ImportError: pass # Load optional test_config # For automated tests if test_config: app.config.update(test_config) # Initialize Flask extensions db = SQLAlchemy(app) # Initialize Flask-SQLAlchemy babel = Babel(app) # Initialize Flask-BabelEx @babel.localeselector def get_locale(): translations = [ str(translation) for translation in babel.list_translations() ] language = request.accept_languages.best_match(translations) return language # Define the User data-model. Make sure to add flask_user UserMixin !!! class User(db.Model, UserMixin): __tablename__ = 'users' id = db.Column(db.Integer, primary_key=True) # User authentication information. The collation='NOCASE' is required # to search case insensitively when USER_IFIND_MODE is 'nocase_collation'. username = db.Column(db.String(50), nullable=True, unique=True) password = db.Column(db.String(255), nullable=False, server_default='') # User email information. The collation='NOCASE' is required # to search case insensitively when USER_IFIND_MODE is 'nocase_collation'. email = db.Column(db.String(255, collation='NOCASE'), nullable=False, unique=True) email_confirmed_at = db.Column(db.DateTime(), nullable=True) # User information is_enabled = db.Column(db.Boolean(), nullable=False, server_default='0') first_name = db.Column(db.String(100, collation='NOCASE'), nullable=False, server_default='') last_name = db.Column(db.String(100, collation='NOCASE'), nullable=False, server_default='') class UserInvitation(db.Model): __tablename__ = 'user_invitations' id = db.Column(db.Integer, primary_key=True) # UserInvitation email information. The collation='NOCASE' is required # to search case insensitively when USER_IFIND_MODE is 'nocase_collation'. email = db.Column(db.String(255, collation='NOCASE'), nullable=False) # save the user of the invitee invited_by_user_id = db.Column(db.Integer, db.ForeignKey('users.id')) # Create all database tables db.create_all() # Setup Flask-User db_adapter = SQLAlchemyAdapter( db, User, UserInvitationClass=UserInvitation) # Select database adapter user_manager = UserManager(db_adapter, app) # Init Flask-User and bind to app @user_registered.connect_via(app) def after_registered_hook(sender, user, user_invitation): sender.logger.info("USER REGISTERED") @user_sent_invitation.connect_via(app) def after_invitation_hook(sender, **extra): sender.logger.info("USER SENT INVITATION") # The Home page is accessible to anyone @app.route('/') def home_page(): return render_template_string(""" {% extends "flask_user_layout.html" %} {% block content %} <h2>{%trans%}Home Pages{%endtrans%}</h2> {% if call_or_get(current_user.is_authenticated) %} <p> <a href="{{ url_for('user_profile_page') }}"> {%trans%}Profile Page{%endtrans%}</a></p> <p> <a href="{{ url_for('user.logout') }}"> {%trans%}Sign out{%endtrans%}</a></p> {% else %} <p> <a href="{{ url_for('user.login') }}"> {%trans%}Sign in or Register{%endtrans%}</a></p> {% endif %} {% endblock %} """) user_manager = current_app.user_manager if user_manager.call_or_get(current_user.is_authenticated): return redirect(url_for('user_profile_page')) else: return redirect(url_for('user.login')) # The Profile page requires a logged-in user @app.route('/user/profiles') @login_required # Use of @login_required decorator @confirmed_email_required def user_profile_page(): return render_template_string(""" {% extends "flask_user_layout.html" %} {% block content %} <h2>{%trans%}Profile Page{%endtrans%}</h2> <p> {%trans%}Hello{%endtrans%} {{ current_user.username or current_user.email }},</p> <p> <a href="{{ url_for('home_page') }}"> {%trans%}Home Page{%endtrans%}</a></p> <p> <a href="{{ url_for('user.change_username') }}"> {%trans%}Change username{%endtrans%}</a></p> <p> <a href="{{ url_for('user.change_password') }}"> {%trans%}Change password{%endtrans%}</a></p> <p> <a href="{{ url_for('user.invite_user') }}"> {%trans%}Invite User{%endtrans%}</a></p> <p> <a href="{{ url_for('user.logout') }}"> {%trans%}Sign out{%endtrans%}</a></p> {% endblock %} """) return app
def factory(**config): app = Flask('testapp', instance_path=instance_path) app.config.update(**config) Babel(app) invenioconfigtugraz(app) return app
$ export FLASK_APP=app.py FLASK_DEBUG=1 $ flask run and open the example application in your browser: .. code-block:: console $ open http://127.0.0.1:5000/ To reset the example application run: .. code-block:: console $ ./app-teardown.sh SPHINX-END """ from __future__ import absolute_import, print_function from flask import Flask from flask_babelex import Babel from reroils_data import REROILSDATA # Create Flask application app = Flask(__name__) Babel(app) REROILSDATA(app)
def app(request): app = Flask(__name__) app.response_class = Response app.debug = True app.config['SECRET_KEY'] = 'secret' app.config['TESTING'] = True app.config['LOGIN_DISABLED'] = False app.config['WTF_CSRF_ENABLED'] = False app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False app.config['SECURITY_PASSWORD_SALT'] = 'salty' for opt in [ 'changeable', 'recoverable', 'registerable', 'trackable', 'passwordless', 'confirmable' ]: app.config['SECURITY_' + opt.upper()] = opt in request.keywords if 'settings' in request.keywords: for key, value in request.keywords['settings'].kwargs.items(): app.config['SECURITY_' + key.upper()] = value mail = Mail(app) if 'babel' not in request.keywords or \ request.keywords['babel'].args[0]: babel = Babel(app) app.babel = babel app.json_encoder = JSONEncoder app.mail = mail @app.route('/') def index(): return render_template('index.html', content='Home Page') @app.route('/profile') @login_required def profile(): return render_template('index.html', content='Profile Page') @app.route('/post_login') @login_required def post_login(): return render_template('index.html', content='Post Login') @app.route('/http') @http_auth_required def http(): return 'HTTP Authentication' @app.route('/http_custom_realm') @http_auth_required('My Realm') def http_custom_realm(): return render_template('index.html', content='HTTP Authentication') @app.route('/token', methods=['GET', 'POST']) @auth_token_required def token(): return render_template('index.html', content='Token Authentication') @app.route('/multi_auth') @auth_required('session', 'token', 'basic') def multi_auth(): return render_template('index.html', content='Session, Token, Basic auth') @app.route('/post_logout') def post_logout(): return render_template('index.html', content='Post Logout') @app.route('/post_register') def post_register(): return render_template('index.html', content='Post Register') @app.route('/admin') @roles_required('admin') def admin(): return render_template('index.html', content='Admin Page') @app.route('/admin_and_editor') @roles_required('admin', 'editor') def admin_and_editor(): return render_template('index.html', content='Admin and Editor Page') @app.route('/admin_or_editor') @roles_accepted('admin', 'editor') def admin_or_editor(): return render_template('index.html', content='Admin or Editor Page') @app.route('/unauthorized') def unauthorized(): return render_template('unauthorized.html') @app.route('/page1') def page_1(): return 'Page 1' return app
def create_app(app_name=None): # Configuration settings import config if not app_name: app_name = config.APP_NAME # Only enable password related functionality in server mode. if config.SERVER_MODE is True: # Some times we need to access these config params where application # context is not available (we can't use current_app.config in those # cases even with current_app.app_context()) # So update these params in config itself. # And also these updated config values will picked up by application # since we are updating config before the application instance is # created. config.SECURITY_RECOVERABLE = True config.SECURITY_CHANGEABLE = True # Now we'll open change password page in alertify dialog # we don't want it to redirect to main page after password # change operation so we will open the same password change page again. config.SECURITY_POST_CHANGE_VIEW = 'browser.change_password' """Create the Flask application, startup logging and dynamically load additional modules (blueprints) that are found in this directory.""" app = PgAdmin(__name__, static_url_path='/static') # Removes unwanted whitespace from render_template function app.jinja_env.trim_blocks = True app.config.from_object(config) app.config.update(dict(PROPAGATE_EXCEPTIONS=True)) ########################################################################## # Setup logging and log the application startup ########################################################################## # Add SQL level logging, and set the base logging level logging.addLevelName(25, 'SQL') app.logger.setLevel(logging.DEBUG) app.logger.handlers = [] # We also need to update the handler on the webserver in order to see # request. Setting the level prevents werkzeug from setting up it's own # stream handler thus ensuring all the logging goes through the pgAdmin # logger. logger = logging.getLogger('werkzeug') logger.setLevel(logging.INFO) # Set SQLITE_PATH to TEST_SQLITE_PATH while running test cases if ( 'PGADMIN_TESTING_MODE' in os.environ and os.environ['PGADMIN_TESTING_MODE'] == '1' ): config.SQLITE_PATH = config.TEST_SQLITE_PATH # Ensure the various working directories exist from pgadmin.setup import create_app_data_directory, db_upgrade create_app_data_directory(config) # File logging fh = logging.FileHandler(config.LOG_FILE, encoding='utf-8') fh.setLevel(config.FILE_LOG_LEVEL) fh.setFormatter(logging.Formatter(config.FILE_LOG_FORMAT)) app.logger.addHandler(fh) logger.addHandler(fh) # Console logging ch = logging.StreamHandler() ch.setLevel(config.CONSOLE_LOG_LEVEL) ch.setFormatter(logging.Formatter(config.CONSOLE_LOG_FORMAT)) app.logger.addHandler(ch) logger.addHandler(ch) # Log the startup app.logger.info('########################################################') app.logger.info('Starting %s v%s...', config.APP_NAME, config.APP_VERSION) app.logger.info('########################################################') app.logger.debug("Python syspath: %s", sys.path) ########################################################################## # Setup i18n ########################################################################## # Initialise i18n babel = Babel(app) app.logger.debug('Available translations: %s' % babel.list_translations()) @babel.localeselector def get_locale(): """Get the language for the user.""" language = 'en' if config.SERVER_MODE is False: # Get the user language preference from the miscellaneous module if current_user.is_authenticated: user_id = current_user.id else: user = user_datastore.get_user(config.DESKTOP_USER) if user is not None: user_id = user.id user_language = Preferences.raw_value( 'miscellaneous', 'user_language', None, user_id ) if user_language is not None: language = user_language else: # If language is available in get request then return the same # otherwise check the session or cookie data = request.form if 'language' in data: language = data['language'] or language setattr(session, 'PGADMIN_LANGUAGE', language) elif hasattr(session, 'PGADMIN_LANGUAGE'): language = getattr(session, 'PGADMIN_LANGUAGE', language) elif hasattr(request.cookies, 'PGADMIN_LANGUAGE'): language = getattr( request.cookies, 'PGADMIN_LANGUAGE', language ) return language ########################################################################## # Setup authentication ########################################################################## app.config['SQLALCHEMY_DATABASE_URI'] = u'sqlite:///{0}?timeout={1}' \ .format(config.SQLITE_PATH.replace(u'\\', u'/'), getattr(config, 'SQLITE_TIMEOUT', 500) ) # Create database connection object and mailer db.init_app(app) ########################################################################## # Upgrade the schema (if required) ########################################################################## with app.app_context(): # Run migration for the first time i.e. create database from config import SQLITE_PATH if not os.path.exists(SQLITE_PATH): db_upgrade(app) else: version = Version.query.filter_by(name='ConfigDB').first() schema_version = version.value # Run migration if current schema version is greater than the # schema version stored in version table if CURRENT_SCHEMA_VERSION >= schema_version: db_upgrade(app) # Update schema version to the latest if CURRENT_SCHEMA_VERSION > schema_version: version = Version.query.filter_by(name='ConfigDB').first() version.value = CURRENT_SCHEMA_VERSION db.session.commit() Mail(app) import pgadmin.utils.paths as paths paths.init_app(app) # Setup Flask-Security user_datastore = SQLAlchemyUserDatastore(db, User, Role) security = Security(None, user_datastore) ########################################################################## # Setup security ########################################################################## with app.app_context(): config.CSRF_SESSION_KEY = Keys.query.filter_by( name='CSRF_SESSION_KEY').first().value config.SECRET_KEY = Keys.query.filter_by( name='SECRET_KEY').first().value config.SECURITY_PASSWORD_SALT = Keys.query.filter_by( name='SECURITY_PASSWORD_SALT').first().value # Update the app.config with proper security keyes for signing CSRF data, # signing cookies, and the SALT for hashing the passwords. app.config.update(dict({ 'CSRF_SESSION_KEY': config.CSRF_SESSION_KEY, 'SECRET_KEY': config.SECRET_KEY, 'SECURITY_PASSWORD_SALT': config.SECURITY_PASSWORD_SALT, 'SESSION_COOKIE_DOMAIN': config.SESSION_COOKIE_DOMAIN })) security.init_app(app, user_datastore) # register custom unauthorised handler. app.login_manager.unauthorized_handler(pga_unauthorised) app.session_interface = create_session_interface(app) # Make the Session more secure against XSS & CSRF when running in web mode if config.SERVER_MODE: paranoid = Paranoid(app) paranoid.redirect_view = 'browser.index' ########################################################################## # Load all available server drivers ########################################################################## driver.init_app(app) ########################################################################## # Register language to the preferences after login ########################################################################## @user_logged_in.connect_via(app) def register_language(sender, user): # After logged in, set the language in the preferences if we get from # the login page data = request.form if 'language' in data: language = data['language'] # Set the user language preference misc_preference = Preferences.module('miscellaneous') user_languages = misc_preference.preference( 'user_language' ) if user_languages and language: language = user_languages.set(language) ########################################################################## # Register any local servers we can discover ########################################################################## @user_logged_in.connect_via(app) def on_user_logged_in(sender, user): # Keep hold of the user ID user_id = user.id # Get the first server group for the user servergroup_id = 1 servergroups = ServerGroup.query.filter_by( user_id=user_id ).order_by("id") if servergroups.count() > 0: servergroup = servergroups.first() servergroup_id = servergroup.id '''Add a server to the config database''' def add_server(user_id, servergroup_id, name, superuser, port, discovery_id, comment): # Create a server object if needed, and store it. servers = Server.query.filter_by( user_id=user_id, discovery_id=svr_discovery_id ).order_by("id") if servers.count() > 0: return svr = Server(user_id=user_id, servergroup_id=servergroup_id, name=name, host='localhost', port=port, maintenance_db='postgres', username=superuser, ssl_mode='prefer', comment=svr_comment, discovery_id=discovery_id) db.session.add(svr) db.session.commit() # Figure out what servers are present if winreg is not None: arch_keys = set() proc_arch = os.environ['PROCESSOR_ARCHITECTURE'].lower() try: proc_arch64 = os.environ['PROCESSOR_ARCHITEW6432'].lower() except Exception as e: proc_arch64 = None if proc_arch == 'x86' and not proc_arch64: arch_keys.add(0) elif proc_arch == 'x86' or proc_arch == 'amd64': arch_keys.add(winreg.KEY_WOW64_32KEY) arch_keys.add(winreg.KEY_WOW64_64KEY) for arch_key in arch_keys: for server_type in ('PostgreSQL', 'EnterpriseDB'): try: root_key = winreg.OpenKey( winreg.HKEY_LOCAL_MACHINE, "SOFTWARE\\" + server_type + "\Services", 0, winreg.KEY_READ | arch_key ) for i in xrange(0, winreg.QueryInfoKey(root_key)[0]): inst_id = winreg.EnumKey(root_key, i) inst_key = winreg.OpenKey(root_key, inst_id) svr_name = winreg.QueryValueEx( inst_key, 'Display Name' )[0] svr_superuser = winreg.QueryValueEx( inst_key, 'Database Superuser' )[0] svr_port = winreg.QueryValueEx(inst_key, 'Port')[0] svr_discovery_id = inst_id svr_comment = gettext( "Auto-detected %s installation with the data " "directory at %s" % ( winreg.QueryValueEx( inst_key, 'Display Name' )[0], winreg.QueryValueEx( inst_key, 'Data Directory' )[0] ) ) add_server( user_id, servergroup_id, svr_name, svr_superuser, svr_port, svr_discovery_id, svr_comment ) inst_key.Close() except Exception as e: pass else: # We use the postgres-winreg.ini file on non-Windows try: from configparser import ConfigParser except ImportError: from ConfigParser import ConfigParser # Python 2 registry = ConfigParser() try: registry.read('/etc/postgres-reg.ini') sections = registry.sections() # Loop the sections, and get the data from any that are PG or PPAS for section in sections: if ( section.startswith('PostgreSQL/') or section.startswith('EnterpriseDB/') ): svr_name = registry.get(section, 'Description') svr_superuser = registry.get(section, 'Superuser') svr_port = registry.getint(section, 'Port') svr_discovery_id = section description = registry.get(section, 'Description') data_directory = registry.get(section, 'DataDirectory') if hasattr(str, 'decode'): description = description.decode('utf-8') data_directory = data_directory.decode('utf-8') svr_comment = gettext(u"Auto-detected %s installation " u"with the data directory at %s" % ( description, data_directory ) ) add_server(user_id, servergroup_id, svr_name, svr_superuser, svr_port, svr_discovery_id, svr_comment) except Exception as e: pass @user_logged_in.connect_via(app) @user_logged_out.connect_via(app) def force_session_write(app, user): session.force_write = True ########################################################################## # Load plugin modules ########################################################################## for module in app.find_submodules('pgadmin'): app.logger.info('Registering blueprint module: %s' % module) app.register_blueprint(module) ########################################################################## # Handle the desktop login ########################################################################## @app.before_request def before_request(): """Login the default user if running in desktop mode""" # Check the auth key is valid, if it's set, and we're not in server # mode, and it's not a help file request. if not config.SERVER_MODE and app.PGADMIN_KEY != '': if ( ('key' not in request.args or request.args['key'] != app.PGADMIN_KEY) and request.cookies.get('PGADMIN_KEY') != app.PGADMIN_KEY and request.endpoint != 'help.static' ): abort(401) if not config.SERVER_MODE and not current_user.is_authenticated: user = user_datastore.get_user(config.DESKTOP_USER) # Throw an error if we failed to find the desktop user, to give # the sysadmin a hint. We'll continue to try to login anyway as # that'll through a nice 500 error for us. if user is None: app.logger.error( 'The desktop user %s was not found in the configuration ' 'database.' % config.DESKTOP_USER ) abort(401) login_user(user) @app.after_request def after_request(response): if 'key' in request.args: domain = dict() if config.COOKIE_DEFAULT_DOMAIN and \ config.COOKIE_DEFAULT_DOMAIN != 'localhost': domain['domain'] = config.COOKIE_DEFAULT_DOMAIN response.set_cookie('PGADMIN_KEY', value=request.args['key'], path=config.COOKIE_DEFAULT_PATH, **domain) return response ########################################################################## # Minify output ########################################################################## # HTMLMIN doesn't work with Python 2.6. if not config.DEBUG and sys.version_info >= (2, 7): from flask_htmlmin import HTMLMIN HTMLMIN(app) @app.context_processor def inject_blueprint(): """Inject a reference to the current blueprint, if any.""" return { 'current_app': current_app, 'current_blueprint': current_blueprint } ########################################################################## # All done! ########################################################################## return app
def base_app(request): """Flask application fixture without OAuthClient initialized.""" instance_path = tempfile.mkdtemp() base_app = Flask('testapp') base_app.config.update( TESTING=True, WTF_CSRF_ENABLED=False, LOGIN_DISABLED=False, CACHE_TYPE='simple', OAUTHCLIENT_REMOTE_APPS=dict( cern=CERN_REMOTE_APP, orcid=ORCID_REMOTE_APP, github=GITHUB_REMOTE_APP, ), GITHUB_APP_CREDENTIALS=dict( consumer_key='github_key_changeme', consumer_secret='github_secret_changeme', ), ORCID_APP_CREDENTIALS=dict( consumer_key='orcid_key_changeme', consumer_secret='orcid_secret_changeme', ), CERN_APP_CREDENTIALS=dict( consumer_key='cern_key_changeme', consumer_secret='cern_secret_changeme', ), # use local memory mailbox EMAIL_BACKEND='flask_email.backends.locmem.Mail', SQLALCHEMY_DATABASE_URI=os.getenv('SQLALCHEMY_DATABASE_URI', 'sqlite://'), SERVER_NAME='localhost', DEBUG=False, SECRET_KEY='TEST', SECURITY_DEPRECATED_PASSWORD_SCHEMES=[], SECURITY_PASSWORD_HASH='plaintext', SECURITY_PASSWORD_SCHEMES=['plaintext'], ) FlaskMenu(base_app) Babel(base_app) Mail(base_app) InvenioDB(base_app) InvenioAccounts(base_app) with base_app.app_context(): if str(db.engine.url) != 'sqlite://' and \ not database_exists(str(db.engine.url)): create_database(str(db.engine.url)) db.create_all() def teardown(): with base_app.app_context(): db.session.close() if str(db.engine.url) != 'sqlite://': drop_database(str(db.engine.url)) shutil.rmtree(instance_path) request.addfinalizer(teardown) base_app.test_request_context().push() return base_app
# Initialize Flask and set some config values app = Flask(__name__) app.config['DEBUG'] = True app.config['SECRET_KEY'] = 'super-secret' #debug_toolbar=DebugToolbarExtension() #debug_toolbar.init_app(app) #app.config['DEBUG_TB_INTERCEPT_REDIRECTS']=False app.config[ 'SQLALCHEMY_DATABASE_URI'] = 'mysql+pymysql://root:@127.0.0.1:3306/zsky' app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = True app.config['SQLALCHEMY_POOL_SIZE'] = 5000 db = SQLAlchemy(app) manager = Manager(app) migrate = Migrate(app, db) moment = Moment(app) babel = Babel(app) app.config['BABEL_DEFAULT_LOCALE'] = 'zh_CN' loginmanager = LoginManager() loginmanager.init_app(app) loginmanager.session_protection = 'strong' loginmanager.login_view = 'login' loginmanager.login_message = "请先登录!" cache = Cache(app, config={ 'CACHE_TYPE': 'redis', 'CACHE_REDIS_HOST': '127.0.0.1', 'CACHE_REDIS_PORT': 6379, 'CACHE_REDIS_DB': '', 'CACHE_REDIS_PASSWORD': '' }) cache.init_app(app)
class InvenioI18N(object): """Invenio I18N extension.""" def __init__(self, app=None, date_formats=None, localeselector=None, timezoneselector=None, entry_point_group='invenio_i18n.translations'): """Initialize extension. :param app: Flask application. :param data_formats: Override default date/time formatting. :param localeselector: Callback function used for locale selection. (Default: :func:`invenio_i18n.selectors.get_locale()`) :param timezoneselector: Callback function used for timezone selection. (Default: ``BABEL_DEFAULT_TIMEZONE``) :param entry_point_group: Entrypoint used to load translations from. Set to ``None`` to not load translations from entry points. """ self.domain = MultidirDomain() self.babel = Babel( date_formats=date_formats, configure_jinja=True, default_domain=self.domain, ) self.localeselector = localeselector self.timezoneselector = timezoneselector self.entry_point_group = entry_point_group self._locales_cache = None self._languages_cache = None if app: self.init_app(app) def init_app(self, app): """Flask application initialization. The initialization will: * Set default values for the configuration variables. * Load translations from paths specified in ``I18N_TRANSLATIONS_PATHS``. * Load translations from ``app.root_path>/translations`` if it exists. * Load translations from a specified entry point. * Add ``toutc`` and ``tousertimezone`` template filters. * Install a custom JSON encoder on app. """ self.init_config(app) # Initialize Flask-BabelEx self.babel.init_app(app) self.babel.localeselector(self.localeselector or get_locale) self.babel.timezoneselector(self.timezoneselector or get_timezone) # 1. Paths listed in I18N_TRANSLATIONS_PATHS for p in app.config.get('I18N_TRANSLATIONS_PATHS', []): self.domain.add_path(p) # 2. <app.root_path>/translations app_translations = os.path.join(app.root_path, 'translations') if os.path.exists(app_translations): self.domain.add_path(app_translations) # 3. Entrypoints if self.entry_point_group: self.domain.add_entrypoint(self.entry_point_group) # Register default routes if URL is set. register_default_routes = app.config['I18N_SET_LANGUAGE_URL'] \ and app.config['I18N_LANGUAGES'] app.register_blueprint( create_blueprint(register_default_routes=register_default_routes), url_prefix=app.config['I18N_SET_LANGUAGE_URL']) # Register Jinja2 template filters for date formatting (Flask-Babel # already installs other filters). app.add_template_filter(filter_to_utc, name='toutc') app.add_template_filter(filter_to_user_timezone, name='tousertimezone') app.add_template_filter(filter_language_name, name='language_name') app.add_template_filter(filter_language_name_local, name='language_name_local') app.add_template_global(current_i18n, name='current_i18n') # Lazy string aware JSON encoder. app.json_encoder = get_lazystring_encoder(app) app.extensions['invenio-i18n'] = self def init_config(self, app): """Initialize configuration.""" for k in dir(config): if k.startswith('I18N_'): app.config.setdefault(k, getattr(config, k)) def iter_languages(self): """Iterate over list of languages.""" default_lang = self.babel.default_locale.language default_title = self.babel.default_locale.get_display_name( default_lang) yield (default_lang, default_title) for l, title in current_app.config.get('I18N_LANGUAGES', []): yield l, title def get_languages(self): """Get list of languages.""" if self._languages_cache is None: self._languages_cache = list(self.iter_languages()) return self._languages_cache def get_locales(self): """Get a list of supported locales. Computes the list using ``I18N_LANGUAGES`` configuration variable. """ if self._locales_cache is None: langs = [self.babel.default_locale] for l, dummy_title in current_app.config.get('I18N_LANGUAGES', []): langs.append(self.babel.load_locale(l)) self._locales_cache = langs return self._locales_cache @property def locale(self): """Get current locale.""" return get_current_locale() @property def language(self): """Get current language code.""" return get_current_locale().language @property def timezone(self): """Get current timezone.""" return get_current_timezone()
app = Flask(__name__, template_folder='app/templates', static_folder='app/static') import app.config as config app.config.from_object(config) app.jinja_env.filters['substring'] = jinja2_filter_substring app.jinja_env.filters['startswith'] = jinja2_filter_startswith app.jinja_env.filters['datedelta'] = jinja2_filter_date_with_delta app.jinja_env.filters['heatmap'] = jinja2_filter_photo_collection_heat_map app.jinja_env.filters['averagerating'] = jinja2_filter_get_average_rating app.jinja_env.filters['numberoforder'] = jinja2_filter_get_number_of_order from flask_babelex import Babel babel = Babel(default_locale='zh_Hans_CN') babel.init_app(app) from flask.ext.sqlalchemy import SQLAlchemy db = SQLAlchemy(app) from app.app_provider import AppInfo AppInfo.set_app(app) AppInfo.set_db(db) # 初始化云端的图片存储服务 image_store = ImageStore(app) # 初始化Gallery存储的服务,用于存储所有的用户上传的头像 AppInfo.set_galleries_store_service(image_store) # 初始化Image存储的服务,用于存储所有摄影师上传的作品图像
def create_app(): """ Flask application factory """ # Create Flask app load app.config app = Flask(__name__) app.config.from_object(__name__ + '.ConfigClass') # Initialize Flask-BabelEx babel = Babel(app) # Initialize Flask-SQLAlchemy db = SQLAlchemy(app) # Define the User data-model. # NB: Make sure to add flask_user UserMixin !!! class User(db.Model, UserMixin): __tablename__ = 'users' id = db.Column(db.Integer, primary_key=True) active = db.Column('is_active', db.Boolean(), nullable=False, server_default='1') # User authentication information. The collation='NOCASE' is required # to search case insensitively when USER_IFIND_MODE is 'nocase_collation'. email = db.Column(db.String(255, collation='NOCASE'), nullable=False, unique=True) email_confirmed_at = db.Column(db.DateTime()) password = db.Column(db.String(255), nullable=False, server_default='') # User information first_name = db.Column(db.String(100, collation='NOCASE'), nullable=False, server_default='') last_name = db.Column(db.String(100, collation='NOCASE'), nullable=False, server_default='') # Define the relationship to Role via UserRoles roles = db.relationship('Role', secondary='user_roles') # Define the Role data-model class Role(db.Model): __tablename__ = 'roles' id = db.Column(db.Integer(), primary_key=True) name = db.Column(db.String(50), unique=True) # Define the UserRoles association table class UserRoles(db.Model): __tablename__ = 'user_roles' id = db.Column(db.Integer(), primary_key=True) user_id = db.Column(db.Integer(), db.ForeignKey('users.id', ondelete='CASCADE')) role_id = db.Column(db.Integer(), db.ForeignKey('roles.id', ondelete='CASCADE')) # Setup Flask-User and specify the User data-model user_manager = UserManager(app, db, User) # Create all database tables db.create_all() # Create '*****@*****.**' user with no roles if not User.query.filter(User.email == '*****@*****.**').first(): user = User( email='*****@*****.**', email_confirmed_at=datetime.datetime.utcnow(), password=user_manager.hash_password('Password1'), ) db.session.add(user) db.session.commit() # Create '*****@*****.**' user with 'Admin' and 'Agent' roles if not User.query.filter(User.email == '*****@*****.**').first(): user = User( email='*****@*****.**', email_confirmed_at=datetime.datetime.utcnow(), password=user_manager.hash_password('Password1'), ) user.roles.append(Role(name='Admin')) user.roles.append(Role(name='Agent')) db.session.add(user) db.session.commit() # The Home page is accessible to anyone @app.route('/') def home_page(): return render_template_string(""" {% extends "flask_user_layout.html" %} {% block content %} <h2>{%trans%}Home page{%endtrans%}</h2> <p><a href={{ url_for('user.register') }}>{%trans%}Register{%endtrans%}</a></p> <p><a href={{ url_for('user.login') }}>{%trans%}Sign in{%endtrans%}</a></p> <p><a href={{ url_for('home_page') }}>{%trans%}Home Page{%endtrans%}</a> (accessible to anyone)</p> <p><a href={{ url_for('member_page') }}>{%trans%}Member Page{%endtrans%}</a> (login_required: [email protected] / Password1)</p> <p><a href={{ url_for('admin_page') }}>{%trans%}Admin Page{%endtrans%}</a> (role_required: [email protected] / Password1')</p> <p><a href={{ url_for('user.logout') }}>{%trans%}Sign out{%endtrans%}</a></p> {% endblock %} """) # The Members page is only accessible to authenticated users @app.route('/members') @login_required # Use of @login_required decorator def member_page(): return render_template_string(""" {% extends "flask_user_layout.html" %} {% block content %} <h2>{%trans%}Members page{%endtrans%}</h2> <p><a href={{ url_for('user.register') }}>{%trans%}Register{%endtrans%}</a></p> <p><a href={{ url_for('user.login') }}>{%trans%}Sign in{%endtrans%}</a></p> <p><a href={{ url_for('home_page') }}>{%trans%}Home Page{%endtrans%}</a> (accessible to anyone)</p> <p><a href={{ url_for('member_page') }}>{%trans%}Member Page{%endtrans%}</a> (login_required: [email protected] / Password1)</p> <p><a href={{ url_for('admin_page') }}>{%trans%}Admin Page{%endtrans%}</a> (role_required: [email protected] / Password1')</p> <p><a href={{ url_for('user.logout') }}>{%trans%}Sign out{%endtrans%}</a></p> {% endblock %} """) # The Admin page requires an 'Admin' role. @app.route('/admin') @roles_required('Admin') # Use of @roles_required decorator def admin_page(): return render_template_string(""" {% extends "flask_user_layout.html" %} {% block content %} <h2>{%trans%}Admin Page{%endtrans%}</h2> <p><a href={{ url_for('user.register') }}>{%trans%}Register{%endtrans%}</a></p> <p><a href={{ url_for('user.login') }}>{%trans%}Sign in{%endtrans%}</a></p> <p><a href={{ url_for('home_page') }}>{%trans%}Home Page{%endtrans%}</a> (accessible to anyone)</p> <p><a href={{ url_for('member_page') }}>{%trans%}Member Page{%endtrans%}</a> (login_required: [email protected] / Password1)</p> <p><a href={{ url_for('admin_page') }}>{%trans%}Admin Page{%endtrans%}</a> (role_required: [email protected] / Password1')</p> <p><a href={{ url_for('user.logout') }}>{%trans%}Sign out{%endtrans%}</a></p> {% endblock %} """) return app
class InvenioI18N(object): """Invenio I18N module.""" def __init__( self, app=None, date_formats=None, localeselector=None, timezoneselector=None, entrypoint="invenio_i18n.translations", ): """Initialize extension.""" self.babel = Babel(date_formats=date_formats, configure_jinja=True, default_domain=MultidirDomain()) self.localeselector = localeselector self.timezoneselector = timezoneselector self.entrypoint = entrypoint self._locales_cache = None if app: self.init_app(app) def init_app(self, app): """Flask application initialization.""" # Initialize Flask-BabelEx app.config.setdefault("I18N_LANGUAGES", []) # TODO: allow to plug custom localeselector and timezoneselector self.babel.init_app(app) self.babel.localeselector(self.localeselector or get_locale) self.babel.timezoneselector(self.timezoneselector or get_timezone) # Add paths to search for message catalogs domain = self.babel._default_domain # 1. Paths listed in I18N_TRANSLATIONS_PATHS for p in app.config.get("I18N_TRANSLATIONS_PATHS", []): domain.add_path(p) # 2. <app.root_path>/translations app_translations = os.path.join(app.root_path, "translations") if os.path.exists(app_translations): domain.add_path(app_translations) # 3. Entrypoints if self.entrypoint: domain.add_entrypoint(self.entrypoint) # Register Jinja2 template filters for date formatting (Flask-Babel # already installs other filters). app.add_template_filter(filter_to_utc, name="toutc") app.add_template_filter(filter_to_user_timezone, name="tousertimezone") # Lazy string aware JSON encoder. app.json_encoder = get_lazystring_encoder(app) app.extensions["invenio-i18n"] = self def get_locales(self): """Get a list of supported locales.""" if self._locales_cache is None: langs = [self.babel.default_locale] for l in current_app.config.get("I18N_LANGUAGES", []): langs.append(self.babel.load_locale(l)) self._locales_cache = langs return self._locales_cache
provide_automatic_options = True required_methods.add('OPTIONS') else: provide_automatic_options = False # Add the required methods now. methods |= required_methods if not isinstance(rule, Rule): rule = self.url_rule_class(rule, methods=methods, **options) rule.provide_automatic_options = provide_automatic_options self.url_map.add(rule) if view_func is not None: old_func = self.view_functions.get(endpoint) if old_func is not None and old_func != view_func: raise AssertionError('View function mapping is overwriting an ' 'existing endpoint function: %s' % endpoint) self.view_functions[endpoint] = view_func app = ServerFlask('server') CORS(app, resources=r'/*') app.url_map.converters['regex'] = RegexConverter Babel(app, 'zh_CN') Compress(app)