From bd90b34c42bdd5f55ae296f32d978e3224535c17 Mon Sep 17 00:00:00 2001
From: Andreas Svanberg <andreass@dsv.su.se>
Date: Thu, 25 Apr 2024 09:51:51 +0200
Subject: [PATCH] Fix URKUND integration with new Guice UnitOfWork changes

Can not fetch the settings from the authenticator since that is ran on a HTTP request dispatching thread where no UnitOfWork has started.It is not possible to fetch the credentials in the constructor since then it would not be possible to change the settings while the system is running. Instead recreate the client with prefetched credentials on every request.
---
 .../plagiarism/urkund/UrkundApiImpl.java      | 26 +++++++++++--------
 1 file changed, 15 insertions(+), 11 deletions(-)

diff --git a/core/src/main/java/se/su/dsv/scipro/plagiarism/urkund/UrkundApiImpl.java b/core/src/main/java/se/su/dsv/scipro/plagiarism/urkund/UrkundApiImpl.java
index 37fe3d3c02..774dfdda3a 100644
--- a/core/src/main/java/se/su/dsv/scipro/plagiarism/urkund/UrkundApiImpl.java
+++ b/core/src/main/java/se/su/dsv/scipro/plagiarism/urkund/UrkundApiImpl.java
@@ -6,9 +6,10 @@ import se.su.dsv.scipro.file.FileDescription;
 import se.su.dsv.scipro.file.FileService;
 
 import jakarta.inject.Inject;
-import jakarta.inject.Provider;
+
 import java.io.IOException;
 import java.io.InputStream;
+import java.io.UncheckedIOException;
 import java.net.Authenticator;
 import java.net.PasswordAuthentication;
 import java.net.URI;
@@ -31,15 +32,13 @@ import java.util.concurrent.Flow;
 public class UrkundApiImpl implements UrkundApi {
 
     private final ObjectMapper objectMapper;
-    private final HttpClient client;
+    private final UrkundSettingsRepository urkundSettingsRepository;
     private final FileService fileService;
 
     @Inject
-    UrkundApiImpl(final Provider<UrkundSettings> urkundSettings, FileService fileService) {
+    UrkundApiImpl(final UrkundSettingsRepository urkundSettingsRepository, FileService fileService) {
+        this.urkundSettingsRepository = urkundSettingsRepository;
         this.fileService = fileService;
-        client = HttpClient.newBuilder()
-                .authenticator(new UrkundAuthenticator(urkundSettings))
-                .build();
         objectMapper = new ObjectMapper();
         objectMapper.findAndRegisterModules();
         objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
@@ -99,10 +98,16 @@ public class UrkundApiImpl implements UrkundApi {
     }
 
     private <A> A sendToUrkund_(final HttpRequest request, final FailingFunction<HttpResponse<InputStream>, A> f) {
+        UrkundSettings urkundSettings = urkundSettingsRepository.getSettings();
+        HttpClient client = HttpClient.newBuilder()
+                .authenticator(new UrkundAuthenticator(urkundSettings))
+                .build();
         try {
             final HttpResponse<InputStream> response = client.send(request, HttpResponse.BodyHandlers.ofInputStream());
             return f.apply(response);
-        } catch (IOException | InterruptedException e) {
+        } catch (IOException e) {
+            throw new UncheckedIOException(e);
+        } catch (InterruptedException e) {
             Thread.currentThread().interrupt();
             throw new RuntimeException(e);
         }
@@ -129,15 +134,14 @@ public class UrkundApiImpl implements UrkundApi {
     }
 
     private static class UrkundAuthenticator extends Authenticator {
-        private final Provider<UrkundSettings> urkundSettings;
+        private final UrkundSettings settings;
 
-        public UrkundAuthenticator(Provider<UrkundSettings> urkundSettings) {
-            this.urkundSettings = urkundSettings;
+        public UrkundAuthenticator(UrkundSettings settings) {
+            this.settings = settings;
         }
 
         @Override
         protected PasswordAuthentication getPasswordAuthentication() {
-            final UrkundSettings settings = urkundSettings.get();
             return new PasswordAuthentication(settings.getUsername(), settings.getPassword().toCharArray());
         }
     }