11#!/usr/bin/env python3
22
3- import re
43import os
54import sys
6- import json
75import time
86import getopt
9- import subprocess
107import urllib .error
118import urllib .request
129import comanage_scripts_utils as utils
1310
1411
1512SCRIPT = os .path .basename (__file__ )
1613ENDPOINT = "https://registry-test.cilogon.org/registry/"
14+ LDAP_SERVER = "ldaps://ldap-test.cilogon.org"
15+ LDAP_USER = "uid=registry_user,ou=system,o=OSG,o=CO,dc=cilogon,dc=org"
1716OSG_CO_ID = 8
18- MINTIMEOUT = 5
19- MAXTIMEOUT = 625
20- TIMEOUTMULTIPLE = 5
2117CACHE_FILENAME = "COmanage_Projects_cache.txt"
2218CACHE_LIFETIME_HOURS = 0.5
2319
24- LDAP_AUTH_COMMAND = [
25- "awk" , "/ldap_default_authtok/ {print $3}" , "/etc/sssd/conf.d/0060_domain_CILOGON.ORG.conf" ,
26- ]
27-
28- LDAP_GROUP_MEMBERS_COMMAND = [
29- "ldapsearch" ,
30- "-H" ,
31- "ldaps://ldap.cilogon.org" ,
32- "-D" ,
33- "uid=readonly_user,ou=system,o=OSG,o=CO,dc=cilogon,dc=org" ,
34- "-w" , "{auth}" ,
35- "-b" ,
36- "ou=groups,o=OSG,o=CO,dc=cilogon,dc=org" ,
37- "-s" ,
38- "one" ,
39- "(cn=*)" ,
40- ]
41-
42- LDAP_ACTIVE_USERS_COMMAND = [
43- "ldapsearch" ,
44- "-LLL" ,
45- "-H" , "ldaps://ldap.cilogon.org" ,
46- "-D" , "uid=readonly_user,ou=system,o=OSG,o=CO,dc=cilogon,dc=org" ,
47- "-x" ,
48- "-w" , "{auth}" ,
49- "-b" , "ou=people,o=OSG,o=CO,dc=cilogon,dc=org" ,
50- "{filter}" , "voPersonApplicationUID" ,
51- "|" , "grep" , "voPersonApplicationUID" ,
52- "|" , "sort" ,
53- ]
5420
5521_usage = f"""\
5622 usage: [PASS=...] { SCRIPT } [OPTIONS]
5723
5824OPTIONS:
5925 -u USER[:PASS] specify USER and optionally PASS on command line
6026 -c OSG_CO_ID specify OSG CO ID (default = { OSG_CO_ID } )
27+ -s LDAP_SERVER specify LDAP server to read data from
28+ -l LDAP_USER specify LDAP user for reading data from LDAP server
29+ -a ldap_authfile specify path to file to open and read LDAP authtok
6130 -d passfd specify open fd to read PASS
6231 -f passfile specify path to file to open and read PASS
6332 -e ENDPOINT specify REST endpoint
@@ -87,6 +56,9 @@ class Options:
8756 osg_co_id = OSG_CO_ID
8857 outfile = None
8958 authstr = None
59+ ldap_server = LDAP_SERVER
60+ ldap_user = LDAP_USER
61+ ldap_authtok = None
9062 filtergrp = None
9163
9264
@@ -110,14 +82,8 @@ def co_group_is_project(gid):
11082
11183
11284def get_co_group_osggid (gid ):
113- resp_data = get_co_group_identifiers (gid )
114- data = get_datalist (resp_data , "Identifiers" )
115- return list (filter (lambda x : x ["Type" ] == "osggid" , data ))[0 ]["Identifier" ]
116-
117-
118- def get_co_group_osggid (gid ):
119- resp_data = get_co_group_identifiers (gid )
120- data = get_datalist (resp_data , "Identifiers" )
85+ resp_data = utils .get_co_group_identifiers (gid , options .endpoint , options .authstr )
86+ data = utils .get_datalist (resp_data , "Identifiers" )
12187 return list (filter (lambda x : x ["Type" ] == "osggid" , data ))[0 ]["Identifier" ]
12288
12389
@@ -147,11 +113,15 @@ def parse_options(args):
147113
148114 passfd = None
149115 passfile = None
116+ ldap_authfile = None
150117
151118 for op , arg in ops :
152119 if op == '-h' : usage ()
153120 if op == '-u' : options .user = arg
154121 if op == '-c' : options .osg_co_id = int (arg )
122+ if op == '-s' : options .ldap_server = arg
123+ if op == '-l' : options .ldap_user = arg
124+ if op == '-a' : ldap_authfile = arg
155125 if op == '-d' : passfd = int (arg )
156126 if op == '-f' : passfile = arg
157127 if op == '-e' : options .endpoint = arg
@@ -161,69 +131,20 @@ def parse_options(args):
161131 try :
162132 user , passwd = utils .getpw (options .user , passfd , passfile )
163133 options .authstr = utils .mkauthstr (user , passwd )
134+ options .ldap_authtok = utils .get_ldap_authtok (ldap_authfile )
164135 except PermissionError :
165136 usage ("PASS required" )
166137
167138
168- def get_ldap_group_members_data ():
169- gidNumber_str = "gidNumber: "
170- gidNumber_regex = re .compile (gidNumber_str )
171- member_str = "hasMember: "
172- member_regex = re .compile (member_str )
173-
174- auth_str = subprocess .run (
175- LDAP_AUTH_COMMAND ,
176- stdout = subprocess .PIPE
177- ).stdout .decode ('utf-8' ).strip ()
178-
179- ldap_group_members_command = LDAP_GROUP_MEMBERS_COMMAND
180- ldap_group_members_command [LDAP_GROUP_MEMBERS_COMMAND .index ("{auth}" )] = auth_str
181-
182- data_file = subprocess .run (
183- ldap_group_members_command , stdout = subprocess .PIPE ).stdout .decode ('utf-8' ).split ('\n ' )
184-
185- search_results = list (filter (
186- lambda x : not re .compile ("#|dn:|cn:|objectClass:" ).match (x ),
187- (line for line in data_file )))
188-
189- search_results .reverse ()
190-
139+ def get_ldap_group_members_dict ():
191140 group_data_dict = dict ()
192- index = 0
193- while index < len (search_results ) - 1 :
194- while not gidNumber_regex .match (search_results [index ]):
195- index += 1
196- gid = search_results [index ].replace (gidNumber_str , "" )
197- members_list = []
198- while search_results [index ] != "" :
199- if member_regex .match (search_results [index ]):
200- members_list .append (search_results [index ].replace (member_str , "" ))
201- index += 1
202- group_data_dict [gid ] = members_list
203- index += 1
141+ for group_gid in utils .get_ldap_groups (options .ldap_server , options .ldap_user , options .ldap_authtok ):
142+ group_members = utils .get_ldap_group_members (group_gid , options .ldap_server , options .ldap_user , options .ldap_authtok )
143+ group_data_dict [group_gid ] = group_members
204144
205145 return group_data_dict
206146
207147
208- def get_ldap_active_users (filter_group_name ):
209- auth_str = subprocess .run (
210- LDAP_AUTH_COMMAND ,
211- stdout = subprocess .PIPE
212- ).stdout .decode ('utf-8' ).strip ()
213-
214- filter_str = ("(isMemberOf=CO:members:active)" if filter_group_name is None
215- else f"(&(isMemberOf={ filter_group_name } )(isMemberOf=CO:members:active))" )
216-
217- ldap_active_users_command = LDAP_ACTIVE_USERS_COMMAND
218- ldap_active_users_command [LDAP_ACTIVE_USERS_COMMAND .index ("{auth}" )] = auth_str
219- ldap_active_users_command [LDAP_ACTIVE_USERS_COMMAND .index ("{filter}" )] = filter_str
220-
221- active_users = subprocess .run (ldap_active_users_command , stdout = subprocess .PIPE ).stdout .decode ('utf-8' ).split ('\n ' )
222- users = set (line .replace ("voPersonApplicationUID: " , "" ) if re .compile ("dn: voPerson*" )
223- else "" for line in active_users )
224- return users
225-
226-
227148def create_user_to_projects_map (project_to_user_map , active_users , osggids_to_names ):
228149 users_to_projects_map = dict ()
229150 for osggid in project_to_user_map :
@@ -256,26 +177,25 @@ def get_co_api_data():
256177 for entry in entries :
257178 osggid_name_pair = entry .split (":" )
258179 if len (osggid_name_pair ) == 2 :
259- project_osggids_to_name [osggid_name_pair [0 ]] = osggid_name_pair [1 ]
180+ project_osggids_to_name [int (osggid_name_pair [0 ])] = osggid_name_pair [1 ].strip ()
181+ r .close ()
260182 else :
183+ r .close ()
261184 raise OSError
262185 except OSError :
263186 with open (CACHE_FILENAME , "w" ) as w :
264187 project_osggids_to_name = get_groups_data_from_api ()
265188 print (time .time (), file = w )
266189 for osggid , name in project_osggids_to_name .items ():
267190 print (f"{ osggid } :{ name } " , file = w )
268- finally :
269- if r :
270- r .close ()
271191
272192 return project_osggids_to_name
273193
274194
275195def get_osguser_groups (filter_group_name = None ):
276196 project_osggids_to_name = get_co_api_data ()
277- ldap_groups_members = get_ldap_group_members_data ()
278- ldap_users = get_ldap_active_users (filter_group_name )
197+ ldap_groups_members = get_ldap_group_members_dict ()
198+ ldap_users = utils . get_ldap_active_users (options . ldap_server , options . ldap_user , options . ldap_authtok , filter_group_name )
279199
280200 active_project_osggids = set (ldap_groups_members .keys ()).intersection (set (project_osggids_to_name .keys ()))
281201 project_to_user_map = {
0 commit comments