gateway.websocket: cast user_ids to List[Union[int, Any]]

this finishes the implementation, as before it was simply List[Any]
(List[str] on well-formed requests), which means Any was always being
passed to get_member_multi, which only works with ints.
This commit is contained in:
Luna 2019-09-07 12:13:21 -03:00
parent f1ca177118
commit 3973ca863c
3 changed files with 32 additions and 6 deletions

16
docs/differences.md Normal file
View File

@ -0,0 +1,16 @@
# API Differences
## Request Guild Members
### In regards to ID serialization
Request Guild Members does not follow the same logic Discord does when
invalid IDs are given on the `user_ids` field.
Instead of returning them as non-string numbers, **they're returned as-is.**
This should not cause any problems to well-formed requests.
### Assumptions on business logic
When using `user_ids`, Litecord will ignore the given `query` in the payload.

View File

@ -32,7 +32,7 @@ from litecord.auth import raw_token_check
from litecord.enums import RelationshipType, ChannelType from litecord.enums import RelationshipType, ChannelType
from litecord.schemas import validate, GW_STATUS_UPDATE from litecord.schemas import validate, GW_STATUS_UPDATE
from litecord.utils import ( from litecord.utils import (
task_wrapper, yield_chunks task_wrapper, yield_chunks, maybe_int
) )
from litecord.permissions import get_permissions from litecord.permissions import get_permissions
@ -770,11 +770,12 @@ class GatewayWebsocket:
if not exists: if not exists:
return return
# limit user_ids to 1000 possible members # limit user_ids to 1000 possible members, and try your best
user_ids = user_ids[:1000] # to convert them to ints, giving the same user id if it fails.
# this is checked later on to fill the not_found array
user_ids = [maybe_int(uid) for uid in user_ids[:1000]]
# assumption: requesting user_ids means # ASSUMPTION: requesting user_ids means we don't do query.
# we don't do query.
if user_ids: if user_ids:
members = await self.storage.get_member_multi(guild_id, user_ids) members = await self.storage.get_member_multi(guild_id, user_ids)
mids = [m['user']['id'] for m in members] mids = [m['user']['id'] for m in members]

View File

@ -19,7 +19,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
import asyncio import asyncio
import json import json
from typing import Any, Iterable, Optional, Sequence, List, Dict from typing import Any, Iterable, Optional, Sequence, List, Dict, Union
from logbook import Logger from logbook import Logger
from quart.json import JSONEncoder from quart.json import JSONEncoder
@ -214,3 +214,12 @@ async def search_result_from_list(rows: List) -> Dict[str, Any]:
'messages': res, 'messages': res,
'analytics_id': '', 'analytics_id': '',
} }
def maybe_int(val: Any) -> Union[int, Any]:
"""Try to convert a given value to an integer. Returns the same value
if it is not."""
try:
return int(val)
except (ValueError, TypeError):
return val