Merge lp:~cjwatson/launchpad/git-private-code-import into lp:launchpad

Proposed by Colin Watson
Status: Merged
Merged at revision: 18764
Proposed branch: lp:~cjwatson/launchpad/git-private-code-import
Merge into: lp:launchpad
Diff against target: 95 lines (+50/-7)
2 files modified
lib/lp/code/xmlrpc/git.py (+2/-1)
lib/lp/code/xmlrpc/tests/test_git.py (+48/-6)
To merge this branch: bzr merge lp:~cjwatson/launchpad/git-private-code-import
Reviewer Review Type Date Requested Status
William Grant code Approve
Daniel Manrique (community) Abstain
Review via email: mp+353874@code.launchpad.net

Commit message

Fix incorrect visibility check that broke code imports targeted at private Git repositories.

To post a comment you must log in.
Revision history for this message
Daniel Manrique (roadmr) wrote :

LGTM, thanks! I'm not a Launchpad code reviewer and I don't know this codebase well enough, so I'll abstain, but this makes sense.

review: Abstain
Revision history for this message
William Grant (wgrant) :
review: Approve (code)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'lib/lp/code/xmlrpc/git.py'
--- lib/lp/code/xmlrpc/git.py 2016-10-14 11:48:57 +0000
+++ lib/lp/code/xmlrpc/git.py 2018-08-28 14:08:04 +0000
@@ -108,7 +108,8 @@
108 # The authentication parameters specifically grant access to108 # The authentication parameters specifically grant access to
109 # this repository, so we can bypass other checks.109 # this repository, so we can bypass other checks.
110 # For the time being, this only works for code imports.110 # For the time being, this only works for code imports.
111 assert repository.repository_type == GitRepositoryType.IMPORTED111 assert (
112 naked_repository.repository_type == GitRepositoryType.IMPORTED)
112 hosting_path = naked_repository.getInternalPath()113 hosting_path = naked_repository.getInternalPath()
113 writable = True114 writable = True
114 private = naked_repository.private115 private = naked_repository.private
115116
=== modified file 'lib/lp/code/xmlrpc/tests/test_git.py'
--- lib/lp/code/xmlrpc/tests/test_git.py 2016-10-14 11:48:57 +0000
+++ lib/lp/code/xmlrpc/tests/test_git.py 2018-08-28 14:08:04 +0000
@@ -53,13 +53,14 @@
53 self.repository_set = getUtility(IGitRepositorySet)53 self.repository_set = getUtility(IGitRepositorySet)
5454
55 def assertGitRepositoryNotFound(self, requester, path, permission="read",55 def assertGitRepositoryNotFound(self, requester, path, permission="read",
56 can_authenticate=False):56 can_authenticate=False, macaroon_raw=None):
57 """Assert that the given path cannot be translated."""57 """Assert that the given path cannot be translated."""
58 if requester is not None:58 if requester is not None:
59 requester = requester.id59 requester = requester.id
60 fault = self.git_api.translatePath(60 auth_params = {"uid": requester, "can-authenticate": can_authenticate}
61 path, permission,61 if macaroon_raw is not None:
62 {"uid": requester, "can-authenticate": can_authenticate})62 auth_params["macaroon"] = macaroon_raw
63 fault = self.git_api.translatePath(path, permission, auth_params)
63 self.assertEqual(64 self.assertEqual(
64 faults.GitRepositoryNotFound(path.strip("/")), fault)65 faults.GitRepositoryNotFound(path.strip("/")), fault)
6566
@@ -145,8 +146,8 @@
145 translation = self.git_api.translatePath(path, permission, auth_params)146 translation = self.git_api.translatePath(path, permission, auth_params)
146 login(ANONYMOUS)147 login(ANONYMOUS)
147 self.assertEqual(148 self.assertEqual(
148 {"path": repository.getInternalPath(), "writable": writable,149 {"path": removeSecurityProxy(repository).getInternalPath(),
149 "trailing": trailing, "private": private},150 "writable": writable, "trailing": trailing, "private": private},
150 translation)151 translation)
151152
152 def assertCreates(self, requester, path, can_authenticate=False,153 def assertCreates(self, requester, path, can_authenticate=False,
@@ -663,6 +664,47 @@
663 self.assertPermissionDenied(664 self.assertPermissionDenied(
664 None, path, permission="write", macaroon_raw="nonsense")665 None, path, permission="write", macaroon_raw="nonsense")
665666
667 def test_translatePath_private_code_import(self):
668 # A code import worker with a suitable macaroon can write to a
669 # repository associated with a running private code import job.
670 self.pushConfig("codeimport", macaroon_secret_key="some-secret")
671 machine = self.factory.makeCodeImportMachine(set_online=True)
672 code_imports = [
673 self.factory.makeCodeImport(
674 target_rcs_type=TargetRevisionControlSystems.GIT)
675 for _ in range(2)]
676 private_repository = code_imports[0].git_repository
677 removeSecurityProxy(private_repository).transitionToInformationType(
678 InformationType.PRIVATESECURITY, private_repository.owner)
679 with celebrity_logged_in("vcs_imports"):
680 jobs = [
681 self.factory.makeCodeImportJob(code_import=code_import)
682 for code_import in code_imports]
683 issuer = getUtility(IMacaroonIssuer, "code-import-job")
684 macaroons = [
685 removeSecurityProxy(issuer).issueMacaroon(job) for job in jobs]
686 path = u"/%s" % code_imports[0].git_repository.unique_name
687 self.assertPermissionDenied(
688 None, path, permission="write", macaroon_raw=macaroons[0])
689 with celebrity_logged_in("vcs_imports"):
690 getUtility(ICodeImportJobWorkflow).startJob(jobs[0], machine)
691 self.assertTranslates(
692 None, path, code_imports[0].git_repository, True,
693 permission="write", macaroon_raw=macaroons[0].serialize(),
694 private=True)
695 # The expected faults are slightly different from the public case,
696 # because we deny the existence of private repositories.
697 self.assertGitRepositoryNotFound(
698 None, path, permission="write",
699 macaroon_raw=macaroons[1].serialize())
700 self.assertGitRepositoryNotFound(
701 None, path, permission="write",
702 macaroon_raw=Macaroon(
703 location=config.vhost.mainsite.hostname, identifier="another",
704 key="another-secret").serialize())
705 self.assertGitRepositoryNotFound(
706 None, path, permission="write", macaroon_raw="nonsense")
707
666 def test_notify(self):708 def test_notify(self):
667 # The notify call creates a GitRefScanJob.709 # The notify call creates a GitRefScanJob.
668 repository = self.factory.makeGitRepository()710 repository = self.factory.makeGitRepository()