SMTPSenderRefused when sending mail from GAE dev_appserver on gmail - google-app-engine

Here are my email related dev_appserver options:
--smtp_host=smtp.gmail.com --smtp_port=25 --smtp_user=me#mydomain.com --smtp_password="password"
Now, this still doesn't work and every time Google release a new dev_appserver I have to edit api/mail_stub.py to get things to work locally as per this S/O answer.
However, even this workaround has now stopped working. I get the following exception:
SMTPSenderRefused: (555, '5.5.2 Syntax error. mw9sm14633203wib.0 - gsmtp', <email.header.Header instance at 0x10c9c9248>)
Does anyone smarter than me know how to fix it?
UPDATE
I was able to get email to send on dev_appserver by using email addresses (eg. for sender and recipient) in their 'plain' format of a simple string (name#domain.com) rather than using the angle bracket style (Name <name#domain.com>). This is not a problem in production: recipients and sender email addresses can use angle brackets in the mail.send_mail call. I raised a ticket about this divergent behaviour between dev_appserver and production: https://code.google.com/p/googleappengine/issues/detail?id=10211&thanks=10211&ts=1383140754

Looks like it's because the 'sender' is now stored as a "email.header.Header" instance in the dev server instead of a string (since SDK 1.8.3 I think).
From my testing, when a 'From' string like "Name " is passed into smtplib.SMTP.sendmail, it parses the string to find the part within angle brackets, if any, to use as the SMTP sender, giving "". However, if this parameter is an "email.header.Header", then is just converts to string and uses it without further parsing, giving ">", thus causing the problem we're seeing.
Here's the patch I just posted on the issue tracker to google/appengine/api/mail_stub.py to convert this parameter back to a string (works for me):
--- google/appengine/api/mail_stub-orig.py 2014-12-12 20:04:53.612070031 +0000
+++ google/appengine/api/mail_stub.py 2014-12-12 20:05:07.532294605 +0000
## -215,7 +215,7 ##
tos = [mime_message[to] for to in ['To', 'Cc', 'Bcc'] if mime_message[to]]
- smtp.sendmail(mime_message['From'], tos, mime_message.as_string())
+ smtp.sendmail(str(mime_message['From']), tos, mime_message.as_string())
finally:
smtp.quit()

Another alternative is to patch the SMTP server that you use for testing the app engine mail functionality in your dev environment (instead of patching mail_stub.py).
For example, I'm using subethasmtp Wiser and was able to work around this issue by patching org.subethamail.smtp.util.EmailUtils.extractEmailAddress to accept nested angle brackets (details posted here).

Related

Thunderbird Lightning caldav sync doesn't show any data/events

when i try to synchronize my caldav server implementation with Thunderbird 45.4.0 and Lightning 4.7.4 (one particular calendar collection) it doesnt show any data or events in the calendar though the last call of the sequence provided the data.
In the Thunderbird error log i can see one error:
Zeitstempel: 07.11.16, 14:21:12
Fehler: [calCachedCalendar] replay action failed: null,
uri=http://127.0.0.1:8003/sap/sports/webdav/appsvc/webdav/services/
server.xsjs/cal/_D043133/, result=2147500037, op=[xpconnect wrapped
calIOperation]
Quelldatei:
file:///Users/d043133/Library/Thunderbird/Profiles/hfbvuk9f.default/
extensions/%7Be2fda1a4-762b-4020-b5ad-a41df1933103%7D/calendar-
js/calCachedCalendar.js
Zeile: 327
the call sequence is as follows (detailed content via gist-links):
Propfind Request - Response
Options Request - Response
Propfind Request - Response
Report Request - Response - Response Raw
The synchronization with other clients like macOS-calendar and ios-calendar works in principle and shows the data. Does anyone has a clue what is going wrong here?
Not sure whether that is the cause but I can see two incorrect things:
a) Your <href/> property has trailing spaces:
<d:href>/sap/sports/webdav/appsvc/webdav/services/server.xsjs/cal/_D043133/EVENT%3A070768ba5dd78ff15458f1985cdaabb1.ics
</d:href>
b) your ORGANIZER property is not a valid URI
ORGANIZER:_D043133
i was able to find the cause of the above issue by debugging Thunderbird as propsed by Philipp. The Report Response has http status code 200, but as it is a multistatus response Thunderbird/Lightning expects status code 207 ;-)
Thanks for the hints!

Difference between "drive.metadata.readonly" and "drive.readonly.metadata"

I want to ask what is the difference between DriveScopes.DRIVE_METADATA_READONLY and https://www.googleapis.com/auth/drive.readonly.metadata? In other words, what is the difference between
these two forms:
https://www.googleapis.com/auth/drive.metadata.readonly //DriveScopes.DRIVE_METADATA_READONLY
https://www.googleapis.com/auth/drive.readonly.metadata
When I was using service account for working with Drive API it takes me a long time to figure out, why my app was throwing unauthorized exception:
Uncaught exception from servlet
com.google.api.client.auth.oauth2.TokenResponseException: 403
{
"error" : "access_denied",
"error_description" : "Requested client not authorized."
}
The String constant DriveScopes.DRIVE_METADATA_READONLY was causing the exception. In which context should I use this constant?
That's clearly a mistake in the Java API client.
The API documentation states that the correct scope is :
https://www.googleapis.com/auth/drive.readonly.metadata
Whereas when you look at the latest javadoc (at the time of this answer), you get :
https://www.googleapis.com/auth/drive.metadata.readonly
You should ignore the DriveScopes constant and create your own constant, while the Google Drive team fixes this.

