Add admin status check endpoint to guild routes
Introduced `/guilds/members/{guildId}/{userId}/admin` endpoint to determine if a guild member is an admin. Added `AdminStatusResponse` DTO and documented the new route with OpenAPI annotations. This feature allows for efficient admin status verification with fallback to REST fetch on cache miss.
This commit is contained in:
1 parent
861b3f90e7
commit
e0ec43813d
2 files changed
+52
No files matched your search
@@ -19,6 +19,7 @@ import io.javalin.openapi.OpenApiRequestBody;
|
|||||||
import io.javalin.openapi.OpenApiResponse;
|
import io.javalin.openapi.OpenApiResponse;
|
||||||
import me.bobert.netneutrality.db.service.GuildService;
|
import me.bobert.netneutrality.db.service.GuildService;
|
||||||
import me.bobert.netneutrality.db.service.GuildServiceProvider;
|
import me.bobert.netneutrality.db.service.GuildServiceProvider;
|
||||||
|
import me.bobert.netneutrality.http.server.dto.AdminStatusResponse;
|
||||||
import me.bobert.netneutrality.http.server.dto.ChannelSummaryResponse;
|
import me.bobert.netneutrality.http.server.dto.ChannelSummaryResponse;
|
||||||
import me.bobert.netneutrality.http.server.dto.ErrorResponse;
|
import me.bobert.netneutrality.http.server.dto.ErrorResponse;
|
||||||
import me.bobert.netneutrality.http.server.dto.GuildBooleanUpdateRequest;
|
import me.bobert.netneutrality.http.server.dto.GuildBooleanUpdateRequest;
|
||||||
@@ -31,6 +32,7 @@ import me.bobert.netneutrality.http.server.dto.MemberSummaryResponse;
|
|||||||
import me.bobert.netneutrality.http.server.dto.OwnerResponse;
|
import me.bobert.netneutrality.http.server.dto.OwnerResponse;
|
||||||
import me.bobert.netneutrality.http.server.dto.RoleSummaryResponse;
|
import me.bobert.netneutrality.http.server.dto.RoleSummaryResponse;
|
||||||
import me.bobert.netneutrality.http.server.dto.VoiceChannelSummaryResponse;
|
import me.bobert.netneutrality.http.server.dto.VoiceChannelSummaryResponse;
|
||||||
|
import me.bobert.netneutrality.utils.UserFunction;
|
||||||
import net.dv8tion.jda.api.JDA;
|
import net.dv8tion.jda.api.JDA;
|
||||||
import net.dv8tion.jda.api.entities.Guild;
|
import net.dv8tion.jda.api.entities.Guild;
|
||||||
import net.dv8tion.jda.api.entities.Member;
|
import net.dv8tion.jda.api.entities.Member;
|
||||||
@@ -59,6 +61,7 @@ public final class GuildRoutes {
|
|||||||
routes.get("/guilds/roles/{guildId}", ctx -> roles(jdaSupplier, ctx));
|
routes.get("/guilds/roles/{guildId}", ctx -> roles(jdaSupplier, ctx));
|
||||||
routes.get("/guilds/members/{guildId}/{userId}", ctx -> member(jdaSupplier, ctx));
|
routes.get("/guilds/members/{guildId}/{userId}", ctx -> member(jdaSupplier, ctx));
|
||||||
routes.get("/guilds/members/{guildId}/{userId}/roles", ctx -> memberRoles(jdaSupplier, ctx));
|
routes.get("/guilds/members/{guildId}/{userId}/roles", ctx -> memberRoles(jdaSupplier, ctx));
|
||||||
|
routes.get("/guilds/members/{guildId}/{userId}/admin", ctx -> memberAdmin(jdaSupplier, ctx));
|
||||||
routes.get("/guilds/voice-channels/{guildId}", ctx -> voiceChannels(jdaSupplier, ctx));
|
routes.get("/guilds/voice-channels/{guildId}", ctx -> voiceChannels(jdaSupplier, ctx));
|
||||||
routes.get("/guilds/voice-channels/{guildId}/{channelId}", ctx -> voiceChannel(jdaSupplier, ctx));
|
routes.get("/guilds/voice-channels/{guildId}/{channelId}", ctx -> voiceChannel(jdaSupplier, ctx));
|
||||||
routes.get("/guilds/config/{guildId}", ctx -> config(jdaSupplier, guildServices, ctx));
|
routes.get("/guilds/config/{guildId}", ctx -> config(jdaSupplier, guildServices, ctx));
|
||||||
@@ -235,6 +238,38 @@ public final class GuildRoutes {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@OpenApi(
|
||||||
|
path = "/guilds/members/{guildId}/{userId}/admin",
|
||||||
|
methods = HttpMethod.GET,
|
||||||
|
summary = "Check whether a guild member is an admin of the guild, falling back to a REST fetch on a member cache miss",
|
||||||
|
tags = {"Guilds"},
|
||||||
|
pathParams = {
|
||||||
|
@io.javalin.openapi.OpenApiParam(name = "guildId", description = "The Discord guild id"),
|
||||||
|
@io.javalin.openapi.OpenApiParam(name = "userId", description = "The Discord user id")
|
||||||
|
},
|
||||||
|
responses = {
|
||||||
|
@OpenApiResponse(status = "200", content = @OpenApiContent(from = AdminStatusResponse.class)),
|
||||||
|
@OpenApiResponse(status = "404", content = @OpenApiContent(from = ErrorResponse.class))
|
||||||
|
}
|
||||||
|
)
|
||||||
|
private static void memberAdmin(Supplier<JDA> jdaSupplier, Context ctx) {
|
||||||
|
Guild guild = guild(jdaSupplier, ctx);
|
||||||
|
String userId = ctx.pathParam("userId");
|
||||||
|
|
||||||
|
CacheOrFetch.<Member>resolve(
|
||||||
|
ctx,
|
||||||
|
() -> guild.getMemberById(userId),
|
||||||
|
() -> guild.retrieveMemberById(userId),
|
||||||
|
member -> {
|
||||||
|
Map<String, Object> summary = new LinkedHashMap<>();
|
||||||
|
summary.put("guild_id", guild.getId());
|
||||||
|
summary.put("user_id", member.getId());
|
||||||
|
summary.put("is_admin", UserFunction.isAdmin(member));
|
||||||
|
return summary;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Builds the {@code /guilds/members/{guildId}/{userId}} response for a resolved member.
|
* Builds the {@code /guilds/members/{guildId}/{userId}} response for a resolved member.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -0,0 +1,17 @@
|
|||||||
|
package me.bobert.netneutrality.http.server.dto;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) anthorob
|
||||||
|
*
|
||||||
|
* https://discord.gg/qUa6zNFZsd
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* OpenAPI schema for the {@code /guilds/members/{guildId}/{userId}/admin} response.
|
||||||
|
*/
|
||||||
|
public record AdminStatusResponse(
|
||||||
|
String guildId,
|
||||||
|
String userId,
|
||||||
|
boolean isAdmin
|
||||||
|
) {
|
||||||
|
}
|
||||||
Reference in new issue
Block a user