Skip to content

Commit

Permalink
Merge branch 'master' into matching_algo
Browse files Browse the repository at this point in the history
  • Loading branch information
adhi-thirumala authored Dec 8, 2024
2 parents 04eba45 + 64534c5 commit d80a2a4
Show file tree
Hide file tree
Showing 14 changed files with 343 additions and 99 deletions.
26 changes: 23 additions & 3 deletions Project/backend/java-server/app/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import org.gradle.internal.impldep.org.junit.experimental.categories.Categories.CategoryFilter.exclude


/*
* This file was generated by the Gradle 'init' task.
Expand Down Expand Up @@ -32,6 +32,7 @@ repositories {
}

dependencies {
implementation("org.springframework.boot:spring-boot-starter-actuator")
// Use JUnit test framework.
testImplementation(libs.junit)

Expand All @@ -43,9 +44,13 @@ dependencies {
exclude(group = "org.springframework.boot", module = "spring-boot-starter-logging")
}
implementation("io.github.cdimascio:dotenv-java:2.3.0")
implementation("com.github.Mokulu:discord-oauth2-api:1.0.4")
implementation("org.postgresql:postgresql:42.7.4")
implementation("ch.qos.logback:logback-classic:1.4.11")
implementation("org.springframework.boot:spring-boot-starter-data-jpa")
implementation("org.springframework.boot:spring-boot-starter-jdbc")
implementation("org.postgresql:postgresql")
implementation("com.fasterxml.jackson.core:jackson-databind")
implementation("ch.qos.logback:logback-classic:1.4.12")
implementation("com.github.scribejava:scribejava-apis:8.3.3")
testImplementation("org.springframework.boot:spring-boot-starter-test") {
exclude(group = "org.springframework.boot", module = "spring-boot-starter-logging")
}
Expand All @@ -58,4 +63,19 @@ java { toolchain { languageVersion = JavaLanguageVersion.of(23) } }

application { mainClass = "org.server.Main" }


tasks.register<Copy>("getDeps") {
from(sourceSets.main.get().runtimeClasspath)
into("runtime/")

doFirst {
delete("runtime")
mkdir("runtime")
}

doLast {
delete("runtime")
}
}

tasks.withType<Test> { useJUnitPlatform() }
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package org.server;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

/** This class represents the routes for check-in. */
@RestController
public class CheckInRoutes {

/**
* Checks in the user.
*
* @return the response entity containing whether the check-in was successful
*/
@GetMapping("/api/v1/checkin")
public String checkIn() {
return "Check-in successful!";
}
}
143 changes: 105 additions & 38 deletions Project/backend/java-server/app/src/main/java/org/server/DiscordOps.java
Original file line number Diff line number Diff line change
@@ -1,77 +1,144 @@
package org.server;

import com.fasterxml.jackson.annotation.JsonProperty;
import com.github.scribejava.apis.DiscordApi;
import com.github.scribejava.core.builder.ServiceBuilder;
import com.github.scribejava.core.model.OAuth2AccessToken;
import com.github.scribejava.core.model.OAuthRequest;
import com.github.scribejava.core.model.Response;
import com.github.scribejava.core.model.Verb;
import com.github.scribejava.core.oauth.OAuth20Service;
import io.github.cdimascio.dotenv.Dotenv;
import io.mokulu.discord.oauth.DiscordAPI;
import io.mokulu.discord.oauth.DiscordOAuth;
import io.mokulu.discord.oauth.model.TokensResponse;
import io.mokulu.discord.oauth.model.User;
import java.io.IOException;
import java.util.concurrent.ExecutionException;
import java.util.logging.Logger;
import org.springframework.context.annotation.Configuration;

