1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
|
from functools import wraps
from flask import Blueprint, Flask, Response, request, url_for, redirect, g, render_template, session, abort, current_app
auth = Blueprint('auth', __name__)
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('auth.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('auth.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 current_app.config and \
'ADMIN_PASSWORD' in current_app.config and \
username == current_app.config['ADMIN_USERNAME'] and pw == current_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("auth.login")}">Unauthorized! Invalid admin credential... returning to login form', 401)
@auth.route("/logout")
@auth.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
@auth.route("/login/new")
@auth.route("/login/new/")
def login_new():
return redirect(url_for("auth.login", new=""))
@auth.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("auth.login_form"))
elif request.method == "POST":
if request.authorization:
return redirect(url_for("auth.login_basic"),code=307)
return redirect(url_for("auth.login_generic"))
#return f"Authentication method not supported yet.",400
@auth.route("/login/basic",methods=['POST','GET'])
@auth.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("auth.login_generic"),code=307)
@auth.route("/login/form", methods=['POST','GET'])
@auth.route("/login/form/", methods=['POST','GET'])
def login_form():
if request.method == "GET":
return render_template("login_form.html",
login_url = url_for("auth.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("auth.login_generic"), code=307)
@auth.route("/login/generic", methods=['POST','GET'])
@auth.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)
session.permanent = True
session['user']=user
return resp
|