From 39099700fe55aace45ef2fe080ed346c26080e66 Mon Sep 17 00:00:00 2001
From: Ralph Soika
Date: Fri, 25 Apr 2025 09:52:50 +0200
Subject: [PATCH] zoho token management
---
.../zoho/ZohoController.java | 14 ++
.../zoho/ZohoOAuthManager.java | 151 +++++++++++-------
.../src/main/webapp/pages/admin/zoho.xhtml | 65 ++++++--
3 files changed, 162 insertions(+), 68 deletions(-)
diff --git a/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/zoho/ZohoController.java b/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/zoho/ZohoController.java
index d32068c..6f7675d 100644
--- a/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/zoho/ZohoController.java
+++ b/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/zoho/ZohoController.java
@@ -71,4 +71,18 @@ public class ZohoController extends ConfigController {
this.getWorkitem().setItemValue("message", message);
}
}
+
+ /**
+ * Ruft zohoOAuhtManager.refreshToken auf
+ */
+ public void refreshAccessToken() {
+ //
+ try {
+ zohoOAuthManager.refreshAccessToken();
+ } catch (PluginException e) {
+ String message = "Failed to refresh token: " + e.getMessage();
+ logger.warning(message);
+ this.getWorkitem().setItemValue("message", message);
+ }
+ }
}
diff --git a/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/zoho/ZohoOAuthManager.java b/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/zoho/ZohoOAuthManager.java
index 90b46b3..36d3d79 100644
--- a/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/zoho/ZohoOAuthManager.java
+++ b/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/zoho/ZohoOAuthManager.java
@@ -8,6 +8,7 @@ import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.charset.StandardCharsets;
import java.time.Duration;
+import java.util.Date;
import java.util.logging.Logger;
import org.imixs.workflow.ItemCollection;
@@ -56,6 +57,11 @@ public class ZohoOAuthManager {
this.jsonb = JsonbBuilder.create();
}
+ @Lock(LockType.READ)
+ public String getValidAccessToken() {
+ return accessToken;
+ }
+
/**
* Step 3: Generate Access and Refresh Token
*
@@ -112,19 +118,8 @@ public class ZohoOAuthManager {
TokenResponse tokenResponse = jsonb.fromJson(response.body(),
TokenResponse.class);
+ saveTokenData(zohoConfig, tokenResponse);
- accessToken = tokenResponse.getAccess_token();
-
- logger.info("│ ├── accessToken=" + accessToken);
- refreshToken = tokenResponse.getRefresh_token();
- logger.info("│ ├── refreshToken=" + refreshToken);
- logger.info("│ ├── expires_in=" + tokenResponse.getExpires_in());
-
- zohoConfig.setItemValue("zoho.accessToken", accessToken);
- zohoConfig.setItemValue("zoho.refreshToken", refreshToken);
- zohoConfig.setItemValue("zoho.expires", tokenResponse.getExpires_in());
- zohoConfig.setItemValue("message", "Access Token OK");
- configService.save(zohoConfig);
} else {
throw new RuntimeException("Failed to get tokens: " +
response.statusCode() + " - " + response.body());
@@ -136,65 +131,111 @@ public class ZohoOAuthManager {
}
}
- @Lock(LockType.READ)
- public String getValidAccessToken() {
-
- return null;
- }
-
/**
* This method updates the Access Token based on the current Refresh Token
*
* @throws IOException
+ * @throws PluginException
*/
- public void testRefreshAccessToken() throws IOException {
+ @Lock(LockType.WRITE)
+ public void refreshAccessToken() throws PluginException {
- // logger.info("├── refresh Zoho access token");
- // refreshToken =
- // "1000.cf458816e97f848df8134ce1c7e923a1.5b9dbdee317e35d7f0c619e7648d55ff";
- // try {
+ logger.info("├── refresh Zoho access token");
- // String requestUrl = "https://accounts.zoho.eu/oauth/v2/token" +
- // "?refresh_token=" + URLEncoder.encode(refreshToken, StandardCharsets.UTF_8) +
- // "&client_id=" + URLEncoder.encode(clientID.get(), StandardCharsets.UTF_8) +
- // "&client_secret=" + URLEncoder.encode(clientSecret.get(),
- // StandardCharsets.UTF_8) +
- // "&grant_type=refresh_token";
+ ItemCollection zohoConfig = configService.loadConfiguration(ZohoController.ZOHO_CONFIGURATION);
- // logger.info("│ ├── Request URI=" + requestUrl);
+ String clientID = zohoConfig.getItemValueString("zoho.clientid");
+ String clientSecret = zohoConfig.getItemValueString("zoho.clientsecret");
- // HttpRequest request = HttpRequest.newBuilder()
- // .uri(URI.create(requestUrl))
- // .header("Content-Type", "application/x-www-form-urlencoded")
- // .POST(HttpRequest.BodyPublishers.noBody()) // Wichtig: Kein Body!
- // .build();
+ refreshToken = zohoConfig.getItemValueString("zoho.refreshToken");
+ try {
- // HttpResponse response;
+ String requestUrl = "https://accounts.zoho.eu/oauth/v2/token" +
+ "?refresh_token=" + URLEncoder.encode(refreshToken, StandardCharsets.UTF_8) +
+ "&client_id=" + URLEncoder.encode(clientID, StandardCharsets.UTF_8) +
+ "&client_secret=" + URLEncoder.encode(clientSecret,
+ StandardCharsets.UTF_8)
+ +
+ "&grant_type=refresh_token";
- // response = httpClient.send(request,
- // HttpResponse.BodyHandlers.ofString());
+ logger.info("│ ├── Request URI=" + requestUrl);
- // logger.info("│ ├── Response statusCode=" + response.statusCode());
- // if (response.statusCode() == 200) {
+ HttpRequest request = HttpRequest.newBuilder()
+ .uri(URI.create(requestUrl))
+ .header("Content-Type", "application/x-www-form-urlencoded")
+ .POST(HttpRequest.BodyPublishers.noBody()) // Wichtig: Kein Body!
+ .build();
- // // 1. Response-Logging für Debugging
- // logger.info("│ ├── Response Body=" + response.body());
+ HttpResponse response;
- // TokenResponse tokenResponse = jsonb.fromJson(response.body(),
- // TokenResponse.class);
+ response = httpClient.send(request,
+ HttpResponse.BodyHandlers.ofString());
- // String accessToken = tokenResponse.getAccess_token();
- // logger.info("│ ├── accessToken=" + accessToken);
- // logger.info("│ ├── expires_in=" + tokenResponse.getExpires_in());
- // } else {
- // throw new RuntimeException("Failed to get tokens: " +
- // response.statusCode() + " - " + response.body());
- // }
+ logger.info("│ ├── Response statusCode=" + response.statusCode());
+ if (response.statusCode() == 200) {
- // } catch (IOException | InterruptedException e) {
- // throw new InvalidAccessException("Unable to resolve access tokens: " +
- // e.getMessage());
- // }
+ // 1. Response-Logging für Debugging
+ logger.info("│ ├── Response Body=" + response.body());
+
+ TokenResponse tokenResponse = jsonb.fromJson(response.body(),
+ TokenResponse.class);
+
+ saveTokenData(zohoConfig, tokenResponse);
+
+ // String accessToken = tokenResponse.getAccess_token();
+ // logger.info("│ ├── accessToken=" + accessToken);
+ // logger.info("│ ├── expires_in=" + tokenResponse.getExpires_in());
+ } else {
+ throw new RuntimeException("Failed to get tokens: " +
+ response.statusCode() + " - " + response.body());
+ }
+
+ } catch (IOException | InterruptedException e) {
+ throw new PluginException(ZohoOAuthManager.class.getSimpleName(),
+ ZohoOAuthManager.ERROR_CONFIG, "Unable to refresh access tokens: " + e.getMessage());
+ }
}
+
+ /**
+ * Helper method to update the config itemcolleciton based on a tokenResponse
+ *
+ * @param zohoConfig
+ * @param tokenResponse
+ */
+ private void saveTokenData(ItemCollection zohoConfig, TokenResponse tokenResponse) {
+
+ String apiDomain = tokenResponse.getApi_domain();
+ if (apiDomain != null && !apiDomain.isEmpty()) {
+ logger.info("│ ├── apiDomain=" + apiDomain);
+ zohoConfig.setItemValue("zoho.apiDomain", apiDomain);
+ }
+ String scope = tokenResponse.getScope();
+ if (scope != null && !scope.isEmpty()) {
+ logger.info("│ ├── scope=" + scope);
+ zohoConfig.setItemValue("zoho.scope", scope);
+ }
+
+ accessToken = tokenResponse.getAccess_token();
+ if (accessToken != null && !accessToken.isEmpty()) {
+ logger.info("│ ├── accessToken=" + accessToken);
+ zohoConfig.setItemValue("zoho.accessToken", accessToken);
+ }
+ refreshToken = tokenResponse.getRefresh_token();
+ if (refreshToken != null && !refreshToken.isEmpty()) {
+ logger.info("│ ├── refreshToken=" + refreshToken);
+ zohoConfig.setItemValue("zoho.refreshToken", refreshToken);
+ }
+ logger.info("│ ├── expires_in=" + tokenResponse.getExpires_in());
+ // Expires-Zeit in Millisekunden berechnen
+ long expiresInSeconds = tokenResponse.getExpires_in() - 60;
+ long currentTimeMillis = System.currentTimeMillis();
+ long expiresTimeMillis = currentTimeMillis + (expiresInSeconds * 1000);
+ // Expires-Zeit in ein Date-Objekt konvertieren
+ Date expiresDate = new Date(expiresTimeMillis);
+ zohoConfig.setItemValue("zoho.expires", expiresDate);
+ zohoConfig.setItemValue("message", "Access Token OK");
+ configService.save(zohoConfig);
+ }
+
}
diff --git a/office-alexander-logistics-app/src/main/webapp/pages/admin/zoho.xhtml b/office-alexander-logistics-app/src/main/webapp/pages/admin/zoho.xhtml
index f137890..7e1112e 100644
--- a/office-alexander-logistics-app/src/main/webapp/pages/admin/zoho.xhtml
+++ b/office-alexander-logistics-app/src/main/webapp/pages/admin/zoho.xhtml
@@ -81,7 +81,6 @@
Fordern Sie einen ZOHO API COde
an
-
- Melden Sie sich auf der ZOHO API Console an
@@ -94,8 +93,8 @@
-
Generieren Sie einen neuen Access Code
- Scope:
- ZohoBooks.invoices.CREATE,ZohoBooks.invoices.READ,ZohoBooks.invoices.UPDATE,ZohoBooks.invoices.DELETE
+ Scope:
+ ZohoBooks.invoices.CREATE,ZohoBooks.invoices.READ,ZohoBooks.invoices.UPDATE
-
Code über den Button "Create" anfordern und in das Feld "Access Code"
@@ -107,20 +106,60 @@
+ value="Token generieren">
+
+
-
-
-
-
- AccessToken:
-
-
- RefreshToken:
-
+
+