예제 #1
0
def get_secrets():
    if os.getenv('DATABASE_URL') and os.getenv('FLASK_SECRET'):
        return {
            'postgres': {
                'url': os.getenv('DATABASE_URL')
            },
            'sessions_secret': os.getenv('FLASK_SECRET')
        }

    secrets_file_name = 'secrets.yaml'

    if not os.path.isfile(os.path.join(CONFIGS_PARENT_DIR, secrets_file_name)):
        secrets_file_name = 'app.yml'

    try:
        with open(os.path.join(CONFIGS_PARENT_DIR,
                               secrets_file_name)) as secrets_file:
            secrets = yaml.load(secrets_file, Loader=yaml.SafeLoader)
    except (IOError, FileNotFoundError):
        if not env.current_env_is_local():
            raise

        secrets = {'sessions_secret': 'placeholder'}

    return secrets
예제 #2
0
def get_config():
    if os.getenv('TROTTO_CONFIG'):
        return yaml.load(base64.b64decode(os.getenv('TROTTO_CONFIG')),
                         Loader=yaml.SafeLoader)

    if os.getenv('DATABASE_URL') and os.getenv('FLASK_SECRET'):
        return {
            'postgres': {
                'url': os.getenv('DATABASE_URL')
            },
            'sessions_secret': os.getenv('FLASK_SECRET')
        }

    config_file_name = 'secrets.yaml'

    if not os.path.isfile(os.path.join(CONFIGS_PARENT_DIR, config_file_name)):
        config_file_name = 'app.yml'

    try:
        with open(os.path.join(CONFIGS_PARENT_DIR,
                               config_file_name)) as config_file:
            config = yaml.load(config_file, Loader=yaml.SafeLoader)
    except (IOError, FileNotFoundError):
        if not env.current_env_is_local():
            raise

        config = {'sessions_secret': 'placeholder'}

    return config
예제 #3
0
    def attempt_auth_by_user_header(self):
        # only for testing
        if not env.current_env_is_local():
            return

        if self.request.headers.get('TROTTO_USER_UNDER_TEST'):
            self.user_email = self.request.headers.get(
                'TROTTO_USER_UNDER_TEST')
            self.user_org = get_organization_id_for_email(self.user_email)
예제 #4
0
    def dispatch(self):
        if self.request.host == 'dev.trot.to':
            if not users.get_current_user():
                self.redirect(users.create_login_url('/'))
                return
            elif not users.is_current_user_admin():
                self.abort(403)

        self.is_local_env = not os.getenv('SERVER_SOFTWARE',
                                          '').startswith('Google App Engine/')

        # Get a session store for this request.
        self.session_store = sessions.get_store(request=self.request)

        self.login_error = None

        self.user_email = None
        self.user = None

        if not self.user_email:
            self.user_email = self.session.get('user_email')
            self.user_org = get_organization_id_for_email(
                self.user_email) if self.user_email else None

        if not self.user_email:
            self.attempt_auth_by_emailed_link()

        if not self.user_email and env.current_env_is_local():
            self.attempt_auth_by_user_header()

        self.session['already_accepted_terms'] = False
        if self.user_email:
            self.user = get_or_create_user(self.user_email, self.user_org)
            self.session[
                'already_accepted_terms'] = not not self.user.accepted_terms_at

            if not self.session.get('csrf_token'):
                self.session['csrf_token'] = utils.generate_secret(32)

        try:
            self.redirect_to = None
            self.check_authorization()

            if self.redirect_to:
                self.response.write(
                    json.dumps({'redirect_to': self.redirect_to}))
                return

            # Dispatch the request.
            webapp2.RequestHandler.dispatch(self)
        finally:
            # Save all sessions, IFF secure connection
            if self.request.scheme == 'https' or self.is_local_env:
                self.session_store.save_sessions(self.response)
예제 #5
0
def get_path_to_oauth_secrets():
    production_path = os.path.join(os.path.dirname(__file__),
                                   '../config/client_secrets.json')

    if not os.path.isfile(production_path):
        if env.current_env_is_local():
            return os.path.join(os.path.dirname(__file__),
                                '../local/client_secrets_local_only.json')
        else:
            if os.getenv('GOOGLE_OAUTH_CLIENT_JSON'):
                with open(production_path, 'w') as f:
                    f.write(os.getenv('GOOGLE_OAUTH_CLIENT_JSON'))
            else:
                raise MissingConfigError(
                    'Missing `config/client_secrets.json` in non-local environment'
                )

    return production_path
예제 #6
0
def get_webapp2_config():
    try:
        sessions_secret = get_secrets()['sessions_secret']
    except IOError:
        if env.current_env_is_local():
            sessions_secret = 'local-only-mock-sessions-secret'
        else:
            raise

    config = {}
    config['webapp2_extras.sessions'] = {
        'secret_key': sessions_secret,
        'cookie_args': {
            'secure':
            os.getenv('SERVER_SOFTWARE', '').startswith('Google App Engine/')
        }
    }

    return config
예제 #7
0
    def check_authorization(self):
        if not self.user_email:
            request_data = {
                'origin': self.request.headers.get('Origin'),
                'method': self.request.method,
                'path': self.request.path,
                'body': self.request.body
            }

            if 'slack' in self.request.path_url:
                self.abort(
                    400
                )  # Guard against leaking Slack token or other sensitive data in response

            self.redirect_to = '%s/play_queued_request?r=%s' % (
                self.request.path_url.rstrip('/'),
                base64.urlsafe_b64encode(json.dumps(request_data)))

        if (not env.current_env_is_local()
                and self.request.method not in ['GET', 'OPTIONS']
                and self.request.headers.get('X-CSRF') !=
                self.session.get('csrf_token')):
            self.abort(401)