# Imports
import hashlib
from django.apps import apps as django_apps
from django.utils.crypto import get_random_string
from django.utils.timezone import now
import logging
from superdjango.conf import SUPERDJANGO
from superdjango.shortcuts import user_in_group
log = logging.getLogger(__name__)
# Exports
__all__ = (
"generate_session_key",
"get_user_impersonation_model",
"user_is_allowed_to_impersonate",
)
# Functions
[docs]def generate_session_key():
"""Generate a session key to identify an impersonation.
:rtype: str
"""
return hashlib.sha1('{0}:{1}'.format(get_random_string(), now()).encode('utf-8')).hexdigest()
[docs]def get_user_impersonation_model():
"""Get the model used to log impersonation history.
:rtype: ImpersonationHistoryModel | None
"""
if SUPERDJANGO.USER_IMPERSONATION_MODEL is None:
return None
try:
return django_apps.get_model(SUPERDJANGO.USER_IMPERSONATION_MODEL, require_ready=False)
except ValueError:
log.warning('SUPERDJANGO_USER_IMPERSONATION_MODEL must be in the form of "app_label.ModelName".')
return None
except LookupError:
message = 'SUPERDJANGO_USER_IMPERSONATION_MODEL refers to model "%s" which has not been installed.'
log.warning(message % SUPERDJANGO.USER_IMPERSONATION_MODEL)
return None
[docs]def user_is_allowed_to_impersonate(user):
"""Determine whether the given user is allowed to impersonate another user.
:param user: The user instance to be checked.
:type user: AUTH_USER_MODEL
:rtype: bool
"""
# Super users are always allowed.
if user.is_superuser:
return True
# Check staff users.
if SUPERDJANGO.USER_IMPERSONATION_ENABLED_FOR_STAFF and user.is_staff:
return True
# Check against group membership.
if SUPERDJANGO.USER_IMPERSONATION_ENABLED_FOR_GROUPS is not None:
for group in SUPERDJANGO.USER_IMPERSONATION_ENABLED_FOR_GROUPS:
if user_in_group(user, group):
return True
return False