diff --git a/endpoints/api/suconfig.py b/endpoints/api/suconfig.py index 4b7bee5d3..dd90285bf 100644 --- a/endpoints/api/suconfig.py +++ b/endpoints/api/suconfig.py @@ -5,23 +5,22 @@ import os import signal from flask import abort + +from app import app, config_provider, superusers, OVERRIDE_CONFIG_DIRECTORY +from auth.permissions import SuperUserPermission +from auth.auth_context import get_authenticated_user +from data.database import configure +from data.runmigration import run_alembic_migration +from data.users import get_federated_service_name, get_users_handler +from endpoints.api.suconfig_models_pre_oci import pre_oci_model as model from endpoints.api import (ApiResource, nickname, resource, internal_only, show_if, require_fresh_login, request, validate_json_request, verify_not_prod, InvalidRequest) - from endpoints.common import common_login -from app import app, config_provider, superusers, OVERRIDE_CONFIG_DIRECTORY -from data import model -from data.database import configure -from auth.permissions import SuperUserPermission -from auth.auth_context import get_authenticated_user -from data.database import User from util.config.configutil import add_enterprise_config_defaults from util.config.database import sync_database_with_config from util.config.validator import validate_service_for_config, CONFIG_FILENAMES from util.license import decode_license, LicenseDecodeError -from data.runmigration import run_alembic_migration -from data.users import get_federated_service_name, get_users_handler import features @@ -34,16 +33,12 @@ def database_is_valid(): if app.config['TESTING']: return False - try: - list(User.select().limit(1)) - return True - except: - return False + return model.is_valid() def database_has_users(): """ Returns whether the database has any users defined. """ - return bool(list(User.select().limit(1))) + return model.has_users() @resource('/v1/superuser/registrystatus') @@ -230,7 +225,7 @@ class SuperUserConfig(ApiResource): abort(401) service_name = get_federated_service_name(config_object['AUTHENTICATION_TYPE']) - if not model.user.lookup_federated_login(current_user, service_name): + if not model.has_federated_login(current_user.username, service_name): # Verify the user's credentials and retrieve the user's external username+email. handler = get_users_handler(config_object, config_provider, OVERRIDE_CONFIG_DIRECTORY) (result, err_msg) = handler.verify_credentials(current_user.username, @@ -240,7 +235,7 @@ class SuperUserConfig(ApiResource): abort(400) # Link the existing user to the external user. - model.user.attach_federated_login(current_user, service_name, result.username) + model.attach_federated_login(current_user.username, service_name, result.username) # Ensure database is up-to-date with config sync_database_with_config(config_object) @@ -390,7 +385,7 @@ class SuperUserCreateInitialSuperUser(ApiResource): email = data['email'] # Create the user in the database. - superuser = model.user.create_user(username, password, email, auto_verify=True) + superuser_uuid = model.create_superuser(username, password, email) # Add the user to the config. config_object = config_provider.get_config() @@ -401,7 +396,7 @@ class SuperUserCreateInitialSuperUser(ApiResource): superusers.register_superuser(username) # Conduct login with that user. - common_login(superuser.uuid) + common_login(superuser_uuid) return { 'status': True diff --git a/endpoints/api/suconfig_models_interface.py b/endpoints/api/suconfig_models_interface.py new file mode 100644 index 000000000..13cd1e774 --- /dev/null +++ b/endpoints/api/suconfig_models_interface.py @@ -0,0 +1,37 @@ +from abc import ABCMeta, abstractmethod +from six import add_metaclass + +@add_metaclass(ABCMeta) +class SuperuserConfigDataInterface(object): + """ + Interface that represents all data store interactions required by the superuser config API. + """ + @abstractmethod + def is_valid(self): + """ + Returns true if the configured database is valid. + """ + + @abstractmethod + def has_users(self): + """ + Returns true if there are any users defined. + """ + + @abstractmethod + def create_superuser(self, username, password, email): + """ + Creates a new superuser with the given username, password and email. Returns the user's UUID. + """ + + @abstractmethod + def has_federated_login(self, username, service_name): + """ + Returns true if the matching user has a federated login under the matching service. + """ + + @abstractmethod + def attach_federated_login(self, username, service_name, federated_username): + """ + Attaches a federatated login to the matching user, under the given service. + """ diff --git a/endpoints/api/suconfig_models_pre_oci.py b/endpoints/api/suconfig_models_pre_oci.py new file mode 100644 index 000000000..9bcb40acd --- /dev/null +++ b/endpoints/api/suconfig_models_pre_oci.py @@ -0,0 +1,33 @@ +from data import model +from data.database import User +from endpoints.api.suconfig_models_interface import SuperuserConfigDataInterface + +class PreOCIModel(SuperuserConfigDataInterface): + def is_valid(self): + try: + list(User.select().limit(1)) + return True + except: + return False + + def has_users(self): + return bool(list(User.select().limit(1))) + + def create_superuser(self, username, password, email): + return model.user.create_user(username, password, email, auto_verify=True).uuid + + def has_federated_login(self, username, service_name): + user = model.user.get_user(username) + if user is None: + return False + + return bool(model.user.lookup_federated_login(user, service_name)) + + def attach_federated_login(self, username, service_name, federated_username): + user = model.user.get_user(username) + if user is None: + return False + + model.user.attach_federated_login(user, service_name, federated_username) + +pre_oci_model = PreOCIModel()