0vergeared commited on
Commit
ab04db2
·
verified ·
1 Parent(s): cff0eda

Update server.py

Browse files
Files changed (1) hide show
  1. server.py +111 -127
server.py CHANGED
@@ -1,175 +1,159 @@
1
  import os
2
  import sqlite3
3
- import csv
4
- import json
5
  import pathlib
6
- import random
7
  from datetime import datetime, timedelta
8
- from flask import Flask, request, render_template_string, redirect, url_for, session, send_file, jsonify
9
  from flask_limiter import Limiter
10
  from flask_limiter.util import get_remote_address
11
- from datasets import Dataset
12
  from huggingface_hub import HfApi
 
13
 
14
- # === Config ===
15
  ADMIN_USER = os.getenv("ADMIN_USER", "admin")
16
  ADMIN_PASS = os.getenv("ADMIN_PASS", "Welcome123")
17
- FLASK_SECRET = os.getenv("FLASK_SECRET", "IDONTKNOWWHATISTHIS")
18
- HF_TOKEN = os.getenv("HF_TOKEN", "")
19
- HF_DATASET_REPO = "0vergeared/otp-logs"
20
 
21
- DATABASE = "/tmp/otp.db"
22
- EXPORT_CSV = "/tmp/otp_logs.csv"
23
- EXPORT_JSON = "/tmp/otp_logs.json"
24
- pathlib.Path("/tmp").mkdir(parents=True, exist_ok=True)
25
 
26
- # === App Setup ===
27
- app = Flask(__name__)
28
  app.secret_key = FLASK_SECRET
29
 
30
- limiter = Limiter(key_func=get_remote_address)
31
- limiter.init_app(app)
32
 
33
- # === Helpers ===
34
- def generate_otp():
35
- return str(random.randint(100000, 999999))
 
 
 
36
 
37
  def init_db():
38
  with sqlite3.connect(DATABASE) as conn:
39
  c = conn.cursor()
40
- c.execute("""
41
- CREATE TABLE IF NOT EXISTS otps (
42
- id INTEGER PRIMARY KEY AUTOINCREMENT,
43
- otp TEXT,
44
- generated_at TEXT,
45
- expires_at TEXT,
46
- used_at TEXT,
47
- ip_address TEXT,
48
- status TEXT
49
- )
50
- """)
51
  conn.commit()
52
 
53
- def export_logs():
54
- with sqlite3.connect(DATABASE) as conn:
55
- c = conn.cursor()
56
- c.execute("SELECT otp, generated_at, expires_at, used_at, ip_address, status FROM otps ORDER BY id DESC")
57
- rows = c.fetchall()
58
-
59
- # Save CSV
60
- with open(EXPORT_CSV, "w", newline="") as f:
61
- writer = csv.writer(f)
62
- writer.writerow(["otp", "generated_at", "expires_at", "used_at", "ip_address", "status"])
63
- writer.writerows(rows)
64
-
65
- # Save JSON
66
- json_data = [
67
- {
68
- "otp": row[0],
69
- "generated_at": row[1],
70
- "expires_at": row[2],
71
- "used_at": row[3],
72
- "ip_address": row[4],
73
- "status": row[5]
74
- }
75
- for row in rows
76
- ]
77
- with open(EXPORT_JSON, "w") as f:
78
- json.dump(json_data, f, indent=2)
79
 
80
  def upload_to_hf(otp_row):
 
 
 
 
 
 
 
 
 
 
 
 
81
  try:
82
- import pandas as pd
83
- df = pd.DataFrame([otp_row], columns=["otp", "generated_at", "expires_at", "used_at", "ip_address", "status"])
84
- dataset = Dataset.from_pandas(df)
85
- dataset.push_to_hub(repo_id=HF_DATASET_REPO, token=HF_TOKEN)
86
- print("✅ OTP log pushed to Hugging Face")
 
 
 
 
87
  except Exception as e:
88
- print("⚠️ Failed to upload OTP log:", e)
89
 
90
- # === Routes ===
91
-
92
- @app.route("/")
93
- def home():
94
- if "admin" not in session:
95
- return redirect(url_for("login"))
96
- return redirect(url_for("generate"))
97
 
98
- @app.route("/login", methods=["GET", "POST"])
99
- def login():
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
100
  if request.method == "POST":
101
- if request.form["username"] == ADMIN_USER and request.form["password"] == ADMIN_PASS:
 
 
102
  session["admin"] = True
