Ejemplo n.º 1
0
def init_app(app, user_datastore, LoginForm):
    def load_user(user_id):
        return user_datastore.get_user(user_id)

    def load_user_from_request(request):
        apikey = request.headers.environ.get("HTTP_X_API_KEY", None)
        if apikey:
            user = user_datastore.find_user(apikey=apikey)
            if not user:
                return None
        else:
            auth = request.headers.get("Authorization")
            if not auth or auth.count(":") != 1:
                return None
            login, password = auth.split(":")
            user = user_datastore.find_user(email=login.strip())
            if user is None:
                return None
            if not verify_and_update_password(password.strip(), user):
                return None
        return user if login_user(user) else None

    security = Security()
    security.init_app(app, user_datastore, login_form=LoginForm)
    app.login_manager.request_loader(load_user_from_request)
    app.login_manager.user_loader(load_user)
    user_logged_out.connect(invalidate_user)
Ejemplo n.º 2
0
 def _enable_session_activity(self, app):
     """Enable session activity."""
     user_logged_in.connect(login_listener, app)
     user_logged_out.connect(logout_listener, app)
     from .views.settings import blueprint
     from .views.security import security, revoke_session
     blueprint.route('/security/', methods=['GET'])(security)
     blueprint.route('/sessions/revoke/', methods=['POST'])(revoke_session)
Ejemplo n.º 3
0
    def _enable_logger_activity(self, app):
        """
        Enable session activity.

        :param app: The flask application.
        """
        user_logged_in.connect(login_listener, app)
        user_logged_out.connect(logout_listener, app)
Ejemplo n.º 4
0
    def _enable_session_activity(self, app):
        """Enable session activity."""
        user_logged_in.connect(login_listener, app)
        user_logged_in.connect(csrf_token_reset, app)
        user_logged_out.connect(logout_listener, app)
        user_logged_out.connect(csrf_token_reset, app)
        from .views.security import revoke_session, security
        from .views.settings import blueprint

        blueprint.route("/security/", methods=["GET"])(security)
        blueprint.route("/sessions/revoke/", methods=["POST"])(revoke_session)
Ejemplo n.º 5
0
 def init_app(self, app):
     login_manager.init_app(app)
     login_manager.login_view = 'login.login_form'
     Service.init_app(self, app)
     self.login_url_prefix = app.config.get('LOGIN_URL', '/user')
     app.before_request(self.do_access_control)
     app.before_request(self.update_user_session_data)
     user_logged_in.connect(self.user_logged_in, sender=app)
     user_logged_out.connect(self.user_logged_out, sender=app)
     app.register_blueprint(login_views, url_prefix=self.login_url_prefix)
     with app.app_context():
         actions.register(*_ACTIONS)
Ejemplo n.º 6
0
 def init_app(self, app):
   login_manager.init_app(app)
   login_manager.login_view = 'login.login_form'
   Service.init_app(self, app)
   self.login_url_prefix = app.config.get('LOGIN_URL', '/user')
   app.before_request(self.do_access_control)
   app.before_request(self.update_user_session_data)
   user_logged_in.connect(self.user_logged_in, sender=app)
   user_logged_out.connect(self.user_logged_out, sender=app)
   app.register_blueprint(login_views, url_prefix=self.login_url_prefix)
   with app.app_context():
     actions.register(*_ACTIONS)
Ejemplo n.º 7
0
    def setUp(self):
        super().setUp()
        
        self.flask_app = self._create_app()
        self.client = self.flask_app.test_client()
        self._ctx = self.flask_app.test_request_context()
        self._ctx.push()

        self.json_mod = json
        self.templates = []
        self.current_user = None
        template_rendered.connect(self._add_template)
        if HAVE_FLASK_LOGIN:
            user_logged_in.connect(self._signal_login)
            user_logged_out.connect(self._signal_logout)
Ejemplo n.º 8
0
    def setUp(self):
        super().setUp()

        self.flask_app = self._create_app()
        self.client = self.flask_app.test_client()
        self._ctx = self.flask_app.test_request_context()
        self._ctx.push()

        self.json_mod = json
        self.templates = []
        self.current_user = None
        template_rendered.connect(self._add_template)
        if HAVE_FLASK_LOGIN:
            user_logged_in.connect(self._signal_login)
            user_logged_out.connect(self._signal_logout)
