mirror of
https://github.com/fluxerapp/fluxer
synced 2026-10-17 21:15:32 +09:00
perf(guild): add a lean channel auth context rpc (#2226)
This commit is contained in:
1 parent
8dc2bad843
commit
ba54b61dcf
11 files changed
+383
-25
No files matched your search
@@ -37,6 +37,7 @@ route(M, P) ->
|
||||
-define(HANDLER_MAP, #{
|
||||
<<"guild.dispatch">> => fun gateway_rpc_guild_lifecycle:handle/2,
|
||||
<<"guild.get_data">> => fun gateway_rpc_guild_lifecycle:handle/2,
|
||||
<<"guild.get_auth_context">> => fun gateway_rpc_guild_lifecycle:handle/2,
|
||||
<<"guild.start">> => fun gateway_rpc_guild_lifecycle:handle/2,
|
||||
<<"guild.stop">> => fun gateway_rpc_guild_lifecycle:handle/2,
|
||||
<<"guild.reload">> => fun gateway_rpc_guild_lifecycle:handle/2,
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
-spec handle(binary(), map()) -> term().
|
||||
handle(<<"guild.dispatch">>, P) -> handle_dispatch(P);
|
||||
handle(<<"guild.get_data">>, P) -> handle_get_data(P);
|
||||
handle(<<"guild.get_auth_context">>, P) -> handle_get_auth_context(P);
|
||||
handle(<<"guild.start">>, P) -> handle_start(P);
|
||||
handle(<<"guild.stop">>, P) -> handle_stop(P);
|
||||
handle(<<"guild.reload">>, P) -> handle_reload(P);
|
||||
@@ -47,6 +48,39 @@ handle_get_data(#{<<"guild_id">> := GuildIdBin, <<"user_id">> := UserIdBin}) ->
|
||||
<<"guild_not_found">>
|
||||
).
|
||||
|
||||
-spec handle_get_auth_context(map()) -> term().
|
||||
handle_get_auth_context(#{<<"guild_id">> := GuildIdBin, <<"user_id">> := UserIdBin} = Params) ->
|
||||
GuildId = validation:snowflake_or_throw(<<"guild_id">>, GuildIdBin),
|
||||
UserId = optional_user_id(UserIdBin),
|
||||
ChannelId = optional_channel_id(maps:get(<<"channel_id">>, Params, null)),
|
||||
gateway_rpc_guild_infra:with_guild(
|
||||
GuildId,
|
||||
fun(Pid) ->
|
||||
get_auth_context_from_guild(Pid, UserId, ChannelId)
|
||||
end,
|
||||
<<"guild_not_found">>
|
||||
).
|
||||
|
||||
-spec optional_channel_id(term()) -> integer() | null.
|
||||
optional_channel_id(Value) ->
|
||||
case validation:validate_optional_snowflake(Value) of
|
||||
{ok, null} -> null;
|
||||
{ok, ChannelId} when is_integer(ChannelId) -> ChannelId;
|
||||
_ -> gateway_rpc_error:raise(validation_invalid_params)
|
||||
end.
|
||||
|
||||
-spec get_auth_context_from_guild(pid(), integer() | null, integer() | null) -> term().
|
||||
get_auth_context_from_guild(Pid, UserId, ChannelId) ->
|
||||
Request = {get_guild_auth_context, #{user_id => UserId, channel_id => ChannelId}},
|
||||
case gen_server:call(Pid, Request, ?GUILD_CALL_TIMEOUT) of
|
||||
#{auth_context := null} ->
|
||||
gateway_rpc_error:raise(<<"forbidden">>);
|
||||
#{auth_context := AuthContext} ->
|
||||
AuthContext;
|
||||
_ ->
|
||||
gateway_rpc_error:raise(<<"guild_data_error">>)
|
||||
end.
|
||||
|
||||
-spec optional_user_id(term()) -> integer() | null.
|
||||
optional_user_id(Value) ->
|
||||
case validation:validate_optional_snowflake(Value) of
|
||||
@@ -194,4 +228,13 @@ optional_user_id_preserves_null_for_skip_membership_check_test() ->
|
||||
|
||||
optional_user_id_accepts_snowflake_test() ->
|
||||
?assertEqual(123, optional_user_id(<<"123">>)).
|
||||
|
||||
optional_channel_id_defaults_to_null_test() ->
|
||||
?assertEqual(null, optional_channel_id(null)).
|
||||
|
||||
optional_channel_id_accepts_snowflake_test() ->
|
||||
?assertEqual(456, optional_channel_id(<<"456">>)).
|
||||
|
||||
optional_channel_id_rejects_garbage_test() ->
|
||||
?assertError({gateway_rpc_error, _}, optional_channel_id(<<"nope">>)).
|
||||
-endif.
|
||||
@@ -89,6 +89,7 @@ query_call_handler(get_user_permissions) -> query;
|
||||
query_call_handler(can_manage_roles) -> query;
|
||||
query_call_handler(can_manage_role) -> query;
|
||||
query_call_handler(get_guild_data) -> query;
|
||||
query_call_handler(get_guild_auth_context) -> query;
|
||||
query_call_handler(get_assignable_roles) -> query;
|
||||
query_call_handler(get_user_max_role_position) -> query;
|
||||
query_call_handler(check_target_member) -> query;
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
-typing([eqwalizer]).
|
||||
|
||||
-export([get_guild_data/2]).
|
||||
-export([get_auth_context/2]).
|
||||
-export([get_guild_member/2]).
|
||||
-export([get_guild_members_batch/2]).
|
||||
-export([has_member/2]).
|
||||
@@ -33,6 +34,50 @@ get_guild_data(#{user_id := UserId}, State) ->
|
||||
get_guild_data_for_user(UserId, Data, State)
|
||||
end.
|
||||
|
||||
-spec get_auth_context(map(), guild_state()) -> guild_reply(map()).
|
||||
get_auth_context(#{user_id := UserId, channel_id := ChannelId}, State) ->
|
||||
Data = guild_data_index:ensure_data_map(State),
|
||||
case UserId of
|
||||
null ->
|
||||
{reply, #{auth_context => build_auth_context(ChannelId, Data, State)}, State};
|
||||
_ ->
|
||||
get_auth_context_for_member(UserId, ChannelId, Data, State)
|
||||
end.
|
||||
|
||||
-spec get_auth_context_for_member(user_id(), integer() | null, map(), guild_state()) ->
|
||||
guild_reply(map()).
|
||||
get_auth_context_for_member(UserId, ChannelId, Data, State) ->
|
||||
case guild_data_index:get_member(UserId, Data) of
|
||||
undefined ->
|
||||
{reply, #{auth_context => null, error_reason => <<"forbidden">>}, State};
|
||||
_Member ->
|
||||
{reply, #{auth_context => build_auth_context(ChannelId, Data, State)}, State}
|
||||
end.
|
||||
|
||||
-spec build_auth_context(integer() | null, map(), guild_state()) -> map().
|
||||
build_auth_context(ChannelId, Data, State) ->
|
||||
#{
|
||||
<<"guild">> => build_auth_guild(Data, State),
|
||||
<<"parent_channel">> => find_channel(ChannelId, Data)
|
||||
}.
|
||||
|
||||
-spec build_auth_guild(map(), guild_state()) -> map().
|
||||
build_auth_guild(Data, State) ->
|
||||
GuildProperties = map_utils:ensure_map(maps:get(<<"guild">>, Data, #{})),
|
||||
GuildProperties#{
|
||||
<<"roles">> => map_utils:ensure_list(maps:get(<<"roles">>, Data, [])),
|
||||
<<"member_count">> => maps:get(
|
||||
member_count, State, guild_data_index:member_count(Data)
|
||||
),
|
||||
<<"online_count">> => guild_member_list:get_online_count(State)
|
||||
}.
|
||||
|
||||
-spec find_channel(integer() | null, map()) -> map() | null.
|
||||
find_channel(null, _Data) ->
|
||||
null;
|
||||
find_channel(ChannelId, Data) ->
|
||||
maps:get(ChannelId, guild_data_index:channel_index(Data), null).
|
||||
|
||||
-spec get_guild_member(map(), guild_state()) -> guild_reply(map()).
|
||||
get_guild_member(Request, State) ->
|
||||
guild_data_members:get_guild_member(Request, State).
|
||||
|
||||
@@ -241,6 +241,8 @@ handle_max_role_position(#{user_id := UserId}, State) ->
|
||||
-spec handle_call_data(term(), guild_state()) -> {reply, term(), guild_state()}.
|
||||
handle_call_data({get_guild_data, Req}, State) ->
|
||||
guild_data:get_guild_data(request_map(Req), State);
|
||||
handle_call_data({get_guild_auth_context, Req}, State) ->
|
||||
guild_data:get_auth_context(request_map(Req), State);
|
||||
handle_call_data({get_guild_member, Req}, State) ->
|
||||
guild_data:get_guild_member(request_map(Req), State);
|
||||
handle_call_data({get_guild_members_batch, Req}, State) ->
|
||||
|
||||
Reference in new issue
Block a user