Skip to content

Commit 95fde7e

Browse files
committed
backend: add Google Authentication, update SQL layout, add secrets
1 parent e6832f1 commit 95fde7e

File tree

1 file changed

+71
-11
lines changed

1 file changed

+71
-11
lines changed

python_backend/server.py

Lines changed: 71 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,22 @@
22
import flask
33
import mysql.connector
44

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
511
mysql_user = 'anonymous'
612
mysql_pwd = 'PiWaC!23CyZzkAYYpi&2S'
713
mysql_host = 'mysql1'
814
mysql_db = 'all_the_things'
15+
#NOTE: Replace oauth_id with your own client ID
16+
oauth_id = '42.apps.googleusercontent.com'
917

1018
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)
1321

1422

1523
mycursor = mydb.cursor()
@@ -18,12 +26,13 @@
1826

1927
print("Hello python! This is {}".format(sys.argv[0]))
2028
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))
2332

2433
#mydb.close()
2534

26-
# The API
35+
# The API
2736
app = flask.Flask(__name__, static_folder="/var/fullstack/frontend", static_url_path="")
2837

2938
@app.route('/', defaults={'path': 'index.html'})
@@ -34,16 +43,67 @@ def serve_page(path):
3443

3544
@app.route('/api/users/', methods=['GET'])
3645
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("\nTOKEN VALID. User: {}\nUser 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
42102

43103
if __name__ == '__main__':
44104
# Note that flask by default listens to localhost / 127.0.0.1
45105
# that's not going to work with docker port forwarding - localhost addresses
46106
# are not allowed to escape the local network so they can't be forwarded out of
47-
# a docker network.
107+
# a docker network.
48108
app.run(host="0.0.0.0") #debug=True)
49109
mydb.close()

0 commit comments

Comments
 (0)