diff --git a/client/CMakeLists.txt b/client/CMakeLists.txt index 8132ae51..55c0deda 100644 --- a/client/CMakeLists.txt +++ b/client/CMakeLists.txt @@ -281,13 +281,14 @@ if(IOS) find_library(FW_AUTHENTICATIONSERVICES AuthenticationServices) find_library(FW_UIKIT UIKit) + find_library(FW_AVFOUNDATION AVFoundation) find_library(FW_FOUNDATION Foundation) find_library(FW_STOREKIT StoreKit) find_library(FW_USERNOTIFICATIONS UserNotifications) set(LIBS ${LIBS} ${FW_AUTHENTICATIONSERVICES} ${FW_UIKIT} - ${FW_FOUNDATION} ${FW_STOREKIT} + ${FW_AVFOUNDATION} ${FW_FOUNDATION} ${FW_STOREKIT} ${FW_USERNOTIFICATIONS} ) @@ -440,14 +441,13 @@ if(IOS) PROPERTIES MACOSX_PACKAGE_LOCATION "Resources" ) -target_sources(${PROJECT} PRIVATE - ${CMAKE_CURRENT_LIST_DIR}/ios/Media.xcassets - -) -set_source_files_properties( - ${CMAKE_CURRENT_LIST_DIR}/ios/Media.xcassets - PROPERTIES MACOSX_PACKAGE_LOCATION "Resources" -) + target_sources(${PROJECT} PRIVATE + ${CMAKE_CURRENT_LIST_DIR}/ios/Media.xcassets + ) + set_source_files_properties( + ${CMAKE_CURRENT_LIST_DIR}/ios/Media.xcassets + PROPERTIES MACOSX_PACKAGE_LOCATION "Resources" + ) add_subdirectory(ios/networkextension) add_dependencies(${PROJECT} networkextension) @@ -475,19 +475,13 @@ set_source_files_properties( ) set_target_properties (${PROJECT} PROPERTIES XCODE_ATTRIBUTE_CODE_SIGN_STYLE Manual) - set_target_properties(${PROJECT} PROPERTIES XCODE_ATTRIBUTE_PROVISIONING_PROFILE_SPECIFIER "match AppStore org.amnezia.AmneziaVPN") - set_target_properties(${PROJECT} PROPERTIES XCODE_ATTRIBUTE_PROVISIONING_PROFILE_SPECIFIER[variant=Debug] "match Development org.amnezia.AmneziaVPN") - - set_target_properties ("networkextension" PROPERTIES XCODE_ATTRIBUTE_CODE_SIGN_STYLE Manual) - + set_target_properties("networkextension" PROPERTIES XCODE_ATTRIBUTE_CODE_SIGN_STYLE Manual) set_target_properties("networkextension" PROPERTIES XCODE_ATTRIBUTE_PROVISIONING_PROFILE_SPECIFIER "match AppStore org.amnezia.AmneziaVPN.network-extension") - set_target_properties("networkextension" PROPERTIES XCODE_ATTRIBUTE_PROVISIONING_PROFILE_SPECIFIER[variant=Debug] "match Development org.amnezia.AmneziaVPN.network-extension") - endif() if(ANDROID) diff --git a/client/android/build.gradle b/client/android/build.gradle index 94604ad8..16507a89 100644 --- a/client/android/build.gradle +++ b/client/android/build.gradle @@ -135,7 +135,7 @@ android { defaultConfig { resConfig "en" minSdkVersion = 24 - targetSdkVersion = 30 + targetSdkVersion = 31 versionCode 10 // Change to a higher number versionName "2.0.10" // Change to a higher number diff --git a/client/android/shadowsocks/build.gradle b/client/android/shadowsocks/build.gradle index d87139fe..69ebd0bd 100644 --- a/client/android/shadowsocks/build.gradle +++ b/client/android/shadowsocks/build.gradle @@ -53,7 +53,7 @@ dependencies { implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.2.0" implementation "androidx.room:room-runtime:2.2.5" // runtime implementation "androidx.preference:preference:1.1.0" - implementation "androidx.work:work-runtime-ktx:2.3.4" + implementation "androidx.work:work-runtime-ktx:2.7.1" implementation "androidx.browser:browser:1.3.0-alpha01" implementation "androidx.constraintlayout:constraintlayout:1.1.3" implementation "com.google.android.material:material:1.2.0-alpha05" diff --git a/client/android/shadowsocks/src/main/AndroidManifest.xml b/client/android/shadowsocks/src/main/AndroidManifest.xml index 9769ab7a..ee498ab8 100644 --- a/client/android/shadowsocks/src/main/AndroidManifest.xml +++ b/client/android/shadowsocks/src/main/AndroidManifest.xml @@ -68,7 +68,8 @@ android:name="org.amnezia.vpn.shadowsocks.core.BootReceiver" android:directBootAware="true" android:enabled="false" - android:process=":QtOnlyProcess"> + android:process=":QtOnlyProcess" + android:exported="true"> diff --git a/client/android/shadowsocks/src/main/java/org/amnezia/vpn/shadowsocks/core/Core.kt b/client/android/shadowsocks/src/main/java/org/amnezia/vpn/shadowsocks/core/Core.kt index 170bfb75..93bfcacc 100644 --- a/client/android/shadowsocks/src/main/java/org/amnezia/vpn/shadowsocks/core/Core.kt +++ b/client/android/shadowsocks/src/main/java/org/amnezia/vpn/shadowsocks/core/Core.kt @@ -84,8 +84,9 @@ object Core { fun init(app: Application, configureClass: KClass) { Core.app = app configureIntent = { - PendingIntent.getActivity(it, 0, Intent(it, configureClass.java) - .setFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT), 0) + PendingIntent.getActivity(it, 0, + Intent(it, configureClass.java).setFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT), + PendingIntent.FLAG_IMMUTABLE or PendingIntent.FLAG_UPDATE_CURRENT) } if (Build.VERSION.SDK_INT >= 24) { // migrate old files @@ -99,7 +100,6 @@ object Core { // overhead of debug mode is minimal: https://github.com/Kotlin/kotlinx.coroutines/blob/f528898/docs/debugging.md#debug-mode System.setProperty(DEBUG_PROPERTY_NAME, DEBUG_PROPERTY_VALUE_ON) - WorkManager.initialize(deviceStorage, Configuration.Builder().build()) // handle data restored/crash if (Build.VERSION.SDK_INT >= 24 && DataStore.directBootAware && diff --git a/client/android/src/org/amnezia/vpn/NotificationUtil.kt b/client/android/src/org/amnezia/vpn/NotificationUtil.kt index 15e706ed..d2808d5d 100644 --- a/client/android/src/org/amnezia/vpn/NotificationUtil.kt +++ b/client/android/src/org/amnezia/vpn/NotificationUtil.kt @@ -99,7 +99,7 @@ object NotificationUtil { val mainActivityName = "org.amnezia.vpn.qt.VPNActivity" val activity = Class.forName(mainActivityName) val intent = Intent(service, activity) - val pendingIntent = PendingIntent.getActivity(service, 0, intent, 0) + val pendingIntent = PendingIntent.getActivity(service, 0, intent, PendingIntent.FLAG_IMMUTABLE or PendingIntent.FLAG_UPDATE_CURRENT) // Build our notification sNotificationBuilder?.let { it.setSmallIcon(org.amnezia.vpn.R.drawable.ic_amnezia_round) diff --git a/client/core/servercontroller.cpp b/client/core/servercontroller.cpp index 2f4d6ae5..d91cfb64 100644 --- a/client/core/servercontroller.cpp +++ b/client/core/servercontroller.cpp @@ -701,3 +701,49 @@ ErrorCode ServerController::isServerPortBusy(const ServerCredentials &credential } return ErrorCode::NoError; } + +ErrorCode ServerController::getAlreadyInstalledContainers(const ServerCredentials &credentials, QMap &installedContainers) +{ + QString stdOut; + auto cbReadStdOut = [&](const QString &data, libssh::Client &) { + stdOut += data + "\n"; + return ErrorCode::NoError; + }; + auto cbReadStdErr = [&](const QString &data, libssh::Client &) { + stdOut += data + "\n"; + return ErrorCode::NoError; + }; + + QString script = QString("sudo docker ps --format '{{.Names}} {{.Ports}}'"); + + ErrorCode errorCode = runScript(credentials, script, cbReadStdOut, cbReadStdErr); + if (errorCode != ErrorCode::NoError) { + return errorCode; + } + + auto containersInfo = stdOut.split("\n"); + for (auto &containerInfo : containersInfo) { + if (containerInfo.isEmpty()) { + continue; + } + const static QRegularExpression containerAndPortRegExp("(amnezia[-a-z]*).*?:([0-9]*)->[0-9]*/(udp|tcp).*"); + QRegularExpressionMatch containerAndPortMatch = containerAndPortRegExp.match(containerInfo); + if (containerAndPortMatch.hasMatch()) { + QString name = containerAndPortMatch.captured(1); + QString port = containerAndPortMatch.captured(2); + QString transportProto = containerAndPortMatch.captured(3); + DockerContainer container = ContainerProps::containerFromString(name); + Proto mainProto = ContainerProps::defaultProtocol(container); + QJsonObject config { + { config_key::container, name }, + { ProtocolProps::protoToString(mainProto), QJsonObject { + { config_key::port, port }, + { config_key::transport_proto, transportProto }} + } + }; + installedContainers.insert(container, config); + } + } + + return ErrorCode::NoError; +} diff --git a/client/core/servercontroller.h b/client/core/servercontroller.h index 1db75401..fc16d081 100644 --- a/client/core/servercontroller.h +++ b/client/core/servercontroller.h @@ -71,6 +71,7 @@ public: QString checkSshConnection(const ServerCredentials &credentials, ErrorCode *errorCode = nullptr); void setCancelInstallation(const bool cancel); + ErrorCode getAlreadyInstalledContainers(const ServerCredentials &credentials, QMap &installedContainers); private: ErrorCode installDockerWorker(const ServerCredentials &credentials, DockerContainer container); ErrorCode prepareHostWorker(const ServerCredentials &credentials, DockerContainer container, const QJsonObject &config = QJsonObject()); diff --git a/client/resources.qrc b/client/resources.qrc index fd26f5ad..67937bda 100644 --- a/client/resources.qrc +++ b/client/resources.qrc @@ -163,5 +163,7 @@ images/svg/settings_suggest_black_24dp.svg server_scripts/website_tor/Dockerfile ui/qml/Controls/PopupWithQuestion.qml + ui/qml/Pages/PageAdvancedServerSettings.qml + ui/qml/Controls/PopupWarning.qml diff --git a/client/server_scripts/install_docker.sh b/client/server_scripts/install_docker.sh index baff7cb6..bb14e4cf 100644 --- a/client/server_scripts/install_docker.sh +++ b/client/server_scripts/install_docker.sh @@ -6,4 +6,5 @@ if [[ -f "$pm_apt" ]]; then export DEBIAN_FRONTEND=noninteractive; fi;\ if [[ -z "$docker_service" ]]; then sudo $pm update -y -q; sudo $pm install -y -q curl $docker_pkg; fi;\ docker_service=$(systemctl list-units --full -all | grep docker.service | grep -v inactive | grep -v dead | grep -v failed);\ if [[ -z "$docker_service" ]]; then sleep 5 && sudo systemctl start docker && sleep 5; fi;\ +if [[ -f "$pm_yum" ]]; then sudo systemctl enable docker && sudo systemctl start docker; fi;\ docker --version diff --git a/client/ui/pages.h b/client/ui/pages.h index 69f417fa..dfc9a509 100644 --- a/client/ui/pages.h +++ b/client/ui/pages.h @@ -24,7 +24,7 @@ enum class Page {Start = 0, NewServer, NewServerProtocols, Vpn, Wizard, WizardLow, WizardMedium, WizardHigh, WizardVpnMode, ServerConfiguringProgress, GeneralSettings, AppSettings, NetworkSettings, ServerSettings, ServerContainers, ServersList, ShareConnection, Sites, - ProtocolSettings, ProtocolShare, QrDecoder, QrDecoderIos, About, ViewConfig}; + ProtocolSettings, ProtocolShare, QrDecoder, QrDecoderIos, About, ViewConfig, AdvancedServerSettings}; Q_ENUM_NS(Page) static void declareQmlPageEnum() { diff --git a/client/ui/pages_logic/AdvancedServerSettingsLogic.cpp b/client/ui/pages_logic/AdvancedServerSettingsLogic.cpp new file mode 100644 index 00000000..0b02241c --- /dev/null +++ b/client/ui/pages_logic/AdvancedServerSettingsLogic.cpp @@ -0,0 +1,88 @@ +#include "AdvancedServerSettingsLogic.h" + +#include "VpnLogic.h" +#include "ui/uilogic.h" +#include "core/errorstrings.h" +#include "core/servercontroller.h" + +AdvancedServerSettingsLogic::AdvancedServerSettingsLogic(UiLogic *uiLogic, QObject *parent): PageLogicBase(uiLogic, parent), + m_labelWaitInfoVisible{true}, + m_pushButtonClearVisible{true}, + m_pushButtonClearText{tr("Clear server from Amnezia software")} +{ +} + +void AdvancedServerSettingsLogic::onUpdatePage() +{ + set_labelWaitInfoVisible(false); + set_labelWaitInfoText(""); + set_pushButtonClearVisible(m_settings->haveAuthData(uiLogic()->m_selectedServerIndex)); + const QJsonObject &server = m_settings->server(uiLogic()->m_selectedServerIndex); + const QString &port = server.value(config_key::port).toString(); + + const QString &userName = server.value(config_key::userName).toString(); + const QString &hostName = server.value(config_key::hostName).toString(); + QString name = QString("%1%2%3%4%5").arg(userName, + userName.isEmpty() ? "" : "@", + hostName, + port.isEmpty() ? "" : ":", + port); + + set_labelServerText(name); + + DockerContainer selectedContainer = m_settings->defaultContainer(uiLogic()->m_selectedServerIndex); + QString selectedContainerName = ContainerProps::containerHumanNames().value(selectedContainer); + set_labelCurrentVpnProtocolText(tr("Service: ") + selectedContainerName); +} + +void AdvancedServerSettingsLogic::onPushButtonClearServerClicked() +{ + set_pageEnabled(false); + set_pushButtonClearText(tr("Uninstalling Amnezia software...")); + + if (m_settings->defaultServerIndex() == uiLogic()->m_selectedServerIndex) { + uiLogic()->pageLogic()->onDisconnect(); + } + + ErrorCode e = m_serverController->removeAllContainers(m_settings->serverCredentials(uiLogic()->m_selectedServerIndex)); + m_serverController->disconnectFromHost(m_settings->serverCredentials(uiLogic()->m_selectedServerIndex)); + if (e) { + emit uiLogic()->showWarningMessage(tr("Error occurred while cleaning the server.") + "\n" + + tr("Error message: ") + errorString(e) + "\n" + + tr("See logs for details.")); + } else { + set_labelWaitInfoVisible(true); + set_labelWaitInfoText(tr("Amnezia server successfully uninstalled")); + } + + m_settings->setContainers(uiLogic()->m_selectedServerIndex, {}); + m_settings->setDefaultContainer(uiLogic()->m_selectedServerIndex, DockerContainer::None); + + set_pageEnabled(true); + set_pushButtonClearText(tr("Clear server from Amnezia software")); +} + +void AdvancedServerSettingsLogic::onPushButtonScanServerClicked() +{ + set_labelWaitInfoVisible(false); + set_pageEnabled(false); + + bool isServerCreated; + auto containersCount = m_settings->containers(uiLogic()->m_selectedServerIndex).size(); + ErrorCode errorCode = uiLogic()->addAlreadyInstalledContainersGui(false, isServerCreated); + if (errorCode != ErrorCode::NoError) { + emit uiLogic()->showWarningMessage(tr("Error occurred while scanning the server.") + "\n" + + tr("Error message: ") + errorString(errorCode) + "\n" + + tr("See logs for details.")); + } + auto newContainersCount = m_settings->containers(uiLogic()->m_selectedServerIndex).size(); + if (containersCount != newContainersCount) { + emit uiLogic()->showWarningMessage(tr("All containers installed on the server are added to the GUI")); + } else { + emit uiLogic()->showWarningMessage(tr("No installed containers found on the server")); + } + + + onUpdatePage(); + set_pageEnabled(true); +} diff --git a/client/ui/pages_logic/AdvancedServerSettingsLogic.h b/client/ui/pages_logic/AdvancedServerSettingsLogic.h new file mode 100644 index 00000000..692968f1 --- /dev/null +++ b/client/ui/pages_logic/AdvancedServerSettingsLogic.h @@ -0,0 +1,31 @@ +#ifndef ADVANCEDSERVERSETTINGSLOGIC_H +#define ADVANCEDSERVERSETTINGSLOGIC_H + +#include "PageLogicBase.h" + +class UiLogic; + +class AdvancedServerSettingsLogic : public PageLogicBase +{ + Q_OBJECT + + AUTO_PROPERTY(bool, labelWaitInfoVisible) + AUTO_PROPERTY(QString, labelWaitInfoText) + + AUTO_PROPERTY(QString, pushButtonClearText) + AUTO_PROPERTY(bool, pushButtonClearVisible) + + AUTO_PROPERTY(QString, labelServerText) + AUTO_PROPERTY(QString, labelCurrentVpnProtocolText) + +public: + explicit AdvancedServerSettingsLogic(UiLogic *uiLogic, QObject *parent = nullptr); + ~AdvancedServerSettingsLogic() = default; + + Q_INVOKABLE void onUpdatePage() override; + + Q_INVOKABLE void onPushButtonClearServerClicked(); + Q_INVOKABLE void onPushButtonScanServerClicked(); +}; + +#endif // ADVANCEDSERVERSETTINGSLOGIC_H diff --git a/client/ui/pages_logic/AppSettingsLogic.cpp b/client/ui/pages_logic/AppSettingsLogic.cpp index 3590c480..e5358009 100644 --- a/client/ui/pages_logic/AppSettingsLogic.cpp +++ b/client/ui/pages_logic/AppSettingsLogic.cpp @@ -7,7 +7,6 @@ #include #include -#include #include using namespace amnezia; @@ -96,10 +95,8 @@ void AppSettingsLogic::onPushButtonRestoreAppConfigClicked() if (ok) { emit uiLogic()->goToPage(Page::Vpn); emit uiLogic()->setStartPage(Page::Vpn); - } - else { - QMessageBox::warning(nullptr, APPLICATION_NAME, - tr("Can't import config, file is corrupted.")); + } else { + emit uiLogic()->showWarningMessage(tr("Can't import config, file is corrupted.")); } } diff --git a/client/ui/pages_logic/GeneralSettingsLogic.cpp b/client/ui/pages_logic/GeneralSettingsLogic.cpp index c4b04c01..cbdf2692 100644 --- a/client/ui/pages_logic/GeneralSettingsLogic.cpp +++ b/client/ui/pages_logic/GeneralSettingsLogic.cpp @@ -12,29 +12,29 @@ GeneralSettingsLogic::GeneralSettingsLogic(UiLogic *logic, QObject *parent): void GeneralSettingsLogic::onUpdatePage() { - uiLogic()->selectedServerIndex = m_settings->defaultServerIndex(); - set_existsAnyServer(uiLogic()->selectedServerIndex >= 0); - uiLogic()->selectedDockerContainer = m_settings->defaultContainer(m_settings->defaultServerIndex()); + uiLogic()->m_selectedServerIndex = m_settings->defaultServerIndex(); + set_existsAnyServer(uiLogic()->m_selectedServerIndex >= 0); + uiLogic()->m_selectedDockerContainer = m_settings->defaultContainer(m_settings->defaultServerIndex()); set_pushButtonGeneralSettingsShareConnectionEnable(m_settings->haveAuthData(m_settings->defaultServerIndex())); } void GeneralSettingsLogic::onPushButtonGeneralSettingsServerSettingsClicked() { - uiLogic()->selectedServerIndex = m_settings->defaultServerIndex(); - uiLogic()->selectedDockerContainer = m_settings->defaultContainer(m_settings->defaultServerIndex()); + uiLogic()->m_selectedServerIndex = m_settings->defaultServerIndex(); + uiLogic()->m_selectedDockerContainer = m_settings->defaultContainer(m_settings->defaultServerIndex()); emit uiLogic()->goToPage(Page::ServerSettings); } void GeneralSettingsLogic::onPushButtonGeneralSettingsShareConnectionClicked() { - uiLogic()->selectedServerIndex = m_settings->defaultServerIndex(); - uiLogic()->selectedDockerContainer = m_settings->defaultContainer(uiLogic()->selectedServerIndex); + uiLogic()->m_selectedServerIndex = m_settings->defaultServerIndex(); + uiLogic()->m_selectedDockerContainer = m_settings->defaultContainer(uiLogic()->m_selectedServerIndex); - qobject_cast(uiLogic()->protocolsModel())->setSelectedServerIndex(uiLogic()->selectedServerIndex); - qobject_cast(uiLogic()->protocolsModel())->setSelectedDockerContainer(uiLogic()->selectedDockerContainer); + qobject_cast(uiLogic()->protocolsModel())->setSelectedServerIndex(uiLogic()->m_selectedServerIndex); + qobject_cast(uiLogic()->protocolsModel())->setSelectedDockerContainer(uiLogic()->m_selectedDockerContainer); - uiLogic()->pageLogic()->updateSharingPage(uiLogic()->selectedServerIndex, uiLogic()->selectedDockerContainer); + uiLogic()->pageLogic()->updateSharingPage(uiLogic()->m_selectedServerIndex, uiLogic()->m_selectedDockerContainer); emit uiLogic()->goToPage(Page::ShareConnection); } diff --git a/client/ui/pages_logic/NewServerProtocolsLogic.cpp b/client/ui/pages_logic/NewServerProtocolsLogic.cpp index cabe1bc0..a1db7565 100644 --- a/client/ui/pages_logic/NewServerProtocolsLogic.cpp +++ b/client/ui/pages_logic/NewServerProtocolsLogic.cpp @@ -17,7 +17,6 @@ void NewServerProtocolsLogic::onUpdatePage() void NewServerProtocolsLogic::onPushButtonConfigureClicked(DockerContainer c, int port, TransportProto tp) { - QMap containers; Proto mainProto = ContainerProps::defaultProtocol(c); QJsonObject config { @@ -28,8 +27,8 @@ void NewServerProtocolsLogic::onPushButtonConfigureClicked(DockerContainer c, in } }; - containers.insert(c, config); + QPair container(c, config); - uiLogic()->installServer(containers); + uiLogic()->installServer(container); } diff --git a/client/ui/pages_logic/ServerConfiguringProgressLogic.cpp b/client/ui/pages_logic/ServerConfiguringProgressLogic.cpp index c6e7085b..f6a8abdb 100644 --- a/client/ui/pages_logic/ServerConfiguringProgressLogic.cpp +++ b/client/ui/pages_logic/ServerConfiguringProgressLogic.cpp @@ -3,7 +3,6 @@ #include "core/errorstrings.h" #include #include -#include #include "core/servercontroller.h" @@ -142,9 +141,6 @@ ErrorCode ServerConfiguringProgressLogic::doInstallAction(const std::function(uiLogic()->containersModel()); - c_model->setSelectedServerIndex(uiLogic()->selectedServerIndex); + c_model->setSelectedServerIndex(uiLogic()->m_selectedServerIndex); ProtocolsModel *p_model = qobject_cast(uiLogic()->protocolsModel()); - p_model->setSelectedServerIndex(uiLogic()->selectedServerIndex); + p_model->setSelectedServerIndex(uiLogic()->m_selectedServerIndex); - set_isManagedServer(m_settings->haveAuthData(uiLogic()->selectedServerIndex)); + set_isManagedServer(m_settings->haveAuthData(uiLogic()->m_selectedServerIndex)); emit updatePage(); } void ServerContainersLogic::onPushButtonProtoSettingsClicked(DockerContainer c, Proto p) { qDebug()<< "ServerContainersLogic::onPushButtonProtoSettingsClicked" << c << p; - uiLogic()->selectedDockerContainer = c; - uiLogic()->protocolLogic(p)->updateProtocolPage(m_settings->protocolConfig(uiLogic()->selectedServerIndex, uiLogic()->selectedDockerContainer, p), - uiLogic()->selectedDockerContainer, - m_settings->haveAuthData(uiLogic()->selectedServerIndex)); + uiLogic()->m_selectedDockerContainer = c; + uiLogic()->protocolLogic(p)->updateProtocolPage(m_settings->protocolConfig(uiLogic()->m_selectedServerIndex, uiLogic()->m_selectedDockerContainer, p), + uiLogic()->m_selectedDockerContainer, + m_settings->haveAuthData(uiLogic()->m_selectedServerIndex)); emit uiLogic()->goToProtocolPage(p); } void ServerContainersLogic::onPushButtonDefaultClicked(DockerContainer c) { - if (m_settings->defaultContainer(uiLogic()->selectedServerIndex) == c) return; + if (m_settings->defaultContainer(uiLogic()->m_selectedServerIndex) == c) return; - m_settings->setDefaultContainer(uiLogic()->selectedServerIndex, c); + m_settings->setDefaultContainer(uiLogic()->m_selectedServerIndex, c); uiLogic()->onUpdateAllPages(); - if (uiLogic()->selectedServerIndex != m_settings->defaultServerIndex()) return; + if (uiLogic()->m_selectedServerIndex != m_settings->defaultServerIndex()) return; if (!uiLogic()->m_vpnConnection) return; if (!uiLogic()->m_vpnConnection->isConnected()) return; @@ -61,21 +62,21 @@ void ServerContainersLogic::onPushButtonDefaultClicked(DockerContainer c) void ServerContainersLogic::onPushButtonShareClicked(DockerContainer c) { - uiLogic()->pageLogic()->updateSharingPage(uiLogic()->selectedServerIndex, c); + uiLogic()->pageLogic()->updateSharingPage(uiLogic()->m_selectedServerIndex, c); emit uiLogic()->goToPage(Page::ShareConnection); } void ServerContainersLogic::onPushButtonRemoveClicked(DockerContainer container) { //buttonSetEnabledFunc(false); - ErrorCode e = m_serverController->removeContainer(m_settings->serverCredentials(uiLogic()->selectedServerIndex), container); - m_settings->removeContainerConfig(uiLogic()->selectedServerIndex, container); + ErrorCode e = m_serverController->removeContainer(m_settings->serverCredentials(uiLogic()->m_selectedServerIndex), container); + m_settings->removeContainerConfig(uiLogic()->m_selectedServerIndex, container); //buttonSetEnabledFunc(true); - if (m_settings->defaultContainer(uiLogic()->selectedServerIndex) == container) { - const auto &c = m_settings->containers(uiLogic()->selectedServerIndex); - if (c.isEmpty()) m_settings->setDefaultContainer(uiLogic()->selectedServerIndex, DockerContainer::None); - else m_settings->setDefaultContainer(uiLogic()->selectedServerIndex, c.keys().first()); + if (m_settings->defaultContainer(uiLogic()->m_selectedServerIndex) == container) { + const auto &c = m_settings->containers(uiLogic()->m_selectedServerIndex); + if (c.isEmpty()) m_settings->setDefaultContainer(uiLogic()->m_selectedServerIndex, DockerContainer::None); + else m_settings->setDefaultContainer(uiLogic()->m_selectedServerIndex, c.keys().first()); } uiLogic()->onUpdateAllPages(); } @@ -87,17 +88,33 @@ void ServerContainersLogic::onPushButtonContinueClicked(DockerContainer c, int p emit uiLogic()->goToPage(Page::ServerConfiguringProgress); qApp->processEvents(); - ErrorCode e = uiLogic()->pageLogic()->doInstallAction([this, c, &config](){ - return m_serverController->setupContainer(m_settings->serverCredentials(uiLogic()->selectedServerIndex), c, config); - }); + bool isServerCreated = false; + ErrorCode errorCode = uiLogic()->addAlreadyInstalledContainersGui(false, isServerCreated); - if (!e) { - m_settings->setContainerConfig(uiLogic()->selectedServerIndex, c, config); - if (ContainerProps::containerService(c) == ServiceType::Vpn) { - m_settings->setDefaultContainer(uiLogic()->selectedServerIndex, c); + if (errorCode == ErrorCode::NoError) { + if (!uiLogic()->isContainerAlreadyAddedToGui(c)) { + auto installAction = [this, c, &config]() { + return m_serverController->setupContainer(m_settings->serverCredentials(uiLogic()->m_selectedServerIndex), c, config); + }; + errorCode = uiLogic()->pageLogic()->doInstallAction(installAction); + + if (errorCode == ErrorCode::NoError) { + m_settings->setContainerConfig(uiLogic()->m_selectedServerIndex, c, config); + if (ContainerProps::containerService(c) == ServiceType::Vpn) { + m_settings->setDefaultContainer(uiLogic()->m_selectedServerIndex, c); + } + } + } else { + emit uiLogic()->showWarningMessage("Attention! The container you are trying to install is already installed on the server. " + "All installed containers have been added to the application "); } - } - uiLogic()->onUpdateAllPages(); + uiLogic()->onUpdateAllPages(); + } + if (errorCode != ErrorCode::NoError) { + emit uiLogic()->showWarningMessage(tr("Error occurred while configuring server.") + "\n" + + tr("Error message: ") + errorString(errorCode) + "\n" + + tr("See logs for details.")); + } emit uiLogic()->closePage(); } diff --git a/client/ui/pages_logic/ServerListLogic.cpp b/client/ui/pages_logic/ServerListLogic.cpp index 42a629b3..e91b1e33 100644 --- a/client/ui/pages_logic/ServerListLogic.cpp +++ b/client/ui/pages_logic/ServerListLogic.cpp @@ -20,7 +20,8 @@ void ServerListLogic::onServerListPushbuttonDefaultClicked(int index) void ServerListLogic::onServerListPushbuttonSettingsClicked(int index) { - uiLogic()->selectedServerIndex = index; + uiLogic()->m_selectedServerIndex = index; + uiLogic()->m_installCredentials = m_settings->serverCredentials(index); uiLogic()->goToPage(Page::ServerSettings); } diff --git a/client/ui/pages_logic/ServerSettingsLogic.cpp b/client/ui/pages_logic/ServerSettingsLogic.cpp index 32a62e08..92b093a5 100644 --- a/client/ui/pages_logic/ServerSettingsLogic.cpp +++ b/client/ui/pages_logic/ServerSettingsLogic.cpp @@ -16,10 +16,8 @@ ServerSettingsLogic::ServerSettingsLogic(UiLogic *logic, QObject *parent): PageLogicBase(logic, parent), m_labelWaitInfoVisible{true}, - m_pushButtonClearVisible{true}, m_pushButtonClearClientCacheVisible{true}, m_pushButtonShareFullVisible{true}, - m_pushButtonClearText{tr("Clear server from Amnezia software")}, m_pushButtonClearClientCacheText{tr("Clear client cached profile")} { } @@ -27,10 +25,9 @@ void ServerSettingsLogic::onUpdatePage() { set_labelWaitInfoVisible(false); set_labelWaitInfoText(""); - set_pushButtonClearVisible(m_settings->haveAuthData(uiLogic()->selectedServerIndex)); - set_pushButtonClearClientCacheVisible(m_settings->haveAuthData(uiLogic()->selectedServerIndex)); - set_pushButtonShareFullVisible(m_settings->haveAuthData(uiLogic()->selectedServerIndex)); - const QJsonObject &server = m_settings->server(uiLogic()->selectedServerIndex); + set_pushButtonClearClientCacheVisible(m_settings->haveAuthData(uiLogic()->m_selectedServerIndex)); + set_pushButtonShareFullVisible(m_settings->haveAuthData(uiLogic()->m_selectedServerIndex)); + const QJsonObject &server = m_settings->server(uiLogic()->m_selectedServerIndex); const QString &port = server.value(config_key::port).toString(); const QString &userName = server.value(config_key::userName).toString(); @@ -45,52 +42,22 @@ void ServerSettingsLogic::onUpdatePage() set_labelServerText(name); set_lineEditDescriptionText(server.value(config_key::description).toString()); - DockerContainer selectedContainer = m_settings->defaultContainer(uiLogic()->selectedServerIndex); + DockerContainer selectedContainer = m_settings->defaultContainer(uiLogic()->m_selectedServerIndex); QString selectedContainerName = ContainerProps::containerHumanNames().value(selectedContainer); set_labelCurrentVpnProtocolText(tr("Service: ") + selectedContainerName); } -void ServerSettingsLogic::onPushButtonClearServer() -{ - set_pageEnabled(false); - set_pushButtonClearText(tr("Uninstalling Amnezia software...")); - - if (m_settings->defaultServerIndex() == uiLogic()->selectedServerIndex) { - uiLogic()->pageLogic()->onDisconnect(); - } - - ErrorCode e = m_serverController->removeAllContainers(m_settings->serverCredentials(uiLogic()->selectedServerIndex)); - m_serverController->disconnectFromHost(m_settings->serverCredentials(uiLogic()->selectedServerIndex)); - if (e) { - uiLogic()->set_dialogConnectErrorText( - tr("Error occurred while configuring server.") + "\n" + - errorString(e) + "\n" + - tr("See logs for details.")); - emit uiLogic()->showConnectErrorDialog(); - } - else { - set_labelWaitInfoVisible(true); - set_labelWaitInfoText(tr("Amnezia server successfully uninstalled")); - } - - m_settings->setContainers(uiLogic()->selectedServerIndex, {}); - m_settings->setDefaultContainer(uiLogic()->selectedServerIndex, DockerContainer::None); - - set_pageEnabled(true); - set_pushButtonClearText(tr("Clear server from Amnezia software")); -} - void ServerSettingsLogic::onPushButtonForgetServer() { - if (m_settings->defaultServerIndex() == uiLogic()->selectedServerIndex && uiLogic()->m_vpnConnection->isConnected()) { + if (m_settings->defaultServerIndex() == uiLogic()->m_selectedServerIndex && uiLogic()->m_vpnConnection->isConnected()) { uiLogic()->pageLogic()->onDisconnect(); } - m_settings->removeServer(uiLogic()->selectedServerIndex); + m_settings->removeServer(uiLogic()->m_selectedServerIndex); - if (m_settings->defaultServerIndex() == uiLogic()->selectedServerIndex) { + if (m_settings->defaultServerIndex() == uiLogic()->m_selectedServerIndex) { m_settings->setDefaultServer(0); } - else if (m_settings->defaultServerIndex() > uiLogic()->selectedServerIndex) { + else if (m_settings->defaultServerIndex() > uiLogic()->m_selectedServerIndex) { m_settings->setDefaultServer(m_settings->defaultServerIndex() - 1); } @@ -99,7 +66,7 @@ void ServerSettingsLogic::onPushButtonForgetServer() } - uiLogic()->selectedServerIndex = -1; + uiLogic()->m_selectedServerIndex = -1; uiLogic()->onUpdateAllPages(); if (m_settings->serversCount() == 0) { @@ -114,9 +81,9 @@ void ServerSettingsLogic::onPushButtonClearClientCacheClicked() { set_pushButtonClearClientCacheText(tr("Cache cleared")); - const auto &containers = m_settings->containers(uiLogic()->selectedServerIndex); - for (DockerContainer container: containers.keys()) { - m_settings->clearLastConnectionConfig(uiLogic()->selectedServerIndex, container); + const auto &containers = m_settings->containers(uiLogic()->m_selectedServerIndex); + for (DockerContainer container : containers.keys()) { + m_settings->clearLastConnectionConfig(uiLogic()->m_selectedServerIndex, container); } QTimer::singleShot(3000, this, [this]() { @@ -127,9 +94,9 @@ void ServerSettingsLogic::onPushButtonClearClientCacheClicked() void ServerSettingsLogic::onLineEditDescriptionEditingFinished() { const QString &newText = lineEditDescriptionText(); - QJsonObject server = m_settings->server(uiLogic()->selectedServerIndex); + QJsonObject server = m_settings->server(uiLogic()->m_selectedServerIndex); server.insert(config_key::description, newText); - m_settings->editServer(uiLogic()->selectedServerIndex, server); + m_settings->editServer(uiLogic()->m_selectedServerIndex, server); uiLogic()->onUpdateAllPages(); } @@ -154,7 +121,7 @@ void ServerSettingsLogic::onPushButtonShareFullClicked() auto appContext = activity.callObjectMethod( "getApplicationContext", "()Landroid/content/Context;"); if (appContext.isValid()) { - QAndroidActivityResultReceiver *receiver = new authResultReceiver(uiLogic(), uiLogic()->selectedServerIndex); + QAndroidActivityResultReceiver *receiver = new authResultReceiver(uiLogic(), uiLogic()->m_selectedServerIndex); auto intent = QJniObject::callStaticObjectMethod( "org/amnezia/vpn/AuthHelper", "getAuthIntent", "(Landroid/content/Context;)Landroid/content/Intent;", appContext.object()); @@ -163,12 +130,12 @@ void ServerSettingsLogic::onPushButtonShareFullClicked() QtAndroidPrivate::startActivity(intent.object(), 1, receiver); } } else { - uiLogic()->pageLogic()->updateSharingPage(uiLogic()->selectedServerIndex, DockerContainer::None); + uiLogic()->pageLogic()->updateSharingPage(uiLogic()->m_selectedServerIndex, DockerContainer::None); emit uiLogic()->goToShareProtocolPage(Proto::Any); } } #else - uiLogic()->pageLogic()->updateSharingPage(uiLogic()->selectedServerIndex, DockerContainer::None); + uiLogic()->pageLogic()->updateSharingPage(uiLogic()->m_selectedServerIndex, DockerContainer::None); emit uiLogic()->goToShareProtocolPage(Proto::Any); #endif } diff --git a/client/ui/pages_logic/ServerSettingsLogic.h b/client/ui/pages_logic/ServerSettingsLogic.h index d561ec48..a75dfa47 100644 --- a/client/ui/pages_logic/ServerSettingsLogic.h +++ b/client/ui/pages_logic/ServerSettingsLogic.h @@ -16,9 +16,7 @@ class ServerSettingsLogic : public PageLogicBase AUTO_PROPERTY(bool, labelWaitInfoVisible) AUTO_PROPERTY(QString, labelWaitInfoText) - AUTO_PROPERTY(QString, pushButtonClearText) AUTO_PROPERTY(QString, pushButtonClearClientCacheText) - AUTO_PROPERTY(bool, pushButtonClearVisible) AUTO_PROPERTY(bool, pushButtonClearClientCacheVisible) AUTO_PROPERTY(bool, pushButtonShareFullVisible) AUTO_PROPERTY(QString, labelServerText) @@ -28,7 +26,6 @@ class ServerSettingsLogic : public PageLogicBase public: Q_INVOKABLE void onUpdatePage() override; - Q_INVOKABLE void onPushButtonClearServer(); Q_INVOKABLE void onPushButtonForgetServer(); Q_INVOKABLE void onPushButtonShareFullClicked(); Q_INVOKABLE void onPushButtonClearClientCacheClicked(); diff --git a/client/ui/pages_logic/ShareConnectionLogic.cpp b/client/ui/pages_logic/ShareConnectionLogic.cpp index 85849391..821cc0fc 100644 --- a/client/ui/pages_logic/ShareConnectionLogic.cpp +++ b/client/ui/pages_logic/ShareConnectionLogic.cpp @@ -1,7 +1,6 @@ #include #include #include -#include #include "qrcodegen.hpp" @@ -68,8 +67,8 @@ void ShareConnectionLogic::onPushButtonShareAmneziaGenerateClicked() set_shareAmneziaQrCodeTextSeriesLength(0); QJsonObject serverConfig; - int serverIndex = uiLogic()->selectedServerIndex; - DockerContainer container = uiLogic()->selectedDockerContainer; + int serverIndex = uiLogic()->m_selectedServerIndex; + DockerContainer container = uiLogic()->m_selectedDockerContainer; // Full access if (shareFullAccess()) { @@ -127,8 +126,8 @@ void ShareConnectionLogic::onPushButtonShareAmneziaGenerateClicked() void ShareConnectionLogic::onPushButtonShareOpenVpnGenerateClicked() { - int serverIndex = uiLogic()->selectedServerIndex; - DockerContainer container = uiLogic()->selectedDockerContainer; + int serverIndex = uiLogic()->m_selectedServerIndex; + DockerContainer container = uiLogic()->m_selectedDockerContainer; ServerCredentials credentials = m_settings->serverCredentials(serverIndex); const QJsonObject &containerConfig = m_settings->containerConfig(serverIndex, container); @@ -142,8 +141,8 @@ void ShareConnectionLogic::onPushButtonShareOpenVpnGenerateClicked() void ShareConnectionLogic::onPushButtonShareShadowSocksGenerateClicked() { - int serverIndex = uiLogic()->selectedServerIndex; - DockerContainer container = uiLogic()->selectedDockerContainer; + int serverIndex = uiLogic()->m_selectedServerIndex; + DockerContainer container = uiLogic()->m_selectedDockerContainer; ServerCredentials credentials = m_settings->serverCredentials(serverIndex); QJsonObject protoConfig = m_settings->protocolConfig(serverIndex, container, Proto::ShadowSocks); @@ -186,8 +185,8 @@ void ShareConnectionLogic::onPushButtonShareShadowSocksGenerateClicked() void ShareConnectionLogic::onPushButtonShareCloakGenerateClicked() { - int serverIndex = uiLogic()->selectedServerIndex; - DockerContainer container = uiLogic()->selectedDockerContainer; + int serverIndex = uiLogic()->m_selectedServerIndex; + DockerContainer container = uiLogic()->m_selectedDockerContainer; ServerCredentials credentials = m_settings->serverCredentials(serverIndex); QJsonObject protoConfig = m_settings->protocolConfig(serverIndex, container, Proto::Cloak); @@ -209,8 +208,8 @@ void ShareConnectionLogic::onPushButtonShareCloakGenerateClicked() void ShareConnectionLogic::onPushButtonShareWireGuardGenerateClicked() { - int serverIndex = uiLogic()->selectedServerIndex; - DockerContainer container = uiLogic()->selectedDockerContainer; + int serverIndex = uiLogic()->m_selectedServerIndex; + DockerContainer container = uiLogic()->m_selectedDockerContainer; ServerCredentials credentials = m_settings->serverCredentials(serverIndex); const QJsonObject &containerConfig = m_settings->containerConfig(serverIndex, container); @@ -218,9 +217,9 @@ void ShareConnectionLogic::onPushButtonShareWireGuardGenerateClicked() ErrorCode e = ErrorCode::NoError; QString cfg = m_configurator->wireguardConfigurator->genWireguardConfig(credentials, container, containerConfig, &e); if (e) { - QMessageBox::warning(nullptr, APPLICATION_NAME, - tr("Error occurred while configuring server.") + "\n" + - errorString(e)); + emit uiLogic()->showWarningMessage(tr("Error occurred while generating the config.") + "\n" + + tr("Error message: ") + errorString(e) + "\n" + + tr("See logs for details.")); return; } cfg = m_configurator->processConfigWithExportSettings(serverIndex, container, Proto::WireGuard, cfg); @@ -236,8 +235,8 @@ void ShareConnectionLogic::onPushButtonShareWireGuardGenerateClicked() void ShareConnectionLogic::onPushButtonShareIkev2GenerateClicked() { - int serverIndex = uiLogic()->selectedServerIndex; - DockerContainer container = uiLogic()->selectedDockerContainer; + int serverIndex = uiLogic()->m_selectedServerIndex; + DockerContainer container = uiLogic()->m_selectedDockerContainer; ServerCredentials credentials = m_settings->serverCredentials(serverIndex); Ikev2Configurator::ConnectionData connData = m_configurator->ikev2Configurator->prepareIkev2Config(credentials, container); @@ -259,8 +258,8 @@ void ShareConnectionLogic::onPushButtonShareIkev2GenerateClicked() void ShareConnectionLogic::updateSharingPage(int serverIndex, DockerContainer container) { - uiLogic()->selectedDockerContainer = container; - uiLogic()->selectedServerIndex = serverIndex; + uiLogic()->m_selectedDockerContainer = container; + uiLogic()->m_selectedServerIndex = serverIndex; set_shareFullAccess(container == DockerContainer::None); m_shareAmneziaQrCodeTextSeries.clear(); diff --git a/client/ui/pages_logic/ShareConnectionLogic.h b/client/ui/pages_logic/ShareConnectionLogic.h index 5d46be97..3b9655aa 100644 --- a/client/ui/pages_logic/ShareConnectionLogic.h +++ b/client/ui/pages_logic/ShareConnectionLogic.h @@ -50,6 +50,5 @@ public: QList genQrCodeImageSeries(const QByteArray &data); QString svgToBase64(const QString &image); - }; #endif // SHARE_CONNECTION_LOGIC_H diff --git a/client/ui/pages_logic/StartPageLogic.cpp b/client/ui/pages_logic/StartPageLogic.cpp index 06febc05..8c78667d 100644 --- a/client/ui/pages_logic/StartPageLogic.cpp +++ b/client/ui/pages_logic/StartPageLogic.cpp @@ -156,7 +156,7 @@ void StartPageLogic::onPushButtonConnect() set_pushButtonConnectEnabled(true); set_pushButtonConnectText(tr("Connect")); - uiLogic()->installCredentials = serverCredentials; + uiLogic()->m_installCredentials = serverCredentials; if (ok) emit uiLogic()->goToPage(Page::NewServer); } diff --git a/client/ui/pages_logic/ViewConfigLogic.cpp b/client/ui/pages_logic/ViewConfigLogic.cpp index 9ccd9d3e..5f711498 100644 --- a/client/ui/pages_logic/ViewConfigLogic.cpp +++ b/client/ui/pages_logic/ViewConfigLogic.cpp @@ -79,8 +79,8 @@ void ViewConfigLogic::importConfig() if (!configJson().contains(config_key::containers) || configJson().value(config_key::containers).toArray().isEmpty()) { - uiLogic()->selectedServerIndex = m_settings->defaultServerIndex(); - uiLogic()->selectedDockerContainer = m_settings->defaultContainer(uiLogic()->selectedServerIndex); + uiLogic()->m_selectedServerIndex = m_settings->defaultServerIndex(); + uiLogic()->m_selectedDockerContainer = m_settings->defaultContainer(uiLogic()->m_selectedServerIndex); uiLogic()->onUpdateAllPages(); emit uiLogic()->goToPage(Page::Vpn); emit uiLogic()->setStartPage(Page::Vpn); diff --git a/client/ui/pages_logic/WizardLogic.cpp b/client/ui/pages_logic/WizardLogic.cpp index 5fe820f1..23a20aed 100644 --- a/client/ui/pages_logic/WizardLogic.cpp +++ b/client/ui/pages_logic/WizardLogic.cpp @@ -18,7 +18,7 @@ void WizardLogic::onUpdatePage() set_radioButtonMediumChecked(true); } -QMap WizardLogic::getInstallConfigsFromWizardPage() const +QPair WizardLogic::getInstallConfigsFromWizardPage() const { QJsonObject cloakConfig { { config_key::container, ContainerProps::containerToString(DockerContainer::Cloak) }, @@ -33,27 +33,29 @@ QMap WizardLogic::getInstallConfigsFromWizardPage( { config_key::container, ContainerProps::containerToString(DockerContainer::OpenVpn) } }; - QMap containers; + QPair container; + + DockerContainer dockerContainer; if (radioButtonHighChecked()) { - containers.insert(DockerContainer::Cloak, cloakConfig); + container = {DockerContainer::Cloak, cloakConfig}; } if (radioButtonMediumChecked()) { - containers.insert(DockerContainer::ShadowSocks, ssConfig); + container = {DockerContainer::ShadowSocks, ssConfig}; } if (radioButtonLowChecked()) { - containers.insert(DockerContainer::OpenVpn, openVpnConfig); + container = {DockerContainer::OpenVpn, openVpnConfig}; } - return containers; + return container; } void WizardLogic::onPushButtonVpnModeFinishClicked() { - auto containers = getInstallConfigsFromWizardPage(); - uiLogic()->installServer(containers); + auto container = getInstallConfigsFromWizardPage(); + uiLogic()->installServer(container); if (checkBoxVpnModeChecked()) { m_settings->setRouteMode(Settings::VpnOnlyForwardSites); } else { @@ -63,6 +65,6 @@ void WizardLogic::onPushButtonVpnModeFinishClicked() void WizardLogic::onPushButtonLowFinishClicked() { - auto containers = getInstallConfigsFromWizardPage(); - uiLogic()->installServer(containers); + auto container = getInstallConfigsFromWizardPage(); + uiLogic()->installServer(container); } diff --git a/client/ui/pages_logic/WizardLogic.h b/client/ui/pages_logic/WizardLogic.h index 3827c86e..a2e45af7 100644 --- a/client/ui/pages_logic/WizardLogic.h +++ b/client/ui/pages_logic/WizardLogic.h @@ -25,7 +25,7 @@ public: explicit WizardLogic(UiLogic *uiLogic, QObject *parent = nullptr); ~WizardLogic() = default; - QMap getInstallConfigsFromWizardPage() const; + QPair getInstallConfigsFromWizardPage() const; }; #endif // WIZARD_LOGIC_H diff --git a/client/ui/pages_logic/protocols/CloakLogic.cpp b/client/ui/pages_logic/protocols/CloakLogic.cpp index 6e179013..d62f8624 100644 --- a/client/ui/pages_logic/protocols/CloakLogic.cpp +++ b/client/ui/pages_logic/protocols/CloakLogic.cpp @@ -55,10 +55,10 @@ QJsonObject CloakLogic::getProtocolConfigFromPage(QJsonObject oldConfig) void CloakLogic::onPushButtonSaveClicked() { - QJsonObject protocolConfig = m_settings->protocolConfig(uiLogic()->selectedServerIndex, uiLogic()->selectedDockerContainer, Proto::Cloak); + QJsonObject protocolConfig = m_settings->protocolConfig(uiLogic()->m_selectedServerIndex, uiLogic()->m_selectedDockerContainer, Proto::Cloak); protocolConfig = getProtocolConfigFromPage(protocolConfig); - QJsonObject containerConfig = m_settings->containerConfig(uiLogic()->selectedServerIndex, uiLogic()->selectedDockerContainer); + QJsonObject containerConfig = m_settings->containerConfig(uiLogic()->m_selectedServerIndex, uiLogic()->m_selectedDockerContainer); QJsonObject newContainerConfig = containerConfig; newContainerConfig.insert(ProtocolProps::protoToString(Proto::Cloak), protocolConfig); @@ -113,8 +113,8 @@ void CloakLogic::onPushButtonSaveClicked() progressBarFunc.setTextVisibleFunc(true); progressBarFunc.setTextFunc(QString("Configuring...")); ErrorCode e = uiLogic()->pageLogic()->doInstallAction([this, containerConfig, &newContainerConfig](){ - return m_serverController->updateContainer(m_settings->serverCredentials(uiLogic()->selectedServerIndex), - uiLogic()->selectedDockerContainer, + return m_serverController->updateContainer(m_settings->serverCredentials(uiLogic()->m_selectedServerIndex), + uiLogic()->m_selectedDockerContainer, containerConfig, newContainerConfig); }, @@ -123,11 +123,11 @@ void CloakLogic::onPushButtonSaveClicked() busyInfoFuncy, cancelButtonFunc); if (!e) { - m_settings->setContainerConfig(uiLogic()->selectedServerIndex, uiLogic()->selectedDockerContainer, newContainerConfig); - m_settings->clearLastConnectionConfig(uiLogic()->selectedServerIndex, uiLogic()->selectedDockerContainer); + m_settings->setContainerConfig(uiLogic()->m_selectedServerIndex, uiLogic()->m_selectedDockerContainer, newContainerConfig); + m_settings->clearLastConnectionConfig(uiLogic()->m_selectedServerIndex, uiLogic()->m_selectedDockerContainer); } - qDebug() << "Protocol saved with code:" << e << "for" << uiLogic()->selectedServerIndex << uiLogic()->selectedDockerContainer; + qDebug() << "Protocol saved with code:" << e << "for" << uiLogic()->m_selectedServerIndex << uiLogic()->m_selectedDockerContainer; } void CloakLogic::onPushButtonCancelClicked() diff --git a/client/ui/pages_logic/protocols/OpenVpnLogic.cpp b/client/ui/pages_logic/protocols/OpenVpnLogic.cpp index 7ed71962..d5deecf3 100644 --- a/client/ui/pages_logic/protocols/OpenVpnLogic.cpp +++ b/client/ui/pages_logic/protocols/OpenVpnLogic.cpp @@ -105,10 +105,10 @@ void OpenVpnLogic::updateProtocolPage(const QJsonObject &openvpnConfig, DockerCo void OpenVpnLogic::onPushButtonSaveClicked() { - QJsonObject protocolConfig = m_settings->protocolConfig(uiLogic()->selectedServerIndex, uiLogic()->selectedDockerContainer, Proto::OpenVpn); + QJsonObject protocolConfig = m_settings->protocolConfig(uiLogic()->m_selectedServerIndex, uiLogic()->m_selectedDockerContainer, Proto::OpenVpn); protocolConfig = getProtocolConfigFromPage(protocolConfig); - QJsonObject containerConfig = m_settings->containerConfig(uiLogic()->selectedServerIndex, uiLogic()->selectedDockerContainer); + QJsonObject containerConfig = m_settings->containerConfig(uiLogic()->m_selectedServerIndex, uiLogic()->m_selectedDockerContainer); QJsonObject newContainerConfig = containerConfig; newContainerConfig.insert(ProtocolProps::protoToString(Proto::OpenVpn), protocolConfig); @@ -163,8 +163,8 @@ void OpenVpnLogic::onPushButtonSaveClicked() progressBarFunc.setTextVisibleFunc(true); progressBarFunc.setTextFunc(QString("Configuring...")); ErrorCode e = uiLogic()->pageLogic()->doInstallAction([this, containerConfig, &newContainerConfig](){ - return m_serverController->updateContainer(m_settings->serverCredentials(uiLogic()->selectedServerIndex), - uiLogic()->selectedDockerContainer, + return m_serverController->updateContainer(m_settings->serverCredentials(uiLogic()->m_selectedServerIndex), + uiLogic()->m_selectedDockerContainer, containerConfig, newContainerConfig); }, @@ -173,10 +173,10 @@ void OpenVpnLogic::onPushButtonSaveClicked() busyInfoFuncy, cancelButtonFunc); if (!e) { - m_settings->setContainerConfig(uiLogic()->selectedServerIndex, uiLogic()->selectedDockerContainer, newContainerConfig); - m_settings->clearLastConnectionConfig(uiLogic()->selectedServerIndex, uiLogic()->selectedDockerContainer); + m_settings->setContainerConfig(uiLogic()->m_selectedServerIndex, uiLogic()->m_selectedDockerContainer, newContainerConfig); + m_settings->clearLastConnectionConfig(uiLogic()->m_selectedServerIndex, uiLogic()->m_selectedDockerContainer); } - qDebug() << "Protocol saved with code:" << e << "for" << uiLogic()->selectedServerIndex << uiLogic()->selectedDockerContainer; + qDebug() << "Protocol saved with code:" << e << "for" << uiLogic()->m_selectedServerIndex << uiLogic()->m_selectedDockerContainer; } QJsonObject OpenVpnLogic::getProtocolConfigFromPage(QJsonObject oldConfig) diff --git a/client/ui/pages_logic/protocols/OtherProtocolsLogic.cpp b/client/ui/pages_logic/protocols/OtherProtocolsLogic.cpp index 8bd9d105..965a3baf 100644 --- a/client/ui/pages_logic/protocols/OtherProtocolsLogic.cpp +++ b/client/ui/pages_logic/protocols/OtherProtocolsLogic.cpp @@ -81,7 +81,7 @@ void OtherProtocolsLogic::onPushButtonSftpMountDriveClicked() { QString mountPath; QString cmd; - QString host = m_settings->serverCredentials(uiLogic()->selectedServerIndex).hostName; + QString host = m_settings->serverCredentials(uiLogic()->m_selectedServerIndex).hostName; #ifdef Q_OS_WINDOWS diff --git a/client/ui/pages_logic/protocols/ShadowSocksLogic.cpp b/client/ui/pages_logic/protocols/ShadowSocksLogic.cpp index 94a8ee04..5259a6e0 100644 --- a/client/ui/pages_logic/protocols/ShadowSocksLogic.cpp +++ b/client/ui/pages_logic/protocols/ShadowSocksLogic.cpp @@ -49,9 +49,9 @@ QJsonObject ShadowSocksLogic::getProtocolConfigFromPage(QJsonObject oldConfig) void ShadowSocksLogic::onPushButtonSaveClicked() { - QJsonObject protocolConfig = m_settings->protocolConfig(uiLogic()->selectedServerIndex, uiLogic()->selectedDockerContainer, Proto::ShadowSocks); + QJsonObject protocolConfig = m_settings->protocolConfig(uiLogic()->m_selectedServerIndex, uiLogic()->m_selectedDockerContainer, Proto::ShadowSocks); - QJsonObject containerConfig = m_settings->containerConfig(uiLogic()->selectedServerIndex, uiLogic()->selectedDockerContainer); + QJsonObject containerConfig = m_settings->containerConfig(uiLogic()->m_selectedServerIndex, uiLogic()->m_selectedDockerContainer); QJsonObject newContainerConfig = containerConfig; newContainerConfig.insert(ProtocolProps::protoToString(Proto::ShadowSocks), protocolConfig); ServerConfiguringProgressLogic::PageFunc pageFunc; @@ -105,8 +105,8 @@ void ShadowSocksLogic::onPushButtonSaveClicked() progressBarFunc.setTextVisibleFunc(true); progressBarFunc.setTextFunc(QString("Configuring...")); ErrorCode e = uiLogic()->pageLogic()->doInstallAction([this, containerConfig, &newContainerConfig](){ - return m_serverController->updateContainer(m_settings->serverCredentials(uiLogic()->selectedServerIndex), - uiLogic()->selectedDockerContainer, + return m_serverController->updateContainer(m_settings->serverCredentials(uiLogic()->m_selectedServerIndex), + uiLogic()->m_selectedDockerContainer, containerConfig, newContainerConfig); }, @@ -115,10 +115,10 @@ void ShadowSocksLogic::onPushButtonSaveClicked() busyInfoFuncy, cancelButtonFunc); if (!e) { - m_settings->setContainerConfig(uiLogic()->selectedServerIndex, uiLogic()->selectedDockerContainer, newContainerConfig); - m_settings->clearLastConnectionConfig(uiLogic()->selectedServerIndex, uiLogic()->selectedDockerContainer); + m_settings->setContainerConfig(uiLogic()->m_selectedServerIndex, uiLogic()->m_selectedDockerContainer, newContainerConfig); + m_settings->clearLastConnectionConfig(uiLogic()->m_selectedServerIndex, uiLogic()->m_selectedDockerContainer); } - qDebug() << "Protocol saved with code:" << e << "for" << uiLogic()->selectedServerIndex << uiLogic()->selectedDockerContainer; + qDebug() << "Protocol saved with code:" << e << "for" << uiLogic()->m_selectedServerIndex << uiLogic()->m_selectedDockerContainer; } void ShadowSocksLogic::onPushButtonCancelClicked() diff --git a/client/ui/qml/Controls/PopupWarning.qml b/client/ui/qml/Controls/PopupWarning.qml new file mode 100644 index 00000000..57c332eb --- /dev/null +++ b/client/ui/qml/Controls/PopupWarning.qml @@ -0,0 +1,34 @@ +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts + +Popup { + id: root + + property string popupWarningText + + anchors.centerIn: Overlay.overlay + modal: true + closePolicy: Popup.NoAutoClose + width: parent.width - 20 + + ColumnLayout { + width: parent.width + Text { + horizontalAlignment: Text.AlignHCenter + Layout.fillWidth: true + wrapMode: Text.WordWrap + font.pixelSize: 16 + text: root.popupWarningText + } + + BlueButtonType { + Layout.preferredWidth: parent.width / 2 + Layout.fillWidth: true + text: "Continue" + onClicked: { + root.close() + } + } + } +} diff --git a/client/ui/qml/Pages/PageAdvancedServerSettings.qml b/client/ui/qml/Pages/PageAdvancedServerSettings.qml new file mode 100644 index 00000000..e00f7326 --- /dev/null +++ b/client/ui/qml/Pages/PageAdvancedServerSettings.qml @@ -0,0 +1,109 @@ +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts +import PageEnum 1.0 +import "./" +import "../Controls" +import "../Config" + +PageBase { + id: root + page: PageEnum.AdvancedServerSettings + logic: AdvancedServerSettingsLogic + + enabled: AdvancedServerSettingsLogic.pageEnabled + + BackButton { + id: back + } + + Caption { + id: caption + text: qsTr("Advanced server settings") + anchors.horizontalCenter: parent.horizontalCenter + } + + BusyIndicator { + z: 99 + anchors.horizontalCenter: parent.horizontalCenter + anchors.verticalCenter: parent.verticalCenter + visible: !AdvancedServerSettingsLogic.pageEnabled + running: !AdvancedServerSettingsLogic.pageEnabled + } + + FlickableType { + id: fl + anchors.top: caption.bottom + anchors.bottom: logo.top + contentHeight: content.height + + ColumnLayout { + id: content + enabled: logic.pageEnabled + anchors.top: parent.top + anchors.left: parent.left + anchors.right: parent.right + anchors.rightMargin: 15 + + LabelType { + Layout.fillWidth: true + font.pixelSize: 20 + horizontalAlignment: Text.AlignHCenter + text: AdvancedServerSettingsLogic.labelCurrentVpnProtocolText + } + + TextFieldType { + Layout.fillWidth: true + font.pixelSize: 20 + horizontalAlignment: Text.AlignHCenter + text: AdvancedServerSettingsLogic.labelServerText + readOnly: true + background: Item {} + } + + LabelType { + Layout.fillWidth: true + horizontalAlignment: Text.AlignHCenter + text: AdvancedServerSettingsLogic.labelWaitInfoText + visible: AdvancedServerSettingsLogic.labelWaitInfoVisible + } + + BlueButtonType { + Layout.fillWidth: true + Layout.topMargin: 10 + text: "Scan the server for installed containers" + visible: AdvancedServerSettingsLogic.pushButtonClearVisible + onClicked: { + AdvancedServerSettingsLogic.onPushButtonScanServerClicked() + } + } + + BlueButtonType { + Layout.fillWidth: true + Layout.topMargin: 10 + text: AdvancedServerSettingsLogic.pushButtonClearText + visible: AdvancedServerSettingsLogic.pushButtonClearVisible + onClicked: { + popupClearServer.open() + } + } + + PopupWithQuestion { + id: popupClearServer + questionText: "Attention! All containers will be deleted on the server. This means that configuration files, keys and certificates will be deleted. Continue?" + yesFunc: function() { + close() + AdvancedServerSettingsLogic.onPushButtonClearServerClicked() + } + noFunc: function() { + close() + } + } + } + } + + Logo { + id : logo + anchors.bottom: parent.bottom + } +} diff --git a/client/ui/qml/Pages/PageServerSettings.qml b/client/ui/qml/Pages/PageServerSettings.qml index 85bc07e3..60459955 100644 --- a/client/ui/qml/Pages/PageServerSettings.qml +++ b/client/ui/qml/Pages/PageServerSettings.qml @@ -74,6 +74,7 @@ PageBase { UiLogic.goToPage(PageEnum.ServerContainers) } } + BlueButtonType { Layout.fillWidth: true Layout.topMargin: 10 @@ -86,33 +87,21 @@ PageBase { BlueButtonType { Layout.fillWidth: true - Layout.topMargin: 60 - text: ServerSettingsLogic.pushButtonClearClientCacheText - visible: ServerSettingsLogic.pushButtonClearClientCacheVisible + Layout.topMargin: 10 + text: qsTr("Advanced server settings") + visible: ServerSettingsLogic.pushButtonShareFullVisible //todo onClicked: { - ServerSettingsLogic.onPushButtonClearClientCacheClicked() + UiLogic.goToPage(PageEnum.AdvancedServerSettings) } } BlueButtonType { Layout.fillWidth: true - Layout.topMargin: 10 - text: ServerSettingsLogic.pushButtonClearText - visible: ServerSettingsLogic.pushButtonClearVisible - onClicked: { - popupClearServer.open() - } - } - - PopupWithQuestion { - id: popupClearServer - questionText: "Attention! All containers will be deleted on the server. This means that configuration files, keys and certificates will be deleted. Continue?" - yesFunc: function() { - ServerSettingsLogic.onPushButtonClearServer() - close() - } - noFunc: function() { - close() + Layout.topMargin: 60 + text: ServerSettingsLogic.pushButtonClearClientCacheText + visible: ServerSettingsLogic.pushButtonClearClientCacheVisible + onClicked: { + ServerSettingsLogic.onPushButtonClearClientCacheClicked() } } @@ -139,7 +128,6 @@ PageBase { } } - Logo { id : logo anchors.bottom: parent.bottom diff --git a/client/ui/qml/Pages/PageSetupWizardHighLevel.qml b/client/ui/qml/Pages/PageSetupWizardHighLevel.qml index 8b4bd322..e0f194ff 100644 --- a/client/ui/qml/Pages/PageSetupWizardHighLevel.qml +++ b/client/ui/qml/Pages/PageSetupWizardHighLevel.qml @@ -54,12 +54,12 @@ You SHOULD set this website address to some foreign website which is not blocked text: WizardLogic.lineEditHighWebsiteMaskingText onEditingFinished: { let _text = website_masking.text - _text.replace("http://", ""); - _text.replace("https://", ""); + _text = _text.replace("http://", ""); + _text = _text.replace("https://", ""); if (!_text) { return } - _text = _text.split("/").first(); + _text = _text.split("/")[0]; WizardLogic.lineEditHighWebsiteMaskingText = _text } onAccepted: { diff --git a/client/ui/qml/main.qml b/client/ui/qml/main.qml index 10552c11..b8758384 100644 --- a/client/ui/qml/main.qml +++ b/client/ui/qml/main.qml @@ -230,6 +230,10 @@ Window { function onToggleLogPanel() { drawer_log.visible = !drawer_log.visible } + function onShowWarningMessage(message) { + popupWarning.popupWarningText = message + popupWarning.open() + } } MessageDialog { @@ -238,12 +242,6 @@ Window { text: qsTr("It's public key. Private key required") visible: false } - MessageDialog { - id: connectErrorDialog - title: "AmneziaVPN" - text: UiLogic.dialogConnectErrorText - visible: false - } Drawer { id: drawer_log @@ -353,4 +351,8 @@ Window { } } } + + PopupWarning { + id: popupWarning + } } diff --git a/client/ui/uilogic.cpp b/client/ui/uilogic.cpp index 3d442cab..895a526c 100644 --- a/client/ui/uilogic.cpp +++ b/client/ui/uilogic.cpp @@ -10,7 +10,6 @@ #include #include #include -#include #include #include #include @@ -67,6 +66,7 @@ #include "pages_logic/ViewConfigLogic.h" #include "pages_logic/VpnLogic.h" #include "pages_logic/WizardLogic.h" +#include "pages_logic/AdvancedServerSettingsLogic.h" #include "pages_logic/protocols/CloakLogic.h" #include "pages_logic/protocols/OpenVpnLogic.h" @@ -157,7 +157,7 @@ void UiLogic::initalizeUiLogic() emit goToPage(Page::Start, true, false); } - selectedServerIndex = m_settings->defaultServerIndex(); + m_selectedServerIndex = m_settings->defaultServerIndex(); qInfo().noquote() << QString("Started %1 version %2").arg(APPLICATION_NAME).arg(APP_VERSION); qInfo().noquote() << QString("%1 (%2)").arg(QSysInfo::prettyProductName()).arg(QSysInfo::currentCpuArchitecture()); @@ -199,8 +199,8 @@ void UiLogic::keyPressEvent(Qt::Key key) qApp->quit(); break; case Qt::Key_H: - selectedServerIndex = m_settings->defaultServerIndex(); - selectedDockerContainer = m_settings->defaultContainer(selectedServerIndex); + m_selectedServerIndex = m_settings->defaultServerIndex(); + m_selectedDockerContainer = m_settings->defaultContainer(m_selectedServerIndex); //updateSharingPage(selectedServerIndex, m_settings->serverCredentials(selectedServerIndex), selectedDockerContainer); emit goToPage(Page::ShareConnection); @@ -214,7 +214,7 @@ void UiLogic::keyPressEvent(Qt::Key key) emit goToPage(Page::Start); break; case Qt::Key_S: - selectedServerIndex = m_settings->defaultServerIndex(); + m_selectedServerIndex = m_settings->defaultServerIndex(); emit goToPage(Page::ServerSettings); break; case Qt::Key_P: @@ -262,15 +262,13 @@ QString UiLogic::containerDesc(int container) void UiLogic::onGotoCurrentProtocolsPage() { - selectedServerIndex = m_settings->defaultServerIndex(); - selectedDockerContainer = m_settings->defaultContainer(selectedServerIndex); + m_selectedServerIndex = m_settings->defaultServerIndex(); + m_selectedDockerContainer = m_settings->defaultContainer(m_selectedServerIndex); emit goToPage(Page::ServerContainers); } -void UiLogic::installServer(QMap &containers) +void UiLogic::installServer(QPair &container) { - if (containers.isEmpty()) return; - emit goToPage(Page::ServerConfiguringProgress); QEventLoop loop; QTimer::singleShot(500, &loop, SLOT(quit())); @@ -325,43 +323,55 @@ void UiLogic::installServer(QMap &containers) pageLogic()->set_pushButtonCancelVisible(visible); }; - int count = 0; - ErrorCode error; - for (QMap::iterator i = containers.begin(); i != containers.end(); i++, count++) { - progressBarFunc.setTextFunc(QString("Installing %1 %2 %3").arg(count+1).arg(tr("of")).arg(containers.size())); + bool isServerCreated = false; + ErrorCode errorCode = addAlreadyInstalledContainersGui(true, isServerCreated); + if (errorCode == ErrorCode::NoError) { + if (!isContainerAlreadyAddedToGui(container.first)) { + progressBarFunc.setTextFunc(QString("Installing %1").arg(ContainerProps::containerToString(container.first))); + auto installAction = [&] () { + return m_serverController->setupContainer(m_installCredentials, container.first, container.second); + }; + errorCode = pageLogic()->doInstallAction(installAction, pageFunc, progressBarFunc, + noButton, waitInfoFunc, + busyInfoFunc, cancelButtonFunc); + m_serverController->disconnectFromHost(m_installCredentials); - error = pageLogic()->doInstallAction([&] () { - return m_serverController->setupContainer(installCredentials, i.key(), i.value()); - }, pageFunc, progressBarFunc, noButton, waitInfoFunc, busyInfoFunc, cancelButtonFunc); + if (errorCode == ErrorCode::NoError) { + if (!isServerCreated) { + QJsonObject server; + server.insert(config_key::hostName, m_installCredentials.hostName); + server.insert(config_key::userName, m_installCredentials.userName); + server.insert(config_key::password, m_installCredentials.password); + server.insert(config_key::port, m_installCredentials.port); + server.insert(config_key::description, m_settings->nextAvailableServerName()); - m_serverController->disconnectFromHost(installCredentials); - } + server.insert(config_key::containers, QJsonArray{container.second}); + server.insert(config_key::defaultContainer, ContainerProps::containerToString(container.first)); - if (error == ErrorCode::NoError) { - QJsonObject server; - server.insert(config_key::hostName, installCredentials.hostName); - server.insert(config_key::userName, installCredentials.userName); - server.insert(config_key::password, installCredentials.password); - server.insert(config_key::port, installCredentials.port); - server.insert(config_key::description, m_settings->nextAvailableServerName()); + m_settings->addServer(server); + m_settings->setDefaultServer(m_settings->serversCount() - 1); + } else { + m_settings->setContainerConfig(m_settings->serversCount() - 1, container.first, container.second); + m_settings->setDefaultContainer(m_settings->serversCount() - 1, container.first); + } + onUpdateAllPages(); - QJsonArray containerConfigs; - for (const QJsonObject &cfg : containers) { - containerConfigs.append(cfg); + emit setStartPage(Page::Vpn); + qApp->processEvents(); + return; + } + } else { + onUpdateAllPages(); + emit showWarningMessage("Attention! The container you are trying to install is already installed on the server. " + "All installed containers have been added to the application "); + emit setStartPage(Page::Vpn); + return; } - server.insert(config_key::containers, containerConfigs); - server.insert(config_key::defaultContainer, ContainerProps::containerToString(containers.firstKey())); - - m_settings->addServer(server); - m_settings->setDefaultServer(m_settings->serversCount() - 1); - onUpdateAllPages(); - - emit setStartPage(Page::Vpn); - qApp->processEvents(); - } - else { - emit closePage(); } + emit showWarningMessage(tr("Error occurred while configuring server.") + "\n" + + tr("Error message: ") + errorString(errorCode) + "\n" + + tr("See logs for details.")); + emit closePage(); } PageProtocolLogicBase *UiLogic::protocolLogic(Proto p) @@ -497,4 +507,72 @@ void UiLogic::registerPagesLogic() registerPageLogic(); registerPageLogic(); registerPageLogic(); + registerPageLogic(); +} + +ErrorCode UiLogic::addAlreadyInstalledContainersGui(bool createNewServer, bool &isServerCreated) +{ + isServerCreated = false; + ServerCredentials credentials; + if (createNewServer) { + credentials = m_installCredentials; + } else { + credentials = m_settings->serverCredentials(m_selectedServerIndex); + } + + QMap installedContainers; + ErrorCode errorCode = m_serverController->getAlreadyInstalledContainers(credentials, installedContainers); + m_serverController->disconnectFromHost(credentials); + if (errorCode != ErrorCode::NoError) { + return errorCode; + } + + if (!installedContainers.empty()) { + QJsonObject server; + QJsonArray containerConfigs; + if (createNewServer) { + server.insert(config_key::hostName, credentials.hostName); + server.insert(config_key::userName, credentials.userName); + server.insert(config_key::password, credentials.password); + server.insert(config_key::port, credentials.port); + server.insert(config_key::description, m_settings->nextAvailableServerName()); + } + + for (auto container = installedContainers.begin(); container != installedContainers.end(); container++) { + if (isContainerAlreadyAddedToGui(container.key())) { + continue; + } + + if (createNewServer) { + containerConfigs.append(container.value()); + server.insert(config_key::containers, containerConfigs); + } else { + m_settings->setContainerConfig(m_selectedServerIndex, container.key(), container.value()); + m_settings->setDefaultContainer(m_selectedServerIndex, installedContainers.firstKey()); + } + } + + if (createNewServer) { + server.insert(config_key::defaultContainer, ContainerProps::containerToString(installedContainers.firstKey())); + m_settings->addServer(server); + m_settings->setDefaultServer(m_settings->serversCount() - 1); + isServerCreated = true; + } + } + + return ErrorCode::NoError; +} + +bool UiLogic::isContainerAlreadyAddedToGui(DockerContainer container) +{ + for (int i = 0; i < m_settings->serversCount(); i++) { + const ServerCredentials credentials = m_settings->serverCredentials(i); + if (m_installCredentials.hostName == credentials.hostName && m_installCredentials.port == credentials.port) { + const QJsonObject containerConfig = m_settings->containerConfig(i, container); + if (!containerConfig.isEmpty()) { + return true; + } + } + } + return false; } diff --git a/client/ui/uilogic.h b/client/ui/uilogic.h index 4cc006dd..92035fe5 100644 --- a/client/ui/uilogic.h +++ b/client/ui/uilogic.h @@ -42,6 +42,7 @@ class StartPageLogic; class ViewConfigLogic; class VpnLogic; class WizardLogic; +class AdvancedServerSettingsLogic; class PageProtocolLogicBase; class OpenVpnLogic; @@ -52,6 +53,7 @@ class OtherProtocolsLogic; class VpnConnection; +class CreateServerTest; class UiLogic : public QObject { @@ -60,7 +62,7 @@ class UiLogic : public QObject AUTO_PROPERTY(bool, pageEnabled) AUTO_PROPERTY(int, pagesStackDepth) AUTO_PROPERTY(int, currentPageValue) - AUTO_PROPERTY(QString, dialogConnectErrorText) + AUTO_PROPERTY(QString, popupWarningText) READONLY_PROPERTY(QObject *, containersModel) READONLY_PROPERTY(QObject *, protocolsModel) @@ -87,6 +89,7 @@ public: friend class ViewConfigLogic; friend class VpnLogic; friend class WizardLogic; + friend class AdvancedServerSettingsLogic; friend class PageProtocolLogicBase; friend class OpenVpnLogic; @@ -95,6 +98,8 @@ public: friend class OtherProtocolsLogic; + friend class CreateServerTest; + Q_INVOKABLE virtual void onUpdatePage() {} // UiLogic is set as logic class for some qml pages Q_INVOKABLE void onUpdateAllPages(); @@ -112,11 +117,11 @@ public: Q_INVOKABLE void saveBinaryFile(const QString& desc, QString ext, const QString& data); Q_INVOKABLE void copyToClipboard(const QString& text); + Q_INVOKABLE amnezia::ErrorCode addAlreadyInstalledContainersGui(bool createNewServer, bool &isServerCreated); + void shareTempFile(const QString &suggestedName, QString ext, const QString& data); signals: - void dialogConnectErrorTextChanged(); - void goToPage(PageEnumNS::Page page, bool reset = true, bool slide = true); void goToProtocolPage(Proto protocol, bool reset = true, bool slide = true); void goToShareProtocolPage(Proto protocol, bool reset = true, bool slide = true); @@ -129,13 +134,15 @@ signals: void hide(); void raise(); void toggleLogPanel(); + void showWarningMessage(QString message); private slots: // containers - INOUT arg - void installServer(QMap &containers); + void installServer(QPair &container); private: PageEnumNS::Page currentPage(); + bool isContainerAlreadyAddedToGui(DockerContainer container); public: Q_INVOKABLE PageProtocolLogicBase *protocolLogic(Proto p); @@ -178,8 +185,8 @@ private: NotificationHandler* m_notificationHandler; - int selectedServerIndex = -1; // server index to use when proto settings page opened - DockerContainer selectedDockerContainer; // same - ServerCredentials installCredentials; // used to save cred between pages new_server and new_server_protocols and wizard + int m_selectedServerIndex = -1; // server index to use when proto settings page opened + DockerContainer m_selectedDockerContainer; // same + ServerCredentials m_installCredentials; // used to save cred between pages new_server and new_server_protocols and wizard }; #endif // UILOGIC_H diff --git a/client/utilities.cpp b/client/utilities.cpp index dc17e33f..d83f563d 100644 --- a/client/utilities.cpp +++ b/client/utilities.cpp @@ -241,7 +241,7 @@ QString Utils::certUtilPath() { #ifdef Q_OS_WIN QString winPath = QString::fromUtf8(qgetenv("windir")); - return winPath + "system32\\certutil.exe"; + return winPath + "\\system32\\certutil.exe"; #else return ""; #endif diff --git a/client/vpnconnection.cpp b/client/vpnconnection.cpp index 4ff67a07..e01f7e61 100644 --- a/client/vpnconnection.cpp +++ b/client/vpnconnection.cpp @@ -105,8 +105,8 @@ void VpnConnection::onConnectionStateChanged(VpnProtocol::VpnConnectionState sta } else { m_isIOSConnected = false; - m_receivedBytes = 0; - m_sentBytes = 0; +// m_receivedBytes = 0; +// m_sentBytes = 0; } #endif emit connectionStateChanged(state);