Google TaskQueue JSON API - Can not oauth - 403 Forbidden - google-api

I am attempting to use the Google JSON API - taskqueue/v1beta2
https://developers.google.com/apis-explorer/#p/taskqueue/v1beta2/taskqueue.tasks.list
I am not able to successfully authenticate for this service using the API explorer. I can use other JSON APIs like the storage API under the same project & account. When I go the the APIs tab in the developer console there is nothing listed for "TaskQueue" or "TaskQueue JSON API".
Edit: The oauth flow seems to work correctly, with scopes:
https://www.googleapis.com/auth/taskqueue
https://www.googleapis.com/auth/taskqueue.consumer
No matter what I do I get a 403 Forbidden response. How can I authorize my account to use the TaskQueue API? Here is my response from the API explorer:
403 Forbidden
cache-control: private, max-age=0
content-encoding: gzip
content-length: 146
content-type: application/json; charset=UTF-8
date: Mon, 19 Jan 2015 17:20:50 GMT
expires: Mon, 19 Jan 2015 17:20:50 GMT
server: GSE
vary: Origin, X-Origin
{
"error": {
"errors": [
{
"domain": "global",
"reason": "forbidden",
"message": "you are not allowed to make this api call"
}
],
"code": 403,
"message": "you are not allowed to make this api call"
}
}

The REST API only works for pull queues, and you need to also specify the email address of the user you are authorizing as in your queue.yaml. From the docs:
queue:
- name: pull-queue
mode: pull
acl:
- user_email: bar#foo.com # can list, get, lease, delete, and update tasks
- writer_email: user#gmail.com # can insert tasks
- writer_email: bar#foo.com # can insert tasks, in addition to rights granted by being a user_email above
Defining pull queues
https://cloud.google.com/appengine/docs/python/config/queue#Python_Defining_pull_queues

Related

How to fix Access Denied / 503 from AWS lambda in serverless-next.js deployment

I am deploying a Next.js app using serverless component (serverless-next.js, not the plugin). After deploying, my API routes run smoothly, but some (not all) pages and all content in /public folder are not accessible.
On the web, requests to those resources end with a 503:
content-length: 1019
content-type: text/html
date: Tue, 27 Oct 2020 19:55:05 GMT
server: CloudFront
status: 503
via: 1.1 79ba346413d83ce62db11c8d0b05c22d.cloudfront.net (CloudFront)
x-amz-cf-id: RalFtcB6W4pm1_eTgzr0Y9LWCR-uwfqgW2alSgX_X72YVlUxlEkrKw==
x-amz-cf-pop: PRG50-C1
x-cache: LambdaExecutionError from cloudfront
I tracked down the error to Default Lambda#Edge for Next CloudFront distribution where I can see a record for every call in CloudWatch logs:
{
"errorType": "AccessDenied",
"errorMessage": "Access Denied",
"Code": "AccessDenied",
"RequestId": "75B8CCC0B1F960A7",
"HostId": "92cygvWjn3xLwT0PChJPc56ExzUFBDFTHyjLXQ/BWbT7pCVMb3I2ww15+Gzs2fSuXjHEPSfUIdg=",
"name": "AccessDenied",
"$fault": "client",
"$metadata": {
"httpStatusCode": 403,
"httpHeaders": {
"x-amz-request-id": "75B8CCC0B1F960A7",
"x-amz-id-2": "92cygvWjn3xLwT0PChJPc56ExzUFBDFTHyjLXQ/BWbT7pCVMb3I2ww15+Gzs2fSuXjHEPSfUIdg=",
"content-type": "application/xml",
"transfer-encoding": "chunked",
"date": "Tue, 27 Oct 2020 19:54:59 GMT",
"server": "AmazonS3"
},
"attempts": 1,
"totalRetryDelay": 0
},
"stack": [
"AccessDenied: Access Denied",
" at deserializeAws_restXmlGetObjectCommandError (/var/task/index.js:14166:41)",
" at processTicksAndRejections (internal/process/task_queues.js:97:5)"
]
}
I checked the origin S3 bucket and all resources are there. I tried to remove complete deployment and do a clean deploy to no avail. As I understand the problem lies in S3 permissions, I granted the policy under which the lambda is invoked full access to S3 but the problem persists.
Any help how to debug this further appreciated.

ElasticSearch is unable to recognize Context-Type header with encoding defined

