diff --git a/endpoints/v2/manifest.py b/endpoints/v2/manifest.py index 8533d3be3..b927c82d4 100644 --- a/endpoints/v2/manifest.py +++ b/endpoints/v2/manifest.py @@ -4,7 +4,6 @@ import logging import re import jwt.utils -import yaml import json from flask import make_response, request, url_for @@ -64,9 +63,7 @@ class SignedManifest(object): def __init__(self, manifest_bytes): self._bytes = manifest_bytes - # TODO(jakedt): If the manifest_bytes doesn't parse as valid YAML, safe_load returns the - # same string again. We should throw some sort of exception. - self._parsed = yaml.safe_load(manifest_bytes) + self._parsed = json.loads(manifest_bytes) self._signatures = self._parsed[_SIGNATURES_KEY] self._namespace, self._repo_name = self._parsed[_REPO_NAME_KEY].split('/') self._tag = self._parsed[_REPO_TAG_KEY] @@ -110,9 +107,7 @@ class SignedManifest(object): image_digest = digest_tools.Digest.parse_digest(blob_sum_obj[_BLOB_SUM_KEY]) metadata_string = history_obj[_V1_COMPAT_KEY] - # TODO(jakedt): If the metadata_string doesn't parse as valid YAML, safe_load returns the - # same string again. We should throw some sort of exception. - v1_metadata = yaml.safe_load(metadata_string) + v1_metadata = json.loads(metadata_string) command_list = v1_metadata.get('container_config', {}).get('Cmd', None) command = json.dumps(command_list) if command_list else None @@ -123,12 +118,15 @@ class SignedManifest(object): @property def payload(self): - protected = self._signatures[0][_PROTECTED_KEY] - parsed_protected = yaml.safe_load(jwt.utils.base64url_decode(protected)) + protected = str(self._signatures[0][_PROTECTED_KEY]) + + parsed_protected = json.loads(jwt.utils.base64url_decode(protected)) logger.debug('parsed_protected: %s', parsed_protected) + signed_content_head = self._bytes[:parsed_protected[_FORMAT_LENGTH_KEY]] logger.debug('signed content head: %s', signed_content_head) - signed_content_tail = jwt.utils.base64url_decode(parsed_protected[_FORMAT_TAIL_KEY]) + + signed_content_tail = jwt.utils.base64url_decode(str(parsed_protected[_FORMAT_TAIL_KEY])) logger.debug('signed content tail: %s', signed_content_tail) return signed_content_head + signed_content_tail diff --git a/test/registry_tests.py b/test/registry_tests.py index bce6f8aeb..a94f65fa3 100644 --- a/test/registry_tests.py +++ b/test/registry_tests.py @@ -24,6 +24,7 @@ import endpoints.decorated import json import features import hashlib +import logging import tarfile import shutil @@ -48,6 +49,8 @@ except ValueError: # DB connection. testbp = Blueprint('testbp', __name__) +logger = logging.getLogger(__name__) + @testbp.route('/csrf', methods=['GET']) def generate_csrf(): @@ -101,6 +104,7 @@ class TestFeature(object): _PORT_NUMBER = 5001 _CLEAN_DATABASE_PATH = None +_JWK = RSAKey(key=RSA.generate(2048)) def get_new_database_uri(): @@ -334,6 +338,9 @@ class V2RegistryPushMixin(V2RegistryMixin): checksum = 'sha256:' + hashlib.sha256(full_contents).hexdigest() builder.add_layer(checksum, json.dumps({'id': image_id, 'data': contents})) + # Build the manifest. + manifest = builder.build(_JWK) + # Push the image's layers. for image_id, contents in images.iteritems(): chunks = None @@ -368,10 +375,6 @@ class V2RegistryPushMixin(V2RegistryMixin): self.conduct('PUT', location, params=dict(digest=checksum), expected_code=201, auth='jwt') # Write the manifest. - new_key = RSA.generate(2048) - jwk = RSAKey(key=new_key) - manifest = builder.build(jwk) - self.conduct('PUT', '/v2/%s/%s/manifests/%s' % (namespace, repository, tag_name), data=manifest.bytes, expected_code=202, headers={'Content-Type': 'application/json'}, auth='jwt')