from django.conf import settings
from django.contrib import auth as django_contrib_auth
from django.utils.deprecation import MiddlewareMixin
from django.utils.functional import SimpleLazyObject
from . import auth as usermerge_auth

# Create your middleware here.
# https://docs.djangoproject.com/en/2.0/topics/http/middleware/

# AuthenticationMiddleware is a middleware component that associates the current user with every incoming web request. Original source code for the get_user() function and the aforementioned component can be found in https://github.com/django/django/blob/master/django/contrib/auth/middleware.py (for more information, see https://docs.djangoproject.com/en/2.0/ref/middleware/#django.contrib.auth.middleware.AuthenticationMiddleware).
# For more information on default/customizing user authentication and password management, see https://docs.djangoproject.com/en/2.0/topics/auth/, auth.py and backends.py .
# The login() function of the application's authentication module (usermerge.auth) is used to log a user (usermerge.{User/Admin} instance) in via the login page of the application - see the log_in() view - and stores the PLATFORM_SESSION_KEY value in the session data based on the platform (name) selected in the corresponding form. On the other hand, the login() function of the default authentication module (django.contrib.auth) is used to log a user (auth.User instance) in via the login page of the admin site (see https://docs.djangoproject.com/en/2.0/ref/contrib/admin/) and does not store any PLATFORM_SESSION_KEY value in the session data as the corresponding form does not include any platform field.

def get_user(request):
    if not hasattr(request, '_cached_user'):
        # If the PLATFORM_SESSION_KEY value exists in the session data, retrieve the user instance associated with the given request
        # session by using the get_user() function of the application's authentication module. Otherwise, retrieve it by using the
        # get_user() function of the default authentication module. For more information, see the relative comment at the top.
        if usermerge_auth.PLATFORM_SESSION_KEY in request.session:
            request._cached_user = usermerge_auth.get_user(request)
        else:
            request._cached_user = django_contrib_auth.get_user(request)
    return request._cached_user

class AuthenticationMiddleware(MiddlewareMixin):
    def process_request(self, request):
        assert hasattr(request, 'session'), (
            'The Django authentication middleware requires session middleware to be installed. Edit your MIDDLEWARE%s setting to '
            'insert "django.contrib.sessions.middleware.SessionMiddleware" before "usermerge.middleware.AuthenticationMiddleware".'
        ) % ('_CLASSES' if settings.MIDDLEWARE is None else '')
        request.user = SimpleLazyObject(lambda: get_user(request))