WooCommerce webhooks with Django Rest Framework - django

I am trying to integrate WooCommerce webhooks with Django but without success. I found a solution to a similar issue, but still cant make it work.
The thing is that, Woocomerce is generating this secret key automatically. I guess that I have to hard code it by myself in the admin panel ?
Also about the code bellow(solution found in the web), Django is complaining that request has no property payload. I guess that it must be data ?
mport base64
import hashlib
import hmac
request_sig = request.headers.get("x-wc-webhook-signature")
signature = hmac.new(<your_secret_key>.encode(), request.payload, hashlib.sha256).digest()
if hmac.compare_digest(
request_sig.encode(), base64.b64encode(signature)
):
return True
return False
enter code here

Related

Unable to verify Firebase token

I am making an app in flutter which uses Google sign-in. I also have a Django backend linked to the app and I want to verify the user in the Django backend. I found many solutions on the internet but none is working. Probably I am messing up somewhere.
I tried using python-jose for verification and here is the code:
from jose import jwt
import urllib.request, json
token = '<token recieved using await user.getIdToken in flutter>'
target_audience = "<tried projectid/appid>"
certificate_url = 'https://www.googleapis.com/robot/v1/metadata/x509/securetoken#system.gserviceaccount.com'
response = urllib.request.urlopen(certificate_url)
certs = response.read()
certs = json.loads(certs)
print(certs)
user = jwt.decode(token, certs, algorithms='RS256',
audience=target_audience)
I also tried oauth2client, the code is here:
from oauth2client import crypt
import urllib.request, json
certificate_url = 'https://www.googleapis.com/robot/v1/metadata/x509/securetoken#system.gserviceaccount.com'
target_audience = 'tried projectid/appid'
response = urllib.request.urlopen(certificate_url)
certs = response.read()
certs = json.loads(certs)
print(certs)
crypt.MAX_TOKEN_LIFETIME_SECS = 30 * 86400
idtoken = 'token received from await user.getIdToken()'
crypt.verify_signed_jwt_with_certs(idtoken, certs, target_audience)
I also tried firebase_admin for python:
import firebase_admin
from firebase_admin import credentials
from firebase_admin import auth
cred = credentials.Certificate('<firebase service accounts private key>')
default_app = firebase_admin.initialize_app(cred)
token = 'token from flutter'
verifyied =auth.verify_id_token(id_token=token)
Just to check whether the firebase_admin library itself is working or not, I passed the userid to server from the app and tried deleting the user using firebase_admin and I could do that. But for some reason I am unable to verify the token.
Thanks for the help.
I have also faced the same issue.
Case:
Initially: I was printing auth token in vscode console and was verifying in terminal.
It gave me the error: token length cannot be 1 more than % 4.
I tried verifying the token from jwt.io and it was seemingly correct.
Actual Reason for the issue:
The console output of vscode (in my case windows 7 and 64 bit). Is limited to 1064 characters for a line.
Although the actual length of token is supposed to be 1170 characters.
Workaround Solution:
Print the substring in the vscode console and the join them in python shell to verify.
Answering my own question. The problem was that my server was not actually deployed, so, I was copying the token printed in vscode console when the user logs in and pasting it into the python code and trying to verify the token. Turns out it doesn't work that way.
I hosted my Django app and passed the token in a post request and then tried to verify the token and it worked.
You can refer the solutions here if you are stuck :
https://coders-blogs.blogspot.com/2018/11/authenticating-user-on-backend-of-your.html

Dropbox and Django SSO using SAML

Summary
I am looking to use Dropbox SSO functionality by using the authentication from a Django site. Note that I'm not looking to use SAML as a backend for my Django site.
Resources
1) Dropbox Custom SSO help page: https://www.dropbox.com/en/help/1921#custom
2) Creating a SAML response: https://robinelvin.wordpress.com/2009/09/04/saml-with-django/
3) Struggled to find any examples from Google of people doing this kind of SSO. Lots of links about people using SAML as a Django backend.
Question
In the dropbox admin settings I can add my X509 certificate and the login link. This means that when you try to login into Dropbox using SSO it nicely forwards you to my Django site's login page using a GET request with a SAMLRequest in the querystring.
However, my understanding is that I now need to, once the user is authenticated on the Django site, fire a POST request back to Dropbox at their SAML login link with a SAMLResponse in the post data. Using the second resource above I believe I can create the SAMLResponse xml but I am unsure how to redirect the user to the dropbox SAML login link with the SAML data from my Django view.
Any help much appreciated.
Managed to get the functionality I needed using django-saml2-idp https://github.com/peopledoc/django-saml2-idp
Good documentation on installing here: https://github.com/peopledoc/django-saml2-idp/blob/master/doc/INSTALL.txt
Settings in the Dropbox Admin console required the X509 certificate and then the login url set to: https://****.com/idp/login
Note that I had issues installing the M2Crypto dependency so used an Ubuntu package via:
sudo apt-get install python-m2crypto
Additionally I'm using Django 1.9.6 so needed to make overrides to the views.py, urls.py, and registry.py files to make them compatible (various import statements needed updating and the urls changed to the new list format rather than using patterns).
Created a Dropbox Processor as follows:
import base64
import zlib
from saml2idp import base
from saml2idp.xml_render import _get_assertion_xml
def get_assertion_dropbox_xml(parameters, signed=False):
return _get_assertion_xml(ASSERTION_DROPBOX, parameters, signed)
ASSERTION_DROPBOX = (
'<saml:Assertion xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" '
'ID="${ASSERTION_ID}" '
'IssueInstant="${ISSUE_INSTANT}" '
'Version="2.0">'
'<saml:Issuer>${ISSUER}</saml:Issuer>'
'${ASSERTION_SIGNATURE}'
'${SUBJECT_STATEMENT}'
'<saml:Conditions NotBefore="${NOT_BEFORE}" NotOnOrAfter="${NOT_ON_OR_AFTER}">'
'<saml:AudienceRestriction>'
'<saml:Audience>${AUDIENCE}</saml:Audience>'
'</saml:AudienceRestriction>'
'</saml:Conditions>'
'<saml:AuthnStatement AuthnInstant="${AUTH_INSTANT}"'
'>'
'<saml:AuthnContext>'
'<saml:AuthnContextClassRef>urn:oasis:names:tc:SAML:2.0:ac:classes:Password</saml:AuthnContextClassRef>'
'</saml:AuthnContext>'
'</saml:AuthnStatement>'
'${ATTRIBUTE_STATEMENT}'
'</saml:Assertion>'
)
class Processor(base.Processor):
def _decode_request(self):
"""
Decodes _request_xml from _saml_request.
"""
self._request_xml = zlib.decompress(base64.b64decode(self._saml_request), -15)
def _format_assertion(self):
self._assertion_xml = get_assertion_dropbox_xml(self._assertion_params, signed=False)
Which you register in your settings.py file as follows:
SAML2IDP_CONFIG = {
'autosubmit': True,
'certificate_file': '/****/certificate.pem',
'private_key_file': '/****/private-key.pem',
'issuer': 'https://www.****.com',
'signing': True,
}
sampleSpConfig = {
'acs_url': 'https://www.dropbox.com/saml_login',
'processor': 'dropbox.Processor',
}
SAML2IDP_REMOTES = {
'sample': sampleSpConfig,
}
Works like a dream. Hope this helps somebody out there.

Unit test through an oauth flow in Django

I have an oauth flow in which a user grants access to a certain scope and then my application can do stuff. For this to work, I need an access token with the defined scope.
I implemented this (with the django allauth package) and it works great. But...
I would like to test it.
This is what I have so far (request package is like an urllib on steroids):
login = self.client.login(username='test_user', password='test')
self.assertTrue(login)
resp = self.client.post(reverse('oauth_login'))
self.assertEqual(resp.status_code, 302)
payload = {'session_key': 'email', 'session_password': 'pw', }
resp2 = requests.post(resp['location'], data=payload)
resp3 = self.client.get(reverse('do_stuff_with_access_token'))
self.assertEqual(resp.status_code, 302)
The issue here is that I do not get the access token in my request variables. My guess is that I am going out of the scope of the application and Django does not get the variable in its request scope.
How can you test this in an elegant manner? Mocking an access_token seems a bit wrong to me. I am now trying to go Selenium for filling in the form, but even that is not really a success so far...
Thanks!
Kudos to Mark!
To help anyone on their way.
Mocking worked out. In my case (django 1.4) you need to add your tokens to the session. A lot of different advices can be found on the net, but I like simple things and this works in Django at least with the test suite:
session = self.client.session
session['request_token'] = {...}
session['access_token'] = {...}
session.save()
I faced the same problem and found the following solved my dilemma:
user = User.objects.get(username='lauren')
client = APIClient()
client.force_authenticate(user=user)
This was taken directly from the Django documentation:
http://www.django-rest-framework.org/api-guide/testing/#force_authenticateusernone-tokennone
Unfortunately it took a number of searches before getting to this point. I hope this saves someone else some time.

django socialauth twitter , google oauth , facebook does not work

