diff --git a/app/api/externalauth.py b/app/api/externalauth.py index 5f9c564c..20ead5fa 100644 --- a/app/api/externalauth.py +++ b/app/api/externalauth.py @@ -3,7 +3,7 @@ from django.contrib.auth import login from rest_framework.views import APIView from rest_framework import exceptions, permissions, parsers from rest_framework.response import Response -from app.auth.backends import get_user_from_external_auth_response +from app.auth.backends import get_user_from_external_auth_response, cluster_mismatch import requests from webodm import settings @@ -30,6 +30,8 @@ class ExternalTokenAuth(APIView): if user is not None: login(request, user, backend='django.contrib.auth.backends.ModelBackend') return Response({'redirect': '/'}) + elif cluster_mismatch(res) and settings.CLUSTER_URL != '': + return Response({'redirect': settings.CLUSTER_URL % res['cluster_id']}) else: return Response({'error': 'Invalid credentials'}) else: diff --git a/app/auth/backends.py b/app/auth/backends.py index c3c13ea1..0a520753 100644 --- a/app/auth/backends.py +++ b/app/auth/backends.py @@ -8,11 +8,26 @@ import logging logger = logging.getLogger('app.logger') +def cluster_mismatch(res): + if settings.CLUSTER_ID is None: + return False + + if 'cluster_id' in res: + # Check cluster ID field + try: + return int(res['cluster_id']) != settings.CLUSTER_ID + except ValueError: + return True + return False + def get_user_from_external_auth_response(res): if 'message' in res or 'error' in res: return None if 'user_id' in res and 'username' in res: + if cluster_mismatch(res): + return None + try: user = User.objects.get(pk=res['user_id']) except User.DoesNotExist: diff --git a/webodm/settings.py b/webodm/settings.py index 8267a60c..5b4e3fdf 100644 --- a/webodm/settings.py +++ b/webodm/settings.py @@ -21,7 +21,7 @@ from django.contrib.messages import constants as messages BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) -# Quick-start development settings - unsuitable for production +# For best practices # See https://docs.djangoproject.com/en/1.10/howto/deployment/checklist/ try: @@ -370,6 +370,13 @@ NODE_OPTIMISTIC_MODE = False # URL to external auth endpoint EXTERNAL_AUTH_ENDPOINT = '' +# Enable cluster mode for this instance by setting an integer ID >= 1 +CLUSTER_ID = None + +# Set the Cluster URL pattern common to all servers in the cluster +# e.g. https://mycluster%s.mydomain +CLUSTER_URL = '' + # URL to a page where a user can reset the password RESET_PASSWORD_LINK = ''