forked from openhab/openhab-addons
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[boschindego] Refactor OAuth2 implementation (openhab#14950)
* Delete OAuth2 token when thing is removed * Fix reinitialization * Introduce abstraction for OAuthClientService * Improve thing status synchronization --------- Signed-off-by: Jacob Laursen <jacob-github@vindvejr.dk> Signed-off-by: Matt Myers <mmyers75@icloud.com>
- Loading branch information
Showing
8 changed files
with
286 additions
and
87 deletions.
There are no files selected for viewing
103 changes: 103 additions & 0 deletions
103
...ndego/src/main/java/org/openhab/binding/boschindego/internal/AuthorizationController.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,103 @@ | ||
/** | ||
* Copyright (c) 2010-2023 Contributors to the openHAB project | ||
* | ||
* See the NOTICE file(s) distributed with this work for additional | ||
* information. | ||
* | ||
* This program and the accompanying materials are made available under the | ||
* terms of the Eclipse Public License 2.0 which is available at | ||
* http://www.eclipse.org/legal/epl-2.0 | ||
* | ||
* SPDX-License-Identifier: EPL-2.0 | ||
*/ | ||
package org.openhab.binding.boschindego.internal; | ||
|
||
import static org.openhab.binding.boschindego.internal.BoschIndegoBindingConstants.*; | ||
|
||
import java.io.IOException; | ||
|
||
import org.eclipse.jdt.annotation.NonNullByDefault; | ||
import org.openhab.binding.boschindego.internal.exceptions.IndegoAuthenticationException; | ||
import org.openhab.core.auth.client.oauth2.AccessTokenResponse; | ||
import org.openhab.core.auth.client.oauth2.OAuthClientService; | ||
import org.openhab.core.auth.client.oauth2.OAuthException; | ||
import org.openhab.core.auth.client.oauth2.OAuthResponseException; | ||
|
||
/** | ||
* The {@link AuthorizationController} acts as a bridge between | ||
* {@link OAuthClientService} and {@link IndegoController}. | ||
* | ||
* @author Jacob Laursen - Initial contribution | ||
*/ | ||
@NonNullByDefault | ||
public class AuthorizationController implements AuthorizationProvider { | ||
|
||
private static final String BEARER = "Bearer "; | ||
|
||
private final AuthorizationListener listener; | ||
|
||
private OAuthClientService oAuthClientService; | ||
|
||
public AuthorizationController(OAuthClientService oAuthClientService, AuthorizationListener listener) { | ||
this.oAuthClientService = oAuthClientService; | ||
this.listener = listener; | ||
} | ||
|
||
public void setOAuthClientService(OAuthClientService oAuthClientService) { | ||
this.oAuthClientService = oAuthClientService; | ||
} | ||
|
||
public String getAuthorizationHeader() throws IndegoAuthenticationException { | ||
final AccessTokenResponse accessTokenResponse; | ||
try { | ||
accessTokenResponse = getAccessToken(); | ||
} catch (OAuthException | OAuthResponseException e) { | ||
var throwable = new IndegoAuthenticationException( | ||
"Error fetching access token. Invalid authcode? Please generate a new one -> " | ||
+ getAuthorizationUrl(), | ||
e); | ||
listener.onFailedAuthorization(throwable); | ||
throw throwable; | ||
} catch (IOException e) { | ||
var throwable = new IndegoAuthenticationException("An unexpected IOException occurred: " + e.getMessage(), | ||
e); | ||
listener.onFailedAuthorization(throwable); | ||
throw throwable; | ||
} | ||
|
||
String accessToken = accessTokenResponse.getAccessToken(); | ||
if (accessToken == null || accessToken.isEmpty()) { | ||
var throwable = new IndegoAuthenticationException( | ||
"No access token. Is this thing authorized? -> " + getAuthorizationUrl()); | ||
listener.onFailedAuthorization(throwable); | ||
throw throwable; | ||
} | ||
if (accessTokenResponse.getRefreshToken() == null || accessTokenResponse.getRefreshToken().isEmpty()) { | ||
var throwable = new IndegoAuthenticationException( | ||
"No refresh token. Please reauthorize -> " + getAuthorizationUrl()); | ||
listener.onFailedAuthorization(throwable); | ||
throw throwable; | ||
} | ||
|
||
listener.onSuccessfulAuthorization(); | ||
|
||
return BEARER + accessToken; | ||
} | ||
|
||
public AccessTokenResponse getAccessToken() throws OAuthException, OAuthResponseException, IOException { | ||
AccessTokenResponse accessTokenResponse = oAuthClientService.getAccessTokenResponse(); | ||
if (accessTokenResponse == null) { | ||
throw new OAuthException("No access token response"); | ||
} | ||
|
||
return accessTokenResponse; | ||
} | ||
|
||
private String getAuthorizationUrl() { | ||
try { | ||
return oAuthClientService.getAuthorizationUrl(BSK_REDIRECT_URI, BSK_SCOPE, null); | ||
} catch (OAuthException e) { | ||
return ""; | ||
} | ||
} | ||
} |
40 changes: 40 additions & 0 deletions
40
...hindego/src/main/java/org/openhab/binding/boschindego/internal/AuthorizationListener.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
/** | ||
* Copyright (c) 2010-2023 Contributors to the openHAB project | ||
* | ||
* See the NOTICE file(s) distributed with this work for additional | ||
* information. | ||
* | ||
* This program and the accompanying materials are made available under the | ||
* terms of the Eclipse Public License 2.0 which is available at | ||
* http://www.eclipse.org/legal/epl-2.0 | ||
* | ||
* SPDX-License-Identifier: EPL-2.0 | ||
*/ | ||
package org.openhab.binding.boschindego.internal; | ||
|
||
import org.eclipse.jdt.annotation.NonNullByDefault; | ||
|
||
/** | ||
* {@link} AuthorizationListener} is used for notifying {@link BoschAccountHandler} | ||
* when authorization state has changed and for notifying {@link BoschIndegoHandler} | ||
* when authorization flow is completed. | ||
* | ||
* @author Jacob Laursen - Initial contribution | ||
*/ | ||
@NonNullByDefault | ||
public interface AuthorizationListener { | ||
/** | ||
* Called upon successful OAuth authorization. | ||
*/ | ||
void onSuccessfulAuthorization(); | ||
|
||
/** | ||
* Called upon failed OAuth authorization. | ||
*/ | ||
void onFailedAuthorization(Throwable throwable); | ||
|
||
/** | ||
* Called upon successful completion of OAuth authorization flow. | ||
*/ | ||
void onAuthorizationFlowCompleted(); | ||
} |
34 changes: 34 additions & 0 deletions
34
...hindego/src/main/java/org/openhab/binding/boschindego/internal/AuthorizationProvider.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
/** | ||
* Copyright (c) 2010-2023 Contributors to the openHAB project | ||
* | ||
* See the NOTICE file(s) distributed with this work for additional | ||
* information. | ||
* | ||
* This program and the accompanying materials are made available under the | ||
* terms of the Eclipse Public License 2.0 which is available at | ||
* http://www.eclipse.org/legal/epl-2.0 | ||
* | ||
* SPDX-License-Identifier: EPL-2.0 | ||
*/ | ||
package org.openhab.binding.boschindego.internal; | ||
|
||
import org.eclipse.jdt.annotation.NonNullByDefault; | ||
import org.openhab.binding.boschindego.internal.exceptions.IndegoException; | ||
|
||
/** | ||
* The {@link AuthorizationProvider} is responsible for providing | ||
* authorization headers needed for communicating with the Bosch Indego | ||
* cloud services. | ||
* | ||
* @author Jacob Laursen - Initial contribution | ||
*/ | ||
@NonNullByDefault | ||
public interface AuthorizationProvider { | ||
/** | ||
* Get HTTP authorization header for authenticating with Bosch Indego services. | ||
* | ||
* @return the header contents | ||
* @throws IndegoException if not authorized | ||
*/ | ||
String getAuthorizationHeader() throws IndegoException; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.