Browse Source

Add export option to LDAP client

master
Joshua Rubingh 9 months ago
parent
commit
8c367253fd
  1. 1
      .gitignore
  2. 84
      agent.py
  3. 32
      export.py

1
.gitignore vendored

@ -142,3 +142,4 @@ cython_debug/ @@ -142,3 +142,4 @@ cython_debug/
# Development IDE
.vscode/launch.json
.running
LDAP_export.json

84
agent.py

@ -16,6 +16,7 @@ import time @@ -16,6 +16,7 @@ import time
import glob
import codecs
import zipfile
import copy
class TimedCompressedRotatingFileHandler(logging.handlers.TimedRotatingFileHandler):
@ -615,6 +616,89 @@ class VRWLDAP(): @@ -615,6 +616,89 @@ class VRWLDAP():
# It looks like this is taken care by the LDAP server
self.connection.modify(researcher_dn, {'groupMembership': [(MODIFY_DELETE, [group])]})
def export_studies(self):
"""This will export all the existing studies that are created in the LDAP server. The starting point is `self.__RESOURCE_GROUPS_BASE` setting
Returns:
dict: A python dictionary with all the studies with the study ID as key
"""
studies = {}
logger.debug(f'Exporting all studies in DN "{self.__RESOURCE_GROUPS_BASE}"')
# We are missing Faculty information here....
if self.connection.search(self.__RESOURCE_GROUPS_BASE, f'(ou=*)', attributes=['ou', 'description', ]):
entries = copy.deepcopy(self.connection.entries)
for entry in entries:
# Skip starting point... not sure why it is found in the list...
if entry.entry_dn == self.__RESOURCE_GROUPS_BASE:
continue
dn = entry.ou.value.strip()
# But when using the description field, we get a better study name (I think)
study_name = entry.description.value.strip().replace('Researchgroup', '').strip()
studies[dn] = {
'dn': dn,
'name': study_name,
'description': None if not entry.description else entry.description.value.strip(),
'contributors': {}
}
return studies
def export_researchers(self, studies):
"""Export all the existing researchers. And will update the studies with the correct researchers with their role and workspace
Args:
studies (dict): A dict of all the studies generated by `export_studies`
Returns:
tuple: Returns a tuple with two values. First is a list with all the researchers, the second is a list with all the studies
"""
researchers = []
logger.debug(f'Exporting all researchers in DN "{self.__RESOURCE_MEMBERS_BASE}"')
# We are missing Faculty information here....
if self.connection.search(self.__RESOURCE_MEMBERS_BASE, f'(uid=*)', attributes=['sn', 'givenName', 'uid', 'mobile', 'employeeNumber', 'groupMembership']):
for entry in self.connection.entries:
uid = entry.uid.value.strip()
researchers.append({
'uid': uid,
'first_name': None if not entry.givenName else entry.givenName.value.strip(),
'last_name': None if not entry.sn else entry.sn.value.strip(),
'email_address': None if not entry.uid else entry.uid.value.strip(),
'mobile': None if not entry.mobile else entry.mobile.value.strip(),
'pnumber': None if not entry.employeeNumber else entry.employeeNumber.value.strip()
})
# Loop over group member ships to construct the contributors data
for group in entry.groupMembership:
group = group.replace('cn=', '').split(',')[0].split(':')
if len(group) < 2:
continue
group_id = group[0]
if uid not in studies[group_id]['contributors']:
studies[group_id]['contributors'][uid] = {
'uid': uid,
'role': 'Contributor',
'workspace': ''
}
if group[1].lower() == 'ws' and len(group) == 4:
studies[group_id]['contributors'][uid]['workspace'] = 'Premium' if 'large' == group[3].lower() else 'Basic'
elif group[1].lower() == 'role' and len(group) == 3:
studies[group_id]['contributors'][uid]['role'] = 'Administrator' if 'datamanager' == group[2].lower() else 'Contributor'
# convert study dict to list. Is less data and easier for the import later on.
studies_list = []
for study_data in studies.values():
studies_list.append(study_data)
return (researchers, studies_list)
def export(self):
return self.export_researchers(self.export_studies())
class VRE_API_CLient():
"""This is the VRE API client. With this client you can easily get the latest VRW actions from the VRE API.

32
export.py

@ -0,0 +1,32 @@ @@ -0,0 +1,32 @@
from agent import WORKINGDIR, logger, VRWLDAP
from dotenv import dotenv_values
import json
from pathlib import Path
if __name__ == "__main__":
config = dotenv_values(f'{WORKINGDIR}/.env')
print('Start exporting data')
# Load LDAP client
ldap_client = VRWLDAP(config['LDAP_HOST'], int(config['LDAP_PORT']), config['LDAP_USER'], config['LDAP_PASS'], config['LDAP_SSL'], not config['LDAP_MANUAL_GROUPS'])
if not ldap_client.check_connection():
logger.error(f'Could not login to the LDAP server. Check connection credentials.')
quit()
# Get the data from the LDAP server
(researchers, studies) = ldap_client.export()
# Make a nice dict for JSON export saving
data = {
'researchers': researchers,
'studies': studies,
}
json_data = json.dumps(data, indent=2)
# Write data to file
export_file = Path('LDAP_export.json')
export_file.write_text(json_data)
print('Data exported to: LDAP_export.json')
Loading…
Cancel
Save