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:
commit
635d8888ff
3 changed files with 84 additions and 19 deletions
|
@ -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
|
||||||
|
|
37
endpoints/api/suconfig_models_interface.py
Normal file
37
endpoints/api/suconfig_models_interface.py
Normal 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.
|
||||||
|
"""
|
33
endpoints/api/suconfig_models_pre_oci.py
Normal file
33
endpoints/api/suconfig_models_pre_oci.py
Normal 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()
|
Reference in a new issue