Ajout du projet
This commit is contained in:
parent
a9291727f5
commit
1a13ed504d
1
res/css/bulma/bulma.min.css
vendored
Normal file
1
res/css/bulma/bulma.min.css
vendored
Normal file
File diff suppressed because one or more lines are too long
151
server.py
Normal file
151
server.py
Normal file
@ -0,0 +1,151 @@
|
||||
from flask import Flask, render_template, request, json
|
||||
import subprocess
|
||||
import os
|
||||
import time
|
||||
|
||||
DUMPS_DIR = "DumpDir"
|
||||
KEYFILE = "key-file.txt"
|
||||
HOST = "localhost"
|
||||
PORT = "5000"
|
||||
|
||||
|
||||
def runCommand(command):
|
||||
process = subprocess.Popen(
|
||||
command,
|
||||
stdout=subprocess.PIPE,
|
||||
stderr=subprocess.PIPE,
|
||||
shell=True)
|
||||
stdout, stderr = process.communicate()
|
||||
return stdout, stderr, process.returncode
|
||||
|
||||
|
||||
### Partie Flask (Serveur Web)
|
||||
app = Flask('__name__', static_folder="res")
|
||||
app.config['DEBUG'] = False
|
||||
|
||||
|
||||
# Page principal
|
||||
@app.route('/')
|
||||
def root():
|
||||
if request.args.get("error"): # On affiche l'erreur si il y en a une.
|
||||
error = request.args.get("error")
|
||||
return render_template('index.html', error=error)
|
||||
else :
|
||||
return render_template('index.html')
|
||||
|
||||
|
||||
# Page d'attente du badge du client
|
||||
@app.route('/waitingBadge')
|
||||
def waitingBadge():
|
||||
nbBadge = request.args.get('nbBadge', default=1, type=int)
|
||||
return render_template('waitingBadge.html', nbBadge=nbBadge)
|
||||
|
||||
# Une fois que le badge est détecté
|
||||
@app.route('/detectBadge')
|
||||
def detectBadge():
|
||||
while True: # Boucle infinie tant que le badge n'est pas detecté.
|
||||
result = {'Error': '1'}
|
||||
stdout, stderr, return_code = runCommand('nfc-list')
|
||||
stdout = stdout.decode("utf-8")
|
||||
lines = stdout.split('\n')
|
||||
if "Interface opened" in lines[1]:
|
||||
if len(lines) > 6:
|
||||
badge_type = lines[4].replace(' ', ' ')
|
||||
if '00 04' in badge_type:
|
||||
result = {'status': 'OK'}
|
||||
break
|
||||
else: # Si le badge n'est pas compatble avec le badge cloner.
|
||||
result = {'status': 'ERROR', 'message': 'Badge non compatible !'}
|
||||
break
|
||||
else :
|
||||
result = {'status': 'ERROR', 'message': 'Lecteur NFC non connecté !'}
|
||||
break
|
||||
return json.dumps(result)
|
||||
|
||||
# Permet de lire et copier le badge du client (Route appellée avec du JS depuis la page waitingBadge.html)
|
||||
@app.route('/readBadge')
|
||||
def readBadge():
|
||||
while True: # Boucle infinie tant que le badge n'est pas detecté.
|
||||
result = {'Error': '1'}
|
||||
stdout, stderr, return_code = runCommand('nfc-list')
|
||||
stdout = stdout.decode("utf-8")
|
||||
lines = stdout.split('\n')
|
||||
if "Interface opened" in lines[1]:
|
||||
if len(lines) > 6:
|
||||
badge_type = lines[4].replace(' ', ' ')
|
||||
if '00 04' in badge_type:
|
||||
badge_UID = lines[5].replace('UID (NFCID1): ', '').replace(' ', '')
|
||||
if os.path.isfile('%s/%s.dmp' %(DUMPS_DIR, badge_UID)) : #Si un dump existe déjà pour cet UID
|
||||
result = {'status': 'OK', 'UID': badge_UID}
|
||||
break
|
||||
else :
|
||||
stdout, stderr, status_code = runCommand('mfoc -f %s -P 500 -O %s/%s.dmp' %(KEYFILE, DUMPS_DIR, badge_UID))
|
||||
if status_code == 0: #Si on a réussi à avoir le dump
|
||||
result = {'status': 'OK', 'UID': badge_UID}
|
||||
break
|
||||
else :
|
||||
result = {'status': 'ERROR', 'message': 'Impossible de cracker le badge !'}
|
||||
break
|
||||
else: # Si le badge n'est pas compatble avec le badge cloner.
|
||||
result = {'status': 'ERROR', 'message': 'Badge non compatible !'}
|
||||
break
|
||||
else :
|
||||
result = {'status': 'ERROR', 'message': 'Lecteur NFC non connecté !'}
|
||||
break
|
||||
return json.dumps(result)
|
||||
|
||||
|
||||
|
||||
# Page d'attente des badges à cloner
|
||||
@app.route('/writeBadge/<nbBadge>/<uid>')
|
||||
def writeBadge(nbBadge, uid):
|
||||
if request.args.get("error"): # On affiche l'erreur si il y en a une.
|
||||
error = request.args.get("error")
|
||||
return render_template('writeBadge.html', nbBadge=int(nbBadge), uid=uid, error=error)
|
||||
return render_template('writeBadge.html', nbBadge=int(nbBadge), uid=uid)
|
||||
|
||||
#Permet de cloner les badges
|
||||
@app.route('/copyBadge/<uid>')
|
||||
def copyBadge(uid):
|
||||
while True: # Boucle infinie tant que le badge n'est pas detecté.
|
||||
result = {'Error': '1'}
|
||||
stdout, stderr, return_code = runCommand('nfc-list')
|
||||
stdout = stdout.decode("utf-8")
|
||||
lines = stdout.split('\n')
|
||||
if "Interface opened" in lines[1]:
|
||||
if len(lines) > 6:
|
||||
badge_type = lines[4].replace(' ', ' ')
|
||||
if '00 04' in badge_type:
|
||||
stdout, stderr, status_code = runCommand('mfoc -P 500 -O %s/new.dmp' %(DUMPS_DIR))
|
||||
print(stdout)
|
||||
print(status_code)
|
||||
if status_code == 0: #Si on a réussi à avoir le dump
|
||||
stdout, stderr, status_code = runCommand('nfc-mfclassic W a %s/%s.dmp %s/new.dmp' %(DUMPS_DIR, uid, DUMPS_DIR))
|
||||
print(stdout)
|
||||
print(status_code)
|
||||
if status_code == 0: #Si on a réussi à copier
|
||||
result = {'status': 'OK', 'message': 'Badge copié !'}
|
||||
break
|
||||
else :
|
||||
result = {'status': 'ERROR', 'message': 'Avez-vous mis un badge réinscriptible ?'}
|
||||
break
|
||||
else :
|
||||
result = {'status': 'ERROR', 'message': 'Impossible d\'écrire sur ce badge'}
|
||||
break
|
||||
else: # Si le badge n'est pas compatble avec le badge cloner.
|
||||
result = {'status': 'ERROR', 'message': 'Badge non compatible !'}
|
||||
break
|
||||
else :
|
||||
result = {'status': 'ERROR', 'message': 'Lecteur NFC non connecté !'}
|
||||
break
|
||||
return json.dumps(result)
|
||||
|
||||
@app.route('/wait')
|
||||
def wait():
|
||||
raison = request.args.get("raison")
|
||||
redirect = request.args.get("redirect")
|
||||
return render_template('wait.html',raison=raison, redirect=redirect)
|
||||
|
||||
|
||||
app.run(host=HOST, port=PORT)
|
||||
### Fin partie Flask ###
|
||||
32
templates/index.html
Normal file
32
templates/index.html
Normal file
@ -0,0 +1,32 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="fr">
|
||||
<head>
|
||||
<title>Badge Cloner</title>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
||||
<meta name="author" content="j4rj4r">
|
||||
<link rel="stylesheet" href="res/css/bulma/bulma.min.css">
|
||||
</head>
|
||||
<body>
|
||||
<div class="container is-fluid">
|
||||
<section class="hero">
|
||||
<div class="hero-body">
|
||||
<div class="container has-text-centered">
|
||||
<h1 class="title is-spaced">Badge Cloner</h1>
|
||||
{% if error is defined %}
|
||||
<p class="has-text-danger"> {{ error }}</p>
|
||||
{% endif %}
|
||||
<h2 class="subtitle">Choisir le nombre de badges à cloner :</h2>
|
||||
<div class=" is-centered">
|
||||
<form action="/waitingBadge" method="get">
|
||||
<input name="nbBadge" class="input" min="1" value="1" required type="number"/>
|
||||
<hr>
|
||||
<button class="control button is-primary is-large">Clonage</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
22
templates/wait.html
Normal file
22
templates/wait.html
Normal file
@ -0,0 +1,22 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="fr">
|
||||
<head>
|
||||
<title>Badge Cloner</title>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
||||
<meta name="author" content="j4rj4r">
|
||||
<link rel="stylesheet" href="res/css/bulma/bulma.min.css">
|
||||
</head>
|
||||
<body>
|
||||
<div class="container is-fluid">
|
||||
<section class="hero"><div class="hero-body">
|
||||
<div class="container has-text-centered">
|
||||
<h1 class="title is-spaced">Page d'attente</h1>
|
||||
<h2 id="info" class="subtitle">{{raison}}</h2>
|
||||
<a href="{{redirect}}" class="button is-link">Suivant</a>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
48
templates/waitingBadge.html
Normal file
48
templates/waitingBadge.html
Normal file
@ -0,0 +1,48 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="fr">
|
||||
<head>
|
||||
<title>Badge Cloner</title>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
||||
<meta name="author" content="j4rj4r">
|
||||
<link rel="stylesheet" href="res/css/bulma/bulma.min.css">
|
||||
</head>
|
||||
<body>
|
||||
<div class="container is-fluid">
|
||||
<section class="hero"><div class="hero-body">
|
||||
<div class="container has-text-centered">
|
||||
<h1 class="title is-spaced">Badge du client</h1>
|
||||
<h2 id="info" class="subtitle">En attente du badge à copier ...</h2>
|
||||
<a href="/" class="button is-link">Annuler</a>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
<script>
|
||||
var xhr = new XMLHttpRequest();
|
||||
xhr.open('GET', '/detectBadge', true);
|
||||
xhr.onload = function() {
|
||||
var jsonreponse = JSON.parse(xhr.response);
|
||||
if (jsonreponse.status == "OK") {
|
||||
document.getElementById("info").textContent = "Tentative de copie du badge ...";
|
||||
|
||||
var xhr2 = new XMLHttpRequest();
|
||||
xhr2.open('GET', '/readBadge', true);
|
||||
xhr2.onload = function() {
|
||||
var jsonreponse = JSON.parse(xhr2.response);
|
||||
if (jsonreponse.status == "OK") {
|
||||
window.location.href = "/wait?raison=Appuyer%20sur%20le%20bouton%20pour%20commencer%20la%20copie%20des%20badges.&redirect=/writeBadge/{{nbBadge}}/" + jsonreponse.UID;
|
||||
} else {
|
||||
window.location.href = "/?error=" + jsonreponse.message;
|
||||
}
|
||||
};
|
||||
xhr2.send(null);
|
||||
} else {
|
||||
window.location.href = "/?error=" + jsonreponse.message;
|
||||
}
|
||||
};
|
||||
|
||||
xhr.send(null);
|
||||
</script>
|
||||
52
templates/writeBadge.html
Normal file
52
templates/writeBadge.html
Normal file
@ -0,0 +1,52 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="fr">
|
||||
<head>
|
||||
<title>Badge Cloner</title>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
||||
<meta name="author" content="j4rj4r">
|
||||
<link rel="stylesheet" href="/res/css/bulma/bulma.min.css">
|
||||
</head>
|
||||
<body>
|
||||
<div class="container is-fluid">
|
||||
<section class="hero"><div class="hero-body">
|
||||
<div class="container has-text-centered">
|
||||
<h1 class="title is-spaced">Vos badges</h1>
|
||||
<h2 class="subtitle">En attente du badge numéro {{nbBadge}}</h2>
|
||||
{% if error is defined %}
|
||||
<p class="has-text-danger"> {{ error }}</p>
|
||||
{% endif %}
|
||||
<a href="/" class="button is-link">Annuler</a>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
<script>
|
||||
if ({{nbBadge}} >= 1) {
|
||||
var xhr = new XMLHttpRequest();
|
||||
xhr.open('GET', '/copyBadge/{{uid}}', true);
|
||||
|
||||
xhr.onload = function() {
|
||||
var jsonreponse = JSON.parse(xhr.response);
|
||||
if (jsonreponse.status == "OK") {
|
||||
//console.log("Badge cloné")
|
||||
if ({{nbBadge-1}} == 0 ){
|
||||
window.location.href = "/wait?raison=Tous%20les%20badges%20sont%20copi%C3%A9s%20%21&redirect=/";
|
||||
}
|
||||
else{
|
||||
window.location.href = "/wait?raison=Badge%20clon%C3%A9%20%21%20Appuyer%20sur%20le%20bouton%20pour%20passer%20au%20badge%20suivant.&redirect=/writeBadge/{{nbBadge-1}}/{{uid}}";
|
||||
}
|
||||
} else {
|
||||
window.location.href = "/writeBadge/{{nbBadge}}/{{uid}}" + "?error=" + jsonreponse.message;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
xhr.send(null);
|
||||
|
||||
} else {
|
||||
window.location.href = "/"
|
||||
}
|
||||
</script>
|
||||
Loading…
x
Reference in New Issue
Block a user