diff --git a/endpoints/api.py b/endpoints/api.py index 5cedca1f5..88305f213 100644 --- a/endpoints/api.py +++ b/endpoints/api.py @@ -1218,8 +1218,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, diff --git a/endpoints/index.py b/endpoints/index.py index 00020d317..4647d43ff 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, @@ -35,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 @@ -54,7 +56,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 +132,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 +153,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) @@ -213,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']) 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,