From df84e1074060dd0d16a94ccc7cf24615b9a519b4 Mon Sep 17 00:00:00 2001 From: j-dimension Date: Sun, 8 Dec 2024 21:21:45 +0100 Subject: [PATCH] update auth token upon client start - server could have been down and token therefore expired. issue #2724 --- .../jlawyer/client/mail/EmailInboxPanel.java | 10 ++ .../jlawyer/client/mail/FolderContainer.java | 4 + .../jlawyer/services/EmailServiceRemote.java | 1 + .../jlawyer/services/EmailService.java | 143 ++++++++++-------- 4 files changed, 97 insertions(+), 61 deletions(-) diff --git a/j-lawyer-client/src/com/jdimension/jlawyer/client/mail/EmailInboxPanel.java b/j-lawyer-client/src/com/jdimension/jlawyer/client/mail/EmailInboxPanel.java index 83284754..730e99f6 100755 --- a/j-lawyer-client/src/com/jdimension/jlawyer/client/mail/EmailInboxPanel.java +++ b/j-lawyer-client/src/com/jdimension/jlawyer/client/mail/EmailInboxPanel.java @@ -983,6 +983,16 @@ private void refreshFolders(boolean showErrorDialogOnFailure) throws Exception { for (MailboxSetup ms : mailboxes) { try { + + if(ms.isMsExchange()) { + try { + ClientSettings settings=ClientSettings.getInstance(); + JLawyerServiceLocator locator = JLawyerServiceLocator.getInstance(settings.getLookupProperties()); + locator.lookupEmailServiceRemote().updateAuthToken(ms.getId()); + } catch (Exception ex) { + log.error("unable to update auth token for mailbox " + ms.getEmailAddress(), ex); + } + } this.connect(showErrorDialogOnFailure, ms); diff --git a/j-lawyer-client/src/com/jdimension/jlawyer/client/mail/FolderContainer.java b/j-lawyer-client/src/com/jdimension/jlawyer/client/mail/FolderContainer.java index 177b2f9f..c0f1cc18 100755 --- a/j-lawyer-client/src/com/jdimension/jlawyer/client/mail/FolderContainer.java +++ b/j-lawyer-client/src/com/jdimension/jlawyer/client/mail/FolderContainer.java @@ -689,6 +689,10 @@ public class FolderContainer { double retentionTime = -1; +// private Message[] cachedMessages=null; +// private String cachedMessagesKey=null; + + static { folderNameMapping.put(CommonMailUtils.INBOX, "Posteingang"); folderNameMapping.put(CommonMailUtils.SENT, "Gesendet"); diff --git a/j-lawyer-server-api/src/com/jdimension/jlawyer/services/EmailServiceRemote.java b/j-lawyer-server-api/src/com/jdimension/jlawyer/services/EmailServiceRemote.java index bc025d99..9ea20085 100644 --- a/j-lawyer-server-api/src/com/jdimension/jlawyer/services/EmailServiceRemote.java +++ b/j-lawyer-server-api/src/com/jdimension/jlawyer/services/EmailServiceRemote.java @@ -673,6 +673,7 @@ You should also get your employer (if you work as a programmer) or school, public interface EmailServiceRemote { String getAuthToken(String mailboxId) throws Exception; + boolean updateAuthToken(String mailboxId) throws Exception; String[] requestDeviceCode(String mailboxId) throws Exception; boolean pollForTokens(String mailboxId, String deviceCode) throws Exception; diff --git a/j-lawyer-server/j-lawyer-server-ejb/src/java/com/jdimension/jlawyer/services/EmailService.java b/j-lawyer-server/j-lawyer-server-ejb/src/java/com/jdimension/jlawyer/services/EmailService.java index 4fb10fc5..25edfcc3 100644 --- a/j-lawyer-server/j-lawyer-server-ejb/src/java/com/jdimension/jlawyer/services/EmailService.java +++ b/j-lawyer-server/j-lawyer-server-ejb/src/java/com/jdimension/jlawyer/services/EmailService.java @@ -728,79 +728,100 @@ public void refreshAuthTokens() { List mailboxes = this.mailboxSetupFacade.findByMsExchange(true); for (MailboxSetup ms : mailboxes) { - if (ms.getTokenExpiry() == 0 || ((ms.getTokenExpiry() - System.currentTimeMillis()) < (6l * 60l * 1000l))) { - try { - log.info("attempting to update tokens for " + ms.getEmailAddress()); - boolean success=this.updateAuthToken(ms); - if(!success) - log.error("failed to update tokens for " + ms.getEmailAddress()); - else - log.info("successfully updated tokens for " + ms.getEmailAddress()); - } catch (Exception ex) { - log.error("failed to retrieve new access token for mailbox " + ms.getEmailAddress(), ex); - } - } - } - } + try { - private boolean updateAuthToken(MailboxSetup mailbox) throws Exception { + boolean success = this.updateAuthTokenForMailbox(ms); + if (!success) { + log.error("failed to update tokens for " + ms.getEmailAddress()); + } else { + log.info("successfully updated tokens for " + ms.getEmailAddress()); + } + } catch (Exception ex) { + log.error("failed to retrieve new access token for mailbox " + ms.getEmailAddress(), ex); + } - if (ServerStringUtils.isEmpty(mailbox.getTenantId())) { - log.error("Tenant ID is empty when updating access token for " + mailbox.getEmailAddress()); - return false; } - if (ServerStringUtils.isEmpty(mailbox.getClientId())) { - log.error("Client ID is empty when updating access token for " + mailbox.getEmailAddress()); - return false; - } + } - if (ServerStringUtils.isEmpty(mailbox.getRefreshToken())) { - log.error("Refresh token is empty when updating access token for " + mailbox.getEmailAddress()); + @Override + @RolesAllowed({"loginRole"}) + public boolean updateAuthToken(String mailboxId) throws Exception { + + MailboxSetup ms = this.mailboxSetupFacade.find(mailboxId); + if (ms != null) { + return this.updateAuthTokenForMailbox(ms); + } else { + log.error("Auth token update requested for a non-existing mailbox with id " + mailboxId); return false; } + + } + + private boolean updateAuthTokenForMailbox(MailboxSetup mailbox) throws Exception { - String TOKEN_ENDPOINT = "https://login.microsoftonline.com/" + mailbox.getTenantId() + "/oauth2/v2.0/token"; + if (mailbox.getTokenExpiry() == 0 || ((mailbox.getTokenExpiry() - System.currentTimeMillis()) < (6l * 60l * 1000l))) { - try (CloseableHttpClient client = HttpClients.createDefault()) { - HttpPost post = new HttpPost(TOKEN_ENDPOINT); + log.info("attempting to update tokens for " + mailbox.getEmailAddress()); + + if (ServerStringUtils.isEmpty(mailbox.getTenantId())) { + log.error("Tenant ID is empty when updating access token for " + mailbox.getEmailAddress()); + return false; + } - // Create URL-encoded body - String body = "grant_type=" + URLEncoder.encode("refresh_token", StandardCharsets.UTF_8) - + "&refresh_token=" + URLEncoder.encode(mailbox.getRefreshToken(), StandardCharsets.UTF_8) - + "&client_id=" + URLEncoder.encode(mailbox.getClientId(), StandardCharsets.UTF_8); - //"&client_secret=" + URLEncoder.encode(CLIENT_SECRET, StandardCharsets.UTF_8); + if (ServerStringUtils.isEmpty(mailbox.getClientId())) { + log.error("Client ID is empty when updating access token for " + mailbox.getEmailAddress()); + return false; + } - post.setEntity(new StringEntity(body)); - post.setHeader("Content-Type", "application/x-www-form-urlencoded"); + if (ServerStringUtils.isEmpty(mailbox.getRefreshToken())) { + log.error("Refresh token is empty when updating access token for " + mailbox.getEmailAddress()); + return false; + } - ObjectMapper objectMapper = new ObjectMapper(); - try (CloseableHttpResponse response = client.execute(post)) { - if (response.getStatusLine().getStatusCode() == 200) { - Map responseBody = objectMapper.readValue( - response.getEntity().getContent(), - Map.class - ); - - String accessToken = (String) responseBody.get("access_token"); - String refreshToken = (String) responseBody.get("refresh_token"); - int expiresIn = (int) responseBody.get("expires_in"); - // Calculate token expiry time (current time + expires_in seconds) - long tokenExpiryTime = System.currentTimeMillis() + (expiresIn * 1000l); - - mailbox.setAuthToken(accessToken); - mailbox.setRefreshToken(refreshToken); - mailbox.setTokenExpiry(tokenExpiryTime); - this.mailboxSetupFacade.edit(mailbox); - return true; - } else { - log.error("failed to retrieve new access token for mailbox " + mailbox.getEmailAddress() + ", response was HTTP " + response.getStatusLine().getStatusCode() + " with content:"); - log.error(response.getEntity().getContent()); - return false; + String TOKEN_ENDPOINT = "https://login.microsoftonline.com/" + mailbox.getTenantId() + "/oauth2/v2.0/token"; + + try (CloseableHttpClient client = HttpClients.createDefault()) { + HttpPost post = new HttpPost(TOKEN_ENDPOINT); + + // Create URL-encoded body + String body = "grant_type=" + URLEncoder.encode("refresh_token", StandardCharsets.UTF_8) + + "&refresh_token=" + URLEncoder.encode(mailbox.getRefreshToken(), StandardCharsets.UTF_8) + + "&client_id=" + URLEncoder.encode(mailbox.getClientId(), StandardCharsets.UTF_8); + //"&client_secret=" + URLEncoder.encode(CLIENT_SECRET, StandardCharsets.UTF_8); + + post.setEntity(new StringEntity(body)); + post.setHeader("Content-Type", "application/x-www-form-urlencoded"); + + ObjectMapper objectMapper = new ObjectMapper(); + try (CloseableHttpResponse response = client.execute(post)) { + if (response.getStatusLine().getStatusCode() == 200) { + Map responseBody = objectMapper.readValue( + response.getEntity().getContent(), + Map.class + ); + + String accessToken = (String) responseBody.get("access_token"); + String refreshToken = (String) responseBody.get("refresh_token"); + int expiresIn = (int) responseBody.get("expires_in"); + // Calculate token expiry time (current time + expires_in seconds) + long tokenExpiryTime = System.currentTimeMillis() + (expiresIn * 1000l); + + mailbox.setAuthToken(accessToken); + mailbox.setRefreshToken(refreshToken); + mailbox.setTokenExpiry(tokenExpiryTime); + this.mailboxSetupFacade.edit(mailbox); + return true; + } else { + log.error("failed to retrieve new access token for mailbox " + mailbox.getEmailAddress() + ", response was HTTP " + response.getStatusLine().getStatusCode() + " with content:"); + log.error(response.getEntity().getContent()); + return false; + } } } } + return true; } @Override @@ -819,9 +840,9 @@ public String[] requestDeviceCode(String mailboxId) throws Exception { // String body = "client_id=" + ms.getClientId() // + "&scope=https%3A%2F%2Fgraph.microsoft.com%2Fmail.read%20offline_access"; String body = "client_id=" + ms.getClientId() - + "&scope=https%3A%2F%2Foutlook.office365.com%2FIMAP.AccessAsUser.All%20" - + "https%3A%2F%2Foutlook.office365.com%2FSMTP.Send%20" - + "offline_access"; + + "&scope=https%3A%2F%2Foutlook.office365.com%2FIMAP.AccessAsUser.All%20" + + "https%3A%2F%2Foutlook.office365.com%2FSMTP.Send%20" + + "offline_access"; post.setEntity(new StringEntity(body)); post.setHeader("Content-Type", "application/x-www-form-urlencoded"); @@ -881,7 +902,7 @@ public boolean pollForTokens(String mailboxId, String deviceCode) throws Excepti ms.setAuthToken(accessToken); ms.setRefreshToken(refreshToken); - ms.setTokenExpiry(System.currentTimeMillis() + 10l*60l*1000l); + ms.setTokenExpiry(System.currentTimeMillis() + 10l * 60l * 1000l); this.mailboxSetupFacade.edit(ms); return true;