You've already forked snikket-web-portal
Properly handle the various login error conditions
Note that this includes setting content types on the sessions, which is why this spills over into the XML IQ function.
This commit is contained in:
@@ -2,6 +2,7 @@ import binascii
|
|||||||
import contextlib
|
import contextlib
|
||||||
import functools
|
import functools
|
||||||
import hashlib
|
import hashlib
|
||||||
|
import json
|
||||||
|
|
||||||
import aiohttp
|
import aiohttp
|
||||||
|
|
||||||
@@ -22,7 +23,9 @@ class HTTPSessionManager:
|
|||||||
self._app_context_attribute = app_context_attribute
|
self._app_context_attribute = app_context_attribute
|
||||||
|
|
||||||
async def _create(self) -> aiohttp.ClientSession:
|
async def _create(self) -> aiohttp.ClientSession:
|
||||||
return aiohttp.ClientSession()
|
return aiohttp.ClientSession(headers={
|
||||||
|
"Accept": "application/json",
|
||||||
|
})
|
||||||
|
|
||||||
async def teardown(self, exc):
|
async def teardown(self, exc):
|
||||||
app_ctx = _app_ctx_stack.top
|
app_ctx = _app_ctx_stack.top
|
||||||
@@ -71,7 +74,8 @@ class HTTPAuthSessionManager(HTTPSessionManager):
|
|||||||
|
|
||||||
return aiohttp.ClientSession(
|
return aiohttp.ClientSession(
|
||||||
headers={
|
headers={
|
||||||
"Authorization": "Bearer {}".format(token)
|
"Authorization": "Bearer {}".format(token),
|
||||||
|
"Accept": "application/json",
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -141,10 +145,22 @@ class ProsodyClient:
|
|||||||
|
|
||||||
async with session.post(self._login_endpoint, data=request) as resp:
|
async with session.post(self._login_endpoint, data=request) as resp:
|
||||||
auth_status = resp.status
|
auth_status = resp.status
|
||||||
auth_info = (await resp.json())
|
auth_data = (await resp.read())
|
||||||
if auth_status == 401:
|
# XXX: this is a hack to work around mod_http_oauth2 not always
|
||||||
raise abort(401, "Invalid credentials")
|
# setting the correct Content-Type on the reply. #1500 / #1501
|
||||||
elif auth_status == 200:
|
auth_info = json.loads(auth_data.decode("utf-8"))
|
||||||
|
if "error" in auth_info and "context" in auth_info["error"]:
|
||||||
|
auth_info = auth_info["error"]["context"]["oauth2_response"]
|
||||||
|
|
||||||
|
# XXX: prosody-modules#1502
|
||||||
|
if auth_status in [400, 401] or "error" in auth_info:
|
||||||
|
# OAuth2 spec says that’s what can happen when some stuff is
|
||||||
|
# wrong.
|
||||||
|
# we have to interpret the JSON further
|
||||||
|
if auth_info["error"] == "invalid_grant":
|
||||||
|
raise abort(401)
|
||||||
|
|
||||||
|
if auth_status == 200:
|
||||||
token_type = auth_info["token_type"]
|
token_type = auth_info["token_type"]
|
||||||
if token_type != "bearer":
|
if token_type != "bearer":
|
||||||
raise NotImplementedError(
|
raise NotImplementedError(
|
||||||
@@ -153,8 +169,12 @@ class ProsodyClient:
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
return auth_info["access_token"]
|
return auth_info["access_token"]
|
||||||
else:
|
|
||||||
raise abort(500, "Unexpected backend response status: {!r}".format(auth_status, auth_info))
|
raise RuntimeError(
|
||||||
|
"unexpected authentication reply: ({}) {!r}".format(
|
||||||
|
auth_status, auth_info
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
async def login(self, jid: str, password: str):
|
async def login(self, jid: str, password: str):
|
||||||
async with self._plain_session as session:
|
async with self._plain_session as session:
|
||||||
@@ -202,7 +222,8 @@ class ProsodyClient:
|
|||||||
async def _xml_iq_call(self, session, payload, *, headers=None):
|
async def _xml_iq_call(self, session, payload, *, headers=None):
|
||||||
headers = headers or {}
|
headers = headers or {}
|
||||||
headers.update({
|
headers.update({
|
||||||
"Content-Type": "application/xmpp+xml"
|
"Content-Type": "application/xmpp+xml",
|
||||||
|
"Accept": "application/xmpp+xml",
|
||||||
})
|
})
|
||||||
print(payload)
|
print(payload)
|
||||||
async with session.post(self._rest_endpoint,
|
async with session.post(self._rest_endpoint,
|
||||||
|
|||||||
Reference in New Issue
Block a user