Settings.py

Now it is time to introduce some global, i.e. program wide variables:

1  
2
3
class Settings:
    dnSchool = "dc=trainingX, dc=net"                       # Distinguished of domaine
    dnStudents = "ou=Students, ou=SchoolUsers, " + dnSchool # Distinguished Name of OU Students


The Settings class here is not instantiated (no object created). These so-called static properties can easily be accessed via [class name].[property name] (see below)

(A static variable exists only once per class and is common to all objects of this class. If the value of a static variable in an object is changed, the value in all other instances of the class is also changed.)

PyAD.py

Beside the unchanged abstract class AbstractLDAP the improved code of class PyAD is shown below:

 1  
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
from abc import ABC, abstractmethod     # import Abstract Base Classes (ABCs)

class AbstractLDAP(ABC):
 
    def __init__(self, dnStudents):
        self._dnStudents = dnStudents
        super().__init__()
    
    @abstractmethod
    def createStudent(self, username, nameSchoolClass):
        pass
    @abstractmethod
    def deleteStudent(self, username, nameSchoolClass):
        pass
    @abstractmethod
    def createSchoolClass(self, nameSchoolClass):
        pass
    @abstractmethod
    def deleteSchoolClass(self, nameSchoolClass):
        pass

from pyad import *
from Settings import Settings

class PyAD(AbstractLDAP):
    def createStudent(self, username, surname, firstname, password, dateOfBirth, nameSchoolClass):
        query = adquery.ADQuery()
        cnUnique = False
        numChar = 0
        while(cnUnique == False):
            query.execute_query(attributes = ["cn"],            # query: does cn already exist
                where_clause=("cn = '" + username + "'"),
                base_dn = Settings.dnSchool)
            if query.get_row_count() > 0:                       # yes: add character
                numChar = numChar + 1
                if(numChar <= len(firstname)):                  # if the character set of the first name is large enough
                    username = surname + firstname[:numChar]    # add number of characters from beginning of first ame
                else:                                           # if the character set of the first name is used up
                    username = surname + firstname + (numChar - len(firstname))  * 'x'  # added number of 'x'
            else:                                               # cn is unique => create user
                cnUnique = True
                ouSchoolClass = pyad.adcontainer.ADContainer("ou="+nameSchoolClass+", "+self._dnStudents, adsi_ldap_com_object=None, options={})
                aduser.ADUser.create(username
                                     , ouSchoolClass
                                     , password=password
                                     , upn_suffix=None
                                     , enable=True
                                     , optional_attributes={"sn":surname
                                                            , "givenName":firstname
                                                            , "employeeID":dateOfBirth  # using existing employeeId attribute is easier than extending AD scheme
                                                            , "description":"Student"
                                                            , "pwdLastSet":0})          # password must be changed on first login
        return username                                         # return possibly modified username

    def deleteStudent(self, surname, firstname, dateOfBirth, nameSchoolClass):
        # print("delete ", surname, firstname, dateOfBirth, nameSchoolClass)
        dnSchoolClass = "ou="+nameSchoolClass + ", " + self._dnStudents
        query = adquery.ADQuery()
        query.execute_query(attributes = ["cn"],
                where_clause=("sn = '" + surname + "' and givenName = '" + firstname + "' and employeeID = '" + dateOfBirth + "'"),
                base_dn = dnSchoolClass)
        if query.get_row_count() >= 1:                          # if student exists => delete it
            ouSchoolClass = pyad.adcontainer.ADContainer(dnSchoolClass, adsi_ldap_com_object=None, options={})
            for row in query.get_results():
                ouSchoolClass.from_cn(row["cn"]).delete()
   
    def createSchoolClass(self, nameSchoolClass):
        query = adquery.ADQuery()
        query.execute_query(attributes = ["distinguishedName"],
                where_clause=("ou = '" +nameSchoolClass + "'"),
                base_dn = self._dnStudents)
        if query.get_row_count() == 0:                          # if school class not yet exists => create
            ouStudents = pyad.adcontainer.ADContainer(self._dnStudents, adsi_ldap_com_object=None, options={})
            ouStudents.create_container(nameSchoolClass)
   
    def deleteSchoolClass(self, nameSchoolClass):
        dnSchoolClass = "ou="+nameSchoolClass+", "+ self._dnStudents
        query = adquery.ADQuery()
        query.execute_query(attributes = ["distinguishedName"],
                where_clause=("ou = '" +nameSchoolClass + "'"),
                base_dn = self._dnStudents)
        if query.get_row_count() == 1:                          # if school class exists
            query = adquery.ADQuery()
            query.execute_query(attributes = ["sn", "givenName", "employeeID"],  # employeeID holds date of birth,
                where_clause=("cn = '*'"),
                base_dn = dnSchoolClass)
            if query.get_row_count() > 0:                       # if school class not empty 
                for row in query.get_results():                 # delete students
                    self.deleteStudent(row["sn"], row["givenName"], row["employeeID"], nameSchoolClass)
            ouSchoolClass = pyad.adcontainer.ADContainer(dnSchoolClass, adsi_ldap_com_object=None, options={})
            ouSchoolClass.delete()                              # delete school class

            


The method createStudent() returns the possibly modified username so that it can be updated later in the class Student.
The student to be deleted is uniquely identified by the parameters surname, firstname, dateOfBirth and nameSchoolClass of the method deleteStudent.


testPyAD.py

The classes are used as follows:

1  
2
3
4
5
6
7
8
from Settings import Settings
from Ldap import PyAD

ldap = PyAD(Settings.dnStudents)

ldap.createSchoolClass("school_class1")
ldap.createStudent("Miller", "Miller", "Sam", "SM11.11.2000", "11.11.2000", "school_class1")
# ldap.deleteSchoolClass("school_class1")




Last modified: Sunday, 16 April 2023, 11:43 AM