コード例 #1
0
    def test_redirect_view(self):
        app = Flask(__name__)
        app.config['SECRET_KEY'] = 'foo'
        paranoid = Paranoid(app)
        paranoid.redirect_view = 'custom_redirect'

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

        @app.route('/redirect')
        def custom_redirect():
            return 'foo'

        client = app.test_client(use_cookies=True)

        self.assertEqual(paranoid.redirect_view, 'custom_redirect')

        rv = client.get('/', headers={'User-Agent': 'foo'})
        self.assertEqual(rv.status_code, 200)

        rv = client.get('/', headers={'User-Agent': 'bar'})
        self.assertEqual(rv.status_code, 302)
        self.assertTrue(rv.headers['Location'].endswith('/redirect'))
        self.assertIn(self._delete_cookie('session'),
                      rv.headers.getlist('Set-Cookie'))
        self.assertNotIn(self._delete_cookie('remember_token'),
                         rv.headers.getlist('Set-Cookie'))
コード例 #2
0
def init_app(app):
    """
    Application extensions initialization.
    """
    extensions = (
        logging,
        cross_origin_resource_sharing,
        db,
        login_manager,
        marshmallow,
        api,
        oauth2,
        mail,
        edm,
    )
    for extension in extensions:
        extension.init_app(app)

    # minify(app=app)

    paranoid = Paranoid(app)
    paranoid.redirect_view = '/'

    # Initialize Stripe payment
    stripe.api_key = app.config.get('STRIPE_SECRET_KEY')
コード例 #3
0
    def test_flask_login(self):
        app = Flask(__name__)
        app.config['SECRET_KEY'] = 'foo'
        paranoid = Paranoid(app)
        paranoid.redirect_view = 'https://foo.com/foobarbaz'

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

        client = app.test_client(use_cookies=True)
        sys.modules['flask_login'] = '******'

        self.assertEqual(paranoid.redirect_view, 'https://foo.com/foobarbaz')

        rv = client.get('/', headers={'User-Agent': 'foo'})
        self.assertEqual(rv.status_code, 200)

        rv = client.get('/', headers={'User-Agent': 'bar'})
        del sys.modules['flask_login']
        self.assertEqual(rv.status_code, 302)
        self.assertEqual(rv.headers['Location'], 'https://foo.com/foobarbaz')
        self.assertIn(self._delete_cookie('session'),
                      rv.headers.getlist('Set-Cookie'))
        self.assertIn(self._delete_cookie('remember_token', httponly=False),
                      rv.headers.getlist('Set-Cookie'))
コード例 #4
0
def init_app(app):
    """
    Application extensions initialization.
    """
    global _CONFIG_PATH_CHOICES
    _CONFIG_PATH_CHOICES = sorted(app.config.keys())

    extensions = (
        # The extensions in this block need to remain in this order for proper setup
        logging,
        sentry,
        db,
        api,
        config,
        # The remaining extensions
        oauth2,
        cross_origin_resource_sharing,
        login_manager,
        marshmallow,
        edm,
        submission,
        tus,
        mail,
        stripe,
    )
    for extension in extensions:
        extension.init_app(app)

    # minify(app=app)

    paranoid = Paranoid(app)
    paranoid.redirect_view = '/'
コード例 #5
0
    def test_callback(self):
        app = Flask(__name__)
        app.config['SECRET_KEY'] = 'foo'
        paranoid = Paranoid()
        paranoid.init_app(app)
        paranoid.redirect_view = 'custom_redirect'

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

        @paranoid.on_invalid_session
        def custom_callback():
            return 'foo'

        client = app.test_client(use_cookies=True)

        self.assertEqual(paranoid.redirect_view, custom_callback)

        rv = client.get('/', headers={'User-Agent': 'foo'})
        self.assertEqual(rv.status_code, 200)

        rv = client.get('/', headers={'User-Agent': 'bar'})
        self.assertEqual(rv.status_code, 200)
        self.assertEqual(rv.get_data(as_text=True), 'foo')
        self.assertIn(self._delete_cookie('session'),
                      rv.headers.getlist('Set-Cookie'))
        self.assertNotIn(self._delete_cookie('remember_token'),
                         rv.headers.getlist('Set-Cookie'))