I've spent some time trying to fix the elastic search bulk upload warning:
Content type detection for rest requests is deprecated. Specify the content type using the [Content-Type] header
My request is below:
POST http://elasticserver/_bulk HTTP/1.1
Authorization: xxx
Content-Type: application/x-ndjson; charset=utf-8
Host: elasticserver
Content-Length: 8559
... new line delimited json content ...
And my valid response with 200 status is below:
HTTP/1.1 200 OK
Warning: 299 Elasticsearch-5.5.1-19c13d0 "Content type detection for rest requests is deprecated. Specify the content type using the [Content-Type] header." "Mon, 14 Aug 2017 00:46:21 GMT"
content-type: application/json; charset=UTF-8
content-length: 4183
{"took":5538,"errors":false,...}
By experimenting I discovered that the issue is in content type charset definition Content-Type: application/x-ndjson; charset=utf-8 and if I change it to Content-Type: application/x-ndjson I get no warning.
Is it an elastic search issue or I'm forming the request incorrectly?
The official documentation explicitly states that
When sending requests to this endpoint the Content-Type header should be set to application/x-ndjson.
The RestController source code also shows that they are ignoring the charset:
final String lowercaseMediaType = restRequest.header("Content-Type").toLowerCase(Locale.ROOT);
// we also support newline delimited JSON: http://specs.okfnlabs.org/ndjson/
if (lowercaseMediaType.equals("application/x-ndjson")) {
restRequest.setXContentType(XContentType.JSON);
return true;
}

Wiping all my Google Play achievements in the OAuth2 Playground doesn't wipe my achievements

If I go and unlock an achievement in game, and then run a reset, after running through the OAuth process for my user, posting to https://www.googleapis.com/games/v1management/achievements/reset, I receive a correct response,
{
"kind": "gamesManagement#achievementResetAllResponse",
"results": [
{
"definitionId": "CgkIh9rSofwUEAIQAQ",
"kind": "gamesManagement#achievementResetResponse",
"updateOccurred": true,
"currentState": "REVEALED"
}
]
}
If I post to https://www.googleapis.com/games/v1management/achievements/reset again, again I get a successful empty list response, as is expected,
{
"kind": "gamesManagement#achievementResetAllResponse",
"results": []
}
But when I go back into the game, check my achievements, it still shows that I have that achievement. No matter if I log out, log in, restart the app, makes no difference, I still have that achievement,
Even if I post the full reset, https://www.googleapis.com/games/v1management/achievements/resetAllForAllPlayers, I get the successful, no body response,
HTTP/1.1 204 No Content
Expires: Fri, 01 Jan 1990 00:00:00 GMT
Vary: Origin,X-Origin
Server: GSE
Etag: "aHcpPO1q3J7BuZyftdPIkrurI0I/vyGp6PvFo4RvsFtPoIWeCReyIC8"
Pragma: no-cache
Cache-control: no-cache, no-store, max-age=0, must-revalidate
Date: Tue, 06 Oct 2015 15:14:31 GMT

Filtering with Quickbooks Online V2 returns 401 ErrorCode=003200, Empty body posts work perfectly