Ejemplo n.º 9
0
    def init_app(self, app: Flask) -> None:
        login_manager.init_app(app)
        login_manager.login_view = "login.login_form"

        super().init_app(app)

        self.login_url_prefix = app.config.get("LOGIN_URL", "/user")

        app.before_request(self.do_access_control)
        app.before_request(self.update_user_session_data)
        user_logged_in.connect(self.user_logged_in, sender=app)
        user_logged_out.connect(self.user_logged_out, sender=app)

        app.register_blueprint(login_views, url_prefix=self.login_url_prefix)

        with app.app_context():
            actions.register(*_ACTIONS)
Ejemplo n.º 10
0
def create_app(db_connection_string=None, testing=None):
    class CustomFlask(Flask):
        SKIP_RULES = [  # These endpoints will be removed for v3
            '/v3/ws/<workspace_name>/hosts/bulk_delete/',
            '/v3/ws/<workspace_name>/vulns/bulk_delete/',
            '/v3/ws/<workspace_id>/change_readonly/',
            '/v3/ws/<workspace_id>/deactivate/',
            '/v3/ws/<workspace_id>/activate/',
        ]

        def add_url_rule(self, rule, endpoint=None, view_func=None, **options):
            # Flask registers views when an application starts
            # do not add view from SKIP_VIEWS
            for rule_ in CustomFlask.SKIP_RULES:
                if rule_ == rule:
                    return
            return super().add_url_rule(rule, endpoint, view_func, **options)

    app = CustomFlask(__name__, static_folder=None)

    try:
        secret_key = faraday.server.config.faraday_server.secret_key
    except Exception:
        # Now when the config file does not exist it doesn't enter in this
        # condition, but it could happen in the future. TODO check
        save_new_secret_key(app)
    else:
        if secret_key is None:
            # This is what happens now when the config file doesn't exist.
            # TODO check
            save_new_secret_key(app)
        else:
            app.config['SECRET_KEY'] = secret_key

    if faraday.server.config.faraday_server.agent_registration_secret is None:
        save_new_agent_creation_token_secret()

    login_failed_message = ("Invalid username or password", 'error')

    app.config.update({
        'SECURITY_BACKWARDS_COMPAT_AUTH_TOKEN':
        True,
        'SECURITY_PASSWORD_SINGLE_HASH':
        True,
        'WTF_CSRF_ENABLED':
        False,
        'SECURITY_USER_IDENTITY_ATTRIBUTES': [{
            'username': {
                'mapper': uia_username_mapper
            }
        }],
        'SECURITY_POST_LOGIN_VIEW':
        '/_api/session',
        'SECURITY_POST_CHANGE_VIEW':
        '/_api/change',
        'SECURITY_RESET_PASSWORD_TEMPLATE':
        '/security/reset.html',
        'SECURITY_POST_RESET_VIEW':
        '/',
        'SECURITY_SEND_PASSWORD_RESET_EMAIL':
        True,
        # For testing porpouse
        'SECURITY_EMAIL_SENDER':
        "*****@*****.**",
        'SECURITY_CHANGEABLE':
        True,
        'SECURITY_SEND_PASSWORD_CHANGE_EMAIL':
        False,
        'SECURITY_MSG_USER_DOES_NOT_EXIST':
        login_failed_message,
        'SECURITY_TOKEN_AUTHENTICATION_HEADER':
        'Authorization',

        # The line bellow should not be necessary because of the
        # CustomLoginForm, but i'll include it anyway.
        'SECURITY_MSG_INVALID_PASSWORD':
        login_failed_message,
        'SESSION_TYPE':
        'filesystem',
        'SESSION_FILE_DIR':
        faraday.server.config.FARADAY_SERVER_SESSIONS_DIR,
        'SQLALCHEMY_TRACK_MODIFICATIONS':
        False,
        'SQLALCHEMY_RECORD_QUERIES':
        True,
        # app.config['SQLALCHEMY_ECHO'] = True
        'SECURITY_PASSWORD_SCHEMES': [
            'bcrypt',  # This should be the default value
            # 'des_crypt',
            # 'pbkdf2_sha256',
            # 'pbkdf2_sha512',
            # 'sha256_crypt',
            # 'sha512_crypt',
        ],
        'PERMANENT_SESSION_LIFETIME':
        datetime.timedelta(hours=int(
            faraday.server.config.faraday_server.session_timeout or 12)),
        'SESSION_COOKIE_NAME':
        'faraday_session_2',
        'SESSION_COOKIE_SAMESITE':
        'Lax',
    })

    store = FilesystemStore(app.config['SESSION_FILE_DIR'])
    prefixed_store = PrefixDecorator('sessions_', store)
    KVSessionExtension(prefixed_store, app)
    user_logged_in.connect(user_logged_in_succesfull, app)
    user_logged_out.connect(expire_session, app)

    storage_path = faraday.server.config.storage.path
    if not storage_path:
        logger.warn(
            'No storage section or path in the .faraday/config/server.ini. Setting the default value to .faraday/storage'
        )
        storage_path = setup_storage_path()

    if not DepotManager.get('default'):
        if testing:
            DepotManager.configure(
                'default',
                {
                    'depot.storage_path': '/tmp'  # nosec
                })
        else:
            DepotManager.configure('default',
                                   {'depot.storage_path': storage_path})

    check_testing_configuration(testing, app)

    try:
        app.config[
            'SQLALCHEMY_DATABASE_URI'] = db_connection_string or faraday.server.config.database.connection_string.strip(
                "'")
    except AttributeError:
        logger.info(
            'Missing [database] section on server.ini. Please configure the database before running the server.'
        )
    except NoOptionError:
        logger.info(
            'Missing connection_string on [database] section on server.ini. Please configure the database before running the server.'
        )

    from faraday.server.models import db  # pylint:disable=import-outside-toplevel
    db.init_app(app)
    # Session(app)

    # Setup Flask-Security
    app.user_datastore = SQLAlchemyUserDatastore(
        db, user_model=User,
        role_model=None)  # We won't use flask security roles feature

    from faraday.server.api.modules.agent import agent_creation_api  # pylint: disable=import-outside-toplevel

    app.limiter = Limiter(app, key_func=get_remote_address, default_limits=[])
    if not testing:
        app.limiter.limit(faraday.server.config.limiter_config.login_limit)(
            agent_creation_api)

    app.register_blueprint(agent_creation_api)

    Security(app, app.user_datastore, login_form=CustomLoginForm)
    # Make API endpoints require a login user by default. Based on
    # https://stackoverflow.com/questions/13428708/best-way-to-make-flask-logins-login-required-the-default

    app.view_functions['security.login'].is_public = True
    app.view_functions['security.logout'].is_public = True
    app.debug = faraday.server.config.is_debug_mode()
    minify_json_output(app)

    for handler in LOGGING_HANDLERS:
        app.logger.addHandler(handler)
    app.logger.propagate = False
    register_blueprints(app)
    register_handlers(app)

    app.view_functions[
        'agent_creation_api.AgentCreationView:post'].is_public = True
    app.view_functions[
        'agent_creation_api.AgentCreationV3View:post'].is_public = True

    return app