コード例 #6
0
    def test_401(self):
        app = Flask(__name__)
        app.config['SECRET_KEY'] = 'foo'
        Paranoid(app)

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

        client = app.test_client(use_cookies=True)

        rv = client.get('/', headers={'User-Agent': 'foo'})
        self.assertEqual(rv.status_code, 200)

        rv = client.get('/', headers={'User-Agent': 'foo'})
        self.assertEqual(rv.status_code, 200)

        rv = client.get('/', headers={'User-Agent': 'bar'})
        self.assertEqual(rv.status_code, 401)
        self.assertIn(self._delete_cookie('session'),
                      rv.headers.getlist('Set-Cookie'))
        self.assertNotIn(self._delete_cookie('remember_token'),
                         rv.headers.getlist('Set-Cookie'))
コード例 #7
0
    app.register_blueprint(userAPI.users_blueprint)
    Models.database.create_all()
    # a = Models.Admin.query.get(1)
    # try:
    #     x = Models.Admin('Henry123','password123',96279135,'superuser')
    #     Models.database.session.add(x)
    #     Models.database.session.commit()
    # except:
    #     Models.database.session.rollback()
    # print(Models.roles.query.filter_by(type='admin').first())
    # s = Models.Admin.query.filter_by(username='******').first()
    # print(a.adminid)

csrf = CSRFProtect(app)
#session protection
paranoid = Paranoid(app)
paranoid.redirect_view = 'localhost:5000/register'
db = mysql_connect.read_config_file()


# session expiry, still need error emssage
@app.before_request
def before_request():
    # print(psutil.net_io_counters())
    session.permanent = True
    app.permanent_session_lifetime = datetime.timedelta(minutes=1)
    # session.modified = True
    g.user = current_user


# @app.errorhandler(403)
コード例 #8
0
ファイル: __init__.py プロジェクト: thaJeztah/pgadmin4
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
コード例 #9
0
    # try:
    #     x = AdminModels.Admin('testUser', 'password123', 96279135)
    #     AdminModels.database.session.add(x)
    #     AdminModels.database.session.commit()
    # except:
    #     AdminModels.database.session.rollback()

# csp = {
#         'default-src': ['\'self\'','https://fonts.googleapis.com/css'],
#         'img-src': '\'self\' data:',
#         'style-src': '\'unsafe-inline\' \'self\'',
#         'script-src': '\'self\' \'unsafe-inline\''
#
# }
# talisman = Talisman(app)
paranoid = Paranoid(app)
paranoid.redirect_view = 'https://google.com'


@app.before_request
def before_request():
    if current_user.is_authenticated:
        last_login = session['last_login']
        time = datetime.datetime.now() - last_login
        print(time.seconds)
        if time.seconds > 900:  # 30minutes
            logout_user()
            session.clear()
            resp = make_response(redirect(url_for('login')))
            if resp.headers['Location'] == '/':
                return resp
