diff --git a/src/main/java/de/unistuttgart/iste/meitrex/gamification_service/keycloak/DefaultKeycloakClient.java b/src/main/java/de/unistuttgart/iste/meitrex/gamification_service/keycloak/DefaultKeycloakClient.java index 9a5b67c..30e76b1 100644 --- a/src/main/java/de/unistuttgart/iste/meitrex/gamification_service/keycloak/DefaultKeycloakClient.java +++ b/src/main/java/de/unistuttgart/iste/meitrex/gamification_service/keycloak/DefaultKeycloakClient.java @@ -3,8 +3,11 @@ import java.util.*; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.node.ObjectNode; import de.unistuttgart.iste.meitrex.gamification_service.aspects.logging.Loggable; import de.unistuttgart.iste.meitrex.gamification_service.aspects.resiliency.Retryable; +import lombok.extern.slf4j.Slf4j; import org.springframework.http.*; import org.springframework.stereotype.*; import org.springframework.web.reactive.function.*; @@ -14,6 +17,7 @@ @Component +@Slf4j public class DefaultKeycloakClient implements IKeycloakClient { private static Map> extractAttributeMap(JsonNode node) { @@ -45,17 +49,21 @@ private static Map> extractAttributeMap(JsonNode node) { private final WebClient webClient; + private final ObjectMapper objectMapper; + public DefaultKeycloakClient( @Value("${keycloak.realm}") String realm, @Value("${keycloak.clientId}") String clientId, @Value("${keycloak.clientSecret}") String clientSecret, - @Autowired @Qualifier("keycloakServiceClient") WebClient webClient + @Autowired @Qualifier("keycloakServiceClient") WebClient webClient, + @Autowired ObjectMapper objectMapper ) { this.realm = Objects.requireNonNull(realm); this.clientId = Objects.requireNonNull(clientId); this.clientSecret = Objects.requireNonNull(clientSecret); this.webClient = Objects.requireNonNull(webClient); + this.objectMapper = Objects.requireNonNull(objectMapper); } @Override @@ -110,13 +118,26 @@ private void removeValues(UUID userId, String attrName) { private void saveAttributeMap(UUID userId, Map> valueMap) { final String token = getAccessToken(); - Map payload = new HashMap<>(); - payload.put("attributes", valueMap); + JsonNode userNode = webClient.get() + .uri("/admin/realms/" + this.realm + "/users/" + userId) + .headers(headers -> headers.setBearerAuth(token)) + .retrieve() + .bodyToMono(JsonNode.class) + .block(); + + if (userNode == null || !userNode.isObject()) { + throw new IllegalStateException("User not found or invalid json for id=" + userId); + } + + ObjectNode fullUser = (ObjectNode) userNode; + JsonNode attributesNode = objectMapper.valueToTree(valueMap); + fullUser.set("attributes", attributesNode); + webClient.put() .uri("/admin/realms/" + realm + "/users/{id}", userId) .header(HttpHeaders.AUTHORIZATION, "Bearer " + token) .contentType(MediaType.APPLICATION_JSON) - .bodyValue(payload) + .bodyValue(fullUser) .retrieve() .toBodilessEntity() .block(); diff --git a/src/main/java/de/unistuttgart/iste/meitrex/gamification_service/service/PlayerHexadScoreService.java b/src/main/java/de/unistuttgart/iste/meitrex/gamification_service/service/PlayerHexadScoreService.java index 299da2f..249084d 100755 --- a/src/main/java/de/unistuttgart/iste/meitrex/gamification_service/service/PlayerHexadScoreService.java +++ b/src/main/java/de/unistuttgart/iste/meitrex/gamification_service/service/PlayerHexadScoreService.java @@ -8,6 +8,7 @@ import de.unistuttgart.iste.meitrex.gamification_service.persistence.entity.UserEntity; import de.unistuttgart.iste.meitrex.gamification_service.persistence.repository.IPlayerHexadScoreQuestionRepository; import de.unistuttgart.iste.meitrex.gamification_service.service.internal.IUserCreator; +import io.dapr.client.DaprClient; import org.springframework.stereotype.Service; import de.unistuttgart.iste.meitrex.gamification_service.persistence.entity.PlayerHexadScoreEntity; @@ -90,7 +91,6 @@ public PlayerHexadScore calculateDefault(UUID userId, boolean notification) { final String message = "You skipped the questionnaire so we set a default type. Tap to resume."; final String link = "/?resumeSurvey=1"; - final ServerSource source = ServerSource.GAMIFICATION; if (notification) { topicPublisher.notificationEvent( null, diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 5e5642f..a84fac8 100755 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -1,5 +1,5 @@ # for deployment or when using docker compose = prod, for local development = dev -spring.profiles.active=dev +spring.profiles.active=prod # enable graphiql (graphiql is a web interface for exploring GraphQL) spring.graphql.graphiql.enabled=true spring.graphql.graphiql.path=/graphiql