#189 config: introduce FAS_ENABLED
Closed 3 months ago by kparal. Opened 3 months ago by kparal.

file modified
+12 -3
@@ -1,6 +1,3 @@ 

- #

- # config.py - settings used in the blockerbug application

- #

  # Copyright 2012, Red Hat, Inc

  #

  # This program is free software; you can redistribute it and/or modify
@@ -20,11 +17,16 @@ 

  # Authors:

  #   Tim Flink <tflink@redhat.com>

  

+ """config.py - settings used in the blockerbug application"""

+ 

  import os

  import sys

  

  

  class Config(object):

+     """Default configuration for the whole application. Default values are tailored more towards a

+     development environment.

+     """

      PRODUCTION = False

      DEBUG = True

      SECRET_KEY = None  # REPLACE THIS WITH A RANDOM STRING
@@ -34,6 +36,9 @@ 

      BUGZILLA_XMLRPC = BUGZILLA_URL + 'xmlrpc.cgi'

      KOJI_URL = 'http://koji.stg.fedoraproject.org/'

      BODHI_URL = 'https://bodhi.stg.fedoraproject.org/'

+     FAS_ENABLED = False

+     """When FAS is not enabled, a fake stub is used instead, which allows the user to log in (under

+     the credentials+groups defined here in this config) without authentication."""

      FAS_ADMIN_GROUP = 'qa-admin'

      FAS_USER = ''

      FAS_PASSWORD = ''
@@ -75,12 +80,14 @@ 

  

  

  class ProductionConfig(Config):

+     """A `Config` subclass intended for a production deployment"""

      PRODUCTION = True

      DEBUG = False

      BUGZILLA_URL = 'https://bugzilla.redhat.com/'

      BUGZILLA_XMLRPC = BUGZILLA_URL + 'xmlrpc.cgi'

      KOJI_URL = 'http://koji.fedoraproject.org/'

      BODHI_URL = 'https://bodhi.fedoraproject.org/'

+     FAS_ENABLED = True

      FAS_HTTPS_REQUIRED = True

      FAS_BASE_URL = 'https://admin.fedoraproject.org/accounts/'

      PAGURE_URL = "https://pagure.io/"
@@ -90,12 +97,14 @@ 

  

  

  class DevelopmentConfig(Config):

+     """A `Config` subclass intended for a development environment"""

      TRAP_BAD_REQUEST_ERRORS = True

      SQLALCHEMY_DATABASE_URI = 'sqlite:////var/tmp/blockerbugs_db.sqlite'

      SHOW_DB_URI = True

  

  

  class TestingConfig(Config):

+     """A `Config` subclass intended for running the test suite"""

      TESTING = True

      SHOW_DB_URI = True

  

file modified
+10 -7
@@ -1,6 +1,3 @@ 

- #

- # login.py - a login wrapper

- #

  # Copyright 2013, Red Hat, Inc

  #

  # This program is free software; you can redistribute it and/or modify
@@ -20,6 +17,8 @@ 

  # Authors:

  #   Martin Krizek <mkrizek@redhat.com>

  

+ """login.py - a login wrapper"""

+ 

  import munch

  from flask import g, request, redirect

  from flask_fas_openid import FAS
@@ -27,25 +26,29 @@ 

  from blockerbugs import app

  

  

- #: a singleton FAS instance. Use getFAS() to access it.

  _fas = None

+ """A singleton FAS instance. Use getFAS() to access it."""

  

  

  def getFAS():

-     '''Return either the real or a fake FAS object depending on the app config'''

+     """Return either the real or a fake FAS object depending on the app config"""

      global _fas

      if _fas is not None:

          return _fas

  

-     if (app.config['PRODUCTION'] or app.config['TESTING']):

+     if app.config['FAS_ENABLED']:

          _fas = FAS(app)

-     else:  # development

+     else:

          _fas = FakeFAS(app)

  

      return _fas

  

  

  class FakeFAS(object):

+     """A FAS stub class. Allows a login without any authentication. It uses

+     a username provided in the app config (or 'developer'), and automatically

+     puts it into the admin group (as defined in the app config).

+     """

      fake_user = munch.Munch(

          username=app.config['FAS_USER'] or 'developer',

          groups=[app.config['FAS_ADMIN_GROUP']])

@@ -2,6 +2,7 @@ 

  # cli to generate a config file

  SECRET_KEY = 'replace-me-with-something-random'

  SQLALCHEMY_DATABASE_URI = 'postgresql+psycopg2://dbuser:dbpassword@dbhost:dbport/dbname'

+ FAS_ENABLED = False

  FAS_ADMIN_GROUP = "magic-fas-group"

  FAS_USER = "magicuser@unicornsarereal.com"

  FAS_PASSWORD = "password"

@@ -0,0 +1,51 @@ 

+ """Test blockerbugs/util/login.py"""

+ 

+ import pytest

+ import mock

+ import flask_fas_openid

+ 

+ from blockerbugs.util import login

+ from blockerbugs import app

+ 

+ 

+ @pytest.fixture(autouse=True)

+ def reset_fas(monkeypatch):

+     """Reset login._fas to None for all tests, so that they can test its initialization. Also, it is

+     a global variable, we don't want to change the real value, it could affect other test modules.

+     """

+     monkeypatch.setattr(login, '_fas', None)

+ 

+ 

+ @pytest.fixture(autouse=True)

+ def avoid_flask_setup(monkeypatch):

+     """Flask aborts, if a setup method is called after it already handled some requests (which it

+     already did in other test modules). We must avoid calling such setup methods.

+     """

+     monkeypatch.setattr(app, 'before_request', mock.MagicMock())

+     monkeypatch.setattr(app, 'add_url_rule', mock.MagicMock())

+ 

+ 

+ class TestLogin:

+     def test_default_fakefas(self):

+         """During a test suite run, FakeFAS should be used by default"""

+         assert isinstance(login.getFAS(), login.FakeFAS)

+ 

+     def test_singleton(self):

+         """A singleton _fas should not be overwritten with subsequent calls"""

+         fas = login.getFAS()

+         assert fas is login._fas

+         fas2 = login.getFAS()

+         assert fas is fas2 is login._fas

+ 

+     def test_config_fas_enabled(self, monkeypatch):

+         """Config option FAS_ENABLED should affect the returned object"""

+         monkeypatch.setitem(app.config, 'FAS_ENABLED', False)

+         assert isinstance(login.getFAS(), login.FakeFAS)

+ 

+         login._fas = None

+         monkeypatch.setitem(app.config, 'FAS_ENABLED', '')

+         assert isinstance(login.getFAS(), login.FakeFAS)

+ 

+         login._fas = None

+         monkeypatch.setitem(app.config, 'FAS_ENABLED', True)

+         assert isinstance(login.getFAS(), flask_fas_openid.FAS)

This allows to either use FAS or FakeFAS with a configuration change,
independently on the deployment type. This means we no longer need to use
TESTING=True on our staging instance.

Fixes: https://pagure.io/fedora-qa/blockerbugs/issue/182

Build failed. More information on how to proceed and troubleshoot errors available at https://fedoraproject.org/wiki/Zuul-based-ci

Pull-Request has been closed by kparal

3 months ago