Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,10 @@ dependencies {
implementation("org.springframework.boot:spring-boot-starter-data-redis")
implementation("org.springframework.boot:spring-boot-starter-data-rest")
implementation("org.springframework.boot:spring-boot-starter-oauth2-resource-server")
implementation("org.springframework.boot:spring-boot-starter-oauth2-client")
implementation("org.springframework.boot:spring-boot-starter-security")
implementation("org.springframework.boot:spring-boot-starter-web")
implementation("org.mariadb.jdbc:mariadb-java-client:2.7.3")
developmentOnly("org.springframework.boot:spring-boot-devtools")
testImplementation("org.springframework.boot:spring-boot-starter-test")
testImplementation("org.springframework.security:spring-security-test")
Expand All @@ -30,7 +32,8 @@ tasks {
withType<JavaCompile> {
options.encoding = "UTF-8"
}

withType<Test> {
useJUnitPlatform()
}
}
}
Original file line number Diff line number Diff line change
@@ -1,14 +1,21 @@
package net.developerden.backend.controller;


import net.developerden.backend.security.DiscordUser;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class InfoController {

@GetMapping("/user")
public String user(@AuthenticationPrincipal DiscordUser principal) {
return "Hello, %s (%s)".formatted(principal.fullName(), principal.id());
}

@GetMapping("/ping")
public String ping() {
return "pong";
}
}
}
37 changes: 37 additions & 0 deletions src/main/java/net/developerden/backend/security/DiscordUser.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package net.developerden.backend.security;

import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.oauth2.core.user.OAuth2User;

import java.util.Collection;
import java.util.Map;

/* TODO we might wanna convert this to a database entity in the future so we can add more data*/

/**
* Java representation of all of the data that Discord gives us from the /users/@me API endpoint.
*/
public record DiscordUser(String id, String username, String discriminator, String locale) implements OAuth2User {
public String fullName() {
return username + "#" + discriminator;
}

@Override
public Map<String, Object> getAttributes() {
return Map.of(
"id", id,
"username", fullName(),
"locale", locale
);
}

@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
return null;
}

@Override
public String getName() {
return fullName();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package net.developerden.backend.security;

import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.MediaType;
import org.springframework.security.oauth2.client.userinfo.OAuth2UserRequest;
import org.springframework.security.oauth2.client.userinfo.OAuth2UserService;
import org.springframework.security.oauth2.core.OAuth2AuthenticationException;
import org.springframework.security.oauth2.core.user.OAuth2User;
import org.springframework.web.client.RestTemplate;

import java.util.List;

public class DiscordUserService implements OAuth2UserService<OAuth2UserRequest, OAuth2User> {
private static final String DISCORD_USERINFO_URI = "https://discord.com/api/users/@me";


@Override
public OAuth2User loadUser(OAuth2UserRequest userRequest) throws OAuth2AuthenticationException {
final var headers = new HttpHeaders();

final String authorization = userRequest.getAccessToken().getTokenType().getValue() + " " + userRequest.getAccessToken().getTokenValue();
headers.add("Authorization", authorization);

headers.setAccept(List.of(MediaType.APPLICATION_JSON));

final var entity = new HttpEntity<>(headers);

final var user = new RestTemplate()
.exchange(DISCORD_USERINFO_URI, HttpMethod.GET,
entity, DiscordUser.class)
.getBody();

return user;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package net.developerden.backend.security;

import org.springframework.http.HttpStatus;
import org.springframework.security.config.Customizer;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.oauth2.core.user.DefaultOAuth2User;
import org.springframework.security.web.authentication.HttpStatusEntryPoint;

import java.util.Collections;

@EnableWebSecurity
public class OAuth2LoginConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests(a ->
a.antMatchers("/", "/error").permitAll()
.anyRequest().authenticated()
)

.oauth2Login()
.userInfoEndpoint()
.userService(new DiscordUserService());
}
}
6 changes: 0 additions & 6 deletions src/main/resources/application.properties

This file was deleted.

26 changes: 26 additions & 0 deletions src/main/resources/application.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
spring:
jpa:
hibernate:
ddl-auto: none
show-sql: true
datasource:
url: jdbc:mariadb://${DDB_DATABASE_URL}:3306/${DDB_DATABASE_NAME}
username: ${DDB_DATABASE_USER}
password: ${DDB_DATABASE_PASSWORD}
driver-class-name: org.mariadb.jdbc.Driver
security:
oauth2:
client:
registration:
discord:
clientId: ${DDB_CLIENT_ID}
clientSecret: ${DDB_CLIENT_SECRET}
authorizationGrantType: authorization_code
redirectUri: "{baseUrl}/login/oauth2/code/discord"
scope: identify
provider:
discord:
authorizationUri: https://discord.com/api/oauth2/authorize
tokenUri: https://discord.com/api/oauth2/token


16 changes: 16 additions & 0 deletions src/main/resources/static/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=edge"/>
<title>Demo</title>
<meta name="description" content=""/>
<meta name="viewport" content="width=device-width"/>
<base href="/"/>
</head>
<body>
<h1>Demo</h1>
<div class="container"></div>
</body>
<a href="/oauth2/authorization/discord">Login</a>
</html>