WIFI-835: Captive Portal: User List Authentication feature does not work unless user list is pushed to cloud manually.

This commit is contained in:
Mike Hansen
2021-03-05 15:39:01 -05:00
parent d6f907f1af
commit 8510882ed8
2 changed files with 198 additions and 150 deletions

View File

@@ -141,6 +141,9 @@ public class OvsdbDaoBase {
@org.springframework.beans.factory.annotation.Value("${tip.wlan.externalFileStoreURL:https://localhost:9096}") @org.springframework.beans.factory.annotation.Value("${tip.wlan.externalFileStoreURL:https://localhost:9096}")
String externalFileStoreURL; String externalFileStoreURL;
@org.springframework.beans.factory.annotation.Value("${tip.wlan.fileStoreDirectory:/tmp/tip-wlan-filestore}")
String fileStoreDirectoryName;
public OvsdbDaoBase() { public OvsdbDaoBase() {
} }

View File

@@ -11,7 +11,10 @@ import com.telecominfraproject.wlan.profile.bonjour.models.BonjourGatewayProfile
import com.telecominfraproject.wlan.profile.bonjour.models.BonjourServiceSet; import com.telecominfraproject.wlan.profile.bonjour.models.BonjourServiceSet;
import com.telecominfraproject.wlan.profile.captiveportal.models.CaptivePortalAuthenticationType; import com.telecominfraproject.wlan.profile.captiveportal.models.CaptivePortalAuthenticationType;
import com.telecominfraproject.wlan.profile.captiveportal.models.CaptivePortalConfiguration; import com.telecominfraproject.wlan.profile.captiveportal.models.CaptivePortalConfiguration;
import com.telecominfraproject.wlan.profile.captiveportal.user.models.TimedAccessUserRecord;
import com.telecominfraproject.wlan.profile.models.Profile; import com.telecominfraproject.wlan.profile.models.Profile;
import com.telecominfraproject.wlan.profile.models.common.FileCategory;
import com.telecominfraproject.wlan.profile.models.common.FileType;
import com.telecominfraproject.wlan.profile.models.common.ManagedFileInfo; import com.telecominfraproject.wlan.profile.models.common.ManagedFileInfo;
import com.telecominfraproject.wlan.profile.network.models.ApNetworkConfiguration; import com.telecominfraproject.wlan.profile.network.models.ApNetworkConfiguration;
import com.telecominfraproject.wlan.profile.network.models.GreTunnelConfiguration; import com.telecominfraproject.wlan.profile.network.models.GreTunnelConfiguration;
@@ -31,6 +34,12 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import java.util.Map; import java.util.Map;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;
import java.util.*; import java.util.*;
import java.util.Set; import java.util.Set;
import java.util.Map.Entry; import java.util.Map.Entry;
@@ -229,9 +238,9 @@ public class OvsdbSsidConfig extends OvsdbDaoBase {
* @param dynamicVlan * @param dynamicVlan
*/ */
void configureCustomOptionsForSsid(OvsdbClient ovsdbClient, boolean enable80211k, boolean rateLimitEnable, void configureCustomOptionsForSsid(OvsdbClient ovsdbClient, boolean enable80211k, boolean rateLimitEnable,
int ssidDlLimit, int ssidUlLimit, int clientDlLimit, int clientUlLimit, int rtsCtsThreshold, int ssidDlLimit, int ssidUlLimit, int clientDlLimit, int clientUlLimit, int rtsCtsThreshold, int dtimPeriod,
int dtimPeriod, String radiusNasId, String radiusNasIp, String radiusOperatorName, String radiusNasId, String radiusNasIp, String radiusOperatorName, Map<String, Value> updateColumns,
Map<String, Value> updateColumns, int dynamicVlan) { int dynamicVlan) {
Map<String, String> customOptions = new HashMap<>(); Map<String, String> customOptions = new HashMap<>();
configureCustomOptionsForRatesAndLimits(rateLimitEnable, ssidDlLimit, ssidUlLimit, clientDlLimit, clientUlLimit, configureCustomOptionsForRatesAndLimits(rateLimitEnable, ssidDlLimit, ssidUlLimit, clientDlLimit, clientUlLimit,
rtsCtsThreshold, customOptions); rtsCtsThreshold, customOptions);
@@ -249,14 +258,13 @@ public class OvsdbSsidConfig extends OvsdbDaoBase {
} }
void configureSingleSsid(OvsdbClient ovsdbClient, String vifInterfaceName, String ssid, boolean ssidBroadcast, void configureSingleSsid(OvsdbClient ovsdbClient, String vifInterfaceName, String ssid, boolean ssidBroadcast,
Map<String, String> security, int vlanId, boolean rrmEnabled, boolean enable80211r, Map<String, String> security, int vlanId, boolean rrmEnabled, boolean enable80211r, int mobilityDomain,
int mobilityDomain, boolean enable80211v, boolean enable80211k, String minHwMode, boolean enabled, boolean enable80211v, boolean enable80211k, String minHwMode, boolean enabled, int keyRefresh,
int keyRefresh, boolean uapsdEnabled, boolean apBridge, NetworkForwardMode networkForwardMode, boolean uapsdEnabled, boolean apBridge, NetworkForwardMode networkForwardMode,
List<MacAddress> macBlockList, List<MacAddress> macBlockList, boolean rateLimitEnable, int ssidDlLimit, int ssidUlLimit, int clientDlLimit,
boolean rateLimitEnable, int ssidDlLimit, int ssidUlLimit, int clientDlLimit, int clientUlLimit, int clientUlLimit, int rtsCtsThreshold, int dtimPeriod, Map<String, String> captiveMap,
int rtsCtsThreshold, int dtimPeriod, Map<String, String> captiveMap, List<String> walledGardenAllowlist, String radiusNasId, String radiusNasIp, String radiusOperatorName,
List<String> walledGardenAllowlist, String radiusNasId, String greTunnelName, int dynamicVlan, List<Operation> operations) {
String radiusNasIp, String radiusOperatorName, String greTunnelName, int dynamicVlan, List<Operation> operations) {
Map<String, Value> updateColumns = new HashMap<>(); Map<String, Value> updateColumns = new HashMap<>();
// If we are doing a NAT SSID, no bridge, else yes // If we are doing a NAT SSID, no bridge, else yes
@@ -316,8 +324,8 @@ public class OvsdbSsidConfig extends OvsdbDaoBase {
.of(security); .of(security);
updateColumns.put("security", securityMap); updateColumns.put("security", securityMap);
configureCustomOptionsForSsid(ovsdbClient, enable80211k, rateLimitEnable, ssidDlLimit, ssidUlLimit, configureCustomOptionsForSsid(ovsdbClient, enable80211k, rateLimitEnable, ssidDlLimit, ssidUlLimit,
clientDlLimit, clientUlLimit, rtsCtsThreshold, dtimPeriod, radiusNasId, clientDlLimit, clientUlLimit, rtsCtsThreshold, dtimPeriod, radiusNasId, radiusNasIp, radiusOperatorName,
radiusNasIp, radiusOperatorName, updateColumns, dynamicVlan); updateColumns, dynamicVlan);
updateBlockList(updateColumns, macBlockList); updateBlockList(updateColumns, macBlockList);
Row row = new Row(updateColumns); Row row = new Row(updateColumns);
operations.add(new Insert(wifiVifConfigDbTable, row)); operations.add(new Insert(wifiVifConfigDbTable, row));
@@ -410,7 +418,8 @@ public class OvsdbSsidConfig extends OvsdbDaoBase {
ifName = defaultRadio2; ifName = defaultRadio2;
} }
if (ifName == null) { if (ifName == null) {
LOG.debug("Cannot provision SSID for radio {} freqBand {} with VIF if_name null", radioName, freqBand); LOG.debug("Cannot provision SSID for radio {} freqBand {} with VIF if_name null", radioName,
freqBand);
continue; continue;
} }
@@ -538,15 +547,15 @@ public class OvsdbSsidConfig extends OvsdbDaoBase {
} }
try { try {
configureSingleSsid(ovsdbClient, ifName, ssidConfig.getSsid(), ssidBroadcast, configureSingleSsid(ovsdbClient, ifName, ssidConfig.getSsid(), ssidBroadcast, security, vlanId,
security, vlanId, rrmEnabled, enable80211r, mobilityDomain, enable80211v, rrmEnabled, enable80211r, mobilityDomain, enable80211v, enable80211k, minHwMode, enabled,
enable80211k, minHwMode, enabled, keyRefresh, uapsdEnabled, apBridge, keyRefresh, uapsdEnabled, apBridge, ssidConfig.getForwardMode(), macBlockList,
ssidConfig.getForwardMode(), macBlockList,
rateLimitEnable, ssidDlLimit, ssidUlLimit, clientDlLimit, clientUlLimit, rtsCtsThreshold, rateLimitEnable, ssidDlLimit, ssidUlLimit, clientDlLimit, clientUlLimit, rtsCtsThreshold,
dtimPeriod, captiveMap, walledGardenAllowlist, dtimPeriod, captiveMap, walledGardenAllowlist, radiusNasId, radiusNasIp, radiusOperName,
radiusNasId, radiusNasIp, radiusOperName, greTunnelName, dynamicVlan,operations); greTunnelName, dynamicVlan, operations);
networkConfig.configureInetVifInterface(ovsdbClient, ifName, enabled, ssidConfig.getForwardMode(),operations ); networkConfig.configureInetVifInterface(ovsdbClient, ifName, enabled, ssidConfig.getForwardMode(),
operations);
} catch (IllegalStateException e) { } catch (IllegalStateException e) {
// could not provision this SSID, but still can go on // could not provision this SSID, but still can go on
LOG.warn("could not provision SSID {} on {}", ssidConfig.getSsid(), freqBand); LOG.warn("could not provision SSID {} on {}", ssidConfig.getSsid(), freqBand);
@@ -655,24 +664,31 @@ public class OvsdbSsidConfig extends OvsdbDaoBase {
} }
} }
} }
if (captiveProfileDetails.getRedirectURL() != null) { if (captiveProfileDetails.getRedirectURL() != null) {
captiveMap.put("redirect_url", captiveProfileDetails.getRedirectURL()); captiveMap.put("redirect_url", captiveProfileDetails.getRedirectURL());
} }
captiveMap.put("session_timeout", captiveMap.put("session_timeout",
String.valueOf(captiveProfileDetails.getSessionTimeoutInMinutes())); String.valueOf(captiveProfileDetails.getSessionTimeoutInMinutes()));
captiveMap.put("browser_title", captiveProfileDetails.getBrowserTitle()); captiveMap.put("browser_title", captiveProfileDetails.getBrowserTitle());
captiveMap.put("splash_page_title", captiveProfileDetails.getHeaderContent()); captiveMap.put("splash_page_title", captiveProfileDetails.getHeaderContent());
captiveMap.put("acceptance_policy", captiveProfileDetails.getUserAcceptancePolicy()); captiveMap.put("acceptance_policy", captiveProfileDetails.getUserAcceptancePolicy());
captiveMap.put("login_success_text", captiveProfileDetails.getSuccessPageMarkdownText()); captiveMap.put("login_success_text", captiveProfileDetails.getSuccessPageMarkdownText());
captiveMap.put("authentication", captiveMap.put("authentication",
getCaptiveAuthentication(captiveProfileDetails.getAuthenticationType())); getCaptiveAuthentication(captiveProfileDetails.getAuthenticationType()));
if (captiveProfileDetails.getUsernamePasswordFile() != null) { if (!externalFileStoreURL.endsWith("/filestore/")) {
externalFileStoreURL = externalFileStoreURL + "/filestore/";
}
if (captiveProfileDetails.getAuthenticationType().equals(CaptivePortalAuthenticationType.username)) {
// create a user/password file for the AP to pull
Path userFilepath = createCaptivePortalUserFile(captiveProfileDetails.getUserList(),profileCaptive.getId());
ManagedFileInfo mfi = new ManagedFileInfo();
mfi.setFileCategory(FileCategory.UsernamePasswordList);
mfi.setFileType(FileType.TEXT);
mfi.setApExportUrl(userFilepath.getFileName().toString());
captiveMap captiveMap
.put("username_password_file", .put("username_password_file",
ManagedFileInfo.resolveWithPopulatedHostname( ManagedFileInfo.resolveWithPopulatedHostname(
captiveProfileDetails.getUsernamePasswordFile(), externalFileStoreURL) mfi, externalFileStoreURL)
.getApExportUrl()); .getApExportUrl());
} }
if (captiveProfileDetails.getLogoFile() != null) { if (captiveProfileDetails.getLogoFile() != null) {
@@ -693,6 +709,35 @@ public class OvsdbSsidConfig extends OvsdbDaoBase {
} }
} }
Path createCaptivePortalUserFile(List<TimedAccessUserRecord> userList, long captivePortalProfileId) {
Path path = Paths.get(
fileStoreDirectoryName + File.separator + "captive-portal-users-" + captivePortalProfileId + ".txt");
try {
Files.deleteIfExists(path);
} catch (Exception e) {
LOG.error("Cannot delete {}", path, e);
}
for (TimedAccessUserRecord userRecord : userList) {
byte[] bytes = ("username=" + userRecord.getUsername() + ", password=" + userRecord.getPassword()
+ ", firstname=" + userRecord.getUserDetails().getFirstName() + ", lastname="
+ userRecord.getUserDetails().getLastName() + System.lineSeparator()).getBytes();
try {
Files.write(path, bytes, StandardOpenOption.APPEND);
LOG.debug("Successfully written data to the file {}", path);
} catch (IOException e) {
try {
Files.write(path, bytes);
} catch (IOException e1) {
throw new RuntimeException(e1);
}
}
}
return path;
}
/** /**
* Maps between the osvdb security definitions and the cloud's security mode * Maps between the osvdb security definitions and the cloud's security mode
* for the give SSID being configured. * for the give SSID being configured.