Пример #1
0
def test_no_notListed():
    cfg = RawConfigParser()
    cfg.add_section("group hackers")
    cfg.set("group hackers", "members", "wsmith")
    gen = group.getMembership(config=cfg, user="******")
    eq(gen.next(), "all")
    assert_raises(StopIteration, gen.next)
Пример #2
0
def test_no_notListed():
    cfg = RawConfigParser()
    cfg.add_section('group hackers')
    cfg.set('group hackers', 'members', 'wsmith')
    gen = group.getMembership(config=cfg, user='******')
    eq(next(gen), 'all')
    assert_raises(StopIteration, gen.__next__)
Пример #3
0
def test_no_notListed():
    cfg = RawConfigParser()
    cfg.add_section('group hackers')
    cfg.set('group hackers', 'members', 'wsmith')
    gen = group.getMembership(config=cfg, user='******')
    eq(gen.next(), 'all')
    assert_raises(StopIteration, gen.next)
def test_yes_middle():
    cfg = RawConfigParser()
    cfg.add_section('group hackers')
    cfg.set('group hackers', 'members', 'wsmith jdoe danny')
    gen = group.getMembership(config=cfg, user='******')
    eq(gen.next(), 'hackers')
    eq(gen.next(), 'all')
    assert_raises(StopIteration, gen.next)
def test_no_recurse_loop():
    cfg = RawConfigParser()
    cfg.add_section('group hackers')
    cfg.set('group hackers', 'members', '@smackers')
    cfg.add_section('group smackers')
    cfg.set('group smackers', 'members', '@hackers')
    gen = group.getMembership(config=cfg, user='******')
    eq(gen.next(), 'all')
    assert_raises(StopIteration, gen.next)
Пример #6
0
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

    for groupname in group.getMembership(config=config, user=user):
        try:
            repos = config.get('group %s' % groupname, mode)
        except (NoSectionError, NoOptionError):
            repos = []
        else:
            repos = repos.split()

        mapping = None

        if path in repos:
            log.debug('Access ok for %(user)r as %(mode)r on %(path)r' % 
                dict(user=user, mode=mode, path=path ))
            mapping = path
        else:
            try:
                mapping = config.get('group %s' % groupname, 'map %s %s' % (mode, path))
            except (NoSectionError, NoOptionError):
                pass
            else:
                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 = None
            try:
                prefix = config.get('group %s' % groupname, 'repositories')
            except (NoSectionError, NoOptionError):
                try:
                    prefix = config.get('gitosis', 'repositories')
                except (NoSectionError, NoOptionError):
                    prefix = 'repositories'

            log.debug('Using prefix %(prefix)r for %(path)r' 
                % dict(prefix=prefix, path=mapping,))
                
            return (prefix, mapping)
Пример #7
0
def test_no_recurse_loop():
    cfg = RawConfigParser()
    cfg.add_section("group hackers")
    cfg.set("group hackers", "members", "@smackers")
    cfg.add_section("group smackers")
    cfg.set("group smackers", "members", "@hackers")
    gen = group.getMembership(config=cfg, user="******")
    eq(gen.next(), "all")
    assert_raises(StopIteration, gen.next)
Пример #8
0
def allowed(config, user, mode, path):
    """Check if a user is allowed to access a given path.

    Returns ``None`` for no access, or a tuple of toplevel directory
    containing repositories and a relative path to the physical
    repository.

    :param config: ``gitosis`` config object
    :param str user: a user to check access rights for
    :param str mode: access `readonly` or `writable`
    :param str path: name of the repository to check access
                     rights for (this is what you write in ``[repo ... ]``
                     section of your ``gitosis.conf``)
    """
    log = logging.getLogger("gitosis.access.allowed")
    log.debug("Access check for {0} as {1} on {2}...".format(user, mode, path))

    basename, ext = os.path.splitext(path)
    if ext == ".git":
        log.debug("Stripped `.git` suffix from {0}, new value {1}."
                  .format(path, basename))
        path = basename

    # a) first check if a user is an owner of the repository
    #    == has unlimited access.
    owner = config.get("repo {0}".format(path), "owner")
    if owner and owner == user:
        log.debug("Acces ok for {0!r} as {1!r} on {2!r} (owner)"
                  .format(user, mode, path))
        return get_repository_prefix(config), path

    # b) iterate over user's groups and check if it has requested
    #    pass in any of the sections.
    ok = False
    for group in _group.getMembership(config=config, user=user):
        repos = config.get("group {0}".format(group), mode, default="").split()
        if path in repos:
            log.debug("Access ok for {0!r} as {1!r} on {2!r}"
                      .format(user, mode, path))
            ok = True
        elif os.path.join(os.path.dirname(path), "*") in repos:
            log.debug("Wildcard access ok for {0!r} as {1!r} on {2!r}"
                      .format(user, mode, path))
            ok = True
        else:
            mapping = config.get("group {0}".format(group),
                                 "map {0} {1}".format(mode, path))

            if mapping:
                log.debug("Access ok for {0!r} as {1!r} on {2!r}={3!r}"
                          .format(user, mode, path, mapping))
                ok, path = True, mapping

        if ok:
            prefix = get_repository_prefix(config, group)
            log.debug("Using prefix {0!r}for {1!r}".format(prefix, path))
            return prefix, path
