django-push-notification 401 unauthorised - python

I am trying to setup push notifications using the django-push-notifications, I have copied most of the code from the example. I have a button that calls the enablePushNotifications() function:
export function enablePushNotifications() {
console.log("enabling push notifications...");
if (!'serviceWorker' in navigator){
console.log("Push notifications not supported");
return;
}
navigator.serviceWorker.ready.then(
(registration)=>{
registration.pushManager.subscribe({
userVisibleOnly: true
}).then(
(sub)=>{
console.log(sub);
let endpointParts = sub.endpoint.split("/");
let registration_id = endpointParts[endpointParts.length - 1];
let data = {
'browser': loadVersionBrowser(navigator.userAgent).name.toUpperCase(),
'p256dh': btoa(String.fromCharCode.apply(null, new Uint8Array(sub.getKey('p256dh')))),
'auth': btoa(String.fromCharCode.apply(null, new Uint8Array(sub.getKey('auth')))),
'registration_id': registration_id,
'endpoint': sub.endpoint,
};
request(
"/api/subscribe",
data
)
}
).catch(
(error)=>console.error(error)
)
}
)
}
When I open the networking tab I don't see anything strange about the passed properties or headers. Specifically the browser value is correct. The implementation for the /api/subscribe URL is as follows:
import push_notifications.models as pushmodels
def registerPush(request):
data = requestFormatting.get_data(
request
)
device = pushmodels.WebPushDevice(
name=request.user.username,
active=True,
user=request.user,
registration_id=data["registration_id"],
p256dh=data["p256dh"],
auth=data["auth"],
browser=data["browser"]
)
device.save()
device.send_message("hello")
Calling this function raises a PushError: Push failed: 401 Unauthorized. I have tested on both chrome and firefox, both give the same error. I specify my FCM_API_KEY in settings, nothing else. I do not currently use VAPID, though I plan to in the future. I have tried various variations of the code, but nothing seems to work. The documentation is unclear on how to actually initialize devices, and I only picked a WebPushDevice objects since it seems to contain similar attributes as the data provided in the example.
This is my first time trying to use web push, so a little help would be much appreciated!

Related

How to set cookies using GraphQLTestCase

I have dug far and deep but no working solution yet, based on some things I read from a thread somewhere, it seems you have to prefix headers with HTTP_ e.g. HTTP_AUTHORIZATION ends up being the Authorization header, based on that my current attempt is:
class TestImpersonatation(LogonUserMixin, GraphQLTestCase):
:
def test_...(self):
response = self.query(''' ...mutation here... ''',
headers = {
"HTTP_AUTHORIZATION": f"JWT {self.token}",
"HTTP_SET_COOKIE": f"my-jwt-token={self.token}"
},
variables={ ...vars... }
)
but alas, every time I get to my breakpoint there is only ever one cookie set, a csrf token. I am stumped but still trying... next it to se if a Client() instance can be passed in to work some magic instead of relying on the one created inside.

Django rest raising error "The submitted data was not a file. Check the encoding type on the form." to angualar Http Client

The are any solutions to the problem but m not able to find the root cause and also to mention no of the solution is working in my case.
What I am trying to do is to upload a file to Django rest API from a angular Http Client Service.
I am taking up the input form the user passing to the service at the end I have declared a type specific for the type of model I am creating an object for but I am not getting the same error again and again.
I read some where that Django file uploader doesn't understand some char-set format but I still can't understand whats wrong with it.
var report = <CompleteReport> {
title:'heelo',
description:'sdfsdfs',
author: 'report',
article_upload_images: [uuid4(),],
presentation_upload_images: [uuid4(),],
report_article: article_object,
report_image: image_object,
report_podcast: podcast_object,
report_presentation: presentation_object,
report_video: video_object
};
let headers = new HttpHeaders({
'Accept': 'application/json'
});
let options = {headers: headers};
return this.http.post<any>(url, report, options)

CloudKit Server-to-Server auth: Keep getting 401 Authentication failed

