diff --git a/core/internal/server/network/backend_networkmanager_ethernet.go b/core/internal/server/network/backend_networkmanager_ethernet.go index 85f1e6261..b11272f88 100644 --- a/core/internal/server/network/backend_networkmanager_ethernet.go +++ b/core/internal/server/network/backend_networkmanager_ethernet.go @@ -258,16 +258,11 @@ func (b *NetworkManagerBackend) listEthernetConnections() ([]WiredConnection, er return nil, fmt.Errorf("no ethernet device available") } - s := b.settings - if s == nil { - s, err := gonetworkmanager.NewSettings() - if err != nil { - return nil, fmt.Errorf("failed to get settings: %w", err) - } - b.settings = s + settingsMgr, err := b.networkManagerSettings() + if err != nil { + return nil, err } - settingsMgr := s.(gonetworkmanager.Settings) connections, err := settingsMgr.ListConnections() if err != nil { return nil, fmt.Errorf("failed to get connections: %w", err) diff --git a/core/internal/server/network/backend_networkmanager_signals.go b/core/internal/server/network/backend_networkmanager_signals.go index 684a03c20..272ed4b6e 100644 --- a/core/internal/server/network/backend_networkmanager_signals.go +++ b/core/internal/server/network/backend_networkmanager_signals.go @@ -305,6 +305,9 @@ func (b *NetworkManagerBackend) handleDBusSignal(sig *dbus.Signal) { } b.updateHotspotState() b.listCellularConnections() + // Device state does not change when an inactive wired profile is + // added or deleted, so the profile list must be refreshed here too. + b.listEthernetConnections() if b.onStateChange != nil { b.onStateChange() } diff --git a/core/internal/server/network/backend_networkmanager_signals_test.go b/core/internal/server/network/backend_networkmanager_signals_test.go index 1123acb64..0f6c811ac 100644 --- a/core/internal/server/network/backend_networkmanager_signals_test.go +++ b/core/internal/server/network/backend_networkmanager_signals_test.go @@ -130,3 +130,57 @@ func TestNetworkManagerBackend_HandleWiFiChange_CoalescesAccessPointBurst(t *tes return stateChangeCalls.Load() == 1 }, 4*wifiNetworksUpdateDelay, 10*time.Millisecond) } + +func TestNetworkManagerBackend_HandleDBusSignal_ConnectionRemovedRefreshesWiredConnections(t *testing.T) { + mockNM := mock_gonetworkmanager.NewMockNetworkManager(t) + mockNM.EXPECT().GetPropertyActiveConnections().Return([]gonetworkmanager.ActiveConnection{}, nil).Maybe() + + remaining := mock_gonetworkmanager.NewMockConnection(t) + remaining.EXPECT().GetPath().Return(dbus.ObjectPath("/org/freedesktop/NetworkManager/Settings/1")).Maybe() + remaining.EXPECT().GetSettings().Return(gonetworkmanager.ConnectionSettings{ + "connection": { + "id": "Wired connection 1", + "uuid": "uuid-1", + "type": "802-3-ethernet", + }, + }, nil).Maybe() + + mockSettings := mock_gonetworkmanager.NewMockSettings(t) + mockSettings.EXPECT().ListConnections().Return([]gonetworkmanager.Connection{remaining}, nil).Maybe() + + backend, err := NewNetworkManagerBackend(mockNM) + assert.NoError(t, err) + backend.settings = mockSettings + backend.ethernetDevice = mock_gonetworkmanager.NewMockDevice(t) + + backend.stateMutex.Lock() + backend.state.WiredConnections = []WiredConnection{ + {ID: "Wired connection 1", UUID: "uuid-1", Type: "802-3-ethernet"}, + {ID: "Wired connection 2", UUID: "uuid-2", Type: "802-3-ethernet"}, + } + backend.stateMutex.Unlock() + + backend.handleDBusSignal(&dbus.Signal{ + Name: "org.freedesktop.NetworkManager.Settings.ConnectionRemoved", + Body: []any{dbus.ObjectPath("/org/freedesktop/NetworkManager/Settings/2")}, + }) + + backend.stateMutex.RLock() + defer backend.stateMutex.RUnlock() + assert.Len(t, backend.state.WiredConnections, 1) + assert.Equal(t, "uuid-1", backend.state.WiredConnections[0].UUID) +} + +func TestNetworkManagerBackend_ListEthernetConnections_InvalidSettingsHandle(t *testing.T) { + mockNM := mock_gonetworkmanager.NewMockNetworkManager(t) + + backend, err := NewNetworkManagerBackend(mockNM) + assert.NoError(t, err) + backend.settings = "not a settings handle" + backend.ethernetDevice = mock_gonetworkmanager.NewMockDevice(t) + + assert.NotPanics(t, func() { + _, err = backend.listEthernetConnections() + }) + assert.Error(t, err) +}