def test_generate_token_should_fail_if_user_id_too_long(self): user_id = 'A' * 165 pn_client = PushNotifications( 'INSTANCE_ID', 'SECRET_KEY' ) with self.assertRaises(ValueError) as e: pn_client.generate_token(user_id) self.assertIn('longer than the maximum of 164 chars', str(e.exception))
def test_generate_token_should_fail_if_user_id_not_a_string(self): user_id = False pn_client = PushNotifications( 'INSTANCE_ID', 'SECRET_KEY' ) with self.assertRaises(TypeError) as e: pn_client.generate_token(user_id) self.assertIn('user_id must be a string', str(e.exception))
def test_generate_token_should_return_token(self): user_id = 'user-0001' pn_client = PushNotifications( 'INSTANCE_ID', 'SECRET_KEY' ) token_object = pn_client.generate_token(user_id) self.assertIsInstance(token_object, dict) token_string = token_object.get('token') self.assertIsInstance(token_string, six.string_types) self.assertTrue(len(token_string) > 0) decoded_token = jwt.decode( token_string, 'SECRET_KEY', algorithm='HS256', ) expected_issuer = 'https://INSTANCE_ID.pushnotifications.pusher.com' expected_subject = user_id self.assertEquals(decoded_token.get('iss'), expected_issuer) self.assertEquals(decoded_token.get('sub'), expected_subject) self.assertIsNotNone(decoded_token.get('exp')) self.assertTrue(decoded_token.get('exp') > time.time())
def get_beams_token(request): username = request.headers['Username'] password = request.headers['Password'] user = authenticate(request, username=username, password=password) if user is None: return JsonResponse([{'login_status': 0}], safe=False) beams_client = PushNotifications(instance_id=settings.BEAMS_INSTANCE_ID, secret_key=settings.BEAMS_SECRET_KEY) beams_token = beams_client.generate_token(username) return JsonResponse(beams_token, safe=False)
class BeamsClient: beams_client: PushNotifications = None def __init__(self): self.beams_client = PushNotifications( instance_id=os.getenv("PUSHER_INSTANCE_ID"), secret_key=os.getenv("PUSHER_SECRET_KEY"), ) def generate_token(self, user_id): try: beams_token = self.beams_client.generate_token(user_id) return beams_token except Exception as e: print("[GENTK ERROR]", e) return None def push_notification(self, notification, user_ids): try: response = self.beams_client.publish_to_users( user_ids=user_ids, publish_body={ "apns": { "aps": { "alert": notification }, "data": notification["data"] }, "fcm": notification, "web": notification }, ) return response["publishId"] except Exception as e: print("[PUSHN ERROR]", e) return None
class AuthHandler: def __init__(self, helperHandler): self.helperHandler = helperHandler self.beams_client = PushNotifications( instance_id='7032df3e-e5a8-494e-9fc5-3b9f05a68e3c', secret_key= '8AC9B8AABB93DFE452B2EFC2714FCF923841B6740F97207F4512F240264FF493') self.userDao = UserDAO() self.containerDao = ContainerDAO() self.authDao = AuthDao() self.locationDao = LocationDao() def validateCode(self, request, userDao, authDao): f = '%Y-%m-%d %H:%M:%S' keys = ["code", "email"] dic = None try: dic = self.helperHandler.handleRequestAndAuth(request, keys, hasAuth=False) res = self.userDao.selectUser(dic["email"]) self.helperHandler.falseQueryCheck(res) except Exception as e: return json.dumps({"success": False, "message": str(e)}) user = res[1] userDic = user.userToDict() codefromtable = userDic["authCode"] authtime = userDic["authTime"] authtimets = datetime.strptime(authtime, f) timepassed = datetime.now() - authtimets if (dic['code'] != codefromtable): return json.dumps({ "success": False, "message": "Invalid verification code." }) elif (timepassed.total_seconds() >= 300): return json.dumps({ "success": False, "message": "Expired verification code" }) # create new auth if "/validateCode" in str(request): return self.newAuth(dic, userDic, user) resAuth = self.authDao.selectByEmail(dic['email']) auth = resAuth[1] # update the auth authDic = auth.authToDict() authDic["auth_token"] = self.helperHandler.id_generator(size=45) authDic["refresh_token"] = auth.refresh_token auth.dictToAuth(authDic) res = self.authDao.updateAuth(auth) auth = res[1] if type(auth) == str: return json.dumps({"success": res[0], "data": auth}) return json.dumps({"success": res[0], "data": auth.authToDict()}) def newAuth(self, dic, userDic, user): authDic = {} authDic["user"] = dic["email"] authDic["auth_token"] = self.helperHandler.id_generator(size=45) authDic["refresh_token"] = self.helperHandler.id_generator(size=45) authDic["expires_at"] = "" auth = Auth() auth.dictToAuth(authDic) self.authDao.deleteAuth(auth) res = self.authDao.insertAuth(auth) data = auth.authToDict() # fix userAuth as well userDic["authorized"] = "1" user.dictToUser(userDic) self.userDao.updateUser(user) return json.dumps({"success": res[0], "data": data}) # return it def loginErrorHandler(self, userDic, dic): message = None dencryptedpas = self.helperHandler.check_encrypted_password( dic["password"], userDic["password"]) print(dencryptedpas) if message is None and "authorized" in userDic and userDic[ "authorized"] == 0: message = "Email not found, please try signing up." if message is None and dencryptedpas == False: message = "Incorrect password." return message def login(self, request, userDao, authDao): dic = None keys = ["email", "password"] try: dic = self.helperHandler.handleRequestAndAuth(request, keys, hasAuth=False) resUser = self.userDao.selectUser(dic["email"]) self.helperHandler.falseQueryCheck(resUser) resAuth = self.authDao.selectByEmail(dic['email']) self.helperHandler.falseQueryCheck(resAuth) except Exception as e: return json.dumps({"success": False, "message": str(e)}) # handle login errors user = resUser[1] userDic = user.userToDict() errorRes = self.loginErrorHandler(userDic, dic) if errorRes is not None: return json.dumps({"success": False, "message": errorRes}) # retrieve auth auth = resAuth[1] # update the auth authDic = auth.authToDict() authDic["auth_token"] = self.helperHandler.id_generator(size=45) authDic["refresh_token"] = auth.refresh_token auth.dictToAuth(authDic) res = self.authDao.updateAuth(auth) auth = res[1] if type(auth) == str: return json.dumps({"success": res[0], "data": auth}) # return it return json.dumps({"success": res[0], "data": auth.authToDict()}) def refreshCode(self, request, authDao): dic = None keys = ["email", "refresh_token"] try: dic = self.helperHandler.handleRequestAndAuth(request, keys, hasAuth=False) res = self.authDao.selectByEmail(dic["email"]) self.helperHandler.falseQueryCheck(res) except Exception as e: return json.dumps({"success": False, "message": str(e)}) auth = res[1] message = None # refresh token mismatch authDic = auth.authToDict() if dic["refresh_token"] != authDic["refresh_token"]: message = "Invalid token" # handle is auth code is expired timeobj = datetime.strptime(authDic["expires_at"], '%Y-%m-%d %H:%M:%S') if datetime.now() >= timeobj: message = "Expired token" if message is not None: return json.dumps({"success": False, "message": message}) # return normal response authDic["token"] = self.helperHandler.id_generator(size=45) auth.dictToAuth(authDic) res = self.authDao.updateAuth(auth) return json.dumps({"success": True, "data": authDic}) def beams_auth(self, param): beams_token = self.beams_client.generate_token(param) return json.dumps(beams_token) def resendAuthCode(self, request, userDao, authDao): f = '%Y-%m-%d %H:%M:%S' authCode = None dictOfUserAttrib = None keys = ["email"] dic = None try: dic = self.helperHandler.handleRequestAndAuth(request, keys, hasAuth=False) except Exception as e: return json.dumps({"success": False, "message": str(e)}) user = User() user = self.userDao.selectUser(dic["email"]) if user[0] == False: return json.dumps({"success": user[0], "message": user[1]}) authtime = user[1].authTime authtimets = datetime.strptime(authtime, f) timepassed = datetime.now() - authtimets if (timepassed.total_seconds() < 300): self.helperHandler.sendEmail(user[1].email, user[1].authCode) return json.dumps({"success": True, "data": ""}) if (timepassed.total_seconds() > 300): authCode = self.helperHandler.genAuthcode() user[1].authCode = authCode user[1].authTime = datetime.now().strftime('%Y-%m-%d %H:%M:%S') userdic = user[1].userToDict() self.userDao.updateUser(user[1]) self.helperHandler.sendEmail(user[1].email, authCode) return json.dumps({"success": True, "data": ""}) return json.dumps({ "success": False, "message": "Error in resendAuthCode." })