Fix OAuth service handle (#18264)

Fixes #14783
Fixes #18265

Signed-off-by: Jacob Laursen <jacob-github@vindvejr.dk>
pull/18285/head
Jacob Laursen 2025-02-17 19:12:48 +01:00 committed by GitHub
parent d2555cbe7b
commit e3ba9a3ee3
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 42 additions and 10 deletions

View File

@ -227,6 +227,7 @@ public final class MieleCloudBindingConstants {
}
public static final String BRIDGE_STATUS_DESCRIPTION_ACCESS_TOKEN_NOT_CONFIGURED = "@text/mielecloud.bridge.status.access.token.not.configured";
public static final String BRIDGE_STATUS_DESCRIPTION_EMAIL_NOT_CONFIGURED = "@text/mielecloud.bridge.status.email.not.configured";
public static final String BRIDGE_STATUS_DESCRIPTION_ACCOUNT_NOT_AUTHORIZED = "@text/mielecloud.bridge.status.account.not.authorized";
public static final String BRIDGE_STATUS_DESCRIPTION_ACCESS_TOKEN_REFRESH_FAILED = "@text/mielecloud.bridge.status.access.token.refresh.failed";
public static final String BRIDGE_STATUS_DESCRIPTION_TRANSIENT_HTTP_ERROR = "@text/mielecloud.bridge.status.transient.http.error";

View File

@ -72,6 +72,7 @@ public final class OpenHabOAuthTokenRefresher implements OAuthTokenRefresher {
try {
OAuthClientService clientService = getOAuthClientService(serviceHandle);
clientService.removeAccessTokenRefreshListener(refreshListener);
oauthFactory.ungetOAuthService(serviceHandle);
} catch (OAuthException e) {
logger.warn("Failed to remove refresh listener: OAuth client service is unavailable. Cause: {}",
e.getMessage());

View File

@ -76,8 +76,8 @@ public final class OAuthAuthorizationHandlerImpl implements OAuthAuthorizationHa
throw new OngoingAuthorizationException("There is already an ongoing authorization!", timerExpiryTimestamp);
}
this.oauthClientService = oauthFactory.createOAuthClientService(email, TOKEN_URL, AUTHORIZATION_URL, clientId,
clientSecret, null, false);
this.oauthClientService = oauthFactory.createOAuthClientService(bridgeUid.getAsString(), TOKEN_URL,
AUTHORIZATION_URL, clientId, clientSecret, null, false);
this.bridgeUid = bridgeUid;
this.email = email;
redirectUri = null;
@ -136,6 +136,12 @@ public final class OAuthAuthorizationHandlerImpl implements OAuthAuthorizationHa
// Although this method is called "get" it actually fetches and stores the token response as a side effect.
oauthClientService.getAccessTokenResponseByAuthorizationCode(authorizationCode, redirectUri);
// Remove any legacy OAuth service handle.
String email = this.email;
if (email != null) {
oauthFactory.deleteServiceAndAccessToken(email);
}
} catch (IOException e) {
throw new OAuthException("Network error while retrieving token response: " + e.getMessage(), e);
} catch (OAuthResponseException e) {

View File

@ -73,6 +73,7 @@ public class MieleBridgeHandler extends BaseBridgeHandler
private @Nullable CompletableFuture<@Nullable Void> logoutFuture;
private @Nullable MieleWebservice webService;
private @Nullable ThingDiscoveryService discoveryService;
private @Nullable String oAuthServiceHandle;
/**
* Creates a new {@link MieleBridgeHandler}.
@ -109,7 +110,11 @@ public class MieleBridgeHandler extends BaseBridgeHandler
}
private String getOAuthServiceHandle() {
return getConfig().get(MieleCloudBindingConstants.CONFIG_PARAM_EMAIL).toString();
String oAuthServiceHandle = this.oAuthServiceHandle;
if (oAuthServiceHandle == null) {
oAuthServiceHandle = this.oAuthServiceHandle = getThing().getUID().getAsString();
}
return oAuthServiceHandle;
}
@Override
@ -132,13 +137,30 @@ public class MieleBridgeHandler extends BaseBridgeHandler
try {
tokenRefresher.setRefreshListener(this, getOAuthServiceHandle());
} catch (OAuthException e) {
logger.debug("Could not initialize Miele Cloud bridge.", e);
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR,
I18NKeys.BRIDGE_STATUS_DESCRIPTION_ACCOUNT_NOT_AUTHORIZED);
// When the authorization takes place a new initialization will be triggered. Therefore, we can leave the
// bridge in this state.
return;
String oAuthServiceHandleFallback = getConfig().get(MieleCloudBindingConstants.CONFIG_PARAM_EMAIL)
.toString();
if (oAuthServiceHandleFallback == null) {
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR,
I18NKeys.BRIDGE_STATUS_DESCRIPTION_EMAIL_NOT_CONFIGURED);
return;
}
try {
tokenRefresher.setRefreshListener(this, oAuthServiceHandleFallback);
oAuthServiceHandle = oAuthServiceHandleFallback;
logger.warn("Using legacy OAuth service handle, please re-authorize to migrate");
} catch (OAuthException e2) {
logger.debug("Could not initialize Miele Cloud bridge.", e2);
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR,
I18NKeys.BRIDGE_STATUS_DESCRIPTION_ACCOUNT_NOT_AUTHORIZED);
// When the authorization takes place a new initialization will be triggered. Therefore, we can leave
// the bridge in this state.
return;
}
}
languageProvider.setPrioritizedLanguageProvider(this);
tryInitializeWebservice();
@ -169,6 +191,7 @@ public class MieleBridgeHandler extends BaseBridgeHandler
getWebservice().disconnectSse();
languageProvider.unsetPrioritizedLanguageProvider();
tokenRefresher.unsetRefreshListener(getOAuthServiceHandle());
oAuthServiceHandle = null;
stopWebservice();
}

View File

@ -249,8 +249,9 @@ channel-type.mielecloud.battery_level.description=The battery level of the robot
# Error message texts
mielecloud.bridge.status.access.token.not.configured=The OAuth2 access token is not configured.
mielecloud.bridge.status.account.not.authorized=The account has not been authorized. Please consult the documentation on how to do that.
mielecloud.bridge.status.account.not.authorized=The account has not been authorized. Please authorize at http(s)://<YOUROPENHAB>:<YOURPORT>/mielecloud
mielecloud.bridge.status.access.token.refresh.failed=Failed to refresh the OAuth2 access token. Please authorize the account again.
mielecloud.bridge.status.email.not.configured=E-mail address is not configured.
mielecloud.bridge.status.transient.http.error=An unexpected HTTP error occurred. Check the logs if this error persists.
mielecloud.thing.status.webservice.missing=The Miele webservice cannot be accessed over the bridge. Check the bridge configuration.
mielecloud.thing.status.removed=This Miele device has been removed from the Miele@home account.