From 684e41e5c356694a89f218fab47c7eaeb4b2bcde Mon Sep 17 00:00:00 2001 From: Swapnil9693 Date: Tue, 17 Feb 2026 15:25:57 +0530 Subject: [PATCH] log file added --- AppCode/LoginAuth.py | 28 +++++++++-- Dockerfile | 14 +----- docker-compose.yml | 33 ++++++++----- main.py | 69 +++++++++++++++++++++++++-- requirements.txt | 2 + templates/view_logs.html | 24 ++++++++++ templates/view_logs_auth.html | 90 +++++++++++++++++++++++++++++++++++ 7 files changed, 228 insertions(+), 32 deletions(-) create mode 100644 templates/view_logs.html create mode 100644 templates/view_logs_auth.html diff --git a/AppCode/LoginAuth.py b/AppCode/LoginAuth.py index 39d8655..d8c54e6 100644 --- a/AppCode/LoginAuth.py +++ b/AppCode/LoginAuth.py @@ -1,4 +1,5 @@ from flask import Blueprint, render_template, request, redirect, url_for, flash, session +import os from functools import wraps from ldap3 import Server, Connection, ALL from ldap3.core.exceptions import LDAPException @@ -12,7 +13,10 @@ class LoginAuth: # ------------------------------- # LDAP CONFIGURATION # ------------------------------- - self.LDAP_SERVER = "ldap://localhost:389" + self.LDAP_SERVER = os.getenv( + "LDAP_SERVER", + "ldap://host.docker.internal:389" +) self.BASE_DN = "ou=users,dc=lcepl,dc=org" # LDAP Users DN @@ -24,18 +28,16 @@ class LoginAuth: if request.method == 'POST': username = request.form.get("username") password = request.form.get("password") - if not username or not password: flash("Username and password are required!", "danger") return render_template("login.html") - user_dn = f"uid={username},{self.BASE_DN}" server = Server(self.LDAP_SERVER, get_info=ALL) - try: # Attempt LDAP bind conn = Connection(server, user=user_dn, password=password, auto_bind=True) if conn.bound: + session['user'] = username flash(f"Login successful! Welcome {username}", "success") return redirect(url_for('welcome')) @@ -46,10 +48,26 @@ class LoginAuth: finally: if 'conn' in locals(): conn.unbind() - # GET request: show login form return render_template("login.html") + + # LOGIN ROUTE + # @self.bp.route('/login', methods=['GET', 'POST']) + # def login(): + # if request.method == 'POST': + # username = request.form.get("username") + # password = request.form.get("password") + # # Dummy validation — REPLACE with DB check later + # if username == "admin" and password == "admin123": + # session['user'] = username + # flash("Login successful!", "success") + # return redirect(url_for('welcome')) + # else: + # flash("Invalid username or password!", "danger") + # return render_template("login.html") + + # ------------------------------- # LOGOUT ROUTE # ------------------------------- diff --git a/Dockerfile b/Dockerfile index 42dac6e..f073120 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,22 +1,12 @@ FROM python:3.11-slim -# Prevent Python buffering -ENV PYTHONDONTWRITEBYTECODE=1 -ENV PYTHONUNBUFFERED=1 - WORKDIR /app -# Install system deps (if needed later) -RUN apt-get update && apt-get install -y \ - build-essential \ - && rm -rf /var/lib/apt/lists/* - COPY requirements.txt . RUN pip install --no-cache-dir -r requirements.txt COPY . . -EXPOSE 5000 - -CMD ["python", "main.py"] +EXPOSE 5010 +CMD ["gunicorn", "--bind", "0.0.0.0:5010", "main:app"] diff --git a/docker-compose.yml b/docker-compose.yml index 62d4f52..6268cae 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,29 +1,40 @@ version: "3.9" services: + db: - image: mysql:8.0 - container_name: income_tax_db + image: mysql:8 + container_name: tax-mysql restart: always environment: - MYSQL_ROOT_PASSWORD: root - MYSQL_DATABASE: test_income_taxdb - ports: - - "3307:3306" + MYSQL_ROOT_PASSWORD: tiger + MYSQL_DATABASE: income_tax_db volumes: - mysql_data:/var/lib/mysql - - ./db/income_tax.sql:/docker-entrypoint-initdb.d/income_tax.sql - web: + flaskapp: build: . - container_name: income_tax_web + container_name: tax-flask restart: always ports: - "5010:5010" - env_file: - - .env depends_on: - db + environment: + DB_HOST: db + DB_PORT: 3306 + DB_USER: root + DB_PASSWORD: tiger + DB_NAME: income_tax_db + FLASK_HOST: 0.0.0.0 + FLASK_PORT: 5010 + FLASK_DEBUG: "false" + SECRET_KEY: secret1234 + LDAP_SERVER: ldap://host.docker.internal:389 # 👈 ADD THIS + LOG_VIEW_SECRET: super-log-2026 + volumes: + - /var/run/docker.sock:/var/run/docker.sock + - ./logs:/app/logs volumes: mysql_data: diff --git a/main.py b/main.py index 28750b1..091d39a 100644 --- a/main.py +++ b/main.py @@ -1,8 +1,7 @@ -from flask import Flask, render_template, request, redirect, url_for, send_from_directory, abort, flash,send_file ,jsonify +from flask import Flask, render_template, request, redirect, url_for, flash,send_file ,jsonify, session import os -from dotenv import load_dotenv +from dotenv import load_dotenv load_dotenv() -import pandas as pd from werkzeug.utils import secure_filename from datetime import date from AppCode.Config import DBConfig @@ -15,7 +14,6 @@ from AppCode.AOHandler import AOHandler from AppCode.CITHandler import CITHandler from AppCode.ITATHandler import ITATHandler from AppCode.MatCreditHandler import MatCreditHandler -import subprocess @@ -23,10 +21,51 @@ import subprocess app = Flask(__name__) app.secret_key=os.getenv("SECRET_KEY") + +import logging +import sys + +# Remove default handlers +if not os.path.exists("logs"): + os.mkdir("logs") + +file_handler = logging.FileHandler("logs/app.log") +file_handler.setLevel(logging.INFO) + +stream_handler = logging.StreamHandler() +stream_handler.setLevel(logging.INFO) + +formatter = logging.Formatter( + "%(asctime)s | %(levelname)s | User:%(user)s | %(message)s" +) + +file_handler.setFormatter(formatter) +stream_handler.setFormatter(formatter) + +app.logger.setLevel(logging.INFO) +app.logger.addHandler(file_handler) +app.logger.addHandler(stream_handler) + + + auth = LoginAuth() app.register_blueprint(auth.bp) + +@app.before_request +def log_user_activity(): + if request.endpoint and "static" not in request.endpoint: + user = session.get("user", "Anonymous") + ip = request.remote_addr + + + app.logger.info( + f"Accessed: {request.method} {request.path}", + extra={"user": user} + ) + + # welcome page @app.route('/') @auth.login_required @@ -590,6 +629,28 @@ def summary_preview_route(): handler = DocumentHandler() return handler.Summary_preview(request) +@app.route("/view_logs", methods=["GET", "POST"]) +@auth.login_required +def view_logs(): + secret = os.getenv("LOG_VIEW_SECRET") + + if request.method == "POST": + entered = request.form.get("secret") + + if entered != secret: + flash("Invalid secret!", "danger") + return render_template("view_logs_auth.html") + + try: + with open("logs/app.log", "r") as f: + logs = f.readlines() + except FileNotFoundError: + logs = ["Log file not found"] + + + return render_template("view_logs.html", logs=logs) + + return render_template("view_logs_auth.html") # save mat credit bulk data # @app.route("/save_mat_all", methods=["POST"]) diff --git a/requirements.txt b/requirements.txt index 094b0db..095a339 100644 --- a/requirements.txt +++ b/requirements.txt @@ -11,3 +11,5 @@ openpyxl==3.1.2 xlrd==2.0.1 gunicorn==21.2.0 + +ldap3 \ No newline at end of file diff --git a/templates/view_logs.html b/templates/view_logs.html new file mode 100644 index 0000000..b9f25eb --- /dev/null +++ b/templates/view_logs.html @@ -0,0 +1,24 @@ + + + + + + Document + + + +

Application Logs

+
{% for line in logs %} {{ line }} {% endfor %}
+ + diff --git a/templates/view_logs_auth.html b/templates/view_logs_auth.html new file mode 100644 index 0000000..edbdc71 --- /dev/null +++ b/templates/view_logs_auth.html @@ -0,0 +1,90 @@ + + + + + + View Logs - Authorization + + + + + + +
+

Enter Secret to View Logs

+ +
+ + +
+ + {% with messages = get_flashed_messages(with_categories=true) %} + {% for category, message in messages %} +
{{ message }}
+ {% endfor %} + {% endwith %} +
+ + +