1
- import collections
2
1
import base64
3
2
import uuid
4
3
import hashlib
8
7
import requests
9
8
import boto
10
9
import boto .s3 .key
10
+ from boto .s3 .connection import OrdinaryCallingFormat
11
11
12
12
from flask import Flask
13
13
from flask import request
23
23
24
24
s3 = None
25
25
26
+
26
27
def s3key (email , name ):
27
28
global s3
28
29
if not s3 :
29
- s3 = boto .connect_s3 ()
30
- k = boto .s3 .key .Key (s3 .lookup (bucket_name ))
30
+ s3 = boto .connect_s3 (calling_format = OrdinaryCallingFormat ())
31
+ k = boto .s3 .key .Key (
32
+ s3 .get_bucket (bucket_name ))
31
33
k .key = '{}.{}' .format (email , name )
32
34
return k
33
35
36
+
34
37
def s3keys (email ):
35
38
global s3
36
39
if not s3 :
37
- s3 = boto .connect_s3 ()
40
+ s3 = boto .connect_s3 (calling_format = OrdinaryCallingFormat () )
38
41
b = s3 .get_bucket (bucket_name )
39
42
return b .list (prefix = email )
40
43
44
+
41
45
def lookup_key (email , name = None ):
42
46
name = name or 'default'
43
47
k = s3key (email , name )
@@ -46,60 +50,74 @@ def lookup_key(email, name=None):
46
50
except :
47
51
return None
48
52
53
+
49
54
def lookup_keys (email ):
50
55
keys = s3keys (email )
51
56
try :
52
57
return [k .get_contents_as_string () for k in keys ]
53
- except Exception , e :
58
+ except Exception :
54
59
return None
55
60
61
+
56
62
def upload_key (email , name , key ):
57
63
k = s3key (email , name )
58
64
k .set_contents_from_string (key .strip ())
59
65
66
+
60
67
def delete_key (email , name ):
61
68
k = s3key (email , name )
62
69
k .delete ()
63
70
71
+
64
72
def fingerprint (keystring ):
65
73
key = base64 .b64decode (keystring .split (' ' )[1 ])
66
74
fp = hashlib .md5 (key ).hexdigest ()
67
- return ':' .join (a + b for a ,b in zip (fp [::2 ], fp [1 ::2 ]))
75
+ return ':' .join (a + b for a , b in zip (fp [::2 ], fp [1 ::2 ]))
76
+
68
77
69
78
def confirm_key_upload (email , keyname , key ):
70
79
token = str (uuid .uuid4 ())
71
80
pending_actions [token ] = (upload_key , (email , keyname , key ))
72
81
schedule_action_expiration (token )
73
82
send_confirmation ('upload' , token , email )
74
83
84
+
75
85
def confirm_key_delete (email , keyname ):
76
86
token = str (uuid .uuid4 ())
77
87
pending_actions [token ] = (delete_key , (email , keyname ))
78
88
schedule_action_expiration (token )
79
89
send_confirmation ('delete' , token , email )
80
90
91
+
81
92
def schedule_action_expiration (token ):
82
- eventlet .spawn_after (action_expiry , lambda : pending_actions .pop (token , None ))
93
+ eventlet .spawn_after (action_expiry , lambda : pending_actions .pop (
94
+ token , None ))
95
+
83
96
84
97
def send_confirmation (action , token , email ):
85
98
if 'SENDGRID_USERNAME' in os .environ :
86
- requests .post ("https://sendgrid.com/api/mail.send.json" ,
99
+ requests .post (
100
+ "https://sendgrid.com/api/mail.send.json" ,
87
101
data = {
88
- 'api_user' :os .environ .get ('SENDGRID_USERNAME' ),
89
- 'api_key' :os .environ .get ('SENDGRID_PASSWORD' ),
90
- 'to' :email ,
91
- 'subject' :"Keychain.io {} Confirmation" .format (action .capitalize ()),
92
- 'from' :"robot@keychain.io" ,
93
- 'text' :"Click this link to confirm {}:\n {}{}/confirm/{}" .format (
94
- action , request .url_root , email , token )})
102
+ 'api_user' : os .environ .get ('SENDGRID_USERNAME' ),
103
+ 'api_key' : os .environ .get ('SENDGRID_PASSWORD' ),
104
+ 'to' : email ,
105
+ 'subject' : "Keychain.io {} Confirmation" .format (
106
+ action .capitalize ()),
107
+ 'from' : "robot@keychain.io" ,
108
+ 'text' : "Click this link to confirm {}:\n {}{}/confirm/{}"
109
+ .format (action , request .url_root , email , token )
110
+ })
95
111
else :
96
112
print ("Email to {} for {}: {}{}/confirm/{}" .format (
97
113
email , action , request .url_root , email , token ))
98
114
115
+
99
116
@app .route ('/' )
100
117
def index ():
101
118
return redirect ("http://github.com/progrium/keychain.io" )
102
119
120
+
103
121
@app .route ('/<email>/confirm/<token>' )
104
122
def confirm_action (email , token ):
105
123
if token not in pending_actions :
@@ -109,32 +127,39 @@ def confirm_action(email, token):
109
127
action [0 ](* action [1 ])
110
128
return "Action completed\n "
111
129
130
+
112
131
@app .route ('/<email>' , methods = ['GET' , 'PUT' , 'DELETE' ])
113
132
def default_key (email ):
114
133
return named_key (email , 'default' )
115
134
135
+
116
136
@app .route ('/<email>/upload' )
117
137
def default_upload (email ):
118
138
return named_key_action (email , 'default' , 'upload' )
119
139
140
+
120
141
@app .route ('/<email>/install' )
121
142
def default_install (email ):
122
143
return named_key_action (email , 'default' , 'install' )
123
144
145
+
124
146
@app .route ('/<email>/fingerprint' )
125
147
def default_fingerprint (email ):
126
148
return named_key_action (email , 'default' , 'fingerprint' )
127
149
150
+
128
151
@app .route ('/<email>/all' )
129
152
def all_keys (email ):
130
153
keys_ = lookup_keys (email )
131
154
return "{0}\n " .format ('\n ' .join (keys_ ))
132
155
156
+
133
157
@app .route ('/<email>/all/install' )
134
158
def all_install (email ):
135
159
keys_ = lookup_keys (email )
136
160
return render_template ('install.sh' , keys = keys_ )
137
161
162
+
138
163
@app .route ('/<email>/<keyname>' , methods = ['GET' , 'PUT' , 'DELETE' ])
139
164
def named_key (email , keyname ):
140
165
if request .method == 'PUT' :
@@ -160,6 +185,7 @@ def named_key(email, keyname):
160
185
else :
161
186
return "Key not found\n " , 404
162
187
188
+
163
189
@app .route ('/<email>/<keyname>/<action>' )
164
190
def named_key_action (email , keyname , action ):
165
191
if action == 'fingerprint' :
@@ -172,14 +198,13 @@ def named_key_action(email, keyname, action):
172
198
elif action == 'upload' :
173
199
keypath = request .args .get ('keypath' , '' )
174
200
url_root = request .url_root
175
- return render_template ('upload.sh' , email = email ,
176
- keyname = keyname , keypath = keypath , url_root = url_root )
201
+ return render_template (
202
+ 'upload.sh' , email = email ,
203
+ keyname = keyname , keypath = keypath , url_root = url_root )
177
204
178
205
elif action == 'install' :
179
206
key = lookup_key (email , keyname )
180
207
if key :
181
208
return render_template ('install.sh' , keys = [key ])
182
209
else :
183
210
return 'echo "No key to install."'
184
-
185
-
0 commit comments