10
10
import logging
11
11
from jose import jws
12
12
13
-
14
13
class VapidException (Exception ):
14
+ """An exception wrapper for Vapid."""
15
15
pass
16
16
17
17
@@ -24,12 +24,14 @@ class Vapid(object):
24
24
def __init__ (self , private_key_file = None , private_key = None ):
25
25
"""Initialize VAPID using an optional file containing a private key
26
26
in PEM format.
27
-
28
27
:param private_key_file: The name of the file containing the
29
28
private key
30
29
"""
31
30
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 ()
33
35
if private_key :
34
36
try :
35
37
if "BEGIN EC" in private_key :
@@ -38,47 +40,59 @@ def __init__(self, private_key_file=None, private_key=None):
38
40
self ._private_key = \
39
41
ecdsa .SigningKey .from_der (
40
42
base64 .urlsafe_b64decode (private_key ))
41
- except Exception , exc :
43
+ except Exception as exc :
42
44
logging .error ("Could not open private key file: %s" , repr (exc ))
43
45
raise VapidException (exc )
44
- self ._pubilcKey = self ._private_key .get_verifying_key ()
46
+ self ._public_key = self ._private_key .get_verifying_key ()
45
47
46
48
@property
47
49
def private_key (self ):
50
+ """Return the private key."""
48
51
if not self ._private_key :
49
52
raise VapidException (
50
53
"No private key defined. Please import or generate a key." )
51
54
return self ._private_key
52
55
53
56
@private_key .setter
54
57
def private_key (self , value ):
58
+ """Set the private key."""
55
59
self ._private_key = value
56
60
57
61
@property
58
62
def public_key (self ):
63
+ """Return the public key."""
59
64
if not self ._public_key :
60
65
self ._public_key = self .private_key .get_verifying_key ()
61
66
return self ._public_key
62
67
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
+
63
78
def generate_keys (self ):
64
79
"""Generate a valid ECDSA Key Pair."""
65
80
self .private_key = ecdsa .SigningKey .generate (curve = ecdsa .NIST256p )
66
81
self .public_key
67
82
68
83
def save_key (self , key_file ):
69
84
"""Save the private key to a PEM file."""
70
- file = open (key_file , "w " )
85
+ file = open (key_file , "wb " )
71
86
if not self ._private_key :
72
87
self .generate_keys ()
73
88
file .write (self ._private_key .to_pem ())
74
89
file .close ()
75
90
76
91
def save_public_key (self , key_file ):
77
92
"""Save the public key to a PEM file.
78
-
79
93
:param key_file: The name of the file to save the public key
80
94
"""
81
- with open (key_file , "w " ) as file :
95
+ with open (key_file , "wb " ) as file :
82
96
file .write (self .public_key .to_pem ())
83
97
file .close ()
84
98
@@ -88,20 +102,21 @@ def validate(self, token):
88
102
token = base64 .urlsafe_b64encode (sig )
89
103
return token
90
104
91
- def verifyToken (self , sig , token ):
105
+ def verify_token (self , sig , token ):
106
+ """Verify the signature against the token."""
92
107
hsig = base64 .urlsafe_b64decode (sig )
93
108
return self .public_key .verify (hsig , token ,
94
109
hashfunc = self ._hasher )
95
110
96
111
def sign (self , claims , crypto_key = None ):
97
112
"""Sign a set of claims.
98
-
99
113
:param claims: JSON object containing the JWT claims to use.
100
114
:param crypto_key: Optional existing crypto_key header content. The
101
115
vapid public key will be appended to this data.
102
116
:returns result: a hash containing the header fields to use in
103
117
the subscription update.
104
118
"""
119
+ from jose import jws
105
120
if not claims .get ('exp' ):
106
121
claims ['exp' ] = int (time .time ()) + 86400
107
122
if not claims .get ('sub' ):
0 commit comments