Add an alembic migration for the full initial database with the data. Switch LDAP to using bind and creating a federated login entry. Add LDAP support to the registry and index endpoints. Add a username transliteration and suggestion mechanism. Switch the database and model to require a manual initialization call.
This commit is contained in:
parent
08ccad7fe4
commit
5fdccfe3e6
12 changed files with 739 additions and 75 deletions
|
@ -8,11 +8,17 @@ from data.database import *
|
|||
from util.validation import *
|
||||
from util.names import format_robot_username
|
||||
|
||||
from app import storage as store
|
||||
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
transaction_factory = app.config['DB_TRANSACTION_FACTORY']
|
||||
|
||||
|
||||
class Config(object):
|
||||
def __init__(self):
|
||||
self.app_config = None
|
||||
self.store = None
|
||||
|
||||
config = Config()
|
||||
|
||||
|
||||
class DataModelException(Exception):
|
||||
pass
|
||||
|
@ -58,7 +64,7 @@ class InvalidBuildTriggerException(DataModelException):
|
|||
pass
|
||||
|
||||
|
||||
def create_user(username, password, email, is_organization=False):
|
||||
def create_user(username, password, email, add_change_pw_notification=True):
|
||||
if not validate_email(email):
|
||||
raise InvalidEmailAddressException('Invalid email address: %s' % email)
|
||||
|
||||
|
@ -97,7 +103,7 @@ def create_user(username, password, email, is_organization=False):
|
|||
|
||||
# If the password is None, then add a notification for the user to change
|
||||
# their password ASAP.
|
||||
if not pw_hash and not is_organization:
|
||||
if not pw_hash and add_change_pw_notification:
|
||||
create_notification('password_required', new_user)
|
||||
|
||||
return new_user
|
||||
|
@ -105,10 +111,18 @@ def create_user(username, password, email, is_organization=False):
|
|||
raise DataModelException(ex.message)
|
||||
|
||||
|
||||
def is_username_unique(test_username):
|
||||
try:
|
||||
User.get((User.username == test_username))
|
||||
return False
|
||||
except User.DoesNotExist:
|
||||
return True
|
||||
|
||||
|
||||
def create_organization(name, email, creating_user):
|
||||
try:
|
||||
# Create the org
|
||||
new_org = create_user(name, None, email, is_organization=True)
|
||||
new_org = create_user(name, None, email, add_change_pw_notification=False)
|
||||
new_org.organization = True
|
||||
new_org.save()
|
||||
|
||||
|
@ -340,18 +354,16 @@ def attach_federated_login(user, service_name, service_id):
|
|||
|
||||
|
||||
def verify_federated_login(service_name, service_id):
|
||||
selected = FederatedLogin.select(FederatedLogin, User)
|
||||
with_service = selected.join(LoginService)
|
||||
with_user = with_service.switch(FederatedLogin).join(User)
|
||||
found = with_user.where(FederatedLogin.service_ident == service_id,
|
||||
LoginService.name == service_name)
|
||||
|
||||
found_list = list(found)
|
||||
|
||||
if found_list:
|
||||
return found_list[0].user
|
||||
|
||||
return None
|
||||
try:
|
||||
found = (FederatedLogin
|
||||
.select(FederatedLogin, User)
|
||||
.join(LoginService)
|
||||
.switch(FederatedLogin).join(User)
|
||||
.where(FederatedLogin.service_ident == service_id, LoginService.name == service_name)
|
||||
.get())
|
||||
return found.user
|
||||
except FederatedLogin.DoesNotExist:
|
||||
return None
|
||||
|
||||
|
||||
def list_federated_logins(user):
|
||||
|
@ -935,7 +947,7 @@ def __translate_ancestry(old_ancestry, translations, repository, username):
|
|||
|
||||
def find_create_or_link_image(docker_image_id, repository, username,
|
||||
translations):
|
||||
with transaction_factory(db):
|
||||
with config.app_config['DB_TRANSACTION_FACTORY'](db):
|
||||
repo_image = get_repo_image(repository.namespace, repository.name,
|
||||
docker_image_id)
|
||||
if repo_image:
|
||||
|
@ -1018,7 +1030,7 @@ def set_image_size(docker_image_id, namespace_name, repository_name,
|
|||
|
||||
def set_image_metadata(docker_image_id, namespace_name, repository_name,
|
||||
created_date_str, comment, command, parent=None):
|
||||
with transaction_factory(db):
|
||||
with config.app_config['DB_TRANSACTION_FACTORY'](db):
|
||||
query = (Image
|
||||
.select(Image, ImageStorage)
|
||||
.join(Repository)
|
||||
|
@ -1098,10 +1110,10 @@ def garbage_collect_repository(namespace_name, repository_name):
|
|||
image_to_remove.storage.uuid)
|
||||
uuids_to_check_for_gc.add(image_to_remove.storage.uuid)
|
||||
else:
|
||||
image_path = store.image_path(namespace_name, repository_name,
|
||||
image_to_remove.docker_image_id, None)
|
||||
image_path = config.store.image_path(namespace_name, repository_name,
|
||||
image_to_remove.docker_image_id, None)
|
||||
logger.debug('Deleting image storage: %s', image_path)
|
||||
store.remove(image_path)
|
||||
config.store.remove(image_path)
|
||||
|
||||
image_to_remove.delete_instance()
|
||||
|
||||
|
@ -1116,10 +1128,9 @@ def garbage_collect_repository(namespace_name, repository_name):
|
|||
for storage in storage_to_remove:
|
||||
logger.debug('Garbage collecting image storage: %s', storage.uuid)
|
||||
storage.delete_instance()
|
||||
image_path = store.image_path(namespace_name, repository_name,
|
||||
image_to_remove.docker_image_id,
|
||||
storage.uuid)
|
||||
store.remove(image_path)
|
||||
image_path = config.store.image_path(namespace_name, repository_name,
|
||||
image_to_remove.docker_image_id, storage.uuid)
|
||||
config.store.remove(image_path)
|
||||
|
||||
return len(to_remove)
|
||||
|
||||
|
@ -1489,8 +1500,8 @@ def get_pull_credentials(robotname):
|
|||
return {
|
||||
'username': robot.username,
|
||||
'password': login_info.service_ident,
|
||||
'registry': '%s://%s/v1/' % (app.config['PREFERRED_URL_SCHEME'],
|
||||
app.config['SERVER_HOSTNAME']),
|
||||
'registry': '%s://%s/v1/' % (config.app_config['PREFERRED_URL_SCHEME'],
|
||||
config.app_config['SERVER_HOSTNAME']),
|
||||
}
|
||||
|
||||
|
||||
|
|
Reference in a new issue