d4science-iam-client/src/main/java/org/gcube/common/iam/D4ScienceIAMClient.java

235 lines
9.0 KiB
Java

package org.gcube.common.iam;
import java.net.URL;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.gcube.common.keycloak.KeycloakClient;
import org.gcube.common.keycloak.KeycloakClientException;
import org.gcube.common.keycloak.KeycloakClientFactory;
import org.gcube.common.keycloak.model.AccessToken;
import org.gcube.common.keycloak.model.ModelUtils;
import org.gcube.common.keycloak.model.RefreshToken;
import org.gcube.common.keycloak.model.TokenResponse;
/**
* Helper class that acts as IAM client providing
*
* @author Mauro Mugnaini
*
*/
public class D4ScienceIAMClient {
private KeycloakClient keycloakClient;
public static D4ScienceIAMClient newInstance() {
return new D4ScienceIAMClient();
}
private D4ScienceIAMClient() {
keycloakClient = KeycloakClientFactory.newInstance();
}
private KeycloakClient getKeycloakClient() {
return keycloakClient;
}
public D4ScienceIAMClientAutentication authenticate(String context, String clientId, String clientSecret)
throws D4ScienceIAMClientException {
return new D4ScienceIAMClientAutentication(this, context, clientId, clientSecret);
}
public D4ScienceIAMClientAutentication authenticate(URL tokenURL, String clientId, String clientSecret)
throws D4ScienceIAMClientException {
return new D4ScienceIAMClientAutentication(this, tokenURL, clientId, clientSecret);
}
public URL getTokenEndpointURL(String context) throws D4ScienceIAMClientException {
try {
return getKeycloakClient().getRealmBaseURL(context);
} catch (KeycloakClientException e) {
throw new D4ScienceIAMClientException(e);
}
}
public class D4ScienceIAMClientAutentication {
private URL tokenURL;
private TokenResponse tokenResponse;
private D4ScienceIAMClientAutentication(D4ScienceIAMClient client, String context, String clientId,
String clientSecret) throws D4ScienceIAMClientException {
this(client, client.getTokenEndpointURL(context), clientId, clientSecret);
}
private D4ScienceIAMClientAutentication(D4ScienceIAMClient client, URL tokenURL, String clientId,
String clientSecret)
throws D4ScienceIAMClientException {
this.tokenURL = tokenURL;
try {
this.tokenResponse = getKeycloakClient().queryOIDCToken(tokenURL, clientId, clientSecret);
} catch (KeycloakClientException e) {
throw new D4ScienceIAMClientException(e);
}
}
private TokenResponse getAuthenticationTokenResponse() {
return tokenResponse;
}
public String getAccessToken() {
return getAuthenticationTokenResponse().getAccessToken();
}
public boolean isExpired() throws D4ScienceIAMClientException {
try {
return ModelUtils.getAccessTokenFrom(getAuthenticationTokenResponse()).isExpired();
} catch (Exception e) {
throw new D4ScienceIAMClientException(e);
}
}
public boolean canBeRefreshed() throws D4ScienceIAMClientException {
try {
RefreshToken refreshToken = ModelUtils.getRefreshTokenFrom(getAuthenticationTokenResponse());
return refreshToken != null && !refreshToken.isExpired();
} catch (Exception e) {
throw new D4ScienceIAMClientException(e);
}
}
public void refreshAuthentication() throws D4ScienceIAMClientException {
try {
this.tokenResponse = getKeycloakClient().refreshToken(tokenURL, getAuthenticationTokenResponse());
} catch (KeycloakClientException e) {
throw new D4ScienceIAMClientException(e);
}
}
public D4ScienceIAMClientAuthorization authorize(String audience, List<String> permissions)
throws D4ScienceIAMClientException {
return new D4ScienceIAMClientAuthorization(audience, permissions);
}
public class D4ScienceIAMClientAuthorization {
TokenResponse tokenResponse;
private D4ScienceIAMClientAuthorization(String audience, List<String> permissions)
throws D4ScienceIAMClientException {
try {
this.tokenResponse = getKeycloakClient().queryUMAToken(tokenURL, getAuthenticationTokenResponse(),
audience, permissions);
} catch (KeycloakClientException e) {
throw new D4ScienceIAMClientException(e);
}
}
private TokenResponse getAuthorizationTokenResponse() {
return tokenResponse;
}
public String getAccessToken() {
return getAuthorizationTokenResponse().getAccessToken();
}
public boolean isExpired() throws D4ScienceIAMClientException {
try {
return ModelUtils.getAccessTokenFrom(getAuthorizationTokenResponse()).isExpired();
} catch (Exception e) {
throw new D4ScienceIAMClientException(e);
}
}
public boolean canBeRefreshed() throws D4ScienceIAMClientException {
try {
RefreshToken refreshToken = ModelUtils.getRefreshTokenFrom(getAuthorizationTokenResponse());
return refreshToken != null && !refreshToken.isExpired();
} catch (Exception e) {
throw new D4ScienceIAMClientException(e);
}
}
public void refreshAuthorization() throws D4ScienceIAMClientException {
try {
this.tokenResponse = getKeycloakClient().refreshToken(tokenURL, getAuthorizationTokenResponse());
} catch (KeycloakClientException e) {
throw new D4ScienceIAMClientException(e);
}
}
public Set<String> getRoles() throws D4ScienceIAMClientException {
AccessToken accessToken;
try {
accessToken = ModelUtils.getAccessTokenFrom(getAuthorizationTokenResponse());
} catch (Exception e) {
throw new D4ScienceIAMClientException(e);
}
Set<String> allRoles = new HashSet<>(accessToken.getRealmAccess().getRoles());
accessToken.getResourceAccess().forEach((r, a) -> allRoles.addAll(a.getRoles()));
return allRoles;
}
public Set<String> getResourceRoles(String resource) throws D4ScienceIAMClientException {
AccessToken accessToken;
try {
accessToken = ModelUtils.getAccessTokenFrom(getAuthorizationTokenResponse());
} catch (Exception e) {
throw new D4ScienceIAMClientException(e);
}
Set<String> resourceRoles = new HashSet<>(accessToken.getResourceAccess().get(resource).getRoles());
return resourceRoles;
}
public Set<String> getAudienceResourceRoles() throws D4ScienceIAMClientException {
AccessToken accessToken;
try {
accessToken = ModelUtils.getAccessTokenFrom(getAuthorizationTokenResponse());
} catch (Exception e) {
throw new D4ScienceIAMClientException(e);
}
Set<String> resourceRoles = new HashSet<>(
accessToken.getResourceAccess().get(accessToken.getAudience()[0]).getRoles());
return resourceRoles;
}
public String getName() throws D4ScienceIAMClientException {
try {
return (String) ModelUtils.getAccessTokenFrom(getAuthorizationTokenResponse()).getOtherClaims()
.get(D4ScienceCustomClaims.CLIENT_NAME);
} catch (Exception e) {
throw new D4ScienceIAMClientException(e);
}
}
public String getContactPerson() throws D4ScienceIAMClientException {
try {
return (String) ModelUtils.getAccessTokenFrom(getAuthorizationTokenResponse()).getOtherClaims()
.get(D4ScienceCustomClaims.CLIENT_CONTACT_PERSON);
} catch (Exception e) {
throw new D4ScienceIAMClientException(e);
}
}
public String getContactOrganization() throws D4ScienceIAMClientException {
try {
return (String) ModelUtils.getAccessTokenFrom(getAuthorizationTokenResponse()).getOtherClaims()
.get(D4ScienceCustomClaims.CLIENT_CONTACT_ORGANIZATION);
} catch (Exception e) {
throw new D4ScienceIAMClientException(e);
}
}
}
}
}