diff --git a/api/http/handler/motd/motd.go b/api/http/handler/motd/motd.go index dd2112c16..4117de830 100644 --- a/api/http/handler/motd/motd.go +++ b/api/http/handler/motd/motd.go @@ -7,7 +7,9 @@ import ( portainer "github.com/portainer/portainer/api" "github.com/portainer/portainer/api/http/client" "github.com/portainer/portainer/pkg/libcrypto" + libclient "github.com/portainer/portainer/pkg/libhttp/client" "github.com/portainer/portainer/pkg/libhttp/response" + "github.com/rs/zerolog/log" "github.com/segmentio/encoding/json" ) @@ -37,6 +39,12 @@ type motdData struct { // @success 200 {object} motdResponse // @router /motd [get] func (handler *Handler) motd(w http.ResponseWriter, r *http.Request) { + if err := libclient.ExternalRequestDisabled(portainer.MessageOfTheDayURL); err != nil { + log.Debug().Err(err).Msg("External request disabled: MOTD") + response.JSON(w, &motdResponse{Message: ""}) + return + } + motd, err := client.Get(portainer.MessageOfTheDayURL, 0) if err != nil { response.JSON(w, &motdResponse{Message: ""}) diff --git a/api/http/handler/system/version.go b/api/http/handler/system/version.go index 9d80b88a9..52af5879c 100644 --- a/api/http/handler/system/version.go +++ b/api/http/handler/system/version.go @@ -7,6 +7,7 @@ import ( "github.com/portainer/portainer/api/http/client" "github.com/portainer/portainer/api/http/security" "github.com/portainer/portainer/pkg/build" + libclient "github.com/portainer/portainer/pkg/libhttp/client" httperror "github.com/portainer/portainer/pkg/libhttp/error" "github.com/portainer/portainer/pkg/libhttp/response" @@ -69,10 +70,14 @@ func (handler *Handler) version(w http.ResponseWriter, r *http.Request) *httperr } func GetLatestVersion() string { + if err := libclient.ExternalRequestDisabled(portainer.VersionCheckURL); err != nil { + log.Debug().Err(err).Msg("External request disabled: Version check") + return "" + } + motd, err := client.Get(portainer.VersionCheckURL, 5) if err != nil { log.Debug().Err(err).Msg("couldn't fetch latest Portainer release version") - return "" } diff --git a/api/http/handler/templates/utils_fetch_templates.go b/api/http/handler/templates/utils_fetch_templates.go index 6feb9edeb..73f9bad56 100644 --- a/api/http/handler/templates/utils_fetch_templates.go +++ b/api/http/handler/templates/utils_fetch_templates.go @@ -4,7 +4,9 @@ import ( "net/http" portainer "github.com/portainer/portainer/api" + libclient "github.com/portainer/portainer/pkg/libhttp/client" httperror "github.com/portainer/portainer/pkg/libhttp/error" + "github.com/rs/zerolog/log" "github.com/segmentio/encoding/json" ) @@ -24,13 +26,20 @@ func (handler *Handler) fetchTemplates() (*listResponse, *httperror.HandlerError templatesURL = portainer.DefaultTemplatesURL } + var body *listResponse + if err := libclient.ExternalRequestDisabled(templatesURL); err != nil { + if templatesURL == portainer.DefaultTemplatesURL { + log.Debug().Err(err).Msg("External request disabled: Default templates") + return body, nil + } + } + resp, err := http.Get(templatesURL) if err != nil { return nil, httperror.InternalServerError("Unable to retrieve templates via the network", err) } defer resp.Body.Close() - var body *listResponse err = json.NewDecoder(resp.Body).Decode(&body) if err != nil { return nil, httperror.InternalServerError("Unable to parse template file", err) diff --git a/api/portainer.go b/api/portainer.go index 935def1f1..60e5c7a1f 100644 --- a/api/portainer.go +++ b/api/portainer.go @@ -1692,6 +1692,11 @@ const ( KubectlShellImageEnvVar = "KUBECTL_SHELL_IMAGE" // PullLimitCheckDisabledEnvVar is the environment variable used to disable the pull limit check PullLimitCheckDisabledEnvVar = "PULL_LIMIT_CHECK_DISABLED" + // LicenseServerBaseURL represents the base URL of the API used to validate + // an extension license. + LicenseServerBaseURL = "https://api.portainer.io" + // URL to validate licenses along with system metadata. + LicenseCheckInURL = LicenseServerBaseURL + "/licenses/checkin" ) // List of supported features diff --git a/pkg/libhttp/client/client.go b/pkg/libhttp/client/client.go new file mode 100644 index 000000000..1e1f094a1 --- /dev/null +++ b/pkg/libhttp/client/client.go @@ -0,0 +1,22 @@ +package client + +import ( + "errors" + + "github.com/portainer/portainer/pkg/featureflags" +) + +var ( + ErrExternalRequestsBlocked = errors.New("external requests are blocked by feature flag") +) + +// DisableExternalRequest is the feature flag name for blocking outbound requests +const DisableExternalRequests = "disable-external-requests" + +func ExternalRequestDisabled(url string) error { + if featureflags.IsEnabled(DisableExternalRequests) { + return ErrExternalRequestsBlocked + } + + return nil +}