diff --git a/api/http/proxy/factory/docker/transport.go b/api/http/proxy/factory/docker/transport.go index d705d01ff..2c0a66824 100644 --- a/api/http/proxy/factory/docker/transport.go +++ b/api/http/proxy/factory/docker/transport.go @@ -272,6 +272,7 @@ func (transport *Transport) proxyServiceRequest(request *http.Request) (*http.Re if match, _ := path.Match("/services/*/*", requestPath); match { // Handle /services/{id}/{action} requests serviceID := path.Base(path.Dir(requestPath)) + transport.decorateRegistryAuthenticationHeader(request) return transport.restrictedResourceOperation(request, serviceID, serviceID, portainer.ServiceResourceControl, false) } else if match, _ := path.Match("/services/*", requestPath); match { // Handle /services/{id} requests @@ -396,9 +397,14 @@ func (transport *Transport) proxyImageRequest(request *http.Request) (*http.Resp } func (transport *Transport) replaceRegistryAuthenticationHeader(request *http.Request) (*http.Response, error) { + transport.decorateRegistryAuthenticationHeader(request) + return transport.decorateGenericResourceCreationOperation(request, serviceObjectIdentifier, portainer.ServiceResourceControl) +} + +func (transport *Transport) decorateRegistryAuthenticationHeader(request *http.Request) error { accessContext, err := transport.createRegistryAccessContext(request) if err != nil { - return nil, err + return err } originalHeader := request.Header.Get("X-Registry-Auth") @@ -407,23 +413,23 @@ func (transport *Transport) replaceRegistryAuthenticationHeader(request *http.Re decodedHeaderData, err := base64.StdEncoding.DecodeString(originalHeader) if err != nil { - return nil, err + return err } var originalHeaderData portainerRegistryAuthenticationHeader err = json.Unmarshal(decodedHeaderData, &originalHeaderData) if err != nil { - return nil, err + return err } authenticationHeader, err := createRegistryAuthenticationHeader(transport.dataStore, originalHeaderData.RegistryId, accessContext) if err != nil { - return nil, err + return err } headerData, err := json.Marshal(authenticationHeader) if err != nil { - return nil, err + return err } header := base64.StdEncoding.EncodeToString(headerData) @@ -431,7 +437,7 @@ func (transport *Transport) replaceRegistryAuthenticationHeader(request *http.Re request.Header.Set("X-Registry-Auth", header) } - return transport.decorateGenericResourceCreationOperation(request, serviceObjectIdentifier, portainer.ServiceResourceControl) + return nil } func (transport *Transport) restrictedResourceOperation(request *http.Request, resourceID string, dockerResourceID string, resourceType portainer.ResourceControlType, volumeBrowseRestrictionCheck bool) (*http.Response, error) { @@ -492,7 +498,6 @@ func (transport *Transport) restrictedResourceOperation(request *http.Request, r return utils.WriteAccessDeniedResponse() } } - return transport.executeDockerRequest(request) } diff --git a/app/docker/rest/service.js b/app/docker/rest/service.js index d852e98c4..f11c12214 100644 --- a/app/docker/rest/service.js +++ b/app/docker/rest/service.js @@ -28,6 +28,7 @@ angular.module('portainer.docker').factory('Service', [ method: 'POST', params: { id: '@id', action: 'update', version: '@version', rollback: '@rollback' }, headers: { + 'X-Registry-Auth': (config) => btoa(JSON.stringify({ registryId: config.data.registryId })), version: '1.29', }, }, diff --git a/app/docker/views/services/edit/serviceController.js b/app/docker/views/services/edit/serviceController.js index b3e5bcbab..8a3115190 100644 --- a/app/docker/views/services/edit/serviceController.js +++ b/app/docker/views/services/edit/serviceController.js @@ -420,6 +420,7 @@ angular.module('portainer.docker').controller('ServiceController', [ if ($scope.hasChanges(service, ['Image'])) { const image = ImageHelper.createImageConfigForContainer($scope.formValues.RegistryModel); config.TaskTemplate.ContainerSpec.Image = image.fromImage; + config.registryId = $scope.formValues.RegistryModel.Registry.Id; } else { config.TaskTemplate.ContainerSpec.Image = service.Image; }