Override mail settings in application for dev server environments - coldfusion

I am currently in the finishing stages of building an application and have asked the user group to perform production-level usage testing on the application. My application is a makeshift order management system that sends an email to a customer when an order is saved that includes an invoice.
I ran into a problem yesterday when I was doing some testing; this environment currently contains production-quality data, including old customer records. I processed a few orders and forgot about the functionality, and the customer who I did the orders for received emails saying the order is complete. Good that it worked, bad that it lead to this confusion.
The action I would prefer would be to set something somewhere within the application that forces all emails, regardless of the to recipient, to be sent to a specific address, though I would settle for simply being able to turn it off for this application alone. Turning it off on the server level is available not a preferred option due to the need to perform testing on other applications that process email, but are not populated with production-quality data.
Are there any specific flags or code I can use to override server settings in the application to only send email to a certain address based on how we identify our environment, or to not send email altogether?

Reference this page:
http://cookbooks.adobe.com/post_How_can_I_use_Application_level_SMTP_Server_Settin-16469.html
For testing purposes you could set the SMTP server to a non existant IP address. The cfmail routine will still work and coldfusion will move it to an undeliverable folder.
You could add <cfif> statements around it to determine if your on a production URL or dev URL so that it uses the right server while on the production server, or uses the "fake" server while on your development server. OR while on the production server, have an on/off variable that you could use to test emails through your smtp server or shut off emails and route them to the fake SMTP server.
If your on version 8.0 or older, you can setup an application level variable for your mail server and modify your cfmail tags to reference:
<cfmail server="#application.mailserver#" to="" from="" subject="">

This solution presumes you use the same mail server but just want to swap emails to a test address (perhaps yours, so you can see the result). It also presumes your live server name resolves to something that has 'www.something.somethong.' and your dev/test/qa etc servers do not.
In your Application cfc onApplicationStart() try this:
<cfscript>
if(listFirst(CGI.SERVER_NAME,'.') != 'www') {
Application.szEmailToTestEnv = 'test#somewhere.com'; // Use your test email here
}
</cfscript>
Then where you send the email have a bit of logic infront of your mail param such that:
<cfscript>
if(isDefined('Application.szEmailToTestEnv') && len(Application.szEmailToTestEnv)) {
Variables.szEmailTo = Application.szEmailToTestEnv;
} else Variables.szEmailTo = Variables.qCustomerEmail;
</cfscript>
And then in your cfmail:
<cfmail to="#Variables.szEmailTo#"....
Adjust scopes and variable names and value as necessary.
Essentially, any 'site' (say dev.yoursite.com) that is not your live site will then use the test email you set at app startup to send the email and live will continue to use the correct customer email with no code changes between your live and test code.

Related

Torquebox stomplet session empty

I'm trying to implement user authentication for web sockets in Torquebox, and according to everything on the internet, I should be able to access the HTTP session from within a stomplet if I'm running the web app along side the stomp server, which I am.
My configuration looks something like this
web do
context '/'
host 'localhost'
end
stomp do
host 'localhost'
end
stomplet GlobalStomplet do
route '/live/socket'
end
I've tried also commenting out the web and stomp blocks but nothing changes.
Basically, the sockets are working, I can connect, and subscribe. In my stomplet, the on_subscribe method has a few debug lines
Rails.logger.debug "SESSION = #{subscriber.session}"
Rails.logger.debug "SESSION 2 = #{subscriber.getSession.getAttributeNames}"
Rails.logger.debug "SOCKET SESSION = #{TorqueBox::Session::ServletStore.load_session_data(subscriber.getSession)}"
And any other combination of these sort of things, but in every case I am given an empty session. The only exception, is when I explicitly load the session (as in the last debug line above) my session contains a session ID and something like TORQUEBOX_INITIAL_KEYS, but the session ID is not the HTTP session, and is simply something like session-1 and nothing useful.
I have an initialiser in the rails app setting up the torque box session store
MyApp::Application.config.session_store :torquebox_store, {
key: '_app_key'
}
I don't receive any exceptions from anything so I assume there are no obvious problems, but I've tried everything I can think of and still don't have a session that I can use.
What am I doing wrong?
I'm using Torquebox 3.1.0, Rails 4, and jRuby 1.7.11
Well, it seems I wasn't doing anything wrong per-se, but there seems to be an underlying bug in Torquebox (filing a bug report now)
It seems as though torque box web apps are quite happy with me assigning a custom key for the session store, and every works as expected. Unfortunately, it seems as though the stomplets are looking for the normal JSESSIONID only, and ignore the custom defined key.
To confirm, I remove the custom key, and it worked. I then reintroduced it, and again it stopped working. With the key still in place, I manually set the JSESSIONID cookie value, and reconnected and suddenly my session appeared.

