3 Commits

Author SHA1 Message Date
005e9503d6 CourseController
All checks were successful
Build and test backend / Build-backend (pull_request) Successful in 2m2s
Build and test backend / Test-backend (pull_request) Successful in 1m58s
Build and test FrontEnd / Build-frontend (pull_request) Successful in 24s
2024-03-16 16:29:24 +01:00
8128e4c8f8 changed Course entity 2024-03-16 16:28:34 +01:00
115c050e5e master merge 2024-03-16 15:37:59 +01:00
66 changed files with 704 additions and 2033 deletions

View File

@ -17,16 +17,15 @@ jobs:
distribution: 'temurin' distribution: 'temurin'
- uses: gradle/gradle-build-action@v3 - uses: gradle/gradle-build-action@v3
- name: building - name: building
run: ./gradlew backend:build -x test run: ./gradlew backend:build
# Test-backend: Test-backend:
# runs-on: ubuntu-latest runs-on: ubuntu-latest
# steps: steps:
# - uses: actions/checkout@v4 - uses: actions/checkout@v4
# - uses: actions/setup-java@v3 - uses: actions/setup-java@v3
# with: with:
# java-version: '21' java-version: '21'
# distribution: 'temurin' distribution: 'temurin'
# - run: curl -fsSL https://get.docker.com | sh - uses: gradle/gradle-build-action@v3
# - uses: gradle/gradle-build-action@v3 - name: building
# - name: testing run: ./gradlew backend:test
# run: ./gradlew backend:test

2
backend/.gitignore vendored
View File

@ -35,5 +35,3 @@ out/
### VS Code ### ### VS Code ###
.vscode/ .vscode/
/cdn

View File

@ -31,11 +31,8 @@ dependencies {
testImplementation("org.springframework.boot:spring-boot-testcontainers") testImplementation("org.springframework.boot:spring-boot-testcontainers")
testImplementation("org.testcontainers:junit-jupiter") testImplementation("org.testcontainers:junit-jupiter")
testImplementation("org.testcontainers:postgresql") testImplementation("org.testcontainers:postgresql")
testImplementation("io.rest-assured:rest-assured")
testImplementation("org.hamcrest:hamcrest")
} }
tasks.register("run") { tasks.register("run") {
dependsOn(tasks.bootRun) dependsOn(tasks.bootRun)
} }

View File

@ -6,4 +6,4 @@ services:
- 'POSTGRES_USER=devel' - 'POSTGRES_USER=devel'
- 'POSTGRES_PASSWORD=devel' - 'POSTGRES_PASSWORD=devel'
ports: ports:
- '5442:5432' - '5432:5432'

View File

@ -2,7 +2,6 @@ package ovh.herisson.Clyde.EndPoints;
import org.springframework.http.HttpStatus; import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity; import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestHeader; import org.springframework.web.bind.annotation.RequestHeader;
@ -10,12 +9,10 @@ import org.springframework.web.bind.annotation.RestController;
import ovh.herisson.Clyde.Services.AuthenticatorService; import ovh.herisson.Clyde.Services.AuthenticatorService;
import ovh.herisson.Clyde.Tables.Applications; import ovh.herisson.Clyde.Tables.Applications;
import ovh.herisson.Clyde.Tables.Role; import ovh.herisson.Clyde.Tables.Role;
import ovh.herisson.Clyde.Tables.User;
import java.util.ArrayList; import java.util.ArrayList;
@RestController @RestController
@CrossOrigin(originPatterns = "*", allowCredentials = "true")
public class ApplicationsController { public class ApplicationsController {
AuthenticatorService authServ; AuthenticatorService authServ;
@ -30,6 +27,7 @@ public class ApplicationsController {
*/ */
@GetMapping("/apps") @GetMapping("/apps")
public ResponseEntity<Iterable<Applications>> getAuthorizedApps(@RequestHeader("Authorization") String token){ public ResponseEntity<Iterable<Applications>> getAuthorizedApps(@RequestHeader("Authorization") String token){
return new ResponseEntity<>(getAuthorizedApplications(token), HttpStatus.OK); return new ResponseEntity<>(getAuthorizedApplications(token), HttpStatus.OK);
} }
@ -43,33 +41,22 @@ public class ApplicationsController {
} }
public ArrayList<Applications> getAuthorizedApplications(String token){ public ArrayList<Applications> getAuthorizedApplications(String token){
Role posterRole = authServ.getUserFromToken(token).getRole();
ArrayList<Applications> authorizedApps = new ArrayList<>(); ArrayList<Applications> authorizedApps = new ArrayList<>();
//if unAuthed
authorizedApps.add(Applications.Login); authorizedApps.add(Applications.Login);
User user = authServ.getUserFromToken(token);
if(user == null)
return authorizedApps;
// if authed
authorizedApps.add(Applications.Profile); authorizedApps.add(Applications.Profile);
if (!authServ.isNotIn(new Role[]{Role.Teacher,Role.Student,Role.Admin},token)) {
authorizedApps.add(Applications.Msg); authorizedApps.add(Applications.Msg);
authorizedApps.add(Applications.Forum); authorizedApps.add(Applications.Forum);
authorizedApps.add(Applications.Rdv); authorizedApps.add(Applications.Rdv);
}
//if Teacher or Secretary or Admin add ManageCourses App if (posterRole == Role.Student || posterRole == Role.Admin) return authorizedApps;
if (!authServ.isNotIn(new Role[]{Role.Teacher,Role.Secretary,Role.Admin},token))
authorizedApps.add(Applications.ManageCourses);
if (!authServ.isNotIn(new Role[]{Role.InscriptionService,Role.Admin},token)){ if (posterRole == Role.Teacher || posterRole == Role.Secretary || posterRole == Role.Admin) authorizedApps.add(Applications.ManageCourses);
authorizedApps.add(Applications.Inscription);
authorizedApps.add(Applications.StudentsList);} if (posterRole == Role.InscriptionService || posterRole == Role.Admin) authorizedApps.add(Applications.Inscription);
if (!authServ.isNotIn(new Role[]{Role.Secretary,Role.Admin},token)){
authorizedApps.add(Applications.UsersList);}
return authorizedApps; return authorizedApps;
} }
} }

View File

@ -6,12 +6,13 @@ import org.springframework.web.bind.annotation.*;
import ovh.herisson.Clyde.Responses.UnauthorizedResponse; import ovh.herisson.Clyde.Responses.UnauthorizedResponse;
import ovh.herisson.Clyde.Services.AuthenticatorService; import ovh.herisson.Clyde.Services.AuthenticatorService;
import ovh.herisson.Clyde.Services.CourseService; import ovh.herisson.Clyde.Services.CourseService;
import ovh.herisson.Clyde.Services.ProtectionService;
import ovh.herisson.Clyde.Services.TeacherCourseService; import ovh.herisson.Clyde.Services.TeacherCourseService;
import ovh.herisson.Clyde.Tables.Course; import ovh.herisson.Clyde.Tables.Course;
import ovh.herisson.Clyde.Tables.Role; import ovh.herisson.Clyde.Tables.Role;
import ovh.herisson.Clyde.Tables.TeacherCourse;
import ovh.herisson.Clyde.Tables.User; import ovh.herisson.Clyde.Tables.User;
import java.util.HashMap;
import java.util.ArrayList;
import java.util.Map; import java.util.Map;
@RestController @RestController
@ -31,59 +32,20 @@ public class CourseController {
} }
@GetMapping("/course/{id}") @GetMapping("/course/{id}")
public ResponseEntity<HashMap<String,Object>> getCourse(@RequestHeader("Authorization") String token, @PathVariable long id){ public ResponseEntity<Course> getCourse(@RequestHeader("Authorization") String token, @PathVariable long id){
if (authServ.getUserFromToken(token) == null) if (authServ.getUserFromToken(token) == null)
return new UnauthorizedResponse<>(null); return new UnauthorizedResponse<>(null);
Course foundCourse = courseServ.findById(id); return new ResponseEntity<>(courseServ.findById(id), HttpStatus.OK);
if (foundCourse == null)
return new ResponseEntity<>(HttpStatus.BAD_REQUEST);
return new ResponseEntity<>(ProtectionService.courseWithoutPassword(foundCourse), HttpStatus.OK);
}
@GetMapping("/courses")
public ResponseEntity<Iterable<HashMap<String,Object>>> getAllCourses(@RequestHeader("Authorization") String token){
if (authServ.isNotIn(new Role[]{Role.Admin,Role.Secretary},token))
return new UnauthorizedResponse<>(null);
return new ResponseEntity<>(ProtectionService.coursesWithoutPasswords(courseServ.findAll()),HttpStatus.OK);
}
@GetMapping("/courses/owned")
public ResponseEntity<Iterable<HashMap<String ,Object>>> getOwnedCourses(@RequestHeader("Authorization") String token){
if (authServ.isNotIn(new Role[]{Role.Admin,Role.Teacher},token))
return new UnauthorizedResponse<>(null);
return new ResponseEntity<>(ProtectionService.coursesWithoutPasswords(courseServ.findOwnedCourses(authServ.getUserFromToken(token))),HttpStatus.OK);
}
@GetMapping("/course/{id}/assistants")
public ResponseEntity<Iterable<HashMap<String,Object>>> getCourseAssistants(@RequestHeader("Authorization")String token, @PathVariable long id){
if (authServ.getUserFromToken(token) == null)
return new UnauthorizedResponse<>(null);
Iterable<User> assistants = teacherCourseServ.findCourseAssistants(courseServ.findById(id));
return new ResponseEntity<>(ProtectionService.usersWithoutPasswords(assistants),HttpStatus.OK);
} }
@PostMapping("/course") @PostMapping("/course")
public ResponseEntity<Map<String ,Object>> postCourse(@RequestHeader("Authorization") String token, public ResponseEntity<Course> postCourse(@RequestHeader("Authorization") String token, @RequestBody Course course){
@RequestBody Course course) if (authServ.isNotSecretaryOrAdmin(token))
{
System.out.println(course);
System.out.println(token);
if (authServ.isNotIn(new Role[]{Role.Secretary,Role.Admin},token))
return new UnauthorizedResponse<>(null); return new UnauthorizedResponse<>(null);
Course createdCourse = courseServ.save(course); return new ResponseEntity<>(courseServ.save(course), HttpStatus.CREATED);
if (createdCourse == null)
return new ResponseEntity<>(null,HttpStatus.BAD_REQUEST);
return new ResponseEntity<>(ProtectionService.courseWithoutPassword(createdCourse), HttpStatus.CREATED);
} }
@ -93,15 +55,11 @@ public class CourseController {
@PathVariable long id) @PathVariable long id)
{ {
if (authServ.isNotIn(new Role[]{Role.Admin,Role.Teacher,Role.Secretary}, token)) if (authServ.IsNotIn(new Role[]{Role.Admin,Role.Teacher,Role.Secretary}, token)){
return new UnauthorizedResponse<>(null); return new UnauthorizedResponse<>(null);
}
return new ResponseEntity<>(courseServ.modifyData(id, updates, authServ.getUserFromToken(token).getRole()), HttpStatus.OK);
if (!courseServ.modifyData(id, updates, authServ.getUserFromToken(token).getRole()))
return new ResponseEntity<>(HttpStatus.BAD_REQUEST);
return new ResponseEntity<>(HttpStatus.OK);
} }
@PostMapping("/course/{id}") @PostMapping("/course/{id}")
@ -109,30 +67,14 @@ public class CourseController {
@RequestBody Iterable<Long> teacherIds, @RequestBody Iterable<Long> teacherIds,
@PathVariable Long id) @PathVariable Long id)
{ {
if (authServ.IsNotIn(new Role[]{Role.Admin,Role.Secretary}, token))
if (authServ.isNotIn(new Role[]{Role.Admin,Role.Secretary}, token))
return new UnauthorizedResponse<>(null); return new UnauthorizedResponse<>(null);
if (!teacherCourseServ.saveAll(teacherIds,courseServ.findById(id)))
return new ResponseEntity<>(HttpStatus.BAD_REQUEST);
teacherCourseServ.saveAll(teacherIds,courseServ.findById(id));
return new ResponseEntity<>(HttpStatus.OK); return new ResponseEntity<>(HttpStatus.OK);
} }
@DeleteMapping("course/{id}")
public ResponseEntity<String> deleteUser(@RequestHeader("Authorization") String token, @PathVariable Long id){
if (authServ.isNotIn(new Role[]{Role.Admin,Role.Secretary}, token))
return new UnauthorizedResponse<>(null);
Course toDelete = courseServ.findById(id);
if (toDelete == null)
return new ResponseEntity<>(HttpStatus.BAD_REQUEST);
courseServ.delete(courseServ.findById(id));
return new ResponseEntity<>(HttpStatus.OK);
}
} }

View File

@ -4,10 +4,13 @@ package ovh.herisson.Clyde.EndPoints;
import org.springframework.http.HttpStatus; import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity; import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import ovh.herisson.Clyde.Responses.UnauthorizedResponse; import ovh.herisson.Clyde.Services.AuthenticatorService;
import ovh.herisson.Clyde.Services.*; import ovh.herisson.Clyde.Services.CurriculumCourseService;
import ovh.herisson.Clyde.Services.CurriculumService;
import ovh.herisson.Clyde.Tables.Curriculum; import ovh.herisson.Clyde.Tables.Curriculum;
import ovh.herisson.Clyde.Tables.CurriculumCourse;
import ovh.herisson.Clyde.Tables.Role; import ovh.herisson.Clyde.Tables.Role;
import ovh.herisson.Clyde.Tables.User;
import java.util.Map; import java.util.Map;
@ -19,79 +22,39 @@ public class CurriculumController {
private final CurriculumService curriculumServ; private final CurriculumService curriculumServ;
private final AuthenticatorService authServ; private final AuthenticatorService authServ;
private final UserCurriculumService userCurriculumServ;
private final CurriculumCourseService curriculumCourseServ; private final CurriculumCourseService curriculumCourseServ;
public CurriculumController(CurriculumService curriculumServ, AuthenticatorService authServ, UserCurriculumService userCurriculumServ, CurriculumCourseService curriculumCourseServ){ public CurriculumController(CurriculumService curriculumServ, AuthenticatorService authServ, CurriculumCourseService curriculumCourseServ){
this.curriculumServ = curriculumServ; this.curriculumServ = curriculumServ;
this.authServ = authServ; this.authServ = authServ;
this.userCurriculumServ = userCurriculumServ;
this.curriculumCourseServ = curriculumCourseServ; this.curriculumCourseServ = curriculumCourseServ;
} }
@GetMapping("/curriculum/{id}") @GetMapping("/curriculum/{id}")
public ResponseEntity<Map<String,Object>> findById(@PathVariable long id){ public ResponseEntity<Curriculum> findById(@PathVariable long id){
Curriculum foundCurriculum = curriculumServ.findById(id); return new ResponseEntity<>(curriculumServ.findById(id), HttpStatus.OK);
if (foundCurriculum == null)
return new ResponseEntity<>(HttpStatus.BAD_REQUEST);
return new ResponseEntity<>(curriculumCourseServ.getDepthCurriculum(foundCurriculum), HttpStatus.OK);
}
@GetMapping("/curriculum")
public ResponseEntity<Map<String ,Object>> findSelfCurriculum(@RequestHeader("Authorization") String token){
if (authServ.getUserFromToken(token) == null)
return new UnauthorizedResponse<>(null);
Curriculum curriculum = userCurriculumServ.findByUser(authServ.getUserFromToken(token));
if (curriculum == null)
return new ResponseEntity<>(HttpStatus.BAD_REQUEST);
return new ResponseEntity<>(curriculumCourseServ.getDepthCurriculum(curriculum),HttpStatus.OK);
} }
@GetMapping("/curriculums") @GetMapping("/curriculums")
public ResponseEntity<Iterable<Map<String, Object>>> findAllIndDepth(){ public ResponseEntity<Iterable<Map<String, Object>>> findAllindDepth(){
return new ResponseEntity<>(curriculumCourseServ.getAllDepthCurriculum(),HttpStatus.OK); return new ResponseEntity<>(curriculumCourseServ.getAllDepthCurriculum(),HttpStatus.OK);
} }
@PostMapping("/curriculum") @GetMapping("/curriculum")
public ResponseEntity<Curriculum> postCurriculum(@RequestHeader("Authorization") String token,@RequestBody Curriculum curriculum){ public ResponseEntity<Iterable<CurriculumCourse>> findAll(){
return new ResponseEntity<>(curriculumCourseServ.findAll(),HttpStatus.OK);
if (authServ.isNotIn(new Role[]{Role.Secretary,Role.Admin},token))
return new UnauthorizedResponse<>(null);
return new ResponseEntity<>(curriculumServ.save(curriculum),HttpStatus.CREATED);
} }
@PostMapping("/curriculum/{id}") /**@PostMapping("/curriculum") //todo now
public ResponseEntity<String> postCoursesToCurriculum(@RequestHeader("Authorization") String token, public ResponseEntity<String> postCurriculum(@RequestHeader("Authorization") String token,@RequestBody Curriculum curriculum){
@RequestBody Iterable<Long> coursesIds,
@PathVariable long id)
{
if (authServ.isNotIn(new Role[]{Role.Admin,Role.Secretary},token)) if (!isSecretaryOrAdmin(token)){
return new UnauthorizedResponse<>(null); return new UnauthorizedResponse<>("you're not allowed to post a Curriculum");
if (!curriculumCourseServ.saveAll(coursesIds, curriculumServ.findById(id)))
return new ResponseEntity<>(HttpStatus.BAD_REQUEST);
return new ResponseEntity<>(HttpStatus.OK);
} }
@DeleteMapping("/curriculum/{id}") CurriculumServ.save(Curriculum);
public ResponseEntity<String > deleteCurriculum(@RequestHeader("Authorization") String token, @PathVariable Long id){
if (authServ.isNotIn(new Role[]{Role.Admin,Role.Secretary}, token))
return new UnauthorizedResponse<>(null);
Curriculum toDelete = curriculumServ.findById(id); return new ResponseEntity<>("created !",HttpStatus.CREATED);
}**/
if (toDelete == null)
return new ResponseEntity<>(HttpStatus.BAD_REQUEST);
curriculumServ.delete(toDelete);
return new ResponseEntity<>(HttpStatus.OK);
}
} }

