Merge branch 'dev'

This commit is contained in:
pokamest 2023-04-11 18:00:54 +01:00
commit af29637163
201 changed files with 2229 additions and 1503287 deletions

View file

@ -0,0 +1,104 @@
#include "clientManagementModel.h"
#include <QJsonObject>
ClientManagementModel::ClientManagementModel(QObject *parent) : 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_content.size());
}
QVariant ClientManagementModel::data(const QModelIndex &index, int role) const
{
if (!index.isValid() || index.row() < 0
|| index.row() >= static_cast<int>(m_content.size())) {
return QVariant();
}
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();
}
void ClientManagementModel::setData(const QModelIndex &index, QVariant data, int role)
{
if (!index.isValid() || index.row() < 0
|| index.row() >= static_cast<int>(m_content.size())) {
return;
}
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);
}
}
bool ClientManagementModel::removeRows(int row)
{
beginRemoveRows(QModelIndex(), row, row);
m_content.removeAt(row);
endRemoveRows();
return true;
}
QHash<int, QByteArray> ClientManagementModel::roleNames() const
{
QHash<int, QByteArray> roles;
roles[NameRole] = "clientName";
roles[OpenVpnCertIdRole] = "openvpnCertId";
roles[OpenVpnCertDataRole] = "openvpnCertData";
roles[WireGuardPublicKey] = "wireguardPublicKey";
return roles;
}

View file

@ -0,0 +1,37 @@
#ifndef CLIENTMANAGEMENTMODEL_H
#define CLIENTMANAGEMENTMODEL_H
#include <QAbstractListModel>
#include "protocols/protocols_defs.h"
class ClientManagementModel : public QAbstractListModel
{
Q_OBJECT
public:
enum ClientRoles {
NameRole = Qt::UserRole + 1,
OpenVpnCertIdRole,
OpenVpnCertDataRole,
WireGuardPublicKey,
};
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;
void setData(const QModelIndex &index, QVariant data, int role = Qt::DisplayRole);
bool removeRows(int row);
protected:
QHash<int, QByteArray> roleNames() const override;
private:
QVector<QVariant> m_content;
};
#endif // CLIENTMANAGEMENTMODEL_H

View file

