added importController
This commit is contained in:
parent
0479113949
commit
ca6b7fbeb2
6 changed files with 258 additions and 1 deletions
|
@ -124,6 +124,9 @@ void AmneziaApplication::init()
|
||||||
m_installController.reset(new InstallController(m_serversModel, m_containersModel, m_settings));
|
m_installController.reset(new InstallController(m_serversModel, m_containersModel, m_settings));
|
||||||
m_engine->rootContext()->setContextProperty("InstallController", m_installController.get());
|
m_engine->rootContext()->setContextProperty("InstallController", m_installController.get());
|
||||||
|
|
||||||
|
m_importController.reset(new ImportController(m_serversModel, m_containersModel, m_settings));
|
||||||
|
m_engine->rootContext()->setContextProperty("ImportController", m_importController.get());
|
||||||
|
|
||||||
//
|
//
|
||||||
m_uiLogic->registerPagesLogic();
|
m_uiLogic->registerPagesLogic();
|
||||||
|
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
#include "ui/controllers/connectionController.h"
|
#include "ui/controllers/connectionController.h"
|
||||||
#include "ui/controllers/pageController.h"
|
#include "ui/controllers/pageController.h"
|
||||||
#include "ui/controllers/installController.h"
|
#include "ui/controllers/installController.h"
|
||||||
|
#include "ui/controllers/importController.h"
|
||||||
|
|
||||||
#define amnApp (static_cast<AmneziaApplication *>(QCoreApplication::instance()))
|
#define amnApp (static_cast<AmneziaApplication *>(QCoreApplication::instance()))
|
||||||
|
|
||||||
|
@ -71,6 +72,7 @@ private:
|
||||||
QScopedPointer<ConnectionController> m_connectionController;
|
QScopedPointer<ConnectionController> m_connectionController;
|
||||||
QScopedPointer<PageController> m_pageController;
|
QScopedPointer<PageController> m_pageController;
|
||||||
QScopedPointer<InstallController> m_installController;
|
QScopedPointer<InstallController> m_installController;
|
||||||
|
QScopedPointer<ImportController> m_importController;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
204
client/ui/controllers/importController.cpp
Normal file
204
client/ui/controllers/importController.cpp
Normal file
|
@ -0,0 +1,204 @@
|
||||||
|
#include "importController.h"
|
||||||
|
|
||||||
|
#include <QFile>
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
enum class ConfigTypes {
|
||||||
|
Amnezia,
|
||||||
|
OpenVpn,
|
||||||
|
WireGuard
|
||||||
|
};
|
||||||
|
|
||||||
|
ConfigTypes checkConfigFormat(const QString &config)
|
||||||
|
{
|
||||||
|
const QString openVpnConfigPatternCli = "client";
|
||||||
|
const QString openVpnConfigPatternProto1 = "proto tcp";
|
||||||
|
const QString openVpnConfigPatternProto2 = "proto udp";
|
||||||
|
const QString openVpnConfigPatternDriver1 = "dev tun";
|
||||||
|
const QString openVpnConfigPatternDriver2 = "dev tap";
|
||||||
|
|
||||||
|
const QString wireguardConfigPatternSectionInterface = "[Interface]";
|
||||||
|
const QString wireguardConfigPatternSectionPeer = "[Peer]";
|
||||||
|
|
||||||
|
if (config.contains(openVpnConfigPatternCli) &&
|
||||||
|
(config.contains(openVpnConfigPatternProto1) || config.contains(openVpnConfigPatternProto2)) &&
|
||||||
|
(config.contains(openVpnConfigPatternDriver1) || config.contains(openVpnConfigPatternDriver2))) {
|
||||||
|
return ConfigTypes::OpenVpn;
|
||||||
|
} else if (config.contains(wireguardConfigPatternSectionInterface) && config.contains(wireguardConfigPatternSectionPeer)) {
|
||||||
|
return ConfigTypes::WireGuard;
|
||||||
|
}
|
||||||
|
return ConfigTypes::Amnezia;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ImportController::ImportController(const QSharedPointer<ServersModel> &serversModel,
|
||||||
|
const QSharedPointer<ContainersModel> &containersModel,
|
||||||
|
const std::shared_ptr<Settings> &settings,
|
||||||
|
QObject *parent) : QObject(parent), m_serversModel(serversModel), m_containersModel(containersModel), m_settings(settings)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ImportController::importFromFile(const QUrl &fileUrl)
|
||||||
|
{
|
||||||
|
QFile file(fileUrl.toLocalFile());
|
||||||
|
if (file.open(QIODevice::ReadOnly)) {
|
||||||
|
QByteArray data = file.readAll();
|
||||||
|
|
||||||
|
auto configFormat = checkConfigFormat(data);
|
||||||
|
if (configFormat == ConfigTypes::OpenVpn) {
|
||||||
|
return importOpenVpnConfig(data);
|
||||||
|
} else if (configFormat == ConfigTypes::WireGuard) {
|
||||||
|
return importWireGuardConfig(data);
|
||||||
|
} else {
|
||||||
|
return importAmneziaConfig(data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ImportController::import(const QJsonObject &config)
|
||||||
|
{
|
||||||
|
ServerCredentials credentials;
|
||||||
|
credentials.hostName = config.value(config_key::hostName).toString();
|
||||||
|
credentials.port = config.value(config_key::port).toInt();
|
||||||
|
credentials.userName = config.value(config_key::userName).toString();
|
||||||
|
credentials.secretData = config.value(config_key::password).toString();
|
||||||
|
|
||||||
|
if (credentials.isValid() || config.contains(config_key::containers)) {
|
||||||
|
m_settings->addServer(config);
|
||||||
|
|
||||||
|
if (config.value(config_key::containers).toArray().isEmpty()) {
|
||||||
|
m_settings->setDefaultServer(m_settings->serversCount() - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
emit importFinished();
|
||||||
|
} else {
|
||||||
|
qDebug() << "Failed to import profile";
|
||||||
|
qDebug().noquote() << QJsonDocument(config).toJson();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ImportController::importAmneziaConfig(QString data)
|
||||||
|
{
|
||||||
|
data.replace("vpn://", "");
|
||||||
|
QByteArray ba = QByteArray::fromBase64(data.toUtf8(), QByteArray::Base64UrlEncoding | QByteArray::OmitTrailingEquals);
|
||||||
|
|
||||||
|
QByteArray ba_uncompressed = qUncompress(ba);
|
||||||
|
if (!ba_uncompressed.isEmpty()) {
|
||||||
|
ba = ba_uncompressed;
|
||||||
|
}
|
||||||
|
|
||||||
|
QJsonObject config;
|
||||||
|
config = QJsonDocument::fromJson(ba).object();
|
||||||
|
if (!config.isEmpty()) {
|
||||||
|
return import(config);
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
//bool ImportController::importConnectionFromQr(const QByteArray &data)
|
||||||
|
//{
|
||||||
|
// QJsonObject dataObj = QJsonDocument::fromJson(data).object();
|
||||||
|
// if (!dataObj.isEmpty()) {
|
||||||
|
// return importConnection(dataObj);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// QByteArray ba_uncompressed = qUncompress(data);
|
||||||
|
// if (!ba_uncompressed.isEmpty()) {
|
||||||
|
// return importConnection(QJsonDocument::fromJson(ba_uncompressed).object());
|
||||||
|
// }
|
||||||
|
|
||||||
|
// return false;
|
||||||
|
//}
|
||||||
|
|
||||||
|
bool ImportController::importOpenVpnConfig(const QString &data)
|
||||||
|
{
|
||||||
|
QJsonObject openVpnConfig;
|
||||||
|
openVpnConfig[config_key::config] = data;
|
||||||
|
|
||||||
|
QJsonObject lastConfig;
|
||||||
|
lastConfig[config_key::last_config] = QString(QJsonDocument(openVpnConfig).toJson());
|
||||||
|
lastConfig[config_key::isThirdPartyConfig] = true;
|
||||||
|
|
||||||
|
QJsonObject containers;
|
||||||
|
containers.insert(config_key::container, QJsonValue("amnezia-openvpn"));
|
||||||
|
containers.insert(config_key::openvpn, QJsonValue(lastConfig));
|
||||||
|
|
||||||
|
QJsonArray arr;
|
||||||
|
arr.push_back(containers);
|
||||||
|
|
||||||
|
QString hostName;
|
||||||
|
const static QRegularExpression hostNameRegExp("remote (.*) [0-9]*");
|
||||||
|
QRegularExpressionMatch hostNameMatch = hostNameRegExp.match(data);
|
||||||
|
if (hostNameMatch.hasMatch()) {
|
||||||
|
hostName = hostNameMatch.captured(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
QJsonObject config;
|
||||||
|
config[config_key::containers] = arr;
|
||||||
|
config[config_key::defaultContainer] = "amnezia-openvpn";
|
||||||
|
config[config_key::description] = m_settings->nextAvailableServerName();
|
||||||
|
|
||||||
|
|
||||||
|
const static QRegularExpression dnsRegExp("dhcp-option DNS (\\b\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\b)");
|
||||||
|
QRegularExpressionMatchIterator dnsMatch = dnsRegExp.globalMatch(data);
|
||||||
|
if (dnsMatch.hasNext()) {
|
||||||
|
config[config_key::dns1] = dnsMatch.next().captured(1);
|
||||||
|
}
|
||||||
|
if (dnsMatch.hasNext()) {
|
||||||
|
config[config_key::dns2] = dnsMatch.next().captured(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
config[config_key::hostName] = hostName;
|
||||||
|
|
||||||
|
return import(config);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ImportController::importWireGuardConfig(const QString &data)
|
||||||
|
{
|
||||||
|
QJsonObject lastConfig;
|
||||||
|
lastConfig[config_key::config] = data;
|
||||||
|
|
||||||
|
const static QRegularExpression hostNameAndPortRegExp("Endpoint = (.*):([0-9]*)");
|
||||||
|
QRegularExpressionMatch hostNameAndPortMatch = hostNameAndPortRegExp.match(data);
|
||||||
|
QString hostName;
|
||||||
|
QString port;
|
||||||
|
if (hostNameAndPortMatch.hasMatch()) {
|
||||||
|
hostName = hostNameAndPortMatch.captured(1);
|
||||||
|
port = hostNameAndPortMatch.captured(2);
|
||||||
|
}
|
||||||
|
|
||||||
|
QJsonObject wireguardConfig;
|
||||||
|
wireguardConfig[config_key::last_config] = QString(QJsonDocument(lastConfig).toJson());
|
||||||
|
wireguardConfig[config_key::isThirdPartyConfig] = true;
|
||||||
|
wireguardConfig[config_key::port] = port;
|
||||||
|
wireguardConfig[config_key::transport_proto] = "udp";
|
||||||
|
|
||||||
|
QJsonObject containers;
|
||||||
|
containers.insert(config_key::container, QJsonValue("amnezia-wireguard"));
|
||||||
|
containers.insert(config_key::wireguard, QJsonValue(wireguardConfig));
|
||||||
|
|
||||||
|
QJsonArray arr;
|
||||||
|
arr.push_back(containers);
|
||||||
|
|
||||||
|
QJsonObject config;
|
||||||
|
config[config_key::containers] = arr;
|
||||||
|
config[config_key::defaultContainer] = "amnezia-wireguard";
|
||||||
|
config[config_key::description] = m_settings->nextAvailableServerName();
|
||||||
|
|
||||||
|
const static QRegularExpression dnsRegExp("DNS = (\\b\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\b).*(\\b\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\b)");
|
||||||
|
QRegularExpressionMatch dnsMatch = dnsRegExp.match(data);
|
||||||
|
if (dnsMatch.hasMatch()) {
|
||||||
|
config[config_key::dns1] = dnsMatch.captured(1);
|
||||||
|
config[config_key::dns2] = dnsMatch.captured(2);
|
||||||
|
}
|
||||||
|
|
||||||
|
config[config_key::hostName] = hostName;
|
||||||
|
|
||||||
|
return import(config);
|
||||||
|
}
|
37
client/ui/controllers/importController.h
Normal file
37
client/ui/controllers/importController.h
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
#ifndef IMPORTCONTROLLER_H
|
||||||
|
#define IMPORTCONTROLLER_H
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
|
||||||
|
#include "core/defs.h"
|
||||||
|
#include "containers/containers_defs.h"
|
||||||
|
#include "ui/models/servers_model.h"
|
||||||
|
#include "ui/models/containers_model.h"
|
||||||
|
|
||||||
|
class ImportController : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
explicit ImportController(const QSharedPointer<ServersModel> &serversModel,
|
||||||
|
const QSharedPointer<ContainersModel> &containersModel,
|
||||||
|
const std::shared_ptr<Settings> &settings,
|
||||||
|
QObject *parent = nullptr);
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
bool importFromFile(const QUrl &fileUrl);
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void importFinished();
|
||||||
|
private:
|
||||||
|
bool import(const QJsonObject &config);
|
||||||
|
bool importAmneziaConfig(QString data);
|
||||||
|
bool importOpenVpnConfig(const QString &data);
|
||||||
|
bool importWireGuardConfig(const QString &data);
|
||||||
|
|
||||||
|
QSharedPointer<ServersModel> m_serversModel;
|
||||||
|
QSharedPointer<ContainersModel> m_containersModel;
|
||||||
|
std::shared_ptr<Settings> m_settings;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // IMPORTCONTROLLER_H
|
|
@ -13,6 +13,14 @@ import "../Config"
|
||||||
Item {
|
Item {
|
||||||
id: root
|
id: root
|
||||||
|
|
||||||
|
Connections {
|
||||||
|
target: ImportController
|
||||||
|
|
||||||
|
function onImportFinished() {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
FlickableType {
|
FlickableType {
|
||||||
id: fl
|
id: fl
|
||||||
anchors.top: root.top
|
anchors.top: root.top
|
||||||
|
@ -63,7 +71,7 @@ Item {
|
||||||
FileDialog {
|
FileDialog {
|
||||||
id: fileDialog
|
id: fileDialog
|
||||||
onAccepted: {
|
onAccepted: {
|
||||||
|
ImportController.importFromFile(selectedFile)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -84,6 +92,7 @@ Item {
|
||||||
onClickedFunc: function() {
|
onClickedFunc: function() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
height: 1
|
height: 1
|
||||||
|
@ -101,6 +110,7 @@ Item {
|
||||||
PageController.goToPage(PageEnum.PageSetupWizardTextKey)
|
PageController.goToPage(PageEnum.PageSetupWizardTextKey)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
height: 1
|
height: 1
|
||||||
|
|
|
@ -124,6 +124,7 @@ Item {
|
||||||
text: qsTr("Continue")
|
text: qsTr("Continue")
|
||||||
|
|
||||||
onClicked: function() {
|
onClicked: function() {
|
||||||
|
ContainersModel.setCurrentlyInstalledContainerIndex(containers.dockerContainer)
|
||||||
PageController.goToPage(PageEnum.PageSetupWizardInstalling);
|
PageController.goToPage(PageEnum.PageSetupWizardInstalling);
|
||||||
InstallController.install(containers.dockerContainer,
|
InstallController.install(containers.dockerContainer,
|
||||||
containers.containerDefaultPort,
|
containers.containerDefaultPort,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue