Reworked the interaction between models. Now only serversModel directly interacts with server config

This commit is contained in:
vladimir.kuznetsov 2023-12-08 13:50:03 +07:00
parent f3f98a50ed
commit b4c89ad58f
19 changed files with 412 additions and 290 deletions

View file

@ -277,19 +277,16 @@ QQmlApplicationEngine *AmneziaApplication::qmlEngine() const
void AmneziaApplication::initModels()
{
m_containersModel.reset(new ContainersModel(m_settings, this));
m_containersModel.reset(new ContainersModel(this));
m_engine->rootContext()->setContextProperty("ContainersModel", m_containersModel.get());
connect(m_configurator.get(), &VpnConfigurator::newVpnConfigCreated, 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::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);
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?
m_languageModel.reset(new LanguageModel(m_settings, this));
m_engine->rootContext()->setContextProperty("LanguageModel", m_languageModel.get());
@ -298,7 +295,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());
@ -327,8 +324,13 @@ void AmneziaApplication::initModels()
m_clientManagementModel.reset(new ClientManagementModel(m_settings, this));
m_engine->rootContext()->setContextProperty("ClientManagementModel", m_clientManagementModel.get());
connect(m_configurator.get(), &VpnConfigurator::newVpnConfigCreated, m_clientManagementModel.get(),
&ClientManagementModel::appendClient);
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()
@ -354,7 +356,8 @@ 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_clientManagementModel,
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));
@ -362,6 +365,8 @@ void AmneziaApplication::initControllers()
if (m_settingsController->isAutoConnectEnabled() && m_serversModel->getDefaultServerIndex() >= 0) {
QTimer::singleShot(1000, this, [this]() { m_connectionController->openConnection(); });
}
connect(m_settingsController.get(), &SettingsController::amneziaDnsToggled , m_serversModel.get(),
&ServersModel::toggleAmneziaDns);
m_sitesController.reset(new SitesController(m_settings, m_vpnConnection, m_sitesModel));
m_engine->rootContext()->setContextProperty("SitesController", m_sitesController.get());
@ -372,6 +377,6 @@ void AmneziaApplication::initControllers()
m_cloudController.reset(new ApiController(m_serversModel, m_containersModel));
m_engine->rootContext()->setContextProperty("ApiController", m_cloudController.get());
connect(m_cloudController.get(), &ApiController::serverConfigUpdated, this,
[this]() { m_containersModel->setCurrentlyProcessedServerIndex(m_serversModel->getDefaultServerIndex()); });
// connect(m_cloudController.get(), &ApiController::serverConfigUpdated, this,
// [this]() { m_containersModel->setCurrentlyProcessedServerIndex(m_serversModel->getDefaultServerIndex()); });
}

View file

