Commit c3c2c7cd authored by Lukas Burgey's avatar Lukas Burgey
Browse files

Implement external authentication for the RabbitMQ instance

parent 437f501b
...@@ -8,23 +8,39 @@ from ...models import User, RabbitMQInstance ...@@ -8,23 +8,39 @@ from ...models import User, RabbitMQInstance
LOGGER = logging.getLogger(__name__) LOGGER = logging.getLogger(__name__)
def _check_vhost(request): def _valid_vhost(request):
if 'vhost' in request.POST and request.POST['vhost'] == RabbitMQInstance.load().vhost: if 'vhost' in request.POST and request.POST['vhost'] == RabbitMQInstance.load().vhost:
return True return True
LOGGER.error('illegal vhost requested') LOGGER.error('illegal vhost requested')
return False return False
def _check_permission(request): def _valid_permission(request):
if 'permission' in request.POST and request.POST['permission'] != 'write': if 'permission' in request.POST and request.POST['permission'] != 'write':
return True return True
LOGGER.error('illegal permission requested') LOGGER.error('illegal permission requested')
return False return False
def _valid_user(request):
if 'username' in request.POST:
valid = User.objects.filter(
user_type='apiclient',
username=request.POST['username'],
).exists()
if valid:
return True
LOGGER.error('illegal user requested')
return False
def _get_user(request): def _get_user(request):
if 'username' in request.POST: if 'username' in request.POST:
return User.objects.filter(user_type='apiclient').get(username=request.POST['username']) user = User.objects.filter(user_type='apiclient').get(username=request.POST['username'])
if user:
return user
LOGGER.error('unable to get user for request')
return None return None
# VIEWS
# client authentication for RabbitMQ # client authentication for RabbitMQ
def user_endpoint(request): def user_endpoint(request):
if 'username' in request.POST and 'password' in request.POST: if 'username' in request.POST and 'password' in request.POST:
...@@ -33,11 +49,7 @@ def user_endpoint(request): ...@@ -33,11 +49,7 @@ def user_endpoint(request):
user = authenticate(username=username, password=password) user = authenticate(username=username, password=password)
if user: if user:
LOGGER.info('Authenticated client as %s', user) LOGGER.info('Authenticated client as %s', user)
return HttpResponse("allow")
if user.is_superuser:
return HttpResponse("allow administrator")
return HttpResponse("allow management")
LOGGER.error('Failed to authenticate user for RabbitMQ') LOGGER.error('Failed to authenticate user for RabbitMQ')
return HttpResponse("deny") return HttpResponse("deny")
...@@ -46,44 +58,47 @@ def user_endpoint(request): ...@@ -46,44 +58,47 @@ def user_endpoint(request):
# client authorization checks for RabbitMQ # client authorization checks for RabbitMQ
def vhost(request): def vhost(request):
# check if on the correct virtual host # check if on the correct virtual host
if _check_vhost(request): if _valid_vhost(request) and _valid_user(request):
return HttpResponse("allow") return HttpResponse("allow")
LOGGER.error('Authorization check for vhost failed for %s', request.POST) LOGGER.error('Authorization check for vhost failed for %s', request.POST)
return HttpResponse("deny") return HttpResponse("deny")
def resource(request): def resource(request):
if _check_vhost(request): if not _valid_vhost(request) or not _valid_user(request):
return HttpResponse('deny')
if 'resource' in request.POST and 'name' in request.POST:
if request.POST['resource'] == 'queue': if 'resource' in request.POST and 'name' in request.POST:
# the temporary queue a client binds to our exchange if request.POST['resource'] == 'queue':
if request.POST['name'].startswith('amq.gen-'): # the temporary queue a client binds to our exchange
return HttpResponse('allow') if request.POST['name'].startswith('amq.gen-'):
elif request.POST['resource'] == 'exchange' and _check_permission(request): return HttpResponse('allow')
# our exchange elif request.POST['resource'] == 'exchange' and _valid_permission(request):
if request.POST['name'] == RabbitMQInstance.load().exchange: # our exchange
return HttpResponse('allow') if request.POST['name'] == RabbitMQInstance.load().exchange:
elif request.POST['resource'] == 'topic' and _check_permission(request): return HttpResponse('allow')
pass elif request.POST['resource'] == 'topic' and _valid_permission(request):
pass
LOGGER.error('Authorization check for resource failed for %s', request.POST) LOGGER.error('Authorization check for resource failed for %s', request.POST)
return HttpResponse("deny") return HttpResponse('deny')
def topic(request): def topic(request):
# check if on the correct virtual host # check if on the correct virtual host
if _check_vhost(request) and _check_permission(request): if not _valid_vhost(request) or not _valid_permission(request) or not _valid_user(request):
user = _get_user(request) return HttpResponse('deny')
if user:
if 'routing_key' in request.POST: user = _get_user(request)
routing_key = request.POST['routing_key'] if user and 'routing_key' in request.POST:
if routing_key.startswith('service.'): routing_key = request.POST['routing_key']
m = re.search('service.(.+)', routing_key) if routing_key.startswith('service.'):
if m: match = re.search('service.(.+)', routing_key)
service_name = m.group(1) if match:
for service in user.site.services.all(): service_name = match.group(1)
if service_name == service.name: for service in user.site.services.all():
return HttpResponse('allow') if service_name == service.name:
return HttpResponse('allow')
LOGGER.error('Authorization check for topic failed for %s', request.POST) LOGGER.error('Authorization check for topic failed for %s', request.POST)
return HttpResponse('deny') return HttpResponse('deny')
...@@ -121,9 +121,6 @@ class AuthCallback(View): ...@@ -121,9 +121,6 @@ class AuthCallback(View):
login(request, user) login(request, user)
LOGGER.info('AuthCallback: IdP %s authenticated user as %s', oidc_config, user) LOGGER.info('AuthCallback: IdP %s authenticated user as %s', oidc_config, user)
# TODO is this needed?
# response.set_cookie('sessionid', request.COOKIES['sessionid'])
return response return response
except AuthException as exception: except AuthException as exception:
...@@ -137,7 +134,6 @@ class AuthCallback(View): ...@@ -137,7 +134,6 @@ class AuthCallback(View):
class LogoutView(views.APIView): class LogoutView(views.APIView):
def post(self, request): def post(self, request):
LOGGER.debug('logged out %s', request.user) LOGGER.debug('logged out %s', request.user)
# TODO should we logout the user at the oidc client?
logout(request) logout(request)
return Response({}) return Response({})
......
...@@ -69,9 +69,6 @@ class RabbitMQInstance(SingletonModel): ...@@ -69,9 +69,6 @@ class RabbitMQInstance(SingletonModel):
max_length=150, max_length=150,
default='guest', default='guest',
) )
is_active = models.BooleanField(
default=True,
)
def __str__(self): def __str__(self):
return self.host return self.host
......
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