Switching over to oauth2 from toker #40

Merged
niat8586 merged 6 commits from develop into main 2025-07-01 10:08:00 +02:00
8 changed files with 53 additions and 18 deletions

12
compose-oauth.yaml Normal file
View File

@ -0,0 +1,12 @@
services:
oauth2:
build:
context: https://gitea.dsv.su.se/DMC/oauth2-authorization-server.git#20cd09737d4c57bc1ee8098637cbad1a618bf49e
ports:
- '51337:8080'
environment:
- CLIENT_ID=seshat
- CLIENT_SECRET=n0tS3cr3t
- CLIENT_REDIRECT_URI=http://localhost:8181/login/oauth2/code/seshat
- CLIENT_SCOPES=openid email profile

View File

@ -11,17 +11,8 @@ services:
volumes: volumes:
- mariadb_data:/var/lib/mysql - mariadb_data:/var/lib/mysql
oauth2: include:
build: - compose-oauth.yaml
context: https://github.com/dsv-su/toker.git
dockerfile: embedded.Dockerfile
ports:
- '51337:8080'
environment:
- CLIENT_ID=seshat
- CLIENT_SECRET=n0tS3cr3t
- CLIENT_REDIRECT_URI=http://localhost:8181/login/oauth2/code/seshat
volumes: volumes:
mariadb_data: mariadb_data:

View File

