You've already forked snikket-web-portal
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:
@@ -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":
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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():
|
||||
|
||||
Reference in New Issue
Block a user