misc: add {% temporary_access_url %} for temporary access to formdata (#82088) #768
Loading…
Reference in New Issue
No description provided.
Delete Branch "wip/82088-temporary-formdata-url"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
b7875818e3
to63c92f3728
63c92f3728
to03c61f0dab
WIP: misc: add {% temporary_access_url %} for temporary access to formdata (#82088)to misc: add {% temporary_access_url %} for temporary access to formdata (#82088)03c61f0dab
to7743372254
7743372254
to227b8fe1e8
227b8fe1e8
tof14c4f03fb
@ -101,3 +101,3 @@
assert resp.json['err'] == 0
assert resp.json['url'] == 'http://example.net/test/%s/' % formdata.id
assert resp.json['load_url'] == 'http://example.net/code/%s/load' % code.id
assert get_app(pub).get(resp.json['load_url']).location == formdata.get_url()
L'API de code de suivi retourne désormais une URL d'accès temporaire, on vérifie qu'en y accédant on est bien envoyé vers la bonne demande.
@ -1658,7 +1658,6 @@ def test_form_draft_with_file(pub):
resp = login(get_app(pub), username='foo', password='foo').get('/')
resp.forms[0]['code'] = tracking_code
resp = resp.forms[0].submit()
assert resp.location == 'http://example.net/code/%s/load' % tracking_code
À pas mal d'endroits dans les tests il y avait un utilisation ou vérification de /code/XXX/load, c'est modifié.
@ -317,1 +318,3 @@
resp = get_app(pub).get('http://example.net/code/%s/load' % tracking_code)
resp = get_app(pub).get('/')
resp.forms[0]['code'] = tracking_code
resp = resp.forms[0].submit()
Il y avait un petit raccourci ici à aller directement sur l'URL de code de suivi, c'est modifié pour passer par le formulaire de code de suivi (présent nativement sur la page d'accueil, mais qu'on ne voit généralement pas dans Publik).
@ -352,6 +360,19 @@ def test_form_tracking_code_rate_limit(pub, freezer):
# and ok again
get_app(pub).get('/code/ABC/load', status=404)
# ditto with POST to /code/
Avec les changements dans le code il devient utile de faire du rate limiting ici aussi (avant c'était toujours une redirection, maintenant ça va envoyer directement une 404 en cas de code de suivi pas trouvé, sans rate limiting ça permettrait donc de passer sur toutes les combinaisons possibles).
@ -737,0 +763,4 @@
formdata = formdef.data_class().select()[0]
resp = get_app(pub).get(f'/code/{tracking_code}/load')
assert resp.location == formdata.get_url()
C'est encore autorisé pour le moment.
@ -737,0 +768,4 @@
pub.load_site_options()
if not pub.site_options.has_section('options'):
pub.site_options.add_section('options')
pub.site_options.set('options', 'allow-tracking-code-in-url', 'false')
Mais il y a déjà un feature flag pour retirer ça.
@ -737,0 +774,4 @@
get_app(pub).get(f'/code/{tracking_code}/load', status=403)
def test_temporary_access_url(pub, freezer):
Les tests exhaustifs sur la nouvelle URL avec long jeton.
@ -1242,3 +1242,3 @@
'err': 0,
'url': formdata.get_url(),
'load_url': get_publisher().get_frontoffice_url() + '/code/%s/load' % component,
'load_url': formdata.get_temporary_access_url(duration=300),
L'API de code de suivi (utilisée depuis combo) renvoie donc désormais une URL d'accès temporaire.
La documentation prévient depuis longtemps :
@ -845,0 +849,4 @@
token.context = {
'form_slug': self.formdef.slug,
'form_type': self.formdef.xml_root_node,
'form_number_raw': self.id,
Dans l'absolu ça permettrait de référencer une fiche mais il n'y a a priori pas d'utilité.
@ -158,2 +158,3 @@
def load(self):
@classmethod
def get_formdata_from_code(cls, code):
La récupération d'un formdata depuis un code de suivi est déplacée dans cette méthode de classe, pour pouvoir ensuite être également exploitée par /code/load
@ -185,2 +203,4 @@
raise errors.AccessForbiddenError()
if not bypass_checks:
if formdata.formdef.enable_tracking_codes is False:
Le bypass_checks permet de faire une URL d'accès temporaire sur une démarche sans code de suivi activé.
@ -214,2 +214,2 @@
bad_content = False
if form.is_submitted() and not form.has_errors():
if not bypass_checks:
verify_fields = []
Et le bypass_checks zappe aussi la partie où on demande le contenu d'un champ existant.
C'est la situation du besoin d'Anaïs, pouvoir en cours de saisie faire un lien vers la connexion pour inviter l'usager à se connecter, et revenir où il était, ça serait nul au retour de demander à l'usager ce qu'il vient juste de saisir.
À part ça le code ici ne change pas, il est juste indenté.
@ -246,2 +273,4 @@
def load(self):
if get_request().get_method() != 'POST':
raise MethodNotAllowedError(allowed_methods=['POST', 'PUT'])
Le formulaire en page d'accueil (évoqué plus haut) amenait sur /code/load?code=XXX, ici c'est modifié pour accepter uniquement du POST. (parce que pourquoi interdire /code/XXX/load si /code/load?code=XXX permet pareil).
@ -2072,3 +2102,3 @@
r += htmltext('<h3>%s</h3>') % _('Tracking code')
r += htmltext('<form action="/code/load">')
r += htmltext('<form action="/code/load" method="POST">')
r += htmltext('<input size="12" name="code" placeholder="%s"/>') % _('ex: RPQDFVCD')
On passe donc en POST.
@ -447,6 +447,7 @@ class QommonPublisher(Publisher):
'unused-files-behaviour': 'remove',
'relatable-hosts': '',
'disabled-fields': 'ranked-items, table, table-select, tablerows',
'allow-tracking-code-in-url': 'true',
Pour le moment on accepte encore, ça sera changé.
@ -1192,0 +1198,4 @@
# {% temporary_access_url %}
# parameters:
# * days/hours/minutes/seconds, to set duration of access (by default, 5 minutes)
# * bypass_checks, to give direct access, without checking if tracking code is enabled or
On arrive enfin au template tag évoqué dans le ticket.
@ -1192,0 +1215,4 @@
for amount, unit in ((days, 86400), (hours, 3600), (minutes, 60), (seconds, 1)):
duration += (unlazy(amount) or 0) * unit
if not duration:
duration = 300 # 5 minutes
Par défaut 5 minutes.
@ -1192,0 +1217,4 @@
if not duration:
duration = 300 # 5 minutes
duration = min(duration, 10 * 86400) # maximum duration is 10 days.
Et jamais plus de 10 jours.
f14c4f03fb
toedd7867221
@ -1192,0 +1197,4 @@
):
# {% temporary_access_url %}
# parameters:
# * days/hours/minutes/seconds, to set duration of access (by default, 30 minutes)
Valeur par défaut à 30 minutes pour suivre le commentaire https://dev.entrouvert.org/issues/82088#note-9 (qui n'était pas une relecture).
edd7867221
to0feb35a6e8
J'ai posé deux commentaires anecdotiques. Pour le reste, il me semble que tu as pensé à tout.
@ -737,0 +805,4 @@
# valid token
token.context = {'form_slug': formdef.slug, 'form_number_raw': formdata.id}
token.store()
get_app(pub).get(f'/code/{token.id}/load', status=302)
Je m'attendais éventuellement à un test du « location » reçu, mais 302 est déjà un signe que ça marche, on peut effectivement s'en contenter.
Ok j'ajoute :
@ -1242,3 +1242,3 @@
'err': 0,
'url': formdata.get_url(),
'load_url': get_publisher().get_frontoffice_url() + '/code/%s/load' % component,
'load_url': formdata.get_temporary_access_url(duration=300),
Ces 300 secondes sont dans l'idée que le load_url va être appelé très rapidement après ? (par combo, typiquement) ? 300 secondes ça parait presque un peu long dans ce cas... Je mettrais éventuellement un petit commentaire ici pour rappeler sommairement l'usage de ce load_url
Commentaire pas des masses inspirés, et durée réduite à 30 secondes parce que ça doit être bien suffisant depuis combo.
(combo fait ceci :
)
0feb35a6e8
to8371c66c3e