/* * Copyright (C) 2023 Red Hat, Inc. * SPDX-License-Identifier: LGPL-2.1-or-later */ import cockpit from "cockpit"; import { getAdminUserExistsAction, getUserConfigurationPolicyAction, getUsersAction } from "../actions/users-actions.js"; import { debug, error } from "../helpers/log.js"; import { _callClient, _getProperty, _setProperty, objectFromDbus } from "./helpers.js"; const OBJECT_PATH = "/org/fedoraproject/Anaconda/Modules/Users"; const INTERFACE_NAME = "org.fedoraproject.Anaconda.Modules.Users"; const getProperty = (...args) => { return _getProperty(UsersClient, OBJECT_PATH, INTERFACE_NAME, ...args); }; const setProperty = (...args) => { return _setProperty(UsersClient, OBJECT_PATH, INTERFACE_NAME, ...args); }; const callClient = (...args) => { return _callClient(UsersClient, OBJECT_PATH, INTERFACE_NAME, ...args); }; export class UsersClient { constructor (address, dispatch) { if (UsersClient.instance && (!address || UsersClient.instance.address === address)) { return UsersClient.instance; } UsersClient.instance?.client.close(); UsersClient.instance = this; this.client = cockpit.dbus( INTERFACE_NAME, { address, bus: "none", superuser: "try" } ); this.address = address; this.dispatch = dispatch; } /** * @param {object} args Bootstrap args from `Application` (`conf`, `automatedInstall`). */ init (args = {}) { this.client.addEventListener( "close", () => error("Users client closed") ); this.startEventMonitor(args); return Promise.all([ this.dispatch(getUsersAction()), this.dispatch(getAdminUserExistsAction()), this.dispatch(getUserConfigurationPolicyAction(args)), ]); } stopEventMonitor () { this._subscription?.remove(); } startEventMonitor () { this._subscription = this.client.subscribe( { }, async (path, iface, signal, args) => { switch (signal) { case "PropertiesChanged": await this.dispatch(getUsersAction()); break; default: debug(`Unhandled signal on ${path}: ${iface}.${signal}`, JSON.stringify(args)); } } ); } } /** * @param {Array.} users An array of user objects */ export const setUsers = (users) => { return setProperty("Users", cockpit.variant("aa{sv}", users)); }; /** * @param {boolean} locked True if locked, otherwise False */ export const setIsRootAccountLocked = (locked) => { return setProperty("IsRootAccountLocked", cockpit.variant("b", locked)); }; /** * @param {string} password Crypted root password */ export const setCryptedRootPassword = ({ password }) => { return callClient("SetCryptedRootPassword", [password]); }; export const clearRootPassword = () => { return callClient("ClearRootPassword", []); }; export const guessUsernameFromFullName = (fullName) => { return callClient("GuessUsernameFromFullName", [fullName]); }; export const getUsers = () => { return getProperty("Users").then(arr => (arr || []).map(item => objectFromDbus(item))); }; export const getIsRootAccountLocked = () => { return getProperty("IsRootAccountLocked"); }; export const getIsRootPasswordSet = () => { return getProperty("IsRootPasswordSet"); }; export const getCanChangeRootPassword = () => { return getProperty("CanChangeRootPassword"); }; export const getCheckAdminUserExists = () => { return callClient("CheckAdminUserExists", []); };