View File

@ -6,14 +6,17 @@ import org.springframework.web.bind.annotation.*;
import ovh.herisson.Clyde.Responses.UnauthorizedResponse; import ovh.herisson.Clyde.Responses.UnauthorizedResponse;
import ovh.herisson.Clyde.Services.AuthenticatorService; import ovh.herisson.Clyde.Services.AuthenticatorService;
import ovh.herisson.Clyde.Services.InscriptionService; import ovh.herisson.Clyde.Services.InscriptionService;
import ovh.herisson.Clyde.Services.ProtectionService;
import ovh.herisson.Clyde.Tables.InscriptionRequest; import ovh.herisson.Clyde.Tables.InscriptionRequest;
import ovh.herisson.Clyde.Tables.RequestState; import ovh.herisson.Clyde.Tables.RequestState;
import ovh.herisson.Clyde.Tables.Role; import ovh.herisson.Clyde.Tables.Role;
import ovh.herisson.Clyde.Tables.User;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map; import java.util.Map;
@RestController @RestController
@CrossOrigin(originPatterns = "*", allowCredentials = "true") @CrossOrigin(originPatterns = "*", allowCredentials = "true")
public class InscriptionController { public class InscriptionController {
@ -29,54 +32,55 @@ public class InscriptionController {
@GetMapping("/requests/register") @GetMapping("/requests/register")
public ResponseEntity<Iterable<Map<String,Object>>> getAllRequests(@RequestHeader("Authorization") String token){ public ResponseEntity<Iterable<Map<String,Object>>> getAllRequests(@RequestHeader("Authorization") String token){
if (authServ.isNotIn(new Role[]{Role.Admin,Role.InscriptionService},token)) if (authServ.isNotSecretaryOrAdmin(token)){return new UnauthorizedResponse<>(null);}
return new UnauthorizedResponse<>(null);
Iterable<InscriptionRequest> inscriptionRequests = inscriptionServ.getAll(); Iterable<InscriptionRequest> inscriptionRequests = inscriptionServ.getAll();
ArrayList<Map<String,Object>> toReturn = new ArrayList<>();
return new ResponseEntity<>(ProtectionService.requestsWithoutPasswords(inscriptionRequests), HttpStatus.OK); for (InscriptionRequest i:inscriptionRequests){
toReturn.add(requestWithoutPassword(i));
}
return new ResponseEntity<>(toReturn, HttpStatus.OK);
} }
@GetMapping("/request/register/{id}") @GetMapping("/request/register/{id}")
public ResponseEntity<Map<String,Object>> getById(@RequestHeader("Authorization") String token, @PathVariable long id){ public ResponseEntity<Map<String,Object>> getById(@PathVariable long id){
InscriptionRequest inscriptionRequest = inscriptionServ.getById(id);
if (inscriptionRequest == null) {return new ResponseEntity<>(null, HttpStatus.BAD_REQUEST);}
if (authServ.isNotIn(new Role[]{Role.Admin,Role.InscriptionService},token)) return new ResponseEntity<>(requestWithoutPassword(inscriptionRequest), HttpStatus.OK);
return new UnauthorizedResponse<>(null); }
InscriptionRequest foundInscriptionRequest = inscriptionServ.getById(id); @GetMapping("request/user/{id}")
public ResponseEntity<InscriptionRequest> getUserInscriptionRequest(@PathVariable long id, @RequestHeader("Authorize") String token){
if (foundInscriptionRequest == null) //todo return l'inscriptionRequest ACTUELLE du user (check si le poster est bien le même que id target ou secretariat)
return new ResponseEntity<>(null, HttpStatus.BAD_REQUEST); return null;
return new ResponseEntity<>(ProtectionService.requestWithoutPassword(foundInscriptionRequest), HttpStatus.OK);
} }
@PatchMapping("/request/register/{id}") @PatchMapping("/request/register/{id}")
public ResponseEntity<InscriptionRequest> changeRequestState(@PathVariable long id, public ResponseEntity<InscriptionRequest> changeRequestState(@PathVariable long id,
@RequestHeader("Authorization") String token, @RequestHeader("Authorize") String token,
@RequestBody RequestState state) @RequestBody RequestState requestState)
{ {
if (authServ.isNotIn(new Role[]{Role.InscriptionService,Role.Admin},token)) if (authServ.isNotSecretaryOrAdmin(token)) return new UnauthorizedResponse<>(null);
return new UnauthorizedResponse<>(null); inscriptionServ.modifyState(id, requestState);
return null;
if (!inscriptionServ.modifyState(id, state))
return new ResponseEntity<>(HttpStatus.BAD_REQUEST);
return new ResponseEntity<>(HttpStatus.OK);
}
@DeleteMapping("/request/register/{id}")
public ResponseEntity<String > deleteRequest(@RequestHeader("Authorization") String token, @PathVariable Long id){
if (authServ.isNotIn(new Role[]{Role.Admin,Role.InscriptionService}, token))
return new UnauthorizedResponse<>(null);
InscriptionRequest toDelete = inscriptionServ.getById(id);
if (toDelete == null)
return new ResponseEntity<>(HttpStatus.BAD_REQUEST);
inscriptionServ.delete(toDelete);
return new ResponseEntity<>(HttpStatus.OK);
} }
private Map<String, Object> requestWithoutPassword(InscriptionRequest inscriptionRequest) {
Map<String, Object> toReturn = new HashMap<>();
toReturn.put("id", inscriptionRequest.getId());
toReturn.put("firstName", inscriptionRequest.getFirstName());
toReturn.put("lastName", inscriptionRequest.getLastName());
toReturn.put("address", inscriptionRequest.getAddress());
toReturn.put("birthDate", inscriptionRequest.getBirthDate());
toReturn.put("country", inscriptionRequest.getCountry());
toReturn.put("curriculum", inscriptionRequest.getCurriculum());
toReturn.put("profilePictureUrl", inscriptionRequest.getProfilePicture());
toReturn.put("state", inscriptionRequest.getState());
return toReturn;
}
} }

View File

@ -1,5 +1,4 @@
package ovh.herisson.Clyde.EndPoints; package ovh.herisson.Clyde.EndPoints;
import com.fasterxml.jackson.annotation.JsonFormat; import com.fasterxml.jackson.annotation.JsonFormat;
import org.springframework.http.HttpHeaders; import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus; import org.springframework.http.HttpStatus;
@ -7,10 +6,9 @@ import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import ovh.herisson.Clyde.Responses.UnauthorizedResponse; import ovh.herisson.Clyde.Responses.UnauthorizedResponse;
import ovh.herisson.Clyde.Services.AuthenticatorService; import ovh.herisson.Clyde.Services.AuthenticatorService;
import ovh.herisson.Clyde.Services.ProtectionService;
import ovh.herisson.Clyde.Tables.InscriptionRequest; import ovh.herisson.Clyde.Tables.InscriptionRequest;
import java.util.Date; import java.util.Date;
import java.util.Map;
@RestController @RestController
@CrossOrigin(originPatterns = "*", allowCredentials = "true") @CrossOrigin(originPatterns = "*", allowCredentials = "true")
@ -46,11 +44,9 @@ public class LoginController {
return ResponseEntity.ok().headers(responseHeaders).build(); return ResponseEntity.ok().headers(responseHeaders).build();
} }
@PostMapping("/register") @PostMapping("/request/register")
public ResponseEntity<Map<String,Object>> register(@RequestBody InscriptionRequest inscriptionRequest){ public ResponseEntity<String> register(@RequestBody InscriptionRequest inscriptionRequest){
authServ.register(inscriptionRequest);
InscriptionRequest returnedInscriptionRequest = authServ.register(inscriptionRequest); return new ResponseEntity<>("Is OK", HttpStatus.CREATED);
return new ResponseEntity<>(ProtectionService.requestWithoutPassword(returnedInscriptionRequest), HttpStatus.CREATED);
} }
} }

View File

@ -6,6 +6,7 @@ import ovh.herisson.Clyde.Repositories.TokenRepository;
import ovh.herisson.Clyde.Repositories.UserRepository; import ovh.herisson.Clyde.Repositories.UserRepository;
import ovh.herisson.Clyde.Services.*; import ovh.herisson.Clyde.Services.*;
import ovh.herisson.Clyde.Tables.*; import ovh.herisson.Clyde.Tables.*;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Date; import java.util.Date;
@ -22,19 +23,16 @@ public class MockController {
public final CurriculumCourseService CurriculumCourseService; public final CurriculumCourseService CurriculumCourseService;
public final CurriculumService curriculumService; public final CurriculumService curriculumService;
public final CourseService courseService; public final CourseService courseService;
public final InscriptionService inscriptionService;
ArrayList<User> mockUsers; ArrayList<User> mockUsers;
public MockController(UserRepository userRepo, TokenRepository tokenRepo, TokenService tokenService, CurriculumCourseService CurriculumCourseService, CurriculumService curriculumService, CourseService courseService, InscriptionService inscriptionService){ public MockController(UserRepository userRepo, TokenRepository tokenRepo, TokenService tokenService, CurriculumCourseService CurriculumCourseService, CurriculumService curriculumService, CourseService courseService){
this.tokenRepo = tokenRepo; this.tokenRepo = tokenRepo;
this.userRepo = userRepo; this.userRepo = userRepo;
this.tokenService = tokenService; this.tokenService = tokenService;
this.CurriculumCourseService = CurriculumCourseService; this.CurriculumCourseService = CurriculumCourseService;
this.curriculumService = curriculumService; this.curriculumService = curriculumService;
this.courseService = courseService; this.courseService = courseService;
this.inscriptionService = inscriptionService;
} }
/** Saves an example of each user type by : /** Saves an example of each user type by :
@ -51,14 +49,14 @@ public class MockController {
User herobrine = new User("brine","hero","admin@admin.com","in your WalLs","ShadowsLand",new Date(0), null,Role.Admin,passwordEncoder.encode("admin")); User herobrine = new User("brine","hero","admin@admin.com","in your WalLs","ShadowsLand",new Date(0), null,Role.Admin,passwordEncoder.encode("admin"));
User joe = new User("Mama","Joe","student@student.com","roundabout","DaWarudo",new Date(0), null,Role.Student,passwordEncoder.encode("student")); User joe = new User("Mama","Joe","student@student.com","roundabout","DaWarudo",new Date(0), null,Role.Student,passwordEncoder.encode("student"));
User meh = new User("Inspiration","lackOf","secretary@secretary.com","a Box","the street",new Date(0), null,Role.Secretary,passwordEncoder.encode("secretary")); User meh = new User("Inspiration","lackOf","secretary@secretary.com","a Box","the street",new Date(0), null,Role.Teacher,passwordEncoder.encode("secretary"));
User joke = new User("CthemBalls","Lemme","teacher@teacher.com","lab","faculty",new Date(0), null,Role.Teacher,passwordEncoder.encode("teacher")); User joke = new User("CthemBalls","Lemme","teacher@teacher.com","lab","faculty",new Date(0), null,Role.Teacher,passwordEncoder.encode("teacher"));
User jojo = new User("hhoo","yeay","teacher2@teacher2.com","lab","faculty",new Date(0), null,Role.Teacher,passwordEncoder.encode("teacher")); User lena = new User("Louille","Lena","inscriptionService@InscriptionService.com","no","yes",new Date(0), null,Role.Teacher,passwordEncoder.encode("inscriptionService"));
User lena = new User("Louille","Lena","inscriptionService@InscriptionService.com","no","yes",new Date(0), null,Role.InscriptionService,passwordEncoder.encode("inscriptionService")); mockUsers = new ArrayList<>(Arrays.asList(herobrine,joe,meh,joke));
mockUsers = new ArrayList<>(Arrays.asList(herobrine,joe,meh,joke,lena,jojo));
userRepo.saveAll(mockUsers); userRepo.saveAll(mockUsers);
// Course / Curriculum part // Course / Curriculum part
Curriculum infoBab1 = new Curriculum(1,"info"); Curriculum infoBab1 = new Curriculum(1,"info");
@ -70,7 +68,7 @@ public class MockController {
curriculumService.save(psychologyBab1); curriculumService.save(psychologyBab1);
Course progra1 = new Course(5,"Programmation et algorithmique 1",joke); Course progra1 = new Course(5,"Programmation et algorithimque 1",joke);
Course chemistry1 = new Course(12, "Thermochimie",joke); Course chemistry1 = new Course(12, "Thermochimie",joke);
Course psycho1 = new Course(21, "rien faire t'as cru c'est psycho",joke); Course psycho1 = new Course(21, "rien faire t'as cru c'est psycho",joke);
Course commun = new Course(2, "cours commun",joke); Course commun = new Course(2, "cours commun",joke);
@ -92,10 +90,15 @@ public class MockController {
CurriculumCourseService.save(new CurriculumCourse(chemistryBab1,chemistry1)); CurriculumCourseService.save(new CurriculumCourse(chemistryBab1,chemistry1));
InscriptionRequest inscriptionRequest = new InscriptionRequest("helen","prenom","non","helen@gmail.com","america",new Date(),(long) 1,RequestState.Pending,"yes.png","password");
inscriptionService.save(inscriptionRequest); }
@DeleteMapping("/mock")
public void deleteMock(){
for (User user:mockUsers){
tokenRepo.deleteAll(tokenRepo.getByUser(user));
}
userRepo.deleteAll(mockUsers);
} }
} }

View File

@ -11,6 +11,7 @@ import ovh.herisson.Clyde.Tables.StorageFile;
@RestController @RestController
@CrossOrigin(originPatterns = "*", allowCredentials = "true") @CrossOrigin(originPatterns = "*", allowCredentials = "true")
public class StorageController { public class StorageController {
private final StorageService storageServ; private final StorageService storageServ;
public StorageController(StorageService storageServ){ public StorageController(StorageService storageServ){
@ -21,13 +22,12 @@ public class StorageController {
@PostMapping("/upload/{fileType}") @PostMapping("/upload/{fileType}")
public ResponseEntity<StorageFile> handleFileUpload(@RequestParam("file") MultipartFile file, @PathVariable FileType fileType) { public ResponseEntity<StorageFile> handleFileUpload(@RequestParam("file") MultipartFile file, @PathVariable FileType fileType) {
StorageFile fileEntry; StorageFile fileEntry = null;
try { try {
fileEntry = storageServ.store(file,fileType); fileEntry = storageServ.store(file,fileType);
} catch(Exception e){ } catch(Exception e){
e.printStackTrace(); e.printStackTrace();
return new ResponseEntity<>(null,HttpStatus.BAD_REQUEST);
} }

View File

@ -1,15 +1,11 @@
package ovh.herisson.Clyde.EndPoints; package ovh.herisson.Clyde.EndPoints;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.CrossOrigin; import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;
import ovh.herisson.Clyde.Responses.UnauthorizedResponse;
import ovh.herisson.Clyde.Services.AuthenticatorService;
import ovh.herisson.Clyde.Services.TokenService; import ovh.herisson.Clyde.Services.TokenService;
import ovh.herisson.Clyde.Tables.Role;
import ovh.herisson.Clyde.Tables.Token; import ovh.herisson.Clyde.Tables.Token;
@RestController @RestController
@ -18,20 +14,13 @@ public class TokenController {
private final TokenService tokenServ; private final TokenService tokenServ;
private final AuthenticatorService authServ; public TokenController(TokenService tokenServ){
public TokenController(TokenService tokenServ, AuthenticatorService authServ){
this.tokenServ = tokenServ; this.tokenServ = tokenServ;
this.authServ = authServ;
} }
@GetMapping("/tokens") @GetMapping("/tokens")
public ResponseEntity<Iterable<Token>> getTokens(@RequestHeader("Authorization")String token){ public Iterable<Token> getTokens(){
return tokenServ.getAllTokens();
if (authServ.isNotIn(new Role[]{Role.Admin},token))
return new UnauthorizedResponse<>(null);
return new ResponseEntity<>(tokenServ.getAllTokens(), HttpStatus.OK);
} }
} }

View File

@ -1,15 +1,14 @@
package ovh.herisson.Clyde.EndPoints; package ovh.herisson.Clyde.EndPoints;
import org.springframework.http.HttpStatus; import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity; import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import ovh.herisson.Clyde.Responses.UnauthorizedResponse; import ovh.herisson.Clyde.Responses.UnauthorizedResponse;
import ovh.herisson.Clyde.Services.AuthenticatorService; import ovh.herisson.Clyde.Services.AuthenticatorService;
import ovh.herisson.Clyde.Services.ProtectionService;
import ovh.herisson.Clyde.Services.UserService; import ovh.herisson.Clyde.Services.UserService;
import ovh.herisson.Clyde.Tables.Role; import ovh.herisson.Clyde.Tables.Role;
import ovh.herisson.Clyde.Tables.User; import ovh.herisson.Clyde.Tables.User;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
@ -26,114 +25,67 @@ public class UserController {
this.authServ = authServ; this.authServ = authServ;
} }
/** returns information about the connected user
*
* @param token the session token of the user
* @return the user information except his password
*/
@GetMapping("/user") @GetMapping("/user")
public ResponseEntity<HashMap<String,Object>> getUser(@RequestHeader("Authorization") String token){ public ResponseEntity<HashMap<String,Object>> getUser(@RequestHeader("Authorization") String authorization){
User user = authServ.getUserFromToken(token); if (authorization == null) return new UnauthorizedResponse<>(null);
User user = authServ.getUserFromToken(authorization);
if (user == null) return new UnauthorizedResponse<>(null); if (user == null) return new UnauthorizedResponse<>(null);
return new ResponseEntity<>(ProtectionService.userWithoutPassword(user), HttpStatus.OK); return new ResponseEntity<>(userWithoutPassword(user), HttpStatus.OK);
}
@GetMapping("/user/{id}")
public ResponseEntity<HashMap<String ,Object>> getUserById(@RequestHeader("Authorization") String token, @PathVariable Long id){
if (authServ.isNotIn(new Role[]{Role.Admin,Role.Secretary,Role.InscriptionService},token))
return new UnauthorizedResponse<>(null);
return new ResponseEntity<>(ProtectionService.userWithoutPassword(userService.getUserById(id)), HttpStatus.OK);
} }
@PostMapping("/user") @PostMapping("/user")
public ResponseEntity<Map<String ,Object>> postUser(@RequestBody User user,@RequestHeader("Authorization") String token){ public ResponseEntity<String> postUser(@RequestBody User user,@RequestHeader("Authorization") String authorization){
if (authServ.isNotIn(new Role[]{Role.Admin,Role.InscriptionService,Role.Secretary},token)) if (authServ.isNotSecretaryOrAdmin(authorization))
return new UnauthorizedResponse<>(null); return new UnauthorizedResponse<>(null);
return new ResponseEntity<>(ProtectionService.userWithoutPassword(userService.save(user)),HttpStatus.CREATED); userService.save(user);
return new ResponseEntity<>(String.format("Account created with ID:%s",user.getRegNo()),HttpStatus.CREATED);
} }
@GetMapping("/users") @GetMapping("/users")
public ResponseEntity<Iterable<HashMap<String,Object>>> getAllUsers(@RequestHeader("Authorization") String token){ public ResponseEntity<Iterable<HashMap<String,Object>>> getAllUsers(@RequestHeader("Authorization") String authorization){
if (authServ.isNotIn(new Role[]{Role.Admin,Role.Secretary},token)) if (authServ.isNotSecretaryOrAdmin(authorization))
return new UnauthorizedResponse<>(null); return new UnauthorizedResponse<>(null);
Role posterRole = authServ.getUserFromToken(token).getRole(); Iterable<User> users = userService.getAll();
ArrayList<HashMap<String, Object>> withoutPassword = new ArrayList<>();
Iterable<User> users = new ArrayList<>(); for (User u :users){
withoutPassword.add(userWithoutPassword(u));
if (posterRole == Role.Admin)
users = userService.getAll();
else if (posterRole == Role.Secretary)
users = userService.getAllExceptAdmins();
return new ResponseEntity<>(ProtectionService.usersWithoutPasswords(users), HttpStatus.OK);
} }
return new ResponseEntity<>(withoutPassword, HttpStatus.OK);
}
@PatchMapping("/user")
public ResponseEntity<String> patchUser(@RequestBody Map<String,Object> updates, @RequestHeader("Authorization") String authorization) {
/** changes the specified user's information if (authorization == null) return new UnauthorizedResponse<>(null);
*
* @param updates the changes to be made
* @param token the session token of the user posting the change
* @param id the id of the user to change
* @return a string clarifying the issue (if there is any)
*/
@PatchMapping("/user/{id}")
public ResponseEntity<String> patchUser(@RequestHeader("Authorization") String token,
@RequestBody Map<String,Object> updates,
@PathVariable Long id) {
if (token == null) return new UnauthorizedResponse<>(null); User poster = authServ.getUserFromToken(authorization);
if (poster == null) {return new UnauthorizedResponse<>("bad authorization");}
User poster = authServ.getUserFromToken(token); if (!userService.modifyData(poster, updates, poster))
if (poster == null) {return new UnauthorizedResponse<>("bad token");}
if (!userService.modifyData(id, updates, poster))
return new UnauthorizedResponse<>("there was an issue with the updates requested"); return new UnauthorizedResponse<>("there was an issue with the updates requested");
return new ResponseEntity<>(null, HttpStatus.OK); return new ResponseEntity<>("data modified", HttpStatus.OK);
} }
/** return user's data except password
@GetMapping("/teachers") * @param user the user to return
public ResponseEntity<Iterable<HashMap<String,Object>>> getAllTeachers(@RequestHeader("Authorization") String token){ * @return all the user data without the password
if (authServ.getUserFromToken(token) == null) */
return new UnauthorizedResponse<>(null); private HashMap<String,Object> userWithoutPassword(User user){
HashMap<String,Object> toReturn = new HashMap<>();
Iterable<User> teachers = userService.getAllTeachers(); toReturn.put("regNo",user.getRegNo());
toReturn.put("firstName",user.getFirstName());
return new ResponseEntity<>(ProtectionService.usersWithoutPasswords(teachers), HttpStatus.OK); toReturn.put("lastName",user.getLastName());
} toReturn.put("birthDate",user.getBirthDate());
toReturn.put("country",user.getCountry());
toReturn.put("address",user.getAddress());
@GetMapping("/students") toReturn.put("role",user.getRole());
public ResponseEntity<Iterable<HashMap<String,Object>>> getAllStudent(@RequestHeader("Authorization") String token){ return toReturn;
if (authServ.getUserFromToken(token) == null)
return new UnauthorizedResponse<>(null);
Iterable<User> students = userService.getAllStudents();
return new ResponseEntity<>(ProtectionService.usersWithoutPasswords(students), HttpStatus.OK);
}
@DeleteMapping("/user/{id}")
public ResponseEntity<String> deleteStudent(@RequestHeader("Authorization") String token, @PathVariable Long id){
if (authServ.isNotIn(new Role[]{Role.Admin,Role.Secretary},token) && !id.equals(authServ.getUserFromToken(token).getRegNo()))
return new UnauthorizedResponse<>(null);
User toDelete = userService.getUserById(id);
if (toDelete == null)
return new ResponseEntity<>(HttpStatus.BAD_REQUEST);
userService.delete(toDelete);
return new ResponseEntity<>(HttpStatus.OK);
} }
} }

