ColdFusion cfhttp.filecontent - coldfusion

I recently started learning coldfusion. I am getting a bit confused, reading through numerous websites regarding the function cfhttp.filecontent.
Can any of you help me understand and provide me with an example of how I would format the following code I am writing? I am already grabbing name and email from a form on the index page and trying to initiate an API request and get the password back, formatted correctly.
<cfset passwordcomplexity = 4>
<cfinclude template='header.cfm'>
<cfhttp method="GET" url="https://hardest.pw/api/#passwordlenght#/#passwordcomplexity#">
<cfset returnString = cfhttp.filecontent>
<cfdump var="#returnString#">
<!---<cfmail to="#form.email#"
from="no-reply#training-pavel.com"
subject="New random password"
type="text">
Hey there, #form.name#!
We've just generated a new password for you! You can see it below:
</cfmail>--->
<cfinclude template='footer.cfm'>
At the end I just get something like this:
{"code":200,"desc":"Command completed successfully","password":"[&Vo4%T#l8","hardestlink":"https:\/\/hardest.pw\/0758828a-a6f6-4f9b-9bd7-c0dc778de0b7"}

Related

Problem with anchor links using resolveurl

I'm using <cfhttp> to pull in content from another site (coldfusion) and resolveurl="true" so all the links work. The problem I'm having is resolveurl is making the anchor links (href="#search") absolute links as well breaking them. My question is is there a way to make resolveurl="true" bypass anchor links somehow?
For starters, let's use the tutorial code from Adobe.com posted in the comments. You'll want to do something similar.
<cfhttp url="https://www.adobe.com"
method="get" result="httpResp" timeout="120">
<cfhttpparam type="header" name="Content-Type" value="application/json" />
</cfhttp>
<cfscript>
// Find all the URLs in a web page retrieved via cfhttp
// The search is case sensitive
result = REMatch("https?://([-\w\.]+)+(:\d+)?(/([\w/_\.]*(\?\S+)?)?)?", httpResp.Filecontent);
</cfscript>
<!-- Now, Loop through those URLs--->
<cfoutput>
<cfloop array="#result#" item="item" index="index">
<cfif LEFT(item, 1) is "##">
<!---Your logic if it's just an anchor--->
<cfelse>
<!---Your logic if it's a full link--->
</cfif>
<br/>
</cfloop>
</cfoutput>
If it tries to return a full URL before the anchor as you say, (I've been getting inconsistent results with resolveurl="true") hit it with this to only grab the bit you want.
<cfoutput>
<cfloop array="#result#" item="item" index="index">
#ListLast(item, "##")#
</cfloop>
</cfoutput>
What this code does is grab all the URLs, and parse them for anchors.
You'll have to decide what to do next inside your loop. Maybe preserve the values and add them to a new array, so you can save it somewhere with the links fixed?
It's impossible to assume in a situation like this.
There does not appear to be a way to prevent CF from resolving the hashes. In our usage of it the current result is actually beneficial since when we present content from another site we usually want the user to be sent there.
Here is a way to replace link href values with just anchor if one is present using regular expressions. I'm sure there are combinations of issues that could occur here if really malformed html.
<cfsavecontent variable="testcontent">
<strong>test</strong>
go to google
go to section
</cfsavecontent>
<cfset domain = replace("current.domain", ".", "\.", "all") />
<cfset match = "(href\s*=\s*(""|'))\s*(http://#domain#[^##'""]+)(##[^##'""]+)\s*(""|')" />
<cfset result = reReplaceNoCase(testcontent, match, "\1\4\6", "all") />
<cfoutput><pre>#encodeForHTML(result)#</pre></cfoutput>
Output
<strong>test</strong>
go to google
<a href="#section>go to section</a>
Another option if you are displaying the content in a normal page with js/jquery available is to run through each link on display and update it to just be the anchor. This will be less likely error with malformed html. Let me know if you have any interest in that approach.

ColdFusion Dropbox - How to get the token from the response URI

I am trying to implement the OAuth with Dropbox from a ColdFusion application, and I managed how to call the Dropbox method to generate the access token, but... I don't know how to get the generated TOKEN from the response URI. I am getting something like this from Dropbox:
http://localhost/dropbox/generate_token.cfm#access_token=AAAAAAAAYVM_XdCYlbTz0gQOwQkWlg6TDXf84_5h4giikg6J-7Man&token_type=bearer&uid=267693&account_id=dbid%3AAABeDMm-BN0n1DofLZz9kPZAipnQ
How to I retrieve the URL variables in this case? I mean if I do a
<cfdump var="#URL#">
I am getting an empty struct. If I do a
<cfdump var="#CGI#">
I still don't see any of the URL retrieved parameters in the structure. How do I get the variables and their values from the Dropbox response?
UPDATED
At some point I thought I found a way to read the URL but now - for no reason - this doesn't work anymore! I didn't change anything but the solution below doesn't work anymore.
I can read the full URL with JavaScript using document.location but this means to do an extra submit to a ColdFusion page and I don't want to do this. I want to get the Dropbox token from the URL and save it to the database directly in this page...
Any new ideas please?
SOLUTION THAT SEEMED TO WORK AT SOME POINT ...
I found a way to get the URI string using this:
<cfset objRequest = GetPageContext().GetRequest().getParameterMap() />
<cfdump var="#objRequest#">
<cfoutput>
<cfloop collection="#objRequest#" item="i">
<p>
#i# - #objRequest[i][1]#
</p>
</cfloop>
</cfoutput>
From now on, I know how to get the values returned by Dropbox.
I found a way to get the returned parameters by reading the browser URL with JavaScript, so in two steps: first, parse and extract the full URL including the part after the # sign (I found this has a name and it is called the "URL fragment") and second, create a JavaScript form with parsed parameters and resubmitted to the server. Here is the code:
<cfparam name="FORM.action" default="">
<cfif FORM.action IS "save_token">
<cfdump var="#FORM#">
<cfelse>
<form name="main" id="main" method="post">
<input type="hidden" name="action" id="action" value="save_token">
</form>
<script type="text/javascript" language="javascript">
<!--
var parameters = window.location.hash.substr(1).split("&");
function addHidden(theForm, key, value) {
// Create a hidden input element, and append it to the form:
var input = document.createElement("input");
input.type = "hidden";
input.name = key;
input.value = value;
theForm.appendChild(input);
}
// Form reference:
var theForm = document.forms["main"];
for (var i=0; i<parameters.length; i++) {
// Add data:
addHidden(theForm, parameters[i].split("=")[0], parameters[i].split("=")[1]);
}
theForm.submit();
//-->
</script>
</cfif>

grabbing JSON data using coldfusion

I have a URL which when run in the browser, displays JSON data, since I am new to coldfusion, I am wondering, what would be a good way to
grab the data from the web browser? Later on I will be storing the individial JSON data into MySQL database, but I need to figure out step 1
which is grabbing the data.
Please advise.
Thanks
You'll want to do a cfhttp request to load the external content.
Then you can use deserializeJSON to convert the JSON object into the appropriate cfml struct.
See the example Adobe gives in the deserializeJSON documentation.
Here is quick example:
<!--- Set the URL address. --->
<cfset urlAddress="http://ip.jsontest.com/">
<!--- Generate http request from cf --->
<cfhttp url="#urlAddress#" method="GET" resolveurl="Yes" throwOnError="Yes"/>
<!--- handle the response from the server --->
<cfoutput>
This is just a string:<br />
#CFHTTP.FileContent#<br />
</cfoutput>
<cfset cfData=DeserializeJSON(CFHTTP.FileContent)>
This is object:<br />
<cfdump var="#cfData#">
Now you can do something like this:<br />
<cfoutput>#cfData.ip#</cfoutput>
Execute this source here http://cflive.net/

Login System in ColdFusion 9

I am working with a very old login system that my company used before on a website that used frames.
Before, when someone tried a wrong user/pass combination the frame would load a simple cfinclude file with the login form and an error message on top of it.
Now I am using a form in a popup window that calls the application.cfc but instead of getting the error message back on my popup window the page load the cfinclude file from the application component to a new page.
So I need a few things to happen for this application. First, I need the initial popup window to stay up and the page should not submit if the combination of user/pass is wrong, and finally I need the error message to appear somewhere on the popup.
If anyone did something like this before I would really appreciate your feedback.
This is a partial of my code:
Login Form:
<!--- loginErrMsg display - to tell why login is denied --->
<cfif isdefined("loginErrMsg")><span style="color:red">#loginErrMsg#</span><br /></cfif>
<form name="LoginForm" id="LoginForm" action="<cfif test is false>https://secure.example.com</cfif>#loginFormAction#" method="post" target="_top">
</cfoutput>
<input type="hidden" name="loginPost" value="true">
<p>
Login below to take advantage of the great services we offer:
</p>
E-mail:<input name="j_username" class="loginform" type="text" size="30" maxlength="50" id="j_username">
Password: <input name="j_password" type="password" size="30" maxlength="16" class="loginform">
<br />
<input type="submit" name="btn" value="Submit" class="bluebuttonnormal">
</form>
Application.cfc Code:
<cflogin applicationtoken="swmadmin">
<cfif NOT IsDefined("cflogin")>
<cfinclude template="login.cfm">
<cfabort>
<cfelse>
<cfquery name="userlookup" datasource="#ds#">
SELECT clientadminID, roles, isFaxOnly, acctEnabled FROM clientadmin
WHERE
username=<cfqueryparam value="#cflogin.name#" CFSQLTYPE="CF_SQL_VARCHAR" maxlength="50">
and password=<cfqueryparam value="#cflogin.password#" CFSQLTYPE="CF_SQL_VARCHAR" maxlength="16">
</cfquery>
<cfif userlookup.recordcount eq 0>
<cfset loginErrMsg = "Invalid login.">
<cfinclude template="login.cfm">
<cfabort>
</cflogin>
I am working with a very old login system that my company used before
on a website that used frames.
If this is a new website, don't use it. Login forms are a dime a dozen and can be done in your sleep. Start fresh and do it right.
So I need a few things to happen for this application. First, I need
the initial popup window to stay up and the page should not submit if
the combination of user/pass is wrong, and finally I need the error
message to appear somewhere on the popup.
You're going to want to use an AJAX solution here, either write your own or use a good library like jQuery. Once you check the login values you can use jQuery or simple javascript to unhide or update the innerHTML of an empty element to display your error message.
<cflogin ...>
...
</cflogin>
CFLogin makes me sad. Another one of ColdFusion's tags meant to simplify something commonly done that doesn't really help much and sacrifices flexibility. You can get far more control over your application without it. instead of CFLogin, try something like this pseudo code
<cfcomponent>
<cffunction name = "onRequest" ...>
<cfargument name="targetPage" type="String" required = "true" />
<cfif !structKeyExists(session, "roles") and !findNoCase("loginHandler.cfm",cgi.script_name)>
<!--- notice I prevent the redirect on the form handler, otherwise the ajax will get redirected to the login.cfm page --->
<cfinclude template = "login.cfm">
<cfelse>
<cfinclude template = "#arguments.targetPage#">
</cfif>
</cffunction>
</cfcomponent>
Your login.cfm would then contain your form but your button would fire something like jQuery.post() to "loginHandler.cfm", then depending on the result of the login, your callback function may use jQuery.html() to display the error or window.location.replace / window.location.href if the login was successful. Of course, in the event of a successful login, your ColdFusion page would have to create their session variables and do whatever else you want it to do before sending the result back to your AJAX call.

How to access the URL parameter id in Coldfusion if it's after a hashtag #?

After trying for about an hour without success... (coldfusion8) a dummy question, but I*m stuck:
My URL (Jquery Mobile, no pushstate, that's why it looks like it is):
http://www.page.de/test/mem/search.cfm#/test/mem/search.cfm?id=9900000003869
If I output:
<cfdump output="e:\website\dump.txt" label="catch" var="#url#">
I get this:
catch - struct
ID: 9900000003869
But how do i access it... I'm trying forever, nothing works:
<cfdump output="e:\website\dump.txt" label="catch" var="#id#">
<cfdump output="e:\website\dump.txt" label="catch" var="#ID#">
<cfdump output="e:\website\dump.txt" label="catch" var="#url.id#">
<cfdump output="e:\website\dump.txt" label="catch" var="#url.ID#">
<cfdump output="e:\website\dump.txt" label="catch" var="#StructGetValue(url,"id")d#">
...
Thanks for helping!
Ok... This works:
URL = http://www.page.de/test/mem/search.cfm#/test/mem/search.cfm?id=9900000003869
<cfset objRequest = GetPageContext().GetRequest() />
<cfset strUrl = right( objRequest.GetRequestUrl().Append( "?" & objRequest.GetQueryString() ).ToString(), 13)>
Credit
If someone finds an easier, please post. I will check as answer.
You're trying to read this from a txt file?
Can you not simply use:
<cfdump label="catch" var="#url.id#" />
Does that work?
EDIT:
Could you try capturing and formatting what you need first then after, writing it to the file?
For example, try using:
<cfsavecontent variable="myFileContents">
<cfoutput>#url.id#</cfoutput>
</cfsavecontent>
<cffile action="Write" file="e:\website\dump.txt" output="#myFileContents#" />
I have not tested this code, but give it a go and see!
Might want to put a check on that URL variable too using isDefined()
Good luck.
Doing some research on fragment identifiers (which is a new term to me :( )prompted by Peter and Duncan's comments, I've found from wiki: http://en.wikipedia.org/wiki/Fragment_identifier
The fragment identifier functions differently than the rest of the
URI: namely, its processing is exclusively client-side with no
participation from the server — of course the server typically helps
to determine the MIME type, and the MIME type determines the
processing of fragments. When an agent (such as a Web browser)
requests a resource from a Web server, the agent sends the URI to
the server, but does not send the fragment. Instead, the agent waits
for the server to send the resource, and then the agent processes the
resource according to the document type and fragment value.
now, being your client IS sending the fragment and the url variable is accessible to you for some reason, using it is done by my original post to follow.
<cfoutput>
is generally how you output a variable or other evaluations to the screen.
<cfset myName = "Travis">
<cfoutput>Hello, my name is #myName#</cfoutput>
You can also access the variable by using it in a statement that doesn't output anywhere.
<cfset myFullName = myName & " Mak">
You can also use the variables in a query
<cfquery name = "qSomeQuery" datasource = "#application.dsn#">
select * from table where id = #url.id#
</cfquery>
However, that's the bad way to use it in a query, you should always use cfquery param.
<cfquery name = "qSomeQuery" datasource = "#application.dsn#">
select * from table where id = <cfqueryparam cfsqltype="cf_sql_integer" value="#url.id#">
</cfquery>
The problem you're having in testing the variable is due to incorrect syntax.
<cfif isDefined("url.id")> verses <cfif isDefined(url.id)> a more accurate test is <cfif structKeyExists(url, "id")>
For some reason my CF server truncates everything in the url after the # but yours doesn't seem to have this problem. As your cfdump states, you can see your url variables so "accessing" the url variable is as easy as using it: #url.id# or testing it <cfif isDefined("url.id")>