mirror of
https://github.com/amnezia-vpn/amnezia-client.git
synced 2026-05-08 14:33:23 +00:00
* refactor: move business logic from servers model * refactor: move containersModel initialization * refactor: added protocol ui controller and removed settings class from protocols model * refactor: moved cli management to separate controller * refactor: moved app split to separate controller * refactor: moved site split to separate controller * refactor: moved allowed dns to separate controller * refactor: moved language logic to separate ui controller * refactor: removed Settings from devices model * refactor: moved configs and services api logit to separate core controller * refactor: added a layer with a repository between the storage and controllers * refactor: use child parent system instead of smart pointers for controllers and models initialization * refactor: moved install functions from server controller to install controller * refactor: install controller refactoring * chore: renamed exportController to exportUiController * refactor: separate export controller * refactor: removed VpnConfigurationsController * chore: renamed ServerController to SshSession * refactor: replaced ServerController to SshSession * chore: moved qml controllers to separate folder * chore: include fixes * chore: moved utils from core root to core/utils * chore: include fixes * chore: rename core/utils files to camelCase foramt * chore: include fixes * chore: moved some utils to api and selfhosted folders * chore: include fixes * chore: remove unused file * chore: moved serialization folder to core/utils * chore: include fixes * chore: moved some files from client root to core/utils * chore: include fixes * chore: moved ui utils to ui/utils folder * chore: include fixes * chore: move utils from root to ui/utils * chore: include fixes * chore: moved configurators to core/configurators * chore: include fixes * refactor: moved iap logic from ui controller to core * refactor: moved remaining core logic from ApiConfigsController to SubscriptionController * chore: rename apiNewsController to apiNewsUiController * refactor: moved core logic from news ui controller to core * chore: renamed apiConfigsController to subscriptionUiController * chore: include fixes * refactor: merge ApiSettingsController with SubscriptionUiController * chore: moved ui selfhosted controllers to separate folder * chore: include fixes * chore: rename connectionController to connectiomUiController * refactor: moved core logic from connectionUiController * chore: rename settingsController to settingsUiController * refactor: move core logic from settingsUiController * refactor: moved core controller signal/slot connections to separate class * fix: newsController fixes after refactoring * chore: rename model to camelCase * chore: include fixes * chore: remove unused code * chore: move selfhosted core to separate folder * chore: include fixes * chore: rename importController to importUiController * refactor: move core logic from importUiController * chore: minor fixes * chore: remove prem v1 migration * refactor: remove openvpn over cloak and openvpn over shadowsocks * refactor: removed protocolsForContainer function * refactor: add core models * refactor: replace json with c++ structs for server config * refactor: move getDnsPair to ServerConfigUtils * feat: add admin selfhosted config export test * feat: add multi import test * refactor: use coreController for tests * feat: add few simple tests * chore: qrepos in all core controllers * feat: add test for settings * refactor: remove repo dependency from configurators * chore: moved protocols to core folder * chore: include fixes * refactor: moved containersDefs, defs, apiDefs, protocolsDefs to different places * chore: include fixes * chore: build fixes * chore: build fixes * refactor: remove q repo and interface repo * feat: add test for ui servers model and controller * chore: renamed to camelCase * chore: include fixes * refactor: moved core logic from sites ui controller * fix: fixed api config processing * fix: fixed processed server index processing * refactor: protocol models now use c++ structs instead of json configs * refactor: servers model now use c++ struct instead of json config * fix: fixed default server index processing * fix: fix logs init * fix: fix secure settings load keys * chore: build fixes * fix: fixed clear settings * fix: fixed restore backup * fix: sshSession usage * fix: fixed export functions signatures * fix: return missing part from buildContainerWorker * fix: fixed server description on page home * refactor: add container config helpers functions * refactor: c++ structs instead of json * chore: add dns protocol config struct * refactor: move config utils functions to config structs * feat: add test for selfhosted server setup * refactor: separate resources.qrc * fix: fixed server rename * chore: return nameOverriddenByUser * fix: build fixes * fix: fixed models init * refactor: cleanup models usage * fix: fixed models init * chore: cleanup connections and functions signatures * chore: cleanup updateModel calls * feat: added cache to servers repo * chore: cleanup unused functions * chore: ssxray processing * chore: remove transportProtoWithDefault and portWithDefault functions * chore: removed proto types any and l2tp * refactor: moved some constants * fix: fixed native configs export * refactor: remove json from processConfigWith functions * fix: fixed processed server index usage * fix: qml warning fixes * chore: merge fixes * chore: update tests * fix: fixed xray config processing * fix: fixed split tunneling processing * chore: rename sites controllers and model * chore: rename fixes * chore: minor fixes * chore: remove ability to load backup from "file with connection settings" button * fix: fixed api device revoke * fix: remove full model update when renaming a user * fix: fixed premium/free server rename * fix: fixed selfhosted new server install * fix: fixed updateContainer function * fix: fixed revoke for external premium configs * feat: add native configs qr processing * chore: codestyle fixes * fix: fixed admin config create * chore: again remove ability to load backup from "file with connection settings" button * chore: minor fixes * fix: fixed variables initialization * fix: fixed qml imports * fix: minor fixes * fix: fix vpnConnection function calls * feat: add buckup error handling * fix: fixed admin config revok * fix: fixed selfhosted awg installation * fix: ad visability * feat: add empty check for primary dns * chore: minor fixes
339 lines
13 KiB
C++
339 lines
13 KiB
C++
#include "coreController.h"
|
|
|
|
#include <QDirIterator>
|
|
#include <QTranslator>
|
|
#include <QTimer>
|
|
|
|
#include "core/utils/selfhosted/sshSession.h"
|
|
#include "core/controllers/selfhosted/installController.h"
|
|
#include "core/controllers/selfhosted/importController.h"
|
|
#include "core/controllers/coreSignalHandlers.h"
|
|
#include "core/models/serverConfig.h"
|
|
#include "logger.h"
|
|
#include "secureQSettings.h"
|
|
|
|
#if defined(Q_OS_ANDROID)
|
|
#include "core/utils/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, SecureQSettings* settings,
|
|
QQmlApplicationEngine *engine, QObject *parent)
|
|
: QObject(parent), m_vpnConnection(vpnConnection), m_settings(settings), m_engine(engine)
|
|
{
|
|
initRepositories();
|
|
initCoreControllers();
|
|
initModels();
|
|
initControllers();
|
|
initSignalHandlers();
|
|
|
|
initAndroidController();
|
|
initAppleController();
|
|
initLogging();
|
|
|
|
m_translator = new QTranslator(this);
|
|
if (m_appSettingsRepository) {
|
|
updateTranslator(m_appSettingsRepository->getAppLanguage());
|
|
}
|
|
}
|
|
|
|
void CoreController::setQmlContextProperty(const QString &name, QObject *value)
|
|
{
|
|
if (m_engine) {
|
|
m_engine->rootContext()->setContextProperty(name, value);
|
|
}
|
|
}
|
|
|
|
void CoreController::initModels()
|
|
{
|
|
m_containersModel = new ContainersModel(this);
|
|
setQmlContextProperty("ContainersModel", m_containersModel);
|
|
|
|
m_defaultServerContainersModel = new ContainersModel(this);
|
|
setQmlContextProperty("DefaultServerContainersModel", m_defaultServerContainersModel);
|
|
|
|
m_serversModel = new ServersModel(this);
|
|
setQmlContextProperty("ServersModel", m_serversModel);
|
|
|
|
m_languageModel = new LanguageModel(this);
|
|
setQmlContextProperty("LanguageModel", m_languageModel);
|
|
|
|
m_ipSplitTunnelingModel = new IpSplitTunnelingModel(this);
|
|
setQmlContextProperty("IpSplitTunnelingModel", m_ipSplitTunnelingModel);
|
|
|
|
m_allowedDnsModel = new AllowedDnsModel(this);
|
|
setQmlContextProperty("AllowedDnsModel", m_allowedDnsModel);
|
|
|
|
m_appSplitTunnelingModel = new AppSplitTunnelingModel(this);
|
|
setQmlContextProperty("AppSplitTunnelingModel", m_appSplitTunnelingModel);
|
|
|
|
m_protocolsModel = new ProtocolsModel(this);
|
|
setQmlContextProperty("ProtocolsModel", m_protocolsModel);
|
|
|
|
m_openVpnConfigModel = new OpenVpnConfigModel(this);
|
|
setQmlContextProperty("OpenVpnConfigModel", m_openVpnConfigModel);
|
|
|
|
m_wireGuardConfigModel = new WireGuardConfigModel(this);
|
|
setQmlContextProperty("WireGuardConfigModel", m_wireGuardConfigModel);
|
|
|
|
m_awgConfigModel = new AwgConfigModel(this);
|
|
setQmlContextProperty("AwgConfigModel", m_awgConfigModel);
|
|
|
|
m_xrayConfigModel = new XrayConfigModel(this);
|
|
setQmlContextProperty("XrayConfigModel", m_xrayConfigModel);
|
|
|
|
m_torConfigModel = new TorConfigModel(this);
|
|
setQmlContextProperty("TorConfigModel", m_torConfigModel);
|
|
|
|
#ifdef Q_OS_WINDOWS
|
|
m_ikev2ConfigModel = new Ikev2ConfigModel(this);
|
|
setQmlContextProperty("Ikev2ConfigModel", m_ikev2ConfigModel);
|
|
#endif
|
|
|
|
m_sftpConfigModel = new SftpConfigModel(this);
|
|
setQmlContextProperty("SftpConfigModel", m_sftpConfigModel);
|
|
|
|
m_socks5ConfigModel = new Socks5ProxyConfigModel(this);
|
|
setQmlContextProperty("Socks5ProxyConfigModel", m_socks5ConfigModel);
|
|
|
|
m_clientManagementModel = new ClientManagementModel(this);
|
|
setQmlContextProperty("ClientManagementModel", m_clientManagementModel);
|
|
|
|
m_apiServicesModel = new ApiServicesModel(this);
|
|
setQmlContextProperty("ApiServicesModel", m_apiServicesModel);
|
|
|
|
m_apiCountryModel = new ApiCountryModel(this);
|
|
setQmlContextProperty("ApiCountryModel", m_apiCountryModel);
|
|
|
|
m_apiSubscriptionPlansModel = new ApiSubscriptionPlansModel(this);
|
|
setQmlContextProperty("ApiSubscriptionPlansModel", m_apiSubscriptionPlansModel);
|
|
|
|
m_apiBenefitsModel = new ApiBenefitsModel(this);
|
|
setQmlContextProperty("ApiBenefitsModel", m_apiBenefitsModel);
|
|
|
|
m_apiAccountInfoModel = new ApiAccountInfoModel(this);
|
|
setQmlContextProperty("ApiAccountInfoModel", m_apiAccountInfoModel);
|
|
|
|
m_apiDevicesModel = new ApiDevicesModel(this);
|
|
setQmlContextProperty("ApiDevicesModel", m_apiDevicesModel);
|
|
|
|
m_newsModel = new NewsModel(m_appSettingsRepository, this);
|
|
setQmlContextProperty("NewsModel", m_newsModel);
|
|
}
|
|
|
|
void CoreController::initRepositories()
|
|
{
|
|
m_serversRepository = new SecureServersRepository(m_settings, this);
|
|
m_appSettingsRepository = new SecureAppSettingsRepository(m_settings, this);
|
|
|
|
if (m_vpnConnection) {
|
|
m_vpnConnection->setRepositories(m_serversRepository, m_appSettingsRepository);
|
|
}
|
|
}
|
|
|
|
void CoreController::initCoreControllers()
|
|
{
|
|
m_serversController = new ServersController(m_serversRepository, m_appSettingsRepository, this);
|
|
m_appSplitTunnelingController = new AppSplitTunnelingController(m_appSettingsRepository);
|
|
m_usersController = new UsersController(m_serversRepository, this);
|
|
m_ipSplitTunnelingController = new IpSplitTunnelingController(m_appSettingsRepository, this);
|
|
m_allowedDnsController = new AllowedDnsController(m_appSettingsRepository);
|
|
m_servicesCatalogController = new ServicesCatalogController(m_appSettingsRepository);
|
|
m_subscriptionController = new SubscriptionController(m_serversRepository, m_appSettingsRepository);
|
|
m_newsController = new NewsController(m_appSettingsRepository, m_serversController);
|
|
|
|
m_installController = new InstallController(m_serversRepository, m_appSettingsRepository, this);
|
|
m_exportController = new ExportController(m_serversRepository, m_appSettingsRepository, this);
|
|
m_importCoreController = new ImportController(m_serversRepository, m_appSettingsRepository, this);
|
|
m_connectionController = new ConnectionController(m_serversRepository, m_appSettingsRepository, m_vpnConnection.get(), this);
|
|
m_settingsController = new SettingsController(m_serversRepository, m_appSettingsRepository, this);
|
|
}
|
|
|
|
void CoreController::initControllers()
|
|
{
|
|
m_connectionUiController = new ConnectionUiController(m_connectionController, m_serversController, this);
|
|
setQmlContextProperty("ConnectionController", m_connectionUiController);
|
|
|
|
if (m_engine) {
|
|
m_focusController = new FocusController(m_engine, this);
|
|
setQmlContextProperty("FocusController", m_focusController);
|
|
}
|
|
|
|
m_installUiController = new InstallUiController(m_installController, m_serversController, m_settingsController, m_protocolsModel, m_usersController,
|
|
m_awgConfigModel, m_wireGuardConfigModel, m_openVpnConfigModel, m_xrayConfigModel, m_torConfigModel,
|
|
#ifdef Q_OS_WINDOWS
|
|
m_ikev2ConfigModel,
|
|
#endif
|
|
m_sftpConfigModel, m_socks5ConfigModel, this);
|
|
setQmlContextProperty("InstallController", m_installUiController);
|
|
|
|
m_importController = new ImportUiController(m_importCoreController, this);
|
|
setQmlContextProperty("ImportController", m_importController);
|
|
|
|
m_exportUiController = new ExportUiController(m_exportController, this);
|
|
setQmlContextProperty("ExportController", m_exportUiController);
|
|
|
|
m_languageUiController = new LanguageUiController(m_settingsController, m_languageModel, this);
|
|
setQmlContextProperty("LanguageUiController", m_languageUiController);
|
|
|
|
m_settingsUiController = new SettingsUiController(m_settingsController, m_serversController, m_languageUiController, this);
|
|
setQmlContextProperty("SettingsController", m_settingsUiController);
|
|
|
|
m_pageController = new PageController(m_serversController, m_settingsController, this);
|
|
setQmlContextProperty("PageController", m_pageController);
|
|
|
|
m_serversUiController = new ServersUiController(m_serversController, m_settingsController, m_serversModel, m_containersModel, m_defaultServerContainersModel, this);
|
|
setQmlContextProperty("ServersUiController", m_serversUiController);
|
|
|
|
m_ipSplitTunnelingUiController = new IpSplitTunnelingUiController(m_ipSplitTunnelingController, m_ipSplitTunnelingModel, this);
|
|
setQmlContextProperty("IpSplitTunnelingController", m_ipSplitTunnelingUiController);
|
|
|
|
m_allowedDnsUiController = new AllowedDnsUiController(m_allowedDnsController, m_allowedDnsModel, this);
|
|
setQmlContextProperty("AllowedDnsController", m_allowedDnsUiController);
|
|
|
|
m_appSplitTunnelingUiController = new AppSplitTunnelingUiController(m_appSplitTunnelingController, m_appSplitTunnelingModel, this);
|
|
setQmlContextProperty("AppSplitTunnelingController", m_appSplitTunnelingUiController);
|
|
|
|
m_systemController = new SystemController(this);
|
|
setQmlContextProperty("SystemController", m_systemController);
|
|
|
|
m_servicesCatalogUiController = new ServicesCatalogUiController(m_servicesCatalogController, m_apiServicesModel, this);
|
|
setQmlContextProperty("ServicesCatalogUiController", m_servicesCatalogUiController);
|
|
|
|
m_subscriptionUiController = new SubscriptionUiController(m_serversController, m_apiServicesModel, m_servicesCatalogController, m_subscriptionController,
|
|
m_apiSubscriptionPlansModel, m_apiBenefitsModel, m_apiAccountInfoModel,
|
|
m_apiCountryModel, m_apiDevicesModel, m_settingsController, this);
|
|
setQmlContextProperty("SubscriptionUiController", m_subscriptionUiController);
|
|
|
|
m_apiNewsUiController = new ApiNewsUiController(m_newsModel, m_newsController, this);
|
|
setQmlContextProperty("ApiNewsController", m_apiNewsUiController);
|
|
}
|
|
|
|
void CoreController::initAndroidController()
|
|
{
|
|
#ifdef Q_OS_ANDROID
|
|
if (!AndroidController::initLogging()) {
|
|
qFatal("Android logging initialization failed");
|
|
}
|
|
AndroidController::instance()->setSaveLogs(m_appSettingsRepository->isSaveLogs());
|
|
AndroidController::instance()->setScreenshotsEnabled(m_appSettingsRepository->isScreenshotsEnabled());
|
|
|
|
if (!AndroidController::instance()->initialize()) {
|
|
qFatal("Android controller initialization failed");
|
|
}
|
|
|
|
if (m_engine) {
|
|
m_engine->addImageProvider(QLatin1String("installedAppImage"), new InstalledAppsImageProvider);
|
|
}
|
|
#endif
|
|
}
|
|
|
|
void CoreController::initAppleController()
|
|
{
|
|
#ifdef Q_OS_IOS
|
|
IosController::Instance()->initialize();
|
|
QTimer::singleShot(0, this, [this]() { AmneziaVPN::toggleScreenshots(m_appSettingsRepository->isScreenshotsEnabled()); });
|
|
#endif
|
|
}
|
|
|
|
void CoreController::initLogging()
|
|
{
|
|
#if !defined(Q_OS_ANDROID) && !defined(Q_OS_IOS)
|
|
bool enabled = m_appSettingsRepository->isSaveLogs();
|
|
if (enabled) {
|
|
if (!Logger::init(false)) {
|
|
qWarning() << "Initialization of debug subsystem failed";
|
|
}
|
|
}
|
|
Logger::setServiceLogsEnabled(enabled);
|
|
#endif
|
|
}
|
|
|
|
void CoreController::initSignalHandlers()
|
|
{
|
|
m_signalHandlers = new CoreSignalHandlers(this, this);
|
|
m_signalHandlers->initAllHandlers();
|
|
|
|
// Trigger initial update after handlers are connected
|
|
m_serversUiController->updateModel();
|
|
}
|
|
|
|
void CoreController::updateTranslator(const QLocale &locale)
|
|
{
|
|
if (!m_translator->isEmpty()) {
|
|
QCoreApplication::removeTranslator(m_translator);
|
|
}
|
|
|
|
QStringList availableTranslations;
|
|
QDirIterator it(":/translations", QStringList("amneziavpn_*.qm"), QDir::Files);
|
|
while (it.hasNext()) {
|
|
availableTranslations << it.next();
|
|
}
|
|
|
|
// This code allow to load translation for the language only, without country code
|
|
const QString lang = locale.name().split("_").first();
|
|
const QString translationFilePrefix = QString(":/translations/amneziavpn_") + lang;
|
|
QString strFileName = QString(":/translations/amneziavpn_%1.qm").arg(locale.name());
|
|
for (const QString &translation : availableTranslations) {
|
|
if (translation.contains(translationFilePrefix)) {
|
|
strFileName = translation;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (m_translator->load(strFileName)) {
|
|
QCoreApplication::installTranslator(m_translator);
|
|
} else {
|
|
if (m_translator->load(QString(":/translations/amneziavpn_en.qm"))) {
|
|
QCoreApplication::installTranslator(m_translator);
|
|
}
|
|
}
|
|
|
|
if (m_engine) {
|
|
m_engine->retranslate();
|
|
}
|
|
|
|
emit translationsUpdated();
|
|
if (m_languageUiController) {
|
|
emit websiteUrlChanged(m_languageUiController->getCurrentSiteUrl());
|
|
}
|
|
}
|
|
|
|
void CoreController::setQmlRoot()
|
|
{
|
|
if (m_engine && m_systemController) {
|
|
m_systemController->setQmlRoot(m_engine->rootObjects().value(0));
|
|
}
|
|
}
|
|
|
|
PageController* CoreController::pageController() const
|
|
{
|
|
return m_pageController;
|
|
}
|
|
|
|
void CoreController::openConnectionByIndex(int serverIndex)
|
|
{
|
|
if (m_serversModel) {
|
|
m_serversModel->setProcessedServerIndex(serverIndex);
|
|
}
|
|
if (m_serversController) {
|
|
m_serversController->setDefaultServerIndex(serverIndex);
|
|
}
|
|
m_connectionUiController->toggleConnection();
|
|
}
|
|
|
|
void CoreController::importConfigFromData(const QString &data)
|
|
{
|
|
if (!m_importController)
|
|
return;
|
|
|
|
if (m_importController->extractConfigFromData(data)) {
|
|
m_importController->importConfig();
|
|
}
|
|
}
|