...
Cette page illustre ainsi l'intégration d'un dispositif de badgeage en utilisant la solution générique esup-nfc-tag.
Cahier des charges
On dispose de :
- 10 parapluies
- 40 couteaux "suisses"multifonctions
- 100 porte-cartes (multiple)
- 400 porte-cartes simples
...
On souhaite ainsi implémenter une loterie par badgeage de cartes pour distribuer ces 850 lots à environ 800 850 personnes (environ 2000 personnes sont attendues aux JRES pendant 3 jours).
Les chances de gagner sont fonction du stock de chaque lot.
- 1 chance sur 51 85 de gagner un parapluie
- 3 4 chances sur 51 85 de gagner un couteau "suisse"
couteau multifonctions - 10 7 chances sur 51 85 de gagner un porte-cartes (multiple)
- 17 30 chances sur 51 85 de gagner le "goodies spécial 20 ans ESUP"
- 23 40 chances sur 51 85 de gagner le porte-carte simple
...
Via le numéro de série de la carte, on fait une opération de modulo pour attribuer un lot :
- si (csn % 5185) == 0 -> parapluie
- si (csn % 5185) de 1 à 3 4 -> couteau
- si (csn % 5185) de 4 5 à 10 14 -> porte-cartes multiple
- si (csn % 5185) de 11 15 à 27 44 -> goodies 20 ans
- si (csn % 5185) de 28 45 à 50 84 -> porte-carte simple
A chaque badgeage, on garde en mémoire le csn dans un fichier pour indiquer si la carte a déjà été utilisée lors du jeu.
Aucune donnée personnelle n'est récupérée (et récupérable), le listing des identifiants de cartes n'est utilisé que pour la durée du jeu ; il est détruit juste après les JRES.
L'usage est un peu détourné puisqu'd'esup-sgc/esup-nfc-tag est un peu détourné puisqu'ici on n'identifie pas les utilisateurs.
...
| Bloc de code | ||||
|---|---|---|---|---|
| ||||
#!/usr/bin/python
# -*- coding: utf-8 -*-
import cgi
args = cgi.parse()
print "Content-type: application/json"
print
if 'locations' in args.keys():
if args['eppn'][0] in ('bonamvin@univlogin@univ-rouenville1.fr', 'lemaida3@univautrelogin@univ-rouenville1.fr', 'esupdem@univlogin@univ-rouenville2.fr'):
print '["Esup Goodies"]'
else:
print '[]'
elif 'isTagable' in args.keys():
print 'OK'
elif 'validateTag' in args.keys():
print 'OK'
elif 'tagIdCheck' in args.keys():
csn = args['csn'][0]
alreadyChecked = False
suffix = ''
file = open('/var/www/log/goodies.txt',"r")
for line in file:
if csn==line.rstrip('\r\n'):
alreadyChecked = True
suffix = '[RE]'
file.close()
csnAsInt = int(csn, 16)
modCsn = csnAsInt%51csnAsInt%85
if modCsn in range(0,1):
print('{"csn":"-", "eppn":"parapluie", "firstname":"%s", "lastname":"Parapluie !", "locations":"esup-goodies"}' % (suffix))
elif modCsn in range(1,45):
print('{"csn":"-", "eppn":"couteau", "firstname":"%s", "lastname":"Couteau !", "locations":"esup-goodies"}' % (suffix))
elif modCsn in range(45,1115):
print('{"csn":"-", "eppn":"porte-cartes", "firstname":"%s", "lastname":" Porte cartes !", "locations":"esup-goodies"}' % (suffix))
elif modCsn in range(1115,2845):
print('{"csn":"-", "eppn":"mystere", "firstname":"%s", "lastname":"Goodies 20 ans !", "locations":"esup-goodies"}' % (suffix))
# range(2845,5184):
else :
print('{"csn":"-", "eppn":"porte-carte-simple", "firstname":"%s", "lastname":"Porte carte simple", "locations":"esup-goodies"}' % (suffix))
if not alreadyChecked:
file = open('/var/www/log/goodies.txt',"a")
file.write(csn + "\n")
file.close()
else:
print '[]'
|
...
| Bloc de code | ||||
|---|---|---|---|---|
| ||||
<bean id="tagIdCheckEsupGoodies" class="org.esupportail.nfctag.service.api.impl.TagIdCheckRestWs">
<property name="description" value="ESUP Goodies"/>
<property name="tagIdCheckUrl" value="https://esup-sgc-demo.esup-portail.org/esup-sgc-demo.esup-portail.orggoodies?tagIdCheck=tagIdCheck"/>
</bean>
<bean id="esupGoodiesExtApi" class="org.esupportail.nfctag.service.api.impl.AppliExtRestWs">
<property name="isTagableUrl" value="https://esup-sgc-demo.esup-portail.org/esup-sgc-demo.esup-portail.org?isTagable=goodies?isTagable=isTagable"/>
<property name="validateTagUrl" value="https://esup-sgc-demo.esup-portail.org/esup-sgc-demo.esup-portail.orggoodies?validateTag=validateTag"/>
<property name="getLocationsUrl" value="https://esup-sgc-demo.esup-portail.org/esup-sgc-demo.esup-portail.orggoodies?locations=locations"/>
<property name="description" value="Esup Goodies WS"/>
</bean> |
...
| Bloc de code | ||||
|---|---|---|---|---|
| ||||
#!/usr/bin/python # -*- coding: utf-8 -*- nbParapluie = 0 nbCouteau = 0 nbGoodiesMyst = 0 nbPorteCartes = 0 nbPorteCarte = 0 nbPerdu = 0 total = 0 file = open('/tmp/csn.txt',"r") for csn in file: csnAsInt = int(csn, 16) modCsn = csnAsInt%51csnAsInt%85 if modCsn in range(0,1): nbParapluie+=1 elif modCsn in range(1,45): nbCouteau+=1 elif modCsn in range(45,1115): nbPorteCartes+=1 elif modCsn in range(1115,2845): nbGoodiesMyst+=1 elif modCsn in range(2845,5185): nbPorteCarte+=1 else: nbPerdu+=1 total+=1 file.close() print "Total : " + str(total) print "parapluies : " + str(round(nbParapluie*100.0/total,2)) + "%" print "couteaux : " + str(round(nbCouteau*100.0/total,2)) + "%" print "porte-cartes : " + str(round(nbPorteCartes*100.0/total,2)) + "%" print "goodies 20ans : " + str(round(nbGoodiesMyst*100.0/total,2)) + "%" print "porte-carte : " + str(round(nbPorteCarte*100.0/total,2)) + "%" print "perdu (censé être à 0) : " + str(round(nbPerdu*100.0/total,2)) + "%" |
...
| Bloc de code | ||||
|---|---|---|---|---|
| ||||
Total : 147153 parapluies : 1.97%14% couteaux : 54.87%5% porte-cartes : 1311.82%72% goodies 20ans : 3335.51%98% porte-carte : 4446.84%66% perdu (censé être à 0) : 0.0% |
Ce résultat est cohérent avec ce qui avait été imaginé (cf paragraphe "Cahier des charges").
Retex JRES 2021/2022
Du 17 au 20 mai à Marseille, le stand ESUP-Portail proposé lors des JRES 2021/2022 a connu une belle affluence.
L'idée de proposer un jeu pour se voir offrir un article a permis de clarifier la relation entre le congressiste et le représentant ESUP-Portail tenant le stand : chaque congressiste pouvait venir jouer dans le simple but de 'gagner' un lot ; si le jeu était un moyen ludique d'attirer le congressiste, ce-dernier n'avait du coup également aucun sentiment d'obligation vis-à-vis d'ESUP-Portail ; la relation congessiste/association partait ainsi sur des bases saines.
Le jeu de loterie NFC a permis de mettre en avant plus spécifiquement et précisément ESUP-SGC et ESUP-NFC-TAG ; des établissements se sont ainsi montrés intéressés par adopter la solution prochainement (dont des établissements découvrant la solution au travers de la visite au stand).
A noter enfin que le "goodies spécial 20 ans" était des savons de marseille de la savonnerie Marius Fabre (plus de 80% des lots étaient ainsi 'made in france').
Près de 600 'cartes' sans contact différentes ont été badgées et donc près de 600 lots ont été donnés à des congressistes ; plus de 700 badgeages ont été réalisés.
La répartition des lots a été la suivante :
| Bloc de code | ||||
|---|---|---|---|---|
| ||||
5 parapluies
35 couteaux
82 porte-cartes multiples
204 savons
272 porte-cartes simples |
Pédagogie NFC - usage du CSN
Au travers de ce jeu, les congressistes ont pu être sensibilisés au problème de sécurité des cartes :
- intérêt des protège-cartes anti-RFID ;
- intérêt d'utiliser et maitriser une carte type MIFARE Desfire pour sécuriser les usages (sgc, contrôle d'accès, ...) ; ce qui n'était pas le cas pour cette loterie, en toute conscience.
Vers la fin du congrès, on a pu donner un coup de projecteur sur cette page wiki au travers du Rocket Chat ESUP (utilisé par ailleurs comme outil de communication pour tous les participants de ces JRES 2021/2022) afin notamment, en filigrane, d'indiquer que le jeu pouvait, en plus d'être prédictif, être sujet à la tricherie
Hack In Provence s'est prêté au jeu et a gagné le gros lot (ils ont utilisé un dérivé d'un proxmark a priori) ; avec leur accord, on a pu prendre en photo le président de cette association
Côté ESUP, nous avions nous-même piraté notre loterie avec une carte magique et libnfc - cf Tags NFC - getting started#gettingstarted-libnfc



