diff --git a/client/core/servercontroller.cpp b/client/core/servercontroller.cpp index 6140bbce..e14032c7 100644 --- a/client/core/servercontroller.cpp +++ b/client/core/servercontroller.cpp @@ -804,10 +804,10 @@ ErrorCode ServerController::getClientsList(const ServerCredentials &credentials, stdOut += data + "\n"; }; - auto mainProtocolString = ProtocolProps::protoToString(mainProtocol); + const QString mainProtocolString = ProtocolProps::protoToString(mainProtocol); - const QString clientsTableFile = QString("opt/amnezia/%1/clientsTable").arg(mainProtocolString); - QByteArray clientsTableString = getTextFileFromContainer(container, credentials, clientsTableFile, &error); + const QString clientsTableFile = QString("/opt/amnezia/%1/clientsTable").arg(mainProtocolString); + const QByteArray clientsTableString = getTextFileFromContainer(container, credentials, clientsTableFile, &error); if (error != ErrorCode::NoError) { return error; } @@ -847,7 +847,7 @@ ErrorCode ServerController::getClientsList(const ServerCredentials &credentials, } } else if (mainProtocol == Proto::WireGuard) { const QString wireGuardConfigFile = "opt/amnezia/wireguard/wg0.conf"; - QString wireguardConfigString = getTextFileFromContainer(container, credentials, wireGuardConfigFile, &error); + const QString wireguardConfigString = getTextFileFromContainer(container, credentials, wireGuardConfigFile, &error); if (error != ErrorCode::NoError) { return error; } @@ -872,7 +872,7 @@ ErrorCode ServerController::getClientsList(const ServerCredentials &credentials, } } - QByteArray newClientsTableString = QJsonDocument(clientsTable).toJson(); + const QByteArray newClientsTableString = QJsonDocument(clientsTable).toJson(); if (clientsTableString != newClientsTableString) { error = uploadTextFileToContainer(container, credentials, newClientsTableString, clientsTableFile); } @@ -886,9 +886,9 @@ ErrorCode ServerController::getClientsList(const ServerCredentials &credentials, return error; } -ErrorCode ServerController::setClientsList(const ServerCredentials &credentials, DockerContainer container, Proto mainProtocol, QJsonObject &clietns) +ErrorCode ServerController::setClientsList(const ServerCredentials &credentials, DockerContainer container, Proto mainProtocol, const QJsonObject &clietns) { - auto mainProtocolString = ProtocolProps::protoToString(mainProtocol); + const QString mainProtocolString = ProtocolProps::protoToString(mainProtocol); const QString clientsTableFile = QString("opt/amnezia/%1/clientsTable").arg(mainProtocolString); ErrorCode error = uploadTextFileToContainer(container, credentials, QJsonDocument(clietns).toJson(), clientsTableFile); return error; diff --git a/client/core/servercontroller.h b/client/core/servercontroller.h index 11d0dee9..d85520d0 100644 --- a/client/core/servercontroller.h +++ b/client/core/servercontroller.h @@ -74,8 +74,9 @@ public: QSsh::SshConnection *connectToHost(const QSsh::SshConnectionParameters &sshParams); ErrorCode getClientsList(const ServerCredentials &credentials, DockerContainer container, Proto mainProtocol, QJsonObject &clietns); - ErrorCode setClientsList(const ServerCredentials &credentials, DockerContainer container, Proto mainProtocol, QJsonObject &clietns); + ErrorCode setClientsList(const ServerCredentials &credentials, DockerContainer container, Proto mainProtocol, const QJsonObject &clietns); + ErrorCode startupContainerWorker(const ServerCredentials &credentials, DockerContainer container, const QJsonObject &config = QJsonObject()); private: ErrorCode installDockerWorker(const ServerCredentials &credentials, DockerContainer container); @@ -83,7 +84,6 @@ private: ErrorCode buildContainerWorker(const ServerCredentials &credentials, DockerContainer container, const QJsonObject &config = QJsonObject()); ErrorCode runContainerWorker(const ServerCredentials &credentials, DockerContainer container, QJsonObject &config); ErrorCode configureContainerWorker(const ServerCredentials &credentials, DockerContainer container, QJsonObject &config); - ErrorCode startupContainerWorker(const ServerCredentials &credentials, DockerContainer container, const QJsonObject &config = QJsonObject()); std::shared_ptr m_settings; std::shared_ptr m_configurator; diff --git a/client/protocols/protocols_defs.h b/client/protocols/protocols_defs.h index c5f15d5b..1f890f4c 100644 --- a/client/protocols/protocols_defs.h +++ b/client/protocols/protocols_defs.h @@ -77,6 +77,7 @@ constexpr char defaultSubnetAddress[] = "10.8.0.0"; constexpr char defaultSubnetMask[] = "255.255.255.0"; constexpr char defaultSubnetCidr[] = "24"; +constexpr char serverConfigPath[] = "/opt/amnezia/openvpn/server.conf"; constexpr char caCertPath[] = "/opt/amnezia/openvpn/pki/ca.crt"; constexpr char clientCertPath[] = "/opt/amnezia/openvpn/pki/issued"; constexpr char taKeyPath[] = "/opt/amnezia/openvpn/ta.key"; diff --git a/client/ui/models/clientManagementModel.cpp b/client/ui/models/clientManagementModel.cpp index 768adaef..28e9d3c2 100644 --- a/client/ui/models/clientManagementModel.cpp +++ b/client/ui/models/clientManagementModel.cpp @@ -85,6 +85,14 @@ void ClientManagementModel::setData(const QModelIndex &index, QVariant data, int } } +bool ClientManagementModel::removeRows(int row) +{ + beginRemoveRows(QModelIndex(), row, row); + m_content.removeAt(row); + endRemoveRows(); + return true; +} + QHash ClientManagementModel::roleNames() const { QHash roles; diff --git a/client/ui/models/clientManagementModel.h b/client/ui/models/clientManagementModel.h index e8678baf..c3ced1c5 100644 --- a/client/ui/models/clientManagementModel.h +++ b/client/ui/models/clientManagementModel.h @@ -25,6 +25,7 @@ public: 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 roleNames() const override; diff --git a/client/ui/pages_logic/ClientInfoLogic.cpp b/client/ui/pages_logic/ClientInfoLogic.cpp index 503d91f4..8a4237b9 100644 --- a/client/ui/pages_logic/ClientInfoLogic.cpp +++ b/client/ui/pages_logic/ClientInfoLogic.cpp @@ -8,6 +8,17 @@ #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) { @@ -23,16 +34,16 @@ void ClientInfoLogic::onUpdatePage() { set_busyIndicatorIsRunning(false); - DockerContainer selectedContainer = m_settings->defaultContainer(uiLogic()->selectedServerIndex); - QString selectedContainerName = ContainerProps::containerHumanNames().value(selectedContainer); - set_labelCurrentVpnProtocolText(tr("Service: ") + selectedContainerName); + const DockerContainer container = m_settings->defaultContainer(uiLogic()->selectedServerIndex); + const QString containerNameString = ContainerProps::containerHumanNames().value(container); + set_labelCurrentVpnProtocolText(tr("Service: ") + containerNameString); - auto protocols = ContainerProps::protocolsForContainer(selectedContainer); + const QVector protocols = ContainerProps::protocolsForContainer(container); if (!protocols.empty()) { - auto currentMainProtocol = protocols.front(); + const Proto currentMainProtocol = protocols.front(); auto model = qobject_cast(uiLogic()->clientManagementModel()); - auto modelIndex = model->index(m_currentClientIndex); + const QModelIndex modelIndex = model->index(m_currentClientIndex); set_lineEditNameAliasText(model->data(modelIndex, ClientManagementModel::ClientRoles::NameRole).toString()); if (currentMainProtocol == Proto::OpenVpn) { @@ -49,23 +60,19 @@ void ClientInfoLogic::onLineEditNameAliasEditingFinished() set_busyIndicatorIsRunning(true); auto model = qobject_cast(uiLogic()->clientManagementModel()); - auto modelIndex = model->index(m_currentClientIndex); + const QModelIndex modelIndex = model->index(m_currentClientIndex); model->setData(modelIndex, m_lineEditNameAliasText, ClientManagementModel::ClientRoles::NameRole); - - DockerContainer selectedContainer = m_settings->defaultContainer(uiLogic()->selectedServerIndex); - auto protocols = ContainerProps::protocolsForContainer(selectedContainer); + const DockerContainer selectedContainer = m_settings->defaultContainer(uiLogic()->selectedServerIndex); + const QVector protocols = ContainerProps::protocolsForContainer(selectedContainer); if (!protocols.empty()) { - auto currentMainProtocol = protocols.front(); - auto clientsTable = model->getContent(currentMainProtocol); + const Proto currentMainProtocol = protocols.front(); + const QJsonObject clientsTable = model->getContent(currentMainProtocol); ErrorCode error = m_serverController->setClientsList(m_settings->serverCredentials(uiLogic()->selectedServerIndex), selectedContainer, currentMainProtocol, clientsTable); - if (error != ErrorCode::NoError) { - QMessageBox::warning(nullptr, APPLICATION_NAME, - tr("An error occurred while saving the list of clients.") + "\n" + errorString(error)); - } + isErrorOccured(error); } set_busyIndicatorIsRunning(false); @@ -73,7 +80,50 @@ void ClientInfoLogic::onLineEditNameAliasEditingFinished() void ClientInfoLogic::onRevokeOpenVpnCertificateClicked() { + set_busyIndicatorIsRunning(true); + const DockerContainer container = m_settings->defaultContainer(uiLogic()->selectedServerIndex); + const ServerCredentials credentials = m_settings->serverCredentials(uiLogic()->selectedServerIndex); + auto model = qobject_cast(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); + const QString script = m_serverController->replaceVars(getOpenVpnCertData, + m_serverController->genVarsForScript(credentials, container)); + auto error = m_serverController->runScript(credentials, script); + if (isErrorOccured(error)) { + set_busyIndicatorIsRunning(false); + return; + } + + model->removeRows(m_currentClientIndex); + const QJsonObject clientsTable = model->getContent(Proto::OpenVpn); + error = m_serverController->setClientsList(credentials, container, Proto::OpenVpn, clientsTable); + if (isErrorOccured(error)) { + set_busyIndicatorIsRunning(false); + return; + } + + error = m_serverController->uploadTextFileToContainer(container, credentials, "crl-verify crl.pem\n", + protocols::openvpn::serverConfigPath, + QSsh::SftpOverwriteMode::SftpAppendToExisting); + if (isErrorOccured(error)) { + set_busyIndicatorIsRunning(false); + return; + } + + const QJsonObject &containerConfig = m_settings->containerConfig(uiLogic()->selectedServerIndex, container); + error = m_serverController->startupContainerWorker(credentials, container, containerConfig); + if (isErrorOccured(error)) { + set_busyIndicatorIsRunning(false); + return; + } + set_busyIndicatorIsRunning(false); } void ClientInfoLogic::onRevokeWireGuardKeyClicked() diff --git a/client/ui/qml/Pages/ClientInfo/PageClientInfoOpenVPN.qml b/client/ui/qml/Pages/ClientInfo/PageClientInfoOpenVPN.qml index 57a1f74e..b63519b9 100644 --- a/client/ui/qml/Pages/ClientInfo/PageClientInfoOpenVPN.qml +++ b/client/ui/qml/Pages/ClientInfo/PageClientInfoOpenVPN.qml @@ -115,6 +115,7 @@ PageClientInfoBase { text: qsTr("Revoke Certificate") onClicked: { ClientInfoLogic.onRevokeOpenVpnCertificateClicked() + UiLogic.closePage() } } }