/** This class represents the Discord operations. {@code @Author} adhit2 */
@Configuration
public class DiscordOps {
private static final Dotenv dotenv = Dotenv.load();
private static final String clientSecret = dotenv.get("DISCORD_CLIENT_SECRET");
private static final String clientId = dotenv.get("DISCORD_CLIENT_ID");
private static final String redirectUri = dotenv.get("DISCORD_REDIRECT_URI");
private static final String[] scope = {"identify"};

private static final PostgreSQLController pgController = new PostgreSQLController();
private final OAuth20Service service =
new ServiceBuilder(Dotenv.load().get("DISCORD_CLIENT_ID"))
.apiSecret(Dotenv.load().get("DISCORD_CLIENT_SECRET"))
.callback(Dotenv.load().get("DISCORD_REDIRECT_URI"))
.userAgent("ScribeJava")
.build(DiscordApi.instance());

private static final String DISCORD_API_URL = "https://discord.com/api/v10";
private static final String PROTECTED_RESOURCE_URL = "https://discord.com/api/users/@me";

/** Constructs a new {@link DiscordOps}. */
public DiscordOps() {}

private static final DiscordOAuth oauthHandler =
new DiscordOAuth(clientId, clientSecret, redirectUri, scope);
/** This class represents the Discord user. */
public static class DiscordUser {
private String id;
private String username;
private String discriminator;

@JsonProperty("global_name")
private String globalName;

// Getters and setters
public String getId() {
return id;
}

public void setId(String id) {
this.id = id;
}

public String getUsername() {
return username;
}

public void setUsername(String username) {
this.username = username;
}
}

/**
* Fetches the username.
* Gets the username.
*
* @param discordId discord ID
* @param discordId the discord ID
* @return the username
* @throws IOException if an error occurs
*/
public static String getUsername(String discordId) throws IOException {
String accessToken = pgController.getAccessToken(discordId);
User user;
public String getUsername(String discordId)
throws IOException, ExecutionException, InterruptedException {
try {
DiscordAPI api = new DiscordAPI(accessToken);
user = api.fetchUser();
} catch (IOException e) {
// Token might be expired, refresh it
pgController.changeAuthToken(discordId);
accessToken = pgController.getAccessToken(discordId);
user = new DiscordAPI(accessToken).fetchUser();
final OAuthRequest request =
new OAuthRequest(Verb.GET, DISCORD_API_URL + "/users/" + discordId);
service.signRequest(pgController.getAccessToken(discordId), request);
Response response = service.execute(request);
return response.getBody().split("\"username\":\"")[1].split("\"")[0];
} catch (Exception e) {
refreshToken(pgController.getRefreshToken(discordId), discordId);
final OAuthRequest request =
new OAuthRequest(Verb.GET, DISCORD_API_URL + "/users/" + discordId);
service.signRequest(pgController.getAccessToken(discordId), request);
Response response = service.execute(request);
return response.getBody().split("\"username\":\"")[1].split("\"")[0];
}
return user.getUsername();
}

/**
* Gets the user info.
* Refreshes the token.
*
* @param refreshToken refresh token
* @return the user info
* @throws IOException if an error occurs
* @param refreshToken the refresh token
* @param discordId the discord ID
* @throws IOException if an I/O error occurs
* @throws ExecutionException if an execution error occurs
* @throws InterruptedException if an interrupt error occurs
*/
public static String refreshToken(String refreshToken) throws IOException {
TokensResponse tokensResponse = oauthHandler.refreshTokens(refreshToken);
return tokensResponse.getAccessToken();
public void refreshToken(String refreshToken, String discordId)
throws IOException, ExecutionException, InterruptedException {
final OAuth2AccessToken accessToken = service.refreshAccessToken(refreshToken);
pgController.changeAuthToken(
accessToken.getAccessToken(), pgController.getDiscordId(refreshToken));
}

/**
* Gets the tokens.
*
* @param code the code
* @return the tokens
* @throws IOException if an error occurs
* @throws IOException if an I/O error occurs
* @throws ExecutionException if an execution error occurs
* @throws InterruptedException if an interrupt error occurs
*/
public static TokensResponse getTokens(String code) throws IOException {
return oauthHandler.getTokens(code);
public OAuth2AccessToken getTokens(String code)
throws IOException, ExecutionException, InterruptedException {
return service.getAccessToken(code);
}

/**
* Gets the discord ID.
*
* @param accessToken the access token
* @return the discord ID
* @throws IOException if an error occurs
* @throws IOException if an I/O error occurs
* @throws ExecutionException if an execution error occurs
* @throws InterruptedException if an interrupt error occurs
*/
public static String getDiscordId(String accessToken) throws IOException {
return new DiscordAPI(accessToken).fetchUser().getId();
public String getDiscordId(String accessToken)
throws IOException, ExecutionException, InterruptedException {
try {
return getString(accessToken);
} catch (Exception e) {
String discordId = pgController.getDiscordId(accessToken);
refreshToken(pgController.getRefreshToken(discordId), discordId);
return getString(accessToken);
}
}

private String getString(String accessToken)
throws InterruptedException, ExecutionException, IOException {
final OAuthRequest request = new OAuthRequest(Verb.GET, PROTECTED_RESOURCE_URL);
service.signRequest(accessToken, request);
Response response = service.execute(request);
Logger.getGlobal().info(response.getBody());
return response.getBody().split("\"id\":\"")[1].split("\"")[0];
}
}
Original file line number Diff line number Diff line change
@@ -1,10 +1,15 @@
package org.server;

import io.mokulu.discord.oauth.model.TokensResponse;
import com.github.scribejava.core.model.OAuth2AccessToken;
import com.google.gson.JsonObject;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import java.util.concurrent.ExecutionException;

import com.google.gson.JsonParser;

import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
Expand Down Expand Up @@ -55,10 +60,14 @@ public void setSessionToken(String sessionToken) {
* @return the response entity containing whether the login was successful and the session token
*/
@PostMapping(path = "/api/v1/login")
public ResponseEntity<ReturnValue> login(@RequestBody String code) throws IOException {
public ResponseEntity<ReturnValue> login(@RequestBody String code)
throws IOException, ExecutionException, InterruptedException {
PostgreSQLController pgController = new PostgreSQLController();
TokensResponse tr = DiscordOps.getTokens(code);
String discordId = DiscordOps.getDiscordId(tr.getAccessToken());
DiscordOps discordOps = new DiscordOps();
JsonObject json = JsonParser.parseString(code).getAsJsonObject();
code = json.get("code").getAsString();
OAuth2AccessToken tr = discordOps.getTokens(code);
String discordId = discordOps.getDiscordId(tr.getAccessToken());
String sessionToken = pgController.doesUserExist(discordId);
if (sessionToken != null) {
return ResponseEntity.ok(new ReturnValue(true, sessionToken));
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package org.server;

import io.github.cdimascio.dotenv.Dotenv;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

Expand All @@ -17,7 +18,12 @@ public class Main {
*
* @param args Command line arguments.
*/
public static void main(String[] args) {
SpringApplication.run(Main.class, args);

public static void main(String[] args) {
Dotenv dotenv = Dotenv.load();
System.setProperty(
"SPRING_DATASOURCE_URL", "jdbc:postgresql://" + dotenv.get("PGURL") + "/main");
System.setProperty("SPRING_DATASOURCE_USERNAME", dotenv.get("PGUSER"));
System.setProperty("SPRING_DATASOURCE_PASSWORD", dotenv.get("PGPASSWORD"));
}
}
Loading

0 comments on commit d80a2a4

Please sign in to comment.