コード例 #10
0
def create_app():
    app = Flask(__name__)
    app.config['SECRET_KEY'] = 'top-secret!'
    csrf.init_app(app)
    login_manager = LoginManager(app)

    @login_manager.user_loader
    def load_user(id):
        return User(id)

    login_manager.session_protection = 'strong'
    paranoid = Paranoid(app)
    paranoid.redirect_view = '/login'

    @paranoid.on_invalid_session
    def invalid_session():
        return 'Please login', 401

    # http://localhost:5000/login - this will be the login page, we need to use both GET and POST requests
    @app.route('/login', methods=['GET', 'POST'])
    def login():
        # Output message if something goes wrong...
        msg = ''
        # Check if 'username' and 'password' POST requests exist (user submitted form)
        if request.method == 'POST' and 'username' in request.form and 'password' in request.form and 'two_factor_auth' in request.form:
            # Create variables for easy access
            username = request.form['username']
            password = request.form['password']
            hashedPassword = hashlib.md5(password.encode('utf-8')).hexdigest()
            two_factor_auth = request.form['two_factor_auth']

            # Check if account exists using dict
            account = {}
            if username in accounts and accounts[username][
                    'password'] == hashedPassword:
                if accounts[username]['two_factor_auth'] == two_factor_auth:
                    # Fetch one record from dict and return result
                    account['username'] = username
                    account['password'] = hashedPassword
                    account['two_factor_auth'] = two_factor_auth
                    # Account exists in accounts dict in out database
                    # Create session data, we can access this data in other routes
                    session['logged_in'] = True
                    login_user(User(username))
                    msg = 'Success!'
                else:
                    msg = 'Failure: Incorrect two-factor authentication'
            else:
                # Account doesnt exist or username/password incorrect
                msg = 'Failure: Incorrect username or password'
        return render_template('index.html', msg=msg)

    # http://localhost:5000/register - this will be the registration page, we need to use both GET and POST requests
    @app.route('/register', methods=['GET', 'POST'])
    def register():
        # Output message if something goes wrong...
        msg = ''
        # Check if 'username' and 'password' POST requests exist (user submitted form)
        if request.method == 'POST' and 'username' in request.form and 'password' in request.form and 'two_factor_auth' in request.form:
            # Create variables for easy access
            username = request.form['username']
            password = request.form['password']
            hashedPassword = hashlib.md5(password.encode('utf-8')).hexdigest()
            two_factor_auth = request.form['two_factor_auth']

            # Check if account exists using dict
            account = {}
            if username in accounts:
                if accounts[username][
                        'password'] == hashedPassword and accounts[username][
                            'two_factor_auth'] == two_factor_auth:
                    # Fetch one record from dict and return result
                    account['username'] = username
                    account['password'] = hashedPassword
                    account['two_factor_auth'] = two_factor_auth

            # If account exists in accounts dict in out database
            if bool(account):
                msg = 'Failure: Account already exists!'
            elif not re.match(r'[A-Za-z0-9]+', username):
                msg = 'Failure: Username must contain only characters and numbers!'
            elif not re.match(r'[0-9]+', two_factor_auth):
                msg = 'Failure: Enter phone number for 2fa'
            elif not username or not password:
                msg = 'Failure: Please fill out the form!'
            else:
                # Account doesn't exists and the form data is valid, now insert new account into dict
                # Hash password
                hashedPassword = hashlib.md5(
                    password.encode('utf-8')).hexdigest()
                accounts[username] = {
                    'password': hashedPassword,
                    'two_factor_auth': two_factor_auth
                }
                msg = 'Success!'
        elif request.method == 'POST':
            # Form is empty... (no POST data)
            msg = 'Failure: Please fill out the form!'
        # Show registration form with message (if any)
        return render_template('register.html', msg=msg)

    # http://localhost:5000/spell_check - this will be the home page, only accessible for loggedin users
    @app.route('/spell_check', methods=['GET', 'POST'])
    def spell_check():
        msg = ''
        inputtext = ''
        # Check if user is loggedin
        if 'logged_in' in session:
            if request.method == 'POST' and 'inputtext' in request.form:
                inputtext = request.form['inputtext']
                # Put inputtext into file
                f = open('input.txt', 'w')
                f.write(inputtext)
                f.close()
                output = subprocess.getoutput(
                    './spell_check input.txt wordlist.txt')
                msg = ', '.join(output.split())
            # User is loggedin show them the home page
            return render_template('spell_check.html',
                                   msg=msg,
                                   output=inputtext)
        # User is not loggedin redirect to login page
        return redirect(url_for('login'))

    return app