from flask import current_app
from flask_mail import email_dispatched
from flask_login import user_logged_in, user_logged_out
from app.logger import log_user_operation, log_email_operation


def _after_sending_email_hook(message, app):
    log_email_operation(message, 'sent')


email_dispatched.connect(_after_sending_email_hook)


# @user_logged_in.connect_via(current_app)
def _after_user_logged_in_hook(sender, user, **extra):
    log_user_operation(user, 'logged in')


user_logged_in.connect(_after_user_logged_in_hook)


# @user_logged_out.connect_via(current_app)
def _after_user_logged_out_hook(sender, user, **extra):
    log_user_operation(user, 'logged out')


user_logged_out.connect(_after_user_logged_out_hook)
    def __init__(self, app, entry_point_group=None):
        """Initialize state."""
        self.app = app
        self.handlers = {}
        self.disconnect_handlers = {}
        self.signup_handlers = {}

        # Connect signal to remove access tokens on logout
        user_logged_out.connect(oauth_logout_handler)

        oauth = app.extensions['oauthlib.client']

        # Add remote applications
        oauth.init_app(app)

        for remote_app, conf in app.config[
                'OAUTHCLIENT_REMOTE_APPS'].items():
            # Prevent double creation problems
            if remote_app not in oauth.remote_apps:
                remote = oauth.remote_app(
                    remote_app,
                    **conf['params']
                )

            remote = oauth.remote_apps[remote_app]

            # Set token getter for remote
            remote.tokengetter(make_token_getter(remote))

            # Register authorized handler
            self.handlers[remote_app] = remote.authorized_handler(make_handler(
                conf.get('authorized_handler', authorized_default_handler),
                remote,
            ))

            # Register disconnect handler
            self.disconnect_handlers[remote_app] = make_handler(
                conf.get('disconnect_handler', disconnect_handler),
                remote,
                with_response=False,
            )

            # Register sign-up handlers
            def dummy_handler(remote, *args, **kargs):
                pass

            signup_handler = conf.get('signup_handler', dict())
            account_info_handler = make_handler(
                signup_handler.get('info', dummy_handler),
                remote,
                with_response=False
            )
            account_setup_handler = make_handler(
                signup_handler.get('setup', dummy_handler),
                remote,
                with_response=False
            )
            account_view_handler = make_handler(
                signup_handler.get('view', dummy_handler),
                remote,
                with_response=False
            )

            self.signup_handlers[remote_app] = dict(
                info=account_info_handler,
                setup=account_setup_handler,
                view=account_view_handler,
            )
