Note: The default ITS GitLab runner is a shared resource and is subject to slowdowns during heavy usage.
You can run your own GitLab runner that is dedicated just to your group if you need to avoid processing delays.

Commit 8cc0bd83 authored by Paul Arthur's avatar Paul Arthur
Browse files

Fix problems encountered in testing CSAM

* Refactor MCommGroup.fetch(), mainly to reduce nesting.

* LDAP attributes are not case sensitive, but we were doing a
  case-sensitive check for the umichGroup object class.

* Centralize defaulting of list attrs to []; the old code was both
  overly duplicated and failed to account for some situations.
parent 397abb8e
Pipeline #8327 passed with stage
in 25 seconds
...@@ -120,32 +120,24 @@ class MCommGroup: ...@@ -120,32 +120,24 @@ class MCommGroup:
@property @property
def externalMembers(self): def externalMembers(self):
if not hasattr(self, '_externalMembers'): if not hasattr(self, '_externalMembers'):
if not isinstance(self.memberExternal, list):
self.memberExternal = []
self._externalMembers = [x['dn'] for x in self.memberExternal] self._externalMembers = [x['dn'] for x in self.memberExternal]
return self._externalMembers return self._externalMembers
@property @property
def links(self): def links(self):
if not hasattr(self, '_links'): if not hasattr(self, '_links'):
if not isinstance(self.urlLinks, list):
self.urlLinks = []
self._links = [x['labeledUri'] for x in self.urlLinks] self._links = [x['labeledUri'] for x in self.urlLinks]
return self._links return self._links
@property @property
def members(self): def members(self):
if not hasattr(self, '_members'): if not hasattr(self, '_members'):
if not isinstance(self.memberDn, list):
self.memberDn = []
self._members = [parse_dn(x)[0][1] for x in self.memberDn] self._members = [parse_dn(x)[0][1] for x in self.memberDn]
return self._members return self._members
@property @property
def memberGroups(self): def memberGroups(self):
if not hasattr(self, '_memberGroups'): if not hasattr(self, '_memberGroups'):
if not isinstance(self.memberGroupDn, list):
self.memberGroupDn = []
self._memberGroups = [ self._memberGroups = [
parse_dn(x)[0][1] for x in self.memberGroupDn parse_dn(x)[0][1] for x in self.memberGroupDn
] ]
...@@ -154,20 +146,16 @@ class MCommGroup: ...@@ -154,20 +146,16 @@ class MCommGroup:
@property @property
def moderators(self): def moderators(self):
if not hasattr(self, '_moderators'): if not hasattr(self, '_moderators'):
if not isinstance(self.moderator, list):
self.moderator = []
self._moderators = [x['dn'] for x in self.moderator] self._moderators = [x['dn'] for x in self.moderator]
return self._moderators return self._moderators
@property @property
def owners(self): def owners(self):
if not hasattr(self, '_owners'): if not hasattr(self, '_owners'):
if not isinstance(self.ownerDn, list):
self.ownerDn = []
self._owners = [parse_dn(x)[0][1] for x in self.ownerDn] self._owners = [parse_dn(x)[0][1] for x in self.ownerDn]
return self._owners return self._owners
def fetch(self, targets=False): def fetch(self, targets=None):
"""Fetch information for an mcommunity group """Fetch information for an mcommunity group
Parameters Parameters
...@@ -181,41 +169,59 @@ class MCommGroup: ...@@ -181,41 +169,59 @@ class MCommGroup:
""" """
self.dn = core.get_entity_dn(self.client, self.name) self.dn = core.get_entity_dn(self.client, self.name)
if self.dn: if not self.dn:
for i in range(5): raise core.MCommError('Unable to fetch fresh group data')
r = self.client.get(
url='/profile/dn/{}'.format(quote(self.dn)) # Updated data isn't always available immediately, so try to loop
) # for a bit if we don't see any change.
if r.ok: # FIXME: people might call fetch when there actually haven't been any
group = r.json()['group'][0] # changes, so this should probably be controlled by a flag.
group['owners_details'] = group.pop('owners') for i in range(5):
tmp_hash = hashlib.md5(json.dumps(group).encode('utf-8')) r = self.client.get(
if hasattr(self, 'group_hash'): url='/profile/dn/{}'.format(quote(self.dn))
if tmp_hash.hexdigest() == self.group_hash.hexdigest(): )
sleep(2**i) if not r.ok:
continue raise core.MCommError('{}: {}'.format(
if 'umichgroup' in group['objectClass']:
self.group_hash = tmp_hash
if targets:
for target in targets:
setattr(self, target, group[target])
else:
self.__dict__.update(group)
else:
raise core.MCommError(
'Entity found is {}, not group'.format(
', '.join(group['objectClass'])
)
)
break
else:
raise core.MCommError('{}: {}'.format(
r.status_code, r.status_code,
r.text r.text,
)
) )
else: )
raise core.MCommError('Unable to fetch fresh group data')
group = r.json()['group'][0]
group['owners_details'] = group.pop('owners')
new_hash = hashlib.md5(json.dumps(group).encode('utf-8')).hexdigest()
if getattr(self, 'group_hash', None) != new_hash:
self.group_hash = new_hash
break
if i < 4:
sleep(2**i)
group['objectClass'] = [x.lower() for x in group['objectClass']]
if 'umichgroup' not in group['objectClass']:
raise core.MCommError(
'Entity found is {}, not group'.format(
', '.join(group['objectClass'])
)
)
if targets:
for target in targets:
setattr(self, target, group[target])
else:
self.__dict__.update(group)
# Make sure that our list attrs are at least empty lists
for attr in [
'memberDn',
'memberExternal',
'memberGroupDn',
'moderator',
'ownerDn',
'urlLinks',
]:
if not getattr(self, attr, None):
setattr(self, attr, [])
def create(self): def create(self):
"""Create a new mcommunity group """Create a new mcommunity group
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment