Skip to content

Commit c9f5c17

Browse files
committed
feat: update API version, improve validation and coverage, add my-status command
1 parent ff6fb4a commit c9f5c17

File tree

4 files changed

+138
-7
lines changed

4 files changed

+138
-7
lines changed

build.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ dependencies {
4747
implementation group: 'pw.chew', name: 'jda-chewtils-command', version: '2.2.1'
4848
implementation group: 'org.spongepowered', name: 'configurate-gson', version: '4.2.0'
4949

50-
implementation group: 'io.codemc.api', name: 'codemc-api', version: '1.2.2'
50+
implementation group: 'io.codemc.api', name: 'codemc-api', version: '1.2.3'
5151
implementation group: 'org.jetbrains.kotlinx', name: 'kotlinx-coroutines-core', version: '1.10.2'
5252
implementation group: 'org.jetbrains.kotlinx', name: 'kotlinx-serialization-json', version: '1.9.0'
5353
implementation group: 'org.mariadb.jdbc', name: 'mariadb-java-client', version: '3.5.7'

src/main/java/io/codemc/bot/commands/CmdCodeMC.java

Lines changed: 97 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
import io.codemc.bot.CodeMCBot;
2929
import io.codemc.bot.utils.APIUtil;
3030
import io.codemc.bot.utils.CommandUtil;
31+
import kotlinx.serialization.json.JsonArray;
3132
import kotlinx.serialization.json.JsonObject;
3233
import kotlinx.serialization.json.JsonPrimitive;
3334
import net.dv8tion.jda.api.EmbedBuilder;
@@ -42,11 +43,15 @@
4243
import net.dv8tion.jda.api.interactions.commands.build.OptionData;
4344
import net.dv8tion.jda.api.requests.ErrorResponse;
4445

46+
import net.dv8tion.jda.api.utils.MarkdownUtil;
47+
import org.jetbrains.annotations.NotNull;
4548
import org.jetbrains.annotations.VisibleForTesting;
4649
import org.slf4j.Logger;
4750
import org.slf4j.LoggerFactory;
4851

4952
import java.time.Instant;
53+
import java.util.ArrayList;
54+
import java.util.Arrays;
5055
import java.util.List;
5156
import java.util.concurrent.atomic.AtomicBoolean;
5257
import java.util.concurrent.atomic.AtomicInteger;
@@ -70,7 +75,8 @@ public CmdCodeMC(CodeMCBot bot) {
7075
new Unlink(bot),
7176
new ChangePassword(bot),
7277
new CreateUser(bot),
73-
new DeleteUser(bot)
78+
new DeleteUser(bot),
79+
new MyStatus(bot)
7480
};
7581
}
7682

@@ -362,13 +368,103 @@ private boolean validate(InteractionHook hook, String username, AtomicInteger co
362368

363369
if (!noJenkins)
364370
success &= JenkinsAPI.changeJenkinsPassword(username, password);
371+
} else {
372+
success &= NexusAPI.validatePrivileges(username);
365373
}
366374

367375
count.incrementAndGet();
368376
return success;
369377
}
370378
}
371379

380+
@VisibleForTesting
381+
static class MyStatus extends BotCommand {
382+
383+
public MyStatus(CodeMCBot bot) {
384+
super(bot);
385+
386+
this.name = "my-status";
387+
this.help = "Checks the status of your CodeMC Jenkins and Nexus accounts.";
388+
this.aliases = new String[]{"mystatus"};
389+
390+
List<Long> roles = new ArrayList<>();
391+
roles.add(bot.getConfigHandler().getLong("author_role"));
392+
roles.addAll(bot.getConfigHandler().getLongList("allowed_roles", "commands", "codemc"));
393+
394+
this.allowedRoles = roles;
395+
}
396+
397+
@Override
398+
public void withModalReply(SlashCommandEvent event) {
399+
}
400+
401+
@Override
402+
public void withHookReply(InteractionHook hook, SlashCommandEvent event, Guild guild, Member member) {
403+
String username = DatabaseAPI.getAllUsers().stream()
404+
.filter(user -> user.getDiscord() == member.getIdLong())
405+
.map(User::getUsername)
406+
.findFirst()
407+
.orElse(null);
408+
409+
if (username == null) {
410+
CommandUtil.EmbedReply.from(hook).error("You are not linked to any Jenkins/Nexus accounts!").send();
411+
return;
412+
}
413+
414+
MessageEmbed embed = build(username);
415+
hook.sendMessageEmbeds(embed)
416+
.setEphemeral(true)
417+
.queue();
418+
}
419+
420+
@VisibleForTesting
421+
@NotNull
422+
MessageEmbed build(String username) {
423+
int totalUsers = JenkinsAPI.getAllJenkinsUsers().size();
424+
int totalRepositories = NexusAPI.getRepositories().size();
425+
426+
String jenkinsUrl = bot.getConfigHandler().getString("jenkins", "url");
427+
String nexusUrl = bot.getConfigHandler().getString("nexus", "url");
428+
429+
boolean jenkinsExists = JenkinsAPI.existsUser(username);
430+
431+
JsonObject nexusInfo = NexusAPI.getNexusRepository(username);
432+
boolean nexusExists = nexusInfo != null && !nexusInfo.isEmpty();
433+
434+
EmbedBuilder embed = CommandUtil.getEmbed()
435+
.setTitle("CodeMC Account Status for " + username)
436+
.setDescription("Total Jenkins Users: " + totalUsers + "\nTotal Nexus Repositories: " + totalRepositories)
437+
.setTimestamp(Instant.now());
438+
439+
if (jenkinsExists) embed.addField("Jenkins Account", jenkinsUrl + "/job/" + username, true);
440+
else embed.addField("Jenkins Account", MarkdownUtil.underline("Does Not Exist"), true);
441+
442+
if (nexusExists) {
443+
embed.addField("Nexus Repository", nexusUrl + "/#browse/browse:" + username.toLowerCase(), true);
444+
445+
JsonObject user = NexusAPI.getNexusUser(username.toLowerCase());
446+
String userId = ((JsonPrimitive) user.get("userId")).getContent();
447+
String roles = ((JsonArray) user.get("roles"))
448+
.stream()
449+
.map(role -> ((JsonPrimitive) role).getContent())
450+
.reduce((a, b) -> "- " + a + "\n- " + b)
451+
.orElse("None");
452+
embed.addField("Nexus User ID", userId, true);
453+
embed.addField("Nexus Roles", roles, false);
454+
455+
JsonObject role = NexusAPI.getNexusRole(username.toLowerCase());
456+
String privileges = ((JsonArray) role.get("privileges"))
457+
.stream()
458+
.map(priv -> ((JsonPrimitive) priv).getContent())
459+
.reduce((a, b) -> "- " + a + "\n- " + b)
460+
.orElse("None");
461+
embed.addField("Nexus Privileges", privileges, false);
462+
} else embed.addField("Nexus Repository", MarkdownUtil.underline("Does Not Exist"), true);
463+
464+
return embed.build();
465+
}
466+
}
467+
372468
@VisibleForTesting
373469
static class Link extends BotCommand{
374470

@@ -468,11 +564,6 @@ public void withHookReply(InteractionHook hook, SlashCommandEvent event, Guild g
468564
return;
469565
}
470566

471-
if (DatabaseAPI.getUser(username) == null) {
472-
CommandUtil.EmbedReply.from(hook).error("The user is not linked to any Jenkins/Nexus account!").send();
473-
return;
474-
}
475-
476567
DatabaseAPI.removeUser(username);
477568
CommandUtil.EmbedReply.from(hook).success("Unlinked Discord User " + target.getUser().getEffectiveName() + " from their Jenkins/Nexus account!").send();
478569

src/test/java/io/codemc/bot/MockJDA.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -794,6 +794,13 @@ private static <T extends MessageRequest<?> & RestAction<?>> T mockWebhookReply(
794794
return action;
795795
});
796796

797+
if (action instanceof WebhookMessageCreateAction<?> create) {
798+
when(create.setEphemeral(anyBoolean())).thenAnswer(invocation -> {
799+
when(message.isEphemeral()).thenReturn(true);
800+
return action;
801+
});
802+
}
803+
797804
return action;
798805
}
799806

src/test/java/io/codemc/bot/commands/TestCmdCodeMC.java

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -429,4 +429,37 @@ public void testDelUser() {
429429
DatabaseAPI.removeUser("TestDelUser");
430430
}
431431

432+
@Test
433+
@DisplayName("Test /codemc my-status")
434+
public void testMyStatus() {
435+
MyStatus status = (MyStatus) command.getChildren()[9];
436+
String username = "TestStatus";
437+
438+
assertEquals("my-status", status.getName());
439+
assertFalse(status.getHelp().isEmpty());
440+
assertFalse(status.allowedRoles.isEmpty());
441+
assertNotEquals(0, status.getAliases().length);
442+
443+
SlashCommandEvent event = MockJDA.mockSlashCommandEvent(MockJDA.REQUEST_CHANNEL, status, Map.of());
444+
TestCommandListener listener = new TestCommandListener(status);
445+
446+
JenkinsAPI.createJenkinsUser(username, "1234");
447+
NexusAPI.createNexus(username, "1234");
448+
DatabaseAPI.addUser(username, event.getMember().getIdLong());
449+
450+
MockJDA.assertSlashCommandEvent(event, listener, status.build(username));
451+
452+
assertTrue(JenkinsAPI.deleteUser(username));
453+
454+
MockJDA.assertSlashCommandEvent(event, listener, status.build(username));
455+
456+
assertTrue(NexusAPI.deleteNexus(username));
457+
458+
MockJDA.assertSlashCommandEvent(event, listener, status.build(username));
459+
460+
assertEquals(1, DatabaseAPI.removeUser(username));
461+
462+
MockJDA.assertSlashCommandEvent(event, listener, CommandUtil.embedError("You are not linked to any Jenkins/Nexus accounts!"));
463+
}
464+
432465
}

0 commit comments

Comments
 (0)