This is my first post, and I have a problem I could not make it work django OMAB socialauth of three things I just need to google, facebook, and twitter, google works well with open id, but not much twitter and I put in my
settings. py:
TWITTER_CONSUMER_KEY = '00' this is no real
TWITTER_CONSUMER_SECRET = '00' this is no real
FACEBOOK_APP_ID = '' ihave no key
FACEBOOK_API_SECRET = ''
LINKEDIN_CONSUMER_KEY = ''
LINKEDIN_CONSUMER_SECRET = ''
ORKUT_CONSUMER_KEY = ''
ORKUT_CONSUMER_SECRET = ''ihave no key
GOOGLE_OAUTH2_CLIENT_ID = ''
GOOGLE_OAUTH2_CLIENT_SECRET = ''
SOCIAL_AUTH_CREATE_USERS = True
SOCIAL_AUTH_FORCE_RANDOM_USERNAME = False
SOCIAL_AUTH_DEFAULT_USERNAME = 'socialauth_user'
SOCIAL_AUTH_COMPLETE_URL_NAME = 'socialauth_complete'
LOGIN_ERROR_URL = '/login/error/'
#SOCIAL_AUTH_USER_MODEL = 'app.CustomUser'
SOCIAL_AUTH_ERROR_KEY = 'socialauth_error'
GITHUB_APP_ID = ''
GITHUB_API_SECRET = ''
FOURSQUARE_CONSUMER_KEY = ''
FOURSQUARE_CONSUMER_SECRET = ''
LOGIN_URL = '/login-form/'
LOGIN_REDIRECT_URL = '/'
LOGIN_ERROR_URL = '/login-error/'
I am using the example that comes in the zip of OMAB socialauth django , but not working.
When I created my twitter app, I wrote my domain www.sisvei.com , I am testing locally socialauth django ie 127.0.0.1:8000, then sign in with twitter sends me to this url:
http://127.0.0.1:8000/login/error/ and a message saying is the Incorrect authentication service
this happens with facebook and google oauth and oauth2
I'm new to django and I this much work comprising this part of django socialath hopefully help me, thank you very much.
You need to be more specific on "why it doesn't work". Where are you getting the errors?
When debugging a third-party oauth/openid app in Django, generally it boils down to:
configuration & keys - did you make sure to obtain all of the necessary API keys for the services you will be using, and to add them to your configuration?
urls - did you remember to add the necessary urlpatterns to your base urls.py file?
authentication setup on the server - often, you'll need to have a file available or respond with a specific header when the authentication service hits your server. Have you checked to make sure that is set up?
databases - have you run syncdb after installing the app? Are all the tables set up?
templates - if the third party app requires you to set up templates, do you have them set up?
custom views - are you using custom views? If so, try using the built-in views that came with the third party app first, to see if they work
After those are confirmed, you're going to want to be able to see what requests are taking place. Use the debugger included in Chrome/Safari, or get the web developer add-on for Firefox, and look at the network requests as they happen. Do you see HTTP responses other than 200 (say, 404, 500, 403, etc?) those mean that the services aren't responding correctly.
From your error, it looks like you have not correctly set up your callback URL on Twitter. It should be sending you to www.sisvei.com, not 127.0.0.1. Alternatively, check the URL when you get to the Twitter login page -- is the callback URL in the URL, and is it pointing to 127.0.0.1? Then Django is sending it the wrong callback URL.
Finally this:
I wrote my domain www.sisvei.com python does not support this
Is unclear. As far as I know, Python doesn't care what the domain is.
WAIT A MINUTE ...
Are you using runserver? Are you getting the following error?
Error: "www.sisvei.com" is not a valid port number or address:port pair.
If so, there is an easy fix! Just run it like so:
python manage.py runserver www.sisvei.com:80
That should resolve your error if that's what's happening. You're probably running it as
python manage.py runserver 127.0.0.1
127.0.0.1 is a reserved IP address that points back to localhost, your own computer. As a result, it is not possible to use it for authentication or any other purpose outside of programs running on your own machine. See this article for more info.
I'm not sure, but I might be having similar problems, oscar. For me, SocialAuth was generating an AuthenticationURL for facebook, foursquare and hotmail, but not for google, twitter or any of the other address it supports. I think it may be something wrong with the API, so I posted an issue on the social-auth google group...you may want to check there to see if anyone updates!!
https://code.google.com/p/socialauth/issues/detail?id=282&colspec=ID%20Type%20Status%20Priority%20Milestone%20Owner%20Summary%20Modified

Django-social-auth google oauth token usage

I'm using Django-socila-auth plugin. It uses google API for Oauth 1.0 Authentication. Question is have anybody used it with google python API (gdata). I mean how to apply auth session_token, stored in django-social-auth model to my api call.
Can you help me with code to get this token from model and apply to gdata.PhotoService() instance. For now it is like this:
#getting model instance from django-social-auth model
association = Association.objects.get(user=request.user)
google_session_token=association.handle
google_secret=association.secret
#token string from django-social-auth
#model Association field "handle" looks like:
#google_session_token = '.......XG84PjwytqJkvr8WQhDxm1w-JplWK5zPndSHB13f.........'
gd_client = gdata.photos.service.PhotosService()
gd_client.debug = 'true'
gd_client.auth_token = google_session_token
#image.image is a file field, but problem not in this.
#it tries to send file in debug text.
#It just recieves 403 unauthorised callback.
photo = gd_client.InsertPhotoSimple(
'/data/feed/api/user/default/albumid/default', 'New Photo',
'Uploaded using the API', image.image, content_type='image/jpeg')
I'm recieving error
403 Invalid token string.
I understand that it needs secret too but how to apply it to API for auth?(To receive authorization to post photos.). BTW I added Picassa feed URL, as an option string for social-auth to ask permissions, so token I have asks for Picassa feed permissions when authorizing with google.
BTW. Google tutorial I've used is: here
I understand it's Oauth 1.0 rather than AusSub, but question is:
how to authenticate with token and secret I have and post a photo with this permission?
Just to answer my own problem. I used wrong way to do it, because problem in 'gd_client' and AuthSub.
It must check token on server. And it can not do it on localhost. You need to look ahead to Oauth/Oauth2 for better debugging and so on... No matter that it is much complex than AuthSub