Cannot GET Google Realtime API resource - google-drive-realtime-api

I'm playing with the Google Drive API. I've managed to authenticate successfully and retrieve file listings and other things, but my goal is to write an alternative (if limited) editor for documents held in Google Drive. Unfortunately the downloadUrl referred to in the docs (https://developers.google.com/drive/v2/reference/files) does not exist, only exportLinks. It seems in order to deal with the native formatting of documents in Google Drive, it's necessary to use the realtime API.
Very well, I tried to retrieve the undocumented (but hinted at) realtime resource hinted at by the documentation, found at: https://www.googleapis.com/drive/v2/files/FILEID/realtime -
HTTP/1.1 400 Bad Request
Content-Type: application/json; charset=UTF-8
Date: Tue, 05 Aug 2014 03:02:51 GMT
Expires: Tue, 05 Aug 2014 03:02:51 GMT
Cache-Control: private, max-age=0
X-Content-Type-Options: nosniff
X-Frame-Options: SAMEORIGIN
X-XSS-Protection: 1; mode=block
Server: GSE
Alternate-Protocol: 443:quic
Transfer-Encoding: chunked
{
"error": {
"errors": [
{
"domain": "global",
"reason": "lockedDomainCreationFailure",
"message": "The OAuth token was received in the query string, which this API forbids for response formats other than JSON or XML. If possible, try sending the OAuth token in the Authorization header instead."
}
],
"code": 400,
"message": "The OAuth token was received in the query string, which this API forbids for response formats other than JSON or XML. If possible, try sending the OAuth token in the Authorization header instead."
}
}
An odd error message. Authenticating with a header instead of an access_token parameter doesn't make it work. I used the API explorer found for the realtime resource (https://developers.google.com/drive/v2/reference/realtime/get) and it didn't work either. It gives the following message when used with the same file:
400 Bad Request
- Hide headers -
cache-control: private, max-age=0
content-encoding: gzip
content-length: 123
content-type: application/json; charset=UTF-8
date: Tue, 05 Aug 2014 03:14:42 GMT
expires: Tue, 05 Aug 2014 03:14:42 GMT
server: GSE
{
"error": {
"errors": [
{
"domain": "global",
"reason": "invalid",
"message": "Invalid Value"
}
],
"code": 400,
"message": "Invalid Value"
}
}
I know the file is fine because the rest of the API calls I've made against it have worked (exploring the comments functionality and other things). It's frustrating issue I've run against, but hopefully someone can help. I would like to be able to edit collaborative documents outside of the canonical browser based editor in a non-destructive way!
Small update:
GET https://www.googleapis.com/drive/v2/files/1s8NArXPG0CWRHaA9HQ-zND086Uh5CoUFC2p3b3NI3Ek/realtime?key={YOUR_API_KEY}
Is the URL the API explorer (found here https://developers.google.com/drive/v2/reference/realtime/get) shows itself using to get the 400 error message above. As it turns out, I'd only set up an OAuth2 client ID - a "Simple API Key" is needed for the realtime API. A server side API key will not work either - it must be an API key for an Android application, iOS application or a browser based application. This is horrendously inconvenient because I'm not interested in browser based anything, but maybe there's some way to write a small hosted shim to make my dreams come true. Why must you do this, Google??!?

You cannot use the realtime API to access existing documents. It is for creating your own custom data, collaborative data models.

Related

http-only cookie not being set on React client in Azure

I've seen several similar issues reported on here, but none of the solutions or specific setups seem to be quite matching mine.
I have a React client that is calling a backend Framework Web API via apollo, which is setting an http only cookie that I am expecting to be sent back in all subsequent requests. The backend service is configured to accept the client domain as CORS origin and locally as well as when deployed to a test server this is all working fine.
I have now deployed both the client and back end service to separate Azure App Services and the cookie 'appears' to not be getting set on the client.
In the initial response headers I can see the cookie being set in set-cookie, but it is not then included in subsequent requests and does not appear in the applications tab in chrome tools.
My Apollo calls are specifying withCredentials: true
Any idea what the reason for this may be?
Edit.
The response headers coming back from the initial API request are:
Access-Control-Allow-Credentials: true
Access-Control-Allow-Origin: https://my-app-service.azurewebsites.net
Cache-Control: no-cache
Content-Encoding: gzip
Content-Length: 256
Content-Type: application/json; charset=utf-8
Date: Fri, 29 Oct 2021 12:04:27 GMT
Expires: -1
Pragma: no-cache
Server: Microsoft-IIS/10.0
Set-Cookie: {Cookie-Name}={JWT-Token}; expires=Fri, 29-Oct-2021 12:24:27
GMT; path=/; HttpOnly
Vary: Accept-Encoding
X-AspNet-Version: 4.0.30319
X-Powered-By: ASP.NET

How to extend urllib3 connection creation to add additional authentication step?

I would like to create a connection pool to a https endpoint where an addition step is performed after creating each https connection in the pool. The step is to make a https call like so:
POST /_session HTTP/1.1
Content-Length: 32
Content-Type: application/x-www-form-urlencoded
Accept: */*
name=YourUserName&password=YourPassword
If successful, in response a cookie is returned, e.g:
200 OK
Cache-Control: must-revalidate
Content-Length: 42
Content-Type: text/plain; charset=UTF-8
Date: Mon, 04 Mar 2013 14:06:11 GMT
server: CouchDB/1.0.2 (Erlang OTP/R14B)
Set-Cookie: AuthSession="a2ltc3RlYmVsOjUxMzRBQTUzOtiY2_IDUIdsTJEVNEjObAbyhrgz"; Expires=Tue, 05 Mar 2013 14:06:11 GMT; Max-Age=86400; Path=/; HttpOnly; Version=1
x-couch-request-id: a638431d
Where would this extra step go? For example, maybe I should extend the _new_conn method?
class CustomHTTPSConnectionPool(HTTPSConnectionPool):
def _new_conn(self):
conn = super(CustomHTTPSConnectionPool, self)._new_conn()
... call '/_session' and save cookie
return conn
Another consideration is that the cookie will expire and should be renewed, ideally before the expiration. I'm just noting it here, that should probably be the subject of a separate question.
(As discussed in the comments)
If you're trying to create your own CustomHTTPSConnectionPool, you're on the right track.
But reading the docs you linked, I don't think you need this? It seems the state is maintained in the cookie rather than the connection, so you just need to do the handshake, get a cookie, and make sure you pass the cookie with each request and you're good to go regardless of connections.

How to send an email on behalf of a Google Group with the GMail API

We would like our application to send emails with a google group email in the FROM header.
This is possible in the GMail interface, assuming that the Google Group is correctly configured.
But when we try with the GMail API here's the error we got :
403 Forbidden
cache-control: private, max-age=0
content-encoding: gzip
content-length: 175
content-type: application/json; charset=UTF-8
date: Thu, 04 Sep 2014 11:05:36 GMT
expires: Thu, 04 Sep 2014 11:05:36 GMT
server: GSE
{
"error": {
"errors": [
{
"domain": "global",
"reason": "forbidden",
"message": "XXX.XXXX#XXXXX.XXX does not have privileges to XXX.XXXX#XXXXX.XXX mailbox."
}
],
"code": 403,
"message": "XXX.XXXX#XXXXX.XXX does not have privileges to XXX.XXXX#XXXXX.XXX mailbox."
}
}
Is there a way to circumvent this, either with the GMail API or with App Engine's mail features ?
You need to add the group as an owner to the project.
Don't try to put the group in the URL, just use "me", the authenticated user as normal. If that user really does have the group configured as a valid From address in the gmail web interface (they have to have completed a verification flow to confirm they own the address by clicking on a link--they can send emails "From" that group using the web interface) then you should simply be able to send an email with the "From" header being that group and it will be accepted.

Google Cloud Storage access denied and MapReduce. Cannot add Service Account into developers list

I'm running a MapReduce job on Google App Engine with a configuration similar to this:
MapReduceSettings.Builder()
.setBucketName("my-bucket")
.setWorkerQueueName(QUEUE_NAME)
.setModule(MODULE)
.build();
The bucket is used for temporary data by App Engine itself.
The problem is that when I run the job, it fails with the following stacktrace:
com.sun.jersey.spi.container.ContainerResponse mapMappableContainerException: The RuntimeException could not be mapped to a response, re-throwing to the HTTP container
java.lang.RuntimeException: Writeable Bucket 'my-bucket' test failed. See http://developers.google.com/appengine/docs/java/googlecloudstorageclient/activate for more information on how to setup Google Cloude storage.
at com.google.appengine.tools.mapreduce.MapReduceSettings.verifyAndSetBucketName(MapReduceSettings.java:134)
at com.google.appengine.tools.mapreduce.MapReduceSettings.<init>(MapReduceSettings.java:89)
at com.google.appengine.tools.mapreduce.MapReduceSettings.<init>(MapReduceSettings.java:31)
at com.google.appengine.tools.mapreduce.MapReduceSettings$Builder.build(MapReduceSettings.java:83)
at
...
...
Caused by: com.google.appengine.tools.cloudstorage.NonRetriableException: java.lang.RuntimeException: Server replied with 403, verify ACLs are set correctly on the object and bucket: Request: DELETE https://storage.googleapis.com/my-bucket/2f249469-c77a-4540-bbbd-45fcd27d7600.tmp
User-Agent: App Engine GCS Client
no content
Response: 403 with 111 bytes of content
Content-Type: application/xml; charset=UTF-8
Content-Length: 111
Vary: Origin
Date: Tue, 12 Aug 2014 18:20:20 GMT
Expires: Tue, 12 Aug 2014 18:20:20 GMT
Cache-Control: private, max-age=0
Server: UploadServer ("Built on Jul 31 2014 18:25:34 (1406856334)")
Alternate-Protocol: 443:quic
X-Google-Cache-Control: remote-fetch
Via: HTTP/1.1 GWA
<?xml version='1.0' encoding='UTF-8'?><Error><Code>AccessDenied</Code><Message>Access denied.</Message></Error>
I already tried to add the Service Account Name (name-of-my-app#appspot.gserviceaccount.com) as a team member but beside the user it keeps saying
Invitation sent. Waiting for response.
How can I add the Service Account into the developers list so I can give it access to my bucket?
Thanks
I solved it using the gsutils command line tool:
gsutil acl ch -u name-of-my-app#appspot.gserviceaccount.com:WRITE gs://my-bucket
According to Google Storage documentation, sometimes it's not possible to add the service account into the developers list, even if they don't say why
Note: In some circumstances, you might not be able to add the service account as a team member. If you cannot add the service account, use the alternative method, bucket ACLs, as described next.

XmlHttp: How to get the actual statusText from an msxml.xmlhttp object?

A web-server is returning a status code and description in response to a request by an XmlHttp component. The actual status response from the server begins with:
HTTP/1.1 400 Not a valid http POST request
which i can see in though a Fiddler trace:
But when i ask the xmlHttp request for the status and statusText, it shows me the "standard" description for the status text, rather than the actual status text:
xmlHttp.status: 200
xmlHttp.statusText: "Bad Request"
which i can see in in the development IDE:
i've poked around all the other properties of IXMLHttpRequest, and i can't find any that contain the response's actual status text. It's not even in any of the response headers:
Server: ASP.NET Development Server/8.0.0.0
Date: Thu, 28 Jan 2010 21:03:16 GMT
X-AspNet-Version: 2.0.50727
X-LSI-Proxy-Identificaton: {65B76AB2-8A28-4A2B-B282-7E1FDC9DBCA1}
Cache-Control: no-cache
Pragma: no-cache
Content-Type: text/xml; charset=utf-8
Content-Length: 4652
Connection: Close
Internet Explorer, Chrome, and FireFox manage to read the actual status text:
How can i get the actual statusText from a Microsoft xmlHttp object?
Unfortunately code 400 is defined as Bad Request as part of the HTTP/1.1 RFC and XMLHTTP (well more likely URLMON or WinHTTP) is just transforming the number and ignoring the passed status text. As the status line is part of the protocol and not a response header then it makes sense it isn't defined in the list of response headers.
However I would contend that the browsers are only showing the status text "correctly" because they are displaying the custom HTML page which got sent along with it which has that text as the TITLE in the HEAD element.

Resources