content: package io.aiven.klaw.controller;
  
  import jakarta.servlet.http.HttpServletRequest;
  import jakarta.servlet.http.HttpServletResponse;
  import java.util.HashMap;
  import java.util.Map;
  import lombok.extern.slf4j.Slf4j;
  import org.springframework.beans.factory.annotation.Autowired;
  import org.springframework.beans.factory.annotation.Value;
  import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
  import org.springframework.core.ParameterizedTypeReference;
  import org.springframework.core.ResolvableType;
  import org.springframework.security.core.context.SecurityContextHolder;
  import org.springframework.security.oauth2.client.OAuth2AuthorizedClient;
  import org.springframework.security.oauth2.client.OAuth2AuthorizedClientService;
  import org.springframework.security.oauth2.client.authentication.OAuth2AuthenticationToken;
  import org.springframework.security.oauth2.client.registration.ClientRegistration;
  import org.springframework.security.oauth2.client.registration.ClientRegistrationRepository;
  import org.springframework.security.oauth2.core.user.DefaultOAuth2User;
  import org.springframework.stereotype.Controller;
  import org.springframework.ui.Model;
  import org.springframework.web.bind.annotation.GetMapping;
  import org.springframework.web.reactive.function.client.WebClient;
  
  @ConditionalOnProperty(name = "klaw.enable.sso", havingValue = "true")
  @Controller
  @Slf4j
  public class ResourceClientController {
  
    @Value("${resourceserver.api.url:testResourceUrl}")
    private String resourceUrl;
  
    @Value("${klaw.ad.username.attribute:preferred_username}")
    private String preferredUsernameAttribute;
  
    @Value("${klaw.ad.email.attribute:email}")
    private String emailAttribute;
  
    private static final String authorizationRequestBaseUri = "oauth2/authorize-client";
    Map<String, String> oauth2AuthenticationUrls = new HashMap<>();
    @Autowired private OAuth2AuthorizedClientService authorizedClientService;
  
    @Autowired private WebClient webClient;
  
    @Autowired private ClientRegistrationRepository clientRegistrationRepository;
  
    @GetMapping("/resources")
    public String getFoos(
        Model model,
        OAuth2AuthenticationToken authentication,
        HttpServletRequest request,
        HttpServletResponse response) {
      String foos =
          this.webClient
              .get()
              .uri(resourceUrl)
              .retrieve()
              .bodyToMono(new ParameterizedTypeReference<String>() {})
              .block();
      return checkAnonymousLogin(request, response, authentication);
    }
  
    private String checkAnonymousLogin(
        HttpServletRequest request,
        HttpServletResponse response,
        OAuth2AuthenticationToken authentication) {
      try {
        Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        DefaultOAuth2User defaultOAuth2User = (DefaultOAuth2User) principal;
        String userName = (String) defaultOAuth2User.getAttributes().get(preferredUsernameAttribute);
        if (userName == null) {
          userName = (String) defaultOAuth2User.getAttributes().get(emailAttribute);
        }
        OAuth2AuthorizedClient client =
            authorizedClientService.loadAuthorizedClient(
                authentication.getAuthorizedClientRegistrationId(), userName);
        if (client == null) {
          return ("redirect:oauthLogin");
        }
        return ("redirect:index");
      } catch (Exception e) {
        return ("redirect:oauthLogin");
      }
    }
  
    @GetMapping("/oauthLogin")
    public String getLoginPage(
        Model model, OAuth2AuthenticationToken authentication, HttpServletResponse response) {
      Iterable<ClientRegistration> clientRegistrations = null;
      ResolvableType type =
          ResolvableType.forInstance(clientRegistrationRepository).as(Iterable.class);
      if (type != ResolvableType.NONE
          && ClientRegistration.class.isAssignableFrom(type.resolveGenerics()[0])) {
        clientRegistrations = (Iterable<ClientRegistration>) clientRegistrationRepository;
      }
  
      clientRegistrations.forEach(
          registration ->
              oauth2AuthenticationUrls.put(
                  registration.getClientName(),
                  authorizationRequestBaseUri + "/" + registration.getRegistrationId()));
      model.addAttribute("urls", oauth2AuthenticationUrls);
      return "oauthLogin";
    }
  }
  