Access S3 from Lucee/Railo/Coldfusion built in functions - amazon-web-services

I am having trouble accessing an S3 bucket to just list the files using Lucee. I have followed the directions here and here with no luck. I keep getting the error message that the directory does not exist.
This is in my Application.cfc:
this.name="s3-test";
this.mappings = {
"/s3test" = "s3://luceetest/blah"
}
this.s3 = {
"accessKeyid": "XXXXXXXXXXXXXX",
"awsSecretKey": "ZZZZZ/XXXXXX/YYYYY",
"defaultLocation": "Oregon",
};
This is the code I am testing with:
<cfsetting showDebugOutput="Yes">
<cfdirectory action="list" directory="s3://coldlucee/blah" name="blah" recurse="yes" type="file">
<cffile action="write" output="s3 specs" file="s3://coldlucee/blah/test.txt"/>
I have also tried to map it inside of the web interface using the format s3://accessKeyID:awsSecretKey#coldlucee/blah as the resource but it always shows up as red which means it can't be found.
I am hoping someone can help me out with this, it seems so simple in the articles I have read so I might have a configuration error on the Amazon side. I have tried to make the bucket public to no avail though.

I've never been able to get CF's implementation of S3 to work either. I ended up using an S3 REST Wrapper I found here:
https://gist.github.com/CFJSGeek/3f6f14ba86049af75361

Related

Can Postman take a file as a variable from a path?

I have a postman collection, with a set of three API calls I'd like to chain together and feed with a data file using the runner function. Lets say they're:
/prepareUpload
/upload
/confirmUpload
and the output of each is needed for the next step. I'm happily pulling stuff out of the responses and putting them into variables ready for the next call, but the bit I seem to be falling down on is the /upload needs a file parameter of type file, but Postman doesn't seem to let me set it to a variable:
I've tried exporting the collection, manually editing the json to force it to a variable and running that, so something like :
<snip>
{
"key": "file",
"contentType": "{{contentType}}",
"type": "file",
"src": ["{{fullpath}}"]
}
],
"options": {
"formdata": {}
}
where {{contentType}} and {{fullpath}} are coming from my data file, but it never seems to actually do the upload.
Does anyone know if this is possible?
Issue:
In postman if we check the UI, we notice that there is no way to define file path as variable.
This looks like a limitation when we need to run file from different systems
Solution:
The solution is to hack the collection.json file. Open the json and edit the formdata src and replace it with a variable, let say file_path so : {{file_path}}
Now in Postman:
in pre request you can below code to set the path
pm.environment.set("file_path","C:/Users/guest/Desktop/1.png")
You can also save it as environment variable directly or pass through cmd using --env-var when using newman.
Note:
set access file from outside working directory as true (settings from top right corner)
It's not possible to read local files with Postman (There are at least two issues concerning that in there tracker on github: 798, 7210)
A workaround would be, to setup a server that provides the file, so you could get the data via a request to that server.
Ok, so found the answer to this, and the short version is - Postman can't do it, but Newman can :
https://github.com/postmanlabs/newman#file-uploads
It's a fair bit more effort to get it set up and working, but it does provide a solution for automating the whole process.
For Postman (as of Version 9.1.5), on Mac os, you can trick postman by naming a file in your shared directory with your variable name (ie. {{uploadMe}}). Then you choose this file (named as the variable) from the file selector and VoilĂ .
In my case the files I upload are located in the same shared directory and don't forget to set the shared directory in your postman settings.
The solution is quite simple,
Make sure you have the latest version of postman
Go to postman settings to find your working directory and add the desired file to your postman working directory
In the body tab, select formdata
In the pre-request script tab, enter the code below.
pm.request.body.mode = "formdata";
pm.request.body.formdata = {
"key": "preveredKey",
"type": "file",
"src": "fileName.extension"
};

Calling Java JAR functions

