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"])
|
@app.route("/login", methods=["GET", "POST"])
|
||||||
async def login():
|
async def login():
|
||||||
if client.has_session:
|
if client.has_session and (await client.test_session()):
|
||||||
return redirect(url_for('user.index'))
|
return redirect(url_for('user.index'))
|
||||||
|
|
||||||
if request.method == "POST":
|
if request.method == "POST":
|
||||||
|
|||||||
@@ -186,7 +186,7 @@ class ProsodyClient:
|
|||||||
def decorator(f):
|
def decorator(f):
|
||||||
@functools.wraps(f)
|
@functools.wraps(f)
|
||||||
async def wrapped(*args, **kwargs):
|
async def wrapped(*args, **kwargs):
|
||||||
if not self.has_session:
|
if not self.has_session or not (await self.test_session()):
|
||||||
nonlocal redirect_to
|
nonlocal redirect_to
|
||||||
if redirect_to is not False:
|
if redirect_to is not False:
|
||||||
redirect_to = \
|
redirect_to = \
|
||||||
@@ -204,10 +204,12 @@ class ProsodyClient:
|
|||||||
headers.update({
|
headers.update({
|
||||||
"Content-Type": "application/xmpp+xml"
|
"Content-Type": "application/xmpp+xml"
|
||||||
})
|
})
|
||||||
|
print(payload)
|
||||||
async with session.post(self._rest_endpoint,
|
async with session.post(self._rest_endpoint,
|
||||||
headers=headers,
|
headers=headers,
|
||||||
data=payload) as resp:
|
data=payload) as resp:
|
||||||
print(payload)
|
if resp.status != 200:
|
||||||
|
abort(resp.status)
|
||||||
reply_payload = await resp.read()
|
reply_payload = await resp.read()
|
||||||
print(reply_payload)
|
print(reply_payload)
|
||||||
return ET.fromstring(reply_payload)
|
return ET.fromstring(reply_payload)
|
||||||
@@ -224,7 +226,7 @@ class ProsodyClient:
|
|||||||
session=session,
|
session=session,
|
||||||
)
|
)
|
||||||
avatar_hash = avatar_info["sha1"]
|
avatar_hash = avatar_info["sha1"]
|
||||||
except quart.exceptions.BaseException:
|
except quart.exceptions.HTTPException:
|
||||||
avatar_hash = None
|
avatar_hash = None
|
||||||
|
|
||||||
return {
|
return {
|
||||||
@@ -235,6 +237,18 @@ class ProsodyClient:
|
|||||||
"avatar_hash": avatar_hash,
|
"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
|
@autosession
|
||||||
async def get_user_nickname(self, session):
|
async def get_user_nickname(self, session):
|
||||||
iq_resp = await self._xml_iq_call(
|
iq_resp = await self._xml_iq_call(
|
||||||
|
|||||||
@@ -55,12 +55,14 @@ class ProfileForm(FlaskForm):
|
|||||||
|
|
||||||
|
|
||||||
@user_bp.route("/")
|
@user_bp.route("/")
|
||||||
|
@client.require_session()
|
||||||
async def index():
|
async def index():
|
||||||
user_info = await client.get_user_info()
|
user_info = await client.get_user_info()
|
||||||
return await render_template("user_home.html", user_info=user_info)
|
return await render_template("user_home.html", user_info=user_info)
|
||||||
|
|
||||||
|
|
||||||
@user_bp.route('/passwd', methods=["GET", "POST"])
|
@user_bp.route('/passwd', methods=["GET", "POST"])
|
||||||
|
@client.require_session()
|
||||||
async def change_pw():
|
async def change_pw():
|
||||||
form = ChangePasswordForm()
|
form = ChangePasswordForm()
|
||||||
if form.validate_on_submit():
|
if form.validate_on_submit():
|
||||||
@@ -82,6 +84,7 @@ async def change_pw():
|
|||||||
|
|
||||||
|
|
||||||
@user_bp.route("/profile", methods=["GET", "POST"])
|
@user_bp.route("/profile", methods=["GET", "POST"])
|
||||||
|
@client.require_session()
|
||||||
async def profile():
|
async def profile():
|
||||||
form = ProfileForm()
|
form = ProfileForm()
|
||||||
if request.method != "POST":
|
if request.method != "POST":
|
||||||
@@ -106,6 +109,7 @@ async def profile():
|
|||||||
|
|
||||||
|
|
||||||
@user_bp.route("/logout", methods=["GET", "POST"])
|
@user_bp.route("/logout", methods=["GET", "POST"])
|
||||||
|
@client.require_session()
|
||||||
async def logout():
|
async def logout():
|
||||||
form = LogoutForm()
|
form = LogoutForm()
|
||||||
if form.validate_on_submit():
|
if form.validate_on_submit():
|
||||||
|
|||||||
Reference in New Issue
Block a user