Skip to content

Commit

Permalink
Merge pull request #9258 from brave/keys-export
Browse files Browse the repository at this point in the history
IPNS keys export
  • Loading branch information
spylogsster committed Jul 7, 2021
2 parents 5522bee + 7a04ec1 commit c74fae5
Show file tree
Hide file tree
Showing 9 changed files with 161 additions and 20 deletions.
9 changes: 9 additions & 0 deletions app/brave_generated_resources.grd
Original file line number Diff line number Diff line change
Expand Up @@ -823,6 +823,12 @@ By installing this extension, you are agreeing to the Google Widevine Terms of U
<message name="IDS_SETTINGS_IPFS_PEERS_LINK_TITLE" desc="The ipfs peers page link title on IPFS settings page">
Modify the peers list
</message>
<message name="IDS_SETTINGS_IPNS_KEY_EXPORT_ITEM" desc="The text for ipfs key export item">
Export key
</message>
<message name="IDS_SETTINGS_IPNS_KEY_REMOVE_ITEM" desc="The text for ipfs key remove item">
Remove key
</message>
<message name="IDS_SETTINGS_IPFS_PEERS_LINK_TITLE_DESC" desc="The ipfs peers page link description on IPFS settings page">
Set up ipfs peers description
</message>
Expand All @@ -841,6 +847,9 @@ By installing this extension, you are agreeing to the Google Widevine Terms of U
<message name="IDS_SETTINGS_IPNS_KEYS_IMPORT_ERROR" desc="The error text if ipns keys import failed">
'<ph name="KEY_NAME">$1<ex>MyCustomKey</ex></ph>' key import failed
</message>
<message name="IDS_SETTINGS_IPNS_KEYS_EXPORT_ERROR" desc="The error text if ipns keys export failed">
'<ph name="KEY_NAME">$1<ex>MyCustomKey</ex></ph>' key export failed
</message>
<message name="IDS_SETTINGS_IPNS_KEYS_IMPORT_BUTTON_TITLE" desc="The title of the button to import ipns keys">
Import
</message>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ export class BraveIPFSBrowserProxy {
getIPFSEnabled () {}
setIPFSStorageMax (value) {}
importIpnsKey () {}
exportIPNSKey (value) {}
}

/**
Expand All @@ -31,6 +32,11 @@ export class BraveIPFSBrowserProxyImpl {
importIpnsKey (value) {
chrome.send('importIpnsKey', [value])
}

exportIPNSKey (value) {
chrome.send('exportIPNSKey', [value])
}

notifyIpfsNodeStatus () {
chrome.send('notifyIpfsNodeStatus', [])
}
Expand Down
24 changes: 22 additions & 2 deletions browser/resources/settings/brave_ipfs_page/p2p_keys_subpage.html
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
margin-right: 5px;
}
#icon-button {
--cr-icon-image: url(chrome://resources/images/icon_delete_gray.svg);
display: none;
}
#icon-button-self {
--cr-icon-image: url(chrome://resources/images/icon_refresh.svg);
Expand Down Expand Up @@ -65,7 +65,7 @@
<div class="settings-row">
<div class="flex cr-padded-text">
$i18n{ipfsKeysListTitle}
<div class="secondary error-text" id="key-import-error" hidden="[[!importKeysError_]]">
<div class="secondary error-text" id="key-error" hidden="[[!importKeysError_]]">
</div>
</div>
<cr-button on-click="onAddKeyTap_" >
Expand All @@ -86,7 +86,27 @@
on-click="onKeyActionTapped_"
itemName=[[item.name]]>
</cr-icon-button>
<cr-icon-button class="icon-more-vert"
id="key-dots"
on-click="onKeyMenuTapped_"
itemName=[[item.name]]
focus-type="menu"
hidden="[[isDefaultKey_(item.name)]]">
</cr-icon-button>
</div>
<cr-lazy-render id="key-menu">
<template>
<cr-action-menu role-description="$i18n{menu}">
<button class="dropdown-item" on-click="onExportTap_">
$i18n{ipfsExportKey}
</button>
<button class="dropdown-item" id="remove"
on-click="onKeyDeleteTapped_">
$i18n{ipfsKeyRemove}
</button>
</cr-action-menu>
</template>
</cr-lazy-render>
</div>
</template>
</iron-list>
Expand Down
44 changes: 35 additions & 9 deletions browser/resources/settings/brave_ipfs_page/p2p_keys_subpage.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
* You can obtain one at http://mozilla.org/MPL/2.0/. */
import {Router} from '../router.js';
import {BraveIPFSBrowserProxyImpl} from './brave_ipfs_browser_proxy.m.js';
import {assert} from 'chrome://resources/js/assert.m.js';

