added importController

This commit is contained in:
vladimir.kuznetsov 2023-05-22 22:11:20 +08:00
parent 0479113949
commit ca6b7fbeb2
6 changed files with 258 additions and 1 deletions

View file

@ -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();

View file

@ -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;
}; };

View 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);
}

View 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

View file

@ -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

View file

@ -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,