added page to display WireGuard client information
This commit is contained in:
parent
a42beb86c0
commit
8c137ecc52
9 changed files with 216 additions and 76 deletions
|
@ -810,23 +810,26 @@ ErrorCode ServerController::getClientsList(const ServerCredentials &credentials,
|
|||
genVarsForScript(credentials, container)), cbReadStdOut);
|
||||
// TODO error processing
|
||||
if (!stdOut.isEmpty()) {
|
||||
QStringList clietnsNames = stdOut.split("\n", Qt::SkipEmptyParts);
|
||||
clietnsNames.removeAll("AmneziaReq.crt");
|
||||
QStringList certsIds = stdOut.split("\n", Qt::SkipEmptyParts);
|
||||
certsIds.removeAll("AmneziaReq.crt");
|
||||
|
||||
QByteArray clientsTableString = getTextFileFromContainer(container, credentials, "opt/amnezia/openvpn/clientsTable");
|
||||
QJsonObject clientsTable = QJsonDocument::fromJson(clientsTableString).object();
|
||||
for (auto &clietnId : clietnsNames) {
|
||||
clietnId.replace(".crt", "");
|
||||
if (!clientsTable.contains(clietnId)) {
|
||||
int count = 0;
|
||||
for (auto &openvpnCertId : certsIds) {
|
||||
openvpnCertId.replace(".crt", "");
|
||||
if (!clientsTable.contains(openvpnCertId)) {
|
||||
stdOut.clear();
|
||||
error = runScript(credentials,
|
||||
replaceVars(QString("sudo docker exec -i $CONTAINER_NAME bash -c 'cat /opt/amnezia/openvpn/pki/issued/%1.crt'").arg(clietnId),
|
||||
replaceVars(QString("sudo docker exec -i $CONTAINER_NAME bash -c 'cat /opt/amnezia/openvpn/pki/issued/%1.crt'").arg(openvpnCertId),
|
||||
genVarsForScript(credentials, container)), cbReadStdOut);
|
||||
// TODO error processing
|
||||
QJsonObject client;
|
||||
client["name"] = "";
|
||||
client["certificate"] = stdOut;
|
||||
clientsTable[clietnId] = client;
|
||||
client["openvpnCertId"] = openvpnCertId;
|
||||
client["clientName"] = QString("Client %1").arg(count);
|
||||
client["openvpnCertData"] = stdOut;
|
||||
clientsTable[openvpnCertId] = client;
|
||||
count++;
|
||||
}
|
||||
}
|
||||
QByteArray newClientsTableString = QJsonDocument(clientsTable).toJson();
|
||||
|
@ -837,7 +840,33 @@ ErrorCode ServerController::getClientsList(const ServerCredentials &credentials,
|
|||
clietns = clientsTable;
|
||||
}
|
||||
} else if (mainProtocol == Proto::WireGuard) {
|
||||
QString wireguardConfigString = getTextFileFromContainer(container, credentials, "opt/amnezia/wireguard/wg0.conf");
|
||||
|
||||
auto configSections = wireguardConfigString.split("[", Qt::SkipEmptyParts);
|
||||
QJsonObject clientsTable;
|
||||
int count = 0;
|
||||
for (const auto §ion : configSections) {
|
||||
auto configLines = section.split("\n", Qt::SkipEmptyParts);
|
||||
if (!configLines.contains("Peer]")) {
|
||||
continue;
|
||||
}
|
||||
QJsonObject client;
|
||||
for (const auto &line : configLines) {
|
||||
auto configPair = line.split(" = ", Qt::SkipEmptyParts);
|
||||
if (configPair.front() == "# Name") {
|
||||
client["clientName"] = configPair.size() == 2 ? configPair.back() : "";
|
||||
} else if (configPair.front() == "PublicKey") {
|
||||
client["wireguardPublicKey"] = configPair.back();
|
||||
}
|
||||
}
|
||||
if (client["clientName"].isNull()) {
|
||||
client["clientName"] = QString("Client %1").arg(count);
|
||||
count++;
|
||||
}
|
||||
clientsTable[client["wireguardPublicKey"].toString()] = client;
|
||||
}
|
||||
// TODO error processing
|
||||
clietns = clientsTable;
|
||||
}
|
||||
|
||||
return error;
|
||||
|
@ -845,7 +874,12 @@ ErrorCode ServerController::getClientsList(const ServerCredentials &credentials,
|
|||
|
||||
ErrorCode ServerController::setClientsList(const ServerCredentials &credentials, DockerContainer container, Proto mainProtocol, QJsonObject &clietns)
|
||||
{
|
||||
auto error = uploadTextFileToContainer(container, credentials, QJsonDocument(clietns).toJson(), "opt/amnezia/openvpn/clientsTable");
|
||||
ErrorCode error = ErrorCode::NoError;
|
||||
if (mainProtocol == Proto::OpenVpn) {
|
||||
error = uploadTextFileToContainer(container, credentials, QJsonDocument(clietns).toJson(), "opt/amnezia/openvpn/clientsTable");
|
||||
} else if (mainProtocol == Proto::WireGuard) {
|
||||
|
||||
}
|
||||
return error;
|
||||
}
|
||||
|
||||
|
|
|
@ -14,13 +14,22 @@ void ClientManagementModel::clearData()
|
|||
endResetModel();
|
||||
}
|
||||
|
||||
void ClientManagementModel::setContent(const QVector<ClientInfo> &data)
|
||||
void ClientManagementModel::setContent(const QVector<QVariant> &data)
|
||||
{
|
||||
beginResetModel();
|
||||
m_content = data;
|
||||
endResetModel();
|
||||
}
|
||||
|
||||
QJsonObject ClientManagementModel::getContent()
|
||||
{
|
||||
QJsonObject clientsTable;
|
||||
for (const auto &item : m_content) {
|
||||
clientsTable[item.toJsonObject()["openvpnCertId"].toString()] = item.toJsonObject();
|
||||
}
|
||||
return clientsTable;
|
||||
}
|
||||
|
||||
int ClientManagementModel::rowCount(const QModelIndex &parent) const
|
||||
{
|
||||
Q_UNUSED(parent);
|
||||
|
@ -35,14 +44,15 @@ QVariant ClientManagementModel::data(const QModelIndex &index, int role) const
|
|||
}
|
||||
|
||||
if (role == NameRole) {
|
||||
return m_content[index.row()].name;
|
||||
}
|
||||
if (role == CertIdRole) {
|
||||
return m_content[index.row()].certId;
|
||||
}
|
||||
if (role == CertDataRole) {
|
||||
return m_content[index.row()].certData;
|
||||
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();
|
||||
}
|
||||
|
||||
|
@ -53,15 +63,19 @@ void ClientManagementModel::setData(const QModelIndex &index, QVariant data, int
|
|||
return;
|
||||
}
|
||||
|
||||
auto client = m_content[index.row()].toJsonObject();
|
||||
if (role == NameRole) {
|
||||
m_content[index.row()].name = data.toString();
|
||||
}
|
||||
if (role == CertIdRole) {
|
||||
m_content[index.row()].certId = data.toString();
|
||||
}
|
||||
if (role == CertDataRole) {
|
||||
m_content[index.row()].certData = data.toString();
|
||||
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;
|
||||
}
|
||||
m_content[index.row()] = client;
|
||||
emit dataChanged(index, index);
|
||||
}
|
||||
|
||||
|
@ -69,7 +83,8 @@ QHash<int, QByteArray> ClientManagementModel::roleNames() const
|
|||
{
|
||||
QHash<int, QByteArray> roles;
|
||||
roles[NameRole] = "clientName";
|
||||
roles[CertIdRole] = "certId";
|
||||
roles[CertDataRole] = "certData";
|
||||
roles[OpenVpnCertIdRole] = "openvpnCertId";
|
||||
roles[OpenVpnCertDataRole] = "openvpnCertData";
|
||||
roles[WireGuardPublicKey] = "wireguardPublicKey";
|
||||
return roles;
|
||||
}
|
||||
|
|
|
@ -12,21 +12,16 @@ class ClientManagementModel : public QAbstractListModel
|
|||
public:
|
||||
enum ClientRoles {
|
||||
NameRole = Qt::UserRole + 1,
|
||||
CertIdRole,
|
||||
CertDataRole
|
||||
};
|
||||
|
||||
struct ClientInfo
|
||||
{
|
||||
QString name;
|
||||
QString certId;
|
||||
QString certData;
|
||||
OpenVpnCertIdRole,
|
||||
OpenVpnCertDataRole,
|
||||
WireGuardPublicKey,
|
||||
};
|
||||
|
||||
ClientManagementModel(std::shared_ptr<Settings> settings, QObject *parent = nullptr);
|
||||
|
||||
void clearData();
|
||||
void setContent(const QVector<ClientInfo> &data);
|
||||
void setContent(const QVector<QVariant> &data);
|
||||
QJsonObject getContent();
|
||||
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);
|
||||
|
@ -36,7 +31,7 @@ protected:
|
|||
|
||||
private:
|
||||
std::shared_ptr<Settings> m_settings; //TODO remove this?
|
||||
QVector<ClientInfo> m_content;
|
||||
QVector<QVariant> m_content;
|
||||
};
|
||||
|
||||
#endif // CLIENTMANAGEMENTMODEL_H
|
||||
|
|
|
@ -21,11 +21,21 @@ void ClientInfoLogic::onUpdatePage()
|
|||
QString selectedContainerName = ContainerProps::containerHumanNames().value(selectedContainer);
|
||||
set_labelCurrentVpnProtocolText(tr("Service: ") + selectedContainerName);
|
||||
|
||||
auto protocols = ContainerProps::protocolsForContainer(selectedContainer);
|
||||
if (!protocols.empty()) {
|
||||
auto currentMainProtocol = protocols.front();
|
||||
|
||||
auto model = qobject_cast<ClientManagementModel*>(uiLogic()->clientManagementModel());
|
||||
auto modelIndex = model->index(m_currentClientIndex);
|
||||
|
||||
set_lineEditNameAliasText(model->data(modelIndex, ClientManagementModel::ClientRoles::NameRole).toString());
|
||||
set_labelCertId(model->data(modelIndex, ClientManagementModel::ClientRoles::CertIdRole).toString());
|
||||
set_textAreaCertificate(model->data(modelIndex, ClientManagementModel::ClientRoles::CertDataRole).toString());
|
||||
if (currentMainProtocol == Proto::OpenVpn) {
|
||||
set_labelOpenVpnCertId(model->data(modelIndex, ClientManagementModel::ClientRoles::OpenVpnCertIdRole).toString());
|
||||
set_textAreaOpenVpnCertData(model->data(modelIndex, ClientManagementModel::ClientRoles::OpenVpnCertDataRole).toString());
|
||||
} else if (currentMainProtocol == Proto::WireGuard) {
|
||||
set_textAreaWireGuardKeyData(model->data(modelIndex, ClientManagementModel::ClientRoles::WireGuardPublicKey).toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ClientInfoLogic::onLineEditNameAliasEditingFinished()
|
||||
|
@ -34,10 +44,24 @@ void ClientInfoLogic::onLineEditNameAliasEditingFinished()
|
|||
auto modelIndex = model->index(m_currentClientIndex);
|
||||
model->setData(modelIndex, m_lineEditNameAliasText, ClientManagementModel::ClientRoles::NameRole);
|
||||
|
||||
m_serverController->setClientsList();
|
||||
auto clientsTable = model->getContent();
|
||||
DockerContainer selectedContainer = m_settings->defaultContainer(uiLogic()->selectedServerIndex);
|
||||
auto protocols = ContainerProps::protocolsForContainer(selectedContainer);
|
||||
if (!protocols.empty()) {
|
||||
auto currentMainProtocol = protocols.front();
|
||||
m_serverController->setClientsList(m_settings->serverCredentials(uiLogic()->selectedServerIndex),
|
||||
selectedContainer,
|
||||
currentMainProtocol,
|
||||
clientsTable);
|
||||
}
|
||||
}
|
||||
|
||||
void ClientInfoLogic::onRevokeCertificateClicked()
|
||||
void ClientInfoLogic::onRevokeOpenVpnCertificateClicked()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void ClientInfoLogic::onRevokeWireGuardKeyClicked()
|
||||
{
|
||||
|
||||
}
|
||||
|
|
|
@ -10,9 +10,10 @@ class ClientInfoLogic : public PageLogicBase
|
|||
Q_OBJECT
|
||||
|
||||
AUTO_PROPERTY(QString, lineEditNameAliasText)
|
||||
AUTO_PROPERTY(QString, labelCertId)
|
||||
AUTO_PROPERTY(QString, textAreaCertificate)
|
||||
AUTO_PROPERTY(QString, labelOpenVpnCertId)
|
||||
AUTO_PROPERTY(QString, textAreaOpenVpnCertData)
|
||||
AUTO_PROPERTY(QString, labelCurrentVpnProtocolText)
|
||||
AUTO_PROPERTY(QString, textAreaWireGuardKeyData)
|
||||
|
||||
public:
|
||||
ClientInfoLogic(UiLogic *uiLogic, QObject *parent = nullptr);
|
||||
|
@ -23,7 +24,8 @@ public:
|
|||
public slots:
|
||||
void onUpdatePage() override;
|
||||
void onLineEditNameAliasEditingFinished();
|
||||
void onRevokeCertificateClicked();
|
||||
void onRevokeOpenVpnCertificateClicked();
|
||||
void onRevokeWireGuardKeyClicked();
|
||||
|
||||
private:
|
||||
int m_currentClientIndex;
|
||||
|
|
|
@ -13,6 +13,7 @@ ClientManagementLogic::ClientManagementLogic(UiLogic *logic, QObject *parent):
|
|||
|
||||
void ClientManagementLogic::onUpdatePage()
|
||||
{
|
||||
qobject_cast<ClientManagementModel*>(uiLogic()->clientManagementModel())->clearData();
|
||||
DockerContainer selectedContainer = m_settings->defaultContainer(uiLogic()->selectedServerIndex);
|
||||
QString selectedContainerName = ContainerProps::containerHumanNames().value(selectedContainer);
|
||||
set_labelCurrentVpnProtocolText(tr("Service: ") + selectedContainerName);
|
||||
|
@ -26,13 +27,9 @@ void ClientManagementLogic::onUpdatePage()
|
|||
ErrorCode e = m_serverController->getClientsList(m_settings->serverCredentials(uiLogic()->selectedServerIndex),
|
||||
selectedContainer, m_currentMainProtocol, clients);
|
||||
}
|
||||
QVector<ClientManagementModel::ClientInfo> clientsArray;
|
||||
QVector<QVariant> clientsArray;
|
||||
for (auto &clientId : clients.keys()) {
|
||||
ClientManagementModel::ClientInfo clientInfo;
|
||||
clientInfo.certId = clientId;
|
||||
clientInfo.name = clients[clientId].toObject()["name"].toString();
|
||||
clientInfo.certData = clients[clientId].toObject()["certificate"].toString();
|
||||
clientsArray.push_back(clientInfo);
|
||||
clientsArray.push_back(clients[clientId].toObject());
|
||||
}
|
||||
qobject_cast<ClientManagementModel*>(uiLogic()->clientManagementModel())->setContent(clientsArray);
|
||||
}
|
||||
|
|
|
@ -9,7 +9,6 @@ import "../../Config"
|
|||
PageClientInfoBase {
|
||||
id: root
|
||||
protocol: ProtocolEnum.OpenVpn
|
||||
|
||||
BackButton {
|
||||
id: back
|
||||
}
|
||||
|
@ -71,7 +70,7 @@ PageClientInfoBase {
|
|||
LabelType {
|
||||
Layout.fillWidth: true
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
text: ClientInfoLogic.labelCertId
|
||||
text: ClientInfoLogic.labelOpenVpnCertId
|
||||
}
|
||||
|
||||
LabelType {
|
||||
|
@ -87,7 +86,7 @@ PageClientInfoBase {
|
|||
textArea.readOnly: true
|
||||
textArea.wrapMode: TextEdit.WrapAnywhere
|
||||
textArea.verticalAlignment: Text.AlignTop
|
||||
textArea.text: ClientInfoLogic.textAreaCertificate
|
||||
textArea.text: ClientInfoLogic.textAreaOpenVpnCertData
|
||||
}
|
||||
|
||||
BlueButtonType {
|
||||
|
@ -95,7 +94,7 @@ PageClientInfoBase {
|
|||
Layout.preferredHeight: 41
|
||||
text: qsTr("Revoke Certificate")
|
||||
onClicked: {
|
||||
ClientInfoLogic.onRevokeCertificateClicked()
|
||||
ClientInfoLogic.onRevokeOpenVpnCertificateClicked()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,5 +7,84 @@ import "../../Controls"
|
|||
import "../../Config"
|
||||
|
||||
PageClientInfoBase {
|
||||
id: root
|
||||
protocol: ProtocolEnum.WireGuard
|
||||
BackButton {
|
||||
id: back
|
||||
}
|
||||
|
||||
Caption {
|
||||
id: caption
|
||||
text: qsTr("Client Info")
|
||||
}
|
||||
|
||||
Flickable {
|
||||
id: fl
|
||||
width: root.width
|
||||
anchors.top: caption.bottom
|
||||
anchors.topMargin: 20
|
||||
anchors.bottom: root.bottom
|
||||
anchors.bottomMargin: 20
|
||||
anchors.left: root.left
|
||||
anchors.leftMargin: 30
|
||||
anchors.right: root.right
|
||||
anchors.rightMargin: 30
|
||||
|
||||
contentHeight: content.height
|
||||
clip: true
|
||||
|
||||
ColumnLayout {
|
||||
id: content
|
||||
anchors.top: parent.top
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
|
||||
LabelType {
|
||||
Layout.fillWidth: true
|
||||
font.pixelSize: 20
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
text: ClientInfoLogic.labelCurrentVpnProtocolText
|
||||
}
|
||||
|
||||
LabelType {
|
||||
height: 21
|
||||
text: qsTr("Client name")
|
||||
}
|
||||
|
||||
TextFieldType {
|
||||
Layout.fillWidth: true
|
||||
Layout.preferredHeight: 31
|
||||
text: ClientInfoLogic.lineEditNameAliasText
|
||||
onEditingFinished: {
|
||||
ClientInfoLogic.lineEditNameAliasText = text
|
||||
ClientInfoLogic.onLineEditNameAliasEditingFinished()
|
||||
}
|
||||
}
|
||||
|
||||
LabelType {
|
||||
Layout.topMargin: 20
|
||||
height: 21
|
||||
text: qsTr("Public Key")
|
||||
}
|
||||
|
||||
TextAreaType {
|
||||
Layout.preferredHeight: 200
|
||||
Layout.fillWidth: true
|
||||
|
||||
textArea.readOnly: true
|
||||
textArea.wrapMode: TextEdit.WrapAnywhere
|
||||
textArea.verticalAlignment: Text.AlignTop
|
||||
textArea.text: ClientInfoLogic.textAreaWireGuardKeyData
|
||||
}
|
||||
|
||||
BlueButtonType {
|
||||
Layout.fillWidth: true
|
||||
Layout.preferredHeight: 41
|
||||
text: qsTr("Revoke Key")
|
||||
onClicked: {
|
||||
ClientInfoLogic.onRevokeWireGuardKeyClicked()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@ import QtQuick
|
|||
import QtQuick.Controls
|
||||
import QtQuick.Layouts
|
||||
import QtQuick.Shapes 1.4
|
||||
import SortFilterProxyModel 0.2
|
||||
import PageEnum 1.0
|
||||
import "./"
|
||||
import "../Controls"
|
||||
|
@ -45,6 +46,12 @@ PageBase {
|
|||
text: ServerSettingsLogic.labelCurrentVpnProtocolText
|
||||
}
|
||||
|
||||
SortFilterProxyModel {
|
||||
id: proxyClientManagementModel
|
||||
sourceModel: UiLogic.clientManagementModel
|
||||
sorters: RoleSorter { roleName: "clientName" }
|
||||
}
|
||||
|
||||
ListView {
|
||||
id: lv_clients
|
||||
width: parent.width
|
||||
|
@ -56,7 +63,7 @@ PageBase {
|
|||
topMargin: 10
|
||||
spacing: 10
|
||||
clip: true
|
||||
model: UiLogic.clientManagementModel
|
||||
model: proxyClientManagementModel
|
||||
highlightRangeMode: ListView.ApplyRange
|
||||
highlightMoveVelocity: -1
|
||||
delegate: Item {
|
||||
|
@ -69,7 +76,7 @@ PageBase {
|
|||
hoverEnabled: true
|
||||
cursorShape: Qt.PointingHandCursor
|
||||
onClicked: {
|
||||
ClientManagementLogic.onClientItemClicked(index)
|
||||
ClientManagementLogic.onClientItemClicked(proxyClientManagementModel.mapToSource(index))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -96,23 +103,11 @@ PageBase {
|
|||
}
|
||||
}
|
||||
|
||||
Text {
|
||||
x: 10
|
||||
y: 10
|
||||
font.family: "Lato"
|
||||
font.styleName: "normal"
|
||||
color: "#181922"
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
wrapMode: Text.Wrap
|
||||
text: clientName
|
||||
}
|
||||
|
||||
LabelType {
|
||||
x: 20
|
||||
y: 40
|
||||
// width: 141
|
||||
height: 16
|
||||
text: certId
|
||||
y: 20
|
||||
font.pixelSize: 20
|
||||
text: clientName
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue