예제 #1
0
파일: push.py 프로젝트: serlophug/sregistry
def collection_auth_check(request):
    ''' check permissions and 
        return a collection id (cid) if a collection exists and the user
        has permission to upload. If not, a permission denied is returned.
    '''
    auth = request.META.get('HTTP_AUTHORIZATION', None)

    # Load the body, which is json with variables
    body_unicode = request.body.decode('utf-8')
    body = json.loads(body_unicode)

    # Get variables
    tag = body.get('tag', 'latest')
    name = body.get('name')
    collection_name = format_collection_name(body.get('collection'))

    print(tag, name, collection_name, auth, body)

    # Authentication always required for push
    if auth is None:
        raise PermissionDenied(detail="Authentication Required")

    owner = get_request_user(auth)
    timestamp = generate_timestamp()
    payload = "push|%s|%s|%s|%s|" % (collection_name, timestamp, name, tag)

    # Validate Payload
    print(payload)
    if not validate_request(auth, payload, "push", timestamp):
        raise PermissionDenied(detail="Unauthorized")

    try:
        collection = Collection.objects.get(name=collection_name)

    except Collection.DoesNotExist:
        collection = None

    # Validate User Permissions, either for creating collection or adding
    # Here we have permission if:
    # 1- user collections are enabled with USER_COLLECTIONS
    # 2- the user is a superuser or staff
    # 3- the user is owner of a collection
    if not has_permission(auth, collection, pull_permission=False):
        raise PermissionDenied(detail="Unauthorized")

    # If the user cannot create a new collection
    if not owner.has_create_permission():
        raise PermissionDenied(detail="Unauthorized")

    # If we get here user has create permission, does collection exist?
    if collection is None:
        collection = Collection.objects.create(name=collection_name,
                                               secret=str(uuid.uuid4()))
        collection.save()
        collection.owners.add(owner)
        collection.save()

    # Return json response with collection id
    return JsonResponse({'cid': collection.id})
예제 #2
0
def _container_get(request, container, name=None, tag=None):
    '''container get is the shared function for getting a container based
       on a name or an id. It validates the request and returns a response.
       
       Parameters
       ==========
       request: the request from the view with the user
       container: the container object to check
    '''
    if container is None:
        raise NotFound

    if name is None:
        name = container.name

    if tag is None:
        tag = container.tag

    # The user isn't allowed to get more than the limit
    if container.get_count >= container.get_limit:
        return Response(429)

    if container.collection.get_count >= container.collection.get_limit:
        return Response(429)

    # All public images are pull-able

    is_private = container.collection.private

    if not is_private:
        serializer = SingleContainerSerializer(container)
        return Response(serializer.data)

    # Determine if user has permission to get if private
    auth = request.META.get('HTTP_AUTHORIZATION')

    if auth is None:
        print("Auth is None")
        raise PermissionDenied(detail="Authentication Required")

    # Validate User Permissions - must have view to pull private image

    if not has_permission(auth, container.collection):
        print("Does not have permission")
        raise PermissionDenied(detail="Unauthorized")

    timestamp = generate_timestamp()
    payload = "pull|%s|%s|%s|%s|" % (container.collection.name, timestamp,
                                     name, tag)

    if validate_request(auth, payload, "pull", timestamp):
        serializer = SingleContainerSerializer(container)
        return Response(serializer.data)

    return Response(400)
예제 #3
0
    def perform_create(self, serializer):
 
        tag=self.request.data.get('tag','latest')                                   
        name=self.request.data.get('name')
        auth=self.request.META.get('HTTP_AUTHORIZATION', None)
        collection_name=self.request.data.get('collection')

        if auth is None:
            raise PermissionDenied(detail="Authentication Required")

        timestamp = generate_timestamp()
        payload = "push|%s|%s|%s|%s|" %(collection_name,
                                        timestamp,
                                        name,
                                        tag)

        if not validate_request(auth,payload,"push",timestamp):
            raise PermissionDenied(detail="Unauthorized")

        create_new=False

        try:
            collection = Collection.objects.get(name=collection_name) 
        except Collection.DoesNotExist:
            collection = None
            create_new=True
        
        if collection is not None:
            try:
                container = Container.objects.get(collection=collection,
                                                  name=name,
                                                  tag=tag)
                if container.frozen is False:
                    create_new = True
            except Container.DoesNotExist:
                create_new=True

        if create_new is True:
            serializer.save(datafile=self.request.data.get('datafile'),
                            collection=self.request.data.get('collection'),
                            tag=self.request.data.get('tag','latest'),
                            name=self.request.data.get('name'),
                            metadata=self.request.data.get('metadata'))
        else:
            raise PermissionDenied(detail="%s is frozen, push not allowed." %container.get_short_uri())