We're attempting to integrate with the QuickBooks Online V2 api using Ruby 1.9.3 (not RoR).
Using the API Explorer and the Employee endpoint documentation we were able to get a simple list of test employees by using the Google Signet OAuth Gem.
require 'signet'
require 'signet/oauth_1/client'
#intialize oauth1 client
#client = Signet::OAuth1::Client.new(
:temporary_credential_uri => "https://oauth.intuit.com/oauth/v1/get_request_token",
:authorization_uri => "https://appcenter.intuit.com/Connect/Begin",
:token_credential_uri => "https://oauth.intuit.com/oauth/v1/get_access_token",
:client_credential_key => 'qyprdPEfJqU7eOze0Fby9iYhrUS5DQ',
:client_credential_secret => 'fuXsasJo4TrTEd3Yhv4TeMUizmtguh0JioIB5r2I',
:callback => "http://localhost:3000/callback/general"
)
#client.token_credential_key = 'qyprdJUtDSk7owxVfZlq7JeWO1mtpHBkSMD5GhB02PwIC6N0'
#client.token_credential_secret = 'Rq2ekgQWWL9frZAKpcgWef291mR0J5HBE354u5F3'
#setup request
original_request = [
'POST',
'https://qbo.sbfinance.intuit.com/resource/employees/v2/791630875',
# we also tried this url 'https://qbo.intuit.com/qbo28/resource/employees/v2/791630875',
[
['Content-Type', 'application/x-www-form-urlencoded'],
],
[]
]
#execute request
response = #client.fetch_protected_resource(:request => original_request)
puts response.body
As you can see the request is pretty straight-forward.
However once we create a request with a Filter in the body, we get an HTML page with the following error: HTTP Status 401 - message=Exception authenticating OAuth; errorCode=003200; statusCode=401
#setup request
original_request = [
'POST',
'https://qbo.intuit.com/qbo28/resource/employees/v2/791630875',
#'https://qbo.sbfinance.intuit.com/resource/employees/v2/791630875',
[
['Content-Type', 'application/x-www-form-urlencoded'],
],
["Filter=Name :EQUALS: Doe"]
]
We're using the Google OAuth gem, and I've verified the signature generation to be correct using these tools: LinkedIn Oauth Test Console and Beginners guide to OAuth signing requests. They both verify that the signature that Signet is generating is correct for the body I provide.
I've looked at a few SO Questions:
QuickBooks Online querying with filter returns 401 everytime
Unable to create(POST) objects (Account, customer...) on QB Windows using IDS and Sync Manager
But nothing has worked. Any help would be appreciated, we're willing to use a third party gem such as quickeebooks but we would rather not. I assume I'm just missing something simple here.
Please provide me with the following items so I can verify a working answer:
Your request parameters, including uri, header, body and exact client and access tokens (developer app tokens only please, I'll need to verify that I can generate the exact same request, including signature)
You basestring used for generating the HMAC-SHA1 signature. it will look something like
POST&https%3A%2F%2Fqbo.intuit.com%2Fqbo28%2Fresource%2Femployees%2Fv2%2F7916308‌​75&Filter%3DName%2520%253AEQUALS%253A%2520David%2520Test%26oauth_consumer_key%3Dq‌​yprdPEfJqU7eOze0Fby9iYhrUS5DQ%26oauth_nonce%3D-1787433535548338293%26oauth_signat‌​ure_method%3DHMAC-SHA1%26oauth_timestamp%3D1380089100%26oauth_token%3DqyprdJUtDSk‌​7owxVfZlq7JeWO1mtpHBkSMD5GhB02PwIC6N0%26oauth_version%3D1.0
Your response, including header and body data
I had tried to use filter query with employee endpoint. It works fine.
EDIT - Sharing endpoint, filter and resultset related to Employee API Endpoint
https://qbo.intuit.com/qbo28/resource/employees/v2/791926875
Filter= Name :EQUALS: Manas Mukherjee
header - "Authorization: OAuth oauth_token="2eRrd7LhEtHrM1CrqWvy1kmSgeukEgFxW99E1xwhSsLCp1JB", oauth_consumer_key="qyprdXsaKh0a132eNs7NTJLufjfrzm", oauth_version="1.0", oauth_signature_method="HMAC-SHA1", oauth_timestamp="1380084612", oauth_nonce="1556081845430558974", oauth_signature="IMjh%2FTx%2F7GMFDE6WQqZK8b6apjI%3D"[\r][\n]"
Content-Type: application/x-www-form-urlencoded
Data Set
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<qbo:SearchResults xmlns="http://www.intuit.com/sb/cdm/v2" xmlns:qbp="http://www.intuit.com/sb/cdm/qbopayroll/v1" xmlns:qbo="http://www.intuit.com/sb/cdm/qbo">
<qbo:CdmCollections xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="Employees">
<Employee>
<Id idDomain="QBO">20</Id>
<SyncToken>0</SyncToken>
<MetaData>
<CreateTime>2013-09-24T21:37:22-07:00</CreateTime>
<LastUpdatedTime>2013-09-24T21:37:22-07:00</LastUpdatedTime>
</MetaData>
<Name>Manas Mukherjee</Name>
<Address>
<Line1>ABC Str</Line1>
<City>London</City>
<PostalCode>4353543</PostalCode>
<GeoCode>LAT=51.5148382,LNG=-0.1264144</GeoCode>
</Address>
<GivenName>Manas</GivenName>
<MiddleName>Kr</MiddleName>
<FamilyName>Mukherjee</FamilyName>
<ShowAs>Manas Kr Mukherjee</ShowAs>
<BillableTime>false</BillableTime>
</Employee>
</qbo:CdmCollections>
<qbo:Count>1</qbo:Count>
<qbo:CurrentPage>1</qbo:CurrentPage>
</qbo:SearchResults>
OAuth header using your tokens
"Authorization: OAuth oauth_token="qyprdJUtDSk7owxVfZlq7JeWO1mtpHBkSMD5GhB02PwIC6N0", oauth_consumer_key="qyprdPEfJqU7eOze0Fby9iYhrUS5DQ", oauth_version="1.0", oauth_signature_method="HMAC-SHA1", oauth_timestamp="1380089100", oauth_nonce="-1787433535548338293", oauth_signature="Vj67xMVhSKGjVSmGyOxt7SVv0i8%3D"[\r][\n]"
Endpoint - https://qbo.intuit.com/qbo28/resource/employees/v2/791630875
Post data to end point: Filter= Name :EQUALS: David Test
Content-Type: application/x-www-form-urlencoded
It works fine
Thanks
See this sample fiddler request with Filter for items in QBO. I cannot paste the fiddler log here. You can do it for similarly for Employee. The filters should go into the body and encode your header:
Request-
POST https://qbo.intuit.com/qbo1/resource/items/v2/723488155
HTTP/1.1
Content-Type: application/x-www-form-urlencoded
Authorization: OAuth oauth_token="lvprdgF9q4mSQx5A6lKNm3NISXvwIpF16z",oauth_nonce="3740352e-20a4-4d45-af4f-2b783ee20e60",oauth_consumer_key="qyprd7I5WvVnPoiBh1ejZn",oauth_signature_method="HMAC-SHA1",oauth_timestamp="1377106651",oauth_version="1.0",oauth_signature="1OAJXk5uH0sEpYpdhh%2BDMzjQFEs%3D"
Host: qbo.intuit.com
Content-Length: 28
Expect: 100-continue
PageNum=1&ResultsPerPage=100
Response Header-
HTTP/1.1 200 OK
Date: Wed, 21 Aug 2013 17:37:31 GMT
Server: Apache
Set-Cookie: qboeuid=10.129.32.5.1377106651774076; path=/; expires=Thu, 21-Aug-14 17:37:31 GMT; domain=.intuit.com
Set-Cookie: JSESSIONID=82DE11473B5246497B9FDCD8A6DA4C45.c1-pprdqboas30j; Path=/; Secure; HttpOnly
Vary: Accept-Encoding
Content-Type: application/xml;charset=UTF-8
Content-Length: 32525

Access Google Directory API from a Marketplace App using 2lo

I've spent the past couple of days trying to access Google's Directory API in Ruby but haven't been able to get it working. According to this document the Directory API can be authorized using 2lo:
If your application has certain unusual authorization requirements, such as logging in at the same time as requesting data access (hybrid) or domain-wide delegation of authority (2LO), then you cannot currently use OAuth 2.0 tokens. In such cases, you must instead use OAuth 1.0 tokens and an API key. You can find your application's API key in the Google APIs Console, in the Simple API Access section of the API Access pane.
I currently have working code that can access the Provisioning API using 2lo. From the documentation it sounds that I can use this same code to access the Directory API by just adding an API access key parameter to the request and enabling a few permissions. However, it's not working and I have no idea why.
Here is the request code:
def self.get_user2(email)
#client = Google::APIClient.new(:authorization => :two_legged_oauth_1)
#client.authorization.client_credential_key = GOOGLE_APP_KEY
#client.authorization.client_credential_secret = GOOGLE_APP_SECRET
#directory = #client.discovered_api('admin', 'directory_v1')
result = #client.execute(
#directory.users.get,
'userKey' => email,
:key => GOOGLE_API_KEY
)
JSON.parse(result.body)
end
This gets me the response:
{
"error": {
"errors": [
{
"domain": "global",
"reason": "authError",
"message": "Invalid Credentials",
"locationType": "header",
"location": "Authorization"
}
],
"code": 401,
"message": "Invalid Credentials"
}
}
I've added the required scope to my manifest file,
<Scope id="usersAPI">
<Url>https://www.googleapis.com/auth/admin.directory.user.readonly</Url>
<Reason>See all users in your company.</Reason>
</Scope>
and also enabled the Admin SDK for my project in the API console.
Here is the log output after adding Faraday.default_connection.response :logger to my development.rb file:
get https://www.googleapis.com/admin/directory/v1/users/brian#crushing.mygbiz.com?key=AIzaSyAHYBWlC_qiihRtTKTZleZlAw2ts8Q1WO8
User-Agent: "google-api-ruby-client/0.6.4 Mac OS X/10.8.4"
Authorization: "OAuth oauth_consumer_key=\"76548528623.apps.googleusercontent.com\", oauth_signature_method=\"HMAC-SHA1\", oauth_timestamp=\"1375899810\", oauth_nonce=\"de4d976eed6883a06b3f6084e3dd0db4\", oauth_version=\"1.0\", oauth_signature=\"3D7aqhBeaCYOYyaF8bWpaM9MA8U%3D\""
Cache-Control: "no-store"
Content-Type: "application/x-www-form-urlencoded"
401
www-authenticate: "AuthSub realm=\"https://www.google.com/accounts/AuthSubRequest\""
content-type: "application/json; charset=UTF-8"
date: "Wed, 07 Aug 2013 18:23:30 GMT"
expires: "Wed, 07 Aug 2013 18:23:30 GMT"
cache-control: "private, max-age=0"
x-content-type-options: "nosniff"
x-frame-options: "SAMEORIGIN"
x-xss-protection: "1; mode=block"
server: "GSE"
connection: "close"
After searching the internet for the past day I am out of ideas for why this isn't working. Ideas anyone?
It turns out I was missing the 'xoauth_requestor_id' field. Thanks to sqrrrl for answering my question on github

Resources