Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Upgrade for newer Python version and fix for broadcast can't send issue #250

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 9 additions & 11 deletions Pipfile
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,12 @@ test = "python -m unittest discover -s tests -p 'test_*.py'"
[dev-packages]

[packages]
netaddr = "==0.7.18"
oauth2client = "==4.1.3"
pymongo = "==3.5.1"
requests = "==2.21.0"
tornado = "~=6.0"
click = "*"
sentry-sdk = "==0.13.2"
aiocontextvars = "*"
hyper = "*"
pyjwt = "*"
cryptography = "*"
netaddr = "~=1.3.0"
google-auth = "~=2.35.0"
requests = "~=2.32.3"
pymongo = "~=4.10.1"
tornado = "~=6.4.1"
click = "~=8.1.7"
sentry-sdk = "~=2.15.0"
pyjwt = "~=2.9.0"
httpx = {extras = ["http2"], version = "~=0.27.2"}
464 changes: 281 additions & 183 deletions Pipfile.lock

Large diffs are not rendered by default.

32 changes: 18 additions & 14 deletions api/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -224,7 +224,7 @@ def add_to_log(self, action, info=None, level="info"):
log["info"] = strip_tags(info)
log["level"] = strip_tags(level)
log["created"] = int(time.time())
self.db.logs.insert(log)
self.db.logs.insert_one(log)


class EntityBuilder(object):
Expand All @@ -250,7 +250,7 @@ def delete(self, token):
return

try:
result = self.db.tokens.remove({"token": token})
result = self.db.tokens.delete_one({"token": token})
if result["n"] == 0:
self.send_response(NOT_FOUND, dict(status="Token does't exist"))
else:
Expand Down Expand Up @@ -278,7 +278,7 @@ def post(self, devicetoken):
else:
try:
binascii.unhexlify(devicetoken)
except Exception as ex:
except Exception:
self.send_response(BAD_REQUEST, dict(error="Invalid token"))
else:
# if it's not ios then we force FCM type device here
Expand All @@ -288,18 +288,22 @@ def post(self, devicetoken):

