From 7570c5c911f0940b5114ea1e7ee637566337f719 Mon Sep 17 00:00:00 2001 From: riccardom Date: Thu, 4 Jun 2026 14:58:49 +0200 Subject: [PATCH] Toggle gray in/out for Advanced Settings --- client/proto/daemon.pb.go | 21 +++++++++++++++++---- client/proto/daemon.proto | 5 +++++ client/server/server.go | 10 ++++++++++ client/ui/client_ui.go | 16 ++++++++++++++-- 4 files changed, 46 insertions(+), 6 deletions(-) diff --git a/client/proto/daemon.pb.go b/client/proto/daemon.pb.go index 70d9e8212..d01ba8527 100644 --- a/client/proto/daemon.pb.go +++ b/client/proto/daemon.pb.go @@ -4919,8 +4919,13 @@ type GetFeaturesResponse struct { DisableProfiles bool `protobuf:"varint,1,opt,name=disable_profiles,json=disableProfiles,proto3" json:"disable_profiles,omitempty"` DisableUpdateSettings bool `protobuf:"varint,2,opt,name=disable_update_settings,json=disableUpdateSettings,proto3" json:"disable_update_settings,omitempty"` DisableNetworks bool `protobuf:"varint,3,opt,name=disable_networks,json=disableNetworks,proto3" json:"disable_networks,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache + // disable_advanced_settings reflects the MDM-managed kill switch + // (mdm.KeyDisableAdvancedSettings). When true, the GUI must lock the + // "Advanced Settings" submenu item so the user cannot open the + // settings window and edit any field. + DisableAdvancedSettings bool `protobuf:"varint,4,opt,name=disable_advanced_settings,json=disableAdvancedSettings,proto3" json:"disable_advanced_settings,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } func (x *GetFeaturesResponse) Reset() { @@ -4974,6 +4979,13 @@ func (x *GetFeaturesResponse) GetDisableNetworks() bool { return false } +func (x *GetFeaturesResponse) GetDisableAdvancedSettings() bool { + if x != nil { + return x.DisableAdvancedSettings + } + return false +} + // MDMManagedFieldsViolation is attached as a gRPC error detail on a // FailedPrecondition status returned from SetConfig (and similar mutating // RPCs) when the caller tries to modify one or more MDM-enforced fields. @@ -6754,11 +6766,12 @@ const file_daemon_proto_rawDesc = "" + "\f_profileNameB\v\n" + "\t_username\"\x10\n" + "\x0eLogoutResponse\"\x14\n" + - "\x12GetFeaturesRequest\"\xa3\x01\n" + + "\x12GetFeaturesRequest\"\xdf\x01\n" + "\x13GetFeaturesResponse\x12)\n" + "\x10disable_profiles\x18\x01 \x01(\bR\x0fdisableProfiles\x126\n" + "\x17disable_update_settings\x18\x02 \x01(\bR\x15disableUpdateSettings\x12)\n" + - "\x10disable_networks\x18\x03 \x01(\bR\x0fdisableNetworks\"3\n" + + "\x10disable_networks\x18\x03 \x01(\bR\x0fdisableNetworks\x12:\n" + + "\x19disable_advanced_settings\x18\x04 \x01(\bR\x17disableAdvancedSettings\"3\n" + "\x19MDMManagedFieldsViolation\x12\x16\n" + "\x06fields\x18\x01 \x03(\tR\x06fields\"\x16\n" + "\x14TriggerUpdateRequest\"M\n" + diff --git a/client/proto/daemon.proto b/client/proto/daemon.proto index 265ab40bb..e545800b8 100644 --- a/client/proto/daemon.proto +++ b/client/proto/daemon.proto @@ -738,6 +738,11 @@ message GetFeaturesResponse{ bool disable_profiles = 1; bool disable_update_settings = 2; bool disable_networks = 3; + // disable_advanced_settings reflects the MDM-managed kill switch + // (mdm.KeyDisableAdvancedSettings). When true, the GUI must lock the + // "Advanced Settings" submenu item so the user cannot open the + // settings window and edit any field. + bool disable_advanced_settings = 4; } // MDMManagedFieldsViolation is attached as a gRPC error detail on a diff --git a/client/server/server.go b/client/server/server.go index b3b2fc75a..92811c241 100644 --- a/client/server/server.go +++ b/client/server/server.go @@ -1678,6 +1678,16 @@ func (s *Server) GetFeatures(ctx context.Context, msg *proto.GetFeaturesRequest) DisableNetworks: s.networksDisabled, } + // MDM kill switch: read the value from the active policy on the + // in-memory Config snapshot. Returns false on an absent key, so the + // feature flag is only "true" when the admin has explicitly pushed + // disableAdvancedSettings=true via the platform MDM channel. + if s.config != nil { + if v, ok := s.config.Policy().GetBool(mdm.KeyDisableAdvancedSettings); ok { + features.DisableAdvancedSettings = v + } + } + return features, nil } diff --git a/client/ui/client_ui.go b/client/ui/client_ui.go index 9e64637da..9db29e43f 100644 --- a/client/ui/client_ui.go +++ b/client/ui/client_ui.go @@ -1268,6 +1268,20 @@ func (s *serviceClient) checkAndUpdateFeatures() { s.setSettingsEnabled(settingsEnabled) } + // MDM kill switch on the Advanced Settings submenu item: when the + // daemon reports disableAdvancedSettings=true the user must not be + // able to open the settings window at all. Title gets the "(MDM)" + // suffix to match the convention used for individual locked fields. + if s.mAdvancedSettings != nil { + if features != nil && features.DisableAdvancedSettings { + s.mAdvancedSettings.SetTitle("Advanced Settings (MDM)") + s.mAdvancedSettings.Disable() + } else { + s.mAdvancedSettings.SetTitle("Advanced Settings") + s.mAdvancedSettings.Enable() + } + } + // Update profile menu based on current features if s.mProfile != nil { profilesEnabled := features == nil || !features.DisableProfiles @@ -1707,13 +1721,11 @@ func (s *serviceClient) applyMDMLocksToSettingsForm(set map[string]bool) { t.entry.SetText(t.entry.Text + mdmFieldSuffix) } t.entry.Disable() - t.entry.Refresh() } else { if t.inlineTag { t.entry.SetText(strings.TrimSuffix(t.entry.Text, mdmFieldSuffix)) } t.entry.Enable() - t.entry.Refresh() } } type checkTarget struct {