コード例 #11
0
        return anonymous_token


# Initiate LoginManager object
login_manager = LoginManager(application)
login_manager.anonymous_user = AnonymousUser
login_manager.session_protection = 'strong'

# Import and register blueprint modules
# (prevent circular imports)
for module_name, url_prefix in BLUEPRINTS_NAME_WITH_URL_PREFIX:
    module = importlib.import_module('blueprints.%s' % module_name)
    application.register_blueprint(module.blueprint, url_prefix=url_prefix)

# Initiate Paranoid object
paranoid = Paranoid(application)
paranoid.redirect_view = BLUEPRINTS_ROOT_HANDLER

# Import UserStore from models
from models import UserStore


@login_manager.user_loader
def load_user(user_id):
    """
	Return SignedInUser object linked to User entity by uid.
	"""
    return SignedInUser(UserStore.read(user_id))


# Initiate SocketIO object
コード例 #12
0
    app.config.from_object(ProductionConfig)
else:
    print("Unkown configuration name")
    raise
db = SQLAlchemy(app)
migrate = Migrate(app, db)
login = LoginManager(app)
login.login_view = "auth.login"
admin_app = Admin(
    app,
    name="Flask quickstart",
    template_mode="bootstrap3",
    base_template="admin/my_base.html",
)
mail = Mail(app)
paranoid = Paranoid(app)
paranoid.redirect_view = "main.index"

# blog related
pagedown = PageDown(app)
markdown = Markdown(app)

# upload related
images = UploadSet("images", IMAGES)
documents = UploadSet("documents", DOCUMENTS)
configure_uploads(app, (images, documents))
patch_request_class(app, 16 * 1024 * 1024)

from app.auth import auth_blueprint

app.register_blueprint(auth_blueprint, url_prefix="/auth")
コード例 #13
0
def create_app(test_config=None):
    app = Flask(__name__, static_folder='static')

    if test_config is None:
        # load the instance config, if it exists, when not testing
        app.config.from_pyfile('sql/md.cfg', silent=False)
    else:
        # load the test config if passed in
        app.config.from_mapping(test_config)
    # Initiate database connection pool
    params = configuration.mdconfig()
    pool_params = configuration.mdconfig(section='psycopg2')
    app.config['POSTGRESQL_POOL'] = pool.ThreadedConnectionPool(
        pool_params['min_pool_conn'],
        pool_params['max_pool_conn'],
        user=params['user'],
        password=params['password'],
        host=params['host'],
        port=params['port'],
        database=params['database'])
    mail.init_app(app)
    csrf.init_app(app)
    paranoid = Paranoid(app)
    paranoid.redirect_view = 'md.index'
    # cors
    # for swaggerUI
    # https://idratherbewriting.com/learnapidoc/pubapis_swagger.html
    CORS(app, resources={r"/api/*": {"origins": "*"}})
    # errors
    app.register_error_handler(403, forbidden_error)
    app.register_error_handler(404, not_found_error)
    app.register_error_handler(500, internal_error)
    app.register_error_handler(405, not_allowed_error)
    app.register_error_handler(413, reques_entity_too_large_error)
    # define custom jinja filters
    app.jinja_env.filters['match'] = configuration.match
    app.jinja_env.filters['match_multiline'] = configuration.match_multiline
    # ensure the instance folder exists
    try:
        os.makedirs(app.instance_path)
    except OSError:
        pass
    from . import db
    db.init_app(app)
    from . import auth
    app.register_blueprint(auth.bp)
    from . import md
    app.register_blueprint(md.bp)
    from . import ajax
    app.register_blueprint(ajax.bp)
    from . import api
    csrf.exempt(api.bp)
    app.register_blueprint(api.bp)
    from . import static_route
    app.register_blueprint(static_route.bp)
    from . import upload
    app.register_blueprint(upload.bp)
    # from . import error
    # app.register_blueprint(error.bp)
    app.add_url_rule('/', endpoint='index')
    if app.debug:
        print(app.config)
    return app
