1
0
Fork 0
mirror of https://github.com/portainer/portainer.git synced 2025-08-02 20:35:25 +02:00

chore(code): clean up the code EE-7251 (#11948)
Some checks are pending
ci / build_images (map[arch:ppc64le platform:linux version:]) (push) Waiting to run
ci / build_images (map[arch:s390x platform:linux version:]) (push) Waiting to run
ci / build_images (map[arch:amd64 platform:linux version:]) (push) Waiting to run
ci / build_images (map[arch:amd64 platform:windows version:1809]) (push) Waiting to run
ci / build_images (map[arch:amd64 platform:windows version:ltsc2022]) (push) Waiting to run
ci / build_images (map[arch:arm platform:linux version:]) (push) Waiting to run
ci / build_images (map[arch:arm64 platform:linux version:]) (push) Waiting to run
ci / build_manifests (push) Blocked by required conditions
/ triage (push) Waiting to run
Lint / Run linters (push) Waiting to run
Test / test-server (map[arch:amd64 platform:windows version:ltsc2022]) (push) Waiting to run
Test / test-server (map[arch:arm64 platform:linux]) (push) Waiting to run
Test / test-client (push) Waiting to run
Test / test-server (map[arch:amd64 platform:linux]) (push) Waiting to run
Test / test-server (map[arch:amd64 platform:windows version:1809]) (push) Waiting to run

This commit is contained in:
andres-portainer 2024-06-18 15:59:12 -03:00 committed by GitHub
parent be9d3285e1
commit bfa27d9103
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
49 changed files with 338 additions and 368 deletions

View file

@ -86,7 +86,7 @@ func (proxy *ProxyServer) start() error {
err := proxy.server.Serve(listener)
log.Debug().Str("host", proxyHost).Msg("exiting proxy server")
if err != nil && err != http.ErrServerClosed {
if err != nil && !errors.Is(err, http.ErrServerClosed) {
log.Debug().Str("host", proxyHost).Err(err).Msg("proxy server exited with an error")
}
}()

View file

@ -22,7 +22,7 @@ func NewTransport(signatureService portainer.DigitalSignatureService, httpTransp
return transport
}
// RoundTrip is the implementation of the the http.RoundTripper interface
// RoundTrip is the implementation of the http.RoundTripper interface
func (transport *Transport) RoundTrip(request *http.Request) (*http.Response, error) {
signature, err := transport.signatureService.CreateSignature(portainer.PortainerAgentSignatureMessage)
if err != nil {

View file

@ -26,17 +26,16 @@ func (transport *Transport) proxyContainerGroupRequest(request *http.Request) (*
}
func (transport *Transport) proxyContainerGroupPutRequest(request *http.Request) (*http.Response, error) {
tokenData, err := security.RetrieveTokenData(request)
if err != nil {
return nil, httperror.Forbidden("Permission denied to access environment", err)
}
//add a lock before processing existence check
// Add a lock before processing existence check
transport.mutex.Lock()
defer transport.mutex.Unlock()
//generate a temp http GET request based on the current PUT request
// Generate a temp http GET request based on the current PUT request
validationRequest := &http.Request{
Method: http.MethodGet,
URL: request.URL,
@ -45,9 +44,9 @@ func (transport *Transport) proxyContainerGroupPutRequest(request *http.Request)
},
}
//fire the request to Azure API to validate if there is an existing container instance with the same name
//positive - reject the request
//negative - continue the process
// Fire the request to Azure API to validate if there is an existing container instance with the same name
// positive - reject the request
// negative - continue the process
validationResponse, err := http.DefaultTransport.RoundTrip(validationRequest)
if err != nil {
return validationResponse, err
@ -63,6 +62,7 @@ func (transport *Transport) proxyContainerGroupPutRequest(request *http.Request)
"message": "A container instance with the same name already exists inside the selected resource group",
}
err = utils.RewriteResponse(resp, errObj, http.StatusConflict)
return resp, err
}

View file

@ -46,7 +46,7 @@ func NewTransport(credentials *portainer.AzureCredentials, dataStore dataservice
}
}
// RoundTrip is the implementation of the the http.RoundTripper interface
// RoundTrip is the implementation of the http.RoundTripper interface
func (transport *Transport) RoundTrip(request *http.Request) (*http.Response, error) {
return transport.proxyAzureRequest(request)
}

View file

@ -79,7 +79,7 @@ func NewTransport(parameters *TransportParameters, httpTransport *http.Transport
return transport, nil
}
// RoundTrip is the implementation of the the http.RoundTripper interface
// RoundTrip is the implementation of the http.RoundTripper interface
func (transport *Transport) RoundTrip(request *http.Request) (*http.Response, error) {
return transport.ProxyDockerRequest(request)
}
@ -489,63 +489,65 @@ func (transport *Transport) decorateRegistryAuthenticationHeader(request *http.R
}
func (transport *Transport) restrictedResourceOperation(request *http.Request, resourceID string, dockerResourceID string, resourceType portainer.ResourceControlType, volumeBrowseRestrictionCheck bool) (*http.Response, error) {
var err error
tokenData, err := security.RetrieveTokenData(request)
if err != nil {
return nil, err
}
if tokenData.Role != portainer.AdministratorRole {
if volumeBrowseRestrictionCheck {
securitySettings, err := transport.fetchEndpointSecuritySettings()
if err != nil {
return nil, err
}
if tokenData.Role == portainer.AdministratorRole {
return transport.executeDockerRequest(request)
}
if !securitySettings.AllowVolumeBrowserForRegularUsers {
return utils.WriteAccessDeniedResponse()
}
}
teamMemberships, err := transport.dataStore.TeamMembership().TeamMembershipsByUserID(tokenData.ID)
if volumeBrowseRestrictionCheck {
securitySettings, err := transport.fetchEndpointSecuritySettings()
if err != nil {
return nil, err
}
userTeamIDs := make([]portainer.TeamID, 0)
for _, membership := range teamMemberships {
userTeamIDs = append(userTeamIDs, membership.TeamID)
}
resourceControls, err := transport.dataStore.ResourceControl().ReadAll()
if err != nil {
return nil, err
}
resourceControl := authorization.GetResourceControlByResourceIDAndType(resourceID, resourceType, resourceControls)
if resourceControl == nil {
agentTargetHeader := request.Header.Get(portainer.PortainerAgentTargetHeader)
if dockerResourceID == "" {
dockerResourceID = resourceID
}
// This resource was created outside of portainer,
// is part of a Docker service or part of a Docker Swarm/Compose stack.
inheritedResourceControl, err := transport.getInheritedResourceControlFromServiceOrStack(dockerResourceID, agentTargetHeader, resourceType, resourceControls)
if err != nil {
return nil, err
}
if inheritedResourceControl == nil || !authorization.UserCanAccessResource(tokenData.ID, userTeamIDs, inheritedResourceControl) {
return utils.WriteAccessDeniedResponse()
}
}
if resourceControl != nil && !authorization.UserCanAccessResource(tokenData.ID, userTeamIDs, resourceControl) {
if !securitySettings.AllowVolumeBrowserForRegularUsers {
return utils.WriteAccessDeniedResponse()
}
}
teamMemberships, err := transport.dataStore.TeamMembership().TeamMembershipsByUserID(tokenData.ID)
if err != nil {
return nil, err
}
userTeamIDs := make([]portainer.TeamID, 0)
for _, membership := range teamMemberships {
userTeamIDs = append(userTeamIDs, membership.TeamID)
}
resourceControls, err := transport.dataStore.ResourceControl().ReadAll()
if err != nil {
return nil, err
}
resourceControl := authorization.GetResourceControlByResourceIDAndType(resourceID, resourceType, resourceControls)
if resourceControl == nil {
agentTargetHeader := request.Header.Get(portainer.PortainerAgentTargetHeader)
if dockerResourceID == "" {
dockerResourceID = resourceID
}
// This resource was created outside of portainer,
// is part of a Docker service or part of a Docker Swarm/Compose stack.
inheritedResourceControl, err := transport.getInheritedResourceControlFromServiceOrStack(dockerResourceID, agentTargetHeader, resourceType, resourceControls)
if err != nil {
return nil, err
}
if inheritedResourceControl == nil || !authorization.UserCanAccessResource(tokenData.ID, userTeamIDs, inheritedResourceControl) {
return utils.WriteAccessDeniedResponse()
}
}
if resourceControl != nil && !authorization.UserCanAccessResource(tokenData.ID, userTeamIDs, resourceControl) {
return utils.WriteAccessDeniedResponse()
}
return transport.executeDockerRequest(request)
}
@ -587,8 +589,7 @@ func (transport *Transport) rewriteOperation(request *http.Request, operation re
}
func (transport *Transport) interceptAndRewriteRequest(request *http.Request, operation operationRequest) (*http.Response, error) {
err := operation(request)
if err != nil {
if err := operation(request); err != nil {
return nil, err
}
@ -653,21 +654,22 @@ func (transport *Transport) executeGenericResourceDeletionOperation(request *htt
return response, err
}
if response.StatusCode == http.StatusNoContent || response.StatusCode == http.StatusOK {
resourceControl, err := transport.dataStore.ResourceControl().ResourceControlByResourceIDAndType(resourceIdentifierAttribute, resourceType)
if err != nil {
if dataservices.IsErrObjectNotFound(err) {
return response, nil
}
if response.StatusCode != http.StatusNoContent && response.StatusCode != http.StatusOK {
return response, nil
}
return response, err
resourceControl, err := transport.dataStore.ResourceControl().ResourceControlByResourceIDAndType(resourceIdentifierAttribute, resourceType)
if err != nil {
if dataservices.IsErrObjectNotFound(err) {
return response, nil
}
if resourceControl != nil {
err = transport.dataStore.ResourceControl().Delete(resourceControl.ID)
if err != nil {
return response, err
}
return response, err
}
if resourceControl != nil {
if err := transport.dataStore.ResourceControl().Delete(resourceControl.ID); err != nil {
return response, err
}
}
@ -683,6 +685,7 @@ func (transport *Transport) executeRequestAndRewriteResponse(request *http.Reque
if response.StatusCode == http.StatusOK {
err = operation(response, executor)
}
return response, err
}
@ -724,17 +727,19 @@ func (transport *Transport) createRegistryAccessContext(request *http.Request) (
}
accessContext.registries = registries
if user.Role != portainer.AdministratorRole {
accessContext.isAdmin = false
teamMemberships, err := transport.dataStore.TeamMembership().TeamMembershipsByUserID(tokenData.ID)
if err != nil {
return nil, err
}
accessContext.teamMemberships = teamMemberships
if user.Role == portainer.AdministratorRole {
return accessContext, nil
}
accessContext.isAdmin = false
teamMemberships, err := transport.dataStore.TeamMembership().TeamMembershipsByUserID(tokenData.ID)
if err != nil {
return nil, err
}
accessContext.teamMemberships = teamMemberships
return accessContext, nil
}
@ -756,22 +761,24 @@ func (transport *Transport) createOperationContext(request *http.Request) (*rest
resourceControls: resourceControls,
}
if tokenData.Role != portainer.AdministratorRole {
operationContext.isAdmin = false
teamMemberships, err := transport.dataStore.TeamMembership().TeamMembershipsByUserID(tokenData.ID)
if err != nil {
return nil, err
}
userTeamIDs := make([]portainer.TeamID, 0)
for _, membership := range teamMemberships {
userTeamIDs = append(userTeamIDs, membership.TeamID)
}
operationContext.userTeamIDs = userTeamIDs
if tokenData.Role == portainer.AdministratorRole {
return operationContext, nil
}
operationContext.isAdmin = false
teamMemberships, err := transport.dataStore.TeamMembership().TeamMembershipsByUserID(tokenData.ID)
if err != nil {
return nil, err
}
userTeamIDs := make([]portainer.TeamID, 0)
for _, membership := range teamMemberships {
userTeamIDs = append(userTeamIDs, membership.TeamID)
}
operationContext.userTeamIDs = userTeamIDs
return operationContext, nil
}

View file

@ -17,7 +17,7 @@ func NewTransport() *Transport {
}
}
// RoundTrip is the implementation of the the http.RoundTripper interface
// RoundTrip is the implementation of the http.RoundTripper interface
func (transport *Transport) RoundTrip(request *http.Request) (*http.Response, error) {
token := request.Header.Get("Private-Token")
if token == "" {

View file

@ -1,7 +1,6 @@
package factory
import (
"fmt"
"net/http"
"net/url"
@ -81,7 +80,7 @@ func (factory *ProxyFactory) newKubernetesEdgeHTTPProxy(endpoint *portainer.Endp
}
func (factory *ProxyFactory) newKubernetesAgentHTTPSProxy(endpoint *portainer.Endpoint) (http.Handler, error) {
endpointURL := fmt.Sprintf("https://%s", endpoint.URL)
endpointURL := "https://" + endpoint.URL
remoteURL, err := url.Parse(endpointURL)
if err != nil {
return nil, err