@ -10,9 +10,12 @@ import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType; import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity; import org.springframework.http.ResponseEntity;
import org.springframework.security.core.Authentication; import org.springframework.security.core.Authentication;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.security.oauth2.core.user.OAuth2User;
import org.springframework.stereotype.Controller; import org.springframework.stereotype.Controller;
import org.springframework.ui.Model; import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RequestParam;
@ -183,6 +186,11 @@ public class FileController {
return "redirect:/files/manage"; return "redirect:/files/manage";
} }
@ModelAttribute("displayName")
public String getDisplayName(@AuthenticationPrincipal OAuth2User oauth2User) {
return oauth2User.getAttribute("name");
}
private static List<FileMetadata> getFileUploadStatuses(List<FileMetadata> uploaded) { private static List<FileMetadata> getFileUploadStatuses(List<FileMetadata> uploaded) {
return uploaded.stream() return uploaded.stream()
.filter(file -> file.getJobStatus() != null) .filter(file -> file.getJobStatus() != null)

View File

@ -12,6 +12,7 @@ import org.springframework.security.web.authentication.AuthenticationSuccessHand
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import java.io.IOException; import java.io.IOException;
import java.util.Objects;
@Service @Service
public class CustomOAuth2loginSuccessHandler implements AuthenticationSuccessHandler { public class CustomOAuth2loginSuccessHandler implements AuthenticationSuccessHandler {
@ -32,11 +33,13 @@ public class CustomOAuth2loginSuccessHandler implements AuthenticationSuccessHan
String username = oAuth2User.getName(); String username = oAuth2User.getName();
// If the user does not have an email, set it to "no-email". We will not send any eamil notifications to this user. // If the user does not have an email, set it to "no-email". We will not send any eamil notifications to this user.
String email = oAuth2User.getAttribute("mail") != null ? oAuth2User.getAttribute("mail") : "no-email"; String email = Objects.requireNonNullElse(oAuth2User.getAttribute("email"), "no-email");
if(!userService.existsByUsername(username)) { if(!userService.existsByUsername(username)) {
userService.registerUser(username, email); userService.registerUser(username, email);
} else {
userService.updateEmail(username, email);
} }
response.sendRedirect(redirectUrl); response.sendRedirect(redirectUrl);
} }

View File

@ -27,6 +27,18 @@ public class UserService {
.orElseThrow(() -> new IllegalArgumentException("User not found")); .orElseThrow(() -> new IllegalArgumentException("User not found"));
} }
public void updateEmail(String username, String newEmail) {
AppUser user = appUserRepository.findByUsername(username)
.orElseThrow(() -> new IllegalArgumentException("User not found"));
if(newEmail.equalsIgnoreCase("no-email")) {
return;
}
user.setEmail(newEmail);
appUserRepository.save(user);
}
public boolean existsByUsername(String username) { public boolean existsByUsername(String username) {
return appUserRepository.existsByUsername(username); return appUserRepository.existsByUsername(username);
} }

View File

@ -30,12 +30,11 @@ spring.jpa.hibernate.ddl-auto=update
spring.jpa.show-sql=false spring.jpa.show-sql=false
# OAuth2 properties, remember if you change the registration.provider the provider properties must be updated # OAuth2 properties, remember if you change the registration.provider the provider properties must be updated
spring.security.oauth2.client.provider.docker.authorization-uri=http://localhost:51337/authorize spring.security.oauth2.client.provider.docker.issuer-uri=http://localhost:51337
spring.security.oauth2.client.provider.docker.token-uri=http://localhost:51337/exchange
spring.security.oauth2.client.provider.docker.user-info-uri=http://localhost:51337/introspect
spring.security.oauth2.client.provider.docker.user-name-attribute=sub
spring.security.oauth2.client.registration.seshat.client-id=seshat spring.security.oauth2.client.registration.seshat.client-id=seshat
spring.security.oauth2.client.registration.seshat.client-secret=n0tS3cr3t spring.security.oauth2.client.registration.seshat.client-secret=n0tS3cr3t
spring.security.oauth2.client.registration.seshat.authorization-grant-type=authorization_code spring.security.oauth2.client.registration.seshat.authorization-grant-type=authorization_code
spring.security.oauth2.client.registration.seshat.provider=docker spring.security.oauth2.client.registration.seshat.provider=docker
spring.security.oauth2.client.registration.seshat.redirect-uri={baseUrl}/login/oauth2/code/{registrationId} spring.security.oauth2.client.registration.seshat.redirect-uri={baseUrl}/login/oauth2/code/{registrationId}
spring.security.oauth2.client.registration.seshat.scope=openid,profile,email

View File

@ -17,7 +17,7 @@
<a class="user-menu text-white text-decoration-none dropdown-toggle" href="#" id="userMenu" role="button" <a class="user-menu text-white text-decoration-none dropdown-toggle" href="#" id="userMenu" role="button"
data-bs-toggle="dropdown" aria-expanded="false"> data-bs-toggle="dropdown" aria-expanded="false">
<i class="bi bi-person-circle"></i> <i class="bi bi-person-circle"></i>
<span th:text="${#authentication.getName()}">Username</span> <span th:text="${displayName}">Username</span>
</a> </a>
<ul class="dropdown-menu dropdown-menu-end" aria-labelledby="userMenu"> <ul class="dropdown-menu dropdown-menu-end" aria-labelledby="userMenu">
<li><a class="dropdown-item" th:href="@{/logout}">Logout</a></li> <li><a class="dropdown-item" th:href="@{/logout}">Logout</a></li>

View File

@ -3,11 +3,21 @@ package se.su.dsv.seshat;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.testcontainers.service.connection.ServiceConnection; import org.springframework.boot.testcontainers.service.connection.ServiceConnection;
import org.testcontainers.containers.ComposeContainer;
import org.testcontainers.containers.GenericContainer;
import org.testcontainers.junit.jupiter.Container;
import org.testcontainers.junit.jupiter.Testcontainers;
import java.io.File;
@Testcontainers
@SpringBootTest @SpringBootTest
class SeshatApplicationTests { class SeshatApplicationTests {
@ServiceConnection @ServiceConnection
private static org.testcontainers.containers.MariaDBContainer<?> dbContainer = new org.testcontainers.containers.MariaDBContainer<>("mariadb:10.11"); private static org.testcontainers.containers.MariaDBContainer<?> dbContainer = new org.testcontainers.containers.MariaDBContainer<>("mariadb:10.11");
@Container
private static ComposeContainer oauth2Container = new ComposeContainer(new File("compose-oauth.yaml"));
@Test @Test
void contextLoads() { void contextLoads() {
} }