@ -12,7 +12,8 @@ public:
enum Type {
Basic,
Proto,
ShareProto
ShareProto,
ClientInfo
};
Q_ENUM(Type)
};
@ -24,7 +25,8 @@ enum class Page {Start = 0, NewServer, NewServerProtocols, Vpn,
Wizard, WizardLow, WizardMedium, WizardHigh, WizardVpnMode, ServerConfiguringProgress,
GeneralSettings, AppSettings, NetworkSettings, ServerSettings,
ServerContainers, ServersList, ShareConnection, Sites,
ProtocolSettings, ProtocolShare, QrDecoder, QrDecoderIos, About, ViewConfig, AdvancedServerSettings};
ProtocolSettings, ProtocolShare, QrDecoder, QrDecoderIos, About, ViewConfig,
AdvancedServerSettings, ClientManagement, ClientInfo};
Q_ENUM_NS(Page)
static void declareQmlPageEnum() {

View file

@ -44,10 +44,11 @@ void AdvancedServerSettingsLogic::onPushButtonClearServerClicked()
uiLogic()->pageLogic<VpnLogic>()->onDisconnect();
}
ErrorCode e = m_serverController->removeAllContainers(m_settings->serverCredentials(uiLogic()->m_selectedServerIndex));
if (e) {
ServerController serverController(m_settings);
ErrorCode errorCode = serverController.removeAllContainers(m_settings->serverCredentials(uiLogic()->m_selectedServerIndex));
if (errorCode) {
emit uiLogic()->showWarningMessage(tr("Error occurred while cleaning the server.") + "\n" +
tr("Error message: ") + errorString(e) + "\n" +
tr("Error message: ") + errorString(errorCode) + "\n" +
tr("See logs for details."));
} else {
set_labelWaitInfoVisible(true);

View file

@ -0,0 +1,213 @@
#include "ClientInfoLogic.h"
#include <QMessageBox>
#include "defines.h"
#include "core/errorstrings.h"
#include "core/servercontroller.h"
#include "ui/models/clientManagementModel.h"
#include "ui/uilogic.h"
namespace {
bool isErrorOccured(ErrorCode error) {
if (error != ErrorCode::NoError) {
QMessageBox::warning(nullptr, APPLICATION_NAME,
QObject::tr("An error occurred while saving the list of clients.") + "\n" + errorString(error));
return true;
}
return false;
}
}
ClientInfoLogic::ClientInfoLogic(UiLogic *logic, QObject *parent):
PageLogicBase(logic, parent)
{
}
void ClientInfoLogic::setCurrentClientId(int index)
{
m_currentClientIndex = index;
}
void ClientInfoLogic::onUpdatePage()
{
set_pageContentVisible(false);
set_busyIndicatorIsRunning(true);
const ServerCredentials credentials = m_settings->serverCredentials(uiLogic()->m_selectedServerIndex);
const DockerContainer container = m_settings->defaultContainer(uiLogic()->m_selectedServerIndex);
const QString containerNameString = ContainerProps::containerHumanNames().value(container);
set_labelCurrentVpnProtocolText(tr("Service: ") + containerNameString);
const QVector<amnezia::Proto> protocols = ContainerProps::protocolsForContainer(container);
if (!protocols.empty()) {
const Proto currentMainProtocol = protocols.front();
auto model = qobject_cast<ClientManagementModel*>(uiLogic()->clientManagementModel());
const QModelIndex modelIndex = model->index(m_currentClientIndex);
set_lineEditNameAliasText(model->data(modelIndex, ClientManagementModel::ClientRoles::NameRole).toString());
if (currentMainProtocol == Proto::OpenVpn) {
const QString certId = model->data(modelIndex, ClientManagementModel::ClientRoles::OpenVpnCertIdRole).toString();
QString certData = model->data(modelIndex, ClientManagementModel::ClientRoles::OpenVpnCertDataRole).toString();
if (certData.isEmpty() && !certId.isEmpty()) {
QString stdOut;
auto cbReadStdOut = [&](const QString &data, libssh::Client &) {
stdOut += data + "\n";
return ErrorCode::NoError;
};
const QString getOpenVpnCertData = QString("sudo docker exec -i $CONTAINER_NAME bash -c 'cat /opt/amnezia/openvpn/pki/issued/%1.crt'")
.arg(certId);
ServerController serverController(m_settings);
const QString script = serverController.replaceVars(getOpenVpnCertData, serverController.genVarsForScript(credentials, container));
ErrorCode error = serverController.runScript(credentials, script, cbReadStdOut);
certData = stdOut;
if (isErrorOccured(error)) {
set_busyIndicatorIsRunning(false);
emit uiLogic()->closePage();
return;
}
}
set_labelOpenVpnCertId(certId);
set_textAreaOpenVpnCertData(certData);
} else if (currentMainProtocol == Proto::WireGuard) {
set_textAreaWireGuardKeyData(model->data(modelIndex, ClientManagementModel::ClientRoles::WireGuardPublicKey).toString());
}
}
set_pageContentVisible(true);
set_busyIndicatorIsRunning(false);
}
void ClientInfoLogic::onLineEditNameAliasEditingFinished()
{
set_busyIndicatorIsRunning(true);
auto model = qobject_cast<ClientManagementModel*>(uiLogic()->clientManagementModel());
const QModelIndex modelIndex = model->index(m_currentClientIndex);
model->setData(modelIndex, m_lineEditNameAliasText, ClientManagementModel::ClientRoles::NameRole);
const DockerContainer selectedContainer = m_settings->defaultContainer(uiLogic()->m_selectedServerIndex);
const ServerCredentials credentials = m_settings->serverCredentials(uiLogic()->m_selectedServerIndex);
const QVector<amnezia::Proto> protocols = ContainerProps::protocolsForContainer(selectedContainer);
if (!protocols.empty()) {
const Proto currentMainProtocol = protocols.front();
const QJsonObject clientsTable = model->getContent(currentMainProtocol);
ErrorCode error = setClientsList(credentials,
selectedContainer,
currentMainProtocol,
clientsTable);
isErrorOccured(error);
}
set_busyIndicatorIsRunning(false);
}
void ClientInfoLogic::onRevokeOpenVpnCertificateClicked()
{
set_busyIndicatorIsRunning(true);
const DockerContainer container = m_settings->defaultContainer(uiLogic()->m_selectedServerIndex);
const ServerCredentials credentials = m_settings->serverCredentials(uiLogic()->m_selectedServerIndex);
auto model = qobject_cast<ClientManagementModel*>(uiLogic()->clientManagementModel());
const QModelIndex modelIndex = model->index(m_currentClientIndex);
const QString certId = model->data(modelIndex, ClientManagementModel::ClientRoles::OpenVpnCertIdRole).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(certId);
ServerController serverController(m_settings);
const QString script = serverController.replaceVars(getOpenVpnCertData,
serverController.genVarsForScript(credentials, container));
auto error = serverController.runScript(credentials, script);
if (isErrorOccured(error)) {
set_busyIndicatorIsRunning(false);
emit uiLogic()->goToPage(Page::ServerSettings);
return;
}
model->removeRows(m_currentClientIndex);
const QJsonObject clientsTable = model->getContent(Proto::OpenVpn);
error = setClientsList(credentials, container, Proto::OpenVpn, clientsTable);
if (isErrorOccured(error)) {
set_busyIndicatorIsRunning(false);
return;
}
const QJsonObject &containerConfig = m_settings->containerConfig(uiLogic()->m_selectedServerIndex, container);
error = serverController.startupContainerWorker(credentials, container, containerConfig);
if (isErrorOccured(error)) {
set_busyIndicatorIsRunning(false);
return;
}
set_busyIndicatorIsRunning(false);
}
void ClientInfoLogic::onRevokeWireGuardKeyClicked()
{
set_busyIndicatorIsRunning(true);
ErrorCode error;
const DockerContainer container = m_settings->defaultContainer(uiLogic()->m_selectedServerIndex);
const ServerCredentials credentials = m_settings->serverCredentials(uiLogic()->m_selectedServerIndex);
ServerController serverController(m_settings);
const QString wireGuardConfigFile = "opt/amnezia/wireguard/wg0.conf";
const QString wireguardConfigString = serverController.getTextFileFromContainer(container, credentials, wireGuardConfigFile, &error);
if (isErrorOccured(error)) {
set_busyIndicatorIsRunning(false);
return;
}
auto model = qobject_cast<ClientManagementModel*>(uiLogic()->clientManagementModel());
const QModelIndex modelIndex = model->index(m_currentClientIndex);
const QString key = model->data(modelIndex, ClientManagementModel::ClientRoles::WireGuardPublicKey).toString();
auto configSections = wireguardConfigString.split("[", Qt::SkipEmptyParts);
for (auto &section : configSections) {
if (section.contains(key)) {
configSections.removeOne(section);
}
}
QString newWireGuardConfig = configSections.join("[");
newWireGuardConfig.insert(0, "[");
error = serverController.uploadTextFileToContainer(container, credentials, newWireGuardConfig,
protocols::wireguard::serverConfigPath,
libssh::SftpOverwriteMode::SftpOverwriteExisting);
if (isErrorOccured(error)) {
set_busyIndicatorIsRunning(false);
return;
}
model->removeRows(m_currentClientIndex);
const QJsonObject clientsTable = model->getContent(Proto::WireGuard);
error = setClientsList(credentials, container, Proto::WireGuard, clientsTable);
if (isErrorOccured(error)) {
set_busyIndicatorIsRunning(false);
return;
}
const QString script = "sudo docker exec -i $CONTAINER_NAME bash -c 'wg syncconf wg0 <(wg-quick strip /opt/amnezia/wireguard/wg0.conf)'";
error = serverController.runScript(credentials,
serverController.replaceVars(script, serverController.genVarsForScript(credentials, container)));
if (isErrorOccured(error)) {
set_busyIndicatorIsRunning(false);
return;
}
set_busyIndicatorIsRunning(false);
}
ErrorCode ClientInfoLogic::setClientsList(const ServerCredentials &credentials, DockerContainer container, Proto mainProtocol, const QJsonObject &clietns)
{
const QString mainProtocolString = ProtocolProps::protoToString(mainProtocol);
const QString clientsTableFile = QString("opt/amnezia/%1/clientsTable").arg(mainProtocolString);
ServerController serverController(m_settings);
ErrorCode error = serverController.uploadTextFileToContainer(container, credentials, QJsonDocument(clietns).toJson(), clientsTableFile);
return error;
}

View file

@ -0,0 +1,42 @@
#ifndef CLIENTINFOLOGIC_H
#define CLIENTINFOLOGIC_H
#include "PageLogicBase.h"
#include "core/defs.h"
#include "containers/containers_defs.h"
#include "protocols/protocols_defs.h"
class UiLogic;
class ClientInfoLogic : public PageLogicBase
{
Q_OBJECT
AUTO_PROPERTY(QString, lineEditNameAliasText)
AUTO_PROPERTY(QString, labelOpenVpnCertId)
AUTO_PROPERTY(QString, textAreaOpenVpnCertData)
AUTO_PROPERTY(QString, labelCurrentVpnProtocolText)
AUTO_PROPERTY(QString, textAreaWireGuardKeyData)
AUTO_PROPERTY(bool, busyIndicatorIsRunning);
AUTO_PROPERTY(bool, pageContentVisible);
public:
ClientInfoLogic(UiLogic *uiLogic, QObject *parent = nullptr);
~ClientInfoLogic() = default;
void setCurrentClientId(int index);
public slots:
void onUpdatePage() override;
void onLineEditNameAliasEditingFinished();
void onRevokeOpenVpnCertificateClicked();
void onRevokeWireGuardKeyClicked();
private:
ErrorCode setClientsList(const ServerCredentials &credentials, DockerContainer container, Proto mainProtocol, const QJsonObject &clietns);
int m_currentClientIndex;
};
#endif // CLIENTINFOLOGIC_H

View file

@ -0,0 +1,143 @@
#include "ClientManagementLogic.h"
#include <QMessageBox>
#include "defines.h"
#include "core/errorstrings.h"
#include "core/servercontroller.h"
#include "ui/pages_logic/ClientInfoLogic.h"
#include "ui/models/clientManagementModel.h"
#include "ui/uilogic.h"
ClientManagementLogic::ClientManagementLogic(UiLogic *logic, QObject *parent):
PageLogicBase(logic, parent)
{
}
void ClientManagementLogic::onUpdatePage()
{
set_busyIndicatorIsRunning(true);
qobject_cast<ClientManagementModel*>(uiLogic()->clientManagementModel())->clearData();
DockerContainer selectedContainer = m_settings->defaultContainer(uiLogic()->m_selectedServerIndex);
QString selectedContainerName = ContainerProps::containerHumanNames().value(selectedContainer);
set_labelCurrentVpnProtocolText(tr("Service: ") + selectedContainerName);
QJsonObject clients;
auto protocols = ContainerProps::protocolsForContainer(selectedContainer);
if (!protocols.empty()) {
m_currentMainProtocol = protocols.front();
const ServerCredentials credentials = m_settings->serverCredentials(uiLogic()->m_selectedServerIndex);
ErrorCode error = getClientsList(credentials, selectedContainer, m_currentMainProtocol, clients);
if (error != ErrorCode::NoError) {
QMessageBox::warning(nullptr, APPLICATION_NAME,
tr("An error occurred while getting the list of clients.") + "\n" + errorString(error));
set_busyIndicatorIsRunning(false);
return;
}
}
QVector<QVariant> clientsArray;
for (auto &clientId : clients.keys()) {
clientsArray.push_back(clients[clientId].toObject());
}
qobject_cast<ClientManagementModel*>(uiLogic()->clientManagementModel())->setContent(clientsArray);
set_busyIndicatorIsRunning(false);
}
void ClientManagementLogic::onClientItemClicked(int index)
{
uiLogic()->pageLogic<ClientInfoLogic>()->setCurrentClientId(index);
emit uiLogic()->goToClientInfoPage(m_currentMainProtocol);
}
ErrorCode ClientManagementLogic::getClientsList(const ServerCredentials &credentials, DockerContainer container, Proto mainProtocol, QJsonObject &clietns)
{
ErrorCode error = ErrorCode::NoError;
QString stdOut;
auto cbReadStdOut = [&](const QString &data, libssh::Client &) {
stdOut += data + "\n";
return ErrorCode::NoError;
};
const QString mainProtocolString = ProtocolProps::protoToString(mainProtocol);
ServerController serverController(m_settings);
const QString clientsTableFile = QString("/opt/amnezia/%1/clientsTable").arg(mainProtocolString);
const QByteArray clientsTableString = serverController.getTextFileFromContainer(container, credentials, clientsTableFile, &error);
if (error != ErrorCode::NoError) {
return error;
}
QJsonObject clientsTable = QJsonDocument::fromJson(clientsTableString).object();
int count = 0;
if (mainProtocol == Proto::OpenVpn) {
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) {
return error;
}
if (!stdOut.isEmpty()) {
QStringList certsIds = stdOut.split("\n", Qt::SkipEmptyParts);
certsIds.removeAll("AmneziaReq.crt");
for (auto &openvpnCertId : certsIds) {
openvpnCertId.replace(".crt", "");
if (!clientsTable.contains(openvpnCertId)) {
QJsonObject client;
client["openvpnCertId"] = openvpnCertId;
client["clientName"] = QString("Client %1").arg(count);
client["openvpnCertData"] = "";
clientsTable[openvpnCertId] = client;
count++;
}
}
}
} else if (mainProtocol == Proto::WireGuard) {
const QString wireGuardConfigFile = "opt/amnezia/wireguard/wg0.conf";
const QString wireguardConfigString = serverController.getTextFileFromContainer(container, credentials, wireGuardConfigFile, &error);
if (error != ErrorCode::NoError) {
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 (!clientsTable.contains(wireguardKey)) {
QJsonObject client;
client["clientName"] = QString("Client %1").arg(count);
client["wireguardPublicKey"] = wireguardKey;
clientsTable[wireguardKey] = client;
count++;
}
}
}
const QByteArray newClientsTableString = QJsonDocument(clientsTable).toJson();
if (clientsTableString != newClientsTableString) {
error = serverController.uploadTextFileToContainer(container, credentials, newClientsTableString, clientsTableFile);
}
if (error != ErrorCode::NoError) {
return error;
}
clietns = clientsTable;
return error;
}

View file

@ -0,0 +1,33 @@
#ifndef CLIENTMANAGMENTLOGIC_H
#define CLIENTMANAGMENTLOGIC_H
#include "PageLogicBase.h"
#include "core/defs.h"
#include "containers/containers_defs.h"
#include "protocols/protocols_defs.h"
class UiLogic;
class ClientManagementLogic : public PageLogicBase
{
Q_OBJECT
AUTO_PROPERTY(QString, labelCurrentVpnProtocolText)
AUTO_PROPERTY(bool, busyIndicatorIsRunning);
public:
ClientManagementLogic(UiLogic *uiLogic, QObject *parent = nullptr);
~ClientManagementLogic() = default;
public slots:
void onUpdatePage() override;
void onClientItemClicked(int index);
private:
ErrorCode getClientsList(const ServerCredentials &credentials, DockerContainer container, Proto mainProtocol, QJsonObject &clietns);
amnezia::Proto m_currentMainProtocol;
};
#endif // CLIENTMANAGMENTLOGIC_H

View file

@ -11,7 +11,6 @@ PageLogicBase::PageLogicBase(UiLogic *logic, QObject *parent):
{
m_settings = logic->m_settings;
m_configurator = logic->m_configurator;
m_serverController = logic->m_serverController;
}

View file

@ -28,7 +28,6 @@ protected:
std::shared_ptr<Settings> m_settings;
std::shared_ptr<VpnConfigurator> m_configurator;
std::shared_ptr<ServerController> m_serverController;
signals:
void updatePage();

View file

@ -96,19 +96,18 @@ ErrorCode ServerConfiguringProgressLogic::doInstallAction(const std::function<Er
progress.setValueFunc(0);
timer.start(1000);
ServerController serverController(m_settings);
QMetaObject::Connection cancelDoInstallActionConnection;
if (cancelButton.setVisibleFunc) {
cancelDoInstallActionConnection = connect(this, &ServerConfiguringProgressLogic::cancelDoInstallAction,
m_serverController.get(), &ServerController::setCancelInstallation);
&serverController, &ServerController::setCancelInstallation);
}
QMetaObject::Connection serverBusyConnection;
if (serverBusyInfo.setVisibleFunc && serverBusyInfo.setTextFunc) {
serverBusyConnection = connect(m_serverController.get(),
&ServerController::serverIsBusy,
this,
[&serverBusyInfo, &timer, &cancelButton](const bool isBusy) {
auto onServerIsBusy = [&serverBusyInfo, &timer, &cancelButton](const bool isBusy) {
isBusy ? timer.stop() : timer.start(1000);
serverBusyInfo.setVisibleFunc(isBusy);
serverBusyInfo.setTextFunc(isBusy ? "Amnesia has detected that your server is currently "
@ -118,7 +117,9 @@ ErrorCode ServerConfiguringProgressLogic::doInstallAction(const std::function<Er
if (cancelButton.setVisibleFunc) {
cancelButton.setVisibleFunc(isBusy ? true : false);
}
});
};
serverBusyConnection = connect(&serverController, &ServerController::serverIsBusy, this, onServerIsBusy);
}
ErrorCode e = action();
@ -182,5 +183,5 @@ ErrorCode ServerConfiguringProgressLogic::doInstallAction(const std::function<Er
void ServerConfiguringProgressLogic::onPushButtonCancelClicked()
{
cancelDoInstallAction(true);
emit cancelDoInstallAction(true);
}

View file

@ -68,7 +68,8 @@ void ServerContainersLogic::onPushButtonShareClicked(DockerContainer c)
void ServerContainersLogic::onPushButtonRemoveClicked(DockerContainer container)
{
//buttonSetEnabledFunc(false);
ErrorCode e = m_serverController->removeContainer(m_settings->serverCredentials(uiLogic()->m_selectedServerIndex), container);
ServerController serverController(m_settings);
ErrorCode e = serverController.removeContainer(m_settings->serverCredentials(uiLogic()->m_selectedServerIndex), container);
m_settings->removeContainerConfig(uiLogic()->m_selectedServerIndex, container);
//buttonSetEnabledFunc(true);
@ -82,7 +83,8 @@ void ServerContainersLogic::onPushButtonRemoveClicked(DockerContainer container)
void ServerContainersLogic::onPushButtonContinueClicked(DockerContainer c, int port, TransportProto tp)
{
QJsonObject config = m_serverController->createContainerInitialConfig(c, port, tp);
ServerController serverController(m_settings);
QJsonObject config = serverController.createContainerInitialConfig(c, port, tp);
emit uiLogic()->goToPage(Page::ServerConfiguringProgress);
qApp->processEvents();
@ -93,7 +95,8 @@ void ServerContainersLogic::onPushButtonContinueClicked(DockerContainer c, int p
if (errorCode == ErrorCode::NoError) {
if (!uiLogic()->isContainerAlreadyAddedToGui(c)) {
auto installAction = [this, c, &config]() {
return m_serverController->setupContainer(m_settings->serverCredentials(uiLogic()->m_selectedServerIndex), c, config);
ServerController serverController(m_settings);
return serverController.setupContainer(m_settings->serverCredentials(uiLogic()->m_selectedServerIndex), c, config);
};
errorCode = uiLogic()->pageLogic<ServerConfiguringProgressLogic>()->doInstallAction(installAction);

View file

@ -6,9 +6,11 @@
#include "configurators/vpn_configurator.h"
#include "../uilogic.h"
#include "utilities.h"
#include "core/servercontroller.h"
#include <QFileDialog>
#include <QStandardPaths>
#include <QEventLoop>
#ifdef Q_OS_ANDROID
#include <QJniObject>
@ -94,8 +96,7 @@ void StartPageLogic::onPushButtonConnect()
set_labelWaitInfoText(tr("Please fill in all fields"));
return;
}
}
else {
} else {
if (lineEditIpText().isEmpty() ||
lineEditLoginText().isEmpty() ||
lineEditPasswordText().isEmpty() ) {
@ -111,7 +112,7 @@ void StartPageLogic::onPushButtonConnect()
serverCredentials.hostName = serverCredentials.hostName.split(":").at(0);
}
serverCredentials.userName = lineEditLoginText();
if (pushButtonConnectKeyChecked()){
if (pushButtonConnectKeyChecked()) {
QString key = textEditSshKeyText();
if (key.startsWith("ssh-rsa")) {
emit uiLogic()->showPublicKeyWarning();
@ -123,28 +124,44 @@ void StartPageLogic::onPushButtonConnect()
}
serverCredentials.password = key;
}
else {
} else {
serverCredentials.password = lineEditPasswordText();
}
set_pushButtonConnectEnabled(false);
set_pushButtonConnectText(tr("Connecting..."));
ErrorCode e = ErrorCode::NoError;
#ifdef Q_DEBUG
//QString output = m_serverController->checkSshConnection(serverCredentials, &e);
#else
ServerController serverController(m_settings);
ErrorCode errorCode = ErrorCode::NoError;
if (pushButtonConnectKeyChecked()) {
auto passphraseCallback = [this, &serverController]() {
emit showPassphraseRequestMessage();
QEventLoop loop;
QObject::connect(this, &StartPageLogic::passphraseDialogClosed, &loop, &QEventLoop::quit);
loop.exec();
return m_privateKeyPassphrase;
};
QString decryptedPrivateKey;
errorCode = serverController.getDecryptedPrivateKey(serverCredentials, decryptedPrivateKey, passphraseCallback);
if (errorCode == ErrorCode::NoError) {
serverCredentials.password = decryptedPrivateKey;
}
}
QString output;
#endif
if (errorCode == ErrorCode::NoError) {
output = serverController.checkSshConnection(serverCredentials, &errorCode);
}
bool ok = true;
if (e) {
if (errorCode) {
set_labelWaitInfoVisible(true);
set_labelWaitInfoText(errorString(e));
set_labelWaitInfoText(errorString(errorCode));
ok = false;
}
else {
} else {
if (output.contains("Please login as the user")) {
output.replace("\n", "");
set_labelWaitInfoVisible(true);

View file

@ -23,6 +23,8 @@ class StartPageLogic : public PageLogicBase
AUTO_PROPERTY(QString, labelWaitInfoText)
AUTO_PROPERTY(bool, pushButtonBackFromStartVisible)
AUTO_PROPERTY(QString, privateKeyPassphrase);
READONLY_PROPERTY(QRegularExpression, ipAddressPortRegex)
public:
Q_INVOKABLE void onUpdatePage() override;
@ -47,5 +49,8 @@ public:
explicit StartPageLogic(UiLogic *uiLogic, QObject *parent = nullptr);
~StartPageLogic() = default;
signals:
void showPassphraseRequestMessage();
void passphraseDialogClosed();
};
#endif // START_PAGE_LOGIC_H

View file

@ -112,15 +112,16 @@ void CloakLogic::onPushButtonSaveClicked()
progressBarFunc.setTextVisibleFunc(true);
progressBarFunc.setTextFunc(QString("Configuring..."));
ErrorCode e = uiLogic()->pageLogic<ServerConfiguringProgressLogic>()->doInstallAction([this, containerConfig, &newContainerConfig](){
return m_serverController->updateContainer(m_settings->serverCredentials(uiLogic()->m_selectedServerIndex),
uiLogic()->m_selectedDockerContainer,
containerConfig,
newContainerConfig);
},
pageFunc, progressBarFunc,
saveButtonFunc, waitInfoFunc,
busyInfoFuncy, cancelButtonFunc);
auto installAction = [this, containerConfig, &newContainerConfig]() {
ServerController serverController(m_settings);
return serverController.updateContainer(m_settings->serverCredentials(uiLogic()->m_selectedServerIndex),
uiLogic()->m_selectedDockerContainer, containerConfig, newContainerConfig);
};
ErrorCode e = uiLogic()->pageLogic<ServerConfiguringProgressLogic>()->doInstallAction(installAction, pageFunc, progressBarFunc,
saveButtonFunc, waitInfoFunc,
busyInfoFuncy, cancelButtonFunc);
if (!e) {
m_settings->setContainerConfig(uiLogic()->m_selectedServerIndex, uiLogic()->m_selectedDockerContainer, newContainerConfig);

View file

@ -162,15 +162,16 @@ void OpenVpnLogic::onPushButtonSaveClicked()
progressBarFunc.setTextVisibleFunc(true);
progressBarFunc.setTextFunc(QString("Configuring..."));
ErrorCode e = uiLogic()->pageLogic<ServerConfiguringProgressLogic>()->doInstallAction([this, containerConfig, &newContainerConfig](){
return m_serverController->updateContainer(m_settings->serverCredentials(uiLogic()->m_selectedServerIndex),
uiLogic()->m_selectedDockerContainer,
containerConfig,
newContainerConfig);
},
pageFunc, progressBarFunc,
saveButtonFunc, waitInfoFunc,
busyInfoFuncy, cancelButtonFunc);
auto installAction = [this, containerConfig, &newContainerConfig]() {
ServerController serverController(m_settings);
return serverController.updateContainer(m_settings->serverCredentials(uiLogic()->m_selectedServerIndex),
uiLogic()->m_selectedDockerContainer, containerConfig, newContainerConfig);
};
ErrorCode e = uiLogic()->pageLogic<ServerConfiguringProgressLogic>()->doInstallAction(installAction, pageFunc, progressBarFunc,
saveButtonFunc, waitInfoFunc,
busyInfoFuncy, cancelButtonFunc);
if (!e) {
m_settings->setContainerConfig(uiLogic()->m_selectedServerIndex, uiLogic()->m_selectedDockerContainer, newContainerConfig);

View file

@ -104,15 +104,15 @@ void ShadowSocksLogic::onPushButtonSaveClicked()
progressBarFunc.setTextVisibleFunc(true);
progressBarFunc.setTextFunc(QString("Configuring..."));
ErrorCode e = uiLogic()->pageLogic<ServerConfiguringProgressLogic>()->doInstallAction([this, containerConfig, &newContainerConfig](){
return m_serverController->updateContainer(m_settings->serverCredentials(uiLogic()->m_selectedServerIndex),
uiLogic()->m_selectedDockerContainer,
containerConfig,
newContainerConfig);
},
pageFunc, progressBarFunc,
saveButtonFunc, waitInfoFunc,
busyInfoFuncy, cancelButtonFunc);
auto installAction = [this, containerConfig, &newContainerConfig]() {
ServerController serverController(m_settings);
return serverController.updateContainer(m_settings->serverCredentials(uiLogic()->m_selectedServerIndex),
uiLogic()->m_selectedDockerContainer, containerConfig, newContainerConfig);
};
ErrorCode e = uiLogic()->pageLogic<ServerConfiguringProgressLogic>()->doInstallAction(installAction, pageFunc, progressBarFunc,
saveButtonFunc, waitInfoFunc,
busyInfoFuncy, cancelButtonFunc);
if (!e) {
m_settings->setContainerConfig(uiLogic()->m_selectedServerIndex, uiLogic()->m_selectedDockerContainer, newContainerConfig);

View file

@ -0,0 +1,62 @@
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
Popup {
id: root
property alias text: textField.text
property alias placeholderText: textField.placeholderText
property string yesText: "yes"
property string noText: "no"
property var yesFunc
property var noFunc
signal editingFinished()
anchors.centerIn: Overlay.overlay
modal: true
closePolicy: Popup.NoAutoClose
width: parent.width - 20
ColumnLayout {
width: parent.width
TextField {
id: textField
horizontalAlignment: Text.AlignHCenter
Layout.fillWidth: true
font.pixelSize: 16
echoMode: TextInput.Password
}
RowLayout {
Layout.fillWidth: true
BlueButtonType {
id: yesButton
Layout.preferredWidth: parent.width / 2
Layout.fillWidth: true
text: yesText
onClicked: {
root.enabled = false
if (yesFunc && typeof yesFunc === "function") {
yesFunc()
}
root.enabled = true
}
}
BlueButtonType {
id: noButton
Layout.preferredWidth: parent.width / 2
Layout.fillWidth: true
text: noText
onClicked: {
if (noFunc && typeof noFunc === "function") {
noFunc()
}
}
}
}
}
}

View file

@ -0,0 +1,15 @@
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
import PageEnum 1.0
import ProtocolEnum 1.0
import "../"
import "../../Controls"
import "../../Config"
PageBase {
id: root
property var protocol: ProtocolEnum.Any
page: PageEnum.ClientInfo
logic: ClientInfoLogic
}

View file

@ -0,0 +1,115 @@
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
import ProtocolEnum 1.0
import "../"
import "../../Controls"
import "../../Config"
PageClientInfoBase {
id: root
protocol: ProtocolEnum.OpenVpn
BackButton {
id: back
enabled: !ClientInfoLogic.busyIndicatorIsRunning
}
Caption {
id: caption
text: qsTr("Client Info")
}
BusyIndicator {
z: 99
anchors.horizontalCenter: parent.horizontalCenter
anchors.verticalCenter: parent.verticalCenter
visible: ClientInfoLogic.busyIndicatorIsRunning
running: ClientInfoLogic.busyIndicatorIsRunning
}
FlickableType {
id: fl
anchors.top: caption.bottom
contentHeight: content.height
visible: ClientInfoLogic.pageContentVisible
ColumnLayout {
id: content
anchors.top: parent.top
anchors.left: parent.left
anchors.right: parent.right
anchors.rightMargin: GC.defaultMargin
LabelType {
enabled: !ClientInfoLogic.busyIndicatorIsRunning
Layout.fillWidth: true
font.pixelSize: 20
horizontalAlignment: Text.AlignHCenter
text: ClientInfoLogic.labelCurrentVpnProtocolText
}
LabelType {
enabled: !ClientInfoLogic.busyIndicatorIsRunning
height: 21
text: qsTr("Client name")
}
TextFieldType {
enabled: !ClientInfoLogic.busyIndicatorIsRunning
Layout.fillWidth: true
Layout.preferredHeight: 31
text: ClientInfoLogic.lineEditNameAliasText
onEditingFinished: {
if (text !== ClientInfoLogic.lineEditNameAliasText) {
ClientInfoLogic.lineEditNameAliasText = text
ClientInfoLogic.onLineEditNameAliasEditingFinished()
}
}
}
LabelType {
enabled: !ClientInfoLogic.busyIndicatorIsRunning
Layout.topMargin: 20
height: 21
text: qsTr("Certificate id")
}
LabelType {
enabled: !ClientInfoLogic.busyIndicatorIsRunning
Layout.fillWidth: true
horizontalAlignment: Text.AlignHCenter
text: ClientInfoLogic.labelOpenVpnCertId
}
LabelType {
enabled: !ClientInfoLogic.busyIndicatorIsRunning
Layout.topMargin: 20
height: 21
text: qsTr("Certificate")
}
TextAreaType {
enabled: !ClientInfoLogic.busyIndicatorIsRunning
Layout.preferredHeight: 200
Layout.fillWidth: true
textArea.readOnly: true
textArea.wrapMode: TextEdit.WrapAnywhere
textArea.verticalAlignment: Text.AlignTop
textArea.text: ClientInfoLogic.textAreaOpenVpnCertData
}
BlueButtonType {
enabled: !ClientInfoLogic.busyIndicatorIsRunning
Layout.fillWidth: true
Layout.preferredHeight: 41
text: qsTr("Revoke Certificate")
onClicked: {
ClientInfoLogic.onRevokeOpenVpnCertificateClicked()
UiLogic.closePage()
}
}
}
}
}

View file

@ -0,0 +1,100 @@
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
import ProtocolEnum 1.0
import "../"
import "../../Controls"
import "../../Config"
PageClientInfoBase {
id: root
protocol: ProtocolEnum.WireGuard
BackButton {
id: back
enabled: !ClientInfoLogic.busyIndicatorIsRunning
}
Caption {
id: caption
text: qsTr("Client Info")
}
BusyIndicator {
z: 99
anchors.horizontalCenter: parent.horizontalCenter
anchors.verticalCenter: parent.verticalCenter
visible: ClientInfoLogic.busyIndicatorIsRunning
running: ClientInfoLogic.busyIndicatorIsRunning
}
FlickableType {
id: fl
anchors.top: caption.bottom
contentHeight: content.height
ColumnLayout {
id: content
anchors.top: parent.top
anchors.left: parent.left
anchors.right: parent.right
anchors.rightMargin: GC.defaultMargin
LabelType {
enabled: !ClientInfoLogic.busyIndicatorIsRunning
Layout.fillWidth: true
font.pixelSize: 20
horizontalAlignment: Text.AlignHCenter
text: ClientInfoLogic.labelCurrentVpnProtocolText
}
LabelType {
enabled: !ClientInfoLogic.busyIndicatorIsRunning
height: 21
text: qsTr("Client name")
}
TextFieldType {
enabled: !ClientInfoLogic.busyIndicatorIsRunning
Layout.fillWidth: true
Layout.preferredHeight: 31
text: ClientInfoLogic.lineEditNameAliasText
onEditingFinished: {
if (text !== ClientInfoLogic.lineEditNameAliasText) {
ClientInfoLogic.lineEditNameAliasText = text
ClientInfoLogic.onLineEditNameAliasEditingFinished()
}
}
}
LabelType {
enabled: !ClientInfoLogic.busyIndicatorIsRunning
Layout.topMargin: 20
height: 21
text: qsTr("Public Key")
}
TextAreaType {
enabled: !ClientInfoLogic.busyIndicatorIsRunning
Layout.preferredHeight: 200
Layout.fillWidth: true
textArea.readOnly: true
textArea.wrapMode: TextEdit.WrapAnywhere
textArea.verticalAlignment: Text.AlignTop
textArea.text: ClientInfoLogic.textAreaWireGuardKeyData
}
BlueButtonType {
enabled: !ClientInfoLogic.busyIndicatorIsRunning
Layout.fillWidth: true
Layout.preferredHeight: 41
text: qsTr("Revoke Key")
onClicked: {
ClientInfoLogic.onRevokeWireGuardKeyClicked()
UiLogic.closePage()
}
}
}
}
}

View file

@ -0,0 +1,120 @@
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
import QtQuick.Shapes 1.4
import SortFilterProxyModel 0.2
import PageEnum 1.0
import "./"
import "../Controls"
import "../Config"
PageBase {
id: root
page: PageEnum.ClientManagement
logic: ClientManagementLogic
enabled: !ClientManagementLogic.busyIndicatorIsRunning
BackButton {
id: back
}
Caption {
id: caption
text: qsTr("Clients Management")
}
BusyIndicator {
z: 99
anchors.horizontalCenter: parent.horizontalCenter
anchors.verticalCenter: parent.verticalCenter
visible: ClientManagementLogic.busyIndicatorIsRunning
running: ClientManagementLogic.busyIndicatorIsRunning
}
FlickableType {
id: fl
anchors.top: caption.bottom
contentHeight: content.height
Column {
id: content
anchors.top: parent.top
anchors.left: parent.left
anchors.right: parent.right
LabelType {
font.pixelSize: 20
leftPadding: -20
anchors.horizontalCenter: parent.horizontalCenter
horizontalAlignment: Text.AlignHCenter
text: ClientManagementLogic.labelCurrentVpnProtocolText
}
SortFilterProxyModel {
id: proxyClientManagementModel
sourceModel: UiLogic.clientManagementModel
sorters: RoleSorter { roleName: "clientName" }
}
ListView {
id: lv_clients
width: parent.width
implicitHeight: contentHeight + 20
anchors.left: parent.left
anchors.right: parent.right
anchors.leftMargin: 10
anchors.rightMargin: 10
topMargin: 10
spacing: 10
clip: true
model: proxyClientManagementModel
highlightRangeMode: ListView.ApplyRange
highlightMoveVelocity: -1
delegate: Item {
implicitWidth: lv_clients.width
implicitHeight: 60
MouseArea {
id: ms
anchors.fill: parent
hoverEnabled: true
cursorShape: Qt.PointingHandCursor
onClicked: {
ClientManagementLogic.onClientItemClicked(proxyClientManagementModel.mapToSource(index))
}
}
Rectangle {
anchors.fill: parent
gradient: ms.containsMouse ? gradient_containsMouse : gradient_notContainsMouse
LinearGradient {
id: gradient_notContainsMouse
x1: 0 ; y1:0
x2: 0 ; y2: height
stops: [
GradientStop { position: 0.0; color: "#FAFBFE" },
GradientStop { position: 1.0; color: "#ECEEFF" }
]
}
LinearGradient {
id: gradient_containsMouse
x1: 0 ; y1:0
x2: 0 ; y2: height
stops: [
GradientStop { position: 0.0; color: "#FAFBFE" },
GradientStop { position: 1.0; color: "#DCDEDF" }
]
}
}
LabelType {
x: 20
y: 20
font.pixelSize: 20
text: clientName
}
}
}
}
}
}

View file

@ -16,6 +16,7 @@ PageBase {
BackButton {
id: back
}
Caption {
id: caption
text: qsTr("Server settings")
@ -96,8 +97,16 @@ PageBase {
}
BlueButtonType {
Layout.fillWidth: true
Layout.topMargin: 60
Layout.fillWidth: true
text: qsTr("Clients Management")
onClicked: {
UiLogic.goToPage(PageEnum.ClientManagement)
}
}
BlueButtonType {
Layout.fillWidth: true
Layout.topMargin: 10
text: ServerSettingsLogic.pushButtonClearClientCacheText
visible: ServerSettingsLogic.pushButtonClearClientCacheVisible
onClicked: {

View file

@ -10,6 +10,14 @@ PageBase {
page: PageEnum.Start
logic: StartPageLogic
Connections {
target: StartPageLogic
function onShowPassphraseRequestMessage() {
popupWithTextField.open()
}
}
BackButton {
id: back_from_start
visible: pageLoader.depth > 1
@ -325,4 +333,22 @@ PageBase {
}
}
}
PopupWithTextField {
id: popupWithTextField
placeholderText: "Enter private key passphrase"
yesFunc: function() {
editingFinished()
close()
StartPageLogic.passphraseDialogClosed()
text = ""
}
noFunc: function() {
close()
StartPageLogic.passphraseDialogClosed()
}
onEditingFinished: {
StartPageLogic.privateKeyPassphrase = text
}
}
}

View file

@ -12,12 +12,14 @@ import "Controls"
import "Pages"
import "Pages/Protocols"
import "Pages/Share"
import "Pages/ClientInfo"
import "Config"
Window {
property var pages: ({})
property var protocolPages: ({})
property var sharePages: ({})
property var clientInfoPages: ({})
id: root
visible: true
@ -38,6 +40,7 @@ Window {
if (type === PageType.Basic) p_obj = pages[page]
else if (type === PageType.Proto) p_obj = protocolPages[page]
else if (type === PageType.ShareProto) p_obj = sharePages[page]
else if (type === PageType.ClientInfo) p_obj = clientInfoPages[page]
else return
//console.debug("QML gotoPage " + type + " " + page + " " + p_obj)
@ -154,6 +157,19 @@ Window {
}
}
FolderListModel {
id: folderModelClientInfo
folder: "qrc:/ui/qml/Pages/ClientInfo/"
nameFilters: ["*.qml"]
showDirs: false
onStatusChanged: if (status == FolderListModel.Ready) {
for (var i=0; i<folderModelClientInfo.count; i++) {
createPagesObjects(folderModelClientInfo.get(i, "filePath"), PageType.ClientInfo);
}
}
}
function createPagesObjects(file, type) {
if (file.indexOf("Base") !== -1) return; // skip Base Pages
//console.debug("Creating component " + file + " for " + type);
@ -177,6 +193,9 @@ Window {
else if (type === PageType.ShareProto) {
sharePages[obj.protocol] = obj
}
else if (type === PageType.ClientInfo) {
clientInfoPages[obj.protocol] = obj
}
// console.debug("Created component " + component.url + " for " + type);
}
@ -206,7 +225,10 @@ Window {
//console.debug("Qml Connections onGoToShareProtocolPage " + protocol);
root.gotoPage(PageType.ShareProto, protocol, reset, slide)
}
function onGoToClientInfoPage(protocol, reset, slide) {
//console.debug("Qml Connections onGoToClientInfoPage " + protocol);
root.gotoPage(PageType.ClientInfo, protocol, reset, slide)
}
function onClosePage() {
root.close_page()

View file

@ -66,6 +66,8 @@
#include "pages_logic/VpnLogic.h"
#include "pages_logic/WizardLogic.h"
#include "pages_logic/AdvancedServerSettingsLogic.h"
#include "pages_logic/ClientManagementLogic.h"
#include "pages_logic/ClientInfoLogic.h"
#include "pages_logic/protocols/CloakLogic.h"
#include "pages_logic/protocols/OpenVpnLogic.h"
@ -77,16 +79,15 @@ using namespace amnezia;
using namespace PageEnumNS;
UiLogic::UiLogic(std::shared_ptr<Settings> settings, std::shared_ptr<VpnConfigurator> configurator,
std::shared_ptr<ServerController> serverController,
QObject *parent) :
QObject(parent),
m_settings(settings),
m_configurator(configurator),
m_serverController(serverController)
m_configurator(configurator)
{
m_containersModel = new ContainersModel(settings, this);
m_protocolsModel = new ProtocolsModel(settings, this);
m_vpnConnection = new VpnConnection(settings, configurator, serverController);
m_clientManagementModel = new ClientManagementModel(this);
m_vpnConnection = new VpnConnection(settings, configurator);
m_vpnConnection->moveToThread(&m_vpnConnectionThread);
m_vpnConnectionThread.start();
@ -336,7 +337,8 @@ void UiLogic::installServer(QPair<DockerContainer, QJsonObject> &container)
if (!isContainerAlreadyAddedToGui(container.first)) {
progressBarFunc.setTextFunc(QString("Installing %1").arg(ContainerProps::containerToString(container.first)));
auto installAction = [&] () {
return m_serverController->setupContainer(m_installCredentials, container.first, container.second);
ServerController serverController(m_settings);
return serverController.setupContainer(m_installCredentials, container.first, container.second);
};
errorCode = pageLogic<ServerConfiguringProgressLogic>()->doInstallAction(installAction, pageFunc, progressBarFunc,
noButton, waitInfoFunc,
@ -534,6 +536,8 @@ void UiLogic::registerPagesLogic()
registerPageLogic<ViewConfigLogic>();
registerPageLogic<VpnLogic>();
registerPageLogic<WizardLogic>();
registerPageLogic<ClientManagementLogic>();
registerPageLogic<ClientInfoLogic>();
registerPageLogic<AdvancedServerSettingsLogic>();
}
@ -556,7 +560,8 @@ ErrorCode UiLogic::addAlreadyInstalledContainersGui(bool &isServerCreated)
}
QMap<DockerContainer, QJsonObject> installedContainers;
ErrorCode errorCode = m_serverController->getAlreadyInstalledContainers(installCredentials, installedContainers);
ServerController serverController(m_settings);
ErrorCode errorCode = serverController.getAlreadyInstalledContainers(installCredentials, installedContainers);
if (errorCode != ErrorCode::NoError) {
return errorCode;
}
@ -610,3 +615,4 @@ bool UiLogic::isContainerAlreadyAddedToGui(DockerContainer container)
}
return false;
}

View file

@ -19,6 +19,7 @@
#include "models/containers_model.h"
#include "models/protocols_model.h"
#include "models/clientManagementModel.h"
#include "notificationhandler.h"
@ -43,6 +44,8 @@ class StartPageLogic;
class ViewConfigLogic;
class VpnLogic;
class WizardLogic;
class ClientManagementLogic;
class ClientInfoLogic;
class AdvancedServerSettingsLogic;
class PageProtocolLogicBase;
@ -63,14 +66,13 @@ class UiLogic : public QObject
AUTO_PROPERTY(bool, pageEnabled)
AUTO_PROPERTY(int, pagesStackDepth)
AUTO_PROPERTY(int, currentPageValue)
AUTO_PROPERTY(QString, popupWarningText)
READONLY_PROPERTY(QObject *, containersModel)
READONLY_PROPERTY(QObject *, protocolsModel)
READONLY_PROPERTY(QObject *, clientManagementModel)
public:
explicit UiLogic(std::shared_ptr<Settings> settings, std::shared_ptr<VpnConfigurator> configurator,
std::shared_ptr<ServerController> serverController, QObject *parent = nullptr);
explicit UiLogic(std::shared_ptr<Settings> settings, std::shared_ptr<VpnConfigurator> configurator, QObject *parent = nullptr);
~UiLogic();
void showOnStartup();
@ -90,6 +92,8 @@ public:
friend class ViewConfigLogic;
friend class VpnLogic;
friend class WizardLogic;
friend class ClientManagementLogic;
friend class ClientInfoLogic;
friend class AdvancedServerSettingsLogic;
friend class PageProtocolLogicBase;
@ -131,6 +135,7 @@ signals:
void goToPage(PageEnumNS::Page page, bool reset = true, bool slide = true);
void goToProtocolPage(Proto protocol, bool reset = true, bool slide = true);
void goToShareProtocolPage(Proto protocol, bool reset = true, bool slide = true);
void goToClientInfoPage(Proto protocol, bool reset = true, bool slide = true);
void closePage();
void setStartPage(PageEnumNS::Page page, bool slide = true);
@ -187,7 +192,6 @@ private:
std::shared_ptr<Settings> m_settings;
std::shared_ptr<VpnConfigurator> m_configurator;
std::shared_ptr<ServerController> m_serverController;
NotificationHandler* m_notificationHandler;