Skip to content
Snippets Groups Projects
Commit 889dac69 authored by Art's avatar Art :lizard:
Browse files

Add LOGIN_PERM_CODENAME (log in requires permission if set)

parent e657c538
No related branches found
No related tags found
No related merge requests found
......@@ -34,6 +34,8 @@ SP_SLS_X_FRAME_OPTIONS = None # in case you encounter problems with SLS view no
GROUPS_SAML_ATTRIBUTE = "IDMGroups" # this SAML attribute is expected to contain list of groups for a user
GROUP_RESOLVER = "ssoauth.auth_utils.groups_from_saml2_dn_list" # in case you want to override how groups are resolved for users
LOGIN_PERM_CODENAME = None # None or str; value "can_log_in" will require this permission for users to log in
PREDEFINED_GROUPS = {
# Predefined groups and the corresponding permissions are here.
# Both groups and permissions are created/updated automatically after applying migrations.
......
......@@ -136,12 +136,20 @@ def cleanup_direct_permissions(user):
user.user_permissions.clear()
def set_user_compat_flags(user, user_is_active=True):
user.is_active = user_is_active # cannot do much with it, by default activates all users that came from SSO
def set_user_compat_flags(user):
def get_full_perm_name(codename):
return "{app}.{codename}".format(
app=get_user_model()._meta.app_label,
codename=codename,
)
# defaults are restrictive
user.is_staff = False
user.is_superuser = False
# superuser
# is_active must be initially set to True, otherwise has_perm() will not function
user.is_active = True
# is_superuser
try:
group_su = Group.objects.get(name=app_settings.SUPERUSER_GROUP_NAME)
if group_su in user.groups.all():
......@@ -149,14 +157,20 @@ def set_user_compat_flags(user, user_is_active=True):
user.is_superuser = True
except Group.DoesNotExist as e:
logger.error("Could not fetch the superuser group. Forgot to migrate?")
# staff
full_staff_perm_name = "{app}.{codename}".format(
app=get_user_model()._meta.app_label,
codename=app_settings.STAFF_PERM_CODENAME,
)
if user.has_perm(full_staff_perm_name):
logger.info("User {user} is staff (has admin access)".format(**locals()))
# is_staff
if user.has_perm(get_full_perm_name(app_settings.STAFF_PERM_CODENAME)):
logger.info("User {user} is staff (has admin access).".format(**locals()))
user.is_staff = True
# is_active (actually represents the log in permission)
if app_settings.LOGIN_PERM_CODENAME:
if user.has_perm(get_full_perm_name(app_settings.LOGIN_PERM_CODENAME)):
logger.info("User {user} is active.".format(**locals()))
user.is_active = True
else:
logger.info("User {user} is inactive (does not have LOGIN_PERM_CODENAME).".format(**locals()))
user.is_active = False
else:
user.is_active = True # without LOGIN_PERM_CODENAME every SSO user is considered active
# done
user.save()
......@@ -15,6 +15,8 @@ class Command(BaseCommand):
try:
self.ensure_group_exists(app_settings.SUPERUSER_GROUP_NAME)
self.ensure_permission_exists(app_settings.STAFF_PERM_CODENAME)
if app_settings.LOGIN_PERM_CODENAME:
self.ensure_permission_exists(app_settings.LOGIN_PERM_CODENAME)
except Exception as e:
raise CommandError("Could not ensure that compatibility groups and permissions exist. {0}".format(str(e)))
......
......@@ -74,13 +74,16 @@ class LogInView(SAMLMixin, View):
def get(self, request, *args, **kwargs):
if request.user.is_authenticated:
logger.warning("{u} is already authenticated and attempts to log in again.".format(u=request.user))
if self.already_authenticated_403:
logger.warning("Assuming 403 (you configured the view this way).")
raise exceptions.PermissionDenied()
if self.already_authenticated_redirect:
logger.warning("Redirecting (you configured the view this way).")
return http.HttpResponseRedirect(urls.reverse(self.already_authenticated_redirect))
if request.user.last_login > timezone.now() - timedelta(seconds=20):
# possible redirect loop (e.g. django.contrib.admin causes them)
logger.error("{u} is logging in too often (avoiding redirect loops)".format(u=request.user))
logger.error("{u} is logging in too often (probably an endless redirect loop).".format(u=request.user))
raise exceptions.PermissionDenied()
# logging in
auth = self.get_onelogin_auth(request)
......@@ -205,8 +208,13 @@ class ACSAuthNView(SAMLMixin, View):
auth_utils.set_user_compat_flags(user=user)
user.backend = app_settings.PRETEND_AUTH_BACKEND
request.user = user
if user.is_active:
contrib_auth.login(request, user)
logger.debug("Logged in {user}".format(**locals()))
else:
msg = "Inactive user attempted to log in: {user}".format(**locals())
logger.info(msg)
raise exceptions.PermissionDenied(msg)
@method_decorator(never_cache, "dispatch")
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment