I'm doing a webhook request from Paypal webhook simulator to an App Engine service, developped in flask.
The webservice has a route to get webhooks using this simple code in flask:
#app.route('/webhook',methods = ['POST'])
def webhook():
print(request.method )
if request.method == 'POST':
print(request.json)
return 'success', 200
else:
abort(400)
Unfortunatelly, the request doesn't work, and there is no log message from the flask app, not even from the print(request.method).
Picture of Web hook test failed
Webhooks URL:
https://www.mywebsite/webhook
After sending test, I have the following event status:
Your event failed to queue at May 13 2022, 20:28:47
Error details:
{}
Do you know why the webhook test isn't working?
The error comes from the sandbox account created by default. When starting a sandbox service, Paypal creates a default account that doesn't have all the functions, including the webhook one. I've created a new sandbox account and the webhook works.
Related
I'm attempting to set up OIDC with Keycloak as my IdP and Django (using Django Rest Framework and mozilla-django-oidc) as my client server. I have got keycloak installed and a rough Django application stood up that successfully redirects to keycloak where I can then successfully authenticate (to keycloak), but when I'm redirected back to django I'm missing information, specifically oidc_states.
The redirect to django triggers this log entry:
[12/Oct/2021 08:28:06] "GET /api/oidc/callback/?state=QGsO26esqdtHZcsfRfYoXvUy0QWcGdZv&session_state=493887a4-600e-4dd2-aaaf-4134ea671c9a&code=dfe1573e-cf8e-4829-8874-a3500ba63712.493887a4-600e-4dd2-aaaf-4134ea671c9a.c1dfdb46-140c-4ccd-8308-6db3b468346a HTTP/1.1" 302 0
This contains three keys: state, session_state, and code.
The default callback view provided by mozilla-django-oidc contains this:
def get(self, request):
"""Callback handler for OIDC authorization code flow"""
if request.GET.get('error'):
if request.user.is_authenticated:
auth.logout(request)
assert not request.user.is_authenticated
elif 'code' in request.GET and 'state' in request.GET:
if 'oidc_states' not in request.session:
return self.login_failure()
# ...
Because keycloak isn't making the redirect with oidc_states added, this is immediately failing and I haven't been able to figure out why. I'm guessing that the problem is with my keycloak client configuration?
To any wayward travelers, I wish you luck. Ultimately, I solved my problem by re-configuring my mozilla-django-oidc settings. Specifically, I was missing:
AUTHENTICATION_BACKENDS = (
"django.contrib.auth.backends.ModelBackend", # default
"mozilla_django_oidc.auth.OIDCAuthenticationBackend",
)
This allowed for my application to authenticate both with the existing flow and using the new OIDC flow. The call to authenticate in the OIDC callback view was failing because I didn't have this authentication backend specified, so it was trying to just use the default.
I wanted to get a notification to angular when gcp bucket got updated .Can anyone help me with that?
The idea is: whenever a bucket is updated a http post request is sent to your python web application. All you need in python is to handle this post request.
For example
import http.server
import socketserver
from http import HTTPStatus
class Handler(http.server.SimpleHTTPRequestHandler):
def do_GET(self):
self.send_response(HTTPStatus.OK)
self.end_headers()
self.wfile.write(b'Hello world')
def post(self):
if 'X-Goog-Resource-State' in self.request.headers:
resource_state = self.request.headers['X-Goog-Resource-State']
if resource_state == 'sync':
logging.info('Sync message received.')
else:
an_object = json.loads(self.request.body)
bucket = an_object['bucket']
object_name = an_object['name']
logging.info('%s/%s %s', bucket, object_name, resource_state)
else:
logging.info("Other post.")
httpd = socketserver.TCPServer(('', 8093), Handler)
httpd.serve_forever()
After the web server above is up, then, in Cloud Console redirect notifications to your URL
gsutil notification watchbucket yourULR gs://BucketName
The def post(self) is coppied from webapp2 example here
https://cloud.google.com/storage/docs/object-change-notification
Web server code is copied from here
https://gist.github.com/davidbgk/b10113c3779b8388e96e6d0c44e03a74
I am trying to send a JSON response from Django back-end to my angular front-end.
When I make the request I receive nothing in Postman or Angular but,opening the link in browser seems to be returning the correct result
My View is :
#api_view(['GET'])
def my_view(request):
print(request.user.username)
return JsonResponse({'username': request.user.username})
When I open http://127.0.0.1:8000/accounts/get_username/ in browser I receive
{"username": "aditya8010"} on the web page.
But when i do a get request using POSTMAN I recieve
{
"username": ""
}
Same with Angular
this.http.get("http://127.0.0.1:8000/accounts/get_username/").subscribe((res) => {
this.username = JSON.stringify(res["username"])
console.log(this.username," ", res)
})
this code also prints an empty username string.
Another thing I have noticed is that my print statement in the view does print anything random I put in there when called from POSTMAN or Browser but when I use request.user.username it doesnt print anything when called by POSTMAN.
And each time the response code is 200
What am I doing wrong.
When you're sending the request you are not providing authentication credentials (i.e. something that identifies the user that is sending the request). How do you obtain this credentials?
You need to establish an authentication method. There are several but I recommend using Token authentication with knox package. Basically, you have an endpoint that logins the user with his username and password (normal json post request) and that endpoint returns a token. This token is what identifies the user. You send this token in the header of each request you need to be authenticated. That means you probably should include an IsAuthenticated permission for the view. In postman:
API view:
from rest_framework.permissions import IsAuthenticated
#api_view(['GET'])
#authentication_classes([IsAuthenticated])
def my_view(request):
print(request.user.username)
return JsonResponse({'username': request.user.username})
When it is in a browser, your login information is remembered in the session. When using postman or Angular, you need to provide the user's information in the request header manually.
I am integrating google calendar with my web application which is a django app. when i am doing it on localhost server, its working fine. Google authentication page opens in client browser, but when i am uploading that code to the server and integrating google calendar, then Google authentication page opens in terminal where i run my django server.
This is the page that opens for authentication in terminal
I want to provide this auth through client web browser.
`
def get_credentials(request):
creds = None
# If there are no (valid) credentials available, let the user log in.
if os.path.exists('token.pickle_' + request.GET.get('bot_id')):
with open('token.pickle_' + request.GET.get('bot_id'), 'rb') as token:
creds = pickle.load(token)
print(creds)
if not creds or not creds.valid:
if creds and creds.expired and creds.refresh_token:
creds.refresh(Request())
else:
flow = InstalledAppFlow.from_client_secrets_file(
CLIENT_SECRET_FILE, SCOPES)
creds = flow.run_local_server()
# Save the credentials for the next run
with open('token.pickle_' + request.GET.get('bot_id'), 'wb') as token:
pickle.dump(creds, token)
serializer = CalenderIntegrationSerializer(data={'bot_id': int(request.GET.get('bot_id')), 'status': True})
if serializer.is_valid():
serializer.save()
if os.path.exists('token.pickle_' + request.GET.get('bot_id')):
context = {'signin_url': creds}
return JsonResponse({'status': 200, 'data': 'Integration done!', 'is_integrated': True})
`
And this is my reference google calendar code python
This code is specifically for local development:
https://developers.google.com/api-client-library/python/auth/installed-app
The code gives you a hint on how to construct the URL, which you then need to send back to your user as a temporary redirect; e.g. using the redirect function. Then you need to have a django handler which accepts the redirect and executes the second half of the function. So:
Split your code into two functions.
Build a url, send a redirect with your endpoint as the callback
Google will redirect back to your endpoint after the user completes the flow.
Parse the results
Execute your code.
I have a simple endpoint in my API (Django Rest Framework).
When I try to make a HTTP POST requests in Postman, it works perfectly fine.
However, in my Angular 5 app, when I do POST request to the same endpoint, I get Http 403 error with CSRF missing error:
CSRF verification failed. Request aborted.
My API viewset
(api/views.py):
class EventViewset(viewsets.ModelViewSet):
serializer_class = EventSerializer
def get_queryset(self):
return Event.objects.filter(server__organization=self.request.user.organization)
My angular app works on localhost:4200
Angular POST:
public createEvent(organization, data) {
return this.http.post(`${this.apiUrl}/${organization}/events`, data);
}