mirror of
https://github.com/amnezia-vpn/amnezia-client.git
synced 2026-05-26 12:56:45 +03:00
Compare commits
20 Commits
files_chec
...
sudo
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7c6daf1e83 | ||
|
|
f4c06f952e | ||
|
|
ab13e98ad2 | ||
|
|
4e29ce7139 | ||
|
|
60d58915c0 | ||
|
|
c0302b7a01 | ||
|
|
fecdd60787 | ||
|
|
75987b8b45 | ||
|
|
4109e9db58 | ||
|
|
8e10144717 | ||
|
|
2410bf6838 | ||
|
|
bd595f2c94 | ||
|
|
7d7a4c154d | ||
|
|
d66304f814 | ||
|
|
e7a1a93d84 | ||
|
|
9f29bc9afe | ||
|
|
a6ffd2a675 | ||
|
|
795737bbc3 | ||
|
|
61f55af76b | ||
|
|
6c5a12e626 |
@@ -107,7 +107,7 @@ set(HEADERS ${HEADERS}
|
||||
${CMAKE_CURRENT_LIST_DIR}/core/errorstrings.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/core/scripts_registry.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/core/server_defs.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/core/controllers/serverController.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/core/servercontroller.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/protocols/protocols_defs.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/protocols/qml_register_protocols.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/ui/notificationhandler.h
|
||||
@@ -146,7 +146,7 @@ set(SOURCES ${SOURCES}
|
||||
${CMAKE_CURRENT_LIST_DIR}/core/errorstrings.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/core/scripts_registry.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/core/server_defs.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/core/controllers/serverController.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/core/servercontroller.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/protocols/protocols_defs.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/ui/notificationhandler.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/ui/qautostart.cpp
|
||||
|
||||
@@ -277,16 +277,19 @@ QQmlApplicationEngine *AmneziaApplication::qmlEngine() const
|
||||
|
||||
void AmneziaApplication::initModels()
|
||||
{
|
||||
m_containersModel.reset(new ContainersModel(this));
|
||||
m_containersModel.reset(new ContainersModel(m_settings, this));
|
||||
m_engine->rootContext()->setContextProperty("ContainersModel", m_containersModel.get());
|
||||
connect(m_vpnConnection.get(), &VpnConnection::newVpnConfigurationCreated, m_containersModel.get(),
|
||||
&ContainersModel::updateContainersConfig);
|
||||
|
||||
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::defaultContainerChanged, m_containersModel.get(),
|
||||
&ContainersModel::setDefaultContainer);
|
||||
m_containersModel->setDefaultContainer(m_serversModel->getDefaultContainer()); // make better?
|
||||
connect(m_serversModel.get(), &ServersModel::currentlyProcessedServerIndexChanged, m_containersModel.get(),
|
||||
&ContainersModel::setCurrentlyProcessedServerIndex);
|
||||
connect(m_serversModel.get(), &ServersModel::defaultServerIndexChanged, m_containersModel.get(),
|
||||
&ContainersModel::setCurrentlyProcessedServerIndex);
|
||||
connect(m_containersModel.get(), &ContainersModel::containersModelUpdated, m_serversModel.get(),
|
||||
&ServersModel::updateContainersConfig);
|
||||
|
||||
m_languageModel.reset(new LanguageModel(m_settings, this));
|
||||
m_engine->rootContext()->setContextProperty("LanguageModel", m_languageModel.get());
|
||||
@@ -295,7 +298,7 @@ void AmneziaApplication::initModels()
|
||||
|
||||
m_sitesModel.reset(new SitesModel(m_settings, this));
|
||||
m_engine->rootContext()->setContextProperty("SitesModel", m_sitesModel.get());
|
||||
|
||||
|
||||
m_protocolsModel.reset(new ProtocolsModel(m_settings, this));
|
||||
m_engine->rootContext()->setContextProperty("ProtocolsModel", m_protocolsModel.get());
|
||||
|
||||
@@ -321,16 +324,6 @@ void AmneziaApplication::initModels()
|
||||
|
||||
m_sftpConfigModel.reset(new SftpConfigModel(this));
|
||||
m_engine->rootContext()->setContextProperty("SftpConfigModel", m_sftpConfigModel.get());
|
||||
|
||||
m_clientManagementModel.reset(new ClientManagementModel(m_settings, this));
|
||||
m_engine->rootContext()->setContextProperty("ClientManagementModel", m_clientManagementModel.get());
|
||||
|
||||
connect(m_configurator.get(), &VpnConfigurator::newVpnConfigCreated, this,
|
||||
[this](const QString &clientId, const QString &clientName, const DockerContainer container,
|
||||
ServerCredentials credentials) {
|
||||
m_serversModel->reloadContainerConfig();
|
||||
m_clientManagementModel->appendClient(clientId, clientName, container, credentials);
|
||||
});
|
||||
}
|
||||
|
||||
void AmneziaApplication::initControllers()
|
||||
@@ -356,24 +349,18 @@ void AmneziaApplication::initControllers()
|
||||
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_configurator));
|
||||
m_exportController.reset(new ExportController(m_serversModel, m_containersModel, m_settings, m_configurator));
|
||||
m_engine->rootContext()->setContextProperty("ExportController", m_exportController.get());
|
||||
|
||||
m_settingsController.reset(new SettingsController(m_serversModel, m_containersModel, m_languageModel, m_settings));
|
||||
m_engine->rootContext()->setContextProperty("SettingsController", m_settingsController.get());
|
||||
if (m_settingsController->isAutoConnectEnabled() && m_serversModel->getDefaultServerIndex() >= 0) {
|
||||
if (m_settingsController->isAutoStartEnabled() && 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_systemController.reset(new SystemController(m_settings));
|
||||
m_engine->rootContext()->setContextProperty("SystemController", m_systemController.get());
|
||||
|
||||
m_cloudController.reset(new ApiController(m_serversModel, m_containersModel));
|
||||
m_engine->rootContext()->setContextProperty("ApiController", m_cloudController.get());
|
||||
}
|
||||
|
||||
@@ -24,7 +24,6 @@
|
||||
#include "ui/controllers/settingsController.h"
|
||||
#include "ui/controllers/sitesController.h"
|
||||
#include "ui/controllers/systemController.h"
|
||||
#include "ui/controllers/apiController.h"
|
||||
#include "ui/models/containers_model.h"
|
||||
#include "ui/models/languageModel.h"
|
||||
#include "ui/models/protocols/cloakConfigModel.h"
|
||||
@@ -40,7 +39,6 @@
|
||||
#include "ui/models/servers_model.h"
|
||||
#include "ui/models/services/sftpConfigModel.h"
|
||||
#include "ui/models/sites_model.h"
|
||||
#include "ui/models/clientManagementModel.h"
|
||||
|
||||
#define amnApp (static_cast<AmneziaApplication *>(QCoreApplication::instance()))
|
||||
|
||||
@@ -96,7 +94,6 @@ private:
|
||||
QSharedPointer<LanguageModel> m_languageModel;
|
||||
QSharedPointer<ProtocolsModel> m_protocolsModel;
|
||||
QSharedPointer<SitesModel> m_sitesModel;
|
||||
QSharedPointer<ClientManagementModel> m_clientManagementModel;
|
||||
|
||||
QScopedPointer<OpenVpnConfigModel> m_openVpnConfigModel;
|
||||
QScopedPointer<ShadowSocksConfigModel> m_shadowSocksConfigModel;
|
||||
@@ -121,7 +118,6 @@ private:
|
||||
QScopedPointer<SettingsController> m_settingsController;
|
||||
QScopedPointer<SitesController> m_sitesController;
|
||||
QScopedPointer<SystemController> m_systemController;
|
||||
QScopedPointer<ApiController> m_cloudController;
|
||||
};
|
||||
|
||||
#endif // AMNEZIA_APPLICATION_H
|
||||
|
||||
@@ -3,17 +3,18 @@
|
||||
#include <QJsonDocument>
|
||||
#include <QJsonObject>
|
||||
|
||||
#include "core/controllers/serverController.h"
|
||||
#include "core/servercontroller.h"
|
||||
|
||||
AwgConfigurator::AwgConfigurator(std::shared_ptr<Settings> settings, QObject *parent)
|
||||
: WireguardConfigurator(settings, true, parent)
|
||||
{
|
||||
}
|
||||
|
||||
QString AwgConfigurator::genAwgConfig(const ServerCredentials &credentials, DockerContainer container,
|
||||
const QJsonObject &containerConfig, QString &clientId, ErrorCode *errorCode)
|
||||
QString AwgConfigurator::genAwgConfig(const ServerCredentials &credentials,
|
||||
DockerContainer container,
|
||||
const QJsonObject &containerConfig, ErrorCode *errorCode)
|
||||
{
|
||||
QString config = WireguardConfigurator::genWireguardConfig(credentials, container, containerConfig, clientId, errorCode);
|
||||
QString config = WireguardConfigurator::genWireguardConfig(credentials, container, containerConfig, errorCode);
|
||||
|
||||
QJsonObject jsonConfig = QJsonDocument::fromJson(config.toUtf8()).object();
|
||||
QString awgConfig = jsonConfig.value(config_key::config).toString();
|
||||
|
||||
@@ -12,7 +12,7 @@ public:
|
||||
AwgConfigurator(std::shared_ptr<Settings> settings, QObject *parent = nullptr);
|
||||
|
||||
QString genAwgConfig(const ServerCredentials &credentials, DockerContainer container,
|
||||
const QJsonObject &containerConfig, QString &clientId, ErrorCode *errorCode = nullptr);
|
||||
const QJsonObject &containerConfig, ErrorCode *errorCode = nullptr);
|
||||
};
|
||||
|
||||
#endif // AWGCONFIGURATOR_H
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
#include <QJsonObject>
|
||||
#include <QJsonDocument>
|
||||
|
||||
#include "core/controllers/serverController.h"
|
||||
#include "core/servercontroller.h"
|
||||
#include "containers/containers_defs.h"
|
||||
|
||||
CloakConfigurator::CloakConfigurator(std::shared_ptr<Settings> settings, QObject *parent):
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
#include "containers/containers_defs.h"
|
||||
#include "core/scripts_registry.h"
|
||||
#include "core/server_defs.h"
|
||||
#include "core/controllers/serverController.h"
|
||||
#include "core/servercontroller.h"
|
||||
#include "utilities.h"
|
||||
|
||||
Ikev2Configurator::Ikev2Configurator(std::shared_ptr<Settings> settings, QObject *parent)
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
#include "containers/containers_defs.h"
|
||||
#include "core/scripts_registry.h"
|
||||
#include "core/server_defs.h"
|
||||
#include "core/controllers/serverController.h"
|
||||
#include "core/servercontroller.h"
|
||||
#include "settings.h"
|
||||
#include "utilities.h"
|
||||
|
||||
@@ -83,7 +83,7 @@ OpenVpnConfigurator::ConnectionData OpenVpnConfigurator::prepareOpenVpnConfig(co
|
||||
}
|
||||
|
||||
QString OpenVpnConfigurator::genOpenVpnConfig(const ServerCredentials &credentials, DockerContainer container,
|
||||
const QJsonObject &containerConfig, QString &clientId, ErrorCode *errorCode)
|
||||
const QJsonObject &containerConfig, ErrorCode *errorCode)
|
||||
{
|
||||
ServerController serverController(m_settings);
|
||||
QString config =
|
||||
@@ -113,8 +113,6 @@ QString OpenVpnConfigurator::genOpenVpnConfig(const ServerCredentials &credentia
|
||||
QJsonObject jConfig;
|
||||
jConfig[config_key::config] = config;
|
||||
|
||||
clientId = connData.clientId;
|
||||
|
||||
return QJsonDocument(jConfig).toJson();
|
||||
}
|
||||
|
||||
@@ -133,13 +131,13 @@ QString OpenVpnConfigurator::processConfigWithLocalSettings(QString jsonConfig)
|
||||
config.append("block-ipv6\n");
|
||||
}
|
||||
if (m_settings->routeMode() == Settings::VpnOnlyForwardSites) {
|
||||
|
||||
|
||||
// no redirect-gateway
|
||||
}
|
||||
if (m_settings->routeMode() == Settings::VpnAllExceptSites) {
|
||||
#ifndef Q_OS_ANDROID
|
||||
#ifndef Q_OS_ANDROID
|
||||
config.append("\nredirect-gateway ipv6 !ipv4 bypass-dhcp\n");
|
||||
#endif
|
||||
#endif
|
||||
// Prevent ipv6 leak
|
||||
config.append("ifconfig-ipv6 fd15:53b6:dead::2/64 fd15:53b6:dead::1\n");
|
||||
config.append("block-ipv6\n");
|
||||
|
||||
@@ -24,7 +24,7 @@ public:
|
||||
};
|
||||
|
||||
QString genOpenVpnConfig(const ServerCredentials &credentials, DockerContainer container,
|
||||
const QJsonObject &containerConfig, QString &clientId, ErrorCode *errorCode = nullptr);
|
||||
const QJsonObject &containerConfig, ErrorCode *errorCode = nullptr);
|
||||
|
||||
QString processConfigWithLocalSettings(QString jsonConfig);
|
||||
QString processConfigWithExportSettings(QString jsonConfig);
|
||||
@@ -32,9 +32,9 @@ public:
|
||||
ErrorCode signCert(DockerContainer container,
|
||||
const ServerCredentials &credentials, QString clientId);
|
||||
|
||||
static ConnectionData createCertRequest();
|
||||
|
||||
private:
|
||||
ConnectionData createCertRequest();
|
||||
|
||||
ConnectionData prepareOpenVpnConfig(const ServerCredentials &credentials,
|
||||
DockerContainer container, ErrorCode *errorCode = nullptr);
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
#include <QJsonDocument>
|
||||
|
||||
#include "containers/containers_defs.h"
|
||||
#include "core/controllers/serverController.h"
|
||||
#include "core/servercontroller.h"
|
||||
|
||||
ShadowSocksConfigurator::ShadowSocksConfigurator(std::shared_ptr<Settings> settings, QObject *parent):
|
||||
ConfiguratorBase(settings, parent)
|
||||
|
||||
@@ -28,11 +28,11 @@ VpnConfigurator::VpnConfigurator(std::shared_ptr<Settings> settings, QObject *pa
|
||||
}
|
||||
|
||||
QString VpnConfigurator::genVpnProtocolConfig(const ServerCredentials &credentials, DockerContainer container,
|
||||
const QJsonObject &containerConfig, Proto proto, QString &clientId, ErrorCode *errorCode)
|
||||
const QJsonObject &containerConfig, Proto proto, ErrorCode *errorCode)
|
||||
{
|
||||
switch (proto) {
|
||||
case Proto::OpenVpn:
|
||||
return openVpnConfigurator->genOpenVpnConfig(credentials, container, containerConfig, clientId, errorCode);
|
||||
return openVpnConfigurator->genOpenVpnConfig(credentials, container, containerConfig, errorCode);
|
||||
|
||||
case Proto::ShadowSocks:
|
||||
return shadowSocksConfigurator->genShadowSocksConfig(credentials, container, containerConfig, errorCode);
|
||||
@@ -40,10 +40,10 @@ QString VpnConfigurator::genVpnProtocolConfig(const ServerCredentials &credentia
|
||||
case Proto::Cloak: return cloakConfigurator->genCloakConfig(credentials, container, containerConfig, errorCode);
|
||||
|
||||
case Proto::WireGuard:
|
||||
return wireguardConfigurator->genWireguardConfig(credentials, container, containerConfig, clientId, errorCode);
|
||||
return wireguardConfigurator->genWireguardConfig(credentials, container, containerConfig, errorCode);
|
||||
|
||||
case Proto::Awg:
|
||||
return awgConfigurator->genAwgConfig(credentials, container, containerConfig, clientId, errorCode);
|
||||
return awgConfigurator->genAwgConfig(credentials, container, containerConfig, errorCode);
|
||||
|
||||
case Proto::Ikev2: return ikev2Configurator->genIkev2Config(credentials, container, containerConfig, errorCode);
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
#include "configurator_base.h"
|
||||
#include "core/defs.h"
|
||||
|
||||
|
||||
class OpenVpnConfigurator;
|
||||
class ShadowSocksConfigurator;
|
||||
class CloakConfigurator;
|
||||
@@ -15,15 +16,14 @@ class SshConfigurator;
|
||||
class AwgConfigurator;
|
||||
|
||||
// Retrieve connection settings from server
|
||||
class VpnConfigurator : public ConfiguratorBase
|
||||
class VpnConfigurator : ConfiguratorBase
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit VpnConfigurator(std::shared_ptr<Settings> settings, QObject *parent = nullptr);
|
||||
|
||||
QString genVpnProtocolConfig(const ServerCredentials &credentials, DockerContainer container,
|
||||
const QJsonObject &containerConfig, Proto proto, QString &clientId,
|
||||
ErrorCode *errorCode = nullptr);
|
||||
const QJsonObject &containerConfig, Proto proto, ErrorCode *errorCode = nullptr);
|
||||
|
||||
QPair<QString, QString> getDnsForConfig(int serverIndex);
|
||||
QString &processConfigWithDnsSettings(int serverIndex, DockerContainer container, Proto proto, QString &config);
|
||||
@@ -32,8 +32,8 @@ public:
|
||||
QString &processConfigWithExportSettings(int serverIndex, DockerContainer container, Proto proto, QString &config);
|
||||
|
||||
// workaround for containers which is not support normal configuration
|
||||
void updateContainerConfigAfterInstallation(DockerContainer container, QJsonObject &containerConfig,
|
||||
const QString &stdOut);
|
||||
void updateContainerConfigAfterInstallation(DockerContainer container,
|
||||
QJsonObject &containerConfig, const QString &stdOut);
|
||||
|
||||
std::shared_ptr<OpenVpnConfigurator> openVpnConfigurator;
|
||||
std::shared_ptr<ShadowSocksConfigurator> shadowSocksConfigurator;
|
||||
@@ -42,10 +42,6 @@ public:
|
||||
std::shared_ptr<Ikev2Configurator> ikev2Configurator;
|
||||
std::shared_ptr<SshConfigurator> sshConfigurator;
|
||||
std::shared_ptr<AwgConfigurator> awgConfigurator;
|
||||
|
||||
signals:
|
||||
void newVpnConfigCreated(const QString &clientId, const QString &clientName, const DockerContainer container,
|
||||
ServerCredentials credentials);
|
||||
};
|
||||
|
||||
#endif // VPN_CONFIGURATOR_H
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
#include "containers/containers_defs.h"
|
||||
#include "core/scripts_registry.h"
|
||||
#include "core/server_defs.h"
|
||||
#include "core/controllers/serverController.h"
|
||||
#include "core/servercontroller.h"
|
||||
#include "settings.h"
|
||||
#include "utilities.h"
|
||||
|
||||
@@ -177,7 +177,7 @@ WireguardConfigurator::ConnectionData WireguardConfigurator::prepareWireguardCon
|
||||
}
|
||||
|
||||
QString WireguardConfigurator::genWireguardConfig(const ServerCredentials &credentials, DockerContainer container,
|
||||
const QJsonObject &containerConfig, QString &clientId, ErrorCode *errorCode)
|
||||
const QJsonObject &containerConfig, ErrorCode *errorCode)
|
||||
{
|
||||
ServerController serverController(m_settings);
|
||||
QString scriptData = amnezia::scriptData(m_configTemplate, container);
|
||||
@@ -205,8 +205,6 @@ QString WireguardConfigurator::genWireguardConfig(const ServerCredentials &crede
|
||||
jConfig[config_key::psk_key] = connData.pskKey;
|
||||
jConfig[config_key::server_pub_key] = connData.serverPubKey;
|
||||
|
||||
clientId = connData.clientPubKey;
|
||||
|
||||
return QJsonDocument(jConfig).toJson();
|
||||
}
|
||||
|
||||
|
||||
@@ -26,7 +26,7 @@ public:
|
||||
};
|
||||
|
||||
QString genWireguardConfig(const ServerCredentials &credentials, DockerContainer container,
|
||||
const QJsonObject &containerConfig, QString &clientId, ErrorCode *errorCode = nullptr);
|
||||
const QJsonObject &containerConfig, ErrorCode *errorCode = nullptr);
|
||||
|
||||
QString processConfigWithLocalSettings(QString config);
|
||||
QString processConfigWithExportSettings(QString config);
|
||||
|
||||
@@ -54,11 +54,11 @@ QVector<amnezia::Proto> ContainerProps::protocolsForContainer(amnezia::DockerCon
|
||||
|
||||
case DockerContainer::ShadowSocks: return { Proto::OpenVpn, Proto::ShadowSocks };
|
||||
|
||||
case DockerContainer::Cloak: return { Proto::OpenVpn, /*Proto::ShadowSocks,*/ Proto::Cloak };
|
||||
case DockerContainer::Cloak: return { Proto::OpenVpn, Proto::ShadowSocks, Proto::Cloak };
|
||||
|
||||
case DockerContainer::Ipsec: return { Proto::Ikev2 /*, Protocol::L2tp */ };
|
||||
|
||||
case DockerContainer::Dns: return { Proto::Dns };
|
||||
case DockerContainer::Dns: return {};
|
||||
|
||||
case DockerContainer::Sftp: return { Proto::Sftp };
|
||||
|
||||
|
||||
@@ -47,6 +47,7 @@ enum ErrorCode
|
||||
SshSftpNoMediaError,
|
||||
|
||||
// Local errors
|
||||
FailedToSaveConfigData,
|
||||
OpenVpnConfigMissing,
|
||||
OpenVpnManagementServerError,
|
||||
ConfigMissing,
|
||||
@@ -66,6 +67,7 @@ enum ErrorCode
|
||||
|
||||
// 3rd party utils errors
|
||||
OpenSslFailed,
|
||||
OpenVpnExecutableCrashed,
|
||||
ShadowSocksExecutableCrashed,
|
||||
CloakExecutableCrashed,
|
||||
|
||||
|
||||
@@ -42,6 +42,7 @@ QString errorString(ErrorCode code){
|
||||
case(SshSftpNoMediaError): return QObject::tr("Sftp error: No media was in remote drive");
|
||||
|
||||
// Local errors
|
||||
case (FailedToSaveConfigData): return QObject::tr("Failed to save config to disk");
|
||||
case (OpenVpnConfigMissing): return QObject::tr("OpenVPN config missing");
|
||||
case (OpenVpnManagementServerError): return QObject::tr("OpenVPN management server error");
|
||||
|
||||
@@ -57,7 +58,7 @@ QString errorString(ErrorCode code){
|
||||
case (OpenVpnTapAdapterError): return QObject::tr("Can't setup OpenVPN TAP network adapter");
|
||||
case (AddressPoolError): return QObject::tr("VPN pool error: no available addresses");
|
||||
|
||||
case (ImportInvalidConfigError): return QObject::tr("The config does not contain any containers and credentials for connecting to the server");
|
||||
case (ImportInvalidConfigError): return QObject::tr("The config does not contain any containers and credentiaks for connecting to the server");
|
||||
|
||||
case(InternalError):
|
||||
default:
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#include "serverController.h"
|
||||
#include "servercontroller.h"
|
||||
|
||||
#include <QCryptographicHash>
|
||||
#include <QDir>
|
||||
@@ -24,8 +24,8 @@
|
||||
|
||||
#include "containers/containers_defs.h"
|
||||
#include "logger.h"
|
||||
#include "core/scripts_registry.h"
|
||||
#include "core/server_defs.h"
|
||||
#include "scripts_registry.h"
|
||||
#include "server_defs.h"
|
||||
#include "settings.h"
|
||||
#include "utilities.h"
|
||||
|
||||
@@ -634,9 +634,9 @@ QString ServerController::checkSshConnection(const ServerCredentials &credential
|
||||
return stdOut;
|
||||
}
|
||||
|
||||
void ServerController::cancelInstallation()
|
||||
void ServerController::setCancelInstallation(const bool cancel)
|
||||
{
|
||||
m_cancelInstallation = true;
|
||||
m_cancelInstallation = cancel;
|
||||
}
|
||||
|
||||
ErrorCode ServerController::setupServerFirewall(const ServerCredentials &credentials)
|
||||
@@ -737,7 +737,6 @@ ErrorCode ServerController::isUserInSudo(const ServerCredentials &credentials, D
|
||||
|
||||
ErrorCode ServerController::isServerDpkgBusy(const ServerCredentials &credentials, DockerContainer container)
|
||||
{
|
||||
m_cancelInstallation = false;
|
||||
QString stdOut;
|
||||
auto cbReadStdOut = [&](const QString &data, libssh::Client &) {
|
||||
stdOut += data + "\n";
|
||||
@@ -785,6 +784,7 @@ ErrorCode ServerController::isServerDpkgBusy(const ServerCredentials &credential
|
||||
watcher.setFuture(future);
|
||||
wait.exec();
|
||||
|
||||
m_cancelInstallation = false;
|
||||
emit serverIsBusy(false);
|
||||
|
||||
return future.result();
|
||||
@@ -5,8 +5,8 @@
|
||||
#include <QObject>
|
||||
|
||||
#include "containers/containers_defs.h"
|
||||
#include "core/defs.h"
|
||||
#include "core/sshclient.h"
|
||||
#include "defs.h"
|
||||
#include "sshclient.h"
|
||||
|
||||
class Settings;
|
||||
class VpnConfigurator;
|
||||
@@ -56,7 +56,7 @@ public:
|
||||
|
||||
QString checkSshConnection(const ServerCredentials &credentials, ErrorCode *errorCode = nullptr);
|
||||
|
||||
void cancelInstallation();
|
||||
void setCancelInstallation(const bool cancel);
|
||||
|
||||
ErrorCode getDecryptedPrivateKey(const ServerCredentials &credentials, QString &decryptedPrivateKey,
|
||||
const std::function<QString()> &callback);
|
||||
@@ -1,6 +0,0 @@
|
||||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g id="x, ×, close">
|
||||
<path id="Vector" d="M18 6L6 18" stroke="#D7D8DB" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path id="Vector_2" d="M6 6L18 18" stroke="#D7D8DB" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 374 B |
@@ -1,6 +0,0 @@
|
||||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g id="search">
|
||||
<path id="Vector" d="M11 19C15.4183 19 19 15.4183 19 11C19 6.58172 15.4183 3 11 3C6.58172 3 3 6.58172 3 11C3 15.4183 6.58172 19 11 19Z" stroke="#D7D8DB" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path id="Vector_2" d="M21.0004 20.9984L16.6504 16.6484" stroke="#D7D8DB" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 483 B |
@@ -21,7 +21,6 @@ namespace amnezia
|
||||
constexpr char dns2[] = "dns2";
|
||||
|
||||
constexpr char description[] = "description";
|
||||
constexpr char name[] = "name";
|
||||
constexpr char cert[] = "cert";
|
||||
constexpr char config[] = "config";
|
||||
|
||||
@@ -80,8 +79,6 @@ namespace amnezia
|
||||
constexpr char sftp[] = "sftp";
|
||||
constexpr char awg[] = "awg";
|
||||
|
||||
constexpr char configVersion[] = "config_version";
|
||||
|
||||
constexpr char splitTunnelSites[] = "splitTunnelSites";
|
||||
constexpr char splitTunnelType[] = "splitTunnelType";
|
||||
|
||||
|
||||
@@ -222,8 +222,5 @@
|
||||
<file>server_scripts/awg/configure_container.sh</file>
|
||||
<file>server_scripts/awg/run_container.sh</file>
|
||||
<file>server_scripts/awg/Dockerfile</file>
|
||||
<file>ui/qml/Pages2/PageShareFullAccess.qml</file>
|
||||
<file>images/controls/close.svg</file>
|
||||
<file>images/controls/search.svg</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
|
||||
@@ -7,19 +7,11 @@ if [ "$dist" = "debian" ]; then export DEBIAN_FRONTEND=noninteractive; fi;\
|
||||
if ! command -v sudo > /dev/null 2>&1; then $pm $check_pkgs; $pm $silent_inst sudo; fi;\
|
||||
if ! command -v fuser > /dev/null 2>&1; then sudo $pm $check_pkgs; sudo $pm $silent_inst psmisc; fi;\
|
||||
if ! command -v lsof > /dev/null 2>&1; then sudo $pm $check_pkgs; sudo $pm $silent_inst lsof; fi;\
|
||||
if ! command -v docker > /dev/null 2>&1; then \
|
||||
if [ "$dist" = "centos" ]; then CHECK_FILE="/etc/yum/pluginconf.d/subscription-manager.conf";\
|
||||
if [ -f "$CHECK_FILE" ]; then FILE_Ex=1; else FILE_Ex=0; fi;\
|
||||
fi;\
|
||||
sudo $pm $check_pkgs; sudo $pm $silent_inst $docker_pkg;\
|
||||
if [ "$dist" = "centos" ] && [ "$FILE_Ex" = "0" ]; then \
|
||||
if [ -f "$CHECK_FILE" ]; then echo "$(sed '2 s/enabled=1/enabled=0/' $CHECK_FILE)" > $CHECK_FILE; fi;\
|
||||
fi;\
|
||||
sleep 5; sudo systemctl enable --now docker; sleep 5;\
|
||||
if ! command -v docker > /dev/null 2>&1; then sudo $pm $check_pkgs; sudo $pm $silent_inst $docker_pkg;\
|
||||
sleep 5 && sudo systemctl enable --now docker && sleep 5;\
|
||||
fi;\
|
||||
if [ "$(systemctl is-active docker)" != "active" ]; then \
|
||||
sudo $pm $check_pkgs; sudo $pm $silent_inst $docker_pkg;\
|
||||
sleep 5; sudo systemctl start docker; sleep 5;\
|
||||
if [ "$(systemctl is-active docker)" != "active" ]; then sudo $pm $check_pkgs; sudo $pm $silent_inst $docker_pkg;\
|
||||
sleep 5 && sudo systemctl start docker && sleep 5;\
|
||||
fi;\
|
||||
if ! command -v sudo > /dev/null 2>&1; then echo "Failed to install sudo, command not found"; exit 1; fi;\
|
||||
if ! command -v sudo > /dev/null 2>&1; then echo "Failed to install Docker"; exit 1; fi;\
|
||||
docker --version
|
||||
|
||||
@@ -27,26 +27,9 @@
|
||||
<translation>VPN Подключен</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>CloudController</name>
|
||||
<message>
|
||||
<location filename="../ui/controllers/cloudController.cpp" line="102"/>
|
||||
<source>Error when retrieving configuration from cloud server</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>CloudController</name>
|
||||
<message>
|
||||
<location filename="../ui/controllers/cloudController.cpp" line="102"/>
|
||||
<source>Error when retrieving configuration from cloud server</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>ConnectionController</name>
|
||||
<message>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="38"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="38"/>
|
||||
<source>VPN Protocols is not installed.
|
||||
Please install VPN container at first</source>
|
||||
@@ -54,35 +37,35 @@
|
||||
Пожалуйста, установите протокол</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="62"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="61"/>
|
||||
<source>Connection...</source>
|
||||
<translation>Подключение...</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="83"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="66"/>
|
||||
<source>Connected</source>
|
||||
<translation>Подключено</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="128"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="111"/>
|
||||
<source>Settings updated successfully, Reconnnection...</source>
|
||||
<translation>Настройки успешно обновлены. Подключение...</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="92"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="75"/>
|
||||
<source>Reconnection...</source>
|
||||
<translation>Переподключение...</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/connectionController.h" line="58"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="97"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="111"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="117"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="80"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="94"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="100"/>
|
||||
<source>Connect</source>
|
||||
<translation>Подключиться</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="102"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="85"/>
|
||||
<source>Disconnection...</source>
|
||||
<translation>Отключение...</translation>
|
||||
</message>
|
||||
@@ -156,7 +139,7 @@
|
||||
<context>
|
||||
<name>ImportController</name>
|
||||
<message>
|
||||
<location filename="../ui/controllers/importController.cpp" line="384"/>
|
||||
<location filename="../ui/controllers/importController.cpp" line="427"/>
|
||||
<source>Scanned %1 of %2.</source>
|
||||
<translation>Отсканировано %1 из%2.</translation>
|
||||
</message>
|
||||
@@ -164,52 +147,58 @@
|
||||
<context>
|
||||
<name>InstallController</name>
|
||||
<message>
|
||||
<location filename="../ui/controllers/installController.cpp" line="110"/>
|
||||
<location filename="../ui/controllers/installController.cpp" line="162"/>
|
||||
<location filename="../ui/controllers/installController.cpp" line="143"/>
|
||||
<location filename="../ui/controllers/installController.cpp" line="193"/>
|
||||
<source>%1 installed successfully. </source>
|
||||
<translation>%1 успешно установлен. </translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/installController.cpp" line="112"/>
|
||||
<location filename="../ui/controllers/installController.cpp" line="164"/>
|
||||
<location filename="../ui/controllers/installController.cpp" line="145"/>
|
||||
<location filename="../ui/controllers/installController.cpp" line="195"/>
|
||||
<source>%1 is already installed on the server. </source>
|
||||
<translation>%1 уже установлен на сервер. </translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/installController.cpp" line="115"/>
|
||||
<location filename="../ui/controllers/installController.cpp" line="183"/>
|
||||
<location filename="../ui/controllers/installController.cpp" line="148"/>
|
||||
<source>
|
||||
Added containers that were already installed on the server</source>
|
||||
<translation>
|
||||
В приложение добавлены обнаруженные на сервере протоклы и сервисы</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/installController.cpp" line="214"/>
|
||||
<source>
|
||||
Already installed containers were found on the server. All installed containers have been added to the application</source>
|
||||
<translation>
|
||||
На сервере обнаружены установленные протоколы и сервисы, все они добавлены в приложение</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/installController.cpp" line="264"/>
|
||||
<location filename="../ui/controllers/installController.cpp" line="295"/>
|
||||
<source>Settings updated successfully</source>
|
||||
<translation>Настройки успешно обновлены</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/installController.cpp" line="279"/>
|
||||
<location filename="../ui/controllers/installController.cpp" line="310"/>
|
||||
<source>Server '%1' was removed</source>
|
||||
<translation>Сервер '%1' был удален</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/installController.cpp" line="289"/>
|
||||
<location filename="../ui/controllers/installController.cpp" line="320"/>
|
||||
<source>All containers from server '%1' have been removed</source>
|
||||
<translation>Все протоклы и сервисы были удалены с сервера '%1'</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/installController.cpp" line="306"/>
|
||||
<location filename="../ui/controllers/installController.cpp" line="337"/>
|
||||
<source>%1 has been removed from the server '%2'</source>
|
||||
<translation>%1 был удален с сервера '%2'</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/installController.cpp" line="452"/>
|
||||
<location filename="../ui/controllers/installController.cpp" line="483"/>
|
||||
<source>Please login as the user</source>
|
||||
<translation>Пожалуйста, войдите в систему от имени пользователя</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/installController.cpp" line="479"/>
|
||||
<location filename="../ui/controllers/installController.cpp" line="511"/>
|
||||
<source>Server added successfully</source>
|
||||
<translation>Сервер успешно добавлен</translation>
|
||||
</message>
|
||||
@@ -277,12 +266,12 @@ Already installed containers were found on the server. All installed containers
|
||||
<context>
|
||||
<name>PageHome</name>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageHome.qml" line="193"/>
|
||||
<location filename="../ui/qml/Pages2/PageHome.qml" line="354"/>
|
||||
<source>VPN protocol</source>
|
||||
<translation>VPN протокол</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageHome.qml" line="238"/>
|
||||
<location filename="../ui/qml/Pages2/PageHome.qml" line="398"/>
|
||||
<source>Servers</source>
|
||||
<translation>Серверы</translation>
|
||||
</message>
|
||||
@@ -1011,18 +1000,18 @@ Already installed containers were found on the server. All installed containers
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSettingsApplication.qml" line="52"/>
|
||||
<source>Allow application screenshots</source>
|
||||
<translation>Разрешить скриншоты</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSettingsApplication.qml" line="72"/>
|
||||
<source>Auto start</source>
|
||||
<translation type="unfinished"></translation>
|
||||
<translation>Авто-запуск</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSettingsApplication.qml" line="53"/>
|
||||
<source>Launch the application every time </source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSettingsApplication.qml" line="53"/>
|
||||
<source> starts</source>
|
||||
<translation type="unfinished"></translation>
|
||||
<location filename="../ui/qml/Pages2/PageSettingsApplication.qml" line="73"/>
|
||||
<source>Launch the application every time the device is starts</source>
|
||||
<translation>Запускать приложение при каждом включении</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSettingsApplication.qml" line="93"/>
|
||||
@@ -1943,7 +1932,12 @@ and will not be shared or disclosed to the Amnezia or any third parties</source>
|
||||
<translation>Доступ </translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="306"/>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="222"/>
|
||||
<source>File with accessing settings to </source>
|
||||
<translation>Файл с настройками доступа к </translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="309"/>
|
||||
<source>Connection to </source>
|
||||
<translation>Подключение к </translation>
|
||||
</message>
|
||||
@@ -1983,12 +1977,13 @@ and will not be shared or disclosed to the Amnezia or any third parties</source>
|
||||
<translation>Поделиться доступом к VPN, без возможности управления сервером</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="248"/>
|
||||
<source>Protocols</source>
|
||||
<translation type="unfinished"></translation>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="175"/>
|
||||
<source>Share access to server management. The user with whom you share full access to the server will be able to add and remove any protocols and services to the server, as well as change settings.</source>
|
||||
<translation>Поделиться доступом к управлению сервером. Пользователь, с которым вы делитесь полным доступом к серверу, сможет добавлять и удалять любые протоколы и службы на сервере, а также изменять настройки.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="249"/>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="251"/>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="252"/>
|
||||
<source>Protocol</source>
|
||||
<translation>Протокол</translation>
|
||||
</message>
|
||||
@@ -2447,7 +2442,7 @@ and will not be shared or disclosed to the Amnezia or any third parties</source>
|
||||
<message>
|
||||
<location filename="../core/errorstrings.cpp" line="61"/>
|
||||
<source>The config does not contain any containers and credentiaks for connecting to the server</source>
|
||||
<translation type="unfinished"></translation>
|
||||
<translation>The config does not contain any containers and credentiaks for connecting to the server</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../core/errorstrings.cpp" line="65"/>
|
||||
@@ -2747,16 +2742,6 @@ This means that AmneziaWG keeps the fast performance of the original while addin
|
||||
<source>&Randomize colors</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../3rd/wireguard-tools/contrib/highlighter/gui/highlight.cpp" line="39"/>
|
||||
<source>WireGuard Configuration Highlighter</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../3rd/wireguard-tools/contrib/highlighter/gui/highlight.cpp" line="82"/>
|
||||
<source>&Randomize colors</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>SelectLanguageDrawer</name>
|
||||
@@ -2828,8 +2813,8 @@ This means that AmneziaWG keeps the fast performance of the original while addin
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Components/ShareConnectionDrawer.qml" line="126"/>
|
||||
<source>Show content</source>
|
||||
<translation type="unfinished"></translation>
|
||||
<source>Show connection settings</source>
|
||||
<translation>Показать настройки подключения</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Components/ShareConnectionDrawer.qml" line="251"/>
|
||||
@@ -2924,7 +2909,7 @@ This means that AmneziaWG keeps the fast performance of the original while addin
|
||||
<context>
|
||||
<name>VpnConnection</name>
|
||||
<message>
|
||||
<location filename="../vpnconnection.cpp" line="405"/>
|
||||
<location filename="../vpnconnection.cpp" line="406"/>
|
||||
<source>Mbps</source>
|
||||
<translation>Mbps</translation>
|
||||
</message>
|
||||
|
||||
@@ -27,14 +27,6 @@
|
||||
<translation>VPN已连接</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>CloudController</name>
|
||||
<message>
|
||||
<location filename="../ui/controllers/cloudController.cpp" line="102"/>
|
||||
<source>Error when retrieving configuration from cloud server</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>ConnectionController</name>
|
||||
<message>
|
||||
@@ -2576,10 +2568,6 @@ and will not be shared or disclosed to the Amnezia or any third parties</source>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../core/errorstrings.cpp" line="61"/>
|
||||
<source>The config does not contain any containers and credentials for connecting to the server</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>The config does not contain any containers and credentiaks for connecting to the server</source>
|
||||
<translation>该配置不包含任何用于连接到服务器的容器和凭据。</translation>
|
||||
</message>
|
||||
@@ -2893,16 +2881,6 @@ While it offers a blend of security, stability, and speed, it's essential t
|
||||
<source>&Randomize colors</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../3rd/wireguard-tools/contrib/highlighter/gui/highlight.cpp" line="39"/>
|
||||
<source>WireGuard Configuration Highlighter</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../3rd/wireguard-tools/contrib/highlighter/gui/highlight.cpp" line="82"/>
|
||||
<source>&Randomize colors</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>SelectLanguageDrawer</name>
|
||||
|
||||
@@ -1,129 +0,0 @@
|
||||
#include "apiController.h"
|
||||
|
||||
#include <QEventLoop>
|
||||
#include <QNetworkAccessManager>
|
||||
#include <QNetworkReply>
|
||||
|
||||
#include "configurators/openvpn_configurator.h"
|
||||
|
||||
namespace
|
||||
{
|
||||
namespace configKey
|
||||
{
|
||||
constexpr char cloak[] = "cloak";
|
||||
|
||||
constexpr char apiEdnpoint[] = "api_endpoint";
|
||||
constexpr char accessToken[] = "api_key";
|
||||
constexpr char certificate[] = "certificate";
|
||||
constexpr char publicKey[] = "public_key";
|
||||
constexpr char protocol[] = "protocol";
|
||||
}
|
||||
}
|
||||
|
||||
ApiController::ApiController(const QSharedPointer<ServersModel> &serversModel,
|
||||
const QSharedPointer<ContainersModel> &containersModel, QObject *parent)
|
||||
: QObject(parent), m_serversModel(serversModel), m_containersModel(containersModel)
|
||||
{
|
||||
}
|
||||
|
||||
QString ApiController::genPublicKey(const QString &protocol)
|
||||
{
|
||||
if (protocol == configKey::cloak) {
|
||||
return ".";
|
||||
}
|
||||
return QString();
|
||||
}
|
||||
|
||||
QString ApiController::genCertificateRequest(const QString &protocol)
|
||||
{
|
||||
if (protocol == configKey::cloak) {
|
||||
m_certRequest = OpenVpnConfigurator::createCertRequest();
|
||||
return m_certRequest.request;
|
||||
}
|
||||
return QString();
|
||||
}
|
||||
|
||||
void ApiController::processCloudConfig(const QString &protocol, QString &config)
|
||||
{
|
||||
if (protocol == configKey::cloak) {
|
||||
config.replace("<key>", "<key>\n");
|
||||
config.replace("$OPENVPN_PRIV_KEY", m_certRequest.privKey);
|
||||
return;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
bool ApiController::updateServerConfigFromApi()
|
||||
{
|
||||
auto serverConfig = m_serversModel->getDefaultServerConfig();
|
||||
|
||||
auto containerConfig = serverConfig.value(config_key::containers).toArray();
|
||||
|
||||
if (serverConfig.value(config_key::configVersion).toInt() && containerConfig.isEmpty()) {
|
||||
QNetworkAccessManager manager;
|
||||
|
||||
QNetworkRequest request;
|
||||
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.replace("https", "http")); // todo remove
|
||||
|
||||
QString protocol = serverConfig.value(configKey::protocol).toString();
|
||||
|
||||
QJsonObject obj;
|
||||
|
||||
obj[configKey::publicKey] = genPublicKey(protocol);
|
||||
obj[configKey::certificate] = genCertificateRequest(protocol);
|
||||
|
||||
QByteArray requestBody = QJsonDocument(obj).toJson();
|
||||
qDebug() << requestBody;
|
||||
|
||||
QScopedPointer<QNetworkReply> reply;
|
||||
reply.reset(manager.post(request, requestBody));
|
||||
|
||||
QEventLoop wait;
|
||||
QObject::connect(reply.get(), &QNetworkReply::finished, &wait, &QEventLoop::quit);
|
||||
wait.exec();
|
||||
|
||||
if (reply->error() == QNetworkReply::NoError) {
|
||||
QString contents = QString::fromUtf8(reply->readAll());
|
||||
auto data = QJsonDocument::fromJson(contents.toUtf8()).object().value(config_key::config).toString();
|
||||
|
||||
data.replace("vpn://", "");
|
||||
QByteArray ba = QByteArray::fromBase64(data.toUtf8(),
|
||||
QByteArray::Base64UrlEncoding | QByteArray::OmitTrailingEquals);
|
||||
|
||||
QByteArray ba_uncompressed = qUncompress(ba);
|
||||
if (!ba_uncompressed.isEmpty()) {
|
||||
ba = ba_uncompressed;
|
||||
}
|
||||
|
||||
QString configStr = ba;
|
||||
processCloudConfig(protocol, configStr);
|
||||
|
||||
QJsonObject cloudConfig = QJsonDocument::fromJson(configStr.toUtf8()).object();
|
||||
|
||||
serverConfig.insert("cloudConfig", cloudConfig);
|
||||
serverConfig.insert(config_key::dns1, cloudConfig.value(config_key::dns1));
|
||||
serverConfig.insert(config_key::dns2, cloudConfig.value(config_key::dns2));
|
||||
serverConfig.insert(config_key::containers, cloudConfig.value(config_key::containers));
|
||||
serverConfig.insert(config_key::hostName, cloudConfig.value(config_key::hostName));
|
||||
|
||||
auto defaultContainer = cloudConfig.value(config_key::defaultContainer).toString();
|
||||
serverConfig.insert(config_key::defaultContainer, defaultContainer);
|
||||
m_serversModel->editServer(serverConfig);
|
||||
emit m_serversModel->defaultContainerChanged(ContainerProps::containerFromString(defaultContainer));
|
||||
} else {
|
||||
QString err = reply->errorString();
|
||||
qDebug() << QString::fromUtf8(reply->readAll()); //todo remove debug output
|
||||
qDebug() << reply->error();
|
||||
qDebug() << err;
|
||||
qDebug() << reply->attribute(QNetworkRequest::HttpStatusCodeAttribute);
|
||||
emit errorOccurred(tr("Error when retrieving configuration from cloud server"));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -1,36 +0,0 @@
|
||||
#ifndef APICONTROLLER_H
|
||||
#define APICONTROLLER_H
|
||||
|
||||
#include <QObject>
|
||||
|
||||
#include "configurators/openvpn_configurator.h"
|
||||
#include "ui/models/containers_model.h"
|
||||
#include "ui/models/servers_model.h"
|
||||
|
||||
class ApiController : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit ApiController(const QSharedPointer<ServersModel> &serversModel,
|
||||
const QSharedPointer<ContainersModel> &containersModel, QObject *parent = nullptr);
|
||||
|
||||
public slots:
|
||||
bool updateServerConfigFromApi();
|
||||
|
||||
signals:
|
||||
void errorOccurred(const QString &errorMessage);
|
||||
|
||||
private:
|
||||
QString genPublicKey(const QString &protocol);
|
||||
QString genCertificateRequest(const QString &protocol);
|
||||
|
||||
void processCloudConfig(const QString &protocol, QString &config);
|
||||
|
||||
QSharedPointer<ServersModel> m_serversModel;
|
||||
QSharedPointer<ContainersModel> m_containersModel;
|
||||
|
||||
OpenVpnConfigurator::ConnectionData m_certRequest;
|
||||
};
|
||||
|
||||
#endif // APICONTROLLER_H
|
||||
@@ -26,10 +26,13 @@ ConnectionController::ConnectionController(const QSharedPointer<ServersModel> &s
|
||||
void ConnectionController::openConnection()
|
||||
{
|
||||
int serverIndex = m_serversModel->getDefaultServerIndex();
|
||||
ServerCredentials credentials = m_serversModel->getServerCredentials(serverIndex);
|
||||
ServerCredentials credentials =
|
||||
qvariant_cast<ServerCredentials>(m_serversModel->data(serverIndex, ServersModel::Roles::CredentialsRole));
|
||||
|
||||
DockerContainer container = m_containersModel->getDefaultContainer();
|
||||
const QJsonObject &containerConfig = m_containersModel->getContainerConfig(container);
|
||||
QModelIndex containerModelIndex = m_containersModel->index(container);
|
||||
const QJsonObject &containerConfig =
|
||||
qvariant_cast<QJsonObject>(m_containersModel->data(containerModelIndex, ContainersModel::Roles::ConfigRole));
|
||||
|
||||
if (container == DockerContainer::None) {
|
||||
emit connectionErrorOccurred(tr("VPN Protocols is not installed.\n Please install VPN container at first"));
|
||||
@@ -37,7 +40,6 @@ void ConnectionController::openConnection()
|
||||
}
|
||||
|
||||
qApp->processEvents();
|
||||
|
||||
emit connectToVpn(serverIndex, credentials, container, containerConfig);
|
||||
}
|
||||
|
||||
@@ -108,8 +110,6 @@ void ConnectionController::onCurrentContainerUpdated()
|
||||
if (m_isConnected || m_isConnectionInProgress) {
|
||||
emit reconnectWithUpdatedContainer(tr("Settings updated successfully, Reconnnection..."));
|
||||
openConnection();
|
||||
} else {
|
||||
emit reconnectWithUpdatedContainer(tr("Settings updated successfully"));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -8,9 +8,7 @@
|
||||
#include <QImage>
|
||||
#include <QStandardPaths>
|
||||
|
||||
#include "configurators/cloak_configurator.h"
|
||||
#include "configurators/openvpn_configurator.h"
|
||||
#include "configurators/shadowsocks_configurator.h"
|
||||
#include "configurators/wireguard_configurator.h"
|
||||
#include "core/errorstrings.h"
|
||||
#include "systemController.h"
|
||||
@@ -21,13 +19,11 @@
|
||||
|
||||
ExportController::ExportController(const QSharedPointer<ServersModel> &serversModel,
|
||||
const QSharedPointer<ContainersModel> &containersModel,
|
||||
const QSharedPointer<ClientManagementModel> &clientManagementModel,
|
||||
const std::shared_ptr<Settings> &settings,
|
||||
const std::shared_ptr<VpnConfigurator> &configurator, QObject *parent)
|
||||
: QObject(parent),
|
||||
m_serversModel(serversModel),
|
||||
m_containersModel(containersModel),
|
||||
m_clientManagementModel(clientManagementModel),
|
||||
m_settings(settings),
|
||||
m_configurator(configurator)
|
||||
{
|
||||
@@ -79,40 +75,35 @@ void ExportController::generateFullAccessConfigAndroid()
|
||||
}
|
||||
#endif
|
||||
|
||||
void ExportController::generateConnectionConfig(const QString &clientName)
|
||||
void ExportController::generateConnectionConfig()
|
||||
{
|
||||
clearPreviousConfig();
|
||||
|
||||
int serverIndex = m_serversModel->getCurrentlyProcessedServerIndex();
|
||||
ServerCredentials credentials = m_serversModel->getServerCredentials(serverIndex);
|
||||
ServerCredentials credentials =
|
||||
qvariant_cast<ServerCredentials>(m_serversModel->data(serverIndex, ServersModel::Roles::CredentialsRole));
|
||||
|
||||
DockerContainer container = static_cast<DockerContainer>(m_containersModel->getCurrentlyProcessedContainerIndex());
|
||||
QJsonObject containerConfig = m_containersModel->getContainerConfig(container);
|
||||
QModelIndex containerModelIndex = m_containersModel->index(container);
|
||||
QJsonObject containerConfig =
|
||||
qvariant_cast<QJsonObject>(m_containersModel->data(containerModelIndex, ContainersModel::Roles::ConfigRole));
|
||||
containerConfig.insert(config_key::container, ContainerProps::containerToString(container));
|
||||
|
||||
ErrorCode errorCode = ErrorCode::NoError;
|
||||
for (Proto protocol : ContainerProps::protocolsForContainer(container)) {
|
||||
QJsonObject protocolConfig = m_settings->protocolConfig(serverIndex, container, protocol);
|
||||
|
||||
QString clientId;
|
||||
QString vpnConfig = m_configurator->genVpnProtocolConfig(credentials, container, containerConfig, protocol,
|
||||
clientId, &errorCode);
|
||||
QString vpnConfig =
|
||||
m_configurator->genVpnProtocolConfig(credentials, container, containerConfig, protocol, &errorCode);
|
||||
if (errorCode) {
|
||||
emit exportErrorOccurred(errorString(errorCode));
|
||||
return;
|
||||
}
|
||||
protocolConfig.insert(config_key::last_config, vpnConfig);
|
||||
containerConfig.insert(ProtocolProps::protoToString(protocol), protocolConfig);
|
||||
if (protocol == Proto::OpenVpn || protocol == Proto::Awg || protocol == Proto::WireGuard) {
|
||||
errorCode = m_clientManagementModel->appendClient(clientId, clientName, container, credentials);
|
||||
if (errorCode) {
|
||||
emit exportErrorOccurred(errorString(errorCode));
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
QJsonObject config = m_settings->server(serverIndex); // todo change to servers_model
|
||||
QJsonObject config = m_settings->server(serverIndex);
|
||||
if (!errorCode) {
|
||||
config.remove(config_key::userName);
|
||||
config.remove(config_key::password);
|
||||
@@ -135,21 +126,23 @@ void ExportController::generateConnectionConfig(const QString &clientName)
|
||||
emit exportConfigChanged();
|
||||
}
|
||||
|
||||
void ExportController::generateOpenVpnConfig(const QString &clientName)
|
||||
void ExportController::generateOpenVpnConfig()
|
||||
{
|
||||
clearPreviousConfig();
|
||||
|
||||
int serverIndex = m_serversModel->getCurrentlyProcessedServerIndex();
|
||||
ServerCredentials credentials = m_serversModel->getServerCredentials(serverIndex);
|
||||
ServerCredentials credentials =
|
||||
qvariant_cast<ServerCredentials>(m_serversModel->data(serverIndex, ServersModel::Roles::CredentialsRole));
|
||||
|
||||
DockerContainer container = static_cast<DockerContainer>(m_containersModel->getCurrentlyProcessedContainerIndex());
|
||||
QJsonObject containerConfig = m_containersModel->getContainerConfig(container);
|
||||
QModelIndex containerModelIndex = m_containersModel->index(container);
|
||||
QJsonObject containerConfig =
|
||||
qvariant_cast<QJsonObject>(m_containersModel->data(containerModelIndex, ContainersModel::Roles::ConfigRole));
|
||||
containerConfig.insert(config_key::container, ContainerProps::containerToString(container));
|
||||
|
||||
ErrorCode errorCode = ErrorCode::NoError;
|
||||
QString clientId;
|
||||
QString config = m_configurator->openVpnConfigurator->genOpenVpnConfig(credentials, container, containerConfig,
|
||||
clientId, &errorCode);
|
||||
QString config =
|
||||
m_configurator->openVpnConfigurator->genOpenVpnConfig(credentials, container, containerConfig, &errorCode);
|
||||
if (errorCode) {
|
||||
emit exportErrorOccurred(errorString(errorCode));
|
||||
return;
|
||||
@@ -162,32 +155,26 @@ void ExportController::generateOpenVpnConfig(const QString &clientName)
|
||||
m_config.append(line + "\n");
|
||||
}
|
||||
|
||||
m_qrCodes = generateQrCodeImageSeries(m_config.toUtf8());
|
||||
|
||||
errorCode = m_clientManagementModel->appendClient(clientId, clientName, container, credentials);
|
||||
if (errorCode) {
|
||||
emit exportErrorOccurred(errorString(errorCode));
|
||||
return;
|
||||
}
|
||||
|
||||
emit exportConfigChanged();
|
||||
}
|
||||
|
||||
void ExportController::generateWireGuardConfig(const QString &clientName)
|
||||
void ExportController::generateWireGuardConfig()
|
||||
{
|
||||
clearPreviousConfig();
|
||||
|
||||
int serverIndex = m_serversModel->getCurrentlyProcessedServerIndex();
|
||||
ServerCredentials credentials = m_serversModel->getServerCredentials(serverIndex);
|
||||
ServerCredentials credentials =
|
||||
qvariant_cast<ServerCredentials>(m_serversModel->data(serverIndex, ServersModel::Roles::CredentialsRole));
|
||||
|
||||
DockerContainer container = static_cast<DockerContainer>(m_containersModel->getCurrentlyProcessedContainerIndex());
|
||||
QJsonObject containerConfig = m_containersModel->getContainerConfig(container);
|
||||
QModelIndex containerModelIndex = m_containersModel->index(container);
|
||||
QJsonObject containerConfig =
|
||||
qvariant_cast<QJsonObject>(m_containersModel->data(containerModelIndex, ContainersModel::Roles::ConfigRole));
|
||||
containerConfig.insert(config_key::container, ContainerProps::containerToString(container));
|
||||
|
||||
QString clientId;
|
||||
ErrorCode errorCode = ErrorCode::NoError;
|
||||
QString config = m_configurator->wireguardConfigurator->genWireguardConfig(credentials, container, containerConfig,
|
||||
clientId, &errorCode);
|
||||
&errorCode);
|
||||
if (errorCode) {
|
||||
emit exportErrorOccurred(errorString(errorCode));
|
||||
return;
|
||||
@@ -200,84 +187,6 @@ void ExportController::generateWireGuardConfig(const QString &clientName)
|
||||
m_config.append(line + "\n");
|
||||
}
|
||||
|
||||
qrcodegen::QrCode qr = qrcodegen::QrCode::encodeText(m_config.toUtf8(), qrcodegen::QrCode::Ecc::LOW);
|
||||
m_qrCodes << svgToBase64(QString::fromStdString(toSvgString(qr, 1)));
|
||||
|
||||
errorCode = m_clientManagementModel->appendClient(clientId, clientName, container, credentials);
|
||||
if (errorCode) {
|
||||
emit exportErrorOccurred(errorString(errorCode));
|
||||
return;
|
||||
}
|
||||
|
||||
emit exportConfigChanged();
|
||||
}
|
||||
|
||||
void ExportController::generateShadowSocksConfig()
|
||||
{
|
||||
clearPreviousConfig();
|
||||
|
||||
int serverIndex = m_serversModel->getCurrentlyProcessedServerIndex();
|
||||
ServerCredentials credentials = m_serversModel->getServerCredentials(serverIndex);
|
||||
|
||||
DockerContainer container = static_cast<DockerContainer>(m_containersModel->getCurrentlyProcessedContainerIndex());
|
||||
QJsonObject containerConfig = m_containersModel->getContainerConfig(container);
|
||||
containerConfig.insert(config_key::container, ContainerProps::containerToString(container));
|
||||
|
||||
ErrorCode errorCode = ErrorCode::NoError;
|
||||
QString config = m_configurator->shadowSocksConfigurator->genShadowSocksConfig(credentials, container,
|
||||
containerConfig, &errorCode);
|
||||
|
||||
config = m_configurator->processConfigWithExportSettings(serverIndex, container, Proto::ShadowSocks, config);
|
||||
QJsonObject configJson = QJsonDocument::fromJson(config.toUtf8()).object();
|
||||
|
||||
QStringList lines = QString(QJsonDocument(configJson).toJson()).replace("\r", "").split("\n");
|
||||
for (const QString &line : lines) {
|
||||
m_config.append(line + "\n");
|
||||
}
|
||||
|
||||
m_nativeConfigString =
|
||||
QString("%1:%2@%3:%4")
|
||||
.arg(configJson.value("method").toString(), configJson.value("password").toString(),
|
||||
configJson.value("server").toString(), configJson.value("server_port").toString());
|
||||
|
||||
m_nativeConfigString = "ss://" + m_nativeConfigString.toUtf8().toBase64();
|
||||
|
||||
qrcodegen::QrCode qr = qrcodegen::QrCode::encodeText(m_nativeConfigString.toUtf8(), qrcodegen::QrCode::Ecc::LOW);
|
||||
m_qrCodes << svgToBase64(QString::fromStdString(toSvgString(qr, 1)));
|
||||
|
||||
emit exportConfigChanged();
|
||||
}
|
||||
|
||||
void ExportController::generateCloakConfig()
|
||||
{
|
||||
clearPreviousConfig();
|
||||
|
||||
int serverIndex = m_serversModel->getCurrentlyProcessedServerIndex();
|
||||
ServerCredentials credentials = m_serversModel->getServerCredentials(serverIndex);
|
||||
|
||||
DockerContainer container = static_cast<DockerContainer>(m_containersModel->getCurrentlyProcessedContainerIndex());
|
||||
QJsonObject containerConfig = m_containersModel->getContainerConfig(container);
|
||||
containerConfig.insert(config_key::container, ContainerProps::containerToString(container));
|
||||
|
||||
ErrorCode errorCode = ErrorCode::NoError;
|
||||
QString config =
|
||||
m_configurator->cloakConfigurator->genCloakConfig(credentials, container, containerConfig, &errorCode);
|
||||
|
||||
if (errorCode) {
|
||||
emit exportErrorOccurred(errorString(errorCode));
|
||||
return;
|
||||
}
|
||||
config = m_configurator->processConfigWithExportSettings(serverIndex, container, Proto::Cloak, config);
|
||||
QJsonObject configJson = QJsonDocument::fromJson(config.toUtf8()).object();
|
||||
|
||||
configJson.remove(config_key::transport_proto);
|
||||
configJson.insert("ProxyMethod", "shadowsocks");
|
||||
|
||||
QStringList lines = QString(QJsonDocument(configJson).toJson()).replace("\r", "").split("\n");
|
||||
for (const QString &line : lines) {
|
||||
m_config.append(line + "\n");
|
||||
}
|
||||
|
||||
emit exportConfigChanged();
|
||||
}
|
||||
|
||||
@@ -286,11 +195,6 @@ QString ExportController::getConfig()
|
||||
return m_config;
|
||||
}
|
||||
|
||||
QString ExportController::getNativeConfigString()
|
||||
{
|
||||
return m_nativeConfigString;
|
||||
}
|
||||
|
||||
QList<QString> ExportController::getQrCodes()
|
||||
{
|
||||
return m_qrCodes;
|
||||
@@ -301,30 +205,6 @@ void ExportController::exportConfig(const QString &fileName)
|
||||
SystemController::saveFile(fileName, m_config);
|
||||
}
|
||||
|
||||
void ExportController::updateClientManagementModel(const DockerContainer container, ServerCredentials credentials)
|
||||
{
|
||||
ErrorCode errorCode = m_clientManagementModel->updateModel(container, credentials);
|
||||
if (errorCode != ErrorCode::NoError) {
|
||||
emit exportErrorOccurred(errorString(errorCode));
|
||||
}
|
||||
}
|
||||
|
||||
void ExportController::revokeConfig(const int row, const DockerContainer container, ServerCredentials credentials)
|
||||
{
|
||||
ErrorCode errorCode = m_clientManagementModel->revokeClient(row, container, credentials);
|
||||
if (errorCode != ErrorCode::NoError) {
|
||||
emit exportErrorOccurred(errorString(errorCode));
|
||||
}
|
||||
}
|
||||
|
||||
void ExportController::renameClient(const int row, const QString &clientName, const DockerContainer container, ServerCredentials credentials)
|
||||
{
|
||||
ErrorCode errorCode = m_clientManagementModel->renameClient(row, clientName, container, credentials);
|
||||
if (errorCode != ErrorCode::NoError) {
|
||||
emit exportErrorOccurred(errorString(errorCode));
|
||||
}
|
||||
}
|
||||
|
||||
QList<QString> ExportController::generateQrCodeImageSeries(const QByteArray &data)
|
||||
{
|
||||
double k = 850;
|
||||
@@ -339,7 +219,7 @@ QList<QString> ExportController::generateQrCodeImageSeries(const QByteArray &dat
|
||||
QByteArray ba = chunk.toBase64(QByteArray::Base64UrlEncoding | QByteArray::OmitTrailingEquals);
|
||||
|
||||
qrcodegen::QrCode qr = qrcodegen::QrCode::encodeText(ba, qrcodegen::QrCode::Ecc::LOW);
|
||||
QString svg = QString::fromStdString(toSvgString(qr, 1));
|
||||
QString svg = QString::fromStdString(toSvgString(qr, 0));
|
||||
chunks.append(svgToBase64(svg));
|
||||
}
|
||||
|
||||
@@ -359,6 +239,5 @@ int ExportController::getQrCodesCount()
|
||||
void ExportController::clearPreviousConfig()
|
||||
{
|
||||
m_config.clear();
|
||||
m_nativeConfigString.clear();
|
||||
m_qrCodes.clear();
|
||||
}
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
#include "configurators/vpn_configurator.h"
|
||||
#include "ui/models/containers_model.h"
|
||||
#include "ui/models/servers_model.h"
|
||||
#include "ui/models/clientManagementModel.h"
|
||||
#ifdef Q_OS_ANDROID
|
||||
#include "platforms/android/authResultReceiver.h"
|
||||
#endif
|
||||
@@ -17,36 +16,27 @@ class ExportController : public QObject
|
||||
public:
|
||||
explicit ExportController(const QSharedPointer<ServersModel> &serversModel,
|
||||
const QSharedPointer<ContainersModel> &containersModel,
|
||||
const QSharedPointer<ClientManagementModel> &clientManagementModel,
|
||||
const std::shared_ptr<Settings> &settings,
|
||||
const std::shared_ptr<VpnConfigurator> &configurator, QObject *parent = nullptr);
|
||||
|
||||
Q_PROPERTY(QList<QString> qrCodes READ getQrCodes NOTIFY exportConfigChanged)
|
||||
Q_PROPERTY(int qrCodesCount READ getQrCodesCount NOTIFY exportConfigChanged)
|
||||
Q_PROPERTY(QString config READ getConfig NOTIFY exportConfigChanged)
|
||||
Q_PROPERTY(QString nativeConfigString READ getNativeConfigString NOTIFY exportConfigChanged)
|
||||
|
||||
public slots:
|
||||
void generateFullAccessConfig();
|
||||
#if defined(Q_OS_ANDROID)
|
||||
void generateFullAccessConfigAndroid();
|
||||
#endif
|
||||
void generateConnectionConfig(const QString &clientName);
|
||||
void generateOpenVpnConfig(const QString &clientName);
|
||||
void generateWireGuardConfig(const QString &clientName);
|
||||
void generateShadowSocksConfig();
|
||||
void generateCloakConfig();
|
||||
void generateConnectionConfig();
|
||||
void generateOpenVpnConfig();
|
||||
void generateWireGuardConfig();
|
||||
|
||||
QString getConfig();
|
||||
QString getNativeConfigString();
|
||||
QList<QString> getQrCodes();
|
||||
|
||||
void exportConfig(const QString &fileName);
|
||||
|
||||
void updateClientManagementModel(const DockerContainer container, ServerCredentials credentials);
|
||||
void revokeConfig(const int row, const DockerContainer container, ServerCredentials credentials);
|
||||
void renameClient(const int row, const QString &clientName, const DockerContainer container, ServerCredentials credentials);
|
||||
|
||||
signals:
|
||||
void generateConfig(int type);
|
||||
void exportErrorOccurred(const QString &errorMessage);
|
||||
@@ -65,12 +55,10 @@ private:
|
||||
|
||||
QSharedPointer<ServersModel> m_serversModel;
|
||||
QSharedPointer<ContainersModel> m_containersModel;
|
||||
QSharedPointer<ClientManagementModel> m_clientManagementModel;
|
||||
std::shared_ptr<Settings> m_settings;
|
||||
std::shared_ptr<VpnConfigurator> m_configurator;
|
||||
|
||||
QString m_config;
|
||||
QString m_nativeConfigString;
|
||||
QList<QString> m_qrCodes;
|
||||
|
||||
#ifdef Q_OS_ANDROID
|
||||
|
||||
@@ -141,9 +141,7 @@ void ImportController::importConfig()
|
||||
credentials.userName = m_config.value(config_key::userName).toString();
|
||||
credentials.secretData = m_config.value(config_key::password).toString();
|
||||
|
||||
if (credentials.isValid()
|
||||
|| m_config.contains(config_key::containers)
|
||||
|| m_config.contains(config_key::configVersion)) { // todo
|
||||
if (credentials.isValid() || m_config.contains(config_key::containers)) {
|
||||
m_serversModel->addServer(m_config);
|
||||
|
||||
emit importFinished();
|
||||
@@ -167,9 +165,7 @@ QJsonObject ImportController::extractAmneziaConfig(QString &data)
|
||||
ba = ba_uncompressed;
|
||||
}
|
||||
|
||||
QJsonObject config = QJsonDocument::fromJson(ba).object();
|
||||
|
||||
return config;
|
||||
return QJsonDocument::fromJson(ba).object();
|
||||
}
|
||||
|
||||
QJsonObject ImportController::extractOpenVpnConfig(const QString &data)
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
#include <QRandomGenerator>
|
||||
|
||||
#include "core/errorstrings.h"
|
||||
#include "core/controllers/serverController.h"
|
||||
#include "core/servercontroller.h"
|
||||
#include "utilities.h"
|
||||
|
||||
namespace
|
||||
@@ -130,7 +130,6 @@ void InstallController::installServer(DockerContainer container, QJsonObject &co
|
||||
{
|
||||
ServerController serverController(m_settings);
|
||||
connect(&serverController, &ServerController::serverIsBusy, this, &InstallController::serverIsBusy);
|
||||
connect(this, &InstallController::cancelInstallation, &serverController, &ServerController::cancelInstallation);
|
||||
|
||||
QMap<DockerContainer, QJsonObject> installedContainers;
|
||||
ErrorCode errorCode =
|
||||
@@ -182,7 +181,6 @@ void InstallController::installContainer(DockerContainer container, QJsonObject
|
||||
|
||||
ServerController serverController(m_settings);
|
||||
connect(&serverController, &ServerController::serverIsBusy, this, &InstallController::serverIsBusy);
|
||||
connect(this, &InstallController::cancelInstallation, &serverController, &ServerController::cancelInstallation);
|
||||
|
||||
QMap<DockerContainer, QJsonObject> installedContainers;
|
||||
ErrorCode errorCode = serverController.getAlreadyInstalledContainers(serverCredentials, installedContainers);
|
||||
@@ -201,9 +199,12 @@ void InstallController::installContainer(DockerContainer container, QJsonObject
|
||||
|
||||
if (errorCode == ErrorCode::NoError) {
|
||||
for (auto iterator = installedContainers.begin(); iterator != installedContainers.end(); iterator++) {
|
||||
QJsonObject containerConfig = m_containersModel->getContainerConfig(iterator.key());
|
||||
auto modelIndex = m_containersModel->index(iterator.key());
|
||||
QJsonObject containerConfig =
|
||||
qvariant_cast<QJsonObject>(m_containersModel->data(modelIndex, ContainersModel::Roles::ConfigRole));
|
||||
if (containerConfig.isEmpty()) {
|
||||
m_serversModel->addContainerConfig(iterator.key(), iterator.value());
|
||||
m_containersModel->setData(m_containersModel->index(iterator.key()), iterator.value(),
|
||||
ContainersModel::Roles::ConfigRole);
|
||||
if (container != iterator.key()) { // skip the newly installed container
|
||||
isInstalledContainerAddedToGui = true;
|
||||
}
|
||||
@@ -251,9 +252,12 @@ void InstallController::scanServerForInstalledContainers()
|
||||
bool isInstalledContainerAddedToGui = false;
|
||||
|
||||
for (auto iterator = installedContainers.begin(); iterator != installedContainers.end(); iterator++) {
|
||||
QJsonObject containerConfig = m_containersModel->getContainerConfig(iterator.key());
|
||||
auto modelIndex = m_containersModel->index(iterator.key());
|
||||
QJsonObject containerConfig =
|
||||
qvariant_cast<QJsonObject>(m_containersModel->data(modelIndex, ContainersModel::Roles::ConfigRole));
|
||||
if (containerConfig.isEmpty()) {
|
||||
m_serversModel->addContainerConfig(iterator.key(), iterator.value());
|
||||
m_containersModel->setData(m_containersModel->index(iterator.key()), iterator.value(),
|
||||
ContainersModel::Roles::ConfigRole);
|
||||
isInstalledContainerAddedToGui = true;
|
||||
}
|
||||
}
|
||||
@@ -272,15 +276,16 @@ void InstallController::updateContainer(QJsonObject config)
|
||||
qvariant_cast<ServerCredentials>(m_serversModel->data(serverIndex, ServersModel::Roles::CredentialsRole));
|
||||
|
||||
const DockerContainer container = ContainerProps::containerFromString(config.value(config_key::container).toString());
|
||||
QJsonObject oldContainerConfig = m_containersModel->getContainerConfig(container);
|
||||
auto modelIndex = m_containersModel->index(container);
|
||||
QJsonObject oldContainerConfig =
|
||||
qvariant_cast<QJsonObject>(m_containersModel->data(modelIndex, ContainersModel::Roles::ConfigRole));
|
||||
|
||||
ServerController serverController(m_settings);
|
||||
connect(&serverController, &ServerController::serverIsBusy, this, &InstallController::serverIsBusy);
|
||||
connect(this, &InstallController::cancelInstallation, &serverController, &ServerController::cancelInstallation);
|
||||
|
||||
auto errorCode = serverController.updateContainer(serverCredentials, container, oldContainerConfig, config);
|
||||
if (errorCode == ErrorCode::NoError) {
|
||||
m_serversModel->updateContainerConfig(container, config);
|
||||
m_containersModel->setData(modelIndex, config, ContainersModel::Roles::ConfigRole);
|
||||
m_protocolModel->updateModel(config);
|
||||
|
||||
if ((serverIndex == m_serversModel->getDefaultServerIndex())
|
||||
@@ -310,7 +315,7 @@ void InstallController::removeAllContainers()
|
||||
int serverIndex = m_serversModel->getCurrentlyProcessedServerIndex();
|
||||
QString serverName = m_serversModel->data(serverIndex, ServersModel::Roles::NameRole).toString();
|
||||
|
||||
ErrorCode errorCode = m_serversModel->removeAllContainers();
|
||||
ErrorCode errorCode = m_containersModel->removeAllContainers();
|
||||
if (errorCode == ErrorCode::NoError) {
|
||||
emit removeAllContainersFinished(tr("All containers from server '%1' have been removed").arg(serverName));
|
||||
return;
|
||||
@@ -324,12 +329,12 @@ void InstallController::removeCurrentlyProcessedContainer()
|
||||
QString serverName = m_serversModel->data(serverIndex, ServersModel::Roles::NameRole).toString();
|
||||
|
||||
int container = m_containersModel->getCurrentlyProcessedContainerIndex();
|
||||
QString containerName = m_containersModel->getCurrentlyProcessedContainerName();
|
||||
QString containerName = m_containersModel->data(container, ContainersModel::Roles::NameRole).toString();
|
||||
|
||||
ErrorCode errorCode = m_serversModel->removeContainer(container);
|
||||
ErrorCode errorCode = m_containersModel->removeCurrentlyProcessedContainer();
|
||||
if (errorCode == ErrorCode::NoError) {
|
||||
|
||||
emit removeCurrentlyProcessedContainerFinished(tr("%1 has been removed from the server '%2'").arg(containerName, serverName));
|
||||
emit removeCurrentlyProcessedContainerFinished(tr("%1 has been removed from the server '%2'").arg(containerName).arg(serverName));
|
||||
return;
|
||||
}
|
||||
emit installationErrorOccurred(errorString(errorCode));
|
||||
|
||||
@@ -65,7 +65,6 @@ signals:
|
||||
void passphraseRequestFinished();
|
||||
|
||||
void serverIsBusy(const bool isBusy);
|
||||
void cancelInstallation();
|
||||
|
||||
void currentContainerUpdated();
|
||||
|
||||
|
||||
@@ -51,9 +51,7 @@ namespace PageLoader
|
||||
PageProtocolWireGuardSettings,
|
||||
PageProtocolAwgSettings,
|
||||
PageProtocolIKev2Settings,
|
||||
PageProtocolRaw,
|
||||
|
||||
PageShareFullAccess
|
||||
PageProtocolRaw
|
||||
};
|
||||
Q_ENUM_NS(PageEnum)
|
||||
|
||||
|
||||
@@ -42,7 +42,6 @@ SettingsController::SettingsController(const QSharedPointer<ServersModel> &serve
|
||||
void SettingsController::toggleAmneziaDns(bool enable)
|
||||
{
|
||||
m_settings->setUseAmneziaDns(enable);
|
||||
emit amneziaDnsToggled(enable);
|
||||
}
|
||||
|
||||
bool SettingsController::isAmneziaDnsEnabled()
|
||||
@@ -139,7 +138,7 @@ void SettingsController::clearSettings()
|
||||
|
||||
void SettingsController::clearCachedProfiles()
|
||||
{
|
||||
m_serversModel->clearCachedProfiles();
|
||||
m_containersModel->clearCachedProfiles();
|
||||
emit changeSettingsFinished(tr("Cached profiles cleared"));
|
||||
}
|
||||
|
||||
|
||||
@@ -70,8 +70,6 @@ signals:
|
||||
|
||||
void importBackupFromOutside(QString filePath);
|
||||
|
||||
void amneziaDnsToggled(bool enable);
|
||||
|
||||
private:
|
||||
QSharedPointer<ServersModel> m_serversModel;
|
||||
QSharedPointer<ContainersModel> m_containersModel;
|
||||
|
||||
@@ -1,373 +1,104 @@
|
||||
#include "clientManagementModel.h"
|
||||
|
||||
#include <QJsonDocument>
|
||||
#include <QJsonObject>
|
||||
|
||||
#include "core/controllers/serverController.h"
|
||||
#include "logger.h"
|
||||
|
||||
namespace
|
||||
ClientManagementModel::ClientManagementModel(QObject *parent) : QAbstractListModel(parent)
|
||||
{
|
||||
Logger logger("ClientManagementModel");
|
||||
|
||||
namespace configKey {
|
||||
constexpr char clientId[] = "clientId";
|
||||
constexpr char clientName[] = "clientName";
|
||||
constexpr char container[] = "container";
|
||||
constexpr char userData[] = "userData";
|
||||
}
|
||||
}
|
||||
|
||||
ClientManagementModel::ClientManagementModel(std::shared_ptr<Settings> settings, QObject *parent)
|
||||
: m_settings(settings), QAbstractListModel(parent)
|
||||
void ClientManagementModel::clearData()
|
||||
{
|
||||
beginResetModel();
|
||||
m_content.clear();
|
||||
endResetModel();
|
||||
}
|
||||
|
||||
void ClientManagementModel::setContent(const QVector<QVariant> &data)
|
||||
{
|
||||
beginResetModel();
|
||||
m_content = data;
|
||||
endResetModel();
|
||||
}
|
||||
|
||||
QJsonObject ClientManagementModel::getContent(amnezia::Proto protocol)
|
||||
{
|
||||
QJsonObject clientsTable;
|
||||
for (const auto &item : m_content) {
|
||||
if (protocol == amnezia::Proto::OpenVpn) {
|
||||
clientsTable[item.toJsonObject()["openvpnCertId"].toString()] = item.toJsonObject();
|
||||
} else if (protocol == amnezia::Proto::WireGuard) {
|
||||
clientsTable[item.toJsonObject()["wireguardPublicKey"].toString()] = item.toJsonObject();
|
||||
}
|
||||
}
|
||||
return clientsTable;
|
||||
}
|
||||
|
||||
int ClientManagementModel::rowCount(const QModelIndex &parent) const
|
||||
{
|
||||
Q_UNUSED(parent);
|
||||
return static_cast<int>(m_clientsTable.size());
|
||||
return static_cast<int>(m_content.size());
|
||||
}
|
||||
|
||||
QVariant ClientManagementModel::data(const QModelIndex &index, int role) const
|
||||
{
|
||||
if (!index.isValid() || index.row() < 0 || index.row() >= static_cast<int>(m_clientsTable.size())) {
|
||||
if (!index.isValid() || index.row() < 0
|
||||
|| index.row() >= static_cast<int>(m_content.size())) {
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
auto client = m_clientsTable.at(index.row()).toObject();
|
||||
auto userData = client.value(configKey::userData).toObject();
|
||||
|
||||
switch (role) {
|
||||
case ClientNameRole: return userData.value(configKey::clientName).toString();
|
||||
if (role == NameRole) {
|
||||
return m_content[index.row()].toJsonObject()["clientName"].toString();
|
||||
} else if (role == OpenVpnCertIdRole) {
|
||||
return m_content[index.row()].toJsonObject()["openvpnCertId"].toString();
|
||||
} else if (role == OpenVpnCertDataRole) {
|
||||
return m_content[index.row()].toJsonObject()["openvpnCertData"].toString();
|
||||
} else if (role == WireGuardPublicKey) {
|
||||
return m_content[index.row()].toJsonObject()["wireguardPublicKey"].toString();
|
||||
}
|
||||
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
ErrorCode ClientManagementModel::updateModel(DockerContainer container, ServerCredentials credentials)
|
||||
void ClientManagementModel::setData(const QModelIndex &index, QVariant data, int role)
|
||||
{
|
||||
beginResetModel();
|
||||
m_clientsTable = QJsonArray();
|
||||
|
||||
ServerController serverController(m_settings);
|
||||
|
||||
ErrorCode error = ErrorCode::NoError;
|
||||
|
||||
const QString clientsTableFile =
|
||||
QString("/opt/amnezia/%1/clientsTable").arg(ContainerProps::containerTypeToString(container));
|
||||
const QByteArray clientsTableString =
|
||||
serverController.getTextFileFromContainer(container, credentials, clientsTableFile, &error);
|
||||
if (error != ErrorCode::NoError) {
|
||||
logger.error() << "Failed to get the clientsTable file from the server";
|
||||
endResetModel();
|
||||
return error;
|
||||
if (!index.isValid() || index.row() < 0
|
||||
|| index.row() >= static_cast<int>(m_content.size())) {
|
||||
return;
|
||||
}
|
||||
|
||||
m_clientsTable = QJsonDocument::fromJson(clientsTableString).array();
|
||||
|
||||
if (m_clientsTable.isEmpty()) {
|
||||
int count = 0;
|
||||
|
||||
if (container == DockerContainer::OpenVpn || container == DockerContainer::ShadowSocks
|
||||
|| container == DockerContainer::Cloak) {
|
||||
error = getOpenVpnClients(serverController, container, credentials, count);
|
||||
} else if (container == DockerContainer::WireGuard || container == DockerContainer::Awg) {
|
||||
error = getWireGuardClients(serverController, container, credentials, count);
|
||||
}
|
||||
if (error != ErrorCode::NoError) {
|
||||
endResetModel();
|
||||
return error;
|
||||
}
|
||||
|
||||
const QByteArray newClientsTableString = QJsonDocument(m_clientsTable).toJson();
|
||||
if (clientsTableString != newClientsTableString) {
|
||||
error = serverController.uploadTextFileToContainer(container, credentials, newClientsTableString,
|
||||
clientsTableFile);
|
||||
if (error != ErrorCode::NoError) {
|
||||
logger.error() << "Failed to upload the clientsTable file to the server";
|
||||
}
|
||||
}
|
||||
auto client = m_content[index.row()].toJsonObject();
|
||||
if (role == NameRole) {
|
||||
client["clientName"] = data.toString();
|
||||
} else if (role == OpenVpnCertIdRole) {
|
||||
client["openvpnCertId"] = data.toString();
|
||||
} else if (role == OpenVpnCertDataRole) {
|
||||
client["openvpnCertData"] = data.toString();
|
||||
} else if (role == WireGuardPublicKey) {
|
||||
client["wireguardPublicKey"] = data.toString();
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
if (m_content[index.row()] != client) {
|
||||
m_content[index.row()] = client;
|
||||
emit dataChanged(index, index);
|
||||
}
|
||||
|
||||
endResetModel();
|
||||
return error;
|
||||
}
|
||||
|
||||
ErrorCode ClientManagementModel::getOpenVpnClients(ServerController &serverController, DockerContainer container, ServerCredentials credentials, int &count)
|
||||
bool ClientManagementModel::removeRows(int row)
|
||||
{
|
||||
ErrorCode error = ErrorCode::NoError;
|
||||
QString stdOut;
|
||||
auto cbReadStdOut = [&](const QString &data, libssh::Client &) {
|
||||
stdOut += data + "\n";
|
||||
return ErrorCode::NoError;
|
||||
};
|
||||
|
||||
const QString getOpenVpnClientsList =
|
||||
"sudo docker exec -i $CONTAINER_NAME bash -c 'ls /opt/amnezia/openvpn/pki/issued'";
|
||||
QString script = serverController.replaceVars(getOpenVpnClientsList,
|
||||
serverController.genVarsForScript(credentials, container));
|
||||
error = serverController.runScript(credentials, script, cbReadStdOut);
|
||||
if (error != ErrorCode::NoError) {
|
||||
logger.error() << "Failed to retrieve the list of issued certificates on the server";
|
||||
return error;
|
||||
}
|
||||
|
||||
if (!stdOut.isEmpty()) {
|
||||
QStringList certsIds = stdOut.split("\n", Qt::SkipEmptyParts);
|
||||
certsIds.removeAll("AmneziaReq.crt");
|
||||
|
||||
for (auto &openvpnCertId : certsIds) {
|
||||
openvpnCertId.replace(".crt", "");
|
||||
if (!isClientExists(openvpnCertId)) {
|
||||
QJsonObject client;
|
||||
client[configKey::clientId] = openvpnCertId;
|
||||
|
||||
QJsonObject userData;
|
||||
userData[configKey::clientName] = QString("Client %1").arg(count);
|
||||
client[configKey::userData] = userData;
|
||||
|
||||
m_clientsTable.push_back(client);
|
||||
|
||||
count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
return error;
|
||||
}
|
||||
|
||||
ErrorCode ClientManagementModel::getWireGuardClients(ServerController &serverController, DockerContainer container, ServerCredentials credentials, int &count)
|
||||
{
|
||||
ErrorCode error = ErrorCode::NoError;
|
||||
|
||||
const QString wireGuardConfigFile =
|
||||
QString("opt/amnezia/%1/wg0.conf").arg(container == DockerContainer::WireGuard ? "wireguard" : "awg");
|
||||
const QString wireguardConfigString =
|
||||
serverController.getTextFileFromContainer(container, credentials, wireGuardConfigFile, &error);
|
||||
if (error != ErrorCode::NoError) {
|
||||
logger.error() << "Failed to get the wg conf file from the server";
|
||||
return error;
|
||||
}
|
||||
|
||||
auto configLines = wireguardConfigString.split("\n", Qt::SkipEmptyParts);
|
||||
QStringList wireguardKeys;
|
||||
for (const auto &line : configLines) {
|
||||
auto configPair = line.split(" = ", Qt::SkipEmptyParts);
|
||||
if (configPair.front() == "PublicKey") {
|
||||
wireguardKeys.push_back(configPair.back());
|
||||
}
|
||||
}
|
||||
|
||||
for (auto &wireguardKey : wireguardKeys) {
|
||||
if (!isClientExists(wireguardKey)) {
|
||||
QJsonObject client;
|
||||
client[configKey::clientId] = wireguardKey;
|
||||
|
||||
QJsonObject userData;
|
||||
userData[configKey::clientName] = QString("Client %1").arg(count);
|
||||
client[configKey::userData] = userData;
|
||||
|
||||
m_clientsTable.push_back(client);
|
||||
|
||||
count++;
|
||||
}
|
||||
}
|
||||
return error;
|
||||
}
|
||||
|
||||
bool ClientManagementModel::isClientExists(const QString &clientId)
|
||||
{
|
||||
for (const QJsonValue &value : qAsConst(m_clientsTable)) {
|
||||
if (value.isObject()) {
|
||||
QJsonObject obj = value.toObject();
|
||||
if (obj.contains(configKey::clientId) && obj[configKey::clientId].toString() == clientId) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
ErrorCode ClientManagementModel::appendClient(const QString &clientId, const QString &clientName,
|
||||
const DockerContainer container, ServerCredentials credentials)
|
||||
{
|
||||
ErrorCode error;
|
||||
|
||||
error = updateModel(container, credentials);
|
||||
if (error != ErrorCode::NoError) {
|
||||
return error;
|
||||
}
|
||||
|
||||
for (int i = 0; i < m_clientsTable.size(); i++) {
|
||||
if (m_clientsTable.at(i).toObject().value(configKey::clientId) == clientId) {
|
||||
return renameClient(i, clientName, container, credentials);
|
||||
}
|
||||
}
|
||||
|
||||
beginResetModel();
|
||||
QJsonObject client;
|
||||
client[configKey::clientId] = clientId;
|
||||
|
||||
QJsonObject userData;
|
||||
userData[configKey::clientName] = clientName;
|
||||
client[configKey::userData] = userData;
|
||||
m_clientsTable.push_back(client);
|
||||
endResetModel();
|
||||
|
||||
const QByteArray clientsTableString = QJsonDocument(m_clientsTable).toJson();
|
||||
|
||||
ServerController serverController(m_settings);
|
||||
const QString clientsTableFile =
|
||||
QString("/opt/amnezia/%1/clientsTable").arg(ContainerProps::containerTypeToString(container));
|
||||
|
||||
error = serverController.uploadTextFileToContainer(container, credentials, clientsTableString, clientsTableFile);
|
||||
if (error != ErrorCode::NoError) {
|
||||
logger.error() << "Failed to upload the clientsTable file to the server";
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
ErrorCode ClientManagementModel::renameClient(const int row, const QString &clientName, const DockerContainer container,
|
||||
ServerCredentials credentials)
|
||||
{
|
||||
auto client = m_clientsTable.at(row).toObject();
|
||||
auto userData = client[configKey::userData].toObject();
|
||||
userData[configKey::clientName] = clientName;
|
||||
client[configKey::userData] = userData;
|
||||
|
||||
m_clientsTable.replace(row, client);
|
||||
emit dataChanged(index(row, 0), index(row, 0));
|
||||
|
||||
const QByteArray clientsTableString = QJsonDocument(m_clientsTable).toJson();
|
||||
|
||||
ServerController serverController(m_settings);
|
||||
const QString clientsTableFile =
|
||||
QString("/opt/amnezia/%1/clientsTable").arg(ContainerProps::containerTypeToString(container));
|
||||
|
||||
ErrorCode error =
|
||||
serverController.uploadTextFileToContainer(container, credentials, clientsTableString, clientsTableFile);
|
||||
if (error != ErrorCode::NoError) {
|
||||
logger.error() << "Failed to upload the clientsTable file to the server";
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
ErrorCode ClientManagementModel::revokeClient(const int row, const DockerContainer container,
|
||||
ServerCredentials credentials)
|
||||
{
|
||||
if (container == DockerContainer::OpenVpn || container == DockerContainer::ShadowSocks
|
||||
|| container == DockerContainer::Cloak) {
|
||||
return revokeOpenVpn(row, container, credentials);
|
||||
} else if (container == DockerContainer::WireGuard || container == DockerContainer::Awg) {
|
||||
return revokeWireGuard(row, container, credentials);
|
||||
}
|
||||
return ErrorCode::NoError;
|
||||
}
|
||||
|
||||
ErrorCode ClientManagementModel::revokeOpenVpn(const int row, const DockerContainer container,
|
||||
ServerCredentials credentials)
|
||||
{
|
||||
auto client = m_clientsTable.at(row).toObject();
|
||||
QString clientId = client.value(configKey::clientId).toString();
|
||||
|
||||
const QString getOpenVpnCertData = QString("sudo docker exec -i $CONTAINER_NAME bash -c '"
|
||||
"cd /opt/amnezia/openvpn ;\\"
|
||||
"easyrsa revoke %1 ;\\"
|
||||
"easyrsa gen-crl ;\\"
|
||||
"cp pki/crl.pem .'")
|
||||
.arg(clientId);
|
||||
|
||||
ServerController serverController(m_settings);
|
||||
const QString script =
|
||||
serverController.replaceVars(getOpenVpnCertData, serverController.genVarsForScript(credentials, container));
|
||||
ErrorCode error = serverController.runScript(credentials, script);
|
||||
if (error != ErrorCode::NoError) {
|
||||
logger.error() << "Failed to revoke the certificate";
|
||||
return error;
|
||||
}
|
||||
|
||||
beginRemoveRows(QModelIndex(), row, row);
|
||||
m_clientsTable.removeAt(row);
|
||||
m_content.removeAt(row);
|
||||
endRemoveRows();
|
||||
|
||||
const QByteArray clientsTableString = QJsonDocument(m_clientsTable).toJson();
|
||||
|
||||
const QString clientsTableFile =
|
||||
QString("/opt/amnezia/%1/clientsTable").arg(ContainerProps::containerTypeToString(container));
|
||||
error = serverController.uploadTextFileToContainer(container, credentials, clientsTableString, clientsTableFile);
|
||||
if (error != ErrorCode::NoError) {
|
||||
logger.error() << "Failed to upload the clientsTable file to the server";
|
||||
return error;
|
||||
}
|
||||
|
||||
return ErrorCode::NoError;
|
||||
}
|
||||
|
||||
ErrorCode ClientManagementModel::revokeWireGuard(const int row, const DockerContainer container,
|
||||
ServerCredentials credentials)
|
||||
{
|
||||
ErrorCode error;
|
||||
ServerController serverController(m_settings);
|
||||
|
||||
const QString wireGuardConfigFile =
|
||||
QString("/opt/amnezia/%1/wg0.conf").arg(container == DockerContainer::WireGuard ? "wireguard" : "awg");
|
||||
const QString wireguardConfigString =
|
||||
serverController.getTextFileFromContainer(container, credentials, wireGuardConfigFile, &error);
|
||||
if (error != ErrorCode::NoError) {
|
||||
logger.error() << "Failed to get the wg conf file from the server";
|
||||
return error;
|
||||
}
|
||||
|
||||
auto client = m_clientsTable.at(row).toObject();
|
||||
QString clientId = client.value(configKey::clientId).toString();
|
||||
|
||||
auto configSections = wireguardConfigString.split("[", Qt::SkipEmptyParts);
|
||||
for (auto §ion : configSections) {
|
||||
if (section.contains(clientId)) {
|
||||
configSections.removeOne(section);
|
||||
break;
|
||||
}
|
||||
}
|
||||
QString newWireGuardConfig = configSections.join("[");
|
||||
newWireGuardConfig.insert(0, "[");
|
||||
error = serverController.uploadTextFileToContainer(container, credentials, newWireGuardConfig, wireGuardConfigFile);
|
||||
if (error != ErrorCode::NoError) {
|
||||
logger.error() << "Failed to upload the wg conf file to the server";
|
||||
return error;
|
||||
}
|
||||
|
||||
beginRemoveRows(QModelIndex(), row, row);
|
||||
m_clientsTable.removeAt(row);
|
||||
endRemoveRows();
|
||||
|
||||
const QByteArray clientsTableString = QJsonDocument(m_clientsTable).toJson();
|
||||
|
||||
const QString clientsTableFile =
|
||||
QString("/opt/amnezia/%1/clientsTable").arg(ContainerProps::containerTypeToString(container));
|
||||
error = serverController.uploadTextFileToContainer(container, credentials, clientsTableString, clientsTableFile);
|
||||
if (error != ErrorCode::NoError) {
|
||||
logger.error() << "Failed to upload the clientsTable file to the server";
|
||||
return error;
|
||||
}
|
||||
|
||||
const QString script = "sudo docker exec -i $CONTAINER_NAME bash -c 'wg syncconf wg0 <(wg-quick strip %1)'";
|
||||
error = serverController.runScript(
|
||||
credentials,
|
||||
serverController.replaceVars(script.arg(wireGuardConfigFile),
|
||||
serverController.genVarsForScript(credentials, container)));
|
||||
if (error != ErrorCode::NoError) {
|
||||
logger.error() << "Failed to execute the command 'wg syncconf' on the server";
|
||||
return error;
|
||||
}
|
||||
|
||||
return ErrorCode::NoError;
|
||||
return true;
|
||||
}
|
||||
|
||||
QHash<int, QByteArray> ClientManagementModel::roleNames() const
|
||||
{
|
||||
QHash<int, QByteArray> roles;
|
||||
roles[ClientNameRole] = "clientName";
|
||||
roles[NameRole] = "clientName";
|
||||
roles[OpenVpnCertIdRole] = "openvpnCertId";
|
||||
roles[OpenVpnCertDataRole] = "openvpnCertData";
|
||||
roles[WireGuardPublicKey] = "wireguardPublicKey";
|
||||
return roles;
|
||||
}
|
||||
|
||||
@@ -2,48 +2,36 @@
|
||||
#define CLIENTMANAGEMENTMODEL_H
|
||||
|
||||
#include <QAbstractListModel>
|
||||
#include <QJsonArray>
|
||||
|
||||
#include "core/controllers/serverController.h"
|
||||
#include "settings.h"
|
||||
#include "protocols/protocols_defs.h"
|
||||
|
||||
class ClientManagementModel : public QAbstractListModel
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
enum Roles {
|
||||
ClientNameRole = Qt::UserRole + 1,
|
||||
enum ClientRoles {
|
||||
NameRole = Qt::UserRole + 1,
|
||||
OpenVpnCertIdRole,
|
||||
OpenVpnCertDataRole,
|
||||
WireGuardPublicKey,
|
||||
};
|
||||
|
||||
ClientManagementModel(std::shared_ptr<Settings> settings, QObject *parent = nullptr);
|
||||
ClientManagementModel(QObject *parent = nullptr);
|
||||
|
||||
void clearData();
|
||||
void setContent(const QVector<QVariant> &data);
|
||||
QJsonObject getContent(amnezia::Proto protocol);
|
||||
int rowCount(const QModelIndex &parent = QModelIndex()) const override;
|
||||
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
|
||||
|
||||
public slots:
|
||||
ErrorCode updateModel(DockerContainer container, ServerCredentials credentials);
|
||||
ErrorCode appendClient(const QString &clientId, const QString &clientName, const DockerContainer container,
|
||||
ServerCredentials credentials);
|
||||
ErrorCode renameClient(const int row, const QString &userName, const DockerContainer container,
|
||||
ServerCredentials credentials);
|
||||
ErrorCode revokeClient(const int index, const DockerContainer container, ServerCredentials credentials);
|
||||
void setData(const QModelIndex &index, QVariant data, int role = Qt::DisplayRole);
|
||||
bool removeRows(int row);
|
||||
|
||||
protected:
|
||||
QHash<int, QByteArray> roleNames() const override;
|
||||
|
||||
private:
|
||||
bool isClientExists(const QString &clientId);
|
||||
|
||||
ErrorCode revokeOpenVpn(const int row, const DockerContainer container, ServerCredentials credentials);
|
||||
ErrorCode revokeWireGuard(const int row, const DockerContainer container, ServerCredentials credentials);
|
||||
|
||||
ErrorCode getOpenVpnClients(ServerController &serverController, DockerContainer container, ServerCredentials credentials, int &count);
|
||||
ErrorCode getWireGuardClients(ServerController &serverController, DockerContainer container, ServerCredentials credentials, int &count);
|
||||
|
||||
QJsonArray m_clientsTable;
|
||||
|
||||
std::shared_ptr<Settings> m_settings;
|
||||
QVector<QVariant> m_content;
|
||||
};
|
||||
|
||||
#endif // CLIENTMANAGEMENTMODEL_H
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
#include "containers_model.h"
|
||||
|
||||
#include <QJsonArray>
|
||||
#include "core/servercontroller.h"
|
||||
|
||||
ContainersModel::ContainersModel(QObject *parent)
|
||||
: QAbstractListModel(parent)
|
||||
ContainersModel::ContainersModel(std::shared_ptr<Settings> settings, QObject *parent)
|
||||
: m_settings(settings), QAbstractListModel(parent)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -13,6 +13,37 @@ int ContainersModel::rowCount(const QModelIndex &parent) const
|
||||
return ContainerProps::allContainers().size();
|
||||
}
|
||||
|
||||
bool ContainersModel::setData(const QModelIndex &index, const QVariant &value, int role)
|
||||
{
|
||||
if (!index.isValid() || index.row() < 0 || index.row() >= ContainerProps::allContainers().size()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
DockerContainer container = ContainerProps::allContainers().at(index.row());
|
||||
|
||||
switch (role) {
|
||||
case ConfigRole: {
|
||||
m_settings->setContainerConfig(m_currentlyProcessedServerIndex, container, value.toJsonObject());
|
||||
m_containers = m_settings->containers(m_currentlyProcessedServerIndex);
|
||||
if (m_defaultContainerIndex != DockerContainer::None) {
|
||||
break;
|
||||
} else if (ContainerProps::containerService(container) == ServiceType::Other) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
case IsDefaultRole: { //todo remove
|
||||
m_settings->setDefaultContainer(m_currentlyProcessedServerIndex, container);
|
||||
m_defaultContainerIndex = container;
|
||||
emit defaultContainerChanged();
|
||||
}
|
||||
default: break;
|
||||
}
|
||||
|
||||
emit containersModelUpdated();
|
||||
emit dataChanged(index, index);
|
||||
return true;
|
||||
}
|
||||
|
||||
QVariant ContainersModel::data(const QModelIndex &index, int role) const
|
||||
{
|
||||
if (!index.isValid() || index.row() < 0 || index.row() >= ContainerProps::allContainers().size()) {
|
||||
@@ -53,32 +84,37 @@ QVariant ContainersModel::data(const int index, int role) const
|
||||
return data(modelIndex, role);
|
||||
}
|
||||
|
||||
void ContainersModel::updateModel(QJsonArray &containers)
|
||||
void ContainersModel::setCurrentlyProcessedServerIndex(const int index)
|
||||
{
|
||||
beginResetModel();
|
||||
m_containers.clear();
|
||||
for (const QJsonValue &val : containers) {
|
||||
m_containers.insert(ContainerProps::containerFromString(val.toObject().value(config_key::container).toString()),
|
||||
val.toObject());
|
||||
}
|
||||
m_currentlyProcessedServerIndex = index;
|
||||
m_containers = m_settings->containers(m_currentlyProcessedServerIndex);
|
||||
m_defaultContainerIndex = m_settings->defaultContainer(m_currentlyProcessedServerIndex);
|
||||
endResetModel();
|
||||
emit defaultContainerChanged();
|
||||
}
|
||||
|
||||
void ContainersModel::setDefaultContainer(const int containerIndex)
|
||||
void ContainersModel::setCurrentlyProcessedContainerIndex(int index)
|
||||
{
|
||||
m_defaultContainerIndex = static_cast<DockerContainer>(containerIndex);
|
||||
emit dataChanged(index(containerIndex, 0), index(containerIndex, 0));
|
||||
m_currentlyProcessedContainerIndex = index;
|
||||
}
|
||||
|
||||
|
||||
DockerContainer ContainersModel::getDefaultContainer()
|
||||
{
|
||||
return m_defaultContainerIndex;
|
||||
}
|
||||
|
||||
void ContainersModel::setCurrentlyProcessedContainerIndex(int index)
|
||||
QString ContainersModel::getDefaultContainerName()
|
||||
{
|
||||
m_currentlyProcessedContainerIndex = index;
|
||||
return ContainerProps::containerHumanNames().value(m_defaultContainerIndex);
|
||||
}
|
||||
|
||||
void ContainersModel::setDefaultContainer(int index)
|
||||
{
|
||||
auto container = static_cast<DockerContainer>(index);
|
||||
m_settings->setDefaultContainer(m_currentlyProcessedServerIndex, container);
|
||||
m_defaultContainerIndex = container;
|
||||
emit defaultContainerChanged();
|
||||
}
|
||||
|
||||
int ContainersModel::getCurrentlyProcessedContainerIndex()
|
||||
@@ -91,9 +127,91 @@ QString ContainersModel::getCurrentlyProcessedContainerName()
|
||||
return ContainerProps::containerHumanNames().value(static_cast<DockerContainer>(m_currentlyProcessedContainerIndex));
|
||||
}
|
||||
|
||||
QJsonObject ContainersModel::getContainerConfig(const int containerIndex)
|
||||
QJsonObject ContainersModel::getCurrentlyProcessedContainerConfig()
|
||||
{
|
||||
return qvariant_cast<QJsonObject>(data(index(containerIndex), ConfigRole));
|
||||
return qvariant_cast<QJsonObject>(data(index(m_currentlyProcessedContainerIndex), ConfigRole));
|
||||
}
|
||||
|
||||
QStringList ContainersModel::getAllInstalledServicesName(const int serverIndex)
|
||||
{
|
||||
QStringList servicesName;
|
||||
const auto &containers = m_settings->containers(serverIndex);
|
||||
for (const DockerContainer &container : containers.keys()) {
|
||||
if (ContainerProps::containerService(container) == ServiceType::Other && m_containers.contains(container)) {
|
||||
if (container == DockerContainer::Dns) {
|
||||
servicesName.append("DNS");
|
||||
} else if (container == DockerContainer::Sftp) {
|
||||
servicesName.append("SFTP");
|
||||
} else if (container == DockerContainer::TorWebSite) {
|
||||
servicesName.append("TOR");
|
||||
}
|
||||
}
|
||||
}
|
||||
servicesName.sort();
|
||||
return servicesName;
|
||||
}
|
||||
|
||||
ErrorCode ContainersModel::removeAllContainers()
|
||||
{
|
||||
|
||||
ServerController serverController(m_settings);
|
||||
ErrorCode errorCode =
|
||||
serverController.removeAllContainers(m_settings->serverCredentials(m_currentlyProcessedServerIndex));
|
||||
|
||||
if (errorCode == ErrorCode::NoError) {
|
||||
beginResetModel();
|
||||
|
||||
m_settings->setContainers(m_currentlyProcessedServerIndex, {});
|
||||
m_containers = m_settings->containers(m_currentlyProcessedServerIndex);
|
||||
|
||||
setData(index(DockerContainer::None, 0), true, IsDefaultRole);
|
||||
endResetModel();
|
||||
}
|
||||
return errorCode;
|
||||
}
|
||||
|
||||
ErrorCode ContainersModel::removeCurrentlyProcessedContainer()
|
||||
{
|
||||
ServerController serverController(m_settings);
|
||||
auto credentials = m_settings->serverCredentials(m_currentlyProcessedServerIndex);
|
||||
auto dockerContainer = static_cast<DockerContainer>(m_currentlyProcessedContainerIndex);
|
||||
|
||||
ErrorCode errorCode = serverController.removeContainer(credentials, dockerContainer);
|
||||
|
||||
if (errorCode == ErrorCode::NoError) {
|
||||
beginResetModel();
|
||||
m_settings->removeContainerConfig(m_currentlyProcessedServerIndex, dockerContainer);
|
||||
m_containers = m_settings->containers(m_currentlyProcessedServerIndex);
|
||||
|
||||
if (m_defaultContainerIndex == m_currentlyProcessedContainerIndex) {
|
||||
if (m_containers.isEmpty()) {
|
||||
setData(index(DockerContainer::None, 0), true, IsDefaultRole);
|
||||
} else {
|
||||
setData(index(m_containers.begin().key(), 0), true, IsDefaultRole);
|
||||
}
|
||||
}
|
||||
endResetModel();
|
||||
}
|
||||
return errorCode;
|
||||
}
|
||||
|
||||
void ContainersModel::clearCachedProfiles()
|
||||
{
|
||||
const auto &containers = m_settings->containers(m_currentlyProcessedServerIndex);
|
||||
for (DockerContainer container : containers.keys()) {
|
||||
m_settings->clearLastConnectionConfig(m_currentlyProcessedServerIndex, container);
|
||||
}
|
||||
}
|
||||
|
||||
bool ContainersModel::isAmneziaDnsContainerInstalled()
|
||||
{
|
||||
return m_containers.contains(DockerContainer::Dns);
|
||||
}
|
||||
|
||||
bool ContainersModel::isAmneziaDnsContainerInstalled(const int serverIndex)
|
||||
{
|
||||
QMap<DockerContainer, QJsonObject> containers = m_settings->containers(serverIndex);
|
||||
return containers.contains(DockerContainer::Dns);
|
||||
}
|
||||
|
||||
bool ContainersModel::isAnyContainerInstalled()
|
||||
@@ -110,6 +228,11 @@ bool ContainersModel::isAnyContainerInstalled()
|
||||
return false;
|
||||
}
|
||||
|
||||
void ContainersModel::updateContainersConfig()
|
||||
{
|
||||
m_containers = m_settings->containers(m_currentlyProcessedServerIndex);
|
||||
}
|
||||
|
||||
QHash<int, QByteArray> ContainersModel::roleNames() const
|
||||
{
|
||||
QHash<int, QByteArray> roles;
|
||||
|
||||
@@ -7,12 +7,13 @@
|
||||
#include <vector>
|
||||
|
||||
#include "containers/containers_defs.h"
|
||||
#include "settings.h"
|
||||
|
||||
class ContainersModel : public QAbstractListModel
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
ContainersModel(QObject *parent = nullptr);
|
||||
ContainersModel(std::shared_ptr<Settings> settings, QObject *parent = nullptr);
|
||||
|
||||
enum Roles {
|
||||
NameRole = Qt::UserRole + 1,
|
||||
@@ -36,24 +37,37 @@ public:
|
||||
|
||||
int rowCount(const QModelIndex &parent = QModelIndex()) const override;
|
||||
|
||||
bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole) override;
|
||||
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
|
||||
QVariant data(const int index, int role) const;
|
||||
|
||||
Q_PROPERTY(QString defaultContainerName READ getDefaultContainerName NOTIFY defaultContainerChanged)
|
||||
|
||||
public slots:
|
||||
void updateModel(QJsonArray &containers);
|
||||
|
||||
DockerContainer getDefaultContainer();
|
||||
void setDefaultContainer(const int containerIndex);
|
||||
QString getDefaultContainerName();
|
||||
void setDefaultContainer(int index);
|
||||
|
||||
void setCurrentlyProcessedContainerIndex(int containerIndex);
|
||||
void setCurrentlyProcessedServerIndex(const int index);
|
||||
|
||||
void setCurrentlyProcessedContainerIndex(int index);
|
||||
int getCurrentlyProcessedContainerIndex();
|
||||
|
||||
QString getCurrentlyProcessedContainerName();
|
||||
QJsonObject getCurrentlyProcessedContainerConfig();
|
||||
QStringList getAllInstalledServicesName(const int serverIndex);
|
||||
|
||||
QJsonObject getContainerConfig(const int containerIndex);
|
||||
ErrorCode removeAllContainers();
|
||||
ErrorCode removeCurrentlyProcessedContainer();
|
||||
void clearCachedProfiles();
|
||||
|
||||
bool isAmneziaDnsContainerInstalled();
|
||||
bool isAmneziaDnsContainerInstalled(const int serverIndex);
|
||||
|
||||
bool isAnyContainerInstalled();
|
||||
|
||||
void updateContainersConfig();
|
||||
|
||||
protected:
|
||||
QHash<int, QByteArray> roleNames() const override;
|
||||
|
||||
@@ -64,8 +78,11 @@ signals:
|
||||
private:
|
||||
QMap<DockerContainer, QJsonObject> m_containers;
|
||||
|
||||
int m_currentlyProcessedServerIndex;
|
||||
int m_currentlyProcessedContainerIndex;
|
||||
DockerContainer m_defaultContainerIndex;
|
||||
|
||||
std::shared_ptr<Settings> m_settings;
|
||||
};
|
||||
|
||||
#endif // CONTAINERS_MODEL_H
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
#include "servers_model.h"
|
||||
|
||||
#include "core/controllers/serverController.h"
|
||||
|
||||
ServersModel::ServersModel(std::shared_ptr<Settings> settings, QObject *parent)
|
||||
: m_settings(settings), QAbstractListModel(parent)
|
||||
{
|
||||
@@ -10,11 +8,6 @@ ServersModel::ServersModel(std::shared_ptr<Settings> settings, QObject *parent)
|
||||
m_currentlyProcessedServerIndex = m_defaultServerIndex;
|
||||
|
||||
connect(this, &ServersModel::defaultServerIndexChanged, this, &ServersModel::defaultServerNameChanged);
|
||||
connect(this, &ServersModel::defaultContainerChanged, this, &ServersModel::defaultServerDescriptionChanged);
|
||||
connect(this, &ServersModel::defaultServerIndexChanged, this, [this](const int serverIndex) {
|
||||
auto defaultContainer = ContainerProps::containerFromString(m_servers.at(serverIndex).toObject().value(config_key::defaultContainer).toString());
|
||||
emit ServersModel::defaultContainerChanged(defaultContainer);
|
||||
});
|
||||
}
|
||||
|
||||
int ServersModel::rowCount(const QModelIndex &parent) const
|
||||
@@ -57,23 +50,14 @@ QVariant ServersModel::data(const QModelIndex &index, int role) const
|
||||
}
|
||||
|
||||
const QJsonObject server = m_servers.at(index.row()).toObject();
|
||||
const auto configVersion = server.value(config_key::configVersion).toInt();
|
||||
|
||||
switch (role) {
|
||||
case NameRole: {
|
||||
if (configVersion) {
|
||||
return server.value(config_key::name).toString();
|
||||
}
|
||||
auto name = server.value(config_key::description).toString();
|
||||
if (name.isEmpty()) {
|
||||
auto description = server.value(config_key::description).toString();
|
||||
if (description.isEmpty()) {
|
||||
return server.value(config_key::hostName).toString();
|
||||
}
|
||||
return name;
|
||||
}
|
||||
case ServerDescriptionRole: {
|
||||
if (configVersion) {
|
||||
return server.value(config_key::description).toString();
|
||||
}
|
||||
return server.value(config_key::hostName).toString();
|
||||
return description;
|
||||
}
|
||||
case HostNameRole: return server.value(config_key::hostName).toString();
|
||||
case CredentialsRole: return QVariant::fromValue(serverCredentials(index.row()));
|
||||
@@ -88,9 +72,6 @@ QVariant ServersModel::data(const QModelIndex &index, int role) const
|
||||
QString primaryDns = server.value(config_key::dns1).toString();
|
||||
return primaryDns == protocols::dns::amneziaDnsIp;
|
||||
}
|
||||
case DefaultContainerRole: {
|
||||
return ContainerProps::containerFromString(server.value(config_key::defaultContainer).toString());
|
||||
}
|
||||
}
|
||||
|
||||
return QVariant();
|
||||
@@ -133,53 +114,6 @@ const QString ServersModel::getDefaultServerHostName()
|
||||
return qvariant_cast<QString>(data(m_defaultServerIndex, HostNameRole));
|
||||
}
|
||||
|
||||
QString ServersModel::getDefaultServerDescription(const QJsonObject &server)
|
||||
{
|
||||
const auto configVersion = server.value(config_key::configVersion).toInt();
|
||||
|
||||
QString description;
|
||||
|
||||
if (configVersion) {
|
||||
return server.value(config_key::description).toString();
|
||||
} else if (isDefaultServerHasWriteAccess()) {
|
||||
if (m_isAmneziaDnsEnabled
|
||||
&& isAmneziaDnsContainerInstalled(m_defaultServerIndex)) {
|
||||
description += "Amnezia DNS | ";
|
||||
}
|
||||
} else {
|
||||
if (isDefaultServerConfigContainsAmneziaDns()) {
|
||||
description += "Amnezia DNS | ";
|
||||
}
|
||||
}
|
||||
return description;
|
||||
}
|
||||
|
||||
const QString ServersModel::getDefaultServerDescriptionCollapsed()
|
||||
{
|
||||
const QJsonObject server = m_servers.at(m_defaultServerIndex).toObject();
|
||||
const auto configVersion = server.value(config_key::configVersion).toInt();
|
||||
auto description = getDefaultServerDescription(server);
|
||||
if (configVersion) {
|
||||
return description;
|
||||
}
|
||||
|
||||
auto container = ContainerProps::containerFromString(server.value(config_key::defaultContainer).toString());
|
||||
|
||||
return description += ContainerProps::containerHumanNames().value(container) + " | " + server.value(config_key::hostName).toString();
|
||||
}
|
||||
|
||||
const QString ServersModel::getDefaultServerDescriptionExpanded()
|
||||
{
|
||||
const QJsonObject server = m_servers.at(m_defaultServerIndex).toObject();
|
||||
const auto configVersion = server.value(config_key::configVersion).toInt();
|
||||
auto description = getDefaultServerDescription(server);
|
||||
if (configVersion) {
|
||||
return description;
|
||||
}
|
||||
|
||||
return description += server.value(config_key::hostName).toString();
|
||||
}
|
||||
|
||||
const int ServersModel::getServersCount()
|
||||
{
|
||||
return m_servers.count();
|
||||
@@ -198,7 +132,6 @@ bool ServersModel::hasServerWithWriteAccess()
|
||||
void ServersModel::setCurrentlyProcessedServerIndex(const int index)
|
||||
{
|
||||
m_currentlyProcessedServerIndex = index;
|
||||
updateContainersModel();
|
||||
emit currentlyProcessedServerIndexChanged(m_currentlyProcessedServerIndex);
|
||||
}
|
||||
|
||||
@@ -212,16 +145,6 @@ QString ServersModel::getCurrentlyProcessedServerHostName()
|
||||
return qvariant_cast<QString>(data(m_currentlyProcessedServerIndex, HostNameRole));
|
||||
}
|
||||
|
||||
const ServerCredentials ServersModel::getCurrentlyProcessedServerCredentials()
|
||||
{
|
||||
return serverCredentials(m_currentlyProcessedServerIndex);
|
||||
}
|
||||
|
||||
const ServerCredentials ServersModel::getServerCredentials(const int index)
|
||||
{
|
||||
return serverCredentials(index);
|
||||
}
|
||||
|
||||
bool ServersModel::isDefaultServerCurrentlyProcessed()
|
||||
{
|
||||
return m_defaultServerIndex == m_currentlyProcessedServerIndex;
|
||||
@@ -245,15 +168,6 @@ void ServersModel::addServer(const QJsonObject &server)
|
||||
endResetModel();
|
||||
}
|
||||
|
||||
void ServersModel::editServer(const QJsonObject &server)
|
||||
{
|
||||
beginResetModel();
|
||||
m_settings->editServer(m_currentlyProcessedServerIndex, server);
|
||||
m_servers = m_settings->serversArray();
|
||||
endResetModel();
|
||||
updateContainersModel();
|
||||
}
|
||||
|
||||
void ServersModel::removeServer()
|
||||
{
|
||||
beginResetModel();
|
||||
@@ -279,27 +193,23 @@ bool ServersModel::isDefaultServerConfigContainsAmneziaDns()
|
||||
return primaryDns == protocols::dns::amneziaDnsIp;
|
||||
}
|
||||
|
||||
void ServersModel::updateContainersConfig()
|
||||
{
|
||||
auto server = m_settings->server(m_currentlyProcessedServerIndex);
|
||||
m_servers.replace(m_currentlyProcessedServerIndex, server);
|
||||
}
|
||||
|
||||
QHash<int, QByteArray> ServersModel::roleNames() const
|
||||
{
|
||||
QHash<int, QByteArray> roles;
|
||||
|
||||
roles[NameRole] = "serverName";
|
||||
roles[NameRole] = "name";
|
||||
roles[ServerDescriptionRole] = "serverDescription";
|
||||
|
||||
roles[HostNameRole] = "hostName";
|
||||
|
||||
roles[CredentialsRole] = "credentials";
|
||||
roles[CredentialsLoginRole] = "credentialsLogin";
|
||||
|
||||
roles[IsDefaultRole] = "isDefault";
|
||||
roles[IsCurrentlyProcessedRole] = "isCurrentlyProcessed";
|
||||
|
||||
roles[HasWriteAccessRole] = "hasWriteAccess";
|
||||
|
||||
roles[ContainsAmneziaDnsRole] = "containsAmneziaDns";
|
||||
|
||||
roles[DefaultContainerRole] = "defaultContainer";
|
||||
return roles;
|
||||
}
|
||||
|
||||
@@ -315,206 +225,3 @@ ServerCredentials ServersModel::serverCredentials(int index) const
|
||||
|
||||
return credentials;
|
||||
}
|
||||
|
||||
void ServersModel::updateContainersModel()
|
||||
{
|
||||
auto containers = m_servers.at(m_currentlyProcessedServerIndex).toObject().value(config_key::containers).toArray();
|
||||
emit containersUpdated(containers);
|
||||
}
|
||||
|
||||
QJsonObject ServersModel::getDefaultServerConfig()
|
||||
{
|
||||
return m_servers.at(m_defaultServerIndex).toObject();
|
||||
}
|
||||
|
||||
void ServersModel::reloadContainerConfig()
|
||||
{
|
||||
QJsonObject server = m_servers.at(m_currentlyProcessedServerIndex).toObject();
|
||||
auto container = ContainerProps::containerFromString(server.value(config_key::defaultContainer).toString());
|
||||
|
||||
auto containers = server.value(config_key::containers).toArray();
|
||||
|
||||
auto config = m_settings->containerConfig(m_currentlyProcessedServerIndex, container);
|
||||
for (auto i = 0; i < containers.size(); i++) {
|
||||
auto c = ContainerProps::containerFromString(containers.at(i).toObject().value(config_key::container).toString());
|
||||
if (c == container) {
|
||||
containers.replace(i, config);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
server.insert(config_key::containers, containers);
|
||||
editServer(server);
|
||||
}
|
||||
|
||||
void ServersModel::updateContainerConfig(const int containerIndex, const QJsonObject config)
|
||||
{
|
||||
auto container = static_cast<DockerContainer>(containerIndex);
|
||||
QJsonObject server = m_servers.at(m_currentlyProcessedServerIndex).toObject();
|
||||
|
||||
auto containers = server.value(config_key::containers).toArray();
|
||||
for (auto i = 0; i < containers.size(); i++) {
|
||||
auto c = ContainerProps::containerFromString(containers.at(i).toObject().value(config_key::container).toString());
|
||||
if (c == container) {
|
||||
containers.replace(i, config);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
server.insert(config_key::containers, containers);
|
||||
|
||||
auto defaultContainer = server.value(config_key::defaultContainer).toString();
|
||||
if ((ContainerProps::containerFromString(defaultContainer) == DockerContainer::None || ContainerProps::containerService(container) != ServiceType::Other)) {
|
||||
server.insert(config_key::defaultContainer, ContainerProps::containerToString(container));
|
||||
}
|
||||
|
||||
editServer(server);
|
||||
}
|
||||
|
||||
void ServersModel::addContainerConfig(const int containerIndex, const QJsonObject config)
|
||||
{
|
||||
auto container = static_cast<DockerContainer>(containerIndex);
|
||||
QJsonObject server = m_servers.at(m_currentlyProcessedServerIndex).toObject();
|
||||
|
||||
auto containers = server.value(config_key::containers).toArray();
|
||||
containers.push_back(config);
|
||||
|
||||
server.insert(config_key::containers, containers);
|
||||
|
||||
bool isDefaultContainerChanged = false;
|
||||
auto defaultContainer = server.value(config_key::defaultContainer).toString();
|
||||
if ((ContainerProps::containerFromString(defaultContainer) == DockerContainer::None || ContainerProps::containerService(container) != ServiceType::Other)) {
|
||||
server.insert(config_key::defaultContainer, ContainerProps::containerToString(container));
|
||||
isDefaultContainerChanged = true;
|
||||
}
|
||||
|
||||
editServer(server);
|
||||
if (isDefaultContainerChanged) {
|
||||
emit defaultContainerChanged(container);
|
||||
}
|
||||
}
|
||||
|
||||
void ServersModel::setDefaultContainer(const int containerIndex)
|
||||
{
|
||||
auto container = static_cast<DockerContainer>(containerIndex);
|
||||
QJsonObject s = m_servers.at(m_currentlyProcessedServerIndex).toObject();
|
||||
s.insert(config_key::defaultContainer, ContainerProps::containerToString(container));
|
||||
editServer(s); //check
|
||||
emit defaultContainerChanged(container);
|
||||
}
|
||||
|
||||
DockerContainer ServersModel::getDefaultContainer()
|
||||
{
|
||||
return qvariant_cast<DockerContainer>(data(m_currentlyProcessedServerIndex, DefaultContainerRole));
|
||||
}
|
||||
|
||||
const QString ServersModel::getDefaultContainerName()
|
||||
{
|
||||
auto defaultContainer = getDefaultContainer();
|
||||
return ContainerProps::containerHumanNames().value(defaultContainer);
|
||||
}
|
||||
|
||||
ErrorCode ServersModel::removeAllContainers()
|
||||
{
|
||||
ServerController serverController(m_settings);
|
||||
ErrorCode errorCode =
|
||||
serverController.removeAllContainers(m_settings->serverCredentials(m_currentlyProcessedServerIndex));
|
||||
|
||||
if (errorCode == ErrorCode::NoError) {
|
||||
QJsonObject s = m_servers.at(m_currentlyProcessedServerIndex).toObject();
|
||||
s.insert(config_key::containers, {});
|
||||
s.insert(config_key::defaultContainer, ContainerProps::containerToString(DockerContainer::None));
|
||||
|
||||
editServer(s);
|
||||
emit defaultContainerChanged(DockerContainer::None);
|
||||
}
|
||||
return errorCode;
|
||||
}
|
||||
|
||||
ErrorCode ServersModel::removeContainer(const int containerIndex)
|
||||
{
|
||||
ServerController serverController(m_settings);
|
||||
auto credentials = m_settings->serverCredentials(m_currentlyProcessedServerIndex);
|
||||
auto dockerContainer = static_cast<DockerContainer>(containerIndex);
|
||||
|
||||
ErrorCode errorCode = serverController.removeContainer(credentials, dockerContainer);
|
||||
|
||||
if (errorCode == ErrorCode::NoError) {
|
||||
QJsonObject server = m_servers.at(m_currentlyProcessedServerIndex).toObject();
|
||||
|
||||
auto containers = server.value(config_key::containers).toArray();
|
||||
for (auto it = containers.begin(); it != containers.end(); it++) {
|
||||
if (it->toObject().value(config_key::container).toString() == ContainerProps::containerToString(dockerContainer)) {
|
||||
containers.erase(it);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
server.insert(config_key::containers, containers);
|
||||
|
||||
auto defaultContainer = ContainerProps::containerFromString(server.value(config_key::defaultContainer).toString());
|
||||
if (defaultContainer == containerIndex) {
|
||||
if (containers.empty()) {
|
||||
defaultContainer = DockerContainer::None;
|
||||
} else {
|
||||
defaultContainer = ContainerProps::containerFromString(containers.begin()->toObject().value(config_key::container).toString());
|
||||
}
|
||||
server.insert(config_key::defaultContainer, ContainerProps::containerToString(defaultContainer));
|
||||
}
|
||||
|
||||
editServer(server);
|
||||
emit defaultContainerChanged(defaultContainer);
|
||||
}
|
||||
return errorCode;
|
||||
}
|
||||
|
||||
void ServersModel::clearCachedProfiles()
|
||||
{
|
||||
const auto &containers = m_settings->containers(m_currentlyProcessedServerIndex);
|
||||
for (DockerContainer container : containers.keys()) {
|
||||
m_settings->clearLastConnectionConfig(m_currentlyProcessedServerIndex, container);
|
||||
}
|
||||
|
||||
m_servers.replace(m_currentlyProcessedServerIndex, m_settings->server(m_currentlyProcessedServerIndex));
|
||||
updateContainersModel();
|
||||
}
|
||||
|
||||
bool ServersModel::isAmneziaDnsContainerInstalled(const int serverIndex)
|
||||
{
|
||||
QJsonObject server = m_servers.at(serverIndex).toObject();
|
||||
auto containers = server.value(config_key::containers).toArray();
|
||||
for (auto it = containers.begin(); it != containers.end(); it++) {
|
||||
if (it->toObject().value(config_key::container).toString() == ContainerProps::containerToString(DockerContainer::Dns)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
QStringList ServersModel::getAllInstalledServicesName(const int serverIndex)
|
||||
{
|
||||
QStringList servicesName;
|
||||
QJsonObject server = m_servers.at(serverIndex).toObject();
|
||||
const auto containers = server.value(config_key::containers).toArray();
|
||||
for (auto it = containers.begin(); it != containers.end(); it++) {
|
||||
auto container = ContainerProps::containerFromString(it->toObject().value(config_key::container).toString());
|
||||
if (ContainerProps::containerService(container) == ServiceType::Other) {
|
||||
if (container == DockerContainer::Dns) {
|
||||
servicesName.append("DNS");
|
||||
} else if (container == DockerContainer::Sftp) {
|
||||
servicesName.append("SFTP");
|
||||
} else if (container == DockerContainer::TorWebSite) {
|
||||
servicesName.append("TOR");
|
||||
}
|
||||
}
|
||||
}
|
||||
servicesName.sort();
|
||||
return servicesName;
|
||||
}
|
||||
|
||||
void ServersModel::toggleAmneziaDns(bool enabled)
|
||||
{
|
||||
m_isAmneziaDnsEnabled = enabled;
|
||||
emit defaultServerDescriptionChanged();
|
||||
}
|
||||
|
||||
|
||||
@@ -11,21 +11,13 @@ class ServersModel : public QAbstractListModel
|
||||
public:
|
||||
enum Roles {
|
||||
NameRole = Qt::UserRole + 1,
|
||||
ServerDescriptionRole,
|
||||
|
||||
HostNameRole,
|
||||
|
||||
CredentialsRole,
|
||||
CredentialsLoginRole,
|
||||
|
||||
IsDefaultRole,
|
||||
IsCurrentlyProcessedRole,
|
||||
|
||||
HasWriteAccessRole,
|
||||
|
||||
ContainsAmneziaDnsRole,
|
||||
|
||||
DefaultContainerRole
|
||||
ContainsAmneziaDnsRole
|
||||
};
|
||||
|
||||
ServersModel(std::shared_ptr<Settings> settings, QObject *parent = nullptr);
|
||||
@@ -41,10 +33,6 @@ public:
|
||||
Q_PROPERTY(int defaultIndex READ getDefaultServerIndex WRITE setDefaultServerIndex NOTIFY defaultServerIndexChanged)
|
||||
Q_PROPERTY(QString defaultServerName READ getDefaultServerName NOTIFY defaultServerNameChanged)
|
||||
Q_PROPERTY(QString defaultServerHostName READ getDefaultServerHostName NOTIFY defaultServerIndexChanged)
|
||||
Q_PROPERTY(QString defaultContainerName READ getDefaultContainerName NOTIFY defaultContainerChanged)
|
||||
Q_PROPERTY(QString defaultServerDescriptionCollapsed READ getDefaultServerDescriptionCollapsed NOTIFY defaultServerDescriptionChanged)
|
||||
Q_PROPERTY(QString defaultServerDescriptionExpanded READ getDefaultServerDescriptionExpanded NOTIFY defaultServerDescriptionChanged)
|
||||
|
||||
Q_PROPERTY(int currentlyProcessedIndex READ getCurrentlyProcessedServerIndex WRITE setCurrentlyProcessedServerIndex
|
||||
NOTIFY currentlyProcessedServerIndexChanged)
|
||||
|
||||
@@ -53,8 +41,6 @@ public slots:
|
||||
const int getDefaultServerIndex();
|
||||
const QString getDefaultServerName();
|
||||
const QString getDefaultServerHostName();
|
||||
const QString getDefaultServerDescriptionCollapsed();
|
||||
const QString getDefaultServerDescriptionExpanded();
|
||||
bool isDefaultServerCurrentlyProcessed();
|
||||
|
||||
bool isCurrentlyProcessedServerHasWriteAccess();
|
||||
@@ -67,34 +53,13 @@ public slots:
|
||||
int getCurrentlyProcessedServerIndex();
|
||||
|
||||
QString getCurrentlyProcessedServerHostName();
|
||||
const ServerCredentials getCurrentlyProcessedServerCredentials();
|
||||
const ServerCredentials getServerCredentials(const int index);
|
||||
|
||||
void addServer(const QJsonObject &server);
|
||||
void editServer(const QJsonObject &server);
|
||||
void removeServer();
|
||||
|
||||
bool isDefaultServerConfigContainsAmneziaDns();
|
||||
bool isAmneziaDnsContainerInstalled(const int serverIndex);
|
||||
|
||||
QJsonObject getDefaultServerConfig();
|
||||
|
||||
void reloadContainerConfig();
|
||||
void updateContainerConfig(const int containerIndex, const QJsonObject config);
|
||||
void addContainerConfig(const int containerIndex, const QJsonObject config);
|
||||
|
||||
void clearCachedProfiles();
|
||||
|
||||
ErrorCode removeContainer(const int containerIndex);
|
||||
ErrorCode removeAllContainers();
|
||||
|
||||
void setDefaultContainer(const int containerIndex);
|
||||
DockerContainer getDefaultContainer();
|
||||
const QString getDefaultContainerName();
|
||||
|
||||
QStringList getAllInstalledServicesName(const int serverIndex);
|
||||
|
||||
void toggleAmneziaDns(bool enabled);
|
||||
void updateContainersConfig();
|
||||
|
||||
protected:
|
||||
QHash<int, QByteArray> roleNames() const override;
|
||||
@@ -103,16 +68,9 @@ signals:
|
||||
void currentlyProcessedServerIndexChanged(const int index);
|
||||
void defaultServerIndexChanged(const int index);
|
||||
void defaultServerNameChanged();
|
||||
void defaultServerDescriptionChanged();
|
||||
|
||||
void containersUpdated(QJsonArray &containers);
|
||||
void defaultContainerChanged(const int containerIndex);
|
||||
|
||||
private:
|
||||
ServerCredentials serverCredentials(int index) const;
|
||||
void updateContainersModel();
|
||||
|
||||
QString getDefaultServerDescription(const QJsonObject &server);
|
||||
|
||||
QJsonArray m_servers;
|
||||
|
||||
@@ -120,8 +78,6 @@ private:
|
||||
|
||||
int m_defaultServerIndex;
|
||||
int m_currentlyProcessedServerIndex;
|
||||
|
||||
bool m_isAmneziaDnsEnabled = m_settings->useAmneziaDns();
|
||||
};
|
||||
|
||||
#endif // SERVERSMODEL_H
|
||||
|
||||
@@ -138,10 +138,6 @@ Button {
|
||||
}
|
||||
|
||||
onClicked: {
|
||||
if (!ApiController.updateServerConfigFromApi()) {
|
||||
return
|
||||
}
|
||||
|
||||
if (!ContainersModel.isAnyContainerInstalled()) {
|
||||
PageController.setTriggeredBtConnectButton(true)
|
||||
|
||||
|
||||
@@ -60,8 +60,9 @@ ListView {
|
||||
}
|
||||
|
||||
if (checked) {
|
||||
ServersModel.setDefaultContainer(proxyContainersModel.mapToSource(index))
|
||||
isDefault = true
|
||||
|
||||
menuContent.currentIndex = index
|
||||
containersDropDown.menuVisible = false
|
||||
} else {
|
||||
if (!isSupported && isInstalled) {
|
||||
|
||||
@@ -112,30 +112,6 @@ DrawerType {
|
||||
}
|
||||
}
|
||||
|
||||
BasicButtonType {
|
||||
Layout.fillWidth: true
|
||||
Layout.topMargin: 8
|
||||
|
||||
visible: nativeConfigString.text !== ""
|
||||
|
||||
defaultColor: "transparent"
|
||||
hoveredColor: Qt.rgba(1, 1, 1, 0.08)
|
||||
pressedColor: Qt.rgba(1, 1, 1, 0.12)
|
||||
disabledColor: "#878B91"
|
||||
textColor: "#D7D8DB"
|
||||
borderWidth: 1
|
||||
|
||||
text: qsTr("Copy config string")
|
||||
imageSource: "qrc:/images/controls/copy.svg"
|
||||
|
||||
onClicked: {
|
||||
nativeConfigString.selectAll()
|
||||
nativeConfigString.copy()
|
||||
nativeConfigString.select(0, 0)
|
||||
PageController.showNotificationMessage(qsTr("Copied"))
|
||||
}
|
||||
}
|
||||
|
||||
BasicButtonType {
|
||||
Layout.fillWidth: true
|
||||
Layout.topMargin: 24
|
||||
@@ -194,12 +170,6 @@ DrawerType {
|
||||
}
|
||||
|
||||
TextField {
|
||||
id: nativeConfigString
|
||||
visible: false
|
||||
text: ExportController.nativeConfigString
|
||||
}
|
||||
|
||||
TextArea {
|
||||
id: configText
|
||||
|
||||
Layout.fillWidth: true
|
||||
@@ -243,6 +213,7 @@ DrawerType {
|
||||
|
||||
Image {
|
||||
anchors.fill: parent
|
||||
anchors.margins: 2
|
||||
smooth: false
|
||||
|
||||
source: ExportController.qrCodesCount ? ExportController.qrCodes[0] : ""
|
||||
|
||||
@@ -87,7 +87,6 @@ Switch {
|
||||
id: content
|
||||
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
anchors.left: parent.left
|
||||
|
||||
ListItemTitleType {
|
||||
Layout.fillWidth: true
|
||||
|
||||
@@ -22,6 +22,10 @@ PageType {
|
||||
|
||||
property string borderColor: "#2C2D30"
|
||||
|
||||
property string defaultServerName: ServersModel.defaultServerName
|
||||
property string defaultServerHostName: ServersModel.defaultServerHostName
|
||||
property string defaultContainerName: ContainersModel.defaultContainerName
|
||||
|
||||
Connections {
|
||||
target: PageController
|
||||
|
||||
@@ -36,6 +40,41 @@ PageType {
|
||||
}
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: ServersModel
|
||||
|
||||
function onDefaultServerIndexChanged() {
|
||||
updateDescriptions()
|
||||
}
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: ContainersModel
|
||||
|
||||
function onDefaultContainerChanged() {
|
||||
updateDescriptions()
|
||||
}
|
||||
}
|
||||
|
||||
function updateDescriptions() {
|
||||
var description = ""
|
||||
if (ServersModel.isDefaultServerHasWriteAccess()) {
|
||||
if (SettingsController.isAmneziaDnsEnabled()
|
||||
&& ContainersModel.isAmneziaDnsContainerInstalled(ServersModel.getDefaultServerIndex())) {
|
||||
description += "Amnezia DNS | "
|
||||
}
|
||||
} else {
|
||||
if (ServersModel.isDefaultServerConfigContainsAmneziaDns()) {
|
||||
description += "Amnezia DNS | "
|
||||
}
|
||||
}
|
||||
|
||||
collapsedServerMenuDescription.text = description + root.defaultContainerName + " | " + root.defaultServerHostName
|
||||
expandedServersMenuDescription.text = description + root.defaultServerHostName
|
||||
}
|
||||
|
||||
Component.onCompleted: updateDescriptions()
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
enabled: buttonContent.state === "expanded"
|
||||
@@ -228,7 +267,7 @@ PageType {
|
||||
maximumLineCount: 2
|
||||
elide: Qt.ElideRight
|
||||
|
||||
text: ServersModel.defaultServerName
|
||||
text: root.defaultServerName
|
||||
horizontalAlignment: Qt.AlignHCenter
|
||||
|
||||
Behavior on opacity {
|
||||
@@ -265,7 +304,6 @@ PageType {
|
||||
Layout.bottomMargin: 44
|
||||
Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter
|
||||
visible: buttonContent.collapsedVisibility
|
||||
text: ServersModel.defaultServerDescriptionCollapsed
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
@@ -281,7 +319,7 @@ PageType {
|
||||
Layout.leftMargin: 16
|
||||
Layout.rightMargin: 16
|
||||
|
||||
text: ServersModel.defaultServerName
|
||||
text: root.defaultServerName
|
||||
horizontalAlignment: Qt.AlignHCenter
|
||||
maximumLineCount: 2
|
||||
elide: Qt.ElideRight
|
||||
@@ -293,7 +331,6 @@ PageType {
|
||||
Layout.fillWidth: true
|
||||
horizontalAlignment: Qt.AlignHCenter
|
||||
verticalAlignment: Qt.AlignVCenter
|
||||
text: ServersModel.defaultServerDescriptionExpanded
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
@@ -312,7 +349,7 @@ PageType {
|
||||
rootButtonTextTopMargin: 8
|
||||
rootButtonTextBottomMargin: 8
|
||||
|
||||
text: ServersModel.defaultContainerName
|
||||
text: root.defaultContainerName
|
||||
textColor: "#0E0E11"
|
||||
headerText: qsTr("VPN protocol")
|
||||
headerBackButtonImage: "qrc:/images/controls/arrow-left.svg"
|
||||
@@ -431,7 +468,7 @@ PageType {
|
||||
var description = ""
|
||||
if (hasWriteAccess) {
|
||||
if (SettingsController.isAmneziaDnsEnabled()
|
||||
&& ServersModel.isAmneziaDnsContainerInstalled(index)) {
|
||||
&& ContainersModel.isAmneziaDnsContainerInstalled(index)) {
|
||||
description += "Amnezia DNS | "
|
||||
}
|
||||
} else {
|
||||
|
||||
@@ -312,8 +312,9 @@ PageType {
|
||||
|
||||
onClicked: {
|
||||
forceActiveFocus()
|
||||
PageController.goToPage(PageEnum.PageSetupWizardInstalling);
|
||||
PageController.showBusyIndicator(true)
|
||||
InstallController.updateContainer(AwgConfigModel.getConfig())
|
||||
PageController.showBusyIndicator(false)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,8 +4,6 @@ import QtQuick.Layouts
|
||||
|
||||
import SortFilterProxyModel 0.2
|
||||
|
||||
import PageEnum 1.0
|
||||
|
||||
import "./"
|
||||
import "../Controls2"
|
||||
import "../Controls2/TextTypes"
|
||||
@@ -162,8 +160,9 @@ PageType {
|
||||
|
||||
onClicked: {
|
||||
forceActiveFocus()
|
||||
PageController.goToPage(PageEnum.PageSetupWizardInstalling);
|
||||
PageController.showBusyIndicator(true)
|
||||
InstallController.updateContainer(CloakConfigModel.getConfig())
|
||||
PageController.showBusyIndicator(false)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -390,8 +390,9 @@ PageType {
|
||||
|
||||
onClicked: {
|
||||
forceActiveFocus()
|
||||
PageController.goToPage(PageEnum.PageSetupWizardInstalling);
|
||||
PageController.showBusyIndicator(true)
|
||||
InstallController.updateContainer(OpenVpnConfigModel.getConfig())
|
||||
PageController.showBusyIndicator(false)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,8 +4,6 @@ import QtQuick.Layouts
|
||||
|
||||
import SortFilterProxyModel 0.2
|
||||
|
||||
import PageEnum 1.0
|
||||
|
||||
import "./"
|
||||
import "../Controls2"
|
||||
import "../Controls2/TextTypes"
|
||||
@@ -140,8 +138,9 @@ PageType {
|
||||
|
||||
onClicked: {
|
||||
forceActiveFocus()
|
||||
PageController.goToPage(PageEnum.PageSetupWizardInstalling);
|
||||
PageController.showBusyIndicator(true)
|
||||
InstallController.updateContainer(ShadowSocksConfigModel.getConfig())
|
||||
PageController.showBusyIndicator(false)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -66,8 +66,8 @@ PageType {
|
||||
|
||||
text: qsTr("Website address")
|
||||
descriptionText: {
|
||||
var config = ContainersModel.getCurrentlyProcessedContainerConfig()
|
||||
var containerIndex = ContainersModel.getCurrentlyProcessedContainerIndex()
|
||||
var config = ContainersModel.getContainerConfig(containerIndex)
|
||||
return config[ContainerProps.containerTypeToString(containerIndex)]["site"]
|
||||
}
|
||||
|
||||
|
||||
@@ -77,7 +77,7 @@ PageType {
|
||||
text: name
|
||||
descriptionText: {
|
||||
var servicesNameString = ""
|
||||
var servicesName = ServersModel.getAllInstalledServicesName(index)
|
||||
var servicesName = ContainersModel.getAllInstalledServicesName(index)
|
||||
for (var i = 0; i < servicesName.length; i++) {
|
||||
servicesNameString += servicesName[i] + " · "
|
||||
}
|
||||
|
||||
@@ -54,7 +54,7 @@ PageType {
|
||||
regularExpression: InstallController.ipAddressPortRegExp()
|
||||
}
|
||||
|
||||
onFocusChanged: {
|
||||
onTextFieldTextChanged: {
|
||||
textField.text = textField.text.replace(/^\s+|\s+$/g, '');
|
||||
}
|
||||
}
|
||||
@@ -81,10 +81,6 @@ PageType {
|
||||
clickedFunc: function() {
|
||||
hidePassword = !hidePassword
|
||||
}
|
||||
|
||||
onFocusChanged: {
|
||||
textField.text = textField.text.replace(/^\s+|\s+$/g, '');
|
||||
}
|
||||
}
|
||||
|
||||
BasicButtonType {
|
||||
@@ -94,7 +90,6 @@ PageType {
|
||||
text: qsTr("Continue")
|
||||
|
||||
onClicked: function() {
|
||||
forceActiveFocus()
|
||||
if (!isCredentialsFilled()) {
|
||||
return
|
||||
}
|
||||
@@ -117,7 +112,8 @@ PageType {
|
||||
Layout.fillWidth: true
|
||||
Layout.topMargin: 12
|
||||
|
||||
text: qsTr("All data you enter will remain strictly confidential and will not be shared or disclosed to the Amnezia or any third parties")
|
||||
text: qsTr("All data you enter will remain strictly confidential
|
||||
and will not be shared or disclosed to the Amnezia or any third parties")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,14 +19,13 @@ PageType {
|
||||
|
||||
property bool isTimerRunning: true
|
||||
property string progressBarText: qsTr("Usually it takes no more than 5 minutes")
|
||||
property bool isCancelButtonVisible: false
|
||||
|
||||
Connections {
|
||||
target: InstallController
|
||||
|
||||
function onInstallContainerFinished(finishedMessage, isServiceInstall) {
|
||||
if (!ConnectionController.isConnected && !isServiceInstall) {
|
||||
ServersModel.setDefaultContainer(ContainersModel.getCurrentlyProcessedContainerIndex())
|
||||
ContainersModel.setDefaultContainer(ContainersModel.getCurrentlyProcessedContainerIndex())
|
||||
}
|
||||
|
||||
PageController.closePage() // close installing page
|
||||
@@ -62,13 +61,11 @@ PageType {
|
||||
|
||||
function onServerIsBusy(isBusy) {
|
||||
if (isBusy) {
|
||||
root.isCancelButtonVisible = true
|
||||
root.progressBarText = qsTr("Amnezia has detected that your server is currently ") +
|
||||
qsTr("busy installing other software. Amnezia installation ") +
|
||||
qsTr("will pause until the server finishes installing other software")
|
||||
root.isTimerRunning = false
|
||||
} else {
|
||||
root.isCancelButtonVisible = false
|
||||
root.progressBarText = qsTr("Usually it takes no more than 5 minutes")
|
||||
root.isTimerRunning = true
|
||||
}
|
||||
@@ -153,22 +150,6 @@ PageType {
|
||||
|
||||
text: root.progressBarText
|
||||
}
|
||||
|
||||
BasicButtonType {
|
||||
id: cancelIntallationButton
|
||||
|
||||
Layout.fillWidth: true
|
||||
Layout.topMargin: 24
|
||||
|
||||
visible: root.isCancelButtonVisible
|
||||
|
||||
text: qsTr("Cancel installation")
|
||||
|
||||
onClicked: {
|
||||
InstallController.cancelInstallation()
|
||||
PageController.showBusyIndicator(true)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -60,7 +60,6 @@ PageType {
|
||||
target: InstallController
|
||||
|
||||
function onInstallationErrorOccurred(errorMessage) {
|
||||
PageController.showBusyIndicator(false)
|
||||
PageController.showErrorMessage(errorMessage)
|
||||
|
||||
var currentPageName = stackView.currentItem.objectName
|
||||
|
||||
@@ -24,7 +24,7 @@ PageType {
|
||||
}
|
||||
|
||||
function onImportFinished() {
|
||||
if (!ConnectionController.isConnected) {
|
||||
if (ConnectionController.isConnected) {
|
||||
ServersModel.setDefaultServerIndex(ServersModel.getServersCount() - 1);
|
||||
}
|
||||
|
||||
|
||||
@@ -18,29 +18,15 @@ PageType {
|
||||
|
||||
enum ConfigType {
|
||||
AmneziaConnection,
|
||||
AmneziaFullAccess,
|
||||
OpenVpn,
|
||||
WireGuard,
|
||||
ShadowSocks,
|
||||
Cloak
|
||||
}
|
||||
|
||||
signal revokeConfig(int index)
|
||||
onRevokeConfig: function(index) {
|
||||
PageController.showBusyIndicator(true)
|
||||
ExportController.revokeConfig(index,
|
||||
ContainersModel.getCurrentlyProcessedContainerIndex(),
|
||||
ServersModel.getCurrentlyProcessedServerCredentials())
|
||||
PageController.showBusyIndicator(false)
|
||||
PageController.showNotificationMessage(qsTr("Config revoked"))
|
||||
WireGuard
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: ExportController
|
||||
|
||||
function onGenerateConfig(type) {
|
||||
shareConnectionDrawer.headerText = qsTr("Connection to ") + serverSelector.text
|
||||
shareConnectionDrawer.configContentHeaderText = qsTr("File with connection settings to ") + serverSelector.text
|
||||
|
||||
shareConnectionDrawer.needCloseButton = false
|
||||
|
||||
shareConnectionDrawer.open()
|
||||
@@ -48,34 +34,28 @@ PageType {
|
||||
PageController.showBusyIndicator(true)
|
||||
|
||||
switch (type) {
|
||||
case PageShare.ConfigType.AmneziaConnection: ExportController.generateConnectionConfig(clientNameTextField.textFieldText); break;
|
||||
case PageShare.ConfigType.AmneziaConnection: ExportController.generateConnectionConfig(); break;
|
||||
case PageShare.ConfigType.AmneziaFullAccess: {
|
||||
if (Qt.platform.os === "android") {
|
||||
ExportController.generateFullAccessConfigAndroid();
|
||||
} else {
|
||||
ExportController.generateFullAccessConfig();
|
||||
}
|
||||
break;
|
||||
}
|
||||
case PageShare.ConfigType.OpenVpn: {
|
||||
ExportController.generateOpenVpnConfig(clientNameTextField.textFieldText)
|
||||
ExportController.generateOpenVpnConfig();
|
||||
shareConnectionDrawer.configCaption = qsTr("Save OpenVPN config")
|
||||
shareConnectionDrawer.configExtension = ".ovpn"
|
||||
shareConnectionDrawer.configFileName = "amnezia_for_openvpn"
|
||||
break
|
||||
break;
|
||||
}
|
||||
case PageShare.ConfigType.WireGuard: {
|
||||
ExportController.generateWireGuardConfig(clientNameTextField.textFieldText)
|
||||
ExportController.generateWireGuardConfig();
|
||||
shareConnectionDrawer.configCaption = qsTr("Save WireGuard config")
|
||||
shareConnectionDrawer.configExtension = ".conf"
|
||||
shareConnectionDrawer.configFileName = "amnezia_for_wireguard"
|
||||
break
|
||||
}
|
||||
case PageShare.ConfigType.ShadowSocks: {
|
||||
ExportController.generateShadowSocksConfig()
|
||||
shareConnectionDrawer.configCaption = qsTr("Save ShadowSocks config")
|
||||
shareConnectionDrawer.configExtension = ".json"
|
||||
shareConnectionDrawer.configFileName = "amnezia_for_shadowsocks"
|
||||
break
|
||||
}
|
||||
case PageShare.ConfigType.Cloak: {
|
||||
ExportController.generateCloakConfig()
|
||||
shareConnectionDrawer.configCaption = qsTr("Save Cloak config")
|
||||
shareConnectionDrawer.configExtension = ".json"
|
||||
shareConnectionDrawer.configFileName = "amnezia_for_cloak"
|
||||
break
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -93,7 +73,8 @@ PageType {
|
||||
}
|
||||
}
|
||||
|
||||
property bool isSearchBarVisible: false
|
||||
property string fullConfigServerSelectorText
|
||||
property string connectionServerSelectorText
|
||||
property bool showContent: false
|
||||
property bool shareButtonEnabled: true
|
||||
property list<QtObject> connectionTypesModel: [
|
||||
@@ -115,16 +96,6 @@ PageType {
|
||||
property string name: qsTr("WireGuard native format")
|
||||
property var type: PageShare.ConfigType.WireGuard
|
||||
}
|
||||
QtObject {
|
||||
id: shadowSocksConnectionFormat
|
||||
property string name: qsTr("ShadowSocks native format")
|
||||
property var type: PageShare.ConfigType.ShadowSocks
|
||||
}
|
||||
QtObject {
|
||||
id: cloakConnectionFormat
|
||||
property string name: qsTr("Cloak native format")
|
||||
property var type: PageShare.ConfigType.Cloak
|
||||
}
|
||||
|
||||
FlickableType {
|
||||
anchors.top: parent.top
|
||||
@@ -148,51 +119,6 @@ PageType {
|
||||
Layout.topMargin: 24
|
||||
|
||||
headerText: qsTr("Share VPN Access")
|
||||
|
||||
actionButtonImage: "qrc:/images/controls/more-vertical.svg"
|
||||
actionButtonFunction: function() {
|
||||
shareFullAccessDrawer.open()
|
||||
}
|
||||
|
||||
DrawerType {
|
||||
id: shareFullAccessDrawer
|
||||
|
||||
width: root.width
|
||||
height: root.height * 0.45
|
||||
|
||||
|
||||
ColumnLayout {
|
||||
anchors.top: parent.top
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
anchors.topMargin: 16
|
||||
|
||||
spacing: 0
|
||||
|
||||
Header2Type {
|
||||
Layout.fillWidth: true
|
||||
Layout.bottomMargin: 16
|
||||
Layout.leftMargin: 16
|
||||
Layout.rightMargin: 16
|
||||
|
||||
headerText: qsTr("Share full access to the server and VPN")
|
||||
descriptionText: qsTr("Use for your own devices, or share with those you trust to manage the server.")
|
||||
}
|
||||
|
||||
|
||||
LabelWithButtonType {
|
||||
Layout.fillWidth: true
|
||||
|
||||
text: qsTr("Share")
|
||||
rightImageSource: "qrc:/images/controls/chevron-right.svg"
|
||||
|
||||
clickedFunction: function() {
|
||||
PageController.goToPage(PageEnum.PageShareFullAccess)
|
||||
shareFullAccessDrawer.close()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
@@ -221,21 +147,20 @@ PageType {
|
||||
|
||||
onClicked: {
|
||||
accessTypeSelector.currentIndex = 0
|
||||
serverSelector.text = root.connectionServerSelectorText
|
||||
}
|
||||
}
|
||||
|
||||
HorizontalRadioButton {
|
||||
checked: accessTypeSelector.currentIndex === 1
|
||||
checked: root.currentIndex === 1
|
||||
|
||||
implicitWidth: (root.width - 32) / 2
|
||||
text: qsTr("Users")
|
||||
text: qsTr("Full access")
|
||||
|
||||
onClicked: {
|
||||
accessTypeSelector.currentIndex = 1
|
||||
PageController.showBusyIndicator(true)
|
||||
ExportController.updateClientManagementModel(ContainersModel.getCurrentlyProcessedContainerIndex(),
|
||||
ServersModel.getCurrentlyProcessedServerCredentials())
|
||||
PageController.showBusyIndicator(false)
|
||||
serverSelector.text = root.fullConfigServerSelectorText
|
||||
root.shareButtonEnabled = true
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -246,30 +171,16 @@ PageType {
|
||||
Layout.topMargin: 24
|
||||
Layout.bottomMargin: 24
|
||||
|
||||
visible: accessTypeSelector.currentIndex === 0
|
||||
|
||||
text: qsTr("Share VPN access without the ability to manage the server")
|
||||
text: accessTypeSelector.currentIndex === 0 ? qsTr("Share VPN access without the ability to manage the server") :
|
||||
qsTr("Share access to server management. The user with whom you share full access to the server will be able to add and remove any protocols and services to the server, as well as change settings.")
|
||||
color: "#878B91"
|
||||
}
|
||||
|
||||
TextFieldWithHeaderType {
|
||||
id: clientNameTextField
|
||||
Layout.fillWidth: true
|
||||
Layout.topMargin: 16
|
||||
|
||||
visible: accessTypeSelector.currentIndex === 0
|
||||
|
||||
headerText: qsTr("User name")
|
||||
textFieldText: "New client"
|
||||
|
||||
checkEmptyText: true
|
||||
}
|
||||
|
||||
DropDownType {
|
||||
id: serverSelector
|
||||
|
||||
signal severSelectorIndexChanged
|
||||
property int currentIndex: -1
|
||||
property int currentIndex: 0
|
||||
|
||||
Layout.fillWidth: true
|
||||
Layout.topMargin: 16
|
||||
@@ -296,6 +207,8 @@ PageType {
|
||||
]
|
||||
}
|
||||
|
||||
currentIndex: 0
|
||||
|
||||
clickedFunction: function() {
|
||||
handler()
|
||||
|
||||
@@ -304,17 +217,22 @@ PageType {
|
||||
serverSelector.severSelectorIndexChanged()
|
||||
}
|
||||
|
||||
if (accessTypeSelector.currentIndex !== 0) {
|
||||
shareConnectionDrawer.headerText = qsTr("Accessing ") + serverSelector.text
|
||||
shareConnectionDrawer.configContentHeaderText = qsTr("File with accessing settings to ") + serverSelector.text
|
||||
}
|
||||
serverSelector.menuVisible = false
|
||||
}
|
||||
|
||||
Component.onCompleted: {
|
||||
serverSelectorListView.currentIndex = ServersModel.isDefaultServerHasWriteAccess() ?
|
||||
proxyServersModel.mapFromSource(ServersModel.defaultIndex) : 0
|
||||
serverSelectorListView.triggerCurrentItem()
|
||||
handler()
|
||||
serverSelector.severSelectorIndexChanged()
|
||||
}
|
||||
|
||||
function handler() {
|
||||
serverSelector.text = selectedText
|
||||
root.fullConfigServerSelectorText = selectedText
|
||||
root.connectionServerSelectorText = selectedText
|
||||
ServersModel.currentlyProcessedIndex = proxyServersModel.mapToSource(currentIndex)
|
||||
}
|
||||
}
|
||||
@@ -323,6 +241,8 @@ PageType {
|
||||
DropDownType {
|
||||
id: protocolSelector
|
||||
|
||||
visible: accessTypeSelector.currentIndex === 0
|
||||
|
||||
Layout.fillWidth: true
|
||||
Layout.topMargin: 16
|
||||
|
||||
@@ -360,11 +280,17 @@ PageType {
|
||||
protocolSelector.menuVisible = false
|
||||
}
|
||||
|
||||
Component.onCompleted: {
|
||||
if (accessTypeSelector.currentIndex === 0) {
|
||||
handler()
|
||||
}
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: serverSelector
|
||||
|
||||
function onSeverSelectorIndexChanged() {
|
||||
protocolSelectorListView.currentIndex = proxyContainersModel.mapFromSource(ServersModel.getDefaultContainer())
|
||||
protocolSelectorListView.currentIndex = 0
|
||||
protocolSelectorListView.triggerCurrentItem()
|
||||
}
|
||||
}
|
||||
@@ -378,17 +304,13 @@ PageType {
|
||||
}
|
||||
|
||||
protocolSelector.text = selectedText
|
||||
root.connectionServerSelectorText = serverSelector.text
|
||||
|
||||
shareConnectionDrawer.headerText = qsTr("Connection to ") + serverSelector.text
|
||||
shareConnectionDrawer.configContentHeaderText = qsTr("File with connection settings to ") + serverSelector.text
|
||||
ContainersModel.setCurrentlyProcessedContainerIndex(proxyContainersModel.mapToSource(currentIndex))
|
||||
|
||||
fillConnectionTypeModel()
|
||||
|
||||
if (accessTypeSelector.currentIndex === 1) {
|
||||
PageController.showBusyIndicator(true)
|
||||
ExportController.updateClientManagementModel(ContainersModel.getCurrentlyProcessedContainerIndex(),
|
||||
ServersModel.getCurrentlyProcessedServerCredentials())
|
||||
PageController.showBusyIndicator(false)
|
||||
}
|
||||
}
|
||||
|
||||
function fillConnectionTypeModel() {
|
||||
@@ -400,13 +322,6 @@ PageType {
|
||||
root.connectionTypesModel.push(openVpnConnectionFormat)
|
||||
} else if (index === ContainerProps.containerFromString("amnezia-wireguard")) {
|
||||
root.connectionTypesModel.push(wireGuardConnectionFormat)
|
||||
} else if (index === ContainerProps.containerFromString("amnezia-shadowsocks")) {
|
||||
root.connectionTypesModel.push(openVpnConnectionFormat)
|
||||
root.connectionTypesModel.push(shadowSocksConnectionFormat)
|
||||
} else if (index === ContainerProps.containerFromString("amnezia-openvpn-cloak")) {
|
||||
root.connectionTypesModel.push(openVpnConnectionFormat)
|
||||
root.connectionTypesModel.push(shadowSocksConnectionFormat)
|
||||
root.connectionTypesModel.push(cloakConnectionFormat)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -463,235 +378,18 @@ PageType {
|
||||
Layout.topMargin: 40
|
||||
|
||||
enabled: shareButtonEnabled
|
||||
visible: accessTypeSelector.currentIndex === 0
|
||||
|
||||
text: qsTr("Share")
|
||||
imageSource: "qrc:/images/controls/share-2.svg"
|
||||
|
||||
onClicked: {
|
||||
ExportController.generateConfig(root.connectionTypesModel[exportTypeSelector.currentIndex].type)
|
||||
}
|
||||
}
|
||||
|
||||
Header2Type {
|
||||
Layout.fillWidth: true
|
||||
Layout.topMargin: 24
|
||||
Layout.bottomMargin: 16
|
||||
|
||||
visible: accessTypeSelector.currentIndex === 1 && !root.isSearchBarVisible
|
||||
|
||||
headerText: qsTr("Users")
|
||||
actionButtonImage: "qrc:/images/controls/search.svg"
|
||||
actionButtonFunction: function() {
|
||||
root.isSearchBarVisible = true
|
||||
}
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
Layout.topMargin: 24
|
||||
Layout.bottomMargin: 16
|
||||
visible: accessTypeSelector.currentIndex === 1 && root.isSearchBarVisible
|
||||
|
||||
TextFieldWithHeaderType {
|
||||
id: searchTextField
|
||||
Layout.fillWidth: true
|
||||
|
||||
textFieldPlaceholderText: qsTr("Search")
|
||||
}
|
||||
|
||||
ImageButtonType {
|
||||
image: "qrc:/images/controls/close.svg"
|
||||
imageColor: "#D7D8DB"
|
||||
|
||||
onClicked: function() {
|
||||
root.isSearchBarVisible = false
|
||||
searchTextField.textFieldText = ""
|
||||
if (accessTypeSelector.currentIndex === 0) {
|
||||
ExportController.generateConfig(root.connectionTypesModel[exportTypeSelector.currentIndex].type)
|
||||
} else {
|
||||
ExportController.generateConfig(PageShare.ConfigType.AmneziaFullAccess)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ListView {
|
||||
id: clientsListView
|
||||
Layout.fillWidth: true
|
||||
Layout.preferredHeight: childrenRect.height
|
||||
|
||||
visible: accessTypeSelector.currentIndex === 1
|
||||
|
||||
model: SortFilterProxyModel {
|
||||
id: proxyClientManagementModel
|
||||
sourceModel: ClientManagementModel
|
||||
filters: RegExpFilter {
|
||||
roleName: "clientName"
|
||||
pattern: ".*" + searchTextField.textFieldText + ".*"
|
||||
caseSensitivity: Qt.CaseInsensitive
|
||||
}
|
||||
}
|
||||
|
||||
clip: true
|
||||
interactive: false
|
||||
|
||||
delegate: Item {
|
||||
implicitWidth: clientsListView.width
|
||||
implicitHeight: delegateContent.implicitHeight
|
||||
|
||||
ColumnLayout {
|
||||
id: delegateContent
|
||||
|
||||
anchors.top: parent.top
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
|
||||
anchors.rightMargin: -16
|
||||
anchors.leftMargin: -16
|
||||
|
||||
LabelWithButtonType {
|
||||
Layout.fillWidth: true
|
||||
|
||||
text: clientName
|
||||
rightImageSource: "qrc:/images/controls/chevron-right.svg"
|
||||
|
||||
clickedFunction: function() {
|
||||
clientInfoDrawer.open()
|
||||
}
|
||||
}
|
||||
|
||||
DividerType {}
|
||||
|
||||
DrawerType {
|
||||
id: clientInfoDrawer
|
||||
|
||||
width: root.width
|
||||
height: root.height * 0.5
|
||||
|
||||
ColumnLayout {
|
||||
anchors.top: parent.top
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
anchors.topMargin: 16
|
||||
anchors.leftMargin: 16
|
||||
anchors.rightMargin: 16
|
||||
|
||||
spacing: 8
|
||||
|
||||
Header2Type {
|
||||
Layout.fillWidth: true
|
||||
Layout.bottomMargin: 24
|
||||
|
||||
headerText: clientName
|
||||
descriptionText: serverSelector.text
|
||||
}
|
||||
|
||||
BasicButtonType {
|
||||
Layout.fillWidth: true
|
||||
Layout.topMargin: 24
|
||||
|
||||
defaultColor: "transparent"
|
||||
hoveredColor: Qt.rgba(1, 1, 1, 0.08)
|
||||
pressedColor: Qt.rgba(1, 1, 1, 0.12)
|
||||
disabledColor: "#878B91"
|
||||
textColor: "#D7D8DB"
|
||||
borderWidth: 1
|
||||
|
||||
text: qsTr("Rename")
|
||||
|
||||
onClicked: function() {
|
||||
clientNameEditDrawer.open()
|
||||
}
|
||||
|
||||
DrawerType {
|
||||
id: clientNameEditDrawer
|
||||
|
||||
width: root.width
|
||||
height: root.height * 0.35
|
||||
|
||||
onVisibleChanged: {
|
||||
if (clientNameEditDrawer.visible) {
|
||||
clientNameEditor.textField.forceActiveFocus()
|
||||
}
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
anchors.top: parent.top
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
anchors.topMargin: 16
|
||||
anchors.leftMargin: 16
|
||||
anchors.rightMargin: 16
|
||||
|
||||
TextFieldWithHeaderType {
|
||||
id: clientNameEditor
|
||||
Layout.fillWidth: true
|
||||
headerText: qsTr("Client name")
|
||||
textFieldText: clientName
|
||||
textField.maximumLength: 30
|
||||
}
|
||||
|
||||
BasicButtonType {
|
||||
Layout.fillWidth: true
|
||||
|
||||
text: qsTr("Save")
|
||||
|
||||
onClicked: {
|
||||
if (clientNameEditor.textFieldText !== clientName) {
|
||||
PageController.showBusyIndicator(true)
|
||||
ExportController.renameClient(index,
|
||||
clientNameEditor.textFieldText,
|
||||
ContainersModel.getCurrentlyProcessedContainerIndex(),
|
||||
ServersModel.getCurrentlyProcessedServerCredentials())
|
||||
PageController.showBusyIndicator(false)
|
||||
clientNameEditDrawer.close()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BasicButtonType {
|
||||
Layout.fillWidth: true
|
||||
|
||||
defaultColor: "transparent"
|
||||
hoveredColor: Qt.rgba(1, 1, 1, 0.08)
|
||||
pressedColor: Qt.rgba(1, 1, 1, 0.12)
|
||||
disabledColor: "#878B91"
|
||||
textColor: "#D7D8DB"
|
||||
borderWidth: 1
|
||||
|
||||
text: qsTr("Revoke")
|
||||
|
||||
onClicked: function() {
|
||||
questionDrawer.headerText = qsTr("Revoke the config for a user - ") + clientName + "?"
|
||||
questionDrawer.descriptionText = qsTr("The user will no longer be able to connect to your server.")
|
||||
questionDrawer.yesButtonText = qsTr("Continue")
|
||||
questionDrawer.noButtonText = qsTr("Cancel")
|
||||
|
||||
questionDrawer.yesButtonFunction = function() {
|
||||
questionDrawer.close()
|
||||
clientInfoDrawer.close()
|
||||
root.revokeConfig(index)
|
||||
}
|
||||
questionDrawer.noButtonFunction = function() {
|
||||
questionDrawer.close()
|
||||
}
|
||||
questionDrawer.open()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
QuestionDrawer {
|
||||
id: questionDrawer
|
||||
}
|
||||
}
|
||||
}
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
onPressed: function(mouse) {
|
||||
forceActiveFocus()
|
||||
mouse.accepted = false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,155 +0,0 @@
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import QtQuick.Layouts
|
||||
import QtQuick.Dialogs
|
||||
|
||||
import SortFilterProxyModel 0.2
|
||||
|
||||
import PageEnum 1.0
|
||||
import ContainerProps 1.0
|
||||
|
||||
import "./"
|
||||
import "../Controls2"
|
||||
import "../Controls2/TextTypes"
|
||||
import "../Components"
|
||||
|
||||
PageType {
|
||||
id: root
|
||||
|
||||
BackButtonType {
|
||||
id: backButton
|
||||
|
||||
anchors.top: parent.top
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
anchors.topMargin: 20
|
||||
}
|
||||
|
||||
FlickableType {
|
||||
anchors.top: backButton.bottom
|
||||
anchors.bottom: parent.bottom
|
||||
contentHeight: content.height
|
||||
|
||||
ColumnLayout {
|
||||
id: content
|
||||
|
||||
anchors.top: parent.top
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
|
||||
anchors.rightMargin: 16
|
||||
anchors.leftMargin: 16
|
||||
|
||||
spacing: 0
|
||||
|
||||
HeaderType {
|
||||
Layout.fillWidth: true
|
||||
Layout.topMargin: 24
|
||||
|
||||
headerText: qsTr("Full access to the server and VPN")
|
||||
}
|
||||
|
||||
ParagraphTextType {
|
||||
Layout.fillWidth: true
|
||||
Layout.topMargin: 24
|
||||
Layout.bottomMargin: 24
|
||||
|
||||
text: qsTr("We recommend that you use full access to the server only for your own additional devices.\n") +
|
||||
qsTr("If you share full access with other people, they can remove and add protocols and services to the server, which will cause the VPN to work incorrectly for all users. ")
|
||||
color: "#878B91"
|
||||
}
|
||||
|
||||
DropDownType {
|
||||
id: serverSelector
|
||||
|
||||
signal severSelectorIndexChanged
|
||||
property int currentIndex: 0
|
||||
|
||||
Layout.fillWidth: true
|
||||
Layout.topMargin: 16
|
||||
|
||||
drawerHeight: 0.4375
|
||||
|
||||
descriptionText: qsTr("Server")
|
||||
headerText: qsTr("Server")
|
||||
|
||||
listView: ListViewWithRadioButtonType {
|
||||
id: serverSelectorListView
|
||||
|
||||
rootWidth: root.width
|
||||
imageSource: "qrc:/images/controls/check.svg"
|
||||
|
||||
model: SortFilterProxyModel {
|
||||
id: proxyServersModel
|
||||
sourceModel: ServersModel
|
||||
filters: [
|
||||
ValueFilter {
|
||||
roleName: "hasWriteAccess"
|
||||
value: true
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
currentIndex: 0
|
||||
|
||||
clickedFunction: function() {
|
||||
handler()
|
||||
|
||||
if (serverSelector.currentIndex !== serverSelectorListView.currentIndex) {
|
||||
serverSelector.currentIndex = serverSelectorListView.currentIndex
|
||||
}
|
||||
|
||||
shareConnectionDrawer.headerText = qsTr("Accessing ") + serverSelector.text
|
||||
shareConnectionDrawer.configContentHeaderText = qsTr("File with accessing settings to ") + serverSelector.text
|
||||
serverSelector.menuVisible = false
|
||||
}
|
||||
|
||||
Component.onCompleted: {
|
||||
handler()
|
||||
}
|
||||
|
||||
function handler() {
|
||||
serverSelector.text = selectedText
|
||||
ServersModel.currentlyProcessedIndex = proxyServersModel.mapToSource(currentIndex)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BasicButtonType {
|
||||
Layout.fillWidth: true
|
||||
Layout.topMargin: 40
|
||||
|
||||
text: qsTr("Share")
|
||||
imageSource: "qrc:/images/controls/share-2.svg"
|
||||
|
||||
onClicked: function() {
|
||||
shareConnectionDrawer.headerText = qsTr("Connection to ") + serverSelector.text
|
||||
shareConnectionDrawer.configContentHeaderText = qsTr("File with connection settings to ") + serverSelector.text
|
||||
|
||||
shareConnectionDrawer.needCloseButton = false
|
||||
|
||||
shareConnectionDrawer.open()
|
||||
shareConnectionDrawer.contentVisible = false
|
||||
PageController.showBusyIndicator(true)
|
||||
|
||||
if (Qt.platform.os === "android") {
|
||||
ExportController.generateFullAccessConfigAndroid();
|
||||
} else {
|
||||
ExportController.generateFullAccessConfig();
|
||||
}
|
||||
|
||||
PageController.showBusyIndicator(false)
|
||||
|
||||
shareConnectionDrawer.needCloseButton = true
|
||||
PageController.showTopCloseButton(true)
|
||||
|
||||
shareConnectionDrawer.contentVisible = true
|
||||
}
|
||||
}
|
||||
|
||||
ShareConnectionDrawer {
|
||||
id: shareConnectionDrawer
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -82,7 +82,6 @@ PageType {
|
||||
target: InstallController
|
||||
|
||||
function onInstallationErrorOccurred(errorMessage) {
|
||||
PageController.showBusyIndicator(false)
|
||||
PageController.showErrorMessage(errorMessage)
|
||||
|
||||
var needCloseCurrentPage = false
|
||||
@@ -100,7 +99,6 @@ PageType {
|
||||
|
||||
function onUpdateContainerFinished(message) {
|
||||
PageController.showNotificationMessage(message)
|
||||
PageController.closePage()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -109,7 +107,6 @@ PageType {
|
||||
|
||||
function onReconnectWithUpdatedContainer(message) {
|
||||
PageController.showNotificationMessage(message)
|
||||
PageController.closePage()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
#include <configurators/shadowsocks_configurator.h>
|
||||
#include <configurators/vpn_configurator.h>
|
||||
#include <configurators/wireguard_configurator.h>
|
||||
#include "core/controllers/serverController.h"
|
||||
#include <core/servercontroller.h>
|
||||
|
||||
#ifdef AMNEZIA_DESKTOP
|
||||
#include "core/ipcclient.h"
|
||||
@@ -227,8 +227,7 @@ QString VpnConnection::createVpnConfigurationForProto(int serverIndex, const Ser
|
||||
configData = lastVpnConfig.value(proto);
|
||||
configData = m_configurator->processConfigWithLocalSettings(serverIndex, container, proto, configData);
|
||||
} else {
|
||||
QString clientId;
|
||||
configData = m_configurator->genVpnProtocolConfig(credentials, container, containerConfig, proto, clientId, errorCode);
|
||||
configData = m_configurator->genVpnProtocolConfig(credentials, container, containerConfig, proto, errorCode);
|
||||
|
||||
if (errorCode && *errorCode) {
|
||||
return "";
|
||||
@@ -245,8 +244,6 @@ QString VpnConnection::createVpnConfigurationForProto(int serverIndex, const Ser
|
||||
protoObject.insert(config_key::last_config, configDataBeforeLocalProcessing);
|
||||
m_settings->setProtocolConfig(serverIndex, container, proto, protoObject);
|
||||
}
|
||||
|
||||
emit m_configurator->newVpnConfigCreated(clientId, "unnamed client", container, credentials);
|
||||
}
|
||||
|
||||
return configData;
|
||||
@@ -261,7 +258,9 @@ QJsonObject VpnConnection::createVpnConfiguration(int serverIndex, const ServerC
|
||||
for (ProtocolEnumNS::Proto proto : ContainerProps::protocolsForContainer(container)) {
|
||||
QJsonObject vpnConfigData =
|
||||
QJsonDocument::fromJson(createVpnConfigurationForProto(serverIndex, credentials, container,
|
||||
containerConfig, proto, errorCode).toUtf8()).object();
|
||||
containerConfig, proto, errorCode)
|
||||
.toUtf8())
|
||||
.object();
|
||||
|
||||
if (errorCode && *errorCode) {
|
||||
return {};
|
||||
@@ -324,7 +323,7 @@ void VpnConnection::connectToVpn(int serverIndex, const ServerCredentials &crede
|
||||
ErrorCode e = ErrorCode::NoError;
|
||||
|
||||
m_vpnConfiguration = createVpnConfiguration(serverIndex, credentials, container, containerConfig, &e);
|
||||
|
||||
emit newVpnConfigurationCreated();
|
||||
if (e) {
|
||||
emit connectionStateChanged(Vpn::ConnectionState::Error);
|
||||
return;
|
||||
|
||||
@@ -79,6 +79,8 @@ signals:
|
||||
|
||||
void serviceIsNotReady();
|
||||
|
||||
void newVpnConfigurationCreated();
|
||||
|
||||
protected slots:
|
||||
void onBytesChanged(quint64 receivedBytes, quint64 sentBytes);
|
||||
void onConnectionStateChanged(Vpn::ConnectionState state);
|
||||
|
||||
@@ -76,7 +76,9 @@ function raiseInstallerWindow()
|
||||
function appProcessIsRunning()
|
||||
{
|
||||
if (runningOnWindows()) {
|
||||
var result = installer.execute("tasklist");
|
||||
var cmdArgs = ["/FI", "WINDOWTITLE eq " + appName()];
|
||||
var result = installer.execute("tasklist", cmdArgs);
|
||||
|
||||
if ( Number(result[1]) === 0 ) {
|
||||
if (result[0].indexOf(appExecutableFileName()) !== -1) {
|
||||
return true;
|
||||
|
||||
Reference in New Issue
Block a user