I'm attempting to connect to Java (JAR) libraries to communicate with the "QuickBooks Merchant Services API".
Each call to the API requires an OAuth2 access token. My first step is to use the Java SDK that QuickBooks provides to get the access token.
I downloaded the "jar-with-dependencies.jar" option from this page. According to Maven, 6.0.1 is the current version.
https://search.maven.org/search?q=a:oauth2-platform-api
I created a folder named "java" off of the root of the web site and stored this file in that folder.
oauth2-platform-api-6.0.1-jar-with-dependencies.jar
In Application.cfc, I added this line of code:
<!--- Application.cfc snippet --->
<cfset this['javaSettings'] = {
LoadPaths = ["#expandPath('/java')#"]
,loadColdFusionClassPath = true
,reloadOnChange = true
,watchInterval = 100
,watchExtensions = "jar,class,xml"
}>
In a test.cfm file I have the following lines of code in a function:
variables['oauth2Config'] = createObject("java", "com.intuit.oauth2.config.OAuth2Config").OAuth2ConfigBuilder(arguments.clientId, arguments.clientSecret).callDiscoveryAPI(Environment.SANDBOX).buildConfig();
In an example on the developer.intuit.com web site, the Java code looks like this:
OAuth2Config oauth2Config = new OAuth2Config.OAuth2ConfigBuilder("clientId", "clientSecret").callDiscoveryAPI(Environment.SANDBOX).buildConfig();
When I run the code, I get the following error message.
Class not found: com.intuit.oauth2.config.OAuth2Config
I have swapped out the "LoadPaths" key with several different variants but all result in the same error.
LoadPaths = ["/java"]
LoadPaths = ["./java"]
LoadPaths = ["./java/oauth2-platform-api-6.0.1-jar-with-dependencies.jar"]
I have tried modifying the initialization call:
local['oauth2Config'] = createObject("java", "OAuth2Config").OAuth2ConfigBuilder(arguments.clientId, arguments.clientSecret).callDiscoveryAPI(Environment.SANDBOX).buildConfig();
That resulted in basically the same kind of error:
Class not found: OAuth2Config
I'm pretty sure that I'm doing something wrong in the this.javaSettings struct in Application.cfc. I was hoping that the Java JAR approach would be easier, but I may end up using the REST API that Intuit has. I still have to use OAuth2 and I'm not sure if the cfoauth tag/function will work with this system.
Let me know if you see anything that will help me get past this problem.
CF can't find OAuth2ConfigBuilder because it's inner class, which requires a slightly different syntax:
createObject("java", "com.intuit.oauth2.config.OAuth2Config$OAuth2ConfigBuilder");
Environment is also a class within the jar. You must create a reference to it before using the constant Environment.SANDBOX
Even after fixing those issues, a brief test with CF2016 threw a LinkageError due to the inclusion of slf4j within the custom jar, while also loading the jars from CF/lib (which includes slf4j too). Switching to loadColdFusionClassPath = false seemed to get past that error.
java.lang.LinkageError: loader constraint violation: when resolving
method
"org.slf4j.impl.StaticLoggerBinder.getLoggerFactory()Lorg/slf4j/ILoggerFactory;"
the class loader (instance of
coldfusion/runtime/java/JavaDynamicClassLoader)
...
Application.cfc
this['javaSettings'] = {
LoadPaths = ["#expandPath('/java')#"]
,loadColdFusionClassPath = false
, ...
};
Code:
variables['environ'] = createObject("java", "com.intuit.oauth2.config.Environment");
variables['builder'] = createObject("java", "com.intuit.oauth2.config.OAuth2Config$OAuth2ConfigBuilder");
variables['oauth2Config'] = variables['builder'].init( arguments.clientId, arguments.clientSecret).
callDiscoveryAPI( variables['environ'].SANDBOX ).buildConfig();

Timeout error when listing S3 buckets using erlcloud

I'm trying to use the erlcloud library for S3 uploads in my app. As a test, I'm trying to get it to list buckets via an iex console:
iex(4)> s3 = :erlcloud_s3.new("KEY_ID", "SECRET_KEY")
...
iex(5)> :erlcloud_s3.list_buckets(s3)
** (ErlangError) erlang error: {:aws_error, {:socket_error, :timeout}}
(erlcloud) src/erlcloud_s3.erl:909: :erlcloud_s3.s3_request/8
(erlcloud) src/erlcloud_s3.erl:893: :erlcloud_s3.s3_xml_request/8
(erlcloud) src/erlcloud_s3.erl:238: :erlcloud_s3.list_buckets/1
I've checked that inets, ssl, and erlcoud are all started, and I know the credentials work fine, because I've tested them in a similar fashion with a Ruby library in irb.
I've tried configuring it with a longer timeout, but no matter how high I set it I still get this error.
Any ideas? Or approaches I could take to debug this?
I could simulate the same error, and could resolve it by replacing double-quote with single-quote.
> iex(4)> s3 = :erlcloud_s3.new('KEY_ID', 'SECRET_KEY')
> iex(5)> :erlcloud_s3.list_buckets(s3)
Assuming the double-quote was used, it may be caused by a type mismatch between string and char-list.