コード例 #14
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)

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

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

    return app
コード例 #15
0
ファイル: __init__.py プロジェクト: sjq-sohjunqi/Speech2Text
from flask import Flask
from config import Config
from flask_sqlalchemy import SQLAlchemy
from flask_bcrypt import Bcrypt
from flask_paranoid import Paranoid
import pymysql
from werkzeug.utils import secure_filename
from flask_mail import Mail, Message

pymysql.install_as_MySQLdb()

S2T = Flask(__name__)
S2T.debug = True
paranoid = Paranoid(S2T)
paranoid.redirect_view = '/'
S2T.config.from_object(Config)
db = SQLAlchemy(S2T)
bcrypt = Bcrypt(S2T)

'''Change when in production'''
#S2T.config['SERVER_NAME'] = '127.0.0.1:5000'
S2T.config['SERVER_NAME'] = 'sohjunqi.pythonanywhere.com'

'''Temp folder for conversions'''
S2T.config['TEMP_FOLDER'] = 'tran_temp'

'''Storage folder'''
S2T.config['STORAGE_FOLDER'] = 'transcripts'

''''Profile pictures folder'''
S2T.config['PROFILE_FOLDER'] = 'profiles'
コード例 #16
0
from flask_login import LoginManager
from flask_paranoid import Paranoid
from typing import Callable

from TexDBook.src.python.core.init_app import app, default_init_app
from TexDBook.src.python.util.flask.flask_utils_types import JsonOrMessage
from TexDBook.src.python.util.flask.rest_api import json, rest_api
from TexDBook.src.python.util.oop import override
from TexDBook.src.python.util.password import sha256

init_app = default_init_app

login_manager = LoginManager()  # type: LoginManager
login_manager.init_app(app)

paranoid = Paranoid()  # type: Paranoid
paranoid.init_app(app)

# @override(Paranoid)
# def write_token_to_session(_super, self, token):
#     print("writing token: " + token)
#     print(paranoid.create_token())
#     print(paranoid.get_token_from_session())
#     print(request.headers.get("User-Agent"))
#     print(request.headers.get("X-Forwarded-For"))
#     print(request.remote_addr)
#     return _super(self, token)


@override(Paranoid)
def create_token(_super, self):
コード例 #17
0
from waitress import serve

# Local modules
from app import _create_app
from app.db.firebase import CrudDB, Authentication

# Utilities
from werkzeug.exceptions import HTTPException  # Handler errors web
import requests
import uuid
import random
import pdb

# Creation of the application IMPORTANT
app = _create_app()
paranoid = Paranoid(app)  # Session hash


@app.route('/', methods=['GET', 'POST'])
@paranoid.on_invalid_session
def index():
    """
    Funtion manager to show the
    home of the app
    """

    if not session.get('user_session'):
        flash('Please log in first!')

        return redirect(url_for('login'))
