def test_owner_full_access(): cfg = GitosisRawConfigParser() cfg.add_section("repo foo/bar") cfg.set("repo foo/bar", "owner", "jdoe") assert access.allowed(cfg, user="******", mode="writable", path="foo/bar") == ("repositories", "foo/bar") assert access.allowed(cfg, user="******", mode="readable", path="foo/bar") == ("repositories", "foo/bar")
def test_read_yes_all(): cfg = GitosisRawConfigParser() cfg.add_section("group fooers") cfg.set("group fooers", "members", "@all") cfg.set("group fooers", "readonly", "foo/bar") assert access.allowed(cfg, user="******", mode="readonly", path="foo/bar") == ("repositories", "foo/bar")
def test_read_yes_map_with_writable(): cfg = GitosisRawConfigParser() cfg.add_section("group fooers") cfg.set("group fooers", "members", "jdoe") cfg.set("group fooers", "map writable foo/bar", "quux/thud") assert access.allowed(cfg, user="******", mode="readonly", path="foo/bar") is None
def test_write_yes_map(): cfg = GitosisRawConfigParser() cfg.add_section("group fooers") cfg.set("group fooers", "members", "jdoe") cfg.set("group fooers", "map writable foo/bar", "quux/thud") assert access.allowed(config=cfg, user="******", mode="writable", path="foo/bar") == ("repositories", "quux/thud")
def test_write_no_simple_with_readonly(): cfg = GitosisRawConfigParser() cfg.add_section("group fooers") cfg.set("group fooers", "members", "jdoe") cfg.set("group fooers", "readonly", "foo/bar") assert access.allowed(cfg, user="******", mode="writable", path="foo/bar") is None
def test_dotgit(): # a .git extension is always allowed to be added cfg = GitosisRawConfigParser() cfg.add_section("group fooers") cfg.set("group fooers", "members", "jdoe") cfg.set("group fooers", "writable", "foo/bar") assert access.allowed(cfg, user="******", mode="writable", path="foo/bar.git") == ("repositories", "foo/bar")
def test_base_local(): cfg = GitosisRawConfigParser() cfg.add_section("group fooers") cfg.set("group fooers", "repositories", "some/relative/path") cfg.set("group fooers", "members", "jdoe") cfg.set("group fooers", "map writable foo/bar", "baz/quux/thud") assert access.allowed(cfg, user="******", mode="writable", path="foo/bar") == ("some/relative/path", "baz/quux/thud")
def test_base_global_unset(): cfg = GitosisRawConfigParser() cfg.add_section("gitosis") cfg.add_section("group fooers") cfg.set("group fooers", "members", "jdoe") cfg.set("group fooers", "readonly", "foo xyzzy bar") assert access.allowed(cfg, user="******", mode="readonly", path="xyzzy") == ("repositories", "xyzzy")
def test_base_global_absolute(): cfg = GitosisRawConfigParser() cfg.add_section("gitosis") cfg.set("gitosis", "repositories", "/a/leading/path") cfg.add_section("group fooers") cfg.set("group fooers", "members", "jdoe") cfg.set("group fooers", "map writable foo/bar", "baz/quux/thud") assert access.allowed(cfg, user="******", mode="writable", path="foo/bar") == ("/a/leading/path", "baz/quux/thud")
def serve(cfg, user, command): """Check the git command for sanity, and then run the git command.""" log = logging.getLogger('gitosis.serve.serve') if '\n' in command: raise CommandMayNotContainNewlineError() try: verb, args = command.split(None, 1) except ValueError: # all known "git-foo" commands take one argument; improve # if/when needed raise UnknownCommandError() if verb == 'git': try: subverb, args = args.split(None, 1) except ValueError: # all known "git foo" commands take one argument; improve # if/when needed raise UnknownCommandError() verb = '%s %s' % (verb, subverb) if (verb not in COMMANDS_WRITE and verb not in COMMANDS_READONLY): raise UnknownCommandError() log.debug('Got command %(cmd)r and args %(args)r' % dict( cmd=verb, args=args, )) if args.startswith("'/") and args.endswith("'"): args = args[1:-1] repos = cfg.repository_dir reposreal = os.path.realpath(repos) if args.startswith(repos): args = os.path.realpath(args)[len(repos)+1:] elif args.startswith(reposreal): args = os.path.realpath(args)[len(reposreal)+1:] else: args = args[1:] args = "'%s'" % (args, ) match = ALLOW_RE.match(args) if match is None: raise UnsafeArgumentsError() path = match.group('path') # write access is always sufficient newpath = access.allowed( config=cfg, user=user, mode='writable', path=path) if newpath is None: # didn't have write access; try once more with the popular # misspelling newpath = access.allowed( config=cfg, user=user, mode='writeable', path=path) if newpath is not None: log.warning('Repository %r config has typo "writeable", ' +'should be "writable"', path, ) if newpath is None: # didn't have write access newpath = access.allowed( config=cfg, user=user, mode='readonly', path=path) if newpath is None: raise ReadAccessDenied() if verb in COMMANDS_WRITE: # didn't have write access and tried to write raise WriteAccessDenied() (topdir, relpath) = newpath assert not relpath.endswith('.git'), \ 'git extension should have been stripped: %r' % relpath repopath = '%s.git' % relpath fullpath = os.path.join(topdir, repopath) if not os.path.exists(fullpath): # it doesn't exist on the filesystem, but the configuration # refers to it, we're serving a write request, and the user is # authorized to do that: create the repository on the fly # create leading directories path = topdir newdirmode = cfg.get('repo %s' % (relpath, ), 'dirmode') if newdirmode is None: newdirmode = cfg.get('gitosis', 'dirmode', default='0750') # Convert string as octal to a number newdirmode = int(newdirmode, 8) for segment in repopath.split(os.sep)[:-1]: path = os.path.join(path, segment) util.mkdir(path, newdirmode) repository.init(path=fullpath, mode=newdirmode) run_hook.build_reposistory_data(cfg) # put the verb back together with the new path newcmd = "%(verb)s '%(path)s'" % dict( verb=verb, path=fullpath, ) return newcmd
def test_write_no_simple(): cfg = GitosisRawConfigParser() assert access.allowed(cfg, user="******", mode="writable", path="foo/bar") is None
def test_read_no_simple(): cfg = GitosisRawConfigParser() assert access.allowed(cfg, user="******", mode="readonly", path="foo/bar") is None