예제 #4
0
def delete_container(request, container):
    '''delete a container only given authentication to do so'''

    auth = request.META.get('HTTP_AUTHORIZATION', None)

    if auth is None:
        bot.debug("authentication is invalid.")
        return False

    timestamp = generate_timestamp()
    payload = "delete|%s|%s|%s|%s|" % (container.collection.name, timestamp,
                                       container.name, container.tag)
    bot.debug("Request payload %s" % payload)

    if not validate_request(auth, payload, "delete", timestamp):
        bot.debug("request is invalid.")
        return False

    return True
예제 #5
0
    def get(self, request, cid):
        container = self.get_object(cid)
        if container is None:
            return Response({})

        serializer = SingleContainerSerializer(container)
        is_private = container.collection.private

        if not is_private:
            return Response(serializer.data)

        # Determine if user has permission to get if private
        auth = request.META.get('HTTP_AUTHORIZATION')

        if auth is None:
            raise PermissionDenied(detail="Authentication Required")

        timestamp = generate_timestamp()
        payload = "pull|%s|%s|%s|%s|" % (collection, timestamp, name, tag)

        if validate_request(auth, payload, "pull", timestamp):
            return Response(serializer.data)

        return Response(400)
예제 #6
0
    def perform_create(self, serializer):

        tag = self.request.data.get('tag', 'latest')
        name = self.request.data.get('name')
        auth = self.request.META.get('HTTP_AUTHORIZATION', None)
        collection_name = self.request.data.get('collection')

        # Authentication always required for push

        if auth is None:
            raise PermissionDenied(detail="Authentication Required")

        owner = get_request_user(auth)
        timestamp = generate_timestamp()
        payload = "push|%s|%s|%s|%s|" % (collection_name, timestamp, name, tag)

        # Validate Payload

        if not validate_request(auth, payload, "push", timestamp):
            raise PermissionDenied(detail="Unauthorized")

        create_new = False

        try:
            collection = Collection.objects.get(name=collection_name)

            # Only owners can push
            if not owner in collection.owners.all():
                raise PermissionDenied(detail="Unauthorized")

        except Collection.DoesNotExist:
            collection = None
            create_new = True

        # Validate User Permissions

        if not has_permission(auth, collection, pull_permission=False):
            raise PermissionDenied(detail="Unauthorized")

        if collection is not None:

            try:
                container = Container.objects.get(collection=collection,
                                                  name=name,
                                                  tag=tag)
                if container.frozen is False:
                    create_new = True

            except Container.DoesNotExist:
                create_new = True

        # New collection, pusher is owner

        if create_new is True:

            serializer.save(datafile=self.request.data.get('datafile'),
                            collection=self.request.data.get('collection'),
                            tag=self.request.data.get('tag', 'latest'),
                            name=self.request.data.get('name'),
                            owner_id=owner.id,
                            metadata=self.request.data.get('metadata'))
        else:
            raise PermissionDenied(detail="%s is frozen, push not allowed." %
                                   container.get_short_uri())
