Skip to content

Commit 0f71218

Browse files
committed
feat: add help command, add more info to my-status
1 parent 3e8c4ea commit 0f71218

File tree

1 file changed

+189
-36
lines changed

1 file changed

+189
-36
lines changed

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

Lines changed: 189 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -48,13 +48,19 @@
4848
import org.jetbrains.annotations.VisibleForTesting;
4949
import org.slf4j.Logger;
5050
import org.slf4j.LoggerFactory;
51+
import org.w3c.dom.Document;
5152

53+
import javax.xml.parsers.DocumentBuilder;
54+
import javax.xml.parsers.DocumentBuilderFactory;
55+
import java.io.ByteArrayInputStream;
5256
import java.time.Instant;
5357
import java.util.ArrayList;
5458
import java.util.Arrays;
5559
import java.util.List;
60+
import java.util.Map;
5661
import java.util.concurrent.atomic.AtomicBoolean;
5762
import java.util.concurrent.atomic.AtomicInteger;
63+
import java.util.stream.Collectors;
5864

5965
public class CmdCodeMC extends BotCommand {
6066

@@ -76,7 +82,8 @@ public CmdCodeMC(CodeMCBot bot) {
7682
new ChangePassword(bot),
7783
new CreateUser(bot),
7884
new DeleteUser(bot),
79-
new MyStatus(bot)
85+
new MyStatus(bot),
86+
new Help(bot)
8087
};
8188
}
8289

@@ -420,48 +427,194 @@ public void withHookReply(InteractionHook hook, SlashCommandEvent event, Guild g
420427
@VisibleForTesting
421428
@NotNull
422429
MessageEmbed build(String username) {
423-
int totalUsers = JenkinsAPI.getAllJenkinsUsers().size();
424-
int totalRepositories = NexusAPI.getRepositories().size();
430+
try {
431+
int totalUsers = JenkinsAPI.getAllJenkinsUsers().size();
432+
int totalRepositories = NexusAPI.getRepositories().size();
433+
434+
String jenkinsUrl = bot.getConfigHandler().getString("jenkins", "url");
435+
String nexusUrl = bot.getConfigHandler().getString("nexus", "url");
436+
437+
438+
EmbedBuilder embed = CommandUtil.getEmbed()
439+
.setTitle("CodeMC Account Status for " + username)
440+
.setDescription("Total Jenkins Users: " + totalUsers + "\nTotal Nexus Repositories: " + totalRepositories)
441+
.setTimestamp(Instant.now());
442+
443+
boolean jenkinsExists = JenkinsAPI.existsUser(username);
444+
if (jenkinsExists) {
445+
String config = JenkinsAPI.getJenkinsUser(username);
446+
embed.addField("Jenkins Account", jenkinsUrl + "/job/" + username, true);
447+
448+
if (config.contains("com.cloudbees.hudson.plugins.folder.properties.AuthorizationMatrixProperty")) {
449+
embed.addField("Jenkins Permissions", "Contains Authorization Matrix", true);
450+
} else {
451+
embed.addField("Jenkins Permissions", MarkdownUtil.underline("Missing Authorization Matrix"), true);
452+
}
453+
454+
if (config.contains("<id>nexus-repository</id>")) {
455+
embed.addField("Jenkins Nexus Credentials", "Nexus Repository Credentials Added", true);
456+
} else {
457+
embed.addField("Jenkins Nexus Credentials", MarkdownUtil.underline("Nexus Repository Not Linked"), true);
458+
}
459+
} else {
460+
embed.addField("Jenkins Account", MarkdownUtil.underline("Does Not Exist"), true);
461+
}
462+
463+
JsonObject nexusInfo = NexusAPI.getNexusRepository(username);
464+
boolean nexusExists = nexusInfo != null && !nexusInfo.isEmpty();
465+
466+
if (nexusExists) {
467+
embed.addField("Nexus Repository", nexusUrl + "/#browse/browse:" + username.toLowerCase(), true);
468+
469+
JsonObject user = NexusAPI.getNexusUser(username.toLowerCase());
470+
String userId = ((JsonPrimitive) user.get("userId")).getContent();
471+
String roles = ((JsonArray) user.get("roles"))
472+
.stream()
473+
.map(role -> ((JsonPrimitive) role).getContent())
474+
.collect(Collectors.joining("\n- ", "- ", ""));
475+
476+
embed.addField("Nexus User ID", userId, true);
477+
embed.addField("Nexus Roles", roles, false);
478+
479+
JsonObject role = NexusAPI.getNexusRole(username.toLowerCase());
480+
String privileges = ((JsonArray) role.get("privileges"))
481+
.stream()
482+
.map(priv -> ((JsonPrimitive) priv).getContent())
483+
.collect(Collectors.joining("\n- ", "- ", ""));
484+
485+
embed.addField("Nexus Privileges", privileges, false);
486+
} else embed.addField("Nexus Repository", MarkdownUtil.underline("Does Not Exist"), true);
487+
488+
return embed.build();
489+
} catch (Exception e) {
490+
LOGGER.error("Failed to build MyStatus embed for user '{}'", username, e);
491+
return CommandUtil.getEmbed()
492+
.setTitle("CodeMC Account Status for " + username)
493+
.setDescription("An error occurred while fetching your account status.")
494+
.setTimestamp(Instant.now())
495+
.build();
496+
}
497+
}
498+
}
425499

426-
String jenkinsUrl = bot.getConfigHandler().getString("jenkins", "url");
427-
String nexusUrl = bot.getConfigHandler().getString("nexus", "url");
500+
@VisibleForTesting
501+
static class Help extends BotCommand {
428502

429-
boolean jenkinsExists = JenkinsAPI.existsUser(username);
503+
public Help(CodeMCBot bot) {
504+
super(bot);
430505

431-
JsonObject nexusInfo = NexusAPI.getNexusRepository(username);
432-
boolean nexusExists = nexusInfo != null && !nexusInfo.isEmpty();
506+
this.name = "help";
507+
this.help = "Displays help information for CodeMC commands.";
508+
}
509+
510+
@Override
511+
public void withModalReply(SlashCommandEvent event) {
512+
}
513+
514+
@Override
515+
public void withHookReply(InteractionHook hook, SlashCommandEvent event, Guild guild, Member member) {
516+
List<Role> roles = member.getRoles();
517+
boolean isAuthor = roles.stream()
518+
.anyMatch(role -> role.getIdLong() == bot.getConfigHandler().getLong("author_role"));
519+
520+
List<Long> reviewerRoles = bot.getConfigHandler().getLongList("allowed_roles", "commands", "application");
521+
boolean isReviewer = roles.stream()
522+
.anyMatch(role -> reviewerRoles.contains(role.getIdLong()));
523+
524+
List<Long> adminRoles = bot.getConfigHandler().getLongList("allowed_roles", "commands", "codemc");
525+
boolean isAdmin = roles.stream()
526+
.anyMatch(role -> adminRoles.contains(role.getIdLong()));
433527

434528
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());
529+
.setTitle("CodeMC Command Help")
530+
.setDescription("Here is a list of available commands:");
438531

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);
532+
userHelp(embed);
463533

464-
return embed.build();
534+
if (isReviewer) {
535+
reviewerHelp(embed);
536+
}
537+
538+
if (isAuthor) {
539+
authorHelp(embed);
540+
}
541+
542+
if (isAdmin) {
543+
adminHelp(embed);
544+
}
545+
546+
embed.setTimestamp(Instant.now());
547+
548+
hook.sendMessageEmbeds(embed.build())
549+
.setEphemeral(true)
550+
.queue();
551+
}
552+
553+
@VisibleForTesting
554+
void userHelp(EmbedBuilder builder) {
555+
Map<String, String> commands = Map.of(
556+
"/codemc help", "Displays this help message.",
557+
"/codemc jenkins", "Fetch information about a Jenkins Author.",
558+
"/codemc nexus", "Fetch information about a Nexus Repository."
559+
);
560+
561+
for (Map.Entry<String, String> entry : commands.entrySet()) {
562+
builder.addField(entry.getKey(), entry.getValue(), false);
563+
}
564+
565+
builder.setFooter("User View");
566+
}
567+
568+
@VisibleForTesting
569+
void authorHelp(EmbedBuilder builder) {
570+
builder.addBlankField(false);
571+
572+
Map<String, String> commands = Map.of(
573+
"/codemc my-status", "Check the status of your CodeMC Jenkins and Nexus accounts. This will usually report any issues with your accounts, and will help administrators with diagnosing issues.",
574+
"/codemc change-password", "Regenerates your Nexus Credentials. Useful if you suspect they have been compromised, or if they are not working."
575+
);
576+
577+
for (Map.Entry<String, String> entry : commands.entrySet()) {
578+
builder.addField(entry.getKey(), entry.getValue(), false);
579+
}
580+
581+
builder.setFooter("Author View");
582+
}
583+
584+
@VisibleForTesting
585+
void reviewerHelp(EmbedBuilder builder) {
586+
builder.addBlankField(false);
587+
588+
Map<String, String> commands = Map.of(
589+
"/application accept", "Accepts a user's application for Author status.",
590+
"/application deny", "Denies a user's application for Author status."
591+
);
592+
593+
for (Map.Entry<String, String> entry : commands.entrySet()) {
594+
builder.addField(entry.getKey(), entry.getValue(), false);
595+
}
596+
597+
builder.setFooter("Reviewer View");
598+
}
599+
600+
@VisibleForTesting
601+
void adminHelp(EmbedBuilder builder) {
602+
builder.addBlankField(false);
603+
604+
Map<String, String> commands = Map.of(
605+
"/codemc validate", "Performs a validation check on all or a specific user's existing jenkins credentials. Useful for regenerating credentials for a user.",
606+
"/codemc remove", "Removes a user from the CodeMC Services, and revokes their Author role.",
607+
"/codemc link", "Links a Discord User to a Jenkins/Nexus User. If it currently exists, it will be overridden.",
608+
"/codemc unlink", "Unlinks a discord user from their Jenkins/Nexus account.",
609+
"/codemc createuser", "Creates a new user in the Jenkins/Nexus services. Useful if user configuration is corrupted and recreation is necesssary. You can specify a user to link it to.",
610+
"/codemc deluser", "Deletes a user in the Jenkins/Nexus services. Useful if user configuration is corrupted and recreation is necesssary. Does not affect discord roles."
611+
);
612+
613+
for (Map.Entry<String, String> entry : commands.entrySet()) {
614+
builder.addField(entry.getKey(), entry.getValue(), false);
615+
}
616+
617+
builder.setFooter("Administrator View");
465618
}
466619
}
467620

0 commit comments

Comments
 (0)