Skip to content
Browse files
Another turning of the crank, on a draft daemon.
* move GATHER_DELAY and LDAP_URL into the authz.yaml
* parse auth.conf for now to get SPECIAL and EXPLICIT
* pass the above data to the Generator
* grab some template->output mappings from the .yaml
* change .write_file() to iterate over the new mappings
* rename QUERIES to SPECIAL to follow the config name
* switch to .write_file(t, o)
  • Loading branch information
gstein committed Mar 23, 2021
1 parent 667633c commit 16bd6a23741785e154fe306f6cc68c8049f85437
Showing 2 changed files with 41 additions and 18 deletions.
@@ -15,12 +15,12 @@
# See the License for the specific language governing permissions and
# limitations under the License.

import os.path
import time

import asfpy.pubsub
import asfpy.syslog
import yaml
import ezt

import gen

@@ -29,26 +29,47 @@
# The service will set the working directory, so we can find this.
CONFIG_FNAME = 'authz.yaml'

# Gather up a bunch of changes, then write new files. We want to
# avoid writing for each change. Gather them up for a bit of time,
# then dump the group of changes into the new authz files.

# Specify a time in the far future to indicate that we have not
# (recently) signaled a need to write the authz files.

### move this to the config
LDAP_URL = 'ldaps://'

class Authorization:
def __init__(self, cfg, debug=False):
self.cfg = cfg
self.debug = debug

# Gather up a bunch of changes, then write new files. We want to
# avoid writing for each change. Gather them up for a bit of time,
# then dump the group of changes into the new authz files.
self.delay = cfg['config']['delay']
print('DELAY:', self.delay)

url = cfg['config']['ldap']
print('LDAP:', url)

### read auth.conf ... better yet: merge that into the yaml config
self.gen = gen.Generator(LDAP_URL, (), ())
### for now: ln -s modules/subversion_server/files/authorization/auth.conf .
import configparser
cp = configparser.ConfigParser()'auth.conf')
special = dict((k, v.strip()) for k, v in cp.items('special'))
explicit = dict((k, v.split()) for k, v in cp.items('explicit'))

self.gen = gen.Generator(url, special, explicit)

tdir = cfg['generate']['template_dir']
odir = cfg['generate']['output_dir']
#print(f'TDIR: {tdir}\nODIR: {odir}')

self.mappings = { }
for name in cfg['generate']:
ob = cfg['generate'][name]
if isinstance(ob, dict):
# Note: NAME is unused, except as a descriptor/grouping
t = os.path.join(tdir, ob['template'])
o = os.path.join(odir, ob['output'])
self.mappings[t] = o

# Write new authz files on startup.
self.write_signal = 0 # epoch
@@ -70,14 +91,15 @@ def write_files(self):
self.write_signal = FAR_FUTURE
if self.debug:
print('WRITE_FILES: written at', time.time())
for t, o in self.mappings.items():
self.gen.write_file(t, o)

def handler(self, payload):
# If a (re)write has been signaled, then wait for a bit before
# writing more files. This prevents rewriting on EVERY change.
# Given that a heartbeat occurs every 5 seconds (as of this
# comment), we'll get an opportunity to check/write.
if time.time() > self.write_signal + GATHER_DELAY:
if time.time() > self.write_signal + self.delay:

# What kind of packet/payload arrived from PUBSUB ?
@@ -18,6 +18,7 @@
import re

import ldap
import ezt

class FunkyLDAP(Exception):
@@ -74,9 +75,9 @@ class Generator:
QUERY_PMC = ('ou=project,ou=groups,dc=apache,dc=org', 'owner')
QUERY_COMMITTERS = ('ou=groups,dc=apache,dc=org', 'memberUid')

def __init__(self, ldap_url, queries, explicit):
def __init__(self, ldap_url, special, explicit):
self.client = LDAPClient(ldap_url)
self.queries = queries
self.special = special
self.explicit = explicit

def group_members(self, group):
@@ -97,9 +98,9 @@ def group_members(self, group):
if group == 'committers':
# Special case this one. It uses a different attribute.
dn, attr = self.QUERY_COMMITTERS
elif group in self.queries:
elif group in self.special:
# These are defined in [special]
dn = self.queries[group]
dn = self.special[group]
attr = None
elif group != cn:
# cn has had -(p)pmc sliced off. Look up the PMC.
@@ -112,5 +113,5 @@ def group_members(self, group):
# Find the group members within LDAP.
return self.client.get_members(cn, dn, attr)

def write_files(self):
def write_file(self, template, output):
print(f'WRITE_FILE: t="{template}" o="{output}"')

0 comments on commit 16bd6a2

Please sign in to comment.