Fix various edge cases around stale sessions

If a session cookie is set, but prosody doesn’t know about the
session anymore, we could get into fun states. This patch fixes
them by requiring the session to be tested with a ping request
on each HTTP request.
This commit is contained in:
Jonas Schäfer
2020-03-07 13:10:49 +01:00
parent 5ee2d97eb6
commit 71733adc90
3 changed files with 22 additions and 4 deletions

View File

@@ -19,7 +19,7 @@ client.default_login_redirect = "login"
@app.route("/login", methods=["GET", "POST"])
async def login():
if client.has_session:
if client.has_session and (await client.test_session()):
return redirect(url_for('user.index'))
if request.method == "POST":

View File

@@ -186,7 +186,7 @@ class ProsodyClient:
def decorator(f):
@functools.wraps(f)
async def wrapped(*args, **kwargs):
if not self.has_session:
if not self.has_session or not (await self.test_session()):
nonlocal redirect_to
if redirect_to is not False:
redirect_to = \
@@ -204,10 +204,12 @@ class ProsodyClient:
headers.update({
"Content-Type": "application/xmpp+xml"
})
print(payload)
async with session.post(self._rest_endpoint,
headers=headers,
data=payload) as resp:
print(payload)
if resp.status != 200:
abort(resp.status)
reply_payload = await resp.read()
print(reply_payload)
return ET.fromstring(reply_payload)
@@ -224,7 +226,7 @@ class ProsodyClient:
session=session,
)
avatar_hash = avatar_info["sha1"]
except quart.exceptions.BaseException:
except quart.exceptions.HTTPException:
avatar_hash = None
return {
@@ -235,6 +237,18 @@ class ProsodyClient:
"avatar_hash": avatar_hash,
}
@autosession
async def test_session(self, session):
req = {
"kind": "iq",
"type": "get",
"ping": True,
"to": self.session_address,
}
async with session.post(self._rest_endpoint, data=req) as resp:
return resp.status == 200
@autosession
async def get_user_nickname(self, session):
iq_resp = await self._xml_iq_call(

View File

@@ -55,12 +55,14 @@ class ProfileForm(FlaskForm):
@user_bp.route("/")
@client.require_session()
async def index():
user_info = await client.get_user_info()
return await render_template("user_home.html", user_info=user_info)
@user_bp.route('/passwd', methods=["GET", "POST"])
@client.require_session()
async def change_pw():
form = ChangePasswordForm()
if form.validate_on_submit():
@@ -82,6 +84,7 @@ async def change_pw():
@user_bp.route("/profile", methods=["GET", "POST"])
@client.require_session()
async def profile():
form = ProfileForm()
if request.method != "POST":
@@ -106,6 +109,7 @@ async def profile():
@user_bp.route("/logout", methods=["GET", "POST"])
@client.require_session()
async def logout():
form = LogoutForm()
if form.validate_on_submit():