mirror of
https://github.com/noctalia-dev/noctalia-shell.git
synced 2026-05-11 17:08:27 +08:00
basic enterprise support
This commit is contained in:
@@ -546,7 +546,8 @@
|
||||
"width": "Width",
|
||||
"wifi": "Wi-Fi",
|
||||
"windows": "Windows",
|
||||
"yes": "Yes"
|
||||
"yes": "Yes",
|
||||
"username": "Username"
|
||||
},
|
||||
"control-center": {
|
||||
"power-profile": {
|
||||
@@ -2161,6 +2162,10 @@
|
||||
"fair": "Fair",
|
||||
"good": "Good",
|
||||
"poor": "Poor"
|
||||
},
|
||||
"enterprise": {
|
||||
"username": "Identity / Username",
|
||||
"password": "User password"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,6 +21,7 @@ Item {
|
||||
|
||||
// State properties
|
||||
property string passwordSsid: ""
|
||||
property string identity: ""
|
||||
property string expandedSsid: ""
|
||||
property string infoSsid: ""
|
||||
property int ipVersion: 4
|
||||
@@ -91,10 +92,11 @@ Item {
|
||||
// Actions
|
||||
function requestPassword(ssid) {
|
||||
passwordSsid = ssid;
|
||||
identity = "";
|
||||
expandedSsid = "";
|
||||
}
|
||||
function submitPassword(ssid, password) {
|
||||
NetworkService.connect(ssid, password);
|
||||
function submitPassword(ssid, password, identity = "") {
|
||||
NetworkService.connect(ssid, password, false, identity);
|
||||
passwordSsid = "";
|
||||
}
|
||||
function cancelPassword() {
|
||||
@@ -355,6 +357,7 @@ Item {
|
||||
|
||||
property string customSsid: ""
|
||||
property string customPassword: ""
|
||||
property string customIdentity: ""
|
||||
property string customSecurityKey: "wpa2-psk"
|
||||
|
||||
onOpened: {
|
||||
@@ -425,7 +428,7 @@ Item {
|
||||
onTextChanged: addNetworkPopup.customSsid = text
|
||||
onAccepted: {
|
||||
if (addNetworkPopup.customSsid.length > 0 && (addNetworkPopup.customSecurityKey === "open" || addNetworkPopup.customPassword.length > 0)) {
|
||||
NetworkService.connectManual(addNetworkPopup.customSsid, addNetworkPopup.customPassword, addNetworkPopup.customSecurityKey);
|
||||
NetworkService.connectManual(addNetworkPopup.customSsid, addNetworkPopup.customPassword, addNetworkPopup.customSecurityKey, addNetworkPopup.customIdentity);
|
||||
addNetworkPopup.close();
|
||||
}
|
||||
}
|
||||
@@ -440,6 +443,17 @@ Item {
|
||||
}
|
||||
}
|
||||
|
||||
NTextInput {
|
||||
id: customIdentityInput
|
||||
Layout.fillWidth: true
|
||||
inputIconName: "user"
|
||||
visible: addNetworkPopup.customSecurityKey.indexOf("-eap") !== -1
|
||||
placeholderText: I18n.tr("wifi.enterprise.username")
|
||||
label: I18n.tr("wifi.enterprise.username")
|
||||
text: addNetworkPopup.customIdentity
|
||||
onTextChanged: addNetworkPopup.customIdentity = text
|
||||
}
|
||||
|
||||
NTextInput {
|
||||
id: customPasswordInput
|
||||
Layout.fillWidth: true
|
||||
@@ -452,7 +466,7 @@ Item {
|
||||
inputItem.echoMode: TextInput.Password
|
||||
onAccepted: {
|
||||
if (addNetworkPopup.customSsid.length > 0 && addNetworkPopup.customPassword.length > 0) {
|
||||
NetworkService.connectManual(addNetworkPopup.customSsid, addNetworkPopup.customPassword, addNetworkPopup.customSecurityKey);
|
||||
NetworkService.connectManual(addNetworkPopup.customSsid, addNetworkPopup.customPassword, addNetworkPopup.customSecurityKey, addNetworkPopup.customIdentity);
|
||||
addNetworkPopup.close();
|
||||
}
|
||||
}
|
||||
@@ -480,9 +494,9 @@ Item {
|
||||
text: I18n.tr("common.connect")
|
||||
backgroundColor: Color.mPrimary
|
||||
textColor: Color.mOnPrimary
|
||||
enabled: addNetworkPopup.customSsid.length > 0 && (addNetworkPopup.customSecurityKey === "open" || addNetworkPopup.customPassword.length > 0)
|
||||
enabled: addNetworkPopup.customSsid.length > 0 && (addNetworkPopup.customSecurityKey === "open" || addNetworkPopup.customPassword.length > 0) && (addNetworkPopup.customSecurityKey.indexOf("-eap") === -1 || addNetworkPopup.customIdentity.length > 0)
|
||||
onClicked: {
|
||||
NetworkService.connectManual(addNetworkPopup.customSsid, addNetworkPopup.customPassword, addNetworkPopup.customSecurityKey);
|
||||
NetworkService.connectManual(addNetworkPopup.customSsid, addNetworkPopup.customPassword, addNetworkPopup.customSecurityKey, addNetworkPopup.customIdentity);
|
||||
addNetworkPopup.close();
|
||||
}
|
||||
}
|
||||
@@ -498,6 +512,7 @@ Item {
|
||||
|
||||
readonly property bool isBusy: NetworkService.connectingTo === modelData.ssid || NetworkService.disconnectingFrom === modelData.ssid || NetworkService.forgettingNetwork === modelData.ssid
|
||||
readonly property bool isExpanded: root.infoSsid === modelData.ssid
|
||||
readonly property bool isEnterprise: NetworkService.isEnterprise(modelData.security)
|
||||
|
||||
function getContentColor(defaultColor = Color.mOnSurface) {
|
||||
if (root.passwordSsid === modelData.ssid || NetworkService.connectingTo === modelData.ssid) {
|
||||
@@ -987,72 +1002,126 @@ Item {
|
||||
Rectangle {
|
||||
visible: root.passwordSsid === modelData.ssid && !networkItem.isBusy
|
||||
Layout.fillWidth: true
|
||||
height: passwordRow.implicitHeight + Style.margin2S
|
||||
height: passwordLayout.implicitHeight + Style.margin2S
|
||||
color: Color.mSurfaceVariant
|
||||
border.color: Color.mOutline
|
||||
border.width: Style.borderS
|
||||
radius: Style.iRadiusXS
|
||||
|
||||
RowLayout {
|
||||
id: passwordRow
|
||||
ColumnLayout {
|
||||
id: passwordLayout
|
||||
anchors.fill: parent
|
||||
anchors.margins: Style.marginS
|
||||
spacing: Style.marginM
|
||||
spacing: Style.marginS
|
||||
|
||||
Rectangle {
|
||||
// Inputs Container
|
||||
ColumnLayout {
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
radius: Style.iRadiusXS
|
||||
color: Color.mSurface
|
||||
border.color: pwdInput.activeFocus ? Color.mSecondary : Color.mOutline
|
||||
border.width: Style.borderS
|
||||
spacing: Style.marginS
|
||||
|
||||
TextInput {
|
||||
id: pwdInput
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
anchors.margins: Style.marginS
|
||||
font.family: Settings.data.ui.fontFixed
|
||||
font.pointSize: Style.fontSizeS
|
||||
color: Color.mOnSurface
|
||||
echoMode: TextInput.Password
|
||||
selectByMouse: true
|
||||
focus: visible
|
||||
passwordCharacter: "●"
|
||||
onVisibleChanged: {
|
||||
if (visible) {
|
||||
forceActiveFocus();
|
||||
}
|
||||
}
|
||||
onAccepted: {
|
||||
if (text && !NetworkService.connecting) {
|
||||
root.submitPassword(modelData.ssid, text);
|
||||
}
|
||||
}
|
||||
// Identity field (Enterprise only)
|
||||
Rectangle {
|
||||
visible: networkItem.isEnterprise
|
||||
Layout.fillWidth: true
|
||||
Layout.preferredHeight: Style.baseWidgetSize * 0.9
|
||||
radius: Style.iRadiusXS
|
||||
color: Color.mSurface
|
||||
border.color: identityInput.activeFocus ? Color.mSecondary : Color.mOutline
|
||||
border.width: Style.borderS
|
||||
|
||||
NText {
|
||||
visible: parent.text.length === 0
|
||||
TextInput {
|
||||
id: identityInput
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
text: I18n.tr("wifi.panel.enter-password")
|
||||
color: Color.mOnSurfaceVariant
|
||||
pointSize: Style.fontSizeS
|
||||
anchors.margins: Style.marginS
|
||||
font.family: Settings.data.ui.fontFixed
|
||||
font.pointSize: Style.fontSizeS
|
||||
color: Color.mOnSurface
|
||||
selectByMouse: true
|
||||
onVisibleChanged: {
|
||||
if (visible) {
|
||||
forceActiveFocus();
|
||||
}
|
||||
}
|
||||
onAccepted: pwdInput.forceActiveFocus()
|
||||
|
||||
NText {
|
||||
visible: parent.text.length === 0
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
text: I18n.tr("wifi.enterprise.username")
|
||||
color: Color.mOnSurfaceVariant
|
||||
pointSize: Style.fontSizeS
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Password field
|
||||
Rectangle {
|
||||
Layout.fillWidth: true
|
||||
Layout.preferredHeight: Style.baseWidgetSize * 0.9
|
||||
radius: Style.iRadiusXS
|
||||
color: Color.mSurface
|
||||
border.color: pwdInput.activeFocus ? Color.mSecondary : Color.mOutline
|
||||
border.width: Style.borderS
|
||||
|
||||
TextInput {
|
||||
id: pwdInput
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
anchors.margins: Style.marginS
|
||||
font.family: Settings.data.ui.fontFixed
|
||||
font.pointSize: Style.fontSizeS
|
||||
color: Color.mOnSurface
|
||||
echoMode: TextInput.Password
|
||||
selectByMouse: true
|
||||
passwordCharacter: "●"
|
||||
onVisibleChanged: {
|
||||
if (visible && !networkItem.isEnterprise) {
|
||||
forceActiveFocus();
|
||||
}
|
||||
}
|
||||
onAccepted: {
|
||||
if (text && !NetworkService.connecting) {
|
||||
if (!networkItem.isEnterprise || identityInput.text.length > 0) {
|
||||
root.submitPassword(modelData.ssid, text, identityInput.text);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
NText {
|
||||
visible: parent.text.length === 0
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
text: networkItem.isEnterprise ? I18n.tr("wifi.enterprise.password") : I18n.tr("wifi.panel.enter-password")
|
||||
color: Color.mOnSurfaceVariant
|
||||
pointSize: Style.fontSizeS
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
NButton {
|
||||
text: I18n.tr("common.connect")
|
||||
fontSize: Style.fontSizeS
|
||||
enabled: pwdInput.text.length > 0 && !NetworkService.connecting
|
||||
outlined: true
|
||||
onClicked: root.submitPassword(modelData.ssid, pwdInput.text)
|
||||
}
|
||||
RowLayout {
|
||||
Layout.fillWidth: true
|
||||
spacing: Style.marginS
|
||||
|
||||
NIconButton {
|
||||
icon: "close"
|
||||
baseSize: Style.baseWidgetSize * 0.8
|
||||
onClicked: root.cancelPassword()
|
||||
Item {
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
|
||||
NButton {
|
||||
text: I18n.tr("common.connect")
|
||||
fontSize: Style.fontSizeS
|
||||
enabled: pwdInput.text.length > 0 && (!networkItem.isEnterprise || identityInput.text.length > 0) && !NetworkService.connecting
|
||||
outlined: true
|
||||
onClicked: root.submitPassword(modelData.ssid, pwdInput.text, identityInput.text)
|
||||
}
|
||||
|
||||
NIconButton {
|
||||
icon: "close"
|
||||
baseSize: Style.baseWidgetSize * 0.8
|
||||
onClicked: root.cancelPassword()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -342,10 +342,18 @@ Singleton {
|
||||
refreshActiveEthernetDetails();
|
||||
}
|
||||
|
||||
function connect(ssid, password = "", isHidden = false) {
|
||||
function connect(ssid, password = "", isHidden = false, identity = "") {
|
||||
if (!ProgramCheckerService.nmcliAvailable || connecting) {
|
||||
return;
|
||||
}
|
||||
|
||||
// For enterprise networks, use the robust manual connection logic (profile creation)
|
||||
// as it handles 802.1X parameters much more reliably than 'device wifi connect'.
|
||||
if (isEnterprise(networks[ssid] ? networks[ssid].security : "")) {
|
||||
connectManual(ssid, password, "wpa-eap", identity);
|
||||
return;
|
||||
}
|
||||
|
||||
connecting = true;
|
||||
connectingTo = ssid;
|
||||
lastError = "";
|
||||
@@ -366,7 +374,7 @@ Singleton {
|
||||
connectProcess.running = true;
|
||||
}
|
||||
|
||||
function connectManual(ssid, password, securityKey) {
|
||||
function connectManual(ssid, password, securityKey, identity = "") {
|
||||
if (!ProgramCheckerService.nmcliAvailable || connecting) {
|
||||
return;
|
||||
}
|
||||
@@ -377,6 +385,7 @@ Singleton {
|
||||
manualConnectProcess.ssid = ssid;
|
||||
manualConnectProcess.password = password;
|
||||
manualConnectProcess.securityKey = securityKey;
|
||||
manualConnectProcess.identity = identity;
|
||||
manualConnectProcess.running = true;
|
||||
}
|
||||
|
||||
@@ -468,6 +477,14 @@ Singleton {
|
||||
return security && security !== "--" && security.trim() !== "";
|
||||
}
|
||||
|
||||
function isEnterprise(security) {
|
||||
if (!security) {
|
||||
return false;
|
||||
}
|
||||
const s = security.toUpperCase();
|
||||
return s.indexOf("802.1X") !== -1 || s.indexOf("EAP") !== -1 || s.indexOf("ENTERPRISE") !== -1;
|
||||
}
|
||||
|
||||
function getSignalStrengthLabel(signal) {
|
||||
switch (true) {
|
||||
case (signal >= 80):
|
||||
@@ -1434,6 +1451,7 @@ Singleton {
|
||||
property string ssid: ""
|
||||
property string password: ""
|
||||
property string securityKey: ""
|
||||
property string identity: ""
|
||||
running: false
|
||||
|
||||
command: {
|
||||
@@ -1441,6 +1459,7 @@ Singleton {
|
||||
SSID="$1"
|
||||
PWD="$2"
|
||||
SEC="$3"
|
||||
IDENT="$4"
|
||||
|
||||
# Remove existing profile to avoid conflict
|
||||
nmcli connection delete id "$SSID" 2>/dev/null || true
|
||||
@@ -1453,9 +1472,8 @@ elif [ "$SEC" = "sae" ]; then
|
||||
elif [ "$SEC" = "wep" ]; then
|
||||
nmcli connection add type wifi con-name "$SSID" ssid "$SSID" -- wifi-sec.key-mgmt none wifi-sec.wep-key0 "$PWD" 802-11-wireless.hidden yes
|
||||
elif [[ "$SEC" == *-eap ]]; then
|
||||
# Enterprise not fully supported in Stage 1
|
||||
echo "Enterprise networks not supported yet"
|
||||
exit 1
|
||||
# WPA Enterprise (PEAP-MSCHAPv2 default)
|
||||
nmcli connection add type wifi con-name "$SSID" ssid "$SSID" -- wifi-sec.key-mgmt wpa-eap 802-1x.eap peap 802-1x.phase2-auth mschapv2 802-1x.identity "$IDENT" 802-1x.password "$PWD" 802-11-wireless.hidden yes
|
||||
else
|
||||
nmcli connection add type wifi con-name "$SSID" ssid "$SSID" -- 802-11-wireless.hidden yes
|
||||
fi
|
||||
@@ -1464,7 +1482,7 @@ fi
|
||||
nmcli connection up id "$SSID"
|
||||
`;
|
||||
|
||||
return ["sh", "-c", script, "--", ssid, password, securityKey];
|
||||
return ["sh", "-c", script, "--", ssid, password, securityKey, identity];
|
||||
}
|
||||
|
||||
stdout: StdioCollector {
|
||||
|
||||
Reference in New Issue
Block a user