def fork_repo(request, repo): settings = get_settings(request) auth = request.auth_backend username, repo_name = repo.split('/', 1) if auth.has_permission(request.user, ('kittygit', 'read', '%s/%s' % (username, repo_name))): to_repo_dir = get_full_repo_dir(settings, request.user, repo_name) from_repo_dir = get_full_repo_dir(settings, username, repo_name) success = operations.fork_repository( settings.get('git', 'git'), request.stdin, request.stdout, request.stderr, from_repo_dir, to_repo_dir ) if success: auth.add_permission(request.user, ('kittygit', 'write', '%s/%s' % (request.user, repo_name))) auth.add_permission(request.user, ('kittygit', 'read', '%s/%s' % (request.user, repo_name))) auth.add_permission(username, ('kittygit', 'read', '%s/%s' % (request.user, repo_name))) clone_base = get_clone_base_url(settings) return Success({'message':"Repository '%s' successfully forked.\nClone it at '%s:%s/%s.git'" % (repo, clone_base, request.user, repo_name)}) else: raise NappingCatException('Fork failed.') else: raise KittyGitUnauthorized("You don't have permission to read %s.git. Sorry!" % repo)
def create_repo(request, repo_name, template_dir=None): auth = request.auth_backend settings = get_settings(request) if auth.has_permission(request.user, ('kittygit','create')): auth.add_permission(request.user, ('kittygit','write','%s/%s' % (request.user, repo_name))) auth.add_permission(request.user, ('kittygit', 'read', '%s/%s' % (request.user, repo_name))) full_repo_dir = get_full_repo_dir(settings, request.user, repo_name) success = operations.create_repository( settings.get('git', 'git'), request.stdin, request.stdout, request.stderr, full_repo_dir, template_dir ) if success: clone_base = get_clone_base_url(settings) clone_path = '/'.join([request.user, repo_name]) + '.git' return Success({ 'message':""" Successfully created a new repository. Clone it at %s:%s """.strip() % (clone_base, clone_path), 'clone_path':clone_path }) else: raise NappingCatException('Create repo failed.') raise KittyGitUnauthorized('You don\'t have permission to create a repo.')
def test_fail(self): settings_str = """ [kittyconfig] auth = tests.gittests.test_utils.AllAuth [kittygit] repo_dir = %s """.strip() % self.test_dir test_settings = fake_settings(settings_str) user = '******' % random.randint(0, 100) repo_name = 'repo-%d' % random.randint(0, 100) repo = '%s/%s.git' % (user, repo_name) streams = (sys.stdin, sys.stdout, sys.stderr) random_root_patterns = random.randint(1, 100) request = Request(user, "kitty-git create-repo 'repo'", test_settings, streams, random_root_patterns) settings = handlers.get_settings(request) full_repo_dir = utils.get_full_repo_dir(settings, user, repo_name) self.mox.StubOutWithMock(subprocess, 'call') subprocess.call( args=['git','--git-dir=.', 'init', '--bare'], cwd=full_repo_dir, stdout=sys.stderr, close_fds=True ).AndReturn(random.randint(1,100)) self.assertRaises(NappingCatException, handlers.create_repo, request, repo_name)
def test_success_with_template_dir(self): settings_str = """ [kittyconfig] auth = tests.gittests.test_utils.AllAuth [kittygit] repo_dir = %s """.strip() % self.test_dir test_settings = fake_settings(settings_str) user = '******' % random.randint(0, 100) repo_name = 'repo-%d' % random.randint(0, 100) repo = '%s/%s.git' % (user, repo_name) with open('/dev/null', 'w') as out_stream: with open('/dev/null', 'w') as err_stream: streams = (sys.stdin, out_stream, err_stream) random_root_patterns = random.randint(1, 100) request = Request(user, "kitty-git create-repo 'repo'", test_settings, streams, random_root_patterns) settings = handlers.get_settings(request) full_repo_dir = utils.get_full_repo_dir(settings, user, repo_name) result = handlers.create_repo(request, repo_name, os.path.join(os.getcwd(), 'tests/support')) self.assertTrue(user in result.content['message']) self.assertTrue(repo_name in result.content['message']) self.assertTrue(os.path.isdir(full_repo_dir)) self.assertTrue(os.path.isfile('tests/support/hooks/post-commit')) import time; time.sleep(1) # pass the time for a bit for things to # flush to disk self.assertTrue(os.path.isfile('%s/hooks/post-commit' % full_repo_dir))
def test_takes_user_dir(self): random_dir = 'rand%d' % random.randint(1,100) settings = { 'repo_dir':random_dir } user = '******' % random.randint(1,100) repo = 'repo-%d' % random.randint(1,100) results = utils.get_full_repo_dir(settings, user, repo) self.assertEqual('%s/%s/%s.git' % (random_dir, user, repo), results)
def test_successful(self): settings_str = """ [kittyconfig] auth = tests.gittests.test_utils.AllAuth [kittygit] repo_dir = %s """.strip() % self.test_dir test_settings = fake_settings(settings_str) user = '******' % random.randint(0, 100) repo_name = str(random.randint(0,100)) repo = '%s/%s.git' % (user, repo_name) variants = ( ("git-upload-pack '%s'", "-upload-pack "), ("git upload-pack '%s'", " upload-pack "), ("git-receive-pack '%s'", "-receive-pack "), ("git receive-pack '%s'", " receive-pack "), ) streams = (sys.stdin, sys.stdout, sys.stderr) for cmd, action in variants: random_root_patterns = random.randint(1, 100) request = Request(user, cmd % repo, test_settings, streams, random_root_patterns) path = utils.get_full_repo_dir(handlers.get_settings(request), user, repo_name) with open('/dev/null', 'w') as output: operations.create_repository('git', output, output, output, path, bare=True) self.mox.StubOutWithMock(subprocess, 'call') subprocess.call( args=['git', 'shell', '-c', ' '.join(['git%s'%action.strip(), "'%s'"%path])], cwd=path, stdout=sys.stdout, stderr=sys.stderr, stdin=sys.stdin, ).AndReturn(0) self.mox.ReplayAll() result = handlers.handle_git(request, action) self.assertTrue(isinstance(result, Response)) self.assertTrue(user in str(result)) self.assertTrue(repo_name in str(result)) self.mox.UnsetStubs() shutil.rmtree(path)
def handle_git(request, action, permission_prefix='kittygit'): settings = get_settings(request) auth = request.auth_backend command, subcommand, repo = None, None, None if action in (' receive-pack ', ' upload-pack '): command, subcommand, repo = request.command.split(' ', 2) else: command, repo = request.command.split(' ', 1) modes = { ' receive-pack ':'write', '-receive-pack ':'write', ' upload-pack ':'read', '-upload-pack ':'read', } perm = modes[action] parsed_repo = repo[1:-1][:-4] # remove quotes and .git extension username, repo_name = parsed_repo.split('/', 1) if auth.has_permission(request.user, (permission_prefix, perm, parsed_repo)): directory = get_full_repo_dir(settings, username, repo_name) success = operations.git_shell( settings.get('git', 'git'), request.stdin, request.stdout, request.stderr, action, directory ) if success: verb = { 'write':'wrote to', 'read':'read from', }[perm] return Success("Successfully %s repo '%s'" % (verb, parsed_repo), TextResponse) raise NappingCatException('git%s failed.' % action.strip()) else: raise KittyGitUnauthorized("You don't have permission to %s repo '%s'" % (perm, parsed_repo))
def test_success(self): settings_str = """ [kittyconfig] auth = tests.gittests.test_utils.AllAuth [kittygit] repo_dir = %s """.strip() % self.test_dir test_settings = fake_settings(settings_str) user = '******' % random.randint(0, 100) repo_name = 'repo-%d' % random.randint(0, 100) repo = '%s/%s.git' % (user, repo_name) with open('/dev/null', 'w') as out_stream: with open('/dev/null', 'w') as err_stream: streams = (sys.stdin, out_stream, err_stream) random_root_patterns = random.randint(1, 100) request = Request(user, "kitty-git create-repo 'repo'", test_settings, streams, random_root_patterns) settings = handlers.get_settings(request) full_repo_dir = utils.get_full_repo_dir(settings, user, repo_name) result = handlers.create_repo(request, repo_name) self.assertTrue(user in result.content['message']) self.assertTrue(repo_name in result.content['message']) self.assertTrue(os.path.isdir(full_repo_dir))
def test_safe_default(self): settings = {} user = '******' % random.randint(1,100) repo = 'repo-%d' % random.randint(1,100) results = utils.get_full_repo_dir(settings, user, repo) self.assertEqual(os.path.expanduser('~/repos/%s/%s.git' % (user, repo)), results)