Compare commits
3 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| e822ea36bf | |||
| cd767caac7 | |||
| 8b9766234b |
+29
-1
@@ -50,6 +50,7 @@ import socket
|
||||
import io
|
||||
import html
|
||||
import logging
|
||||
from logging.handlers import RotatingFileHandler
|
||||
import secrets
|
||||
import importlib
|
||||
try:
|
||||
@@ -76,10 +77,19 @@ from data_protection import (
|
||||
BASE_DIR = os.path.dirname(os.path.abspath(__file__))
|
||||
import settings as cfg
|
||||
from settings import MongoClient
|
||||
from tenant import get_tenant_context
|
||||
|
||||
|
||||
app = Flask(__name__, static_folder='static') # Correctly set static folder
|
||||
app.logger.setLevel(logging.WARNING)
|
||||
app.logger.setLevel(logging.INFO)
|
||||
if not os.path.exists(cfg.LOGS_FOLDER):
|
||||
os.makedirs(cfg.LOGS_FOLDER, exist_ok=True)
|
||||
log_file_path = os.path.join(cfg.LOGS_FOLDER, 'application.log')
|
||||
file_handler = RotatingFileHandler(log_file_path, maxBytes=10 * 1024 * 1024, backupCount=5, encoding='utf-8')
|
||||
file_handler.setLevel(logging.INFO)
|
||||
file_handler.setFormatter(logging.Formatter('%(asctime)s %(levelname)s %(name)s %(message)s'))
|
||||
app.logger.handlers = []
|
||||
app.logger.addHandler(file_handler)
|
||||
app.secret_key = cfg.SECRET_KEY
|
||||
app.debug = cfg.DEBUG
|
||||
app.config['UPLOAD_FOLDER'] = cfg.UPLOAD_FOLDER
|
||||
@@ -1092,6 +1102,15 @@ def inject_version():
|
||||
client.close()
|
||||
|
||||
current_module = _get_current_module(request.path)
|
||||
current_tenant_db = MONGODB_DB
|
||||
current_tenant_id = None
|
||||
try:
|
||||
ctx = get_tenant_context()
|
||||
if ctx:
|
||||
current_tenant_db = ctx.db_name or current_tenant_db
|
||||
current_tenant_id = ctx.tenant_id
|
||||
except Exception:
|
||||
current_tenant_db = MONGODB_DB
|
||||
|
||||
return {
|
||||
'APP_VERSION': APP_VERSION,
|
||||
@@ -1104,6 +1123,8 @@ def inject_version():
|
||||
'is_admin': is_admin,
|
||||
'unread_notification_count': unread_notification_count,
|
||||
'current_permissions': current_permissions,
|
||||
'current_tenant_db': current_tenant_db,
|
||||
'current_tenant_id': current_tenant_id,
|
||||
'permission_action_options': PERMISSION_ACTION_OPTIONS,
|
||||
'permission_page_options': PERMISSION_PAGE_OPTIONS,
|
||||
'permission_presets': us.get_permission_preset_definitions(),
|
||||
@@ -4036,13 +4057,19 @@ def login():
|
||||
if request.method == 'POST':
|
||||
username = request.form['username']
|
||||
password = request.form['password']
|
||||
ctx = get_tenant_context()
|
||||
current_tenant_id = ctx.tenant_id if ctx else None
|
||||
current_tenant_db = ctx.db_name if ctx else cfg.MONGODB_DB
|
||||
app.logger.info(f"Login attempt: username={username!r} tenant={current_tenant_id or 'default'} db={current_tenant_db} host={request.host} ip={request.remote_addr}")
|
||||
if not username or not password:
|
||||
app.logger.warning(f"Login blocked: missing credentials tenant={current_tenant_id or 'default'} host={request.host} ip={request.remote_addr}")
|
||||
flash('Bitte alle Felder ausfüllen', 'error')
|
||||
return redirect(url_for('login'))
|
||||
|
||||
user = us.check_nm_pwd(username, password)
|
||||
|
||||
if user:
|
||||
app.logger.info(f"Login success: username={username!r} tenant={current_tenant_id or 'default'} db={current_tenant_db} host={request.host} ip={request.remote_addr}")
|
||||
session['username'] = username
|
||||
is_admin_user = bool(user.get('Admin', False))
|
||||
session['admin'] = is_admin_user
|
||||
@@ -4063,6 +4090,7 @@ def login():
|
||||
else:
|
||||
return redirect(url_for('home'))
|
||||
else:
|
||||
app.logger.warning(f"Login failed: username={username!r} tenant={current_tenant_id or 'default'} db={current_tenant_db} host={request.host} ip={request.remote_addr}")
|
||||
flash('Ungültige Anmeldedaten', 'error')
|
||||
get_flashed_messages()
|
||||
return render_template('login.html')
|
||||
|
||||
+15
-1
@@ -191,6 +191,17 @@
|
||||
white-space: nowrap;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.navbar-text.tenant-badge {
|
||||
font-size: 0.82rem;
|
||||
color: rgba(255,255,255,0.9);
|
||||
background: rgba(255,255,255,0.12);
|
||||
border: 1px solid rgba(255,255,255,0.18);
|
||||
padding: 0.25rem 0.55rem;
|
||||
border-radius: 999px;
|
||||
white-space: nowrap;
|
||||
margin-right: 0.75rem;
|
||||
}
|
||||
|
||||
.navbar-brand::before {
|
||||
content: attr(data-icon);
|
||||
@@ -1113,7 +1124,10 @@
|
||||
<button class="function-search-btn" type="submit">Los</button>
|
||||
</form>
|
||||
</div>
|
||||
<span class="navbar-text text-light me-3">{{ session['username'] }}</span>
|
||||
{% if current_tenant_db %}
|
||||
<span class="navbar-text tenant-badge" title="Aktive Tenant-Datenbank">{{ current_tenant_db }}</span>
|
||||
{% endif %}
|
||||
<span class="navbar-text text-light me-3">{{ session['username'] }}</span>
|
||||
<div class="dropdown me-2 user-menu-wrap">
|
||||
<button class="btn btn-secondary dropdown-toggle user-menu-btn" type="button" id="invUserMenuDropdown" data-bs-toggle="dropdown" aria-expanded="false" data-notification-button="true">
|
||||
👤
|
||||
|
||||
@@ -14,6 +14,15 @@
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-md-6">
|
||||
<h2 class="text-center">Login</h2>
|
||||
{% if current_tenant_id or current_tenant_db %}
|
||||
<div class="alert alert-info text-center small mb-4" role="alert">
|
||||
{% if current_tenant_id %}
|
||||
Aktiver Tenant: <strong>{{ current_tenant_id }}</strong> · Datenbank: <strong>{{ current_tenant_db }}</strong>
|
||||
{% else %}
|
||||
Aktive Datenbank: <strong>{{ current_tenant_db }}</strong>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endif %}
|
||||
<form method="POST" action="{{ url_for('login') }}">
|
||||
<div class="mb-3">
|
||||
<label for="username" class="form-label">Username</label>
|
||||
|
||||
@@ -128,7 +128,9 @@ class TenantContext:
|
||||
if tenant_from_port:
|
||||
self.tenant_id = tenant_from_port
|
||||
self.config = get_tenant_config(tenant_from_port)
|
||||
logger.info(f"Tenant resolution by port: host={host} port={port} tenant={tenant_from_port}")
|
||||
return self._get_db_name(tenant_from_port)
|
||||
logger.info(f"Tenant port not mapped: host={host} port={port}")
|
||||
|
||||
# Priority 3: Subdomain extraction
|
||||
parts = host.split('.')
|
||||
@@ -144,7 +146,9 @@ class TenantContext:
|
||||
self.subdomain = potential_subdomain
|
||||
self.tenant_id = potential_subdomain
|
||||
self.config = get_tenant_config(potential_subdomain)
|
||||
logger.info(f"Tenant resolution by subdomain: host={host} tenant={potential_subdomain}")
|
||||
return self._get_db_name(potential_subdomain)
|
||||
logger.info(f"Tenant subdomain ignored: {potential_subdomain}")
|
||||
|
||||
# Fallback to default tenant if no tenant identifier found.
|
||||
# If no explicit 'default' tenant config exists, use configured MongoDB DB.
|
||||
|
||||
Reference in New Issue
Block a user