Commit ffe41e69 authored by Nicolas Joyard's avatar Nicolas Joyard

Ajout login par token

parent 2a7c5c2a
......@@ -19,26 +19,7 @@ DEBUT_RELEVES = datetime.date(_y, _m, DEBUT_ACTION.day)
DELAI_RELANCE = 7
DELAI_REPONSE = 2
#
# Lors de la modification de ces énumérations, penser à créer une migration DB
# pour mettre à jour les types ENUM correspondants en base de données.
#
CHAMBRES = {
'AN': 'Assemblée nationale',
'SEN': 'Sénat',
}
SEXES = {
'F': 'Femme',
'H': 'Homme',
}
#
# Lors de la modification de cette énumération, relancer l'import des étapes.
# L'ordre est utilisé comme clé primaire lors de cet import.
#
# Etapes
ETAPE_DOC_PUBLIE = -31
ETAPE_DOC_MASQUE = -30
......@@ -198,3 +179,19 @@ ETAPES = [
]
ETAPES_BY_ORDRE = {e['ordre']: e for e in ETAPES}
#
# Lors de la modification de ces énumérations, penser à créer une migration DB
# pour mettre à jour les types ENUM correspondants en base de données.
#
CHAMBRES = {
'AN': 'Assemblée nationale',
'SEN': 'Sénat',
}
SEXES = {
'F': 'Femme',
'H': 'Homme',
}
......@@ -15,8 +15,9 @@ from ..models.constants import (ETAPE_A_CONFIRMER, ETAPE_A_ENVOYER,
ETAPE_COM_A_MODERER, ETAPE_COM_PUBLIE,
ETAPE_ENVOYE, ETAPE_NA)
from ..tools.files import generer_demande, handle_upload
from ..tools.routing import not_found, redirect_back, remote_addr, require_user
from ..tools.text import check_suivi, slugify
from ..tools.routing import (can_login_from_token, not_found, redirect_back,
remote_addr, require_user)
from ..tools.text import check_suivi, create_usertoken as token, slugify
def pris_en_charge(parl, force=False):
......@@ -71,6 +72,7 @@ def setup_routes(app):
)
@app.route('/parlementaires/<id>', endpoint='parlementaire')
@can_login_from_token
def parlementaire(id):
parl = Parlementaire.query \
.filter_by(id=id) \
......@@ -143,6 +145,8 @@ def setup_routes(app):
subject = 'Transparence IRFM - Envoi d\'une demande de documents'
body = render_template('courriers/mail_prise_en_charge.txt.j2',
token=token(session['user']['id'],
app.config['SECRET_KEY']),
parlementaire=parl)
msg = Message(subject=subject, body=body,
sender=('Regards Citoyens',
......@@ -152,6 +156,9 @@ def setup_routes(app):
with open(os.path.join(files_root, filename), 'rb') as f:
msg.attach(filename, 'application/pdf', f.read())
if app.config['MAIL_SUPPRESS_SEND']:
print(msg)
mail.send(msg)
return redirect(url_for('parlementaire', id=id))
......
......@@ -17,7 +17,7 @@ Voici la marche à suivre :
2. Retournez sur la page du parlementaire pour nous envoyer le numéro de suivi
du courrier et ansi confirmer l'envoi :
<{{ url_for('parlementaire', id=parlementaire.id, _external=True) }}>.
<{{ url_for('parlementaire', id=parlementaire.id, ut=token, _external=True) }}>.
N'oubliez pas cette étape pour que nous puissions suivre l'avancement de
l'opération ! Vous pourrez si vous le souhaitez joindre une photo ou un
......@@ -27,7 +27,7 @@ Voici la marche à suivre :
vous en devenez automatiquement membre. L'adhésion est gratuite et sans
aucune obligation. Vous pouvez si vous le souhaitez vous abonner à la liste
de discussion des membres de l'association depuis la page de votre profil:
<{{ url_for('profil', _external=True) }}>.
<{{ url_for('profil', ut=token, _external=True) }}>.
Note : pour pouvoir confirmer l'envoi, vous devrez vous identifier avec les
mêmes identifiants, à savoir :
......@@ -36,7 +36,7 @@ mêmes identifiants, à savoir :
E-mail: {{ session.user.email }}
Enfin, si vous changez d'avis (ce n'est pas grave !), merci de le signaler sur
la page du parlementaire <{{ url_for('parlementaire', id=parlementaire.id, _external=True) }}>.
la page du parlementaire <{{ url_for('parlementaire', id=parlementaire.id, ut=token, _external=True) }}>.
N'hésitez pas à nous contacter par e-mail en cas de souci.
......
......@@ -16,15 +16,9 @@ envoyé, et si vous le souhaitez, d'y joindre une photo ou un scan de la preuve
d'envoi.
Pour retrouver la liste des parlementaires que vous avez pris en charge,
accédez au site <{{ url_for('home', _external=True) }}>. Vous devrez vous
identifier (en cliquant sur le bouton « S'identifier » en haut à droite de la
page) avec les informations utilisées lors de la prise en charge de l'envoi,
c'est-à-dire :
utilisez le lien ci-dessous:
Pseudo: {{ user.nick }}
E-mail: {{ user.email }}
Vous pourrez alors cliquer sur « Mes actions » dans le menu en tête de page.
<{{ url_for('mes_actions', ut=token, _external=True) }}>
Sans nouvelles de votre part sous {{ delai_reponse }} jours, nous remettrons l'envoi à
disposition d'autres citoyens.
......
......@@ -15,6 +15,7 @@ from ..models.constants import (DELAI_RELANCE, DELAI_REPONSE, ETAPE_NA,
ETAPE_A_CONFIRMER)
from ..tools.files import generer_demande
from ..tools.text import create_usertoken as token
def mailing_lists():
......@@ -153,6 +154,7 @@ def envoyer_relances(app, envoyer):
subject = 'Transparence IRFM - Relance'
body = render_template('courriers/mail_relance.txt.j2',
user=user,
token=token(user.id, app.config['SECRET_KEY']),
parls=[a.parlementaire for a in acts],
delai_relance=DELAI_RELANCE,
delai_reponse=DELAI_REPONSE)
......
# -*- coding: utf-8 -*-
from flask import flash, redirect, request, session, url_for
from flask import current_app, flash, redirect, request, session, url_for
from .text import is_safe_url
from .text import check_usertoken, is_safe_url
from ..models import User
def try_login_from_token():
if 'ut' not in request.values:
return
uid = check_usertoken(request.values['ut'],
current_app.config['SECRET_KEY'])
try:
user = User.query.filter(User.id == uid).one()
session['user'] = {
'id': user.id,
'nick': user.nick,
'email': user.email,
'admin': False
}
except:
return
def redirect_back(fallback=None, **kwargs):
for k, v in kwargs.items():
flash(v, category=k)
......@@ -23,8 +42,17 @@ def not_found():
return redirect_back(error='Oups, la page demandée n\'existe pas')
def can_login_from_token(f):
def decorator(*args, **kwargs):
try_login_from_token()
return f(*args, **kwargs)
return decorator
def require_user(f):
def decorator(*args, **kwargs):
try_login_from_token()
if not session.get('user'):
return redirect_back(login_error='Vous devez vous identifier pour '
'accéder à cette page',
......
......@@ -21,6 +21,17 @@ def check_password(candidate, hashed_password, secret):
hashed_password)
def create_usertoken(uid, secret):
return '%s:%s' % (uid, hash_password('user #%s' % uid, secret))
def check_usertoken(token, secret):
if ':' in token:
uid, tok = token.split(':', 1)
if hmac.compare_digest(hash_password('user #%s' % uid, secret), tok):
return uid
def check_suivi(text):
return text and re.search(r'^\d[A-Z]\d{11}$', text.upper())
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment