11package net .modgarden .backend .handler .v1 .discord ;
22
33import com .mojang .serialization .Codec ;
4- import com .mojang .serialization .JsonOps ;
54import com .mojang .serialization .codecs .RecordCodecBuilder ;
65import io .javalin .http .Context ;
76import net .modgarden .backend .ModGardenBackend ;
87import net .modgarden .backend .data .LinkCode ;
98import net .modgarden .backend .data .profile .User ;
10- import net .modgarden .backend .util .ExtraCodecs ;
119
12- import java .math .BigInteger ;
1310import java .sql .Connection ;
1411import java .sql .ResultSet ;
1512import java .sql .SQLException ;
16- import java .util .ArrayList ;
17- import java .util .List ;
1813import java .util .Locale ;
19- import java .util .UUID ;
2014
2115public class DiscordBotLinkHandler {
2216 public static void link (Context ctx ) {
@@ -49,19 +43,20 @@ public static void link(Context ctx) {
4943 deleteStatement .execute ();
5044 if (accountId == null ) {
5145 ctx .result ("Invalid link code for " + capitalisedService + "." );
52- ctx .status (422 );
46+ ctx .status (400 );
5347 return ;
5448 }
5549
5650 if (body .service .equals (LinkCode .Service .MODRINTH .serializedName ())) {
57- handleModrinth (ctx , connection , body .discordId , accountId , capitalisedService );
51+ handleModrinth (ctx , connection , body .discordId , accountId );
5852 return ;
5953 } else if (body .service .equals (LinkCode .Service .MINECRAFT .serializedName ())) {
60- handleMinecraft (ctx , connection , body .discordId , accountId , capitalisedService );
54+ handleMinecraft (ctx , connection , body .discordId , accountId );
55+ DiscordBotOAuthHandler .invalidateFromUuid (body .linkCode );
6156 return ;
6257 }
6358 ctx .result ("Invalid link code service '" + capitalisedService + "'." );
64- ctx .status (422 );
59+ ctx .status (400 );
6560 } catch (SQLException ex ) {
6661 ModGardenBackend .LOG .error ("Exception in SQL query." , ex );
6762 ctx .result ("Internal Error." );
@@ -72,78 +67,66 @@ public static void link(Context ctx) {
7267 private static void handleModrinth (Context ctx ,
7368 Connection connection ,
7469 String discordId ,
75- String accountId ,
76- String capitalisedService ) throws SQLException {
70+ String accountId ) throws SQLException {
7771 try (var accountCheckStatement = connection .prepareStatement ("SELECT 1 FROM users WHERE modrinth_id = ?" );
7872 var userCheckStatement = connection .prepareStatement ("SELECT 1 FROM users WHERE discord_id = ? AND modrinth_id IS NOT NULL" );
7973 var insertStatement = connection .prepareStatement ("UPDATE users SET modrinth_id = ? WHERE discord_id = ?" )) {
8074 accountCheckStatement .setString (1 , accountId );
8175 ResultSet accountCheckResult = accountCheckStatement .executeQuery ();
8276 if (accountCheckResult .isBeforeFirst () && accountCheckResult .getBoolean (1 )) {
83- ctx .result ("The specified " + capitalisedService + " account has already been linked to a Mod Garden account." );
84- ctx .status (422 );
77+ ctx .result ("The specified Modrinth account has already been linked to a Mod Garden account." );
78+ ctx .status (400 );
8579 return ;
8680 }
8781
8882 userCheckStatement .setString (1 , discordId );
8983 ResultSet userCheckResult = userCheckStatement .executeQuery ();
9084 if (userCheckResult .isBeforeFirst () && userCheckResult .getBoolean (1 )) {
91- ctx .result ("The specified Mod Garden account is already linked with " + capitalisedService + " ." );
92- ctx .status (422 );
85+ ctx .result ("The specified Mod Garden account is already linked with Modrinth ." );
86+ ctx .status (400 );
9387 return ;
9488 }
9589
9690 insertStatement .setString (1 , accountId );
9791 insertStatement .setString (2 , discordId );
9892 insertStatement .execute ();
9993
100- ctx .result ("Successfully linked " + capitalisedService + " account to Mod Garden account associated with Discord ID '" + discordId + "'." );
94+ ctx .result ("Successfully linked Modrinth account to Mod Garden account associated with Discord ID '" + discordId + "'." );
10195 ctx .status (201 );
10296 }
10397 }
10498
10599 private static void handleMinecraft (Context ctx ,
106- Connection connection ,
107- String discordId ,
108- String uuid ,
109- String capitalisedService ) throws SQLException {
110- try (var accountCheckStatement = connection .prepareStatement ("SELECT 1 FROM users WHERE instr(minecraft_accounts, ?) > 0" );
111- var insertStatement = connection .prepareStatement ("UPDATE users SET minecraft_accounts = ? WHERE discord_id = ?" )) {
112- accountCheckStatement .setString (1 , uuid );
113- ResultSet accountCheckResult = accountCheckStatement .executeQuery ();
114- if (accountCheckResult .isBeforeFirst () && accountCheckResult .getBoolean (1 )) {
115- ctx .result ("The specified " + capitalisedService + " account has already been linked to a Mod Garden account." );
116- ctx .status (422 );
117- return ;
118- }
119-
100+ Connection connection ,
101+ String discordId ,
102+ String uuid ) throws SQLException {
103+ try (var accountCheckStatement = connection .prepareStatement ("SELECT user_id FROM minecraft_accounts WHERE uuid = ?" );
104+ var insertStatement = connection .prepareStatement ("INSERT INTO minecraft_accounts (uuid, user_id) VALUES (?, ?)" )) {
120105 User user = User .query (discordId , "discord" );
121106 if (user == null ) {
122107 ctx .result ("Could not find user from Discord ID '" + discordId + "'." );
123- ctx .status (422 );
108+ ctx .status (400 );
124109 return ;
125110 }
126111
127- List <UUID > uuids = new ArrayList <>(user .minecraftAccounts ());
128- uuids .add (new UUID (
129- new BigInteger (uuid .substring (0 , 16 ), 16 ).longValue (),
130- new BigInteger (uuid .substring (16 ), 16 ).longValue ()
131- ));
132-
133- var dataResult = ExtraCodecs .UUID_CODEC .listOf ().encodeStart (JsonOps .INSTANCE , uuids );
134-
135- if (!dataResult .hasResultOrPartial ()) {
136- ModGardenBackend .LOG .error ("Failed to create Minecraft account data. {}" , dataResult .error ().orElseThrow ().message ());
137- ctx .result ("Failed to create Minecraft account data." );
138- ctx .status (500 );
112+ accountCheckStatement .setString (1 , uuid );
113+ ResultSet accountCheckResult = accountCheckStatement .executeQuery ();
114+ if (accountCheckResult .isBeforeFirst () && accountCheckResult .getString (1 ) != null ) {
115+ if (accountCheckResult .getString (1 ).equals (user .id ())) {
116+ ctx .result ("Your Minecraft account is already linked to your Mod Garden account." );
117+ ctx .status (200 );
118+ return ;
119+ }
120+ ctx .result ("The specified Minecraft account has already been linked to a Mod Garden account." );
121+ ctx .status (400 );
139122 return ;
140123 }
141124
142- accountCheckStatement .setString (1 , dataResult . getOrThrow (). toString () );
143- accountCheckStatement .setString (2 , discordId );
125+ insertStatement .setString (1 , uuid );
126+ insertStatement .setString (2 , user . id () );
144127 insertStatement .execute ();
145128
146- ctx .result ("Successfully linked " + capitalisedService + " account to Mod Garden account associated with Discord ID '" + discordId + "'." );
129+ ctx .result ("Successfully linked Minecraft account to Mod Garden account associated with Discord ID '" + discordId + "'." );
147130 ctx .status (201 );
148131 }
149132 }
0 commit comments