Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Django restrict/allow access by groups from ldap

I have Django project that has two apps App1 and App2) each app has only 1 view. . My project connected to openldap using django-auth-ldap. I have two groups(Group1, Group2).

I Added decorators before my views in app1 and app2 (@login_required) and the result as expected that all users from group1 and group2 will be able to login to both apps.

I want to be able to just allow group1 to access app1 only and group2 access app2 only.

I tried many codes but no one work with me.

Here is my code:

app1.views.py

from django.shortcuts import render
from django.template import loader
from django.http import HttpResponse
from django.contrib.auth.decorators import login_required
from django.contrib.auth import views as auth_views
@login_required(login_url='/accounts/login/')
def index(request):
    #getting our template
    template = loader.get_template('main/index.html')
    #rendering the template in HttpResponse
    return HttpResponse(template.render())

Here is my ldap settings from settings.py:

#Generated by 'django-admin startproject' using Django 1.11.


import os
import django



AUTHENTICATION_BACKENDS = ('django_auth_ldap.backend.LDAPBackend',)

import ldap
from django_auth_ldap.config import LDAPSearch, GroupOfNamesType


AUTH_LDAP_SERVER_URI = "ldap://mydomain.com"

AUTH_LDAP_BIND_DN = "cn=admin,dc=mydomain,dc=com"

AUTH_LDAP_BIND_PASSWORD = "mypass"

AUTH_LDAP_USER_SEARCH = LDAPSearch("ou=ou_org_unit,dc=mydomain,dc=com",
ldap.SCOPE_SUBTREE, "(uid=%(user)s)")

AUTH_LDAP_GROUP_SEARCH = LDAPSearch("ou=ou_org_unit,cn=group1,cn=group2,dc=mydomain,dc=com",
    ldap.SCOPE_SUBTREE, "(objectClass=groupOfNames)"
)

AUTH_LDAP_GROUP_TYPE = GroupOfNamesType()

AUTH_LDAP_USER_ATTR_MAP = {
    "first_name": "givenName",
    "last_name": "sn",
    "email": "mail"
}

AUTH_LDAP_FIND_GROUP_PERMS = True
AUTH_LDAP_CACHE_GROUPS = True
AUTH_LDAP_GROUP_CACHE_TIMEOUT = 3600
like image 423
Eyla Avatar asked Mar 09 '23 00:03

Eyla


1 Answers

First I would map a property to the user object that specifies which group the user is in:

AUTH_LDAP_USER_ATTR_MAP = {
    "first_name": "givenName",
    "last_name": "sn",
    "email": "mail",
    "ldap_group": "cn"   # not 100% sure if this is what's required, just guessing
}

Then make a decorator with user_passes_test:

from django.contrib.auth.decorators import user_passes_test

def ldap_group_required(group_name):
    """
    Checks if a user is in the specified LDAP group.
    """
    return user_passes_test(
        lambda u: hasattr(u, 'ldap_group') and u.ldap_group == group_name,
        login_url='/accounts/login/'
    )

Use it on a view like so:

@ldap_group_required('group1')
def index(request):
    #getting our template
    template = loader.get_template('main/index.html')
    #rendering the template in HttpResponse
    return HttpResponse(template.render())

If you check out the source code, this is effectively how login_required works.

like image 71
mindcruzer Avatar answered Mar 27 '23 04:03

mindcruzer