コード例 #18
0
ファイル: __init__.py プロジェクト: e2jk/syncboom
def create_app(config_class=Config):
    app = Flask(__name__)
    app.config.from_object(config_class)

    db.init_app(app)
    migrate.init_app(app, db)
    login.init_app(app)
    mail.init_app(app)
    bootstrap.init_app(app)
    moment.init_app(app)
    babel.init_app(app)
    cache.init_app(app)
    app.redis = Redis.from_url(app.config['REDIS_URL'])
    app.task_queue = rq.Queue('syncboom-tasks', connection=app.redis)
    paranoid = Paranoid(app)
    paranoid.redirect_view = '/'

    app.before_request(app_before_request)

    from app.errors import bp as errors_bp
    app.register_blueprint(errors_bp)

    from app.auth import bp as auth_bp
    app.register_blueprint(auth_bp, url_prefix='/auth')

    from app.main import bp as main_bp
    app.register_blueprint(main_bp)

    from app.mapping import bp as mapping_bp
    app.register_blueprint(mapping_bp, url_prefix='/mapping')

    if not app.debug and not app.testing:
        if app.config['MAIL_SERVER']:
            auth = None
            if app.config['MAIL_USERNAME'] or app.config['MAIL_PASSWORD']:
                auth = (app.config['MAIL_USERNAME'],
                        app.config['MAIL_PASSWORD'])
            secure = None
            if app.config['MAIL_USE_TLS']:
                secure = ()
            mail_handler = SMTPHandler(
                mailhost=(app.config['MAIL_SERVER'], app.config['MAIL_PORT']),
                fromaddr='no-reply@' + app.config['MAIL_SERVER'],
                toaddrs=app.config['ADMINS'],
                subject='[SyncBoom] Failure',
                credentials=auth,
                secure=secure)
            mail_handler.setLevel(logging.ERROR)
            app.logger.addHandler(mail_handler)

        if app.config['LOG_TO_STDOUT']:
            stream_handler = logging.StreamHandler()
            stream_handler.setLevel(logging.INFO)
            app.logger.addHandler(stream_handler)
        else:
            if not os.path.exists('logs'):
                os.mkdir('logs')
            file_handler = RotatingFileHandler('logs/syncboom.log',
                                               maxBytes=10240,
                                               backupCount=10)
            file_handler.setFormatter(
                logging.Formatter('%(asctime)s %(levelname)s: %(message)s '
                                  '[in %(pathname)s:%(lineno)d]'))
            file_handler.setLevel(logging.INFO)
            app.logger.addHandler(file_handler)

        app.logger.setLevel(logging.INFO)

    # Serve local Bootstrap files when in debug mode
    app.config["BOOTSTRAP_SERVE_LOCAL"] = app.debug

    @app.after_request
    def set_secure_headers(response):
        secure_headers.flask(response)
        return response

    return app
コード例 #19
0
ファイル: __init__.py プロジェクト: codacy-badger/bee_api
import os

from flask_cors import CORS
from flask_restful import Api
from flask import Flask
from flask_security import (Security, SQLAlchemyUserDatastore)
from flask_paranoid import Paranoid

app = Flask(__name__)
CORS(app)
paranoid = Paranoid(app)
paranoid.redirect_view = '/'

app_settings = os.getenv('APP_SETTINGS', 'config.DevelopmentConfig')

travis = os.getenv('TRAVIS', None)
if travis:
    app_settings = 'config-sample.TestingConfig'

app.config.from_object(app_settings)

from database import (db)
from classes.user.model import (User, Role)
from classes.user.forms import (UserRegisterForm, UserLoginForm)
#from classes.upload.hive_data import (HiveData)

api = Api(app)

#hive_data = HiveData(influxDB)

if not app.debug and not app.testing and not app.config['SSL_DISABLE']:
コード例 #20
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
    ##########################################################################

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

    # 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:
        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_out.connect_via(app)
    def clear_current_user_connections(app, user):
        from config import PG_DEFAULT_DRIVER
        from pgadmin.utils.driver import get_driver
        _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)

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

    ##########################################################################
    # 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
    ##########################################################################
    # 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
