...
| Info | ||
|---|---|---|
| ||
Lors des JRES 2021 (2022) à Marseille et en présentant un badge/périphérique RFID (en privlégiant privilégiant la carte multi-services de votre établissement si vous en disposez) au stand Esup-Portail, en fonction du numéro de série de ce badge, vous gagnerez peut-être gagnez un des goodies ESUP-Portail. Ce jeu s'appuie sur esup-sgc / esup-nfc-tag ; la description de cette mise en place est décrite dans cette page et fait ainsi office également de documentation illustrative technique du projet. Aucune donnée personnelle n'est récupérée, utilisée et conservée. |
...
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-carte cartes simples
A cela, dans le cadre des 20 ans d'ESUP-Portail, on ajoute dans le jeu environ 300 goodies "spécial 20 ans" ESUP
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 doivent donc être fonction de ce nombre de joueurs potentiels et sont fonction du stock de chaque lot.
- 1 chance sur 59 85 de gagner un parapluie
- puis 1 chance sur 31 de gagner un couteau "suisse"
- 4 chances sur 85 de gagner un couteau multifonctions
- 10 chances sur 85 de puis 1 chance sur 5 de gagner un porte-cartes (multiple)
- puis 1 chance sur 3 de gagner un porte-carte simple
- puis encore 1 chance sur 3 de gagner le goodies "30 chances sur 85 de gagner le "goodies spécial 20 ans " ESUPESUP"
- 40 chances sur 85 de gagner le porte-carte simple
Le badgeage peut être fait sur toute carte/dispositif RFID par les membres ESUP tenant le stand (après authentification Shibboleth via la fédération ESR) via un téléphone NFC disposant de ESUP-NFC-TAG-DROID disponible sur le Google Play ESUP-Portail.
...
Via le numéro de série de la carte, on fait une opération de modulo pour attribuer un lot (les modulos ont été choisis arbitrairement) :
- si (csn % 5985) == 16 0 -> parapluie
- si (csn % 31)==2 85) de 1 à 4 -> couteau
- si (csn % 5)==2 85) de 5 à 14 -> porte-cartes multiple
- si (csn % 85) de 15 à 44 -> goodies 20 ans
- si 3)==0 -> porte-carte simple (csn % 3)==1 -> goodies 20 ans85) de 45 à 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 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 import re 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 re.search(csn, linecsn==line.rstrip('\r\n'): alreadyChecked = True suffix = '[RE]' file.close() csnAsInt = int(csn, 16) ifmodCsn csnAsInt%59==16: csnAsInt%85 if modCsn in range(0,1): print('{"csn":"-", "eppn":"parapluie", "firstname":"%s", "lastname":"Parapluie !", "locations":"esup-goodies"}' % ('Gagné' + ('[RE]' if alreadyChecked else ''suffix))) elif csnAsInt%31==2 modCsn in range(1,5): print('{"csn":"-", "eppn":"couteau", "firstname":"%s", "lastname":"Couteau !", "locations":"esup-goodies"}' % ('Gagné' + ('[RE]' if alreadyChecked else ''))suffix)) elif csnAsInt%5==2 modCsn in range(5,15): print('{"csn":"-", "eppn":"porte-cartes", "firstname":"%s", "lastname":" Porte cartes !", "locations":"esup-goodies"}' % ('Gagné' + ('[RE]' if alreadyChecked else ''suffix))) elif csnAsInt%3==0modCsn in range(15,45): print('{"csn":"-", "eppn":"porte-carte-simplemystere", "firstname":"%s", "lastname":"PorteGoodies 20 carteans simple!", "locations":"esup-goodies"}' % ('Gagné' + ('[RE]' if alreadyChecked else '')))suffix)) # range(45,84): else : elif csnAsInt%3==1: print('{"csn":"-", "eppn":"mystereporte-carte-simple", "firstname":"%s", "lastname":"GoodiesPorte 20carte ans !simple", "locations":"esup-goodies"}' % ('Gagné' + ('[RE]' if alreadyChecked else '')))suffix)) if not alreadyChecked: else: file = printopen('{"csn":"-", "eppn":"perdu", "firstname":"%s", "lastname":":''-(", "locations":"esup-goodies"}' % ('Perdu' + ('[RE]' if alreadyChecked else ''))) if not alreadyChecked/var/www/log/goodies.txt',"a") file.write(csn + "\n") file.close() else: file = open('/var/www/log/goodies.txt',"a") print '[]' |
On déclare ces 2 implémentations de WS dans la configuration d'esup-nfc-tag-server ( src/main/resources/META-INF/spring/applicationContext-custom.xml ) :
| Bloc de code | ||||
|---|---|---|---|---|
| ||||
<bean id="tagIdCheckEsupGoodies" file.write(csn + "\n") class="org.esupportail.nfctag.service.api.impl.TagIdCheckRestWs"> <property name="description" value="ESUP file.close() else: Goodies"/> print '[]' |
On déclare ces 2 implémentations de WS dans la configuration d'esup-nfc-tag-server ( src/main/resources/META-INF/spring/applicationContext-custom.xml ) :
| Bloc de code | ||||
|---|---|---|---|---|
| ||||
<property name="tagIdCheckUrl" value="https://esup-sgc-demo.esup-portail.org/esup-goodies?tagIdCheck=tagIdCheck"/> </bean> <bean id="tagIdCheckEsupGoodiesesupGoodiesExtApi" class="org.esupportail.nfctag.service.api.impl.TagIdCheckRestWsAppliExtRestWs"> <property name="description" value="ESUP Goodies"/> <property name="tagIdCheckUrl"isTagableUrl" value="https://esup-sgc-demo.esup-portail.org/esup-sgc-demo.esup-portail.org?tagIdCheck=tagIdCheckgoodies?isTagable=isTagable"/> </bean> <bean<property idname="esupGoodiesExtApivalidateTagUrl" classvalue="org.esupportail.nfctag.service.api.impl.AppliExtRestWs"https://esup-sgc-demo.esup-portail.org/esup-goodies?validateTag=validateTag"/> <property name="isTagableUrlgetLocationsUrl" value="https://esup-sgc-demo.esup-portail.org/esup-sgc-demo.esup-portail.org?isTagable=isTagablegoodies?locations=locations"/> <property name="validateTagUrldescription" value="https://esup-sgc-demo.esup-portail.org/esup-sgc-demo.esup-portail.org?validateTag=validateTagEsup Goodies WS"/> <property name="getLocationsUrl" value="https://esup-sgc-demo.esup-portail.org/esup-sgc-demo.esup-portail.org?locations=locations"/> <property name="description" value="Esup Goodies WS"/> </bean> |
Enfin, après prise en compte (déploiement et redémarrage d'esup-nfc-tag-server), on déclare une 'application' esup-nfc-tag via l'interface de celui-ci :
</bean> |
Enfin, après prise en compte (déploiement et redémarrage d'esup-nfc-tag-server), on déclare une 'application' esup-nfc-tag via l'interface de celui-ci :
Les utilisateurs 'login@univ-Les utilisateurs 'login@univ-ville1.fr', 'autrelogin@univ-ville1.fr', 'login@univ-ville2.fr' peuvent ainsi badger des cartes et voir apparaitre sur leur téléphone et simultanément sur un ou des écrans si le badgeage est gagnant et pour quel lot gagné.
Statistiques - vérification des % de gain en fonction d'un échantillon de CSN
...
L'université de rouen ne dispose par exemple que de cartes avec des CSN pairs (peutPeut-être lié à la technologie Mifare Desfire ?).
...
| 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%85 if csnAsInt%59==16modCsn in range(0,1): nbParapluie+=1 elif csnAsInt%31==2modCsn in range(1,5): nbCouteau+=1 elif csnAsInt%5==2 modCsn in range(5,15): nbPorteCartes+=1 elif csnAsInt%3==0modCsn in range(15,45): nbPorteCartenbGoodiesMyst+=1 elif csnAsInt%3==1modCsn in range(45,85): nbGoodiesMystnbPorteCarte+=1 else: nbPerdu+=1 total+=1 file.close() print "Total : " + str(total) + "\n" print "parapluies : " + str(round(nbParapluie*100.0/total,2)) + "%\n" print "couteaux : " + str(round(nbCouteau*100.0/total,2)) + "%\n" print "porte-cartes : " + str(round(nbPorteCartes*100.0/total,2)) + "%\n" print "porte-cartegoodies 20ans : " + str(round(nbPorteCartenbGoodiesMyst*100.0/total,2)) + "%\n" print "goodies 20ansporte-carte : " + str(round(nbGoodiesMystnbPorteCarte*100.0/total,2)) + "%\n" print "perdu (censé être à 0) : " + str(round(nbPerdu*100.0/total,2)) + "%\n" |
Sur l'échantillon rouennais (récupérés en base de esup-sgc à univ-rouen), on a le résultat suivant :
| Bloc de code | ||||
|---|---|---|---|---|
| ||||
Total : 147153 parapluies : 1.75%14% couteaux : 34.18%5% porte-cartes : 1811.72% goodies 20ans : 35.98% porte-carte : 2546.27% goodies 20ans66% perdu (censé être à 0) : 25.44% perdu : 25.38%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



