Commit b0f2d9b3 authored by lukas.burgey's avatar lukas.burgey

Merge branch 'dev'

parents 446773f6 ef8a0bd7
Pipeline #110567 passed with stage
in 1 minute and 23 seconds
......@@ -226,19 +226,9 @@ class VODeployment(Deployment):
created_new_states = False
for service in self.services:
state, created = DeploymentState.objects.get_or_create(
user=self.user,
userinfo=self.user.userinfo,
site=service.site,
service=service,
service_name=service.name,
)
_, created = DeploymentState.get_or_create(self.user, service, self)
if created:
LOGGER.debug(state.msg('Created'))
state.bind_to_deployment(self) # make sure the state is bound to us
created_new_states = created
created_new_states = True
return created_new_states
......@@ -257,19 +247,9 @@ class VODeployment(Deployment):
def service_added(self, service):
LOGGER.debug(self.msg('Adding service {}'.format(service)))
state, created = DeploymentState.objects.get_or_create(
user=self.user,
userinfo=self.user.userinfo,
site=service.site,
service=service,
service_name=service.name,
)
if created:
LOGGER.debug(state.msg('Created'))
state, _ = DeploymentState.get_or_create(self.user, service, self)
state.bind_to_deployment(self) # make sure the state is bound to us
if self.state_target == DEPLOYED:
if state is not None and self.state_target == DEPLOYED:
state.publish_to_client()
state.publish_to_user()
......@@ -310,18 +290,7 @@ class ServiceDeployment(Deployment):
raise ValueError('User is not permitted to have a deployment of this service!')
def _assure_states_exist(self):
state, created = DeploymentState.objects.get_or_create(
user=self.user,
userinfo=self.user.userinfo,
site=self.service.site,
service=self.service,
service_name=self.service.name,
)
if created:
LOGGER.debug(state.msg('Created'))
state.bind_to_deployment(self) # make sure the state is bound to us
_, created = DeploymentState.get_or_create(self.user, self.service, self)
return created
@classmethod
......@@ -462,6 +431,34 @@ class DeploymentState(models.Model):
return False
@classmethod
def get_or_create(cls, user, service, deployment):
try:
state, created = cls.objects.get_or_create(
user=user,
site=service.site,
service=service,
defaults={
'userinfo': user.userinfo,
'service_name': service.name,
}
)
if created:
LOGGER.debug(state.msg('Created'))
state.bind_to_deployment(deployment)
return state, created
except cls.MultipleObjectsReturned:
LOGGER.error(
'Multiple DeploymentStates for %s and %s and %s',
user,
service,
deployment,
)
return None, False
# adds the deployment to our related deployments
def bind_to_deployment(self, deployment):
if not self.deployments.filter(id=deployment.id).exists():
......@@ -513,6 +510,9 @@ class DeploymentState(models.Model):
LOGGER.debug(self.msg('Patched by client: {} - {}'.format(self.state, self.message)))
if self.state == NOT_DEPLOYED and self.is_orphaned:
# publish one last time so the webpage displays "not_deployed"
self.publish_to_user()
LOGGER.debug(self.msg('Deleting'))
# don't delete 'self' but the DepState via its id
DeploymentState.objects.get(id=self.id).delete()
......@@ -554,17 +554,17 @@ class DeploymentState(models.Model):
QUESTIONNAIRE: self.publish_to_user, # needs answers
},
NOT_DEPLOYED: {
DEPLOYED: REMOVAL_PENDING, # needs to get removed
DEPLOYMENT_PENDING: NOT_DEPLOYED, # aborting a deployment
DEPLOYED: [REMOVAL_PENDING, self.publish_to_user, self.publish_to_client], # needs to get removed
DEPLOYMENT_PENDING: [NOT_DEPLOYED, self.publish_to_user], # aborting a deployment
NOT_DEPLOYED: None, # already reached correct state
REMOVAL_PENDING: None, # already on the way to the correct state
# these four states indicate that the last deployment run was not successful
# we therefore can turn around an say that the we reached the NOT_DEPLOYED state
FAILED: NOT_DEPLOYED,
FAILED_PERMANENTLY: NOT_DEPLOYED,
REJECTED: NOT_DEPLOYED,
QUESTIONNAIRE: NOT_DEPLOYED,
FAILED: [NOT_DEPLOYED, self.publish_to_user],
FAILED_PERMANENTLY: [NOT_DEPLOYED, self.publish_to_user],
REJECTED: [NOT_DEPLOYED, self.publish_to_user],
QUESTIONNAIRE: [NOT_DEPLOYED, self.publish_to_user],
},
}
self._apply_transition(state_transitions)
......@@ -629,6 +629,7 @@ class DeploymentState(models.Model):
# same state
if self.state != state:
LOGGER.debug(self.msg('Target: {} | State: {} -> {}'.format(self.state_target, self.state, state)))
self.state = state
# reset the failed attempts if not failure
......@@ -637,8 +638,6 @@ class DeploymentState(models.Model):
self.save()
LOGGER.debug(self.msg('Target: {} | State: {} -> {}'.format(self.state_target, self.state, state)))
if publish_to_user:
self.publish_to_user()
......
......@@ -195,7 +195,11 @@ class User(AbstractUser):
# vo deployments
for dep in self.deployments.filter(vodeployment__vo=vo):
LOGGER.info(dep.msg('Deleting as user is not permitted anymore'))
states = list(dep.states.all())
dep.delete()
for state in states:
state.dep_target_changed() # inform the deployments states about its deletion
# service deployments
from feudal.backend.models.deployments import ServiceDeployment
......@@ -208,7 +212,11 @@ class User(AbstractUser):
if not still_permitted:
LOGGER.info(dep.msg('Deleting as user is not permitted anymore'))
states = list(dep.states.all())
dep.delete()
for state in states:
state.dep_target_changed() # inform the deployments states about its deletion
def _update_userinfo_entitlements(self, userinfo):
''' returns True if the entitlements changed in the userinfo '''
......
# pylint: disable=too-many-return-statements
import logging
import json
......@@ -19,25 +17,14 @@ ALLOW = HttpResponse('allow')
DENY = HttpResponse('deny')
### HELPERS FOR ALL ENDPOINTS ###
def _valid_vhost(request):
if request.POST.get('vhost') == RabbitMQInstance().vhost:
return True
LOGGER.error('illegal vhost requested')
return False
def _valid_permission(request):
perm = request.POST.get('permission', [])
if 'write' not in perm:
return True
LOGGER.info('Illegal permission requested %s', perm)
return False
def _valid_user(request):
return _apiclient_valid(request) or _webpage_client_userid(request)
def _apiclient_valid(request):
valid = User.objects.filter(
user_type=User.TYPE_CHOICE_DOWNSTREAM,
......@@ -47,13 +34,6 @@ def _apiclient_valid(request):
return True
return False
def _apiclient_get(request):
return User.objects.get(
user_type=User.TYPE_CHOICE_DOWNSTREAM,
username=request.POST.get('username'),
)
def _webpage_client_userid(request):
userid = ''
username = request.POST.get('username')
......@@ -64,6 +44,8 @@ def _webpage_client_userid(request):
return userid
### USER ENDPOINT ###
def _webpage_client_valid(request):
userid = _webpage_client_userid(request)
try:
......@@ -71,19 +53,15 @@ def _webpage_client_valid(request):
session_key=request.POST.get('password'),
)
sd = session.get_decoded()
if settings.DEBUG:
LOGGER.debug('Session data: %s', json.dumps(sd, sort_keys=True, indent=4))
LOGGER.log(settings.DEBUGX_LOG_LEVEL, 'Session data: %s', json.dumps(sd, sort_keys=True, indent=4))
return sd.get('_auth_user_id') == userid
except Session.DoesNotExist:
# LOGGER.info("User %s has no session", userid)
LOGGER.log(settings.DEBUGX_LOG_LEVEL, 'User %s has no session', userid)
return False
# VIEWS: authentication and authorization for
# apiclients and webpage-clients
def user_endpoint(request):
if _webpage_client_valid(request):
# LOGGER.info('Authenticated webpage client')
......@@ -103,6 +81,11 @@ def user_endpoint(request):
return DENY
### VHOST ENDPOINT ###
def _valid_user(request):
return _apiclient_valid(request) or _webpage_client_userid(request)
def vhost_endpoint(request):
# check if on the correct virtual host
if _valid_vhost(request) and _valid_user(request):
......@@ -112,6 +95,8 @@ def vhost_endpoint(request):
return DENY
### RESOURCE ENDPOINT ###
def _resource_authorized_webpage_client(request):
resource = request.POST.get('resource')
name = request.POST.get('name', '')
......@@ -128,7 +113,6 @@ def _resource_authorized_webpage_client(request):
and name == _webpage_client_userid(request)
)
def _resource_authorized_apiclient(request):
resource = request.POST.get('resource')
name = request.POST.get('name', '')
......@@ -142,7 +126,6 @@ def _resource_authorized_apiclient(request):
and 'write' not in permission
)
def resource_auth_decision(request, decision):
user = request.POST.get('username')
permission = request.POST.get('permission', [])
......@@ -153,7 +136,6 @@ def resource_auth_decision(request, decision):
return decision
def resource_endpoint(request):
if _valid_vhost(request):
if (
......@@ -171,6 +153,15 @@ def resource_endpoint(request):
return resource_auth_decision(request, DENY)
### TOPIC ENDPOINT ###
def _valid_permission(request):
perm = request.POST.get('permission', [])
if 'write' not in perm:
return True
LOGGER.info('Illegal permission requested %s', perm)
return False
def topic_auth_decision(request, decision):
user = request.POST.get('username')
permission = request.POST.get('permission', [])
......@@ -182,17 +173,15 @@ def topic_auth_decision(request, decision):
return decision
def topic_endpoint_webpageclient(request, webpage_client_userid):
try:
User.objects.get(id=webpage_client_userid)
return topic_auth_decision(request, ALLOW)
except User.DoesNotExist as error:
LOGGER.info(error)
except User.DoesNotExist:
LOGGER.log(settings.DEBUGX_LOG_LEVEL, 'Webpage client %s does not exist', webpage_client_userid)
return topic_auth_decision(request, DENY)
def topic_endpoint_apiclient(request, apiclient):
name = request.POST.get('name', '')
routing_key = request.POST.get('routing_key', '')
......@@ -242,19 +231,23 @@ def topic_endpoint_apiclient(request, apiclient):
return topic_auth_decision(request, DENY)
def topic_endpoint(request):
if not _valid_vhost(request) or not _valid_permission(request):
return DENY
webpage_client_userid = _webpage_client_userid(request)
LOGGER.log(settings.DEBUGX_LOG_LEVEL, 'Webpage client userid: %s', webpage_client_userid)
if webpage_client_userid != '':
return topic_endpoint_webpageclient(request, webpage_client_userid)
try:
apiclient = _apiclient_get(request)
apiclient = User.objects.get(
user_type=User.TYPE_CHOICE_DOWNSTREAM,
username=request.POST.get('username'),
)
return topic_endpoint_apiclient(request, apiclient)
except User.DoesNotExist as e:
LOGGER.debug('Auth: Topic endpoint: %s', e)
except User.DoesNotExist:
LOGGER.log(settings.DEBUGX_LOG_LEVEL, 'Apiclient %s does not exist', request.POST.get('username'))
return topic_auth_decision(request, DENY)
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