Ejemplo n.º 13
0
def setup_app():
    """Setup OAuth clients."""
    # Connect signal to remove access tokens on logout
    user_logged_out.connect(oauth_logout_handler)

    # Add remote applications
    oauth.init_app(current_app)

    for remote_app, conf in cfg['OAUTHCLIENT_REMOTE_APPS'].items():
        # Prevent double creation problems
        if remote_app not in oauth.remote_apps:
            remote = oauth.remote_app(
                remote_app,
                **conf['params']
            )

        remote = oauth.remote_apps[remote_app]

        # Set token getter for remote
        remote.tokengetter(make_token_getter(remote))

        # Register authorized handler
        handlers.register(
            remote_app,
            remote.authorized_handler(make_handler(
                conf.get('authorized_handler', authorized_default_handler),
                remote,
            ))
        )

        # Register disconnect handler
        disconnect_handlers.register(
            remote_app, make_handler(
                conf.get('disconnect_handler', disconnect_handler),
                remote,
                with_response=False,
            )
        )

        # Register sign-up handlers
        def dummy_handler(remote, *args, **kargs):
            pass

        signup_handler = conf.get('signup_handler', dict())
        account_info_handler = make_handler(
            signup_handler.get('info', dummy_handler),
            remote,
            with_response=False
        )
        account_setup_handler = make_handler(
            signup_handler.get('setup', dummy_handler),
            remote,
            with_response=False
        )
        account_view_handler = make_handler(
            signup_handler.get('view', dummy_handler),
            remote,
            with_response=False
        )

        signup_handlers.register(
            remote_app,
            dict(
                info=account_info_handler,
                setup=account_setup_handler,
                view=account_view_handler,
            )
        )
Ejemplo n.º 14
0
    def __init__(self, app):
        """Initialize state."""
        self.app = app
        self.handlers = {}
        self.disconnect_handlers = {}
        self.signup_handlers = {}

        # Connect signal to remove access tokens on logout
        user_logged_out.connect(oauth_logout_handler)

        self.oauth = app.extensions.get('oauthlib.client') or FlaskOAuth()

        # Add remote applications
        self.oauth.init_app(app)

        for remote_app, conf in app.config['OAUTHCLIENT_REMOTE_APPS'].items():
            # Prevent double creation problems
            if remote_app not in self.oauth.remote_apps:
                remote = self.oauth.remote_app(remote_app, **conf['params'])

            remote = self.oauth.remote_apps[remote_app]

            # Set token getter for remote
            remote.tokengetter(make_token_getter(remote))

            # Register authorized handler
            self.handlers[remote_app] = remote.authorized_handler(
                make_handler(
                    conf.get('authorized_handler', authorized_default_handler),
                    remote,
                ))

            # Register disconnect handler
            self.disconnect_handlers[remote_app] = make_handler(
                conf.get('disconnect_handler', disconnect_handler),
                remote,
                with_response=False,
            )

            # Register sign-up handlers
            def dummy_handler(remote, *args, **kargs):
                pass

            signup_handler = conf.get('signup_handler', dict())
            account_info_handler = make_handler(signup_handler.get(
                'info', dummy_handler),
                                                remote,
                                                with_response=False)
            account_setup_handler = make_handler(signup_handler.get(
                'setup', dummy_handler),
                                                 remote,
                                                 with_response=False)
            account_view_handler = make_handler(signup_handler.get(
                'view', dummy_handler),
                                                remote,
                                                with_response=False)

            self.signup_handlers[remote_app] = dict(
                info=account_info_handler,
                setup=account_setup_handler,
                view=account_view_handler,
            )