(function() {
'use strict';
Expand Down Expand Up @@ -47,7 +48,7 @@ Polymer({
type: Boolean,
value: false,
},
importKeysError_: {
actionKeysError_: {
type: Boolean,
value: false,
},
Expand All @@ -72,10 +73,18 @@ Polymer({
this.addWebUIListener('brave-ipfs-keys-loaded', (success) => {
this.updateKeys()
})
this.addWebUIListener('brave-ipfs-key-exported', (key, success) => {
this.actionKeysError_ = !success
if (this.actionKeysError_ ) {
const errorLabel = (this.$$('#key-error'));
errorLabel.textContent = this.i18n('ipfsExportKeysError', key)
return;
}
})
this.addWebUIListener('brave-ipfs-key-imported', (key, value, success) => {
this.importKeysError_ = !success
if (this.importKeysError_ ) {
const errorLabel = (this.$$('#key-import-error'));
this.actionKeysError_ = !success
if (this.actionKeysError_ ) {
const errorLabel = (this.$$('#key-error'));
errorLabel.textContent = this.i18n('ipfsImporKeysError', key)
return;
}
Expand All @@ -96,7 +105,7 @@ Polymer({
toggleUILayout: function(launched) {
this.launchNodeButtonEnabled_ = !launched;
this.localNodeLaunched = launched
this.importKeysError_ = false
this.actionKeysError_ = false
if (launched) {
this.localNodeLaunchError_ = false
} else {
Expand Down Expand Up @@ -160,11 +169,16 @@ Polymer({

onKeyActionTapped_: function(event) {
let name = event.model.item.name
if (name == 'self') {
this.showRotatep2pKeyDialog_ = true
if (name != 'self')
return;
}
var message = this.i18n('ipfsDeleteKeyConfirmation', name)
this.showRotatep2pKeyDialog_ = true
return;
},

onKeyDeleteTapped_: function(event) {
this.$$('cr-action-menu').close();
let name_to_remove = event.model.item.name
var message = this.i18n('ipfsDeleteKeyConfirmation', name_to_remove)
if (!window.confirm(message))
return
this.browserProxy_.removeIpnsKey(name).then(removed_name => {
Expand All @@ -175,6 +189,18 @@ Polymer({
return;
}
});
},

onExportTap_: function(event) {
this.$$('cr-action-menu').close();
let name_to_export = event.model.item.name
this.browserProxy_.exportIPNSKey(name_to_export);
},

onKeyMenuTapped_: function(event) {
const actionMenu =
/** @type {!CrActionMenuElement} */ (this.$$('#key-menu').get());
actionMenu.showAt(assert(this.$$('#key-dots')));
}
});
})();
55 changes: 51 additions & 4 deletions browser/ui/webui/settings/brave_default_extensions_handler.cc
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include <string>

#include "base/bind.h"
#include "base/strings/utf_string_conversions.h"
#include "base/values.h"
#include "brave/browser/extensions/brave_component_loader.h"
#include "brave/common/pref_names.h"
Expand Down Expand Up @@ -96,6 +97,10 @@ void BraveDefaultExtensionsHandler::RegisterMessages() {
"launchIPFSService",
base::BindRepeating(&BraveDefaultExtensionsHandler::LaunchIPFSService,
base::Unretained(this)));
web_ui()->RegisterMessageCallback(
"exportIPNSKey",
base::BindRepeating(&BraveDefaultExtensionsHandler::ExportIPNSKey,
base::Unretained(this)));
#endif

web_ui()->RegisterMessageCallback(
Expand Down Expand Up @@ -394,6 +399,33 @@ void BraveDefaultExtensionsHandler::OnWidevineEnabledChanged() {
}
}

void BraveDefaultExtensionsHandler::ExportIPNSKey(const base::ListValue* args) {
CHECK_EQ(args->GetSize(), 1U);
CHECK(profile_);
std::string key_name;
args->GetString(0, &key_name);
DCHECK(!key_name.empty());
auto* web_contents = web_ui()->GetWebContents();
select_file_dialog_ = ui::SelectFileDialog::Create(
this, std::make_unique<ChromeSelectFilePolicy>(web_contents));
if (!select_file_dialog_) {
VLOG(1) << "Export already in progress";
return;
}
Profile* profile =
Profile::FromBrowserContext(web_contents->GetBrowserContext());
const base::FilePath directory = profile->last_selected_directory();
gfx::NativeWindow parent_window = web_contents->GetTopLevelNativeWindow();
ui::SelectFileDialog::FileTypeInfo file_types;
file_types.allowed_paths = ui::SelectFileDialog::FileTypeInfo::NATIVE_PATH;
dialog_key_ = key_name;
auto suggested_directory = directory.AppendASCII(key_name);
dialog_type_ = ui::SelectFileDialog::SELECT_SAVEAS_FILE;
select_file_dialog_->SelectFile(
ui::SelectFileDialog::SELECT_SAVEAS_FILE, base::UTF8ToUTF16(key_name),
suggested_directory, &file_types, 0, FILE_PATH_LITERAL("key"),
parent_window, nullptr);
}

void BraveDefaultExtensionsHandler::SetIPFSCompanionEnabled(
const base::ListValue* args) {
Expand Down Expand Up @@ -515,14 +547,28 @@ void BraveDefaultExtensionsHandler::FileSelected(const base::FilePath& path,
ipfs::IpfsServiceFactory::GetForContext(profile_);
if (!service)
return;
service->GetIpnsKeysManager()->ImportKey(
path, dialog_key_,
base::BindOnce(&BraveDefaultExtensionsHandler::OnKeyImported,
weak_ptr_factory_.GetWeakPtr()));
if (dialog_type_ == ui::SelectFileDialog::SELECT_OPEN_FILE) {
service->GetIpnsKeysManager()->ImportKey(
path, dialog_key_,
base::BindOnce(&BraveDefaultExtensionsHandler::OnKeyImported,
weak_ptr_factory_.GetWeakPtr()));
} else if (dialog_type_ == ui::SelectFileDialog::SELECT_SAVEAS_FILE) {
service->ExportKey(
dialog_key_, path,
base::BindOnce(&BraveDefaultExtensionsHandler::OnKeyExported,
weak_ptr_factory_.GetWeakPtr(), dialog_key_));
}
dialog_type_ = ui::SelectFileDialog::SELECT_NONE;
select_file_dialog_.reset();
dialog_key_.clear();
}

void BraveDefaultExtensionsHandler::OnKeyExported(const std::string& key,
bool success) {
FireWebUIListener("brave-ipfs-key-exported", base::Value(key),
base::Value(success));
}

void BraveDefaultExtensionsHandler::OnKeyImported(const std::string& key,
const std::string& value,
bool success) {
Expand Down Expand Up @@ -554,6 +600,7 @@ void BraveDefaultExtensionsHandler::ImportIpnsKey(const base::ListValue* args) {
ui::SelectFileDialog::FileTypeInfo file_types;
file_types.allowed_paths = ui::SelectFileDialog::FileTypeInfo::NATIVE_PATH;
dialog_key_ = key_name;
dialog_type_ = ui::SelectFileDialog::SELECT_OPEN_FILE;
select_file_dialog_->SelectFile(
ui::SelectFileDialog::SELECT_OPEN_FILE, std::u16string(), directory,
&file_types, 0, FILE_PATH_LITERAL("key"), parent_window, nullptr);
Expand Down
3 changes: 3 additions & 0 deletions browser/ui/webui/settings/brave_default_extensions_handler.h
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ class BraveDefaultExtensionsHandler : public settings::SettingsPageUIHandler
void SetIPFSStorageMax(const base::ListValue* args);
void ImportIpnsKey(const base::ListValue* args);
void LaunchIPFSService(const base::ListValue* args);
void ExportIPNSKey(const base::ListValue* args);

// ui::SelectFileDialog::Listener
void FileSelected(const base::FilePath& path,
Expand All @@ -86,6 +87,7 @@ class BraveDefaultExtensionsHandler : public settings::SettingsPageUIHandler
void OnKeyImported(const std::string& key,
const std::string& value,
bool success);
void OnKeyExported(const std::string& key, bool success);
// ipfs::IpfsServiceObserver
void OnIpfsLaunched(bool result, int64_t pid) override;
void OnIpfsShutdown() override;
Expand All @@ -94,6 +96,7 @@ class BraveDefaultExtensionsHandler : public settings::SettingsPageUIHandler
void NotifyNodeStatus();

std::string dialog_key_;
ui::SelectFileDialog::Type dialog_type_ = ui::SelectFileDialog::SELECT_NONE;
scoped_refptr<ui::SelectFileDialog> select_file_dialog_;
#endif

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -303,6 +303,9 @@ void BraveAddCommonStrings(content::WebUIDataSource* html_source,
{"ipfsRotateKeyDialogTitle", IDS_SETTINGS_IPFS_ROTATE_KEY_DIALOG_TITLE},
{"ipfsRotationLaunchError", IDS_SETTINGS_IPFS_ROTATION_LAUNCH_ERROR},
{"ipfsRotationStopError", IDS_SETTINGS_IPFS_ROTATION_STOP_ERROR},
{"ipfsExportKey", IDS_SETTINGS_IPNS_KEY_EXPORT_ITEM},
{"ipfsKeyRemove", IDS_SETTINGS_IPNS_KEY_REMOVE_ITEM},
{"ipfsExportKeysError", IDS_SETTINGS_IPNS_KEYS_EXPORT_ERROR},
};
html_source->AddLocalizedStrings(localized_strings);
html_source->AddString("webRTCLearnMoreURL", kWebRTCLearnMoreURL);
Expand Down
26 changes: 22 additions & 4 deletions components/ipfs/ipfs_service.cc
Original file line number Diff line number Diff line change
Expand Up @@ -305,13 +305,31 @@ void IpfsService::RotateKey(const std::string& oldkey, BoolCallback callback) {
cmdline.AppendArg("key");
cmdline.AppendArg("rotate");
cmdline.AppendArg("--oldkey=" + oldkey);
ExecuteNodeCommand(cmdline, GetDataPath(), std::move(callback));
}

base::LaunchOptions options;
void IpfsService::ExportKey(const std::string& key,
const base::FilePath& target_path,
BoolCallback callback) {
base::FilePath path = GetIpfsExecutablePath();
if (path.empty())
return;

base::CommandLine cmdline(path);
cmdline.AppendArg("key");
cmdline.AppendArg("export");
cmdline.AppendArg("-o=" + target_path.MaybeAsASCII());
cmdline.AppendArg(key);
ExecuteNodeCommand(cmdline, GetDataPath(), std::move(callback));
}
void IpfsService::ExecuteNodeCommand(const base::CommandLine& command_line,
const base::FilePath& data,
BoolCallback callback) {
base::LaunchOptions options;
#if defined(OS_WIN)
options.environment[L"IPFS_PATH"] = GetDataPath().value();
options.environment[L"IPFS_PATH"] = data.value();
#else
options.environment["IPFS_PATH"] = GetDataPath().value();
options.environment["IPFS_PATH"] = data.value();
#endif

#if defined(OS_LINUX)
Expand All @@ -320,7 +338,7 @@ void IpfsService::RotateKey(const std::string& oldkey, BoolCallback callback) {
#if defined(OS_WIN)
options.start_hidden = true;
#endif
base::Process process = base::LaunchProcess(cmdline, options);
base::Process process = base::LaunchProcess(command_line, options);
if (!process.IsValid()) {
if (callback)
std::move(callback).Run(false);
Expand Down
11 changes: 10 additions & 1 deletion components/ipfs/ipfs_service.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
#include "url/gurl.h"

namespace base {
class CommandLine;
class Process;
class SequencedTaskRunner;
} // namespace base
Expand Down Expand Up @@ -118,6 +119,9 @@ class IpfsService : public KeyedService,
void OnImportFinished(ipfs::ImportCompletedCallback callback,
size_t key,
const ipfs::ImportedData& data);
void ExportKey(const std::string& key,
const base::FilePath& target_path,
BoolCallback callback);
#endif
void GetConnectedPeers(GetConnectedPeersCallback callback,
int retries = kPeersDefaultRetries);
Expand All @@ -143,7 +147,6 @@ class IpfsService : public KeyedService,
prewarm_callback_for_testing_ = std::move(callback);
}
#if BUILDFLAG(IPFS_LOCAL_NODE_ENABLED)
static bool WaitUntilExecutionFinished(base::Process process);
IpnsKeysManager* GetIpnsKeysManager() { return ipns_keys_manager_.get(); }
#endif
protected:
Expand All @@ -166,6 +169,12 @@ class IpfsService : public KeyedService,
void NotifyIpnsKeysLoaded(bool result);
// Launches the ipfs service in an utility process.
void LaunchIfNotRunning(const base::FilePath& executable_path);
#if BUILDFLAG(IPFS_LOCAL_NODE_ENABLED)
static bool WaitUntilExecutionFinished(base::Process process);
void ExecuteNodeCommand(const base::CommandLine& command_line,
const base::FilePath& data,
BoolCallback callback);
#endif
base::TimeDelta CalculatePeersRetryTime();

void OnGetConnectedPeers(SimpleURLLoaderList::iterator iter,
Expand Down

0 comments on commit c74fae5

Please sign in to comment.