Android: fix BYOD enrollment page to get up-to-date MDM enabled status (#27011)

This commit is contained in:
Martin Angers 2025-03-11 11:06:25 -04:00 committed by GitHub
parent fec311d68c
commit c8b1af7603
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 60 additions and 29 deletions

View file

@ -1081,13 +1081,10 @@ the way that the Fleet server works.
frontendHandler = service.RedirectSetupToLogin(svc, logger, frontendHandler, config.Server.URLPrefix)
}
// TODO: need a mechanism to check if android feature is enabled
endUserEnrollOTAHandler = service.ServeEndUserEnrollOTA(
svc,
config.Server.URLPrefix,
appCfg.MDM.EnabledAndConfigured,
appCfg.MDM.AndroidEnabledAndConfigured,
os.Getenv("FLEET_DEV_ANDROID_ENABLED") == "1",
ds,
logger,
)
}

View file

@ -6,6 +6,7 @@ import (
"io"
"net/http"
"net/url"
"os"
assetfs "github.com/elazarl/go-bindata-assetfs"
"github.com/fleetdm/fleet/v4/server/bindata"
@ -76,15 +77,14 @@ func ServeFrontend(urlPrefix string, sandbox bool, logger log.Logger) http.Handl
func ServeEndUserEnrollOTA(
svc fleet.Service,
urlPrefix string,
isMacMDMEnabled bool,
isAndroidMDMEnabled bool,
isAndroidFeatureEnabled bool, // TODO: remove android feature flag
ds fleet.Datastore,
logger log.Logger,
) http.Handler {
herr := func(w http.ResponseWriter, err string) {
logger.Log("err", err)
http.Error(w, err, http.StatusInternalServerError)
}
androidFeatureEnabled := os.Getenv("FLEET_DEV_ANDROID_ENABLED") == "1"
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
endpoint_utils.WriteBrowserSecurityHeaders(w)
@ -93,12 +93,17 @@ func ServeEndUserEnrollOTA(
herr(w, "setup required err: "+err.Error())
return
}
if setupRequired {
herr(w, "fleet instance not setup")
return
}
appCfg, err := ds.AppConfig(r.Context())
if err != nil {
herr(w, "load appconfig err: "+err.Error())
return
}
fs := newBinaryFileSystem("/frontend")
file, err := fs.Open("templates/enroll-ota.html")
if err != nil {
@ -132,9 +137,9 @@ func ServeEndUserEnrollOTA(
}{
URLPrefix: urlPrefix,
EnrollURL: enrollURL,
AndroidMDMEnabled: isAndroidMDMEnabled,
MacMDMEnabled: isMacMDMEnabled,
AndroidFeatureEnabled: isAndroidFeatureEnabled,
AndroidMDMEnabled: appCfg.MDM.AndroidEnabledAndConfigured,
MacMDMEnabled: appCfg.MDM.EnabledAndConfigured,
AndroidFeatureEnabled: androidFeatureEnabled,
}); err != nil {
herr(w, "execute react template: "+err.Error())
return

View file

@ -3,14 +3,17 @@ package service
import (
"bytes"
"context"
"fmt"
"io"
"net/http"
"net/http/httptest"
"os"
"testing"
"github.com/fleetdm/fleet/v4/server/fleet"
"github.com/fleetdm/fleet/v4/server/mock"
"github.com/go-kit/log"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
@ -53,26 +56,52 @@ func TestServeEndUserEnrollOTA(t *testing.T) {
ds.HasUsersFunc = func(ctx context.Context) (bool, error) {
return true, nil
}
appCfg := &fleet.AppConfig{
MDM: fleet.MDM{
EnabledAndConfigured: false,
AndroidEnabledAndConfigured: false,
},
}
ds.AppConfigFunc = func(ctx context.Context) (*fleet.AppConfig, error) {
return appCfg, nil
}
svc, _ := newTestService(t, ds, nil, nil)
logger := log.NewLogfmtLogger(os.Stdout)
h := ServeEndUserEnrollOTA(svc, "", true, true, true, logger)
ts := httptest.NewServer(h)
t.Cleanup(func() {
ts.Close()
})
for _, enabled := range []bool{true, false} {
t.Run(fmt.Sprintf("MDM enabled: %t", enabled), func(t *testing.T) {
appCfg.MDM.EnabledAndConfigured = enabled
appCfg.MDM.AndroidEnabledAndConfigured = enabled
if enabled {
t.Setenv("FLEET_DEV_ANDROID_ENABLED", "1")
} else {
t.Setenv("FLEET_DEV_ANDROID_ENABLED", "0")
}
// assert html is returned
response, err := http.DefaultClient.Get(ts.URL + "?enroll_secret=foo")
require.NoError(t, err)
require.Equal(t, http.StatusOK, response.StatusCode)
require.Equal(t, response.Header.Get("Content-Type"), "text/html; charset=utf-8")
logger := log.NewLogfmtLogger(os.Stdout)
h := ServeEndUserEnrollOTA(svc, "", ds, logger)
ts := httptest.NewServer(h)
t.Cleanup(func() {
ts.Close()
})
// assert it contains the content we expect
defer response.Body.Close()
bodyBytes, err := io.ReadAll(response.Body)
require.NoError(t, err)
bodyString := string(bodyBytes)
require.Contains(t, bodyString, "api/v1/fleet/enrollment_profiles/ota?enroll_secret=foo")
require.Contains(t, bodyString, "/api/v1/fleet/android_enterprise/enrollment_token")
// assert html is returned
response, err := http.DefaultClient.Get(ts.URL + "?enroll_secret=foo")
require.NoError(t, err)
require.Equal(t, http.StatusOK, response.StatusCode)
require.Equal(t, response.Header.Get("Content-Type"), "text/html; charset=utf-8")
assert.True(t, ds.AppConfigFuncInvoked)
// assert it contains the content we expect
defer response.Body.Close()
bodyBytes, err := io.ReadAll(response.Body)
require.NoError(t, err)
bodyString := string(bodyBytes)
require.Contains(t, bodyString, "api/v1/fleet/enrollment_profiles/ota?enroll_secret=foo")
require.Contains(t, bodyString, "/api/v1/fleet/android_enterprise/enrollment_token")
require.Contains(t, bodyString, fmt.Sprintf(`const ANDROID_MDM_ENABLED = "%t" === "true";`, enabled))
require.Contains(t, bodyString, fmt.Sprintf(`const MAC_MDM_ENABLED = "%t" == "true";`, enabled))
require.Contains(t, bodyString, fmt.Sprintf(`const ANDROID_FEATURE_ENABLED = "%t" === "true";`, enabled))
})
}
}