Add some logging and only permit backend CAS auth if the user is not already authenticated
This commit is contained in:
		@@ -16,11 +16,14 @@ from django.db import IntegrityError
 | 
			
		||||
from .cas import CASClient
 | 
			
		||||
from .models import FederatedUser, FederateSLO, User
 | 
			
		||||
 | 
			
		||||
import logging
 | 
			
		||||
from importlib import import_module
 | 
			
		||||
from six.moves import urllib
 | 
			
		||||
 | 
			
		||||
SessionStore = import_module(settings.SESSION_ENGINE).SessionStore
 | 
			
		||||
 | 
			
		||||
logger = logging.getLogger(__name__)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class CASFederateValidateUser(object):
 | 
			
		||||
    """Class CAS client used to authenticate the user again a CAS provider"""
 | 
			
		||||
@@ -88,6 +91,12 @@ class CASFederateValidateUser(object):
 | 
			
		||||
            slos = []
 | 
			
		||||
        for slo in slos:
 | 
			
		||||
            for federate_slo in FederateSLO.objects.filter(ticket=slo.text):
 | 
			
		||||
                logger.info(
 | 
			
		||||
                    "Got an SLO requests for ticket %s, logging out user %s" % (
 | 
			
		||||
                        federate_slo.username,
 | 
			
		||||
                        federate_slo.ticket
 | 
			
		||||
                    )
 | 
			
		||||
                )
 | 
			
		||||
                session = SessionStore(session_key=federate_slo.session_key)
 | 
			
		||||
                session.flush()
 | 
			
		||||
                try:
 | 
			
		||||
 
 | 
			
		||||
@@ -228,11 +228,12 @@ class CanLogin(object):
 | 
			
		||||
        self.assertEqual(response.status_code, code)
 | 
			
		||||
        # this message is displayed to the user upon successful authentication, so it should not
 | 
			
		||||
        # appear
 | 
			
		||||
        self.assertFalse(
 | 
			
		||||
        self.assertNotIn(
 | 
			
		||||
            (
 | 
			
		||||
                b"You have successfully logged into "
 | 
			
		||||
                b"the Central Authentication Service"
 | 
			
		||||
            ) in response.content
 | 
			
		||||
            ),
 | 
			
		||||
            response.content
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
        # if authentication has failed, these session variables should not be set
 | 
			
		||||
 
 | 
			
		||||
@@ -208,6 +208,7 @@ class FederateAuth(View):
 | 
			
		||||
    def post(self, request, provider=None):
 | 
			
		||||
        """method called on POST request"""
 | 
			
		||||
        if not settings.CAS_FEDERATE:
 | 
			
		||||
            logger.warning("CAS_FEDERATE is False, set it to True to use the federated mode")
 | 
			
		||||
            return redirect("cas_server:login")
 | 
			
		||||
        # POST with a provider, this is probably an SLO request
 | 
			
		||||
        try:
 | 
			
		||||
@@ -251,15 +252,26 @@ class FederateAuth(View):
 | 
			
		||||
    def get(self, request, provider=None):
 | 
			
		||||
        """method called on GET request"""
 | 
			
		||||
        if not settings.CAS_FEDERATE:
 | 
			
		||||
            logger.warning("CAS_FEDERATE is False, set it to True to use the federated mode")
 | 
			
		||||
            return redirect("cas_server:login")
 | 
			
		||||
        if self.request.session.get("authenticated"):
 | 
			
		||||
            logger.warning("User already authenticated, dropping federate authentication request")
 | 
			
		||||
            return redirect("cas_server:login")
 | 
			
		||||
        try:
 | 
			
		||||
            provider = FederatedIendityProvider.objects.get(suffix=provider)
 | 
			
		||||
            auth = self.get_cas_client(request, provider)
 | 
			
		||||
            if 'ticket' not in request.GET:
 | 
			
		||||
                logger.info("Trying to authenticate again %s" % auth.provider.server_url)
 | 
			
		||||
                return HttpResponseRedirect(auth.get_login_url())
 | 
			
		||||
            else:
 | 
			
		||||
                ticket = request.GET['ticket']
 | 
			
		||||
                if auth.verify_ticket(ticket):
 | 
			
		||||
                    logger.info(
 | 
			
		||||
                        "Got a valid ticket for %s from %s" % (
 | 
			
		||||
                            auth.username,
 | 
			
		||||
                            auth.provider.server_url
 | 
			
		||||
                        )
 | 
			
		||||
                    )
 | 
			
		||||
                    params = utils.copy_params(request.GET, ignore={"ticket"})
 | 
			
		||||
                    request.session["federate_username"] = auth.federated_username
 | 
			
		||||
                    request.session["federate_ticket"] = ticket
 | 
			
		||||
@@ -267,8 +279,15 @@ class FederateAuth(View):
 | 
			
		||||
                    url = utils.reverse_params("cas_server:login", params)
 | 
			
		||||
                    return HttpResponseRedirect(url)
 | 
			
		||||
                else:
 | 
			
		||||
                    logger.info(
 | 
			
		||||
                        "Got a invalid ticket for %s from %s. Retrying to authenticate" % (
 | 
			
		||||
                            auth.username,
 | 
			
		||||
                            auth.provider.server_url
 | 
			
		||||
                        )
 | 
			
		||||
                    )
 | 
			
		||||
                    return HttpResponseRedirect(auth.get_login_url())
 | 
			
		||||
        except FederatedIendityProvider.DoesNotExist:
 | 
			
		||||
            logger.warning("Identity provider suffix %s not found" % provider)
 | 
			
		||||
            return redirect("cas_server:login")
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user