Commit 65251eb0 authored by Lukas Burgey's avatar Lukas Burgey
Browse files

Add activation and deactivation of users

parent 40e8e0a2
......@@ -31,7 +31,7 @@ ch.setFormatter(formatter)
logger.addHandler(ch)
logger.debug('logging initialized')
logger.info('LOGGER INITIALIZED')
def log_exception(exception):
......
......@@ -189,20 +189,17 @@ class RabbitMQInstance(models.Model):
# PUBLIC API
def register_site(self, site):
logger.info(self.msg('register: {}'.format(
print_client(site.client))))
self.create_user(site)
self.set_permissions(site)
self.set_topic_permissions(site)
logger.info(self.msg('registered {}'.format(site.client)))
def update_site(self, site):
self.set_topic_permissions(site)
logger.info(self.msg('updated permissions for {}'.format(
print_client(site.client))))
logger.info(self.msg('updated permissions for {}'.format(site.client)))
def deregister_site(self, site):
logger.info(self.msg('deregistered {}'.format(
print_client(site.client))))
logger.info(self.msg('deregistered {}'.format(site.client)))
def is_client_connected(self, site):
connections = self.rest_get("connections/")
......@@ -254,17 +251,63 @@ class User(AbstractUser):
password = models.CharField(max_length=150, blank=True, null=True)
# we hide deleted keys here
# the full list of ssh keys is at self._ssh_keys
# the full list of ssh keys is self._ssh_keys
@property
def ssh_keys(self):
return self._ssh_keys.filter(deleted=False)
def __str__(self):
if self.user_type == 'admin':
return 'ADMIN {}'.format(self.username)
if self.user_type == 'oidcuser':
if not self.is_active:
return 'DEACTIVATED USER {}'.format(self.username)
return 'USER {}'.format(self.username)
if self.user_type == 'apiclient':
return 'APICLIENT {}@{}'.format(self.username, self.site)
def print_client(user):
return '{}@{}'.format(
user.username,
user.site,
)
def msg(self, msg):
return '[{}] {}'.format(self, msg)
# oidcuser: withdraw and delete all credentials and delete the user
def remove(self):
if self.user_type == 'oidcuser':
self.deactivate()
logger.info(self.msg('Deleting'))
# TODO: deleting the user brings problems:
# the deletion cascades down to DeploymentTask and DeploymentTaskItem
# but these need to be conserved so all clients withdrawals can be tracked
self.delete()
def activate(self):
if self.is_active:
logger.error(self.msg('already activated'))
return
if self.user_type == 'oidcuser':
self.is_active = True
self.save()
for dep in self.deployments.all():
dep.activate()
logger.info(self.msg('activated'))
# oidcuser: withdraw all credentials
def deactivate(self):
if not self.is_active:
logger.error(self.msg('already deactivated'))
return
if self.user_type == 'oidcuser':
self.is_active = False
self.save()
for dep in self.deployments.all():
dep.deactivate()
logger.info(self.msg('deactivated'))
def construct_user(user_info):
......@@ -361,6 +404,10 @@ class SSHPublicKey(models.Model):
# Deployment describes the credential state per user as it is supposed to be
#
# (exception: if is_active=False the ssh_keys contain the keys to be deployed
# if the deployment is reactivated)
#
# DeploymentTask is what is sent to the clients via rabbitmq
# The DeploymentTaskItem track the acknowledgements from the clients
class Deployment(models.Model):
......@@ -374,19 +421,18 @@ class Deployment(models.Model):
related_name='deployments',
on_delete=models.CASCADE,
)
# SET_NULL: we allow credentials to be deleted after deployment
ssh_keys = models.ManyToManyField(
SSHPublicKey,
related_name='deployments',
blank=True,
)
# these ssh keys are to be withdrawn by the clients
ssh_keys_to_withdraw = models.ManyToManyField(
SSHPublicKey,
related_name='withdrawn_deployments',
blank=True,
)
is_active = models.BooleanField(
default=True)
@property
def withdrawals(self):
......@@ -399,14 +445,40 @@ class Deployment(models.Model):
def __str__(self):
return '{}:{}'.format(self.service, self.user)
def deploy_key(self, key):
self.ssh_keys.add(key)
def msg(self, msg):
return '[Deployment:{}] {}'.format(self, msg)
if key in self.ssh_keys_to_withdraw.all():
self.ssh_keys_to_withdraw.remove(key)
# deploy credentials which were deployed prior to deactivation
def activate(self):
if self.is_active:
logger.error(self.msg('already active'))
return
logger.debug(self.msg(str(self.ssh_keys.all())))
for key in self.ssh_keys.all():
self._deploy_key(key)
self.is_active = True
self.save()
logger.info(self.msg('activated'))
# withdraw all credentials
def deactivate(self):
if not self.is_active:
logger.error(self.msg('already deactivated'))
return
self.is_active = False
self.save()
# and delete outstanding tasks which are made obsolete by this task
for key in self.ssh_keys.all():
self._withdraw_key(key)
logger.info(self.msg('deactivated'))
# only deploy the key
def _deploy_key(self, key):
# delete outstanding tasks which are made obsolete by this task
for withdrawal in self.withdrawals.filter(key=key):
logger.debug(withdrawal.msg('now obsolete'))
withdrawal.delete()
......@@ -432,14 +504,8 @@ class Deployment(models.Model):
# publish the task
task.publish()
def withdraw_key(self, key):
self.ssh_keys.remove(key)
# keys which are to be withdrawn by the clients
self.ssh_keys_to_withdraw.add(key)
self.save()
# and delete outstanding tasks which are made obsolete by this task
def _withdraw_key(self, key):
# delete outstanding tasks which are made obsolete by this task
for deploy in self.deploys.filter(key=key):
logger.debug(deploy.msg("now obsolete"))
deploy.delete()
......@@ -465,6 +531,34 @@ class Deployment(models.Model):
# publish the task
task.publish()
# deploy key and track changes in the key lists
def deploy_key(self, key):
if not self.is_active:
logger.error(self.msg('cannot deploy while deactivated'))
raise Exception('deployment deactivated')
self.ssh_keys.add(key)
if key in self.ssh_keys_to_withdraw.all():
self.ssh_keys_to_withdraw.remove(key)
self.save()
self._deploy_key(key)
# withdraw key and track changes in the key lists
def withdraw_key(self, key):
if not self.is_active:
logger.error(self.msg('cannot withdraw while deactivated'))
raise Exception('deployment deactivated')
self.ssh_keys.remove(key)
# keys which are to be withdrawn by the clients
self.ssh_keys_to_withdraw.add(key)
self.save()
self._withdraw_key(key)
class DeploymentTask(models.Model):
ACTION_CHOICES = (
......@@ -495,8 +589,7 @@ class DeploymentTask(models.Model):
return self.deployment.service
def __str__(self):
return "{}:{}:{}:{} - {}".format(
self.id,
return "{}:{}:{} - {}".format(
self.deployment.service,
self.deployment.user,
self.key,
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment