added client management panel

- added classes for displaying the client management panel
- added class for displaying the client info
- added page to display a list of clients
- added page to display OpenVpn client information
- added diagram with OpenVpn certificate revocation process
This commit is contained in:
vladimir.kuznetsov 2023-01-09 12:38:01 +03:00
parent 3f257af7a9
commit a42beb86c0
19 changed files with 771 additions and 102 deletions

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,103 @@
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
}
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("Certificate id")
}
LabelType {
Layout.fillWidth: true
horizontalAlignment: Text.AlignHCenter
text: ClientInfoLogic.labelCertId
}
LabelType {
Layout.topMargin: 20
height: 21
text: qsTr("Certificate")
}
TextAreaType {
Layout.preferredHeight: 200
Layout.fillWidth: true
textArea.readOnly: true
textArea.wrapMode: TextEdit.WrapAnywhere
textArea.verticalAlignment: Text.AlignTop
textArea.text: ClientInfoLogic.textAreaCertificate
}
BlueButtonType {
Layout.fillWidth: true
Layout.preferredHeight: 41
text: qsTr("Revoke Certificate")
onClicked: {
ClientInfoLogic.onRevokeCertificateClicked()
}
}
}
}
}

View file

@ -0,0 +1,11 @@
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
import ProtocolEnum 1.0
import "../"
import "../../Controls"
import "../../Config"
PageClientInfoBase {
}

View file

@ -0,0 +1,121 @@
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
import QtQuick.Shapes 1.4
import PageEnum 1.0
import "./"
import "../Controls"
import "../Config"
PageBase {
id: root
page: PageEnum.ClientManagement
logic: ClientManagementLogic
BackButton {
id: back
}
Caption {
id: caption
text: qsTr("Clients Management")
}
Flickable {
id: fl
width: root.width
anchors.top: caption.bottom
anchors.topMargin: 20
anchors.bottom: root.bottom
anchors.bottomMargin: 20
contentHeight: content.height
clip: true
Column {
id: content
anchors.top: parent.top
anchors.left: parent.left
anchors.right: parent.right
LabelType {
anchors.left: parent.left
font.pixelSize: 20
horizontalAlignment: Text.AlignHCenter
text: ServerSettingsLogic.labelCurrentVpnProtocolText
}
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: UiLogic.clientManagementModel
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(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" }
]
}
}
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
}
}
}
}
}
}

View file