Strange behaviour when uploading scaled file using Fine Uloader

I have implemented FileUploader 4.4 and it works perfectly when uploading multiple files using Coldfusion.
The end point code is very simple and looks like this:
<cffile action="upload"
destination="#application.Config.imageDir#"
nameconflict="overwrite"
filefield="FORM.qqFile" />
<cfif CFFILE.contenttype EQ "image" OR ListFindNoCase("jpg,jpeg,gif,png", CFFILE.serverFileExt)>
<cfset local.fileName = CFFILE.serverFile />
</cfif>
Whenever I upload single, or multiple images, the local.filename variable is correctly set to the image file name value that you usually see in qqfilename, for example "image0001.jpg"
The javasript code to send this data is simply:
$('#fine-uploader').fineUploader({
request: {
endpoint: '<cfoutput>#application.Config.fineUploaderProxy#?cfc=#cfcName#&functionName=#functionName#</cfoutput>'
}
});
However, as soon as I add scaling, then a strange behaviour starts occurring. The scaled version is sent to my upload handler, however, the file name that is being sent is always "blob" for every scaled image, instead of the name I would expect, being something like
"image0001(small).jpg"
The code I add to activate the scaling is simply:
$('#fine-uploader').fineUploader({
scaling: {
sizes: [
{name: "small", maxSize: 50}
]
},
request: {
endpoint: '<cfoutput>#application.Config.fineUploaderProxy#?cfc=#cfcName#&functionName=#functionName#</cfoutput>'
}
});
Could someone please help me as to why the filename "blob" is being with the qqfile instead of the actual file name? I am using the latest version of Chrome.
Thanks
This is due to the fact that Fine Uploader doesn't actually send a File when it generates a scaled version off a reference file. The entity is specifically a Blob. While a File has a name property, a Blob does not. It is because of this that the browser, when constructing the multipart segment for a Blob, sets the filename parameter to "blob". There are ways to overcome this, but not reliably cross browser. So, Fine Uploader will always send the actual file name in a "qqfilename" parameter. Your server should look at this value to reliably determine the files name in all cases.

Retrieving Common Access Card (CAC) information from a client

So I found some code
<cfset x509 = GetPageContext().getRequest().getAttribute("javax.servlet.request.X509Certificate") />
<cfoutput>not before = #x509[1].getNotBefore()#</cfoutput><br/>
<cfoutput>not after = #x509[1].getNotAfter()#<br></cfoutput>
<cfoutput>#ToBase64(x509[1].getEncoded())#<br></cfoutput>
<cfoutput>#x509[1].getIssuerDN()#<br></cfoutput>
<cfoutput>#x509[1].getIssuerX500Principal()#<br></cfoutput>
What I want this code to do is display the information from the CAC, instead I am getting an error Variable X509 is undefined...
Edit
An alternate solution seems to be to use CGI.CERT_SUBJECT however I am not exacly sure how to get this variable to be anything other than an empty string. FWIW I am try to get this to work on a standalone coldfusion server.
The getAttribute() method returns a NULL variable when the attribute is not found, which is what's happening in this case. You have to see if it's defined before you can display it.
<cfif StructKeyExists( variables, "x509" )>
{ Code }
</cfif>
On how to get the attribute you're after, I couldn't tell you, but this will prevent the error from occuring.
Depending on your web server (I know Apache does this if you set SSLOptions +StdEnvVars +ExportCertData), you can get the PEM-encoded cert as an environment variable (i.e., cgi.ssl_client_cert) and you can get other info (DN, issuer's DN, etc) as well. Here's a list of the environment variables.