Is there a list of applicationError codes & descriptions for the Google AppEngine ApplicationException?

Hello everyone and thanks up front for your time,
I am working on a java-based GAE web application and now and then I get ApiProxy.ApplicationExceptions.
In the current case they appear randomly and come with the applicationError 108 when I open a write channel to a blob using the (yes I know, still experimental) FileStore API. Although the API is still in an experimental state, I'd like to handle the thrown exception correctly. Thus my question:
Where can I find a list of possible application errors including their descriptions?
As of right now it is not possible for me to figure out where the problem resides since the thrown exception does not contain something like a message, hint or reason phrase but only the error ID 108:
Caused by: com.google.apphosting.api.ApiProxy$ApplicationException: ApplicationError: 108:
at java.lang.Thread.getStackTrace(Thread.java:1495)
at com.google.apphosting.runtime.ApiProxyImpl.doSyncCall(ApiProxyImpl.java:240)
at com.google.apphosting.runtime.ApiProxyImpl.access$000(ApiProxyImpl.java:66)
at com.google.apphosting.runtime.ApiProxyImpl$1.run(ApiProxyImpl.java:183)
at com.google.apphosting.runtime.ApiProxyImpl$1.run(ApiProxyImpl.java:180)
at java.security.AccessController.doPrivileged(Native Method)
at com.google.apphosting.runtime.ApiProxyImpl.makeSyncCall(ApiProxyImpl.java:180)
at com.google.apphosting.runtime.ApiProxyImpl.makeSyncCall(ApiProxyImpl.java:66)
at com.googlecode.objectify.cache.TriggerFutureHook.makeSyncCall(TriggerFutureHook.java:154)
at com.google.apphosting.api.ApiProxy.makeSyncCall(ApiProxy.java:107)
at com.google.apphosting.api.ApiProxy.makeSyncCall(ApiProxy.java:56)
at com.google.appengine.api.files.FileServiceImpl.makeSyncCall(FileServiceImpl.java:584)
... 65 more
Also, the corresponding javadoc is quite conservative with giving information: https://developers.google.com/appengine/docs/java/javadoc/com/google/apphosting/api/ApiProxy.ApplicationException
Currently I bluntly cancel these requests with a 500, but since I am not sure what has happened I should probably do something else/more.
Thanksalot!
the best information I could get is from the Python source code :
http://code.google.com/p/googleappengine/source/browse/trunk/python/google/appengine/api/files/file_service_pb.py

How to understand log files downloaded from App Engine?

What is the format of Google App Engine log files, as downloaded by appcfg.sh request_logs?
As far as I've been able to determine, the format of the log file is as follows:
CLIENT_IP_ADDRESS - USERNAME [DATE:TIME TIMEZONE] "METHOD URL HTTP/VERSION" RESPONSE_CODE ??? URL USER_AGENT
LOG_LEVEL:TIMESTAMP MESSAGE
:
LOG_LEVEL:TIMESTAMP MESSAGE
:
LOG_LEVEL:TIMESTAMP MESSAGE
:
Each of the indented lines is associated with the non-indented line above it - that's how you determine which request each of them relates to, I think. The solitary colons are used to separate one log message from the next.
The non-indented lines are in reverse chronological order, but the groups of indented lines below them are in chronological order.
A strange client IP address like 0.1.0.2 indicates a within-App-Engine post from your app to your app's task queue. Actually, though, you can also see that it is within-App-Engine by looking at the user agent for that request.

Authentication fails in databasedotcom

I am trying to adopt databasedotcom gem, but couldn't get beyond the authentication. Here is what I did (after installing databasedotcom gem):
rails c (or irb then require 'databasedotcom')
client=Databasedotcom::Client.new :client_id => 'foo', :client_secret=>'bar'
client.ca_file = '/Users/tjiang/missioncontrol/tmp/ca-bundle.crt'
client.verify_mode = OpenSSL::SSL::VERIFY_PEER
client.authenticate :username=>'myusername', :password=>'mypassword'
All credentials are copy-and-pasted in the process so no mistake there; the certificate was downloaded here: http://certifie.com/ca-bundle/ca-bundle.crt.txt
I tried Ruby 187 and 193 as well as inside and outside Rails, repeatedly, but always got this error message:
Databasedotcom::SalesForceError: authentication failure from /Library/Ruby/Gems/1.8/gems/databasedotcom-1.3.0/lib/databasedotcom/client.rb:112:in `authenticate'
I wonder what I have missed here? Particularly, I am concerned about the Callback URL I used when creating a Remote Access in Salesforce (I tried 'oob', 'http://localhost:3000', and 'https://www.salesforce.com', but none made any difference).
It turns out this is due to a bug in databasedotcom. When you use username and password to authenticate, it puts them into an url query string WITHOUT encoding and POST a request with that url. As a result, the plus sign in my username will be interpreted as a blank space.
Solution: CGI::escape() both your username and password.

Resources