From f8e80d09a3eb50655326733e157eac997f51d81f Mon Sep 17 00:00:00 2001 From: Marius Vollmer Date: Mon, 13 Jan 2020 16:55:54 +0200 Subject: [PATCH] realmd: Don't directly manipulate the DOM Both the realmd code and the systemd code would try to to set the "disabled" attribute of the #system_information_hostname_button element, and would race each other. To get better decoupling, the realmd code has been changed to only export the necessary information to construct the buttons (instead of modifying the DOM directly with jQuery), and the systemd code now uses that to render them with React. As part of that the realmd code hase been moved into pkg/systemd since that is the only user. Closes #13369 --- Makefile.am | 1 - pkg/lib/cockpit-components-privileged.jsx | 2 +- pkg/realmd/manifest.json.in | 7 -- .../README.md => systemd/README-realmd.md} | 2 +- pkg/systemd/index.html | 1 - .../overview-cards/configurationCard.jsx | 53 +++++++-- .../overview-cards/realmd-operation.html} | 0 .../overview-cards/realmd-operation.js} | 103 +++++++----------- test/verify/check-realms | 51 +++++---- tools/cockpit.spec | 6 +- tools/debian/cockpit-system.install | 1 - tools/debian/control | 3 +- 12 files changed, 112 insertions(+), 118 deletions(-) delete mode 100644 pkg/realmd/manifest.json.in rename pkg/{realmd/README.md => systemd/README-realmd.md} (98%) rename pkg/{realmd/operation.html => systemd/overview-cards/realmd-operation.html} (100%) rename pkg/{realmd/operation.js => systemd/overview-cards/realmd-operation.js} (89%) diff --git a/Makefile.am b/Makefile.am index 8a4c02166..044cd377b 100644 --- a/Makefile.am +++ b/Makefile.am @@ -162,7 +162,6 @@ WEBPACK_PACKAGES = \ pcp \ packagekit \ playground \ - realmd \ selinux \ shell \ sosreport \ diff --git a/pkg/lib/cockpit-components-privileged.jsx b/pkg/lib/cockpit-components-privileged.jsx index 042230064..0d48a61b3 100644 --- a/pkg/lib/cockpit-components-privileged.jsx +++ b/pkg/lib/cockpit-components-privileged.jsx @@ -34,7 +34,7 @@ import cockpit from "cockpit"; */ export function Privileged({ excuse, allowed, placement, tooltipId, children }) { // wrap into extra so that a disabled child keeps the tooltip working - let contents = { children }; + let contents = { children }; if (!allowed) { contents = ( - diff --git a/pkg/systemd/overview-cards/configurationCard.jsx b/pkg/systemd/overview-cards/configurationCard.jsx index e8cde4438..f07e84f56 100644 --- a/pkg/systemd/overview-cards/configurationCard.jsx +++ b/pkg/systemd/overview-cards/configurationCard.jsx @@ -27,8 +27,9 @@ import $ from "jquery"; import { mustache } from "mustache"; import * as packagekit from "packagekit.js"; import { install_dialog } from "cockpit-components-install-dialog.jsx"; -import { PrivilegedButton } from "cockpit-components-privileged.jsx"; +import { Privileged, PrivilegedButton } from "cockpit-components-privileged.jsx"; import { ServerTime } from './serverTime.js'; +import * as realmd from "./realmd-operation.js"; /* These add themselves to jQuery so just including is enough */ import "patterns"; @@ -78,6 +79,8 @@ export class ConfigurationCard extends React.Component { this.host_keys_show = this.host_keys_show.bind(this); this.host_keys_hide = this.host_keys_hide.bind(this); + + this.realmd = realmd.setup(); } componentDidMount() { @@ -94,6 +97,8 @@ export class ConfigurationCard extends React.Component { }); $("#system_information_ssh_keys").on("hide.bs.modal", () => this.host_keys_hide()); + + this.realmd.addEventListener("changed", () => this.setState({})); } systime_setup() { @@ -321,14 +326,27 @@ export class ConfigurationCard extends React.Component { } render() { + // We use a Privileged component for its ability to + // conditionally show a tooltip, even when the button is not + // actually disabled, so the "allowed" property really means + // "does not have tooltip" here. + + const hostname_tooltip = (this.permission.allowed === false + ? cockpit.format(_("The user $0 is not permitted to modify hostnames"), + this.permission.user ? this.permission.user.name : '') + : this.realmd.hostname_button_tooltip); + const hostname_disabled = this.permission.allowed === false || this.realmd.hostname_button_disabled; + const hostname_button = ( - $('#system_information_change_hostname').modal('show') } - excuse={ _("The user $0 is not permitted to modify hostnames") } - permission={ this.permission } ariaLabel="edit hostname"> - {this.props.hostname !== "" ? _("edit") : _("Set Hostname")} - ); + + + ); const systime_button = ( ); + const domain_tooltip = (this.permission.allowed === false + ? cockpit.format(_("The user $0 is not permitted to modify realms"), + this.permission.user ? this.permission.user.name : '') + : this.realmd.button_tooltip); + const domain_disabled = this.permission.allowed === false || this.realmd.button_disabled; + + const domain_button = ( + + + ); + return ( {_("Configuration")} @@ -365,7 +400,7 @@ export class ConfigurationCard extends React.Component { {_("Domain")} -

+ {domain_button} diff --git a/pkg/realmd/operation.html b/pkg/systemd/overview-cards/realmd-operation.html similarity index 100% rename from pkg/realmd/operation.html rename to pkg/systemd/overview-cards/realmd-operation.html diff --git a/pkg/realmd/operation.js b/pkg/systemd/overview-cards/realmd-operation.js similarity index 89% rename from pkg/realmd/operation.js rename to pkg/systemd/overview-cards/realmd-operation.js index a0aba8def..6f4718b85 100644 --- a/pkg/realmd/operation.js +++ b/pkg/systemd/overview-cards/realmd-operation.js @@ -4,7 +4,7 @@ import * as packagekit from "packagekit.js"; import { install_dialog } from "cockpit-components-install-dialog.jsx"; import "patterns"; -import operation_html from "raw-loader!./operation.html"; +import operation_html from "raw-loader!./realmd-operation.html"; const _ = cockpit.gettext; @@ -16,7 +16,7 @@ var KERBEROS = "org.freedesktop.realmd.Kerberos"; var KERBEROS_MEMBERSHIP = "org.freedesktop.realmd.KerberosMembership"; var REALM = "org.freedesktop.realmd.Realm"; -function instance(realmd, mode, realm, button) { +function instance(realmd, mode, realm, state) { var dialog = jQuery.parseHTML(operation_html)[0]; /* Scope the jQuery selector to our dialog */ @@ -287,10 +287,8 @@ function instance(realmd, mode, realm, button) { } } - if (operation) - button.attr('disabled', 'disabled'); - else - button.removeAttr('disabled'); + state.button_disabled = !!operation; + state.dispatchEvent("changed"); if (mode != 'join') return; @@ -564,14 +562,20 @@ function instance(realmd, mode, realm, button) { return dialog; } -function setup() { +export function setup() { var $ = jQuery; - var element = $(""); - var link = $("