コード例 #21
0
ファイル: __init__.py プロジェクト: jcastib/MobiDetails
def create_app(test_config=None):
    app = Flask(__name__, static_folder='static')

    if test_config is None:
        # load the instance config, if it exists, when not testing
        app.config.from_pyfile('sql/md.cfg', silent=False)
        # app.config.from_object('config.Config')
        # app.config.update(
        #     SECRET_KEY = os.urandom(24),
        #     SESSION_COOKIE_SECURE = False,
        #     WTF_CSRF_TIME_LIMIT = None
        # )
    else:
        # load the test config if passed in
        app.config.from_mapping(test_config)
    # # config flaskmail
    # params = config.mdconfig(section='email_auth')
    # flask_params = config.mdconfig(section='flask')
    # app.config.update(
    #     # FLASK SETTINGS
    #     DEBUG = flask_params['debug'],

    #     # EMAIL SETTINGS
    #     MAIL_SERVER = params['mail_server'],
    #     MAIL_PORT = params['mail_port'],
    #     MAIL_USE_TLS = params['mail_use_tls'],
    #     MAIL_USERNAME = params['mail_username'],
    #     MAIL_PASSWORD = params['mail_password'],
    #     MAIL_DEFAULT_SENDER = params['mail_default_sender'],
    #     # CSRF tokens config
    #     WTF_CSRF_TIME_LIMIT = None
    # )
    mail.init_app(app)
    csrf.init_app(app)
    paranoid = Paranoid(app)
    paranoid.redirect_view = '/MD/auth/login'
    # cors
    # for swaggerUI
    # https://idratherbewriting.com/learnapidoc/pubapis_swagger.html
    CORS(app, resources={r"/api/*": {"origins": "*"}})
    # errors
    app.register_error_handler(403, forbidden_error)
    app.register_error_handler(404, not_found_error)
    app.register_error_handler(500, internal_error)
    app.register_error_handler(405, not_allowed_error)
    app.register_error_handler(413, reques_entity_too_large_error)
    # define custom jinja filters
    app.jinja_env.filters['match'] = config.match
    # if test_config is None:
    #     # load the instance config, if it exists, when not testing
    #     app.config.from_pyfile('config.py', silent=True)
    # else:
    #     # load the test config if passed in
    #     app.config.from_mapping(test_config)
    # ensure the instance folder exists
    try:
        os.makedirs(app.instance_path)
    except OSError:
        pass
    from . import db
    db.init_app(app)
    from . import auth
    app.register_blueprint(auth.bp)
    from . import md
    app.register_blueprint(md.bp)
    from . import ajax
    app.register_blueprint(ajax.bp)
    from . import api
    csrf.exempt(api.bp)
    app.register_blueprint(api.bp)
    from . import static_route
    app.register_blueprint(static_route.bp)
    from . import upload
    app.register_blueprint(upload.bp)
    # from . import error
    # app.register_blueprint(error.bp)
    app.add_url_rule('/', endpoint='index')
    # a simple page that says hello
    # @app.route('/factory_test')
    # def hello():
    #     return 'Flask factory ok!'
    # if not app.debug:
    #     # logging into a file
    #     # (from https://blog.miguelgrinberg.com/post/the-flask-mega-tutorial-part-vii-error-handling)
    #     if not os.path.exists('logs'):
    #         os.mkdir('logs')
    #     file_handler = RotatingFileHandler('logs/mobidetails.log', maxBytes=10240,
    #                                        backupCount=10)
    #     file_handler.setFormatter(logging.Formatter(
    #         '%(asctime)s %(levelname)s: %(message)s [in %(pathname)s:%(lineno)d]'))
    #     file_handler.setLevel(logging.INFO)
    #     app.logger.addHandler(file_handler)
    #     app.logger.setLevel(logging.INFO)
    #     app.logger.info('Mobidetails startup')
    if app.debug:
        print(app.config)
    return app
コード例 #22
0

# Initiate LoginManager object
login_manager = LoginManager(application)
login_manager.anonymous_user = AnonymousUser
login_manager.session_protection = 'strong'

# Import and register blueprint modules
# (prevent circular imports)
for module_name, url_prefix in [('root', '/'), ('poll', '/poll/'),
                                ('live', '/live/')]:
    module = importlib.import_module('blueprints.%s' % module_name)
    application.register_blueprint(module.blueprint, url_prefix=url_prefix)

# Initiate Paranoid object
paranoid = Paranoid(application)
paranoid.redirect_view = 'root.get_home'

