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()
|
||||
|
||||
qt_standard_project_setup()
|
||||
qt_add_executable(${PROJECT} MANUAL_FINALIZATION
|
||||
core/api/apiDefs.h
|
||||
core/qrCodeUtils.h core/qrCodeUtils.cpp
|
||||
)
|
||||
qt_add_executable(${PROJECT} MANUAL_FINALIZATION)
|
||||
|
||||
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)
|
||||
|
|
|
@ -14,22 +14,14 @@
|
|||
#include <QTranslator>
|
||||
|
||||
#include "logger.h"
|
||||
#include "ui/controllers/pageController.h"
|
||||
#include "ui/models/installedAppsModel.h"
|
||||
#include "version.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"
|
||||
|
||||
#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)
|
||||
{
|
||||
setQuitOnLastWindowClosed(false);
|
||||
|
@ -84,79 +76,12 @@ void AmneziaApplication::init()
|
|||
m_vpnConnection->moveToThread(&m_vpnConnectionThread);
|
||||
m_vpnConnectionThread.start();
|
||||
|
||||
initModels();
|
||||
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_coreController.reset(new CoreController(m_vpnConnection, m_settings, m_engine));
|
||||
|
||||
m_engine->addImportPath("qrc:/ui/qml/Modules/");
|
||||
m_engine->load(url);
|
||||
m_systemController->setQmlRoot(m_engine->rootObjects().value(0));
|
||||
|
||||
m_coreController->setQmlRoot();
|
||||
|
||||
bool enabled = m_settings->isSaveLogs();
|
||||
#ifndef Q_OS_ANDROID
|
||||
|
@ -168,13 +93,13 @@ void AmneziaApplication::init()
|
|||
#endif
|
||||
Logger::setServiceLogsEnabled(enabled);
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
#ifdef Q_OS_WIN //TODO
|
||||
if (m_parser.isSet("a"))
|
||||
m_pageController->showOnStartup();
|
||||
m_coreController->pageController()->showOnStartup();
|
||||
else
|
||||
emit m_pageController->raiseMainWindow();
|
||||
emit m_coreController->pageController()->raiseMainWindow();
|
||||
#else
|
||||
m_pageController->showOnStartup();
|
||||
m_coreController->pageController()->showOnStartup();
|
||||
#endif
|
||||
|
||||
// Android TextArea clipboard workaround
|
||||
|
@ -231,33 +156,6 @@ void AmneziaApplication::loadFonts()
|
|||
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()
|
||||
{
|
||||
m_parser.setApplicationDescription(APPLICATION_NAME);
|
||||
|
@ -295,7 +193,7 @@ void AmneziaApplication::startLocalServer()
|
|||
QLocalSocket *clientConnection = server->nextPendingConnection();
|
||||
clientConnection->deleteLater();
|
||||
}
|
||||
emit m_pageController->raiseMainWindow();
|
||||
emit m_coreController->pageController()->raiseMainWindow(); //TODO
|
||||
});
|
||||
}
|
||||
#endif
|
||||
|
@ -304,173 +202,3 @@ QQmlApplicationEngine *AmneziaApplication::qmlEngine() const
|
|||
{
|
||||
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>
|
||||
#endif
|
||||
|
||||
#include "core/controllers/coreController.h"
|
||||
#include "settings.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()))
|
||||
|
||||
#if defined(Q_OS_ANDROID) || defined(Q_OS_IOS)
|
||||
|
@ -70,8 +34,6 @@ public:
|
|||
void init();
|
||||
void registerTypes();
|
||||
void loadFonts();
|
||||
void loadTranslator();
|
||||
void updateTranslator(const QLocale &locale);
|
||||
bool parseCommands();
|
||||
|
||||
#if !defined(Q_OS_ANDROID) && !defined(Q_OS_IOS)
|
||||
|
@ -79,71 +41,26 @@ public:
|
|||
#endif
|
||||
|
||||
QQmlApplicationEngine *qmlEngine() const;
|
||||
QNetworkAccessManager *manager() { return m_nam; }
|
||||
|
||||
signals:
|
||||
void translationsUpdated();
|
||||
QNetworkAccessManager *manager()
|
||||
{
|
||||
return m_nam;
|
||||
}
|
||||
|
||||
private:
|
||||
void initModels();
|
||||
void initControllers();
|
||||
|
||||
QQmlApplicationEngine *m_engine {};
|
||||
std::shared_ptr<Settings> m_settings;
|
||||
|
||||
QScopedPointer<CoreController> m_coreController;
|
||||
|
||||
QSharedPointer<ContainerProps> m_containerProps;
|
||||
QSharedPointer<ProtocolProps> m_protocolProps;
|
||||
|
||||
QSharedPointer<QTranslator> m_translator;
|
||||
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;
|
||||
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;
|
||||
|
||||
QMetaObject::Connection m_reloadConfigErrorOccurredConnection;
|
||||
};
|
||||
|
||||
#endif // AMNEZIA_APPLICATION_H
|
||||
|
|
|
@ -9,7 +9,9 @@ set(HEADERS ${HEADERS}
|
|||
${CLIENT_ROOT_DIR}/core/errorstrings.h
|
||||
${CLIENT_ROOT_DIR}/core/scripts_registry.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/serverController.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/scripts_registry.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/serverController.cpp
|
||||
${CLIENT_ROOT_DIR}/core/controllers/vpnConfigurationController.cpp
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
namespace apiDefs
|
||||
{
|
||||
enum ConfigType {
|
||||
AmneziaFreeV2 = 1,
|
||||
AmneziaFreeV2 = 0,
|
||||
AmneziaFreeV3,
|
||||
AmneziaPremiumV1,
|
||||
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);
|
||||
|
||||
apiDefs::ConfigType getConfigType(const QJsonObject &serverConfigObject);
|
||||
apiDefs::ConfigSource getConfigSource(const QJsonObject &serverConfigObject);
|
||||
}
|
||||
|
||||
#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,
|
||||
const QJsonObject &containerConfig, const DockerContainer container,
|
||||
ErrorCode &errorCode)
|
||||
const QJsonObject &containerConfig, const DockerContainer container)
|
||||
{
|
||||
QJsonObject vpnConfiguration {};
|
||||
|
||||
|
@ -103,7 +102,8 @@ QJsonObject VpnConfigurationsController::createVpnConfiguration(const QPair<QStr
|
|||
if (container == DockerContainer::Awg || container == DockerContainer::WireGuard) {
|
||||
// add mtu for old configs
|
||||
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
|
||||
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:
|
||||
ErrorCode createProtocolConfigForContainer(const ServerCredentials &credentials, const DockerContainer container,
|
||||
|
@ -21,7 +22,7 @@ public slots:
|
|||
const DockerContainer container, const QJsonObject &containerConfig, const Proto protocol,
|
||||
QString &protocolConfigString);
|
||||
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);
|
||||
signals:
|
||||
|
|
|
@ -44,6 +44,7 @@ namespace amnezia
|
|||
InternalError = 101,
|
||||
NotImplementedError = 102,
|
||||
AmneziaServiceNotRunning = 103,
|
||||
NotSupportedOnThisPlatform = 104,
|
||||
|
||||
// Server errors
|
||||
ServerCheckFailed = 200,
|
||||
|
@ -94,6 +95,7 @@ namespace amnezia
|
|||
// import and install errors
|
||||
ImportInvalidConfigError = 900,
|
||||
ImportOpenConfigError = 901,
|
||||
NoInstalledContainersError = 902,
|
||||
|
||||
// Android errors
|
||||
AndroidError = 1000,
|
||||
|
|
|
@ -12,6 +12,7 @@ QString errorString(ErrorCode code) {
|
|||
case(ErrorCode::UnknownError): errorMessage = QObject::tr("Unknown error"); 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::NotSupportedOnThisPlatform): errorMessage = QObject::tr("The selected protocol is not supported on the current platform"); break;
|
||||
|
||||
// Server errors
|
||||
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::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
|
||||
case (ErrorCode::AndroidError): errorMessage = QObject::tr("VPN connection error"); break;
|
||||
|
|
|
@ -1,8 +1,13 @@
|
|||
#include "apiConfigsController.h"
|
||||
|
||||
#include <QEventLoop>
|
||||
|
||||
#include "amnezia_application.h"
|
||||
#include "configurators/wireguard_configurator.h"
|
||||
#include "core/api/apiDefs.h"
|
||||
#include "core/api/apiUtils.h"
|
||||
#include "core/controllers/gatewayController.h"
|
||||
#include "core/networkUtilities.h"
|
||||
#include "core/qrCodeUtils.h"
|
||||
#include "ui/controllers/systemController.h"
|
||||
#include "version.h"
|
||||
|
@ -18,6 +23,7 @@ namespace
|
|||
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";
|
||||
|
@ -43,9 +49,10 @@ namespace
|
|||
}
|
||||
}
|
||||
|
||||
ApiConfigsController::ApiConfigsController(const QSharedPointer<ServersModel> &serversModel, const std::shared_ptr<Settings> &settings,
|
||||
QObject *parent)
|
||||
: QObject(parent), m_serversModel(serversModel), m_settings(settings)
|
||||
ApiConfigsController::ApiConfigsController(const QSharedPointer<ServersModel> &serversModel,
|
||||
const QSharedPointer<ApiServicesModel> &apiServicesModel,
|
||||
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();
|
||||
}
|
||||
|
||||
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 apiPayload;
|
||||
|
@ -126,6 +338,82 @@ QJsonObject ApiConfigsController::fillApiPayload(const QString &protocol, const
|
|||
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()
|
||||
{
|
||||
return m_qrCodes;
|
||||
|
|
|
@ -4,14 +4,15 @@
|
|||
#include <QObject>
|
||||
|
||||
#include "configurators/openvpn_configurator.h"
|
||||
#include "ui/models/api/apiServicesModel.h"
|
||||
#include "ui/models/servers_model.h"
|
||||
|
||||
class ApiConfigsController : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
ApiConfigsController(const QSharedPointer<ServersModel> &serversModel, const std::shared_ptr<Settings> &settings,
|
||||
QObject *parent = nullptr);
|
||||
ApiConfigsController(const QSharedPointer<ServersModel> &serversModel, const QSharedPointer<ApiServicesModel> &apiServicesModel,
|
||||
const std::shared_ptr<Settings> &settings, QObject *parent = nullptr);
|
||||
|
||||
Q_PROPERTY(QList<QString> qrCodes READ getQrCodes NOTIFY vpnKeyExportReady)
|
||||
Q_PROPERTY(int qrCodesCount READ getQrCodesCount NOTIFY vpnKeyExportReady)
|
||||
|
@ -21,8 +22,22 @@ public slots:
|
|||
// bool exportVpnKey(const QString &fileName);
|
||||
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:
|
||||
void errorOccurred(ErrorCode errorCode);
|
||||
|
||||
void installServerFromApiFinished(const QString &message);
|
||||
void changeApiCountryFinished(const QString &message);
|
||||
void reloadServerFromApiFinished(const QString &message);
|
||||
void updateServerFromApiFinished();
|
||||
|
||||
void vpnKeyExportReady();
|
||||
|
||||
private:
|
||||
|
@ -36,6 +51,8 @@ private:
|
|||
|
||||
ApiPayloadData generateApiPayloadData(const QString &protocol);
|
||||
QJsonObject fillApiPayload(const QString &protocol, const ApiPayloadData &apiPayloadData);
|
||||
void fillServerConfig(const QString &protocol, const ApiPayloadData &apiPayloadData, const QByteArray &apiResponseBody,
|
||||
QJsonObject &serverConfig);
|
||||
|
||||
QList<QString> getQrCodes();
|
||||
int getQrCodesCount();
|
||||
|
@ -43,6 +60,7 @@ private:
|
|||
QList<QString> m_qrCodes;
|
||||
|
||||
QSharedPointer<ServersModel> m_serversModel;
|
||||
QSharedPointer<ApiServicesModel> m_apiServicesModel;
|
||||
std::shared_ptr<Settings> m_settings;
|
||||
};
|
||||
|
||||
|
|
|
@ -5,10 +5,8 @@
|
|||
#else
|
||||
#include <QApplication>
|
||||
#endif
|
||||
#include <QtConcurrent>
|
||||
|
||||
#include "core/controllers/vpnConfigurationController.h"
|
||||
#include "core/api/apiDefs.h"
|
||||
#include "version.h"
|
||||
|
||||
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::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;
|
||||
}
|
||||
|
@ -35,8 +33,7 @@ ConnectionController::ConnectionController(const QSharedPointer<ServersModel> &s
|
|||
void ConnectionController::openConnection()
|
||||
{
|
||||
#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);
|
||||
return;
|
||||
}
|
||||
|
@ -44,26 +41,24 @@ void ConnectionController::openConnection()
|
|||
|
||||
int serverIndex = m_serversModel->getDefaultServerIndex();
|
||||
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
|
||||
&& !m_serversModel->data(serverIndex, ServersModel::Roles::HasInstalledContainers).toBool()) {
|
||||
emit updateApiConfigFromTelegram();
|
||||
} 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();
|
||||
if (!m_containersModel->isSupportedByCurrentPlatform(container)) {
|
||||
emit connectionErrorOccurred(ErrorCode::NotSupportedOnThisPlatform);
|
||||
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);
|
||||
|
||||
auto dns = m_serversModel->getDnsPair(serverIndex);
|
||||
|
||||
auto vpnConfiguration = vpnConfigurationController.createVpnConfiguration(dns, serverConfig, containerConfig, container);
|
||||
emit connectToVpn(serverIndex, credentials, container, vpnConfiguration);
|
||||
}
|
||||
|
||||
void ConnectionController::closeConnection()
|
||||
|
@ -167,7 +162,7 @@ void ConnectionController::toggleConnection()
|
|||
} else if (isConnected()) {
|
||||
closeConnection();
|
||||
} else {
|
||||
openConnection();
|
||||
emit prepareConfig();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -180,98 +175,3 @@ bool ConnectionController::isConnected() const
|
|||
{
|
||||
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();
|
||||
|
||||
ErrorCode updateProtocolConfig(const DockerContainer container, const ServerCredentials &credentials, QJsonObject &containerConfig,
|
||||
QSharedPointer<ServerController> serverController = nullptr);
|
||||
|
||||
signals:
|
||||
void connectToVpn(int serverIndex, const ServerCredentials &credentials, DockerContainer container, const QJsonObject &vpnConfiguration);
|
||||
void disconnectFromVpn();
|
||||
void connectionStateChanged();
|
||||
|
||||
void connectionErrorOccurred(const QString &errorMessage);
|
||||
void connectionErrorOccurred(ErrorCode errorCode);
|
||||
void reconnectWithUpdatedContainer(const QString &message);
|
||||
|
||||
void noInstalledContainers();
|
||||
|
||||
void connectButtonClicked();
|
||||
void preparingConfig();
|
||||
|
||||
void updateApiConfigFromGateway();
|
||||
void updateApiConfigFromTelegram();
|
||||
void configFromApiUpdated();
|
||||
void prepareConfig();
|
||||
|
||||
private:
|
||||
Vpn::ConnectionState getCurrentConnectionState();
|
||||
bool isProtocolConfigExists(const QJsonObject &containerConfig, const DockerContainer container);
|
||||
|
||||
void continueConnection();
|
||||
|
||||
|
|
|
@ -6,8 +6,8 @@
|
|||
#include <QJsonObject>
|
||||
#include <QRandomGenerator>
|
||||
#include <QStandardPaths>
|
||||
#include <QtConcurrent>
|
||||
|
||||
#include "core/controllers/apiController.h"
|
||||
#include "core/controllers/serverController.h"
|
||||
#include "core/controllers/vpnConfigurationController.h"
|
||||
#include "core/networkUtilities.h"
|
||||
|
@ -15,6 +15,7 @@
|
|||
#include "ui/models/protocols/awgConfigModel.h"
|
||||
#include "ui/models/protocols/wireguardConfigModel.h"
|
||||
#include "utilities.h"
|
||||
#include "core/api/apiUtils.h"
|
||||
|
||||
namespace
|
||||
{
|
||||
|
@ -39,14 +40,12 @@ namespace
|
|||
InstallController::InstallController(const QSharedPointer<ServersModel> &serversModel, const QSharedPointer<ContainersModel> &containersModel,
|
||||
const QSharedPointer<ProtocolsModel> &protocolsModel,
|
||||
const QSharedPointer<ClientManagementModel> &clientManagementModel,
|
||||
const QSharedPointer<ApiServicesModel> &apiServicesModel, const std::shared_ptr<Settings> &settings,
|
||||
QObject *parent)
|
||||
const std::shared_ptr<Settings> &settings, QObject *parent)
|
||||
: QObject(parent),
|
||||
m_serversModel(serversModel),
|
||||
m_containersModel(containersModel),
|
||||
m_protocolModel(protocolsModel),
|
||||
m_clientManagementModel(clientManagementModel),
|
||||
m_apiServicesModel(apiServicesModel),
|
||||
m_settings(settings)
|
||||
{
|
||||
}
|
||||
|
@ -773,110 +772,79 @@ void InstallController::addEmptyServer()
|
|||
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;
|
||||
ErrorCode errorCode = apiController.getServicesList(responseBody);
|
||||
if (errorCode != ErrorCode::NoError) {
|
||||
emit installationErrorOccurred(errorCode);
|
||||
if (apiUtils::isServerFromApi(serverConfigObject)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!m_serversModel->data(serverIndex, ServersModel::Roles::HasInstalledContainers).toBool()) {
|
||||
emit noInstalledContainers();
|
||||
return false;
|
||||
}
|
||||
|
||||
QJsonObject data = QJsonDocument::fromJson(responseBody).object();
|
||||
m_apiServicesModel->updateModel(data);
|
||||
return true;
|
||||
}
|
||||
DockerContainer container = qvariant_cast<DockerContainer>(m_serversModel->data(serverIndex, ServersModel::Roles::DefaultContainerRole));
|
||||
|
||||
bool InstallController::installServiceFromApi()
|
||||
{
|
||||
if (m_serversModel->isServerFromApiAlreadyExists(m_apiServicesModel->getCountryCode(), m_apiServicesModel->getSelectedServiceType(),
|
||||
m_apiServicesModel->getSelectedServiceProtocol())) {
|
||||
emit installationErrorOccurred(ErrorCode::ApiConfigAlreadyAdded);
|
||||
if (container == DockerContainer::None) {
|
||||
emit installationErrorOccurred(ErrorCode::NoInstalledContainersError);
|
||||
return false;
|
||||
}
|
||||
|
||||
ApiController apiController(m_settings->getGatewayEndpoint(), m_settings->isDevGatewayEnv());
|
||||
QJsonObject serverConfig;
|
||||
QSharedPointer<ServerController> serverController(new ServerController(m_settings));
|
||||
VpnConfigurationsController vpnConfigurationController(m_settings, serverController);
|
||||
|
||||
ErrorCode errorCode = apiController.getConfigForService(m_settings->getInstallationUuid(true), m_apiServicesModel->getCountryCode(),
|
||||
m_apiServicesModel->getSelectedServiceType(),
|
||||
m_apiServicesModel->getSelectedServiceProtocol(), "", QJsonObject(), serverConfig);
|
||||
if (errorCode != ErrorCode::NoError) {
|
||||
emit installationErrorOccurred(errorCode);
|
||||
return false;
|
||||
}
|
||||
QJsonObject containerConfig = m_containersModel->getContainerConfig(container);
|
||||
ServerCredentials credentials = m_serversModel->getServerCredentials(serverIndex);
|
||||
|
||||
auto serviceInfo = m_apiServicesModel->getSelectedServiceInfo();
|
||||
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());
|
||||
QFutureWatcher<ErrorCode> watcher;
|
||||
|
||||
serverConfig.insert(configKey::apiConfig, apiConfig);
|
||||
QFuture<ErrorCode> future = QtConcurrent::run([this, container, &credentials, &containerConfig, &serverController]() {
|
||||
ErrorCode errorCode = ErrorCode::NoError;
|
||||
|
||||
m_serversModel->addServer(serverConfig);
|
||||
emit installServerFromApiFinished(tr("%1 installed successfully.").arg(m_apiServicesModel->getSelectedServiceName()));
|
||||
return true;
|
||||
}
|
||||
auto 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();
|
||||
|
||||
bool InstallController::updateServiceFromApi(const int serverIndex, const QString &newCountryCode, const QString &newCountryName,
|
||||
bool reloadServiceConfig)
|
||||
{
|
||||
ApiController apiController(m_settings->getGatewayEndpoint(), m_settings->isDevGatewayEnv());
|
||||
if (protocolConfig.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
};
|
||||
|
||||
auto serverConfig = m_serversModel->getServerConfig(serverIndex);
|
||||
auto apiConfig = serverConfig.value(configKey::apiConfig).toObject();
|
||||
auto authData = serverConfig.value(configKey::authData).toObject();
|
||||
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);
|
||||
|
||||
QJsonObject newServerConfig;
|
||||
|
||||
ErrorCode errorCode = apiController.getConfigForService(
|
||||
m_settings->getInstallationUuid(true), apiConfig.value(configKey::userCountryCode).toString(),
|
||||
apiConfig.value(configKey::serviceType).toString(), apiConfig.value(configKey::serviceProtocol).toString(), newCountryCode,
|
||||
authData, newServerConfig);
|
||||
if (errorCode != ErrorCode::NoError) {
|
||||
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();
|
||||
errorCode = m_clientManagementModel->appendClient(container, credentials, containerConfig,
|
||||
QString("Admin [%1]").arg(QSysInfo::prettyProductName()), serverController);
|
||||
if (errorCode != ErrorCode::NoError) {
|
||||
return errorCode;
|
||||
}
|
||||
}
|
||||
return errorCode;
|
||||
});
|
||||
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);
|
||||
apiController->deleteLater();
|
||||
});
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool InstallController::isUpdateDockerContainerRequired(const DockerContainer container, const QJsonObject &oldConfig,
|
||||
|
|
|
@ -10,7 +10,6 @@
|
|||
#include "ui/models/containers_model.h"
|
||||
#include "ui/models/protocols_model.h"
|
||||
#include "ui/models/servers_model.h"
|
||||
#include "ui/models/apiServicesModel.h"
|
||||
|
||||
class InstallController : public QObject
|
||||
{
|
||||
|
@ -19,7 +18,6 @@ public:
|
|||
explicit InstallController(const QSharedPointer<ServersModel> &serversModel, const QSharedPointer<ContainersModel> &containersModel,
|
||||
const QSharedPointer<ProtocolsModel> &protocolsModel,
|
||||
const QSharedPointer<ClientManagementModel> &clientManagementModel,
|
||||
const QSharedPointer<ApiServicesModel> &apiServicesModel,
|
||||
const std::shared_ptr<Settings> &settings, QObject *parent = nullptr);
|
||||
~InstallController();
|
||||
|
||||
|
@ -52,21 +50,13 @@ public slots:
|
|||
|
||||
void addEmptyServer();
|
||||
|
||||
bool fillAvailableServices();
|
||||
bool installServiceFromApi();
|
||||
bool updateServiceFromApi(const int serverIndex, const QString &newCountryCode, const QString &newCountryName, bool reloadServiceConfig = false);
|
||||
|
||||
void updateServiceFromTelegram(const int serverIndex);
|
||||
bool isConfigValid();
|
||||
|
||||
signals:
|
||||
void installContainerFinished(const QString &finishMessage, bool isServiceInstall);
|
||||
void installServerFinished(const QString &finishMessage);
|
||||
void installServerFromApiFinished(const QString &message);
|
||||
|
||||
void updateContainerFinished(const QString &message);
|
||||
void updateServerFromApiFinished();
|
||||
void changeApiCountryFinished(const QString &message);
|
||||
void reloadServerFromApiFinished(const QString &message);
|
||||
|
||||
void scanServerFinished(bool isInstalledContainerFound);
|
||||
|
||||
|
@ -91,6 +81,8 @@ signals:
|
|||
void cachedProfileCleared(const QString &message);
|
||||
void apiConfigRemoved(const QString &message);
|
||||
|
||||
void noInstalledContainers();
|
||||
|
||||
private:
|
||||
void installServer(const DockerContainer container, const QMap<DockerContainer, QJsonObject> &installedContainers,
|
||||
const ServerCredentials &serverCredentials, const QSharedPointer<ServerController> &serverController,
|
||||
|
@ -108,7 +100,6 @@ private:
|
|||
QSharedPointer<ContainersModel> m_containersModel;
|
||||
QSharedPointer<ProtocolsModel> m_protocolModel;
|
||||
QSharedPointer<ClientManagementModel> m_clientManagementModel;
|
||||
QSharedPointer<ApiServicesModel> m_apiServicesModel;
|
||||
|
||||
std::shared_ptr<Settings> m_settings;
|
||||
|
||||
|
|
|
@ -261,7 +261,7 @@ void ServersModel::setProcessedServerIndex(const int index)
|
|||
updateContainersModel();
|
||||
if (data(index, IsServerFromGatewayApiRole).toBool()) {
|
||||
if (data(index, IsCountrySelectionAvailableRole).toBool()) {
|
||||
emit updateApiLanguageModel();
|
||||
emit updateApiCountryModel();
|
||||
}
|
||||
emit updateApiServicesModel();
|
||||
}
|
||||
|
|
|
@ -140,7 +140,7 @@ signals:
|
|||
void defaultServerContainersUpdated(const QJsonArray &containers);
|
||||
void defaultServerDefaultContainerChanged(const int containerIndex);
|
||||
|
||||
void updateApiLanguageModel();
|
||||
void updateApiCountryModel();
|
||||
void updateApiServicesModel();
|
||||
|
||||
private:
|
||||
|
|
|
@ -136,7 +136,7 @@ PageType {
|
|||
PageController.showBusyIndicator(true)
|
||||
var prevIndex = ApiCountryModel.currentIndex
|
||||
ApiCountryModel.currentIndex = index
|
||||
if (!InstallController.updateServiceFromApi(ServersModel.defaultIndex, countryCode, countryName)) {
|
||||
if (!ApiConfigsController.updateServiceFromGateway(ServersModel.defaultIndex, countryCode, countryName)) {
|
||||
ApiCountryModel.currentIndex = prevIndex
|
||||
}
|
||||
}
|
||||
|
|
|
@ -253,7 +253,7 @@ PageType {
|
|||
PageController.showNotificationMessage(qsTr("Cannot reload API config during active connection"))
|
||||
} else {
|
||||
PageController.showBusyIndicator(true)
|
||||
InstallController.updateServiceFromApi(ServersModel.processedIndex, "", "", true)
|
||||
ApiConfigsController.updateServiceFromGateway(ServersModel.processedIndex, "", "", true)
|
||||
PageController.showBusyIndicator(false)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -138,7 +138,7 @@ PageType {
|
|||
PageController.closePage()
|
||||
} else {
|
||||
PageController.showBusyIndicator(true)
|
||||
InstallController.installServiceFromApi()
|
||||
ApiConfigsController.importServiceFromGateway()
|
||||
PageController.showBusyIndicator(false)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -254,7 +254,7 @@ PageType {
|
|||
property bool isVisible: true
|
||||
property var handler: function() {
|
||||
PageController.showBusyIndicator(true)
|
||||
var result = InstallController.fillAvailableServices()
|
||||
var result = ApiConfigsController.fillAvailableServices()
|
||||
PageController.showBusyIndicator(false)
|
||||
if (result) {
|
||||
PageController.goToPage(PageEnum.PageSetupWizardApiServicesList)
|
||||
|
|
|
@ -46,7 +46,7 @@ PageType {
|
|||
shareConnectionDrawer.configContentHeaderText = qsTr("File with connection settings to ") + serverSelector.text
|
||||
|
||||
shareConnectionDrawer.openTriggered()
|
||||
shareConnectionDrawer.contentVisible = false
|
||||
shareConnectionDrawer.contentVisible = true
|
||||
PageController.showBusyIndicator(true)
|
||||
|
||||
switch (type) {
|
||||
|
|
|
@ -132,29 +132,6 @@ PageType {
|
|||
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) {
|
||||
if (!ServersModel.getServersCount()) {
|
||||
PageController.goToPageHome()
|
||||
|
@ -164,6 +141,14 @@ PageType {
|
|||
}
|
||||
PageController.showNotificationMessage(finishedMessage)
|
||||
}
|
||||
|
||||
function onNoInstalledContainers() {
|
||||
PageController.setTriggeredByConnectButton(true)
|
||||
|
||||
ServersModel.processedIndex = ServersModel.getDefaultServerIndex()
|
||||
InstallController.setShouldCreateServer(false)
|
||||
PageController.goToPage(PageEnum.PageSetupWizardEasy)
|
||||
}
|
||||
}
|
||||
|
||||
Connections {
|
||||
|
@ -175,14 +160,6 @@ PageType {
|
|||
PageController.showNotificationMessage(message)
|
||||
PageController.closePage()
|
||||
}
|
||||
|
||||
function onNoInstalledContainers() {
|
||||
PageController.setTriggeredByConnectButton(true)
|
||||
|
||||
ServersModel.processedIndex = ServersModel.getDefaultServerIndex()
|
||||
InstallController.setShouldCreateServer(false)
|
||||
PageController.goToPage(PageEnum.PageSetupWizardEasy)
|
||||
}
|
||||
}
|
||||
|
||||
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 {
|
||||
id: tabBarStackView
|
||||
objectName: "tabBarStackView"
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue