From 7a747640ea4e583a8c073953ab34d83619b525bd Mon Sep 17 00:00:00 2001 From: michaeloffner Date: Thu, 5 Oct 2023 21:07:06 +0200 Subject: [PATCH] add support for VFS path to S3 metadata and ACL functions --- build.number | 4 +-- .../resource/s3/function/S3AddACL.java | 6 ++-- .../resource/s3/function/S3Function.java | 32 +++++++++++++++++++ .../resource/s3/function/S3GetACL.java | 9 +++--- .../resource/s3/function/S3GetMetaData.java | 9 +++--- .../resource/s3/function/S3SetACL.java | 7 ++-- .../resource/s3/function/S3SetMetaData.java | 7 ++-- 7 files changed, 56 insertions(+), 18 deletions(-) diff --git a/build.number b/build.number index 5193995..9c69610 100644 --- a/build.number +++ b/build.number @@ -1,3 +1,3 @@ #Build Number for ANT. Do not edit! -#Thu Oct 05 16:42:25 CEST 2023 -build.number=23 +#Thu Oct 05 21:05:38 CEST 2023 +build.number=24 diff --git a/source/java/src/org/lucee/extension/resource/s3/function/S3AddACL.java b/source/java/src/org/lucee/extension/resource/s3/function/S3AddACL.java index 0d43cba..8655dea 100644 --- a/source/java/src/org/lucee/extension/resource/s3/function/S3AddACL.java +++ b/source/java/src/org/lucee/extension/resource/s3/function/S3AddACL.java @@ -48,10 +48,12 @@ public Object invoke(final PageContext pc, final Object[] args) throws PageExcep String host = args.length > 5 && args[5] != null ? cast.toString(args[5]) : null; double timeout = args.length > 6 && !isEmpty(args[6]) ? cast.toDoubleValue(args[6]) : 0; + PropsAndEndpoint pae = extractFromPath(eng, bucketName, objectName, accessKeyId, secretAccessKey, host); + try { // create S3 Instance - S3 s3 = S3.getInstance(toS3Properties(pc, accessKeyId, secretAccessKey, host), toTimeout(timeout)); - s3.addAccessControlList(bucketName, objectName, objACL); + S3 s3 = S3.getInstance(pae.props != null ? pae.props : toS3Properties(pc, accessKeyId, secretAccessKey, host), toTimeout(timeout)); + s3.addAccessControlList(pae.bucketName, pae.objectName, objACL); return null; } catch (Exception e) { diff --git a/source/java/src/org/lucee/extension/resource/s3/function/S3Function.java b/source/java/src/org/lucee/extension/resource/s3/function/S3Function.java index fd09843..949685b 100644 --- a/source/java/src/org/lucee/extension/resource/s3/function/S3Function.java +++ b/source/java/src/org/lucee/extension/resource/s3/function/S3Function.java @@ -22,10 +22,12 @@ import org.lucee.extension.resource.s3.S3Properties; import org.lucee.extension.resource.s3.S3Resource; +import org.lucee.extension.resource.s3.S3ResourceProvider; import org.lucee.extension.resource.s3.S3Util; import lucee.commons.io.res.Resource; import lucee.commons.io.res.ResourceProvider; +import lucee.commons.lang.types.RefString; import lucee.loader.engine.CFMLEngine; import lucee.loader.engine.CFMLEngineFactory; import lucee.loader.util.Util; @@ -133,4 +135,34 @@ public boolean isEmpty(Object object) { if (object instanceof CharSequence) Util.isEmpty(object.toString(), true); return object == null; } + + PropsAndEndpoint extractFromPath(CFMLEngine eng, String bucketName, String objectName, String accessKeyId, String secretAccessKey, String host) { + S3Properties props = null; + // handle if the bucketName is a VFS path + if (Util.isEmpty(objectName) && bucketName != null && bucketName.toLowerCase().startsWith("s3://")) { + props = new S3Properties(); + props.setAccessKeyId(accessKeyId); + props.setSecretAccessKey(secretAccessKey); + props.setHost(host); + RefString location = eng.getCreationUtil().createRefString(null); + String[] bo = S3Resource.toBO(S3ResourceProvider.loadWithNewPattern(props, location, bucketName.substring(5), Util.isEmpty(accessKeyId))); + bucketName = bo[0]; + objectName = bo[1]; + + if (objectName != null && objectName.endsWith("/")) objectName = objectName.substring(0, objectName.length() - 1); + } + return new PropsAndEndpoint(props, bucketName, objectName); + } + + static class PropsAndEndpoint { + S3Properties props; + String bucketName; + String objectName; + + public PropsAndEndpoint(S3Properties props, String bucketName, String objectName) { + this.props = props; + this.bucketName = bucketName; + this.objectName = objectName; + } + } } diff --git a/source/java/src/org/lucee/extension/resource/s3/function/S3GetACL.java b/source/java/src/org/lucee/extension/resource/s3/function/S3GetACL.java index 686a73d..2196abf 100644 --- a/source/java/src/org/lucee/extension/resource/s3/function/S3GetACL.java +++ b/source/java/src/org/lucee/extension/resource/s3/function/S3GetACL.java @@ -19,7 +19,6 @@ package org.lucee.extension.resource.s3.function; import org.lucee.extension.resource.s3.S3; -import org.lucee.extension.resource.s3.S3ResourceProvider; import lucee.loader.engine.CFMLEngine; import lucee.loader.engine.CFMLEngineFactory; @@ -35,7 +34,7 @@ public class S3GetACL extends S3Function { public Object invoke(PageContext pc, Object[] args) throws PageException { CFMLEngine eng = CFMLEngineFactory.getInstance(); Cast cast = eng.getCastUtil(); - if (args.length > 6 || args.length < 2) throw eng.getExceptionUtil().createFunctionException(pc, "S3GetACL", 1, 6, args.length); + if (args.length > 6 || args.length < 1) throw eng.getExceptionUtil().createFunctionException(pc, "S3GetACL", 1, 6, args.length); // required String bucketName = cast.toString(args[0]); @@ -47,10 +46,12 @@ public Object invoke(PageContext pc, Object[] args) throws PageException { String host = args.length > 4 && args[4] != null ? cast.toString(args[4]) : null; double timeout = args.length > 5 && !isEmpty(args[5]) ? cast.toDoubleValue(args[5]) : 0; + PropsAndEndpoint pae = extractFromPath(eng, bucketName, objectName, accessKeyId, secretAccessKey, host); + try { // create S3 Instance - S3 s3 = S3.getInstance(toS3Properties(pc, accessKeyId, secretAccessKey, host), toTimeout(timeout)); - return s3.getAccessControlList(bucketName, objectName); + S3 s3 = S3.getInstance(pae.props != null ? pae.props : toS3Properties(pc, accessKeyId, secretAccessKey, host), toTimeout(timeout)); + return s3.getAccessControlList(pae.bucketName, pae.objectName); } catch (Exception e) { throw eng.getCastUtil().toPageException(e); diff --git a/source/java/src/org/lucee/extension/resource/s3/function/S3GetMetaData.java b/source/java/src/org/lucee/extension/resource/s3/function/S3GetMetaData.java index 9265fa4..6bf511c 100644 --- a/source/java/src/org/lucee/extension/resource/s3/function/S3GetMetaData.java +++ b/source/java/src/org/lucee/extension/resource/s3/function/S3GetMetaData.java @@ -19,7 +19,6 @@ package org.lucee.extension.resource.s3.function; import org.lucee.extension.resource.s3.S3; -import org.lucee.extension.resource.s3.S3ResourceProvider; import lucee.loader.engine.CFMLEngine; import lucee.loader.engine.CFMLEngineFactory; @@ -35,7 +34,7 @@ public class S3GetMetaData extends S3Function { public Object invoke(PageContext pc, Object[] args) throws PageException { CFMLEngine eng = CFMLEngineFactory.getInstance(); Cast cast = eng.getCastUtil(); - if (args.length > 6 || args.length < 2) throw eng.getExceptionUtil().createFunctionException(pc, "S3GetMetaData", 1, 6, args.length); + if (args.length > 6 || args.length < 1) throw eng.getExceptionUtil().createFunctionException(pc, "S3GetMetaData", 1, 6, args.length); // required String bucketName = cast.toString(args[0]); @@ -47,10 +46,12 @@ public Object invoke(PageContext pc, Object[] args) throws PageException { String host = args.length > 4 && args[4] != null ? cast.toString(args[4]) : null; double timeout = args.length > 5 && !isEmpty(args[5]) ? cast.toDoubleValue(args[5]) : 0; + PropsAndEndpoint pae = extractFromPath(eng, bucketName, objectName, accessKeyId, secretAccessKey, host); + try { // create S3 Instance - S3 s3 = S3.getInstance(toS3Properties(pc, accessKeyId, secretAccessKey, host), toTimeout(timeout)); - return s3.getMetaData(bucketName, objectName); + S3 s3 = S3.getInstance(pae.props != null ? pae.props : toS3Properties(pc, accessKeyId, secretAccessKey, host), toTimeout(timeout)); + return s3.getMetaData(pae.bucketName, pae.objectName); } catch (Exception e) { throw eng.getCastUtil().toPageException(e); diff --git a/source/java/src/org/lucee/extension/resource/s3/function/S3SetACL.java b/source/java/src/org/lucee/extension/resource/s3/function/S3SetACL.java index ea96b78..ab0baf7 100644 --- a/source/java/src/org/lucee/extension/resource/s3/function/S3SetACL.java +++ b/source/java/src/org/lucee/extension/resource/s3/function/S3SetACL.java @@ -19,7 +19,6 @@ package org.lucee.extension.resource.s3.function; import org.lucee.extension.resource.s3.S3; -import org.lucee.extension.resource.s3.S3ResourceProvider; import lucee.loader.engine.CFMLEngine; import lucee.loader.engine.CFMLEngineFactory; @@ -49,10 +48,12 @@ public Object invoke(PageContext pc, Object[] args) throws PageException { String host = args.length > 5 && args[5] != null ? cast.toString(args[5]) : null; double timeout = args.length > 6 && !isEmpty(args[6]) ? cast.toDoubleValue(args[6]) : 0; + PropsAndEndpoint pae = extractFromPath(eng, bucketName, objectName, accessKeyId, secretAccessKey, host); + try { // create S3 Instance - S3 s3 = S3.getInstance(toS3Properties(pc, accessKeyId, secretAccessKey, host), toTimeout(timeout)); - s3.setAccessControlList(null, bucketName, objectName, objACL); + S3 s3 = S3.getInstance(pae.props != null ? pae.props : toS3Properties(pc, accessKeyId, secretAccessKey, host), toTimeout(timeout)); + s3.setAccessControlList(null, pae.bucketName, pae.objectName, objACL); return null; } catch (Exception e) { diff --git a/source/java/src/org/lucee/extension/resource/s3/function/S3SetMetaData.java b/source/java/src/org/lucee/extension/resource/s3/function/S3SetMetaData.java index 2a035e8..928762f 100644 --- a/source/java/src/org/lucee/extension/resource/s3/function/S3SetMetaData.java +++ b/source/java/src/org/lucee/extension/resource/s3/function/S3SetMetaData.java @@ -19,7 +19,6 @@ package org.lucee.extension.resource.s3.function; import org.lucee.extension.resource.s3.S3; -import org.lucee.extension.resource.s3.S3ResourceProvider; import lucee.loader.engine.CFMLEngine; import lucee.loader.engine.CFMLEngineFactory; @@ -50,10 +49,12 @@ public Object invoke(PageContext pc, Object[] args) throws PageException { String host = args.length > 5 && args[5] != null ? cast.toString(args[5]) : null; double timeout = args.length > 6 && !isEmpty(args[6]) ? cast.toDoubleValue(args[6]) : 0; + PropsAndEndpoint pae = extractFromPath(eng, bucketName, objectName, accessKeyId, secretAccessKey, host); + try { // create S3 Instance - S3 s3 = S3.getInstance(toS3Properties(pc, accessKeyId, secretAccessKey, host), toTimeout(timeout)); - s3.setMetaData(bucketName, objectName, metadata); + S3 s3 = S3.getInstance(pae.props != null ? pae.props : toS3Properties(pc, accessKeyId, secretAccessKey, host), toTimeout(timeout)); + s3.setMetaData(pae.bucketName, pae.objectName, metadata); return null; } catch (Exception e) {