mirror of https://github.com/micromata/borgbackup-butler.git

Kai Reinhard
31.53.2019 c5744a6785201a7859e701e7925f23013ff61aff
Repo config...
2 files modified
120 ■■■■ changed files
borgbutler-server/src/main/java/de/micromata/borgbutler/server/rest/FilesystemBrowserRest.java 41 ●●●●● patch | view | raw | blame | history
borgbutler-webapp/src/components/views/repos/ConfigureRepoPage.jsx 79 ●●●● patch | view | raw | blame | history
borgbutler-server/src/main/java/de/micromata/borgbutler/server/rest/FilesystemBrowserRest.java
@@ -35,13 +35,11 @@
            log.info(msg);
            return msg;
        }
        JFileChooser chooser;
        if (StringUtils.isNotBlank(current)) {
            chooser = new JFileChooser(current);
        } else {
            chooser = new JFileChooser();
        if (chooser != null) {
            log.warn("Cannot call already opened file choose twice. Close file chooser first.");
            return "{\"directory\": \"\"}";
        }
        chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
        File file = null;
        synchronized (FilesystemBrowserRest.class) {
            if (frame == null) {
                frame = new JFrame("BorgButler");
@@ -50,18 +48,28 @@
                frame.getContentPane().add(label);
                frame.pack();
            }
        }
        frame.setVisible(true);
        frame.setAlwaysOnTop(true);
        int returnCode = chooser.showDialog(frame, "Choose");
        frame.setVisible(false);
        frame.setAlwaysOnTop(false);
        File file = null;
        if (returnCode == JFileChooser.APPROVE_OPTION) {
            file = chooser.getSelectedFile();
            try {
                if (StringUtils.isNotBlank(current)) {
                    chooser = new JFileChooser(current);
                } else {
                    chooser = new JFileChooser();
                }
                chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
                frame.setVisible(true);
                frame.setAlwaysOnTop(true);
                int returnCode = chooser.showDialog(frame, "Choose");
                frame.setVisible(false);
                frame.setAlwaysOnTop(false);
                if (returnCode == JFileChooser.APPROVE_OPTION) {
                    file = chooser.getSelectedFile();
                }
            } finally {
                chooser = null;
            }
        }
        String filename = file != null ? JsonUtils.toJson(file.getAbsolutePath()) : "";
        String result = "{\"directory\":" + filename + "}";
        String result = "{\"directory\":\"" + filename + "\"}";
        return result;
    }
