How to increase time of office 365 push notification web hook verification - python

According to microsoft Document I have to follow below steps:
If the listener service successfully validates the URL, it returns a
success response within 5 seconds as follows:
Sets the content type in the response header to text\plain.
Includes the same validation token in the response body.
Returns an HTTP 200 response code. The listener can discard the validation token subsequently.
My enpoint is look like this:
#app.route('/outlook/push', methods=['POST'])
def outlook_push():
return (request.args.get('validationtoken'), 200, {'Content-Type': 'plain/text'})
but this exceeds the time limit(5s)
I am getting error like this:
{'error': {'code': 'ErrorInvalidParameter', 'message': "Notification URL 'https://5cbae04e.ngrok.io/outlook/push?validationtoken=NmIzZDJiMTMtZjhmNy00ZWMwLTg1MDctNDQwMDQ0OWM2NmE1' verification failed 'System.Net.WebException: The operation has timed out\r\n at System.Net.HttpWebRequest.GetResponse()\r\n at Microsoft.Exchange.OData.Model.Notifications.PushNotification.PushSubscriptionCallbackUrlValidationHelper.SendRequestAndVerifyResponse(Uri callbackUrl, PushSubscription pushSubscription)'."}}
Is there anyway to increase time limit?

I don't think it can be changed, and your problem probably is that your route is defined to accept POST method. And office365 is making GET request in there :)

Related

Python Requests / HTTPX - Authenticate All Redirected URL - How To

I wonder if there is a way to authenticate each redirected URL when working with Python modules such as httpx or requests?
Problem Statement
I am trying to connect to an API endpoint under the company network. Due to the company's cyber security measures, the API endpoint will be randomly masked with a company proxy, which causes the 307 Redirect status code.
my current code snippet looks like the below:
import httpx
api_url = 'https://demo.vizionapi.com/carriers'
head = {
'X-API-Key':'API KEY'
}
response = httpx.get(url=api_url, verify='supporting_files/cacert.pem',
headers=head, auth=('my username', 'my password'),
follow_redirects=True)
With above code, I received the 401 authentication needed error (But auth has been passed). This error will only happen when redirection occurs due to the company proxy.
Question:
My assumption is the authentication is only being passed into the first URL not the redirected URL. Therefore, I wonder if anyone know how I can use the same auth parameter for all URLs (direct & redirect)?
Any suggestion will be deeply appracaited.
I don't know what requests behavior with regards to auth during redirect is, but the first solution to come to mind is to manually follow the redirects yourself. Put your request in a loop that checks for the 3xx response codes, and handle auth however you want to.

Creating Subscription for Microsoft Graph API: Subscription validation request failed

I try to create a Subscription for Microsoft Graph API. However, I get the error
Subscription validation request failed. Response must exactly match validationToken query parameter.
The Validation Request looks as follows :
POST /?validationToken=Validation%3a+Testing+client+application+reachability+for+subscription+Request-Id%3a+c69b04df-f3d3-411c-8ceb-7f1ad8b7a927 HTTP/1.1
Using FastApi, the API where validation request is sent to look like
from fastapi import FastAPI
app = FastAPI()
#app.post("/")
def read_call_record(validationToken):
data = {"validationToken": validationToken}
return data
The returned data variable looks like:
{'validationToken': 'Validation: Testing client application reachability for subscription Request-Id: c69b04df-f3d3-411c-8ceb-7f1ad8b7a927'}
Can someone help
Your code needs to Url Decode the validationToken query parameter and return it back to Graph.
From the documentation, your response must happen within 10 seconds with the following properties:
A status code of HTTP 200 OK.
A content type of text/plain.
A body that includes the URL decoded validation token. Simply reflect back the same string that was sent in the validationToken query parameter.
Important: If the client returns an encoded validation token, the validation will fail.
I found the awnser myself. Here function that works:
#app.post("/")
def read_call_record(validationToken):
return Response(content=validationToken, media_type='text/plain')

Streamlabs API 405 response code

