def cacheAccess(config, mode, cache): """ Computes access lists for all repositories in one pass. """ for sectname in config.sections(): GROUP_PREFIX = 'group ' USER_PREFIX = 'user ' REPO_PREFIX = 'repo ' if sectname.startswith(USER_PREFIX): idx = 0 name = sectname[len(USER_PREFIX):] elif sectname.startswith(GROUP_PREFIX): idx = 1 name = sectname[len(GROUP_PREFIX):] elif sectname.startswith(REPO_PREFIX): # Single repository: handle owner name = sectname[len(REPO_PREFIX):] if (mode,name) not in cache: cache[mode,name] = (set(),set()) continue else: continue repos = util.getConfigList(config, sectname, mode) for (iname, ivalue) in config.items(sectname): if iname.startswith('map %s ' % mode): repos.append(ivalue) for path in repos: if (mode,path) not in cache: cache[mode,path] = (set(),set()) cache[mode,path][idx].add(name)
def _getMembership(config, user, seen): log = logging.getLogger('gitosis.group.getMembership') for section in config.sections(): GROUP_PREFIX = 'group ' if not section.startswith(GROUP_PREFIX): continue group = section[len(GROUP_PREFIX):] if group in seen: continue members = util.getConfigList(config, section, 'members') # @all is the only group where membership needs to be # bootstrapped like this, anything else gets started from the # username itself if (user in members or '@all' in members): log.debug('found %(user)r in %(group)r' % dict( user=user, group=group, )) seen.add(group) yield group for member_of in _getMembership( config, '@%s' % group, seen, ): yield member_of
def listMembers(config, group, mset): """ Generate a list of members of a group :type config: RawConfigParser :type group: str :param mset: Set of members to amend """ if group <> 'all': members = util.getConfigList(config, 'group %s' % group, 'members') for user in members: mset.add(user) if user.startswith('@'): listMembers(config, user[1:], mset)
def haveAccess(config, user, mode, path): """ Map request for write access to allowed path. Note for read-only access, the caller should check for write access too. Returns ``None`` for no access, or a tuple of toplevel directory containing repositories and a relative path to the physical repository. """ log = logging.getLogger('gitosis.access.haveAccess') log.debug( 'Access check for %(user)r as %(mode)r on %(path)r...' % dict( user=user, mode=mode, path=path, )) basename, ext = os.path.splitext(path) if ext == '.git': log.debug( 'Stripping .git suffix from %(path)r, new value %(basename)r' % dict( path=path, basename=basename, )) path = basename sections = ['group %s' % item for item in group.getMembership(config=config, user=user)] sections.insert(0, 'user %s' % user) for sectname in sections: repos = util.getConfigList(config, sectname, mode) mapping = None if pathMatchPatterns(path, repos): log.debug( 'Access ok for %(user)r as %(mode)r on %(path)r' % dict( user=user, mode=mode, path=path, )) mapping = path else: mapping = util.getConfigDefault(config, sectname, 'map %s %s' % (mode, path), None) if mapping: log.debug( 'Access ok for %(user)r as %(mode)r on %(path)r=%(mapping)r' % dict( user=user, mode=mode, path=path, mapping=mapping, )) if mapping is not None: prefix = util.getConfigDefault(config, sectname, 'repositories', 'repositories', 'gitosis') log.debug( 'Using prefix %(prefix)r for %(path)r' % dict( prefix=prefix, path=mapping, )) return (prefix, mapping)