Merge branch 'dev' into refactoring/android

This commit is contained in:
albexk 2023-12-26 18:23:53 +03:00
commit e605f549bd
10 changed files with 128 additions and 37 deletions

View file

@ -322,12 +322,15 @@ void AmneziaApplication::initModels()
m_clientManagementModel.reset(new ClientManagementModel(m_settings, this));
m_engine->rootContext()->setContextProperty("ClientManagementModel", m_clientManagementModel.get());
connect(m_clientManagementModel.get(), &ClientManagementModel::adminConfigRevoked,
m_serversModel.get(), &ServersModel::clearCachedProfile);
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);
emit m_configurator->clientModelUpdated();
});
}

View file

@ -46,6 +46,7 @@ public:
signals:
void newVpnConfigCreated(const QString &clientId, const QString &clientName, const DockerContainer container,
ServerCredentials credentials);
void clientModelUpdated();
};
#endif // VPN_CONFIGURATOR_H

View file

@ -92,7 +92,7 @@
<message>
<location filename="../ui/qml/Components/ConnectionTypeSelectionDrawer.qml" line="38"/>
<source>Configure your server</source>
<translation>Настроить ваш сервер</translation>
<translation>Настроить свой сервер</translation>
</message>
<message>
<location filename="../ui/qml/Components/ConnectionTypeSelectionDrawer.qml" line="52"/>
@ -174,7 +174,7 @@
<location filename="../ui/controllers/installController.cpp" line="149"/>
<source>
Added containers that were already installed on the server</source>
<translation type="unfinished"></translation>
<translation type="unfinished">Добавлены сервисы и протоколы, которые были ранее установлены на сервер</translation>
</message>
<message>
<location filename="../ui/controllers/installController.cpp" line="213"/>
@ -196,7 +196,7 @@ Already installed containers were found on the server. All installed containers
<message>
<location filename="../ui/controllers/installController.cpp" line="315"/>
<source>All containers from server &apos;%1&apos; have been removed</source>
<translation>Все протоклы и сервисы были удалены с сервера &apos;%1&apos;</translation>
<translation>Все протоколы и сервисы были удалены с сервера &apos;%1&apos;</translation>
</message>
<message>
<location filename="../ui/controllers/installController.cpp" line="332"/>
@ -1012,17 +1012,17 @@ Already installed containers were found on the server. All installed containers
<message>
<location filename="../ui/qml/Pages2/PageSettingsApplication.qml" line="52"/>
<source>Allow application screenshots</source>
<translation type="unfinished"></translation>
<translation type="unfinished">Разрешить скриншоты приложения</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSettingsApplication.qml" line="72"/>
<source>Auto start</source>
<translation type="unfinished"></translation>
<translation type="unfinished">Автозапуск</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSettingsApplication.qml" line="73"/>
<source>Launch the application every time the device is starts</source>
<translation type="unfinished"></translation>
<translation type="unfinished">Открывать приложение при запуске устройства</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSettingsApplication.qml" line="93"/>
@ -1353,7 +1353,7 @@ Already installed containers were found on the server. All installed containers
<message>
<location filename="../ui/qml/Pages2/PageSettingsServerData.qml" line="91"/>
<source>Clear cached profiles?</source>
<translation>Удалить кэш Amnezia с сервера?</translation>
<translation>Удалить кэш Amnezia?</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSettingsServerData.qml" line="25"/>
@ -1680,7 +1680,7 @@ and will not be shared or disclosed to the Amnezia or any third parties</source>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="120"/>
<source>All data you enter will remain strictly confidential and will not be shared or disclosed to the Amnezia or any third parties</source>
<translation type="unfinished"></translation>
<translation type="unfinished">Все введенные вами данные останутся строго конфиденциальными и не будут переданы или раскрыты Amnezia или третьим лицам</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="129"/>
@ -1703,7 +1703,7 @@ and will not be shared or disclosed to the Amnezia or any third parties</source>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardEasy.qml" line="67"/>
<source>What is the level of internet control in your region?</source>
<translation>Какой уровень контроля интеренета в вашем регионе?</translation>
<translation>Какой уровень контроля интернета в вашем регионе?</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardEasy.qml" line="137"/>
@ -1978,12 +1978,12 @@ and will not be shared or disclosed to the Amnezia or any third parties</source>
<message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="68"/>
<source>Save ShadowSocks config</source>
<translation type="unfinished"></translation>
<translation type="unfinished">Сохранить конфигурацию ShadowSocks</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="75"/>
<source>Save Cloak config</source>
<translation type="unfinished"></translation>
<translation type="unfinished">Сохранить конфигурацию Cloak</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="105"/>
@ -1993,12 +1993,12 @@ and will not be shared or disclosed to the Amnezia or any third parties</source>
<message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="120"/>
<source>ShadowSocks native format</source>
<translation type="unfinished"></translation>
<translation type="unfinished">ShadowSocks нативный формат</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="125"/>
<source>Cloak native format</source>
<translation type="unfinished"></translation>
<translation type="unfinished">Cloak нативный формат</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="150"/>
@ -2008,23 +2008,23 @@ and will not be shared or disclosed to the Amnezia or any third parties</source>
<message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="178"/>
<source>Share full access to the server and VPN</source>
<translation type="unfinished"></translation>
<translation type="unfinished">Поделиться полным доступом к серверу</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="179"/>
<source>Use for your own devices, or share with those you trust to manage the server.</source>
<translation type="unfinished"></translation>
<translation type="unfinished">Используйте для собственных устройств или передайте управление сервером тем, кому вы доверяете.</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="231"/>
<location filename="../ui/qml/Pages2/PageShare.qml" line="483"/>
<source>Users</source>
<translation type="unfinished"></translation>
<translation type="unfinished">Пользователи</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="262"/>
<source>User name</source>
<translation type="unfinished"></translation>
<translation type="unfinished">Имя пользователя</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="499"/>
@ -2059,7 +2059,7 @@ and will not be shared or disclosed to the Amnezia or any third parties</source>
<message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="664"/>
<source>The user will no longer be able to connect to your server.</source>
<translation type="unfinished"></translation>
<translation type="unfinished">Пользователь больше не сможет подключаться к вашему серверу</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="665"/>
@ -2104,24 +2104,24 @@ and will not be shared or disclosed to the Amnezia or any third parties</source>
<message>
<location filename="../ui/qml/Pages2/PageShareFullAccess.qml" line="49"/>
<source>Full access to the server and VPN</source>
<translation type="unfinished"></translation>
<translation type="unfinished">Полный доступ к серверу и VPN</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageShareFullAccess.qml" line="57"/>
<source>We recommend that you use full access to the server only for your own additional devices.
</source>
<translation type="unfinished"></translation>
<translation type="unfinished">Мы рекомендуем использовать полный доступ к серверу только для собственных устройств.</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageShareFullAccess.qml" line="58"/>
<source>If you share full access with other people, they can remove and add protocols and services to the server, which will cause the VPN to work incorrectly for all users. </source>
<translation type="unfinished"></translation>
<translation type="unfinished">Если вы поделитесь полным доступом с другими людьми, то они смогут удалять и добавлять протоколы и сервисы на сервер, что приведет к некорректной работе VPN для всех пользователей.</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageShareFullAccess.qml" line="73"/>
<location filename="../ui/qml/Pages2/PageShareFullAccess.qml" line="74"/>
<source>Server</source>
<translation type="unfinished"></translation>
<translation type="unfinished">Сервер</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageShareFullAccess.qml" line="102"/>
@ -2537,7 +2537,7 @@ and will not be shared or disclosed to the Amnezia or any third parties</source>
<message>
<location filename="../core/errorstrings.cpp" line="60"/>
<source>The config does not contain any containers and credentials for connecting to the server</source>
<translation type="unfinished"></translation>
<translation type="unfinished">Конфиг не содержит контейнеров и учетных данных для подключения к серверу</translation>
</message>
<message>
<source>Failed to save config to disk</source>
@ -2814,7 +2814,7 @@ This means that AmneziaWG keeps the fast performance of the original while addin
<message>
<location filename="../containers/containers_defs.cpp" line="216"/>
<source>Sftp file sharing service - is secure FTP service</source>
<translation>Сервис обмена файлами Sftp - безопасный FTP-сервис</translation>
<translation>Файловое хранилище для безопасного хранения данных</translation>
</message>
<message>
<location filename="../protocols/protocols_defs.cpp" line="77"/>
@ -2959,7 +2959,7 @@ This means that AmneziaWG keeps the fast performance of the original while addin
<message>
<location filename="../ui/qml/Components/ShareConnectionDrawer.qml" line="150"/>
<source>Show connection settings</source>
<translation type="unfinished"></translation>
<translation type="unfinished">Показать настройки подключения</translation>
</message>
<message>
<location filename="../ui/qml/Components/ShareConnectionDrawer.qml" line="280"/>

View file

@ -48,6 +48,22 @@ void ExportController::generateFullAccessConfig()
int serverIndex = m_serversModel->getCurrentlyProcessedServerIndex();
QJsonObject config = m_settings->server(serverIndex);
QJsonArray containers = config.value(config_key::containers).toArray();
for (auto i = 0; i < containers.size(); i++) {
auto containerConfig = containers.at(i).toObject();
auto containerType = ContainerProps::containerFromString(containerConfig.value(config_key::container).toString());
for (auto protocol : ContainerProps::protocolsForContainer(containerType)) {
auto protocolConfig = containerConfig.value(ProtocolProps::protoToString(protocol)).toObject();
protocolConfig.remove(config_key::last_config);
containerConfig[ProtocolProps::protoToString(protocol)] = protocolConfig;
}
containers.replace(i, containerConfig);
}
config[config_key::containers] = containers;
QByteArray compressedConfig = QJsonDocument(config).toJson();
compressedConfig = qCompress(compressedConfig, 8);
m_config = QString("vpn://%1")

View file

@ -15,6 +15,7 @@ namespace
constexpr char clientName[] = "clientName";
constexpr char container[] = "container";
constexpr char userData[] = "userData";
constexpr char creationDate[] = "creationDate";
}
}
@ -40,11 +41,29 @@ QVariant ClientManagementModel::data(const QModelIndex &index, int role) const
switch (role) {
case ClientNameRole: return userData.value(configKey::clientName).toString();
case CreationDateRole: return userData.value(configKey::creationDate).toString();
}
return QVariant();
}
void ClientManagementModel::migration(const QByteArray &clientsTableString)
{
QJsonObject clientsTable = QJsonDocument::fromJson(clientsTableString).object();
for (auto &clientId : clientsTable.keys()) {
QJsonObject client;
client[configKey::clientId] = clientId;
QJsonObject userData;
userData[configKey::clientName] = clientsTable.value(clientId).toObject().value(configKey::clientName);
client[configKey::userData] = userData;
m_clientsTable.push_back(client);
}
}
ErrorCode ClientManagementModel::updateModel(DockerContainer container, ServerCredentials credentials)
{
beginResetModel();
@ -54,8 +73,14 @@ ErrorCode ClientManagementModel::updateModel(DockerContainer container, ServerCr
ErrorCode error = ErrorCode::NoError;
const QString clientsTableFile =
QString("/opt/amnezia/%1/clientsTable").arg(ContainerProps::containerTypeToString(container));
QString clientsTableFile = QString("/opt/amnezia/%1/clientsTable");
if (container == DockerContainer::OpenVpn || container == DockerContainer::ShadowSocks
|| container == DockerContainer::Cloak) {
clientsTableFile = clientsTableFile.arg(ContainerProps::containerTypeToString(DockerContainer::OpenVpn));
} else {
clientsTableFile = clientsTableFile.arg(ContainerProps::containerTypeToString(container));
}
const QByteArray clientsTableString =
serverController.getTextFileFromContainer(container, credentials, clientsTableFile, &error);
if (error != ErrorCode::NoError) {
@ -67,6 +92,8 @@ ErrorCode ClientManagementModel::updateModel(DockerContainer container, ServerCr
m_clientsTable = QJsonDocument::fromJson(clientsTableString).array();
if (m_clientsTable.isEmpty()) {
migration(clientsTableString);
int count = 0;
if (container == DockerContainer::OpenVpn || container == DockerContainer::ShadowSocks
@ -200,19 +227,20 @@ ErrorCode ClientManagementModel::appendClient(const QString &clientId, const QSt
for (int i = 0; i < m_clientsTable.size(); i++) {
if (m_clientsTable.at(i).toObject().value(configKey::clientId) == clientId) {
return renameClient(i, clientName, container, credentials);
return renameClient(i, clientName, container, credentials, true);
}
}
beginResetModel();
beginInsertRows(QModelIndex(), rowCount(), 1);
QJsonObject client;
client[configKey::clientId] = clientId;
QJsonObject userData;
userData[configKey::clientName] = clientName;
userData[configKey::creationDate] = QDateTime::currentDateTime().toString();
client[configKey::userData] = userData;
m_clientsTable.push_back(client);
endResetModel();
endInsertRows();
const QByteArray clientsTableString = QJsonDocument(m_clientsTable).toJson();
@ -229,11 +257,14 @@ ErrorCode ClientManagementModel::appendClient(const QString &clientId, const QSt
}
ErrorCode ClientManagementModel::renameClient(const int row, const QString &clientName, const DockerContainer container,
ServerCredentials credentials)
ServerCredentials credentials, bool addTimeStamp)
{
auto client = m_clientsTable.at(row).toObject();
auto userData = client[configKey::userData].toObject();
userData[configKey::clientName] = clientName;
if (addTimeStamp) {
userData[configKey::creationDate] = QDateTime::currentDateTime().toString();
}
client[configKey::userData] = userData;
m_clientsTable.replace(row, client);
@ -257,13 +288,33 @@ ErrorCode ClientManagementModel::renameClient(const int row, const QString &clie
ErrorCode ClientManagementModel::revokeClient(const int row, const DockerContainer container,
ServerCredentials credentials)
{
ErrorCode errorCode = ErrorCode::NoError;
if (container == DockerContainer::OpenVpn || container == DockerContainer::ShadowSocks
|| container == DockerContainer::Cloak) {
return revokeOpenVpn(row, container, credentials);
errorCode = revokeOpenVpn(row, container, credentials);
} else if (container == DockerContainer::WireGuard || container == DockerContainer::Awg) {
return revokeWireGuard(row, container, credentials);
errorCode = revokeWireGuard(row, container, credentials);
}
return ErrorCode::NoError;
if (errorCode == ErrorCode::NoError) {
auto client = m_clientsTable.at(row).toObject();
QString clientId = client.value(configKey::clientId).toString();
const auto server = m_settings->defaultServer();
QJsonArray containers = server.value(config_key::containers).toArray();
for (auto i = 0; i < containers.size(); i++) {
auto containerConfig = containers.at(i).toObject();
auto containerType = ContainerProps::containerFromString(containerConfig.value(config_key::container).toString());
auto protocolConfig = containerConfig.value(ContainerProps::containerTypeToString(containerType)).toObject();
if (protocolConfig.value(config_key::last_config).toString().contains(clientId)) {
emit adminConfigRevoked(container);
}
}
}
return errorCode;
}
ErrorCode ClientManagementModel::revokeOpenVpn(const int row, const DockerContainer container,
@ -369,5 +420,6 @@ QHash<int, QByteArray> ClientManagementModel::roleNames() const
{
QHash<int, QByteArray> roles;
roles[ClientNameRole] = "clientName";
roles[CreationDateRole] = "creationDate";
return roles;
}

View file

@ -14,6 +14,7 @@ class ClientManagementModel : public QAbstractListModel
public:
enum Roles {
ClientNameRole = Qt::UserRole + 1,
CreationDateRole
};
ClientManagementModel(std::shared_ptr<Settings> settings, QObject *parent = nullptr);
@ -26,15 +27,20 @@ public slots:
ErrorCode appendClient(const QString &clientId, const QString &clientName, const DockerContainer container,
ServerCredentials credentials);
ErrorCode renameClient(const int row, const QString &userName, const DockerContainer container,
ServerCredentials credentials);
ServerCredentials credentials, bool addTimeStamp = false);
ErrorCode revokeClient(const int index, const DockerContainer container, ServerCredentials credentials);
protected:
QHash<int, QByteArray> roleNames() const override;
signals:
void adminConfigRevoked(const DockerContainer container);
private:
bool isClientExists(const QString &clientId);
void migration(const QByteArray &clientsTableString);
ErrorCode revokeOpenVpn(const int row, const DockerContainer container, ServerCredentials credentials);
ErrorCode revokeWireGuard(const int row, const DockerContainer container, ServerCredentials credentials);

View file

@ -479,6 +479,14 @@ void ServersModel::clearCachedProfiles()
updateContainersModel();
}
void ServersModel::clearCachedProfile(const DockerContainer container)
{
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();

View file

@ -84,6 +84,7 @@ public slots:
void addContainerConfig(const int containerIndex, const QJsonObject config);
void clearCachedProfiles();
void clearCachedProfile(const DockerContainer container);
ErrorCode removeContainer(const int containerIndex);
ErrorCode removeAllContainers();

View file

@ -581,7 +581,7 @@ PageType {
Layout.bottomMargin: 24
headerText: clientName
descriptionText: serverSelector.text
descriptionText: qsTr("Creation date: ") + creationDate
}
BasicButtonType {

View file

@ -4,6 +4,7 @@
#include <QFile>
#include <QHostInfo>
#include <QJsonObject>
#include <QEventLoop>
#include <configurators/cloak_configurator.h>
#include <configurators/openvpn_configurator.h>
@ -250,7 +251,10 @@ QString VpnConnection::createVpnConfigurationForProto(int serverIndex, const Ser
m_settings->setProtocolConfig(serverIndex, container, proto, protoObject);
}
emit m_configurator->newVpnConfigCreated(clientId, "unnamed client", container, credentials);
QEventLoop wait;
emit m_configurator->newVpnConfigCreated(clientId, QString("Admin [%1]").arg(QSysInfo::prettyProductName()), container, credentials);
QObject::connect(m_configurator.get(), &VpnConfigurator::clientModelUpdated, &wait, &QEventLoop::quit);
wait.exec();
}
return configData;