def test_base_global_relative(): cfg = RawConfigParser() cfg.add_section('gitosis') cfg.set('gitosis', 'repositories', 'some/relative/path') cfg.add_section('group fooers') cfg.set('group fooers', 'members', 'jdoe') cfg.set('group fooers', 'map writable foo/bar', 'baz/quux/thud') eq( access.haveAccess(config=cfg, user='******', mode='writable', path='foo/bar'), ('some/relative/path', 'baz/quux/thud', 'write')) eq( access.haveAccess(config=cfg, user='******', mode='writeable', path='foo/bar'), ('some/relative/path', 'baz/quux/thud', 'write')) eq( access.haveAccess(config=cfg, user='******', mode='write', path='foo/bar'), ('some/relative/path', 'baz/quux/thud', 'write'))
def test_write_no_simple(): cfg = RawConfigParser() eq(access.haveAccess(config=cfg, user='******', mode='writable', path='foo/bar'), None) eq(access.haveAccess(config=cfg, user='******', mode='writeable', path='foo/bar'), None) eq(access.haveAccess(config=cfg, user='******', mode='write', path='foo/bar'), None)
def test_read_no_simple(): cfg = RawConfigParser() eq( access.haveAccess(config=cfg, user='******', mode='readonly', path='foo/bar'), None) eq(access.haveAccess(config=cfg, user='******', mode='read', path='foo/bar'), None)
def test_write_no_simple_wouldHaveReadonly(): cfg = RawConfigParser() cfg.add_section('group fooers') cfg.set('group fooers', 'members', 'jdoe') cfg.set('group fooers', 'readonly', 'foo/bar') eq(access.haveAccess(config=cfg, user='******', mode='writable', path='foo/bar'), None) eq(access.haveAccess(config=cfg, user='******', mode='write', path='foo/bar'), None)
def test_read_yes_simple(): cfg = RawConfigParser() cfg.add_section('group fooers') cfg.set('group fooers', 'members', 'jdoe') cfg.set('group fooers', 'readonly', 'foo/bar') eq(access.haveAccess(config=cfg, user='******', mode='readonly', path='foo/bar'), ('repositories', 'foo/bar', 'read')) eq(access.haveAccess(config=cfg, user='******', mode='read', path='foo/bar'), ('repositories', 'foo/bar', 'read'))
def test_read_yes_map_wouldHaveWritable(): cfg = RawConfigParser() cfg.add_section('group fooers') cfg.set('group fooers', 'members', 'jdoe') cfg.set('group fooers', 'map writable foo/bar', 'quux/thud') eq(access.haveAccess(config=cfg, user='******', mode='readonly', path='foo/bar'), None) eq(access.haveAccess(config=cfg, user='******', mode='read', path='foo/bar'), None)
def test_write_yes_map_multi_spaces(): cfg = RawConfigParser() cfg.add_section('group fooers') cfg.set('group fooers', 'members', 'jdoe') cfg.set('group fooers', 'map writeable foo/bar', 'quux/thud') eq(access.haveAccess(config=cfg, user='******', mode='writable', path='foo/bar'), ('repositories', 'quux/thud', 'write')) eq(access.haveAccess(config=cfg, user='******', mode='writeable', path='foo/bar'), ('repositories', 'quux/thud', 'write')) eq(access.haveAccess(config=cfg, user='******', mode='writable', path='foo/bar'), ('repositories', 'quux/thud', 'write'))
def test_base_global_unset(): cfg = RawConfigParser() cfg.add_section('gitosis') cfg.add_section('group fooers') cfg.set('group fooers', 'members', 'jdoe') cfg.set('group fooers', 'readonly', 'foo xyzzy bar') eq(access.haveAccess( config=cfg, user='******', mode='readonly', path='xyzzy'), ('repositories', 'xyzzy', 'read')) eq(access.haveAccess( config=cfg, user='******', mode='read', path='xyzzy'), ('repositories', 'xyzzy', 'read'))
def test_dotgit(): # a .git extension is always allowed to be added cfg = RawConfigParser() cfg.add_section('group fooers') cfg.set('group fooers', 'members', 'jdoe') cfg.set('group fooers', 'writable', 'foo/bar') eq(access.haveAccess(config=cfg, user='******', mode='writable', path='foo/bar.git'), ('repositories', 'foo/bar', 'write')) eq(access.haveAccess(config=cfg, user='******', mode='writeable', path='foo/bar.git'), ('repositories', 'foo/bar', 'write')) eq(access.haveAccess(config=cfg, user='******', mode='write', path='foo/bar.git'), ('repositories', 'foo/bar', 'write'))
def test_read_yes_all(): cfg = RawConfigParser() cfg.add_section('group fooers') cfg.set('group fooers', 'members', '@all') cfg.set('group fooers', 'readonly', 'foo/bar') eq( access.haveAccess(config=cfg, user='******', mode='readonly', path='foo/bar'), ('repositories', 'foo/bar', 'read')) eq(access.haveAccess(config=cfg, user='******', mode='read', path='foo/bar'), ('repositories', 'foo/bar', 'read'))
def test_read_yes_map_wouldHaveWritable(): cfg = RawConfigParser() cfg.add_section('group fooers') cfg.set('group fooers', 'members', 'jdoe') cfg.set('group fooers', 'map writable foo/bar', 'quux/thud') eq( access.haveAccess(config=cfg, user='******', mode='readonly', path='foo/bar'), None) eq(access.haveAccess(config=cfg, user='******', mode='read', path='foo/bar'), None)
def test_base_global_unset(): cfg = RawConfigParser() cfg.add_section('gitosis') cfg.add_section('group fooers') cfg.set('group fooers', 'members', 'jdoe') cfg.set('group fooers', 'readonly', 'foo xyzzy bar') eq( access.haveAccess(config=cfg, user='******', mode='readonly', path='xyzzy'), ('repositories', 'xyzzy', 'read')) eq(access.haveAccess(config=cfg, user='******', mode='read', path='xyzzy'), ('repositories', 'xyzzy', 'read'))
def test_typo_readable(): cfg = RawConfigParser() cfg.add_section('group foo') cfg.set('group foo', 'members', 'jdoe') cfg.set('group foo', 'readable', 'foo') log = logging.getLogger('gitosis.access.haveAccess') buf = StringIO() handler = logging.StreamHandler(buf) log.addHandler(handler) access.haveAccess(config=cfg, user='******', mode='read', path='foo.git') log.removeHandler(handler) handler.flush() assert ("Repository 'foo' config has typo \"readable\", shou" + "ld be \"read\"" in buf.getvalue().splitlines())
def test_write_no_simple_wouldHaveReadonly(): cfg = RawConfigParser() cfg.add_section('group fooers') cfg.set('group fooers', 'members', 'jdoe') cfg.set('group fooers', 'readonly', 'foo/bar') eq( access.haveAccess(config=cfg, user='******', mode='writable', path='foo/bar'), None) eq( access.haveAccess(config=cfg, user='******', mode='write', path='foo/bar'), None)
def test_base_local(): cfg = RawConfigParser() 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') eq(access.haveAccess( config=cfg, user='******', mode='writable', path='foo/bar'), ('some/relative/path', 'baz/quux/thud', 'write')) eq(access.haveAccess( config=cfg, user='******', mode='writeable', path='foo/bar'), ('some/relative/path', 'baz/quux/thud', 'write')) eq(access.haveAccess( config=cfg, user='******', mode='write', path='foo/bar'), ('some/relative/path', 'baz/quux/thud', 'write'))
def test_init_yes_simple(): cfg = RawConfigParser() cfg.add_section('group fooers') cfg.set('group fooers', 'members', 'jdoe') cfg.set('group fooers', 'init', 'foo/bar') eq(access.haveAccess(config=cfg, user='******', mode='init', path='foo/bar'), ('repositories', 'foo/bar', 'init'))
def test_user(): cfg = RawConfigParser() cfg.add_section('user jdoe') cfg.set('user jdoe', 'readonly', 'foo xyzzy bar') eq(access.haveAccess( config=cfg, user='******', mode='readonly', path='xyzzy'), ('repositories', 'xyzzy'))
def test_base_global_absolute(): cfg = RawConfigParser() 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') eq(access.haveAccess( config=cfg, user='******', mode='writable', path='foo/bar'), ('/a/leading/path', 'baz/quux/thud', 'write')) eq(access.haveAccess( config=cfg, user='******', mode='writeable', path='foo/bar'), ('/a/leading/path', 'baz/quux/thud', 'write')) eq(access.haveAccess( config=cfg, user='******', mode='write', path='foo/bar'), ('/a/leading/path', 'baz/quux/thud', 'write'))
def test_write_no_simple(): cfg = RawConfigParser() eq( access.haveAccess(config=cfg, user='******', mode='writable', path='foo/bar'), None)
def set_export_ok(config): try: global_enable = config.getboolean('gitosis', 'daemon') except (NoSectionError, NoOptionError): global_enable = False log.debug( 'Global default is %r', {True: 'allow', False: 'deny'}.get(global_enable), ) try: enable_if_all = config.getboolean('gitosis', 'daemon-if-all') except (NoSectionError, NoOptionError): enable_if_all = False log.debug( 'If accessible to @all: %r', {True: 'allow', False: 'unchanged'}.get(enable_if_all), ) for (dirpath, repo, name) in walk_repos(config): try: enable = config.getboolean('repo %s' % name, 'daemon') except (NoSectionError, NoOptionError): enable = global_enable if not enable and enable_if_all: (users,groups,all_refs) = access.haveAccess(config,name) enable = ('@all' in all_refs) if enable: log.debug('Allow %r', name) allow_export(os.path.join(dirpath, repo)) else: log.debug('Deny %r', name) deny_export(os.path.join(dirpath, repo))
def test_pattern(): cfg = RawConfigParser() cfg.add_section('group fooers') cfg.set('group fooers', 'members', 'jdoe') cfg.set('group fooers', 'writable', 'foo/*') eq(access.haveAccess(config=cfg, user='******', mode='writable', path='foo/bar'), ('repositories', 'foo/bar'))
def test_typo_readable(): cfg = RawConfigParser() cfg.add_section('group foo') cfg.set('group foo', 'members', 'jdoe') cfg.set('group foo', 'readable', 'foo') log = logging.getLogger('gitosis.access.haveAccess') buf = StringIO() handler = logging.StreamHandler(buf) log.addHandler(handler) access.haveAccess(config=cfg, user='******', mode='read', path='foo.git') log.removeHandler(handler) handler.flush() assert ( "Repository 'foo' config has typo \"readable\", shou" +"ld be \"read\"" in buf.getvalue().splitlines() )
def test_allow_all(): cfg = RawConfigParser() cfg.add_section('user jdoe') cfg.set('user jdoe', 'allow-read-all', 'yes') cfg.add_section('repo xyzzy') eq(access.haveAccess( config=cfg, user='******', mode='readonly', path='xyzzy'), ('repositories', 'xyzzy'))
def test_write_yes_simple(): cfg = RawConfigParser() cfg.add_section('rsp') cfg.set('rsp', 'haveAccessURL', 'example.org') cfg.add_section('group fooers') cfg.set('group fooers', 'members', 'jdoe') cfg.set('group fooers', 'writable', 'foo/bar') eq(access.haveAccess(config=cfg, user='******', mode='writable', path='foo/bar'), ('repositories', 'foo/bar'))
def test_write_no_map_wouldHaveReadonly(): cfg = RawConfigParser() cfg.add_section('group fooers') cfg.set('group fooers', 'members', 'jdoe') cfg.set('group fooers', 'map readonly foo/bar', 'quux/thud') cfg.add_section('rsp') cfg.set('rsp', 'haveAccessURL', 'example.org') eq(access.haveAccess(config=cfg, user='******', mode='writable', path='foo/bar'), None)
def test_write_yes_alias(): cfg = RawConfigParser() cfg.add_section('gitosis') cfg.set('gitosis', 'foo', 'bar baz') cfg.add_section('group fooers') cfg.set('group fooers', 'members', 'jdoe') cfg.set('group fooers', 'writable', '@foo') eq(access.haveAccess(config=cfg, user='******', mode='writable', path='bar'), ('repositories', 'bar'))
def test_read_yes_simple_wouldHaveWritable(): cfg = RawConfigParser() cfg.add_section('group fooers') cfg.set('group fooers', 'members', 'jdoe') cfg.set('group fooers', 'writable', 'foo/bar') cfg.add_section('rsp') cfg.set('rsp', 'haveAccessURL', 'example.org') eq(access.haveAccess(config=cfg, user='******', mode='readonly', path='foo/bar'), None)
def test_user(): cfg = RawConfigParser() cfg.add_section('user jdoe') cfg.set('user jdoe', 'readonly', 'foo xyzzy bar') eq( access.haveAccess(config=cfg, user='******', mode='readonly', path='xyzzy'), ('repositories', 'xyzzy'))
def test_read_yes_map(): cfg = RawConfigParser() cfg.add_section('group fooers') cfg.set('group fooers', 'members', 'jdoe') cfg.set('group fooers', 'map readonly foo/bar', 'quux/thud') cfg.add_section('rsp') cfg.set('rsp', 'haveAccessURL', 'example.org') eq(access.haveAccess(config=cfg, user='******', mode='readonly', path='foo/bar'), ('repositories', 'quux/thud'))
def test_bad_owner(): cfg = RawConfigParser() cfg.add_section('gitosis') cfg.set('gitosis', 'owner-readonly', 'yes') cfg.add_section('repo xyzzy') cfg.set('repo xyzzy', 'owner', 'jdoe') eq(access.haveAccess( config=cfg, user='******', mode='readonly', path='xyzzy'), None)
def test_write_yes_map(): cfg = RawConfigParser() cfg.add_section('group fooers') cfg.set('group fooers', 'members', 'jdoe') cfg.set('group fooers', 'map writable foo/bar', 'quux/thud') eq( access.haveAccess(config=cfg, user='******', mode='writable', path='foo/bar'), ('repositories', 'quux/thud'))
def test_dotgit(): # a .git extension is always allowed to be added cfg = RawConfigParser() cfg.add_section('group fooers') cfg.set('group fooers', 'members', 'jdoe') cfg.set('group fooers', 'writable', 'foo/bar') eq( access.haveAccess(config=cfg, user='******', mode='writable', path='foo/bar.git'), ('repositories', 'foo/bar'))
def test_base_global_relative(): cfg = RawConfigParser() cfg.add_section('gitosis') cfg.set('gitosis', 'repositories', 'some/relative/path') cfg.add_section('group fooers') cfg.set('group fooers', 'members', 'jdoe') cfg.set('group fooers', 'map writable foo/bar', 'baz/quux/thud') cfg.add_section('rsp') cfg.set('rsp', 'haveAccessURL', 'example.org') eq(access.haveAccess( config=cfg, user='******', mode='writable', path='foo/bar'), ('some/relative/path', 'baz/quux/thud'))
def test_base_global_relative_simple(): cfg = RawConfigParser() cfg.add_section('gitosis') cfg.set('gitosis', 'repositories', 'some/relative/path') cfg.add_section('group fooers') cfg.set('group fooers', 'members', 'jdoe') cfg.set('group fooers', 'readonly', 'foo xyzzy bar') cfg.add_section('rsp') cfg.set('rsp', 'haveAccessURL', 'example.org') eq(access.haveAccess( config=cfg, user='******', mode='readonly', path='xyzzy'), ('some/relative/path', 'xyzzy'))
def path_for_write(cfg, user, path): # write access is always sufficient newpath = access.haveAccess( 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.haveAccess( 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, ) return newpath
def test_fnmatch_write_yes_map(): cfg = RawConfigParser() cfg.add_section('group fooers') cfg.set('group fooers', 'members', 'jiangxin') cfg.set('group fooers', 'map writable foo/*', 'ossxp/\\1') cfg.set('group fooers', 'map read bar**', 'ossxp/\\1') eq( access.haveAccess(config=cfg, user='******', mode='write', path='foo'), None) eq( access.haveAccess(config=cfg, user='******', mode='write', path='foo-bar'), None) eq( access.haveAccess(config=cfg, user='******', mode='write', path='foo/bar'), ('repositories', 'ossxp/foo/bar', 'write')) eq(access.haveAccess(config=cfg, user='******', mode='read', path='bar'), ('repositories', 'ossxp/bar', 'read')) eq( access.haveAccess(config=cfg, user='******', mode='read', path='bar-foo'), ('repositories', 'ossxp/bar-foo', 'read')) eq( access.haveAccess(config=cfg, user='******', mode='read', path='bar/foo'), ('repositories', 'ossxp/bar/foo', 'read')) eq( access.haveAccess(config=cfg, user='******', mode='read', path='bar/foo/1'), ('repositories', 'ossxp/bar/foo/1', 'read'))
def test_fnmatch_write_yes_map(): cfg = RawConfigParser() cfg.add_section('group fooers') cfg.set('group fooers', 'members', 'jiangxin') cfg.set('group fooers', 'map writable foo/*', 'ossxp/\\1') cfg.set('group fooers', 'map read bar**', 'ossxp/\\1') eq(access.haveAccess(config=cfg, user='******', mode='write', path='foo'), None) eq(access.haveAccess(config=cfg, user='******', mode='write', path='foo-bar'), None) eq(access.haveAccess(config=cfg, user='******', mode='write', path='foo/bar'), ('repositories', 'ossxp/foo/bar', 'write')) eq(access.haveAccess(config=cfg, user='******', mode='read', path='bar'), ('repositories', 'ossxp/bar', 'read')) eq(access.haveAccess(config=cfg, user='******', mode='read', path='bar-foo'), ('repositories', 'ossxp/bar-foo', 'read')) eq(access.haveAccess(config=cfg, user='******', mode='read', path='bar/foo'), ('repositories', 'ossxp/bar/foo', 'read')) eq(access.haveAccess(config=cfg, user='******', mode='read', path='bar/foo/1'), ('repositories', 'ossxp/bar/foo/1', 'read'))
def test_write_no_simple(): cfg = RawConfigParser() cfg.add_section('rsp') cfg.set('rsp', 'haveAccessURL', 'example.org') eq(access.haveAccess(config=cfg, user='******', mode='writable', path='foo/bar'), None)
def serve( cfg, user, command, ): 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() match = ALLOW_RE.match(args) if match is None: raise UnsafeArgumentsError() path = match.group('path') # write access is always sufficient newpath = access.haveAccess( 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.haveAccess( 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.haveAccess( 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) and verb in COMMANDS_WRITE): # 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 p = topdir for segment in repopath.split(os.sep)[:-1]: p = os.path.join(p, segment) util.mkdir(p, 0755) repository.init(path=fullpath) gitweb.set_descriptions( config=cfg, ) generated = util.getGeneratedFilesDir(config=cfg) gitweb.generate_project_list( config=cfg, path=os.path.join(generated, 'projects.list'), ) gitdaemon.set_export_ok( config=cfg, ) # put the verb back together with the new path newcmd = "%(verb)s '%(path)s'" % dict( verb=verb, path=fullpath, ) return newcmd
def serve( cfg, user, command, ): 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() try: match = ALLOW_RE.match(unicode(args, 'utf-8')) except UnicodeDecodeError: raise UnsafeArgumentsError() if match is None: raise UnsafeArgumentsError() path = match.group('path') # admin access is always sufficient newpath = access.haveAccess(config=cfg, user=user, mode='admin', path=path) # write access is always sufficient if newpath is None: newpath = access.haveAccess(config=cfg, user=user, mode='write', path=path) if newpath is None: # didn't have write access newpath = access.haveAccess(config=cfg, user=user, mode='read', 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, mode) = 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) and verb in COMMANDS_WRITE: # 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 # If user not has admin permission, raise a Error if mode != 'admin': raise InitAccessDenied() # create leading directories p = topdir for segment in repopath.split(os.sep)[:-1]: p = os.path.join(p, segment) util.mkdir(p, 0755) repository.init(path=fullpath) # only update description of this repository gitweb.set_repo_descriptions( config=cfg, path=fullpath, ) # not update projects.list here, but in gitosis-admin post-update # only update export flag of this repository gitdaemon.set_repo_export_ok( config=cfg, path=fullpath, ) # put the verb back together with the new path newcmd = "%(verb)s '%(path)s'" % dict( verb=verb, path=fullpath, ) return newcmd
def test_read_no_simple(): cfg = RawConfigParser() eq(access.haveAccess(config=cfg, user='******', mode='readonly', path='foo/bar'), None)
def serve( cfg, user, command, ): 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) elif verb == 'cvs': try: args, server = args.split(None, 1) except: raise UnknownCommandError() if server != 'server': raise UnknownCommandError() path = path_from_args(args) newpath = path_for_write(cfg=cfg, user=user, path=path) if newpath is None: raise WriteAccessDenied() (topdir, repopath) = construct_path(newpath) # Put the repository and base path in the environment repos_dir = util.getRepositoryDir(cfg) fullpath = os.path.join(repos_dir, repopath) os.environ['GIT_CVSSERVER_BASE_PATH'] = repos_dir os.environ['GIT_CVSSERVER_ROOTS'] = fullpath # Put the user's information in the environment try: section = 'user %s' % user name = cfg.get(section, 'name') email = cfg.get(section, 'email') except: log.error('Missing name or email for user "%s"' % user) raise WriteAccessDenied() os.environ['GIT_AUTHOR_NAME'] = name os.environ['GIT_AUTHOR_EMAIL'] = email return 'cvs server' if (verb not in COMMANDS_WRITE and verb not in COMMANDS_READONLY): raise UnknownCommandError() path = path_from_args(args) # write access is always sufficient newpath = path_for_write( cfg=cfg, user=user, path=path) if newpath is None: # didn't have write access newpath = access.haveAccess( 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, repopath) = construct_path(newpath) 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 auto_init_repo(cfg,topdir,repopath) gitweb.set_descriptions( config=cfg, ) generated = util.getGeneratedFilesDir(config=cfg) gitweb.generate_project_list( config=cfg, path=os.path.join(generated, 'projects.list'), ) gitdaemon.set_export_ok( config=cfg, ) htaccess.gen_htaccess_if_enabled( config=cfg, ) # put the verb back together with the new path newcmd = "%(verb)s '%(path)s'" % dict( verb=verb, path=fullpath, ) return newcmd
def serve( cfg, user, command, ): 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() try: match = ALLOW_RE.match(unicode(args, 'utf-8')) except UnicodeDecodeError: raise UnsafeArgumentsError() if match is None: raise UnsafeArgumentsError() path = match.group('path') # admin access is always sufficient newpath = access.haveAccess( config=cfg, user=user, mode='admin', path=path) # write access is always sufficient if newpath is None: newpath = access.haveAccess( config=cfg, user=user, mode='write', path=path) if newpath is None: # didn't have write access newpath = access.haveAccess( config=cfg, user=user, mode='read', 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, mode) = 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) and verb in COMMANDS_WRITE: # 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 # If user not has admin permission, raise a Error if mode != 'admin': raise InitAccessDenied() # create leading directories p = topdir for segment in repopath.split(os.sep)[:-1]: p = os.path.join(p, segment) util.mkdir(p, 0755) repository.init(path=fullpath) # only update description of this repository gitweb.set_repo_descriptions( config=cfg, path=fullpath, ) # not update projects.list here, but in gitosis-admin post-update # only update export flag of this repository gitdaemon.set_repo_export_ok( config=cfg, path=fullpath, ) # put the verb back together with the new path newcmd = "%(verb)s '%(path)s'" % dict( verb=verb, path=fullpath, ) return newcmd
try: all_repos.index(repo) except ValueError, e: all_repos.append(repo) elif (str(opt) == "readonly"): readonlyies = cfg.get(sec, opt) for repo in readonlyies: try: all_repos.index(repo) except ValueError, e: all_repos.append(repo) readonly_repos = [] writable_repos = [] # At this point should have a list of unique repos. for repo in all_repos: rs = access.haveAccess(cfg, user, "writable", repo) if (rs): # has read and write access writable_repos.append(repo) else: rs = access.haveAccess(cfg, user, "readonly", repo) if (rs): # has read only access readonly_repos.append(repo) else: # has no access pass for repo in writable_repos: print "%s, writable" % str(repo) for repo in readonly_repos: print "%s, readonly" % str(repo)
def serve( cfg, user, command, ): 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() match = ALLOW_RE.match(args) if match is None: raise UnsafeArgumentsError() path = match.group('path') # write access is always sufficient newpath = access.haveAccess( 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.haveAccess( 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.haveAccess( 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 p = topdir for segment in repopath.split(os.sep)[:-1]: p = os.path.join(p, segment) util.mkdir(p, 0750) repository.init(path=fullpath) gitweb.set_descriptions( config=cfg, ) generated = util.getGeneratedFilesDir(config=cfg) gitweb.generate_project_list( config=cfg, path=os.path.join(generated, 'projects.list'), ) gitdaemon.set_export_ok( config=cfg, ) # put the verb back together with the new path newcmd = "%(verb)s '%(path)s'" % dict( verb=verb, path=fullpath, ) return newcmd
def get_repo_list(config, user): """ get list of repos and metadata, return as a dictionary """ repositories = util.getRepositoryDir(config) repos = {} try: global_enable = config.getboolean('gitosis', 'gitweb') except (NoSectionError, NoOptionError): global_enable = False for section in config.sections(): l = section.split(None, 1) type_ = l.pop(0) if type_ != 'repo': continue if not l: continue try: enable = config.getboolean(section, 'gitweb') except (NoSectionError, NoOptionError): enable = global_enable if not enable: continue name, = l owner = "" url = "" acl = "" initialized = False descr = "" if not os.path.exists(os.path.join(repositories, name)): namedotgit = '%s.git' % name if os.path.exists(os.path.join(repositories, namedotgit)): name = namedotgit if os.path.exists(os.path.join(repositories, name)): initialized = True if initialized == False: name = '%s.git' % name # check that user has either 'writeable' or 'readonly' access # otherwise don't show them this repo at all has_write = access.haveAccess(config, user, 'writeable', name) if has_write == None: # try misspelling 'writable' has_write = access.haveAccess(config, user, 'writable', name) has_read = access.haveAccess(config, user, 'readonly', name) if has_write: acl = "read/write" elif has_read: acl = "readonly" else: acl = "none" # get 'owner = ' from [repo foo] try: owner = config.get(section, 'owner') except (NoSectionError, NoOptionError): pass # get 'url = ' from [repo foo] try: url = config.get(section, 'url') except (NoSectionError, NoOptionError): pass # get 'description = ' from [repo foo] try: descr = config.get(section, 'description') except (NoSectionError, NoOptionError): pass log.debug('section=%(section)r desc=%(description)r' % dict(section=section, description=descr)) repos[name] = { 'owner': owner, 'url': url, 'acl': acl, 'initialized': initialized, 'description': descr } return repos