/* * This file is part of Cockpit. * * Copyright (C) 2020 Red Hat, Inc. * * Cockpit 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. * * Cockpit 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 Cockpit; If not, see <http://www.gnu.org/licenses/>. */ import cockpit from "cockpit"; import React, { useState } from "react"; import "./certificateActions.css"; import { Button, Checkbox, Dropdown, DropdownItem, Form, FormGroup, KebabToggle, Modal, } from "@patternfly/react-core"; import { ResubmitCertificateModal } from './requestCertificate.jsx'; import { removeRequest } from "./dbus.js"; const _ = cockpit.gettext; export const RemoveModal = ({ onClose, certs, cert, certPath, addAlert, appOnValueChanged, idPrefix }) => { const [deleteFiles, setDeleteFiles] = useState(false); const onRemoveResponse = () => { delete certs[certPath]; appOnValueChanged("certs, certs"); onClose(); }; const onRemove = () => { if (deleteFiles) { cockpit.file(cert["key-file"].v, { superuser: "try" }).replace(null) // delete key file .then(() => cockpit.file(cert["cert-file"].v, { superuser: "try" }).replace(null)) // delete cert file .then(() => removeRequest(certPath)) // There is no dbus signal for cert removal, so we have to update UI manually .then(() => onRemoveResponse()) .catch(error => { addAlert(_("Error: ") + (error.name || error.problem), error.message); onClose(); }); } else { removeRequest(certPath) // There is no dbus signal for cert removal, so we have to update UI manually .then(() => onRemoveResponse()) .catch(error => { addAlert(_("Error: ") + error.name, error.message); onClose(); }); } }; const title = _("Remove certificate: ") + (cert["cert-storage"].v === "FILE" ? cert.nickname.v : cert["cert-nickname"].v); const fileCertBody = ( <Form isHorizontal> <FormGroup label={_("Certificate file")} hasNoPaddingTop> <samp id={idPrefix + "cert-file"}> {cert["cert-file"].v} </samp> </FormGroup> <FormGroup label={_("Key file")}> <samp id={idPrefix + "key-file"} hasNoPaddingTop> {cert["key-file"].v} </samp> </FormGroup> </Form> ); const nssdbCertBody = ( <Form isHorizontal> <FormGroup label={_("NSSDB path")} hasNoPaddingTop> <samp id={idPrefix + "cert-database"}> {cert["cert-database"].v} </samp> </FormGroup> <FormGroup label={_("Nickname")} hasNoPaddingTop> <samp id={idPrefix + "cert-nickname"}> {cert["cert-nickname"].v} </samp> </FormGroup> </Form> ); const body = (<> { cert["cert-storage"].v === "FILE" ? fileCertBody : nssdbCertBody } { cert["key-file"] && cert["cert-file"] && cert["key-file"].v && cert["cert-file"].v && ( <Checkbox id={idPrefix + "-delete-files"} className="checkbox-delete-files" isChecked={deleteFiles} label={_("Also delete certificate and key files")} onChange={e => setDeleteFiles(!deleteFiles)} /> )} </>); return ( <Modal id={idPrefix + "-remove-dialog"} position="top" variant="medium" onClose={onClose} isOpen title={title} footer={<> <Button variant="danger" onClick={onRemove}> { deleteFiles ? _("Remove and delete") : _("Remove") } </Button> <Button variant="link" className="btn-cancel" onClick={onClose}> {_("Cancel")} </Button> </>}> {body} </Modal> ); }; export const CertificateActions = ({ cas, certs, cert, certPath, addAlert, appOnValueChanged, idPrefix }) => { const [dropdownOpen, setDropdownOpen] = useState(false); const [showRemoveModal, setShowRemoveModal] = useState(false); const [showResubmitModal, setShowResubmitModal] = useState(false); const dropdownItems = [ <DropdownItem key={`${idPrefix}-resubmit`} id={`${idPrefix}-resubmit`} onClick={() => setShowResubmitModal(true)}> {_("Resubmit")} </DropdownItem>, <DropdownItem className="pf-m-danger" key={`${idPrefix}-remove`} id={`${idPrefix}-remove`} onClick={() => setShowRemoveModal(true)}> {_("Remove")} </DropdownItem>, ]; return ( <> <Dropdown onSelect={() => setDropdownOpen(!dropdownOpen)} id={`${idPrefix}-action-kebab`} toggle={ <KebabToggle key={`${idPrefix}-action-kebab-toggle`} onToggle={() => setDropdownOpen(!dropdownOpen)} /> } isOpen={dropdownOpen} position="right" dropdownItems={dropdownItems} isPlain /> {showRemoveModal && <RemoveModal onClose={() => setShowRemoveModal(false)} certs={certs} cert={cert} certPath={certPath} addAlert={addAlert} appOnValueChanged={appOnValueChanged} idPrefix={idPrefix} />} {showResubmitModal && <ResubmitCertificateModal onClose={() => setShowResubmitModal(false)} cas={cas} addAlert={addAlert} cert={cert} certPath={certPath} />} </> ); };