Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
vapid_data = {}
webpush_settings = getattr(settings, 'WEBPUSH_SETTINGS', {})
vapid_private_key = webpush_settings.get('VAPID_PRIVATE_KEY')
vapid_admin_email = webpush_settings.get('VAPID_ADMIN_EMAIL')
# Vapid keys are optional, and mandatory only for Chrome.
# If Vapid key is provided, include vapid key and claims
if vapid_private_key:
vapid_data = {
'vapid_private_key': vapid_private_key,
'vapid_claims': {"sub": "mailto:{}".format(vapid_admin_email)}
}
try:
req = webpush(subscription_info=subscription_data, data=payload, ttl=ttl, **vapid_data)
return req
except WebPushException as e:
# If the subscription is expired, delete it.
if e.response.status_code == 410:
subscription.delete()
else:
# Its other type of exception!
raise e
def notifyNewAgent():
dashboard_notifications = db.session.query(DashboardRegistration).all()
if dashboard_notifications is not None:
for registration in dashboard_notifications:
try:
webpush(
subscription_info={
"endpoint": registration.endpoint,
"keys": {
"p256dh": registration.authKey,
"auth": registration.authSecret
}
},
data="",
vapid_private_key="./private_key.pem",
vapid_claims={
"sub": "mailto:YourNameHere@example.org",
}
)
except WebPushException as ex:
print(ex)
return
def _send_webpush(subscription_info: dict, data: dict) -> bool:
"""
Send a webpush message asynchronously
"""
if not WEB_PUSH_ENABLED:
return False
json_data = json.dumps(data)
try:
webpush(
subscription_info=subscription_info,
data=json_data,
vapid_private_key=VAPID_PRIVATE_KEY,
vapid_claims=VAPID_CLAIMS,
)
return True
except WebPushException as error:
logger.error(error)
# Mozilla returns additional information in the body of the response.
if error.response and error.response.json():
logger.error(error.response.json())
return False
except TypeError as error:
logger.error(error)
raise error
async def send_web_push(subscription_information, message_body):
claims = dict(settings.VAPID_CLAIMS)
try:
return webpush(
subscription_info=subscription_information,
data=message_body,
vapid_private_key=settings.VAPID_PRIVATE_KEY,
vapid_claims=claims,
)
except WebPushException as ex:
logger.exception("Exception while trying to send push notification")
if ex.response and ex.response.json():
extra = ex.response.json()
logger.info(
"Remote service replied with a %s:%s, %s",
extra.code,
extra.errno,
extra.message,
)
def main():
""" Send data """
try:
args = get_config()
result = webpush(
args.sub_info,
data=args.data,
vapid_private_key=args.key,
vapid_claims=args.claims,
curl=args.curl,
content_encoding=args.encoding,
verbose=args.verbose)
print(result)
except Exception as ex:
print("ERROR: {}".format(ex))
:param data: A serialized block of byte data (String, JSON, bit array,
etc.) Make sure that whatever you send, your client knows how
to understand it.
:type data: str
:param content_encoding: The content_encoding type to use to encrypt
the data. Defaults to RFC8188 "aes128gcm". The previous draft-01 is
"aesgcm", however this format is now deprecated.
:type content_encoding: enum("aesgcm", "aes128gcm")
"""
# Salt is a random 16 byte array.
if not data:
self.verb("No data found...")
return
if not self.auth_key or not self.receiver_key:
raise WebPushException("No keys specified in subscription info")
self.verb("Encoding data...")
salt = None
if content_encoding not in self.valid_encodings:
raise WebPushException("Invalid content encoding specified. "
"Select from " +
json.dumps(self.valid_encodings))
if content_encoding == "aesgcm":
self.verb("Generating salt for aesgcm...")
salt = os.urandom(16)
# The server key is an ephemeral ECDH key used only for this
# transaction
server_key = ec.generate_private_key(ec.SECP256R1, default_backend())
crypto_key = server_key.public_key().public_bytes(
encoding=serialization.Encoding.X962,
format=serialization.PublicFormat.UncompressedPoint
)
:param content_encoding: The content_encoding type to use to encrypt
the data. Defaults to RFC8188 "aes128gcm". The previous draft-01 is
"aesgcm", however this format is now deprecated.
:type content_encoding: enum("aesgcm", "aes128gcm")
"""
# Salt is a random 16 byte array.
if not data:
self.verb("No data found...")
return
if not self.auth_key or not self.receiver_key:
raise WebPushException("No keys specified in subscription info")
self.verb("Encoding data...")
salt = None
if content_encoding not in self.valid_encodings:
raise WebPushException("Invalid content encoding specified. "
"Select from " +
json.dumps(self.valid_encodings))
if content_encoding == "aesgcm":
self.verb("Generating salt for aesgcm...")
salt = os.urandom(16)
# The server key is an ephemeral ECDH key used only for this
# transaction
server_key = ec.generate_private_key(ec.SECP256R1, default_backend())
crypto_key = server_key.public_key().public_bytes(
encoding=serialization.Encoding.X962,
format=serialization.PublicFormat.UncompressedPoint
)
if isinstance(data, six.text_type):
data = bytes(data.encode('utf8'))
if content_encoding == "aes128gcm":
if 'endpoint' not in subscription_info:
raise WebPushException("subscription_info missing endpoint URL")
self.subscription_info = deepcopy(subscription_info)
self.auth_key = self.receiver_key = None
if 'keys' in subscription_info:
keys = self.subscription_info['keys']
for k in ['p256dh', 'auth']:
if keys.get(k) is None:
raise WebPushException("Missing keys value: {}".format(k))
if isinstance(keys[k], six.text_type):
keys[k] = bytes(keys[k].encode('utf8'))
receiver_raw = base64.urlsafe_b64decode(
self._repad(keys['p256dh']))
if len(receiver_raw) != 65 and receiver_raw[0] != "\x04":
raise WebPushException("Invalid p256dh key specified")
self.receiver_key = receiver_raw
self.auth_key = base64.urlsafe_b64decode(
self._repad(keys['auth']))
to the same client.
:type requests_session: requests.Session
:param verbose: provide verbose feedback
:type verbose: bool
"""
self.verbose = verbose
if requests_session is None:
self.requests_method = requests
else:
self.requests_method = requests_session
if 'endpoint' not in subscription_info:
raise WebPushException("subscription_info missing endpoint URL")
self.subscription_info = deepcopy(subscription_info)
self.auth_key = self.receiver_key = None
if 'keys' in subscription_info:
keys = self.subscription_info['keys']
for k in ['p256dh', 'auth']:
if keys.get(k) is None:
raise WebPushException("Missing keys value: {}".format(k))
if isinstance(keys[k], six.text_type):
keys[k] = bytes(keys[k].encode('utf8'))
receiver_raw = base64.urlsafe_b64decode(
self._repad(keys['p256dh']))
if len(receiver_raw) != 65 and receiver_raw[0] != "\x04":
raise WebPushException("Invalid p256dh key specified")
self.receiver_key = receiver_raw
self.auth_key = base64.urlsafe_b64decode(
self._repad(keys['auth']))