dcai / airnotifier Goto Github PK
View Code? Open in Web Editor NEWPush Notifications Server for Human Beings.
License: Other
Push Notifications Server for Human Beings.
License: Other
It's a pain to write checkbox/radiobox/select list in raw html.
This is a privacy issue, we are login messages/notifications that are private for the users.
In order to help debugging I think that a setting for enable logging "partial information" like the size of the message, and the access key used to send the notification will be ok
The access key are still present in the datbase/storage
This is somehow related to (and produces the same error as) issue #19 .
How to reproduce:
What happens:
Stacktrace:
Traceback (most recent call last): File "/usr/lib/python2.6/site-packages/tornado/web.py", line 1077, in _execute *self.path_args, **self.path_kwargs) File "/usr/lib/python2.6/site-packages/tornado/web.py", line 1892, in wrapper return method(self, *args, **kwargs) File "/opt/airnotifier-moodle/controllers/site_controller.py", line 275, in post gcm = self.gcmconnections[appname][0] KeyError: u'project_name'
Notes:
Is not clear for the user that Airnotifier needs to be restarted. The behaviour is different from APNs: there is no start/stop button.
Thank you for your work.
To create accesskeys
I didn't put certificates file but I'm running the server. I obtain infinite warnings:
[W 121116 03:57:18 apns:117] moodlehtml5app[0] is offline 1
[E 121116 03:57:18 iostream:297] Uncaught exception, closing connection.
Traceback (most recent call last):
File "/usr/local/lib/python2.7/dist-packages/tornado/iostream.py", line 270, in _handle_events
self._handle_connect()
File "/usr/local/lib/python2.7/dist-packages/tornado/iostream.py", line 700, in _handle_connect
**self._ssl_options)
File "/usr/lib/python2.7/ssl.py", line 381, in wrap_socket
ciphers=ciphers)
File "/usr/lib/python2.7/ssl.py", line 141, in init
ciphers)
SSLError: [Errno 336265218] _ssl.c:351: error:140B0002:SSL routines:SSL_CTX_use_PrivateKey_file:system lib
[E 121116 03:57:18 ioloop:334] Exception in I/O handler for fd 9
Traceback (most recent call last):
File "/usr/local/lib/python2.7/dist-packages/tornado/ioloop.py", line 327, in start
self._handlers[fd](fd, events)
File "/usr/local/lib/python2.7/dist-packages/tornado/iostream.py", line 270, in _handle_events
self._handle_connect()
File "/usr/local/lib/python2.7/dist-packages/tornado/iostream.py", line 700, in _handle_connect
**self._ssl_options)
File "/usr/lib/python2.7/ssl.py", line 381, in wrap_socket
ciphers=ciphers)
File "/usr/lib/python2.7/ssl.py", line 141, in init
ciphers)
SSLError: [Errno 336265218] _ssl.c:351: error:140B0002:SSL routines:SSL_CTX_use_PrivateKey_file:system lib
PS: not sure of the order.
JSON based http request body.
Related to: MOBILE-579
Messaging plugin: moodle-message_airnotifier
tornado.database is deprecated and I won't install anymore by default.
WIP
cc @mouneyrac
When broadcasting from the administration (I didn't test broadcasting from the api but I suppose it's the same) the server now crashes:
[E 121119 03:33:28 web:1085] Uncaught exception POST /applications/moodlehtml5app/broadcast (202.74.162.6)
HTTPRequest(protocol='http', host='notify.moodle.net:8801', method='POST', uri='/applications/moodlehtml5app/broadcast', version='HTTP/1.1', remote_ip='202.74.162.6', body='------WebKitFormBoundaryzUZ2TFuiGlNUZLn0\r\nContent-Disposition: form-data; name="appname"\r\n\r\nmoodlehtml5app\r\n------WebKitFormBoundaryzUZ2TFuiGlNUZLn0\r\nContent-Disposition: form-data; name="notification"\r\n\r\nho\r\n------WebKitFormBoundaryzUZ2TFuiGlNUZLn0--\r\n', headers={'Origin': 'http://notify.moodle.net:8801', 'Content-Length': '253', 'Accept-Language': 'en-US,en;q=0.8', 'Accept-Encoding': 'gzip,deflate,sdch', 'Host': 'notify.moodle.net:8801', 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,/;q=0.8', 'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_2) AppleWebKit/537.17 (KHTML, like Gecko) Chrome/24.0.1312.14 Safari/537.17', 'Accept-Charset': 'ISO-8859-1,utf-8;q=0.7,_;q=0.3', 'Connection': 'keep-alive', 'Referer': 'http://notify.moodle.net:8801/applications/moodlehtml5app/broadcast', 'Cache-Control': 'max-age=0', 'Cookie': 'user=NTA2YTZlYzdkMWEzYTYzNjIyMGU0YTcy|1352692359|dddfba63c7a046de3694ff8b56d8c40209e70f8f; __cfduid=dc1f9ba5e08a3e2171e9fca572ae34b631352968574', 'Content-Type': 'multipart/form-data; boundary=----WebKitFormBoundaryzUZ2TFuiGlNUZLn0'})
Traceback (most recent call last):
File "/usr/local/lib/python2.7/dist-packages/tornado/web.py", line 1042, in _execute
getattr(self, self.request.method.lower())(_args, *_kwargs)
File "/usr/local/lib/python2.7/dist-packages/tornado/web.py", line 1809, in wrapper
return method(self, *args, *_kwargs)
File "/home/airnotifier/app/controllers/site_controller.py", line 228, in post
count = len(self.apnsconnections[app['shortname']])
KeyError: u'moodlehtml5app'
I have this error about finish() being called twice. Here it happens when I send a notification POST request, but simply delete a token/access key in the airnotifier web admin to see this error. It happens almost all the time.
[I 120717 14:48:52 web:1393] 200 POST /notification/ (::1) 4.46ms
[E 120717 14:48:52 web:1031] Uncaught exception POST /notification/ (::1)
HTTPRequest(protocol='http', host='localhost:8801', method='POST', uri='/notification/', version='HTTP/1.1', remote_ip='::1', body='------------------------------63a8a43542cd\r\nContent-Disposition: form-data; name="alert"\r\n\r\nstudent student: test\r\n------------------------------63a8a43542cd\r\nContent-Disposition: form-data; name="token"\r\n\r\n96e3d3cc20fd890b6df5330f91a9d5688569ed6c84ea95aa6a57799b25f9f22c\r\n------------------------------63a8a43542cd\r\nContent-Disposition: form-data; name="url"\r\n\r\nhttp://jerome.moodle.local/~jerome/Moodle_HEAD/message/index.php?user=2&id=700014\r\n------------------------------63a8a43542cd--\r\n', headers={'Content-Length': '492', 'X-An-App-Name': 'moodle', 'Accept-Encoding': 'deflate, gzip', 'Accept': 'application/json', 'User-Agent': 'MoodleBot/1.0', 'Host': 'localhost:8801', 'X-An-App-Key': '0078798be19828b29d31c2b285f782e9', 'Expect': '100-continue', 'Content-Type': 'multipart/form-data; boundary=----------------------------63a8a43542cd'})
Traceback (most recent call last):
File "/Library/Python/2.7/site-packages/tornado-2.2.1-py2.7.egg/tornado/web.py", line 988, in _execute
getattr(self, self.request.method.lower())(_args, *_kwargs)
File "/Users/jerome/Documents/airnotifier/apihandlers.py", line 249, in post
self.send_response(dict(error=str(ex)))
File "/Users/jerome/Documents/airnotifier/apihandlers.py", line 109, in send_response
self.finish(data)
File "/Users/jerome/Documents/airnotifier/apihandlers.py", line 112, in finish
super(APIBaseHandler, self).finish(chunk)
File "/Library/Python/2.7/site-packages/tornado-2.2.1-py2.7.egg/tornado/web.py", line 636, in finish
raise RuntimeError("finish() called twice. May be caused "
RuntimeError: finish() called twice. May be caused by using async operations without the @asynchronous decorator.
[E 120717 14:48:52 web:686] Cannot send error response after headers written
[I 120717 14:48:52 web:1393] 200 POST /notification/ (::1) 2.44ms
[E 120717 14:48:52 web:1031] Uncaught exception POST /notification/ (::1)
HTTPRequest(protocol='http', host='localhost:8801', method='POST', uri='/notification/', version='HTTP/1.1', remote_ip='::1', body='------------------------------7c2b2d26e1ef\r\nContent-Disposition: form-data; name="alert"\r\n\r\nstudent student: test\r\n------------------------------7c2b2d26e1ef\r\nContent-Disposition: form-data; name="token"\r\n\r\n016169f56ff32fc7a8a4061f459fb86ffad348dbb785c4805a891020da2e3cd1\r\n------------------------------7c2b2d26e1ef\r\nContent-Disposition: form-data; name="url"\r\n\r\nhttp://jerome.moodle.local/~jerome/Moodle_HEAD/message/index.php?user=2&id=700014\r\n------------------------------7c2b2d26e1ef--\r\n', headers={'Content-Length': '492', 'X-An-App-Name': 'moodle', 'Accept-Encoding': 'deflate, gzip', 'Accept': 'application/json', 'User-Agent': 'MoodleBot/1.0', 'Host': 'localhost:8801', 'X-An-App-Key': '0078798be19828b29d31c2b285f782e9', 'Expect': '100-continue', 'Content-Type': 'multipart/form-data; boundary=----------------------------7c2b2d26e1ef'})
Traceback (most recent call last):
File "/Library/Python/2.7/site-packages/tornado-2.2.1-py2.7.egg/tornado/web.py", line 988, in _execute
getattr(self, self.request.method.lower())(_args, *_kwargs)
File "/Users/jerome/Documents/airnotifier/apihandlers.py", line 249, in post
self.send_response(dict(error=str(ex)))
File "/Users/jerome/Documents/airnotifier/apihandlers.py", line 109, in send_response
self.finish(data)
File "/Users/jerome/Documents/airnotifier/apihandlers.py", line 112, in finish
super(APIBaseHandler, self).finish(chunk)
File "/Library/Python/2.7/site-packages/tornado-2.2.1-py2.7.egg/tornado/web.py", line 636, in finish
raise RuntimeError("finish() called twice. May be caused "
RuntimeError: finish() called twice. May be caused by using async operations without the @asynchronous decorator.
[E 120717 14:48:52 web:686] Cannot send error response after headers written
[I 120717 14:48:52 web:1393] 200 POST /notification/ (::1) 41.43ms
[E 120717 14:48:52 web:1031] Uncaught exception POST /notification/ (::1)
HTTPRequest(protocol='http', host='localhost:8801', method='POST', uri='/notification/', version='HTTP/1.1', remote_ip='::1', body='------------------------------c40d1f28f2a7\r\nContent-Disposition: form-data; name="alert"\r\n\r\nstudent student: test\r\n------------------------------c40d1f28f2a7\r\nContent-Disposition: form-data; name="token"\r\n\r\n8ea8780e41bbb31cf4c50af08eab1e86bba5c95105fa504f0edd1073b4655462\r\n------------------------------c40d1f28f2a7\r\nContent-Disposition: form-data; name="url"\r\n\r\nhttp://jerome.moodle.local/~jerome/Moodle_HEAD/message/index.php?user=2&id=700014\r\n------------------------------c40d1f28f2a7--\r\n', headers={'Content-Length': '492', 'X-An-App-Name': 'moodle', 'Accept-Encoding': 'deflate, gzip', 'Accept': 'application/json', 'User-Agent': 'MoodleBot/1.0', 'Host': 'localhost:8801', 'X-An-App-Key': '0078798be19828b29d31c2b285f782e9', 'Expect': '100-continue', 'Content-Type': 'multipart/form-data; boundary=----------------------------c40d1f28f2a7'})
Traceback (most recent call last):
File "/Library/Python/2.7/site-packages/tornado-2.2.1-py2.7.egg/tornado/web.py", line 988, in _execute
getattr(self, self.request.method.lower())(_args, *_kwargs)
File "/Users/jerome/Documents/airnotifier/apihandlers.py", line 249, in post
self.send_response(dict(error=str(ex)))
File "/Users/jerome/Documents/airnotifier/apihandlers.py", line 109, in send_response
self.finish(data)
File "/Users/jerome/Documents/airnotifier/apihandlers.py", line 112, in finish
super(APIBaseHandler, self).finish(chunk)
File "/Library/Python/2.7/site-packages/tornado-2.2.1-py2.7.egg/tornado/web.py", line 636, in finish
raise RuntimeError("finish() called twice. May be caused "
RuntimeError: finish() called twice. May be caused by using async operations without the @asynchronous decorator.
[E 120717 14:48:52 web:686] Cannot send error response after headers written
cc @mouneyrac
Regardless of the language and library you use, the push notification payload is a JSON payload:
{
"aps": {
"badge": 10,
"alert": "Hello world!",
"sound": "cat.caf"
}
}
The aps token is the Apple APN data. You can add custom data to your payload as well:
{
"aps": {
"badge": 10,
"alert": "Hello world!",
"sound": "cat.caf"
},
"job_id": 1
}
In airnotifier it is not possible to send additional params as 'job_id' above.
Hi Dongsheng,
can you add a section on the README.md to explain how to install/run it for newbies ;)
cheers,
Jerome
PS: if I remember it, I'll write it, trying...
Hi Dongsheng,
is there any protection against a site sending million of notification in order to ban airnotifier server from Apple?
Clean up the handler mess
You can't crete an application id like com.moodle.moodlemobile
Currently some wiki pages are incomplete or contains errors. It would be good to keep it up to date.
Note that I'm currently working on http://docs.moodle.org/dev/Moodle_Mobile_Push_Notifications. I'll explain there Moodle push notification use case using Airnotifier and how to setup airnotifier for this Moodle use case. You may find some idea/info there for Airnotifier wiki.
I am getting the following error message while creating a new application in Airnotifier:
Traceback (most recent call last):
File "/usr/lib/python2.7/site-packages/tornado/web.py", line 1077, in _execute
_self.path_args, *_self.path_kwargs)
File "/usr/lib/python2.7/site-packages/tornado/web.py", line 1892, in wrapper
return method(self, _args, *_kwargs)
File "/var/airnotifier/controllers/settings.py", line 222, in post
self.render("app_settings.html", app=app, error=str(ex))
File "/usr/lib/python2.7/site-packages/tornado/web.py", line 524, in render
html = self.render_string(template_name, **kwargs)
File "/var/airnotifier/controllers/base.py", line 123, in render_string
return super(WebBaseHandler, self).render_string(template_name, **kwargs)
File "/usr/lib/python2.7/site-packages/tornado/web.py", line 631, in render_string
return t.generate(**namespace)
File "/usr/lib/python2.7/site-packages/tornado/template.py", line 270, in generate
return execute()
File "app_settings_html.generated.py", line 63, in _execute
_tmp = modules.TabBar(app, 'settings') # app_settings.html:8 (via base.html:49)
File "/usr/lib/python2.7/site-packages/tornado/web.py", line 1130, in render
rendered = self._active_modules[name].render(_args, *_kwargs)
File "/var/airnotifier/uimodules.py", line 13, in render
html = self.render_string("modules/tabbar.html", app=app, active=active)
File "/usr/lib/python2.7/site-packages/tornado/web.py", line 1940, in render_string
return self.handler.render_string(path, **kwargs)
File "/var/airnotifier/controllers/base.py", line 123, in render_string
return super(WebBaseHandler, self).render_string(template_name, **kwargs)
File "/usr/lib/python2.7/site-packages/tornado/web.py", line 631, in render_string
return t.generate(**namespace)
File "/usr/lib/python2.7/site-packages/tornado/template.py", line 270, in generate
return execute()
File "modules/tabbar_html.generated.py", line 12, in _execute
_tmp = app['shortname'] # modules/tabbar.html:3
TypeError: 'NoneType' object has no attribute 'getitem'
My Server Details are:
AirNotifier
Version
20140720
Tornado
Version
3.0
MongoDB
ok
1.0
OpenSSLVersion
bits
64
javascriptEngine
V8
version
2.6.4
allocator
tcmalloc
debug
False
compilerFlags
-Wnon-virtual-dtor -Woverloaded-virtual -fPIC -fno-strict-aliasing -ggdb -pthread -Wall -Wsign-compare -Wno-unknown-pragmas -Winvalid-pch -pipe -Werror -O3 -Wno-unused-function -Wno-deprecated-declarations -fno-builtin-memcmp
maxBsonObjectSize
16777216
sysInfo
Linux build7.nj1.10gen.cc 2.6.32-431.3.1.el6.x86_64 #1 SMP Fri Jan 3 21:39:27 UTC 2014 x86_64 BOOST_LIB_VERSION=1_49
loaderFlags
-fPIC -pthread -Wl,-z,now -rdynamic
gitVersion
3a830be0eb92d772aa855ebb711ac91d658ee910
Python
arch
('64bit', 'ELF')
modules
builtin, main, _ast, _codecs, _sre, _symtable, _warnings, _weakref, errno, exceptions, gc, imp, marshal, posix, pwd, signal, sys, thread, zipimport
machine
x86_64
platform
linux2
version
2.7.5 (default, Jun 17 2014, 18:11:42) [GCC 4.8.2 20140120 (Red Hat 4.8.2-16)]
build
Jun 17 2014 18:11:42
os
posix
compiler
GCC 4.8.2 20140120 (Red Hat 4.8.2-16)
Windows Push Notification Services (WNS) overview (Windows Runtime apps)
Scenario | Recommendation |
---|---|
New Silverlight 8.1 app | WNS |
Upgrading WP 8 app to a Silverlight 8.1 app and already using MPNS | WNS/MPNS |
Upgrading WP 8 app to a 8.1 app and want to add new notifications | WNS/MPNS |
I tried to send an invalid access key:
jerome:Moodle_HEAD jerome$ curl -i -H "Accept: application/json" -H "X-AN-APP-KEY: f6b15c1ac0606980c46f87c476c9f28e" -H "X-AN-APP-NAME: moodlehtml5app" -X POST http://notify.moodle.net:8801/tokens/847648764874678
HTTP/1.1 500 Internal Server Error
Content-Length: 93
X-Powered-By: AirNotifier/1.0
Content-Type: application/json; charset=utf-8
Server: TornadoServer/2.4
And an exception is raised on the server:
[E 121116 04:19:17 web:1085] Uncaught exception POST /tokens/847648764874678 (202.74.162.6)
HTTPRequest(protocol='http', host='notify.moodle.net:8801', method='POST', uri='/tokens/847648764874678', version='HTTP/1.1', remote_ip='202.74.162.6', body='', headers={'Host': 'notify.moodle.net:8801', 'X-An-App-Name': 'moodlehtml5app', 'X-An-App-Key': 'f6b15c1ac0606980c46f87c476c9f28e', 'Accept': 'application/json', 'User-Agent': 'curl/7.24.0 (x86_64-apple-darwin12.0) libcurl/7.24.0 OpenSSL/0.9.8r zlib/1.2.5'})
Traceback (most recent call last):
File "/usr/local/lib/python2.7/dist-packages/tornado/web.py", line 1037, in _execute
self.prepare()
File "/home/airnotifier/app/controllers/api_controller.py", line 79, in prepare
if not key.has_key('permission'):
AttributeError: 'NoneType' object has no attribute 'has_key'
[E 121116 04:19:17 web:1462] 500 POST /tokens/847648764874678 (202.74.162.6) 1.62ms
When I call the REST API to create a token, the token is created however I receive:
{"error": "No permission to create token"}
Stop using raw pymongo APIs
Separate tabs into different handlers.
Use header
Accept: application/vnd.airnotifier.v2+json
When not provided, use the older request handler
Messages to be sent to Airnotifier should be formatted to delete new lines (in both Windows and UNIX) formats.
The app may crash if receive a message with new lines
Upgraded to 2.0 fixed the issue, apparently $or is supported since 1.6 onward: http://www.mongodb.org/display/DOCS/Advanced+Queries#AdvancedQueries-%24or
The accesskeys endpoint needs fix.
I'm not sure about the issue but something is weird.
1- I created a access key that only create token (for the device to register)
2- I created a access key that only broadcast
3- I register the device with the 'create token' access key => it works
4- I broadcast from the web interface => it works
5- I try to broadcast with the 'broadcast' access key => it doesn't work.
To make it "works" in 5) I wrote before the for token in tokens:
tokens = self.db.tokens.find()
I uploaded the certificate.cer and key.p12 and when I press "Launch" I have this infinite error loop:
[W 130430 17:28:00 apns:117] moodlemobile[0] is offline 1
[I 130430 17:28:00 web:1514] 200 GET /applications/moodlemobile (202.74.162.6) 26.94ms
[E 130430 17:28:00 iostream:308] Uncaught exception, closing connection.
Traceback (most recent call last):
File "/usr/local/lib/python2.7/dist-packages/tornado/iostream.py", line 283, in _handle_events
self._handle_connect()
File "/usr/local/lib/python2.7/dist-packages/tornado/iostream.py", line 841, in _handle_connect
do_handshake_on_connect=False)
File "/usr/local/lib/python2.7/dist-packages/tornado/netutil.py", line 322, in ssl_wrap_socket
return ssl.wrap_socket(socket, *_dict(context, *_kwargs))
File "/usr/lib/python2.7/ssl.py", line 381, in wrap_socket
ciphers=ciphers)
File "/usr/lib/python2.7/ssl.py", line 141, in init
ciphers)
SSLError: [Errno 336265225] _ssl.c:351: error:140B0009:SSL routines:SSL_CTX_use_PrivateKey_file:PEM lib
[E 130430 17:28:00 ioloop:660] Exception in I/O handler for fd 11
Traceback (most recent call last):
File "/usr/local/lib/python2.7/dist-packages/tornado/ioloop.py", line 653, in start
self._handlers[fd](fd, events)
File "/usr/local/lib/python2.7/dist-packages/tornado/stack_context.py", line 241, in wrapped
callback(_args, *_kwargs)
File "/usr/local/lib/python2.7/dist-packages/tornado/iostream.py", line 283, in _handle_events
self._handle_connect()
File "/usr/local/lib/python2.7/dist-packages/tornado/iostream.py", line 841, in _handle_connect
do_handshake_on_connect=False)
File "/usr/local/lib/python2.7/dist-packages/tornado/netutil.py", line 322, in ssl_wrap_socket
return ssl.wrap_socket(socket, *_dict(context, *_kwargs))
File "/usr/lib/python2.7/ssl.py", line 381, in wrap_socket
ciphers=ciphers)
File "/usr/lib/python2.7/ssl.py", line 141, in init
ciphers)
SSLError: [Errno 336265225] _ssl.c:351: error:140B0009:SSL routines:SSL_CTX_use_PrivateKey_file:PEM lib
It should consume JSON entity too.
Instead the description the word "None" appears, this happens for both keys created in the app or using the API
If Airnotifier logs messages with html tags (including script) the javascript code is injected in the page
The message text must be filtered prior to be stored in the log table
And then when you delete one of those, all the applications with the same name are deleted
if self.permission & 1 == 1:
should be
if self.permission & 1 != 1:
I'll also add some () and some doc to make it a bit more clear.
ubuntu@ip-10-1-11-135:/home/airnotifier/app$ python airnotifier.py
Traceback (most recent call last):
File "airnotifier.py", line 139, in
apnsconns = init_apns()
File "airnotifier.py", line 133, in init_apns
apn = APNClient(app['environment'], app['certfile'], app['keyfile'], app['shortname'], instanceid)
KeyError: 'certfile'
Note:
a) when I previously killed the python process, the server was launch
b) I didn't any upload certificate files
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.