aboutsummaryrefslogtreecommitdiff
path: root/stackbin.py
diff options
context:
space:
mode:
Diffstat (limited to 'stackbin.py')
-rwxr-xr-xstackbin.py146
1 files changed, 7 insertions, 139 deletions
diff --git a/stackbin.py b/stackbin.py
index 30b9066..56380e6 100755
--- a/stackbin.py
+++ b/stackbin.py
@@ -20,12 +20,12 @@
# Documentation: see README.md
from datetime import datetime, timedelta
from itsdangerous import Signer
-from flask import (Flask, Response, request, url_for, redirect, g, render_template, session, abort)
+from flask import Blueprint, Flask, Response, request, url_for, redirect, g, render_template, session, abort, current_app
from flask_sqlalchemy import SQLAlchemy
from werkzeug.middleware.proxy_fix import ProxyFix
from pytimeparse.timeparse import timeparse # python3-pytimeparse
import os
-from functools import wraps
+from stackbin_auth import auth, requires_session
# uwsgidecorators load will fail when using initdb.py but is also not necessary
try:
from uwsgidecorators import timer # python3-uwsgidecorators
@@ -68,6 +68,7 @@ def get_unsigned(string, salt="blank"):
return Signer(app.secret_key, salt=salt).unsign(str(string)).decode("utf-8")
app = Flask(__name__)
+app.register_blueprint(auth) # url_prefix='/'
try:
app.config.from_pyfile(os.environ['STACKBIN_CONF'])
except:
@@ -78,64 +79,6 @@ if "STATIC_FOLDER" in app.config:
if "TEMPLATE_FOLDER" in app.config:
app.template_folder=app.config["TEMPLATE_FOLDER"]
-def requires_session(function):
- '''
- Requires a valid session, provided by cookie!
- '''
- @wraps(function)
- def decorated(*args, **kwargs):
- if not session:
- #return Response("requires session",401)
- return redirect(url_for('login'))
- else:
- if 'user' not in session:
- return Response("User is not in this session.",401)
- s_user = session['user']
- c_user = request.cookies.get('user')
- print(f"session user: {s_user}")
- print(f"cookie user: {c_user}")
- if session['user'] != c_user:
- return Response("Wrong user for this session!.",401)
- # otherwise, everything is good!
- return function(s_user, [], *args,**kwargs)
- # catch-all
- #return Response("requires session",401)
- return redirect(url_for('login'))
- return decorated
-
-def requires_admin_credential(function):
- """
- Requires the user pass the correct admin credential configured
- in the conf file.
- """
- @wraps(function)
- def decorated(*args, **kwargs):
- # formdata is in session if we are coming from login_basic()
- form = session.get('formdata', None)
- if form:
- session.pop('formdata')
- if 'username' in form:
- username = form['username']
- if 'password' in form:
- pw = form['password']
- else:
- # then we are coming from the form with POST data
- if 'username' not in request.form or 'password' not in request.form:
- return _unauthorized_admin()
- username = request.form['username']
- pw = request.form['password']
- if 'ADMIN_USERNAME' in app.config and \
- 'ADMIN_PASSWORD' in app.config and \
- username == app.config['ADMIN_USERNAME'] and pw == app.config['ADMIN_PASSWORD']:
- return function(username, [], *args, **kwargs)
- else:
- return _unauthorized_admin()
-
- return decorated
-
-def _unauthorized_admin():
- return Response(f'<meta http-equiv="Refresh" content="4; url={url_for("login")}">Unauthorized! Invalid admin credential... returning to login form', 401)
-
def url_for_other_page(page):
args = request.view_args.copy()
args['page'] = page
@@ -377,86 +320,11 @@ def get_proxied_path():
app.wsgi_app = ProxyFix(app.wsgi_app,x_for=pl,x_host=pl,x_port=pl,x_prefix=pl,x_proto=pl)
return redirect(url_for('new_paste'))
-@app.route("/logout")
+# stubs, to simplify any templates that ask url_for("login")
+@app.route('/login/')
+def login(user="None"): True
@app.route("/logout/")
-def logout():
- resp = Response(f'<meta http-equiv="Refresh" content="1; url={url_for("new_paste")}">logged out')
- # not documented but is found on the Internet in a few random places:
- session.clear()
- #resp.set_cookie('user','',expires=0)
- return resp
-
-@app.route("/login/new")
-@app.route("/login/new/")
-def login_new():
- return redirect(url_for("login", new=""))
-@app.route("/login/", methods=['POST','GET'])
-def login(user="None"):
- if request.method == "GET":
- if 'user' in session and request.cookies.get('user') == session['user'] and (not 'new' in request.args):
- return redirect(url_for("admin"))
- auth_header = request.headers.get("Authorization")
- # default, show login form
- return redirect(url_for("login_form"))
- elif request.method == "POST":
- if request.authorization:
- return redirect(url_for("login_basic"),code=307)
- return redirect(url_for("login_generic"))
- #return f"Authentication method not supported yet.",400
-
-@app.route("/login/basic",methods=['POST','GET'])
-@app.route("/login/basic/",methods=['POST','GET'])
-def login_basic():
- if not request.authorization:
- return Response(f"Please provide username and password.",401,{'WWW-Authenticate': 'Basic'})
- if 'username' not in request.authorization:
- return Response(f"No username provided.",401)
- if 'password' not in request.authorization:
- return Response(f"No password provided.",401)
- username = request.authorization.username
- pw = request.authorization.password
- form={'username':username,'password':pw}
- session['formdata'] = form
- return redirect(url_for("login_generic"),code=307)
-
-@app.route("/login/form", methods=['POST','GET'])
-@app.route("/login/form/", methods=['POST','GET'])
-def login_form():
- if request.method == "GET":
- return render_template("login_form.html",
- login_url = url_for("login_form")
- )
- else:
- # assume it is a POST
- username=""
- if 'username' in request.form:
- username = request.form['username']
- password=""
- if 'password' in request.form:
- password = request.form['password']
- form={'username':username,'password':password}
- session['formdata'] = form
- return redirect(url_for("login_generic"), code=307)
-
-@app.route("/login/generic", methods=['POST','GET'])
-@app.route("/login/generic/", methods=['POST','GET'])
-@requires_admin_credential
-def login_generic(user,groups=[]):
- resp = Response(f'<meta http-equiv="Refresh" content="1; url={url_for("admin")}">success')
- session['user_id'] = "admin"
- resp = login_success(session,resp,user,groups)
- return resp
-
-def login_success(session,resp,user,groups=[]):
- resp.set_cookie('user',user)
- #end_time = datetime.datetime.now(datetime.timezone.utc) + app.permanent_session_lifetime
- #end_time_str = datetime.datetime.strftime(end_time,"%FT%TZ")
- #resp.set_cookie('timestamp',end_time_str)
- session.permanent = True
- session['user']=user
- #session['end_time'] = end_time_str
- print(f"DEBUG: got valid user {user}")
- return resp
+def logout(): True
# Initialize the database if it does not already exist
db.create_all()
bgstack15