Serve keys from canonical project name

Rather than asking users to know the 'source' name in order to
retrieve the project's public key, use the tenant and canonical
project name.  The tenant already appears in most web urls, and
the project name should be known to the user.

Change-Id: Icd1269ffdd8879bd177fd452978a2c88b2f1b205
This commit is contained in:
James E. Blair 2017-09-15 20:12:30 -06:00 committed by Tobias Henkel
parent 17518a7486
commit 3f42c532df
4 changed files with 8 additions and 14 deletions

View File

@ -15,9 +15,8 @@ Each project in Zuul has its own automatically generated RSA keypair
which can be used by anyone to encrypt a secret and only Zuul is able
to decrypt it. Zuul serves each project's public key using its
build-in webserver. They can be fetched at the path
``/keys/<source>/<project>.pub`` where ``<project>`` is the name of a
project and ``<source>`` is the name of that project's connection in
the main Zuul configuration file.
``/<tenant>/<project>.pub`` where ``<project>`` is the canonical name
of a project and ``<tenant>`` is the name of a tenant with that project.
Zuul currently supports one encryption scheme, PKCS#1 with OAEP, which
can not store secrets longer than the 3760 bits (derived from the key

View File

@ -43,10 +43,7 @@ def main():
parser.add_argument('url',
help="The base URL of the zuul server and tenant. "
"E.g., https://zuul.example.com/tenant-name")
# TODO(jeblair,mordred): When projects have canonical names, use that here.
# TODO(jeblair): Throw a fit if SSL is not used.
parser.add_argument('source',
help="The Zuul source of the project.")
parser.add_argument('project',
help="The name of the project.")
parser.add_argument('--infile',
@ -61,8 +58,7 @@ def main():
"to standard output.")
args = parser.parse_args()
req = Request("%s/keys/%s/%s.pub" % (
args.url, args.source, args.project))
req = Request("%s/%s.pub" % (args.url, args.project))
pubkey = urlopen(req)
if args.infile:

View File

@ -303,8 +303,7 @@ class RPCListener(object):
def handle_key_get(self, job):
args = json.loads(job.arguments)
source_name, project_name = args.get("source"), args.get("project")
source = self.sched.connections.getSource(source_name)
project = source.getProject(project_name)
tenant = self.sched.abide.tenants.get(args.get("tenant"))
(trusted, project) = tenant.getProject(args.get("project"))
job.sendWorkComplete(
encryption.serialize_rsa_public_key(project.public_key))

View File

@ -193,9 +193,9 @@ class GearmanHandler(object):
return web.json_response(json.loads(job.data[0]))
def key_get(self, request):
source = request.match_info["source"]
tenant = request.match_info["tenant"]
project = request.match_info["project"]
job = self.rpc.submitJob('zuul:key_get', {'source': source,
job = self.rpc.submitJob('zuul:key_get', {'tenant': tenant,
'project': project})
return web.Response(body=job.data[0])
@ -375,7 +375,7 @@ class ZuulWeb(object):
('GET', '/{tenant}/status.json', self._handleStatusRequest),
('GET', '/{tenant}/jobs.json', self._handleJobsRequest),
('GET', '/{tenant}/console-stream', self._handleWebsocket),
('GET', '/{source}/{project}.pub', self._handleKeyRequest),
('GET', '/{tenant}/{project}.pub', self._handleKeyRequest),
('GET', '/{tenant}/status.html', self._handleStaticRequest),
('GET', '/{tenant}/jobs.html', self._handleStaticRequest),
('GET', '/{tenant}/stream.html', self._handleStaticRequest),