storagehub/src/main/java/org/gcube/data/access/storagehub/handlers/PublicLinkHandler.java

144 lines
4.7 KiB
Java

package org.gcube.data.access.storagehub.handlers;
import static org.gcube.common.storagehub.model.Constants.enchriptedPrefix;
import static org.gcube.common.storagehub.model.Constants.enchriptedVolatile;
import static org.gcube.common.storagehub.model.Constants.versionPrefix;
import java.util.Base64;
import jakarta.inject.Singleton;
import jakarta.servlet.ServletContext;
import org.gcube.common.encryption.encrypter.StringEncrypter;
import org.gcube.common.security.AuthorizedTasks;
import org.gcube.common.security.secrets.Secret;
import org.gcube.common.storagehub.model.exceptions.BackendGenericError;
import org.gcube.common.storagehub.model.exceptions.StorageHubException;
import org.gcube.data.access.storagehub.types.LinkType;
import org.gcube.data.access.storagehub.types.PublicLink;
import org.gcube.smartgears.ContextProvider;
@Singleton
public class PublicLinkHandler {
public String getForItem(String itemId, ServletContext context) throws BackendGenericError{
return getUrl(itemId, enchriptedPrefix, context);
}
public String getForVersionedItem(String itemId, String version, ServletContext context) throws BackendGenericError {
return getUrl(String.format("%s%s%s",itemId, versionPrefix, version), enchriptedPrefix, context);
}
public String getForVolatile(String fileId, String storageName, ServletContext context) throws BackendGenericError {
return getUrl(String.format("%s_%s",fileId, storageName), enchriptedVolatile, context);
}
public PublicLink resolveEnchriptedId(String enchriptedId) throws StorageHubException {
String complexId = enchriptedId;
boolean isVolatile = false;
if (enchriptedId.startsWith(enchriptedPrefix) || enchriptedId.startsWith(enchriptedVolatile) ) {
final String enchriptedValue = enchriptedId.startsWith(enchriptedPrefix) ? enchriptedPrefix : enchriptedVolatile;
isVolatile = enchriptedId.startsWith(enchriptedVolatile);
try {
String infraContext = String.format("/%s", ContextProvider.get().container().configuration().infrastructure());
Secret infraSecret = ContextProvider.get().container().authorizationProvider().getSecretForContext(infraContext);
complexId = AuthorizedTasks.executeSafely(() -> {
return StringEncrypter.getEncrypter().decrypt(
new String(Base64.getUrlDecoder().decode(enchriptedId.replace(enchriptedValue, ""))));
}, infraSecret);
}catch(Throwable e){
throw new BackendGenericError("invalid public url",e);
}
}
if (isVolatile) {
String[] volatileIdSplit = complexId.split("_");
return new VolatilePublicLink(volatileIdSplit[0], volatileIdSplit[1]);
}else {
if (complexId.contains(versionPrefix)) {
String[] split = complexId.split(versionPrefix);
String itemId = split[0];
String versionName = split[1];
return new ItemPublicLink(itemId, versionName);
} else
return new ItemPublicLink(complexId);
}
}
private String getUrl(String toEnchript, String prefix, ServletContext context) throws BackendGenericError{
String infraContext = String.format("/%s", ContextProvider.get().container().configuration().infrastructure());
Secret infraSecret = ContextProvider.get().container().authorizationProvider().getSecretForContext(infraContext);
try {
String enchriptedQueryString = AuthorizedTasks.executeSafely(
() -> {return StringEncrypter.getEncrypter().encrypt(toEnchript);},infraSecret);
String basepath = context.getInitParameter("resolver-basepath");
String filePublicUrl = String.format("%s/%s%s",basepath, prefix, Base64.getUrlEncoder().encodeToString(enchriptedQueryString.getBytes()));
return filePublicUrl;
}catch (Throwable e) {
throw new BackendGenericError("error encrypting item id",e );
}
}
public static class VolatilePublicLink implements PublicLink {
private String storageKey;
private String storageName;
protected VolatilePublicLink(String storageKey, String storageName){
this.storageKey = storageKey;
this.storageName = storageName;
}
@Override
public LinkType getType() {return LinkType.VOLATILE;}
@Override
public String getId() { return storageKey; }
@Override
public String getStorageName() { return storageName; }
}
public static class ItemPublicLink implements PublicLink {
private String itemId;
private String version;
private LinkType type;
protected ItemPublicLink(String itemId){
this.itemId = itemId;
this.type = LinkType.STANDARD;
}
protected ItemPublicLink(String itemId, String version){
this.itemId = itemId;
this.version = version;
this.type = LinkType.VERSIONED;
}
@Override
public LinkType getType() {return type;}
@Override
public String getId() { return itemId; }
@Override
public String getVersion() { return version; }
}
}