I'm trying to use Streamlabs API. Streamlabs API uses Oauth2 for creating apps. So first I send whoever's using my app to an authorization link containing my app's client id and the scopes I want to use.
(Something like this: streamlabs.com/api/v1.0/authorize?client_id=CLIENT-ID-HERE&redirect_uri=REDIRECT-URI&response_type=code&scope=SOME+SCOPES+HERE)
Once I've done that I receive a code at the redirect uri specified. I then use that code to get the access token for permanent access to the connected user's account. I then receive the access token from a POST request that works perfectly... Now I run into the problem. When getting the temporary code before the access token I specified the scopes: "donations.read +donations.create+alerts.write+alerts.create".
When authorizing, the app asks for permission to the different scopes. The scope in focus is "alerts.write" so that I can send test alerts using POST requests. But this doesn't work for some reason. To send a test alert I have to send a POST request to this url: "https://streamlabs.com/api/alerts/send_test_alert"
I've tried doing that in two different ways.
1:
import requests
url = "https://streamlabs.com/api/alerts/send_test_alert"
data = {
"access_token":"UserAccessTokenHere",
"type":"donation"
}
response = requests.post(url=url, data=data)
print(response.text)
2:
import requests
url = "https://streamlabs.com/api/alerts/send_test_alert?access_token=UserAccessTokenHere&type=donation"
response = requests.post(url=url)
print(response.text)
If I do print(response) it prints "Response [405]".
But if I do print(response.text) I get a long HTML document for this page: Error response page
Any ideas what's going wrong with my Python requests? send_test_alert documentation here: Link
I've contacted support and looks like you've made the same error as me.
You're not actually sending a request to the right URL.
You are a sending a request to: "https://streamlabs.com/api/alerts/send_test_alert"
You should be using the URL: "https://streamlabs.com/api/v1.0/alerts/send_test_alert"

Stormpath failed to find resource

In order to authenticate in Flask with Stormpath, the user sends an access token in the request's header.
headers = {
'Authorization': 'Bearer <token_id>'
}
I validate it with:
authenticator = ApiRequestAuthenticator(application)
uri = 'bla_dont_care.com'
result = authenticator.authenticate(headers=request.headers, http_method='GET', uri=uri, body={}, scopes=[])
is_valid = result.account is not None
The authenticator is not being initiated in every request but saved in memory.
My response time raised from 40ms to 450ms. I read that the Stormpath SDK caches the API calls specifically for this.
Trying to debug this, I did see that the cache get 2 misses per 1 request here. The key it failes to find is https://api.stormpath.com/v1/applications/VJiXDWTWnYdNgrFe9BoI3/accounts/6TGIMWF47DO0XUK96M07XEMG1. It fails to find the resource here.
What account is it looking for? 6TGIMWF47DO0XUK96M07XEMG1 is not the account sent. How can I debug this?

Post print dictionary/json returns error to client

I am sending post request in the body of some json data, to process on server and I want the results back to client(c++ app on phone) in the form of json data and hence parse on mobile.
I have the following code inside handler:
class ServerHandler(tornado.web.RequestHandler):
def post(self):
data = tornado.escape.json_decode(self.request.body)
id = data.get('id',None)
#process data from db (take a while) and pack in result which is dictinary
result = process_data(id)# returns dictionary from db= takes time
print 'END OF HANDLER'
print json.dumps(result)
#before this code below I have tried also
#return result
#return self.write(result)
#return self.write(json.dumps(result))
#return json.dumps(result)
self.set_header('Content-Type', 'application/json')
json_ = tornado.escape.json_encode(result)
self.write(json_)
self.finish()
#return json.dumps(result)
I always get printed 'END OF HANDLER' and valid dictinary/json below on console but when I read at client mobile I always get
<html><title>405: Method Not Allowed</title><body>405: Method Not Allowed</body></html>
Does anyone have any idea what is the bug ?
(I am using CIwGameHttpRequest for sending request and it works when file is static =>name.json but now same content is giving error in post request. )
The error (HTTP 405 Method Not Allowed) means that you have made a request to a valid URL, but you are using an HTTP verb (e.g. GET, POST, PUT, DELETE) that cannot be used with that URL.
Your web service code appears to handle the POST verb, as evidenced by the post method name, and also by the fact that incoming requests appear to have a request body. You haven't shown us your C++ client code, so all I can do is to speculate that it is making a GET request. Does your C++ code call Request->setPOST();? (I haven't worked with CIwGameHttpRequest before, but Googling for it I found this page from which I took that line of code.)
I've not worked with Tornado before, but I imagine that there is some mechanism somewhere that allows you to connect a URL to a RequestHandler. Given that you have a 405 Method Not Allowed error rather than 404 Not Found, it seems that however this is done you've done it correctly. You issue a GET request to Tornado for the URL, it determines that it should call your handler, and only when it tries to use your handler it realises that it can't handle GET requests, concludes that your handler (and hence its URL) doesn't support GETs and returns a 405 error.

Categories