SEBWIN-788: Implemented automatic connection attempt and retry on invalid credentials. Improved wording of username label in credentials dialog.
This commit is contained in:
parent
b3228aedef
commit
84bbcb82ef
12 changed files with 99 additions and 61 deletions
|
@ -106,7 +106,7 @@
|
||||||
Benutzername:
|
Benutzername:
|
||||||
</Entry>
|
</Entry>
|
||||||
<Entry key="CredentialsDialog_UsernameOptionalLabel">
|
<Entry key="CredentialsDialog_UsernameOptionalLabel">
|
||||||
Benutzername (optional):
|
Benutzername (falls erforderlich):
|
||||||
</Entry>
|
</Entry>
|
||||||
<Entry key="CredentialsDialog_WirelessNetworkMessage">
|
<Entry key="CredentialsDialog_WirelessNetworkMessage">
|
||||||
Bitte geben Sie die erforderlichen Anmeldeinformationen ein, um eine Verbindung mit dem drahtlosen Netzwerk "%%_NAME_%%" herzustellen.
|
Bitte geben Sie die erforderlichen Anmeldeinformationen ein, um eine Verbindung mit dem drahtlosen Netzwerk "%%_NAME_%%" herzustellen.
|
||||||
|
|
|
@ -106,7 +106,7 @@
|
||||||
Username:
|
Username:
|
||||||
</Entry>
|
</Entry>
|
||||||
<Entry key="CredentialsDialog_UsernameOptionalLabel">
|
<Entry key="CredentialsDialog_UsernameOptionalLabel">
|
||||||
Username (optional):
|
Username (if required):
|
||||||
</Entry>
|
</Entry>
|
||||||
<Entry key="CredentialsDialog_WirelessNetworkMessage">
|
<Entry key="CredentialsDialog_WirelessNetworkMessage">
|
||||||
Please enter the required credentials to establish a connection to the wireless network "%%_NAME_%%".
|
Please enter the required credentials to establish a connection to the wireless network "%%_NAME_%%".
|
||||||
|
|
|
@ -106,7 +106,7 @@
|
||||||
Nombre de usuario:
|
Nombre de usuario:
|
||||||
</Entry>
|
</Entry>
|
||||||
<Entry key="CredentialsDialog_UsernameOptionalLabel">
|
<Entry key="CredentialsDialog_UsernameOptionalLabel">
|
||||||
Nombre de usuario (opcional):
|
Nombre de usuario (si se requiere):
|
||||||
</Entry>
|
</Entry>
|
||||||
<Entry key="CredentialsDialog_WirelessNetworkMessage">
|
<Entry key="CredentialsDialog_WirelessNetworkMessage">
|
||||||
Por favor, introduzca las credenciales necesarias para establecer una conexión con la red inalámbrica "%%_NAME_%%".
|
Por favor, introduzca las credenciales necesarias para establecer una conexión con la red inalámbrica "%%_NAME_%%".
|
||||||
|
|
|
@ -106,7 +106,7 @@
|
||||||
Kasutajanimi:
|
Kasutajanimi:
|
||||||
</Entry>
|
</Entry>
|
||||||
<Entry key="CredentialsDialog_UsernameOptionalLabel">
|
<Entry key="CredentialsDialog_UsernameOptionalLabel">
|
||||||
Kasutajanimi (vabatahtlik):
|
Kasutajanimi (kui see on nõutav):
|
||||||
</Entry>
|
</Entry>
|
||||||
<Entry key="CredentialsDialog_WirelessNetworkMessage">
|
<Entry key="CredentialsDialog_WirelessNetworkMessage">
|
||||||
Palun sisestage vajalikud volitused, et luua ühendus traadita võrguga "%%_NAME_%%".
|
Palun sisestage vajalikud volitused, et luua ühendus traadita võrguga "%%_NAME_%%".
|
||||||
|
|
|
@ -106,7 +106,7 @@
|
||||||
Nom d'utilisateur:
|
Nom d'utilisateur:
|
||||||
</Entry>
|
</Entry>
|
||||||
<Entry key="CredentialsDialog_UsernameOptionalLabel">
|
<Entry key="CredentialsDialog_UsernameOptionalLabel">
|
||||||
Nom d'utilisateur (facultatif):
|
Nom d'utilisateur (si requis):
|
||||||
</Entry>
|
</Entry>
|
||||||
<Entry key="CredentialsDialog_WirelessNetworkMessage">
|
<Entry key="CredentialsDialog_WirelessNetworkMessage">
|
||||||
Veuillez saisir les informations d'identification requises pour établir une connexion au réseau sans fil "%%_NAME_%%".
|
Veuillez saisir les informations d'identification requises pour établir une connexion au réseau sans fil "%%_NAME_%%".
|
||||||
|
|
|
@ -106,7 +106,7 @@
|
||||||
Nama pengguna:
|
Nama pengguna:
|
||||||
</Entry>
|
</Entry>
|
||||||
<Entry key="CredentialsDialog_UsernameOptionalLabel">
|
<Entry key="CredentialsDialog_UsernameOptionalLabel">
|
||||||
Nama pengguna (opsional):
|
Nama pengguna (jika diperlukan):
|
||||||
</Entry>
|
</Entry>
|
||||||
<Entry key="CredentialsDialog_WirelessNetworkMessage">
|
<Entry key="CredentialsDialog_WirelessNetworkMessage">
|
||||||
Masukkan kredensial yang diperlukan untuk membuat sambungan ke jaringan nirkabel "%%_NAMA_%%".
|
Masukkan kredensial yang diperlukan untuk membuat sambungan ke jaringan nirkabel "%%_NAMA_%%".
|
||||||
|
|
|
@ -106,7 +106,7 @@
|
||||||
Nome utente:
|
Nome utente:
|
||||||
</Entry>
|
</Entry>
|
||||||
<Entry key="CredentialsDialog_UsernameOptionalLabel">
|
<Entry key="CredentialsDialog_UsernameOptionalLabel">
|
||||||
Nome utente (facoltativo):
|
Nome utente (se richiesto):
|
||||||
</Entry>
|
</Entry>
|
||||||
<Entry key="CredentialsDialog_WirelessNetworkMessage">
|
<Entry key="CredentialsDialog_WirelessNetworkMessage">
|
||||||
Inserire le credenziali richieste per stabilire una connessione alla rete wireless "%%_NAME_%%".
|
Inserire le credenziali richieste per stabilire una connessione alla rete wireless "%%_NAME_%%".
|
||||||
|
|
|
@ -106,7 +106,7 @@
|
||||||
Gebruikersnaam:
|
Gebruikersnaam:
|
||||||
</Entry>
|
</Entry>
|
||||||
<Entry key="CredentialsDialog_UsernameOptionalLabel">
|
<Entry key="CredentialsDialog_UsernameOptionalLabel">
|
||||||
Gebruikersnaam (optioneel):
|
Gebruikersnaam (indien vereist):
|
||||||
</Entry>
|
</Entry>
|
||||||
<Entry key="CredentialsDialog_WirelessNetworkMessage">
|
<Entry key="CredentialsDialog_WirelessNetworkMessage">
|
||||||
Voer de vereiste gegevens in om verbinding te maken met het draadloze netwerk “%%_NAME_%%”.
|
Voer de vereiste gegevens in om verbinding te maken met het draadloze netwerk “%%_NAME_%%”.
|
||||||
|
|
|
@ -106,7 +106,7 @@
|
||||||
Имя пользователя:
|
Имя пользователя:
|
||||||
</Entry>
|
</Entry>
|
||||||
<Entry key="CredentialsDialog_UsernameOptionalLabel">
|
<Entry key="CredentialsDialog_UsernameOptionalLabel">
|
||||||
Имя пользователя (необязательно):
|
Имя пользователя (если требуется):
|
||||||
</Entry>
|
</Entry>
|
||||||
<Entry key="CredentialsDialog_WirelessNetworkMessage">
|
<Entry key="CredentialsDialog_WirelessNetworkMessage">
|
||||||
Введите необходимые учетные данные для установления соединения с беспроводной сетью "%%_NAME_%%".
|
Введите необходимые учетные данные для установления соединения с беспроводной сетью "%%_NAME_%%".
|
||||||
|
|
|
@ -106,7 +106,7 @@
|
||||||
用户名:
|
用户名:
|
||||||
</Entry>
|
</Entry>
|
||||||
<Entry key="CredentialsDialog_UsernameOptionalLabel">
|
<Entry key="CredentialsDialog_UsernameOptionalLabel">
|
||||||
用户名(可选):
|
用户名(如需要):
|
||||||
</Entry>
|
</Entry>
|
||||||
<Entry key="CredentialsDialog_WirelessNetworkMessage">
|
<Entry key="CredentialsDialog_WirelessNetworkMessage">
|
||||||
请输入与无线网络 "%%_NAME_%%" 建立连接所需的凭证。
|
请输入与无线网络 "%%_NAME_%%" 建立连接所需的凭证。
|
||||||
|
|
|
@ -11,6 +11,7 @@ using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using SafeExamBrowser.SystemComponents.Contracts.Network;
|
using SafeExamBrowser.SystemComponents.Contracts.Network;
|
||||||
using Windows.Devices.WiFi;
|
using Windows.Devices.WiFi;
|
||||||
|
using Windows.Networking.Connectivity;
|
||||||
|
|
||||||
namespace SafeExamBrowser.SystemComponents.Network
|
namespace SafeExamBrowser.SystemComponents.Network
|
||||||
{
|
{
|
||||||
|
@ -21,6 +22,16 @@ namespace SafeExamBrowser.SystemComponents.Network
|
||||||
return networks.Where(n => !string.IsNullOrEmpty(n.Ssid)).GroupBy(n => n.Ssid).Select(g => g.First()).OrderBy(n => n.Ssid);
|
return networks.Where(n => !string.IsNullOrEmpty(n.Ssid)).GroupBy(n => n.Ssid).Select(g => g.First()).OrderBy(n => n.Ssid);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal static bool IsOpen(this WiFiAvailableNetwork network)
|
||||||
|
{
|
||||||
|
return network.SecuritySettings.NetworkAuthenticationType == NetworkAuthenticationType.Open80211 && network.SecuritySettings.NetworkEncryptionType == NetworkEncryptionType.None;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static string ToLogString(this WiFiAvailableNetwork network)
|
||||||
|
{
|
||||||
|
return $"'{network.Ssid}' ({network.SecuritySettings.NetworkAuthenticationType}, {network.SecuritySettings.NetworkEncryptionType})";
|
||||||
|
}
|
||||||
|
|
||||||
internal static WirelessNetwork ToWirelessNetwork(this WiFiAvailableNetwork network)
|
internal static WirelessNetwork ToWirelessNetwork(this WiFiAvailableNetwork network)
|
||||||
{
|
{
|
||||||
return new WirelessNetwork
|
return new WirelessNetwork
|
||||||
|
|
|
@ -7,9 +7,11 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Concurrent;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Net.NetworkInformation;
|
using System.Net.NetworkInformation;
|
||||||
|
using System.Threading.Tasks;
|
||||||
using SafeExamBrowser.Logging.Contracts;
|
using SafeExamBrowser.Logging.Contracts;
|
||||||
using SafeExamBrowser.SystemComponents.Contracts.Network;
|
using SafeExamBrowser.SystemComponents.Contracts.Network;
|
||||||
using SafeExamBrowser.SystemComponents.Contracts.Network.Events;
|
using SafeExamBrowser.SystemComponents.Contracts.Network.Events;
|
||||||
|
@ -27,12 +29,13 @@ namespace SafeExamBrowser.SystemComponents.Network
|
||||||
{
|
{
|
||||||
private readonly object @lock = new object();
|
private readonly object @lock = new object();
|
||||||
|
|
||||||
|
private readonly ConcurrentDictionary<string, object> attempts;
|
||||||
private readonly ILogger logger;
|
private readonly ILogger logger;
|
||||||
private readonly INativeMethods nativeMethods;
|
private readonly INativeMethods nativeMethods;
|
||||||
private readonly List<WirelessNetwork> wirelessNetworks;
|
private readonly List<WirelessNetwork> wirelessNetworks;
|
||||||
|
|
||||||
private Timer timer;
|
|
||||||
private WiFiAdapter adapter;
|
private WiFiAdapter adapter;
|
||||||
|
private Timer timer;
|
||||||
|
|
||||||
private bool HasWirelessAdapter => adapter != default;
|
private bool HasWirelessAdapter => adapter != default;
|
||||||
|
|
||||||
|
@ -44,6 +47,7 @@ namespace SafeExamBrowser.SystemComponents.Network
|
||||||
|
|
||||||
public NetworkAdapter(ILogger logger, INativeMethods nativeMethods)
|
public NetworkAdapter(ILogger logger, INativeMethods nativeMethods)
|
||||||
{
|
{
|
||||||
|
this.attempts = new ConcurrentDictionary<string, object>();
|
||||||
this.logger = logger;
|
this.logger = logger;
|
||||||
this.nativeMethods = nativeMethods;
|
this.nativeMethods = nativeMethods;
|
||||||
this.wirelessNetworks = new List<WirelessNetwork>();
|
this.wirelessNetworks = new List<WirelessNetwork>();
|
||||||
|
@ -51,6 +55,7 @@ namespace SafeExamBrowser.SystemComponents.Network
|
||||||
|
|
||||||
public void ConnectToWirelessNetwork(string name)
|
public void ConnectToWirelessNetwork(string name)
|
||||||
{
|
{
|
||||||
|
var isFirstAttempt = !attempts.TryGetValue(name, out _);
|
||||||
var network = default(WiFiAvailableNetwork);
|
var network = default(WiFiAvailableNetwork);
|
||||||
|
|
||||||
lock (@lock)
|
lock (@lock)
|
||||||
|
@ -60,29 +65,21 @@ namespace SafeExamBrowser.SystemComponents.Network
|
||||||
|
|
||||||
if (network != default)
|
if (network != default)
|
||||||
{
|
{
|
||||||
var isOpen = network.SecuritySettings.NetworkAuthenticationType == NetworkAuthenticationType.Open80211 && network.SecuritySettings.NetworkEncryptionType == NetworkEncryptionType.None;
|
if (isFirstAttempt || network.IsOpen())
|
||||||
|
|
||||||
if (isOpen)
|
|
||||||
{
|
{
|
||||||
logger.Info($"Attempting to connect to open wireless network '{name}'...");
|
ConnectAutomatically(network);
|
||||||
|
|
||||||
adapter.ConnectAsync(network, WiFiReconnectionKind.Automatic).Completed = (o, s) => Adapter_ConnectCompleted(name, o, s);
|
|
||||||
Status = ConnectionStatus.Connecting;
|
|
||||||
}
|
}
|
||||||
else if (TryGetCredentials(name, out var credentials))
|
else
|
||||||
{
|
{
|
||||||
logger.Info($"Attempting to connect to wireless network '{name}' with credentials...");
|
ConnectWithAuthentication(network);
|
||||||
|
|
||||||
adapter.ConnectAsync(network, WiFiReconnectionKind.Automatic, credentials).Completed = (o, s) => Adapter_ConnectCompleted(name, o, s);
|
|
||||||
Status = ConnectionStatus.Connecting;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Changed?.Invoke();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
logger.Warn($"Could not find wireless network '{name}'!");
|
logger.Warn($"Could not find wireless network '{name}'!");
|
||||||
}
|
}
|
||||||
|
|
||||||
Changed?.Invoke();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public IEnumerable<IWirelessNetwork> GetWirelessNetworks()
|
public IEnumerable<IWirelessNetwork> GetWirelessNetworks()
|
||||||
|
@ -146,6 +143,68 @@ namespace SafeExamBrowser.SystemComponents.Network
|
||||||
logger.Info("Stopped monitoring the network adapter.");
|
logger.Info("Stopped monitoring the network adapter.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void Adapter_AvailableNetworksChanged(WiFiAdapter sender, object args)
|
||||||
|
{
|
||||||
|
Update(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Adapter_ConnectCompleted(WiFiAvailableNetwork network, IAsyncOperation<WiFiConnectionResult> operation, AsyncStatus status)
|
||||||
|
{
|
||||||
|
var connectionStatus = default(WiFiConnectionStatus?);
|
||||||
|
|
||||||
|
if (status == AsyncStatus.Completed)
|
||||||
|
{
|
||||||
|
connectionStatus = operation.GetResults()?.ConnectionStatus;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
logger.Error($"Failed to complete connection operation! Status: {status}.");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (connectionStatus == WiFiConnectionStatus.Success)
|
||||||
|
{
|
||||||
|
attempts.TryRemove(network.Ssid, out _);
|
||||||
|
logger.Info($"Successfully connected to wireless network {network.ToLogString()}.");
|
||||||
|
}
|
||||||
|
else if (connectionStatus == WiFiConnectionStatus.InvalidCredential)
|
||||||
|
{
|
||||||
|
attempts.TryAdd(network.Ssid, default);
|
||||||
|
logger.Info($"Failed to connect to wireless network {network.ToLogString()} due to invalid credentials. Retrying...");
|
||||||
|
Task.Run(() => ConnectToWirelessNetwork(network.Ssid));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Status = ConnectionStatus.Disconnected;
|
||||||
|
logger.Error($"Failed to connect to wireless network {network.ToLogString()}! Reason: {connectionStatus}.");
|
||||||
|
}
|
||||||
|
|
||||||
|
Update();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ConnectAutomatically(WiFiAvailableNetwork network)
|
||||||
|
{
|
||||||
|
logger.Info($"Attempting to automatically connect to {(network.IsOpen() ? "open" : "protected")} wireless network {network.ToLogString()}...");
|
||||||
|
|
||||||
|
adapter.ConnectAsync(network, WiFiReconnectionKind.Automatic).Completed = (o, s) => Adapter_ConnectCompleted(network, o, s);
|
||||||
|
Status = ConnectionStatus.Connecting;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ConnectWithAuthentication(WiFiAvailableNetwork network)
|
||||||
|
{
|
||||||
|
if (TryGetCredentials(network.Ssid, out var credentials))
|
||||||
|
{
|
||||||
|
logger.Info($"Attempting to connect to protected wirless network {network.ToLogString()}...");
|
||||||
|
|
||||||
|
adapter.ConnectAsync(network, WiFiReconnectionKind.Automatic, credentials).Completed = (o, s) => Adapter_ConnectCompleted(network, o, s);
|
||||||
|
Status = ConnectionStatus.Connecting;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Status = ConnectionStatus.Disconnected;
|
||||||
|
Update();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void InitializeAdapter()
|
private void InitializeAdapter()
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
|
@ -188,38 +247,6 @@ namespace SafeExamBrowser.SystemComponents.Network
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Adapter_AvailableNetworksChanged(WiFiAdapter sender, object args)
|
|
||||||
{
|
|
||||||
Update(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void Adapter_ConnectCompleted(string name, IAsyncOperation<WiFiConnectionResult> operation, AsyncStatus status)
|
|
||||||
{
|
|
||||||
var connectionStatus = default(WiFiConnectionStatus?);
|
|
||||||
|
|
||||||
if (status == AsyncStatus.Completed)
|
|
||||||
{
|
|
||||||
connectionStatus = operation.GetResults()?.ConnectionStatus;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
logger.Error($"Failed to complete connection operation! Status: {status}.");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (connectionStatus == WiFiConnectionStatus.Success)
|
|
||||||
{
|
|
||||||
Status = ConnectionStatus.Connected;
|
|
||||||
logger.Info($"Successfully connected to wireless network '{name}'.");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Status = ConnectionStatus.Disconnected;
|
|
||||||
logger.Error($"Failed to connect to wireless network '{name}'! Reason: {connectionStatus}.");
|
|
||||||
}
|
|
||||||
|
|
||||||
Update();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void NetworkChange_NetworkAddressChanged(object sender, EventArgs e)
|
private void NetworkChange_NetworkAddressChanged(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
logger.Debug("Network address changed.");
|
logger.Debug("Network address changed.");
|
||||||
|
@ -292,7 +319,7 @@ namespace SafeExamBrowser.SystemComponents.Network
|
||||||
{
|
{
|
||||||
lock (@lock)
|
lock (@lock)
|
||||||
{
|
{
|
||||||
var hasInternet = nativeMethods.HasInternetConnection();
|
var hasConnection = nativeMethods.HasInternetConnection();
|
||||||
var isConnecting = Status == ConnectionStatus.Connecting;
|
var isConnecting = Status == ConnectionStatus.Connecting;
|
||||||
var previousStatus = Status;
|
var previousStatus = Status;
|
||||||
|
|
||||||
|
@ -300,7 +327,7 @@ namespace SafeExamBrowser.SystemComponents.Network
|
||||||
|
|
||||||
if (HasWirelessAdapter)
|
if (HasWirelessAdapter)
|
||||||
{
|
{
|
||||||
TryGetCurrentWirelessNetwork(out var currentNetwork);
|
hasConnection &= TryGetCurrentWirelessNetwork(out var currentNetwork);
|
||||||
|
|
||||||
foreach (var network in adapter.NetworkReport.AvailableNetworks.FilterAndOrder())
|
foreach (var network in adapter.NetworkReport.AvailableNetworks.FilterAndOrder())
|
||||||
{
|
{
|
||||||
|
@ -320,8 +347,8 @@ namespace SafeExamBrowser.SystemComponents.Network
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Type = HasWirelessAdapter ? ConnectionType.Wireless : (hasInternet ? ConnectionType.Wired : ConnectionType.Undefined);
|
Type = HasWirelessAdapter ? ConnectionType.Wireless : (hasConnection ? ConnectionType.Wired : ConnectionType.Undefined);
|
||||||
Status = hasInternet ? ConnectionStatus.Connected : (HasWirelessAdapter && isConnecting ? ConnectionStatus.Connecting : ConnectionStatus.Disconnected);
|
Status = hasConnection ? ConnectionStatus.Connected : (isConnecting ? ConnectionStatus.Connecting : ConnectionStatus.Disconnected);
|
||||||
|
|
||||||
LogNetworkChanges(previousStatus, wirelessNetworks.FirstOrDefault(n => n.Status == ConnectionStatus.Connected));
|
LogNetworkChanges(previousStatus, wirelessNetworks.FirstOrDefault(n => n.Status == ConnectionStatus.Connected));
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue