Files
netbird/client/ios/NetBirdSDK/preferences.go
T
riccardom 2885e3771d [client] Name the resolving reader for what it does, not what it makes
ReadOrGenerateConfig reads the profile config and falls back to the defaults in
memory when there is no file. "Generate" reads as "produces and stores", which
is the opposite of the property the rename it came from was meant to advertise:
the read is pure, writes nothing and mints no identity.

ReadConfigOrDefault says the same without the side effect, and pairs with
GetExistingConfig, which fails where this one falls back. Its doc comment now
states the absence of a write rather than only the fallback.

Pure rename; the two remaining mentions of the pre-branch name ReadConfig in
the tests go with it.

Reported by pappz in review.
2026-09-25 13:21:15 +02:00

197 lines
5.7 KiB
Go

//go:build ios
package NetBirdSDK
import (
"sync/atomic"
"github.com/netbirdio/netbird/client/internal/profilemanager"
"github.com/netbirdio/netbird/client/mdm"
)
// Preferences export a subset of the internal config for gomobile
type Preferences struct {
configInput profilemanager.ConfigInput
mdmLoader atomic.Pointer[mdm.Loader]
}
// NewPreferences create new Preferences instance
func NewPreferences(configPath string, stateFilePath string) *Preferences {
ci := profilemanager.ConfigInput{
ConfigPath: configPath,
StateFilePath: stateFilePath,
}
return &Preferences{configInput: ci}
}
// SetMDMPolicyFetcher registers the native-provided MDM policy fetcher on
// this Preferences instance; passing nil disables MDM enforcement.
func (p *Preferences) SetMDMPolicyFetcher(f PolicyFetcher) {
p.mdmLoader.Store(loaderFor(f))
}
// GetRestrictionsJSON returns the UI enforcement snapshot derived from the
// active MDM policy, in the JSON shape shared with the desktop frontend.
func (p *Preferences) GetRestrictionsJSON() (string, error) {
return mdm.BuildRestrictions(p.policy()).JSON()
}
func (p *Preferences) policy() *mdm.Policy {
return p.mdmLoader.Load().Load()
}
// GetManagementURL read url from config file
func (p *Preferences) GetManagementURL() (string, error) {
if v, ok := p.policy().GetString(mdm.KeyManagementURL); ok {
return mdm.CanonicalURL(v), nil
}
if p.configInput.ManagementURL != "" {
return p.configInput.ManagementURL, nil
}
cfg, err := profilemanager.ReadConfigOrDefault(p.configInput.ConfigPath)
if err != nil {
return "", err
}
return cfg.ManagementURL.String(), nil
}
// SetManagementURL store the given url and wait for commit
func (p *Preferences) SetManagementURL(url string) {
p.configInput.ManagementURL = url
}
// GetAdminURL read url from config file
func (p *Preferences) GetAdminURL() (string, error) {
if p.configInput.AdminURL != "" {
return p.configInput.AdminURL, nil
}
cfg, err := profilemanager.ReadConfigOrDefault(p.configInput.ConfigPath)
if err != nil {
return "", err
}
return cfg.AdminURL.String(), err
}
// SetAdminURL store the given url and wait for commit
func (p *Preferences) SetAdminURL(url string) {
p.configInput.AdminURL = url
}
// HasPreSharedKey reports whether a pre-shared key is staged, persisted, or
// enforced by MDM; the key itself is never handed to the native layer.
func (p *Preferences) HasPreSharedKey() (bool, error) {
if _, ok := p.policy().GetString(mdm.KeyPreSharedKey); ok {
return true, nil
}
if p.configInput.PreSharedKey != nil {
return *p.configInput.PreSharedKey != "", nil
}
cfg, err := profilemanager.ReadConfigOrDefault(p.configInput.ConfigPath)
if err != nil {
return false, err
}
return cfg.PreSharedKey != "", nil
}
// SetPreSharedKey store the given key and wait for commit
func (p *Preferences) SetPreSharedKey(key string) {
p.configInput.PreSharedKey = &key
}
// SetRosenpassEnabled store if rosenpass is enabled
func (p *Preferences) SetRosenpassEnabled(enabled bool) {
p.configInput.RosenpassEnabled = &enabled
}
// GetRosenpassEnabled read rosenpass enabled from config file
func (p *Preferences) GetRosenpassEnabled() (bool, error) {
if v, ok := p.policy().GetBool(mdm.KeyRosenpassEnabled); ok {
return v, nil
}
if p.configInput.RosenpassEnabled != nil {
return *p.configInput.RosenpassEnabled, nil
}
cfg, err := profilemanager.ReadConfigOrDefault(p.configInput.ConfigPath)
if err != nil {
return false, err
}
return cfg.RosenpassEnabled, err
}
// SetRosenpassPermissive store the given permissive and wait for commit
func (p *Preferences) SetRosenpassPermissive(permissive bool) {
p.configInput.RosenpassPermissive = &permissive
}
// GetRosenpassPermissive read rosenpass permissive from config file
func (p *Preferences) GetRosenpassPermissive() (bool, error) {
if v, ok := p.policy().GetBool(mdm.KeyRosenpassPermissive); ok {
return v, nil
}
if p.configInput.RosenpassPermissive != nil {
return *p.configInput.RosenpassPermissive, nil
}
cfg, err := profilemanager.ReadConfigOrDefault(p.configInput.ConfigPath)
if err != nil {
return false, err
}
return cfg.RosenpassPermissive, err
}
// GetDisableIPv6 reads disable IPv6 setting from config file
func (p *Preferences) GetDisableIPv6() (bool, error) {
if p.configInput.DisableIPv6 != nil {
return *p.configInput.DisableIPv6, nil
}
cfg, err := profilemanager.ReadConfigOrDefault(p.configInput.ConfigPath)
if err != nil {
return false, err
}
return cfg.DisableIPv6, err
}
// SetDisableIPv6 stores the given value and waits for commit
func (p *Preferences) SetDisableIPv6(disable bool) {
p.configInput.DisableIPv6 = &disable
}
// GetRemoteJobsAllowed reads the remote jobs opt-in from config file
func (p *Preferences) GetRemoteJobsAllowed() (bool, error) {
policy := p.policy()
if !policy.HasKey(mdm.KeyRemoteJobsAllowed) && p.configInput.RemoteJobsAllowed != nil {
return *p.configInput.RemoteJobsAllowed, nil
}
cfg, err := profilemanager.ReadConfigOrDefault(p.configInput.ConfigPath)
if err != nil {
return false, err
}
cfg.ApplyMDMPolicy(policy)
if cfg.RemoteJobsAllowed == nil {
return false, nil
}
return *cfg.RemoteJobsAllowed, nil
}
// SetRemoteJobsAllowed stores the given value and waits for commit
func (p *Preferences) SetRemoteJobsAllowed(allowed bool) {
p.configInput.RemoteJobsAllowed = &allowed
}
// Commit write out the changes into config file
func (p *Preferences) Commit() error {
if err := profilemanager.CheckMDMConflicts(p.configInput, p.policy()); err != nil {
return err
}
// Use DirectUpdateOrCreateConfig to avoid atomic file operations (temp file + rename)
// which are blocked by the tvOS sandbox in App Group containers
_, err := profilemanager.DirectUpdateOrCreateConfig(p.configInput)
return err
}