Fix #798: Migrate SkipSSLVerify setting to per-server

This commit is contained in:
Drew Weymouth
2026-01-29 08:35:21 -08:00
parent 703a8ede53
commit 9aeb7d0bd2
5 changed files with 57 additions and 40 deletions
+14 -2
View File
@@ -21,6 +21,7 @@ type ServerConnection struct {
AltHostname string AltHostname string
Username string Username string
LegacyAuth bool LegacyAuth bool
SkipSSLVerify bool
} }
type ServerConfig struct { type ServerConfig struct {
@@ -50,7 +51,7 @@ type AppConfig struct {
EnableLrcLib bool EnableLrcLib bool
CustomLrcLibUrl string CustomLrcLibUrl string
EnablePasswordStorage bool EnablePasswordStorage bool
SkipSSLVerify bool SkipSSLVerify bool // Deprecated: use per-server SkipSSLVerify. Drop in future version.
EnqueueBatchSize int EnqueueBatchSize int
Language string Language string
DisableDPIDetection bool DisableDPIDetection bool
@@ -212,7 +213,6 @@ func DefaultConfig(appVersionTag string) *Config {
ShowTrackChangeNotification: false, ShowTrackChangeNotification: false,
EnableLrcLib: true, EnableLrcLib: true,
EnablePasswordStorage: true, EnablePasswordStorage: true,
SkipSSLVerify: false,
EnqueueBatchSize: 100, EnqueueBatchSize: 100,
Language: "auto", Language: "auto",
EnableAutoUpdateChecker: true, EnableAutoUpdateChecker: true,
@@ -311,6 +311,7 @@ func ReadConfigFile(filepath, appVersionTag string) (*Config, error) {
if err := toml.NewDecoder(f).Decode(c); err != nil { if err := toml.NewDecoder(f).Decode(c); err != nil {
return nil, err return nil, err
} }
c.migrateDeprecatedSettings()
// Backfill Subsonic to empty ServerType fields // Backfill Subsonic to empty ServerType fields
// for updating configs created before multiple MediaProviders were added // for updating configs created before multiple MediaProviders were added
@@ -331,6 +332,8 @@ func (c *Config) WriteConfigFile(filepath string) error {
} }
defer writeLock.Unlock() defer writeLock.Unlock()
// clear deprecated global SkipSSLVerify after migrating to per-server settings
c.Application.SkipSSLVerify = false
b, err := toml.Marshal(c) b, err := toml.Marshal(c)
if err != nil { if err != nil {
return err return err
@@ -339,3 +342,12 @@ func (c *Config) WriteConfigFile(filepath string) error {
return nil return nil
} }
func (c *Config) migrateDeprecatedSettings() {
// Migrate deprecated global SkipSSLVerify to per-server settings
if c.Application.SkipSSLVerify {
for _, s := range c.Servers {
s.SkipSSLVerify = true
}
}
}
+6 -6
View File
@@ -185,7 +185,7 @@ func (s *ServerManager) connect(connection ServerConnection, password string) (m
log.Printf("error creating Jellyfin client: %s", err.Error()) log.Printf("error creating Jellyfin client: %s", err.Error())
return nil, err return nil, err
} }
s.checkSetInsecureSkipVerify(client.HTTPClient) s.checkSetInsecureSkipVerify(connection.SkipSSLVerify, client.HTTPClient)
cli = &jellyfinMP.JellyfinServer{ cli = &jellyfinMP.JellyfinServer{
Client: *client, Client: *client,
} }
@@ -196,7 +196,7 @@ func (s *ServerManager) connect(connection ServerConnection, password string) (m
log.Printf("error creating Jellyfin alternative client: %s", err.Error()) log.Printf("error creating Jellyfin alternative client: %s", err.Error())
return nil, err return nil, err
} }
s.checkSetInsecureSkipVerify(altClient.HTTPClient) s.checkSetInsecureSkipVerify(connection.SkipSSLVerify, altClient.HTTPClient)
altCli = &jellyfinMP.JellyfinServer{ altCli = &jellyfinMP.JellyfinServer{
Client: *altClient, Client: *altClient,
} }
@@ -213,7 +213,7 @@ func (s *ServerManager) connect(connection ServerConnection, password string) (m
ClientName: res.AppName, ClientName: res.AppName,
}, },
} }
s.checkSetInsecureSkipVerify(cli.(*subsonicMP.SubsonicServer).Client.Client) s.checkSetInsecureSkipVerify(connection.SkipSSLVerify, cli.(*subsonicMP.SubsonicServer).Client.Client)
altCli = &subsonicMP.SubsonicServer{ altCli = &subsonicMP.SubsonicServer{
Client: subsonic.Client{ Client: subsonic.Client{
UserAgent: ua, UserAgent: ua,
@@ -224,7 +224,7 @@ func (s *ServerManager) connect(connection ServerConnection, password string) (m
ClientName: res.AppName, ClientName: res.AppName,
}, },
} }
s.checkSetInsecureSkipVerify(altCli.(*subsonicMP.SubsonicServer).Client.Client) s.checkSetInsecureSkipVerify(connection.SkipSSLVerify, altCli.(*subsonicMP.SubsonicServer).Client.Client)
} }
var authError error var authError error
pingChan := make(chan bool, 2) // false for primary hostname, true for alternate pingChan := make(chan bool, 2) // false for primary hostname, true for alternate
@@ -255,8 +255,8 @@ func (s *ServerManager) connect(connection ServerConnection, password string) (m
} }
} }
func (s *ServerManager) checkSetInsecureSkipVerify(cli *http.Client) { func (s *ServerManager) checkSetInsecureSkipVerify(skip bool, cli *http.Client) {
if s.config.Application.SkipSSLVerify { if skip {
cli.Transport = &http.Transport{ cli.Transport = &http.Transport{
TLSClientConfig: &tls.Config{InsecureSkipVerify: true}, TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
} }
+4
View File
@@ -32,6 +32,7 @@ func (m *Controller) PromptForFirstServer() {
AltHostname: d.AltHost, AltHostname: d.AltHost,
Username: d.Username, Username: d.Username,
LegacyAuth: d.LegacyAuth, LegacyAuth: d.LegacyAuth,
SkipSSLVerify: d.SkipSSLVerify,
} }
server := m.App.ServerManager.AddServer(d.Nickname, conn) server := m.App.ServerManager.AddServer(d.Nickname, conn)
if err := m.trySetPasswordAndConnectToServer(server, d.Password); err != nil { if err := m.trySetPasswordAndConnectToServer(server, d.Password); err != nil {
@@ -138,6 +139,7 @@ func (m *Controller) PromptForLoginAndConnect() {
server.Nickname = editD.Nickname server.Nickname = editD.Nickname
server.Username = editD.Username server.Username = editD.Username
server.LegacyAuth = editD.LegacyAuth server.LegacyAuth = editD.LegacyAuth
server.SkipSSLVerify = editD.SkipSSLVerify
m.trySetPasswordAndConnectToServer(server, editD.Password) m.trySetPasswordAndConnectToServer(server, editD.Password)
m.doModalClosed() m.doModalClosed()
} }
@@ -169,6 +171,7 @@ func (m *Controller) PromptForLoginAndConnect() {
AltHostname: newD.AltHost, AltHostname: newD.AltHost,
Username: newD.Username, Username: newD.Username,
LegacyAuth: newD.LegacyAuth, LegacyAuth: newD.LegacyAuth,
SkipSSLVerify: newD.SkipSSLVerify,
} }
server := m.App.ServerManager.AddServer(newD.Nickname, conn) server := m.App.ServerManager.AddServer(newD.Nickname, conn)
m.trySetPasswordAndConnectToServer(server, newD.Password) m.trySetPasswordAndConnectToServer(server, newD.Password)
@@ -238,6 +241,7 @@ func (c *Controller) testConnectionAndUpdateDialogText(dlg *dialogs.AddEditServe
AltHostname: dlg.AltHost, AltHostname: dlg.AltHost,
Username: dlg.Username, Username: dlg.Username,
LegacyAuth: dlg.LegacyAuth, LegacyAuth: dlg.LegacyAuth,
SkipSSLVerify: dlg.SkipSSLVerify,
} }
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel() defer cancel()
+4 -1
View File
@@ -24,6 +24,7 @@ type AddEditServerDialog struct {
Username string Username string
Password string Password string
LegacyAuth bool LegacyAuth bool
SkipSSLVerify bool
OnSubmit func() OnSubmit func()
OnCancel func() OnCancel func()
@@ -45,6 +46,7 @@ func NewAddEditServerDialog(title string, cancelable bool, prefillServer *backen
a.AltHost = prefillServer.AltHostname a.AltHost = prefillServer.AltHostname
a.Username = prefillServer.Username a.Username = prefillServer.Username
a.LegacyAuth = prefillServer.LegacyAuth a.LegacyAuth = prefillServer.LegacyAuth
a.SkipSSLVerify = prefillServer.SkipSSLVerify
} }
titleLabel := widget.NewLabel(title) titleLabel := widget.NewLabel(title)
@@ -58,6 +60,7 @@ func NewAddEditServerDialog(title string, cancelable bool, prefillServer *backen
legacyAuthCheck.Hide() legacyAuthCheck.Hide()
} }
}) })
skipSSLCheck := widget.NewCheckWithData(lang.L("Skip SSL certificate verification"), binding.BindBool(&a.SkipSSLVerify))
serverTypeChoice.Required = true serverTypeChoice.Required = true
serverTypeChoice.Horizontal = true serverTypeChoice.Horizontal = true
selected := backend.ServerTypeSubsonic selected := backend.ServerTypeSubsonic
@@ -113,7 +116,7 @@ func NewAddEditServerDialog(title string, cancelable bool, prefillServer *backen
widget.NewLabel(lang.L("Password")), widget.NewLabel(lang.L("Password")),
a.passField, a.passField,
), ),
container.NewHBox(layout.NewSpacer(), legacyAuthCheck), container.NewHBox(layout.NewSpacer(), legacyAuthCheck, skipSSLCheck),
widget.NewSeparator(), widget.NewSeparator(),
bottomRow, bottomRow,
) )
-2
View File
@@ -617,7 +617,6 @@ func (s *SettingsDialog) createAppearanceTab(window fyne.Window) *container.TabI
func (s *SettingsDialog) createAdvancedTab() *container.TabItem { func (s *SettingsDialog) createAdvancedTab() *container.TabItem {
multi := widget.NewCheckWithData(lang.L("Allow multiple app instances"), binding.BindBool(&s.config.Application.AllowMultiInstance)) multi := widget.NewCheckWithData(lang.L("Allow multiple app instances"), binding.BindBool(&s.config.Application.AllowMultiInstance))
sslSkip := widget.NewCheckWithData(lang.L("Skip SSL certificate verification"), binding.BindBool(&s.config.Application.SkipSSLVerify))
update := widget.NewCheckWithData(lang.L("Automatically check for updates"), binding.BindBool(&s.config.Application.EnableAutoUpdateChecker)) update := widget.NewCheckWithData(lang.L("Automatically check for updates"), binding.BindBool(&s.config.Application.EnableAutoUpdateChecker))
lrclib := widget.NewCheckWithData(lang.L("Enable LrcLib lyrics fetcher"), binding.BindBool(&s.config.Application.EnableLrcLib)) lrclib := widget.NewCheckWithData(lang.L("Enable LrcLib lyrics fetcher"), binding.BindBool(&s.config.Application.EnableLrcLib))
@@ -659,7 +658,6 @@ func (s *SettingsDialog) createAdvancedTab() *container.TabItem {
return container.NewTabItem(lang.L("Advanced"), container.NewVBox( return container.NewTabItem(lang.L("Advanced"), container.NewVBox(
multi, multi,
sslSkip,
update, update,
lrclib, lrclib,
osMediaAPIs, osMediaAPIs,