Lot of things

Refactored Role enum to be the same as Keycloak roles
Managed CORS errors in backend
Edited Keycloak config to avoid CORS error
Edited frontend API to avoid CORS errors
Changed Activite creation management
Added debug print in Login (should be removed);
This commit is contained in:
Alexis Leboeuf
2026-01-08 11:26:16 +01:00
parent fc98b7aef9
commit 9a2d1ae5e6
12 changed files with 45 additions and 12 deletions

6
back_end/package-lock.json generated Normal file
View File

@@ -0,0 +1,6 @@
{
"name": "back_end",
"lockfileVersion": 3,
"requires": true,
"packages": {}
}

View File

@@ -6,11 +6,15 @@ import java.util.Map;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationToken;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.CorsConfigurationSource;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
@Configuration
@EnableWebSecurity
@@ -19,9 +23,10 @@ public class WebSecurityConfig {
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http
.cors(cors -> cors.configurationSource(corsConfigurationSource()))
.csrf(csrf -> csrf.disable())
.authorizeHttpRequests(auth -> auth
.requestMatchers("/", "/public", "/coach/**").permitAll() // allow coach endpoints
.requestMatchers(HttpMethod.OPTIONS, "/", "/public", "/coach/**").permitAll() // allow coach endpoints
.requestMatchers("/admin/**").hasRole("admin")
.requestMatchers("/user/**").hasRole("user")
.anyRequest().authenticated())
@@ -29,6 +34,7 @@ public class WebSecurityConfig {
.jwt(jwt -> jwt.jwtAuthenticationConverter(jwtToken -> {
Map<String, Collection<String>> realmAccess = jwtToken.getClaim("realm_access");
Collection<String> roles = realmAccess.get("roles");
System.out.println("ROLES FROM TOKEN " + roles);
List<SimpleGrantedAuthority> authorities = roles.stream()
.map(role -> new SimpleGrantedAuthority("ROLE_" + role))
.toList();
@@ -37,4 +43,18 @@ public class WebSecurityConfig {
return http.build();
}
@Bean
public CorsConfigurationSource corsConfigurationSource() {
CorsConfiguration config = new CorsConfiguration();
config.setAllowedOrigins(List.of("http://localhost:3000"));
config.setAllowedMethods(List.of("GET", "POST", "PUT", "DELETE", "OPTIONS"));
config.setAllowCredentials(true);
config.setAllowedHeaders(List.of("Authorization", "Content-Type"));
UrlBasedCorsConfigurationSource source =
new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", config);
return source;
}
}

View File

@@ -14,7 +14,7 @@ import jakarta.persistence.Entity;
public class Admin extends User{
public Admin(String id_keycloak, String name, String prenom){
super(name, id_keycloak, prenom, Role.ADMIN );
super(name, id_keycloak, prenom, Role.admin );
}
@Override

View File

@@ -28,7 +28,7 @@ public class Athlete extends User{
private List<Session> sessions = new ArrayList<>(); // plusieurs sessions sont possibles
public Athlete(String name, String id_keycloak, String prenom){
super(name, id_keycloak, prenom, Role.ATHLETE);
super(name, id_keycloak, prenom, Role.athlete);
}
@Override

View File

@@ -20,7 +20,7 @@ public class Coach extends User{
private List<Session> sessions = new ArrayList<>(); // Un coach peut avoir plusieurs sessions
public Coach(String name, String id_keycloak, String prenom){
super(name, id_keycloak, prenom, Role.COACH );
super(name, id_keycloak, prenom, Role.coach );
}
@Override

View File

@@ -1,7 +1,7 @@
package hackathon.FrisbYEE.jpa.metier;
public enum Role {
ADMIN,
COACH,
ATHLETE
admin,
coach,
athlete
}

View File

@@ -58,7 +58,7 @@ public class Session {
}
public void setCoach(Coach coach) {
if (coach.getRole() != Role.COACH) {
if (coach.getRole() != Role.coach) {
throw new IllegalArgumentException("L'utilisateur n'est pas un coach");
}
this.coach = coach;
@@ -66,7 +66,7 @@ public class Session {
public void setAthletes(List<Athlete> athletes) {
for (Athlete athlete : athletes) {
if (athlete.getRole() != Role.ATHLETE) {
if (athlete.getRole() != Role.athlete) {
throw new IllegalArgumentException("L'utilisateur n'est pas un athlète");
}
}

View File

@@ -20,6 +20,7 @@ import org.springframework.web.bind.annotation.*;
import java.util.List;
import java.util.stream.Collectors;
@CrossOrigin(origins = "http://localhost:3000")
@Controller
@RequestMapping("/activite")
@@ -49,6 +50,7 @@ public class ActiviteResource {
public ResponseEntity<String> create(@RequestBody ActiviteDTO dto) {
try {
System.out.println("ROLE TEST " + hackathon.FrisbYEE.jpa.metier.Role.coach);
Session session = sessionDAO.findById(dto.getSessionId()).get();
Activite activite = mapToEntity(dto);
activite.setSession(session);

View File

@@ -1,6 +1,7 @@
{
"realm": "Frisbyee_realm",
"resource": "Frisbyee_client",
"clientId": "Frisbyee_client",
"auth-server-url": "http://localhost:8080",
"public-client": true
}

View File

@@ -6,6 +6,7 @@ const api = axios.create({
headers: {
"Content-Type": "application/json",
},
withCredentials: true,
});
api.interceptors.request.use((config) => {

View File

@@ -1,7 +1,7 @@
import { useState, useEffect } from "react";
import { Session, User, Coach, Activite, Groupe } from "../classes";
import { useLocalData } from "../context/useLocalData";
import { sessionService } from "../api";
import { activiteService, sessionService } from "../api";
export const CreateSession = () => {
const {user} = useLocalData()
@@ -24,7 +24,7 @@ export const CreateSession = () => {
newActivite.duree= activiteDuree;
newActivite.data= new Map<string,string>();
try{
await sessionService.create(newActivite);
await activiteService.create(newActivite);
console.log("Session créée");
setActivities([...activities, newActivite]);

View File

@@ -16,7 +16,7 @@ export const Login =() =>{
function handleLogin(): void {
keycloak.login()
keycloak.login();
//TODO setUser
}
@@ -39,6 +39,9 @@ export const Login =() =>{
<div>
User nom : { user.nom}
</div>
<div>
User role : { user.role}
</div>
</div>
}