MM-10417 Add local image proxy and enable by default (#9967)
* MM-10417 Add local image proxy and enable by default * Remove unused function * Add dependencies for willnorris/imageproxy * Fixed compilation errors * Lock to the master version of willnorris/imageproxy * Fix atmos/camo proxy when no SiteURL is specified * Re-add default values for deprecated settings * Fix unit tests added by merge * Pass imageproxy to App struct * Remove unneeded locking when creating the image proxy * Remove empty test file
Этот коммит содержится в:
коммит произвёл
GitHub
родитель
e961b4cd0d
Коммит
ba5566d1a0
@@ -174,6 +174,9 @@ const (
|
||||
|
||||
CLIENT_SIDE_CERT_CHECK_PRIMARY_AUTH = "primary"
|
||||
CLIENT_SIDE_CERT_CHECK_SECONDARY_AUTH = "secondary"
|
||||
|
||||
IMAGE_PROXY_TYPE_LOCAL = "local"
|
||||
IMAGE_PROXY_TYPE_ATMOS_CAMO = "atmos/camo"
|
||||
)
|
||||
|
||||
var ServerTLSSupportedCiphers = map[string]uint16{
|
||||
@@ -272,9 +275,9 @@ type ServiceSettings struct {
|
||||
ExperimentalEnableDefaultChannelLeaveJoinMessages *bool
|
||||
ExperimentalGroupUnreadChannels *string
|
||||
ExperimentalChannelOrganization *bool
|
||||
ImageProxyType *string
|
||||
ImageProxyURL *string
|
||||
ImageProxyOptions *string
|
||||
DEPRECATED_DO_NOT_USE_ImageProxyType *string `json:"ImageProxyType"` // This field is deprecated and must not be used.
|
||||
DEPRECATED_DO_NOT_USE_ImageProxyURL *string `json:"ImageProxyURL"` // This field is deprecated and must not be used.
|
||||
DEPRECATED_DO_NOT_USE_ImageProxyOptions *string `json:"ImageProxyOptions"` // This field is deprecated and must not be used.
|
||||
EnableAPITeamDeletion *bool
|
||||
ExperimentalEnableHardenedMode *bool
|
||||
EnableEmailInvitations *bool
|
||||
@@ -550,16 +553,16 @@ func (s *ServiceSettings) SetDefaults() {
|
||||
s.ExperimentalChannelOrganization = NewBool(experimentalUnreadEnabled)
|
||||
}
|
||||
|
||||
if s.ImageProxyType == nil {
|
||||
s.ImageProxyType = NewString("")
|
||||
if s.DEPRECATED_DO_NOT_USE_ImageProxyType == nil {
|
||||
s.DEPRECATED_DO_NOT_USE_ImageProxyType = NewString("")
|
||||
}
|
||||
|
||||
if s.ImageProxyURL == nil {
|
||||
s.ImageProxyURL = NewString("")
|
||||
if s.DEPRECATED_DO_NOT_USE_ImageProxyURL == nil {
|
||||
s.DEPRECATED_DO_NOT_USE_ImageProxyURL = NewString("")
|
||||
}
|
||||
|
||||
if s.ImageProxyOptions == nil {
|
||||
s.ImageProxyOptions = NewString("")
|
||||
if s.DEPRECATED_DO_NOT_USE_ImageProxyOptions == nil {
|
||||
s.DEPRECATED_DO_NOT_USE_ImageProxyOptions = NewString("")
|
||||
}
|
||||
|
||||
if s.EnableAPITeamDeletion == nil {
|
||||
@@ -1931,6 +1934,43 @@ func (s *TimezoneSettings) SetDefaults() {
|
||||
}
|
||||
}
|
||||
|
||||
type ImageProxySettings struct {
|
||||
Enable *bool
|
||||
ImageProxyType *string
|
||||
RemoteImageProxyURL *string
|
||||
RemoteImageProxyOptions *string
|
||||
}
|
||||
|
||||
func (ips *ImageProxySettings) SetDefaults(ss ServiceSettings) {
|
||||
if ips.Enable == nil {
|
||||
ips.Enable = NewBool(true)
|
||||
}
|
||||
|
||||
if ips.ImageProxyType == nil {
|
||||
if ss.DEPRECATED_DO_NOT_USE_ImageProxyType == nil || *ss.DEPRECATED_DO_NOT_USE_ImageProxyType == "" {
|
||||
ips.ImageProxyType = NewString(IMAGE_PROXY_TYPE_LOCAL)
|
||||
} else {
|
||||
ips.ImageProxyType = ss.DEPRECATED_DO_NOT_USE_ImageProxyType
|
||||
}
|
||||
}
|
||||
|
||||
if ips.RemoteImageProxyURL == nil {
|
||||
if ss.DEPRECATED_DO_NOT_USE_ImageProxyURL == nil {
|
||||
ips.RemoteImageProxyURL = NewString("")
|
||||
} else {
|
||||
ips.RemoteImageProxyURL = ss.DEPRECATED_DO_NOT_USE_ImageProxyURL
|
||||
}
|
||||
}
|
||||
|
||||
if ips.RemoteImageProxyOptions == nil {
|
||||
if ss.DEPRECATED_DO_NOT_USE_ImageProxyOptions == nil {
|
||||
ips.RemoteImageProxyOptions = NewString("")
|
||||
} else {
|
||||
ips.RemoteImageProxyOptions = ss.DEPRECATED_DO_NOT_USE_ImageProxyOptions
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
type ConfigFunc func() *Config
|
||||
|
||||
type Config struct {
|
||||
@@ -1966,6 +2006,7 @@ type Config struct {
|
||||
PluginSettings PluginSettings
|
||||
DisplaySettings DisplaySettings
|
||||
TimezoneSettings TimezoneSettings
|
||||
ImageProxySettings ImageProxySettings
|
||||
}
|
||||
|
||||
func (o *Config) Clone() *Config {
|
||||
@@ -2037,6 +2078,7 @@ func (o *Config) SetDefaults() {
|
||||
o.MessageExportSettings.SetDefaults()
|
||||
o.TimezoneSettings.SetDefaults()
|
||||
o.DisplaySettings.SetDefaults()
|
||||
o.ImageProxySettings.SetDefaults(o.ServiceSettings)
|
||||
}
|
||||
|
||||
func (o *Config) IsValid() *AppError {
|
||||
@@ -2108,6 +2150,10 @@ func (o *Config) IsValid() *AppError {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := o.ImageProxySettings.isValid(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -2392,16 +2438,6 @@ func (ss *ServiceSettings) isValid() *AppError {
|
||||
return NewAppError("Config.IsValid", "model.config.is_valid.group_unread_channels.app_error", nil, "", http.StatusBadRequest)
|
||||
}
|
||||
|
||||
switch *ss.ImageProxyType {
|
||||
case "":
|
||||
case "atmos/camo":
|
||||
if *ss.ImageProxyOptions == "" {
|
||||
return NewAppError("Config.IsValid", "model.config.is_valid.atmos_camo_image_proxy_options.app_error", nil, "", http.StatusBadRequest)
|
||||
}
|
||||
default:
|
||||
return NewAppError("Config.IsValid", "model.config.is_valid.image_proxy_type.app_error", nil, "", http.StatusBadRequest)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -2521,6 +2557,27 @@ func (ds *DisplaySettings) isValid() *AppError {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (ips *ImageProxySettings) isValid() *AppError {
|
||||
if *ips.Enable {
|
||||
switch *ips.ImageProxyType {
|
||||
case IMAGE_PROXY_TYPE_LOCAL:
|
||||
// No other settings to validate
|
||||
case IMAGE_PROXY_TYPE_ATMOS_CAMO:
|
||||
if *ips.RemoteImageProxyURL == "" {
|
||||
return NewAppError("Config.IsValid", "model.config.is_valid.atmos_camo_image_proxy_url.app_error", nil, "", http.StatusBadRequest)
|
||||
}
|
||||
|
||||
if *ips.RemoteImageProxyOptions == "" {
|
||||
return NewAppError("Config.IsValid", "model.config.is_valid.atmos_camo_image_proxy_options.app_error", nil, "", http.StatusBadRequest)
|
||||
}
|
||||
default:
|
||||
return NewAppError("Config.IsValid", "model.config.is_valid.image_proxy_type.app_error", nil, "", http.StatusBadRequest)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (o *Config) GetSanitizeOptions() map[string]bool {
|
||||
options := map[string]bool{}
|
||||
options["fullname"] = o.PrivacySettings.ShowFullName
|
||||
|
||||
@@ -564,3 +564,128 @@ func TestListenAddressIsValidated(t *testing.T) {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func TestImageProxySettingsSetDefaults(t *testing.T) {
|
||||
ss := ServiceSettings{
|
||||
DEPRECATED_DO_NOT_USE_ImageProxyType: NewString(IMAGE_PROXY_TYPE_ATMOS_CAMO),
|
||||
DEPRECATED_DO_NOT_USE_ImageProxyURL: NewString("http://images.example.com"),
|
||||
DEPRECATED_DO_NOT_USE_ImageProxyOptions: NewString("1234abcd"),
|
||||
}
|
||||
|
||||
t.Run("default, no old settings", func(t *testing.T) {
|
||||
ips := ImageProxySettings{}
|
||||
ips.SetDefaults(ServiceSettings{})
|
||||
|
||||
assert.Equal(t, true, *ips.Enable)
|
||||
assert.Equal(t, IMAGE_PROXY_TYPE_LOCAL, *ips.ImageProxyType)
|
||||
assert.Equal(t, "", *ips.RemoteImageProxyURL)
|
||||
assert.Equal(t, "", *ips.RemoteImageProxyOptions)
|
||||
})
|
||||
|
||||
t.Run("default, old settings", func(t *testing.T) {
|
||||
ips := ImageProxySettings{}
|
||||
ips.SetDefaults(ss)
|
||||
|
||||
assert.Equal(t, true, *ips.Enable)
|
||||
assert.Equal(t, *ss.DEPRECATED_DO_NOT_USE_ImageProxyType, *ips.ImageProxyType)
|
||||
assert.Equal(t, *ss.DEPRECATED_DO_NOT_USE_ImageProxyURL, *ips.RemoteImageProxyURL)
|
||||
assert.Equal(t, *ss.DEPRECATED_DO_NOT_USE_ImageProxyOptions, *ips.RemoteImageProxyOptions)
|
||||
})
|
||||
|
||||
t.Run("not default, old settings", func(t *testing.T) {
|
||||
url := "http://images.mattermost.com"
|
||||
options := "aaaaaaaa"
|
||||
|
||||
ips := ImageProxySettings{
|
||||
Enable: NewBool(false),
|
||||
ImageProxyType: NewString(IMAGE_PROXY_TYPE_LOCAL),
|
||||
RemoteImageProxyURL: &url,
|
||||
RemoteImageProxyOptions: &options,
|
||||
}
|
||||
ips.SetDefaults(ss)
|
||||
|
||||
assert.Equal(t, false, *ips.Enable)
|
||||
assert.Equal(t, IMAGE_PROXY_TYPE_LOCAL, *ips.ImageProxyType)
|
||||
assert.Equal(t, url, *ips.RemoteImageProxyURL)
|
||||
assert.Equal(t, options, *ips.RemoteImageProxyOptions)
|
||||
})
|
||||
}
|
||||
|
||||
func TestImageProxySettingsIsValid(t *testing.T) {
|
||||
for _, test := range []struct {
|
||||
Name string
|
||||
Enable bool
|
||||
ImageProxyType string
|
||||
RemoteImageProxyURL string
|
||||
RemoteImageProxyOptions string
|
||||
ExpectError bool
|
||||
}{
|
||||
{
|
||||
Name: "disabled",
|
||||
Enable: false,
|
||||
ExpectError: false,
|
||||
},
|
||||
{
|
||||
Name: "disabled with bad values",
|
||||
Enable: false,
|
||||
ImageProxyType: "garbage",
|
||||
RemoteImageProxyURL: "garbage",
|
||||
RemoteImageProxyOptions: "garbage",
|
||||
ExpectError: false,
|
||||
},
|
||||
{
|
||||
Name: "missing type",
|
||||
Enable: true,
|
||||
ImageProxyType: "",
|
||||
ExpectError: true,
|
||||
},
|
||||
{
|
||||
Name: "local",
|
||||
Enable: true,
|
||||
ImageProxyType: "local",
|
||||
RemoteImageProxyURL: "garbage",
|
||||
RemoteImageProxyOptions: "garbage",
|
||||
ExpectError: false,
|
||||
},
|
||||
{
|
||||
Name: "atmos/camo",
|
||||
Enable: true,
|
||||
ImageProxyType: IMAGE_PROXY_TYPE_ATMOS_CAMO,
|
||||
RemoteImageProxyURL: "someurl",
|
||||
RemoteImageProxyOptions: "someoptions",
|
||||
ExpectError: false,
|
||||
},
|
||||
{
|
||||
Name: "atmos/camo, missing url",
|
||||
Enable: true,
|
||||
ImageProxyType: IMAGE_PROXY_TYPE_ATMOS_CAMO,
|
||||
RemoteImageProxyURL: "",
|
||||
RemoteImageProxyOptions: "garbage",
|
||||
ExpectError: true,
|
||||
},
|
||||
{
|
||||
Name: "atmos/camo, missing options",
|
||||
Enable: true,
|
||||
ImageProxyType: IMAGE_PROXY_TYPE_ATMOS_CAMO,
|
||||
RemoteImageProxyURL: "someurl",
|
||||
RemoteImageProxyOptions: "",
|
||||
ExpectError: true,
|
||||
},
|
||||
} {
|
||||
t.Run(test.Name, func(t *testing.T) {
|
||||
ips := &ImageProxySettings{
|
||||
Enable: &test.Enable,
|
||||
ImageProxyType: &test.ImageProxyType,
|
||||
RemoteImageProxyURL: &test.RemoteImageProxyURL,
|
||||
RemoteImageProxyOptions: &test.RemoteImageProxyOptions,
|
||||
}
|
||||
|
||||
err := ips.isValid()
|
||||
if test.ExpectError {
|
||||
assert.NotNil(t, err)
|
||||
} else {
|
||||
assert.Nil(t, err)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
Ссылка в новой задаче
Block a user