103
- return redirect(url_for("generate"))
104
- return "Login failed"
105
- return render_template_string("""
106
- <h2>Admin Login</h2>
107
- <form method="post">
108
- Username: <input name="username"><br>
109
- Password: <input type="password" name="password"><br>
110
- <input type="submit" value="Login">
111
- </form>
112
- """)
113
-
114
- @app.route("/generate", methods=["GET", "POST"])
115
- def generate():
116
- if "admin" not in session:
117
- return redirect(url_for("login"))
118
 
119
  if request.method == "POST":
120
  otp = generate_otp()
121
  now = datetime.utcnow()
122
- expires_at = now + timedelta(minutes=10)
 
123
 
124
  with sqlite3.connect(DATABASE) as conn:
125
  c = conn.cursor()
126
  c.execute("INSERT INTO otps (otp, generated_at, expires_at, ip_address, status) VALUES (?, ?, ?, ?, ?)",
127
- (otp, now.isoformat(), expires_at.isoformat(), request.remote_addr, "generated"))
128
  conn.commit()
129
 
130
- # Export logs
131
- export_logs()
132
-
133
- # Push to Hugging Face Dataset
134
- otp_row = [otp, now.isoformat(), expires_at.isoformat(), None, request.remote_addr, "generated"]
135
  upload_to_hf(otp_row)
136
 
137
- return f"Generated OTP: <b>{otp}</b> (expires in 10 mins)<br><a href='/generate'>Back</a>"
138
 
139
- return render_template_string("""
140
- <h2>Generate OTP</h2>
141
- <form method="post">
142
- <input type="submit" value="Generate OTP">
143
- </form>
144
- <a href='/download-csv'>Download CSV</a> |
145
- <a href='/download-json'>Download JSON</a> |
146
- <a href='/logout'>Logout</a>
147
- """)
148
 
149
  @app.route("/logout")
150
  def logout():
151
- session.pop("admin", None)
152
- return redirect(url_for("login"))
153
-
154
- @app.route("/download-csv")
155
- def download_csv():
156
- export_logs()
157
- return send_file(EXPORT_CSV, as_attachment=True)
158
-
159
- @app.route("/download-json")
160
- def download_json():
161
- export_logs()
162
- return send_file(EXPORT_JSON, as_attachment=True)
163
-
164
- @app.route("/debug")
165
- def debug():
166
- return jsonify({
167
- "db_exists": os.path.exists(DATABASE),
168
- "csv_exists": os.path.exists(EXPORT_CSV),
169
- "json_exists": os.path.exists(EXPORT_JSON),
170
- })
171
-
172
- # === Run App ===
173
  if __name__ == "__main__":
174
  init_db()
175
  app.run(host="0.0.0.0", port=7860)
 
1
  import os
2
  import sqlite3
3
+ import secrets
 
4
  import pathlib
 
5
  from datetime import datetime, timedelta
6
+ from flask import Flask, request, redirect, url_for, render_template, session, flash
7
  from flask_limiter import Limiter
8
  from flask_limiter.util import get_remote_address
 
9
  from huggingface_hub import HfApi
10
+ import pandas as pd
11
 
12
+ # ENV values
13
  ADMIN_USER = os.getenv("ADMIN_USER", "admin")
14
  ADMIN_PASS = os.getenv("ADMIN_PASS", "Welcome123")
15
+ FLASK_SECRET = os.getenv("FLASK_SECRET", "supersecret")
16
+ HF_TOKEN = os.getenv("HF_TOKEN")
17
+ HF_REPO_ID = "0vergeared/otp-logs"
18
 
19
+ # Paths
20
+ DATABASE = "otp.db"
21
+ TEMPLATES = "templates"
22
+ STATIC = "static"
23
 
24
+ # Setup
25
+ app = Flask(__name__, template_folder=TEMPLATES, static_folder=STATIC)
26
  app.secret_key = FLASK_SECRET
27
 
28
+ # Rate Limiting
29
+ limiter = Limiter(get_remote_address, app=app)
30
 
31
+ # Make sure Hugging Face Hub doesn't cache
32
+ os.environ["HF_DATASETS_CACHE"] = "/tmp/hf_cache"
33
+
34
+ # Make sure templates/static folders exist
35
+ os.makedirs(TEMPLATES, exist_ok=True)
36
+ os.makedirs(STATIC, exist_ok=True)
37
 
38
  def init_db():
39
  with sqlite3.connect(DATABASE) as conn:
40
  c = conn.cursor()
41
+ c.execute('''CREATE TABLE IF NOT EXISTS otps (
42
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
43
+ otp TEXT UNIQUE,
44
+ generated_at TEXT,
45
+ expires_at TEXT,
46
+ used_at TEXT,
47
+ ip_address TEXT,
48
+ status TEXT
49
+ )''')
 
 
50
  conn.commit()