Coldfusion 8 Submit Changes does not save Mail Server Settings in CF Administrator

I am currently running Coldfusion 8,0,1,195765 on a Windows 2003 SP 2 server over IIS 6.0.
I needed to change one of the Mail Server Settings in the ColdFusion Administrator, but when I clicked Submit Changes, the page appeared to refresh, and the field was reverted.
I made a change to another page to make sure that changes could be made, and sure enough, the change was applied.
There are no errors shown - everything looks normal, aside from the change.
I was able to make my changes programatically, using mail.cfc, and my change did appear in CF Admin.
My concern is that mail functions have been corrupted or compromised - my primary request for the stackoverflow gurus is how can I restore my Mail Server Settings functionality?
My secondary request is How could this have happened?
Thank you for reading my question.
I am having a similar problem with debugging.
Regarding your first question... You can access the administrator api programatically. Here's how you can verify connection and verify what the current settings are:
<cfscript>
/* you must log in first */
adminObj = createObject("component","cfide.adminapi.administrator"); // this assumes default installation
adminObj.login("password"); // enter your cf admin password
mailServerObj = createObject("component","cfide.adminapi.mail");
value = mailServerObj.getMailServers();
</cfscript>
<cfdump var="#value#">
Value is an array of your current mail server settings.
To make a change change the last part of your script to:
mailServerObj = createObject("component","cfide.adminapi.mail");
mailServerObj.setMailServers(
"yourMailServer",
portNumber,
username="yourUsername",
password="yourPassword",
priority="yourServerPriority");
value = mailServerObj.getMailServers();
The only required value is the entry for yourMailServer. Also, the optional value, portNumber, must be numeric.
Check out http://livedocs.adobe.com/coldfusion/8/htmldocs/help.html?content=basiconfig_37.html for the Adobe documentation for using the Administrator API.
You can also see a complete listing of the Administrator API CFC and their respective functions, check out http://www.cfexecute.com/admin-api-documentation/

Obtain the IP Address of a server

Here is the situation, we have a site that is hosted and updated by a third party vendor. I am providing links to additional resources that are hosted on our servers. A client will access the vendor site and click on a link to gain access to our additional resources. To validate that the request came from our third party vendor I need to get the IP address of the vendors server.
My question is, is there a way to get the IP address of the vendors servers using ColdFusion? I can't use the clients IP address, I need the vendor server address the client is using.
You have to work with 3rd party to accomplish this goal, this is for sure.
I can see at least two more or less working approaches here.
(1) Append some kind of protection token to the links. Your vendor generates encrypted string or hash including some information only you two know, so you can decrypt (or generate same hash) and validate it.
Example with hashing:
moment = DateConvert("local2utc", Now());
token = Hash("SecretSaultYouBothKnow" & DateFormat(moment, "yyyy-mm-dd") & TimeFormat(moment, "-HH-mm"));
This token is passed with link and expires quickly to prevent sharing/leaking.
You can generate and validate it on your side.
It's a raw idea and there could be possible problems with validation, plus avoiding invalid links for clients (maybe skip "mm" mask as well).
Encrypted/decrypted string would work similarly. You both just need to now the secret key.
By the way, your vendor could encrypt their server IP address or other identifier for you to check it against your database and maybe apply some other actions.
(2) Your vendor could set up simple web-service for you to validate the incoming links (it could respond with 0/1 or something else simple).
Exact implementation may be different. Again, it could be some token in URL which you send back for validation.
This is similar to solution which Jason suggested: vendor could send the server-to-server request to your server on link click and then relocate to the resource. But this may be complicated because you have to be sure 1st request is already handled when client arrives.
Hope these ideas make sense.
No, there isn't. Not if the request comes directly from the client. If the vendor sends some sort of a message first you can use that to validate. Or if the vendor's server is the one making the request on behalf of the client then you could use CGI.REMOTE_ADDR. But if the vendor is just providing a link to your site, then no, you cannot be assured of the IP of the vendor's server.
The closest you could come is to check the HTTP_REFERER, as Jeremy said above, but that can be spoofed (very easily), so it wouldn't be very secure.
To access the CGI variables available to ColdFusion, you can do something like this:
<cfset ThisIP = CGI.SERVER_NAME>
There are many useful CGI variables available here:
http://www.perlfect.com/articles/cgi_env.shtml
try placing a page on your server that uses the cfhttp tag to fetch:
http://www.dslreports.com/whois
That will give you the IP address of the web server.

How to pipe an email into Django?

I'm part of a two-man business selling LED glow toys and one aspect of this is handling support requests. I have a server running exim4 and DJango and have email working so that if a user sends an email to support#myhost.com I'm able to pick up the email and respond.
I'd like to develop something a bit tidier to keep track of the email chain for a particular support request.
To do this, I was thinking of piping the output of my email using a rule in my support email's filter:
pipe /usr/bin/email_to_django_script
What I'm unsure of is how best to go about the last step to actually turning the email content into something DJango can process.
What's the best method to do this? Would a script using curl -d be a sensible option or are there better / less convoluted ways?
You can pipe the output of the email server into a management command. As an example, I have a file /inquiries/management/commands/proc_email.py. I have a single Command class, and the handle() method gets most of the email from the environment, and the body of the email from STDIN:
from_email = strip_tags(os.environ.get('SENDER', None))
to_email = strip_tags(os.environ.get('RECIPIENT', None))
emailMessage = email.message_from_string(''.join(sys.stdin.readlines()))
There is other code in there, but that is how I get the important bits out of it. You can then pipe this into your ORM objects, and access it from the website at some later time.
This is then accessed through /path/to/project/manage.py proc_email.
Depending on your email server, you can also use plus addressing to insure replies come back to the same address. For example, I have my Reply-To headers set to inquiry+12345#whatever.com. The mail server (postfix) then dumps this into the environment under EXTENSION. If no number is supplied, I simply create a new Inquiry, instead of attaching to an existing one.
Not exactly a pure Django solution but I would recommend taking a look at Lamson Project. It's an email server written in Python that you can use to build email applications like what you are describing. I can also integrate with the Django ORM. http://lamsonproject.org/docs/hooking_into_django.html

CFMail with catchall email addresses

I can't believe I've never noticed this before, but it seems that CFMail won't send to an email address that isn't explicitly set up on the destination mailserver.
This means that if I'm using 'info#somedomainorother.com' and have that set up to catch all email on the domain, CFMail won't send to 'test#somedomainorother.com'.
This causes a massive amount of problems for me, as I'm using CFMail to send out order confirmations, member activations and all manner of other bits and pieces.
Whatever your views on using catchall addresses, it can't be denied that people do use them So, in any case that a user enters a made-up address into one of my sites, they won't receive their email.
There must, simply MUST be a way around this - can anyone help?
For refernece, the message that appears in the logs when sending to a catchall address is 'Invalid Addresses'.
EDIT: Here's the CFMail syntax I'm using -
<cfmail to="#Arguments.sEmailAddress#" from="#Application.sAppEmailAddress#" subject="Stock reminder confirmation: #Local.qGetProductDetails.sProductName# - #Application.sCompanyName#" type="HTML" server="#Application.sAppEmailServer#" username="#Application.sAppEmailAddress#" password="#Application.sAppEmailPassword#">
Translates into:
<cfmail to="thisisatest#somedomainorother.com" from="application#mydomainname.com" subject="Stock reminder confirmation: Some product - My Company" type="HTML" server="mail.mydomainname.com" username="application#mydomainname.com" password="XXXXXX">
All works fine for info#somedomainorother.com but not for randombunchofcharacters#somedomainorother.com.
Important to note of course, that the catch-all is working correctly in all other respects, test emails from mail clients work perfectly.
Its not ColdFusion that cares about email validity, its the SMTP server. CF only cares about well formed email addresses.
If you initiated a telnet session to your mail server and tried to use the same address, I'm sure it would have the same result.
Debugging tips for SMTP Connectivity:
http://www.talkingtree.com/blog/index.cfm/2004/11/22/debug-smtp
Can I see your CFMAIL tag setup? CFMAIL doesn't care as long as the email address is properly formatted.
Urgh!
Turns out it was an issue with the server. For some reason, catchall email accounts serverwide had stopped working properly. After an email to my hosting provider, it's all working fine with no code changes.
They're somewhat cagey as to what caused the issue, and I was still able to use an email client to send mail out to the addresses...
Thanks for the help in any case. ;)