Ejemplo n.º 15
0
def setup_app():
    """Setup OAuth clients."""
    # Connect signal to remove access tokens on logout
    user_logged_out.connect(oauth_logout_handler)

    # Add remote applications
    oauth.init_app(current_app)

    for remote_app, conf in cfg['OAUTHCLIENT_REMOTE_APPS'].items():
        # Prevent double creation problems
        if remote_app not in oauth.remote_apps:
            remote = oauth.remote_app(
                remote_app,
                **conf['params']
            )

        remote = oauth.remote_apps[remote_app]

        # Set token getter for remote
        remote.tokengetter(make_token_getter(remote))

        # Register authorized handler
        handlers.register(
            remote_app,
            remote.authorized_handler(make_handler(
                conf.get('authorized_handler', authorized_default_handler),
                remote,
            ))
        )

        # Register disconnect handler
        disconnect_handlers.register(
            remote_app, make_handler(
                conf.get('disconnect_handler', disconnect_handler),
                remote,
                with_response=False,
            )
        )

        # Register sign-up handlers
        def dummy_handler(remote, *args, **kargs):
            pass

        signup_handler = conf.get('signup_handler', dict())
        account_info_handler = make_handler(
            signup_handler.get('info', dummy_handler),
            remote,
            with_response=False
        )
        account_setup_handler = make_handler(
            signup_handler.get('setup', dummy_handler),
            remote,
            with_response=False
        )
        account_view_handler = make_handler(
            signup_handler.get('view', dummy_handler),
            remote,
            with_response=False
        )

        signup_handlers.register(
            remote_app,
            dict(
                info=account_info_handler,
                setup=account_setup_handler,
                view=account_view_handler,
            )
        )
Ejemplo n.º 16
0
        session['lang'] = reqlang
    else:
        reqlang = session.get('lang')
        if not reqlang:
            if current_user.is_authenticated:
                reqlang = current_user.language
                session['lang'] = reqlang
    return reqlang


from flask_login import user_logged_in, user_logged_out
from models import syslog


def log_user_logged_in(sender, user, **extra):
    syslog.log(type="user logged in")
    session['lang'] = current_user.language


def log_user_logged_out(sender, user, **extra):
    syslog.log(type="user logged out")


syslog.syslog_init()
syslog.log(type="application initialized")

user_logged_in.connect(log_user_logged_in, shareds.app)
user_logged_out.connect(log_user_logged_out, shareds.app)

import setups
Ejemplo n.º 17
0
def init_security_logging():
    user_logged_in.connect(log_user_logged_in)
    user_logged_out.connect(log_user_logged_out)

    user_registered.connect(log_user_registered)
    user_confirmed.connect(log_user_confirmed)
Ejemplo n.º 18
0
    def __init__(self, app, remote_app_config_key, default_disconnect_handler,
                 default_authorized_handler,
                 default_remote_app_response_handler=None,
                 default_response_handler=None):
        """Initialize state."""
        self.app = app
        self.handlers = {}
        self.disconnect_handlers = {}
        self.signup_handlers = {}
        self.remote_app_response_handler = {}

        # Connect signal to remove access tokens on logout
        user_logged_out.connect(handlers.oauth_logout_handler)

        self.oauth = app.extensions.get('oauthlib.client') or FlaskOAuth()

        # Init config
        self.init_config(app)

        # Add remote applications
        self.oauth.init_app(app)

        remote_app_class = load_or_import_from_config(
            'OAUTHCLIENT_REMOTE_APP', app, default=OAuthRemoteApp
        )

        def dummy_handler(remote, *args, **kargs):
            pass

        self.default_response_handler = default_response_handler or \
            dummy_handler

        for remote_app, conf in app.config[
                remote_app_config_key].items():
            # Prevent double creation problems
            if remote_app not in self.oauth.remote_apps:
                # use this app's specific remote app class if there is one.
                current_remote_app_class = obj_or_import_string(
                    conf.get('remote_app'), default=remote_app_class
                )
                # Register the remote app. We are doing this because the
                # current version of OAuth.remote_app does not allow to specify
                # the remote app class. Use it once it is fixed.
                self.oauth.remote_apps[remote_app] = current_remote_app_class(
                    self.oauth,
                    remote_app,
                    **conf['params']
                )

            remote = self.oauth.remote_apps[remote_app]

            # Set token getter for remote
            remote.tokengetter(handlers.make_token_getter(remote))

            # Register authorized handler
            self.handlers[remote_app] = handlers.authorized_handler(
                handlers.make_handler(
                    conf.get(
                        'authorized_handler', default_authorized_handler),
                    remote
                ),
                remote.authorized_response
            )

            # Register disconnect handler
            self.disconnect_handlers[remote_app] = handlers.make_handler(
                conf.get('disconnect_handler', default_disconnect_handler),
                remote,
                with_response=False,
            )
            self.remote_app_response_handler[
                remote_app] = obj_or_import_string(
                    conf.get(
                        'response_handler',
                        default_remote_app_response_handler or dummy_handler))

            # Register sign-up handlers

            signup_handler = conf.get('signup_handler', dict())
            account_info_handler = handlers.make_handler(
                signup_handler.get('info', dummy_handler),
                remote,
                with_response=False
            )
            account_setup_handler = handlers.make_handler(
                signup_handler.get('setup', dummy_handler),
                remote,
                with_response=False
            )
            account_view_handler = handlers.make_handler(
                signup_handler.get('view', dummy_handler),
                remote,
                with_response=False
            )

            self.signup_handlers[remote_app] = dict(
                info=account_info_handler,
                setup=account_setup_handler,
                view=account_view_handler,
            )

        if 'cern' in self.oauth.remote_apps:
            warnings.warn(
                "CERN Remote app is deprecated, use CERN OpenID instead.",
                DeprecationWarning
            )
