"git@forgeb1.univ-lehavre.fr:aw242765/docker-swarm-md5.git" n'existait pas sur "c3a63be6ae995d3d822f37d3f6a99d1aa1d051c6"
Newer
Older
import os
import redis
import hashlib
import itertools
import logging
import subprocess
import re # <-- Import pour extraire le numéro du port
from flask import Flask, request, jsonify
from flask_cors import CORS # Import pour activer CORS
# Configuration du logging
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
CORS(app) # Activation de CORS pour toutes les routes
redis_host = os.getenv("REDIS_HOST", "redis") # "redis" correspond au service Redis dans Docker
redis_url = os.getenv("REDIS_PORT", "6379") # Valeur par défaut
# Extraction du numéro de port de Redis (compatible avec GitLab CI/CD et Docker)
redis_port_match = re.search(r":(\d+)", redis_url)
redis_port = int(redis_port_match.group(1)) if redis_port_match else 6379
# Connexion à Redis
redis_client = redis.StrictRedis(host=redis_host, port=redis_port, db=0, decode_responses=True)
# Clé pour le compteur de requêtes reçues
REQUEST_RECEIVED_KEY = "request_received_count"
# Initialisation du compteur si inexistant
if not redis_client.exists(REQUEST_RECEIVED_KEY):
redis_client.set(REQUEST_RECEIVED_KEY, 0)
@app.before_request
def count_requests():
"""
Middleware exécuté avant chaque requête pour incrémenter le compteur global de requêtes reçues.
"""
redis_client.incr(REQUEST_RECEIVED_KEY)
logger.info(f"📩 Nouvelle requête reçue ! Nombre total : {redis_client.get(REQUEST_RECEIVED_KEY)}")
@app.route("/health", methods=["GET"])
def health():
""" Vérifie si l'application fonctionne correctement. """
logger.info("✅ Vérification du statut de l'application (health check)")
return jsonify({"status": "ok"}), 200
@app.route("/bruteforce", methods=["POST"])
def bruteforce():
"""
Endpoint pour bruteforcer un hash MD5.
"""
data = request.json
if not data or "hash" not in data:
logger.warning("⚠️ Requête invalide reçue sur /bruteforce")
return jsonify({
"status": "fail",
"data": None,
"errors": {"message": "Invalid payload. Please provide a valid hash."}
}), 400
target_hash = data["hash"]
logger.info(f"🔍 Bruteforce demandé pour le hash : {target_hash}")
# Vérifier si le hash existe déjà dans Redis
if redis_client.exists(target_hash):
original = redis_client.get(target_hash)
logger.info(f"✅ Hash trouvé en cache : {original}")
return jsonify({
"status": "success",
"data": {"hash": target_hash, "original": original},
"errors": None
}), 200
charset = "abcdefghijklmnopqrstuvwxyz0123456789"
for guess in itertools.product(charset, repeat=length):
guess_str = ''.join(guess)
if hashlib.md5(guess_str.encode()).hexdigest() == target_hash:
redis_client.set(target_hash, guess_str)
logger.info(f"✅ Hash {target_hash} trouvé : {guess_str}")
return jsonify({
"status": "success",
"data": {"hash": target_hash, "original": guess_str},
"errors": None
}), 200
logger.warning(f"❌ Aucun résultat trouvé pour le hash : {target_hash}")
return jsonify({
"status": "fail",
"data": None,
"errors": {"message": "No match found."}
@app.route("/resolved", methods=["GET"])
def get_resolved_hashes():
"""
Endpoint pour récupérer tous les hash résolus.
"""
keys = redis_client.keys()
resolved_hashes = {key: redis_client.get(key) for key in keys if key != REQUEST_RECEIVED_KEY}
logger.info(f"📜 Liste des hash résolus récupérée ({len(resolved_hashes)} entrées)")
return jsonify({
"status": "success",
"errors": None
}), 200
@app.route("/resolved/<string:hash_value>", methods=["GET"])
def get_resolved_hash(hash_value):
"""
Endpoint pour récupérer un hash spécifique.
"""
if redis_client.exists(hash_value):
original = redis_client.get(hash_value)
logger.info(f"🔎 Recherche du hash {hash_value} : {original}")
return jsonify({
"status": "success",
"data": {"hash": hash_value, "original": original},
"errors": None
}), 200
else:
logger.warning(f"⚠️ Aucune entrée trouvée pour le hash : {hash_value}")
return jsonify({
"status": "fail",
"data": None,
"errors": {"message": f"No resolved entry found for hash: {hash_value}"}
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
@app.route("/request_count", methods=["GET"])
def get_request_count():
"""
Endpoint pour récupérer le nombre total de requêtes reçues.
"""
count = redis_client.get(REQUEST_RECEIVED_KEY)
logger.info(f"📊 Nombre total de requêtes reçues : {count}")
return jsonify({
"status": "success",
"data": {"request_received_count": int(count) if count else 0},
"errors": None
}), 200
@app.route("/clear_cache", methods=["DELETE"])
def clear_cache():
"""
Endpoint pour effacer toutes les entrées stockées dans Redis (sauf le compteur de requêtes).
"""
keys = redis_client.keys()
for key in keys:
if key != REQUEST_RECEIVED_KEY:
redis_client.delete(key)
logger.info("🗑️ Cache nettoyé, toutes les entrées supprimées sauf le compteur de requêtes.")
return jsonify({"status": "success", "message": "Cache cleared."}), 200
@app.route("/replicas", methods=["GET"])
def get_replicas():
"""
Endpoint pour récupérer le nombre actuel de réplicas du backend dans Docker Swarm.
"""
SERVICE_NAME = "md5_stack_backend"
try:
result = subprocess.run(["docker", "service", "ls"], capture_output=True, text=True)
for line in result.stdout.split("\n"):
if SERVICE_NAME in line:
replicas = line.split()[3].split("/")[0] # Extraction du nombre de réplicas actuels
logger.info(f"🔢 Nombre de réplicas actuels : {replicas}")
return jsonify({"status": "success", "data": {"replicas": int(replicas)}, "errors": None}), 200
except Exception as e:
logger.error(f"❌ Erreur récupération réplicas : {e}")
return jsonify({"status": "fail", "data": None, "errors": {"message": str(e)}}), 500
return jsonify({"status": "fail", "data": None, "errors": {"message": "Service not found"}}), 404
@app.route("/cpu_usage", methods=["GET"])
def get_cpu_usage():
"""
Endpoint pour récupérer l'utilisation CPU actuelle du service backend dans Docker Swarm.
"""
SERVICE_NAME = "md5_stack_backend"
try:
result = subprocess.run(["docker", "stats", "--no-stream", "--format", "{{.Name}} {{.CPUPerc}}"],
capture_output=True, text=True)
for line in result.stdout.split("\n"):
if SERVICE_NAME in line:
cpu_usage = line.split()[1].replace("%", "") # Extraction de l'utilisation CPU
logger.info(f"⚡ Utilisation CPU actuelle : {cpu_usage}%")
return jsonify({"status": "success", "data": {"cpu_usage": float(cpu_usage)}, "errors": None}), 200
except Exception as e:
logger.error(f"❌ Erreur récupération CPU : {e}")
return jsonify({"status": "fail", "data": None, "errors": {"message": str(e)}}), 500
if __name__ == "__main__":
app.run(host="0.0.0.0", port=5000)