Connect to enterprise (802.1X) Wi-Fi networks from the network panel
This commit is contained in:
@@ -232,6 +232,14 @@ function isProtected(security, openSecurity) {
|
|||||||
return security !== openSecurity
|
return security !== openSecurity
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var enterpriseConnectScript =
|
||||||
|
"u=$(uuidgen);" +
|
||||||
|
" nmcli connection add type wifi con-name \"$1\" ssid \"$1\" connection.uuid \"$u\"" +
|
||||||
|
" wifi-sec.key-mgmt wpa-eap 802-1x.eap peap 802-1x.phase2-auth mschapv2" +
|
||||||
|
" 802-1x.identity \"$2\" 802-1x.password \"$3\" 802-1x.auth-timeout 8" +
|
||||||
|
" && nmcli connection up uuid \"$u\"" +
|
||||||
|
" || { nmcli connection delete uuid \"$u\" >/dev/null 2>&1; false; }"
|
||||||
|
|
||||||
function networkFailureReason(reason, reasons) {
|
function networkFailureReason(reason, reasons) {
|
||||||
var r = reasons || {}
|
var r = reasons || {}
|
||||||
if (reason === r.NoSecrets) return "Passphrase required"
|
if (reason === r.NoSecrets) return "Passphrase required"
|
||||||
@@ -263,6 +271,7 @@ if (typeof module !== "undefined") {
|
|||||||
sortWifiRows: sortWifiRows,
|
sortWifiRows: sortWifiRows,
|
||||||
wifiSectionTitle: wifiSectionTitle,
|
wifiSectionTitle: wifiSectionTitle,
|
||||||
isProtected: isProtected,
|
isProtected: isProtected,
|
||||||
|
enterpriseConnectScript: enterpriseConnectScript,
|
||||||
networkFailureReason: networkFailureReason
|
networkFailureReason: networkFailureReason
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,7 +16,13 @@ Panel {
|
|||||||
// Centralized close so callers can't forget to drop the passphrase prompt.
|
// Centralized close so callers can't forget to drop the passphrase prompt.
|
||||||
function close() {
|
function close() {
|
||||||
root.controller.hide()
|
root.controller.hide()
|
||||||
|
cancelPasswordPrompt()
|
||||||
|
}
|
||||||
|
|
||||||
|
function cancelPasswordPrompt() {
|
||||||
passwordSsid = ""
|
passwordSsid = ""
|
||||||
|
passwordText = ""
|
||||||
|
identityText = ""
|
||||||
}
|
}
|
||||||
|
|
||||||
// Live connection details from `ip` / /sys / iw.
|
// Live connection details from `ip` / /sys / iw.
|
||||||
@@ -84,6 +90,7 @@ Panel {
|
|||||||
property string failureReason: ""
|
property string failureReason: ""
|
||||||
property string passwordSsid: ""
|
property string passwordSsid: ""
|
||||||
property string passwordText: ""
|
property string passwordText: ""
|
||||||
|
property string identityText: ""
|
||||||
|
|
||||||
// True while any wifi action is mid-flight. Rows
|
// True while any wifi action is mid-flight. Rows
|
||||||
// disable themselves on this so clicks on the other rows don't silently
|
// disable themselves on this so clicks on the other rows don't silently
|
||||||
@@ -489,7 +496,10 @@ Panel {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function openPasswordPrompt(ssid) {
|
function openPasswordPrompt(ssid) {
|
||||||
if (passwordSsid !== ssid) passwordText = ""
|
if (passwordSsid !== ssid) {
|
||||||
|
passwordText = ""
|
||||||
|
identityText = ""
|
||||||
|
}
|
||||||
passwordSsid = ssid
|
passwordSsid = ssid
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -567,6 +577,12 @@ Panel {
|
|||||||
runNetworkAction("connect", networkForSsid(ssid), function(network) { network.connectWithPsk(passphrase) })
|
runNetworkAction("connect", networkForSsid(ssid), function(network) { network.connectWithPsk(passphrase) })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function connectEnterprise(ssid, identity, passphrase) {
|
||||||
|
runNetworkAction("connect", networkForSsid(ssid), function(network) {
|
||||||
|
Quickshell.execDetached(["bash", "-c", Model.enterpriseConnectScript, "nmcli-eap", ssid, identity, passphrase])
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
function disconnect(network) {
|
function disconnect(network) {
|
||||||
runNetworkAction("disconnect", network || connectedWifiNetwork, function(net) { net.disconnect() })
|
runNetworkAction("disconnect", network || connectedWifiNetwork, function(net) { net.disconnect() })
|
||||||
}
|
}
|
||||||
@@ -1234,6 +1250,9 @@ Panel {
|
|||||||
readonly property bool isConnected: net && net.connected
|
readonly property bool isConnected: net && net.connected
|
||||||
readonly property bool isKnown: !!(net && net.known)
|
readonly property bool isKnown: !!(net && net.known)
|
||||||
readonly property bool isProtected: net ? root.isProtected(net.security) : false
|
readonly property bool isProtected: net ? root.isProtected(net.security) : false
|
||||||
|
readonly property bool isEnterprise: net
|
||||||
|
? (net.security === WifiSecurityType.Wpa2Eap || net.security === WifiSecurityType.WpaEap)
|
||||||
|
: false
|
||||||
readonly property bool canForgetFromLock: isKnown && isProtected && !isConnected
|
readonly property bool canForgetFromLock: isKnown && isProtected && !isConnected
|
||||||
readonly property bool isSelected: root.focusSection === "wifi" && root.selectedIndex === index
|
readonly property bool isSelected: root.focusSection === "wifi" && root.selectedIndex === index
|
||||||
readonly property bool forgetFocused: isSelected && root.wifiActionFocused && canForgetFromLock
|
readonly property bool forgetFocused: isSelected && root.wifiActionFocused && canForgetFromLock
|
||||||
@@ -1250,6 +1269,12 @@ Panel {
|
|||||||
readonly property bool isFailed: root.failureReason !== "" && root.failureSsid === (net ? net.ssid : "")
|
readonly property bool isFailed: root.failureReason !== "" && root.failureSsid === (net ? net.ssid : "")
|
||||||
readonly property bool isPasswordOpen: root.passwordSsid !== "" && root.passwordSsid === (net ? net.ssid : "")
|
readonly property bool isPasswordOpen: root.passwordSsid !== "" && root.passwordSsid === (net ? net.ssid : "")
|
||||||
|
|
||||||
|
function submitCredentials() {
|
||||||
|
if (!net || root.busy || root.passwordText.length === 0) return
|
||||||
|
if (!isEnterprise) return root.connectWithPassphrase(net.ssid, root.passwordText)
|
||||||
|
if (root.identityText.length > 0) root.connectEnterprise(net.ssid, root.identityText, root.passwordText)
|
||||||
|
}
|
||||||
|
|
||||||
Connections {
|
Connections {
|
||||||
target: row.net ? row.net.network : null
|
target: row.net ? row.net.network : null
|
||||||
function onConnectionFailed(reason) {
|
function onConnectionFailed(reason) {
|
||||||
@@ -1449,15 +1474,40 @@ Panel {
|
|||||||
anchors.leftMargin: Style.space(10)
|
anchors.leftMargin: Style.space(10)
|
||||||
anchors.rightMargin: Style.space(10)
|
anchors.rightMargin: Style.space(10)
|
||||||
anchors.topMargin: Style.space(4)
|
anchors.topMargin: Style.space(4)
|
||||||
implicitHeight: pwField.implicitHeight + Style.spacing.rowGap
|
implicitHeight: (idField.visible ? idField.implicitHeight + Style.space(4) : 0) + pwField.implicitHeight + Style.spacing.rowGap
|
||||||
height: implicitHeight
|
height: implicitHeight
|
||||||
|
|
||||||
|
TextField {
|
||||||
|
id: idField
|
||||||
|
visible: row.isEnterprise && !row.isBusy && !row.isFailed
|
||||||
|
anchors.left: parent.left
|
||||||
|
anchors.right: connectPwBtn.left
|
||||||
|
anchors.top: parent.top
|
||||||
|
anchors.rightMargin: Style.space(6)
|
||||||
|
placeholderText: "Identity (user@domain)"
|
||||||
|
font.family: Style.font.family
|
||||||
|
font.pixelSize: Style.font.body
|
||||||
|
foreground: root.bar.foreground
|
||||||
|
horizontalPadding: Style.spacing.controlGap
|
||||||
|
verticalPadding: Style.spacing.controlPaddingY
|
||||||
|
enabled: !row.isBusy
|
||||||
|
text: row.isPasswordOpen ? root.identityText : ""
|
||||||
|
|
||||||
|
onAccepted: pwField.forceActiveFocus()
|
||||||
|
onTextChanged: if (row.isPasswordOpen && text !== root.identityText) root.identityText = text
|
||||||
|
Keys.onEscapePressed: root.cancelPasswordPrompt()
|
||||||
|
|
||||||
|
onVisibleChanged: if (visible) Qt.callLater(forceActiveFocus)
|
||||||
|
Component.onCompleted: if (visible) Qt.callLater(forceActiveFocus)
|
||||||
|
}
|
||||||
|
|
||||||
TextField {
|
TextField {
|
||||||
id: pwField
|
id: pwField
|
||||||
visible: !row.isBusy && !row.isFailed
|
visible: !row.isBusy && !row.isFailed
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
anchors.right: connectPwBtn.left
|
anchors.right: connectPwBtn.left
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.bottom: parent.bottom
|
||||||
|
anchors.bottomMargin: Style.spacing.rowGap / 2
|
||||||
anchors.rightMargin: Style.space(6)
|
anchors.rightMargin: Style.space(6)
|
||||||
password: true
|
password: true
|
||||||
placeholderText: "Passphrase"
|
placeholderText: "Passphrase"
|
||||||
@@ -1469,14 +1519,12 @@ Panel {
|
|||||||
enabled: !row.isBusy
|
enabled: !row.isBusy
|
||||||
text: row.isPasswordOpen ? root.passwordText : ""
|
text: row.isPasswordOpen ? root.passwordText : ""
|
||||||
|
|
||||||
onAccepted: {
|
onAccepted: row.submitCredentials()
|
||||||
if (!root.busy && row.net && text.length > 0) root.connectWithPassphrase(row.net.ssid, text)
|
|
||||||
}
|
|
||||||
onTextChanged: if (row.isPasswordOpen && text !== root.passwordText) root.passwordText = text
|
onTextChanged: if (row.isPasswordOpen && text !== root.passwordText) root.passwordText = text
|
||||||
Keys.onEscapePressed: { root.passwordSsid = ""; root.passwordText = "" }
|
Keys.onEscapePressed: root.cancelPasswordPrompt()
|
||||||
|
|
||||||
onVisibleChanged: if (visible) Qt.callLater(forceActiveFocus)
|
onVisibleChanged: if (visible && !row.isEnterprise) Qt.callLater(forceActiveFocus)
|
||||||
Component.onCompleted: if (visible) Qt.callLater(forceActiveFocus)
|
Component.onCompleted: if (visible && !row.isEnterprise) Qt.callLater(forceActiveFocus)
|
||||||
}
|
}
|
||||||
|
|
||||||
BorderSurface {
|
BorderSurface {
|
||||||
@@ -1509,12 +1557,12 @@ Panel {
|
|||||||
visible: !row.isBusy && !row.isFailed
|
visible: !row.isBusy && !row.isFailed
|
||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
enabled: row.net && pwField.text.length > 0
|
enabled: row.net && pwField.text.length > 0 && (!row.isEnterprise || idField.text.length > 0)
|
||||||
iconText: ""
|
iconText: ""
|
||||||
tooltipText: "Connect"
|
tooltipText: "Connect"
|
||||||
foreground: root.bar.foreground
|
foreground: root.bar.foreground
|
||||||
fontFamily: root.bar.fontFamily
|
fontFamily: root.bar.fontFamily
|
||||||
onClicked: if (row.net) root.connectWithPassphrase(row.net.ssid, root.passwordText)
|
onClicked: row.submitCredentials()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user