Hi,
I have not looked into the code yet. But, from Remote Openhab binding’s introduction page, it doesn’t let us to put in username password. So, I assume that it doesn’t support connecting remote OH2/3 instances via OpenHabCloud? Reason being that all my remote OH instances are connected to OpenhabCloud, and i thought it would be easier to have the master OH3 accessing the remote instances via OpenHabcloud instead.
Thanks
Lolodomo
(Lolodomo)
February 3, 2021, 8:46pm
2
It does not.
Feature not implemented.
Should be investigated, I am even not sure this would be possible.
My naive idea is to add authencation store to httpclient. Once logged in, I think we can access items via /rest? Cheers
Lolodomo
(Lolodomo)
February 4, 2021, 12:17pm
4
I will investigate this weekend. It may be relatively easy to add this feature but not yet certain.
OK, no problem. I think have done a quick hack on this and here are my code. Anyway, thanks for your contribution
In RemoteopenhabRestClient:
public String executeUrl(HttpMethod httpMethod, String url, String acceptHeader, @Nullable InputStream content,
@Nullable String contentType, boolean asyncReading) throws RemoteopenhabException {
final Request request = httpClient.newRequest(url).method(httpMethod).timeout(REQUEST_TIMEOUT,
TimeUnit.MILLISECONDS);
final String credentialToken = Base64.getEncoder()
.encodeToString((this.username + ":" + this.password).getBytes());
request.header(HttpHeaders.ACCEPT, acceptHeader);
**request.header(HttpHeader.AUTHORIZATION, "Basic " + credentialToken);**
if (!accessToken.isEmpty()) {
request.header(HttpHeaders.AUTHORIZATION, "Bearer " + accessToken);
}
…
Then on
private SseEventSource createEventSource(String restSseUrl) {
Client client;
String credentialToken = Base64.getEncoder().encodeToString((this.username + ":" + this.password).getBytes());
// Avoid a timeout exception after 1 minute by setting the read timeout to 0 (infinite)
if (trustedCertificate) {
client = clientBuilder.sslContext(httpClient.getSslContextFactory().getSslContext())
.register(new RemoteopenhabAuthenticator(this.username, this.password))
.hostnameVerifier(new HostnameVerifier() {
@Override
public boolean verify(@Nullable String hostname, @Nullable SSLSession session) {
return true;
}
}).readTimeout(0, TimeUnit.SECONDS).register(new RemoteopenhabStreamingRequestFilter(accessToken))
.build();
} else {
client = clientBuilder.readTimeout(0, TimeUnit.SECONDS)
.register(new RemoteopenhabAuthenticator(this.username, this.password))
.register(new RemoteopenhabStreamingRequestFilter(accessToken)).build();
}
SseEventSource eventSource = eventSourceFactory.newSource(client.target(restSseUrl));
eventSource.register(this::onEvent, this::onError);
return eventSource;
}
Here is the authenticator:
public class RemoteopenhabAuthenticator implements ClientRequestFilter {
private String user;
private String password;
@Override
public void filter(ClientRequestContext requestContext) throws IOException {
MultivaluedMap<String, Object> headers = requestContext.getHeaders();
final String basicAuthentication = getBasicAuthentication();
headers.add("Authorization", basicAuthentication);
}
public RemoteopenhabAuthenticator(String user, String password) {
this.user = user;
this.password = password;
}
private String getBasicAuthentication() {
String token = this.user + ":" + this.password;
try {
return "BASIC " + DatatypeConverter.printBase64Binary(token.getBytes("UTF-8"));
} catch (UnsupportedEncodingException ex) {
throw new IllegalStateException("Cannot encode with UTF-8", ex);
}
}
}
Lolodomo
(Lolodomo)
February 4, 2021, 4:21pm
6
Don’t hesitate to propose a PR if you validated a solution. It will save my time for something else.
Lolodomo
(Lolodomo)
February 4, 2021, 4:24pm
7
I will review and test your solution once submitted.