1010import logging
1111from jose import jws
1212
13-
1413class VapidException (Exception ):
14+ """An exception wrapper for Vapid."""
1515 pass
1616
1717
@@ -24,12 +24,14 @@ class Vapid(object):
2424 def __init__ (self , private_key_file = None , private_key = None ):
2525 """Initialize VAPID using an optional file containing a private key
2626 in PEM format.
27-
2827 :param private_key_file: The name of the file containing the
2928 private key
3029 """
3130 if private_key_file :
32- private_key = open (private_key_file ).read ()
31+ if not os .path .isfile (private_key_file ):
32+ self .save_key (private_key_file )
33+ return
34+ private_key = open (private_key_file , 'r' ).read ()
3335 if private_key :
3436 try :
3537 if "BEGIN EC" in private_key :
@@ -38,47 +40,59 @@ def __init__(self, private_key_file=None, private_key=None):
3840 self ._private_key = \
3941 ecdsa .SigningKey .from_der (
4042 base64 .urlsafe_b64decode (private_key ))
41- except Exception , exc :
43+ except Exception as exc :
4244 logging .error ("Could not open private key file: %s" , repr (exc ))
4345 raise VapidException (exc )
44- self ._pubilcKey = self ._private_key .get_verifying_key ()
46+ self ._public_key = self ._private_key .get_verifying_key ()
4547
4648 @property
4749 def private_key (self ):
50+ """Return the private key."""
4851 if not self ._private_key :
4952 raise VapidException (
5053 "No private key defined. Please import or generate a key." )
5154 return self ._private_key
5255
5356 @private_key .setter
5457 def private_key (self , value ):
58+ """Set the private key."""
5559 self ._private_key = value
5660
5761 @property
5862 def public_key (self ):
63+ """Return the public key."""
5964 if not self ._public_key :
6065 self ._public_key = self .private_key .get_verifying_key ()
6166 return self ._public_key
6267
68+ @property
69+ def private_key_base64 (self ):
70+ """Return the base64'ed private key."""
71+ return base64 .urlsafe_b64encode (self .private_key .to_string ())
72+
73+ @property
74+ def public_key_base64 (self ):
75+ """Return the base64'ed public key."""
76+ return base64 .urlsafe_b64encode (self .public_key .to_string ())
77+
6378 def generate_keys (self ):
6479 """Generate a valid ECDSA Key Pair."""
6580 self .private_key = ecdsa .SigningKey .generate (curve = ecdsa .NIST256p )
6681 self .public_key
6782
6883 def save_key (self , key_file ):
6984 """Save the private key to a PEM file."""
70- file = open (key_file , "w " )
85+ file = open (key_file , "wb " )
7186 if not self ._private_key :
7287 self .generate_keys ()
7388 file .write (self ._private_key .to_pem ())
7489 file .close ()
7590
7691 def save_public_key (self , key_file ):
7792 """Save the public key to a PEM file.
78-
7993 :param key_file: The name of the file to save the public key
8094 """
81- with open (key_file , "w " ) as file :
95+ with open (key_file , "wb " ) as file :
8296 file .write (self .public_key .to_pem ())
8397 file .close ()
8498
@@ -88,20 +102,21 @@ def validate(self, token):
88102 token = base64 .urlsafe_b64encode (sig )
89103 return token
90104
91- def verifyToken (self , sig , token ):
105+ def verify_token (self , sig , token ):
106+ """Verify the signature against the token."""
92107 hsig = base64 .urlsafe_b64decode (sig )
93108 return self .public_key .verify (hsig , token ,
94109 hashfunc = self ._hasher )
95110
96111 def sign (self , claims , crypto_key = None ):
97112 """Sign a set of claims.
98-
99113 :param claims: JSON object containing the JWT claims to use.
100114 :param crypto_key: Optional existing crypto_key header content. The
101115 vapid public key will be appended to this data.
102116 :returns result: a hash containing the header fields to use in
103117 the subscription update.
104118 """
119+ from jose import jws
105120 if not claims .get ('exp' ):
106121 claims ['exp' ] = int (time .time ()) + 86400
107122 if not claims .get ('sub' ):
0 commit comments