@ -1,5 +1,6 @@
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
import PageEnum 1.0
import "./"
import "../Controls"
@ -15,114 +16,135 @@ PageBase {
BackButton {
id: back
}
Caption {
id: caption
text: qsTr("Server settings")
anchors.horizontalCenter: parent.horizontalCenter
}
LabelType {
anchors.horizontalCenter: parent.horizontalCenter
y: 150
width: 341
height: 31
font.pixelSize: 20
horizontalAlignment: Text.AlignHCenter
text: ServerSettingsLogic.labelCurrentVpnProtocolText
}
// LabelType {
// anchors.horizontalCenter: parent.horizontalCenter
// y: 120
// width: 341
// height: 31
// font.pixelSize: 20
// horizontalAlignment: Text.AlignHCenter
// text: ServerSettingsLogic.labelServerText
// }
TextFieldType {
anchors.horizontalCenter: parent.horizontalCenter
y: 120
width: 341
height: 31
font.pixelSize: 20
horizontalAlignment: Text.AlignHCenter
text: ServerSettingsLogic.labelServerText
readOnly: true
background: Item {}
}
LabelType {
anchors.horizontalCenter: parent.horizontalCenter
y: 530
width: 301
height: 41
text: ServerSettingsLogic.labelWaitInfoText
visible: ServerSettingsLogic.labelWaitInfoVisible
}
TextFieldType {
anchors.horizontalCenter: parent.horizontalCenter
y: 80
width: 251
height: 31
text: ServerSettingsLogic.lineEditDescriptionText
onEditingFinished: {
ServerSettingsLogic.lineEditDescriptionText = text
ServerSettingsLogic.onLineEditDescriptionEditingFinished()
}
}
BlueButtonType {
anchors.horizontalCenter: parent.horizontalCenter
y: 410
width: parent.width - 40
height: 40
text: ServerSettingsLogic.pushButtonClearText
visible: ServerSettingsLogic.pushButtonClearVisible
onClicked: {
ServerSettingsLogic.onPushButtonClearServer()
}
}
BlueButtonType {
anchors.horizontalCenter: parent.horizontalCenter
y: 350
width: parent.width - 40
height: 40
text: ServerSettingsLogic.pushButtonClearClientCacheText
visible: ServerSettingsLogic.pushButtonClearClientCacheVisible
onClicked: {
ServerSettingsLogic.onPushButtonClearClientCacheClicked()
}
}
BlueButtonType {
anchors.horizontalCenter: parent.horizontalCenter
y: 470
width: parent.width - 40
height: 40
text: qsTr("Forget this server")
onClicked: {
ServerSettingsLogic.onPushButtonForgetServer()
}
}
BlueButtonType {
anchors.horizontalCenter: parent.horizontalCenter
y: 210
width: parent.width - 40
height: 40
text: qsTr("Protocols and Services")
onClicked: {
UiLogic.goToPage(PageEnum.ServerContainers)
}
}
BlueButtonType {
anchors.horizontalCenter: parent.horizontalCenter
y: 260
width: parent.width - 40
height: 40
text: qsTr("Share Server (FULL ACCESS)")
visible: ServerSettingsLogic.pushButtonShareFullVisible
onClicked: {
ServerSettingsLogic.onPushButtonShareFullClicked()
Flickable {
id: fl
width: root.width
anchors.top: caption.bottom
anchors.topMargin: 20
anchors.bottom: logo.top
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
enabled: logic.pageEnabled
anchors.top: parent.top
anchors.left: parent.left
anchors.right: parent.right
TextFieldType {
Layout.alignment: Qt.AlignHCenter
Layout.preferredWidth: 251
Layout.preferredHeight: 31
text: ServerSettingsLogic.lineEditDescriptionText
onEditingFinished: {
ServerSettingsLogic.lineEditDescriptionText = text
ServerSettingsLogic.onLineEditDescriptionEditingFinished()
}
}
TextFieldType {
Layout.fillWidth: true
font.pixelSize: 20
horizontalAlignment: Text.AlignHCenter
text: ServerSettingsLogic.labelServerText
readOnly: true
background: Item {}
}
LabelType {
Layout.fillWidth: true
font.pixelSize: 20
horizontalAlignment: Text.AlignHCenter
text: ServerSettingsLogic.labelCurrentVpnProtocolText
}
BlueButtonType {
Layout.topMargin: 15
Layout.fillWidth: true
Layout.preferredHeight: 41
text: qsTr("Protocols and Services")
onClicked: {
UiLogic.goToPage(PageEnum.ServerContainers)
}
}
BlueButtonType {
Layout.topMargin: 10
Layout.fillWidth: true
Layout.preferredHeight: 41
text: qsTr("Share Server (FULL ACCESS)")
visible: ServerSettingsLogic.pushButtonShareFullVisible
onClicked: {
ServerSettingsLogic.onPushButtonShareFullClicked()
}
}
BlueButtonType {
Layout.topMargin: 10
Layout.fillWidth: true
Layout.preferredHeight: 41
text: qsTr("Clients Management")
onClicked: {
UiLogic.goToPage(PageEnum.ClientManagement)
}
}
BlueButtonType {
Layout.topMargin: 30
Layout.fillWidth: true
Layout.preferredHeight: 41
text: ServerSettingsLogic.pushButtonClearClientCacheText
visible: ServerSettingsLogic.pushButtonClearClientCacheVisible
onClicked: {
ServerSettingsLogic.onPushButtonClearClientCacheClicked()
}
}
BlueButtonType {
Layout.topMargin: 10
Layout.fillWidth: true
Layout.preferredHeight: 41
text: ServerSettingsLogic.pushButtonClearText
visible: ServerSettingsLogic.pushButtonClearVisible
onClicked: {
ServerSettingsLogic.onPushButtonClearServer()
}
}
BlueButtonType {
Layout.topMargin: 10
Layout.fillWidth: true
Layout.preferredHeight: 41
text: qsTr("Forget this server")
onClicked: {
ServerSettingsLogic.onPushButtonForgetServer()
}
}
LabelType {
Layout.fillWidth: true
text: ServerSettingsLogic.labelWaitInfoText
visible: ServerSettingsLogic.labelWaitInfoVisible
}
}
}
Logo {
id: logo
anchors.bottom: parent.bottom
}
}

View file

@ -13,12 +13,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
@ -39,6 +41,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)
@ -175,6 +178,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 compenent " + file + " for " + type);
@ -198,6 +214,9 @@ Window {
else if (type === PageType.ShareProto) {
sharePages[obj.protocol] = obj
}
else if (type === PageType.ClientInfo) {
clientInfoPages[obj.protocol] = obj
}
// console.debug("Created compenent " + component.url + " for " + type);
}
@ -227,7 +246,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()