Пример #9
0
def test_no_recurse_loop():
    cfg = RawConfigParser()
    cfg.add_section('group hackers')
    cfg.set('group hackers', 'members', '@smackers')
    cfg.add_section('group smackers')
    cfg.set('group smackers', 'members', '@hackers')
    gen = group.getMembership(config=cfg, user='******')
    eq(gen.next(), 'all')
    assert_raises(StopIteration, gen.next)
Пример #10
0
def test_yes_recurse_one_ordering():
    cfg = RawConfigParser()
    cfg.add_section("group smackers")
    cfg.set("group smackers", "members", "danny jdoe")
    cfg.add_section("group hackers")
    cfg.set("group hackers", "members", "wsmith @smackers")
    gen = group.getMembership(config=cfg, user="******")
    eq(gen.next(), "smackers")
    eq(gen.next(), "hackers")
    eq(gen.next(), "all")
    assert_raises(StopIteration, gen.next)
Пример #11
0
def test_yes_recurse_one_ordering():
    cfg = RawConfigParser()
    cfg.add_section('group smackers')
    cfg.set('group smackers', 'members', 'danny jdoe')
    cfg.add_section('group hackers')
    cfg.set('group hackers', 'members', 'wsmith @smackers')
    gen = group.getMembership(config=cfg, user='******')
    eq(next(gen), 'smackers')
    eq(next(gen), 'hackers')
    eq(next(gen), 'all')
    assert_raises(StopIteration, gen.__next__)
Пример #12
0
def test_yes_recurse_one_ordering():
    cfg = RawConfigParser()
    cfg.add_section('group smackers')
    cfg.set('group smackers', 'members', 'danny jdoe')
    cfg.add_section('group hackers')
    cfg.set('group hackers', 'members', 'wsmith @smackers')
    gen = group.getMembership(config=cfg, user='******')
    eq(gen.next(), 'smackers')
    eq(gen.next(), 'hackers')
    eq(gen.next(), 'all')
    assert_raises(StopIteration, gen.next)
Пример #13
0
def test_yes_recurse_junk():
    cfg = RawConfigParser()
    cfg.add_section('group hackers')
    cfg.set('group hackers', 'members', '@notexist @smackers')
    cfg.add_section('group smackers')
    cfg.set('group smackers', 'members', 'jdoe')
    gen = group.getMembership(config=cfg, user='******')
    eq(next(gen), 'smackers')
    eq(next(gen), 'hackers')
    eq(next(gen), 'all')
    assert_raises(StopIteration, gen.__next__)
def test_yes_recurse_three():
    cfg = RawConfigParser()
    cfg.add_section('group hackers')
    cfg.set('group hackers', 'members', 'wsmith @smackers')
    cfg.add_section('group smackers')
    cfg.set('group smackers', 'members', 'danny @snackers')
    cfg.add_section('group snackers')
    cfg.set('group snackers', 'members', '@whackers foo')
    cfg.add_section('group whackers')
    cfg.set('group whackers', 'members', 'jdoe')
    gen = group.getMembership(config=cfg, user='******')
    eq(gen.next(), 'whackers')
    eq(gen.next(), 'snackers')
    eq(gen.next(), 'smackers')
    eq(gen.next(), 'hackers')
    eq(gen.next(), 'all')
    assert_raises(StopIteration, gen.next)
Пример #15
0
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.
    """
    detail = []
    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

    repo = None
    try:
        repo = config.lookup_repo(path)
    except GitoliteConfigException:
        log.exception("When lookup which repo contains '%s'" % path)

    if not repo:
        log.warning("No repo contains path '%s'" % path)
        return

    mapping = None
    try:
        users = config.get_repo(repo, mode)
    except GitoliteConfigException:
        log.exception("When get '%s' of '%s':" % (mode, repo))
        return

    if users:
        if user in users:
            mapping = path
        else:
            for groupname in group.getMembership(config=config, user=user):
                if groupname in users:
                    mapping = path
                    detail.append("as group '%s'" % groupname)
                    break
            
    if mapping is not None:
        if detail:
            detail = '(%s)' % ', '.join(detail)
        else:
            detail = ''

        log.debug(
            'Access ok for %(user)r as %(mode)r on %(path)r(%(detail)s)'
            % dict(
            user=user,
            mode=mode,
            path=path,
            detail=detail
            ))

        prefix = config.get_gitosis('repositories')
        if prefix == None:
            prefix = 'repositories'

        log.debug(
            'Using prefix %(prefix)r for %(path)r'
            % dict(
            prefix=prefix,
            path=mapping,
            ))
        return (prefix, mapping)
Пример #16
0
def test_no_emptyConfig():
    cfg = RawConfigParser()
    gen = group.getMembership(config=cfg, user='******')
    eq(next(gen), 'all')
    assert_raises(StopIteration, gen.__next__)
Пример #17
0
def test_no_emptyGroup():
    cfg = RawConfigParser()
    cfg.add_section("group hackers")
    gen = group.getMembership(config=cfg, user="******")
    eq(gen.next(), "all")
    assert_raises(StopIteration, gen.next)
Пример #18
0
def test_no_emptyGroup():
    cfg = RawConfigParser()
    cfg.add_section('group hackers')
    gen = group.getMembership(config=cfg, user='******')
    eq(next(gen), 'all')
    assert_raises(StopIteration, gen.__next__)
Пример #19
0
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

    for groupname in group.getMembership(config=config, user=user):
        try:
            repos = config.get('group %s' % groupname, mode)
        except (NoSectionError, NoOptionError):
            repos = []
        else:
            repos = repos.split()

        mapping = None

        if path in repos or isWildcardAccessible(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:
            try:
                mapping = config.get('group %s' % groupname,
                                     'map %s %s' % (mode, path))
            except (NoSectionError, NoOptionError):
                pass
            else:
                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 = None
            try:
                prefix = config.get('group %s' % groupname, 'repositories')
            except (NoSectionError, NoOptionError):
                try:
                    prefix = config.get('gitosis', 'repositories')
                except (NoSectionError, NoOptionError):
                    prefix = 'repositories'

            log.debug('Using prefix %(prefix)r for %(path)r' % dict(
                prefix=prefix,
                path=mapping,
            ))
            return (prefix, mapping)
Пример #20
0
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')

    synonyms = {}
    synonyms['read'] = ['readonly', 'readable']
    synonyms['write'] = ['writable', 'writeable']
    synonyms['admin'] = ['init','initial']

    mode_syns = []
    for key, mode_syns in synonyms.items():
        if mode == key:
            break
        elif mode in mode_syns:
            if mod != mode_syns[0]:
                log.warning(
                    'Provide haveAccess with mode: "'
                    + mode + '" '
                    + 'for repository %r should be "' + key +'"',
                    path,
                    )
            mode = key
            break
    if key != mode:
        log.warning('Unknown acl mode %s, check gitosis config file.' % mode)
        mode_syns = [mode]
    else:
        mode_syns.append(mode)


    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

    for groupname in group.getMembership(config=config, user=user):
        repos = ""
        try:
            options = config.options('group %s' % groupname)
            for syn in mode_syns:
                if syn in options:
                    if syn != mode and syn != mode_syns[0]:
                        log.warning(
                            'Repository %r config has typo "'
                            + syn + '", '
                            +'should be "' + mode +'"',
                            path,
                            )
                    repos = config.get('group %s' % groupname, syn)
                    break
        except (NoSectionError, NoOptionError):
            repos = []
        else:
            repos = repos.split()

        mapping = None

        # fnmatch provide glob match support. Jiang Xin <jiangxin AT ossxp.com>
        for r in repos:
            if fnmatch(path, r):
                log.debug(
                    'Access ok for %(user)r as %(mode)r on %(path)r'
                    % dict(
                    user=user,
                    mode=mode,
                    path=path,
                    ))
                mapping = path
                break

        # Check mapping even if (path,mode) found in this group.
        try:
            re_mapping = None
            for option in config.options('group %s' % groupname):
                if not option.startswith('map'):
                    continue
                (_ignore, opt_right) = option.split(' ',1)
                (opt_mode, opt_path) = opt_right.strip().split(' ',1)
                opt_path = opt_path.strip()
                if opt_mode not in mode_syns:
                    continue
                if fnmatch(path, opt_path):
                    re_mapping = config.get('group %s' % groupname, option)
                    if ':' in re_mapping:
                        (opt_from, opt_to) = re_mapping.split(':',1)
                        re_mapping = re.sub(opt_from, opt_to, path)
                    elif '\\1' in re_mapping:
                        re_mapping = re_mapping.replace('\\1', path)
                    break
        except (NoSectionError, NoOptionError):
            pass
        else:
            if re_mapping is not None:
                mapping = re_mapping
                log.debug(
                    'Mapping 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 = None
            try:
                prefix = config.get(
                    'group %s' % groupname, 'repositories')
            except (NoSectionError, NoOptionError):
                try:
                    prefix = config.get('gitosis', 'repositories')
                except (NoSectionError, NoOptionError):
                    prefix = 'repositories'

            log.debug(
                'Using prefix %(prefix)r for %(path)r'
                % dict(
                prefix=prefix,
                path=mapping,
                ))
            return (prefix, mapping, mode)
Пример #21
0
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')

    synonyms = {}
    synonyms['read'] = ['readonly', 'readable']
    synonyms['write'] = ['writable', 'writeable']
    synonyms['admin'] = ['init', 'initial']

    mode_syns = []
    for key, mode_syns in synonyms.items():
        if mode == key:
            break
        elif mode in mode_syns:
            if mod != mode_syns[0]:
                log.warning(
                    'Provide haveAccess with mode: "' + mode + '" ' +
                    'for repository %r should be "' + key + '"',
                    path,
                )
            mode = key
            break
    if key != mode:
        log.warning('Unknown acl mode %s, check gitosis config file.' % mode)
        mode_syns = [mode]
    else:
        mode_syns.append(mode)

    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

    for groupname in group.getMembership(config=config, user=user):
        repos = ""
        try:
            options = config.options('group %s' % groupname)
            for syn in mode_syns:
                if syn in options:
                    if syn != mode and syn != mode_syns[0]:
                        log.warning(
                            'Repository %r config has typo "' + syn + '", ' +
                            'should be "' + mode + '"',
                            path,
                        )
                    repos = config.get('group %s' % groupname, syn)
                    break
        except (NoSectionError, NoOptionError):
            repos = []
        else:
            repos = repos.split()

        mapping = None

        # fnmatch provide glob match support. Jiang Xin <jiangxin AT ossxp.com>
        for r in repos:
            if fnmatch(path, r):
                log.debug('Access ok for %(user)r as %(mode)r on %(path)r' %
                          dict(
                              user=user,
                              mode=mode,
                              path=path,
                          ))
                mapping = path
                break

        # Check mapping even if (path,mode) found in this group.
        try:
            re_mapping = None
            for option in config.options('group %s' % groupname):
                if not option.startswith('map'):
                    continue
                (_ignore, opt_right) = option.split(' ', 1)
                (opt_mode, opt_path) = opt_right.strip().split(' ', 1)
                opt_path = opt_path.strip()
                if opt_mode not in mode_syns:
                    continue
                if fnmatch(path, opt_path):
                    re_mapping = config.get('group %s' % groupname, option)
                    if ':' in re_mapping:
                        (opt_from, opt_to) = re_mapping.split(':', 1)
                        re_mapping = re.sub(opt_from, opt_to, path)
                    elif '\\1' in re_mapping:
                        re_mapping = re_mapping.replace('\\1', path)
                    break
        except (NoSectionError, NoOptionError):
            pass
        else:
            if re_mapping is not None:
                mapping = re_mapping
                log.debug(
                    'Mapping 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 = None
            try:
                prefix = config.get('group %s' % groupname, 'repositories')
            except (NoSectionError, NoOptionError):
                try:
                    prefix = config.get('gitosis', 'repositories')
                except (NoSectionError, NoOptionError):
                    prefix = 'repositories'

            log.debug('Using prefix %(prefix)r for %(path)r' % dict(
                prefix=prefix,
                path=mapping,
            ))
            return (prefix, mapping, mode)
Пример #22
0
def test_no_emptyConfig():
    cfg = RawConfigParser()
    gen = group.getMembership(config=cfg, user='******')
    eq(gen.next(), 'all')
    assert_raises(StopIteration, gen.next)
Пример #23
0
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

    # First test an explicit '[user %s]' section
    log.debug(
        'Checking for explicit access for %(user)r as %(mode)r on %(path)r' %
        dict(
            user=user,
            mode=mode,
            path=path,
        ))

    try:
        repos = config.get('user %s' % user, mode)
    except (NoSectionError, NoOptionError):
        repos = []
    else:
        log.debug('Found section for %(user)r as %(mode)r = %(repos)r' % dict(
            user=user,
            mode=mode,
            repos=repos,
        ))
        repos = repos.split()

    mapping = None
    groupname = None

    if path in repos:
        log.debug('Explicit access ok for %(user)r as %(mode)r on %(path)r' %
                  dict(
                      user=user,
                      mode=mode,
                      path=path,
                  ))
        mapping = path
    else:
        # then go in old code
        for groupname in group.getMembership(config=config, user=user):
            try:
                repos = config.get('group %s' % groupname, mode)
            except (NoSectionError, NoOptionError):
                repos = []
            else:
                repos = repos.split()

            mapping = None
            if path in repos:
                log.debug('Access ok for %(user)r as %(mode)r on %(path)r' %
                          dict(
                              user=user,
                              mode=mode,
                              path=path,
                          ))
                mapping = path
                break
            else:
                try:
                    mapping = config.get('group %s' % groupname,
                                         'map %s %s' % (mode, path))
                except (NoSectionError, NoOptionError):
                    pass
                else:
                    log.debug(
                        'Access ok for %(user)r as %(mode)r on %(path)r=%(mapping)r'
                        % dict(
                            user=user,
                            mode=mode,
                            path=path,
                            mapping=mapping,
                        ))
                    break

    # If we used a [user _] section, we consider being in the 'gitosis' group
    if groupname is None:
        groupname = 'gitosis'

    if mapping is not None:
        prefix = None
        try:
            prefix = config.get('group %s' % groupname, 'repositories')
        except (NoSectionError, NoOptionError):
            try:
                prefix = config.get('gitosis', 'repositories')
            except (NoSectionError, NoOptionError):
                prefix = 'repositories'

        log.debug('Using prefix %(prefix)r for %(path)r' % dict(
            prefix=prefix,
            path=mapping,
        ))
        return (prefix, mapping)
Пример #24
0
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

    try:
        default_prefix = config.get('gitosis', 'repositories')
    except (NoSectionError, NoOptionError):
        default_prefix = 'repositories'

    sections = ['group %s' % item for item in
                 group.getMembership(config=config, user=user)]
    sections.insert(0, 'user %s' % user)

    for sectname in sections:
        try:
            repos = config.get(sectname, mode)
        except (NoSectionError, NoOptionError):
            repos = []
        else:
            repos = repos.split()

        mapping = None

        if path in repos:
            log.debug(
                'Access ok for %(user)r as %(mode)r on %(path)r'
                % dict(
                user=user,
                mode=mode,
                path=path,
                ))
            mapping = path
        else:
            try:
                mapping = config.get(sectname,
                                     'map %s %s' % (mode, path))
            except (NoSectionError, NoOptionError):
                pass
            else:
                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 None and mode == 'readonly':
            try:
                if config.getboolean(sectname, 'allow-read-all'):
                    log.debug(
                        'Access ok for %(user)r as %(mode)r on %(path)r via allow-read-all'
                        % dict(user=user,mode=mode,path=path))
                    mapping = path
            except (NoSectionError, NoOptionError):
                pass

        if mapping is not None:
            prefix = None
            try:
                prefix = config.get(sectname, 'repositories')
            except (NoSectionError, NoOptionError):
                prefix = default_prefix

            log.debug(
                'Using prefix %(prefix)r for %(path)r'
                % dict(
                prefix=prefix,
                path=mapping,
                ))
            return (prefix, mapping)

    owner = getOwnerAccess(config, mode, path)
    if owner == user:
        try:
            prefix = config.get('user %s' % owner, 'repositories')
        except (NoSectionError, NoOptionError):
            prefix = default_prefix

        log.debug(
            'Access ok for %(user)r as %(mode)r on owned %(path)r, using prefix %(prefix)r'
            % dict(
                prefix=prefix,
                path=path,
                user=user,
                mode=mode,
                ))
        return (prefix, path)
Пример #25
0
def test_no_emptyGroup():
    cfg = RawConfigParser()
    cfg.add_section('group hackers')
    gen = group.getMembership(config=cfg, user='******')
    eq(gen.next(), 'all')
    assert_raises(StopIteration, gen.next)
Пример #26
0
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)