Ejemplo n.º 19
0
#
def log_session_start(app, user):
  session = LoginSession.new()
  db.session.add(session)
  db.session.commit()


def log_session_end(app, user):
  session = LoginSession.query.get_active_for(user)
  if session:
    session.ended_at = datetime.utcnow()
    db.session.commit()


user_logged_in.connect(log_session_start)
user_logged_out.connect(log_session_end)


# login redirect utilities
#  from http://flask.pocoo.org/snippets/62/
def is_safe_url(target):
  ref_url = urlparse(request.host_url)
  test_url = urlparse(urljoin(request.url_root, target))
  return test_url.scheme in ('http', 'https') and \
      ref_url.netloc == test_url.netloc


def check_for_redirect(target):
  target = urljoin(request.url_root, target)
  url = urlparse(target)
  reqctx = _request_ctx_stack.top
Ejemplo n.º 20
0
#
def log_session_start(app, user):
    session = LoginSession.new()
    db.session.add(session)
    db.session.commit()


def log_session_end(app, user):
    session = LoginSession.query.get_active_for(user)
    if session:
        session.ended_at = datetime.utcnow()
        db.session.commit()


user_logged_in.connect(log_session_start)
user_logged_out.connect(log_session_end)


# login redirect utilities
#  from http://flask.pocoo.org/snippets/62/
def is_safe_url(target):
    ref_url = urlparse(request.host_url)
    test_url = urlparse(urljoin(request.url_root, target))
    return test_url.scheme in ('http', 'https') and \
        ref_url.netloc == test_url.netloc


def check_for_redirect(target):
    target = urljoin(request.url_root, target)
    url = urlparse(target)
    reqctx = _request_ctx_stack.top
Ejemplo n.º 21
0
    def __init__(self, app):
        """Initialize state."""
        self.app = app
        self.handlers = {}
        self.disconnect_handlers = {}
        self.signup_handlers = {}

        # Connect signal to remove access tokens on logout
        user_logged_out.connect(oauth_logout_handler)

        self.oauth = app.extensions.get('oauthlib.client') or FlaskOAuth()

        # Add remote applications
        self.oauth.init_app(app)

        remote_app_class = load_or_import_from_config(
            'OAUTHCLIENT_REMOTE_APP', app, default=OAuthRemoteApp
        )

        for remote_app, conf in app.config[
                'OAUTHCLIENT_REMOTE_APPS'].items():
            # Prevent double creation problems
            if remote_app not in self.oauth.remote_apps:
                # use this app's specific remote app class if there is one.
                current_remote_app_class = obj_or_import_string(
                    conf.get('remote_app'), default=remote_app_class
                )
                # Register the remote app. We are doing this because the
                # current version of OAuth.remote_app does not allow to specify
                # the remote app class. Use it once it is fixed.
                self.oauth.remote_apps[remote_app] = current_remote_app_class(
                    self.oauth,
                    remote_app,
                    **conf['params']
                )

            remote = self.oauth.remote_apps[remote_app]

            # Set token getter for remote
            remote.tokengetter(make_token_getter(remote))

            # Register authorized handler
            self.handlers[remote_app] = remote.authorized_handler(make_handler(
                conf.get('authorized_handler', authorized_default_handler),
                remote,
            ))

            # Register disconnect handler
            self.disconnect_handlers[remote_app] = make_handler(
                conf.get('disconnect_handler', disconnect_handler),
                remote,
                with_response=False,
            )

            # Register sign-up handlers
            def dummy_handler(remote, *args, **kargs):
                pass

            signup_handler = conf.get('signup_handler', dict())
            account_info_handler = make_handler(
                signup_handler.get('info', dummy_handler),
                remote,
                with_response=False
            )
            account_setup_handler = make_handler(
                signup_handler.get('setup', dummy_handler),
                remote,
                with_response=False
            )
            account_view_handler = make_handler(
                signup_handler.get('view', dummy_handler),
                remote,
                with_response=False
            )

            self.signup_handlers[remote_app] = dict(
                info=account_info_handler,
                setup=account_setup_handler,
                view=account_view_handler,
            )
