Skip to content

Commit

Permalink
Merge pull request #5280 from rvykydal/users-step
Browse files Browse the repository at this point in the history
Users step
  • Loading branch information
rvykydal authored Nov 6, 2023
2 parents 93b3967 + fb8257c commit e81d86b
Show file tree
Hide file tree
Showing 20 changed files with 865 additions and 362 deletions.
56 changes: 56 additions & 0 deletions ui/webui/src/apis/users.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
/*
* Copyright (C) 2023 Red Hat, Inc.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2.1 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with This program; If not, see <http://www.gnu.org/licenses/>.
*/
import cockpit from "cockpit";
import { _setProperty } from "./helpers.js";

const OBJECT_PATH = "/org/fedoraproject/Anaconda/Modules/Users";
const INTERFACE_NAME = "org.fedoraproject.Anaconda.Modules.Users";

const setProperty = (...args) => {
return _setProperty(UsersClient, OBJECT_PATH, INTERFACE_NAME, ...args);
};

export class UsersClient {
constructor (address) {
if (UsersClient.instance && (!address || UsersClient.instance.address === address)) {
return UsersClient.instance;
}

UsersClient.instance?.client.close();

UsersClient.instance = this;

this.client = cockpit.dbus(
INTERFACE_NAME,
{ superuser: "try", bus: "none", address }
);
this.address = address;
}

init () {
this.client.addEventListener(
"close", () => console.error("Users client closed")
);
}
}

/**
* @param {Array.<Object>} users An array of user objects
*/
export const setUsers = (users) => {
return setProperty("Users", cockpit.variant("aa{sv}", users));
};
35 changes: 30 additions & 5 deletions ui/webui/src/components/AnacondaWizard.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ import { getDefaultScenario } from "./storage/InstallationScenario.jsx";
import { MountPointMapping, getPageProps as getMountPointMappingProps } from "./storage/MountPointMapping.jsx";
import { DiskEncryption, getStorageEncryptionState, getPageProps as getDiskEncryptionProps } from "./storage/DiskEncryption.jsx";
import { InstallationLanguage, getPageProps as getInstallationLanguageProps } from "./localization/InstallationLanguage.jsx";
import { Accounts, getPageProps as getAccountsProps, getAccountsState, accountsToDbusUsers } from "./users/Accounts.jsx";
import { InstallationProgress } from "./installation/InstallationProgress.jsx";
import { ReviewConfiguration, ReviewConfigurationConfirmModal, getPageProps as getReviewConfigurationProps } from "./review/ReviewConfiguration.jsx";
import { exitGui } from "../helpers/exit.js";
Expand All @@ -50,6 +51,9 @@ import {
applyStorage,
resetPartitioning,
} from "../apis/storage_partitioning.js";
import {
setUsers,
} from "../apis/users.js";
import { SystemTypeContext, OsReleaseContext } from "./Common.jsx";

const _ = cockpit.gettext;
Expand All @@ -63,6 +67,7 @@ export const AnacondaWizard = ({ dispatch, storageData, localizationData, runtim
const [stepNotification, setStepNotification] = useState();
const [storageEncryption, setStorageEncryption] = useState(getStorageEncryptionState());
const [storageScenarioId, setStorageScenarioId] = useState(window.sessionStorage.getItem("storage-scenario-id") || getDefaultScenario().id);
const [accounts, setAccounts] = useState(getAccountsState());
const [showWizard, setShowWizard] = useState(true);
const osRelease = useContext(OsReleaseContext);
const isBootIso = useContext(SystemTypeContext) === "BOOT_ISO";
Expand Down Expand Up @@ -143,6 +148,15 @@ export const AnacondaWizard = ({ dispatch, storageData, localizationData, runtim
...getDiskEncryptionProps({ storageScenarioId })
}]
},
{
component: Accounts,
data: {
accounts,
setAccounts,
passwordPolicies: runtimeData.passwordPolicies,
},
...getAccountsProps({ isBootIso })
},
{
component: ReviewConfiguration,
data: {
Expand Down Expand Up @@ -178,10 +192,14 @@ export const AnacondaWizard = ({ dispatch, storageData, localizationData, runtim
const firstStepId = stepsOrder.filter(step => !step.isHidden)[0].id;
const currentStepId = path[0] || firstStepId;

const isStepFollowedBy = (earlierStepId, laterStepId) => {
const earlierStepIdx = flattenedStepsIds.findIndex(s => s === earlierStepId);
const laterStepIdx = flattenedStepsIds.findIndex(s => s === laterStepId);
return earlierStepIdx < laterStepIdx;
};

const canJumpToStep = (stepId, currentStepId) => {
const stepIdx = flattenedStepsIds.findIndex(s => s === stepId);
const currentStepIdx = flattenedStepsIds.findIndex(s => s === currentStepId);
return stepIdx <= currentStepIdx;
return stepId === currentStepId || isStepFollowedBy(stepId, currentStepId);
};

const createSteps = (stepsOrder) => {
Expand Down Expand Up @@ -224,8 +242,10 @@ export const AnacondaWizard = ({ dispatch, storageData, localizationData, runtim
setIsFormValid(false);
}

// Reset the applied partitioning when going back from review page
if (prevStep.prevId === "installation-review") {
// Reset the applied partitioning when going back from a step after creating partitioning to a step
// before creating partitioning.
if ((prevStep.prevId === "accounts" || isStepFollowedBy("accounts", prevStep.prevId)) &&
isStepFollowedBy(newStep.id, "accounts")) {
setIsFormDisabled(true);
resetPartitioning()
.then(
Expand Down Expand Up @@ -262,6 +282,7 @@ export const AnacondaWizard = ({ dispatch, storageData, localizationData, runtim
stepsOrder={stepsOrder}
storageEncryption={storageEncryption}
storageScenarioId={storageScenarioId}
accounts={accounts}
/>}
hideClose
mainAriaLabel={`${title} content`}
Expand All @@ -288,6 +309,7 @@ const Footer = ({
stepsOrder,
storageEncryption,
storageScenarioId,
accounts,
}) => {
const [nextWaitsConfirmation, setNextWaitsConfirmation] = useState(false);
const [quitWaitsConfirmation, setQuitWaitsConfirmation] = useState(false);
Expand Down Expand Up @@ -338,6 +360,9 @@ const Footer = ({
setStepNotification();
},
});
} else if (activeStep.id === "accounts") {
setUsers(accountsToDbusUsers(accounts));
onNext();
} else {
onNext();
}
Expand Down
Loading

0 comments on commit e81d86b

Please sign in to comment.