From 1f1565fdaa188e6d7dc7378c8f8fa2e5403e36b5 Mon Sep 17 00:00:00 2001 From: yackob03 Date: Mon, 11 Nov 2013 11:58:30 -0500 Subject: [PATCH 1/6] Fix the bug where trying to unsubscribe a customer with no subscription throws an error. --- endpoints/api.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/endpoints/api.py b/endpoints/api.py index bac8d10c9..4d31518ef 100644 --- a/endpoints/api.py +++ b/endpoints/api.py @@ -1217,8 +1217,10 @@ def subscribe(user, plan, token, accepted_plans): cus = stripe.Customer.retrieve(user.stripe_id) if plan_found['price'] == 0: - cus.cancel_subscription() - cus.save() + if cus.subscription is not None: + # We only have to cancel the subscription if they actually have one + cus.cancel_subscription() + cus.save() response_json = { 'plan': plan, From 18809842b891d471c4d31059c7841806703e5a50 Mon Sep 17 00:00:00 2001 From: yackob03 Date: Mon, 11 Nov 2013 16:28:05 -0500 Subject: [PATCH 2/6] Fix a typo in the index code and follow some pylint recommendations. --- endpoints/index.py | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/endpoints/index.py b/endpoints/index.py index 00020d317..40c5f5368 100644 --- a/endpoints/index.py +++ b/endpoints/index.py @@ -1,6 +1,4 @@ import json -import urllib -import json import logging import urlparse @@ -11,7 +9,7 @@ from data import model from app import app, mixpanel from auth.auth import (process_auth, get_authenticated_user, get_validated_token) -from util.names import parse_namespace_repository, parse_repository_name +from util.names import parse_repository_name from util.email import send_confirmation_email from auth.permissions import (ModifyRepositoryPermission, UserPermission, ReadRepositoryPermission, @@ -54,7 +52,7 @@ def create_user(): if username == '$token': try: - token = model.load_token_data(password) + model.load_token_data(password) return make_response('Verified', 201) except model.InvalidTokenException: abort(401) @@ -130,7 +128,7 @@ def create_repository(namespace, repository): abort(403) else: - permission = CreateRepoPermission('namespace') + permission = CreateRepositoryPermission('namespace') if not permission.can(): logger.info('Attempt to create a new repo with insufficient perms.') abort(403) @@ -151,7 +149,7 @@ def create_repository(namespace, repository): existing.delete_instance(recursive=True) for image_description in added_images.values(): - image = model.create_image(image_description['id'], repo) + model.create_image(image_description['id'], repo) response = make_response('Created', 201) From e6926b62be3bdbea3a036cd287558ec0b1ff630c Mon Sep 17 00:00:00 2001 From: yackob03 Date: Mon, 11 Nov 2013 16:31:29 -0500 Subject: [PATCH 3/6] Actually use the namesapce rather than the literal word namespace, doh --- endpoints/index.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/endpoints/index.py b/endpoints/index.py index 40c5f5368..671f8766f 100644 --- a/endpoints/index.py +++ b/endpoints/index.py @@ -128,7 +128,7 @@ def create_repository(namespace, repository): abort(403) else: - permission = CreateRepositoryPermission('namespace') + permission = CreateRepositoryPermission(namespace) if not permission.can(): logger.info('Attempt to create a new repo with insufficient perms.') abort(403) From 2e9f7cd19d4270bf32ffc1c2c4abbfe4b63c2c5c Mon Sep 17 00:00:00 2001 From: yackob03 Date: Mon, 11 Nov 2013 16:41:33 -0500 Subject: [PATCH 4/6] Restore the temp_store_handler. --- endpoints/registry.py | 2 +- storage/basestorage.py | 15 +++++++++++++++ 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/endpoints/registry.py b/endpoints/registry.py index 5d71a1f81..d4fadce53 100644 --- a/endpoints/registry.py +++ b/endpoints/registry.py @@ -114,7 +114,7 @@ def put_image_layer(namespace, repository, image_id): # compute checksums csums = [] sr = SocketReader(input_stream) - tmp, store_hndlr = storage.temp_store_handler() + tmp, store_hndlr = store.temp_store_handler() sr.add_handler(store_hndlr) h, sum_hndlr = checksums.simple_checksum_handler(json_data) sr.add_handler(sum_hndlr) diff --git a/storage/basestorage.py b/storage/basestorage.py index 283fde227..f38b39790 100644 --- a/storage/basestorage.py +++ b/storage/basestorage.py @@ -1,3 +1,6 @@ +import tempfile + + class Storage(object): """Storage is organized as follow: @@ -13,6 +16,18 @@ class Storage(object): # Set the IO buffer to 64kB buffer_size = 64 * 1024 + @staticmethod + def temp_store_handler(): + tmpf = tempfile.TemporaryFile() + + def fn(buf): + try: + tmpf.write(buf) + except IOError: + pass + + return tmpf, fn + #FIXME(samalba): Move all path resolver in each module (out of the base) def images_list_path(self, namespace, repository): return '{0}/{1}/{2}/_images_list'.format(self.repositories, From 31875395094e622d19b5300e47dc7ed19bd0ffa8 Mon Sep 17 00:00:00 2001 From: yackob03 Date: Mon, 11 Nov 2013 17:01:21 -0500 Subject: [PATCH 5/6] Catch an error when trying to generate an access token. --- endpoints/index.py | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/endpoints/index.py b/endpoints/index.py index 671f8766f..d6f3ea448 100644 --- a/endpoints/index.py +++ b/endpoints/index.py @@ -33,10 +33,14 @@ def generate_headers(role='read'): if has_token_request: repo = model.get_repository(namespace, repository) - token = model.create_access_token(repo, role) - token_str = 'signature=%s' % token.code - response.headers['WWW-Authenticate'] = token_str - response.headers['X-Docker-Token'] = token_str + if repo: + token = model.create_access_token(repo, role) + token_str = 'signature=%s' % token.code + response.headers['WWW-Authenticate'] = token_str + response.headers['X-Docker-Token'] = token_str + else: + logger.info('Token request in non-existing repo: %s/%s' % + (namespace, repository)) return response return wrapper From 64cbc735fb2362c511797fcf9eda88c82c62245d Mon Sep 17 00:00:00 2001 From: yackob03 Date: Mon, 11 Nov 2013 17:11:21 -0500 Subject: [PATCH 6/6] 403s on pulls have to be 404s for now. --- endpoints/index.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/endpoints/index.py b/endpoints/index.py index d6f3ea448..4647d43ff 100644 --- a/endpoints/index.py +++ b/endpoints/index.py @@ -215,7 +215,8 @@ def get_repository_images(namespace, repository): return resp - abort(403) + # TODO Submit a pull to docker CLI to get it to accept 403s + abort(404) @app.route('/v1/repositories//images', methods=['DELETE'])