51
 
52
+ def generate_otp():
53
+ return ''.join(secrets.choice("0123456789") for _ in range(6))
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
54
 
55
  def upload_to_hf(otp_row):
56
+ csv_path = "/tmp/otp_all.csv"
57
+ file_exists = os.path.exists(csv_path)
58
+
59
+ df_new = pd.DataFrame([otp_row], columns=["otp", "generated_at", "expires_at", "used_at", "ip", "status"])
60
+ if file_exists:
61
+ df_old = pd.read_csv(csv_path)
62
+ df = pd.concat([df_old, df_new], ignore_index=True)
63
+ else:
64
+ df = df_new
65
+
66
+ df.to_csv(csv_path, index=False)
67
+
68
  try:
69
+ api = HfApi()
70
+ api.upload_file(
71
+ path_or_fileobj=csv_path,
72
+ path_in_repo="otp_all.csv",
73
+ repo_id=HF_REPO_ID,
74
+ token=HF_TOKEN,
75
+ create_pr=False
76
+ )
77
+ print("✅ OTP log uploaded to HF.")
78
  except Exception as e:
79
+ print("⚠️ Failed to upload to HF:", e)
80
 
81
+ @app.route("/", methods=["GET", "POST"])
82
+ def index():
83
+ if request.method == "POST":
84
+ otp_input = request.form.get("otp")
85
+ now = datetime.utcnow()
 
 
86
 
87
+ with sqlite3.connect(DATABASE) as conn:
88
+ c = conn.cursor()
89
+ c.execute("SELECT * FROM otps WHERE otp = ?", (otp_input,))
90
+ row = c.fetchone()
91
+
92
+ if row:
93
+ otp, gen_at, exp_at, used_at, ip, status = row[1:7]
94
+ exp_time = datetime.fromisoformat(exp_at)
95
+ if used_at:
96
+ flash("OTP already used!", "danger")
97
+ elif now > exp_time:
98
+ flash("OTP expired!", "danger")
99
+ else:
100
+ used_time = now.isoformat()
101
+ c.execute("UPDATE otps SET used_at = ?, status = ? WHERE otp = ?", (used_time, "used", otp_input))
102
+ conn.commit()
103
+
104
+ # Log to Hugging Face
105
+ otp_row = [otp_input, gen_at, exp_at, used_time, request.remote_addr, "used"]
106
+ upload_to_hf(otp_row)
107
+
108
+ flash("OTP accepted. Installation can continue!", "success")
109
+ return redirect(url_for("index"))
110
+ else:
111
+ flash("Invalid OTP!", "danger")
112
+
113
+ return render_template("index.html")
114
+
115
+ @app.route("/admin", methods=["GET", "POST"])
116
+ def admin():
117
  if request.method == "POST":
118
+ username = request.form.get("username")
119
+ password = request.form.get("password")
120
+ if username == ADMIN_USER and password == ADMIN_PASS:
121
  session["admin"] = True
122
+ return redirect(url_for("dashboard"))
123
+ else:
124
+ flash("Login failed", "danger")
125
+ return render_template("admin_login.html")
126
+
127
+ @app.route("/dashboard", methods=["GET", "POST"])
128
+ def dashboard():
129
+ if not session.get("admin"):
130
+ return redirect(url_for("admin"))
 
 
 
 
 
 
131
 
132
  if request.method == "POST":
133
  otp = generate_otp()
134
  now = datetime.utcnow()
135
+ expires = now + timedelta(minutes=10)
136
+ ip = request.remote_addr
137
 
138
  with sqlite3.connect(DATABASE) as conn:
139
  c = conn.cursor()
140
  c.execute("INSERT INTO otps (otp, generated_at, expires_at, ip_address, status) VALUES (?, ?, ?, ?, ?)",
141
+ (otp, now.isoformat(), expires.isoformat(), ip, "generated"))
142
  conn.commit()
143
 
144
+ # Log to HF
145
+ otp_row = [otp, now.isoformat(), expires.isoformat(), None, ip, "generated"]
 
 
 
146
  upload_to_hf(otp_row)
147
 
148
+ flash(f" OTP Generated: {otp}", "success")
149
 
150
+ return render_template("dashboard.html")
 
 
 
 
 
 
 
 
151
 
152
  @app.route("/logout")
153
  def logout():
154
+ session.clear()
155
+ return redirect(url_for("index"))
156
+
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
157
  if __name__ == "__main__":
158
  init_db()
159
  app.run(host="0.0.0.0", port=7860)