Ejemplo n.º 22
0
def init_signals(app):
    user_logged_in.connect(on_user_logged_in, app)
    user_logged_out.connect(on_user_logged_out, app)
    voucher_generated.connect(on_voucher_generated, app)
    voucher_logged_in.connect(on_voucher_logged_in, app)
Ejemplo n.º 23
0
def create_app(db_connection_string=None, testing=None):
    app = Flask(__name__)

    try:
        secret_key = faraday.server.config.faraday_server.secret_key
    except Exception:
        # Now when the config file does not exist it doesn't enter in this
        # condition, but it could happen in the future. TODO check
        save_new_secret_key(app)
    else:
        if secret_key is None:
            # This is what happens now when the config file doesn't exist.
            # TODO check
            save_new_secret_key(app)
        else:
            app.config['SECRET_KEY'] = secret_key

    if faraday.server.config.faraday_server.agent_token is None:
        save_new_agent_creation_token()

    login_failed_message = ("Invalid username or password", 'error')

    app.config.update({
        'SECURITY_PASSWORD_SINGLE_HASH': True,
        'WTF_CSRF_ENABLED': False,
        'SECURITY_USER_IDENTITY_ATTRIBUTES': ['username'],
        'SECURITY_POST_LOGIN_VIEW': '/_api/session',
        'SECURITY_POST_LOGOUT_VIEW': '/_api/login',
        'SECURITY_POST_CHANGE_VIEW': '/_api/change',
        'SECURITY_CHANGEABLE': True,
        'SECURITY_SEND_PASSWORD_CHANGE_EMAIL': False,
        'SECURITY_MSG_USER_DOES_NOT_EXIST': login_failed_message,
        'SECURITY_TOKEN_AUTHENTICATION_HEADER': 'Authorization',

        # The line bellow should not be necessary because of the
        # CustomLoginForm, but i'll include it anyway.
        'SECURITY_MSG_INVALID_PASSWORD': login_failed_message,

        'SESSION_TYPE': 'filesystem',
        'SESSION_FILE_DIR': faraday.server.config.FARADAY_SERVER_SESSIONS_DIR,

        'SQLALCHEMY_TRACK_MODIFICATIONS': False,
        'SQLALCHEMY_RECORD_QUERIES': True,
        # app.config['SQLALCHEMY_ECHO'] = True
        'SECURITY_PASSWORD_SCHEMES': [
            'bcrypt',  # This should be the default value
            # 'des_crypt',
            'pbkdf2_sha1',  # Used by CouchDB passwords
            # 'pbkdf2_sha256',
            # 'pbkdf2_sha512',
            # 'sha256_crypt',
            # 'sha512_crypt',
            'plaintext',  # TODO: remove it
        ],
        'PERMANENT_SESSION_LIFETIME': datetime.timedelta(hours=12),
        'SESSION_COOKIE_NAME': 'faraday_session_2',
        'SESSION_COOKIE_SAMESITE': 'Lax',
    })

    store = FilesystemStore(app.config['SESSION_FILE_DIR'])
    prefixed_store = PrefixDecorator('sessions_', store)
    KVSessionExtension(prefixed_store, app)
    user_logged_out.connect(expire_session, app)

    storage_path = faraday.server.config.storage.path
    if not storage_path:
        logger.warn('No storage section or path in the .faraday/config/server.ini. Setting the default value to .faraday/storage')
        storage_path = setup_storage_path()

    if not DepotManager.get('default'):
        if testing:
            DepotManager.configure('default', {
                'depot.storage_path': '/tmp'
            })
        else:
            DepotManager.configure('default', {
                'depot.storage_path': storage_path
            })

    check_testing_configuration(testing, app)

    try:
        app.config['SQLALCHEMY_DATABASE_URI'] = db_connection_string or faraday.server.config.database.connection_string.strip("'")
    except AttributeError:
        logger.info('Missing [database] section on server.ini. Please configure the database before running the server.')
    except NoOptionError:
        logger.info('Missing connection_string on [database] section on server.ini. Please configure the database before running the server.')

    from faraday.server.models import db # pylint:disable=import-outside-toplevel
    db.init_app(app)
    #Session(app)

    # Setup Flask-Security
    app.user_datastore = SQLAlchemyUserDatastore(
        db,
        user_model=User,
        role_model=None)  # We won't use flask security roles feature
    Security(app, app.user_datastore, login_form=CustomLoginForm)
    # Make API endpoints require a login user by default. Based on
    # https://stackoverflow.com/questions/13428708/best-way-to-make-flask-logins-login-required-the-default

    app.view_functions['security.login'].is_public = True
    app.view_functions['security.logout'].is_public = True

    app.debug = faraday.server.config.is_debug_mode()
    minify_json_output(app)

    for handler in LOGGING_HANDLERS:
        app.logger.addHandler(handler)

    register_blueprints(app)
    register_handlers(app)

    app.view_functions['agent_api.AgentCreationView:post'].is_public = True

    return app