View File

@ -17,7 +17,7 @@ public class JdbcConfig {
public DataSource psqlSource(){ public DataSource psqlSource(){
DriverManagerDataSource source = new DriverManagerDataSource(); DriverManagerDataSource source = new DriverManagerDataSource();
source.setDriverClassName("org.postgresql.Driver"); source.setDriverClassName("org.postgresql.Driver");
source.setUrl("jdbc:postgresql://localhost:5442/clyde"); source.setUrl("jdbc:postgresql://localhost:5432/clyde");
source.setUsername("devel"); source.setUsername("devel");
source.setPassword("devel"); source.setPassword("devel");

View File

@ -1,15 +1,8 @@
package ovh.herisson.Clyde.Repositories; package ovh.herisson.Clyde.Repositories;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.CrudRepository; import org.springframework.data.repository.CrudRepository;
import ovh.herisson.Clyde.Tables.Course; import ovh.herisson.Clyde.Tables.Course;
import ovh.herisson.Clyde.Tables.User;
public interface CourseRepository extends CrudRepository<Course,Long> { public interface CourseRepository extends CrudRepository<Course,Long> {
Course findById(long id); Course findById(long id);
@Query("select c from Course c where c.owner = ?1")
Iterable<Course> findAllOwnedCoures(User teacher);
} }

View File

@ -1,14 +1,9 @@
package ovh.herisson.Clyde.Repositories; package ovh.herisson.Clyde.Repositories;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.CrudRepository; import org.springframework.data.repository.CrudRepository;
import ovh.herisson.Clyde.Tables.StorageFile; import ovh.herisson.Clyde.Tables.StorageFile;
import java.util.ArrayList;
public interface FileRepository extends CrudRepository<StorageFile,Long> { public interface FileRepository extends CrudRepository<StorageFile,Long> {
public StorageFile getStorageFileByName(String name);
} }

View File

@ -1,14 +1,8 @@
package ovh.herisson.Clyde.Repositories; package ovh.herisson.Clyde.Repositories;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.CrudRepository; import org.springframework.data.repository.CrudRepository;
import ovh.herisson.Clyde.Tables.Course;
import ovh.herisson.Clyde.Tables.TeacherCourse; import ovh.herisson.Clyde.Tables.TeacherCourse;
import ovh.herisson.Clyde.Tables.User;
public interface TeacherCourseRepository extends CrudRepository<TeacherCourse, Long> { public interface TeacherCourseRepository extends CrudRepository<TeacherCourse, Long> {
@Query("select tc.user from TeacherCourse tc where tc.course = ?1")
Iterable<User> findAllAssistantOfCourse(Course course);
} }

View File

@ -10,5 +10,7 @@ public interface TokenRepository extends CrudRepository<Token,Long> {
Token getByToken(String token); Token getByToken(String token);
Iterable<Token> getByUser(User user);
ArrayList <Token> getByUserOrderByExpirationDate(User user); ArrayList <Token> getByUserOrderByExpirationDate(User user);
} }

View File

@ -1,13 +0,0 @@
package ovh.herisson.Clyde.Repositories;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.CrudRepository;
import ovh.herisson.Clyde.Tables.Curriculum;
import ovh.herisson.Clyde.Tables.User;
import ovh.herisson.Clyde.Tables.UserCurriculum;
public interface UserCurriculumRepository extends CrudRepository<UserCurriculum, Long> {
@Query("select uc.curriculum from UserCurriculum uc where uc.user = ?1")
Curriculum findByUser(User student);
}

View File

@ -4,20 +4,15 @@ import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.CrudRepository; import org.springframework.data.repository.CrudRepository;
import ovh.herisson.Clyde.Tables.User; import ovh.herisson.Clyde.Tables.User;
import java.util.List;
public interface UserRepository extends CrudRepository<User, Long> { public interface UserRepository extends CrudRepository<User, Long> {
User findById(long id); User findById(long id);
User findByEmail(String email); User findByEmail(String email);
/**
@Query(value = "select a.* from Users a ",nativeQuery = true)
@Query("select u from User u where u.role = ovh.herisson.Clyde.Tables.Role.Teacher") Iterable<User> findAllUsers();**/
Iterable<User> findAllTeachers();
@Query("select u from User u where u.role = ovh.herisson.Clyde.Tables.Role.Student")
Iterable<User> findAllStudents();
@Query("select u from User u where u.role <> ovh.herisson.Clyde.Tables.Role.Admin")
Iterable<User> findAllExceptAdmins();
} }

View File

@ -1,7 +1,11 @@
package ovh.herisson.Clyde.Services; package ovh.herisson.Clyde.Services;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import ovh.herisson.Clyde.Tables.*; import ovh.herisson.Clyde.Tables.InscriptionRequest;
import ovh.herisson.Clyde.Tables.Role;
import ovh.herisson.Clyde.Tables.Token;
import ovh.herisson.Clyde.Tables.User;
import java.util.Date; import java.util.Date;
@Service @Service
@ -31,12 +35,22 @@ public class AuthenticatorService {
return token; return token;
} }
public InscriptionRequest register(InscriptionRequest inscriptionRequest) { public void register(InscriptionRequest inscriptionRequest) {
inscriptionRequest.setState(RequestState.Pending); inscriptionService.save(inscriptionRequest);
return inscriptionService.save(inscriptionRequest);
} }
public boolean isNotIn(Role[] roles, String token){
public boolean isNotSecretaryOrAdmin(String authorization){
if (authorization ==null)
return true;
User poster = getUserFromToken(authorization);
if (poster == null) return true;
return poster.getRole() != Role.Secretary || poster.getRole() != Role.Admin;
}
public boolean IsNotIn(Role[] roles, String token){
if (token == null) if (token == null)
return true; return true;

View File

@ -5,6 +5,7 @@ import ovh.herisson.Clyde.Repositories.CourseRepository;
import ovh.herisson.Clyde.Tables.Course; import ovh.herisson.Clyde.Tables.Course;
import ovh.herisson.Clyde.Tables.Role; import ovh.herisson.Clyde.Tables.Role;
import ovh.herisson.Clyde.Tables.User; import ovh.herisson.Clyde.Tables.User;
import java.util.Map; import java.util.Map;
@Service @Service
@ -17,8 +18,6 @@ public class CourseService {
} }
public Course save(Course course){ public Course save(Course course){
if (course.getOwner().getRole() != Role.Teacher)
return null;
return courseRepo.save(course); return courseRepo.save(course);
} }
@ -26,37 +25,18 @@ public class CourseService {
return courseRepo.findById(id); return courseRepo.findById(id);
} }
public Course modifyData(long id, Map<String, Object> updates, Role role) {
public Iterable<Course> findAll() {
return courseRepo.findAll();
}
public Iterable<Course> findOwnedCourses(User userFromToken) {
return courseRepo.findAllOwnedCoures(userFromToken);
}
public boolean modifyData(long id, Map<String, Object> updates, Role role) {
Course target = courseRepo.findById(id); Course target = courseRepo.findById(id);
if (target == null)
return false;
if (role == Role.Teacher){ if (role == Role.Teacher){
for (Map.Entry<String, Object> entry : updates.entrySet()){ for (Map.Entry<String, Object> entry : updates.entrySet()){
if (entry.getKey().equals("title")){ if (entry.getKey().equals("title")){
target.setTitle((String) entry.getValue()); target.setTitle((String) entry.getValue());
courseRepo.save(target); return courseRepo.save(target);
return true;
} }
} }
} }
if (role != Role.Secretary)
return false;
for (Map.Entry<String ,Object> entry: updates.entrySet()){ for (Map.Entry<String ,Object> entry: updates.entrySet()){
switch (entry.getKey()){ switch (entry.getKey()){
case "title": case "title":
@ -66,18 +46,10 @@ public class CourseService {
target.setCredits((Integer) entry.getValue()); target.setCredits((Integer) entry.getValue());
break; break;
case "owner": case "owner":
if (((User) entry.getValue() ).getRole() != Role.Teacher) target.setOwner((User) entry.getValue()); //todo check if is a teacher !
break;
target.setOwner((User) entry.getValue());
break; break;
} }
} }
courseRepo.save(target); return courseRepo.save(target);
return true;
}
public void delete(Course course) {
courseRepo.delete(course);
} }
} }

View File

@ -4,7 +4,9 @@ import org.springframework.stereotype.Service;
import ovh.herisson.Clyde.Repositories.CourseRepository; import ovh.herisson.Clyde.Repositories.CourseRepository;
import ovh.herisson.Clyde.Repositories.CurriculumCourseRepository; import ovh.herisson.Clyde.Repositories.CurriculumCourseRepository;
import ovh.herisson.Clyde.Repositories.CurriculumRepository; import ovh.herisson.Clyde.Repositories.CurriculumRepository;
import ovh.herisson.Clyde.Tables.*; import ovh.herisson.Clyde.Tables.Course;
import ovh.herisson.Clyde.Tables.Curriculum;
import ovh.herisson.Clyde.Tables.CurriculumCourse;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
@ -29,18 +31,17 @@ public class CurriculumCourseService {
curriculumCourseRepo.save(curriculumCourse); curriculumCourseRepo.save(curriculumCourse);
} }
public Iterable<CurriculumCourse> findAll(){
return curriculumCourseRepo.findAll();
}
public Map<String, Object> getDepthCurriculum(Curriculum curriculum){ public Map<String, Object> getDepthCurriculum(Curriculum curriculum){
if (curriculum == null)
return null;
HashMap<String ,Object> toReturn = new HashMap<>(); HashMap<String ,Object> toReturn = new HashMap<>();
ArrayList<Map<String ,Object>> courses = new ArrayList<>(); ArrayList<Course> courses = new ArrayList<>();
Iterable<Course> foundCourses = curriculumCourseRepo.findCoursesByCurriculum(curriculum); for (Course c: curriculumCourseRepo.findCoursesByCurriculum(curriculum)){
courses.add(c);
for (Course c: foundCourses){
courses.add(ProtectionService.courseWithoutPassword(c));
} }
toReturn.put("courses",courses); toReturn.put("courses",courses);
toReturn.put("curriculumId", curriculum.getCurriculumId()); toReturn.put("curriculumId", curriculum.getCurriculumId());
@ -55,39 +56,13 @@ public class CurriculumCourseService {
ArrayList<Map<String,Object>> toReturn = new ArrayList<>(); ArrayList<Map<String,Object>> toReturn = new ArrayList<>();
for (Curriculum curriculum : curriculumRepo.findAll()){ for (Curriculum curriculum : curriculumCourseRepo.findDistinctCurriculums()){
toReturn.add(getDepthCurriculum(curriculum)); toReturn.add(getDepthCurriculum(curriculum));
} }
return toReturn; return toReturn;
} }
/** tries to add all courses to the curriculum
*
* @param coursesIds the ids of the courses to be added
* @param curriculum the curriculum to add the courses to
* @return if the changes were made
*/
public boolean saveAll(Iterable<Long> coursesIds, Curriculum curriculum) {
if (curriculum == null || coursesIds == null)
return false;
ArrayList<Course> toAdd = new ArrayList<>();
for (Long courseId : coursesIds){
Course course = courseRepo.findById((long) courseId);
if (course == null)
return false;
if (!toAdd.contains(course))
toAdd.add(course);
}
for (Course course : toAdd){
curriculumCourseRepo.save(new CurriculumCourse(curriculum,course));
}
return true;
}
} }

View File

@ -1,6 +1,7 @@
package ovh.herisson.Clyde.Services; package ovh.herisson.Clyde.Services;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import ovh.herisson.Clyde.Repositories.CourseRepository;
import ovh.herisson.Clyde.Repositories.CurriculumRepository; import ovh.herisson.Clyde.Repositories.CurriculumRepository;
import ovh.herisson.Clyde.Tables.Curriculum; import ovh.herisson.Clyde.Tables.Curriculum;
@ -9,17 +10,23 @@ public class CurriculumService {
private final CurriculumRepository curriculumRepo; private final CurriculumRepository curriculumRepo;
public CurriculumService(CurriculumRepository curriculumRepo){ private final CourseRepository courseRepo;
public CurriculumService(CurriculumRepository curriculumRepo, CourseRepository courseRepo){
this.curriculumRepo = curriculumRepo; this.curriculumRepo = curriculumRepo;
this.courseRepo = courseRepo;
} }
public Curriculum save(Curriculum curriculum){
return curriculumRepo.save(curriculum);
public void save(Curriculum curriculum){
curriculumRepo.save(curriculum);
} }
public Curriculum findById(long id){ public Curriculum findById(long id){
return curriculumRepo.findById(id); return curriculumRepo.findById(id);
} }
public void delete(Curriculum curriculum) { public Iterable<Curriculum> findAll(){
curriculumRepo.delete(curriculum); return curriculumRepo.findAll();
} }
} }

View File

