def test__missing_credentials(self): """ LDAP: test login flow for - missing credentials """ self.appbuilder = AppBuilder(self.app, self.db.session) sm = self.appbuilder.sm # validate - no users are registered self.assertEqual(sm.get_all_users(), []) # validate - login failure (missing username) self.assertIsNone(sm.auth_user_ldap(None, "password")) self.assertIsNone(sm.auth_user_ldap("", "password")) # validate - login failure (missing password) self.assertIsNone(sm.auth_user_ldap("username", None)) self.assertIsNone(sm.auth_user_ldap("username", "")) # validate - login failure (missing username/password) self.assertIsNone(sm.auth_user_ldap(None, None)) self.assertIsNone(sm.auth_user_ldap("", None)) self.assertIsNone(sm.auth_user_ldap("", "")) self.assertIsNone(sm.auth_user_ldap(None, "")) # validate - no users were created self.assertEqual(sm.get_all_users(), []) # validate - expected LDAP methods were called self.assertEquals(self.ldapobj.methods_called(with_args=True), [])
def setUp(self): from flask import Flask from flask_appbuilder import AppBuilder from flask_appbuilder.views import ModelView self.app = Flask(__name__) self.basedir = os.path.abspath(os.path.dirname(__file__)) self.app.config.from_object("flask_appbuilder.tests.config_api") self.app.config["FAB_API_MAX_PAGE_SIZE"] = MAX_PAGE_SIZE self.db = SQLA(self.app) self.appbuilder = AppBuilder(self.app, self.db.session) class Model1View(ModelView): datamodel = SQLAInterface(Model1) context = self context._conditional_value = True class Model1ViewDynamic(ModelView): datamodel = SQLAInterface(Model1) self.appbuilder.add_view(Model1View, "Model1") self.appbuilder.add_view( Model1ViewDynamic, "Model1Dynamic", label="Model1 Dynamic", menu_cond=lambda: context._conditional_value, )
def test__inactive_user(self): """ LDAP: test login flow for - inactive user """ self.appbuilder = AppBuilder(self.app, self.db.session) sm = self.appbuilder.sm # validate - no users are registered self.assertEqual(sm.get_all_users(), []) # register a user new_user = sm.add_user( username="******", first_name="Alice", last_name="Doe", email="*****@*****.**", role=[], ) # validate - user was registered self.assertEqual(len(sm.get_all_users()), 1) # set user inactive new_user.active = False # attempt login user = sm.auth_user_ldap("alice", "alice_password") # validate - user was not allowed to log in self.assertIsNone(user) # validate - expected LDAP methods were called self.assertEquals(self.ldapobj.methods_called(with_args=True), [])
def test_ldapsearch(self): con = ldap.initialize("ldap://localhost/") con.simple_bind_s("cn=manager,ou=example,o=test", "ldaptest") self.app.config["AUTH_LDAP_SEARCH_FILTER"] = "" self.appbuilder = AppBuilder(self.app, self.db.session) initialize_call = ("initialize", ("ldap://localhost/", ), {}) simple_bind_s_call = ( "simple_bind_s", ("cn=manager,ou=example,o=test", "ldaptest"), {}, ) search_s_call = ( "search_s", ("ou=example,o=test", 2, "(cn=alice)", [None, None, None]), {}, ) user = self.appbuilder.sm._search_ldap(ldap, con, "alice") self.assertEqual( self.ldapobj.methods_called(with_args=True), [initialize_call, simple_bind_s_call, search_s_call], ) self.assertEqual(user[0][0], self.alice[0])
def test__indirect_bind__unregistered__no_self_register(self): """ LDAP: test login flow for - indirect bind - unregistered user - no self-registration """ # noqa self.app.config["AUTH_LDAP_SEARCH"] = "ou=users,o=test" self.app.config["AUTH_LDAP_BIND_USER"] = "******" self.app.config["AUTH_LDAP_BIND_PASSWORD"] = "******" self.app.config["AUTH_USER_REGISTRATION"] = False self.appbuilder = AppBuilder(self.app, self.db.session) sm = self.appbuilder.sm # validate - no users are registered self.assertEqual(sm.get_all_users(), []) # attempt login user = sm.auth_user_ldap("alice", "alice_password") # validate - user was not allowed to log in self.assertIsNone(user) # validate - no users were registered self.assertEqual(sm.get_all_users(), []) # validate - expected LDAP methods were called self.assertEqual(self.ldapobj.methods_called(with_args=True), [])
def test__direct_bind__registered__no_search(self): """ LDAP: test login flow for - direct bind - registered user - no ldap search """ self.app.config["AUTH_LDAP_SEARCH"] = None self.app.config["AUTH_LDAP_USERNAME_FORMAT"] = "uid=%s,ou=users,o=test" self.appbuilder = AppBuilder(self.app, self.db.session) sm = self.appbuilder.sm # validate - no users are registered self.assertEqual(sm.get_all_users(), []) # register a user new_user = sm.add_user( # noqa username="******", first_name="Alice", last_name="Doe", email="*****@*****.**", role=[], ) # validate - user was registered self.assertEqual(len(sm.get_all_users()), 1) # attempt login user = sm.auth_user_ldap("alice", "alice_password") # validate - user was allowed to log in (because they are already registered) self.assertIsInstance(user, sm.user_model) # validate - expected LDAP methods were called self.assertEqual( self.ldapobj.methods_called(with_args=True), [self.call_initialize, self.call_set_option, self.call_bind_alice], )
def test__unregistered(self): """ OAUTH: test login flow for - unregistered user """ self.app.config["AUTH_USER_REGISTRATION"] = True self.app.config["AUTH_USER_REGISTRATION_ROLE"] = "Public" self.appbuilder = AppBuilder(self.app, self.db.session) sm = self.appbuilder.sm # validate - no users are registered self.assertOnlyDefaultUsers() # attempt login user = sm.auth_user_oauth(self.userinfo_alice) # validate - user was allowed to log in self.assertIsInstance(user, sm.user_model) # validate - user was registered self.assertEqual(len(sm.get_all_users()), 3) # validate - user was given the AUTH_USER_REGISTRATION_ROLE role self.assertEqual(user.roles, [sm.find_role("Public")]) # validate - user was given the correct attributes self.assertEqual(user.first_name, "Alice") self.assertEqual(user.last_name, "Doe") self.assertEqual(user.email, "*****@*****.**")
def test__indirect_bind__unregistered__no_search(self): """ LDAP: test login flow for - indirect bind - unregistered user - no ldap search """ self.app.config["AUTH_LDAP_SEARCH"] = None self.app.config["AUTH_LDAP_BIND_USER"] = "******" self.app.config["AUTH_LDAP_BIND_PASSWORD"] = "******" self.app.config["AUTH_USER_REGISTRATION"] = True self.app.config["AUTH_USER_REGISTRATION_ROLE"] = "Public" self.appbuilder = AppBuilder(self.app, self.db.session) sm = self.appbuilder.sm # validate - no users are registered self.assertEqual(sm.get_all_users(), []) # attempt login user = sm.auth_user_ldap("alice", "alice_password") # validate - user was NOT allowed to log in # (because indirect bind requires search) self.assertIsNone(user) # validate - expected LDAP methods were called self.assertEqual( self.ldapobj.methods_called(with_args=True), [self.call_initialize, self.call_set_option, self.call_bind_admin], )
def test__unregistered__jmespath_role(self): """ OAUTH: test login flow for - unregistered user - jmespath registration role """ self.app.config["AUTH_USER_REGISTRATION"] = True self.app.config[ "AUTH_USER_REGISTRATION_ROLE_JMESPATH"] = "contains(['alice'], username) && 'User' || 'Public'" self.appbuilder = AppBuilder(self.app, self.db.session) sm = self.appbuilder.sm # add User role sm.add_role("User") # validate - no users are registered self.assertOnlyDefaultUsers() # attempt login user = sm.auth_user_oauth(self.userinfo_alice) # validate - user was allowed to log in self.assertIsInstance(user, sm.user_model) # validate - user was registered self.assertEqual(len(sm.get_all_users()), 3) # validate - user was given the correct roles self.assertListEqual(user.roles, [sm.find_role("User")]) # validate - user was given the correct attributes (read from LDAP) self.assertEqual(user.first_name, "Alice") self.assertEqual(user.last_name, "Doe") self.assertEqual(user.email, "*****@*****.**")
def test__registered__multi_role__no_role_sync(self): """ OAUTH: test login flow for - registered user - multi role mapping - no login role-sync """ # noqa self.app.config["AUTH_ROLES_MAPPING"] = {"GROUP_1": ["Admin", "User"]} self.app.config["AUTH_ROLES_SYNC_AT_LOGIN"] = False self.appbuilder = AppBuilder(self.app, self.db.session) sm = self.appbuilder.sm # add User role sm.add_role("User") # validate - no users are registered self.assertOnlyDefaultUsers() # register a user new_user = sm.add_user( # noqa username="******", first_name="Alice", last_name="Doe", email="*****@*****.**", role=[], ) # validate - user was registered self.assertEqual(len(sm.get_all_users()), 3) # attempt login user = sm.auth_user_oauth(self.userinfo_alice) # validate - user was allowed to log in self.assertIsInstance(user, sm.user_model) # validate - user was given no roles self.assertListEqual(user.roles, [])
def test__inactive_user(self): """ OAUTH: test login flow for - inactive user """ self.appbuilder = AppBuilder(self.app, self.db.session) sm = self.appbuilder.sm # validate - no users are registered self.assertOnlyDefaultUsers() # register a user new_user = sm.add_user( username="******", first_name="Alice", last_name="Doe", email="*****@*****.**", role=[], ) # validate - user was registered self.assertEqual(len(sm.get_all_users()), 3) # set user inactive new_user.active = False # attempt login user = sm.auth_user_oauth(self.userinfo_alice) # validate - user was not allowed to log in self.assertIsNone(user)
def test___search_ldap(self): """ LDAP: test `_search_ldap` method """ self.app.config["AUTH_LDAP_BIND_USER"] = "******" self.app.config["AUTH_LDAP_BIND_PASSWORD"] = "******" self.app.config["AUTH_LDAP_SEARCH"] = "ou=users,o=test" self.appbuilder = AppBuilder(self.app, self.db.session) sm = self.appbuilder.sm # prepare `con` object con = ldap.initialize("ldap://localhost/") sm._ldap_bind_indirect(ldap, con) # run `_search_ldap` method user_dn, user_attributes = sm._search_ldap(ldap, con, "alice") # validate - search returned expected data self.assertEqual(user_dn, self.user_alice[0]) self.assertEqual(user_attributes["givenName"], self.user_alice[1]["givenName"]) self.assertEqual(user_attributes["sn"], self.user_alice[1]["sn"]) self.assertEqual(user_attributes["email"], self.user_alice[1]["email"]) # validate - expected LDAP methods were called self.assertEqual( self.ldapobj.methods_called(with_args=True), [self.call_initialize, self.call_bind_admin, self.call_search_alice], )
def test___search_ldap_with_search_referrals(self): """ LDAP: test `_search_ldap` method w/returned search referrals """ self.app.config["AUTH_LDAP_BIND_USER"] = "******" self.app.config["AUTH_LDAP_BIND_PASSWORD"] = "******" self.app.config["AUTH_LDAP_SEARCH"] = "ou=users,o=test" self.appbuilder = AppBuilder(self.app, self.db.session) sm = self.appbuilder.sm # run `_search_ldap` method w/mocked ldap connection mock_con = Mock() mock_con.search_s.return_value = [ ( None, [ "ldap://ForestDnsZones.mycompany.com/" "DC=ForestDnsZones,DC=mycompany,DC=com" ], ), self.user_alice, (None, ["ldap://mycompany.com/CN=Configuration,DC=mycompany,DC=com"]), ] user_dn, user_attributes = sm._search_ldap(ldap, mock_con, "alice") # validate - search returned expected data self.assertEqual(user_dn, self.user_alice[0]) self.assertEqual(user_attributes["givenName"], self.user_alice[1]["givenName"]) self.assertEqual(user_attributes["sn"], self.user_alice[1]["sn"]) self.assertEqual(user_attributes["email"], self.user_alice[1]["email"]) mock_con.search_s.assert_called()
def setUp(self): from flask import Flask from flask_appbuilder import AppBuilder self.app = Flask(__name__) self.app.config.from_object("flask_appbuilder.tests.config_api") self.db = SQLA(self.app) self.appbuilder = AppBuilder(self.app, self.db.session)
def setUp(self): self.app = Flask(__name__) self.app.jinja_env.undefined = jinja2.StrictUndefined self.app.config.from_object("flask_appbuilder.tests.config_api") logging.basicConfig(level=logging.ERROR) self.db = SQLA(self.app) self.appbuilder = AppBuilder(self.app, self.db.session)
def test_self_registration_not_enabled(self): self.app.config["AUTH_USER_REGISTRATION"] = False self.appbuilder = AppBuilder(self.app, self.db.session) result = self.appbuilder.sm.auth_user_oauth( userinfo={"username": "******"}) self.assertIsNone(result) self.assertEqual(len(self.appbuilder.sm.get_all_users()), 0)
def test_register_and_attach_static_role(self): self.app.config["AUTH_USER_REGISTRATION"] = True self.app.config["AUTH_USER_REGISTRATION_ROLE"] = "Public" self.appbuilder = AppBuilder(self.app, self.db.session) user = self.appbuilder.sm.auth_user_oauth( userinfo={"username": "******"}) self.assertEqual(user.roles[0].name, "Public")
def test__multi_group_user_mapping_to_same_role(self): """ LDAP: test login flow for - user in multiple groups mapping to same role """ self.app.config["AUTH_ROLES_MAPPING"] = { "cn=staff,ou=groups,o=test": ["Admin"], "cn=admin,ou=groups,o=test": ["Admin", "User"], "cn=exec,ou=groups,o=test": ["Public"], } self.app.config["AUTH_LDAP_SEARCH"] = "ou=users,o=test" self.app.config["AUTH_LDAP_USERNAME_FORMAT"] = "uid=%s,ou=users,o=test" self.app.config["AUTH_USER_REGISTRATION"] = True self.app.config["AUTH_USER_REGISTRATION_ROLE"] = "Public" self.appbuilder = AppBuilder(self.app, self.db.session) sm = self.appbuilder.sm # add User role sm.add_role("User") # validate - no users are registered self.assertEqual(sm.get_all_users(), []) # attempt login user = sm.auth_user_ldap("natalie", "natalie_password") # validate - user was allowed to log in self.assertIsInstance(user, sm.user_model) # validate - user was registered self.assertEqual(len(sm.get_all_users()), 1) # validate - user was given the correct roles self.assertListEqual( user.roles, [ sm.find_role("Admin"), sm.find_role("Public"), sm.find_role("User") ], ) # validate - user was given the correct attributes (read from LDAP) self.assertEqual(user.first_name, "Natalie") self.assertEqual(user.last_name, "Smith") self.assertEqual(user.email, "*****@*****.**") # validate - expected LDAP methods were called self.assertEqual( self.ldapobj.methods_called(with_args=True), [ self.call_initialize, self.call_set_option, self.call_bind_natalie, self.call_search_natalie_memberof, ], )
def test__indirect_bind__unregistered__multi_role(self): """ LDAP: test login flow for - indirect bind - unregistered user - multi role mapping """ self.app.config["AUTH_ROLES_MAPPING"] = { "cn=staff,ou=groups,o=test": ["Admin", "User"] } self.app.config["AUTH_LDAP_SEARCH"] = "ou=users,o=test" self.app.config["AUTH_LDAP_BIND_USER"] = "******" self.app.config["AUTH_LDAP_BIND_PASSWORD"] = "******" self.app.config["AUTH_USER_REGISTRATION"] = True self.app.config["AUTH_USER_REGISTRATION_ROLE"] = "Public" self.appbuilder = AppBuilder(self.app, self.db.session) sm = self.appbuilder.sm # add User role sm.add_role("User") # validate - no users are registered self.assertEqual(sm.get_all_users(), []) # attempt login user = sm.auth_user_ldap("alice", "alice_password") # validate - user was allowed to log in self.assertIsInstance(user, sm.user_model) # validate - user was registered self.assertEqual(len(sm.get_all_users()), 1) # validate - user was given the correct roles self.assertListEqual( user.roles, [ sm.find_role("Admin"), sm.find_role("Public"), sm.find_role("User") ], ) # validate - user was given the correct attributes (read from LDAP) self.assertEqual(user.first_name, "Alice") self.assertEqual(user.last_name, "Doe") self.assertEqual(user.email, "*****@*****.**") # validate - expected LDAP methods were called self.assertEqual( self.ldapobj.methods_called(with_args=True), [ self.call_initialize, self.call_set_option, self.call_bind_admin, self.call_search_alice_memberof, self.call_bind_alice, ], )
def create_user(app): appbuilder = AppBuilder(app, security_manager_class=SecurityManager) appbuilder.sm.create_db() role_admin = appbuilder.sm.find_role(appbuilder.sm.auth_role_admin) user = appbuilder.sm.add_user('test_user', 'test', 'user', '*****@*****.**', role_admin, 'test_user') return user
def test__indirect_bind__registered__multi_role__with_role_sync(self): """ LDAP: test login flow for - indirect bind - registered user - multi role mapping - with login role-sync """ # noqa self.app.config["AUTH_ROLES_MAPPING"] = { "cn=staff,ou=groups,o=test": ["Admin", "User"] } self.app.config["AUTH_ROLES_SYNC_AT_LOGIN"] = True self.app.config["AUTH_LDAP_SEARCH"] = "ou=users,o=test" self.app.config["AUTH_LDAP_BIND_USER"] = "******" self.app.config["AUTH_LDAP_BIND_PASSWORD"] = "******" self.appbuilder = AppBuilder(self.app, self.db.session) sm = self.appbuilder.sm # add User role sm.add_role("User") # validate - no users are registered self.assertEqual(sm.get_all_users(), []) # register a user new_user = sm.add_user( # noqa username="******", first_name="Alice", last_name="Doe", email="*****@*****.**", role=[], ) # validate - user was registered self.assertEqual(len(sm.get_all_users()), 1) # attempt login user = sm.auth_user_ldap("alice", "alice_password") # validate - user was allowed to log in self.assertIsInstance(user, sm.user_model) # validate - user was given the correct roles self.assertListEqual(user.roles, [sm.find_role("Admin"), sm.find_role("User")]) # validate - expected LDAP methods were called self.assertEqual( self.ldapobj.methods_called(with_args=True), [ self.call_initialize, self.call_set_option, self.call_bind_admin, self.call_search_alice_memberof, self.call_bind_alice, ], )
def setUp(self): from flask import Flask from flask_wtf import CSRFProtect from flask_appbuilder import AppBuilder self.app = Flask(__name__) self.app.config.from_object("flask_appbuilder.tests.config_oauth") self.app.config["WTF_CSRF_ENABLED"] = True self.csrf = CSRFProtect(self.app) self.db = SQLA(self.app) self.appbuilder = AppBuilder(self.app, self.db.session)
def test_import_roles(self): with tempfile.TemporaryDirectory() as tmp_dir: app = Flask(__name__) app.config["MONGODB_SETTINGS"] = { "db": "app", "host": "localhost", "port": 27017, } db_mongo = MongoEngine(app) # noqa: F841 app_builder = AppBuilder( # noqa: F841 app, security_manager_class=SecurityManager) cli_runner = app.test_cli_runner() app_builder.sm.role_model.objects(name__nin=[ app_builder.sm.auth_role_public, app_builder.sm.auth_role_admin, ]).delete() path = os.path.join(tmp_dir, "roles.json") with open(path, "w") as fd: fd.write(json.dumps(self.expected_roles)) # before import roles on dst app include only Admin and Public self.assertEqual(len(app_builder.sm.get_all_roles()), 2) import_result = cli_runner.invoke(import_roles, [f"--path={path}"]) self.assertEqual(import_result.exit_code, 0) resulting_roles = app_builder.sm.get_all_roles() for expected_role in self.expected_roles: match = [ r for r in resulting_roles if r.name == expected_role["name"] ] self.assertTrue(match) resulting_role = match[0] expected_role_permission_view_menus = { (pvm["permission"]["name"], pvm["view_menu"]["name"]) for pvm in expected_role["permissions"] } resulting_role_permission_view_menus = { (pvm.permission.name, pvm.view_menu.name) for pvm in resulting_role.permissions } self.assertTrue( all([ pvm in resulting_role_permission_view_menus for pvm in expected_role_permission_view_menus ]))
def setUp(self): from flask import Flask # pylint: disable=C0415,E0401 from flask_appbuilder import AppBuilder # pylint: disable=C0415,E0401 self.app = Flask(__name__) self.app.config.from_object('tests.test_config') self.app.config['PREFERRED_URL_SCHEME'] = 'https' self.db = SQLA(self.app) # pylint: disable=invalid-name self.appbuilder = AppBuilder( self.app, self.db.session, security_manager_class=CustomSecurityManager)
def test___search_ldap_filter(self): """ LDAP: test `_search_ldap` method (with AUTH_LDAP_SEARCH_FILTER) """ # MockLdap needs non-bytes for search filters, so we patch `memberOf` # to a string, only for this test with patch.dict( self.directory[self.user_alice[0]], { "memberOf": [ i.decode() for i in self.directory[self.user_alice[0]]["memberOf"] ] }, ): _mockldap = MockLdap(self.directory) _mockldap.start() _ldapobj = _mockldap["ldap://localhost/"] self.app.config[ "AUTH_LDAP_BIND_USER"] = "******" self.app.config["AUTH_LDAP_BIND_PASSWORD"] = "******" self.app.config["AUTH_LDAP_SEARCH"] = "ou=users,o=test" self.app.config[ "AUTH_LDAP_SEARCH_FILTER"] = "(memberOf=cn=staff,ou=groups,o=test)" self.appbuilder = AppBuilder(self.app, self.db.session) sm = self.appbuilder.sm # prepare `con` object con = ldap.initialize("ldap://localhost/") sm._ldap_bind_indirect(ldap, con) # run `_search_ldap` method user_dn, user_info = sm._search_ldap(ldap, con, "alice") # validate - search returned expected data self.assertEqual(user_dn, self.user_alice[0]) self.assertEqual(user_info["givenName"], self.user_alice[1]["givenName"]) self.assertEqual(user_info["sn"], self.user_alice[1]["sn"]) self.assertEqual(user_info["email"], self.user_alice[1]["email"]) # validate - expected LDAP methods were called self.assertEqual( _ldapobj.methods_called(with_args=True), [ self.call_initialize, self.call_bind_admin, self.call_search_alice_filter, ], )
def create_app(config): """AUTH app factory method.""" app = Flask(__name__) app.config.from_object(config) app.config.from_envvar("CONFIG_ENV", silent=True) db = SQLAlchemy(app) Session(app) Autodoc(app) handler = RotatingFileHandler(app.config.get('FLASK_LOG_PATH', "{0}/{1}". \ format(os.path.abspath(os.path.dirname(__file__)), "authapp.log")), maxBytes=1024 * 1024 * 10, backupCount=13) app.config.setdefault('LOG_NAME', 'authapp') Logging(app, handler) return app, AppBuilder(app, db.session, security_manager_class=security_manager.SecurityManager, \ update_perms=app.config['AUTO_UPDATE_PERM'], indexview=security_manager.IndexView)
def create_app(config_name=None, indexview=None, security_manager_class=None): global app, db, appbuilder app = Flask(__name__) app.wsgi_app = ProxyFix(app.wsgi_app) app.config.from_object('config') if config_name: app.config.from_pyfile(config_name) db = SQLA(app) appbuilder = AppBuilder(app, db.session, indexview=indexview, security_manager_class=security_manager_class) return app
def setUp(self): from flask import Flask from flask_wtf import CSRFProtect from flask_appbuilder import AppBuilder self.app = Flask(__name__) self.app.config["SQLALCHEMY_DATABASE_URI"] = "sqlite:///" self.app.config["SECRET_KEY"] = "thisismyscretkey" self.app.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = False self.app.config["WTF_CSRF_ENABLED"] = True self.csrf = CSRFProtect(self.app) self.db = SQLA(self.app) self.appbuilder = AppBuilder(self.app, self.db.session) self.create_admin_user(self.appbuilder, USERNAME, PASSWORD)
def setUp(self): self.app = Flask(__name__) self.app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite://' self.app.config['CSRF_ENABLED'] = False self.app.config['SECRET_KEY'] = 'thisismyscretkey' self.app.config['WTF_CSRF_ENABLED'] = False self.app.config['TESTING'] = True self.app.config['DEBUG'] = True self.db = SQLA(self.app) app.db = self.db Migrate(self.app, self.db) self.appbuilder = AppBuilder(self.app, self.db.session) with self.app.app_context(): upgrade()
def setUp(self): self.app = Flask(__name__) self.app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///' self.app.config['SECRET_KEY'] = 'secret_key' self.app.config['CSRF_ENABLED'] = False self.app.config['WTF_CSRF_ENABLED'] = False self.db = SQLA(self.app) self.appbuilder = AppBuilder(self.app, self.db.session, security_manager_class=AirflowSecurityManager) self.security_manager = self.appbuilder.sm self.appbuilder.add_view(SomeBaseView, "SomeBaseView", category="BaseViews") self.appbuilder.add_view(SomeModelView, "SomeModelView", category="ModelViews") role_admin = self.security_manager.find_role('Admin') self.user = self.appbuilder.sm.add_user('admin', 'admin', 'user', '*****@*****.**', role_admin, 'general') log.debug("Complete setup!")