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