@ -1,40 +1,21 @@
package ovh.herisson.Clyde.Services; package ovh.herisson.Clyde.Services;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import ovh.herisson.Clyde.Repositories.CurriculumRepository;
import ovh.herisson.Clyde.Repositories.InscriptionRepository; import ovh.herisson.Clyde.Repositories.InscriptionRepository;
import ovh.herisson.Clyde.Repositories.UserCurriculumRepository;
import ovh.herisson.Clyde.Repositories.UserRepository;
import ovh.herisson.Clyde.Tables.InscriptionRequest; import ovh.herisson.Clyde.Tables.InscriptionRequest;
import ovh.herisson.Clyde.Tables.RequestState; import ovh.herisson.Clyde.Tables.RequestState;
import ovh.herisson.Clyde.Tables.User;
import ovh.herisson.Clyde.Tables.UserCurriculum;
@Service @Service
public class InscriptionService { public class InscriptionService {
private final InscriptionRepository inscriptionRepo; InscriptionRepository inscriptionRepo;
private final UserRepository userRepo; public InscriptionService(InscriptionRepository inscriptionRepo){
private final UserCurriculumRepository userCurriculumRepo;
private final CurriculumRepository curriculumRepo;
private final BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
public InscriptionService(InscriptionRepository inscriptionRepo, UserRepository userRepo, UserCurriculumRepository userCurriculumRepo, CurriculumRepository curriculumRepo){
this.inscriptionRepo = inscriptionRepo; this.inscriptionRepo = inscriptionRepo;
this.userRepo = userRepo;
this.userCurriculumRepo = userCurriculumRepo;
this.curriculumRepo = curriculumRepo;
} }
public InscriptionRequest save(InscriptionRequest inscriptionRequest){ public void save(InscriptionRequest inscriptionRequest){
inscriptionRequest.setPassword(passwordEncoder.encode(inscriptionRequest.getPassword())); inscriptionRepo.save(inscriptionRequest);
return inscriptionRepo.save(inscriptionRequest);
} }
public InscriptionRequest getById(long id){ public InscriptionRequest getById(long id){
@ -45,50 +26,9 @@ public class InscriptionService {
return inscriptionRepo.findAll(); return inscriptionRepo.findAll();
} }
public boolean modifyState(long id, RequestState requestState) { public void modifyState(long id, RequestState requestState) {
InscriptionRequest inscrRequest = getById(id); InscriptionRequest inscriptionRequest = getById(id);
inscriptionRequest.setState(requestState);
if (inscrRequest == null) save(inscriptionRequest);
return false;
// if th state is the same we don't send an email
if (requestState == inscrRequest.getState())
return false;
/** todo send an email to tell the poster of the inscrRequest (inscrRequest.getEmail())
* to notify them that the state of their request changed
* FooEmailFormat toSend = (String.format("Your request state changed from %s to %s"),
* inscrRequest.getState(), requestState)
* FooEmailSender.send(toSend, inscrRequest.getEmail())
*/
//saves the user from the request if accepted
if (requestState == RequestState.Accepted)
{
if (curriculumRepo.findById(inscrRequest.getCurriculumId()) == null)
return false;
User userFromRequest = new User(
inscrRequest.getLastName(),
inscrRequest.getFirstName(),
inscrRequest.getEmail(),
inscrRequest.getAddress(),
inscrRequest.getCountry(),
inscrRequest.getBirthDate(),
inscrRequest.getProfilePicture(),
inscrRequest.getPassword()
);
userRepo.save(userFromRequest);
userCurriculumRepo.save(new UserCurriculum(userFromRequest, curriculumRepo.findById(inscrRequest.getCurriculumId())));
}
inscrRequest.setState(requestState);
save(inscrRequest);
return true;
}
public void delete(InscriptionRequest toDelete) {
inscriptionRepo.delete(toDelete);
} }
} }

View File

@ -1,105 +0,0 @@
package ovh.herisson.Clyde.Services;
import ovh.herisson.Clyde.Tables.Course;
import ovh.herisson.Clyde.Tables.InscriptionRequest;
import ovh.herisson.Clyde.Tables.User;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
public class ProtectionService {
/** return user's data except password
* @param user the user to return
* @return all the user data without the password
*/
public static HashMap<String,Object> userWithoutPassword(User user){
if (user ==null)
return null;
HashMap<String,Object> toReturn = new HashMap<>();
toReturn.put("regNo",user.getRegNo());
toReturn.put("lastName",user.getLastName());
toReturn.put("firstName",user.getFirstName());
toReturn.put("email", user.getEmail());
toReturn.put("address",user.getAddress());
toReturn.put("birthDate",user.getBirthDate());
toReturn.put("country",user.getCountry());
toReturn.put("profilePictureUrl",user.getProfilePictureUrl());
toReturn.put("role",user.getRole());
return toReturn;
}
public static Iterable<HashMap<String ,Object>>usersWithoutPasswords(Iterable<User> users){
ArrayList<HashMap<String,Object>> toReturn = new ArrayList<>();
for (User u : users){
toReturn.add(userWithoutPassword(u));
}
return toReturn;
}
public static HashMap<String,Object> courseWithoutPassword(Course course){
if (course == null)
return null;
HashMap<String ,Object> toReturn = new HashMap<>();
toReturn.put("courseId",course.getCourseID());
toReturn.put("credits",course.getCredits());
toReturn.put("title", course.getTitle());
toReturn.put("owner", userWithoutPassword(course.getOwner()));
return toReturn;
}
public static Iterable<HashMap<String ,Object>> coursesWithoutPasswords(Iterable<Course> courses){
ArrayList<HashMap<String,Object>> toReturn = new ArrayList<>();
for (Course course: courses){
toReturn.add(ProtectionService.courseWithoutPassword(course));
}
return toReturn;
}
public static Map<String, Object> requestWithoutPassword(InscriptionRequest inscriptionRequest) {
if (inscriptionRequest == null)
return null;
Map<String, Object> toReturn = new HashMap<>();
toReturn.put("id", inscriptionRequest.getId());
toReturn.put("lastName", inscriptionRequest.getLastName());
toReturn.put("firstName", inscriptionRequest.getFirstName());
toReturn.put("address", inscriptionRequest.getAddress());
toReturn.put("email",inscriptionRequest.getEmail());
toReturn.put("birthDate", inscriptionRequest.getBirthDate());
toReturn.put("country", inscriptionRequest.getCountry());
toReturn.put("curriculum", inscriptionRequest.getCurriculumId());
toReturn.put("state", inscriptionRequest.getState());
toReturn.put("profilePictureUrl", inscriptionRequest.getProfilePicture());
return toReturn;
}
public static Iterable<Map<String ,Object>> requestsWithoutPasswords(Iterable<InscriptionRequest> inscriptionRequests){
ArrayList<Map<String,Object>> toReturn = new ArrayList<>();
for (InscriptionRequest i:inscriptionRequests){
toReturn.add(requestWithoutPassword(i));
}
return toReturn;
}
}

View File

@ -15,6 +15,8 @@ import java.util.UUID;
@Service @Service
public class StorageService { public class StorageService {
private final Path rootLocation = Paths.get("cdn/"); private final Path rootLocation = Paths.get("cdn/");
private final FileRepository fileRepo; private final FileRepository fileRepo;
@ -33,9 +35,6 @@ public class StorageService {
public StorageFile store(MultipartFile file, FileType fileType) { public StorageFile store(MultipartFile file, FileType fileType) {
if (file == null || file.getOriginalFilename() == null)
return null;
if (file.getOriginalFilename().isEmpty()){return null;} if (file.getOriginalFilename().isEmpty()){return null;}
UUID uuid = UUID.randomUUID(); UUID uuid = UUID.randomUUID();
@ -56,7 +55,7 @@ public class StorageService {
String url = this.rootLocation.resolve(Paths.get(Objects.requireNonNull(stringUuid))) String url = this.rootLocation.resolve(Paths.get(Objects.requireNonNull(stringUuid)))
.normalize().toString(); .normalize().toString();
return fileRepo.save(new StorageFile(file.getOriginalFilename(),url, fileType)); return fileRepo.save(new StorageFile(file.getName(),url, fileType));
} }
public void delete(StorageFile file) throws SecurityException { public void delete(StorageFile file) throws SecurityException {

View File

@ -4,7 +4,6 @@ import org.springframework.stereotype.Controller;
import ovh.herisson.Clyde.Repositories.TeacherCourseRepository; import ovh.herisson.Clyde.Repositories.TeacherCourseRepository;
import ovh.herisson.Clyde.Repositories.UserRepository; import ovh.herisson.Clyde.Repositories.UserRepository;
import ovh.herisson.Clyde.Tables.Course; import ovh.herisson.Clyde.Tables.Course;
import ovh.herisson.Clyde.Tables.Role;
import ovh.herisson.Clyde.Tables.TeacherCourse; import ovh.herisson.Clyde.Tables.TeacherCourse;
import ovh.herisson.Clyde.Tables.User; import ovh.herisson.Clyde.Tables.User;
@ -21,33 +20,20 @@ public class TeacherCourseService {
this.userRepo = userRepo; this.userRepo = userRepo;
} }
public Iterable<User> findCourseAssistants(Course course) {
if (course == null)
return null;
return teacherCourseRepo.findAllAssistantOfCourse(course);
}
public boolean saveAll(Iterable<Long> teacherIds, Course course){ public boolean saveAll(Iterable<Long> teacherIds, Course course){
if (course == null || teacherIds == null) ArrayList<Long> addedIds = new ArrayList<>();
return false;
ArrayList<User> toAdd = new ArrayList<>();
for (Long teacherId : teacherIds){ for (Long teacherId : teacherIds){
User teacher = userRepo.findById((long) teacherId); User teacher = userRepo.findById((long) teacherId);
if ( teacher== null){ if ( teacher== null){
return false; return false;
} }
if (!toAdd.contains(teacher) && teacher.getRole() == Role.Teacher) if (!addedIds.contains(teacherId))
{ {
toAdd.add(teacher);
}
}
for (User teacher: toAdd){
teacherCourseRepo.save(new TeacherCourse(teacher,course)); teacherCourseRepo.save(new TeacherCourse(teacher,course));
addedIds.add(teacherId);
}
} }
return true; return true;
} }
} }

View File

@ -40,19 +40,16 @@ public class TokenService {
public User getUserFromToken(String token) { public User getUserFromToken(String token) {
Token tokenRep = tokenRepo.getByToken(token); Token tokenRep = tokenRepo.getByToken(token);
if (tokenRep == null) if (tokenRep == null) return null;
return null;
return tokenRep.getUser(); return tokenRep.getUser();
} }
public void saveToken(Token token){ public void saveToken(Token token){
//Si l'utilisateur a déja 5 token delete celui qui devait expirer le plus vite //Si l'utilisateur a déja 5 token delete celui qui devait expirer le plus vite
ArrayList<Token> tokenList = tokenRepo.getByUserOrderByExpirationDate(token.getUser()); ArrayList<Token> tokenList = tokenRepo.getByUserOrderByExpirationDate(token.getUser());
while(tokenList.size() >= 5){ while(tokenList.size() >= 5){
tokenRepo.delete(tokenList.getFirst()); tokenRepo.delete(tokenList.get(0));
tokenList.remove(tokenList.getFirst()); tokenList.remove(tokenList.get(0));
} }
tokenRepo.save(token); tokenRepo.save(token);
} }
@ -70,5 +67,5 @@ public class TokenService {
tokenRepo.delete(t); tokenRepo.delete(t);
} }
} }
} };
} }

View File

@ -1,20 +0,0 @@
package ovh.herisson.Clyde.Services;
import org.springframework.stereotype.Service;
import ovh.herisson.Clyde.Repositories.UserCurriculumRepository;
import ovh.herisson.Clyde.Tables.Curriculum;
import ovh.herisson.Clyde.Tables.User;
@Service
public class UserCurriculumService {
private final UserCurriculumRepository userCurriculumRepository;
public UserCurriculumService(UserCurriculumRepository userCurriculumRepository) {
this.userCurriculumRepository = userCurriculumRepository;
}
public Curriculum findByUser(User student){
return userCurriculumRepository.findByUser(student);
}
}

View File

