1
0
Fork 0
mirror of https://github.com/YunoHost-Apps/ihatemoney_ynh.git synced 2024-09-03 19:26:15 +02:00

RequestRedirect uses a HTTP 301. We need 303.

This is mainly because 301 is cacheable whereas 303 (See other) isn't.
The redirect response given by the app when trying to connect to a project
(via /project_name) while not authenticated was to permanently redirect to
/authenticate.

Once authenticated, the browser was redirected to the /project_name, that was
cached, leading to an endless loop.

303 see other allows to solve this problem.
This commit is contained in:
Alexis Metaireau 2011-08-21 22:35:01 +02:00
parent 63777c16bc
commit 9eab5be9a3
2 changed files with 14 additions and 26 deletions

View file

@ -1,5 +1,6 @@
from functools import wraps from functools import wraps
from flask import redirect, url_for, session, request from flask import redirect, url_for, session, request
from werkzeug.routing import HTTPException, RoutingException
from models import Bill, Project from models import Bill, Project
from forms import BillForm from forms import BillForm
@ -19,29 +20,17 @@ def get_billform_for(project, set_default=True):
form.set_default() form.set_default()
return form return form
def requires_auth(f): class Redirect303(HTTPException, RoutingException):
"""Decorator checking that the user do have access to the given project id. """Raise if the map requests a redirect. This is for example the case if
`strict_slashes` are activated and an url that requires a trailing slash.
If not, redirects to an authentication page, otherwise display the requested The attribute `new_url` contains the absolute destination url.
page.
""" """
code = 303
@wraps(f) def __init__(self, new_url):
def decorator(*args, **kwargs): RoutingException.__init__(self, new_url)
# if a project id is specified in kwargs, check we have access to it self.new_url = new_url
# get the password matching this project id
# pop project_id out of the kwargs
project_id = kwargs.pop('project_id')
project = Project.query.get(project_id)
if not project:
return redirect(url_for("create_project", project_id=project_id))
if project.id in session and session[project.id] == project.password: def get_response(self, environ):
# add project into kwargs and call the original function return redirect(self.new_url, 303)
kwargs['project'] = project
return f(*args, **kwargs)
else:
# redirect to authentication page
return redirect(url_for("authenticate",
project_id=project.id, redirect_url=request.url))
return decorator

View file

@ -2,12 +2,11 @@ from collections import defaultdict
from flask import * from flask import *
from flaskext.mail import Mail, Message from flaskext.mail import Mail, Message
from werkzeug.routing import RequestRedirect
# local modules # local modules
from models import db, Project, Person, Bill from models import db, Project, Person, Bill
from forms import ProjectForm, AuthenticationForm, BillForm, MemberForm, InviteForm from forms import ProjectForm, AuthenticationForm, BillForm, MemberForm, InviteForm
from utils import get_billform_for, requires_auth from utils import get_billform_for, Redirect303
# create the application, initialize stuff # create the application, initialize stuff
app = Flask(__name__) app = Flask(__name__)
@ -40,13 +39,13 @@ def pull_project(endpoint, values):
if project_id: if project_id:
project = Project.query.get(project_id) project = Project.query.get(project_id)
if not project: if not project:
raise RequestRedirect(url_for("create_project", project_id=project_id)) raise Redirect303(url_for("create_project", project_id=project_id))
if project.id in session and session[project.id] == project.password: if project.id in session and session[project.id] == project.password:
# add project into kwargs and call the original function # add project into kwargs and call the original function
g.project = project g.project = project
else: else:
# redirect to authentication page # redirect to authentication page
raise RequestRedirect( raise Redirect303(
url_for("authenticate", project_id=project_id)) url_for("authenticate", project_id=project_id))
@app.route("/authenticate", methods=["GET", "POST"]) @app.route("/authenticate", methods=["GET", "POST"])