I have been recently exploring the CloudKit and related frameworks. I got the communication with my app working, as well as with my website using CloudKitJS. Where I am struggling is the Server-to-Server communication (which I would need for exporting data from public database in csv.
I have tried Python package requests-cloudkit, which others were suggesting. I have created a Server-to-Server token, and have copied only the key between START and END line once creating the eckey.pem file. I then got this code:
from requests_cloudkit import CloudKitAuth
from restmapper import restmapper
import json
KEY_ID = '[my key ID from CK Dashboard]'
SECRET_FILE_KEY = 'eckey.pem'
AUTH = CloudKitAuth(KEY_ID, SECRET_FILE_KEY)
PARAMS = {
'query':{
'recordType': '[my record type]'
},
}
CloudKit = restmapper.RestMapper("https://api.apple-cloudkit.com/database/1/[my container]/development/")
cloudkit = CloudKit(auth=AUTH)
response = cloudkit.POST.public.records.query(json.dumps(PARAMS))
I am then getting the 401 Authentication failed response. I am stuck on this for days, so I would be grateful for any help or advice. 😊
Creating the server-to-server key is an important first step, but in order to make HTTP requests after that, you have to sign each request.
Look for the Authenticate Web Service Requests section near the bottom of this documentation page.
It's a little bit convoluted, but you have to carefully construct signed headers to include with each request you make. I'm not familiar with how to do it in Python, but here's how I do it in NodeJS which may help:
//Get the timestamp in a very specific format
let date = moment().utc().format('YYYY-MM-DD[T]HH:mm:ss[Z]')
//Construct the subpath
let endpoint = '/records/lookup'
let path = '/database/1/iCloud.*****/development/public'
let subpath = path+endpoint
//Get the key file
let privateKeyFile = fs.readFileSync('../../'+SECRET_FILE_KEY, 'utf8')
//Make a string out of your JSON query
let query = {
recordType: '[my record type]'
}
let requestBody = JSON.stringify(query)
//Hash the query
let bodyHash = crypto.createHash('sha256').update(requestBody, 'utf8').digest('base64')
//Assemble the components you just generated in a special format
//[Current date]:[Request body]:[Web service URL subpath]
let message = date+':'+bodyHash+':'+subpath
//Sign it
let signature = crypto.createSign('RSA-SHA256').update(message).sign(privateKeyFile, 'base64')
//Assemble your headers and include them in your HTTP request
let headers = {
'X-Apple-CloudKit-Request-KeyID': KEY_ID,
'X-Apple-CloudKit-Request-ISO8601Date': date,
'X-Apple-CloudKit-Request-SignatureV1': signature
}
This is a bit hairy at first, but I just put all this stuff in a function that I reuse whenever I need to make a request.
Apple's documentation has pretty much been abandoned and it's hard to find good help with CloudKit Web Services these days.

Post json to django but get 500 error

I'm writing an app to post json to Django, but get a 500 error in terminal like
[27/Jan/2015 20:50:38] "POST /datasave/ds/ HTTP/1.1" 500 10414
This is my jQuery code:
$(function() {
$('#upload').click(function() {
var json_obj = {
username: $('#username').val(),
password: $('#password').val(),
game_id1: '123',
csrfmiddlewaretoken: '{{ csrf_token}}'
};
$.post("http://192.168.0.109:8000/datasave/ds/", JSON.stringify(json_obj),
function(data) {
alert("OK");
},
"json");
})
})
And Django views code:
#csrf_exempt
def ds(request):
dicty = {}
if request.is_ajax:
if request.method == 'POST':
req = json.loads(request.body.decode("utf-8"))
obj, created =
Gamer.objects.update_or_create(
username=req.get(u'username', None),
password=req.get(u'password', None),
game_id1=req.get(u'game_id1', None))
print obj, created
dicty['username'] = req.get(u'username', None)
dicty['password'] = req.get(u'password', None)
dicty['create_at'] = str(timezone.now())
return JsonResponse(dicty)
As you are getting a 500 Internal server error one could assume that there is an issue in your view handler code. It's hard to say what's causing it really, so you should try to figure why it's happening. From looking at your code I can see two things that might cause this error.
First you are using dict as a variable name, which is probably a bad idea since dict is a built-in type in python.
The other possible cause could be the way your are accessing the req dict. You are accessing the keys username, password and game_id1. If any of these should be missing in the dict it will throw a KeyError exception. I like to access dicts using req.get('username', None) instead (replace None with another default value if you prefer. Another way to tackle that issue would be try/catch exception handling.
Also, depending on your Gamer model, trying to create a using an existing username (assuming you have unique=True) would probably throw an exception as well, so you should handle that as well (I think get_or_create could be handy here).
Generally when dealing with problems of this kind, use the inspector in your browser. It lets you see all the data sent and received during the request, which means (if you're running django in DEBUG mode) you'll also get to see the default stack trace page in the inspector. It should hold some valuable indication to what's causing the issue. Another option would be to write a small middleware or enable extended error logging to log errors to strout/stderr.

Can't make GAE Channel API work on local computer

I am creating a small application to test how GAE Channel API works. I think I have done all as it's described in the documentation but when I launch it, it shows an error in FireFox error log about syntax in the beginning and then another repeating error that an element wasn't found that.
Here is the first error info:
Source: http://127.0.0.1:8080/_ah/channel/dev?command=connect&channel=channel-773698929-185804764220139124118
Line 1, symbol 1
Here is the url where my javascript code tries to connect repeatedly and it raises the second error:
http://127.0.0.1:8080/_ah/channel/dev?command=poll&channel=channel-2071442473-185804764220139124118&client=1
I get the token through a JSON request with jQuery $.get. Then I run this code to get the token and open the channel. The error begins to show just when I run socket = channel.open(handler):
var response = JSON.parse(data);
var token = response.token.toString();
channel = new goog.appengine.Channel(token);
var handler = {
'onopen': onOpened,
'onmessage': onMessage,
'onerror': function() {
},
'onclose': function() {
}
};
socket = channel.open(handler);
Here is the server side code in Python to open the channel:
class OpenChannel(webapp.RequestHandler):
def get(self):
user = users.get_current_user()
token = channel.create_channel(user.user_id())
serialized = json.dumps({'token': token})
self.response.headers['Content-Type'] = "application/json"
self.response.out.write(serialized)
What's my error and what can I do? Thanks!
It seems that Channel API works on localhost different way than on GAE hosting. I uploaded it to the cloud and it works well now. Though it looks like it working fine on the local computer, it shows permanent JS error repeating in the error log.
You could try removing the handler argument and adding the handlers as methods of the socket object i.e. socket.onopen = function() {}; etc. That worked for me. But you are right. According to this, you should be able to get this working by using the handler argument. Hmm.

Categories