Podio API returning "unauthorized" response 401 - podio

I'm working on Podio API and as of now access API endpoints with the Python's (3.10.2) requests:
import requests as rq
def podio_api(url, payload=None, get=True):
"""Generic function to return responses from API,
it works with both GET and POST requests"""
url = "https://api.podio.com/" + url
headers = {
"Authorization": "OAuth2 " + get_token(),
"content-type": "application/json",
}
if get:
return rq.get(url, params=payload, headers=headers)
else:
return rq.post(url, json=payload, headers=headers)
The get_token() function successfully returns an access token (that's refreshed, so it's not expired). However, podio_api() started returning a 401 response ("unauthorized").
{'error_parameters': {}, 'error_detail': None, 'error_propagate': False, 'request': {'url': 'http://api.podio.com/app/<app_id>', 'query_string': '', 'method': 'GET'}, 'error_description': 'invalid_request', 'error': 'unauthorized'}
The app was working till yesterday.
Surprisingly, pypodio2 authorization works fine but I'd avoid it as it's an antique package.

Related

OAuth2: Unable to Authenticate API request

Been tasked to export forms and items from Podio using the API. Trying to do this with straight Python and Requests instead of the canned API tool. Am successful at retrieving the access and refresh tokens, but am unable to make the simplest Get request. The response has the error:
"error_description":"Authentication as None is not allowed for this method"
Tried this with 2 versions of using OAuth2 in Requests, both return that response.
What is it trying to tell me? Aside from giving the token, is there any other authentication attributes required?
client = BackendApplicationClient(client_id=CLIENT_ID)
oauth = OAuth2Session(client=client)
token = oauth.fetch_token(token_url=auth_url, client_id=CLIENT_ID,
client_secret=CLIENT_SECRET)
print('token:', token)
access_token = token["access_token"]
api_url = base_url + 'user/status'
r = oauth.get(api_url)
print(r.text)
headers = {'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8',
"Authorization": "Bearer " + token["access_token"]}
response = requests.get(api_url, headers=headers, verify=True)
print(response.text)
Here is full response:
{"error_parameters":{},"error_detail":null,"error_propagate":false,"request":{"url":"http://api.podio.com/user/status","query_string":"","method":"GET"},"error_description":"Authentication as None is not allowed for this method","error":"forbidden"}

Cannot POST request using service account key file in Python, getting 'Invalid IAP credentials: Unable to parse JWT', '401 Status Code'

I am trying to send a POST request to a Google App Engine service with a JSON body accompanied by an authorization token. I am generating the access token from a local service account key JSON file. The code below is generating a credential but finally the authorization is being rejected. I also tried different ways already. Even tried writing the request in Postman with a Bearer token in the Header, or even as a plain cURL command. But whatever I try, getting a 401 authentication error. I need to make sure whether the problem is in my side or on the other side with the service. Explored every documentation avaliable but no luck.
from google.auth.transport import requests
from google.oauth2 import service_account
from google.auth.transport.requests import AuthorizedSession
CREDENTIAL_SCOPES = ["https://www.googleapis.com/auth/cloud-platform"]
CREDENTIALS_KEY_PATH = 'my-local-service-account-key-file.json'
#the example service url I am trying to hit with requests
url = 'https://test.appspot.com/submit'
headers = {"Content-Type": "application/json"}
#example data I am sending with the request body
payload = {
"key1": "value 1",
"key2": "value 2"
}
credentials = service_account.Credentials.from_service_account_file(
CREDENTIALS_KEY_PATH,
scopes=CREDENTIAL_SCOPES
)
credentials.refresh(requests.Request())
authed_session = AuthorizedSession(credentials)
response = authed_session.request('POST',
url,
headers=headers,
data=payload
)
#adding some debug lines for your help
print(response.text)
print(response.status_code)
print(response.headers)
Getting the Output:
Invalid IAP credentials: Unable to parse JWT
401
{'X-Goog-IAP-Generated-Response': 'true', 'Date': 'Mon, 03 May 2021 06:52:11 GMT', 'Content-Type': 'text/html', 'Server': 'Google Frontend', 'Content-Length': '44', 'Alt-Svc': 'h3-29=":443"; ma=2592000,h3-T051=":443"; ma=2592000,h3-Q050=":443"; ma=2592000,h3-Q046=":443"; ma=2592000,h3-Q043=":443"; ma=2592000,quic=":443"; ma=2592000; v="46,43"'}
IAP expects a JWT(OpenID Connect (OIDC)) token in the Authorization header while your method will attach an access token the the Authorization header instead. Take a look at the below code snippet to make a request to an IAP secured resource.
Your code needs to be something like the following:
from google.auth.transport.requests import Request
from google.oauth2 import id_token
import requests
def make_iap_request(url, client_id, method='GET', **kwargs):
"""Makes a request to an application protected by Identity-Aware Proxy.
Args:
url: The Identity-Aware Proxy-protected URL to fetch.
client_id: The client ID used by Identity-Aware Proxy.
method: The request method to use
('GET', 'OPTIONS', 'HEAD', 'POST', 'PUT', 'PATCH', 'DELETE')
**kwargs: Any of the parameters defined for the request function:
https://github.com/requests/requests/blob/master/requests/api.py
If no timeout is provided, it is set to 90 by default.
Returns:
The page body, or raises an exception if the page couldn't be retrieved.
"""
# Set the default timeout, if missing
if 'timeout' not in kwargs:
kwargs['timeout'] = 90
# Obtain an OpenID Connect (OIDC) token from metadata server or using service
# account.
open_id_connect_token = id_token.fetch_id_token(Request(), client_id)
# Fetch the Identity-Aware Proxy-protected URL, including an
# Authorization header containing "Bearer " followed by a
# Google-issued OpenID Connect token for the service account.
resp = requests.request(
method, url,
headers={'Authorization': 'Bearer {}'.format(
open_id_connect_token)}, **kwargs)
if resp.status_code == 403:
raise Exception('Service account does not have permission to '
'access the IAP-protected application.')
elif resp.status_code != 200:
raise Exception(
'Bad response from application: {!r} / {!r} / {!r}'.format(
resp.status_code, resp.headers, resp.text))
else:
return resp.text
Note: The above method works with implicit credentials that can be set by running command: export GOOGLE_APPLICATION_CREDENTIALS=my-local-service-account-key-file.json to set the path to your service account in the environment and then run the python code from the same terminal.
Take a look at this link for more info.

