コード例 #1
0
ファイル: i18n.py プロジェクト: freedomofpress/securedrop
def validate_locale_configuration(config: SDConfig, babel: Babel) -> None:
    """
    Check that configured locales are available in the filesystem and therefore usable by
    Babel.  Warn about configured locales that are not usable, unless we're left with
    no usable default or fallback locale, in which case raise an exception.
    """
    # These locales are available and loadable from the filesystem.
    available = set(babel.list_translations())
    available.add(Locale.parse(FALLBACK_LOCALE))

    # These locales were configured via "securedrop-admin sdconfig", meaning
    # they were present on the Admin Workstation at "securedrop-admin" runtime.
    configured = parse_locale_set(config.SUPPORTED_LOCALES)

    # The intersection of these sets is the set of locales usable by Babel.
    usable = available & configured

    missing = configured - usable
    if missing:
        babel.app.logger.error(
            f"Configured locales {missing} are not in the set of usable locales {usable}"
        )

    defaults = parse_locale_set([config.DEFAULT_LOCALE, FALLBACK_LOCALE])
    if not defaults & usable:
        raise ValueError(
            f"None of the default locales {defaults} are in the set of usable locales {usable}"
        )

    global USABLE_LOCALES
    USABLE_LOCALES = usable
コード例 #2
0
ファイル: i18n.py プロジェクト: AluminumOxide/flask-starter
    class __I18n:
        def __init__(self, app):
            self.i18n = Babel(app)
            self.localeselector = self.i18n.localeselector

        def list_locales(self):
            return list(map(lambda t: str(t), self.i18n.list_translations()))
コード例 #3
0
class CoreRestApi:
    def __init__(self, global_config):
        self.config = global_config['rest_api']
        self.app = Flask('wazo_dird', template_folder=TEMPLATE_FOLDER)
        self.babel = Babel(self.app)
        self.app.config['BABEL_DEFAULT_LOCALE'] = 'en'
        self.app.config['auth'] = global_config['auth']
        AuthResource.auth_config = global_config['auth']

        @self.babel.localeselector
        def get_locale():
            translations = [
                str(translation)
                for translation in self.babel.list_translations()
            ]
            return request.accept_languages.best_match(translations)

        http_helpers.add_logger(self.app, logger)
        self.app.after_request(http_helpers.log_request)
        self.app.secret_key = os.urandom(24)
        self.app.permanent_session_lifetime = timedelta(minutes=5)
        self.load_cors()
        self.api = api
        auth_verifier.set_config(global_config['auth'])

    def load_cors(self):
        cors_config = dict(self.config.get('cors', {}))
        enabled = cors_config.pop('enabled', False)
        if enabled:
            CORS(self.app, **cors_config)

    def run(self):
        self.api.init_app(self.app)

        https_config = self.config['https']

        bind_addr = (https_config['listen'], https_config['port'])

        wsgi_app = ReverseProxied(
            ProxyFix(wsgi.WSGIPathInfoDispatcher({'/': self.app})))
        server = wsgi.WSGIServer(bind_addr=bind_addr, wsgi_app=wsgi_app)
        server.ssl_adapter = http_helpers.ssl_adapter(
            https_config['certificate'], https_config['private_key'])
        logger.debug('WSGIServer starting... uid: %s, listen: %s:%s',
                     os.getuid(), bind_addr[0], bind_addr[1])
        for route in http_helpers.list_routes(self.app):
            logger.debug(route)

        try:
            server.start()
        finally:
            server.stop()
コード例 #4
0
class LibreantViewApp(LibreantCoreApp):
    def __init__(self, import_name, conf={}):
        defaults = {
            'BOOTSTRAP_SERVE_LOCAL': True,
            'AGHERANT_DESCRIPTIONS': [],
            'API_URL': '/api/v1',
            'RESULTS_PER_PAGE': 30,
            'MAX_RESULTS_PER_PAGE': 100
        }
        defaults.update(conf)
        super(LibreantViewApp, self).__init__(import_name, defaults)
        if self.config['AGHERANT_DESCRIPTIONS']:
            self.register_blueprint(agherant, url_prefix='/agherant')
        api = get_blueprint_api(users_routes=self.users_enabled)
        self.register_blueprint(api, url_prefix=self.config['API_URL'])
        Bootstrap(self)
        self.babel = Babel(self)
        self.available_translations = [l.language for l in self.babel.list_translations()]
        if self.users_enabled:
            self.autht = auth.AuthtFromSessionAnon()
            self.authz = auth.AuthzFromSession(authenticator=self.autht)
        else:
            self.autht = auth.TransparentAutht()
            self.authz = auth.TransparentAuthz()
