log file added

This commit is contained in:
Swapnil9693
2026-02-17 15:25:57 +05:30
parent b8c289294d
commit 684e41e5c3
7 changed files with 228 additions and 32 deletions

View File

@@ -1,4 +1,5 @@
from flask import Blueprint, render_template, request, redirect, url_for, flash, session from flask import Blueprint, render_template, request, redirect, url_for, flash, session
import os
from functools import wraps from functools import wraps
from ldap3 import Server, Connection, ALL from ldap3 import Server, Connection, ALL
from ldap3.core.exceptions import LDAPException from ldap3.core.exceptions import LDAPException
@@ -12,7 +13,10 @@ class LoginAuth:
# ------------------------------- # -------------------------------
# LDAP CONFIGURATION # 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 self.BASE_DN = "ou=users,dc=lcepl,dc=org" # LDAP Users DN
@@ -24,18 +28,16 @@ class LoginAuth:
if request.method == 'POST': if request.method == 'POST':
username = request.form.get("username") username = request.form.get("username")
password = request.form.get("password") password = request.form.get("password")
if not username or not password: if not username or not password:
flash("Username and password are required!", "danger") flash("Username and password are required!", "danger")
return render_template("login.html") return render_template("login.html")
user_dn = f"uid={username},{self.BASE_DN}" user_dn = f"uid={username},{self.BASE_DN}"
server = Server(self.LDAP_SERVER, get_info=ALL) server = Server(self.LDAP_SERVER, get_info=ALL)
try: try:
# Attempt LDAP bind # Attempt LDAP bind
conn = Connection(server, user=user_dn, password=password, auto_bind=True) conn = Connection(server, user=user_dn, password=password, auto_bind=True)
if conn.bound: if conn.bound:
session['user'] = username session['user'] = username
flash(f"Login successful! Welcome {username}", "success") flash(f"Login successful! Welcome {username}", "success")
return redirect(url_for('welcome')) return redirect(url_for('welcome'))
@@ -46,10 +48,26 @@ class LoginAuth:
finally: finally:
if 'conn' in locals(): if 'conn' in locals():
conn.unbind() conn.unbind()
# GET request: show login form # GET request: show login form
return render_template("login.html") 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 # LOGOUT ROUTE
# ------------------------------- # -------------------------------

View File

@@ -1,22 +1,12 @@
FROM python:3.11-slim FROM python:3.11-slim
# Prevent Python buffering
ENV PYTHONDONTWRITEBYTECODE=1
ENV PYTHONUNBUFFERED=1
WORKDIR /app 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 . COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt RUN pip install --no-cache-dir -r requirements.txt
COPY . . COPY . .
EXPOSE 5000 EXPOSE 5010
CMD ["python", "main.py"]
CMD ["gunicorn", "--bind", "0.0.0.0:5010", "main:app"]

View File

@@ -1,29 +1,40 @@
version: "3.9" version: "3.9"
services: services:
db: db:
image: mysql:8.0 image: mysql:8
container_name: income_tax_db container_name: tax-mysql
restart: always restart: always
environment: environment:
MYSQL_ROOT_PASSWORD: root MYSQL_ROOT_PASSWORD: tiger
MYSQL_DATABASE: test_income_taxdb MYSQL_DATABASE: income_tax_db
ports:
- "3307:3306"
volumes: volumes:
- mysql_data:/var/lib/mysql - mysql_data:/var/lib/mysql
- ./db/income_tax.sql:/docker-entrypoint-initdb.d/income_tax.sql
web: flaskapp:
build: . build: .
container_name: income_tax_web container_name: tax-flask
restart: always restart: always
ports: ports:
- "5010:5010" - "5010:5010"
env_file:
- .env
depends_on: depends_on:
- db - 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: volumes:
mysql_data: mysql_data:

69
main.py
View File

@@ -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 import os
from dotenv import load_dotenv from dotenv import load_dotenv
load_dotenv() load_dotenv()
import pandas as pd
from werkzeug.utils import secure_filename from werkzeug.utils import secure_filename
from datetime import date from datetime import date
from AppCode.Config import DBConfig from AppCode.Config import DBConfig
@@ -15,7 +14,6 @@ from AppCode.AOHandler import AOHandler
from AppCode.CITHandler import CITHandler from AppCode.CITHandler import CITHandler
from AppCode.ITATHandler import ITATHandler from AppCode.ITATHandler import ITATHandler
from AppCode.MatCreditHandler import MatCreditHandler from AppCode.MatCreditHandler import MatCreditHandler
import subprocess
@@ -23,10 +21,51 @@ import subprocess
app = Flask(__name__) app = Flask(__name__)
app.secret_key=os.getenv("SECRET_KEY") 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() auth = LoginAuth()
app.register_blueprint(auth.bp) 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 # welcome page
@app.route('/') @app.route('/')
@auth.login_required @auth.login_required
@@ -590,6 +629,28 @@ def summary_preview_route():
handler = DocumentHandler() handler = DocumentHandler()
return handler.Summary_preview(request) 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 # save mat credit bulk data
# @app.route("/save_mat_all", methods=["POST"]) # @app.route("/save_mat_all", methods=["POST"])

View File

@@ -11,3 +11,5 @@ openpyxl==3.1.2
xlrd==2.0.1 xlrd==2.0.1
gunicorn==21.2.0 gunicorn==21.2.0
ldap3

24
templates/view_logs.html Normal file
View File

@@ -0,0 +1,24 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<style>
body {
background: black;
color: #00ff00;
font-family: monospace;
}
.log-box {
white-space: pre-wrap;
height: 90vh;
overflow-y: scroll;
}
</style>
</head>
<body>
<h2>Application Logs</h2>
<div class="log-box">{% for line in logs %} {{ line }} {% endfor %}</div>
</body>
</html>

View File

@@ -0,0 +1,90 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>View Logs - Authorization</title>
<style>
body {
margin: 0;
font-family: Arial, Helvetica, sans-serif;
background: linear-gradient(135deg, #0d47a1, #1976d2);
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
}
.container {
background: #ffffff;
padding: 40px;
width: 350px;
border-radius: 12px;
box-shadow: 0 10px 25px rgba(0, 0, 0, 0.2);
text-align: center;
}
h2 {
margin-bottom: 25px;
color: #0d47a1;
}
input[type="password"] {
width: 100%;
padding: 12px;
margin-bottom: 20px;
border-radius: 6px;
border: 1px solid #ccc;
font-size: 14px;
outline: none;
transition: border 0.3s;
}
input[type="password"]:focus {
border: 1px solid #1976d2;
}
button {
width: 100%;
padding: 12px;
background-color: #1976d2;
color: white;
border: none;
border-radius: 6px;
font-size: 15px;
cursor: pointer;
transition: background 0.3s ease;
}
button:hover {
background-color: #0d47a1;
}
.flash-message {
margin-top: 15px;
font-size: 14px;
color: red;
}
</style>
</head>
<body>
<div class="container">
<h2>Enter Secret to View Logs</h2>
<form method="POST">
<input type="password" name="secret" placeholder="Enter Secret Password" required>
<button type="submit">Open Logs</button>
</form>
{% with messages = get_flashed_messages(with_categories=true) %}
{% for category, message in messages %}
<div class="flash-message">{{ message }}</div>
{% endfor %}
{% endwith %}
</div>
</body>
</html>