keycloak-d4science-spi-parent/avatar-importer/src/main/java/org/gcube/keycloak/oidc/avatar/importer/libravatar/Libravatar.java

122 lines
4.4 KiB
Java

package org.gcube.keycloak.oidc.avatar.importer.libravatar;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Map;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.io.IOUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.common.base.Preconditions;
public class Libravatar {
protected static final Logger logger = LoggerFactory.getLogger(Libravatar.class);
private String email;
private LibravatarOptions options = new LibravatarOptions().withoutHttps();
private Libravatar(final String email) {
Preconditions.checkNotNull(email).toLowerCase();
this.email = email;
}
/**
* Construct new libravatar downloader for the provided email
* @param email the email address
* @return the new libravatar downloader instance
*/
public static Libravatar from(String email) {
return new Libravatar(email);
}
/**
* Adds he options to be used for download
* @param options the libravatar options
* @return
*/
public Libravatar withOptions(LibravatarOptions options) {
this.options = options;
return this;
}
/***
* Performs the avatar download by searching for a domain specific server and then on the libravatar public service
* @return the avatar's byte array
* @throws LibravatarException if no default has been set in options ({@link LibravatarOptions#defaultingTo(LibravatarDefaultImage)}) and the image hasn't found on remote server
*/
public byte[] downloadArray() throws LibravatarException {
try (InputStream is = download()) {
return IOUtils.toByteArray(is);
} catch (IOException e) {
throw new LibravatarException("Cannot download image byte's array for email: " + email, e);
}
}
/***
* Performs the avatar download by searching for a domain specific server and then on the libravatar public service
* @return the avatar byte array
* @throws LibravatarException if no default has been set in options ({@link LibravatarOptions#defaultingTo(LibravatarDefaultImage)}) and the image hasn't found on remote server
*
*/
public InputStream download() throws LibravatarException {
try {
return getURL().openStream();
} catch (IOException e) {
throw new LibravatarException("Cannot open image stream for email: " + email, e);
}
}
/**
* Construct the URL to be used for the download
* @return the URL to use
* @throws MalformedURLException
*/
private URL getURL() throws MalformedURLException {
logger.debug("Constructing download URL for email: {}", email);
logger.debug("Getting the DNS queries domain first");
String baseTarget = options.isUseHttps() ? DNSUtil.resolveSecureSRVRecordFromEmail(email)
: DNSUtil.resolveSRVRecordFromEmail(email);
if (baseTarget != null) {
logger.debug("Building URL with the DNS queried domain");
return buildURL(baseTarget);
} else {
logger.debug("Defaulting to the liravatar URL");
return buildURL(options.isUseHttps() ? LibravatarOptions.getSecureBaseUri() : LibravatarOptions.getBaseUri());
}
}
/**
* Builds the URL with query string to be used starting from the provided base URL
* @param baseURL the base url to be used
* @return the complete URL ready to be called
* @throws MalformedURLException
*/
private URL buildURL(String baseURL) throws MalformedURLException {
StringBuilder sb = new StringBuilder(baseURL);
String hash = options.isUseSHA256() ? DigestUtils.sha256Hex(email.getBytes())
: DigestUtils.md5Hex(email.getBytes());
logger.trace("Computed hash is: {}", hash);
sb.append(hash);
Map<String, String> parametersMap = options.toParametersMap();
String queryString = parametersMap.entrySet().stream().map(p -> p.getKey() + "=" + p.getValue())
.reduce((p1, p2) -> p1 + "&" + p2).orElse("");
if (queryString != null && !"".equals(queryString)) {
sb.append("?");
sb.append(queryString);
}
String url = sb.toString();
logger.trace("Resulting URL string is: {}", url);
return new URL(url);
}
}