Ejemplo n.º 24
0
def create_app(settings_override=None, register_security_blueprint=True):
    """Returns the frontend application instance"""
    app = factory.create_app(__name__, __path__, settings_override)

    app.wsgi_app = WhiteNoise(app.wsgi_app,
                              root=app.static_folder,
                              prefix='static/')

    # Init assets
    assets.init_app(app)
    webpack.init_app(app)

    oauth.init_app(app)
    menu.init_app(app)
    gravatar.init_app(app)

    userdatastore = SQLAlchemyUserDatastore(db, models.User, models.Role)

    security_ctx = security.init_app(
        app,
        userdatastore,
        login_form=DeploymentLoginForm,
        register_blueprint=register_security_blueprint)

    @security_ctx.send_mail_task
    def delay_flask_security_mail(msg):
        send_email.delay(subject=msg.subject,
                         sender=msg.sender,
                         recipients=msg.recipients,
                         body=msg.body)

    # initialize the OpenAPI extension
    spec = APISpec(title='Apollo',
                   version='1.0.0',
                   openapi_version='3.0.2',
                   plugins=[MarshmallowPlugin()])
    app.config.update({'APISPEC_SPEC': spec})
    docs.init_app(app)

    csrf.init_app(app)
    init_admin(admin, app)

    monitor(app)

    # Register custom error handlers
    if not app.debug:
        for e in [500, 404, 403]:
            app.register_error_handler(e, handle_error)

    # register deployment selection middleware
    app.before_request(set_request_presets)

    # add Jinja2 filters
    app.jinja_env.filters.update(custom_filters)

    # Login and logout signal handlers
    user_logged_out.connect(clear_session)

    @identity_loaded.connect_via(app)
    def on_identity_loaded(sender, identity):
        if current_user.is_authenticated:
            user = current_user._get_current_object()
            needs = services.users.get_permissions_cache(user)

            for need in needs:
                identity.provides.add(need)

    @app.context_processor
    def inject_permissions():
        ga_key = app.config.get('GOOGLE_ANALYTICS_KEY')
        gtm_key = app.config.get('GOOGLE_TAG_MANAGER_KEY')
        return dict(perms=permissions, ga_key=ga_key, gtm_key=gtm_key)

    # clickjacking protection
    @app.after_request
    def frame_buster(response):
        response.headers['X-Frame-Options'] = app.config.get(
            'X_FRAME_OPTIONS', 'DENY')
        return response

    # content security policy
    @app.after_request
    def content_security_policy(response):
        response.headers['Content-Security-Policy'] = "default-src 'self' " + \
            "*.googlecode.com *.google-analytics.com fonts.gstatic.com fonts.googleapis.com " + \
            "*.googletagmanager.com " + \
            "cdn.heapanalytics.com heapanalytics.com " + \
            "'unsafe-inline' 'unsafe-eval' data:; img-src * data:"
        return response

    def handle_authorize(remote, token, user_info):
        if user_info and 'email' in user_info:
            user = models.User.query.filter_by(
                email=user_info['email']).first()
            if user:
                login_user(user)
                userdatastore.commit()
                return redirect(app.config.get('SECURITY_POST_LOGIN_VIEW'))

        return redirect(url_for_security('login'))

    @app.template_global()
    def modify_query(**values):
        args = request.args.copy()

        for k, v in values.items():
            if not v:
                _ = args.pop(k, None)
            else:
                args[k] = v

        return '{}?{}'.format(request.path, url_encode(args))

    facebook_bp = create_flask_blueprint(Facebook, oauth, handle_authorize)
    google_bp = create_flask_blueprint(Google, oauth, handle_authorize)

    if app.config.get('ENABLE_SOCIAL_LOGIN', False):
        app.register_blueprint(facebook_bp, url_prefix='/facebook')
        app.register_blueprint(google_bp, url_prefix='/google')

    return app
Ejemplo n.º 25
0
 def setUp(self):
     self.clean_db()
     self.current_user = None
     user_logged_in.connect(self._signal_login)
     user_logged_out.connect(self._signal_logout)