refactoring: simplified the validity check of the config before connection
- improved project structure
This commit is contained in:
parent
db3164223a
commit
e9250afd2b
31 changed files with 941 additions and 969 deletions
|
@ -57,10 +57,7 @@ if(WIN32 OR (APPLE AND NOT IOS) OR (LINUX AND NOT ANDROID))
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
qt_standard_project_setup()
|
qt_standard_project_setup()
|
||||||
qt_add_executable(${PROJECT} MANUAL_FINALIZATION
|
qt_add_executable(${PROJECT} MANUAL_FINALIZATION)
|
||||||
core/api/apiDefs.h
|
|
||||||
core/qrCodeUtils.h core/qrCodeUtils.cpp
|
|
||||||
)
|
|
||||||
|
|
||||||
if(WIN32 OR (APPLE AND NOT IOS) OR (LINUX AND NOT ANDROID))
|
if(WIN32 OR (APPLE AND NOT IOS) OR (LINUX AND NOT ANDROID))
|
||||||
qt_add_repc_replicas(${PROJECT} ${CMAKE_CURRENT_LIST_DIR}/../ipc/ipc_interface.rep)
|
qt_add_repc_replicas(${PROJECT} ${CMAKE_CURRENT_LIST_DIR}/../ipc/ipc_interface.rep)
|
||||||
|
|
|
@ -14,22 +14,14 @@
|
||||||
#include <QTranslator>
|
#include <QTranslator>
|
||||||
|
|
||||||
#include "logger.h"
|
#include "logger.h"
|
||||||
|
#include "ui/controllers/pageController.h"
|
||||||
#include "ui/models/installedAppsModel.h"
|
#include "ui/models/installedAppsModel.h"
|
||||||
#include "version.h"
|
#include "version.h"
|
||||||
|
|
||||||
#include "platforms/ios/QRCodeReaderBase.h"
|
#include "platforms/ios/QRCodeReaderBase.h"
|
||||||
#if defined(Q_OS_ANDROID)
|
|
||||||
#include "core/installedAppsImageProvider.h"
|
|
||||||
#include "platforms/android/android_controller.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "protocols/qml_register_protocols.h"
|
#include "protocols/qml_register_protocols.h"
|
||||||
|
|
||||||
#if defined(Q_OS_IOS)
|
|
||||||
#include "platforms/ios/ios_controller.h"
|
|
||||||
#include <AmneziaVPN-Swift.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
AmneziaApplication::AmneziaApplication(int &argc, char *argv[]) : AMNEZIA_BASE_CLASS(argc, argv)
|
AmneziaApplication::AmneziaApplication(int &argc, char *argv[]) : AMNEZIA_BASE_CLASS(argc, argv)
|
||||||
{
|
{
|
||||||
setQuitOnLastWindowClosed(false);
|
setQuitOnLastWindowClosed(false);
|
||||||
|
@ -84,79 +76,12 @@ void AmneziaApplication::init()
|
||||||
m_vpnConnection->moveToThread(&m_vpnConnectionThread);
|
m_vpnConnection->moveToThread(&m_vpnConnectionThread);
|
||||||
m_vpnConnectionThread.start();
|
m_vpnConnectionThread.start();
|
||||||
|
|
||||||
initModels();
|
m_coreController.reset(new CoreController(m_vpnConnection, m_settings, m_engine));
|
||||||
loadTranslator();
|
|
||||||
initControllers();
|
|
||||||
|
|
||||||
#ifdef Q_OS_ANDROID
|
|
||||||
if (!AndroidController::initLogging()) {
|
|
||||||
qFatal("Android logging initialization failed");
|
|
||||||
}
|
|
||||||
AndroidController::instance()->setSaveLogs(m_settings->isSaveLogs());
|
|
||||||
connect(m_settings.get(), &Settings::saveLogsChanged, AndroidController::instance(), &AndroidController::setSaveLogs);
|
|
||||||
|
|
||||||
AndroidController::instance()->setScreenshotsEnabled(m_settings->isScreenshotsEnabled());
|
|
||||||
connect(m_settings.get(), &Settings::screenshotsEnabledChanged, AndroidController::instance(), &AndroidController::setScreenshotsEnabled);
|
|
||||||
|
|
||||||
connect(m_settings.get(), &Settings::serverRemoved, AndroidController::instance(), &AndroidController::resetLastServer);
|
|
||||||
|
|
||||||
connect(m_settings.get(), &Settings::settingsCleared, []() { AndroidController::instance()->resetLastServer(-1); });
|
|
||||||
|
|
||||||
connect(AndroidController::instance(), &AndroidController::initConnectionState, this, [this](Vpn::ConnectionState state) {
|
|
||||||
m_connectionController->onConnectionStateChanged(state);
|
|
||||||
if (m_vpnConnection)
|
|
||||||
m_vpnConnection->restoreConnection();
|
|
||||||
});
|
|
||||||
if (!AndroidController::instance()->initialize()) {
|
|
||||||
qFatal("Android controller initialization failed");
|
|
||||||
}
|
|
||||||
|
|
||||||
connect(AndroidController::instance(), &AndroidController::importConfigFromOutside, this, [this](QString data) {
|
|
||||||
emit m_pageController->goToPageHome();
|
|
||||||
m_importController->extractConfigFromData(data);
|
|
||||||
data.clear();
|
|
||||||
emit m_pageController->goToPageViewConfig();
|
|
||||||
});
|
|
||||||
|
|
||||||
m_engine->addImageProvider(QLatin1String("installedAppImage"), new InstalledAppsImageProvider);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef Q_OS_IOS
|
|
||||||
IosController::Instance()->initialize();
|
|
||||||
connect(IosController::Instance(), &IosController::importConfigFromOutside, this, [this](QString data) {
|
|
||||||
emit m_pageController->goToPageHome();
|
|
||||||
m_importController->extractConfigFromData(data);
|
|
||||||
emit m_pageController->goToPageViewConfig();
|
|
||||||
});
|
|
||||||
|
|
||||||
connect(IosController::Instance(), &IosController::importBackupFromOutside, this, [this](QString filePath) {
|
|
||||||
emit m_pageController->goToPageHome();
|
|
||||||
m_pageController->goToPageSettingsBackup();
|
|
||||||
emit m_settingsController->importBackupFromOutside(filePath);
|
|
||||||
});
|
|
||||||
|
|
||||||
QTimer::singleShot(0, this, [this]() { AmneziaVPN::toggleScreenshots(m_settings->isScreenshotsEnabled()); });
|
|
||||||
|
|
||||||
connect(m_settings.get(), &Settings::screenshotsEnabledChanged, [](bool enabled) { AmneziaVPN::toggleScreenshots(enabled); });
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef Q_OS_ANDROID
|
|
||||||
m_notificationHandler.reset(NotificationHandler::create(nullptr));
|
|
||||||
|
|
||||||
connect(m_vpnConnection.get(), &VpnConnection::connectionStateChanged, m_notificationHandler.get(),
|
|
||||||
&NotificationHandler::setConnectionState);
|
|
||||||
|
|
||||||
connect(m_notificationHandler.get(), &NotificationHandler::raiseRequested, m_pageController.get(), &PageController::raiseMainWindow);
|
|
||||||
connect(m_notificationHandler.get(), &NotificationHandler::connectRequested, m_connectionController.get(),
|
|
||||||
static_cast<void (ConnectionController::*)()>(&ConnectionController::openConnection));
|
|
||||||
connect(m_notificationHandler.get(), &NotificationHandler::disconnectRequested, m_connectionController.get(),
|
|
||||||
&ConnectionController::closeConnection);
|
|
||||||
connect(this, &AmneziaApplication::translationsUpdated, m_notificationHandler.get(), &NotificationHandler::onTranslationsUpdated);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
m_engine->addImportPath("qrc:/ui/qml/Modules/");
|
m_engine->addImportPath("qrc:/ui/qml/Modules/");
|
||||||
m_engine->load(url);
|
m_engine->load(url);
|
||||||
m_systemController->setQmlRoot(m_engine->rootObjects().value(0));
|
|
||||||
|
m_coreController->setQmlRoot();
|
||||||
|
|
||||||
bool enabled = m_settings->isSaveLogs();
|
bool enabled = m_settings->isSaveLogs();
|
||||||
#ifndef Q_OS_ANDROID
|
#ifndef Q_OS_ANDROID
|
||||||
|
@ -168,13 +93,13 @@ void AmneziaApplication::init()
|
||||||
#endif
|
#endif
|
||||||
Logger::setServiceLogsEnabled(enabled);
|
Logger::setServiceLogsEnabled(enabled);
|
||||||
|
|
||||||
#ifdef Q_OS_WIN
|
#ifdef Q_OS_WIN //TODO
|
||||||
if (m_parser.isSet("a"))
|
if (m_parser.isSet("a"))
|
||||||
m_pageController->showOnStartup();
|
m_coreController->pageController()->showOnStartup();
|
||||||
else
|
else
|
||||||
emit m_pageController->raiseMainWindow();
|
emit m_coreController->pageController()->raiseMainWindow();
|
||||||
#else
|
#else
|
||||||
m_pageController->showOnStartup();
|
m_coreController->pageController()->showOnStartup();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Android TextArea clipboard workaround
|
// Android TextArea clipboard workaround
|
||||||
|
@ -231,33 +156,6 @@ void AmneziaApplication::loadFonts()
|
||||||
QFontDatabase::addApplicationFont(":/fonts/pt-root-ui_vf.ttf");
|
QFontDatabase::addApplicationFont(":/fonts/pt-root-ui_vf.ttf");
|
||||||
}
|
}
|
||||||
|
|
||||||
void AmneziaApplication::loadTranslator()
|
|
||||||
{
|
|
||||||
auto locale = m_settings->getAppLanguage();
|
|
||||||
m_translator.reset(new QTranslator());
|
|
||||||
updateTranslator(locale);
|
|
||||||
}
|
|
||||||
|
|
||||||
void AmneziaApplication::updateTranslator(const QLocale &locale)
|
|
||||||
{
|
|
||||||
if (!m_translator->isEmpty()) {
|
|
||||||
QCoreApplication::removeTranslator(m_translator.get());
|
|
||||||
}
|
|
||||||
|
|
||||||
QString strFileName = QString(":/translations/amneziavpn") + QLatin1String("_") + locale.name() + ".qm";
|
|
||||||
if (m_translator->load(strFileName)) {
|
|
||||||
if (QCoreApplication::installTranslator(m_translator.get())) {
|
|
||||||
m_settings->setAppLanguage(locale);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
m_settings->setAppLanguage(QLocale::English);
|
|
||||||
}
|
|
||||||
|
|
||||||
m_engine->retranslate();
|
|
||||||
|
|
||||||
emit translationsUpdated();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool AmneziaApplication::parseCommands()
|
bool AmneziaApplication::parseCommands()
|
||||||
{
|
{
|
||||||
m_parser.setApplicationDescription(APPLICATION_NAME);
|
m_parser.setApplicationDescription(APPLICATION_NAME);
|
||||||
|
@ -295,7 +193,7 @@ void AmneziaApplication::startLocalServer()
|
||||||
QLocalSocket *clientConnection = server->nextPendingConnection();
|
QLocalSocket *clientConnection = server->nextPendingConnection();
|
||||||
clientConnection->deleteLater();
|
clientConnection->deleteLater();
|
||||||
}
|
}
|
||||||
emit m_pageController->raiseMainWindow();
|
emit m_coreController->pageController()->raiseMainWindow(); //TODO
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -304,173 +202,3 @@ QQmlApplicationEngine *AmneziaApplication::qmlEngine() const
|
||||||
{
|
{
|
||||||
return m_engine;
|
return m_engine;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AmneziaApplication::initModels()
|
|
||||||
{
|
|
||||||
m_containersModel.reset(new ContainersModel(this));
|
|
||||||
m_engine->rootContext()->setContextProperty("ContainersModel", m_containersModel.get());
|
|
||||||
|
|
||||||
m_defaultServerContainersModel.reset(new ContainersModel(this));
|
|
||||||
m_engine->rootContext()->setContextProperty("DefaultServerContainersModel", m_defaultServerContainersModel.get());
|
|
||||||
|
|
||||||
m_serversModel.reset(new ServersModel(m_settings, this));
|
|
||||||
m_engine->rootContext()->setContextProperty("ServersModel", m_serversModel.get());
|
|
||||||
connect(m_serversModel.get(), &ServersModel::containersUpdated, m_containersModel.get(), &ContainersModel::updateModel);
|
|
||||||
connect(m_serversModel.get(), &ServersModel::defaultServerContainersUpdated, m_defaultServerContainersModel.get(),
|
|
||||||
&ContainersModel::updateModel);
|
|
||||||
m_serversModel->resetModel();
|
|
||||||
|
|
||||||
m_languageModel.reset(new LanguageModel(m_settings, this));
|
|
||||||
m_engine->rootContext()->setContextProperty("LanguageModel", m_languageModel.get());
|
|
||||||
connect(m_languageModel.get(), &LanguageModel::updateTranslations, this, &AmneziaApplication::updateTranslator);
|
|
||||||
connect(this, &AmneziaApplication::translationsUpdated, m_languageModel.get(), &LanguageModel::translationsUpdated);
|
|
||||||
|
|
||||||
m_sitesModel.reset(new SitesModel(m_settings, this));
|
|
||||||
m_engine->rootContext()->setContextProperty("SitesModel", m_sitesModel.get());
|
|
||||||
|
|
||||||
m_appSplitTunnelingModel.reset(new AppSplitTunnelingModel(m_settings, this));
|
|
||||||
m_engine->rootContext()->setContextProperty("AppSplitTunnelingModel", m_appSplitTunnelingModel.get());
|
|
||||||
|
|
||||||
m_protocolsModel.reset(new ProtocolsModel(m_settings, this));
|
|
||||||
m_engine->rootContext()->setContextProperty("ProtocolsModel", m_protocolsModel.get());
|
|
||||||
|
|
||||||
m_openVpnConfigModel.reset(new OpenVpnConfigModel(this));
|
|
||||||
m_engine->rootContext()->setContextProperty("OpenVpnConfigModel", m_openVpnConfigModel.get());
|
|
||||||
|
|
||||||
m_shadowSocksConfigModel.reset(new ShadowSocksConfigModel(this));
|
|
||||||
m_engine->rootContext()->setContextProperty("ShadowSocksConfigModel", m_shadowSocksConfigModel.get());
|
|
||||||
|
|
||||||
m_cloakConfigModel.reset(new CloakConfigModel(this));
|
|
||||||
m_engine->rootContext()->setContextProperty("CloakConfigModel", m_cloakConfigModel.get());
|
|
||||||
|
|
||||||
m_wireGuardConfigModel.reset(new WireGuardConfigModel(this));
|
|
||||||
m_engine->rootContext()->setContextProperty("WireGuardConfigModel", m_wireGuardConfigModel.get());
|
|
||||||
|
|
||||||
m_awgConfigModel.reset(new AwgConfigModel(this));
|
|
||||||
m_engine->rootContext()->setContextProperty("AwgConfigModel", m_awgConfigModel.get());
|
|
||||||
|
|
||||||
m_xrayConfigModel.reset(new XrayConfigModel(this));
|
|
||||||
m_engine->rootContext()->setContextProperty("XrayConfigModel", m_xrayConfigModel.get());
|
|
||||||
|
|
||||||
#ifdef Q_OS_WINDOWS
|
|
||||||
m_ikev2ConfigModel.reset(new Ikev2ConfigModel(this));
|
|
||||||
m_engine->rootContext()->setContextProperty("Ikev2ConfigModel", m_ikev2ConfigModel.get());
|
|
||||||
#endif
|
|
||||||
|
|
||||||
m_sftpConfigModel.reset(new SftpConfigModel(this));
|
|
||||||
m_engine->rootContext()->setContextProperty("SftpConfigModel", m_sftpConfigModel.get());
|
|
||||||
|
|
||||||
m_socks5ConfigModel.reset(new Socks5ProxyConfigModel(this));
|
|
||||||
m_engine->rootContext()->setContextProperty("Socks5ProxyConfigModel", m_socks5ConfigModel.get());
|
|
||||||
|
|
||||||
m_clientManagementModel.reset(new ClientManagementModel(m_settings, this));
|
|
||||||
m_engine->rootContext()->setContextProperty("ClientManagementModel", m_clientManagementModel.get());
|
|
||||||
connect(m_clientManagementModel.get(), &ClientManagementModel::adminConfigRevoked, m_serversModel.get(),
|
|
||||||
&ServersModel::clearCachedProfile);
|
|
||||||
|
|
||||||
m_apiServicesModel.reset(new ApiServicesModel(this));
|
|
||||||
m_engine->rootContext()->setContextProperty("ApiServicesModel", m_apiServicesModel.get());
|
|
||||||
|
|
||||||
m_apiCountryModel.reset(new ApiCountryModel(this));
|
|
||||||
m_engine->rootContext()->setContextProperty("ApiCountryModel", m_apiCountryModel.get());
|
|
||||||
connect(m_serversModel.get(), &ServersModel::updateApiLanguageModel, this, [this]() {
|
|
||||||
m_apiCountryModel->updateModel(m_serversModel->getProcessedServerData("apiAvailableCountries").toJsonArray(),
|
|
||||||
m_serversModel->getProcessedServerData("apiServerCountryCode").toString());
|
|
||||||
});
|
|
||||||
connect(m_serversModel.get(), &ServersModel::updateApiServicesModel, this,
|
|
||||||
[this]() { m_apiServicesModel->updateModel(m_serversModel->getProcessedServerData("apiConfig").toJsonObject()); });
|
|
||||||
|
|
||||||
m_apiAccountInfoModel.reset(new ApiAccountInfoModel(this));
|
|
||||||
m_engine->rootContext()->setContextProperty("ApiAccountInfoModel", m_apiAccountInfoModel.get());
|
|
||||||
}
|
|
||||||
|
|
||||||
void AmneziaApplication::initControllers()
|
|
||||||
{
|
|
||||||
m_connectionController.reset(
|
|
||||||
new ConnectionController(m_serversModel, m_containersModel, m_clientManagementModel, m_vpnConnection, m_settings));
|
|
||||||
m_engine->rootContext()->setContextProperty("ConnectionController", m_connectionController.get());
|
|
||||||
|
|
||||||
connect(m_connectionController.get(), qOverload<const QString &>(&ConnectionController::connectionErrorOccurred), this,
|
|
||||||
[this](const QString &errorMessage) {
|
|
||||||
emit m_pageController->showErrorMessage(errorMessage);
|
|
||||||
emit m_vpnConnection->connectionStateChanged(Vpn::ConnectionState::Disconnected);
|
|
||||||
});
|
|
||||||
|
|
||||||
connect(m_connectionController.get(), qOverload<ErrorCode>(&ConnectionController::connectionErrorOccurred), this,
|
|
||||||
[this](ErrorCode errorCode) {
|
|
||||||
emit m_pageController->showErrorMessage(errorCode);
|
|
||||||
emit m_vpnConnection->connectionStateChanged(Vpn::ConnectionState::Disconnected);
|
|
||||||
});
|
|
||||||
|
|
||||||
connect(m_connectionController.get(), &ConnectionController::connectButtonClicked, m_connectionController.get(),
|
|
||||||
&ConnectionController::toggleConnection, Qt::QueuedConnection);
|
|
||||||
|
|
||||||
m_pageController.reset(new PageController(m_serversModel, m_settings));
|
|
||||||
m_engine->rootContext()->setContextProperty("PageController", m_pageController.get());
|
|
||||||
|
|
||||||
m_focusController.reset(new FocusController(m_engine, this));
|
|
||||||
m_engine->rootContext()->setContextProperty("FocusController", m_focusController.get());
|
|
||||||
|
|
||||||
m_installController.reset(new InstallController(m_serversModel, m_containersModel, m_protocolsModel, m_clientManagementModel,
|
|
||||||
m_apiServicesModel, m_settings));
|
|
||||||
m_engine->rootContext()->setContextProperty("InstallController", m_installController.get());
|
|
||||||
connect(m_installController.get(), &InstallController::passphraseRequestStarted, m_pageController.get(),
|
|
||||||
&PageController::showPassphraseRequestDrawer);
|
|
||||||
connect(m_pageController.get(), &PageController::passphraseRequestDrawerClosed, m_installController.get(),
|
|
||||||
&InstallController::setEncryptedPassphrase);
|
|
||||||
connect(m_installController.get(), &InstallController::currentContainerUpdated, m_connectionController.get(),
|
|
||||||
&ConnectionController::onCurrentContainerUpdated);
|
|
||||||
|
|
||||||
connect(m_installController.get(), &InstallController::updateServerFromApiFinished, this, [this]() {
|
|
||||||
disconnect(m_reloadConfigErrorOccurredConnection);
|
|
||||||
emit m_connectionController->configFromApiUpdated();
|
|
||||||
});
|
|
||||||
|
|
||||||
connect(m_connectionController.get(), &ConnectionController::updateApiConfigFromGateway, this, [this]() {
|
|
||||||
m_reloadConfigErrorOccurredConnection = connect(
|
|
||||||
m_installController.get(), qOverload<ErrorCode>(&InstallController::installationErrorOccurred), this,
|
|
||||||
[this]() { emit m_vpnConnection->connectionStateChanged(Vpn::ConnectionState::Disconnected); },
|
|
||||||
static_cast<Qt::ConnectionType>(Qt::AutoConnection || Qt::SingleShotConnection));
|
|
||||||
m_installController->updateServiceFromApi(m_serversModel->getDefaultServerIndex(), "", "");
|
|
||||||
});
|
|
||||||
|
|
||||||
connect(m_connectionController.get(), &ConnectionController::updateApiConfigFromTelegram, this, [this]() {
|
|
||||||
m_reloadConfigErrorOccurredConnection = connect(
|
|
||||||
m_installController.get(), qOverload<ErrorCode>(&InstallController::installationErrorOccurred), this,
|
|
||||||
[this]() { emit m_vpnConnection->connectionStateChanged(Vpn::ConnectionState::Disconnected); },
|
|
||||||
static_cast<Qt::ConnectionType>(Qt::AutoConnection || Qt::SingleShotConnection));
|
|
||||||
m_serversModel->removeApiConfig(m_serversModel->getDefaultServerIndex());
|
|
||||||
m_installController->updateServiceFromTelegram(m_serversModel->getDefaultServerIndex());
|
|
||||||
});
|
|
||||||
|
|
||||||
connect(this, &AmneziaApplication::translationsUpdated, m_connectionController.get(), &ConnectionController::onTranslationsUpdated);
|
|
||||||
|
|
||||||
m_importController.reset(new ImportController(m_serversModel, m_containersModel, m_settings));
|
|
||||||
m_engine->rootContext()->setContextProperty("ImportController", m_importController.get());
|
|
||||||
|
|
||||||
m_exportController.reset(new ExportController(m_serversModel, m_containersModel, m_clientManagementModel, m_settings));
|
|
||||||
m_engine->rootContext()->setContextProperty("ExportController", m_exportController.get());
|
|
||||||
|
|
||||||
m_settingsController.reset(
|
|
||||||
new SettingsController(m_serversModel, m_containersModel, m_languageModel, m_sitesModel, m_appSplitTunnelingModel, m_settings));
|
|
||||||
m_engine->rootContext()->setContextProperty("SettingsController", m_settingsController.get());
|
|
||||||
if (m_settingsController->isAutoConnectEnabled() && m_serversModel->getDefaultServerIndex() >= 0) {
|
|
||||||
QTimer::singleShot(1000, this, [this]() { m_connectionController->openConnection(); });
|
|
||||||
}
|
|
||||||
connect(m_settingsController.get(), &SettingsController::amneziaDnsToggled, m_serversModel.get(), &ServersModel::toggleAmneziaDns);
|
|
||||||
|
|
||||||
m_sitesController.reset(new SitesController(m_settings, m_vpnConnection, m_sitesModel));
|
|
||||||
m_engine->rootContext()->setContextProperty("SitesController", m_sitesController.get());
|
|
||||||
|
|
||||||
m_appSplitTunnelingController.reset(new AppSplitTunnelingController(m_settings, m_appSplitTunnelingModel));
|
|
||||||
m_engine->rootContext()->setContextProperty("AppSplitTunnelingController", m_appSplitTunnelingController.get());
|
|
||||||
|
|
||||||
m_systemController.reset(new SystemController(m_settings));
|
|
||||||
m_engine->rootContext()->setContextProperty("SystemController", m_systemController.get());
|
|
||||||
|
|
||||||
m_apiSettingsController.reset(new ApiSettingsController(m_serversModel, m_apiAccountInfoModel, m_apiCountryModel, m_settings));
|
|
||||||
m_engine->rootContext()->setContextProperty("ApiSettingsController", m_apiSettingsController.get());
|
|
||||||
|
|
||||||
m_apiConfigsController.reset(new ApiConfigsController(m_serversModel, m_settings));
|
|
||||||
m_engine->rootContext()->setContextProperty("ApiConfigsController", m_apiConfigsController.get());
|
|
||||||
}
|
|
||||||
|
|
|
@ -12,46 +12,10 @@
|
||||||
#include <QApplication>
|
#include <QApplication>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include "core/controllers/coreController.h"
|
||||||
#include "settings.h"
|
#include "settings.h"
|
||||||
#include "vpnconnection.h"
|
#include "vpnconnection.h"
|
||||||
|
|
||||||
#include "ui/controllers/connectionController.h"
|
|
||||||
#include "ui/controllers/exportController.h"
|
|
||||||
#include "ui/controllers/importController.h"
|
|
||||||
#include "ui/controllers/installController.h"
|
|
||||||
#include "ui/controllers/focusController.h"
|
|
||||||
#include "ui/controllers/pageController.h"
|
|
||||||
#include "ui/controllers/settingsController.h"
|
|
||||||
#include "ui/controllers/sitesController.h"
|
|
||||||
#include "ui/controllers/systemController.h"
|
|
||||||
#include "ui/controllers/appSplitTunnelingController.h"
|
|
||||||
#include "ui/controllers/api/apiConfigsController.h"
|
|
||||||
#include "ui/controllers/api/apiSettingsController.h"
|
|
||||||
#include "ui/models/containers_model.h"
|
|
||||||
#include "ui/models/languageModel.h"
|
|
||||||
#include "ui/models/protocols/cloakConfigModel.h"
|
|
||||||
#ifndef Q_OS_ANDROID
|
|
||||||
#include "ui/notificationhandler.h"
|
|
||||||
#endif
|
|
||||||
#ifdef Q_OS_WINDOWS
|
|
||||||
#include "ui/models/protocols/ikev2ConfigModel.h"
|
|
||||||
#endif
|
|
||||||
#include "ui/models/protocols/awgConfigModel.h"
|
|
||||||
#include "ui/models/protocols/openvpnConfigModel.h"
|
|
||||||
#include "ui/models/protocols/shadowsocksConfigModel.h"
|
|
||||||
#include "ui/models/protocols/wireguardConfigModel.h"
|
|
||||||
#include "ui/models/protocols/xrayConfigModel.h"
|
|
||||||
#include "ui/models/protocols_model.h"
|
|
||||||
#include "ui/models/servers_model.h"
|
|
||||||
#include "ui/models/services/sftpConfigModel.h"
|
|
||||||
#include "ui/models/services/socks5ProxyConfigModel.h"
|
|
||||||
#include "ui/models/sites_model.h"
|
|
||||||
#include "ui/models/clientManagementModel.h"
|
|
||||||
#include "ui/models/appSplitTunnelingModel.h"
|
|
||||||
#include "ui/models/apiServicesModel.h"
|
|
||||||
#include "ui/models/apiCountryModel.h"
|
|
||||||
#include "ui/models/api/apiAccountInfoModel.h"
|
|
||||||
|
|
||||||
#define amnApp (static_cast<AmneziaApplication *>(QCoreApplication::instance()))
|
#define amnApp (static_cast<AmneziaApplication *>(QCoreApplication::instance()))
|
||||||
|
|
||||||
#if defined(Q_OS_ANDROID) || defined(Q_OS_IOS)
|
#if defined(Q_OS_ANDROID) || defined(Q_OS_IOS)
|
||||||
|
@ -70,8 +34,6 @@ public:
|
||||||
void init();
|
void init();
|
||||||
void registerTypes();
|
void registerTypes();
|
||||||
void loadFonts();
|
void loadFonts();
|
||||||
void loadTranslator();
|
|
||||||
void updateTranslator(const QLocale &locale);
|
|
||||||
bool parseCommands();
|
bool parseCommands();
|
||||||
|
|
||||||
#if !defined(Q_OS_ANDROID) && !defined(Q_OS_IOS)
|
#if !defined(Q_OS_ANDROID) && !defined(Q_OS_IOS)
|
||||||
|
@ -79,71 +41,26 @@ public:
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
QQmlApplicationEngine *qmlEngine() const;
|
QQmlApplicationEngine *qmlEngine() const;
|
||||||
QNetworkAccessManager *manager() { return m_nam; }
|
QNetworkAccessManager *manager()
|
||||||
|
{
|
||||||
signals:
|
return m_nam;
|
||||||
void translationsUpdated();
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void initModels();
|
|
||||||
void initControllers();
|
|
||||||
|
|
||||||
QQmlApplicationEngine *m_engine {};
|
QQmlApplicationEngine *m_engine {};
|
||||||
std::shared_ptr<Settings> m_settings;
|
std::shared_ptr<Settings> m_settings;
|
||||||
|
|
||||||
|
QScopedPointer<CoreController> m_coreController;
|
||||||
|
|
||||||
QSharedPointer<ContainerProps> m_containerProps;
|
QSharedPointer<ContainerProps> m_containerProps;
|
||||||
QSharedPointer<ProtocolProps> m_protocolProps;
|
QSharedPointer<ProtocolProps> m_protocolProps;
|
||||||
|
|
||||||
QSharedPointer<QTranslator> m_translator;
|
|
||||||
QCommandLineParser m_parser;
|
QCommandLineParser m_parser;
|
||||||
|
|
||||||
QSharedPointer<ContainersModel> m_containersModel;
|
|
||||||
QSharedPointer<ContainersModel> m_defaultServerContainersModel;
|
|
||||||
QSharedPointer<ServersModel> m_serversModel;
|
|
||||||
QSharedPointer<LanguageModel> m_languageModel;
|
|
||||||
QSharedPointer<ProtocolsModel> m_protocolsModel;
|
|
||||||
QSharedPointer<SitesModel> m_sitesModel;
|
|
||||||
QSharedPointer<AppSplitTunnelingModel> m_appSplitTunnelingModel;
|
|
||||||
QSharedPointer<ClientManagementModel> m_clientManagementModel;
|
|
||||||
QSharedPointer<ApiServicesModel> m_apiServicesModel;
|
|
||||||
QSharedPointer<ApiCountryModel> m_apiCountryModel;
|
|
||||||
QSharedPointer<ApiAccountInfoModel> m_apiAccountInfoModel;
|
|
||||||
|
|
||||||
QScopedPointer<OpenVpnConfigModel> m_openVpnConfigModel;
|
|
||||||
QScopedPointer<ShadowSocksConfigModel> m_shadowSocksConfigModel;
|
|
||||||
QScopedPointer<CloakConfigModel> m_cloakConfigModel;
|
|
||||||
QScopedPointer<XrayConfigModel> m_xrayConfigModel;
|
|
||||||
QScopedPointer<WireGuardConfigModel> m_wireGuardConfigModel;
|
|
||||||
QScopedPointer<AwgConfigModel> m_awgConfigModel;
|
|
||||||
#ifdef Q_OS_WINDOWS
|
|
||||||
QScopedPointer<Ikev2ConfigModel> m_ikev2ConfigModel;
|
|
||||||
#endif
|
|
||||||
QScopedPointer<SftpConfigModel> m_sftpConfigModel;
|
|
||||||
QScopedPointer<Socks5ProxyConfigModel> m_socks5ConfigModel;
|
|
||||||
|
|
||||||
QSharedPointer<VpnConnection> m_vpnConnection;
|
QSharedPointer<VpnConnection> m_vpnConnection;
|
||||||
QThread m_vpnConnectionThread;
|
QThread m_vpnConnectionThread;
|
||||||
#ifndef Q_OS_ANDROID
|
|
||||||
QScopedPointer<NotificationHandler> m_notificationHandler;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
QScopedPointer<ConnectionController> m_connectionController;
|
|
||||||
QScopedPointer<FocusController> m_focusController;
|
|
||||||
QScopedPointer<PageController> m_pageController;
|
|
||||||
QScopedPointer<InstallController> m_installController;
|
|
||||||
QScopedPointer<ImportController> m_importController;
|
|
||||||
QScopedPointer<ExportController> m_exportController;
|
|
||||||
QScopedPointer<SettingsController> m_settingsController;
|
|
||||||
QScopedPointer<SitesController> m_sitesController;
|
|
||||||
QScopedPointer<SystemController> m_systemController;
|
|
||||||
QScopedPointer<AppSplitTunnelingController> m_appSplitTunnelingController;
|
|
||||||
|
|
||||||
QScopedPointer<ApiSettingsController> m_apiSettingsController;
|
|
||||||
QScopedPointer<ApiConfigsController> m_apiConfigsController;
|
|
||||||
|
|
||||||
QNetworkAccessManager *m_nam;
|
QNetworkAccessManager *m_nam;
|
||||||
|
|
||||||
QMetaObject::Connection m_reloadConfigErrorOccurredConnection;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // AMNEZIA_APPLICATION_H
|
#endif // AMNEZIA_APPLICATION_H
|
||||||
|
|
|
@ -9,7 +9,9 @@ set(HEADERS ${HEADERS}
|
||||||
${CLIENT_ROOT_DIR}/core/errorstrings.h
|
${CLIENT_ROOT_DIR}/core/errorstrings.h
|
||||||
${CLIENT_ROOT_DIR}/core/scripts_registry.h
|
${CLIENT_ROOT_DIR}/core/scripts_registry.h
|
||||||
${CLIENT_ROOT_DIR}/core/server_defs.h
|
${CLIENT_ROOT_DIR}/core/server_defs.h
|
||||||
${CLIENT_ROOT_DIR}/core/controllers/apiController.h
|
${CLIENT_ROOT_DIR}/core/api/apiDefs.h
|
||||||
|
${CLIENT_ROOT_DIR}/core/qrCodeUtils.h
|
||||||
|
${CLIENT_ROOT_DIR}/core/controllers/coreController.h
|
||||||
${CLIENT_ROOT_DIR}/core/controllers/gatewayController.h
|
${CLIENT_ROOT_DIR}/core/controllers/gatewayController.h
|
||||||
${CLIENT_ROOT_DIR}/core/controllers/serverController.h
|
${CLIENT_ROOT_DIR}/core/controllers/serverController.h
|
||||||
${CLIENT_ROOT_DIR}/core/controllers/vpnConfigurationController.h
|
${CLIENT_ROOT_DIR}/core/controllers/vpnConfigurationController.h
|
||||||
|
@ -56,7 +58,8 @@ set(SOURCES ${SOURCES}
|
||||||
${CLIENT_ROOT_DIR}/core/errorstrings.cpp
|
${CLIENT_ROOT_DIR}/core/errorstrings.cpp
|
||||||
${CLIENT_ROOT_DIR}/core/scripts_registry.cpp
|
${CLIENT_ROOT_DIR}/core/scripts_registry.cpp
|
||||||
${CLIENT_ROOT_DIR}/core/server_defs.cpp
|
${CLIENT_ROOT_DIR}/core/server_defs.cpp
|
||||||
${CLIENT_ROOT_DIR}/core/controllers/apiController.cpp
|
${CLIENT_ROOT_DIR}/core/qrCodeUtils.cpp
|
||||||
|
${CLIENT_ROOT_DIR}/core/controllers/coreController.cpp
|
||||||
${CLIENT_ROOT_DIR}/core/controllers/gatewayController.cpp
|
${CLIENT_ROOT_DIR}/core/controllers/gatewayController.cpp
|
||||||
${CLIENT_ROOT_DIR}/core/controllers/serverController.cpp
|
${CLIENT_ROOT_DIR}/core/controllers/serverController.cpp
|
||||||
${CLIENT_ROOT_DIR}/core/controllers/vpnConfigurationController.cpp
|
${CLIENT_ROOT_DIR}/core/controllers/vpnConfigurationController.cpp
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
namespace apiDefs
|
namespace apiDefs
|
||||||
{
|
{
|
||||||
enum ConfigType {
|
enum ConfigType {
|
||||||
AmneziaFreeV2 = 1,
|
AmneziaFreeV2 = 0,
|
||||||
AmneziaFreeV3,
|
AmneziaFreeV3,
|
||||||
AmneziaPremiumV1,
|
AmneziaPremiumV1,
|
||||||
AmneziaPremiumV2,
|
AmneziaPremiumV2,
|
||||||
|
|
|
@ -44,3 +44,8 @@ apiDefs::ConfigType apiUtils::getConfigType(const QJsonObject &serverConfigObjec
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
apiDefs::ConfigSource apiUtils::getConfigSource(const QJsonObject &serverConfigObject)
|
||||||
|
{
|
||||||
|
return static_cast<apiDefs::ConfigSource>(serverConfigObject.value(apiDefs::key::configVersion).toInt());
|
||||||
|
}
|
||||||
|
|
|
@ -12,6 +12,7 @@ namespace apiUtils
|
||||||
bool isSubscriptionExpired(const QString &subscriptionEndDate);
|
bool isSubscriptionExpired(const QString &subscriptionEndDate);
|
||||||
|
|
||||||
apiDefs::ConfigType getConfigType(const QJsonObject &serverConfigObject);
|
apiDefs::ConfigType getConfigType(const QJsonObject &serverConfigObject);
|
||||||
|
apiDefs::ConfigSource getConfigSource(const QJsonObject &serverConfigObject);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // APIUTILS_H
|
#endif // APIUTILS_H
|
||||||
|
|
|
@ -1,262 +0,0 @@
|
||||||
#include "apiController.h"
|
|
||||||
|
|
||||||
#include <QEventLoop>
|
|
||||||
#include <QNetworkAccessManager>
|
|
||||||
#include <QNetworkReply>
|
|
||||||
#include <QtConcurrent>
|
|
||||||
|
|
||||||
#include "amnezia_application.h"
|
|
||||||
#include "configurators/wireguard_configurator.h"
|
|
||||||
#include "core/api/apiDefs.h"
|
|
||||||
#include "gatewayController.h"
|
|
||||||
#include "version.h"
|
|
||||||
|
|
||||||
namespace
|
|
||||||
{
|
|
||||||
namespace configKey
|
|
||||||
{
|
|
||||||
constexpr char cloak[] = "cloak";
|
|
||||||
constexpr char awg[] = "awg";
|
|
||||||
|
|
||||||
constexpr char apiEdnpoint[] = "api_endpoint";
|
|
||||||
constexpr char accessToken[] = "api_key";
|
|
||||||
constexpr char certificate[] = "certificate";
|
|
||||||
constexpr char publicKey[] = "public_key";
|
|
||||||
constexpr char protocol[] = "protocol";
|
|
||||||
|
|
||||||
constexpr char uuid[] = "installation_uuid";
|
|
||||||
constexpr char osVersion[] = "os_version";
|
|
||||||
constexpr char appVersion[] = "app_version";
|
|
||||||
|
|
||||||
constexpr char userCountryCode[] = "user_country_code";
|
|
||||||
constexpr char serverCountryCode[] = "server_country_code";
|
|
||||||
constexpr char serviceType[] = "service_type";
|
|
||||||
constexpr char serviceInfo[] = "service_info";
|
|
||||||
|
|
||||||
constexpr char aesKey[] = "aes_key";
|
|
||||||
constexpr char aesIv[] = "aes_iv";
|
|
||||||
constexpr char aesSalt[] = "aes_salt";
|
|
||||||
|
|
||||||
constexpr char apiPayload[] = "api_payload";
|
|
||||||
constexpr char keyPayload[] = "key_payload";
|
|
||||||
|
|
||||||
constexpr char apiConfig[] = "api_config";
|
|
||||||
constexpr char authData[] = "auth_data";
|
|
||||||
}
|
|
||||||
|
|
||||||
const int requestTimeoutMsecs = 12 * 1000; // 12 secs
|
|
||||||
}
|
|
||||||
|
|
||||||
ApiController::ApiController(const QString &gatewayEndpoint, bool isDevEnvironment, QObject *parent)
|
|
||||||
: QObject(parent), m_gatewayEndpoint(gatewayEndpoint), m_isDevEnvironment(isDevEnvironment)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void ApiController::fillServerConfig(const QString &protocol, const ApiController::ApiPayloadData &apiPayloadData,
|
|
||||||
const QByteArray &apiResponseBody, QJsonObject &serverConfig)
|
|
||||||
{
|
|
||||||
QString data = QJsonDocument::fromJson(apiResponseBody).object().value(config_key::config).toString();
|
|
||||||
|
|
||||||
data.replace("vpn://", "");
|
|
||||||
QByteArray ba = QByteArray::fromBase64(data.toUtf8(), QByteArray::Base64UrlEncoding | QByteArray::OmitTrailingEquals);
|
|
||||||
|
|
||||||
if (ba.isEmpty()) {
|
|
||||||
emit errorOccurred(ErrorCode::ApiConfigEmptyError);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
QByteArray ba_uncompressed = qUncompress(ba);
|
|
||||||
if (!ba_uncompressed.isEmpty()) {
|
|
||||||
ba = ba_uncompressed;
|
|
||||||
}
|
|
||||||
|
|
||||||
QString configStr = ba;
|
|
||||||
if (protocol == configKey::cloak) {
|
|
||||||
configStr.replace("<key>", "<key>\n");
|
|
||||||
configStr.replace("$OPENVPN_PRIV_KEY", apiPayloadData.certRequest.privKey);
|
|
||||||
} else if (protocol == configKey::awg) {
|
|
||||||
configStr.replace("$WIREGUARD_CLIENT_PRIVATE_KEY", apiPayloadData.wireGuardClientPrivKey);
|
|
||||||
auto newServerConfig = QJsonDocument::fromJson(configStr.toUtf8()).object();
|
|
||||||
auto containers = newServerConfig.value(config_key::containers).toArray();
|
|
||||||
if (containers.isEmpty()) {
|
|
||||||
return; // todo process error
|
|
||||||
}
|
|
||||||
auto container = containers.at(0).toObject();
|
|
||||||
QString containerName = ContainerProps::containerTypeToString(DockerContainer::Awg);
|
|
||||||
auto containerConfig = container.value(containerName).toObject();
|
|
||||||
auto protocolConfig = QJsonDocument::fromJson(containerConfig.value(config_key::last_config).toString().toUtf8()).object();
|
|
||||||
containerConfig[config_key::junkPacketCount] = protocolConfig.value(config_key::junkPacketCount);
|
|
||||||
containerConfig[config_key::junkPacketMinSize] = protocolConfig.value(config_key::junkPacketMinSize);
|
|
||||||
containerConfig[config_key::junkPacketMaxSize] = protocolConfig.value(config_key::junkPacketMaxSize);
|
|
||||||
containerConfig[config_key::initPacketJunkSize] = protocolConfig.value(config_key::initPacketJunkSize);
|
|
||||||
containerConfig[config_key::responsePacketJunkSize] = protocolConfig.value(config_key::responsePacketJunkSize);
|
|
||||||
containerConfig[config_key::initPacketMagicHeader] = protocolConfig.value(config_key::initPacketMagicHeader);
|
|
||||||
containerConfig[config_key::responsePacketMagicHeader] = protocolConfig.value(config_key::responsePacketMagicHeader);
|
|
||||||
containerConfig[config_key::underloadPacketMagicHeader] = protocolConfig.value(config_key::underloadPacketMagicHeader);
|
|
||||||
containerConfig[config_key::transportPacketMagicHeader] = protocolConfig.value(config_key::transportPacketMagicHeader);
|
|
||||||
container[containerName] = containerConfig;
|
|
||||||
containers.replace(0, container);
|
|
||||||
newServerConfig[config_key::containers] = containers;
|
|
||||||
configStr = QString(QJsonDocument(newServerConfig).toJson());
|
|
||||||
}
|
|
||||||
|
|
||||||
QJsonObject newServerConfig = QJsonDocument::fromJson(configStr.toUtf8()).object();
|
|
||||||
serverConfig[config_key::dns1] = newServerConfig.value(config_key::dns1);
|
|
||||||
serverConfig[config_key::dns2] = newServerConfig.value(config_key::dns2);
|
|
||||||
serverConfig[config_key::containers] = newServerConfig.value(config_key::containers);
|
|
||||||
serverConfig[config_key::hostName] = newServerConfig.value(config_key::hostName);
|
|
||||||
|
|
||||||
if (newServerConfig.value(config_key::configVersion).toInt() == apiDefs::ConfigSource::AmneziaGateway) {
|
|
||||||
serverConfig[config_key::configVersion] = newServerConfig.value(config_key::configVersion);
|
|
||||||
serverConfig[config_key::description] = newServerConfig.value(config_key::description);
|
|
||||||
serverConfig[config_key::name] = newServerConfig.value(config_key::name);
|
|
||||||
}
|
|
||||||
|
|
||||||
auto defaultContainer = newServerConfig.value(config_key::defaultContainer).toString();
|
|
||||||
serverConfig[config_key::defaultContainer] = defaultContainer;
|
|
||||||
|
|
||||||
QVariantMap map = serverConfig.value(configKey::apiConfig).toObject().toVariantMap();
|
|
||||||
map.insert(newServerConfig.value(configKey::apiConfig).toObject().toVariantMap());
|
|
||||||
auto apiConfig = QJsonObject::fromVariantMap(map);
|
|
||||||
|
|
||||||
if (newServerConfig.value(config_key::configVersion).toInt() == apiDefs::ConfigSource::AmneziaGateway) {
|
|
||||||
apiConfig.insert(configKey::serviceInfo, QJsonDocument::fromJson(apiResponseBody).object().value(configKey::serviceInfo).toObject());
|
|
||||||
}
|
|
||||||
|
|
||||||
serverConfig[configKey::apiConfig] = apiConfig;
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
ApiController::ApiPayloadData ApiController::generateApiPayloadData(const QString &protocol)
|
|
||||||
{
|
|
||||||
ApiController::ApiPayloadData apiPayload;
|
|
||||||
if (protocol == configKey::cloak) {
|
|
||||||
apiPayload.certRequest = OpenVpnConfigurator::createCertRequest();
|
|
||||||
} else if (protocol == configKey::awg) {
|
|
||||||
auto connData = WireguardConfigurator::genClientKeys();
|
|
||||||
apiPayload.wireGuardClientPubKey = connData.clientPubKey;
|
|
||||||
apiPayload.wireGuardClientPrivKey = connData.clientPrivKey;
|
|
||||||
}
|
|
||||||
return apiPayload;
|
|
||||||
}
|
|
||||||
|
|
||||||
QJsonObject ApiController::fillApiPayload(const QString &protocol, const ApiController::ApiPayloadData &apiPayloadData)
|
|
||||||
{
|
|
||||||
QJsonObject obj;
|
|
||||||
if (protocol == configKey::cloak) {
|
|
||||||
obj[configKey::certificate] = apiPayloadData.certRequest.request;
|
|
||||||
} else if (protocol == configKey::awg) {
|
|
||||||
obj[configKey::publicKey] = apiPayloadData.wireGuardClientPubKey;
|
|
||||||
}
|
|
||||||
|
|
||||||
obj[configKey::osVersion] = QSysInfo::productType();
|
|
||||||
obj[configKey::appVersion] = QString(APP_VERSION);
|
|
||||||
|
|
||||||
return obj;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ApiController::updateServerConfigFromApi(const QString &installationUuid, const int serverIndex, QJsonObject serverConfig)
|
|
||||||
{
|
|
||||||
#ifdef Q_OS_IOS
|
|
||||||
IosController::Instance()->requestInetAccess();
|
|
||||||
QThread::msleep(10);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (serverConfig.value(config_key::configVersion).toInt()) {
|
|
||||||
QNetworkRequest request;
|
|
||||||
request.setTransferTimeout(requestTimeoutMsecs);
|
|
||||||
request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
|
|
||||||
request.setRawHeader("Authorization", "Api-Key " + serverConfig.value(configKey::accessToken).toString().toUtf8());
|
|
||||||
QString endpoint = serverConfig.value(configKey::apiEdnpoint).toString();
|
|
||||||
request.setUrl(endpoint);
|
|
||||||
|
|
||||||
QString protocol = serverConfig.value(configKey::protocol).toString();
|
|
||||||
|
|
||||||
ApiPayloadData apiPayloadData = generateApiPayloadData(protocol);
|
|
||||||
|
|
||||||
QJsonObject apiPayload = fillApiPayload(protocol, apiPayloadData);
|
|
||||||
apiPayload[configKey::uuid] = installationUuid;
|
|
||||||
|
|
||||||
QByteArray requestBody = QJsonDocument(apiPayload).toJson();
|
|
||||||
|
|
||||||
QNetworkReply *reply = amnApp->manager()->post(request, requestBody);
|
|
||||||
|
|
||||||
QObject::connect(reply, &QNetworkReply::finished, [this, reply, protocol, apiPayloadData, serverIndex, serverConfig]() mutable {
|
|
||||||
if (reply->error() == QNetworkReply::NoError) {
|
|
||||||
auto apiResponseBody = reply->readAll();
|
|
||||||
fillServerConfig(protocol, apiPayloadData, apiResponseBody, serverConfig);
|
|
||||||
emit finished(serverConfig, serverIndex);
|
|
||||||
} else {
|
|
||||||
if (reply->error() == QNetworkReply::NetworkError::OperationCanceledError
|
|
||||||
|| reply->error() == QNetworkReply::NetworkError::TimeoutError) {
|
|
||||||
emit errorOccurred(ErrorCode::ApiConfigTimeoutError);
|
|
||||||
} else {
|
|
||||||
QString err = reply->errorString();
|
|
||||||
qDebug() << QString::fromUtf8(reply->readAll());
|
|
||||||
qDebug() << reply->error();
|
|
||||||
qDebug() << err;
|
|
||||||
qDebug() << reply->attribute(QNetworkRequest::HttpStatusCodeAttribute);
|
|
||||||
emit errorOccurred(ErrorCode::ApiConfigDownloadError);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
reply->deleteLater();
|
|
||||||
});
|
|
||||||
|
|
||||||
QObject::connect(reply, &QNetworkReply::errorOccurred,
|
|
||||||
[this, reply](QNetworkReply::NetworkError error) { qDebug() << reply->errorString() << error; });
|
|
||||||
connect(reply, &QNetworkReply::sslErrors, [this, reply](const QList<QSslError> &errors) {
|
|
||||||
qDebug().noquote() << errors;
|
|
||||||
emit errorOccurred(ErrorCode::ApiConfigSslError);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ErrorCode ApiController::getServicesList(QByteArray &responseBody)
|
|
||||||
{
|
|
||||||
GatewayController gatewayController(m_gatewayEndpoint, m_isDevEnvironment, requestTimeoutMsecs);
|
|
||||||
|
|
||||||
QJsonObject apiPayload;
|
|
||||||
apiPayload[configKey::osVersion] = QSysInfo::productType();
|
|
||||||
|
|
||||||
ErrorCode errorCode = gatewayController.post(QString("%1v1/services"), apiPayload, responseBody);
|
|
||||||
if (errorCode == ErrorCode::NoError) {
|
|
||||||
if (!responseBody.contains("services")) {
|
|
||||||
return ErrorCode::ApiServicesMissingError;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return errorCode;
|
|
||||||
}
|
|
||||||
|
|
||||||
ErrorCode ApiController::getConfigForService(const QString &installationUuid, const QString &userCountryCode, const QString &serviceType,
|
|
||||||
const QString &protocol, const QString &serverCountryCode, const QJsonObject &authData,
|
|
||||||
QJsonObject &serverConfig)
|
|
||||||
{
|
|
||||||
GatewayController gatewayController(m_gatewayEndpoint, m_isDevEnvironment, requestTimeoutMsecs);
|
|
||||||
|
|
||||||
ApiPayloadData apiPayloadData = generateApiPayloadData(protocol);
|
|
||||||
|
|
||||||
QJsonObject apiPayload = fillApiPayload(protocol, apiPayloadData);
|
|
||||||
apiPayload[configKey::userCountryCode] = userCountryCode;
|
|
||||||
if (!serverCountryCode.isEmpty()) {
|
|
||||||
apiPayload[configKey::serverCountryCode] = serverCountryCode;
|
|
||||||
}
|
|
||||||
apiPayload[configKey::serviceType] = serviceType;
|
|
||||||
apiPayload[configKey::uuid] = installationUuid;
|
|
||||||
if (!authData.isEmpty()) {
|
|
||||||
apiPayload[configKey::authData] = authData;
|
|
||||||
}
|
|
||||||
|
|
||||||
QByteArray responseBody;
|
|
||||||
ErrorCode errorCode = gatewayController.post(QString("%1v1/config"), apiPayload, responseBody);
|
|
||||||
|
|
||||||
if (errorCode == ErrorCode::NoError) {
|
|
||||||
fillServerConfig(protocol, apiPayloadData, responseBody, serverConfig);
|
|
||||||
}
|
|
||||||
|
|
||||||
return errorCode;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
|
@ -1,50 +0,0 @@
|
||||||
#ifndef APICONTROLLER_H
|
|
||||||
#define APICONTROLLER_H
|
|
||||||
|
|
||||||
#include <QObject>
|
|
||||||
|
|
||||||
#include "configurators/openvpn_configurator.h"
|
|
||||||
|
|
||||||
#ifdef Q_OS_IOS
|
|
||||||
#include "platforms/ios/ios_controller.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
class ApiController : public QObject
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
|
|
||||||
public:
|
|
||||||
explicit ApiController(const QString &gatewayEndpoint, bool isDevEnvironment, QObject *parent = nullptr);
|
|
||||||
|
|
||||||
public slots:
|
|
||||||
void updateServerConfigFromApi(const QString &installationUuid, const int serverIndex, QJsonObject serverConfig);
|
|
||||||
ErrorCode getServicesList(QByteArray &responseBody);
|
|
||||||
ErrorCode getConfigForService(const QString &installationUuid, const QString &userCountryCode, const QString &serviceType,
|
|
||||||
const QString &protocol, const QString &serverCountryCode, const QJsonObject &authData,
|
|
||||||
QJsonObject &serverConfig);
|
|
||||||
|
|
||||||
signals:
|
|
||||||
void errorOccurred(ErrorCode errorCode);
|
|
||||||
void finished(const QJsonObject &config, const int serverIndex);
|
|
||||||
|
|
||||||
private:
|
|
||||||
struct ApiPayloadData
|
|
||||||
{
|
|
||||||
OpenVpnConfigurator::ConnectionData certRequest;
|
|
||||||
|
|
||||||
QString wireGuardClientPrivKey;
|
|
||||||
QString wireGuardClientPubKey;
|
|
||||||
};
|
|
||||||
|
|
||||||
ApiPayloadData generateApiPayloadData(const QString &protocol);
|
|
||||||
QJsonObject fillApiPayload(const QString &protocol, const ApiController::ApiPayloadData &apiPayloadData);
|
|
||||||
void fillServerConfig(const QString &protocol, const ApiController::ApiPayloadData &apiPayloadData, const QByteArray &apiResponseBody,
|
|
||||||
QJsonObject &serverConfig);
|
|
||||||
QStringList getProxyUrls();
|
|
||||||
|
|
||||||
QString m_gatewayEndpoint;
|
|
||||||
QStringList m_proxyUrls;
|
|
||||||
bool m_isDevEnvironment = false;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // APICONTROLLER_H
|
|
332
client/core/controllers/coreController.cpp
Normal file
332
client/core/controllers/coreController.cpp
Normal file
|
@ -0,0 +1,332 @@
|
||||||
|
#include "coreController.h"
|
||||||
|
|
||||||
|
#if defined(Q_OS_ANDROID)
|
||||||
|
#include "core/installedAppsImageProvider.h"
|
||||||
|
#include "platforms/android/android_controller.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(Q_OS_IOS)
|
||||||
|
#include "platforms/ios/ios_controller.h"
|
||||||
|
#include <AmneziaVPN-Swift.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
CoreController::CoreController(const QSharedPointer<VpnConnection> &vpnConnection, const std::shared_ptr<Settings> &settings,
|
||||||
|
QQmlApplicationEngine *engine, QObject *parent)
|
||||||
|
: QObject(parent), m_vpnConnection(vpnConnection), m_settings(settings), m_engine(engine)
|
||||||
|
{
|
||||||
|
initModels();
|
||||||
|
initControllers();
|
||||||
|
initSignalHandlers();
|
||||||
|
|
||||||
|
initNotificationHandler();
|
||||||
|
|
||||||
|
auto locale = m_settings->getAppLanguage();
|
||||||
|
m_translator.reset(new QTranslator());
|
||||||
|
updateTranslator(locale);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CoreController::initModels()
|
||||||
|
{
|
||||||
|
m_containersModel.reset(new ContainersModel(this));
|
||||||
|
m_engine->rootContext()->setContextProperty("ContainersModel", m_containersModel.get());
|
||||||
|
|
||||||
|
m_defaultServerContainersModel.reset(new ContainersModel(this));
|
||||||
|
m_engine->rootContext()->setContextProperty("DefaultServerContainersModel", m_defaultServerContainersModel.get());
|
||||||
|
|
||||||
|
m_serversModel.reset(new ServersModel(m_settings, this));
|
||||||
|
m_engine->rootContext()->setContextProperty("ServersModel", m_serversModel.get());
|
||||||
|
|
||||||
|
m_languageModel.reset(new LanguageModel(m_settings, this));
|
||||||
|
m_engine->rootContext()->setContextProperty("LanguageModel", m_languageModel.get());
|
||||||
|
|
||||||
|
m_sitesModel.reset(new SitesModel(m_settings, this));
|
||||||
|
m_engine->rootContext()->setContextProperty("SitesModel", m_sitesModel.get());
|
||||||
|
|
||||||
|
m_appSplitTunnelingModel.reset(new AppSplitTunnelingModel(m_settings, this));
|
||||||
|
m_engine->rootContext()->setContextProperty("AppSplitTunnelingModel", m_appSplitTunnelingModel.get());
|
||||||
|
|
||||||
|
m_protocolsModel.reset(new ProtocolsModel(m_settings, this));
|
||||||
|
m_engine->rootContext()->setContextProperty("ProtocolsModel", m_protocolsModel.get());
|
||||||
|
|
||||||
|
m_openVpnConfigModel.reset(new OpenVpnConfigModel(this));
|
||||||
|
m_engine->rootContext()->setContextProperty("OpenVpnConfigModel", m_openVpnConfigModel.get());
|
||||||
|
|
||||||
|
m_shadowSocksConfigModel.reset(new ShadowSocksConfigModel(this));
|
||||||
|
m_engine->rootContext()->setContextProperty("ShadowSocksConfigModel", m_shadowSocksConfigModel.get());
|
||||||
|
|
||||||
|
m_cloakConfigModel.reset(new CloakConfigModel(this));
|
||||||
|
m_engine->rootContext()->setContextProperty("CloakConfigModel", m_cloakConfigModel.get());
|
||||||
|
|
||||||
|
m_wireGuardConfigModel.reset(new WireGuardConfigModel(this));
|
||||||
|
m_engine->rootContext()->setContextProperty("WireGuardConfigModel", m_wireGuardConfigModel.get());
|
||||||
|
|
||||||
|
m_awgConfigModel.reset(new AwgConfigModel(this));
|
||||||
|
m_engine->rootContext()->setContextProperty("AwgConfigModel", m_awgConfigModel.get());
|
||||||
|
|
||||||
|
m_xrayConfigModel.reset(new XrayConfigModel(this));
|
||||||
|
m_engine->rootContext()->setContextProperty("XrayConfigModel", m_xrayConfigModel.get());
|
||||||
|
|
||||||
|
#ifdef Q_OS_WINDOWS
|
||||||
|
m_ikev2ConfigModel.reset(new Ikev2ConfigModel(this));
|
||||||
|
m_engine->rootContext()->setContextProperty("Ikev2ConfigModel", m_ikev2ConfigModel.get());
|
||||||
|
#endif
|
||||||
|
|
||||||
|
m_sftpConfigModel.reset(new SftpConfigModel(this));
|
||||||
|
m_engine->rootContext()->setContextProperty("SftpConfigModel", m_sftpConfigModel.get());
|
||||||
|
|
||||||
|
m_socks5ConfigModel.reset(new Socks5ProxyConfigModel(this));
|
||||||
|
m_engine->rootContext()->setContextProperty("Socks5ProxyConfigModel", m_socks5ConfigModel.get());
|
||||||
|
|
||||||
|
m_clientManagementModel.reset(new ClientManagementModel(m_settings, this));
|
||||||
|
m_engine->rootContext()->setContextProperty("ClientManagementModel", m_clientManagementModel.get());
|
||||||
|
|
||||||
|
m_apiServicesModel.reset(new ApiServicesModel(this));
|
||||||
|
m_engine->rootContext()->setContextProperty("ApiServicesModel", m_apiServicesModel.get());
|
||||||
|
|
||||||
|
m_apiCountryModel.reset(new ApiCountryModel(this));
|
||||||
|
m_engine->rootContext()->setContextProperty("ApiCountryModel", m_apiCountryModel.get());
|
||||||
|
|
||||||
|
m_apiAccountInfoModel.reset(new ApiAccountInfoModel(this));
|
||||||
|
m_engine->rootContext()->setContextProperty("ApiAccountInfoModel", m_apiAccountInfoModel.get());
|
||||||
|
}
|
||||||
|
|
||||||
|
void CoreController::initControllers()
|
||||||
|
{
|
||||||
|
m_connectionController.reset(
|
||||||
|
new ConnectionController(m_serversModel, m_containersModel, m_clientManagementModel, m_vpnConnection, m_settings));
|
||||||
|
m_engine->rootContext()->setContextProperty("ConnectionController", m_connectionController.get());
|
||||||
|
|
||||||
|
m_pageController.reset(new PageController(m_serversModel, m_settings));
|
||||||
|
m_engine->rootContext()->setContextProperty("PageController", m_pageController.get());
|
||||||
|
|
||||||
|
m_focusController.reset(new FocusController(m_engine, this));
|
||||||
|
m_engine->rootContext()->setContextProperty("FocusController", m_focusController.get());
|
||||||
|
|
||||||
|
m_installController.reset(new InstallController(m_serversModel, m_containersModel, m_protocolsModel, m_clientManagementModel, m_settings));
|
||||||
|
m_engine->rootContext()->setContextProperty("InstallController", m_installController.get());
|
||||||
|
|
||||||
|
connect(m_installController.get(), &InstallController::currentContainerUpdated, m_connectionController.get(),
|
||||||
|
&ConnectionController::onCurrentContainerUpdated); // TODO remove this
|
||||||
|
|
||||||
|
m_importController.reset(new ImportController(m_serversModel, m_containersModel, m_settings));
|
||||||
|
m_engine->rootContext()->setContextProperty("ImportController", m_importController.get());
|
||||||
|
|
||||||
|
m_exportController.reset(new ExportController(m_serversModel, m_containersModel, m_clientManagementModel, m_settings));
|
||||||
|
m_engine->rootContext()->setContextProperty("ExportController", m_exportController.get());
|
||||||
|
|
||||||
|
m_settingsController.reset(
|
||||||
|
new SettingsController(m_serversModel, m_containersModel, m_languageModel, m_sitesModel, m_appSplitTunnelingModel, m_settings));
|
||||||
|
m_engine->rootContext()->setContextProperty("SettingsController", m_settingsController.get());
|
||||||
|
|
||||||
|
m_sitesController.reset(new SitesController(m_settings, m_vpnConnection, m_sitesModel));
|
||||||
|
m_engine->rootContext()->setContextProperty("SitesController", m_sitesController.get());
|
||||||
|
|
||||||
|
m_appSplitTunnelingController.reset(new AppSplitTunnelingController(m_settings, m_appSplitTunnelingModel));
|
||||||
|
m_engine->rootContext()->setContextProperty("AppSplitTunnelingController", m_appSplitTunnelingController.get());
|
||||||
|
|
||||||
|
m_systemController.reset(new SystemController(m_settings));
|
||||||
|
m_engine->rootContext()->setContextProperty("SystemController", m_systemController.get());
|
||||||
|
|
||||||
|
m_apiSettingsController.reset(new ApiSettingsController(m_serversModel, m_apiAccountInfoModel, m_apiCountryModel, m_settings));
|
||||||
|
m_engine->rootContext()->setContextProperty("ApiSettingsController", m_apiSettingsController.get());
|
||||||
|
|
||||||
|
m_apiConfigsController.reset(new ApiConfigsController(m_serversModel, m_apiServicesModel, m_settings));
|
||||||
|
m_engine->rootContext()->setContextProperty("ApiConfigsController", m_apiConfigsController.get());
|
||||||
|
}
|
||||||
|
|
||||||
|
void CoreController::initAndroidController()
|
||||||
|
{
|
||||||
|
#ifdef Q_OS_ANDROID
|
||||||
|
if (!AndroidController::initLogging()) {
|
||||||
|
qFatal("Android logging initialization failed");
|
||||||
|
}
|
||||||
|
AndroidController::instance()->setSaveLogs(m_settings->isSaveLogs());
|
||||||
|
connect(m_settings.get(), &Settings::saveLogsChanged, AndroidController::instance(), &AndroidController::setSaveLogs);
|
||||||
|
|
||||||
|
AndroidController::instance()->setScreenshotsEnabled(m_settings->isScreenshotsEnabled());
|
||||||
|
connect(m_settings.get(), &Settings::screenshotsEnabledChanged, AndroidController::instance(), &AndroidController::setScreenshotsEnabled);
|
||||||
|
|
||||||
|
connect(m_settings.get(), &Settings::serverRemoved, AndroidController::instance(), &AndroidController::resetLastServer);
|
||||||
|
|
||||||
|
connect(m_settings.get(), &Settings::settingsCleared, []() { AndroidController::instance()->resetLastServer(-1); });
|
||||||
|
|
||||||
|
connect(AndroidController::instance(), &AndroidController::initConnectionState, this, [this](Vpn::ConnectionState state) {
|
||||||
|
m_connectionController->onConnectionStateChanged(state);
|
||||||
|
if (m_vpnConnection)
|
||||||
|
m_vpnConnection->restoreConnection();
|
||||||
|
});
|
||||||
|
if (!AndroidController::instance()->initialize()) {
|
||||||
|
qFatal("Android controller initialization failed");
|
||||||
|
}
|
||||||
|
|
||||||
|
connect(AndroidController::instance(), &AndroidController::importConfigFromOutside, this, [this](QString data) {
|
||||||
|
emit m_pageController->goToPageHome();
|
||||||
|
m_importController->extractConfigFromData(data);
|
||||||
|
data.clear();
|
||||||
|
emit m_pageController->goToPageViewConfig();
|
||||||
|
});
|
||||||
|
|
||||||
|
m_engine->addImageProvider(QLatin1String("installedAppImage"), new InstalledAppsImageProvider);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void CoreController::initAppleController()
|
||||||
|
{
|
||||||
|
#ifdef Q_OS_IOS
|
||||||
|
IosController::Instance()->initialize();
|
||||||
|
connect(IosController::Instance(), &IosController::importConfigFromOutside, this, [this](QString data) {
|
||||||
|
emit m_pageController->goToPageHome();
|
||||||
|
m_importController->extractConfigFromData(data);
|
||||||
|
emit m_pageController->goToPageViewConfig();
|
||||||
|
});
|
||||||
|
|
||||||
|
connect(IosController::Instance(), &IosController::importBackupFromOutside, this, [this](QString filePath) {
|
||||||
|
emit m_pageController->goToPageHome();
|
||||||
|
m_pageController->goToPageSettingsBackup();
|
||||||
|
emit m_settingsController->importBackupFromOutside(filePath);
|
||||||
|
});
|
||||||
|
|
||||||
|
QTimer::singleShot(0, this, [this]() { AmneziaVPN::toggleScreenshots(m_settings->isScreenshotsEnabled()); });
|
||||||
|
|
||||||
|
connect(m_settings.get(), &Settings::screenshotsEnabledChanged, [](bool enabled) { AmneziaVPN::toggleScreenshots(enabled); });
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void CoreController::initSignalHandlers()
|
||||||
|
{
|
||||||
|
initApiCountryModelUpdateHandler();
|
||||||
|
initContainerModelUpdateHandler();
|
||||||
|
initAdminConfigRevokedHandler();
|
||||||
|
initConnectionErrorOccurredHandler();
|
||||||
|
initPassphraseRequestHandler();
|
||||||
|
initTranslationsUpdatedHandler();
|
||||||
|
initAutoConnectHandler();
|
||||||
|
initAmneziaDnsToggledHandler();
|
||||||
|
initPrepareConfigHandler();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CoreController::initNotificationHandler()
|
||||||
|
{
|
||||||
|
#ifndef Q_OS_ANDROID
|
||||||
|
m_notificationHandler.reset(NotificationHandler::create(nullptr));
|
||||||
|
|
||||||
|
connect(m_vpnConnection.get(), &VpnConnection::connectionStateChanged, m_notificationHandler.get(),
|
||||||
|
&NotificationHandler::setConnectionState);
|
||||||
|
|
||||||
|
connect(m_notificationHandler.get(), &NotificationHandler::raiseRequested, m_pageController.get(), &PageController::raiseMainWindow);
|
||||||
|
connect(m_notificationHandler.get(), &NotificationHandler::connectRequested, m_connectionController.get(),
|
||||||
|
static_cast<void (ConnectionController::*)()>(&ConnectionController::openConnection));
|
||||||
|
connect(m_notificationHandler.get(), &NotificationHandler::disconnectRequested, m_connectionController.get(),
|
||||||
|
&ConnectionController::closeConnection);
|
||||||
|
connect(this, &CoreController::translationsUpdated, m_notificationHandler.get(), &NotificationHandler::onTranslationsUpdated);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void CoreController::updateTranslator(const QLocale &locale)
|
||||||
|
{
|
||||||
|
if (!m_translator->isEmpty()) {
|
||||||
|
QCoreApplication::removeTranslator(m_translator.get());
|
||||||
|
}
|
||||||
|
|
||||||
|
QString strFileName = QString(":/translations/amneziavpn") + QLatin1String("_") + locale.name() + ".qm";
|
||||||
|
if (m_translator->load(strFileName)) {
|
||||||
|
if (QCoreApplication::installTranslator(m_translator.get())) {
|
||||||
|
m_settings->setAppLanguage(locale);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
m_settings->setAppLanguage(QLocale::English);
|
||||||
|
}
|
||||||
|
|
||||||
|
m_engine->retranslate();
|
||||||
|
|
||||||
|
emit translationsUpdated();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CoreController::setQmlRoot()
|
||||||
|
{
|
||||||
|
m_systemController->setQmlRoot(m_engine->rootObjects().value(0));
|
||||||
|
}
|
||||||
|
|
||||||
|
void CoreController::initApiCountryModelUpdateHandler()
|
||||||
|
{
|
||||||
|
// TODO
|
||||||
|
connect(m_serversModel.get(), &ServersModel::updateApiCountryModel, this, [this]() {
|
||||||
|
m_apiCountryModel->updateModel(m_serversModel->getProcessedServerData("apiAvailableCountries").toJsonArray(),
|
||||||
|
m_serversModel->getProcessedServerData("apiServerCountryCode").toString());
|
||||||
|
});
|
||||||
|
connect(m_serversModel.get(), &ServersModel::updateApiServicesModel, this,
|
||||||
|
[this]() { m_apiServicesModel->updateModel(m_serversModel->getProcessedServerData("apiConfig").toJsonObject()); });
|
||||||
|
}
|
||||||
|
|
||||||
|
void CoreController::initContainerModelUpdateHandler()
|
||||||
|
{
|
||||||
|
connect(m_serversModel.get(), &ServersModel::containersUpdated, m_containersModel.get(), &ContainersModel::updateModel);
|
||||||
|
connect(m_serversModel.get(), &ServersModel::defaultServerContainersUpdated, m_defaultServerContainersModel.get(),
|
||||||
|
&ContainersModel::updateModel);
|
||||||
|
m_serversModel->resetModel();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CoreController::initAdminConfigRevokedHandler()
|
||||||
|
{
|
||||||
|
connect(m_clientManagementModel.get(), &ClientManagementModel::adminConfigRevoked, m_serversModel.get(),
|
||||||
|
&ServersModel::clearCachedProfile);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CoreController::initConnectionErrorOccurredHandler()
|
||||||
|
{
|
||||||
|
connect(m_connectionController.get(), &ConnectionController::connectionErrorOccurred, this, [this](ErrorCode errorCode) {
|
||||||
|
emit m_pageController->showErrorMessage(errorCode);
|
||||||
|
emit m_vpnConnection->connectionStateChanged(Vpn::ConnectionState::Disconnected);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void CoreController::initPassphraseRequestHandler()
|
||||||
|
{
|
||||||
|
connect(m_installController.get(), &InstallController::passphraseRequestStarted, m_pageController.get(),
|
||||||
|
&PageController::showPassphraseRequestDrawer);
|
||||||
|
connect(m_pageController.get(), &PageController::passphraseRequestDrawerClosed, m_installController.get(),
|
||||||
|
&InstallController::setEncryptedPassphrase);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CoreController::initTranslationsUpdatedHandler()
|
||||||
|
{
|
||||||
|
connect(m_languageModel.get(), &LanguageModel::updateTranslations, this, &CoreController::updateTranslator);
|
||||||
|
connect(this, &CoreController::translationsUpdated, m_languageModel.get(), &LanguageModel::translationsUpdated);
|
||||||
|
connect(this, &CoreController::translationsUpdated, m_connectionController.get(), &ConnectionController::onTranslationsUpdated);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CoreController::initAutoConnectHandler()
|
||||||
|
{
|
||||||
|
if (m_settingsController->isAutoConnectEnabled() && m_serversModel->getDefaultServerIndex() >= 0) {
|
||||||
|
QTimer::singleShot(1000, this, [this]() { m_connectionController->openConnection(); });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CoreController::initAmneziaDnsToggledHandler()
|
||||||
|
{
|
||||||
|
connect(m_settingsController.get(), &SettingsController::amneziaDnsToggled, m_serversModel.get(), &ServersModel::toggleAmneziaDns);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CoreController::initPrepareConfigHandler()
|
||||||
|
{
|
||||||
|
connect(m_connectionController.get(), &ConnectionController::prepareConfig, this, [this]() {
|
||||||
|
emit m_vpnConnection->connectionStateChanged(Vpn::ConnectionState::Preparing);
|
||||||
|
|
||||||
|
if (!m_apiConfigsController->isConfigValid()) {
|
||||||
|
emit m_vpnConnection->connectionStateChanged(Vpn::ConnectionState::Disconnected);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!m_installController->isConfigValid()) {
|
||||||
|
emit m_vpnConnection->connectionStateChanged(Vpn::ConnectionState::Disconnected);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_connectionController->openConnection();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
QSharedPointer<PageController> CoreController::pageController() const
|
||||||
|
{
|
||||||
|
return m_pageController;
|
||||||
|
}
|
133
client/core/controllers/coreController.h
Normal file
133
client/core/controllers/coreController.h
Normal file
|
@ -0,0 +1,133 @@
|
||||||
|
#ifndef CORECONTROLLER_H
|
||||||
|
#define CORECONTROLLER_H
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
#include <QQmlContext>
|
||||||
|
#include <QThread>
|
||||||
|
|
||||||
|
#include "ui/controllers/api/apiConfigsController.h"
|
||||||
|
#include "ui/controllers/api/apiSettingsController.h"
|
||||||
|
#include "ui/controllers/appSplitTunnelingController.h"
|
||||||
|
#include "ui/controllers/connectionController.h"
|
||||||
|
#include "ui/controllers/exportController.h"
|
||||||
|
#include "ui/controllers/focusController.h"
|
||||||
|
#include "ui/controllers/importController.h"
|
||||||
|
#include "ui/controllers/installController.h"
|
||||||
|
#include "ui/controllers/pageController.h"
|
||||||
|
#include "ui/controllers/settingsController.h"
|
||||||
|
#include "ui/controllers/sitesController.h"
|
||||||
|
#include "ui/controllers/systemController.h"
|
||||||
|
|
||||||
|
#include "ui/models/containers_model.h"
|
||||||
|
#include "ui/models/languageModel.h"
|
||||||
|
#include "ui/models/protocols/cloakConfigModel.h"
|
||||||
|
#ifdef Q_OS_WINDOWS
|
||||||
|
#include "ui/models/protocols/ikev2ConfigModel.h"
|
||||||
|
#endif
|
||||||
|
#include "ui/models/api/apiAccountInfoModel.h"
|
||||||
|
#include "ui/models/api/apiServicesModel.h"
|
||||||
|
#include "ui/models/apiCountryModel.h"
|
||||||
|
#include "ui/models/appSplitTunnelingModel.h"
|
||||||
|
#include "ui/models/clientManagementModel.h"
|
||||||
|
#include "ui/models/protocols/awgConfigModel.h"
|
||||||
|
#include "ui/models/protocols/openvpnConfigModel.h"
|
||||||
|
#include "ui/models/protocols/shadowsocksConfigModel.h"
|
||||||
|
#include "ui/models/protocols/wireguardConfigModel.h"
|
||||||
|
#include "ui/models/protocols/xrayConfigModel.h"
|
||||||
|
#include "ui/models/protocols_model.h"
|
||||||
|
#include "ui/models/servers_model.h"
|
||||||
|
#include "ui/models/services/sftpConfigModel.h"
|
||||||
|
#include "ui/models/services/socks5ProxyConfigModel.h"
|
||||||
|
#include "ui/models/sites_model.h"
|
||||||
|
|
||||||
|
#ifndef Q_OS_ANDROID
|
||||||
|
#include "ui/notificationhandler.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
class CoreController : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit CoreController(const QSharedPointer<VpnConnection> &vpnConnection, const std::shared_ptr<Settings> &settings,
|
||||||
|
QQmlApplicationEngine *engine, QObject *parent = nullptr);
|
||||||
|
|
||||||
|
QSharedPointer<PageController> pageController() const;
|
||||||
|
void setQmlRoot();
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void translationsUpdated();
|
||||||
|
|
||||||
|
private:
|
||||||
|
void initModels();
|
||||||
|
void initControllers();
|
||||||
|
void initAndroidController();
|
||||||
|
void initAppleController();
|
||||||
|
void initSignalHandlers();
|
||||||
|
|
||||||
|
void initNotificationHandler();
|
||||||
|
|
||||||
|
void updateTranslator(const QLocale &locale);
|
||||||
|
|
||||||
|
void initApiCountryModelUpdateHandler();
|
||||||
|
void initContainerModelUpdateHandler();
|
||||||
|
void initAdminConfigRevokedHandler();
|
||||||
|
void initConnectionErrorOccurredHandler();
|
||||||
|
void initPassphraseRequestHandler();
|
||||||
|
void initTranslationsUpdatedHandler();
|
||||||
|
void initAutoConnectHandler();
|
||||||
|
void initAmneziaDnsToggledHandler();
|
||||||
|
void initPrepareConfigHandler();
|
||||||
|
|
||||||
|
QQmlApplicationEngine *m_engine {}; // TODO use parent child system here?
|
||||||
|
std::shared_ptr<Settings> m_settings;
|
||||||
|
QSharedPointer<VpnConnection> m_vpnConnection;
|
||||||
|
QSharedPointer<QTranslator> m_translator;
|
||||||
|
|
||||||
|
#ifndef Q_OS_ANDROID
|
||||||
|
QScopedPointer<NotificationHandler> m_notificationHandler;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
QMetaObject::Connection m_reloadConfigErrorOccurredConnection;
|
||||||
|
|
||||||
|
QScopedPointer<ConnectionController> m_connectionController;
|
||||||
|
QScopedPointer<FocusController> m_focusController;
|
||||||
|
QSharedPointer<PageController> m_pageController; // TODO
|
||||||
|
QScopedPointer<InstallController> m_installController;
|
||||||
|
QScopedPointer<ImportController> m_importController;
|
||||||
|
QScopedPointer<ExportController> m_exportController;
|
||||||
|
QScopedPointer<SettingsController> m_settingsController;
|
||||||
|
QScopedPointer<SitesController> m_sitesController;
|
||||||
|
QScopedPointer<SystemController> m_systemController;
|
||||||
|
QScopedPointer<AppSplitTunnelingController> m_appSplitTunnelingController;
|
||||||
|
|
||||||
|
QScopedPointer<ApiSettingsController> m_apiSettingsController;
|
||||||
|
QScopedPointer<ApiConfigsController> m_apiConfigsController;
|
||||||
|
|
||||||
|
QSharedPointer<ContainersModel> m_containersModel;
|
||||||
|
QSharedPointer<ContainersModel> m_defaultServerContainersModel;
|
||||||
|
QSharedPointer<ServersModel> m_serversModel;
|
||||||
|
QSharedPointer<LanguageModel> m_languageModel;
|
||||||
|
QSharedPointer<ProtocolsModel> m_protocolsModel;
|
||||||
|
QSharedPointer<SitesModel> m_sitesModel;
|
||||||
|
QSharedPointer<AppSplitTunnelingModel> m_appSplitTunnelingModel;
|
||||||
|
QSharedPointer<ClientManagementModel> m_clientManagementModel;
|
||||||
|
|
||||||
|
QSharedPointer<ApiServicesModel> m_apiServicesModel;
|
||||||
|
QSharedPointer<ApiCountryModel> m_apiCountryModel;
|
||||||
|
QSharedPointer<ApiAccountInfoModel> m_apiAccountInfoModel;
|
||||||
|
|
||||||
|
QScopedPointer<OpenVpnConfigModel> m_openVpnConfigModel;
|
||||||
|
QScopedPointer<ShadowSocksConfigModel> m_shadowSocksConfigModel;
|
||||||
|
QScopedPointer<CloakConfigModel> m_cloakConfigModel;
|
||||||
|
QScopedPointer<XrayConfigModel> m_xrayConfigModel;
|
||||||
|
QScopedPointer<WireGuardConfigModel> m_wireGuardConfigModel;
|
||||||
|
QScopedPointer<AwgConfigModel> m_awgConfigModel;
|
||||||
|
#ifdef Q_OS_WINDOWS
|
||||||
|
QScopedPointer<Ikev2ConfigModel> m_ikev2ConfigModel;
|
||||||
|
#endif
|
||||||
|
QScopedPointer<SftpConfigModel> m_sftpConfigModel;
|
||||||
|
QScopedPointer<Socks5ProxyConfigModel> m_socks5ConfigModel;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // CORECONTROLLER_H
|
|
@ -77,8 +77,7 @@ ErrorCode VpnConfigurationsController::createProtocolConfigString(const bool isA
|
||||||
}
|
}
|
||||||
|
|
||||||
QJsonObject VpnConfigurationsController::createVpnConfiguration(const QPair<QString, QString> &dns, const QJsonObject &serverConfig,
|
QJsonObject VpnConfigurationsController::createVpnConfiguration(const QPair<QString, QString> &dns, const QJsonObject &serverConfig,
|
||||||
const QJsonObject &containerConfig, const DockerContainer container,
|
const QJsonObject &containerConfig, const DockerContainer container)
|
||||||
ErrorCode &errorCode)
|
|
||||||
{
|
{
|
||||||
QJsonObject vpnConfiguration {};
|
QJsonObject vpnConfiguration {};
|
||||||
|
|
||||||
|
@ -103,7 +102,8 @@ QJsonObject VpnConfigurationsController::createVpnConfiguration(const QPair<QStr
|
||||||
if (container == DockerContainer::Awg || container == DockerContainer::WireGuard) {
|
if (container == DockerContainer::Awg || container == DockerContainer::WireGuard) {
|
||||||
// add mtu for old configs
|
// add mtu for old configs
|
||||||
if (vpnConfigData[config_key::mtu].toString().isEmpty()) {
|
if (vpnConfigData[config_key::mtu].toString().isEmpty()) {
|
||||||
vpnConfigData[config_key::mtu] = container == DockerContainer::Awg ? protocols::awg::defaultMtu : protocols::wireguard::defaultMtu;
|
vpnConfigData[config_key::mtu] =
|
||||||
|
container == DockerContainer::Awg ? protocols::awg::defaultMtu : protocols::wireguard::defaultMtu;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -12,7 +12,8 @@ class VpnConfigurationsController : public QObject
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
explicit VpnConfigurationsController(const std::shared_ptr<Settings> &settings, QSharedPointer<ServerController> serverController, QObject *parent = nullptr);
|
explicit VpnConfigurationsController(const std::shared_ptr<Settings> &settings, QSharedPointer<ServerController> serverController,
|
||||||
|
QObject *parent = nullptr);
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
ErrorCode createProtocolConfigForContainer(const ServerCredentials &credentials, const DockerContainer container,
|
ErrorCode createProtocolConfigForContainer(const ServerCredentials &credentials, const DockerContainer container,
|
||||||
|
@ -21,7 +22,7 @@ public slots:
|
||||||
const DockerContainer container, const QJsonObject &containerConfig, const Proto protocol,
|
const DockerContainer container, const QJsonObject &containerConfig, const Proto protocol,
|
||||||
QString &protocolConfigString);
|
QString &protocolConfigString);
|
||||||
QJsonObject createVpnConfiguration(const QPair<QString, QString> &dns, const QJsonObject &serverConfig,
|
QJsonObject createVpnConfiguration(const QPair<QString, QString> &dns, const QJsonObject &serverConfig,
|
||||||
const QJsonObject &containerConfig, const DockerContainer container, ErrorCode &errorCode);
|
const QJsonObject &containerConfig, const DockerContainer container);
|
||||||
|
|
||||||
static void updateContainerConfigAfterInstallation(const DockerContainer container, QJsonObject &containerConfig, const QString &stdOut);
|
static void updateContainerConfigAfterInstallation(const DockerContainer container, QJsonObject &containerConfig, const QString &stdOut);
|
||||||
signals:
|
signals:
|
||||||
|
|
|
@ -44,6 +44,7 @@ namespace amnezia
|
||||||
InternalError = 101,
|
InternalError = 101,
|
||||||
NotImplementedError = 102,
|
NotImplementedError = 102,
|
||||||
AmneziaServiceNotRunning = 103,
|
AmneziaServiceNotRunning = 103,
|
||||||
|
NotSupportedOnThisPlatform = 104,
|
||||||
|
|
||||||
// Server errors
|
// Server errors
|
||||||
ServerCheckFailed = 200,
|
ServerCheckFailed = 200,
|
||||||
|
@ -94,6 +95,7 @@ namespace amnezia
|
||||||
// import and install errors
|
// import and install errors
|
||||||
ImportInvalidConfigError = 900,
|
ImportInvalidConfigError = 900,
|
||||||
ImportOpenConfigError = 901,
|
ImportOpenConfigError = 901,
|
||||||
|
NoInstalledContainersError = 902,
|
||||||
|
|
||||||
// Android errors
|
// Android errors
|
||||||
AndroidError = 1000,
|
AndroidError = 1000,
|
||||||
|
|
|
@ -12,6 +12,7 @@ QString errorString(ErrorCode code) {
|
||||||
case(ErrorCode::UnknownError): errorMessage = QObject::tr("Unknown error"); break;
|
case(ErrorCode::UnknownError): errorMessage = QObject::tr("Unknown error"); break;
|
||||||
case(ErrorCode::NotImplementedError): errorMessage = QObject::tr("Function not implemented"); break;
|
case(ErrorCode::NotImplementedError): errorMessage = QObject::tr("Function not implemented"); break;
|
||||||
case(ErrorCode::AmneziaServiceNotRunning): errorMessage = QObject::tr("Background service is not running"); break;
|
case(ErrorCode::AmneziaServiceNotRunning): errorMessage = QObject::tr("Background service is not running"); break;
|
||||||
|
case(ErrorCode::NotSupportedOnThisPlatform): errorMessage = QObject::tr("The selected protocol is not supported on the current platform"); break;
|
||||||
|
|
||||||
// Server errors
|
// Server errors
|
||||||
case(ErrorCode::ServerCheckFailed): errorMessage = QObject::tr("Server check failed"); break;
|
case(ErrorCode::ServerCheckFailed): errorMessage = QObject::tr("Server check failed"); break;
|
||||||
|
@ -51,6 +52,7 @@ QString errorString(ErrorCode code) {
|
||||||
|
|
||||||
case (ErrorCode::ImportInvalidConfigError): errorMessage = QObject::tr("The config does not contain any containers and credentials for connecting to the server"); break;
|
case (ErrorCode::ImportInvalidConfigError): errorMessage = QObject::tr("The config does not contain any containers and credentials for connecting to the server"); break;
|
||||||
case (ErrorCode::ImportOpenConfigError): errorMessage = QObject::tr("Unable to open config file"); break;
|
case (ErrorCode::ImportOpenConfigError): errorMessage = QObject::tr("Unable to open config file"); break;
|
||||||
|
case(ErrorCode::NoInstalledContainersError): errorMessage = QObject::tr("VPN Protocols is not installed.\n Please install VPN container at first"); break;
|
||||||
|
|
||||||
// Android errors
|
// Android errors
|
||||||
case (ErrorCode::AndroidError): errorMessage = QObject::tr("VPN connection error"); break;
|
case (ErrorCode::AndroidError): errorMessage = QObject::tr("VPN connection error"); break;
|
||||||
|
|
|
@ -1,8 +1,13 @@
|
||||||
#include "apiConfigsController.h"
|
#include "apiConfigsController.h"
|
||||||
|
|
||||||
|
#include <QEventLoop>
|
||||||
|
|
||||||
|
#include "amnezia_application.h"
|
||||||
#include "configurators/wireguard_configurator.h"
|
#include "configurators/wireguard_configurator.h"
|
||||||
#include "core/api/apiDefs.h"
|
#include "core/api/apiDefs.h"
|
||||||
|
#include "core/api/apiUtils.h"
|
||||||
#include "core/controllers/gatewayController.h"
|
#include "core/controllers/gatewayController.h"
|
||||||
|
#include "core/networkUtilities.h"
|
||||||
#include "core/qrCodeUtils.h"
|
#include "core/qrCodeUtils.h"
|
||||||
#include "ui/controllers/systemController.h"
|
#include "ui/controllers/systemController.h"
|
||||||
#include "version.h"
|
#include "version.h"
|
||||||
|
@ -18,6 +23,7 @@ namespace
|
||||||
constexpr char accessToken[] = "api_key";
|
constexpr char accessToken[] = "api_key";
|
||||||
constexpr char certificate[] = "certificate";
|
constexpr char certificate[] = "certificate";
|
||||||
constexpr char publicKey[] = "public_key";
|
constexpr char publicKey[] = "public_key";
|
||||||
|
constexpr char protocol[] = "protocol";
|
||||||
|
|
||||||
constexpr char uuid[] = "installation_uuid";
|
constexpr char uuid[] = "installation_uuid";
|
||||||
constexpr char osVersion[] = "os_version";
|
constexpr char osVersion[] = "os_version";
|
||||||
|
@ -43,9 +49,10 @@ namespace
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ApiConfigsController::ApiConfigsController(const QSharedPointer<ServersModel> &serversModel, const std::shared_ptr<Settings> &settings,
|
ApiConfigsController::ApiConfigsController(const QSharedPointer<ServersModel> &serversModel,
|
||||||
QObject *parent)
|
const QSharedPointer<ApiServicesModel> &apiServicesModel,
|
||||||
: QObject(parent), m_serversModel(serversModel), m_settings(settings)
|
const std::shared_ptr<Settings> &settings, QObject *parent)
|
||||||
|
: QObject(parent), m_serversModel(serversModel), m_apiServicesModel(apiServicesModel), m_settings(settings)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -98,6 +105,211 @@ void ApiConfigsController::prepareVpnKeyExport()
|
||||||
emit vpnKeyExportReady();
|
emit vpnKeyExportReady();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ApiConfigsController::fillAvailableServices()
|
||||||
|
{
|
||||||
|
GatewayController gatewayController(m_settings->getGatewayEndpoint(), m_settings->isDevGatewayEnv(), apiDefs::requestTimeoutMsecs);
|
||||||
|
|
||||||
|
QJsonObject apiPayload;
|
||||||
|
apiPayload[configKey::osVersion] = QSysInfo::productType();
|
||||||
|
|
||||||
|
QByteArray responseBody;
|
||||||
|
ErrorCode errorCode = gatewayController.post(QString("%1v1/services"), apiPayload, responseBody);
|
||||||
|
if (errorCode == ErrorCode::NoError) {
|
||||||
|
if (!responseBody.contains("services")) {
|
||||||
|
errorCode = ErrorCode::ApiServicesMissingError;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (errorCode != ErrorCode::NoError) {
|
||||||
|
emit errorOccurred(errorCode);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
QJsonObject data = QJsonDocument::fromJson(responseBody).object();
|
||||||
|
m_apiServicesModel->updateModel(data);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ApiConfigsController::importServiceFromGateway()
|
||||||
|
{
|
||||||
|
if (m_serversModel->isServerFromApiAlreadyExists(m_apiServicesModel->getCountryCode(), m_apiServicesModel->getSelectedServiceType(),
|
||||||
|
m_apiServicesModel->getSelectedServiceProtocol())) {
|
||||||
|
emit errorOccurred(ErrorCode::ApiConfigAlreadyAdded);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
GatewayController gatewayController(m_settings->getGatewayEndpoint(), m_settings->isDevGatewayEnv(), apiDefs::requestTimeoutMsecs);
|
||||||
|
|
||||||
|
auto installationUuid = m_settings->getInstallationUuid(true);
|
||||||
|
auto userCountryCode = m_apiServicesModel->getCountryCode();
|
||||||
|
auto serviceType = m_apiServicesModel->getSelectedServiceType();
|
||||||
|
auto serviceProtocol = m_apiServicesModel->getSelectedServiceProtocol();
|
||||||
|
|
||||||
|
ApiPayloadData apiPayloadData = generateApiPayloadData(serviceProtocol);
|
||||||
|
|
||||||
|
QJsonObject apiPayload = fillApiPayload(serviceProtocol, apiPayloadData);
|
||||||
|
apiPayload[configKey::userCountryCode] = userCountryCode;
|
||||||
|
apiPayload[configKey::serviceType] = serviceType;
|
||||||
|
apiPayload[configKey::uuid] = installationUuid;
|
||||||
|
|
||||||
|
QByteArray responseBody;
|
||||||
|
ErrorCode errorCode = gatewayController.post(QString("%1v1/config"), apiPayload, responseBody);
|
||||||
|
|
||||||
|
QJsonObject serverConfig;
|
||||||
|
if (errorCode == ErrorCode::NoError) {
|
||||||
|
fillServerConfig(serviceProtocol, apiPayloadData, responseBody, serverConfig);
|
||||||
|
|
||||||
|
QJsonObject apiConfig = serverConfig.value(configKey::apiConfig).toObject();
|
||||||
|
apiConfig.insert(configKey::userCountryCode, m_apiServicesModel->getCountryCode());
|
||||||
|
apiConfig.insert(configKey::serviceType, m_apiServicesModel->getSelectedServiceType());
|
||||||
|
apiConfig.insert(configKey::serviceProtocol, m_apiServicesModel->getSelectedServiceProtocol());
|
||||||
|
|
||||||
|
serverConfig.insert(configKey::apiConfig, apiConfig);
|
||||||
|
|
||||||
|
m_serversModel->addServer(serverConfig);
|
||||||
|
emit installServerFromApiFinished(tr("%1 installed successfully.").arg(m_apiServicesModel->getSelectedServiceName()));
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
emit errorOccurred(errorCode);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ApiConfigsController::updateServiceFromGateway(const int serverIndex, const QString &newCountryCode, const QString &newCountryName,
|
||||||
|
bool reloadServiceConfig)
|
||||||
|
{
|
||||||
|
GatewayController gatewayController(m_settings->getGatewayEndpoint(), m_settings->isDevGatewayEnv(), apiDefs::requestTimeoutMsecs);
|
||||||
|
|
||||||
|
auto serverConfig = m_serversModel->getServerConfig(serverIndex);
|
||||||
|
auto apiConfig = serverConfig.value(configKey::apiConfig).toObject();
|
||||||
|
auto authData = serverConfig.value(configKey::authData).toObject();
|
||||||
|
|
||||||
|
auto installationUuid = m_settings->getInstallationUuid(true);
|
||||||
|
auto userCountryCode = apiConfig.value(configKey::userCountryCode).toString();
|
||||||
|
auto serviceType = apiConfig.value(configKey::serviceType).toString();
|
||||||
|
auto serviceProtocol = apiConfig.value(configKey::serviceProtocol).toString();
|
||||||
|
|
||||||
|
ApiPayloadData apiPayloadData = generateApiPayloadData(serviceProtocol);
|
||||||
|
|
||||||
|
QJsonObject apiPayload = fillApiPayload(serviceProtocol, apiPayloadData);
|
||||||
|
apiPayload[configKey::userCountryCode] = userCountryCode;
|
||||||
|
apiPayload[configKey::serviceType] = serviceType;
|
||||||
|
apiPayload[configKey::uuid] = installationUuid;
|
||||||
|
|
||||||
|
if (!newCountryCode.isEmpty()) {
|
||||||
|
apiPayload[configKey::serverCountryCode] = newCountryCode;
|
||||||
|
}
|
||||||
|
if (!authData.isEmpty()) {
|
||||||
|
apiPayload[configKey::authData] = authData;
|
||||||
|
}
|
||||||
|
|
||||||
|
QByteArray responseBody;
|
||||||
|
ErrorCode errorCode = gatewayController.post(QString("%1v1/config"), apiPayload, responseBody);
|
||||||
|
|
||||||
|
QJsonObject newServerConfig;
|
||||||
|
if (errorCode == ErrorCode::NoError) {
|
||||||
|
fillServerConfig(serviceProtocol, apiPayloadData, responseBody, newServerConfig);
|
||||||
|
|
||||||
|
QJsonObject newApiConfig = newServerConfig.value(configKey::apiConfig).toObject();
|
||||||
|
newApiConfig.insert(configKey::userCountryCode, apiConfig.value(configKey::userCountryCode));
|
||||||
|
newApiConfig.insert(configKey::serviceType, apiConfig.value(configKey::serviceType));
|
||||||
|
newApiConfig.insert(configKey::serviceProtocol, apiConfig.value(configKey::serviceProtocol));
|
||||||
|
|
||||||
|
newServerConfig.insert(configKey::apiConfig, newApiConfig);
|
||||||
|
newServerConfig.insert(configKey::authData, authData);
|
||||||
|
|
||||||
|
m_serversModel->editServer(newServerConfig, serverIndex);
|
||||||
|
if (reloadServiceConfig) {
|
||||||
|
emit reloadServerFromApiFinished(tr("API config reloaded"));
|
||||||
|
} else if (newCountryName.isEmpty()) {
|
||||||
|
emit updateServerFromApiFinished();
|
||||||
|
} else {
|
||||||
|
emit changeApiCountryFinished(tr("Successfully changed the country of connection to %1").arg(newCountryName));
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
emit errorOccurred(errorCode);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ApiConfigsController::updateServiceFromTelegram(const int serverIndex)
|
||||||
|
{
|
||||||
|
auto serverConfig = m_serversModel->getServerConfig(serverIndex);
|
||||||
|
auto installationUuid = m_settings->getInstallationUuid(true);
|
||||||
|
|
||||||
|
#ifdef Q_OS_IOS
|
||||||
|
IosController::Instance()->requestInetAccess();
|
||||||
|
QThread::msleep(10);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (serverConfig.value(config_key::configVersion).toInt()) {
|
||||||
|
QNetworkRequest request;
|
||||||
|
request.setTransferTimeout(apiDefs::requestTimeoutMsecs);
|
||||||
|
request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
|
||||||
|
request.setRawHeader("Authorization", "Api-Key " + serverConfig.value(configKey::accessToken).toString().toUtf8());
|
||||||
|
QString endpoint = serverConfig.value(configKey::apiEdnpoint).toString();
|
||||||
|
request.setUrl(endpoint);
|
||||||
|
|
||||||
|
QString protocol = serverConfig.value(configKey::protocol).toString();
|
||||||
|
|
||||||
|
ApiPayloadData apiPayloadData = generateApiPayloadData(protocol);
|
||||||
|
|
||||||
|
QJsonObject apiPayload = fillApiPayload(protocol, apiPayloadData);
|
||||||
|
apiPayload[configKey::uuid] = installationUuid;
|
||||||
|
|
||||||
|
QByteArray requestBody = QJsonDocument(apiPayload).toJson();
|
||||||
|
|
||||||
|
QNetworkReply *reply = amnApp->manager()->post(request, requestBody);
|
||||||
|
|
||||||
|
QEventLoop wait;
|
||||||
|
connect(reply, &QNetworkReply::finished, &wait, &QEventLoop::quit);
|
||||||
|
|
||||||
|
QList<QSslError> sslErrors;
|
||||||
|
connect(reply, &QNetworkReply::sslErrors, [this, &sslErrors](const QList<QSslError> &errors) { sslErrors = errors; });
|
||||||
|
wait.exec();
|
||||||
|
|
||||||
|
auto errorCode = NetworkUtilities::checkNetworkReplyErrors(sslErrors, reply);
|
||||||
|
if (errorCode != ErrorCode::NoError) {
|
||||||
|
reply->deleteLater();
|
||||||
|
emit errorOccurred(errorCode);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto apiResponseBody = reply->readAll();
|
||||||
|
reply->deleteLater();
|
||||||
|
fillServerConfig(protocol, apiPayloadData, apiResponseBody, serverConfig);
|
||||||
|
m_serversModel->editServer(serverConfig, serverIndex);
|
||||||
|
emit updateServerFromApiFinished();
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ApiConfigsController::isConfigValid()
|
||||||
|
{
|
||||||
|
int serverIndex = m_serversModel->getDefaultServerIndex();
|
||||||
|
QJsonObject serverConfigObject = m_serversModel->getServerConfig(serverIndex);
|
||||||
|
auto configSource = apiUtils::getConfigSource(serverConfigObject);
|
||||||
|
|
||||||
|
if (configSource == apiDefs::ConfigSource::Telegram
|
||||||
|
&& !m_serversModel->data(serverIndex, ServersModel::Roles::HasInstalledContainers).toBool()) {
|
||||||
|
m_serversModel->removeApiConfig(serverIndex);
|
||||||
|
return updateServiceFromTelegram(serverIndex);
|
||||||
|
} else if (configSource == apiDefs::ConfigSource::AmneziaGateway
|
||||||
|
&& !m_serversModel->data(serverIndex, ServersModel::Roles::HasInstalledContainers).toBool()) {
|
||||||
|
return updateServiceFromGateway(serverIndex, "", "");
|
||||||
|
} else if (configSource && m_serversModel->isApiKeyExpired(serverIndex)) {
|
||||||
|
qDebug() << "attempt to update api config by expires_at event";
|
||||||
|
if (configSource == apiDefs::ConfigSource::Telegram) {
|
||||||
|
return updateServiceFromGateway(serverIndex, "", "");
|
||||||
|
} else {
|
||||||
|
m_serversModel->removeApiConfig(serverIndex);
|
||||||
|
return updateServiceFromTelegram(serverIndex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
ApiConfigsController::ApiPayloadData ApiConfigsController::generateApiPayloadData(const QString &protocol)
|
ApiConfigsController::ApiPayloadData ApiConfigsController::generateApiPayloadData(const QString &protocol)
|
||||||
{
|
{
|
||||||
ApiConfigsController::ApiPayloadData apiPayload;
|
ApiConfigsController::ApiPayloadData apiPayload;
|
||||||
|
@ -126,6 +338,82 @@ QJsonObject ApiConfigsController::fillApiPayload(const QString &protocol, const
|
||||||
return obj;
|
return obj;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ApiConfigsController::fillServerConfig(const QString &protocol, const ApiPayloadData &apiPayloadData,
|
||||||
|
const QByteArray &apiResponseBody, QJsonObject &serverConfig)
|
||||||
|
{
|
||||||
|
QString data = QJsonDocument::fromJson(apiResponseBody).object().value(config_key::config).toString();
|
||||||
|
|
||||||
|
data.replace("vpn://", "");
|
||||||
|
QByteArray ba = QByteArray::fromBase64(data.toUtf8(), QByteArray::Base64UrlEncoding | QByteArray::OmitTrailingEquals);
|
||||||
|
|
||||||
|
if (ba.isEmpty()) {
|
||||||
|
emit errorOccurred(ErrorCode::ApiConfigEmptyError);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
QByteArray ba_uncompressed = qUncompress(ba);
|
||||||
|
if (!ba_uncompressed.isEmpty()) {
|
||||||
|
ba = ba_uncompressed;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString configStr = ba;
|
||||||
|
if (protocol == configKey::cloak) {
|
||||||
|
configStr.replace("<key>", "<key>\n");
|
||||||
|
configStr.replace("$OPENVPN_PRIV_KEY", apiPayloadData.certRequest.privKey);
|
||||||
|
} else if (protocol == configKey::awg) {
|
||||||
|
configStr.replace("$WIREGUARD_CLIENT_PRIVATE_KEY", apiPayloadData.wireGuardClientPrivKey);
|
||||||
|
auto newServerConfig = QJsonDocument::fromJson(configStr.toUtf8()).object();
|
||||||
|
auto containers = newServerConfig.value(config_key::containers).toArray();
|
||||||
|
if (containers.isEmpty()) {
|
||||||
|
return; // todo process error
|
||||||
|
}
|
||||||
|
auto container = containers.at(0).toObject();
|
||||||
|
QString containerName = ContainerProps::containerTypeToString(DockerContainer::Awg);
|
||||||
|
auto containerConfig = container.value(containerName).toObject();
|
||||||
|
auto protocolConfig = QJsonDocument::fromJson(containerConfig.value(config_key::last_config).toString().toUtf8()).object();
|
||||||
|
containerConfig[config_key::junkPacketCount] = protocolConfig.value(config_key::junkPacketCount);
|
||||||
|
containerConfig[config_key::junkPacketMinSize] = protocolConfig.value(config_key::junkPacketMinSize);
|
||||||
|
containerConfig[config_key::junkPacketMaxSize] = protocolConfig.value(config_key::junkPacketMaxSize);
|
||||||
|
containerConfig[config_key::initPacketJunkSize] = protocolConfig.value(config_key::initPacketJunkSize);
|
||||||
|
containerConfig[config_key::responsePacketJunkSize] = protocolConfig.value(config_key::responsePacketJunkSize);
|
||||||
|
containerConfig[config_key::initPacketMagicHeader] = protocolConfig.value(config_key::initPacketMagicHeader);
|
||||||
|
containerConfig[config_key::responsePacketMagicHeader] = protocolConfig.value(config_key::responsePacketMagicHeader);
|
||||||
|
containerConfig[config_key::underloadPacketMagicHeader] = protocolConfig.value(config_key::underloadPacketMagicHeader);
|
||||||
|
containerConfig[config_key::transportPacketMagicHeader] = protocolConfig.value(config_key::transportPacketMagicHeader);
|
||||||
|
container[containerName] = containerConfig;
|
||||||
|
containers.replace(0, container);
|
||||||
|
newServerConfig[config_key::containers] = containers;
|
||||||
|
configStr = QString(QJsonDocument(newServerConfig).toJson());
|
||||||
|
}
|
||||||
|
|
||||||
|
QJsonObject newServerConfig = QJsonDocument::fromJson(configStr.toUtf8()).object();
|
||||||
|
serverConfig[config_key::dns1] = newServerConfig.value(config_key::dns1);
|
||||||
|
serverConfig[config_key::dns2] = newServerConfig.value(config_key::dns2);
|
||||||
|
serverConfig[config_key::containers] = newServerConfig.value(config_key::containers);
|
||||||
|
serverConfig[config_key::hostName] = newServerConfig.value(config_key::hostName);
|
||||||
|
|
||||||
|
if (newServerConfig.value(config_key::configVersion).toInt() == apiDefs::ConfigSource::AmneziaGateway) {
|
||||||
|
serverConfig[config_key::configVersion] = newServerConfig.value(config_key::configVersion);
|
||||||
|
serverConfig[config_key::description] = newServerConfig.value(config_key::description);
|
||||||
|
serverConfig[config_key::name] = newServerConfig.value(config_key::name);
|
||||||
|
}
|
||||||
|
|
||||||
|
auto defaultContainer = newServerConfig.value(config_key::defaultContainer).toString();
|
||||||
|
serverConfig[config_key::defaultContainer] = defaultContainer;
|
||||||
|
|
||||||
|
QVariantMap map = serverConfig.value(configKey::apiConfig).toObject().toVariantMap();
|
||||||
|
map.insert(newServerConfig.value(configKey::apiConfig).toObject().toVariantMap());
|
||||||
|
auto apiConfig = QJsonObject::fromVariantMap(map);
|
||||||
|
|
||||||
|
if (newServerConfig.value(config_key::configVersion).toInt() == apiDefs::ConfigSource::AmneziaGateway) {
|
||||||
|
apiConfig.insert(configKey::serviceInfo, QJsonDocument::fromJson(apiResponseBody).object().value(configKey::serviceInfo).toObject());
|
||||||
|
}
|
||||||
|
|
||||||
|
serverConfig[configKey::apiConfig] = apiConfig;
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
QList<QString> ApiConfigsController::getQrCodes()
|
QList<QString> ApiConfigsController::getQrCodes()
|
||||||
{
|
{
|
||||||
return m_qrCodes;
|
return m_qrCodes;
|
||||||
|
|
|
@ -4,14 +4,15 @@
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
|
|
||||||
#include "configurators/openvpn_configurator.h"
|
#include "configurators/openvpn_configurator.h"
|
||||||
|
#include "ui/models/api/apiServicesModel.h"
|
||||||
#include "ui/models/servers_model.h"
|
#include "ui/models/servers_model.h"
|
||||||
|
|
||||||
class ApiConfigsController : public QObject
|
class ApiConfigsController : public QObject
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
ApiConfigsController(const QSharedPointer<ServersModel> &serversModel, const std::shared_ptr<Settings> &settings,
|
ApiConfigsController(const QSharedPointer<ServersModel> &serversModel, const QSharedPointer<ApiServicesModel> &apiServicesModel,
|
||||||
QObject *parent = nullptr);
|
const std::shared_ptr<Settings> &settings, QObject *parent = nullptr);
|
||||||
|
|
||||||
Q_PROPERTY(QList<QString> qrCodes READ getQrCodes NOTIFY vpnKeyExportReady)
|
Q_PROPERTY(QList<QString> qrCodes READ getQrCodes NOTIFY vpnKeyExportReady)
|
||||||
Q_PROPERTY(int qrCodesCount READ getQrCodesCount NOTIFY vpnKeyExportReady)
|
Q_PROPERTY(int qrCodesCount READ getQrCodesCount NOTIFY vpnKeyExportReady)
|
||||||
|
@ -21,8 +22,22 @@ public slots:
|
||||||
// bool exportVpnKey(const QString &fileName);
|
// bool exportVpnKey(const QString &fileName);
|
||||||
void prepareVpnKeyExport();
|
void prepareVpnKeyExport();
|
||||||
|
|
||||||
|
bool fillAvailableServices();
|
||||||
|
bool importServiceFromGateway();
|
||||||
|
bool updateServiceFromGateway(const int serverIndex, const QString &newCountryCode, const QString &newCountryName,
|
||||||
|
bool reloadServiceConfig = false);
|
||||||
|
bool updateServiceFromTelegram(const int serverIndex);
|
||||||
|
|
||||||
|
bool isConfigValid();
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void errorOccurred(ErrorCode errorCode);
|
void errorOccurred(ErrorCode errorCode);
|
||||||
|
|
||||||
|
void installServerFromApiFinished(const QString &message);
|
||||||
|
void changeApiCountryFinished(const QString &message);
|
||||||
|
void reloadServerFromApiFinished(const QString &message);
|
||||||
|
void updateServerFromApiFinished();
|
||||||
|
|
||||||
void vpnKeyExportReady();
|
void vpnKeyExportReady();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -36,6 +51,8 @@ private:
|
||||||
|
|
||||||
ApiPayloadData generateApiPayloadData(const QString &protocol);
|
ApiPayloadData generateApiPayloadData(const QString &protocol);
|
||||||
QJsonObject fillApiPayload(const QString &protocol, const ApiPayloadData &apiPayloadData);
|
QJsonObject fillApiPayload(const QString &protocol, const ApiPayloadData &apiPayloadData);
|
||||||
|
void fillServerConfig(const QString &protocol, const ApiPayloadData &apiPayloadData, const QByteArray &apiResponseBody,
|
||||||
|
QJsonObject &serverConfig);
|
||||||
|
|
||||||
QList<QString> getQrCodes();
|
QList<QString> getQrCodes();
|
||||||
int getQrCodesCount();
|
int getQrCodesCount();
|
||||||
|
@ -43,6 +60,7 @@ private:
|
||||||
QList<QString> m_qrCodes;
|
QList<QString> m_qrCodes;
|
||||||
|
|
||||||
QSharedPointer<ServersModel> m_serversModel;
|
QSharedPointer<ServersModel> m_serversModel;
|
||||||
|
QSharedPointer<ApiServicesModel> m_apiServicesModel;
|
||||||
std::shared_ptr<Settings> m_settings;
|
std::shared_ptr<Settings> m_settings;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -5,10 +5,8 @@
|
||||||
#else
|
#else
|
||||||
#include <QApplication>
|
#include <QApplication>
|
||||||
#endif
|
#endif
|
||||||
#include <QtConcurrent>
|
|
||||||
|
|
||||||
#include "core/controllers/vpnConfigurationController.h"
|
#include "core/controllers/vpnConfigurationController.h"
|
||||||
#include "core/api/apiDefs.h"
|
|
||||||
#include "version.h"
|
#include "version.h"
|
||||||
|
|
||||||
ConnectionController::ConnectionController(const QSharedPointer<ServersModel> &serversModel,
|
ConnectionController::ConnectionController(const QSharedPointer<ServersModel> &serversModel,
|
||||||
|
@ -27,7 +25,7 @@ ConnectionController::ConnectionController(const QSharedPointer<ServersModel> &s
|
||||||
connect(this, &ConnectionController::connectToVpn, m_vpnConnection.get(), &VpnConnection::connectToVpn, Qt::QueuedConnection);
|
connect(this, &ConnectionController::connectToVpn, m_vpnConnection.get(), &VpnConnection::connectToVpn, Qt::QueuedConnection);
|
||||||
connect(this, &ConnectionController::disconnectFromVpn, m_vpnConnection.get(), &VpnConnection::disconnectFromVpn, Qt::QueuedConnection);
|
connect(this, &ConnectionController::disconnectFromVpn, m_vpnConnection.get(), &VpnConnection::disconnectFromVpn, Qt::QueuedConnection);
|
||||||
|
|
||||||
connect(this, &ConnectionController::configFromApiUpdated, this, &ConnectionController::continueConnection);
|
connect(this, &ConnectionController::connectButtonClicked, this, &ConnectionController::toggleConnection, Qt::QueuedConnection);
|
||||||
|
|
||||||
m_state = Vpn::ConnectionState::Disconnected;
|
m_state = Vpn::ConnectionState::Disconnected;
|
||||||
}
|
}
|
||||||
|
@ -35,8 +33,7 @@ ConnectionController::ConnectionController(const QSharedPointer<ServersModel> &s
|
||||||
void ConnectionController::openConnection()
|
void ConnectionController::openConnection()
|
||||||
{
|
{
|
||||||
#if !defined(Q_OS_ANDROID) && !defined(Q_OS_IOS)
|
#if !defined(Q_OS_ANDROID) && !defined(Q_OS_IOS)
|
||||||
if (!Utils::processIsRunning(Utils::executable(SERVICE_NAME, false), true))
|
if (!Utils::processIsRunning(Utils::executable(SERVICE_NAME, false), true)) {
|
||||||
{
|
|
||||||
emit connectionErrorOccurred(ErrorCode::AmneziaServiceNotRunning);
|
emit connectionErrorOccurred(ErrorCode::AmneziaServiceNotRunning);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -44,26 +41,24 @@ void ConnectionController::openConnection()
|
||||||
|
|
||||||
int serverIndex = m_serversModel->getDefaultServerIndex();
|
int serverIndex = m_serversModel->getDefaultServerIndex();
|
||||||
QJsonObject serverConfig = m_serversModel->getServerConfig(serverIndex);
|
QJsonObject serverConfig = m_serversModel->getServerConfig(serverIndex);
|
||||||
auto configVersion = serverConfig.value(config_key::configVersion).toInt();
|
|
||||||
|
|
||||||
emit m_vpnConnection->connectionStateChanged(Vpn::ConnectionState::Preparing);
|
DockerContainer container = qvariant_cast<DockerContainer>(m_serversModel->data(serverIndex, ServersModel::Roles::DefaultContainerRole));
|
||||||
|
|
||||||
if (configVersion == apiDefs::ConfigSource::Telegram
|
if (!m_containersModel->isSupportedByCurrentPlatform(container)) {
|
||||||
&& !m_serversModel->data(serverIndex, ServersModel::Roles::HasInstalledContainers).toBool()) {
|
emit connectionErrorOccurred(ErrorCode::NotSupportedOnThisPlatform);
|
||||||
emit updateApiConfigFromTelegram();
|
return;
|
||||||
} else if (configVersion == apiDefs::ConfigSource::AmneziaGateway
|
|
||||||
&& !m_serversModel->data(serverIndex, ServersModel::Roles::HasInstalledContainers).toBool()) {
|
|
||||||
emit updateApiConfigFromGateway();
|
|
||||||
} else if (configVersion && m_serversModel->isApiKeyExpired(serverIndex)) {
|
|
||||||
qDebug() << "attempt to update api config by expires_at event";
|
|
||||||
if (configVersion == apiDefs::ConfigSource::Telegram) {
|
|
||||||
emit updateApiConfigFromTelegram();
|
|
||||||
} else {
|
|
||||||
emit updateApiConfigFromGateway();
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
continueConnection();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QSharedPointer<ServerController> serverController(new ServerController(m_settings));
|
||||||
|
VpnConfigurationsController vpnConfigurationController(m_settings, serverController);
|
||||||
|
|
||||||
|
QJsonObject containerConfig = m_containersModel->getContainerConfig(container);
|
||||||
|
ServerCredentials credentials = m_serversModel->getServerCredentials(serverIndex);
|
||||||
|
|
||||||
|
auto dns = m_serversModel->getDnsPair(serverIndex);
|
||||||
|
|
||||||
|
auto vpnConfiguration = vpnConfigurationController.createVpnConfiguration(dns, serverConfig, containerConfig, container);
|
||||||
|
emit connectToVpn(serverIndex, credentials, container, vpnConfiguration);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConnectionController::closeConnection()
|
void ConnectionController::closeConnection()
|
||||||
|
@ -167,7 +162,7 @@ void ConnectionController::toggleConnection()
|
||||||
} else if (isConnected()) {
|
} else if (isConnected()) {
|
||||||
closeConnection();
|
closeConnection();
|
||||||
} else {
|
} else {
|
||||||
openConnection();
|
emit prepareConfig();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -180,98 +175,3 @@ bool ConnectionController::isConnected() const
|
||||||
{
|
{
|
||||||
return m_isConnected;
|
return m_isConnected;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ConnectionController::isProtocolConfigExists(const QJsonObject &containerConfig, const DockerContainer container)
|
|
||||||
{
|
|
||||||
for (Proto protocol : ContainerProps::protocolsForContainer(container)) {
|
|
||||||
QString protocolConfig =
|
|
||||||
containerConfig.value(ProtocolProps::protoToString(protocol)).toObject().value(config_key::last_config).toString();
|
|
||||||
|
|
||||||
if (protocolConfig.isEmpty()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ConnectionController::continueConnection()
|
|
||||||
{
|
|
||||||
int serverIndex = m_serversModel->getDefaultServerIndex();
|
|
||||||
QJsonObject serverConfig = m_serversModel->getServerConfig(serverIndex);
|
|
||||||
auto configVersion = serverConfig.value(config_key::configVersion).toInt();
|
|
||||||
|
|
||||||
if (!m_serversModel->data(serverIndex, ServersModel::Roles::HasInstalledContainers).toBool()) {
|
|
||||||
emit noInstalledContainers();
|
|
||||||
emit m_vpnConnection->connectionStateChanged(Vpn::ConnectionState::Disconnected);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
DockerContainer container = qvariant_cast<DockerContainer>(m_serversModel->data(serverIndex, ServersModel::Roles::DefaultContainerRole));
|
|
||||||
|
|
||||||
if (!m_containersModel->isSupportedByCurrentPlatform(container)) {
|
|
||||||
emit connectionErrorOccurred(tr("The selected protocol is not supported on the current platform"));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (container == DockerContainer::None) {
|
|
||||||
emit connectionErrorOccurred(tr("VPN Protocols is not installed.\n Please install VPN container at first"));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
QSharedPointer<ServerController> serverController(new ServerController(m_settings));
|
|
||||||
VpnConfigurationsController vpnConfigurationController(m_settings, serverController);
|
|
||||||
|
|
||||||
QJsonObject containerConfig = m_containersModel->getContainerConfig(container);
|
|
||||||
ServerCredentials credentials = m_serversModel->getServerCredentials(serverIndex);
|
|
||||||
ErrorCode errorCode = updateProtocolConfig(container, credentials, containerConfig, serverController);
|
|
||||||
if (errorCode != ErrorCode::NoError) {
|
|
||||||
emit connectionErrorOccurred(errorCode);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto dns = m_serversModel->getDnsPair(serverIndex);
|
|
||||||
|
|
||||||
auto vpnConfiguration = vpnConfigurationController.createVpnConfiguration(dns, serverConfig, containerConfig, container, errorCode);
|
|
||||||
if (errorCode != ErrorCode::NoError) {
|
|
||||||
emit connectionErrorOccurred(tr("unable to create configuration"));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
emit connectToVpn(serverIndex, credentials, container, vpnConfiguration);
|
|
||||||
}
|
|
||||||
|
|
||||||
ErrorCode ConnectionController::updateProtocolConfig(const DockerContainer container, const ServerCredentials &credentials,
|
|
||||||
QJsonObject &containerConfig, QSharedPointer<ServerController> serverController)
|
|
||||||
{
|
|
||||||
QFutureWatcher<ErrorCode> watcher;
|
|
||||||
|
|
||||||
if (serverController.isNull()) {
|
|
||||||
serverController.reset(new ServerController(m_settings));
|
|
||||||
}
|
|
||||||
|
|
||||||
QFuture<ErrorCode> future = QtConcurrent::run([this, container, &credentials, &containerConfig, &serverController]() {
|
|
||||||
ErrorCode errorCode = ErrorCode::NoError;
|
|
||||||
if (!isProtocolConfigExists(containerConfig, container)) {
|
|
||||||
VpnConfigurationsController vpnConfigurationController(m_settings, serverController);
|
|
||||||
errorCode = vpnConfigurationController.createProtocolConfigForContainer(credentials, container, containerConfig);
|
|
||||||
if (errorCode != ErrorCode::NoError) {
|
|
||||||
return errorCode;
|
|
||||||
}
|
|
||||||
m_serversModel->updateContainerConfig(container, containerConfig);
|
|
||||||
|
|
||||||
errorCode = m_clientManagementModel->appendClient(container, credentials, containerConfig,
|
|
||||||
QString("Admin [%1]").arg(QSysInfo::prettyProductName()), serverController);
|
|
||||||
if (errorCode != ErrorCode::NoError) {
|
|
||||||
return errorCode;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return errorCode;
|
|
||||||
});
|
|
||||||
|
|
||||||
QEventLoop wait;
|
|
||||||
connect(&watcher, &QFutureWatcher<ErrorCode>::finished, &wait, &QEventLoop::quit);
|
|
||||||
watcher.setFuture(future);
|
|
||||||
wait.exec();
|
|
||||||
|
|
||||||
return watcher.result();
|
|
||||||
}
|
|
||||||
|
|
|
@ -40,30 +40,20 @@ public slots:
|
||||||
|
|
||||||
void onTranslationsUpdated();
|
void onTranslationsUpdated();
|
||||||
|
|
||||||
ErrorCode updateProtocolConfig(const DockerContainer container, const ServerCredentials &credentials, QJsonObject &containerConfig,
|
|
||||||
QSharedPointer<ServerController> serverController = nullptr);
|
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void connectToVpn(int serverIndex, const ServerCredentials &credentials, DockerContainer container, const QJsonObject &vpnConfiguration);
|
void connectToVpn(int serverIndex, const ServerCredentials &credentials, DockerContainer container, const QJsonObject &vpnConfiguration);
|
||||||
void disconnectFromVpn();
|
void disconnectFromVpn();
|
||||||
void connectionStateChanged();
|
void connectionStateChanged();
|
||||||
|
|
||||||
void connectionErrorOccurred(const QString &errorMessage);
|
|
||||||
void connectionErrorOccurred(ErrorCode errorCode);
|
void connectionErrorOccurred(ErrorCode errorCode);
|
||||||
void reconnectWithUpdatedContainer(const QString &message);
|
void reconnectWithUpdatedContainer(const QString &message);
|
||||||
|
|
||||||
void noInstalledContainers();
|
|
||||||
|
|
||||||
void connectButtonClicked();
|
void connectButtonClicked();
|
||||||
void preparingConfig();
|
void preparingConfig();
|
||||||
|
void prepareConfig();
|
||||||
void updateApiConfigFromGateway();
|
|
||||||
void updateApiConfigFromTelegram();
|
|
||||||
void configFromApiUpdated();
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Vpn::ConnectionState getCurrentConnectionState();
|
Vpn::ConnectionState getCurrentConnectionState();
|
||||||
bool isProtocolConfigExists(const QJsonObject &containerConfig, const DockerContainer container);
|
|
||||||
|
|
||||||
void continueConnection();
|
void continueConnection();
|
||||||
|
|
||||||
|
|
|
@ -6,8 +6,8 @@
|
||||||
#include <QJsonObject>
|
#include <QJsonObject>
|
||||||
#include <QRandomGenerator>
|
#include <QRandomGenerator>
|
||||||
#include <QStandardPaths>
|
#include <QStandardPaths>
|
||||||
|
#include <QtConcurrent>
|
||||||
|
|
||||||
#include "core/controllers/apiController.h"
|
|
||||||
#include "core/controllers/serverController.h"
|
#include "core/controllers/serverController.h"
|
||||||
#include "core/controllers/vpnConfigurationController.h"
|
#include "core/controllers/vpnConfigurationController.h"
|
||||||
#include "core/networkUtilities.h"
|
#include "core/networkUtilities.h"
|
||||||
|
@ -15,6 +15,7 @@
|
||||||
#include "ui/models/protocols/awgConfigModel.h"
|
#include "ui/models/protocols/awgConfigModel.h"
|
||||||
#include "ui/models/protocols/wireguardConfigModel.h"
|
#include "ui/models/protocols/wireguardConfigModel.h"
|
||||||
#include "utilities.h"
|
#include "utilities.h"
|
||||||
|
#include "core/api/apiUtils.h"
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
|
@ -39,14 +40,12 @@ namespace
|
||||||
InstallController::InstallController(const QSharedPointer<ServersModel> &serversModel, const QSharedPointer<ContainersModel> &containersModel,
|
InstallController::InstallController(const QSharedPointer<ServersModel> &serversModel, const QSharedPointer<ContainersModel> &containersModel,
|
||||||
const QSharedPointer<ProtocolsModel> &protocolsModel,
|
const QSharedPointer<ProtocolsModel> &protocolsModel,
|
||||||
const QSharedPointer<ClientManagementModel> &clientManagementModel,
|
const QSharedPointer<ClientManagementModel> &clientManagementModel,
|
||||||
const QSharedPointer<ApiServicesModel> &apiServicesModel, const std::shared_ptr<Settings> &settings,
|
const std::shared_ptr<Settings> &settings, QObject *parent)
|
||||||
QObject *parent)
|
|
||||||
: QObject(parent),
|
: QObject(parent),
|
||||||
m_serversModel(serversModel),
|
m_serversModel(serversModel),
|
||||||
m_containersModel(containersModel),
|
m_containersModel(containersModel),
|
||||||
m_protocolModel(protocolsModel),
|
m_protocolModel(protocolsModel),
|
||||||
m_clientManagementModel(clientManagementModel),
|
m_clientManagementModel(clientManagementModel),
|
||||||
m_apiServicesModel(apiServicesModel),
|
|
||||||
m_settings(settings)
|
m_settings(settings)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
@ -773,110 +772,79 @@ void InstallController::addEmptyServer()
|
||||||
emit installServerFinished(tr("Server added successfully"));
|
emit installServerFinished(tr("Server added successfully"));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool InstallController::fillAvailableServices()
|
bool InstallController::isConfigValid()
|
||||||
{
|
{
|
||||||
ApiController apiController(m_settings->getGatewayEndpoint(), m_settings->isDevGatewayEnv());
|
int serverIndex = m_serversModel->getDefaultServerIndex();
|
||||||
|
QJsonObject serverConfigObject = m_serversModel->getServerConfig(serverIndex);
|
||||||
|
|
||||||
QByteArray responseBody;
|
if (apiUtils::isServerFromApi(serverConfigObject)) {
|
||||||
ErrorCode errorCode = apiController.getServicesList(responseBody);
|
return true;
|
||||||
if (errorCode != ErrorCode::NoError) {
|
}
|
||||||
emit installationErrorOccurred(errorCode);
|
|
||||||
|
if (!m_serversModel->data(serverIndex, ServersModel::Roles::HasInstalledContainers).toBool()) {
|
||||||
|
emit noInstalledContainers();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
QJsonObject data = QJsonDocument::fromJson(responseBody).object();
|
DockerContainer container = qvariant_cast<DockerContainer>(m_serversModel->data(serverIndex, ServersModel::Roles::DefaultContainerRole));
|
||||||
m_apiServicesModel->updateModel(data);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool InstallController::installServiceFromApi()
|
if (container == DockerContainer::None) {
|
||||||
{
|
emit installationErrorOccurred(ErrorCode::NoInstalledContainersError);
|
||||||
if (m_serversModel->isServerFromApiAlreadyExists(m_apiServicesModel->getCountryCode(), m_apiServicesModel->getSelectedServiceType(),
|
|
||||||
m_apiServicesModel->getSelectedServiceProtocol())) {
|
|
||||||
emit installationErrorOccurred(ErrorCode::ApiConfigAlreadyAdded);
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
ApiController apiController(m_settings->getGatewayEndpoint(), m_settings->isDevGatewayEnv());
|
QSharedPointer<ServerController> serverController(new ServerController(m_settings));
|
||||||
QJsonObject serverConfig;
|
VpnConfigurationsController vpnConfigurationController(m_settings, serverController);
|
||||||
|
|
||||||
ErrorCode errorCode = apiController.getConfigForService(m_settings->getInstallationUuid(true), m_apiServicesModel->getCountryCode(),
|
QJsonObject containerConfig = m_containersModel->getContainerConfig(container);
|
||||||
m_apiServicesModel->getSelectedServiceType(),
|
ServerCredentials credentials = m_serversModel->getServerCredentials(serverIndex);
|
||||||
m_apiServicesModel->getSelectedServiceProtocol(), "", QJsonObject(), serverConfig);
|
|
||||||
if (errorCode != ErrorCode::NoError) {
|
|
||||||
emit installationErrorOccurred(errorCode);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto serviceInfo = m_apiServicesModel->getSelectedServiceInfo();
|
QFutureWatcher<ErrorCode> watcher;
|
||||||
QJsonObject apiConfig = serverConfig.value(configKey::apiConfig).toObject();
|
|
||||||
apiConfig.insert(configKey::serviceInfo, serviceInfo);
|
|
||||||
apiConfig.insert(configKey::userCountryCode, m_apiServicesModel->getCountryCode());
|
|
||||||
apiConfig.insert(configKey::serviceType, m_apiServicesModel->getSelectedServiceType());
|
|
||||||
apiConfig.insert(configKey::serviceProtocol, m_apiServicesModel->getSelectedServiceProtocol());
|
|
||||||
|
|
||||||
serverConfig.insert(configKey::apiConfig, apiConfig);
|
QFuture<ErrorCode> future = QtConcurrent::run([this, container, &credentials, &containerConfig, &serverController]() {
|
||||||
|
ErrorCode errorCode = ErrorCode::NoError;
|
||||||
|
|
||||||
m_serversModel->addServer(serverConfig);
|
auto isProtocolConfigExists = [](const QJsonObject &containerConfig, const DockerContainer container) {
|
||||||
emit installServerFromApiFinished(tr("%1 installed successfully.").arg(m_apiServicesModel->getSelectedServiceName()));
|
for (Proto protocol : ContainerProps::protocolsForContainer(container)) {
|
||||||
return true;
|
QString protocolConfig =
|
||||||
}
|
containerConfig.value(ProtocolProps::protoToString(protocol)).toObject().value(config_key::last_config).toString();
|
||||||
|
|
||||||
bool InstallController::updateServiceFromApi(const int serverIndex, const QString &newCountryCode, const QString &newCountryName,
|
if (protocolConfig.isEmpty()) {
|
||||||
bool reloadServiceConfig)
|
return false;
|
||||||
{
|
}
|
||||||
ApiController apiController(m_settings->getGatewayEndpoint(), m_settings->isDevGatewayEnv());
|
}
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
auto serverConfig = m_serversModel->getServerConfig(serverIndex);
|
if (!isProtocolConfigExists(containerConfig, container)) {
|
||||||
auto apiConfig = serverConfig.value(configKey::apiConfig).toObject();
|
VpnConfigurationsController vpnConfigurationController(m_settings, serverController);
|
||||||
auto authData = serverConfig.value(configKey::authData).toObject();
|
errorCode = vpnConfigurationController.createProtocolConfigForContainer(credentials, container, containerConfig);
|
||||||
|
if (errorCode != ErrorCode::NoError) {
|
||||||
|
return errorCode;
|
||||||
|
}
|
||||||
|
m_serversModel->updateContainerConfig(container, containerConfig);
|
||||||
|
|
||||||
QJsonObject newServerConfig;
|
errorCode = m_clientManagementModel->appendClient(container, credentials, containerConfig,
|
||||||
|
QString("Admin [%1]").arg(QSysInfo::prettyProductName()), serverController);
|
||||||
ErrorCode errorCode = apiController.getConfigForService(
|
if (errorCode != ErrorCode::NoError) {
|
||||||
m_settings->getInstallationUuid(true), apiConfig.value(configKey::userCountryCode).toString(),
|
return errorCode;
|
||||||
apiConfig.value(configKey::serviceType).toString(), apiConfig.value(configKey::serviceProtocol).toString(), newCountryCode,
|
}
|
||||||
authData, newServerConfig);
|
}
|
||||||
if (errorCode != ErrorCode::NoError) {
|
return errorCode;
|
||||||
emit installationErrorOccurred(errorCode);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
QJsonObject newApiConfig = newServerConfig.value(configKey::apiConfig).toObject();
|
|
||||||
newApiConfig.insert(configKey::userCountryCode, apiConfig.value(configKey::userCountryCode));
|
|
||||||
newApiConfig.insert(configKey::serviceType, apiConfig.value(configKey::serviceType));
|
|
||||||
newApiConfig.insert(configKey::serviceProtocol, apiConfig.value(configKey::serviceProtocol));
|
|
||||||
|
|
||||||
newServerConfig.insert(configKey::apiConfig, newApiConfig);
|
|
||||||
newServerConfig.insert(configKey::authData, authData);
|
|
||||||
m_serversModel->editServer(newServerConfig, serverIndex);
|
|
||||||
|
|
||||||
if (reloadServiceConfig) {
|
|
||||||
emit reloadServerFromApiFinished(tr("API config reloaded"));
|
|
||||||
} else if (newCountryName.isEmpty()) {
|
|
||||||
emit updateServerFromApiFinished();
|
|
||||||
} else {
|
|
||||||
emit changeApiCountryFinished(tr("Successfully changed the country of connection to %1").arg(newCountryName));
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void InstallController::updateServiceFromTelegram(const int serverIndex)
|
|
||||||
{
|
|
||||||
ApiController *apiController = new ApiController(m_settings->getGatewayEndpoint(), m_settings->isDevGatewayEnv());
|
|
||||||
|
|
||||||
auto serverConfig = m_serversModel->getServerConfig(serverIndex);
|
|
||||||
|
|
||||||
apiController->updateServerConfigFromApi(m_settings->getInstallationUuid(true), serverIndex, serverConfig);
|
|
||||||
connect(apiController, &ApiController::finished, this, [this, apiController](const QJsonObject &config, const int serverIndex) {
|
|
||||||
m_serversModel->editServer(config, serverIndex);
|
|
||||||
emit updateServerFromApiFinished();
|
|
||||||
apiController->deleteLater();
|
|
||||||
});
|
});
|
||||||
connect(apiController, &ApiController::errorOccurred, this, [this, apiController](ErrorCode errorCode) {
|
|
||||||
|
QEventLoop wait;
|
||||||
|
connect(&watcher, &QFutureWatcher<ErrorCode>::finished, &wait, &QEventLoop::quit);
|
||||||
|
watcher.setFuture(future);
|
||||||
|
wait.exec();
|
||||||
|
|
||||||
|
ErrorCode errorCode = watcher.result();
|
||||||
|
|
||||||
|
if (errorCode != ErrorCode::NoError) {
|
||||||
emit installationErrorOccurred(errorCode);
|
emit installationErrorOccurred(errorCode);
|
||||||
apiController->deleteLater();
|
return false;
|
||||||
});
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool InstallController::isUpdateDockerContainerRequired(const DockerContainer container, const QJsonObject &oldConfig,
|
bool InstallController::isUpdateDockerContainerRequired(const DockerContainer container, const QJsonObject &oldConfig,
|
||||||
|
|
|
@ -10,7 +10,6 @@
|
||||||
#include "ui/models/containers_model.h"
|
#include "ui/models/containers_model.h"
|
||||||
#include "ui/models/protocols_model.h"
|
#include "ui/models/protocols_model.h"
|
||||||
#include "ui/models/servers_model.h"
|
#include "ui/models/servers_model.h"
|
||||||
#include "ui/models/apiServicesModel.h"
|
|
||||||
|
|
||||||
class InstallController : public QObject
|
class InstallController : public QObject
|
||||||
{
|
{
|
||||||
|
@ -19,7 +18,6 @@ public:
|
||||||
explicit InstallController(const QSharedPointer<ServersModel> &serversModel, const QSharedPointer<ContainersModel> &containersModel,
|
explicit InstallController(const QSharedPointer<ServersModel> &serversModel, const QSharedPointer<ContainersModel> &containersModel,
|
||||||
const QSharedPointer<ProtocolsModel> &protocolsModel,
|
const QSharedPointer<ProtocolsModel> &protocolsModel,
|
||||||
const QSharedPointer<ClientManagementModel> &clientManagementModel,
|
const QSharedPointer<ClientManagementModel> &clientManagementModel,
|
||||||
const QSharedPointer<ApiServicesModel> &apiServicesModel,
|
|
||||||
const std::shared_ptr<Settings> &settings, QObject *parent = nullptr);
|
const std::shared_ptr<Settings> &settings, QObject *parent = nullptr);
|
||||||
~InstallController();
|
~InstallController();
|
||||||
|
|
||||||
|
@ -52,21 +50,13 @@ public slots:
|
||||||
|
|
||||||
void addEmptyServer();
|
void addEmptyServer();
|
||||||
|
|
||||||
bool fillAvailableServices();
|
bool isConfigValid();
|
||||||
bool installServiceFromApi();
|
|
||||||
bool updateServiceFromApi(const int serverIndex, const QString &newCountryCode, const QString &newCountryName, bool reloadServiceConfig = false);
|
|
||||||
|
|
||||||
void updateServiceFromTelegram(const int serverIndex);
|
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void installContainerFinished(const QString &finishMessage, bool isServiceInstall);
|
void installContainerFinished(const QString &finishMessage, bool isServiceInstall);
|
||||||
void installServerFinished(const QString &finishMessage);
|
void installServerFinished(const QString &finishMessage);
|
||||||
void installServerFromApiFinished(const QString &message);
|
|
||||||
|
|
||||||
void updateContainerFinished(const QString &message);
|
void updateContainerFinished(const QString &message);
|
||||||
void updateServerFromApiFinished();
|
|
||||||
void changeApiCountryFinished(const QString &message);
|
|
||||||
void reloadServerFromApiFinished(const QString &message);
|
|
||||||
|
|
||||||
void scanServerFinished(bool isInstalledContainerFound);
|
void scanServerFinished(bool isInstalledContainerFound);
|
||||||
|
|
||||||
|
@ -91,6 +81,8 @@ signals:
|
||||||
void cachedProfileCleared(const QString &message);
|
void cachedProfileCleared(const QString &message);
|
||||||
void apiConfigRemoved(const QString &message);
|
void apiConfigRemoved(const QString &message);
|
||||||
|
|
||||||
|
void noInstalledContainers();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void installServer(const DockerContainer container, const QMap<DockerContainer, QJsonObject> &installedContainers,
|
void installServer(const DockerContainer container, const QMap<DockerContainer, QJsonObject> &installedContainers,
|
||||||
const ServerCredentials &serverCredentials, const QSharedPointer<ServerController> &serverController,
|
const ServerCredentials &serverCredentials, const QSharedPointer<ServerController> &serverController,
|
||||||
|
@ -108,7 +100,6 @@ private:
|
||||||
QSharedPointer<ContainersModel> m_containersModel;
|
QSharedPointer<ContainersModel> m_containersModel;
|
||||||
QSharedPointer<ProtocolsModel> m_protocolModel;
|
QSharedPointer<ProtocolsModel> m_protocolModel;
|
||||||
QSharedPointer<ClientManagementModel> m_clientManagementModel;
|
QSharedPointer<ClientManagementModel> m_clientManagementModel;
|
||||||
QSharedPointer<ApiServicesModel> m_apiServicesModel;
|
|
||||||
|
|
||||||
std::shared_ptr<Settings> m_settings;
|
std::shared_ptr<Settings> m_settings;
|
||||||
|
|
||||||
|
|
|
@ -261,7 +261,7 @@ void ServersModel::setProcessedServerIndex(const int index)
|
||||||
updateContainersModel();
|
updateContainersModel();
|
||||||
if (data(index, IsServerFromGatewayApiRole).toBool()) {
|
if (data(index, IsServerFromGatewayApiRole).toBool()) {
|
||||||
if (data(index, IsCountrySelectionAvailableRole).toBool()) {
|
if (data(index, IsCountrySelectionAvailableRole).toBool()) {
|
||||||
emit updateApiLanguageModel();
|
emit updateApiCountryModel();
|
||||||
}
|
}
|
||||||
emit updateApiServicesModel();
|
emit updateApiServicesModel();
|
||||||
}
|
}
|
||||||
|
|
|
@ -140,7 +140,7 @@ signals:
|
||||||
void defaultServerContainersUpdated(const QJsonArray &containers);
|
void defaultServerContainersUpdated(const QJsonArray &containers);
|
||||||
void defaultServerDefaultContainerChanged(const int containerIndex);
|
void defaultServerDefaultContainerChanged(const int containerIndex);
|
||||||
|
|
||||||
void updateApiLanguageModel();
|
void updateApiCountryModel();
|
||||||
void updateApiServicesModel();
|
void updateApiServicesModel();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -136,7 +136,7 @@ PageType {
|
||||||
PageController.showBusyIndicator(true)
|
PageController.showBusyIndicator(true)
|
||||||
var prevIndex = ApiCountryModel.currentIndex
|
var prevIndex = ApiCountryModel.currentIndex
|
||||||
ApiCountryModel.currentIndex = index
|
ApiCountryModel.currentIndex = index
|
||||||
if (!InstallController.updateServiceFromApi(ServersModel.defaultIndex, countryCode, countryName)) {
|
if (!ApiConfigsController.updateServiceFromGateway(ServersModel.defaultIndex, countryCode, countryName)) {
|
||||||
ApiCountryModel.currentIndex = prevIndex
|
ApiCountryModel.currentIndex = prevIndex
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -253,7 +253,7 @@ PageType {
|
||||||
PageController.showNotificationMessage(qsTr("Cannot reload API config during active connection"))
|
PageController.showNotificationMessage(qsTr("Cannot reload API config during active connection"))
|
||||||
} else {
|
} else {
|
||||||
PageController.showBusyIndicator(true)
|
PageController.showBusyIndicator(true)
|
||||||
InstallController.updateServiceFromApi(ServersModel.processedIndex, "", "", true)
|
ApiConfigsController.updateServiceFromGateway(ServersModel.processedIndex, "", "", true)
|
||||||
PageController.showBusyIndicator(false)
|
PageController.showBusyIndicator(false)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -138,7 +138,7 @@ PageType {
|
||||||
PageController.closePage()
|
PageController.closePage()
|
||||||
} else {
|
} else {
|
||||||
PageController.showBusyIndicator(true)
|
PageController.showBusyIndicator(true)
|
||||||
InstallController.installServiceFromApi()
|
ApiConfigsController.importServiceFromGateway()
|
||||||
PageController.showBusyIndicator(false)
|
PageController.showBusyIndicator(false)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -254,7 +254,7 @@ PageType {
|
||||||
property bool isVisible: true
|
property bool isVisible: true
|
||||||
property var handler: function() {
|
property var handler: function() {
|
||||||
PageController.showBusyIndicator(true)
|
PageController.showBusyIndicator(true)
|
||||||
var result = InstallController.fillAvailableServices()
|
var result = ApiConfigsController.fillAvailableServices()
|
||||||
PageController.showBusyIndicator(false)
|
PageController.showBusyIndicator(false)
|
||||||
if (result) {
|
if (result) {
|
||||||
PageController.goToPage(PageEnum.PageSetupWizardApiServicesList)
|
PageController.goToPage(PageEnum.PageSetupWizardApiServicesList)
|
||||||
|
|
|
@ -46,7 +46,7 @@ PageType {
|
||||||
shareConnectionDrawer.configContentHeaderText = qsTr("File with connection settings to ") + serverSelector.text
|
shareConnectionDrawer.configContentHeaderText = qsTr("File with connection settings to ") + serverSelector.text
|
||||||
|
|
||||||
shareConnectionDrawer.openTriggered()
|
shareConnectionDrawer.openTriggered()
|
||||||
shareConnectionDrawer.contentVisible = false
|
shareConnectionDrawer.contentVisible = true
|
||||||
PageController.showBusyIndicator(true)
|
PageController.showBusyIndicator(true)
|
||||||
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
|
|
|
@ -132,29 +132,6 @@ PageType {
|
||||||
PageController.showNotificationMessage(message)
|
PageController.showNotificationMessage(message)
|
||||||
}
|
}
|
||||||
|
|
||||||
function onInstallServerFromApiFinished(message) {
|
|
||||||
PageController.showBusyIndicator(false)
|
|
||||||
if (!ConnectionController.isConnected) {
|
|
||||||
ServersModel.setDefaultServerIndex(ServersModel.getServersCount() - 1);
|
|
||||||
ServersModel.processedIndex = ServersModel.defaultIndex
|
|
||||||
}
|
|
||||||
|
|
||||||
PageController.goToPageHome()
|
|
||||||
PageController.showNotificationMessage(message)
|
|
||||||
}
|
|
||||||
|
|
||||||
function onChangeApiCountryFinished(message) {
|
|
||||||
PageController.showBusyIndicator(false)
|
|
||||||
|
|
||||||
PageController.goToPageHome()
|
|
||||||
PageController.showNotificationMessage(message)
|
|
||||||
}
|
|
||||||
|
|
||||||
function onReloadServerFromApiFinished(message) {
|
|
||||||
PageController.goToPageHome()
|
|
||||||
PageController.showNotificationMessage(message)
|
|
||||||
}
|
|
||||||
|
|
||||||
function onRemoveProcessedServerFinished(finishedMessage) {
|
function onRemoveProcessedServerFinished(finishedMessage) {
|
||||||
if (!ServersModel.getServersCount()) {
|
if (!ServersModel.getServersCount()) {
|
||||||
PageController.goToPageHome()
|
PageController.goToPageHome()
|
||||||
|
@ -164,6 +141,14 @@ PageType {
|
||||||
}
|
}
|
||||||
PageController.showNotificationMessage(finishedMessage)
|
PageController.showNotificationMessage(finishedMessage)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function onNoInstalledContainers() {
|
||||||
|
PageController.setTriggeredByConnectButton(true)
|
||||||
|
|
||||||
|
ServersModel.processedIndex = ServersModel.getDefaultServerIndex()
|
||||||
|
InstallController.setShouldCreateServer(false)
|
||||||
|
PageController.goToPage(PageEnum.PageSetupWizardEasy)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Connections {
|
Connections {
|
||||||
|
@ -175,14 +160,6 @@ PageType {
|
||||||
PageController.showNotificationMessage(message)
|
PageController.showNotificationMessage(message)
|
||||||
PageController.closePage()
|
PageController.closePage()
|
||||||
}
|
}
|
||||||
|
|
||||||
function onNoInstalledContainers() {
|
|
||||||
PageController.setTriggeredByConnectButton(true)
|
|
||||||
|
|
||||||
ServersModel.processedIndex = ServersModel.getDefaultServerIndex()
|
|
||||||
InstallController.setShouldCreateServer(false)
|
|
||||||
PageController.goToPage(PageEnum.PageSetupWizardEasy)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Connections {
|
Connections {
|
||||||
|
@ -232,6 +209,37 @@ PageType {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Connections {
|
||||||
|
target: ApiConfigsController
|
||||||
|
|
||||||
|
function onErrorOccurred(error) {
|
||||||
|
PageController.showErrorMessage(error)
|
||||||
|
}
|
||||||
|
|
||||||
|
function onInstallServerFromApiFinished(message) {
|
||||||
|
PageController.showBusyIndicator(false)
|
||||||
|
if (!ConnectionController.isConnected) {
|
||||||
|
ServersModel.setDefaultServerIndex(ServersModel.getServersCount() - 1);
|
||||||
|
ServersModel.processedIndex = ServersModel.defaultIndex
|
||||||
|
}
|
||||||
|
|
||||||
|
PageController.goToPageHome()
|
||||||
|
PageController.showNotificationMessage(message)
|
||||||
|
}
|
||||||
|
|
||||||
|
function onChangeApiCountryFinished(message) {
|
||||||
|
PageController.showBusyIndicator(false)
|
||||||
|
|
||||||
|
PageController.goToPageHome()
|
||||||
|
PageController.showNotificationMessage(message)
|
||||||
|
}
|
||||||
|
|
||||||
|
function onReloadServerFromApiFinished(message) {
|
||||||
|
PageController.goToPageHome()
|
||||||
|
PageController.showNotificationMessage(message)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
StackViewType {
|
StackViewType {
|
||||||
id: tabBarStackView
|
id: tabBarStackView
|
||||||
objectName: "tabBarStackView"
|
objectName: "tabBarStackView"
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue