mirror of
https://github.com/openhab/openhab-addons.git
synced 2025-01-10 15:11:59 +01:00
[unifi] Added support for UniFi OS (#10041)
Signed-off-by: Mathias Maes <watcherwhale@maes.family>
This commit is contained in:
parent
d452469450
commit
6b4fc99164
@ -53,6 +53,7 @@ public class UniFiBindingConstants {
|
||||
public static final String PARAMETER_PORT = "port";
|
||||
public static final String PARAMETER_USERNAME = "username";
|
||||
public static final String PARAMETER_PASSWORD = "password";
|
||||
public static final String PARAMETER_UNIFIOS = "unifios";
|
||||
public static final String PARAMETER_SITE = "site";
|
||||
public static final String PARAMETER_CID = "cid";
|
||||
}
|
||||
|
@ -33,6 +33,8 @@ public class UniFiControllerThingConfig {
|
||||
|
||||
private int refresh = 10;
|
||||
|
||||
private boolean unifios = false;
|
||||
|
||||
public String getHost() {
|
||||
return host;
|
||||
}
|
||||
@ -53,6 +55,10 @@ public class UniFiControllerThingConfig {
|
||||
return refresh;
|
||||
}
|
||||
|
||||
public boolean isUniFiOS() {
|
||||
return unifios;
|
||||
}
|
||||
|
||||
public boolean isValid() {
|
||||
return StringUtils.isNotBlank(host) && StringUtils.isNotBlank(username) && StringUtils.isNotBlank(password);
|
||||
}
|
||||
@ -60,6 +66,6 @@ public class UniFiControllerThingConfig {
|
||||
@Override
|
||||
public String toString() {
|
||||
return "UniFiControllerConfig{host = " + host + ", port = " + port + ", username = " + username
|
||||
+ ", password = *****, refresh = " + refresh + "}";
|
||||
+ ", password = *****, refresh = " + refresh + ", unifios = " + unifios + "}";
|
||||
}
|
||||
}
|
||||
|
@ -65,14 +65,21 @@ public class UniFiController {
|
||||
|
||||
private final String password;
|
||||
|
||||
private final boolean unifios;
|
||||
|
||||
private String csrfToken;
|
||||
|
||||
private final Gson gson;
|
||||
|
||||
public UniFiController(HttpClient httpClient, String host, int port, String username, String password) {
|
||||
public UniFiController(HttpClient httpClient, String host, int port, String username, String password,
|
||||
boolean unifios) {
|
||||
this.httpClient = httpClient;
|
||||
this.host = host;
|
||||
this.port = port;
|
||||
this.username = username;
|
||||
this.password = password;
|
||||
this.unifios = unifios;
|
||||
this.csrfToken = "";
|
||||
UniFiSiteInstanceCreator siteInstanceCreator = new UniFiSiteInstanceCreator(this);
|
||||
UniFiDeviceInstanceCreator deviceInstanceCreator = new UniFiDeviceInstanceCreator(this);
|
||||
UniFiClientInstanceCreator clientInstanceCreator = new UniFiClientInstanceCreator(this);
|
||||
@ -96,8 +103,10 @@ public class UniFiController {
|
||||
}
|
||||
|
||||
public void login() throws UniFiException {
|
||||
csrfToken = "";
|
||||
|
||||
UniFiControllerRequest<Void> req = newRequest(Void.class);
|
||||
req.setPath("/api/login");
|
||||
req.setPath(unifios ? "/api/auth/login" : "/api/login");
|
||||
req.setBodyParameter("username", username);
|
||||
req.setBodyParameter("password", password);
|
||||
// scurb: Changed strict = false to make blocking feature work
|
||||
@ -107,8 +116,9 @@ public class UniFiController {
|
||||
}
|
||||
|
||||
public void logout() throws UniFiException {
|
||||
csrfToken = "";
|
||||
UniFiControllerRequest<Void> req = newRequest(Void.class);
|
||||
req.setPath("/logout");
|
||||
req.setPath(unifios ? "/api/auth/logout" : "/logout");
|
||||
executeRequest(req);
|
||||
}
|
||||
|
||||
@ -172,7 +182,7 @@ public class UniFiController {
|
||||
|
||||
protected void block(UniFiClient client, boolean blocked) throws UniFiException {
|
||||
UniFiControllerRequest<Void> req = newRequest(Void.class);
|
||||
req.setPath("/api/s/" + client.getSite().getName() + "/cmd/stamgr");
|
||||
req.setAPIPath("/api/s/" + client.getSite().getName() + "/cmd/stamgr");
|
||||
req.setBodyParameter("cmd", blocked ? "block-sta" : "unblock-sta");
|
||||
req.setBodyParameter("mac", client.getMac());
|
||||
executeRequest(req);
|
||||
@ -180,7 +190,7 @@ public class UniFiController {
|
||||
|
||||
protected void reconnect(UniFiClient client) throws UniFiException {
|
||||
UniFiControllerRequest<Void> req = newRequest(Void.class);
|
||||
req.setPath("/api/s/" + client.getSite().getName() + "/cmd/stamgr");
|
||||
req.setAPIPath("/api/s/" + client.getSite().getName() + "/cmd/stamgr");
|
||||
req.setBodyParameter("cmd", "kick-sta");
|
||||
req.setBodyParameter("mac", client.getMac());
|
||||
executeRequest(req);
|
||||
@ -189,13 +199,14 @@ public class UniFiController {
|
||||
// Internal API
|
||||
|
||||
private <T> UniFiControllerRequest<T> newRequest(Class<T> responseType) {
|
||||
return new UniFiControllerRequest<>(responseType, gson, httpClient, host, port);
|
||||
return new UniFiControllerRequest<>(responseType, gson, httpClient, host, port, csrfToken, unifios);
|
||||
}
|
||||
|
||||
private <T> @Nullable T executeRequest(UniFiControllerRequest<T> request) throws UniFiException {
|
||||
T result;
|
||||
try {
|
||||
result = request.execute();
|
||||
csrfToken = request.getCsrfToken();
|
||||
} catch (UniFiExpiredSessionException e) {
|
||||
login();
|
||||
result = executeRequest(request);
|
||||
@ -208,7 +219,7 @@ public class UniFiController {
|
||||
|
||||
private UniFiSiteCache getSites() throws UniFiException {
|
||||
UniFiControllerRequest<UniFiSite[]> req = newRequest(UniFiSite[].class);
|
||||
req.setPath("/api/self/sites");
|
||||
req.setAPIPath("/api/self/sites");
|
||||
UniFiSite[] sites = executeRequest(req);
|
||||
UniFiSiteCache cache = new UniFiSiteCache();
|
||||
if (sites != null) {
|
||||
@ -231,7 +242,7 @@ public class UniFiController {
|
||||
|
||||
private UniFiDeviceCache getDevices(UniFiSite site) throws UniFiException {
|
||||
UniFiControllerRequest<UniFiDevice[]> req = newRequest(UniFiDevice[].class);
|
||||
req.setPath("/api/s/" + site.getName() + "/stat/device");
|
||||
req.setAPIPath("/api/s/" + site.getName() + "/stat/device");
|
||||
UniFiDevice[] devices = executeRequest(req);
|
||||
UniFiDeviceCache cache = new UniFiDeviceCache();
|
||||
if (devices != null) {
|
||||
@ -254,7 +265,7 @@ public class UniFiController {
|
||||
|
||||
private UniFiClientCache getClients(UniFiSite site) throws UniFiException {
|
||||
UniFiControllerRequest<UniFiClient[]> req = newRequest(UniFiClient[].class);
|
||||
req.setPath("/api/s/" + site.getName() + "/stat/sta");
|
||||
req.setAPIPath("/api/s/" + site.getName() + "/stat/sta");
|
||||
UniFiClient[] clients = executeRequest(req);
|
||||
UniFiClientCache cache = new UniFiClientCache();
|
||||
if (clients != null) {
|
||||
@ -277,7 +288,7 @@ public class UniFiController {
|
||||
|
||||
private UniFiClientCache getInsights(UniFiSite site) throws UniFiException {
|
||||
UniFiControllerRequest<UniFiClient[]> req = newRequest(UniFiClient[].class);
|
||||
req.setPath("/api/s/" + site.getName() + "/stat/alluser");
|
||||
req.setAPIPath("/api/s/" + site.getName() + "/stat/alluser");
|
||||
req.setQueryParameter("within", 168); // scurb: Changed to 7 days.
|
||||
UniFiClient[] clients = executeRequest(req);
|
||||
UniFiClientCache cache = new UniFiClientCache();
|
||||
|
@ -83,6 +83,10 @@ public class UniFiControllerRequest<T> {
|
||||
|
||||
private String path = "/";
|
||||
|
||||
private final boolean unifios;
|
||||
|
||||
private String csrfToken;
|
||||
|
||||
private Map<String, String> queryParameters = new HashMap<>();
|
||||
|
||||
private Map<String, String> bodyParameters = new HashMap<>();
|
||||
@ -91,12 +95,23 @@ public class UniFiControllerRequest<T> {
|
||||
|
||||
// Public API
|
||||
|
||||
public UniFiControllerRequest(Class<T> resultType, Gson gson, HttpClient httpClient, String host, int port) {
|
||||
public UniFiControllerRequest(Class<T> resultType, Gson gson, HttpClient httpClient, String host, int port,
|
||||
String csrfToken, boolean unifios) {
|
||||
this.resultType = resultType;
|
||||
this.gson = gson;
|
||||
this.httpClient = httpClient;
|
||||
this.host = host;
|
||||
this.port = port;
|
||||
this.csrfToken = csrfToken;
|
||||
this.unifios = unifios;
|
||||
}
|
||||
|
||||
public void setAPIPath(String relativePath) {
|
||||
if (unifios) {
|
||||
this.path = "/proxy/network" + relativePath;
|
||||
} else {
|
||||
this.path = relativePath;
|
||||
}
|
||||
}
|
||||
|
||||
public void setPath(String path) {
|
||||
@ -136,6 +151,11 @@ public class UniFiControllerRequest<T> {
|
||||
if (logger.isTraceEnabled()) {
|
||||
logger.trace("<< {} {} \n{}", status, HttpStatus.getMessage(status), prettyPrintJson(content));
|
||||
}
|
||||
|
||||
String csrfToken = response.getHeaders().get("X-CSRF-Token");
|
||||
if (csrfToken != null && !csrfToken.isEmpty()) {
|
||||
this.csrfToken = csrfToken;
|
||||
}
|
||||
break;
|
||||
case HttpStatus.BAD_REQUEST_400:
|
||||
throw new UniFiInvalidCredentialsException("Invalid Credentials");
|
||||
@ -184,6 +204,10 @@ public class UniFiControllerRequest<T> {
|
||||
return response;
|
||||
}
|
||||
|
||||
public String getCsrfToken() {
|
||||
return csrfToken;
|
||||
}
|
||||
|
||||
private Request newRequest() {
|
||||
HttpMethod method = bodyParameters.isEmpty() ? HttpMethod.GET : HttpMethod.POST;
|
||||
HttpURI uri = new HttpURI(HttpScheme.HTTPS.asString(), host, port, path);
|
||||
@ -198,6 +222,10 @@ public class UniFiControllerRequest<T> {
|
||||
StandardCharsets.UTF_8);
|
||||
request = request.content(content);
|
||||
}
|
||||
|
||||
if (!csrfToken.isEmpty())
|
||||
request.header("x-csrf-token", this.csrfToken);
|
||||
|
||||
return request;
|
||||
}
|
||||
|
||||
|
@ -88,7 +88,7 @@ public class UniFiControllerThingHandler extends BaseBridgeHandler {
|
||||
logger.debug("Initializing the UniFi Controller Handler with config = {}", config);
|
||||
try {
|
||||
controller = new UniFiController(httpClient, config.getHost(), config.getPort(), config.getUsername(),
|
||||
config.getPassword());
|
||||
config.getPassword(), config.isUniFiOS());
|
||||
controller.start();
|
||||
updateStatus(ONLINE);
|
||||
} catch (UniFiInvalidHostException e) {
|
||||
|
@ -21,6 +21,10 @@
|
||||
<description>Port of the UniFi Controller</description>
|
||||
<default>8443</default>
|
||||
</parameter>
|
||||
<parameter name="unifios" type="boolean" required="true">
|
||||
<label>UniFi OS</label>
|
||||
<description>If the UniFi Controller is running on UniFi OS.</description>
|
||||
</parameter>
|
||||
<parameter name="username" type="text" required="true">
|
||||
<label>Username</label>
|
||||
<description>The username to access the UniFi Controller.</description>
|
||||
|
Loading…
Reference in New Issue
Block a user