diff --git a/back_end/src/main/java/hackathon/FrisbYEE/config/WebSecurityConfig.java b/back_end/src/main/java/hackathon/FrisbYEE/config/WebSecurityConfig.java index c96ab6c..e054c00 100644 --- a/back_end/src/main/java/hackathon/FrisbYEE/config/WebSecurityConfig.java +++ b/back_end/src/main/java/hackathon/FrisbYEE/config/WebSecurityConfig.java @@ -26,7 +26,7 @@ public class WebSecurityConfig { .cors(cors -> cors.configurationSource(corsConfigurationSource())) .csrf(csrf -> csrf.disable()) .authorizeHttpRequests(auth -> auth - .requestMatchers(HttpMethod.OPTIONS, "/", "/public", "/coach/**").permitAll() // allow coach endpoints + .requestMatchers(HttpMethod.OPTIONS, "/", "/public", "/coach/**","/athlete/**").permitAll() // allow coach endpoints .requestMatchers("/admin/**").hasRole("admin") .requestMatchers("/user/**").hasRole("user") .anyRequest().authenticated()) diff --git a/back_end/src/main/java/hackathon/FrisbYEE/jpa/metier/Admin.java b/back_end/src/main/java/hackathon/FrisbYEE/jpa/metier/Admin.java index 0dc3a34..beb97b4 100644 --- a/back_end/src/main/java/hackathon/FrisbYEE/jpa/metier/Admin.java +++ b/back_end/src/main/java/hackathon/FrisbYEE/jpa/metier/Admin.java @@ -43,16 +43,6 @@ public class Admin extends User{ super.setPrenom(prenom); } - @Override - public String getId_keycloak() { - return super.getId_keycloak(); - } - - @Override - public void setId_keycloak(String id_keycloak) { - super.setId_keycloak(id_keycloak); - } - @Override public Role getRole() { return super.getRole(); diff --git a/back_end/src/main/java/hackathon/FrisbYEE/jpa/metier/Athlete.java b/back_end/src/main/java/hackathon/FrisbYEE/jpa/metier/Athlete.java index 1992780..745e329 100644 --- a/back_end/src/main/java/hackathon/FrisbYEE/jpa/metier/Athlete.java +++ b/back_end/src/main/java/hackathon/FrisbYEE/jpa/metier/Athlete.java @@ -56,17 +56,6 @@ public class Athlete extends User{ public void setPrenom(String prenom) { super.setPrenom(prenom); } - - @Override - public String getId_keycloak() { - return super.getId_keycloak(); - } - - @Override - public void setId_keycloak(String id_keycloak) { - super.setId_keycloak(id_keycloak); - } - @Override public Role getRole() { return super.getRole(); diff --git a/back_end/src/main/java/hackathon/FrisbYEE/jpa/metier/Coach.java b/back_end/src/main/java/hackathon/FrisbYEE/jpa/metier/Coach.java index 50b9c39..0ddb7a7 100644 --- a/back_end/src/main/java/hackathon/FrisbYEE/jpa/metier/Coach.java +++ b/back_end/src/main/java/hackathon/FrisbYEE/jpa/metier/Coach.java @@ -49,16 +49,6 @@ public class Coach extends User{ super.setPrenom(prenom); } - @Override - public String getId_keycloak() { - return super.getId_keycloak(); - } - - @Override - public void setId_keycloak(String id_keycloak) { - super.setId_keycloak(id_keycloak); - } - @Override public Role getRole() { return super.getRole(); diff --git a/back_end/src/main/java/hackathon/FrisbYEE/jpa/metier/User.java b/back_end/src/main/java/hackathon/FrisbYEE/jpa/metier/User.java index 188bd09..2bdf5ce 100644 --- a/back_end/src/main/java/hackathon/FrisbYEE/jpa/metier/User.java +++ b/back_end/src/main/java/hackathon/FrisbYEE/jpa/metier/User.java @@ -26,8 +26,8 @@ public class User implements Serializable { @GeneratedValue @Column(unique = true, nullable = false) private Integer id; - @Column(nullable = false, unique = true) - private String id_keycloak; + @Column(name = "id_keycloak", unique = true, nullable = false) + private String keycloakId; private String name; private String prenom; @@ -38,7 +38,7 @@ public class User implements Serializable { public User(String name, String id_keycloak, String prenom, Role role) { this.name = name; - this.id_keycloak = id_keycloak; + this.keycloakId = id_keycloak; this.prenom = prenom; this.role = role; } diff --git a/back_end/src/main/java/hackathon/FrisbYEE/jpa/service/AthleteDAO.java b/back_end/src/main/java/hackathon/FrisbYEE/jpa/service/AthleteDAO.java index 476acc8..25da7ef 100644 --- a/back_end/src/main/java/hackathon/FrisbYEE/jpa/service/AthleteDAO.java +++ b/back_end/src/main/java/hackathon/FrisbYEE/jpa/service/AthleteDAO.java @@ -1,11 +1,12 @@ package hackathon.FrisbYEE.jpa.service; import hackathon.FrisbYEE.jpa.metier.Athlete; - +import java.util.Optional; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.stereotype.Repository; @Repository public interface AthleteDAO extends JpaRepository { - + boolean existsByKeycloakId(String keycloakId); + Optional findByKeycloakId(String keycloakId); } \ No newline at end of file diff --git a/back_end/src/main/java/hackathon/FrisbYEE/rest/AthleteResource.java b/back_end/src/main/java/hackathon/FrisbYEE/rest/AthleteResource.java index b4372ee..56c46d3 100644 --- a/back_end/src/main/java/hackathon/FrisbYEE/rest/AthleteResource.java +++ b/back_end/src/main/java/hackathon/FrisbYEE/rest/AthleteResource.java @@ -32,9 +32,9 @@ import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.responses.ApiResponse; import io.swagger.v3.oas.annotations.responses.ApiResponses; - -@Controller +@RestController @RequestMapping("/athlete") +@CrossOrigin(origins = "http://localhost:3000") public class AthleteResource { @Autowired private AthleteDAO athleteDAO; @@ -45,7 +45,7 @@ public class AthleteResource { @ApiResponse(responseCode = "200", description = "Renvoie l'athlète créé", content = @Content(mediaType = "application/json", schema = @Schema(implementation = AthleteDTO.class))) }) @PostMapping("/create") - @PreAuthorize("hasRole('Admin')") // Only admin can create?? + @PreAuthorize("hasRole('Admin') or hasRole('Coach') or hasRole('Athlete')") public ResponseEntity create(@RequestBody AthleteDTO dto) { Athlete athlete = mapToEntity(dto); athleteDAO.save(athlete); @@ -126,8 +126,9 @@ public class AthleteResource { private AthleteDTO mapToDTO(Athlete athlete) { AthleteDTO dto = new AthleteDTO(); - dto.setId_keycloak(athlete.getId_keycloak()); + dto.setId_keycloak(athlete.getKeycloakId()); dto.setName(athlete.getName()); + dto.setPrenom(athlete.getPrenom()); dto.setCategorie(athlete.getCategorie()); dto.setNiveau(athlete.getNiveau()); return dto; @@ -135,6 +136,12 @@ public class AthleteResource { private Athlete mapToEntity(AthleteDTO dto) { Athlete athlete = new Athlete(); + athlete.setName(dto.getName()); + athlete.setPrenom(dto.getPrenom()); + athlete.setKeycloakId(dto.getId_keycloak()); + athlete.setCategorie(dto.getCategorie()); + athlete.setNiveau(dto.getNiveau()); + athlete.setRole(hackathon.FrisbYEE.jpa.metier.Role.ATHLETE); return athlete; } diff --git a/back_end/src/main/java/hackathon/FrisbYEE/rest/CoachResource.java b/back_end/src/main/java/hackathon/FrisbYEE/rest/CoachResource.java index 706a777..acd34f1 100644 --- a/back_end/src/main/java/hackathon/FrisbYEE/rest/CoachResource.java +++ b/back_end/src/main/java/hackathon/FrisbYEE/rest/CoachResource.java @@ -70,14 +70,14 @@ public class CoachResource { private CoachDTO mapToDTO(Coach coach) { CoachDTO dto = new CoachDTO(); - dto.setId_keycloak(coach.getId_keycloak()); + dto.setId_keycloak(coach.getKeycloakId()); dto.setName(coach.getName()); return dto; } private Coach mapToEntity(CoachDTO dto) { Coach coach = new Coach(); - coach.setId_keycloak(dto.getId_keycloak()); + coach.setKeycloakId(dto.getId_keycloak()); coach.setName(dto.getName()); return coach; } diff --git a/back_end/src/main/resources/application.properties b/back_end/src/main/resources/application.properties index a0fc7cf..adbc11b 100644 --- a/back_end/src/main/resources/application.properties +++ b/back_end/src/main/resources/application.properties @@ -8,6 +8,5 @@ spring.jpa.show-sql=true spring.jpa.database-platform=org.hibernate.dialect.PostgreSQLDialect server.port=8081 server.servlet.context-path=/api - spring.security.oauth2.resourceserver.jwt.issuer-uri=http://localhost:8080/realms/Frisbyee_realm spring.security.oauth2.resourceserver.jwt.jwk-set-uri: http://localhost:8080/realms/Frisbyee_realm/protocol/openid-connect/certs \ No newline at end of file diff --git a/front_end/src/App.tsx b/front_end/src/App.tsx index a4b5b7f..733add2 100644 --- a/front_end/src/App.tsx +++ b/front_end/src/App.tsx @@ -11,7 +11,7 @@ import EdtCoach from './components/edt_coach' import { Coach } from "./classes"; import RessourcePanel from './components/ressourcePanel'; import TestAPI from './components/test_api'; - +import EdtAthlete from './components/edt_athlete'; // Test const testCoach = new Coach(); testCoach.id = 1; @@ -36,7 +36,7 @@ function App() { - + diff --git a/front_end/src/classes.tsx b/front_end/src/classes.tsx index 977f100..011a8fc 100644 --- a/front_end/src/classes.tsx +++ b/front_end/src/classes.tsx @@ -3,7 +3,9 @@ export type Role = "Admin" | "Athlete" | "Coach"; export class User{ id!: number; + keycloakId!: String; nom!: String; + prenom!:String; sessions: Session[] = []; //nb: Admin liaison non symétrique /!\ email!: String; role!: Role; @@ -18,21 +20,17 @@ export class Ligne{ export class Admin extends User{ role!: Role; - } export class Athlete extends User{ nom!: String; groupe!: Groupe; role!: Role; - - } export class Coach extends User{ nom!: String; role!: Role; - } export class Session{ diff --git a/front_end/src/components/login.tsx b/front_end/src/components/login.tsx index 25b3179..0abca28 100644 --- a/front_end/src/components/login.tsx +++ b/front_end/src/components/login.tsx @@ -3,16 +3,59 @@ import { useEffect } from 'react'; import { getUserTest, User } from '../classes'; import { useLocalData } from '../context/useLocalData'; - - - export const Login =() =>{ const {user,setUser} = useLocalData() + const { keycloak } = useKeycloak(); + useEffect(() => { + const syncUser = async () => { + if (keycloak.authenticated && keycloak.token) { + console.log("Attempting to sync user with backend..."); + try { + const response = await fetch("http://localhost:8081/api/users/sync", { + method: "POST", + headers: { + "Authorization": `Bearer ${keycloak.token}`, + "Content-Type": "application/json" + }, + }); + console.log("Sync status:", response.status); + } catch (error) { + console.error("Sync fetch failed:", error); + } + } + }; - useEffect(() => { //TODO à supprimer - setUser(getUserTest()) - },[]); + syncUser(); + }, [keycloak.authenticated, keycloak.token]); + + useEffect(() => { + if (keycloak.authenticated && keycloak.token) { + fetch("http://localhost:8081/api/users/sync", { + method: "POST", + headers: { + Authorization: `Bearer ${keycloak.token}`, + }, + }) + .then(res => console.log("Sync response status:", res.status)) + .catch(err => console.error("Sync error:", err));; + } + }, [keycloak.authenticated]); + + useEffect(() => { + if (keycloak.authenticated) { + const tokenParsed = keycloak.tokenParsed; + setUser({ + id: 0, + keycloakId: tokenParsed!.sub!, + email: tokenParsed?.email, + nom: tokenParsed?.family_name, + prenom: tokenParsed?.given_name, + role: "Athlete", + sessions: [] + }); + } + }, [keycloak.authenticated]); function handleLogin(): void { @@ -24,8 +67,6 @@ export const Login =() =>{ keycloak.logout() setUser(new User()); } - - const { keycloak } = useKeycloak() return(
diff --git a/front_end/src/components/ressourcePanel.tsx b/front_end/src/components/ressourcePanel.tsx index 62515dc..ad21358 100644 --- a/front_end/src/components/ressourcePanel.tsx +++ b/front_end/src/components/ressourcePanel.tsx @@ -13,7 +13,9 @@ import { unescapeLeadingUnderscores } from "typescript"; const { user } = useLocalData(); const [value,setValue] = useState("athletes"); console.log("Rôle utilisateur:", user.role); - console.log("name", user.nom); + console.log(user.nom); + console.log(user.prenom); + console.log(user.email); if (user.role === "Athlete") return null; @@ -55,7 +57,7 @@ import { unescapeLeadingUnderscores } from "typescript"; } }); - + const allLignes: Ligne[] = Array.from(ligneMap.values()); // Calculer le temps de jeu pour chaque ligne