Fleet UI: Users page disable checkboxes not meeting requirements (#44080)
This commit is contained in:
@@ -83,8 +83,9 @@ export interface IMdmConfig {
|
||||
macos_manual_agent_install: boolean | null;
|
||||
require_all_software_macos: boolean | null;
|
||||
lock_end_user_info: boolean | null;
|
||||
enable_create_local_admin_account?: boolean;
|
||||
};
|
||||
macos_setup: {
|
||||
macos_setup?: {
|
||||
enable_managed_local_account?: boolean;
|
||||
};
|
||||
macos_migration: IMacOsMigrationSettings;
|
||||
|
||||
@@ -67,8 +67,9 @@ export interface ITeam extends ITeamSummary {
|
||||
macos_manual_agent_install: boolean | null;
|
||||
require_all_software_macos: boolean | null;
|
||||
lock_end_user_info: boolean | null;
|
||||
enable_create_local_admin_account?: boolean;
|
||||
};
|
||||
macos_setup: {
|
||||
macos_setup?: {
|
||||
enable_managed_local_account?: boolean;
|
||||
};
|
||||
windows_updates: {
|
||||
|
||||
@@ -9,7 +9,7 @@ import { ITeamConfig } from "interfaces/team";
|
||||
|
||||
import SectionHeader from "components/SectionHeader/SectionHeader";
|
||||
import Spinner from "components/Spinner";
|
||||
import GenericMsgWithNavButton from "components/GenericMsgWithNavButton";
|
||||
|
||||
import CustomLink from "components/CustomLink";
|
||||
import { LEARN_MORE_ABOUT_BASE_LINK } from "utilities/constants";
|
||||
|
||||
@@ -30,11 +30,15 @@ const getEnabledManagedLocalAccount = (
|
||||
|
||||
if (currentTeamId === 0) {
|
||||
return (
|
||||
globalConfig?.mdm?.macos_setup?.enable_managed_local_account ?? false
|
||||
globalConfig?.mdm?.setup_experience?.enable_create_local_admin_account ??
|
||||
false
|
||||
);
|
||||
}
|
||||
|
||||
return teamConfig?.mdm?.macos_setup?.enable_managed_local_account ?? false;
|
||||
return (
|
||||
teamConfig?.mdm?.setup_experience?.enable_create_local_admin_account ??
|
||||
false
|
||||
);
|
||||
};
|
||||
|
||||
const getEnabledEndUserAuth = (
|
||||
@@ -129,22 +133,13 @@ const Users = ({ currentTeamId, router }: ISetupExperienceCardProps) => {
|
||||
const mdmConfig = globalConfig.mdm;
|
||||
return (
|
||||
<SetupExperienceContentContainer>
|
||||
{!isIdPConfigured(mdmConfig) ? (
|
||||
<GenericMsgWithNavButton
|
||||
header="Require end user authentication during setup"
|
||||
info="Connect Fleet to your identity provider (IdP) to get started."
|
||||
buttonText="Connect"
|
||||
router={router}
|
||||
path={PATHS.ADMIN_INTEGRATIONS_SSO_END_USERS}
|
||||
/>
|
||||
) : (
|
||||
<UsersForm
|
||||
currentTeamId={currentTeamId}
|
||||
defaultIsEndUserAuthEnabled={defaultIsEndUserAuthEnabled}
|
||||
defaultLockEndUserInfo={defaultLockEndUserInfo}
|
||||
defaultEnableManagedLocalAccount={defaultEnableManagedLocalAccount}
|
||||
/>
|
||||
)}
|
||||
<UsersForm
|
||||
currentTeamId={currentTeamId}
|
||||
defaultIsEndUserAuthEnabled={defaultIsEndUserAuthEnabled}
|
||||
defaultLockEndUserInfo={defaultLockEndUserInfo}
|
||||
defaultEnableManagedLocalAccount={defaultEnableManagedLocalAccount}
|
||||
isIdPConfigured={isIdPConfigured(mdmConfig)}
|
||||
/>
|
||||
</SetupExperienceContentContainer>
|
||||
);
|
||||
};
|
||||
|
||||
+82
@@ -10,12 +10,27 @@ describe("UsersForm", () => {
|
||||
defaultIsEndUserAuthEnabled: false,
|
||||
defaultLockEndUserInfo: false,
|
||||
defaultEnableManagedLocalAccount: false,
|
||||
isIdPConfigured: true,
|
||||
};
|
||||
|
||||
const render = createCustomRenderer({
|
||||
withBackendMock: true,
|
||||
});
|
||||
|
||||
const renderWithMdmEnabled = createCustomRenderer({
|
||||
withBackendMock: true,
|
||||
context: {
|
||||
app: { isMacMdmEnabledAndConfigured: true },
|
||||
},
|
||||
});
|
||||
|
||||
const renderWithMdmDisabled = createCustomRenderer({
|
||||
withBackendMock: true,
|
||||
context: {
|
||||
app: { isMacMdmEnabledAndConfigured: false },
|
||||
},
|
||||
});
|
||||
|
||||
it("renders the end user authentication and managed local account checkboxes", () => {
|
||||
render(<UsersForm {...defaultProps} />);
|
||||
expect(screen.getByText("End user authentication")).toBeInTheDocument();
|
||||
@@ -83,4 +98,71 @@ describe("UsersForm", () => {
|
||||
const saveButtons = screen.getAllByRole("button", { name: "Save" });
|
||||
expect(saveButtons).toHaveLength(1);
|
||||
});
|
||||
|
||||
describe("disabled states", () => {
|
||||
it("disables end user authentication checkbox when IdP is not configured", () => {
|
||||
render(<UsersForm {...defaultProps} isIdPConfigured={false} />);
|
||||
expect(
|
||||
screen.getByRole("checkbox", { name: "End user authentication" })
|
||||
).toHaveAttribute("aria-disabled", "true");
|
||||
});
|
||||
|
||||
it("enables end user authentication checkbox when IdP is configured", () => {
|
||||
render(<UsersForm {...defaultProps} isIdPConfigured />);
|
||||
expect(
|
||||
screen.getByRole("checkbox", { name: "End user authentication" })
|
||||
).toHaveAttribute("aria-disabled", "false");
|
||||
});
|
||||
|
||||
it("disables lock end user info when IdP is not configured", () => {
|
||||
render(
|
||||
<UsersForm
|
||||
{...defaultProps}
|
||||
isIdPConfigured={false}
|
||||
defaultIsEndUserAuthEnabled
|
||||
/>
|
||||
);
|
||||
expect(
|
||||
screen.getByRole("checkbox", { name: "Lock end user info" })
|
||||
).toHaveAttribute("aria-disabled", "true");
|
||||
});
|
||||
|
||||
it("does not allow toggling end user auth when IdP is not configured", async () => {
|
||||
const { user } = render(
|
||||
<UsersForm {...defaultProps} isIdPConfigured={false} />
|
||||
);
|
||||
|
||||
const checkbox = screen.getByRole("checkbox", {
|
||||
name: "End user authentication",
|
||||
});
|
||||
await user.click(checkbox);
|
||||
|
||||
expect(checkbox).not.toBeChecked();
|
||||
});
|
||||
|
||||
it("disables managed local account checkbox when Apple MDM is not configured", () => {
|
||||
renderWithMdmDisabled(<UsersForm {...defaultProps} />);
|
||||
expect(
|
||||
screen.getByRole("checkbox", { name: "Managed local account" })
|
||||
).toHaveAttribute("aria-disabled", "true");
|
||||
});
|
||||
|
||||
it("enables managed local account checkbox when Apple MDM is configured", () => {
|
||||
renderWithMdmEnabled(<UsersForm {...defaultProps} />);
|
||||
expect(
|
||||
screen.getByRole("checkbox", { name: "Managed local account" })
|
||||
).toHaveAttribute("aria-disabled", "false");
|
||||
});
|
||||
|
||||
it("does not allow toggling managed local account when Apple MDM is not configured", async () => {
|
||||
const { user } = renderWithMdmDisabled(<UsersForm {...defaultProps} />);
|
||||
|
||||
const checkbox = screen.getByRole("checkbox", {
|
||||
name: "Managed local account",
|
||||
});
|
||||
await user.click(checkbox);
|
||||
|
||||
expect(checkbox).not.toBeChecked();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
+86
-33
@@ -18,6 +18,7 @@ interface IUsersFormProps {
|
||||
defaultIsEndUserAuthEnabled: boolean;
|
||||
defaultLockEndUserInfo: boolean;
|
||||
defaultEnableManagedLocalAccount: boolean;
|
||||
isIdPConfigured: boolean;
|
||||
}
|
||||
|
||||
const UsersForm = ({
|
||||
@@ -25,10 +26,11 @@ const UsersForm = ({
|
||||
defaultIsEndUserAuthEnabled,
|
||||
defaultLockEndUserInfo,
|
||||
defaultEnableManagedLocalAccount,
|
||||
isIdPConfigured,
|
||||
}: IUsersFormProps) => {
|
||||
const { renderFlash } = useContext(NotificationContext);
|
||||
const gitOpsModeEnabled = useContext(AppContext).config?.gitops
|
||||
.gitops_mode_enabled;
|
||||
const { config, isMacMdmEnabledAndConfigured } = useContext(AppContext);
|
||||
const gitOpsModeEnabled = config?.gitops.gitops_mode_enabled;
|
||||
|
||||
const [isEndUserAuthEnabled, setEndUserAuthEnabled] = useState(
|
||||
defaultIsEndUserAuthEnabled
|
||||
@@ -68,7 +70,8 @@ const UsersForm = ({
|
||||
setEnableManagedLocalAccount(newCheckVal);
|
||||
};
|
||||
|
||||
const onClickSave = async () => {
|
||||
const onClickSave = async (e: React.FormEvent<HTMLFormElement>) => {
|
||||
e.preventDefault();
|
||||
setIsUpdating(true);
|
||||
const canLockEndUserInfo = isEndUserAuthEnabled && lockEndUserInfo;
|
||||
|
||||
@@ -91,27 +94,49 @@ const UsersForm = ({
|
||||
return (
|
||||
<div className={baseClass}>
|
||||
<form onSubmit={onClickSave}>
|
||||
<Checkbox
|
||||
disabled={gitOpsModeEnabled}
|
||||
value={isEndUserAuthEnabled}
|
||||
onChange={onToggleEndUserAuth}
|
||||
helpText={
|
||||
<span>
|
||||
End users are required to authenticate with your{" "}
|
||||
<CustomLink
|
||||
url={PATHS.ADMIN_INTEGRATIONS_SSO_END_USERS}
|
||||
text="identity provider (IdP)"
|
||||
/>{" "}
|
||||
when setting up new hosts.
|
||||
</span>
|
||||
<TooltipWrapper
|
||||
tipContent={
|
||||
!isIdPConfigured ? (
|
||||
<span>
|
||||
To enable, first connect Fleet to
|
||||
<br />
|
||||
your{" "}
|
||||
<CustomLink
|
||||
url={PATHS.ADMIN_INTEGRATIONS_SSO_END_USERS}
|
||||
text="identity provider (IdP)"
|
||||
variant="tooltip-link"
|
||||
/>
|
||||
.
|
||||
</span>
|
||||
) : undefined
|
||||
}
|
||||
disableTooltip={isIdPConfigured}
|
||||
underline={false}
|
||||
position="left"
|
||||
showArrow
|
||||
>
|
||||
End user authentication
|
||||
</Checkbox>
|
||||
<Checkbox
|
||||
disabled={gitOpsModeEnabled || !isIdPConfigured}
|
||||
value={isEndUserAuthEnabled}
|
||||
onChange={onToggleEndUserAuth}
|
||||
helpText={
|
||||
<span>
|
||||
End users are required to authenticate with your{" "}
|
||||
<CustomLink
|
||||
url={PATHS.ADMIN_INTEGRATIONS_SSO_END_USERS}
|
||||
text="identity provider (IdP)"
|
||||
/>{" "}
|
||||
when setting up new hosts.
|
||||
</span>
|
||||
}
|
||||
>
|
||||
End user authentication
|
||||
</Checkbox>
|
||||
</TooltipWrapper>
|
||||
{isEndUserAuthEnabled && (
|
||||
<div className={`${baseClass}__advanced-options`}>
|
||||
<Checkbox
|
||||
disabled={gitOpsModeEnabled}
|
||||
disabled={gitOpsModeEnabled || !isIdPConfigured}
|
||||
onChange={onChangeLockEndUserInfo}
|
||||
value={lockEndUserInfo}
|
||||
>
|
||||
@@ -133,22 +158,50 @@ const UsersForm = ({
|
||||
</Checkbox>
|
||||
</div>
|
||||
)}
|
||||
<Checkbox
|
||||
disabled={gitOpsModeEnabled}
|
||||
value={enableManagedLocalAccount}
|
||||
onChange={onToggleManagedLocalAccount}
|
||||
helpText={
|
||||
<span>
|
||||
Fleet generates a user (_fleetadmin) and unique password for each
|
||||
host, accessible in <b>Host details</b> >{" "}
|
||||
<b>Show managed account</b>.
|
||||
</span>
|
||||
<TooltipWrapper
|
||||
tipContent={
|
||||
!isMacMdmEnabledAndConfigured ? (
|
||||
<span>
|
||||
To enable, first turn on{" "}
|
||||
<CustomLink
|
||||
url={PATHS.ADMIN_INTEGRATIONS_MDM_APPLE}
|
||||
text="Apple MDM"
|
||||
variant="tooltip-link"
|
||||
/>
|
||||
.
|
||||
</span>
|
||||
) : undefined
|
||||
}
|
||||
disableTooltip={!!isMacMdmEnabledAndConfigured}
|
||||
underline={false}
|
||||
position="left"
|
||||
showArrow
|
||||
>
|
||||
<TooltipWrapper tipContent="Creates a hidden managed local admin account for remote troubleshooting on macOS hosts.">
|
||||
Managed local account
|
||||
</TooltipWrapper>
|
||||
</Checkbox>
|
||||
<Checkbox
|
||||
disabled={gitOpsModeEnabled || !isMacMdmEnabledAndConfigured}
|
||||
value={enableManagedLocalAccount}
|
||||
onChange={onToggleManagedLocalAccount}
|
||||
helpText={
|
||||
<span>
|
||||
Fleet generates a user (_fleetadmin) and unique password for
|
||||
each host, accessible in <b>Host details</b> >{" "}
|
||||
<b>Show managed account</b>.
|
||||
</span>
|
||||
}
|
||||
>
|
||||
<TooltipWrapper
|
||||
tipContent={
|
||||
<>
|
||||
Creates a hidden managed local admin account for
|
||||
<br />
|
||||
remote troubleshooting on macOS hosts.
|
||||
</>
|
||||
}
|
||||
>
|
||||
Managed local account
|
||||
</TooltipWrapper>
|
||||
</Checkbox>
|
||||
</TooltipWrapper>
|
||||
<GitOpsModeTooltipWrapper
|
||||
renderChildren={(disableChildren) => (
|
||||
<Button
|
||||
|
||||
@@ -340,7 +340,9 @@ const canShowManagedAccount = (config: IHostActionConfigOptions) => {
|
||||
if (hostPlatform !== "darwin") return false;
|
||||
if (!isConnectedToFleetMdm) return false;
|
||||
if (!isAutomaticDeviceEnrollment(hostMdmEnrollmentStatus)) return false;
|
||||
if (!isManagedLocalAccountEnabled) return false;
|
||||
if (!isManagedLocalAccountEnabled && !config.managedAccountStatus) {
|
||||
return false;
|
||||
}
|
||||
return isGlobalAdmin || isGlobalMaintainer || isTeamAdmin || isTeamMaintainer;
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user