token = EntityBuilder.build_token(devicetoken, device, self.appname, channel)
try:
result = self.db.tokens.update(
result = self.db.tokens.update_one(
{"device": device, "token": devicetoken, "appname": self.appname},
token,
{"$set": token},
upsert=True,
)
# result
# {u'updatedExisting': True, u'connectionId': 47, u'ok': 1.0, u'err': None, u'n': 1}
if result["updatedExisting"]:
if result.modified_count > 0:
self.send_response(OK, dict(status="token exists"))
else:
elif result.upserted_id is not None:
self.send_response(OK, dict(status="ok"))
self.add_to_log("Add token", devicetoken)
elif result.matched_count > 0:
self.send_response(OK, dict(status="ok"))
self.add_to_log("No update because of same token", devicetoken)

except Exception as ex:
self.add_to_log("Cannot add token", devicetoken, "warning")
self.send_response(INTERNAL_SERVER_ERROR, dict(error=str(ex)))
Expand All @@ -325,7 +329,7 @@ def post(self):
if cursor:
self.send_response(BAD_REQUEST, dict(error="email already exists"))
else:
userid = self.db.users.insert(user)
userid = self.db.users.insert_one(user)
self.add_to_log("Add user", email)
self.send_response(OK, {"userid": str(userid)})
except Exception as ex:
Expand Down Expand Up @@ -372,7 +376,7 @@ def delete(self, classname, objectId):
"""
self.classname = classname
self.objectid = ObjectId(objectId)
result = self.db[self.collection].remove({"_id": self.objectid})
result = self.db[self.collection].delete_one({"_id": self.objectid})
self.send_response(OK, dict(result=result))

def put(self, classname, objectId):
Expand All @@ -381,7 +385,7 @@ def put(self, classname, objectId):
self.classname = classname
data = json_decode(self.request.body)
self.objectid = ObjectId(objectId)
result = self.db[self.collection].update({"_id": self.objectid}, data)
result = self.db[self.collection].update_one({"_id": self.objectid}, {"$set": data})

@property
def collection(self):
Expand All @@ -404,7 +408,7 @@ def collection(self):
col["collection"] = self.classname
col["created"] = int(time.time())
self.add_to_log("Register collection", self.classname)
self.db.objects.insert(col)
self.db.objects.insert_one(col)

collectionname = "%s%s" % (options.collectionprefix, self.classname)
return collectionname
Expand Down Expand Up @@ -439,8 +443,8 @@ def post(self, classname):
self.send_response(BAD_REQUEST, ex)

self.add_to_log("Add object to %s" % self.classname, data)
objectId = self.db[self.collection].insert(data)
self.send_response(OK, dict(objectId=objectId))
object_id = self.db[self.collection].insert_one(data)
self.send_response(OK, dict(objectId=object_id))


@route(r"/accesskeys/")
Expand Down Expand Up @@ -470,7 +474,7 @@ def post(self):
| API_PERMISSIONS["send_broadcast"][0]
)
key["key"] = md5(str(uuid.uuid4())).hexdigest()
self.db.keys.insert(key)
self.db.keys.insert_one(key)
self.send_response(OK, dict(accesskey=key["key"]))

def verify_request(self):
Expand Down
4 changes: 2 additions & 2 deletions api/accesskeys.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@

from api import APIBaseHandler
from routes import route
from util import *
from util import create_access_key, json_decode


@route(r"/api/v2/accesskeys[\/]?")
Expand Down Expand Up @@ -74,7 +74,7 @@ def post(self):
key["created"] = int(time.time())
key["permission"] = data["permission"]
key["key"] = create_access_key()
self.db.keys.insert(key)
self.db.keys.insert_one(key)
self.send_response(OK, dict(accesskey=key["key"]))
except Exception as ex:
self.send_response(FORBIDDEN, dict(error=str(ex)))
16 changes: 10 additions & 6 deletions api/tokens.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ def delete(self, token):
return

try:
result = self.db.tokens.remove({"token": token})
result = self.db.tokens.delete_one({"token": token})
if result["n"] == 0:
self.send_response(NOT_FOUND, dict(status="Token does't exist"))
else:
Expand Down Expand Up @@ -76,23 +76,27 @@ def post(self):
return
try:
binascii.unhexlify(devicetoken)
except Exception as ex:
except Exception:
self.send_response(BAD_REQUEST, dict(error="Invalid token"))

token = EntityBuilder.build_token(devicetoken, device, self.appname, channel)
try:
result = self.db.tokens.update(
result = self.db.tokens.update_one(
{"device": device, "token": devicetoken, "appname": self.appname},
token,
{"$set": token},
upsert=True,
)
# result
# {u'updatedExisting': True, u'connectionId': 47, u'ok': 1.0, u'err': None, u'n': 1}
if result["updatedExisting"]:
print(result)
if result.modified_count > 0:
self.add_to_log("Token exists", devicetoken)
self.send_response(OK)
else:
elif result.upserted_id is not None:
self.add_to_log("Add token", devicetoken)
self.send_response(OK)
elif result.matched_count > 0:
self.add_to_log("No update because of same token", devicetoken)
self.send_response(OK)
except Exception as ex:
self.send_response(INTERNAL_SERVER_ERROR, dict(error=str(ex)))
4 changes: 2 additions & 2 deletions app.py
Original file line number Diff line number Diff line change
Expand Up @@ -70,13 +70,13 @@
if options.sentrydsn:
sentry_sdk.init(dsn=options.sentrydsn, integrations=[TornadoIntegration()])
else:
logging.warn("Sentry dsn is not set")
logging.warning("Sentry dsn is not set")

mongodb = None
while not mongodb:
try:
mongodb = pymongo.MongoClient(options.mongouri)
except:
except Exception:
logging.error("Cannot not connect to MongoDB")

masterdb = mongodb[options.masterdb]
Expand Down
6 changes: 4 additions & 2 deletions controllers/auth.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,10 @@
# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
import hashlib, os
from controllers.base import *
from controllers.base import WebBaseHandler
from tornado.options import options
from routes import route
from util import get_password


@route(r"/auth/([^/]+)")
Expand Down
31 changes: 16 additions & 15 deletions controllers/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,14 +28,15 @@

from routes import route
import platform
import sys
import os
import tornado.web
import time
from constants import DEVICE_TYPE_IOS, VERSION
from pymongo import DESCENDING
from util import *
from util import get_password
from tornado.options import options
from dao import Dao
import sys
from bson import ObjectId


def buildUpdateFields(params):
Expand All @@ -46,7 +47,7 @@ def buildUpdateFields(params):

def normalize_tokens(tokens):
for token in tokens:
if not "device" in token:
if "device" not in token:
token["device"] = DEVICE_TYPE_IOS
return tokens

Expand Down Expand Up @@ -107,11 +108,11 @@ def currentuser(self):
def get_current_user(self):
""" Get current user from cookie """

userid = self.get_secure_cookie("user")
if not userid:
cookie_user_id = self.get_secure_cookie("user")
if not cookie_user_id:
return None
userId = ObjectId(userid.decode("utf-8"))
user = self.masterdb.managers.find_one({"_id": userId})
user_id = ObjectId(cookie_user_id.decode("utf-8"))
user = self.masterdb.managers.find_one({"_id": user_id})
return user

def render_string(self, template_name, **kwargs):
Expand Down Expand Up @@ -151,7 +152,7 @@ def post(self, appname):
app = self.masterdb.applications.find_one({"shortname": appname})
if not app:
raise tornado.web.HTTPError(500)
self.masterdb.applications.remove({"shortname": appname})
self.masterdb.applications.delete_one({"shortname": appname})
self.mongodbconnection.drop_database(appname)
self.redirect(r"/applications")

Expand Down Expand Up @@ -182,7 +183,7 @@ def post(self, appname):
self.appname = appname
now = int(time.time())
thirtydaysago = now - 60 * 60 * 24 * 30
self.db.logs.remove({"created": {"$lt": thirtydaysago}})
self.db.logs.delete_one({"created": {"$lt": thirtydaysago}})
self.redirect(r"/applications/%s/logs" % appname)


Expand Down Expand Up @@ -264,7 +265,7 @@ def get(self, action):
if self.get_argument("delete", None):
user_id = self.get_argument("delete", None)
if user_id:
self.masterdb.managers.remove({"_id": ObjectId(user_id)})
self.masterdb.managers.delete_one({"_id": ObjectId(user_id)})
self.redirect("/admin/managers")
return
currentuser_orgid = self.currentuser["orgid"]
Expand Down Expand Up @@ -296,11 +297,11 @@ def post(self, action):
user["orgid"] = int(self.get_argument("orgid", 0))
else:
user["orgid"] = currentuser_orgid
result = self.masterdb.managers.update(
{"email": user["email"]}, user, upsert=True
result = self.masterdb.managers.update_one(
{"email": user["email"]}, {"$set": user}, upsert=True
)
managers = self.masterdb.managers.find()
if result["updatedExisting"]:
if result.modified_count > 0:
self.render(
"managers.html",
managers=managers,
Expand All @@ -319,7 +320,7 @@ def post(self, action):
elif action == "changepassword":
password = self.get_argument("newpassword").strip()
passwordhash = get_password(password, options.passwordsalt)
self.masterdb.managers.update(
self.masterdb.managers.update_one(
{"email": self.currentuser["email"]},
{"$set": {"password": passwordhash}},
)
Expand Down
10 changes: 6 additions & 4 deletions controllers/broadcast.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

import tornado.web

from controllers.base import *
from routes import route
from controllers.base import WebBaseHandler


@route(r"/applications/([^/]+)/broadcast")
Expand All @@ -41,16 +41,18 @@ def get(self, appname):
raise tornado.web.HTTPError(500)
self.render("app_broadcast.html", app=app, sent=False)

# TODO: to check and implement for performance in case there are much devices
# to send the broadcast message.
@tornado.web.authenticated
def post(self, appname):
async def post(self, appname):
self.appname = appname
app = self.masterdb.applications.find_one({"shortname": appname})
if not app:
raise tornado.web.HTTPError(500)
alert = self.get_argument("notification").strip()
sound = "default"
channel = "default"
self.application.send_broadcast(
await self.application.send_broadcast(
self.appname, self.db, channel=channel, alert=alert, sound=sound
)
self.render("app_broadcast.html", app=app, sent=True)
Expand Down
12 changes: 7 additions & 5 deletions controllers/keys.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,11 @@
import sys, os
import tornado.web
from api import API_PERMISSIONS
from controllers.base import *
from util import *
from controllers.base import WebBaseHandler
from util import create_access_key
from routes import route
import logging
import time


@route(r"/applications/([^/]+)/keys")
Expand All @@ -55,7 +57,7 @@ def get(self, appname):
)
return
if key_to_be_deleted:
self.db.keys.remove({"key": key_to_be_deleted})
self.db.keys.delete_one({"key": key_to_be_deleted})
self.redirect("/applications/%s/keys" % appname)
self.render(
"app_keys.html",
Expand Down Expand Up @@ -87,9 +89,9 @@ def post(self, appname):
# Alternative key generator, this is SHORT
# crc = binascii.crc32(str(uuid.uuid4())) & 0xffffffff
# key['key'] = '%08x' % crc
keyObjectId = self.db.keys.insert(key)
self.db.keys.insert_one(key)
self.redirect("/applications/%s/keys" % appname)
else:
key["key"] = self.get_argument("accesskey").strip()
self.db.keys.update({"key": key["key"]}, key)
self.db.keys.update_one({"key": key["key"]}, {"$set": key})
self.redirect("/applications/%s/keys" % appname)
Loading