@ -17,15 +17,8 @@ public class UserService {
} }
/** return the user identified by th identifier
*
* @param identifier can be an email or the RegNo
* @return the identified user
*/
public User getUser(String identifier){ public User getUser(String identifier){
if (identifier == null) if (identifier == null) return null;
return null;
try { try {
int id = Integer.parseInt(identifier); int id = Integer.parseInt(identifier);
return userRepo.findById(id); return userRepo.findById(id);
@ -40,18 +33,16 @@ public class UserService {
* *
* @param poster the user wanting to modify target's data * @param poster the user wanting to modify target's data
* @param updates the changes to be made * @param updates the changes to be made
* @param targetId the id of the user to update * @param target the user to update
* @return if the changes were done or not * @return if the changes were done or not
*/ */
public boolean modifyData(long targetId, Map<String ,Object> updates, User poster){ public boolean modifyData(User poster, Map<String ,Object> updates, User target){
User target = userRepo.findById(targetId);
if (target == null)
return false;
if (poster.getRegNo().equals(target.getRegNo())){ if (poster.getRegNo().equals(target.getRegNo())){
for (Map.Entry<String, Object> entry : updates.entrySet()){ for (Map.Entry<String, Object> entry : updates.entrySet()){
if ( entry.getKey().equals("regNo") || entry.getKey().equals("role")) {return false;}
switch (entry.getKey()){ switch (entry.getKey()){
case "firstName": case "firstName":
target.setFirstName((String) entry.getValue()); target.setFirstName((String) entry.getValue());
@ -87,7 +78,7 @@ public class UserService {
{ {
for (Map.Entry<String, Object> entry : updates.entrySet()){ for (Map.Entry<String, Object> entry : updates.entrySet()){
if ( entry.getKey().equals("role")) { if ( !entry.getKey().equals("role")) {return false;}
if (entry.getValue() == Role.Admin){return false;} if (entry.getValue() == Role.Admin){return false;}
@ -96,7 +87,6 @@ public class UserService {
return true; return true;
} }
} }
}
return false; return false;
} }
@ -105,30 +95,12 @@ public class UserService {
return passwordEncoder.matches(tryingPassword, user.getPassword()); return passwordEncoder.matches(tryingPassword, user.getPassword());
} }
public User save(User user){ public void save(User user){
user.setPassword(passwordEncoder.encode(user.getPassword())); user.setPassword(passwordEncoder.encode(user.getPassword()));
return userRepo.save(user); userRepo.save(user);
} }
public Iterable<User> getAll(){ public Iterable<User> getAll(){
return userRepo.findAll(); return userRepo.findAll();
} }
public Iterable<User> getAllExceptAdmins(){
return userRepo.findAllExceptAdmins();
}
public Iterable<User> getAllTeachers (){return userRepo.findAllTeachers();}
public Iterable<User> getAllStudents(){return userRepo.findAllStudents();}
public User getUserById(long id) {
return userRepo.findById(id);
}
public void delete(User user) {
userRepo.delete(user);
}
} }

View File

@ -15,9 +15,7 @@ public enum Applications {
// teachers and Secretary authorization // teachers and Secretary authorization
ManageCourses, ManageCourses,
UsersList,
// InscriptionService authorization // InscriptionService authorization
Inscription, Inscription
StudentsList
} }

View File

@ -1,8 +1,6 @@
package ovh.herisson.Clyde.Tables; package ovh.herisson.Clyde.Tables;
import jakarta.persistence.*; import jakarta.persistence.*;
import org.hibernate.annotations.OnDelete;
import org.hibernate.annotations.OnDeleteAction;
@Entity @Entity
public class Course { public class Course {
@ -13,7 +11,6 @@ public class Course {
private String title; private String title;
@ManyToOne(fetch = FetchType.EAGER) @ManyToOne(fetch = FetchType.EAGER)
@OnDelete(action = OnDeleteAction.SET_NULL)
@JoinColumn(name = "Users") @JoinColumn(name = "Users")
private User owner; private User owner;

View File

@ -1,8 +1,6 @@
package ovh.herisson.Clyde.Tables; package ovh.herisson.Clyde.Tables;
import jakarta.persistence.*; import jakarta.persistence.*;
import org.hibernate.annotations.OnDelete;
import org.hibernate.annotations.OnDeleteAction;
@Entity @Entity
public class CurriculumCourse { public class CurriculumCourse {
@ -12,11 +10,9 @@ public class CurriculumCourse {
@ManyToOne(fetch = FetchType.EAGER) @ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "Curriculum") @JoinColumn(name = "Curriculum")
@OnDelete(action = OnDeleteAction.CASCADE)
private Curriculum curriculum; private Curriculum curriculum;
@ManyToOne(fetch = FetchType.EAGER) @ManyToOne(fetch = FetchType.EAGER)
@OnDelete(action = OnDeleteAction.CASCADE)
@JoinColumn(name = "Course") @JoinColumn(name = "Course")
private Course course; private Course course;

View File

@ -1,6 +1,7 @@
package ovh.herisson.Clyde.Tables; package ovh.herisson.Clyde.Tables;
import jakarta.persistence.*; import jakarta.persistence.*;
import java.util.Date; import java.util.Date;
@ -16,20 +17,21 @@ public class InscriptionRequest {
private String country; private String country;
private Date birthDate; private Date birthDate;
private Long curriculumId; @ManyToOne
@JoinColumn(name="Curriculum")
private Curriculum curriculum;
private RequestState state; private RequestState state;
private String profilePicture; private String profilePicture;
private String password; private String password;
public InscriptionRequest(){} public InscriptionRequest(){}
public InscriptionRequest(String lastName, String firstName, String address, String email, String country, Date birthDate,Long curriculumId, RequestState state, String profilePicture, String password){ public InscriptionRequest(String lastName, String firstName, String address, String email, String country, Date birthDate, RequestState state, String profilePicture, String password){
this.lastName = lastName; this.lastName = lastName;
this.firstName = firstName; this.firstName = firstName;
this.address = address; this.address = address;
this.email = email; this.email = email;
this.country = country; this.country = country;
this.birthDate = birthDate; this.birthDate = birthDate;
this.curriculumId = curriculumId;
this.state = state; this.state = state;
this.profilePicture = profilePicture; this.profilePicture = profilePicture;
this.password = password; this.password = password;
@ -87,12 +89,12 @@ public class InscriptionRequest {
this.birthDate = birthDate; this.birthDate = birthDate;
} }
public long getCurriculumId() { public Curriculum getCurriculum() {
return curriculumId; return curriculum;
} }
public void setCurriculumId(long curriculum) { public void setCurriculum(Curriculum curriculum) {
this.curriculumId = curriculum; this.curriculum = curriculum;
} }
public RequestState getState() { public RequestState getState() {
@ -110,12 +112,4 @@ public class InscriptionRequest {
public void setProfilePicture(String profilePicture) { public void setProfilePicture(String profilePicture) {
this.profilePicture = profilePicture; this.profilePicture = profilePicture;
} }
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
} }

View File

@ -1,23 +1,19 @@
package ovh.herisson.Clyde.Tables; package ovh.herisson.Clyde.Tables;
import jakarta.persistence.*; import jakarta.persistence.*;
import org.hibernate.annotations.OnDelete;
import org.hibernate.annotations.OnDeleteAction;
@Entity @Entity
public class ReInscriptionRequest { public class ReinscriptionRequest {
@Id @Id
@GeneratedValue(strategy = GenerationType.AUTO) @GeneratedValue(strategy = GenerationType.AUTO)
private int id; private int id;
@ManyToOne @ManyToOne
@JoinColumn(name = "Users") @JoinColumn(name = "Users")
@OnDelete(action = OnDeleteAction.CASCADE)
private User user; private User user;
@ManyToOne @ManyToOne
@JoinColumn(name = "Curriculum") @JoinColumn(name = "Curriculum")
@OnDelete(action = OnDeleteAction.CASCADE)
private Curriculum newCurriculum; private Curriculum newCurriculum;
private RequestState state; private RequestState state;
@ -25,16 +21,16 @@ public class ReInscriptionRequest {
//Pour la réinscription on va le mettre a 0 //Pour la réinscription on va le mettre a 0
private boolean type = false; private boolean type = false;
public ReInscriptionRequest(){} public ReinscriptionRequest(){}
public ReInscriptionRequest(User user, Curriculum newCurriculum, RequestState state, boolean type){ public ReinscriptionRequest(User user, Curriculum newCurriculum, RequestState state, boolean type){
this.user = user; this.user = user;
this.newCurriculum = newCurriculum; this.newCurriculum = newCurriculum;
this.state = state; this.state = state;
this.type = type; this.type = type;
} }
public ReInscriptionRequest(User user, Curriculum newCurriculum, RequestState state){ public ReinscriptionRequest(User user, Curriculum newCurriculum, RequestState state){
this.user = user; this.user = user;
this.newCurriculum = newCurriculum; this.newCurriculum = newCurriculum;
this.state = state; this.state = state;

View File

@ -24,6 +24,7 @@ public class StorageFile {
public StorageFile(){} public StorageFile(){}
public void setId(Long id) { public void setId(Long id) {
this.id = id; this.id = id;
} }

View File

@ -1,8 +1,6 @@
package ovh.herisson.Clyde.Tables; package ovh.herisson.Clyde.Tables;
import jakarta.persistence.*; import jakarta.persistence.*;
import org.hibernate.annotations.OnDelete;
import org.hibernate.annotations.OnDeleteAction;
@Entity @Entity
public class TeacherCourse { public class TeacherCourse {
@ -11,13 +9,11 @@ public class TeacherCourse {
private int id; private int id;
@ManyToOne(fetch = FetchType.EAGER) @ManyToOne(fetch = FetchType.EAGER)
@OnDelete(action = OnDeleteAction.CASCADE)
@JoinColumn(name = "Users") @JoinColumn(name = "Users")
private User user; private User user;
@ManyToOne(fetch = FetchType.EAGER) @ManyToOne(fetch = FetchType.EAGER)
@OnDelete(action = OnDeleteAction.CASCADE)
@JoinColumn(name = "Course") @JoinColumn(name = "Course")
private Course course; private Course course;

View File

@ -1,8 +1,8 @@
package ovh.herisson.Clyde.Tables; package ovh.herisson.Clyde.Tables;
import jakarta.persistence.*; import jakarta.persistence.*;
import org.hibernate.annotations.OnDelete; import org.springframework.scheduling.annotation.Scheduled;
import org.hibernate.annotations.OnDeleteAction; import ovh.herisson.Clyde.Repositories.TokenRepository;
import java.util.Date; import java.util.Date;
@ -13,7 +13,6 @@ public class Token {
private int id; private int id;
@ManyToOne(fetch = FetchType.EAGER) @ManyToOne(fetch = FetchType.EAGER)
@OnDelete(action = OnDeleteAction.CASCADE)
@JoinColumn(name ="Users") @JoinColumn(name ="Users")
private User user; private User user;
private String token; private String token;

View File

@ -1,8 +1,11 @@
package ovh.herisson.Clyde.Tables; package ovh.herisson.Clyde.Tables;
import jakarta.persistence.*; import jakarta.persistence.*;
import java.util.Date; import java.util.Date;
//Classe représentant un utilisateur l'attribut password demande surement un peu de rafinement niveau sécurité
//et l'attribut tokenApi doit encore être ajouté vu qu'il faut en discuter
@Entity @Entity
@Table(name = "Users") @Table(name = "Users")
@ -34,6 +37,18 @@ public class User {
this.password = password; this.password = password;
} }
/** Constructor for the first registration request from a student (can't specify a Role)
*
* @param lastName
* @param firstName
* @param email
* @param address
* @param country
* @param birthDate
* @param profilePictureUrl
* @param password
*/
public User(String lastName, String firstName, String email, String address, public User(String lastName, String firstName, String email, String address,
String country, Date birthDate, String profilePictureUrl, String password) String country, Date birthDate, String profilePictureUrl, String password)
{ {
@ -80,8 +95,8 @@ public class User {
return address; return address;
} }
public void setAddress(String address) { public void setAddress(String adress) {
this.address = address; this.address = adress;
} }
public String getCountry() { public String getCountry() {

View File

@ -1,8 +1,6 @@
package ovh.herisson.Clyde.Tables; package ovh.herisson.Clyde.Tables;
import jakarta.persistence.*; import jakarta.persistence.*;
import org.hibernate.annotations.OnDelete;
import org.hibernate.annotations.OnDeleteAction;
@Entity @Entity
public class UserCurriculum { public class UserCurriculum {
@ -12,13 +10,11 @@ public class UserCurriculum {
//Un étudiant peut avoir plusieurs curriculums //Un étudiant peut avoir plusieurs curriculums
@ManyToOne(fetch = FetchType.EAGER) @ManyToOne(fetch = FetchType.EAGER)
@OnDelete(action = OnDeleteAction.CASCADE)
@JoinColumn(name = "Users") @JoinColumn(name = "Users")
private User user; private User user;
@ManyToOne(fetch = FetchType.EAGER) @OneToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "Curriculum") @JoinColumn(name = "Curriculum")
@OnDelete(action = OnDeleteAction.CASCADE)
private Curriculum curriculum; private Curriculum curriculum;
public UserCurriculum(User user, Curriculum curriculum){ public UserCurriculum(User user, Curriculum curriculum){

View File

@ -1,3 +1,2 @@
spring.jpa.hibernate.ddl-auto=create-drop spring.jpa.hibernate.ddl-auto=create-drop
spring.jpa.database-platform=org.hibernate.dialect.PostgreSQLDialect spring.jpa.database-platform=org.hibernate.dialect.PostgreSQLDialect
spring.sql.init.mode=always

View File

@ -8,7 +8,6 @@ class ClydeApplicationTests {
@Test @Test
void contextLoads() { void contextLoads() {
} }
} }

View File

@ -1,105 +0,0 @@
package ovh.herisson.Clyde.Endpoints;
import com.github.dockerjava.api.model.ExposedPort;
import com.github.dockerjava.api.model.HostConfig;
import com.github.dockerjava.api.model.PortBinding;
import com.github.dockerjava.api.model.Ports;
import io.restassured.RestAssured;
import io.restassured.http.ContentType;
import org.junit.Assert;
import org.junit.jupiter.api.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.web.server.LocalServerPort;
import org.springframework.boot.testcontainers.service.connection.ServiceConnection;
import org.springframework.http.MediaType;
import org.springframework.mock.web.MockMultipartFile;
import org.springframework.test.context.ActiveProfiles;
import org.testcontainers.containers.PostgreSQLContainer;
import org.testcontainers.junit.jupiter.Container;
import org.testcontainers.junit.jupiter.Testcontainers;
import ovh.herisson.Clyde.ClydeApplication;
import ovh.herisson.Clyde.EndPoints.StorageController;
import ovh.herisson.Clyde.Repositories.FileRepository;
import ovh.herisson.Clyde.Services.StorageService;
import ovh.herisson.Clyde.Tables.FileType;
import ovh.herisson.Clyde.Tables.StorageFile;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import static io.restassured.RestAssured.with;
@Testcontainers
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@ActiveProfiles(value ="dev")
public class StorageControllerTest {
@LocalServerPort
private Integer port;
@Autowired
private ClydeApplication controller;
@Autowired
private StorageController storageController;
@Autowired
private StorageService storageService;
@Autowired
private FileRepository fileRepository;
@Container
@ServiceConnection
static PostgreSQLContainer<?> postgres = new PostgreSQLContainer<>("postgres:alpine")
.withDatabaseName("clyde")
.withUsername("devel")
.withPassword("devel")
.withCreateContainerCmdModifier(cmd -> cmd.withHostConfig(new HostConfig().withPortBindings(new PortBinding(Ports.Binding.bindPort(5442), new ExposedPort(5432)))));
@BeforeAll
static void beforeAll(){
postgres.start();
}
@AfterAll
static void afterAll(){
postgres.stop();
}
@BeforeEach
void setup(){
RestAssured.baseURI = "http://localhost:" + port;
}
@AfterEach
void afterEach(){
fileRepository.deleteAll();
}
@Test
public void uploadFileTest() throws IOException {
File mmf = new File("test.txt");
mmf.createNewFile();
FileWriter fw = new FileWriter(mmf);
fw.write("Ceci est un test");
fw.close();
with().multiPart("file", mmf).pathParam("fileType", FileType.ProfilePicture).when().request("POST", "/upload/{fileType}").then().statusCode(200);
StorageFile sf = fileRepository.getStorageFileByName("test.txt");
//On vérifie que le fichier a bien été stocké dans la db
Assert.assertFalse(sf == null);
//On vérifie que le fichier a bel et bien été stocké dans le dossier cdn
File extFile = new File(sf.getUrl());
Assert.assertTrue(extFile.exists());
Assert.assertEquals("cdn", extFile.getParent());
//On delete tranquillement les fichiers (la méthode delete a déja été testée dans StorageServiceTest)
storageService.delete(sf);
mmf.delete();
}
}

View File

@ -1,149 +0,0 @@
package ovh.herisson.Clyde.Endpoints;
import com.github.dockerjava.api.model.ExposedPort;
import com.github.dockerjava.api.model.HostConfig;
import com.github.dockerjava.api.model.PortBinding;
import com.github.dockerjava.api.model.Ports;
import io.restassured.RestAssured;
import io.restassured.http.ContentType;
import org.junit.Assert;
import org.junit.jupiter.api.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.web.server.LocalServerPort;
import org.springframework.boot.testcontainers.service.connection.ServiceConnection;
import org.springframework.http.HttpStatus;
import org.springframework.http.HttpStatusCode;
import org.springframework.test.context.ActiveProfiles;
import org.testcontainers.containers.PostgreSQLContainer;
import org.testcontainers.junit.jupiter.Container;
import org.testcontainers.junit.jupiter.Testcontainers;
import ovh.herisson.Clyde.ClydeApplication;
import ovh.herisson.Clyde.Repositories.TokenRepository;
import ovh.herisson.Clyde.Repositories.UserRepository;
import ovh.herisson.Clyde.Responses.UnauthorizedResponse;
import ovh.herisson.Clyde.Services.TokenService;
import ovh.herisson.Clyde.Tables.Role;
import ovh.herisson.Clyde.Tables.Token;
import ovh.herisson.Clyde.Tables.User;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import static io.restassured.RestAssured.with;
import static org.hamcrest.Matchers.equalTo;
@Testcontainers
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@ActiveProfiles(value = "dev")
public class UserControllerTest {
@LocalServerPort
private Integer port;
@Autowired
private ClydeApplication controller;
@Autowired
private TokenService tokenService;
@Autowired
private UserRepository userRepository;
@Autowired
private TokenRepository tokenRepository;
@Container
@ServiceConnection
static PostgreSQLContainer<?> postgres = new PostgreSQLContainer<>("postgres:alpine")
.withDatabaseName("clyde")
.withUsername("devel")
.withPassword("devel")
.withCreateContainerCmdModifier(cmd -> cmd.withHostConfig(new HostConfig().withPortBindings(new PortBinding(Ports.Binding.bindPort(5442), new ExposedPort(5432)))));
@BeforeAll
static void beforeAll(){
postgres.start();
}
@AfterAll
static void afterAll(){
postgres.stop();
}
@BeforeEach
void setup(){
RestAssured.baseURI = "http://localhost:" + port;
}
@AfterEach
void aftereach(){
tokenRepository.deleteAll();
userRepository.deleteAll();
}
@Test
//Verifie qu'un user qui n'a pas les permissions admin ou secretaire ne peut pas post
public void userPostTest(){
User god = new User("god","god","admin@admin.com","everywhere","every",new Date(0), null, Role.Admin,"goddoesntneedpassword");
Token godToken = new Token(god, tokenService.generateNewToken(), new Date());
userRepository.save(god);
tokenService.saveToken(godToken);
//Can god post herobrine himself ?
User herobrine = new User("brine","hero","herobrine@admin.com","in your WalLs","ShadowsLand",new Date(0), null,Role.Student,"test");
with().body(herobrine).contentType(ContentType.JSON).header("Authorization", godToken.getToken()).when().request("POST", "/user").then().statusCode(201);
userRepository.delete(herobrine);
//Can noob post herobrine without authorizations (no)
User noob = new User("boon","noob","noob@admintkt.com","everywhere","every",new Date(0), null, Role.Student,"noob");
Token noobToken = new Token(noob, tokenService.generateNewToken(), new Date());
userRepository.save(noob);
tokenService.saveToken(noobToken);
with().body(herobrine).contentType(ContentType.JSON).header("Authorization", noobToken.getToken()).when().request("POST", "/user").then().statusCode(401);
}
@Test
public void userGetTest(){
User herobrine = new User("brine","hero","herobrine@admin.com","in your WalLs","ShadowsLand",new Date(0), null,Role.Student,"test");
userRepository.save(herobrine);
Token t = new Token(herobrine, tokenService.generateNewToken(), new Date());
tokenRepository.save(t);
with().header("Authorization", t.getToken()).when().request("GET", "/user").then().assertThat().statusCode(200).body("firstName",equalTo("hero"));
}
@Test
public void userPatchTest(){
User herobrine = new User("brine","hero","herobrine@admin.com","in your WalLs","ShadowsLand",new Date(0), null,Role.Admin,"test");
userRepository.save(herobrine);
Token t = new Token(herobrine, tokenService.generateNewToken(), new Date());
tokenRepository.save(t);
Map<String, Object> data = new HashMap<String, Object>();
data.put("firstName", "test");
//Teste que le patch s'execute bien
with().body(data).contentType(ContentType.JSON).header("Authorization", t.getToken()).pathParam("id", herobrine.getRegNo()).when().request("PATCH", "/user/{id}").then().statusCode(200);
//Teste que la donnée a bien été altérée
with().header("Authorization", t.getToken()).when().request("GET", "/user").then().body("firstName",equalTo("test"));
}
@Test
public void UserDeleteTest(){
User god = new User("god","god","admin@admin.com","everywhere","every",new Date(0), null, Role.Admin,"goddoesntneedpassword");
Token godToken = new Token(god, tokenService.generateNewToken(), new Date());
userRepository.save(god);
tokenService.saveToken(godToken);
User herobrine = new User("brine","hero","herobrine@admin.com","in your WalLs","ShadowsLand",new Date(0), null,Role.Student,"test");
userRepository.save(herobrine);
with().header("Authorization", godToken.getToken()).pathParam("id", herobrine.getRegNo()).when().request("DELETE", "/user/{id}").then().statusCode(200);
Assert.assertEquals(userRepository.existsById(herobrine.getRegNo()), false);
}
}

View File

@ -1,41 +0,0 @@
package ovh.herisson.Clyde.Repositories;
import org.junit.Assert;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
import org.springframework.test.context.TestPropertySource;
import ovh.herisson.Clyde.Tables.Role;
import ovh.herisson.Clyde.Tables.User;
import java.util.GregorianCalendar;
@DataJpaTest
@TestPropertySource(properties = {
"spring.test.database.replace=none",
"spring.datasource.url=jdbc:tc:postgresql:16-alpine:///db"
})
public class UserRepoTest {
@Autowired
UserRepository userRepo;
@BeforeEach
public void setup(){
User herobrine = new User("brine","hero","admin@admin.com","in your WalLs","ShadowsLand", new GregorianCalendar(2005, 4, 3).getTime(), null, Role.Admin,"admin");
userRepo.save(herobrine);
}
@AfterEach
public void clean(){
userRepo.deleteAll();
}
@Test
public void usertest(){
Assert.assertEquals("brine", userRepo.findById(1).getLastName());
Assert.assertTrue(new GregorianCalendar(2005, 4, 3).getTime().equals(userRepo.findById(1).getBirthDate()));
}
}

View File

@ -1,80 +0,0 @@
package ovh.herisson.Clyde.Services;
import org.junit.Assert;
import org.junit.Before;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
import org.springframework.mock.web.MockMultipartFile;
import org.springframework.test.context.TestPropertySource;
import org.springframework.web.multipart.MultipartFile;
import org.testcontainers.shaded.com.google.common.net.MediaType;
import ovh.herisson.Clyde.Repositories.FileRepository;
import ovh.herisson.Clyde.Tables.FileType;
import ovh.herisson.Clyde.Tables.StorageFile;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
@DataJpaTest
@TestPropertySource(properties = {
"spring.test.database.replace=none",
"spring.datasource.url=jdbc:tc:postgresql:16-alpine:///db"
})
public class StorageServiceTest {
@Autowired
FileRepository fileRepo;
StorageService ss;
@BeforeEach
public void setup(){
if (ss == null){
ss = new StorageService(fileRepo);
}
}
@AfterEach
public void aftereach(){
fileRepo.deleteAll();
}
@Test
//Check si le fichier est bien sauvegardé dans la DB et si le fichier est bien sauvegardé au bon endroit
public void saveFile(){
//Test si le directory a bien été crée a l'init du fileService
Path rootloc = Paths.get("cdn/");
Assert.assertTrue(Files.exists(rootloc));
}
@Test
public void deleteFile() throws IOException {
File file = new File("cdn/test.txt");
file.createNewFile();
//On vérifie que le fichier a bien été crée
Assert.assertTrue(file.exists());
//StorageFile représentant le fichier
StorageFile sf = new StorageFile("testfile",file.getPath(), FileType.ProfilePicture);
fileRepo.save(sf);
//Check that the storagefile is properly saved
StorageFile resp = fileRepo.getStorageFileByName("testfile");
Assert.assertEquals(sf, resp);
ss.delete(sf);
//On vérifie que le fichier a bien été delete et que le StorageFile a été delete de la DB
Assert.assertFalse(file.exists());
resp = fileRepo.getStorageFileByName("testfile");
Assert.assertEquals(null, resp);
}
}

View File

@ -1,93 +0,0 @@
package ovh.herisson.Clyde.Services;
import org.junit.Assert;
import org.junit.Before;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
import org.springframework.test.context.TestPropertySource;
import ovh.herisson.Clyde.Repositories.TokenRepository;
import ovh.herisson.Clyde.Repositories.UserRepository;
import ovh.herisson.Clyde.Tables.Role;
import ovh.herisson.Clyde.Tables.Token;
import ovh.herisson.Clyde.Tables.User;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import static org.junit.jupiter.api.Assertions.*;
@DataJpaTest
@TestPropertySource(properties = {
"spring.test.database.replace=none",
"spring.datasource.url=jdbc:tc:postgresql:16-alpine:///db"
})
class TokenServiceTest {
@Autowired
TokenRepository tokenRepository;
@Autowired
UserRepository userRepository;
@AfterEach
public void aftereach(){
tokenRepository.deleteAll();
userRepository.deleteAll();
}
@Test
void saveToken() {
User herobrine = userRepository.findById(1);
User herobrinenul = new User("brine","heronul","pasadmin@student.com","in your WalLs","ShadowsLand", new GregorianCalendar(2005, 4, 3).getTime(), null, Role.Admin,"admin");
TokenService tokenService = new TokenService(tokenRepository);
Token testToken = new Token(herobrine, tokenService.generateNewToken(), new Date());
tokenService.saveToken(testToken);
Iterable<Token> t = tokenService.getAllTokens();
Token tok = t.iterator().next();
Assert.assertEquals(herobrine, tok.getUser());
Assert.assertNotEquals(herobrinenul, tok.getUser());
}
@Test
void saveTokenLimit(){
TokenService tokenService = new TokenService(tokenRepository);
//On va stocker les token qu'on va sauvegarder au préalable dans une liste pour tester que les tokens remplacés sont bien ceux avec la date d'expi la plus jeune
//A la fin il ne devrait donc rester que les 5 derniers tokens de tokenList
ArrayList<Token> tokenList = new ArrayList<>();
GregorianCalendar gc = new GregorianCalendar();
User malveillant = new User("mechant", "veutdestoken", "donnezmoidestoken@mail.com", "secret", "secret", null, null, null, "secret");
userRepository.save(malveillant);
for (int i = 0; i < 20; i++){
gc.add(Calendar.DAY_OF_WEEK, 1);
Token t = new Token(malveillant, tokenService.generateNewToken(), gc.getTime());
tokenList.add(t);
tokenService.saveToken(t);
}
//Testons les tokens
ArrayList <Token> resp = tokenRepository.getByUserOrderByExpirationDate(malveillant);
Assert.assertTrue(resp.size() == 5);
for (int i = 1; i <= resp.size(); i++){
Assert.assertEquals(tokenList.get(tokenList.size()-i), resp.get(resp.size()-i));
}
}
}

View File

@ -1,3 +0,0 @@
spring.datasource.driver-class-name=org.testcontainers.jdbc.ContainerDatabaseDriver
spring.jpa.hibernate.ddl-auto=create-drop
spring.jpa.database-platform=org.hibernate.dialect.PostgreSQLDialect

View File

@ -26,8 +26,6 @@ app.inscription.requests=Inscription Requests
app.manage.courses=Manage Courses app.manage.courses=Manage Courses
app.language=Language app.language=Language
app.manage.profile=Manage profile app.manage.profile=Manage profile
app.studentList=Students List
app.users=Users
request.moreInfos=More Infos request.moreInfos=More Infos
request.accept=Accept request.accept=Accept
request.refuse=Refuse request.refuse=Refuse
@ -43,12 +41,10 @@ profile.unRegister=Unregister
profile.course.list=Courses list profile.course.list=Courses list
profile.address=Address profile.address=Address
profile.picture=Profile picture profile.picture=Profile picture
profile.change.curriculum=Change curriculum
name=Name name=Name
Teacher=Teacher teacher=Teacher
Student=Student student=Student
Secretary=Secretary secretary=Secretary
Curriculum=curriculum curriculum=curriculum
Credits=Credits credits=Credits
InscriptionService=I.S.
faculty=Faculty faculty=Faculty

View File

@ -26,8 +26,6 @@ app.inscription.requests=Demandes d'Inscription
app.manage.courses=Gérer les cours app.manage.courses=Gérer les cours
app.language=Langue app.language=Langue
app.manage.profile=Gérer le profil app.manage.profile=Gérer le profil
app.studentList=Liste des étudiants
app.users=Utilisateurs
request.moreInfos=Plus d'Infos request.moreInfos=Plus d'Infos
request.accept=Accepter request.accept=Accepter
request.refuse=Refuser request.refuse=Refuser
@ -43,12 +41,10 @@ profile.unRegister=Désinscription
profile.course.list=Liste des cours profile.course.list=Liste des cours
profile.address=Adresse profile.address=Adresse
profile.picture=Photo de profil profile.picture=Photo de profil
profile.change.curriculum=Changer cursus
name=Nom name=Nom
Teacher=Enseignant teacher=Enseignant
Student=Etudiant student=Etudiant
Secretary=Secrétaire secretary=Secrétaire
Curriculum=Cursus curriculum=Cursus
Credits=Credits credits=Credits
InscriptionService=S.I.
faculty=Faculté faculty=Faculté

View File

@ -1,34 +1,37 @@
<script setup> <script setup>
import { toast } from 'vue3-toastify'; import { toast } from 'vue3-toastify';
import { ref } from 'vue' import { ref, computed } from 'vue'
import i18n, { setLang } from './i18n.js' import i18n, { setLang } from './i18n.js'
import { isLogged } from '@/rest/Users.js'
import { appList, currentView } from '@/rest/apps.js'
var prevURL;
var currentURL = window.location.hash;
window.onhashchange = function() { // Liste des apps
prevURL = currentURL; import LoginPage from './Apps/Login.vue'
currentURL = window.location.hash; import Inscription from "./Apps/Inscription.vue"
import Profil from "./Apps/Profil.vue"
import Courses from "./Apps/ManageCourses.vue"
const apps = {
'/login': LoginPage,
'/inscription': Inscription,
'/profil': Profil,
'/manage-courses' : Courses,
} }
const Logged = ref(isLogged()); const currentPath = ref(window.location.hash)
window.addEventListener('hashchange', () => { window.addEventListener('hashchange', () => {
if((location.hash === "#/home" && prevURL === "#/login") || (location.hash === "#/home" && prevURL === "#/profil")){ currentPath.value = window.location.hash
window.location.reload(); })
}
}); const currentView = computed(() => {
return apps[currentPath.value.slice(1) || '/']
})
const home=ref(i18n("app.home")) const home=ref(i18n("app.home"))
const notifications=ref(i18n("app.notifications")) const notifications=ref(i18n("app.notifications"))
const settings=ref(i18n("app.settings")) const settings=ref(i18n("app.settings"))
const login=ref(i18n("app.login")) const login=ref(i18n("app.login"))
const active=ref(false) const active=ref(false)
const apps = ref([])
appList().then(e => apps.value = e)
</script> </script>
<template> <template>
@ -38,7 +41,7 @@ window.addEventListener('hashchange', () => {
<ul class="horizontal"> <ul class="horizontal">
<li title=home> <li title=home>
<a class="icon" href="#home"> <a class="icon" href="#home">
<img class="clyde" src="/Clyde.png" style="width: 40px; height: auto; margin-top:4px"> <img class="clyde" src="./assets/Clyde.png" style="width: 40px; height: auto; margin-top:4px">
</a></li> </a></li>
<li title=home> <li title=home>
<a class="icon" href="#home"> <a class="icon" href="#home">
@ -46,7 +49,7 @@ window.addEventListener('hashchange', () => {
</a></li> </a></li>
<li style="float: right;" title=login> <li style="float: right;" title=login>
<a class="icon" href="#/login"> <a class="icon" href="#/login">
<div class="fa-solid fa-user" :style="Logged ? 'color: orange' : 'haha'" style="margin-top: 7px; margin-bottom: 3px; "></div> <div class="fa-solid fa-user" style="margin-top: 7px; margin-bottom: 3px;"></div>
</a></li> </a></li>
<li style="float: right;" title=notifications> <li style="float: right;" title=notifications>
<a class="icon" href="#Notifications"> <a class="icon" href="#Notifications">
@ -77,20 +80,37 @@ window.addEventListener('hashchange', () => {
<div class="leftBar"> <div class="leftBar">
<ul class="vertical"> <ul class="vertical">
<li v-for="app in apps"> <li style="margin-top: 25px;" >
<a :href="app.path"> <a href="#Messages">
<div class="fa-solid" :class="app.icon" style="font-size: 40px;"></div> <div class="fa-solid fa-comment" style="font-size: 40px;"></div>
<div class="text">{{app.text}}</div> <div class="text">{{i18n("app.messages")}}</div>
</a> </a></li>
</li> <li >
<a href="#Notifications">
<div class="fa-solid fa-bell" style="font-size: 40px;" ></div>
<div class="text">{{i18n("app.notifications")}}</div>
</a></li>
<li >
<a href="#Schedule">
<div class="fa-solid fa-calendar-days" style="font-size: 40px;"></div>
<div class="text">{{i18n("app.schedules")}}</div>
</a></li>
<li ><a href="#Forum">
<div class="fa-solid fa-envelope" style="font-size: 40px;" ></div>
<div class="text">{{i18n("app.forum")}}</div></a></li>
<li><a href="#/inscription">
<div class="fa-solid fa-users" style="align-self:center;font-size: 40px;"></div>
<div class="text" style="top:0;">{{i18n("app.inscription.requests")}}</div></a></li>
<li><a href="#/manage-courses">
<div class="fa-solid fa-book" style="align-self:center;font-size: 40px;overflow:none;"></div>
<div class="text">{{i18n("app.manage.courses")}}</div></a></li>
</ul> </ul>
</div> </div>
<div class="page"> <div class="page">
<div style=" margin:50px;"> <div style=" margin:50px;">
<Suspense>
<component :is="currentView" /> <component :is="currentView" />
</Suspense>
</div> </div>
</div> </div>
</div> </div>
@ -253,5 +273,3 @@ window.addEventListener('hashchange', () => {
} }
</style> </style>
<!-- vim:set noet sts=0 sw=4 ts=2: -->

View File

@ -1,113 +1,10 @@
<script setup> <script setup>
import i18n from "@/i18n.js" import Req from "./Request.vue"
import {ref} from 'vue' import { getRegisters } from '@/rest/ServiceInscription.js'
import {validateRegister, getAllRegisters } from '@/rest/ServiceInscription.js'
const requests = ref(await getAllRegisters()); const requests_example = getRegisters();
console.log(requests);
async function upPage(id,review){
await validateRegister(id,review);
requests.value = await getAllRegisters();
}
</script> </script>
<template> <template>
<div v-for="item of requests"> <Req v-for="item of requests_example"/>
<div class="bodu" v-if="item.state === 'Pending'">
<div class="container">
<div class="id"><a>{{item.id}}</a></div>
<div class="surname"><a>{{item.lastName}}</a></div>
<div class="firstname"><a>{{item.firstName}}</a></div>
<div class="infos"><button style="background-color:rgb(105,05,105);" >{{i18n("request.moreInfos")}}</button></div>
<div class="accept"><button @click="upPage(item.id,'Accepted')" style="background-color:rgb(0,105,50);">{{i18n("request.accept")}}</button></div>
<div class="refuse"><button @click="upPage(item.id,'Refused')" style="background-color:rgb(105,0,0);">{{i18n("request.refuse")}}</button></div>
</div>
</div>
</div>
</template> </template>
<style scoped>
.container{
color:white;
height:100px;
font-size:20px;
display:grid;
grid-template-columns:[firstCol-start]100px[firstCol-end secondCol-start]150px[secondCol-end thirdCol-start]200px[thirdCol-end fourthCol-start]150px[fourthCol-end]150px[fifthCol-end]150px[sixthCol-end]150px[endCol];
grid-template-areas:
"id type surname firstname infos accept refuse";
column-gap:10px;
}
.infos {
grid-area:infos;
align-self:center;
}
.accept{
grid-area:accept;
align-self:center;
}
.refuse{
grid-area:refuse;
align-self:center;
}
.titles {
grid-area:titles;
background-color:rgb(215,215,215);
}
.id{
grid-area:id;
margin-left:40px;
align-self:center;
}
.type{
grid-area:type;
align-self:center;
}
.surname{
grid-area:surname;
align-self:center;
white-space: nowrap;
overflow: hidden;
text-overflow:ellipsis;
}
.firstname{
grid-area:firstname;
align-self:center;
white-space: nowrap;
overflow: hidden;
text-overflow:ellipsis;
}
button{
font-size:15px;
height:50px;
width:100px;
border:none;
border-radius:20px;
}
.bodu {
width:100%;
margin-bottom:10px;
border:2px solid black;
border-radius:9px;
background-color:rgb(50,50,50);
}
</style>

View File

@ -1,57 +1,25 @@
<script setup> <script setup>
import {reactive, ref } from 'vue' import { ref } from 'vue'
import i18n from '@/i18n.js' import i18n from '@/i18n.js'
import { login , register , disconnect, isLogged} from '@/rest/Users.js' import { login , register } from '@/rest/Users.js'
import { getAllCurriculums } from '@/rest/curriculum.js'
import { uploadProfilePicture } from '@/rest/uploads.js' import { uploadProfilePicture } from '@/rest/uploads.js'
import {toast} from 'vue3-toastify'
import 'vue3-toastify/dist/index.css';
const loginPage= ref(true) const loginPage= ref(true)
const page = ref(0) const page = ref(0)
const outputs = reactive({
surname:null,
firstname:null,
password:null,
birthday:null,
email:null,
address:null,
country:null,
curriculum:null,
})
const submitValue= ref(i18n("login.guest.submit")) const submitValue= ref(i18n("login.guest.submit"))
const surname=ref("")
const firstname=ref("")
const password=ref("")
const passwordConfirm=ref("") const passwordConfirm=ref("")
const birthday=ref("")
const email=ref("")
const address=ref("")
const country=ref("")
const curriculum=ref("")
const imageSaved = ref(false) const imageSaved = ref(false)
const ppData = ref(false) const ppData = ref(false)
const curricula= await getAllCurriculums();
function goBackHome(){
setTimeout(() => {
window.location.href="#/home";
}, "500");
}
function verifyInputs(pass){
if(pass==passwordConfirm.value){
page.value++;
return toast('Password and Confirm Password are correct.', {
type: "success",});
}
else{
return toast('Password and Confirm Password are different',{type: "error",});
}
}
if (isLogged()){
disconnect();
window.location.reload();}
</script> </script>
@ -59,17 +27,17 @@
<div class='loginBox'> <div class='loginBox'>
<div v-if="loginPage"> <div v-if="loginPage">
<form @submit.prevent=" login(outputs.email,outputs.password);goBackHome();"class="form"> <form @submit.prevent="login(email, password)"class="form">
<h1 style="color:rgb(239,60,168); font-family: sans-serif;"> <h1 style="color:rgb(239,60,168); font-family: sans-serif;">
{{i18n("login.guest.signin")}} {{i18n("login.guest.signin")}}
</h1> </h1>
<div class="inputBox"> <div class="inputBox">
<p>ID / {{i18n("login.guest.email")}}</p> <p>ID / {{i18n("login.guest.email")}}</p>
<input type="text" v-model="outputs.email"> <input type="text" v-model="email">
</div> </div>
<div class="inputBox"> <div class="inputBox">
<p>{{i18n("login.guest.password")}}</p> <p>{{i18n("login.guest.password")}}</p>
<input type="password" v-model="outputs.password"> <input type="password" v-model="password">
</div> </div>
<div class="register"> <div class="register">
<a @click="loginPage=!loginPage">{{i18n("login.guest.register")}}</a> <a @click="loginPage=!loginPage">{{i18n("login.guest.register")}}</a>
@ -81,34 +49,35 @@
</div> </div>
<div v-else> <div v-else>
<form class="form"> <form @submit.prevent="register(firstname, surname, birthday, password, mail, address, country, curriculum)" class="form">
<h1 style="color:rgb(239,60,168); font-family: sans-serif; text-align:center;"> <h1 style="color:rgb(239,60,168); font-family: sans-serif; text-align:center;">
{{i18n("login.guest.welcome")}} {{i18n("login.guest.welcome")}}
</h1> </h1>
<div v-if="page === 0"> <div v-if="page === 0">
<div class="inputBox"> <div class="inputBox">
<p>{{i18n("login.guest.surname")}}</p> <p>{{i18n("login.guest.surname")}}</p>
<input type="text" v-model="outputs.surname"> <input type="text" v-model="surname">
</div> </div>
<div class="inputBox"> <div class="inputBox">
<p>{{i18n("login.guest.firstname")}}</p> <p>{{i18n("login.guest.firstname")}}</p>
<input type="text" v-model="outputs.firstname"> <input type="text" v-model="firstname">
</div> </div>
<div class="inputBox"> <div class="inputBox">
<p>{{i18n("login.guest.birthday")}}</p> <p>{{i18n("login.guest.birthday")}}</p>
<input type="date" v-model="outputs.birthday"> <input type="date" v-model="birthday">
</div> </div>
<div class="inputBox"> <div class="inputBox">
<p>{{i18n("login.guest.password")}}</p> <p>{{i18n("login.guest.password")}}</p>
<input type="password" v-model="outputs.password"> <input type="password" v-model="password">
</div> </div>
<div class="inputBox"> <div class="inputBox">
<p>{{i18n("login.guest.confirm")}} {{i18n("login.guest.password")}}</p> <p>{{i18n("login.guest.confirm")}} {{i18n("login.guest.password")}}</p>
<input type="password" v-model="passwordConfirm"> <input type="password" v-model="passwordConfirm">
<!-- TODO: Verify password is same as passwordConfirm -->
</div> </div>
<div class="switchpage"> <div class="switchpage">
<button @click="verifyInputs(outputs.password);">{{i18n("login.guest.nextpage")}}</button> <button @click="page++">{{i18n("login.guest.nextpage")}}</button>
</div> </div>
<div @click="(loginPage=!loginPage) && (page=0)" class="register"> <div @click="(loginPage=!loginPage) && (page=0)" class="register">
@ -118,31 +87,30 @@
<div v-else> <div v-else>
<div class="inputBox"> <div class="inputBox">
<p>{{i18n("login.guest.email")}}</p> <p>{{i18n("login.guest.email")}}</p>
<input type="mail" v-model="outputs.email"> <input type="mail" v-model="email">
</div> </div>
<div class="inputBox"> <div class="inputBox">
<p>{{i18n("login.guest.address")}}</p> <p>{{i18n("login.guest.address")}}</p>
<input type="text" v-model="outputs.address"> <input type="text" v-model="address">
</div> </div>
<div class="inputBox"> <div class="inputBox">
<p>{{i18n("login.guest.country")}}</p> <p>{{i18n("login.guest.country")}}</p>
<input type="text" v-model="outputs.country"> <input type="text" v-model="country">
</div> </div>
<form novalidate enctype="multipart/form-data" class="inputBox"> <form novalidate enctype="multipart/form-data" class="inputBox">
<p>{{i18n("profile.picture").toUpperCase()}}</p> <p>ProfilePicture</p>
<input type="file" :disabled="imageSaved" @change="ppData = uploadProfilePicture($event.target.files); imageSaved = true;" accept="image/*"> <input type="file" :disabled="imageSaved" @change="ppData = uploadProfilePicture($event.target.files); imageSaved = true;" accept="image/*">
</form> </form>
<div class="inputBox"> <div class="inputBox">
<p>{{i18n("Curriculum").toUpperCase()}}</p> <p>{{i18n("curriculum").toUpperCase()}}</p>
<select v-model="outputs.curriculum"> <select v-model="curriculum">
<option v-for="item in curricula">{{item.curriculumId}}</option> <option value="Chemistry">Chemistry</option>
<option value="Psycho">Psychology</option>
<option value="IT">IT</option>
</select> </select>
</div> </div>
<div style="align-self:center;" class="inputBox"> <div style="align-self:center;" class="inputBox">
<button style="margin-top:25px;" @click="register(outputs.firstname, outputs.surname, outputs.birthday, outputs.password, outputs.email, outputs.address, outputs.country, outputs.curriculum, ppData);"> <button style="margin-top:25px;" @click="console.log(outputs)">{{i18n("login.guest.submit")}}</button>
{{i18n("login.guest.submit")}}
</button>
</div> </div>
<div class="switchpage"> <div class="switchpage">
<button @click="page--">{{i18n("login.guest.lastpage")}}</button> <button @click="page--">{{i18n("login.guest.lastpage")}}</button>

View File

@ -1,103 +1,100 @@
<script setup> <script setup>
import i18n from "@/i18n.js" import i18n from "@/i18n.js"
import {reactive , ref} from 'vue' import {ref} from 'vue'
import { getCourses,deleteCourse,alterCourse,createCourse } from "@/rest/courses.js" const curriculum=[
import {getUser, getSelf, getTeachers } from "@/rest/Users.js" {
"id": 12,
"name": "Math pour l'info",
"credits": 11,
"faculty": "science",
"teacher": 42,
"Assistants": []},
{
"id": 42,
"name": "Operating Systems",
"credits": 8,
"faculty": "science",
"teacher": 62,
"Assistants": []},
{
"id": 52,
"name": "Fonctionnement des ordinateurs",
"credits": 11,
"faculty": "science",
"teacher": 59,
"Assistants": []},
]
const self = await getSelf(); const profList=[42,45,62,84,59]
const curriculum = ref(await getCourses(self.role));
const profList = await getTeachers();
const createMod = ref(false) const createMod = ref(false)
const deleteMod = ref(false) const deleteMod = ref(false)
const editElementID = ref("") const editElementID = ref("");
function editItem(id){ function editItem(id){
editElementID = id; editElementID = id;
} }
//Juste pour montrer le Create Mode //Juste pour montrer le Create Mode
const pattern = { const pattern = {
"title":null,
"credits":null,
"owner":null,
}
let toModify = Object.assign({},pattern); "id": 0,
"name": null,
"credits": null,
"faculty": null,
"teacher": null,
"Assistants": []}
let toAdd = Object.assign({}, pattern); let toAdd = Object.assign({}, pattern);
async function addToCourse(){ function addToCourse (){
if (curriculum.length>0){
toAdd.id=(curriculum[curriculum.length-1].id)-1;}
else{
toAdd.id=0;
}
let isnull= false; let isnull= false;
for(const [key, value] of Object.entries(toAdd)){ for(const [key, value] of Object.entries(toAdd)){
console.log(toAdd.owner);
if(value === null){ if(value === null){
isnull=true; isnull=true;
} }
} }
if (!isnull){ if (!isnull){
await createCourse(toAdd.title,toAdd.credits,toAdd.owner); curriculum.push(toAdd);
}
toAdd= Object.assign({},pattern); toAdd= Object.assign({},pattern);
curriculum.value = await getCourses(self.role);
}}
function setModify(item){
for(const el in profList){
if(profList[el].regNo === item.owner.regNo){
toModify.owner= profList[el];
}
}
toModify.credits= item.credits;
toModify.title= item.title;
} }
async function patchCourse(course){
for (let element in toModify){
console.log(toModify,1)
console.log(toModify[element],2)
if (element =="owner" && (toModify[element].regNo != course.owner.regNo)){
await alterCourse(course.courseId,{owner:toModify[element].regNo});
}
else if(element == "title" && (toModify[element] != course.title)){
await alterCourse(course.courseId,{title:toModify[element]});
}
else if(element == "credits" && (parseInt(toModify[element]) != course.credits)){
await alterCourse(course.courseId,{credits:parseInt(toModify[element])});
}
}
toModify= Object.assign({},pattern);
curriculum.value = await getCourses(self.role);
}
//Juste pour montrer le Delete Mode //Juste pour montrer le Delete Mode
let toRemove = null; let toRemove;
async function removeCourse(course) { function removeCourse() {
console.log("ok");
await deleteCourse(course.courseId) console.log(toRemove);
curriculum.value = await getCourses(self.role); let rem=-1;
toRemove = null; for(const [key, value] of Object.entries(curriculum)){
console.log(key);
console.log(value)
if(value.name === toRemove){
rem = key;
break;
}
}
console.log(rem)
if (rem > -1){
curriculum.splice(rem, 1);}
console.log(curriculum);
} }
</script> </script>
<template> <template>
<div class="body"> <div class="body">
<div v-if="!deleteMod && !createMod && (self.role !== 'Teacher')" class="listTitle buttonGrid"> <div v-if="!deleteMod && !createMod" class="listTitle buttonGrid">
<button class="create" @click="editElementID= '';createMod = true;"> <button class="create" @click="createMod = true">
{{i18n("courses.createCourse")}} {{i18n("courses.createCourse")}}
</button> </button>
<button class="delete" @click="deleteMod=true" > <button class="delete" @click="deleteMod=true" >
@ -108,18 +105,22 @@
<form class="listElement"> <form class="listElement">
<div style="margin-bottom:20px;"> <div style="margin-bottom:20px;">
{{i18n("name")}} : {{i18n("name")}} :
<input v-model="toAdd.title"> <input v-model="toAdd.name">
</div> </div>
<div style="margin-bottom:20px;"> <div style="margin-bottom:20px;">
{{i18n("Teacher")}} : {{i18n("teacher")}} :
<select style="max-width:200px;" class="teacher" v-model="toAdd.owner"> <select style="max-width:200px;" class="teacher" v-model="toAdd.teacher">
<option v-for="item in profList" :value="item">{{item.lastName}}</option> <option v-for="item in profList">{{item}}</option>
</select> </select>
</div> </div>
<div style="margin-bottom:20px;"> <div style="margin-bottom:20px;">
{{i18n("Credits")}} : {{i18n("credits")}} :
<input v-model="toAdd.credits"> <input v-model="toAdd.credits">
</div> </div>
<div style="margin-bottom:20px;">
{{i18n("faculty")}} :
<input v-model="toAdd.faculty">
</div>
<button class="create" @click="createMod=!createMod; addToCourse();"> {{i18n("courses.confirm")}} </button> <button class="create" @click="createMod=!createMod; addToCourse();"> {{i18n("courses.confirm")}} </button>
<button style="float:right;" @click="createMod=!createMod">{{i18n("courses.back")}}</button> <button style="float:right;" @click="createMod=!createMod">{{i18n("courses.back")}}</button>
</form> </form>
@ -129,40 +130,43 @@
<div style="margin-bottom:20px;"> <div style="margin-bottom:20px;">
{{i18n("courses.toDelete")}} : {{i18n("courses.toDelete")}} :
<select style="max-width:200px;" class="teacher" v-model="toRemove"> <select style="max-width:200px;" class="teacher" v-model="toRemove">
<option v-for="item in curriculum" :value='item'>{{item.title}}</option> <option v-for="item in curriculum">{{item.name}}</option>
</select> </select>
</div> </div>
<button class="delete" @click="deleteMod=!deleteMod; removeCourse(toRemove);"> {{i18n("courses.deleteCourse")}} </button> <div style="margin-bottom:20px;">
{{i18n("login.password")}}:
<input >
</div>
<div style="margin-bottom:20px;">
{{i18n("login.cPassword")}} :
<input>
</div>
<button class="delete" @click="deleteMod=!deleteMod;removeCourse();"> {{i18n("courses.deleteCourse")}} </button>
<button style="float:right;" @click="deleteMod=!deleteMod"> {{i18n("courses.back")}}</button> <button style="float:right;" @click="deleteMod=!deleteMod"> {{i18n("courses.back")}}</button>
</form> </form>
</div> </div>
<div v-if="!createMod && !deleteMod" v-for="item in curriculum" :key="item.title"> <div v-if="!createMod && !deleteMod" v-for="item in curriculum" :key="item.name">
<div v-if="editElementID !== item.title" style ="padding:15px 15px 15px 15px;"> <div style ="padding:15px 15px 15px 15px;">
<button @click="editElementID = item.title; setModify(item); "> <button v-if="editElementID !== item.name" @click="editElementID = item.name">
{{i18n("courses.modify")}} {{i18n("courses.modify")}}
</button> </button>
</div> <button v-else @click="editElementID= ''"> {{i18n("courses.confirm")}} </button>
<div v-else>
<button @click="editElementID= '';patchCourse(item)"> {{i18n("courses.confirm")}} </button>
<button @click="editElementID= '';"> {{i18n("courses.back")}} </button>
</div> </div>
<div class="listElement" > <div class="listElement" >
<div class="containerElement" v-if="editElementID !== item.title" > <div class="containerElement" v-if="editElementID !== item.name" >
<div class="name"> {{item.title}} </div> <div class="name"> {{item.name}} </div>
<div class="teacher">{{item.owner.lastName}}</div> <div class="teacher">{{item.teacher}}</div>
<div class="credits">{{i18n("Credits")}}:{{item.credits}}</div> <div class="credits">{{i18n("credits")}}:{{item.credits}}</div>
</div> </div>
<div class="containerElement"v-else> <div class="containerElement"v-else>
<input style="max-width:200px;" class="name" v-model="toModify.title"> <input style="max-width:200px;" class="name" v-model="item.name">
<select v-if="self.role === 'Secretary'" style="max-width:200px;" class="teacher" v-model="toModify.owner"> <select style="max-width:200px;" class="teacher" v-model="item.teacher">
<option v-for="(item,index) in profList" :value='item'>{{item.lastName}}</option> <option v-for="item in profList">{{item}}</option>
</select> </select>
<div v-else class="teacher">{{item.owner.lastName}}</div> <input style="max-width:100px;"class="credits" v-model="item.credits">
<input v-if="self.role==='Secretary'"style="max-width:100px;"class="credits" v-model="toModify.credits">
<div v-else class="credits">{{i18n("Credits")}}:{{item.credits}}</div>
</div> </div>
</div> </div>
</div> </div>

View File

@ -1,129 +1,108 @@
<script setup> <script setup>
import {reactive, ref} from 'vue' import {reactive, ref} from 'vue'
import {getSelf,alterSelf,disconnect,deleteUser} from '../rest/Users.js' import {getUser} from '../rest/Users.js'
import {getSelfCurriculum, getAllCurriculums} from '../rest/curriculum.js'
import {getCourses} from "../rest/courses.js"
import i18n from "@/i18n.js" import i18n from "@/i18n.js"
import { uploadProfilePicture } from '@/rest/uploads.js' /*
const user = getUser();
*/
const user =reactive({
profilPicture:"../assets/clyde.png",
lastName:"Ghost",
firstName:"Clyde",
role:"student",
address: "Radiator Springs",
email:"ClydeGhost@gmail.com",
curriculum:[
{
"id": 12,
"name": "Math pour l'info",
"credits": 11,
"faculty": "science",
"teacher": 42,
"Assistants": []},
{
"id": 42,
"name": "Fonctionnement des ordinateurs",
"credits": 11,
"faculty": "science",
"teacher": 42,
"Assistants": []},
const user = ref(await getSelf()); ],
const UserCurriculum = ref(""); option:"IT",
const curricula = ref (await getAllCurriculums()); degree:"BAC1",
if(user.value.role === "Student"){ password:"CeciEstUnMotDePasse123",
UserCurriculum.value = await getSelfCurriculum(); })
}
/*
Teacher user
const user =reactive({
profilPicture:"../assets/clyde.png",
lastName:"Ghost",
firstName:"Clyde",
role:"teacher",
address: "Radiator Springs",
email:"ClydeGhost@gmail.com",
coursesOwned:[
{
"id": 12,
"name": "Math pour l'info",
"faculty": "science",
"teacher": 42,
"Assistants": []},
{
"id": 42,
"name": "Fonctionnement des ordinateurs",
"credits": 11,
"faculty": "science",
"teacher": 42,
"Assistants": []},
],
faculty:"Science",
})*/
if(user.role === "Teacher"){
UserCurriculum.value = await getCourses("Teacher");
}
const modif = ref(false); const modif = ref(false);
const curric = ref(false);
const reg = ref(false);
const pattern = { const toModify = Object.assign({}, user);
profilPictureUrl:null,
email:null,
address:null,
password:null,
};
const patternInfos ={
email: null,
password: null,
passwordConfirm:null,
id:null,
}
let toModify= Object.assign({}, pattern);
let personnalInfos = Object.assign({}, patternInfos);
function resetInputs(inputs,list){
inputs=Object.assign({},list);
}
async function ChangeInfos(){
for (let element in toModify){
if (element =="email" && (toModify[element] !== null)){
await alterSelf(user.value.regNo,{email : toModify[element]});
}
if (element =="profilPictureUrl" && (toModify[element] !== null)){
await alterSelf(user.value.regNo,{ profilPictureUrl : toModify[element]});
}
else if(element == "address" && (toModify[element] !== null)){
await alterSelf(user.value.regNo,{address : toModify[element]});
}
else if(element == "password" && (toModify[element] !== null)){
await alterSelf(user.value.regNo,{password : toModify[element]});
}
}
toModify= Object.assign({},pattern);
user.value = await getSelf()
}
function setModify(item){
toModify.address = item.address;
toModify.profilPictureUrl = item.profilPictureUrl;
toModify.email= item.email;
toModify.password= item.password;
}
async function unRegister(){
deleteUser(user.value.regNo);
disconnect()
setTimeout(() => {
window.location.href="#/home";
}, "500");
}
function getPP(){
if(user.value.profilePictureUrl === null){
return "/Clyde.png"
}
return user.profilePictureUrl
}
</script> </script>
<template> <template>
<div class="body"> <div class="body">
<div class="container"> <div class="container">
<div class="profilPic"> <div class="profilPic">
<img class="subContainter" :src=getPP()> <img class="subContainter" src="../assets/Clyde.png">
</div> </div>
<div class="globalInfos"> <div class="globalInfos">
<div v-if="modif==false && curric==false && reg==false " class="infosContainer" > <div v-if="modif==false" class="infosContainer" >
<div> <div>
{{user.firstName}} {{user.lastName}} {{user.firstName}} {{user.lastName.toUpperCase()}}
</div> </div>
<div> <div>
E-mail: {{user.email}} E-mail: {{user.email}}
</div> </div>
<div v-if="user.role==='Student'"> <div v-if="user.role==='student'">
{{user.option}} {{i18n(user.role)}} {{user.option}} {{i18n(user.role).toUpperCase()}}
</div> </div>
<div v-else> <div v-else>
Role: {{i18n((user.role))}} {{i18n("faculty")}}: {{user.faculty}}
Role: {{i18n(user.role).toUpperCase()}}
</div> </div>
<div> <div>
<button @click="modif=!modif; setModify(user)"> {{i18n("profile.modify.data")}} </button> <button @click="modif=!modif"> {{i18n("profile.modify.data")}} </button>
</div> </div>
<div v-if="(user.role==='Student')"> <div v-if="(user.role==='student')">
<button @click="reg=!reg">{{i18n("profile.reRegister")}}</button> <button>{{i18n("profile.reRegister")}}</button>
<button @click="unRegister()" style="float:right;background-color:rgb(150,0,0);">{{i18n("profile.unRegister")}}</button> <button style="float:right;background-color:rgb(150,0,0);">{{i18n("profile.unRegister")}}</button>
</div>
<div v-if="(user.role==='Student')">
<button @click="curric=!curric">{{i18n("profile.change.curriculum")}}</button>
</div> </div>
</div> </div>
<div v-else-if="modif" class="infosContainer"> <div v-else class="infosContainer">
<div> <div>
{{i18n("profile.picture")}}: {{i18n("profile.picture")}}:
<input type="file" @change="user.profilPicture = uploadProfilePicture($event.target.files);" accept="image/*"> <input type="file">
</div> </div>
<div> <div>
E-mail: E-mail:
@ -131,42 +110,7 @@
</div> </div>
<div> <div>
{{i18n("profile.address")}}: {{i18n("profile.address")}}:
<input type="text" v-model="toModify.id"> <input type="text" v-model="toModify.address">
</div>
<div>
{{i18n("login.password")}}:
<input type="password" v-model="toModify.password">
</div>
<div>
{{i18n("login.cPassword")}}:
<input type="password" v-model="toModify.passwordConfirm">
</div>
<div>
<button @click=" modif=!modif; ChangeInfos();">{{i18n("courses.confirm")}}</button>
<button @click="modif=!modif; resetInputs(toModify,pattern);" style="float:right;">{{i18n("courses.back")}}</button>
</div>
</div>
<div v-else-if="curric" class="infosContainer">
<div style="height:40px;">
{{i18n("Curriculum")}}:
<select v-model="curriculum" >
<option v-for="item in curricula" style="font-size:20px;" :value="item">{{item.option}}</option>
</select>
</div>
<div>
<button @click=" curric=!curric;">{{i18n("courses.confirm")}}</button>
<button @click="curric=!curric; resetInputs(personnalInfos,patternInfos);" style="float:right;">{{i18n("courses.back")}}</button>
</div>
</div>
<div v-else-if="reg" class="infosContainer">
<div>
E-mail:
<input type="mail" v-model="toModify.email" />
</div>
<div>
ID :
<input type="text" v-model="toModify.id">
</div> </div>
<div> <div>
{{i18n("login.password")}}: {{i18n("login.password")}}:
@ -176,25 +120,22 @@
{{i18n("login.cPassword")}}: {{i18n("login.cPassword")}}:
<input type="password" id="confirm"> <input type="password" id="confirm">
</div> </div>
<div> <div>
<button @click=" reg=!reg;">{{i18n("courses.confirm")}}</button> <button @click=" modif=!modif">{{i18n("courses.confirm")}}</button>
<button @click=" reg=!reg; resetInputs(personnalInfos,patternInfos);" style="float:right;">{{i18n("courses.back")}}</button>
</div> </div>
</div> </div>
</div> </div>
<div v-if="modif==false"class="moreInfos">
<div v-if="modif==false && curric==false && reg==false "class="moreInfos"> <div v-if="(user.role==='student')">
<div v-if="(user.role ==='Student')">
<div class="listTitle"> <div class="listTitle">
{{i18n("profile.course.list")}} {{i18n("profile.course.list")}}
</div> </div>
<div class="listElement" v-for="item in UserCurriculum.courses"> <div class="listElement "
v-for="item in user.curriculum">
<div class=" containerElement"> <div class=" containerElement">
<div class="name"> {{item.title}} </div> <div class="name"> {{item.name}} </div>
<div class="teacher">{{item.owner.lastName}}</div> <div class="teacher">{{item.teacher}}</div>
<div class="credits">Credits:{{item.credits}}</div> <div class="credits">Credits:{{item.credits}}</div>
</div> </div>
</div> </div>
@ -203,6 +144,18 @@
<div> <div>
</div> </div>
<div v-if="(user.role==='teacher')">
<div class="listTitle">
{{i18n("profile.course.list")}}
</div>
<div class="listElement " v-for="item in user.coursesOwned">
{{item.name}}
</div>
</div>
<div>
</div>
</div> </div>
</div> </div>
</div> </div>
@ -215,7 +168,7 @@
grid-template-columns:200px 900px; grid-template-columns:200px 900px;
grid-template-rows:200px auto; grid-template-rows:200px auto;
column-gap:30px; column-gap:30px;
row-gap:45px; row-gap:25px;
grid-template-areas: grid-template-areas:
"profilPic globalInfos" "profilPic globalInfos"
"minfos minfos"; "minfos minfos";

View File

@ -0,0 +1,109 @@
<script setup>
import i18n from "@/i18n.js"
const props = defineProps({
id: Number,
type: String,
lastName: String,
firstName: String,
address: String,
country: String,
birthDate: String,
curriculum:String,
degree:String,});
</script>
<template>
<div class="bodu">
<div class="container">
<div class="id"><a>{{id}}</a></div>
<div class="type"><a>{{type}}</a></div>
<div class="surname"><a>{{lastName}}</a></div>
<div class="firstname"><a>{{firstName}}</a></div>
<div class="infos"><button style="background-color:rgb(105,05,105);" >{{i18n("request.moreInfos")}} </button></div>
<div class="accept"><button style="background-color:rgb(0,105,50);">{{i18n("request.accept")}}</button></div>
<div class="refuse"><button style="background-color:rgb(105,0,0);">{{i18n("request.refuse")}}</button></div>
</div>
</div>
</template>
<style scoped>
.container{
color:white;
height:100px;
font-size:20px;
display:grid;
grid-template-columns:[firstCol-start]100px[firstCol-end secondCol-start]150px[secondCol-end thirdCol-start]200px[thirdCol-end fourthCol-start]150px[fourthCol-end]150px[fifthCol-end]150px[sixthCol-end]150px[endCol];
grid-template-areas:
"id type surname firstname infos accept refuse";
column-gap:10px;
}
.infos {
grid-area:infos;
align-self:center;
}
.accept{
grid-area:accept;
align-self:center;
}
.refuse{
grid-area:refuse;
align-self:center;
}
.titles {
grid-area:titles;
background-color:rgb(215,215,215);
}
.id{
grid-area:id;
margin-left:40px;
align-self:center;
}
.type{
grid-area:type;
align-self:center;
}
.surname{
grid-area:surname;
align-self:center;
white-space: nowrap;
overflow: hidden;
text-overflow:ellipsis;
}
.firstname{
grid-area:firstname;
align-self:center;
white-space: nowrap;
overflow: hidden;
text-overflow:ellipsis;
}
button{
font-size:15px;
height:50px;
width:100px;
border:none;
border-radius:20px;
}
.bodu {
width:100%;
margin-bottom:10px;
border:2px solid black;
border-radius:9px;
background-color:rgb(50,50,50);
}
</style>

View File

@ -1,100 +0,0 @@
<script setup>
import i18n from "@/i18n.js"
import { reactive } from 'vue'
import { getStudents } from '../rest/Users.js'
const users = await getStudents();
</script>
<template>
<div v-for="item in users">
<div class="bodu">
<div class="container">
<div class="status"><a style="margin-left:30px">{{item.status}}</a></div>
<div class="option"><a>{{item.role}}</a></div>
<div class="surname"><a>{{item.lastName}}</a></div>
<div class="firstname"><a>{{item.firstName}}</a></div>
<div class="infos"><button style="background-color:rgb(105,05,105);" >{{i18n("request.moreInfos")}} </button></div>
</div>
</div>
</div>
</template>
<style scoped>
.container{
color:white;
height:100px;
font-size:30px;
display:grid;
grid-template-columns:250px 250px 250px 250px 150px;
grid-template-areas:
"status option surname firstname infos";
column-gap:10px;
}
.infos {
grid-area:infos;
align-self:center;
}
.option{
grid-area:option;
align-self:center;
}
.refuse{
grid-area:refuse;
align-self:center;
}
.titles {
grid-area:titles;
background-color:rgb(215,215,215);
}
.id{
grid-area:id;
margin-left:40px;
align-self:center;
}
.status{
grid-area:status;
align-self:center;
}
.surname{
grid-area:surname;
align-self:center;
white-space: nowrap;
overflow: hidden;
text-overflow:ellipsis;
}
.firstname{
grid-area:firstname;
align-self:center;
white-space: nowrap;
overflow: hidden;
text-overflow:ellipsis;
}
button{
font-size:15px;
height:50px;
width:100px;
border:none;
border-radius:20px;
}
.bodu {
width:100%;
margin-bottom:10px;
border:2px solid black;
border-radius:9px;
background-color:rgb(50,50,50);
}
</style>

View File

@ -1,86 +0,0 @@
<script setup>
import i18n from "@/i18n.js"
import { reactive } from 'vue'
import { getAllUsers } from '../rest/Users.js'
const users = await getAllUsers();
</script>
<template>
<div v-for="item in users">
<div class="bodu">
<div class="container">
<div class="role"><a style="margin-left:30px">{{i18n(item.role)}}</a></div>
<div class="surname"><a>{{item.lastName}}</a></div>
<div class="firstname"><a>{{item.firstName}}</a></div>
<div class="infos"><button style="background-color:rgb(105,05,105);" >{{i18n("request.moreInfos")}} </button></div>
</div>
</div>
</div>
</template>
<style scoped>
.container{
justify-content:center;
align-items:center;
color:white;
height:100px;
font-size:30px;
display:grid;
grid-template-columns:250px 250px 250px 150px;
grid-template-areas:
"role surname firstname infos";
column-gap:10px;
}
.infos {
grid-area:infos;
align-items:center;
}
.role {
grid-area:role;
align-self:center;
}
.surname{
grid-area:surname;
align-self:center;
white-space: nowrap;
overflow: hidden;
text-overflow:ellipsis;
}
.firstname{
grid-area:firstname;
align-self:center;
white-space: nowrap;
overflow: hidden;
text-overflow:ellipsis;
}
button{
font-size:15px;
height:50px;
width:100px;
border:none;
border-radius:20px;
}
.bodu {
width:100%;
margin-bottom:10px;
border:2px solid black;
border-radius:9px;
background-color:rgb(50,50,50);
}
</style>

View File

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

@ -33,13 +33,9 @@ export async function getRegisters(id){
return restGet("/request/register") return restGet("/request/register")
} }
export async function getAllRegisters(){
return restGet("/requests/register")
}
/** /**
* Change the state of a requests. * Change the state of a requests.
*/ */
export async function validateRegister(id, state){ export async function validateRegister(id, state){
return restPatch("/request/register/" + id, state); return restPatch("/request/register/" + id, {state: state});
} }

View File

@ -1,18 +1,9 @@
import { restGet, restPost, restPatch, restDelete} from './restConsumer.js' import { restGet, restPost } from './restConsumer.js'
import { getCookie, setCookie } from '@/utils.js'
export async function login(user, pass, exp){ export async function login(user, pass, exp){
return restPost("/login", {identifier: user, password: pass, expirationDate: exp}); return restPost("/login", {identifier: user, password: pass, expirationDate: exp});
} }
export function isLogged(){
return getCookie("session_token") != ""
}
export function disconnect(){
setCookie("session_token", ";expires= Thu, 01 Jan 1970 00:00:01 GMT")
}
/** /**
* Register a user (tokenless) * Register a user (tokenless)
* *
@ -26,17 +17,16 @@ export function disconnect(){
* @param curriculum * @param curriculum
* @param imageId id of the image in database returned when uploaded * @param imageId id of the image in database returned when uploaded
*/ */
export async function register(firstname, lastname, birthDate, password, email, address, country, curriculumId, imageId){ export async function register(firstname, lastname, birthDate, password, email, address, country, curriculum, imageId){
return restPost("/register", { return restPost("/register", {
firstName: firstname, firstname: firstname,
lastName: lastname, lastname: lastname,
birthDate: birthDate, birthDate: birthDate,
password: password, password: password,
email: email, email: email,
address: address, address: address,
country: country, country: country,
curriculumId: curriculumId, curriculum: curriculum
profilePictureUrl: imageId,
}); });
} }
@ -73,7 +63,7 @@ export async function createUser(firstname, lastname, birthDate, email, address,
* if the user is not authenticated. then an empty array should be returned * if the user is not authenticated. then an empty array should be returned
*/ */
export async function getUser(id){ export async function getUser(id){
const endpoint = "/user/" + id; const endpoint = "/user" + id != null ? "/" + id : "";
return restGet(endpoint); return restGet(endpoint);
} }
@ -103,23 +93,7 @@ export async function getAllUsers(){
return restGet("/users"); return restGet("/users");
} }
/**
* Return the list of teachers
*
* @return a list of teachers
* each elements is of the form
* - id
* - name
* - role
*/
export async function getTeachers(){
return restGet("/teachers")
}
export async function getStudents(){
return restGet("/students")
}
/** /**
* Get informations about yourself * Get informations about yourself
* - RegNo * - RegNo
@ -140,13 +114,6 @@ export async function getSelf(){
* - Adress * - Adress
* - Password * - Password
*/ */
export async function alterSelf(id,data){ export async function alterSelf(data){
console.log(data) return restPatch("/user", data);
return restPatch("/user/"+id, data);
}
export async function deleteUser(id){
return restDelete("/user/" + id)
} }

View File

@ -1,66 +0,0 @@
import { restGet } from './restConsumer.js'
import { ref, computed } from 'vue'
import i18n from '@/i18n.js'
// Liste des apps
import LoginPage from '@/Apps/Login.vue'
import Inscription from "@/Apps/Inscription.vue"
import Profil from "@/Apps/Profil.vue"
import Courses from "@/Apps/ManageCourses.vue"
import Users from "@/Apps/UsersList.vue"
import Students from "@/Apps/StudentsList.vue"
const apps = {
'/login': LoginPage,
'/inscription': Inscription,
'/profil': Profil,
'/manage-courses' : Courses,
'/users-list' : Users,
'/students-list' : Students,
}
const appsList = {
'Msg': { path: '#/msg', icon: 'fa-comment', text: i18n("app.messages") },
'Notification': { path: '#/notifs', icon: 'fa-bell', text: i18n("app.notifications") },
'Forum': { path: '#/forum', icon: 'fa-envelope', text: i18n("app.forum") },
'Schedule': { path: '#/schedule', icon: 'fa-calendar-days', text: i18n("app.schedules") },
'Inscription': { path: '#/inscription', icon: 'fa-users', text: i18n("app.inscription.requests") },
'ManageCourses': { path: '#/manage-courses', icon: 'fa-book', text: i18n("app.manage.courses") },
'StudentsList':{ path: '#/students-list',icon: 'fa-users',text: i18n("app.studentList")},
'UsersList':{ path: '#/users-list',icon: 'fa-users',text: i18n("app.users")},
}
const currentPath = ref(window.location.hash)
export const currentView = computed(() => {
return apps[currentPath.value.slice(1) || '/']
})
/**
* Return the list of app accesible by a logged (or not)
* user.
*/
export async function appList(){
let ret = [];
let userAppList = await restGet("/apps");
for (let userapp in userAppList) {
if(appsList[userAppList[userapp]] != null){
ret.push(appsList[userAppList[userapp]])
}
}
return ret;
}
/**
* Check if the specified page is authorized for the
* user
*/
export async function checkPage(page){
return restGet("/apps/" + page)
}
window.addEventListener('hashchange', () => {
currentPath.value = window.location.hash
})
// vim:set noet sts=0 sw=4 ts=2 tw=2:

View File

@ -7,10 +7,8 @@ import { restGet, restPost, restDelete, restPatch } from './restConsumer.js'
/** /**
* Create a new course * Create a new course
*/ */
export async function createCourse(name, credits, owner){ export async function createCourse(name, credits, faculty, teacher, assistants){
console.log(owner); return restPost("/courses", {name: name, credits: credits, faculty: faculty, teacher: teacher, assistants: assistants} )
return restPost("/course", {title: name, credits: credits, owner} )
} }
/** /**
@ -36,25 +34,6 @@ export async function getCourse(id){
return restGet("/course/" + id); return restGet("/course/" + id);
} }
/**
* Get the list of courses to display on secretary's option
*
* @return list of courses of the form
* - id
* - name
* - credits
* - facutly
* - teacher
* - Assistants
*/
export async function getCourses(role){
if(role==="Teacher"){
return restGet("/courses/owned")
}
return restGet("/courses")
}
/** /**
* Change the options of a course * Change the options of a course
* *

View File

@ -2,7 +2,7 @@
* curriculum API * curriculum API
*/ */
import { restGet, restPost, restDelete, restPatch } from './restConsumer.js' import { restGet, restPostn, restDelete, restPatch } from './restConsumer.js'
/** /**
* Create a new curriculum (bundle of courses) * Create a new curriculum (bundle of courses)
@ -19,10 +19,6 @@ export async function deletecurriculum(id){
return restDelete("/curriculum/" + id); return restDelete("/curriculum/" + id);
} }
export async function getAllCurriculums(){
return restGet("/curriculums");
}
/** /**
* Get informations on a particular curriculum * Get informations on a particular curriculum
* *
@ -43,8 +39,3 @@ export async function getcurriculum(id){
export async function altercurriculum(id, courses){ export async function altercurriculum(id, courses){
return restPatch("/curriculum/" + id, courses); return restPatch("/curriculum/" + id, courses);
} }
export async function getSelfCurriculum(){
return restGet("/curriculum");
}

View File

@ -16,8 +16,8 @@ export async function restPostFile(endPoint, file){
return await _rest(endPoint, {method: "POST", credentials: 'include', body: file, headers: headers }); return await _rest(endPoint, {method: "POST", credentials: 'include', body: file, headers: headers });
} }
export async function restDelete(endPoint) { export async function restDelete(endPoint, data) {
return await _rest(endPoint, {method: "DELETE"}); return await _rest(endPoint, {method: "DELETE", credentials: 'include', body: JSON.stringify(data)});
} }
export async function restPatch(endPoint, data) { export async function restPatch(endPoint, data) {
@ -46,6 +46,7 @@ async function _rest(endPoint, config){
pending: config['pending'] != null ? config['pending'] : 'pending', pending: config['pending'] != null ? config['pending'] : 'pending',
error: config['error'] != null ? config['error'] : 'Network Failure...', error: config['error'] != null ? config['error'] : 'Network Failure...',
success: config['success'] != null ? config['success'] : {render(res){ success: config['success'] != null ? config['success'] : {render(res){
console.log(res);
return res.data.ok ? "Success" : "error"; return res.data.ok ? "Success" : "error";
}}, }},
}) })