Skip to content
Snippets Groups Projects
Commit 9764d4db authored by Julian's avatar Julian
Browse files

OAuth2 skeleton code

parent b69d4f18
No related branches found
No related tags found
No related merge requests found
import secrets
import os
import datetime
import functools
from flask import Flask
from flask import Flask, session, request, redirect, abort, Response, url_for, render_template
from requests_oauthlib import OAuth2Session
from .models import *
from .base import bp as base
def create_app(test_config=None):
app = Flask(__name__)
......@@ -15,9 +17,66 @@ def create_app(test_config=None):
app.config.from_pyfile('config.py', silent=True)
else:
app.config.from_mapping(test_config)
# OAuth2Session.fetch_token verifies that the passed URIs scheme (the scheme
# of request.url) is HTTPS. The way we deploy this app, request.url does not
# reflect the actual request url, so we disable this check.
if app.debug:
os.environ['OAUTHLIB_INSECURE_TRANSPORT'] = '1'
db.init_app(app)
def user_required(func):
@functools.wraps(func)
def decorator(*args, **kwargs):
timestamp = datetime.datetime.fromtimestamp(session.get('timestamp', 0))
if datetime.datetime.utcnow() - timestamp > datetime.timedelta(minutes=30):
return redirect(url_for('oauth_login'))
if 'userinfo' not in session:
return redirect(url_for('oauth_login'))
user = User.query.filter_by(loginname=session['userinfo']['nickname']).one_or_none()
if user is None:
return render_template('error_unknown_user.html')
return func(*args, **kwargs)
return decorator
@app.route('/')
@user_required
def index():
return render_template('index.html')
@app.route('/create')
@user_required
def create_account():
return render_template('index.html')
@app.route('/oauth/login')
def oauth_login():
client = OAuth2Session(app.config['OAUTH2_CLIENT_ID'],
redirect_uri=url_for('oauth_callback', _external=True))
url, state = client.authorization_url(app.config['OAUTH2_AUTH_URL'])
session.clear()
session['timestamp'] = datetime.datetime.utcnow().timestamp()
session['oauth-state'] = state
return redirect(url)
@app.route('/oauth/callback')
def oauth_callback():
if 'oauth-state' not in session:
return redirect(url_for('oauth_login'))
timestamp = datetime.datetime.fromtimestamp(session.get('timestamp', 0))
if datetime.datetime.utcnow() - timestamp > datetime.timedelta(minutes=30):
return redirect(url_for('oauth_login'))
client = OAuth2Session(app.config['OAUTH2_CLIENT_ID'],
redirect_uri=url_for('oauth_callback', _external=True),
state=session['oauth-state'])
client.fetch_token(app.config['OAUTH2_TOKEN_URL'],
client_secret=app.config['OAUTH2_CLIENT_SECRET'],
authorization_response=request.url, verify=(not app.debug))
userinfo = client.get(app.config['OAUTH2_USERINFO_URL']).json()
session.clear()
session['timestamp'] = datetime.datetime.utcnow().timestamp()
session['userinfo'] = userinfo
return redirect(url_for('index'))
os.makedirs(app.instance_path, exist_ok=True)
with app.app_context():
db.create_all()
......
SQLALCHEMY_TRACK_MODIFICATIONS=False
# URLs of the OAuth2-based identity provider
OAUTH2_AUTH_URL = 'http://localhost:5000/oauth2/authorize'
OAUTH2_TOKEN_URL = 'http://localhost:5000/oauth2/token'
OAUTH2_USERINFO_URL = 'http://localhost:5000/oauth2/userinfo'
OAUTH2_CLIENT_ID = 'roac'
OAUTH2_CLIENT_SECRET = 'testsecret'
# CSRF protection
SESSION_COOKIE_SECURE=True
SESSION_COOKIE_HTTPONLY=True
SESSION_COOKIE_SAMESITE='Strict'
from flask_sqlalchemy import SQLAlchemy
db = SQLAlchemy()
class User(db.Model):
__tablename__ = 'user'
id = db.Column(db.Integer(), primary_key=True, autoincrement=True)
loginname = db.Column(db.String, nullable=False)
rocketchat_id = db.Column(db.String, nullable=True)
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment