Merge pull request #2819 from coreos-inc/joseph.schorr/QUAY-621/suconfig-api-data-model

Change suconfig to use a data model interface
This commit is contained in:
josephschorr 2017-07-24 18:40:49 -04:00 committed by GitHub
commit 635d8888ff
3 changed files with 84 additions and 19 deletions

View file

@ -5,23 +5,22 @@ import os
import signal import signal
from flask import abort 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, from endpoints.api import (ApiResource, nickname, resource, internal_only, show_if,
require_fresh_login, request, validate_json_request, verify_not_prod, require_fresh_login, request, validate_json_request, verify_not_prod,
InvalidRequest) InvalidRequest)
from endpoints.common import common_login 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.configutil import add_enterprise_config_defaults
from util.config.database import sync_database_with_config from util.config.database import sync_database_with_config
from util.config.validator import validate_service_for_config, CONFIG_FILENAMES from util.config.validator import validate_service_for_config, CONFIG_FILENAMES
from util.license import decode_license, LicenseDecodeError 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 import features
@ -34,16 +33,12 @@ def database_is_valid():
if app.config['TESTING']: if app.config['TESTING']:
return False return False
try: return model.is_valid()
list(User.select().limit(1))
return True
except:
return False
def database_has_users(): def database_has_users():
""" Returns whether the database has any users defined. """ """ Returns whether the database has any users defined. """
return bool(list(User.select().limit(1))) return model.has_users()
@resource('/v1/superuser/registrystatus') @resource('/v1/superuser/registrystatus')
@ -230,7 +225,7 @@ class SuperUserConfig(ApiResource):
abort(401) abort(401)
service_name = get_federated_service_name(config_object['AUTHENTICATION_TYPE']) 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. # Verify the user's credentials and retrieve the user's external username+email.
handler = get_users_handler(config_object, config_provider, OVERRIDE_CONFIG_DIRECTORY) handler = get_users_handler(config_object, config_provider, OVERRIDE_CONFIG_DIRECTORY)
(result, err_msg) = handler.verify_credentials(current_user.username, (result, err_msg) = handler.verify_credentials(current_user.username,
@ -240,7 +235,7 @@ class SuperUserConfig(ApiResource):
abort(400) abort(400)
# Link the existing user to the external user. # 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 # Ensure database is up-to-date with config
sync_database_with_config(config_object) sync_database_with_config(config_object)
@ -390,7 +385,7 @@ class SuperUserCreateInitialSuperUser(ApiResource):
email = data['email'] email = data['email']
# Create the user in the database. # 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. # Add the user to the config.
config_object = config_provider.get_config() config_object = config_provider.get_config()
@ -401,7 +396,7 @@ class SuperUserCreateInitialSuperUser(ApiResource):
superusers.register_superuser(username) superusers.register_superuser(username)
# Conduct login with that user. # Conduct login with that user.
common_login(superuser.uuid) common_login(superuser_uuid)
return { return {
'status': True 'status': True

View file

@ -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.
"""

View file

@ -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()