@ -58,7 +58,7 @@ QVector<amnezia::Proto> ContainerProps::protocolsForContainer(amnezia::DockerCon
case DockerContainer::Ipsec: return { Proto::Ikev2 /*, Protocol::L2tp */ };
case DockerContainer::Dns: return {};
case DockerContainer::Dns: return { Proto::Dns };
case DockerContainer::Sftp: return { Proto::Sftp };

View file

@ -21,6 +21,7 @@ namespace amnezia
constexpr char dns2[] = "dns2";
constexpr char description[] = "description";
constexpr char name[] = "name";
constexpr char cert[] = "cert";
constexpr char config[] = "config";

View file

@ -26,13 +26,10 @@ ConnectionController::ConnectionController(const QSharedPointer<ServersModel> &s
void ConnectionController::openConnection()
{
int serverIndex = m_serversModel->getDefaultServerIndex();
ServerCredentials credentials =
qvariant_cast<ServerCredentials>(m_serversModel->data(serverIndex, ServersModel::Roles::CredentialsRole));
ServerCredentials credentials = m_serversModel->getServerCredentials(serverIndex);
DockerContainer container = m_containersModel->getDefaultContainer();
QModelIndex containerModelIndex = m_containersModel->index(container);
const QJsonObject &containerConfig =
qvariant_cast<QJsonObject>(m_containersModel->data(containerModelIndex, ContainersModel::Roles::ConfigRole));
const QJsonObject &containerConfig = m_containersModel->getContainerConfig(container);
if (container == DockerContainer::None) {
emit connectionErrorOccurred(tr("VPN Protocols is not installed.\n Please install VPN container at first"));

View file

@ -84,12 +84,10 @@ void ExportController::generateConnectionConfig(const QString &clientName)
clearPreviousConfig();
int serverIndex = m_serversModel->getCurrentlyProcessedServerIndex();
ServerCredentials credentials = m_serversModel->getCurrentlyProcessedServerCredentials();
ServerCredentials credentials = m_serversModel->getServerCredentials(serverIndex);
DockerContainer container = static_cast<DockerContainer>(m_containersModel->getCurrentlyProcessedContainerIndex());
QModelIndex containerModelIndex = m_containersModel->index(container);
QJsonObject containerConfig =
qvariant_cast<QJsonObject>(m_containersModel->data(containerModelIndex, ContainersModel::Roles::ConfigRole));
QJsonObject containerConfig = m_containersModel->getContainerConfig(container);
containerConfig.insert(config_key::container, ContainerProps::containerToString(container));
ErrorCode errorCode = ErrorCode::NoError;
@ -142,12 +140,10 @@ void ExportController::generateOpenVpnConfig(const QString &clientName)
clearPreviousConfig();
int serverIndex = m_serversModel->getCurrentlyProcessedServerIndex();
ServerCredentials credentials = m_serversModel->getCurrentlyProcessedServerCredentials();
ServerCredentials credentials = m_serversModel->getServerCredentials(serverIndex);
DockerContainer container = static_cast<DockerContainer>(m_containersModel->getCurrentlyProcessedContainerIndex());
QModelIndex containerModelIndex = m_containersModel->index(container);
QJsonObject containerConfig =
qvariant_cast<QJsonObject>(m_containersModel->data(containerModelIndex, ContainersModel::Roles::ConfigRole));
QJsonObject containerConfig = m_containersModel->getContainerConfig(container);
containerConfig.insert(config_key::container, ContainerProps::containerToString(container));
ErrorCode errorCode = ErrorCode::NoError;
@ -182,12 +178,10 @@ void ExportController::generateWireGuardConfig(const QString &clientName)
clearPreviousConfig();
int serverIndex = m_serversModel->getCurrentlyProcessedServerIndex();
ServerCredentials credentials = m_serversModel->getCurrentlyProcessedServerCredentials();
ServerCredentials credentials = m_serversModel->getServerCredentials(serverIndex);
DockerContainer container = static_cast<DockerContainer>(m_containersModel->getCurrentlyProcessedContainerIndex());
QModelIndex containerModelIndex = m_containersModel->index(container);
QJsonObject containerConfig =
qvariant_cast<QJsonObject>(m_containersModel->data(containerModelIndex, ContainersModel::Roles::ConfigRole));
QJsonObject containerConfig = m_containersModel->getContainerConfig(container);
containerConfig.insert(config_key::container, ContainerProps::containerToString(container));
QString clientId;
@ -223,13 +217,10 @@ void ExportController::generateShadowSocksConfig()
clearPreviousConfig();
int serverIndex = m_serversModel->getCurrentlyProcessedServerIndex();
ServerCredentials credentials =
qvariant_cast<ServerCredentials>(m_serversModel->data(serverIndex, ServersModel::Roles::CredentialsRole));
ServerCredentials credentials = m_serversModel->getServerCredentials(serverIndex);
DockerContainer container = static_cast<DockerContainer>(m_containersModel->getCurrentlyProcessedContainerIndex());
QModelIndex containerModelIndex = m_containersModel->index(container);
QJsonObject containerConfig =
qvariant_cast<QJsonObject>(m_containersModel->data(containerModelIndex, ContainersModel::Roles::ConfigRole));
QJsonObject containerConfig = m_containersModel->getContainerConfig(container);
containerConfig.insert(config_key::container, ContainerProps::containerToString(container));
ErrorCode errorCode = ErrorCode::NoError;
@ -262,13 +253,10 @@ void ExportController::generateCloakConfig()
clearPreviousConfig();
int serverIndex = m_serversModel->getCurrentlyProcessedServerIndex();
ServerCredentials credentials =
qvariant_cast<ServerCredentials>(m_serversModel->data(serverIndex, ServersModel::Roles::CredentialsRole));
ServerCredentials credentials = m_serversModel->getServerCredentials(serverIndex);
DockerContainer container = static_cast<DockerContainer>(m_containersModel->getCurrentlyProcessedContainerIndex());
QModelIndex containerModelIndex = m_containersModel->index(container);
QJsonObject containerConfig =
qvariant_cast<QJsonObject>(m_containersModel->data(containerModelIndex, ContainersModel::Roles::ConfigRole));
QJsonObject containerConfig = m_containersModel->getContainerConfig(container);
containerConfig.insert(config_key::container, ContainerProps::containerToString(container));
ErrorCode errorCode = ErrorCode::NoError;

View file

@ -199,12 +199,9 @@ void InstallController::installContainer(DockerContainer container, QJsonObject
if (errorCode == ErrorCode::NoError) {
for (auto iterator = installedContainers.begin(); iterator != installedContainers.end(); iterator++) {
auto modelIndex = m_containersModel->index(iterator.key());
QJsonObject containerConfig =
qvariant_cast<QJsonObject>(m_containersModel->data(modelIndex, ContainersModel::Roles::ConfigRole));
QJsonObject containerConfig = m_containersModel->getContainerConfig(iterator.key());
if (containerConfig.isEmpty()) {
m_containersModel->setData(m_containersModel->index(iterator.key()), iterator.value(),
ContainersModel::Roles::ConfigRole);
m_serversModel->addContainerConfig(iterator.key(), iterator.value());
if (container != iterator.key()) { // skip the newly installed container
isInstalledContainerAddedToGui = true;
}
@ -252,12 +249,9 @@ void InstallController::scanServerForInstalledContainers()
bool isInstalledContainerAddedToGui = false;
for (auto iterator = installedContainers.begin(); iterator != installedContainers.end(); iterator++) {
auto modelIndex = m_containersModel->index(iterator.key());
QJsonObject containerConfig =
qvariant_cast<QJsonObject>(m_containersModel->data(modelIndex, ContainersModel::Roles::ConfigRole));
QJsonObject containerConfig = m_containersModel->getContainerConfig(iterator.key());
if (containerConfig.isEmpty()) {
m_containersModel->setData(m_containersModel->index(iterator.key()), iterator.value(),
ContainersModel::Roles::ConfigRole);
m_serversModel->addContainerConfig(iterator.key(), iterator.value());
isInstalledContainerAddedToGui = true;
}
}
@ -276,16 +270,14 @@ 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());
auto modelIndex = m_containersModel->index(container);
QJsonObject oldContainerConfig =
qvariant_cast<QJsonObject>(m_containersModel->data(modelIndex, ContainersModel::Roles::ConfigRole));
QJsonObject oldContainerConfig = m_containersModel->getContainerConfig(container);
ServerController serverController(m_settings);
connect(&serverController, &ServerController::serverIsBusy, this, &InstallController::serverIsBusy);
auto errorCode = serverController.updateContainer(serverCredentials, container, oldContainerConfig, config);
if (errorCode == ErrorCode::NoError) {
m_containersModel->setData(modelIndex, config, ContainersModel::Roles::ConfigRole);
m_serversModel->updateContainerConfig(container, config);
m_protocolModel->updateModel(config);
if ((serverIndex == m_serversModel->getDefaultServerIndex())
@ -315,7 +307,7 @@ void InstallController::removeAllContainers()
int serverIndex = m_serversModel->getCurrentlyProcessedServerIndex();
QString serverName = m_serversModel->data(serverIndex, ServersModel::Roles::NameRole).toString();
ErrorCode errorCode = m_containersModel->removeAllContainers();
ErrorCode errorCode = m_serversModel->removeAllContainers();
if (errorCode == ErrorCode::NoError) {
emit removeAllContainersFinished(tr("All containers from server '%1' have been removed").arg(serverName));
return;
@ -329,12 +321,12 @@ void InstallController::removeCurrentlyProcessedContainer()
QString serverName = m_serversModel->data(serverIndex, ServersModel::Roles::NameRole).toString();
int container = m_containersModel->getCurrentlyProcessedContainerIndex();
QString containerName = m_containersModel->data(container, ContainersModel::Roles::NameRole).toString();
QString containerName = m_containersModel->getCurrentlyProcessedContainerName();
ErrorCode errorCode = m_containersModel->removeCurrentlyProcessedContainer();
ErrorCode errorCode = m_serversModel->removeContainer(container);
if (errorCode == ErrorCode::NoError) {
emit removeCurrentlyProcessedContainerFinished(tr("%1 has been removed from the server '%2'").arg(containerName).arg(serverName));
emit removeCurrentlyProcessedContainerFinished(tr("%1 has been removed from the server '%2'").arg(containerName, serverName));
return;
}
emit installationErrorOccurred(errorString(errorCode));

View file

@ -42,6 +42,7 @@ SettingsController::SettingsController(const QSharedPointer<ServersModel> &serve
void SettingsController::toggleAmneziaDns(bool enable)
{
m_settings->setUseAmneziaDns(enable);
emit amneziaDnsToggled(enable);
}
bool SettingsController::isAmneziaDnsEnabled()
@ -138,7 +139,7 @@ void SettingsController::clearSettings()
void SettingsController::clearCachedProfiles()
{
m_containersModel->clearCachedProfiles();
m_serversModel->clearCachedProfiles();
emit changeSettingsFinished(tr("Cached profiles cleared"));
}

View file

@ -70,6 +70,8 @@ signals:
void importBackupFromOutside(QString filePath);
void amneziaDnsToggled(bool enable);
private:
QSharedPointer<ServersModel> m_serversModel;
QSharedPointer<ContainersModel> m_containersModel;

View file

@ -1,9 +1,9 @@
#include "containers_model.h"
#include "core/controllers/serverController.h"
#include <QJsonArray>
ContainersModel::ContainersModel(std::shared_ptr<Settings> settings, QObject *parent)
: m_settings(settings), QAbstractListModel(parent)
ContainersModel::ContainersModel(QObject *parent)
: QAbstractListModel(parent)
{
}
@ -13,37 +13,6 @@ 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()) {
@ -84,37 +53,32 @@ QVariant ContainersModel::data(const int index, int role) const
return data(modelIndex, role);
}
void ContainersModel::setCurrentlyProcessedServerIndex(const int index)
void ContainersModel::updateModel(QJsonArray &containers)
{
beginResetModel();
m_currentlyProcessedServerIndex = index;
m_containers = m_settings->containers(m_currentlyProcessedServerIndex);
m_defaultContainerIndex = m_settings->defaultContainer(m_currentlyProcessedServerIndex);
m_containers.clear();
for (const QJsonValue &val : containers) {
m_containers.insert(ContainerProps::containerFromString(val.toObject().value(config_key::container).toString()),
val.toObject());
}
endResetModel();
emit defaultContainerChanged();
}
void ContainersModel::setCurrentlyProcessedContainerIndex(int index)
void ContainersModel::setDefaultContainer(const int containerIndex)
{
m_currentlyProcessedContainerIndex = index;
m_defaultContainerIndex = static_cast<DockerContainer>(containerIndex);
emit dataChanged(index(containerIndex, 0), index(containerIndex, 0));
}
DockerContainer ContainersModel::getDefaultContainer()
{
return m_defaultContainerIndex;
}
QString ContainersModel::getDefaultContainerName()
void ContainersModel::setCurrentlyProcessedContainerIndex(int 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();
m_currentlyProcessedContainerIndex = index;
}
int ContainersModel::getCurrentlyProcessedContainerIndex()
@ -127,91 +91,9 @@ QString ContainersModel::getCurrentlyProcessedContainerName()
return ContainerProps::containerHumanNames().value(static_cast<DockerContainer>(m_currentlyProcessedContainerIndex));
}
QJsonObject ContainersModel::getCurrentlyProcessedContainerConfig()
QJsonObject ContainersModel::getContainerConfig(const int containerIndex)
{
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);
return qvariant_cast<QJsonObject>(data(index(containerIndex), ConfigRole));
}
bool ContainersModel::isAnyContainerInstalled()
@ -228,11 +110,6 @@ 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;

View file

@ -7,13 +7,12 @@
#include <vector>
#include "containers/containers_defs.h"
#include "settings.h"
class ContainersModel : public QAbstractListModel
{
Q_OBJECT
public:
ContainersModel(std::shared_ptr<Settings> settings, QObject *parent = nullptr);
ContainersModel(QObject *parent = nullptr);
enum Roles {
NameRole = Qt::UserRole + 1,
@ -37,37 +36,24 @@ 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();
QString getDefaultContainerName();
void setDefaultContainer(int index);
void setDefaultContainer(const int containerIndex);
void setCurrentlyProcessedServerIndex(const int index);
void setCurrentlyProcessedContainerIndex(int index);
void setCurrentlyProcessedContainerIndex(int containerIndex);
int getCurrentlyProcessedContainerIndex();
QString getCurrentlyProcessedContainerName();
QJsonObject getCurrentlyProcessedContainerConfig();
QStringList getAllInstalledServicesName(const int serverIndex);
ErrorCode removeAllContainers();
ErrorCode removeCurrentlyProcessedContainer();
void clearCachedProfiles();
bool isAmneziaDnsContainerInstalled();
bool isAmneziaDnsContainerInstalled(const int serverIndex);
QJsonObject getContainerConfig(const int containerIndex);
bool isAnyContainerInstalled();
void updateContainersConfig();
protected:
QHash<int, QByteArray> roleNames() const override;
@ -78,11 +64,8 @@ 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

View file

@ -1,5 +1,7 @@
#include "servers_model.h"
#include "core/controllers/serverController.h"
ServersModel::ServersModel(std::shared_ptr<Settings> settings, QObject *parent)
: m_settings(settings), QAbstractListModel(parent)
{
@ -8,6 +10,11 @@ ServersModel::ServersModel(std::shared_ptr<Settings> settings, QObject *parent)
m_currentlyProcessedServerIndex = m_defaultServerIndex;
connect(this, &ServersModel::defaultServerIndexChanged, this, &ServersModel::defaultServerNameChanged);
connect(this, &ServersModel::defaultServerIndexChanged, 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
@ -50,14 +57,23 @@ 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: {
auto description = server.value(config_key::description).toString();
if (description.isEmpty()) {
if (configVersion) {
return server.value(config_key::name).toString();
}
auto name = server.value(config_key::description).toString();
if (name.isEmpty()) {
return server.value(config_key::hostName).toString();
}
return description;
return name;
}
case ServerDescriptionRole: {
if (configVersion) {
return server.value(config_key::description).toString();
}
return server.value(config_key::hostName).toString();
}
case HostNameRole: return server.value(config_key::hostName).toString();
case CredentialsRole: return QVariant::fromValue(serverCredentials(index.row()));
@ -72,6 +88,9 @@ 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();
@ -114,6 +133,53 @@ 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();
@ -132,6 +198,7 @@ bool ServersModel::hasServerWithWriteAccess()
void ServersModel::setCurrentlyProcessedServerIndex(const int index)
{
m_currentlyProcessedServerIndex = index;
updateContainersModel();
emit currentlyProcessedServerIndexChanged(m_currentlyProcessedServerIndex);
}
@ -150,6 +217,11 @@ 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;
@ -179,6 +251,7 @@ void ServersModel::editServer(const QJsonObject &server)
m_settings->editServer(m_currentlyProcessedServerIndex, server);
m_servers = m_settings->serversArray();
endResetModel();
updateContainersModel();
}
void ServersModel::removeServer()
@ -206,23 +279,27 @@ 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;
}
@ -239,7 +316,205 @@ 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();
}

View file

@ -11,13 +11,21 @@ class ServersModel : public QAbstractListModel
public:
enum Roles {
NameRole = Qt::UserRole + 1,
ServerDescriptionRole,
HostNameRole,
CredentialsRole,
CredentialsLoginRole,
IsDefaultRole,
IsCurrentlyProcessedRole,
HasWriteAccessRole,
ContainsAmneziaDnsRole
ContainsAmneziaDnsRole,
DefaultContainerRole
};
ServersModel(std::shared_ptr<Settings> settings, QObject *parent = nullptr);
@ -33,6 +41,10 @@ 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)
@ -41,6 +53,8 @@ public slots:
const int getDefaultServerIndex();
const QString getDefaultServerName();
const QString getDefaultServerHostName();
const QString getDefaultServerDescriptionCollapsed();
const QString getDefaultServerDescriptionExpanded();
bool isDefaultServerCurrentlyProcessed();
bool isCurrentlyProcessedServerHasWriteAccess();
@ -54,15 +68,33 @@ public slots:
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 updateContainersConfig();
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);
protected:
QHash<int, QByteArray> roleNames() const override;
@ -71,9 +103,16 @@ 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;
@ -81,6 +120,8 @@ private:
int m_defaultServerIndex;
int m_currentlyProcessedServerIndex;
bool m_isAmneziaDnsEnabled = m_settings->useAmneziaDns();
};
#endif // SERVERSMODEL_H

View file

@ -60,9 +60,8 @@ ListView {
}
if (checked) {
isDefault = true
ServersModel.setDefaultContainer(proxyContainersModel.mapToSource(index))
menuContent.currentIndex = index
containersDropDown.menuVisible = false
} else {
if (!isSupported && isInstalled) {

View file

@ -22,10 +22,6 @@ PageType {
property string borderColor: "#2C2D30"
property string defaultServerName: ServersModel.defaultServerName
property string defaultServerHostName: ServersModel.defaultServerHostName
property string defaultContainerName: ContainersModel.defaultContainerName
Connections {
target: PageController
@ -40,41 +36,6 @@ 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"
@ -267,7 +228,7 @@ PageType {
maximumLineCount: 2
elide: Qt.ElideRight
text: root.defaultServerName
text: ServersModel.defaultServerName
horizontalAlignment: Qt.AlignHCenter
Behavior on opacity {
@ -304,6 +265,7 @@ PageType {
Layout.bottomMargin: 44
Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter
visible: buttonContent.collapsedVisibility
text: ServersModel.defaultServerDescriptionCollapsed
}
ColumnLayout {
@ -319,7 +281,7 @@ PageType {
Layout.leftMargin: 16
Layout.rightMargin: 16
text: root.defaultServerName
text: ServersModel.defaultServerName
horizontalAlignment: Qt.AlignHCenter
maximumLineCount: 2
elide: Qt.ElideRight
@ -331,6 +293,7 @@ PageType {
Layout.fillWidth: true
horizontalAlignment: Qt.AlignHCenter
verticalAlignment: Qt.AlignVCenter
text: ServersModel.defaultServerDescriptionExpanded
}
RowLayout {
@ -349,7 +312,7 @@ PageType {
rootButtonTextTopMargin: 8
rootButtonTextBottomMargin: 8
text: root.defaultContainerName
text: ServersModel.defaultContainerName
textColor: "#0E0E11"
headerText: qsTr("VPN protocol")
headerBackButtonImage: "qrc:/images/controls/arrow-left.svg"
@ -468,7 +431,7 @@ PageType {
var description = ""
if (hasWriteAccess) {
if (SettingsController.isAmneziaDnsEnabled()
&& ContainersModel.isAmneziaDnsContainerInstalled(index)) {
&& ServersModel.isAmneziaDnsContainerInstalled(index)) {
description += "Amnezia DNS | "
}
} else {

View file

@ -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"]
}

View file

@ -77,7 +77,7 @@ PageType {
text: name
descriptionText: {
var servicesNameString = ""
var servicesName = ContainersModel.getAllInstalledServicesName(index)
var servicesName = ServersModel.getAllInstalledServicesName(index)
for (var i = 0; i < servicesName.length; i++) {
servicesNameString += servicesName[i] + " · "
}

View file

@ -25,7 +25,7 @@ PageType {
function onInstallContainerFinished(finishedMessage, isServiceInstall) {
if (!ConnectionController.isConnected && !isServiceInstall) {
ContainersModel.setDefaultContainer(ContainersModel.getCurrentlyProcessedContainerIndex())
ServersModel.setDefaultContainer(ContainersModel.getCurrentlyProcessedContainerIndex())
}
PageController.closePage() // close installing page

View file

@ -354,8 +354,6 @@ PageType {
currentIndex: 0
clickedFunction: function() {
protocolSelectorListView.currentItem.y
handler()
protocolSelector.menuVisible = false
@ -365,7 +363,7 @@ PageType {
target: serverSelector
function onSeverSelectorIndexChanged() {
protocolSelectorListView.currentIndex = proxyContainersModel.mapFromSource(ContainersModel.getDefaultContainer())
protocolSelectorListView.currentIndex = proxyContainersModel.mapFromSource(ServersModel.getDefaultContainer())
protocolSelectorListView.triggerCurrentItem()
}
}

View file

@ -234,8 +234,6 @@ QString VpnConnection::createVpnConfigurationForProto(int serverIndex, const Ser
return "";
}
emit m_configurator->newVpnConfigCreated(clientId, "unnamed client", container, credentials);
QString configDataBeforeLocalProcessing = configData;
configData = m_configurator->processConfigWithLocalSettings(serverIndex, container, proto, configData);
@ -247,6 +245,8 @@ 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;