예제 #7
0
def upload_complete(request):
    '''view called on /api/upload/complete after nginx upload module finishes.
    '''
    from shub.apps.api.actions.create import upload_container

    if request.method == "POST":

        path = request.POST.get('file1.path')
        size = request.POST.get('file1.size')
        cid = request.POST.get('collection')
        filename = request.POST.get('file1.name')
        name = request.POST.get('name')
        version = request.POST.get('file1.md5')
        auth = request.META.get('HTTP_AUTHORIZATION', None)
        tag = request.POST.get('tag')
        csrftoken = request.META.get('CSRF_COOKIE')

        if auth is None and csrftoken is None:
            if os.path.exists(filename):
                os.remove(path)
            raise PermissionDenied(detail="Authentication Required")

        if DISABLE_BUILDING:
            if os.path.exists(filename):
                os.remove(path)
            raise PermissionDenied(detail="Uploading is disabled.")

        # at this point, the collection MUST exist
        try:
            collection = Collection.objects.get(id=cid)
        except Collection.DoesNotExist:
            raise PermissionDenied(detail="Authentication Required")

        # If not defined, coming from terminal
        web_interface = True
        if csrftoken is None:
            web_interface = False
            owner = get_request_user(auth)
            timestamp = generate_timestamp()
            payload = "upload|%s|%s|%s|%s|" % (collection.name, timestamp,
                                               name, tag)

            # Validate Payload
            if not validate_request(auth, payload, "upload", timestamp):
                raise PermissionDenied(detail="Unauthorized")

            if not has_permission(auth, collection, pull_permission=False):
                raise PermissionDenied(detail="Unauthorized")

        else:
            owner = request.user

        # If tag is provided, add to name
        if tag is not None:
            name = "%s:%s" % (name, tag)

        # Expected params are upload_id, name, md5, and cid
        message = upload_container(cid=collection.id,
                                   user=owner,
                                   version=version,
                                   upload_id=path,
                                   name=name,
                                   size=size)

        # If the function doesn't return a message (None), indicates success
        if message is None:
            message = "Upload Complete"

        if web_interface is True:
            messages.info(request, message)
            return redirect(collection.get_absolute_url())
        return JsonResponse({"message": message})

    return redirect('collections')
예제 #8
0
    def perform_create(self, serializer):

        print(self.request.data) 
        tag = self.request.data.get('tag', 'latest')                                   
        name = self.request.data.get('name')
        auth = self.request.META.get('HTTP_AUTHORIZATION', None)
        collection_name = self.request.data.get('collection')

        # Building is disabled
        if DISABLE_BUILDING:
            raise PermissionDenied(detail="Building is disabled.")
        
        # Authentication always required for push

        if auth is None:
            print("auth is None")
            raise PermissionDenied(detail="Authentication Required")

        owner = get_request_user(auth)
        timestamp = generate_timestamp()
        payload = "build|%s|%s|%s|%s|" %(collection_name,
                                         timestamp,
                                         name,
                                         tag)


        # Validate Payload
        if not validate_request(auth, payload, "build", timestamp):
            print("auth is not valid for build")
            raise PermissionDenied(detail="Unauthorized")

        # Does the user have create permission?
        if not owner.has_create_permission():
            print("owned doesnt have create permission")
            raise PermissionDenied(detail="Unauthorized Create Permission")

        # Are we over the build limit?
        if is_over_limit():
            message = ("Registry concurrent build limit is " +
                        "%s" % SREGISTRY_GOOGLE_BUILD_LIMIT + ". Please try again later.")
            print(message)
            raise PermissionDenied(detail=message)

        create_new = False

        # Determine the collection to build the recipe to
        try:
            collection = Collection.objects.get(name=collection_name)

            # Only owners can push to existing collections
            if not owner in collection.owners.all():
                print("user not in owners")
                raise PermissionDenied(detail="Unauthorized")

        except Collection.DoesNotExist:
            print("collection does not exist")
            raise PermissionDenied(detail="Not Found")

        # Validate User Permissions
        if not has_permission(auth, collection, pull_permission=False):
            print("user does not have permissions.")
            raise PermissionDenied(detail="Unauthorized")
        
        # The collection must exist when we get here
        try:
            container = Container.objects.get(collection=collection,
                                              name=name,
                                              tag=tag)
            if not container.frozen:
                create_new = True

        except Container.DoesNotExist:
            create_new = True
        
        # Create the recipe to trigger a build
        print(self.request.data.get('datafile'))
 
        if create_new is True:
            serializer.save(datafile=self.request.data.get('datafile'),
                            collection=self.request.data.get('collection'),
                            tag=self.request.data.get('tag', 'latest'),
                            name=self.request.data.get('name'),
                            owner_id=owner.id)
        else:
            raise PermissionDenied(detail="%s is frozen, push not allowed." % container.get_short_uri())