Add local admin login alongside Entra ID authentication

This commit is contained in:
nmemmert committed 2025-11-06 09:51:15 -05:00
1 parent ac4f2b0d32
commit 9bda3ab14b
3 files changed
+97 -3

No files matched your search

+77 -1
View File
@@ -17,6 +17,10 @@ TENANT_ID = os.getenv('TENANT_ID', 'your-tenant-id')
CLIENT_ID = os.getenv('CLIENT_ID', 'your-client-id')
CLIENT_SECRET = os.getenv('CLIENT_SECRET', 'your-client-secret')
# Admin Configuration
ADMIN_USERNAME = os.getenv('ADMIN_USERNAME', 'admin')
ADMIN_PASSWORD = os.getenv('ADMIN_PASSWORD', 'change-this-password')
oauth = OAuth(app)
microsoft = oauth.register(
name='microsoft',
@@ -31,7 +35,7 @@ ALLOWED_EXTENSIONS = {'pdf', 'zip'}
def login_required(f):
@wraps(f)
def decorated_function(*args, **kwargs):
if 'user' not in session:
if 'user' not in session and 'admin' not in session:
return redirect(url_for('login'))
return f(*args, **kwargs)
return decorated_function
@@ -54,9 +58,80 @@ def extract_names_from_pdf(pdf_path):
@app.route('/login')
def login():
return render_template_string('''
<!DOCTYPE html>
<html>
<head>
<title>Login</title>
<style>
body { font-family: Arial, sans-serif; background-color: #f4f4f4; margin: 0; padding: 20px; text-align: center; }
.login-container { background-color: #fff; padding: 30px; border-radius: 10px; box-shadow: 0 0 10px rgba(0,0,0,0.1); display: inline-block; margin: 20px; }
h1 { color: #333; }
.login-options { display: flex; justify-content: space-around; flex-wrap: wrap; }
.login-option { margin: 10px; }
a { color: #007bff; text-decoration: none; padding: 15px 30px; background-color: #007bff; color: white; border-radius: 5px; display: inline-block; }
a:hover { background-color: #0056b3; }
form { margin-top: 20px; }
input[type="text"], input[type="password"] { padding: 10px; margin: 5px; width: 200px; border: 1px solid #ccc; border-radius: 5px; }
input[type="submit"] { background-color: #28a745; color: white; border: none; padding: 10px 20px; border-radius: 5px; cursor: pointer; }
input[type="submit"]:hover { background-color: #218838; }
</style>
</head>
<body>
<img src="/static/trbc-logo-full.png" alt="Logo" width="200">
<h1>PDF Renamer Login</h1>
<div class="login-options">
<div class="login-option">
<h2>Microsoft Entra ID</h2>
<a href="/entra-login">Login with Microsoft</a>
</div>
<div class="login-option">
<h2>Admin Login</h2>
<form method="post" action="/admin-login">
<input type="text" name="username" placeholder="Username" required><br>
<input type="password" name="password" placeholder="Password" required><br>
<input type="submit" value="Admin Login">
</form>
</div>
</div>
</body>
</html>
''')
@app.route('/entra-login')
def entra_login():
redirect_uri = url_for('auth', _external=True)
return microsoft.authorize_redirect(redirect_uri)
@app.route('/admin-login', methods=['POST'])
def admin_login():
username = request.form.get('username')
password = request.form.get('password')
if username == ADMIN_USERNAME and password == ADMIN_PASSWORD:
session['admin'] = True
return redirect(url_for('upload_files'))
else:
return render_template_string('''
<!DOCTYPE html>
<html>
<head>
<title>Login Failed</title>
<style>
body { font-family: Arial, sans-serif; background-color: #f4f4f4; text-align: center; padding: 50px; }
.error { color: #dc3545; background-color: #f8d7da; padding: 20px; border-radius: 5px; border: 1px solid #f5c6cb; }
a { color: #007bff; text-decoration: none; }
</style>
</head>
<body>
<div class="error">
<h1>Login Failed</h1>
<p>Invalid username or password.</p>
<a href="/login">Try Again</a>
</div>
</body>
</html>
''')
@app.route('/auth')
def auth():
token = microsoft.authorize_access_token()
@@ -68,6 +143,7 @@ def auth():
@login_required
def logout():
session.pop('user', None)
session.pop('admin', None)
return redirect(url_for('login'))
@app.route('/', methods=['GET', 'POST'])