2
2
import flask
3
3
import mysql .connector
4
4
5
+ # For Google OAuth token verification
6
+ from google .oauth2 import id_token as goog_token
7
+ from google .auth .transport import requests as goog_req
8
+
9
+ # Config.
10
+ # TODO: Place this in a config file
5
11
mysql_user = 'anonymous'
6
12
mysql_pwd = 'PiWaC!23CyZzkAYYpi&2S'
7
13
mysql_host = 'mysql1'
8
14
mysql_db = 'all_the_things'
15
+ #NOTE: Replace oauth_id with your own client ID
16
+ oauth_id = '42.apps.googleusercontent.com'
9
17
10
18
mydb = mysql .connector .connect (user = mysql_user , password = mysql_pwd ,
11
- host = mysql_host ,
12
- database = mysql_db )
19
+ host = mysql_host ,
20
+ database = mysql_db )
13
21
14
22
15
23
mycursor = mydb .cursor ()
18
26
19
27
print ("Hello python! This is {}" .format (sys .argv [0 ]))
20
28
print ("Listing lonely heroes:" )
21
- for i , name , copter in myresult :
22
- print ("ID: {}, Name: {}, Ponycopter: {}" .format (i , name , bool (copter )))
29
+ for i , name , email , copter , access , img in myresult :
30
+ print ("ID: {}, Name: {}, Email: {}, Ponycopter: {} Access: {} Img: {}"
31
+ .format (i , name , email , bool (copter ), access , img ))
23
32
24
33
#mydb.close()
25
34
26
- # The API
35
+ # The API
27
36
app = flask .Flask (__name__ , static_folder = "/var/fullstack/frontend" , static_url_path = "" )
28
37
29
38
@app .route ('/' , defaults = {'path' : 'index.html' })
@@ -34,16 +43,67 @@ def serve_page(path):
34
43
35
44
@app .route ('/api/users/' , methods = ['GET' ])
36
45
def get_users ():
37
- print ("Requested users" )
38
- mycursor = mydb .cursor ()
39
- mycursor .execute ("SELECT * FROM lonely_heroes" )
40
- myresult = mycursor .fetchall ()
41
- return flask .jsonify (myresult )
46
+ if flask .request .method == 'GET' :
47
+ print ("Requested users" )
48
+ mycursor = mydb .cursor ()
49
+ mycursor .execute ("SELECT * FROM lonely_heroes" )
50
+ myresult = mycursor .fetchall ()
51
+
52
+ auth_token = flask .request .headers .get ("Authorization" )
53
+ if (auth_token ):
54
+ print ("AUTHENTICATION ATTEMPT. Token: {}" .format (auth_token ))
55
+ valid_user = validate_token (auth_token )
56
+
57
+ if not valid_user :
58
+ return flask .jsonify ([])
59
+
60
+ print ("{} is a valid Google user" .format (valid_user ['given_name' ]))
61
+ auth_email = valid_user ['email' ]
62
+
63
+ # If the logged in user is registered and has a high access level
64
+ # add more secrets
65
+ access = 0
66
+ for id , name , email , pony , acc , img in myresult :
67
+ if email == auth_email :
68
+ print ("{} is a registered user in this app, access level {}"
69
+ .format (name , acc ))
70
+ access = acc
71
+
72
+ if (access >= 100 ):
73
+ morph_img = "https://www.denofgeek.com/wp-content/uploads/2020/08/the-matrix-4-morpheus.jpg?resize=768%2C432"
74
+ myresult .insert (0 , (43 , "Morpheus" ,None , True , 100 , morph_img ))
75
+
76
+ smith_img = "https://consequence.net/wp-content/uploads/2020/01/agent-smith-matrix-e1579642927212.jpg?quality=50"
77
+ myresult .insert (0 , (42 , "Agent Smith The Dangerous" ,None , True , 99 , smith_img ))
78
+
79
+ return flask .jsonify (myresult )
80
+
81
+
82
+ def validate_token (token ):
83
+ some_token = "eyJhbGciOiJSUzI1NiIsImtpZCI6IjY5ZWQ1N2Y0MjQ0OTEyODJhMTgwMjBmZDU4NTk1NGI3MGJiNDVhZTAiLCJ0eXAiOiJKV1QifQ.eyJpc3MiOiJhY2NvdW50cy5nb29nbGUuY29tIiwiYXpwIjoiMTk5MTgxNjM0NTkyLW04YmVuaTUzM2Y5ZThhYWJmZWRwZ2ZlZzc3dWhraTk1LmFwcHMuZ29vZ2xldXNlcmNvbnRlbnQuY29tIiwiYXVkIjoiMTk5MTgxNjM0NTkyLW04YmVuaTUzM2Y5ZThhYWJmZWRwZ2ZlZzc3dWhraTk1LmFwcHMuZ29vZ2xldXNlcmNvbnRlbnQuY29tIiwic3ViIjoiMTA2MDA0Mzg5OTc5NzEzNjc5ODc1IiwiZW1haWwiOiJkZXJlay5iaXBhcnRpc2FuQGdtYWlsLmNvbSIsImVtYWlsX3ZlcmlmaWVkIjp0cnVlLCJhdF9oYXNoIjoiejN6dW5vUUtDcGlDS2xrUHdmVjhrUSIsIm5hbWUiOiJEZXJlayBCaXBhcnRpc2FuIiwicGljdHVyZSI6Imh0dHBzOi8vbGgzLmdvb2dsZXVzZXJjb250ZW50LmNvbS9hL0FBVFhBSnlvdGZfSy01S0c2cFg4emZDX05JblI4OGpBbUE0V3ZSYXRUR1c3PXM5Ni1jIiwiZ2l2ZW5fbmFtZSI6IkRlcmVrIiwiZmFtaWx5X25hbWUiOiJCaXBhcnRpc2FuIiwibG9jYWxlIjoiZW4iLCJpYXQiOjE2MjAyOTUzNzQsImV4cCI6MTYyMDI5ODk3NCwianRpIjoiYmNlYmE0M2FkM2RlZTFhNjlmYjgwOTIxZGI4ZWJjNGY0ZGU3YzQxMCJ9.EyOWk8Sph7mawEy5HTSvCgQNWObVp6DmJEMp1fWgmcH6m4q6YNf2Ubge7M_dwP2zp39XoWPrgRQXs2hceFKVlhKnhvGVeVaxS4e-0C9hnQFfKUDTOFMjY-hgBd0UoP9N8cUIcK1MiLgatkRiajX9Rykdf2QSAxXQd0LkD1AAueoCyrwJsDyLnogzlBnvtCc_hN8r9_TLC7v-XBrZPeW3pOrsrmGzQkCnDCtTYg7TtFv-1r5p6OK74DB3x-BqRFVyp7u_9d-zxoG__8sq2WnocutwieXUSf7q1NNWGSzcba0SmOHpg35u5dqWFhGirZRRhTvHlI5D2lqGl1ctR7XWOA"
84
+ if (token == some_token ):
85
+ print ("Token is re-used. OK." )
86
+ return True
87
+ else :
88
+ print ("Never seen this token before..." )
89
+
90
+ try :
91
+ # Specify the CLIENT_ID of the app that accesses the backend:
92
+ idinfo = goog_token .verify_oauth2_token (token , goog_req .Request (), oauth_id )
93
+ print ("\n TOKEN VALID. User: {}\n User data: \n {}\n "
94
+ .format (idinfo ['given_name' ],idinfo ))
95
+ return idinfo
96
+
97
+ except ValueError as err :
98
+ # Invalid token
99
+ print (f"Token validation failed: { err } " )
100
+
101
+ return False
42
102
43
103
if __name__ == '__main__' :
44
104
# Note that flask by default listens to localhost / 127.0.0.1
45
105
# that's not going to work with docker port forwarding - localhost addresses
46
106
# are not allowed to escape the local network so they can't be forwarded out of
47
- # a docker network.
107
+ # a docker network.
48
108
app .run (host = "0.0.0.0" ) #debug=True)
49
109
mydb .close ()
0 commit comments