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.schemas import validate, GW_STATUS_UPDATE
from litecord.utils import (
task_wrapper, yield_chunks
task_wrapper, yield_chunks, maybe_int
)
from litecord.permissions import get_permissions
@ -770,11 +770,12 @@ class GatewayWebsocket:
if not exists:
return
# limit user_ids to 1000 possible members
user_ids = user_ids[:1000]
# limit user_ids to 1000 possible members, and try your best
# 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
# we don't do query.
# ASSUMPTION: requesting user_ids means we don't do query.
if user_ids:
members = await self.storage.get_member_multi(guild_id, user_ids)
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 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 quart.json import JSONEncoder
@ -214,3 +214,12 @@ async def search_result_from_list(rows: List) -> Dict[str, Any]:
'messages': res,
'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