You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
tailscale-android/android/src/main/java/com/tailscale/ipn/mdm/MDMSettings.kt

122 lines
4.8 KiB
Kotlin

// Copyright (c) Tailscale Inc & AUTHORS
// SPDX-License-Identifier: BSD-3-Clause
package com.tailscale.ipn.mdm
import android.content.RestrictionsManager
import com.tailscale.ipn.App
import kotlin.reflect.KVisibility
import kotlin.reflect.full.declaredMemberProperties
import kotlin.reflect.full.isSubclassOf
import kotlin.reflect.jvm.jvmErasure
object MDMSettings {
// The String message used in this NoSuchKeyException must match the value of
// syspolicy.ErrNoSuchKey defined in Go. We compare against its exact text
// to determine whether the requested policy setting is not configured and
// an actual syspolicy.ErrNoSuchKey should be returned from syspolicyHandler
// to the backend.
class NoSuchKeyException : Exception("no such key")
val forceEnabled = BooleanMDMSetting("ForceEnabled", "Force Enabled Connection Toggle")
// Handled on the backed
val exitNodeID = StringMDMSetting("ExitNodeID", "Forced Exit Node: Stable ID")
// (jonathan) TODO: Unused but required. There is some funky go string duration parsing required
// here.
val keyExpirationNotice = StringMDMSetting("KeyExpirationNotice", "Key Expiration Notice Period")
val loginURL = StringMDMSetting("LoginURL", "Custom control server URL")
val managedByCaption = StringMDMSetting("ManagedByCaption", "Managed By - Caption")
val managedByOrganizationName =
StringMDMSetting("ManagedByOrganizationName", "Managed By - Organization Name")
val managedByURL = StringMDMSetting("ManagedByURL", "Managed By - Support URL")
// Handled on the backend
val tailnet = StringMDMSetting("Tailnet", "Recommended/Required Tailnet Name")
val hiddenNetworkDevices =
StringArrayListMDMSetting("HiddenNetworkDevices", "Hidden Network Device Categories")
// Unused on Android
val allowIncomingConnections =
AlwaysNeverUserDecidesMDMSetting("AllowIncomingConnections", "Allow Incoming Connections")
// Unused on Android
val detectThirdPartyAppConflicts =
AlwaysNeverUserDecidesMDMSetting(
"DetectThirdPartyAppConflicts", "Detect potentially problematic third-party apps")
val exitNodeAllowLANAccess =
AlwaysNeverUserDecidesMDMSetting(
"ExitNodeAllowLANAccess", "Allow LAN Access when using an exit node")
// Handled on the backend
val postureChecking =
AlwaysNeverUserDecidesMDMSetting("PostureChecking", "Enable Posture Checking")
val useTailscaleDNSSettings =
AlwaysNeverUserDecidesMDMSetting("UseTailscaleDNSSettings", "Use Tailscale DNS Settings")
// Unused on Android
val useTailscaleSubnets =
AlwaysNeverUserDecidesMDMSetting("UseTailscaleSubnets", "Use Tailscale Subnets")
val exitNodesPicker = ShowHideMDMSetting("ExitNodesPicker", "Exit Nodes Picker")
val manageTailnetLock = ShowHideMDMSetting("ManageTailnetLock", "“Manage Tailnet lock” menu item")
// Unused on Android
val resetToDefaults = ShowHideMDMSetting("ResetToDefaults", "“Reset to Defaults” menu item")
val runExitNode = ShowHideMDMSetting("RunExitNode", "Run as Exit Node")
// Unused on Android
val testMenu = ShowHideMDMSetting("TestMenu", "Show Debug Menu")
// Unused on Android
val updateMenu = ShowHideMDMSetting("UpdateMenu", "“Update Available” menu item")
// (jonathan) TODO: Use this when suggested exit nodes are implemented
val allowedSuggestedExitNodes =
StringArrayListMDMSetting("AllowedSuggestedExitNodes", "Allowed Suggested Exit Nodes")
// Allows admins to define a list of packages that won't be routed via Tailscale.
val excludedPackages = StringMDMSetting("ExcludedPackageNames", "Excluded Package Names")
// Allows admins to define a list of packages that will be routed via Tailscale, letting all other
// apps skip the VPN tunnel.
val includedPackages = StringMDMSetting("IncludedPackageNames", "Included Package Names")
// Handled on the backend
val authKey = StringMDMSetting("AuthKey", "Auth Key for login")
// Overrides the value provided by os.Hostname() in Go
val hostname = StringMDMSetting("Hostname", "Device Hostname")
// Allows admins to skip the get started intro screen
val onboardingFlow = ShowHideMDMSetting("OnboardingFlow", "Suppress the intro screen")
val allSettings by lazy {
MDMSettings::class
.declaredMemberProperties
.filter {
it.visibility == KVisibility.PUBLIC &&
it.returnType.jvmErasure.isSubclassOf(MDMSetting::class)
}
.map { it.call(MDMSettings) as MDMSetting<*> }
}
val allSettingsByKey by lazy { allSettings.associateBy { it.key } }
fun update(app: App, restrictionsManager: RestrictionsManager?) {
val bundle = restrictionsManager?.applicationRestrictions
val preferences = lazy { app.getEncryptedPrefs() }
allSettings.forEach { it.setFrom(bundle, preferences) }
app.notifyPolicyChanged()
}
}