コード例 #5
0
def create_app(app_name=None):

    # Configuration settings
    import config
    if not app_name:
        app_name = config.APP_NAME
    """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)

    # 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)

    from pgadmin.setup import create_app_data_directory, db_upgrade

    # Sanity checks (App data directory exists)
    create_app_data_directory(config)

    ##########################################################################
    # 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
            misc_preference = Preferences.module('miscellaneous', False)
            if misc_preference:
                user_languages = misc_preference.preference('user_language')
                if user_languages:
                    language = user_languages.get() or 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))

    # Only enable password related functionality in server mode.
    if config.SERVER_MODE is True:
        # TODO: Figure out how to disable /logout and /login
        app.config['SECURITY_RECOVERABLE'] = True
        app.config['SECURITY_CHANGEABLE'] = True

    # Create database connection object and mailer
    db.init_app(app)

    ##########################################################################
    # Upgrade the schema (if required)
    ##########################################################################
    db_upgrade(app)

    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))
    app.config.update(dict(SECRET_KEY=config.SECRET_KEY))
    app.config.update(
        dict(SECURITY_PASSWORD_SALT=config.SECURITY_PASSWORD_SALT))

    security.init_app(app)

    app.session_interface = create_session_interface(app)

    ##########################################################################
    # 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:
                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:
                        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 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:
            pass

    ##########################################################################
    # 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 ((not 'key' 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:
            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:
            response.set_cookie('PGADMIN_KEY', value=request.args['key'])

        return response

    ##########################################################################
    # Minify output
    ##########################################################################
    # HTMLMIN doesn't work with Python 2.6.
    if not config.DEBUG and sys.version_info >= (2, 7):
        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!
    ##########################################################################
    app.logger.debug('URL map: %s' % app.url_map)

    return app
コード例 #6
0
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 and 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:
            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:
            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):

        # If Auto Discover servers is turned off then return from the
        # function.
        if not config.AUTO_DISCOVER_SERVERS:
            return

        # 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)
        if app.blueprints.get(module.name) is None:
            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') and \
                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
コード例 #7
0
ファイル: main.py プロジェクト: maxhawkins/random_diet_club
# -*- coding: utf-8 -*-

import logging

from flask import Flask, render_template, request, redirect, g
from flask_babel import Babel, get_locale
from babel import negotiate_locale

app = Flask(__name__)
babel = Babel(app)

AVAILABLE_LOCALES = [str(t) for t in babel.list_translations()]

@babel.localeselector
def get_user_locale():
	preferred = [x.replace('-', '_') for x in request.accept_languages.values()]
	if 'l' in request.args:
		preferred = [request.args['l']]
	elif 'fb_locale' in request.args:
		preferred = [request.args['fb_locale']]
	return negotiate_locale(preferred, AVAILABLE_LOCALES)

@app.before_request
def before_request():
	g.locale = get_locale()
	if g.locale is None:
		g.locale = 'en'

@app.route('/')
def hello():
    return render_template('index.html')
コード例 #8
0
ファイル: app.py プロジェクト: devopstoday11/LinOTP
def create_app(config_name='default', config_extra=None):
    """
    Generate a new instance of the Flask app

    This generates and configures the main application instance. Testing
    environments can use `config_extra` to provide extra configuration values
    such as a temporary database URL.

    @param config_name The name of the configuration to load from settings.py
    @param config_extra An optional dict of configuration override values
    """
    app = LinOTPApp()

    _configure_app(app, config_name, config_extra)

    babel = Babel(app, configure_jinja=False, default_domain="linotp")

    # Determine which languages are available in the i18n directory.
    # Note that we always have English even without a translation file.

    app.available_languages = list(
        {'en'} | {t.language
                  for t in babel.list_translations()})

    setup_mako(app)
    init_logging(app)

    with app.app_context():
        setup_cache(app)
        setup_db(app)

        init_linotp_config(app)
        set_config()  # ensure `request_context` exists

        init_security_provider()

        setup_audit(app)

        reload_token_classes()
        app.check_license()

    @app.before_request
    def setup_env():
        # The following functions are called here because they're
        # stuffing bits into `flask.g`, which is a per-request global
        # object. Much of what is stuffed into `flask.g` is actually
        # application-wide stuff that has no business being stored in
        # `flask.g` in the first place, but lots of code expects to be
        # able to look at the "request context" and find stuff
        # there. Disentangling the application-wide stuff in the
        # request context from the request-scoped stuff is a major
        # project that will not be undertaken just now, and we're
        # probably doing more work here than we need to. Global
        # variables suck.

        set_config()
        allocate_security_module()

    app.add_url_rule('/healthcheck/status', 'healthcheck', healthcheck)

    # Add pre request handlers
    app.before_first_request(init_logging_config)
    app.before_request(app._run_setup)
    app.before_request(app.start_session)

    # Per controller setup and handlers
    app.setup_controllers()

    if 'selfservice' in app.enabled_controllers:

        @app.route('/')
        def index():
            return redirect('/selfservice')

        @app.route('/account/login')
        def login():
            return redirect('/selfservice/login')

        @app.route('/account/logout')
        def logout():
            return redirect('/selfservice/logout')

    # Post handlers
    app.teardown_request(app.finalise_request)

    @app.errorhandler(LinotpError)
    def linotp_error_handler(e):
        """
        Pass LinotpError exceptions to sendError

        If Flask receives an exception which is derived from LinotpError,
        this handler will be called so that an error response can be
        returned to the user.
        """
        return sendError(None, e)

    @babel.localeselector
    def get_locale():
        """Figure out the locale for this request. We look at the
        request's `Accept-Language` header and pick the first language
        in the list that matches one of the languages that we actually
        support.
        """
        return request.accept_languages.best_match(app.available_languages,
                                                   "en")

    # Enable profiling if desired. The options are debatable and could be
    # made more configurable. OTOH, we could all have a pony.
    profiling = False
    if app.config['PROFILE']:
        try:  # Werkzeug >= 1.0.0
            from werkzeug.middleware.profiler import ProfilerMiddleware
            profiling = True
        except ImportError:
            try:  # Werkzeug < 1.0.0
                from werkzeug.contrib.profiler import ProfilerMiddleware
                profiling = True
            except ImportError:
                log.error("PROFILE is enabled but ProfilerMiddleware could "
                          "not be imported. No profiling for you!")
        if profiling:
            app.wsgi_app = ProfilerMiddleware(app.wsgi_app,
                                              profile_dir='profile',
                                              restrictions=[30],
                                              sort_by=['cumulative'])
            log.info("PROFILE is enabled (do not use this in production!)")

    return app
コード例 #9
0
ファイル: app.py プロジェクト: smartree/LinOTP
def create_app(config_name='default', config_extra=None):
    """
    Generate a new instance of the Flask app

    This generates and configures the main application instance. Testing
    environments can use `config_extra` to provide extra configuration values
    such as a temporary database URL.

    @param config_name The name of the configuration to load from settings.py
    @param config_extra An optional dict of configuration override values
    """
    app = LinOTPApp()

    _configure_app(app, config_name, config_extra)

    # Enable custom template directory for Mako. We can get away with this
    # because Mako's `TemplateLookup` object is only created when the first
    # template is rendered. Note that “`app.template_folder` as a tuple” is
    # a Flask-Mako thing and won't work with Jinja2; if we ever decide we
    # want to move over, we will need to come up with something else.

    if app.config["CUSTOM_TEMPLATES_DIR"] is not None:
        app.template_folder = (app.config["CUSTOM_TEMPLATES_DIR"],
                               app.template_folder)

    babel = Babel(app, configure_jinja=False, default_domain="linotp")

    # Determine which languages are available in the i18n directory.
    # Note that we always have English even without a translation file.

    app.available_languages = list(
        {'en'} | {t.language
                  for t in babel.list_translations()})

    mako.init_app(app)
    init_logging(app)

    with app.app_context():
        setup_cache(app)
        setup_db(app)
        set_config()  # ensure `request_context` exists
        initGlobalObject()
        generate_secret_key_file(app)
        reload_token_classes()
        app.check_license()
        app.load_providers()

    @app.before_request
    def setup_env():
        # The following functions are called here because they're
        # stuffing bits into `flask.g`, which is a per-request global
        # object. Much of what is stuffed into `flask.g` is actually
        # application-wide stuff that has no business being stored in
        # `flask.g` in the first place, but lots of code expects to be
        # able to look at the "request context" and find stuff
        # there. Disentangling the application-wide stuff in the
        # request context from the request-scoped stuff is a major
        # project that will not be undertaken just now, and we're
        # probably doing more work here than we need to. Global
        # variables suck.

        set_config()
        initGlobalObject()
        setup_audit(app)
        setup_security_provider(app)

    app.add_url_rule('/healthcheck/status', 'healthcheck', healthcheck)

    # Add pre request handlers
    app.before_first_request(init_logging_config)
    app.before_request(app._run_setup)
    app.before_request(app.start_session)

    # Per controller setup and handlers
    app.setup_controllers()

    if 'selfservice' in app.enabled_controllers:

        @app.route('/')
        def index():
            return redirect('/selfservice')

        @app.route('/account/login')
        def login():
            return redirect('/selfservice/login')

        @app.route('/account/logout')
        def logout():
            return redirect('/selfservice/logout')

    _setup_token_template_path(app)

    # Post handlers
    app.teardown_request(app.finalise_request)

    @app.errorhandler(LinotpError)
    def linotp_error_handler(e):
        """
        Pass LinotpError exceptions to sendError

        If Flask receives an exception which is derived from LinotpError,
        this handler will be called so that an error response can be
        returned to the user.
        """
        return sendError(None, e)

    @babel.localeselector
    def get_locale():
        """Figure out the locale for this request. We look at the
        request's `Accept-Language` header and pick the first language
        in the list that matches one of the languages that we actually
        support.
        """
        return request.accept_languages.best_match(app.available_languages,
                                                   "en")

    # Command line handler
    app.cli.add_command(init_db_command)

    return app
コード例 #10
0
def init(babel: Babel) -> None:
    LANGUAGES.extend([str(locale) for locale in babel.list_translations()])
    babel.localeselector(get_locale)
コード例 #11
0
import requests
from babel import Locale
from flask import Flask, render_template, request, abort, Markup, g
from flask_babel import Babel, gettext, get_locale
from flask_wtf import FlaskForm, CSRFProtect
from wtforms import StringField, validators, FloatField

app = Flask(__name__, static_url_path="/geo/static")
app.config["SECRET_KEY"] = os.environ.get("SECRET_KEY")
app.config["NCZI_TOKEN"] = os.environ.get("NCZI_TOKEN")
app.config["SLACK_HOOK"] = os.environ.get("SLACK_HOOK", None)

csrf = CSRFProtect(app)

babel = Babel(app, default_locale="sk", default_timezone="Europe/Bratislava")
translations = babel.list_translations() + [Locale("sk")]
app.jinja_env.globals["get_locale"] = get_locale
app.jinja_env.globals["translations"] = translations
app.jinja_env.globals["accuracy_bound"] = 25
app.jinja_env.globals["accuracy_timeout"] = 5 * 60 * 1000
app.jinja_env.policies["ext.i18n.trimmed"] = True

if app.env == "production":
    print("!! PROD PROD PROD PROD PROD PROD PROD PROD PROD PROD PROD PROD !!")


@babel.localeselector
def localeselector():
    if hasattr(g, "lang"):
        return g.lang
    return None
コード例 #12
0
from flask import Flask, request, Response, g, has_request_context
from flask_babel import Babel, gettext, lazy_gettext

app = Flask(__name__)
babel = Babel(app, default_locale='en_ZA')
print(list(babel.translation_directories))
print(babel.list_translations())


# @babel.localeselector
# def get_locale():
#     # return request.accept_languages.best_match(app.config['LANGUAGES'])
#     raise Exception('yolo')
#     return 'en_za'


@babel.timezoneselector
def get_timezone():
    user = getattr(g, 'user', None)
    if user is not None:
        return user.timezone


@app.route('/')
def index():
    print(has_request_context())
    return Response(lazy_gettext('Your pos is now live!'))
コード例 #13
0
             "BASIC_AUTH_USERNAME": str,
             "BASIC_AUTH_PASSWORD": str,
             "SECRET_KEY": str,
             "DEBUG": (bool, False),
             "SMTP_SERVER": str,
             "SMTP_USER": str,
             "SMTP_PASS": str,
         })

babel = Babel()

app.jinja_env.add_extension('pyjade.ext.jinja.PyJadeExtension')
app.jinja_env.globals['_'] = _
babel.init_app(app)

all_locales = babel.list_translations() + [Locale('en', 'US')]


# setup smtp
def make_smtp():
    smtp = smtplib.SMTP(app.config['SMTP_SERVER'])
    status, msg = smtp.login(user=app.config['SMTP_USER'],
                             password=app.config['SMTP_PASS'])
    if status != 235:
        raise Exception("Fail to login: {msg}".format(msg=msg))
    return smtp


def send_mail(to):
    today = datetime.date.today()
    with open("mail_template.txt") as template:
コード例 #14
0
def create_app(config_name=None, config_extra=None):
    """
    Generate a new instance of the Flask app

    This generates and configures the main application instance. Testing
    environments can use `config_extra` to provide extra configuration values
    such as a temporary database URL.

    @param config_name The name of the configuration to load from settings.py
    @param config_extra An optional dict of configuration override values
    """
    app = LinOTPApp()

    # We need to do this here because the Flask CLI machinery doesn't seem
    # to pass the correct value.

    if config_name is None:
        config_name = get_env()

    _configure_app(app, config_name, config_extra)

    babel = Babel(app, configure_jinja=False, default_domain="linotp")

    # Determine which languages are available in the i18n directory.
    # Note that we always have English even without a translation file.

    app.available_languages = list(
        {"en"} | {t.language for t in babel.list_translations()}
    )

    setup_mako(app)
    init_logging(app)

    with app.app_context():
        setup_cache(app)
        setup_db(app)

        init_linotp_config(app)
        set_config()  # ensure `request_context` exists

        init_security_provider()

        app.setup_audit()

        reload_token_classes()
        app.check_license()

    app.add_url_rule("/healthcheck/status", "healthcheck", healthcheck)

    # Add pre request handlers
    app.before_first_request(init_logging_config)
    app.before_first_request(app.init_jwt_config)
    app.before_request(app.setup_env)
    app.before_request(app._run_setup)
    app.before_request(app.start_session)

    # Per controller setup and handlers
    app.setup_controllers()

    @app.route("/")
    def index():
        site_root_redirect = config["SITE_ROOT_REDIRECT"]
        if site_root_redirect:
            return redirect(site_root_redirect)

        if "selfservice" in app.enabled_controllers:
            return redirect(url_for("selfservice.index"))

        return abort(404)

    # Post handlers
    app.teardown_request(app.finalise_request)

    @app.errorhandler(LinotpError)
    def linotp_error_handler(e):
        """
        Pass LinotpError exceptions to sendError

        If Flask receives an exception which is derived from LinotpError,
        this handler will be called so that an error response can be
        returned to the user.
        """
        return sendError(None, e)

    @babel.localeselector
    def get_locale():
        """Figure out the locale for this request. We look at the
        request's `Accept-Language` header and pick the first language
        in the list that matches one of the languages that we actually
        support.
        """
        try:
            return request.accept_languages.best_match(
                app.available_languages, "en"
            )
        except RuntimeError as exx:
            # Working outside of request context.
            return babel.default_locale

    # Enable profiling if desired. The options are debatable and could be
    # made more configurable. OTOH, we could all have a pony.
    profiling = False
    if app.config["PROFILE"]:
        try:  # Werkzeug >= 1.0.0
            from werkzeug.middleware.profiler import ProfilerMiddleware

            profiling = True
        except ImportError:
            try:  # Werkzeug < 1.0.0
                from werkzeug.contrib.profiler import ProfilerMiddleware

                profiling = True
            except ImportError:
                log.error(
                    "PROFILE is enabled but ProfilerMiddleware could "
                    "not be imported. No profiling for you!"
                )
        if profiling:
            app.wsgi_app = ProfilerMiddleware(
                app.wsgi_app,
                profile_dir="profile",
                restrictions=[30],
                sort_by=["cumulative"],
            )
            log.info("PROFILE is enabled (do not use this in production!)")

    return app
コード例 #15
0
ファイル: app.py プロジェクト: tuna/registr
Settings(app, rules={
    "BABEL_DEFAULT_LOCALE": (str, "en_US"),
    "SQLALCHEMY_DATABASE_URI": str,
    "BASIC_AUTH_USERNAME": str,
    "BASIC_AUTH_PASSWORD": str,
    "SECRET_KEY": str,
    "DEBUG": (bool, False),
})

babel = Babel()

app.jinja_env.add_extension('pyjade.ext.jinja.PyJadeExtension')
app.jinja_env.globals['_'] = _
babel.init_app(app)

all_locales = babel.list_translations() + [Locale('en', 'US')]


@babel.localeselector
def get_locale():
    # Try to retrieve locale from query strings.
    locale = request.args.get('locale', None)
    if locale is not None:
        session["locale"] = locale
        return locale

    locale = session.get('locale', None)
    if locale is not None:
        return locale

    locale = request.accept_languages.best_match(
コード例 #16
0
class HTTPServer:
    def __init__(self, config):
        self.config = config['rest_api']
        self.app = Flask('wazo_phoned')
        self._configure_babel(config['enabled_plugins'])
        http_helpers.add_logger(self.app, logger)
        self.app.before_request(http_helpers.log_before_request)
        self.app.after_request(http_helpers.log_request)
        self.app.secret_key = os.urandom(24)
        self.app.permanent_session_lifetime = timedelta(minutes=5)
        self.load_cors()

    def load_cors(self):
        cors_config = dict(self.config.get('cors', {}))
        enabled = cors_config.pop('enabled', False)
        if enabled:
            CORS(self.app, **cors_config)

    def _configure_babel(self, enabled_plugins):
        self.babel = Babel(self.app)
        self.app.config['BABEL_DEFAULT_LOCALE'] = BABEL_DEFAULT_LOCALE
        self.app.config['BABEL_TRANSLATION_DIRECTORIES'] = ';'.join(
            self._get_translation_directories(enabled_plugins))

        @self.babel.localeselector
        def get_locale():
            translations = set(
                [str(locale) for locale in self.babel.list_translations()])
            translations.add(BABEL_DEFAULT_LOCALE)
            logger.debug('Available translations: %s', translations)
            logger.debug('accept_languages: %s', request.accept_languages)
            preferred = [
                locale.replace('-', '_')
                for locale in request.accept_languages.values()
            ]
            best_match = negotiate_locale(preferred, translations)
            logger.debug('Best locale match: %s', best_match)
            return best_match

    def _get_translation_directories(self, enabled_plugins):
        main_translation_directory = 'translations'
        result = [main_translation_directory]
        entry_points = (e
                        for e in iter_entry_points(group='wazo_phoned.plugins')
                        if e.name in enabled_plugins)
        for ep in entry_points:
            if resource_isdir(ep.module_name, TRANSLATION_DIRECTORY):
                result.append(
                    resource_filename(ep.module_name, TRANSLATION_DIRECTORY))
        return result

    def run(self):
        http_config = self.config['http']
        https_config = self.config['https']

        wsgi_app = wsgi.WSGIPathInfoDispatcher({'/': self.app})
        cherrypy.server.unsubscribe()
        cherrypy.config.update({'environment': 'production'})

        if https_config['enabled']:
            try:
                bind_addr_https = (https_config['listen'],
                                   https_config['port'])
                server_https = wsgi.WSGIServer(bind_addr=bind_addr_https,
                                               wsgi_app=wsgi_app)
                server_https.ssl_adapter = http_helpers.ssl_adapter(
                    https_config['certificate'], https_config['private_key'])

                ServerAdapter(cherrypy.engine, server_https).subscribe()
                logger.debug(
                    'WSGIServer starting... uid: %s, listen: %s:%s',
                    os.getuid(),
                    bind_addr_https[0],
                    bind_addr_https[1],
                )
            except IOError as e:
                logger.warning("HTTPS server won't start: %s", e)
        else:
            logger.debug('HTTPS server is disabled')

        if http_config['enabled']:
            bind_addr_http = (http_config['listen'], http_config['port'])
            server_http = wsgi.WSGIServer(bind_addr=bind_addr_http,
                                          wsgi_app=wsgi_app)
            ServerAdapter(cherrypy.engine, server_http).subscribe()
            logger.debug(
                'WSGIServer starting... uid: %s, listen: %s:%s',
                os.getuid(),
                bind_addr_http[0],
                bind_addr_http[1],
            )
        else:
            logger.debug('HTTP server is disabled')

        if not http_config['enabled'] and not https_config['enabled']:
            logger.critical('No HTTP/HTTPS server enabled')
            exit()

        list_routes(self.app)

        try:
            cherrypy.engine.start()
            cherrypy.engine.wait(states.EXITING)
        except KeyboardInterrupt:
            logger.warning('Stopping wazo-phoned: KeyboardInterrupt')
            cherrypy.engine.exit()

    def stop(self):
        cherrypy.engine.exit()

    def join(self):
        if cherrypy.engine.state == states.EXITING:
            cherrypy.engine.block()