Skip to content

Commit 979f77a

Browse files
committed
add logs
1 parent d881e10 commit 979f77a

1 file changed

Lines changed: 50 additions & 31 deletions

File tree

app/app.py

Lines changed: 50 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,46 @@
11
import os
2-
from flask import Flask, redirect, url_for, session, render_template_string, render_template
2+
import logging
3+
from logging.handlers import RotatingFileHandler
4+
5+
from flask import Flask, redirect, url_for, session, render_template, render_template_string
36
from authlib.integrations.flask_client import OAuth
47
from authlib.integrations.base_client.errors import OAuthError
58
from dotenv import load_dotenv
69
from functools import wraps
710

8-
# Загружаем переменные из .env файла
11+
# ─── Load environment ──────────────────────────────────────────────────────────
912
load_dotenv()
1013

14+
# ─── Flask app setup ──────────────────────────────────────────────────────────
1115
app = Flask(__name__)
12-
app.secret_key = os.getenv("FLASK_SECRET_KEY", "2tKBGXHD9rjlJQvV1Z7ukCkDeyOjWvF7")
16+
app.secret_key = os.getenv("FLASK_SECRET_KEY", "default_secret_key")
17+
18+
# ─── Logging to file ──────────────────────────────────────────────────────────
19+
# ensure logs directory exists
20+
os.makedirs("logs", exist_ok=True)
21+
22+
# configure root logger
23+
formatter = logging.Formatter(
24+
"%(asctime)s %(levelname)s %(name)s %(threadName)s : %(message)s"
25+
)
26+
27+
file_handler = RotatingFileHandler(
28+
filename="logs/flask-app.log",
29+
maxBytes=10 * 1024 * 1024, # 10 MB
30+
backupCount=5,
31+
encoding="utf-8"
32+
)
33+
file_handler.setLevel(logging.INFO)
34+
file_handler.setFormatter(formatter)
1335

14-
# Регистрация клиента OAuth
36+
# attach handler to Flask's and werkzeug's loggers
37+
app.logger.setLevel(logging.INFO)
38+
app.logger.addHandler(file_handler)
39+
logging.getLogger("werkzeug").addHandler(file_handler)
40+
41+
app.logger.info("Starting Flask application")
42+
43+
# ─── OAuth / Keycloak setup ───────────────────────────────────────────────────
1544
oauth = OAuth(app)
1645
oauth.register(
1746
name="keycloak",
@@ -20,103 +49,92 @@
2049
server_metadata_url=os.getenv("KEYCLOAK_METADATA_URL"),
2150
client_kwargs={
2251
"scope": "openid profile email",
23-
"prompt": "login" # всегда заставлять логиниться
52+
"prompt": "login",
2453
},
2554
)
2655

27-
# Декоратор для проверки ролей
56+
# ─── Role check decorator ──────────────────────────────────────────────────────
2857
def role_required(role):
2958
def decorator(f):
3059
@wraps(f)
3160
def decorated_function(*args, **kwargs):
3261
if 'user' not in session:
62+
app.logger.warning(f"Unauthorized access attempt to {url_for(f.__name__)}")
3363
return redirect(url_for('login'))
34-
3564
user_roles = session['user'].get('realm_access', {}).get('roles', [])
3665
if role not in user_roles:
66+
app.logger.warning(f"Forbidden: user lacks role '{role}' for {url_for(f.__name__)}")
3767
return "<h1>403 Forbidden</h1><p>You do not have permission to access this page.</p>", 403
38-
3968
return f(*args, **kwargs)
40-
4169
return decorated_function
4270
return decorator
4371

44-
# Главная страница
72+
# ─── Routes ────────────────────────────────────────────────────────────────────
4573
@app.route("/")
4674
def index():
4775
user = session.get("user")
48-
if user:
49-
return render_template('index.html', user=user)
50-
else:
51-
return render_template('index.html')
76+
return render_template('index.html', user=user)
5277

53-
# Страница входа
54-
@app.route("/login", methods=["GET"])
78+
@app.route("/login")
5579
def login():
5680
session.clear()
57-
nonce = os.urandom(16).hex() # Генерация nonce
81+
nonce = os.urandom(16).hex()
5882
session["nonce"] = nonce
5983
redirect_uri = url_for("auth", _external=True)
6084
return oauth.keycloak.authorize_redirect(redirect_uri, nonce=nonce)
6185

62-
# Обработка авторизации
6386
@app.route("/auth")
6487
def auth():
6588
try:
6689
token = oauth.keycloak.authorize_access_token()
67-
print("=== FULL TOKEN DATA ===")
68-
print(token)
69-
90+
app.logger.info(f"OAuth token received: {token.keys()}")
7091
nonce = session.pop("nonce", None)
7192
user = oauth.keycloak.parse_id_token(token, nonce=nonce)
7293
session["user"] = user
73-
return redirect("/")
94+
app.logger.info(f"User logged in: {user.get('preferred_username')}")
95+
return redirect(url_for("index"))
7496
except OAuthError as e:
97+
app.logger.error(f"OAuthError during auth: {e.error} - {e.description}")
7598
return f"<h1>Authentication failed</h1><p>{e.error}: {e.description}</p>", 400
7699
except Exception as e:
100+
app.logger.exception("Unexpected error during auth")
77101
return f"<h1>Unexpected error</h1><p>{str(e)}</p>", 500
78102

79-
# Общая защищённая страница (только вход)
80103
@app.route("/protected")
81104
def protected():
82105
if 'user' not in session:
83106
return "<h1>401 Unauthorized</h1><p>You must log in to access this page.</p>", 401
84107
return render_template('protected.html')
85108

86-
# Страница для администраторов
87109
@app.route("/admin")
88110
@role_required("admin")
89111
def admin():
90112
return render_template('admin.html')
91113

92-
# Страница для пользователей с ролью user
93114
@app.route("/user")
94115
@role_required("user")
95116
def user_page():
96117
return render_template('user.html')
97118

98-
# Страница для пользователей с ролью manager
99119
@app.route("/manager")
100120
@role_required("manager")
101121
def manager_page():
102122
return render_template('manager.html')
103123

104-
# Страница для пользователей с ролью viewer
105124
@app.route("/viewer")
106125
@role_required("viewer")
107126
def viewer_page():
108127
return render_template('viewer.html')
109128

110-
# Выход
111129
@app.route("/logout", methods=["POST"])
112130
def logout():
113131
session.clear()
114132
redirect_uri = url_for('index', _external=True)
115133
logout_url = f"{os.getenv('KEYCLOAK_LOGOUT_URL')}?redirect_uri={redirect_uri}"
116-
print("logout")
134+
app.logger.info("User logged out, redirecting to Keycloak logout")
117135
return redirect(logout_url)
118136

119-
# Обработчики ошибок
137+
# ─── Error handlers ────────────────────────────────────────────────────────────
120138
@app.errorhandler(401)
121139
def unauthorized_error(error):
122140
return render_template_string("<h1>401 Unauthorized</h1><p>You must log in to access this page.</p>"), 401
@@ -125,5 +143,6 @@ def unauthorized_error(error):
125143
def forbidden_error(error):
126144
return render_template_string("<h1>403 Forbidden</h1><p>You do not have permission to access this page.</p>"), 403
127145

146+
# ─── Main ─────────────────────────────────────────────────────────────────────
128147
if __name__ == "__main__":
129-
app.run(host="0.0.0.0", port=5000, debug=True)
148+
app.run(host="0.0.0.0", port=5000, debug=True)

0 commit comments

Comments
 (0)