@@ -81,4 +89,5 @@
    }
    private static JFrame frame;
    private static JFileChooser chooser;
}
borgbutler-webapp/src/components/views/repos/ConfigureRepoPage.jsx
@@ -1,5 +1,6 @@
import React from 'react';
import {Link} from 'react-router-dom'
import {Alert} from 'reactstrap';
import {
    FormButton,
    FormField,
@@ -12,6 +13,7 @@
    FormSelect
} from '../../general/forms/FormComponents';
import I18n from "../../general/translation/I18n";
import {getRestServiceUrl} from "../../../utilities/global";
import {PageHeader} from "../../general/BootstrapComponents";
class ConfigureRepoPage extends React.Component {
@@ -22,10 +24,11 @@
        this.handleRepoTextChange = this.handleRepoTextChange.bind(this);
        this.handleCheckboxChange = this.handleCheckboxChange.bind(this);
        this.state = {
            repoConfig: {},
            repoConfig: {
                encryption: 'repoKey'
            },
            mode: 'existingRepo',
            localRemote: 'local',
            encryption: 'repokey',
            passwordMethod: 'passwordCommand',
            passwordCreate: null
        };
@@ -101,6 +104,28 @@
        }*/
    }
    browseDirectory = () => {
        const current = "&current=" + encodeURIComponent(this.state.repoConfig.repo);
        fetch(getRestServiceUrl("files/browse-local-filesystem?type=dir" + current), {
            method: "GET",
            dataType: "JSON",
            headers: {
                "Content-Type": "text/plain; charset=utf-8",
            }
        })
            .then((resp) => {
                return resp.json()
            })
            .then((data) => {
                if (data.directory) {
                    this.setState({repoConfig: {...this.state.repoConfig, repo: data.directory}});
                }
            })
            .catch((error) => {
                console.log(error, "Oups, what's happened?")
            })
    }
    render() {
        const repoConfig = this.state.repoConfig;
        var passwordMethods = [['password-command', 'Password command'],
@@ -108,7 +133,8 @@
            ['macos-keychain', 'Mac OS X keychain'],
            ['gnome-keyring', 'GNOME keyring'],
            ['kwallet', 'KWallet'],
            ['passphrase', 'Passphrase (not recommended)']
            ['passphrase', 'Passphrase (not recommended)'],
            ['none', 'No password (no encryption, not recommended)']
        ];
        let repoPlaceHolder = 'Enter the repo used by Borg.';
        if (this.state.mode === 'initNewRepo' && this.state.localRemote === 'remote') {
@@ -118,10 +144,15 @@
        let browseButton = null;
        if (this.state.localRemote === 'local') {
            repoFieldLength = 9;
            browseButton = <FormButton onClick={null}
                                       hint={'Browse local backup directory.'}>Browse</FormButton>
            browseButton = <FormButton onClick={this.browseDirectory}
                                       hint={'Browse local backup directory.'}><I18n name={'common.browse'}/>
            </FormButton>;
            repoPlaceHolder = 'Enter or browse the local path of the repo home dir used by Borg.';
        }
        let encrypted = true;
        if (this.state.repoConfig.encryption === 'none' || this.state.passwordMethod === 'none') {
            encrypted = false;
        }
        return <React.Fragment>
            <PageHeader>
                Configure repository
@@ -179,7 +210,7 @@
                                     className={this.state.localRemote === 'local' ? 'hidden' : null}/>
                <FormGroup className={this.state.mode === 'existingRepo' ? 'hidden' : null}>
                    <FormLabel length={2}>{'Encryption'}</FormLabel>
                    <FormField length={2}>
                    <FormField length={4}>
                        <FormSelect
                            value={repoConfig.encryption}
                            name={'encryption'}
@@ -193,9 +224,11 @@
                        </FormSelect>
                    </FormField>
                </FormGroup>
                <FormGroup>
                <FormGroup
                    className={this.state.repoConfig.encryption === 'none' ? 'hidden' : null}
                >
                    <FormLabel length={2}>{'Password method'}</FormLabel>
                    <FormField length={3}>
                    <FormField length={4}>
                        <FormSelect
                            value={this.state.passwordMethod}
                            name={'passwordMethod'}
@@ -217,14 +250,37 @@
                                     name={'passwordCommand'} value={repoConfig.passwordCommand}
                                     onChange={this.handleRepoTextChange}
                                     placeholder="Enter the password command to get the command from or choose a method above."
                                     className={this.state.passwordMethod === 'passphrase' ? 'hidden' : null}
                                     className={!encrypted || this.state.passwordMethod === 'passphrase' ? 'hidden' : null}
                />
                <FormLabelInputField label={'Password'} fieldLength={6} type={'password'}
                                     name={'passphrase'} value={repoConfig.passphrase}
                                     onChange={this.handleRepoTextChange}
                                     hint={"It's recommended to use password command instead."}
                                     className={this.state.passwordMethod !== 'passphrase' ? 'hidden' : null}
                                     className={(!encrypted || this.state.passwordMethod !== 'passphrase') ? 'hidden' : null}
                />
                <FormGroup className={!encrypted ? 'hidden' : null}>
                    <FormField length={2}>
                    </FormField>
                    <FormField length={10}>
                        <Alert
                            color={'warning'}
                        >
                            Please keep a copy of your password safe! If your password get lost, your backup might be
                            lost!
                        </Alert>
                    </FormField>
                </FormGroup>
                <FormGroup className={encrypted ? 'hidden' : null}>
                    <FormField length={2}>
                    </FormField>
                    <FormField length={10}>
                        <Alert
                            color={'danger'}
                        >
                            You backup isn't encrpyted! You should ensure, that your destination storage is encrypted and protected.
                        </Alert>
                    </FormField>
                </FormGroup>
                <FormField length={12}>
                    <Link to={'/repos'} className={'btn btn-outline-primary'}><I18n name={'common.cancel'}/>
                    </Link>
@@ -238,9 +294,6 @@
                <ul>
                    <li>Implement 'Save' button ;-)</li>
                    <li>Add own environment variables.</li>
                    <li>Implement browse button for local repos.</li>
                    <li>Note (for new backups): Save your password, otherwise your backup will be lost without!</li>
                    <li>Note (hide password fields): Your backup will not be encrypted!</li>
                    <li>Remove and clone repo.</li>
                </ul>
            </code>