Cookie authentication error using Python requests

I am trying to POST a request to Kibana using the "/api/console/proxy" path.
I have 3 headers in my request:
es_headers = {
'kbn-version': "5.5.0",
'Content-Type': "application/json",
'Cookie': "session_2=eyJhbGciOi....(long string)"
}
I am using Python requests as following:
session = requests.Session()
r = session.post(url, timeout=15, data=json.dumps(body), headers=es_headers)
From "Postman" it works just fine, but from my Python script I get a [200] response but the content of the response is like this:
'Error encountered = Unable to decrypt session details from cookie. So
clearing it.'
I googled this response but couldn't find any info about it (which is weird ...)
Any help appreciated here
Thanks
Try including the cookies separately from the headers, like this:
import requests
es_headers = {
'kbn-version': "5.5.0",
'Content-Type': "application/json",
}
session = requests.Session()
session.cookies.update({'Cookie': "session_2=eyJhbGciOi....(long string)"})
r = session.post(url, timeout=15, data=json.dumps(body), headers=es_headers)
hope this helps

Angular-5 StripeConnect -303 Error -Response for Preflight is invalid (Redirect)

I am doing StripeConnect(Standard Account Type) with Angular 5 and Asp.NetCore.
I am able to get redirected to required URL with code={} value.
When I am trying to use this code in below URL,
https://connect.stripe.com/oauth/token\client_secret={{secret test key}}\code={{code}}\grant_type = authorization_code"
1.I get preflight is invalid (Redirect) error in browser from my angular solution.
2.The html for stripe login page from Postman.
The code I wrote for making the post call to above URL (in angular) is :
getCredentialsFromStripe(code: any)
{
let Url = "https://connect.stripe.com/oauth/token";
//\client_secret=" + {{key}} + "\code=" + code + "\grant_type
= authorization_code";
return this.http.post(Url, {
Body: "client_secret = {{key}}\code =" + code,
Headers: {
'Authorization': 'Bearer '+ code,
"Accept": "application/json; charset=UTF-8",
"Access-Control-Allow-Origin": "https://connect.stripe.com/oauth/token"
}
}).map(res => res.json());
}
As per suggestions on internet,I tried making the post call from backend(.NET core(2.0) API for me),but didn't get through in creating account for standard account type.
Moreover testing from postman is giving the full html page of login ,instead of getting this object:
{
"token_type": "bearer",
"stripe_publishable_key": "{PUBLISHABLE_KEY}",
"scope": "read_write",
"livemode": false,
"stripe_user_id": "{ACCOUNT_ID}",
"refresh_token": "{REFRESH_TOKEN}",
"access_token": "{ACCESS_TOKEN}"
}
Can anybody give me a lead on this.I have been stuck past two days.
Any thoughts will be really appreciated.
Well,I was able to fix it. Instead of creating accounts using the URL (given above) in angular project (following the node.js documents),I called the stripe api's in Asp.net core (my api solution) and called them.It worked easily.

Curl command works, but httparty request gives 403

I have a curl command that makes a POST request, and returns with the correct response:
curl --data 'apiKey=someKey&apiSecureKey=someSecureKey&apiFunctionName=update&apiFunctionParams={"id”:”777”,”user_password":"password","invalid_login_attempts":"0","active_flag":"1"}' https://api-server.com/api-path/file.php
Also, when using Postman, the request works if I check the "form-data" button and paste the same four parameters that are in the curl command above into the body of the Postman request. If I check the "x-www-form-urlencoded" button in Postman, I get a 403 response (see below), so that makes me think it is a header issue.
I need to duplicate this request using httparty. Here is my attempt:
options = {
body: {
apiKey: 'someKey',
apiSecureKey: 'someSecureKey',
apiFunctionName: 'update',
apiFunctionParams: '{"id”:”777”,”user_password":"password","invalid_login_attempts":"0","active_flag":"1"}',
}
}
response = HTTParty.post("https://api-server.com/api-path/file.php", options)
This request gives me a 403 repsonse code:
{"success":false,"response":"403","responseDesc":"Forbidden. Request is missing an API permission code.","params":{"id":"777","user_password":"password","invalid_login_attempts":"0","active_flag":"1"}}
If I try to add a header, such as:
options = {
headers: {'Content-Type' => 'multipart/form-data'},
body: {
apiKey: '20a030e47a28',
apiSecureKey: '3a4e409e0c9f0e72e697fc288a88d751',
apiFunctionName: 'update',
apiFunctionParams: '{"id":"603","user_password":"password","invalid_login_attempts":"0","active_flag":"1"}',
}
response = HTTParty.post("https://beta.fxptouch.com/classes/interface/user_profile.php", options)
I get a nil response.