package org.gcube.common.authorization.client.proxy; import static org.gcube.common.authorization.client.Constants.CLIENT_ID_PARAM; import static org.gcube.common.authorization.client.Constants.CONTEXT_PARAM; import static org.gcube.common.authorization.client.Constants.ROLES_PARAM; import static org.gcube.common.authorization.client.Constants.SERVICE_NAME; import java.io.BufferedReader; import java.io.InputStream; import java.io.InputStreamReader; import java.net.HttpURLConnection; import java.net.URL; import java.util.HashMap; import java.util.List; import java.util.Map; import org.gcube.common.authorization.client.Binder; import org.gcube.common.authorization.client.Constants; import org.gcube.common.authorization.client.exceptions.ObjectNotFound; import org.gcube.common.authorization.library.AuthorizationEntry; import org.gcube.common.encryption.StringEncrypter; import org.gcube.common.scope.api.Environment; import org.gcube.common.scope.api.ScopeProvider; import org.gcube.common.scope.impl.EnvironmentServiceMap; public class DefaultAuthorizationProxy implements AuthorizationProxy { private static Map cache = new HashMap(); private static String endpoint; public DefaultAuthorizationProxy() { endpoint = EnvironmentServiceMap.getInfrastructuresFor(Environment.DEVELOPMENT).endpoint(SERVICE_NAME); } @Override public String generate(String clientId, List roles) throws Exception { final String methodPath = "/generate/token/"; StringBuilder rolesQueryString = new StringBuilder(); if (roles.size()>0){ for (String role: roles) rolesQueryString.append(role).append(","); rolesQueryString.deleteCharAt(rolesQueryString.lastIndexOf(",")); } StringBuilder callUrl = new StringBuilder(endpoint).append(methodPath).append("?") .append(CLIENT_ID_PARAM).append("=").append(clientId).append("&") .append(ROLES_PARAM).append("=").append(rolesQueryString).append("&") .append(CONTEXT_PARAM).append("=").append(ScopeProvider.instance.get()); URL url = new URL(callUrl.toString()); HttpURLConnection connection = (HttpURLConnection)url.openConnection(); connection.setRequestMethod("POST"); if (connection.getResponseCode()!=200) throw new Exception("error contacting authorization service"); String encryptedToken= ""; try(BufferedReader reader = new BufferedReader(new InputStreamReader((InputStream)connection.getContent()));){ StringBuilder result = new StringBuilder(); String line; while((line = reader.readLine()) != null) result.append(line); encryptedToken = result.toString(); } return StringEncrypter.getEncrypter().decrypt(encryptedToken); } @Override public AuthorizationEntry get(final String token) throws ObjectNotFound, Exception{ final String methodPath = "/retrieve/"; StringBuilder callUrl = new StringBuilder(endpoint).append(methodPath).append(token); URL url = new URL(callUrl.toString()); HttpURLConnection connection = makeRequest(url, "GET"); if (connection.getResponseCode()==404) throw new ObjectNotFound("token "+token+" not found"); if (connection.getResponseCode()!=200) throw new Exception("error contacting authorization service"); if (connection.getContentLengthLong()<=0) return null; try(InputStream stream = (InputStream)connection.getContent();){ AuthorizationEntry entry = (AuthorizationEntry)Binder.getContext().createUnmarshaller().unmarshal(stream); cache.put(token, new AuthorizationEntryCache(entry)); return entry; } } /* @Override public BannedService deny(final String userName, final String serviceClass, final String serviceName) throws Exception { URL url = new URL(endpoint+"/deny/"+userName+"/"+serviceClass+"/"+serviceName); HttpURLConnection connection = makeRequest(url, "POST"); if (connection.getResponseCode()!=200 && connection.getResponseCode()!=200) throw new Exception("error contacting authorization service"); if (connection.getContentLengthLong()<=0) return null; try(InputStream stream = (InputStream)connection.getContent();){ BannedService service = (BannedService)Binder.getContext().createUnmarshaller().unmarshal(stream); return service; } } @Override public void allow(final String userName, final String serviceClass, final String serviceName) throws Exception{ URL url = new URL(endpoint+"/deny/"+userName+"/"+serviceClass+"/"+serviceName); HttpURLConnection connection = makeRequest(url, "DELETE"); if (!(connection.getResponseCode()>=200 && connection.getResponseCode()<=206)) throw new Exception("error contacting authorization service"); } @Override public List getBannedServices(final String userName) throws Exception{ URL url = new URL(endpoint+"/deny/"+userName); HttpURLConnection connection = makeRequest(url, "GET"); if (connection.getResponseCode()!=200) throw new Exception("error contacting authorization service"); if (connection.getContentLengthLong()<=0) return Collections.emptyList(); try(InputStream stream = (InputStream)connection.getContent();){ BannedServices services = (BannedServices)Binder.getContext().createUnmarshaller().unmarshal(stream); if (services.get()==null) return Collections.emptyList(); else return services.get(); } } */ private HttpURLConnection makeRequest(URL url, String method) throws Exception{ HttpURLConnection connection = (HttpURLConnection)url.openConnection(); connection.setRequestProperty(Constants.SCOPE_HEADER_ENTRY, ScopeProvider.instance.get()); connection.setRequestMethod(method); return connection; } }