package com.dbg.cloud.acheron.plugins.oauth2; import com.dbg.cloud.acheron.plugins.oauth2.authserver.base.CredentialsStruct; import com.dbg.cloud.acheron.plugins.oauth2.authserver.base.OAuth2AuthorisationServer; import com.dbg.cloud.acheron.plugins.oauth2.authserver.hydra.Hydra; import lombok.AllArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.boot.web.client.RestTemplateBuilder; import org.springframework.cloud.netflix.zuul.filters.Route; import org.springframework.cloud.netflix.zuul.filters.RouteLocator; import java.util.Optional; import java.util.concurrent.ConcurrentHashMap; public interface OAuth2ServerProvider { OAuth2AuthorisationServer authorisationServerOfRealm(String realmId); @AllArgsConstructor @Slf4j final class Default implements OAuth2ServerProvider { private final String clientId; private final String clientSecret; private final RouteLocator routeLocator; private final RestTemplateBuilder restTemplateBuilder; private final ConcurrentHashMap<String, OAuth2AuthorisationServer> cachedServersPerRealm = new ConcurrentHashMap<>(); @Override public OAuth2AuthorisationServer authorisationServerOfRealm(final String realmId) { final OAuth2AuthorisationServer server; if (!cachedServersPerRealm.containsKey(realmId)) { final String authServerRootURL = getAuthServerRootURL(realmId); final CredentialsStruct credentials = new CredentialsStruct(clientId, clientSecret, Optional.empty()); server = new OAuth2AuthorisationServer.ServerWithCachedAuthentication( new Hydra(authServerRootURL, credentials, restTemplateBuilder)); cachedServersPerRealm.put(realmId, server); } else { server = cachedServersPerRealm.get(realmId); } return server; } private String getAuthServerRootURL(final String realmId) { String authServerRootURL = null; final String authServerRoute = "hydra_" + realmId; // This is super inefficient but ok for now // TODO Get auth server URL properly final Optional<Route> potentialRoute = routeLocator.getRoutes().stream().filter( route -> (authServerRoute).equals(route.getId())) .findAny(); if (potentialRoute.isPresent()) { authServerRootURL = potentialRoute.get().getLocation(); log.info("Location of hydra is {}", authServerRootURL); } else { log.error("Could not find location of hydra (looking at route with id: {}", authServerRoute); } return authServerRootURL; } } }