other authentication

trunk
HeNine 3 years ago
parent fb2132dd16
commit 770a97387a

@ -49,9 +49,9 @@ CREATE TABLE buscribe_verifiers
);
-- For testing
INSERT INTO buscribe_verifiers(email, name)
VALUES ('placeholder@example.com', 'Place Holder'),
('aguy@example.com', 'Arnold Guyana');
-- INSERT INTO buscribe_verifiers(email, name)
-- VALUES ('placeholder@example.com', 'Place Holder'),
-- ('aguy@example.com', 'Arnold Guyana');
CREATE TABLE buscribe_line_speakers
(

@ -13,10 +13,10 @@ from professor_api.professor_api import app
def cors(app):
"""WSGI middleware that sets CORS headers"""
HEADERS = [
("Access-Control-Allow-Credentials", "false"),
("Access-Control-Allow-Headers", "*"),
("Access-Control-Allow-Credentials", "true"),
("Access-Control-Allow-Headers", "content-type"),
("Access-Control-Allow-Methods", "GET,HEAD,POST,PUT"),
("Access-Control-Allow-Origin", "*"),
("Access-Control-Allow-Origin", "http://localhost:63342,https://wubloader.raptorpond.com"),
("Access-Control-Expose-Headers", "*"),
("Access-Control-Max-Age", "86400"),
]

@ -1,5 +1,6 @@
import re
import urllib.parse
from functools import wraps
import flask
import gevent
@ -8,9 +9,51 @@ from flask import jsonify, request, copy_current_request_context
from gevent import sleep
from psycopg2.extras import execute_values
from google.oauth2 import id_token
from google.auth.transport import requests
app = flask.Flask('buscribe')
def authenticate(f):
"""Authenticate a token against the database.
Reference: https://developers.google.com/identity/sign-in/web/backend-auth
https://developers.google.com/identity/gsi/web/guides/verify-google-id-token#using-a-google-api-client-library"""
@wraps(f)
def auth_wrapper(*args, **kwargs):
try:
user_token = request.cookies.get("credentials")
print(user_token)
except (KeyError, TypeError):
return 'User token required', 401
try:
idinfo = id_token.verify_oauth2_token(user_token, requests.Request(),
"164084252563-kaks3no7muqb82suvbubg7r0o87aip7n.apps.googleusercontent.com")
if idinfo['iss'] not in ['accounts.google.com', 'https://accounts.google.com']:
raise ValueError('Wrong issuer.')
except ValueError:
return 'Invalid token. Access denied.', 403
# check whether user is in the database
email = idinfo['email'].lower()
conn = app.db_manager.get_conn()
results = database.query(conn, """
SELECT email
FROM buscribe_verifiers
WHERE lower(email) = %s""", email)
row = results.fetchone()
if row is None:
return 'Unknown user. Access denied.', 403
return f(*args, editor=email, **kwargs)
return auth_wrapper
@app.route('/professor/line/<int:line_id>', methods=["GET"])
def get_line(line_id):
db_conn = app.db_manager.get_conn()
@ -47,7 +90,8 @@ def get_playlist(line_id):
@app.route('/professor/line/<int:line_id>', methods=["POST"])
def update_line(line_id):
@authenticate
def update_line(line_id, editor):
db_conn = app.db_manager.get_conn()
if "speakers" in request.json and \
@ -56,11 +100,11 @@ def update_line(line_id):
# Simpler than dealing with uniqueness
database.query(db_conn,
"DELETE FROM buscribe_line_speakers WHERE line = %(line_id)s AND verifier = %(verifier)s;",
line_id=line_id, verifier="placeholder@example.com")
line_id=line_id, verifier=editor)
execute_values(db_conn.cursor(),
"INSERT INTO buscribe_line_speakers(line, speaker, verifier) "
"VALUES %s;",
[(line_id, speaker, "placeholder@example.com") for speaker in
[(line_id, speaker, editor) for speaker in
request.json["speakers"]])
if "transcription" in request.json and \
isinstance(request.json["transcription"], str) and \
@ -70,11 +114,11 @@ def update_line(line_id):
database.query(db_conn,
"DELETE FROM buscribe_verified_lines WHERE line = %(line_id)s AND verifier = %(verifier)s;",
line_id=line_id, verifier="placeholder@example.com")
line_id=line_id, verifier=editor)
database.query(db_conn,
"INSERT INTO buscribe_verified_lines(line, verified_line, verifier) "
"VALUES (%(line)s, %(verified_line)s, %(verifier)s)",
line=line_id, verified_line=verified_line, verifier="placeholder@example.com")
line=line_id, verified_line=verified_line, verifier=editor)
return "", 204
@ -101,7 +145,8 @@ def get_speaker(speaker_id):
@app.route('/professor/speaker', methods=["PUT"])
def new_speaker():
@authenticate
def new_speaker(editor=None):
name = request.json
if not isinstance(name, str):

@ -11,6 +11,7 @@ setup(
"psycogreen",
"wubloader-common",
"python-dateutil",
"flask"
"flask",
"google-auth"
],
)

@ -51,9 +51,6 @@
<!-- data-logo_alignment="left">-->
<!--</div>-->
<div id="googleLoginButton" style="display: none"></div>
<div id="logout" style="display: none"><a href="javascript:doLogout()">Log out</a></div>
<div id="speakers">
<label for="speaker_input">Speakers</label><input id="speaker_input">
</div>
@ -65,6 +62,9 @@
<button id="submit_button" onclick="submit()" type="button">Submit</button><span id="update_indicator"></span>
<div id="googleLoginButton" style="display: none"></div>
<div id="logout" style="display: none"><a href="javascript:doLogout()">Log out</a></div>
<script src="video.js/dist/video.min.js"></script>
<script src="https://accounts.google.com/gsi/client" async defer></script>
<script>

@ -65,8 +65,6 @@ function doLogout() {
function loggedIn(response) {
// credentials = parseJwt(response.credential)
// TODO: add cookie storage specifiers
document.cookie = `credentials=${response.credential}`;
document.getElementById("googleLoginButton").style.display = "none";
@ -120,7 +118,8 @@ async function submit() {
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(speaker)
body: JSON.stringify(speaker),
credentials: "include"
}).then(response =>
parseInt(response.headers.get("Content-Location")
.split("/")
@ -133,7 +132,8 @@ async function submit() {
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({transcription: new_transcription, speakers: new_speakers})
body: JSON.stringify({transcription: new_transcription, speakers: new_speakers}),
credentials: "include"
}).then(response => {
if (response.ok) {
document.getElementById("update_indicator").innerText = "\u2714\ufe0f"

@ -61,3 +61,10 @@ button {
span.verified_cc {
color: #c1ffc1;
}
#logout {
padding: 0.1em;
a {
color: darkgray
}
}

Loading…
Cancel
Save