# Initiate CSRF object
csrf = CSRFProtect(application)

# Import User and UserStore from models
from models.entity.user import User
from models.user_store import UserStore


@login_manager.user_loader
def load_user(user_id):
    """
	Return SignedInUser object linked to User entity by uid.
	"""
コード例 #23
0
from flask_login import LoginManager
from flask_mail import Mail
from flask_migrate import Migrate
from flask_paranoid import Paranoid
from flask_sqlalchemy import SQLAlchemy
from flask_talisman import Talisman
from flask_wtf.csrf import CSRFProtect
from sqlalchemy import event
from sqlalchemy.engine import Engine

database = SQLAlchemy()
migrate = Migrate()

csrf = CSRFProtect()
login = LoginManager()
paranoid = Paranoid()
talisman = Talisman()

bootstrap = Bootstrap()
mail = Mail()


@event.listens_for(Engine, "connect")
def set_sqlite_pragma(dbapi_connection, connection_record):
    cursor = dbapi_connection.cursor()
    cursor.execute("PRAGMA foreign_keys=ON")
    cursor.close()


def create_application(instance_path):
    if instance_path:
コード例 #24
0
# This enables app to be executed by command:
#   - export FLASK_APP=app.py
#   - flask run
app = Flask(__name__, template_folder="./templates")

# app.secret_key = "CS9163Assignment02WebsiteFlaskSessionSecretKey"
# app.WTF_CSRF_SECRET_KEY = "CS9163Assignment02WebsiteFlaskWTFCSRFToken"
app.secret_key = get_secret_key("flask_session_secret_key", "DefaultCS9163Assignment04SecretKey")
app.WTF_CSRF_SECRET_KEY = get_secret_key("flask_wtf_csrf_token", "DefaultCS9163Assignment04SecretKey")
# Random secret_key does work, but this will lose all existed sessions
# when current flask application restarts.
# app.secret_key = ''.join(random.choice(string.ascii_uppercase + string.digits) for _ in range(32))
# app.WTF_CSRF_SECRET_KEY = ''.join(random.choice(string.ascii_uppercase + string.digits) for _ in range(32))

app.config.update(
	SQLALCHEMY_DATABASE_URI='sqlite:///sqlite3/cs9163.sqlite3'
)

app.config.update(
	SESSION_COOKIE_HTTPONLY=True,
	SESSION_COOKIE_SAMESITE='Lax',
	PERMANENT_SESSION_LIFETIME=600
)
csrf = CSRFProtect(app)
paranoid = Paranoid(app)
configure_routes(app)
paranoid.redirect_view = ROOT_URL + '/login'

if __name__ == "__main__":
	app.run(debug=True)
コード例 #25
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
        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('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)
    ##########################################################################
    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:
                db_upgrade(app)
            else:
                if not os.path.exists(SQLITE_PATH):
                    raise FileNotFoundError('SQLite database file "' +
                                            SQLITE_PATH + '" does not exists.')
                raise RuntimeError('Specified SQLite 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:
                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)

    # 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'],
        }))

    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

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

    @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.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 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!
    ##########################################################################
    return app
コード例 #26
0
app.config['SESSION_COOKIE_HTTPONLY'] = True
app.config['REMEMBER_COOKIE_HTTPONLY'] = True

#===============================
# Security options and functions
#===============================
from flask_cors import CORS

cors = CORS(app,
            origins=['http://localhost:3000', 'http://localhost:3001'],
            headers=['Content-Type'],
            expose_headers=['Access-Control-Allow-Origin'],
            supports_credentials=True)

from flask_paranoid import Paranoid
Paranoid(app)

#===============================
# Database options and functions
#===============================
from .models.auth import User, UserRole, Role
from .models.blog import Post, Category
from .database import database


@app.before_request
def before_request():
    database.connect()
    database.create_tables([User, Role, UserRole, Category, Post], safe=True)