Maybe add thymeleaf?

need to test and add config keycloak
This commit is contained in:
Vu Tuan Minh
2025-10-22 01:39:18 +02:00
parent f6250a2724
commit 3f0e3c801c
25 changed files with 323 additions and 413 deletions

45
pom.xml
View File

@@ -15,8 +15,8 @@
</organization> </organization>
<properties> <properties>
<main.basedir>${basedir}/../..</main.basedir> <main.basedir>${basedir}/../..</main.basedir>
<maven.compiler.source>11</maven.compiler.source> <maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target> <maven.compiler.target>17</maven.compiler.target>
</properties> </properties>
@@ -90,9 +90,9 @@
</dependency> </dependency>
<!-- https://mvnrepository.com/artifact/javax.validation/validation-api --> <!-- https://mvnrepository.com/artifact/javax.validation/validation-api -->
<dependency> <dependency>
<groupId>javax.validation</groupId> <groupId>jakarta.validation</groupId>
<artifactId>validation-api</artifactId> <artifactId>jakarta.validation-api</artifactId>
<version>2.0.1.Final</version> <version>3.1.1</version>
</dependency> </dependency>
<dependency> <dependency>
@@ -196,41 +196,7 @@
</plugins> </plugins>
</pluginManagement> </pluginManagement>
</build> </build>
<repositories>
<repository>
<id>spring-snapshots</id>
<name>Spring Snapshots</name>
<url>http://repo.spring.io/snapshot</url>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>
<repository>
<id>spring-milestones</id>
<name>Spring Milestones</name>
<url>http://repo.spring.io/milestone</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
</repositories>
<pluginRepositories> <pluginRepositories>
<pluginRepository>
<id>spring-snapshots</id>
<name>Spring Snapshots</name>
<url>http://repo.spring.io/snapshot</url>
<snapshots>
<enabled>true</enabled>
</snapshots>
</pluginRepository>
<pluginRepository>
<id>spring-milestones</id>
<name>Spring Milestones</name>
<url>http://repo.spring.io/milestone</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</pluginRepository>
<pluginRepository> <pluginRepository>
<id>spring-releases</id> <id>spring-releases</id>
<name>Spring Releases</name> <name>Spring Releases</name>
@@ -240,5 +206,4 @@
</snapshots> </snapshots>
</pluginRepository> </pluginRepository>
</pluginRepositories> </pluginRepositories>
</project> </project>

View File

@@ -1,3 +0,0 @@
mkdir data
cd data
java -cp ..\hsqldb-2.7.2.jar org.hsqldb.Server

View File

@@ -1,4 +0,0 @@
mvn dependency:copy-dependencies
mkdir data 2> /dev/null
cd data
java -cp ../target/dependency/hsqldb-2.7.2.jar org.hsqldb.Server

View File

@@ -1,2 +0,0 @@
java -cp ./target/dependency/hsqldb-2.7.2.jar org.hsqldb.util.DatabaseManagerSwing --driver org.hsqldb.jdbcDriver --url jdbc:hsqldb:hsql://localhost/ --user SA

View File

@@ -1,2 +0,0 @@
#mvn dependency:copy-dependencies
java -cp ./target/dependency/hsqldb-2.7.2.jar org.hsqldb.util.DatabaseManagerSwing --driver org.hsqldb.jdbcDriver --url jdbc:hsqldb:hsql://localhost/ --user SA

View File

@@ -21,9 +21,7 @@ import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication @SpringBootApplication
public class SampleDataJpaApplication { public class SampleDataJpaApplication {
public static void main(String[] args) throws Exception { public static void main(String[] args) throws Exception {
SpringApplication.run(SampleDataJpaApplication.class, args); SpringApplication.run(SampleDataJpaApplication.class, args);
} }
} }

View File

@@ -1,21 +0,0 @@
package sample.data.jpa;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.web.SecurityFilterChain;
@Configuration
public class SecurityConfig {
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
.csrf(csrf -> csrf.disable())
.authorizeHttpRequests(auth -> auth
.anyRequest().permitAll()
);
return http.build();
}
}

View File

@@ -0,0 +1,41 @@
package sample.data.jpa;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
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;
@Configuration
@EnableWebSecurity
public class WebSecurityConfig {
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http.authorizeHttpRequests(auth -> auth
.requestMatchers("/").permitAll()
.requestMatchers("/index").hasAuthority("USER")
.requestMatchers("/admin").hasAuthority("ADMIN")
.requestMatchers("/session/**").hasAnyAuthority("USER", "ADMIN")
.requestMatchers("/quizz/**").hasAuthority("ADMIN")
.anyRequest().authenticated()
)
.oauth2ResourceServer(oauth2 -> oauth2
.jwt(jwt -> jwt.jwtAuthenticationConverter(jwtToken -> {
Map<String, Collection<String>> realmAccess = jwtToken.getClaim("realm_access");
Collection<String> roles = realmAccess.get("roles");
List<SimpleGrantedAuthority> grantedAuthorities = roles.stream()
.map(role -> new SimpleGrantedAuthority(role.toUpperCase()))
.toList();
return new JwtAuthenticationToken(jwtToken, grantedAuthorities);
}))
);
return http.build();
}
}

View File

@@ -0,0 +1,38 @@
package sample.data.jpa.controller;
import java.security.Principal;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationToken;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.servlet.ModelAndView;
@Controller
public class ViewController {
@GetMapping("/index")
@PreAuthorize("hasRole('USER')")
public ModelAndView index(JwtAuthenticationToken authentication) {
ModelAndView modelAndView = new ModelAndView("index");
authentication.getToken().getClaims().forEach((e, v) -> {
System.err.println(e + ' ' + v);
});
modelAndView.addObject("user", authentication);
return modelAndView;
}
@GetMapping("/")
public ModelAndView main() {
ModelAndView modelAndView = new ModelAndView("indexmain");
return modelAndView;
}
@GetMapping("/admin")
@PreAuthorize("hasRole('ADMIN')")
public ModelAndView admin(Principal principal) {
ModelAndView modelAndView = new ModelAndView("admin");
modelAndView.addObject("user", principal);
return modelAndView;
}
}

View File

@@ -1,66 +0,0 @@
package sample.data.jpa.domain;
// Imports ...
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.Table;
import javax.validation.constraints.NotNull;
@Entity
@Table(name = "users")
public class User {
// An autogenerated id (unique for each user in the db)
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private long id;
@NotNull
private String email;
@NotNull
private String name;
// Public methods
public User() { }
public User(long id) {
this.id = id;
}
public User(String email, String name) {
this.email = email;
this.name = name;
}
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
// Getter and setter methods
// ...
}

View File

@@ -16,6 +16,10 @@ public class Utilisateur implements Serializable {
private int id; private int id;
private String name; private String name;
//Pour génénrer un sub diff pour chaque persone
@Column(unique = true)
private String keycloakId;
@Column(unique=true) @Column(unique=true)
private String email; private String email;
private String password; private String password;

View File

@@ -7,6 +7,4 @@ import sample.data.jpa.metier.Question;
@Transactional @Transactional
public interface QuestionDao extends JpaRepository<Question, Integer> { public interface QuestionDao extends JpaRepository<Question, Integer> {
} }

View File

@@ -1,20 +0,0 @@
package sample.data.jpa.service;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.transaction.annotation.Transactional;
import sample.data.jpa.domain.User;
// Imports ...
@Transactional
public interface UserDao extends JpaRepository<User, Long> {
/**
* This method will find an User instance in the database by its email.
* Note that this method is not implemented and its working code will be
* automagically generated from its signature by Spring Data JPA.
*/
public User findByEmail(String email);
}

View File

@@ -5,4 +5,5 @@ import org.springframework.data.jpa.repository.JpaRepository;
import sample.data.jpa.metier.Utilisateur; import sample.data.jpa.metier.Utilisateur;
public interface UtilisateurDao extends JpaRepository<Utilisateur, Integer> { public interface UtilisateurDao extends JpaRepository<Utilisateur, Integer> {
Utilisateur findByKeycloakId(String keycloakId);
} }

View File

@@ -13,14 +13,13 @@ import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.security.access.prepost.PreAuthorize;
import sample.data.jpa.metier.Question; import sample.data.jpa.metier.Question;
import sample.data.jpa.metier.Reponse; import sample.data.jpa.metier.Reponse;
import sample.data.jpa.service.QuestionDao; import sample.data.jpa.service.QuestionDao;
import sample.data.jpa.service.ReponseDao; import sample.data.jpa.service.ReponseDao;
@Controller @Controller
@RequestMapping("/question") @RequestMapping("/question")
public class QuestionController { public class QuestionController {
@@ -46,18 +45,17 @@ public class QuestionController {
*/ */
@PostMapping("/create") @PostMapping("/create")
@ResponseBody @ResponseBody
@PreAuthorize("hasRole('ADMIN')")
public String create(@RequestBody Map<String, String> body) { public String create(@RequestBody Map<String, String> body) {
String qId = ""; String qId = "";
Question q = new Question(); Question q = new Question();
try { try {
if (body.containsKey("enonce")) { if (body.containsKey("enonce")) {
q.setEnonce(body.get("enonce")); q.setEnonce(body.get("enonce"));
} } else q.setEnonce("");
else q.setEnonce("");
qDao.save(q); qDao.save(q);
qId = String.valueOf(q.getId()); qId = String.valueOf(q.getId());
} } catch (Exception ex) {
catch (Exception ex) {
return "Error creating the question : " + ex.toString(); return "Error creating the question : " + ex.toString();
} }
return "Question \"" + q.getEnonce() + "\" succesfully created with id = " + qId; return "Question \"" + q.getEnonce() + "\" succesfully created with id = " + qId;
@@ -69,14 +67,14 @@ public class QuestionController {
*/ */
@PutMapping("/update/{id}") @PutMapping("/update/{id}")
@ResponseBody @ResponseBody
@PreAuthorize("hasRole('ADMIN')")
public String update(@PathVariable("id") int id, @RequestBody Map<String, String> body) { public String update(@PathVariable("id") int id, @RequestBody Map<String, String> body) {
Question q; Question q;
try { try {
q = qDao.findById(id).get(); q = qDao.findById(id).get();
q.setEnonce(body.get("enonce")); q.setEnonce(body.get("enonce"));
qDao.save(q); qDao.save(q);
} } catch (Exception ex) {
catch (Exception ex) {
return "Error updating the question: " + ex.toString(); return "Error updating the question: " + ex.toString();
} }
return "Question " + id + " succesfully updated! : " + q.getEnonce(); return "Question " + id + " succesfully updated! : " + q.getEnonce();
@@ -84,6 +82,7 @@ public class QuestionController {
@GetMapping("/get/{id}") @GetMapping("/get/{id}")
@ResponseBody @ResponseBody
@PreAuthorize("hasAnyRole('ADMIN','USER')")
public String get(@PathVariable("id") int id) { public String get(@PathVariable("id") int id) {
Question q; Question q;
String res = ""; String res = "";
@@ -99,6 +98,7 @@ public class QuestionController {
@GetMapping("/getAll") @GetMapping("/getAll")
@ResponseBody @ResponseBody
@PreAuthorize("hasAnyRole('ADMIN','USER')")
public String getAll() { public String getAll() {
try { try {
List<Question> questions = qDao.findAll(); List<Question> questions = qDao.findAll();
@@ -115,10 +115,9 @@ public class QuestionController {
} }
} }
@GetMapping("/getReponses/{id}") @GetMapping("/getReponses/{id}")
@ResponseBody @ResponseBody
@PreAuthorize("hasAnyRole('ADMIN','USER')")
public String getReponses(@PathVariable("id") int id) { public String getReponses(@PathVariable("id") int id) {
try { try {
Question question = qDao.findById(id).get(); Question question = qDao.findById(id).get();
@@ -134,16 +133,15 @@ public class QuestionController {
} }
res += "]"; res += "]";
return "Réponse de la question " + id + " : " + res; return "Réponse de la question " + id + " : " + res;
} } else return "Réponse non initialisée pour la question : " + id;
else return "Réponse non initialisée pour la question : " + id;
} catch (Exception ex) { } catch (Exception ex) {
return "Erreur lors de la récupération de la réponse : " + ex.toString(); return "Erreur lors de la récupération de la réponse : " + ex.toString();
} }
} }
@PutMapping("/removeReponse/{id}") @PutMapping("/removeReponse/{id}")
@ResponseBody @ResponseBody
@PreAuthorize("hasRole('ADMIN')")
public String removeReponse(@PathVariable("id") int id) { public String removeReponse(@PathVariable("id") int id) {
try { try {
Question question = qDao.findById(id).get(); Question question = qDao.findById(id).get();
@@ -160,6 +158,7 @@ public class QuestionController {
@PutMapping("/setReponse/{id}/{idR}") @PutMapping("/setReponse/{id}/{idR}")
@ResponseBody @ResponseBody
@PreAuthorize("hasRole('ADMIN')")
public String setReponse(@PathVariable("id") int id, @PathVariable("idR") int idR) { public String setReponse(@PathVariable("id") int id, @PathVariable("idR") int idR) {
try { try {
Question question = qDao.findById(id).get(); Question question = qDao.findById(id).get();
@@ -174,20 +173,17 @@ public class QuestionController {
} }
} }
@DeleteMapping("/delete/{id}") @DeleteMapping("/delete/{id}")
@ResponseBody @ResponseBody
@PreAuthorize("hasRole('ADMIN')")
public String delete(@PathVariable("id") int id) { public String delete(@PathVariable("id") int id) {
try { try {
Question q = qDao.findById(id).get(); Question q = qDao.findById(id).get();
qDao.delete(q); qDao.delete(q);
} } catch (Exception ex) {
catch (Exception ex) {
return "Error deleting the question " + id + " :" + ex.toString(); return "Error deleting the question " + id + " :" + ex.toString();
} }
return "Question " + id + " succesfully deleted!"; return "Question " + id + " succesfully deleted!";
} }
} }

View File

@@ -3,6 +3,7 @@ package sample.data.jpa.web;
import java.util.List; import java.util.List;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.stereotype.Controller; import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.DeleteMapping; import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.GetMapping;
@@ -24,28 +25,24 @@ import sample.data.jpa.service.UtilisateurDao;
@Controller @Controller
@RequestMapping("/quizz") @RequestMapping("/quizz")
public class QuizzController { public class QuizzController {
@Autowired @Autowired
private QuizzDao qDao; private QuizzDao qDao;
@Autowired @Autowired
private QuestionDao qtDao; private QuestionDao qtDao;
@Autowired @Autowired
private UtilisateurDao uDao; private UtilisateurDao uDao;
/* /*
Post /quizz/create/{idU} Post /quizz/create
Delete /quizz/delete/{id} Delete /quizz/delete/{id}
Put /quizz/addQuestion/{idQuestion}/{idQuizz} Put /quizz/addQuestion/{idQuestion}/{idQuizz}
Put /quizz/removeQuestion/{idQuestin}/{idQuizz} Put /quizz/removeQuestion/{idQuestin}/{idQuizz}
Get /quizz/get/{id}
Get /quizz/getAll Get /quizz/getAll
Get /quizz/getQuestions/{id} Get /quizz/getQuestions/{id}
*/ */
@PostMapping("/create/{id}") @PostMapping("/create/{id}")
@ResponseBody @ResponseBody
@PreAuthorize("hasRole('ADMIN')")
public String create(@PathVariable("id") int id) { public String create(@PathVariable("id") int id) {
String qId = ""; String qId = "";
String emailU = ""; String emailU = "";
@@ -56,8 +53,7 @@ public class QuizzController {
q.setUtilisateur(u); q.setUtilisateur(u);
qDao.save(q); qDao.save(q);
qId = String.valueOf(q.getId()); qId = String.valueOf(q.getId());
} } catch (Exception ex) {
catch (Exception ex) {
return "Error creating the Quizz : " + ex.toString(); return "Error creating the Quizz : " + ex.toString();
} }
return "Quizz succesfully created by "+ emailU +" with id = " + qId; return "Quizz succesfully created by "+ emailU +" with id = " + qId;
@@ -65,20 +61,20 @@ public class QuizzController {
@DeleteMapping("/delete/{id}") @DeleteMapping("/delete/{id}")
@ResponseBody @ResponseBody
@PreAuthorize("hasRole('ADMIN')")
public String delete(@PathVariable("id") int id) { public String delete(@PathVariable("id") int id) {
try { try {
Quizz q = qDao.findById(id).get(); Quizz q = qDao.findById(id).get();
qDao.delete(q); qDao.delete(q);
} } catch (Exception ex) {
catch (Exception ex) {
return "Error deleting the quizz " + id + " :" + ex.toString(); return "Error deleting the quizz " + id + " :" + ex.toString();
} }
return "Quizz " + id + " succesfully deleted!"; return "Quizz " + id + " succesfully deleted!";
} }
@PutMapping("/addQuestion/{id}/{idQ}") @PutMapping("/addQuestion/{id}/{idQ}")
@ResponseBody @ResponseBody
@PreAuthorize("hasRole('ADMIN')")
public String addQuestion(@PathVariable("id") int id, @PathVariable("idQ") int qId) { public String addQuestion(@PathVariable("id") int id, @PathVariable("idQ") int qId) {
try { try {
Quizz q = qDao.findById(id).get(); Quizz q = qDao.findById(id).get();
@@ -86,16 +82,15 @@ public class QuizzController {
q.getQuestions().add(qt); q.getQuestions().add(qt);
qt.setQuizz(q); qt.setQuizz(q);
qDao.save(q); qDao.save(q);
} } catch (Exception ex) {
catch (Exception ex) {
return "Error adding question from the quizz " + id + " :" + ex.toString(); return "Error adding question from the quizz " + id + " :" + ex.toString();
} }
return "Question " + qId + " add in Quizz " + id; return "Question " + qId + " add in Quizz " + id;
} }
@PutMapping("/removeQuestion/{id}/{idQ}") @PutMapping("/removeQuestion/{id}/{idQ}")
@ResponseBody @ResponseBody
@PreAuthorize("hasRole('ADMIN')")
public String removeQuestion(@PathVariable("id") int id, @PathVariable("idQ") int qId) { public String removeQuestion(@PathVariable("id") int id, @PathVariable("idQ") int qId) {
try { try {
Quizz q = qDao.findById(id).get(); Quizz q = qDao.findById(id).get();
@@ -103,8 +98,7 @@ public class QuizzController {
q.getQuestions().remove(qt); q.getQuestions().remove(qt);
qt.setQuizz(null); qt.setQuizz(null);
qDao.save(q); qDao.save(q);
} } catch (Exception ex) {
catch (Exception ex) {
return "Error removing question from the quizz " + id + " :" + ex.toString(); return "Error removing question from the quizz " + id + " :" + ex.toString();
} }
return "Question remove from Quizz " + id; return "Question remove from Quizz " + id;
@@ -113,6 +107,7 @@ public class QuizzController {
@GetMapping("/get/{id}") @GetMapping("/get/{id}")
@ResponseBody @ResponseBody
@PreAuthorize("hasAnyRole('ADMIN', 'USER')")
public String get(@PathVariable("id") int id){ public String get(@PathVariable("id") int id){
String res = ""; String res = "";
try { try {
@@ -148,6 +143,7 @@ public class QuizzController {
@GetMapping("/getAll") @GetMapping("/getAll")
@ResponseBody @ResponseBody
@PreAuthorize("hasAnyRole('ADMIN', 'USER')")
public String getAll() { public String getAll() {
String res = ""; String res = "";
try { try {
@@ -156,8 +152,7 @@ public class QuizzController {
res += "id: " + quizz.getId() + " , "; res += "id: " + quizz.getId() + " , ";
res += " nbQuestion:" + quizz.getQuestions().size() + "]\n"; res += " nbQuestion:" + quizz.getQuestions().size() + "]\n";
} }
} } catch (Exception ex) {
catch (Exception ex) {
return "Error get all Quizz :" + ex.toString(); return "Error get all Quizz :" + ex.toString();
} }
return "Quizzs : \n" + res; return "Quizzs : \n" + res;
@@ -165,22 +160,20 @@ public class QuizzController {
@GetMapping("/getQuestions/{id}") @GetMapping("/getQuestions/{id}")
@ResponseBody @ResponseBody
@PreAuthorize("hasAnyRole('ADMIN', 'USER')")
public String getQuestion(@PathVariable("id") int id) { public String getQuestion(@PathVariable("id") int id) {
String res = ""; String res = "";
try {; try {
;
Quizz quizz = qDao.findById(id).get(); Quizz quizz = qDao.findById(id).get();
for (Question question : quizz.getQuestions()) { for (Question question : quizz.getQuestions()) {
res += "id: " + question.getId() + " , "; res += "id: " + question.getId() + " , ";
res += "enonce: \"" + question.getEnonce() + "\"\n"; res += "enonce: \"" + question.getEnonce() + "\"\n";
} }
} } catch (Exception ex) {
catch (Exception ex) {
return "Error get question of the Quizz :" + ex.toString(); return "Error get question of the Quizz :" + ex.toString();
} }
return "Questions : \n" + res; return "Questions : \n" + res;
} }
} }

View File

@@ -4,6 +4,7 @@ import java.util.List;
import java.util.Map; import java.util.Map;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.stereotype.Controller; import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.DeleteMapping; import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.GetMapping;
@@ -45,6 +46,7 @@ public class ReponseController {
*/ */
@PostMapping("/create/choix") @PostMapping("/create/choix")
@ResponseBody @ResponseBody
@PreAuthorize("hasRole('ADMIN')")
public String createReponseChoix() { public String createReponseChoix() {
try { try {
Choix r = new Choix(); Choix r = new Choix();
@@ -60,6 +62,7 @@ public class ReponseController {
*/ */
@PostMapping("/create/courte") @PostMapping("/create/courte")
@ResponseBody @ResponseBody
@PreAuthorize("hasRole('ADMIN')")
public String createReponseCourte() { public String createReponseCourte() {
try { try {
ReponseCourte r = new ReponseCourte(); ReponseCourte r = new ReponseCourte();
@@ -72,12 +75,13 @@ public class ReponseController {
@GetMapping("/getAll") @GetMapping("/getAll")
@ResponseBody @ResponseBody
@PreAuthorize("hasAnyRole('ADMIN','USER')")
public String getAll() { public String getAll() {
try { try {
String res = ""; String res = "";
List<Reponse> reponses = rDao.findAll(); List<Reponse> reponses = rDao.findAll();
for (Reponse reponse : reponses) { for (Reponse reponse : reponses) {
res+="id : " + reponse.getId() + "\n" + reponse.prettyPrinter(1) + "\n"; res += "id : " + reponse.getId() + " , " + reponse.toString() + "\n";
} }
return res; return res;
} catch (Exception ex) { } catch (Exception ex) {
@@ -87,6 +91,7 @@ public class ReponseController {
@GetMapping("/get/{id}") @GetMapping("/get/{id}")
@ResponseBody @ResponseBody
@PreAuthorize("hasAnyRole('ADMIN','USER')")
public String get(@PathVariable("id") int id) { public String get(@PathVariable("id") int id) {
try { try {
String res = ""; String res = "";
@@ -101,13 +106,13 @@ public class ReponseController {
@DeleteMapping("/delete/{id}") @DeleteMapping("/delete/{id}")
@ResponseBody @ResponseBody
@PreAuthorize("hasRole('ADMIN')")
public String delete(@PathVariable("id") int id) { public String delete(@PathVariable("id") int id) {
try { try {
Reponse r = rDao.findById(id).get(); Reponse r = rDao.findById(id).get();
rDao.delete(r); rDao.delete(r);
} } catch (Exception ex) {
catch (Exception ex) {
return "Erreur pendant la suppression de la Reponse " + id + " :" + ex.toString(); return "Erreur pendant la suppression de la Reponse " + id + " :" + ex.toString();
} }
return "Reponse " + id + " supprimée avec succès"; return "Reponse " + id + " supprimée avec succès";
@@ -116,6 +121,7 @@ public class ReponseController {
@PutMapping("/addReponse/{id}") @PutMapping("/addReponse/{id}")
@ResponseBody @ResponseBody
@PreAuthorize("hasRole('ADMIN')")
public String addReponse(@PathVariable("id") int id, @RequestBody Map<String, String> body) { public String addReponse(@PathVariable("id") int id, @RequestBody Map<String, String> body) {
try { try {
if (body.containsKey("reponse")) { if (body.containsKey("reponse")) {
@@ -132,6 +138,7 @@ public class ReponseController {
@PutMapping("/removeReponse/{id}") @PutMapping("/removeReponse/{id}")
@ResponseBody @ResponseBody
@PreAuthorize("hasRole('ADMIN')")
public String removeReponses(@PathVariable("id") int id, @RequestBody Map<String, String> body) { public String removeReponses(@PathVariable("id") int id, @RequestBody Map<String, String> body) {
try { try {
Reponse rep = rDao.findById(id).get(); Reponse rep = rDao.findById(id).get();
@@ -148,6 +155,7 @@ public class ReponseController {
@PutMapping("/addChoix/{id}") @PutMapping("/addChoix/{id}")
@ResponseBody @ResponseBody
@PreAuthorize("hasRole('ADMIN')")
public String addChoix(@PathVariable("id") int id, @RequestBody Map<String, String> body) { public String addChoix(@PathVariable("id") int id, @RequestBody Map<String, String> body) {
try { try {
Reponse reponse = rDao.findById(id).get(); Reponse reponse = rDao.findById(id).get();
@@ -156,17 +164,16 @@ public class ReponseController {
((Choix) reponse).getChoix().add(choix); ((Choix) reponse).getChoix().add(choix);
rDao.save(reponse); rDao.save(reponse);
return "Choix \"" + choix + "\" ajouté à la question " + id; return "Choix \"" + choix + "\" ajouté à la question " + id;
} } else return "Erreur : la réponse doit être a choix multiple.";
else return "Erreur : la réponse doit être a choix multiple.";
} catch (Exception ex) { } catch (Exception ex) {
return "Erreur lors de l'ajout du choix : " + ex.toString(); return "Erreur lors de l'ajout du choix : " + ex.toString();
} }
} }
@PutMapping("/removeChoix/{id}") @PutMapping("/removeChoix/{id}")
@ResponseBody @ResponseBody
@PreAuthorize("hasRole('ADMIN')")
public String removeChoix(@PathVariable("id") int id, @RequestBody Map<String, String> body) { public String removeChoix(@PathVariable("id") int id, @RequestBody Map<String, String> body) {
try { try {
Reponse reponse = rDao.findById(id).get(); Reponse reponse = rDao.findById(id).get();
@@ -175,8 +182,7 @@ public class ReponseController {
((Choix) reponse).getChoix().remove(choix); ((Choix) reponse).getChoix().remove(choix);
rDao.save(reponse); rDao.save(reponse);
return "Choix \"" + choix + "\" supprimé à la question " + id; return "Choix \"" + choix + "\" supprimé à la question " + id;
} } else return "Erreur : la réponse doit être a choix multiple.";
else return "Erreur : la réponse doit être a choix multiple.";
} catch (Exception ex) { } catch (Exception ex) {
return "Erreur lors de la suppression du choix : " + ex.toString(); return "Erreur lors de la suppression du choix : " + ex.toString();

View File

@@ -4,6 +4,8 @@ import java.util.List;
import java.util.Map; import java.util.Map;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationToken;
import org.springframework.stereotype.Controller; import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.DeleteMapping; import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.GetMapping;
@@ -24,7 +26,6 @@ import sample.data.jpa.service.UtilisateurDao;
@Controller @Controller
@RequestMapping("/session") @RequestMapping("/session")
public class SessionController { public class SessionController {
@Autowired @Autowired
private SessionDao sDao; private SessionDao sDao;
@Autowired @Autowired
@@ -39,25 +40,22 @@ public class SessionController {
Put /session/addQuizz/{id}/{idQ} Put /session/addQuizz/{id}/{idQ}
Put /session/removeQuizz/{id} Put /session/removeQuizz/{id}
Put /session/update/{id} param : body Jsp, "theme" Put /session/update/{id} param : body Jsp, "theme"
Put /session/addUtilisateur/{id}/{idU} Put /session/join/{sessionId}
Put /session/removeUtilisateur/{id}/{idU} Put /session//leave/{sessionId}
*/ */
@PostMapping("/create") @PostMapping("/create")
@ResponseBody @ResponseBody
@PreAuthorize("hasRole('ADMIN')")
public String create(@RequestBody Map<String, String> body) { public String create(@RequestBody Map<String, String> body) {
String sId = ""; String sId = "";
Session q = new Session(); Session q = new Session();
try { try {
if (body.containsKey("theme")) { if (body.containsKey("theme")) {
q.setTheme(body.get("theme")); q.setTheme(body.get("theme"));
} } else q.setTheme("");
else q.setTheme("");
sDao.save(q); sDao.save(q);
sId = String.valueOf(q.getId()); sId = String.valueOf(q.getId());
} } catch (Exception ex) {
catch (Exception ex) {
return "Error creating the Session : " + ex.toString(); return "Error creating the Session : " + ex.toString();
} }
return "Session \"" + q.getTheme() + "\" succesfully created with id = " + sId; return "Session \"" + q.getTheme() + "\" succesfully created with id = " + sId;
@@ -65,13 +63,13 @@ public class SessionController {
@DeleteMapping("/delete/{id}") @DeleteMapping("/delete/{id}")
@ResponseBody @ResponseBody
@PreAuthorize("hasRole('ADMIN')")
public String delete(@PathVariable("id") int id) { public String delete(@PathVariable("id") int id) {
try { try {
Session q = sDao.findById(id).get(); Session q = sDao.findById(id).get();
sDao.delete(q); sDao.delete(q);
} } catch (Exception ex) {
catch (Exception ex) {
return "Error deleting the session " + id + " :" + ex.toString(); return "Error deleting the session " + id + " :" + ex.toString();
} }
return "Session " + id + " succesfully deleted!"; return "Session " + id + " succesfully deleted!";
@@ -79,6 +77,7 @@ public class SessionController {
@GetMapping("/getAll") @GetMapping("/getAll")
@ResponseBody @ResponseBody
@PreAuthorize("hasAnyRole('ADMIN','USER')")
public String getAll() { public String getAll() {
try { try {
List<Session> sessions = sDao.findAll(); List<Session> sessions = sDao.findAll();
@@ -98,6 +97,7 @@ public class SessionController {
@PutMapping("/addQuizz/{id}/{qid}") @PutMapping("/addQuizz/{id}/{qid}")
@ResponseBody @ResponseBody
@PreAuthorize("hasRole('ADMIN')")
public String addQuizz(@PathVariable("id") int id, @PathVariable("qid") int qId) { public String addQuizz(@PathVariable("id") int id, @PathVariable("qid") int qId) {
try { try {
Session s = sDao.findById(id).get(); Session s = sDao.findById(id).get();
@@ -114,6 +114,7 @@ public class SessionController {
@PutMapping("/removeQuizz/{id}/{qid}") @PutMapping("/removeQuizz/{id}/{qid}")
@ResponseBody @ResponseBody
@PreAuthorize("hasRole('ADMIN')")
public String removeQuizz(@PathVariable("id") int id, @PathVariable("qid") int qId) { public String removeQuizz(@PathVariable("id") int id, @PathVariable("qid") int qId) {
try { try {
Session s = sDao.findById(id).get(); Session s = sDao.findById(id).get();
@@ -128,57 +129,65 @@ public class SessionController {
return "Quizz " + qId + " remove from Session " + id; return "Quizz " + qId + " remove from Session " + id;
} }
/* /*
* Utiliser un Json pour mettre le String "theme" * Utiliser un Json pour mettre le String "theme"
* l'id se met dans l'url * l'id se met dans l'url
*/ */
@PutMapping("/update/{id}") @PutMapping("/update/{id}")
@ResponseBody @ResponseBody
@PreAuthorize("hasRole('ADMIN')")
public String updateQuestion(@PathVariable("id") int id, @RequestBody Map<String, String> body) { public String updateQuestion(@PathVariable("id") int id, @RequestBody Map<String, String> body) {
Session s; Session s;
try { try {
s = sDao.findById(id).get(); s = sDao.findById(id).get();
s.setTheme(body.get("theme")); s.setTheme(body.get("theme"));
sDao.save(s); sDao.save(s);
} } catch (Exception ex) {
catch (Exception ex) {
return "Error updating the Session: " + ex.toString(); return "Error updating the Session: " + ex.toString();
} }
return "Session " + id + " succesfully updated! : " + s.getTheme(); return "Session " + id + " succesfully updated! : " + s.getTheme();
} }
@PutMapping("/join/{sessionId}")
@PutMapping("/addUtilisateur/{id}/{idU}")
@ResponseBody @ResponseBody
public String addSession(@PathVariable("id") int id, @PathVariable("qid") int idU) { @PreAuthorize("hasRole('USER')")
public String joinSession(@PathVariable("sessionId") int sessionId, JwtAuthenticationToken auth) {
try { try {
Utilisateur u = uDao.findById(idU).get(); String keycloakUserId = auth.getToken().getClaim("sub");
Session s = sDao.findById(id).get(); Utilisateur u = uDao.findByKeycloakId(keycloakUserId);
if (u == null) {
return "User not found in database.";
}
Session s = sDao.findById(sessionId).orElseThrow(() -> new Exception("Session not found"));
u.getSessions().add(s); u.getSessions().add(s);
s.getUtilisateurs().add(u); s.getUtilisateurs().add(u);
sDao.save(s); sDao.save(s);
uDao.save(u); uDao.save(u);
return "User " + u.getName() + " joined session " + sessionId;
} catch (Exception ex) { } catch (Exception ex) {
return "Erreur pendant l'ajout de l'utilisateur dans la session : " + ex.toString(); return "Erreur pendant l'ajout de l'utilisateur dans la session : " + ex.toString();
} }
return "Utilisateur " + id + " ajouté à la Session " + id;
} }
@PutMapping("/removeUtilisateur/{id}/{idU}") @PutMapping("/leave/{sessionId}")
@ResponseBody @ResponseBody
public String removeSession(@PathVariable("id") int id, @PathVariable("idU") int idU) { @PreAuthorize("hasRole('USER')")
public String leaveSession(@PathVariable("sessionId") int sessionId, JwtAuthenticationToken auth) {
try { try {
Utilisateur u = uDao.findById(idU).get(); String keycloakUserId = auth.getToken().getClaim("sub");
Session s = sDao.findById(id).get(); Utilisateur u = uDao.findByKeycloakId(keycloakUserId);
if (u == null) {
return "User not found in database.";
}
Session s = sDao.findById(sessionId).orElseThrow(() -> new Exception("Session not found"));
u.getSessions().remove(s); u.getSessions().remove(s);
s.getUtilisateurs().remove(u); s.getUtilisateurs().remove(u);
sDao.save(s); sDao.save(s);
uDao.save(u); uDao.save(u);
return "User " + u.getName() + " left session " + sessionId;
} catch (Exception ex) { } catch (Exception ex) {
return "Erreur pendant la suppression de l'utilisateur de la session : " + ex.toString(); return "Erreur pendant la suppression de l'utilisateur de la session : " + ex.toString();
} }
return "Utilisateur " + id + " retiré de la Session " + id;
} }
} }

View File

@@ -1,92 +0,0 @@
package sample.data.jpa.web;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import sample.data.jpa.domain.User;
import sample.data.jpa.service.UserDao;
@Controller
@RequestMapping("/user")
public class UserController {
/**
* GET /create --> Create a new user and save it in the database.
*/
@RequestMapping("/create")
@ResponseBody
public String create(String email, String name) {
String userId = "";
try {
User user = new User(email, name);
userDao.save(user);
userId = String.valueOf(user.getId());
}
catch (Exception ex) {
return "Error creating the user: " + ex.toString();
}
return "User succesfully created with id = " + userId;
}
/**
* GET /delete --> Delete the user having the passed id.
*/
@RequestMapping("/delete")
@ResponseBody
public String delete(long id) {
try {
User user = new User(id);
userDao.delete(user);
}
catch (Exception ex) {
return "Error deleting the user:" + ex.toString();
}
return "User succesfully deleted!";
}
/**
* GET /get-by-email --> Return the id for the user having the passed
* email.
*/
@RequestMapping("/get-by-email/{email}")
@ResponseBody
public String getByEmail(@PathVariable("email") String email) {
String userId = "";
try {
User user = userDao.findByEmail(email);
userId = String.valueOf(user.getId());
}
catch (Exception ex) {
return "User not found";
}
return "The user id is: " + userId;
}
/**
* GET /update --> Update the email and the name for the user in the
* database having the passed id.
*/
@RequestMapping("/update")
@ResponseBody
public String updateUser(long id, String email, String name) {
try {
User user = userDao.findById(id).get();
user.setEmail(email);
user.setName(name);
userDao.save(user);
}
catch (Exception ex) {
return "Error updating the user: " + ex.toString();
}
return "User succesfully updated!";
}
// Private fields
@Autowired
private UserDao userDao;
}

View File

@@ -1,8 +1,10 @@
package sample.data.jpa.web; package sample.data.jpa.web;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.stereotype.Controller; import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.DeleteMapping; import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.GetMapping;
@@ -38,9 +40,9 @@ public class UtilisateurController {
Put /utilisateur/update/{id} param : body Jsp, "name", "email", "oldpassword, "password" Put /utilisateur/update/{id} param : body Jsp, "name", "email", "oldpassword, "password"
*/ */
@PostMapping("/create") @PostMapping("/create")
@ResponseBody @ResponseBody
@PreAuthorize("hasRole('ADMIN')")
public String create(@RequestBody Map<String, String> body) { public String create(@RequestBody Map<String, String> body) {
try { try {
if(body.containsKey("name") && body.containsKey("email") && body.containsKey("password")){ if(body.containsKey("name") && body.containsKey("email") && body.containsKey("password")){
@@ -51,24 +53,21 @@ public class UtilisateurController {
uDao.save(u); uDao.save(u);
String uId = String.valueOf(u.getId()); String uId = String.valueOf(u.getId());
return "Utilisateur \"" + u.getName() + "\" créé avec succès avec l'id = " + uId; return "Utilisateur \"" + u.getName() + "\" créé avec succès avec l'id = " + uId;
} } else return "Erreur, besoin de name, email et password dans le JSON";
else return "Erreur, besoin de name, email et password dans le JSON"; } catch (Exception ex) {
}
catch (Exception ex) {
return "Erreur durant la création de l'Utilisateur : " + ex.toString(); return "Erreur durant la création de l'Utilisateur : " + ex.toString();
} }
} }
@DeleteMapping("/delete/{id}") @DeleteMapping("/delete/{id}")
@ResponseBody @ResponseBody
@PreAuthorize("hasRole('ADMIN')")
public String delete(@PathVariable("id") int id) { public String delete(@PathVariable("id") int id) {
try { try {
Utilisateur u = uDao.findById(id).get(); Utilisateur u = uDao.findById(id).get();
uDao.delete(u); uDao.delete(u);
} } catch (Exception ex) {
catch (Exception ex) {
return "Erreur pendant la suppression de l'utilisateur " + id + " :" + ex.toString(); return "Erreur pendant la suppression de l'utilisateur " + id + " :" + ex.toString();
} }
return "Utilisateur " + id + " supprimé avec succès !"; return "Utilisateur " + id + " supprimé avec succès !";
@@ -76,6 +75,7 @@ public class UtilisateurController {
@GetMapping("/getAll") @GetMapping("/getAll")
@ResponseBody @ResponseBody
@PreAuthorize("hasAnyRole('ADMIN','USER')")
public String getAll() { public String getAll() {
try { try {
List<Utilisateur> utilisateurs = uDao.findAll(); List<Utilisateur> utilisateurs = uDao.findAll();
@@ -94,6 +94,7 @@ public class UtilisateurController {
@GetMapping("/getSessions/{id}") @GetMapping("/getSessions/{id}")
@ResponseBody @ResponseBody
@PreAuthorize("hasAnyRole('ADMIN','USER')")
public String getSessions(@PathVariable("id") int id){ public String getSessions(@PathVariable("id") int id){
try { try {
Utilisateur u = uDao.findById(id).get(); Utilisateur u = uDao.findById(id).get();
@@ -109,6 +110,7 @@ public class UtilisateurController {
@PutMapping("/addSession/{id}/{qid}") @PutMapping("/addSession/{id}/{qid}")
@ResponseBody @ResponseBody
@PreAuthorize("hasRole('ADMIN')")
public String addSession(@PathVariable("id") int id, @PathVariable("qid") int sId) { public String addSession(@PathVariable("id") int id, @PathVariable("qid") int sId) {
try { try {
Utilisateur u = uDao.findById(id).get(); Utilisateur u = uDao.findById(id).get();
@@ -126,6 +128,7 @@ public class UtilisateurController {
@PutMapping("/removeSession/{id}/{qid}") @PutMapping("/removeSession/{id}/{qid}")
@ResponseBody @ResponseBody
@PreAuthorize("hasRole('ADMIN')")
public String removeSession(@PathVariable("id") int id, @PathVariable("qid") int sId) { public String removeSession(@PathVariable("id") int id, @PathVariable("qid") int sId) {
try { try {
Utilisateur u = uDao.findById(id).get(); Utilisateur u = uDao.findById(id).get();
@@ -143,6 +146,7 @@ public class UtilisateurController {
@PostMapping("/update/{id}") @PostMapping("/update/{id}")
@ResponseBody @ResponseBody
@PreAuthorize("hasRole('ADMIN')")
public String update(@PathVariable("id") int id, @RequestBody Map<String, String> body) { public String update(@PathVariable("id") int id, @RequestBody Map<String, String> body) {
try { try {
if (body.containsKey("name") && body.containsKey("email") && body.containsKey("password")) { if (body.containsKey("name") && body.containsKey("email") && body.containsKey("password")) {
@@ -152,10 +156,8 @@ public class UtilisateurController {
u.setPassword(body.get("password")); u.setPassword(body.get("password"));
uDao.save(u); uDao.save(u);
return "Utilisateur \"" + u.getName() + "\" mis à jour avec succès"; return "Utilisateur \"" + u.getName() + "\" mis à jour avec succès";
} } else return "Erreur, besoin de name, email et password dans le JSON";
else return "Erreur, besoin de name, email et password dans le JSON"; } catch (Exception ex) {
}
catch (Exception ex) {
return "Erreur durant la mise à jour de de l'Utilisateur : " + ex.toString(); return "Erreur durant la mise à jour de de l'Utilisateur : " + ex.toString();
} }
} }

View File

@@ -1,2 +1,14 @@
spring.datasource.name=scratchdb server.port=8082
spring.jmx.default-domain=jpa.sample
spring.h2.console.enabled=true
spring.h2.console.path=/h2
spring.datasource.url=jdbc:h2:mem:testdb
spring.datasource.driver-class-name=org.h2.Driver
spring.datasource.username=sa
spring.datasource.password=
spring.sql.init.platform=h2
spring.sql.init.mode= always
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.H2Dialect
spring.security.oauth2.resourceserver.jwt.issuer-uri=http://localhost:8080/realms/myspringbootapprealm
spring.security.oauth2.resourceserver.jwt.jwk-set-uri=http://localhost:8080/realms/myspringbootapprealm/protocol/openid-connect/certs

View File

@@ -0,0 +1,14 @@
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Admin</title>
</head>
<body>
This is the admin page
<br/>
Logged user: <span th:if="${user} != null" th:text="${user.name}"></span>
<br/>
<a href="/logout">logout</a>
</body>
</html>

View File

@@ -0,0 +1,14 @@
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Index</title>
</head>
<body>
This is the index page.
<br/>
Logged user: <span th:if="${user} != null" th:text="${user.name}"></span>
<br/>
<a href="/admin">admin</a>
<a href="/logout">logout</a>
</body>

View File

@@ -0,0 +1,15 @@
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Main</title>
</head>
<body>
This is the main page.
<br/>
<a href="/index">index</a>
<br/>
<a href="/admin">admin</a>
</body>
</html>
>

View File

@@ -0,0 +1,14 @@
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Logout</title>
</head>
<body>
This is the logout page.
<br/>
Logged user: <span th:if="${user} != null" th:text="${user.name}"></span>
<br/>
<a href="/">main</a>
</body>
</html>