diff --git a/.idea/compiler.xml b/.idea/compiler.xml index fb56945..8509211 100644 --- a/.idea/compiler.xml +++ b/.idea/compiler.xml @@ -2,6 +2,7 @@ + diff --git a/README.md b/README.md new file mode 100644 index 0000000..72c6b27 --- /dev/null +++ b/README.md @@ -0,0 +1,26 @@ +# COURSE_MANAGEMENT_SYSTEM +The objective of the Project is to develop an Application which is similar to D2L. Major sections of this App are: +1. Login / Sign-up, Events +2. Course Catalog and Enrollment Section +3. Course Detail Page +4. Student Accounts +5. Profile +6. Renting Equipment for Classes +7. Advisors Appointment + +All of these Sections are Accessible from a HomePage similar to Campus Connect. The submission document for this app is located [here.](https://docs.google.com/document/d/1O24gv_99QWmvtr7fXyRh1UDozIoA5l4M_CWXlHaJSF8/edit) + +# Project Members + +| Member | Area | +|--------------------------------------|-------------------------------------- | +| Patel Jay Rashmitbhai | event, student, user | +| Reddy Guntaka Satish Harshavardhan | advisor, appointment | +| Puneeth Talluri | Course Catalog, Enrollment Section | +| Patel Shivangi | Course Details, Instructor, Student Accounts | +| Siddiqui Atif | Equipment, rental | + + + + + diff --git a/ReadMe.md b/ReadMe.md index 08b8cf7..5ed4267 100644 --- a/ReadMe.md +++ b/ReadMe.md @@ -1,38 +1,26 @@ # COURSE_MANAGEMENT_SYSTEM The objective of the Project is to develop an Application which is similar to D2L. Major sections of this App would be: -1. Login / Sign-up -2. Course Search and Enrollment -3. Enrolled Courses -4. Course Specific Content +1. Login / Sign-up, Events +2. Course Catalog and Enrollment Section +3. Course Detail Page +4. Student Accounts 5. Profile +6. Student Resources +7. Advisors Appointment All of these Sections will be Accessible from a HomePage similar to Campus Connect. All the sections will be displayed as Cards to select from. The prototype for this app demonstrates these features and is located [here.](https://docs.google.com/presentation/d/1QjD8G9kpWbk5O_mX6PxxExSkT-fPpU7aEpygSH_JCzo/edit?usp=sharing) # Project Members -| Member | Area | -|--------------------------------------|--------------------------------------| -| Patel Jay Rashmitbhai | Login/Sign-up | -| Reddy Guntaka Satish Harshavardhan | Course Search (Catalog) | -| Puneeth Talluri | Enrolled Courses | -| Patel Shivangi | Course Details,Home Page | -| Siddiqui Atif | Profile | +| Member | Area | +|--------------------------------------|-------------------------------------- | +| Patel Jay Rashmitbhai | event, student, user | +| Reddy Guntaka Satish Harshavardhan | advisor, appointment | +| Puneeth Talluri | Course Catalog, Enrollment Section | +| Patel Shivangi | Course Details, Instructor, Student Accounts | +| Siddiqui Atif | Equipment, rental | -# Conflict Resolution -Participate In Zoom Meetings and discord Chat to get a vote on the issue from all team members. - - -# Communication Mechanism -Will meet using Zoom as per milestone requirements. Mandatory meeting the day next to class, Will decide on atleast another 2 meetings before the Milestone Due Date in this meeting. - -# Decision Table - -| # | Area | Decision | Alternative | Rationale | -|---|----------------------|-----------------------|-------------------------|---------------------------------------------------------------------------------------| -| 1 | IDE | Use VS Code | IntelliJ, Eclipse | Language independent editor so that it can be used in non-java course | -| 2 | Dependency Management| Maven | Gradle | All team members are familiar with the build tool | -| 3 | ORM | JPA, Hibernate | - | Need to implement this for Java Object -> Database Rows and vice versa | -| 4 | Database | H2 | MySQL | Sticking to a RDBMS which meets current requirements. Might pivot to NoSql if data asks for that | +We have expanded the scope of the project based on the suggestions by professor. diff --git a/myappvs/pom.xml b/myappvs/pom.xml index 8607f33..8d7a6bd 100644 --- a/myappvs/pom.xml +++ b/myappvs/pom.xml @@ -14,14 +14,18 @@ myappvs Demo project for Spring Boot - 21 + 17 org.springframework.boot spring-boot-starter-web - + + org.apache.commons + commons-lang3 + 3.12.0 + org.projectlombok lombok @@ -37,6 +41,11 @@ org.springframework.boot spring-boot-starter-data-jpa + + org.mockito + mockito-core + test + com.mysql @@ -69,6 +78,12 @@ 0.11.5 + + io.jsonwebtoken + jjwt + 0.9.1 + + net.logstash.logback logstash-logback-encoder @@ -91,8 +106,43 @@ postgresql 9.4-1201-jdbc41 + + + org.springframework.boot + spring-boot-starter-security + + + org.springframework.security + spring-security-config + + + javax.servlet + servlet-api + 2.4 + provided + + + + org.springframework.boot + spring-boot-starter-data-mongodb + + + + org.springframework.boot + spring-boot-starter-thymeleaf + + + org.springdoc + springdoc-openapi-starter-webmvc-ui + 2.1.0 + + + org.springframework.boot + spring-boot-starter-logging + + diff --git a/myappvs/src/main/java/com/CourseManagementSystem/myappvs/CourseApp.java b/myappvs/src/main/java/com/CourseManagementSystem/myappvs/CourseApp.java index df7aa79..c5d6070 100644 --- a/myappvs/src/main/java/com/CourseManagementSystem/myappvs/CourseApp.java +++ b/myappvs/src/main/java/com/CourseManagementSystem/myappvs/CourseApp.java @@ -2,12 +2,29 @@ import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration; +import org.springframework.boot.autoconfigure.security.servlet.UserDetailsServiceAutoConfiguration; import org.springframework.context.annotation.Bean; -//import org.springframework.scheduling.annotation.EnableScheduling; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.data.jpa.repository.config.EnableJpaRepositories; +import org.springframework.data.mongodb.repository.config.EnableMongoRepositories; import org.springframework.web.servlet.config.annotation.CorsRegistry; +import org.springframework.web.servlet.config.annotation.EnableWebMvc; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; +import org.springframework.context.annotation.FilterType; -@SpringBootApplication +import com.CourseManagementSystem.myappvs.Notes.StudentNoteRepository; +import com.CourseManagementSystem.myappvs.event.Eventrepo; + +@SpringBootApplication(scanBasePackages = { + "com.CourseManagementSystem.myappvs.event.EventController", + "com.CourseManagementSystem.myappvs.event.Eventrepository", + "com.CourseManagementSystem.myappvs.Notes.StudentNoteController", + "com.CourseManagementSystem.myappvs.Notes.StudentNoteRepository"}) +@EnableMongoRepositories({"com.CourseManagementSystem.myappvs.event", "com.CourseManagementSystem.myappvs.Notes"}) +@EnableJpaRepositories(excludeFilters = @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, value = { Eventrepo.class, StudentNoteRepository.class})) + +@ComponentScan("com.CourseManagementSystem.myappvs") public class CourseApp { public static void main(String[] args) { @@ -15,13 +32,4 @@ public static void main(String[] args) { System.out.println("Started..."); } - @Bean - public WebMvcConfigurer corsConfigurer() { - return new WebMvcConfigurer() { - public void addCorsMappings(CorsRegistry registry) { - registry.addMapping("/**").allowedMethods("*").allowedOrigins("*"); - } - }; - } - } diff --git a/myappvs/src/main/java/com/CourseManagementSystem/myappvs/Notes/StudentNote.java b/myappvs/src/main/java/com/CourseManagementSystem/myappvs/Notes/StudentNote.java new file mode 100644 index 0000000..86ab1cb --- /dev/null +++ b/myappvs/src/main/java/com/CourseManagementSystem/myappvs/Notes/StudentNote.java @@ -0,0 +1,24 @@ +package com.CourseManagementSystem.myappvs.Notes; + +import org.springframework.data.annotation.Id; +import org.springframework.data.mongodb.core.mapping.Document; + +import lombok.Data; +import lombok.Getter; +import lombok.Setter; + +@Data +@Getter +@Setter +@Document(collection = "student_notes") +public class StudentNote { + + @Id + private String id; + private String studentEmail; + private String courseId; + private String noteTitle; + private String noteContent; + + +} diff --git a/myappvs/src/main/java/com/CourseManagementSystem/myappvs/Notes/StudentNoteController.java b/myappvs/src/main/java/com/CourseManagementSystem/myappvs/Notes/StudentNoteController.java new file mode 100644 index 0000000..31dbdbc --- /dev/null +++ b/myappvs/src/main/java/com/CourseManagementSystem/myappvs/Notes/StudentNoteController.java @@ -0,0 +1,56 @@ +package com.CourseManagementSystem.myappvs.Notes; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.web.bind.annotation.*; + +import com.CourseManagementSystem.myappvs.student.Studentrepository; + +import java.util.List; + +@RestController +@RequestMapping("/studentNotes") +public class StudentNoteController { + + @Autowired + private StudentNoteService service; + +// @Autowired +// private Studentrepository sturepo; + + @GetMapping + public List getNotesByStudentEmail() { + Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); + + // Check if user is authenticated + if (authentication != null && authentication.isAuthenticated()) { + // Extract user email from authentication principal + String emailId = authentication.getName(); + + return service.getNotesByStudentEmail(emailId); + } + return null; + } + + @GetMapping("/{studentEmail}/{courseId}") + public List getNotesByStudentEmailAndCourseId(@PathVariable String studentEmail, @PathVariable String courseId) { + return service.getNotesByStudentEmailAndCourseId(studentEmail, courseId); + } + + @PostMapping + public StudentNote addOrUpdateStudentNote(@RequestBody StudentNote studentNote) { + Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); + + if (authentication != null && authentication.isAuthenticated()) { + String emailId = authentication.getName(); + studentNote.setStudentEmail(emailId); + } + return service.addOrUpdateStudentNote(studentNote); + } + + @DeleteMapping("/{id}") + public void deleteStudentNoteById(@PathVariable String id) { + service.deleteStudentNoteById(id); + } +} \ No newline at end of file diff --git a/myappvs/src/main/java/com/CourseManagementSystem/myappvs/Notes/StudentNoteRepository.java b/myappvs/src/main/java/com/CourseManagementSystem/myappvs/Notes/StudentNoteRepository.java new file mode 100644 index 0000000..2eda671 --- /dev/null +++ b/myappvs/src/main/java/com/CourseManagementSystem/myappvs/Notes/StudentNoteRepository.java @@ -0,0 +1,9 @@ +package com.CourseManagementSystem.myappvs.Notes; + +import org.springframework.data.mongodb.repository.MongoRepository; +import java.util.List; + +public interface StudentNoteRepository extends MongoRepository { + List findByStudentEmail(String studentEmail); + List findByStudentEmailAndCourseId(String studentEmail, String courseId); +} \ No newline at end of file diff --git a/myappvs/src/main/java/com/CourseManagementSystem/myappvs/Notes/StudentNoteService.java b/myappvs/src/main/java/com/CourseManagementSystem/myappvs/Notes/StudentNoteService.java new file mode 100644 index 0000000..4e81e57 --- /dev/null +++ b/myappvs/src/main/java/com/CourseManagementSystem/myappvs/Notes/StudentNoteService.java @@ -0,0 +1,29 @@ + package com.CourseManagementSystem.myappvs.Notes; + +import java.util.List; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +@Component +public class StudentNoteService { + + @Autowired + private StudentNoteRepository repository; + + public List getNotesByStudentEmail(String studentEmail) { + return repository.findByStudentEmail(studentEmail); + } + + public List getNotesByStudentEmailAndCourseId(String studentEmail, String courseId) { + return repository.findByStudentEmailAndCourseId(studentEmail, courseId); + } + + public StudentNote addOrUpdateStudentNote(StudentNote studentNote) { + return repository.save(studentNote); + } + + public void deleteStudentNoteById(String id) { + repository.deleteById(id); + } +} diff --git a/myappvs/src/main/java/com/CourseManagementSystem/myappvs/Notes/package-info.java b/myappvs/src/main/java/com/CourseManagementSystem/myappvs/Notes/package-info.java new file mode 100644 index 0000000..d1e7975 --- /dev/null +++ b/myappvs/src/main/java/com/CourseManagementSystem/myappvs/Notes/package-info.java @@ -0,0 +1,24 @@ +/** + * This Package consists of the Student Notes section which uses MongoDB. The main functionality of this section is that it enables + * the students to create course specific notes and allows them to be managed. The various parts of this section are + * + * + * 1.StudentNote.java + * This entity represents the document storing the note Information such as Student emailId, CourseID Note Title, Note Description. + * + * 2.Catalog Controller + * The Controller class deals with GET, POST, DELETE Mapping of requests in this scenario. + * + * 3.Course Service + * THis is the service class where I make use of the repository to write the logic to fetch the data and return it. + * + * 4.Course Repository + * This is the Interface which extends MongoRepository which is used to retrieve the Students Notes from the online Mongo Atlas configured in the application.properties + * + * 5. studentNotes.html + * The HTML file contains front end code to send requests and to handle responses. + * + * + * @author Puneeth Talluri + */ +package com.CourseManagementSystem.myappvs.Notes; \ No newline at end of file diff --git a/myappvs/src/main/java/com/CourseManagementSystem/myappvs/Testcontroller.java b/myappvs/src/main/java/com/CourseManagementSystem/myappvs/Testcontroller.java index 7e473d3..5548108 100644 --- a/myappvs/src/main/java/com/CourseManagementSystem/myappvs/Testcontroller.java +++ b/myappvs/src/main/java/com/CourseManagementSystem/myappvs/Testcontroller.java @@ -1,6 +1,7 @@ package com.CourseManagementSystem.myappvs; import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; //import org.springframework.web.bind.annotation.RequestMethod; //import org.springframework.web.bind.annotation.RequestParam; @@ -14,5 +15,10 @@ public class Testcontroller { public String handle() { return "This is just for fun!!"; } + +// @GetMapping("/") +// public String showIndex() { +// return "index"; +// } } diff --git a/myappvs/src/main/java/com/CourseManagementSystem/myappvs/advsior/Advisor.java b/myappvs/src/main/java/com/CourseManagementSystem/myappvs/advsior/Advisor.java index 7051d77..231f3a4 100644 --- a/myappvs/src/main/java/com/CourseManagementSystem/myappvs/advsior/Advisor.java +++ b/myappvs/src/main/java/com/CourseManagementSystem/myappvs/advsior/Advisor.java @@ -32,6 +32,6 @@ public class Advisor { private String email; @Exclude - @OneToMany(mappedBy = "advsior",fetch = FetchType.LAZY) + @OneToMany(mappedBy = "advisor",fetch = FetchType.LAZY) private List appointments; } diff --git a/myappvs/src/main/java/com/CourseManagementSystem/myappvs/advsior/AdvisorController.java b/myappvs/src/main/java/com/CourseManagementSystem/myappvs/advsior/AdvisorController.java new file mode 100644 index 0000000..b28c364 --- /dev/null +++ b/myappvs/src/main/java/com/CourseManagementSystem/myappvs/advsior/AdvisorController.java @@ -0,0 +1,26 @@ +package com.CourseManagementSystem.myappvs.advsior; + +import java.util.List; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +import com.CourseManagementSystem.myappvs.appointment.Appointment; +import com.CourseManagementSystem.myappvs.appointment.AppointmentService; + +@RestController +@RequestMapping("/advisors") +public class AdvisorController { + + @Autowired + private AppointmentService service; + + @GetMapping + public List getAppointments(@RequestParam(name = "advisorId", required = true, defaultValue = "none") String advisorId){ + Long id = Long.parseLong(advisorId); + return service.listByAdvisor(id); + } +} diff --git a/myappvs/src/main/java/com/CourseManagementSystem/myappvs/appointment/Appointment.java b/myappvs/src/main/java/com/CourseManagementSystem/myappvs/appointment/Appointment.java index 11e0f1f..20b7eb2 100644 --- a/myappvs/src/main/java/com/CourseManagementSystem/myappvs/appointment/Appointment.java +++ b/myappvs/src/main/java/com/CourseManagementSystem/myappvs/appointment/Appointment.java @@ -39,7 +39,7 @@ public class Appointment { @Exclude @ManyToOne @JoinColumn(name = "advisor_id", nullable = false) - private Advisor advsior; + private Advisor advisor; @Temporal(TemporalType.DATE) private LocalDate appointmentDate; diff --git a/myappvs/src/main/java/com/CourseManagementSystem/myappvs/appointment/AppointmentController.java b/myappvs/src/main/java/com/CourseManagementSystem/myappvs/appointment/AppointmentController.java new file mode 100644 index 0000000..eb5a04f --- /dev/null +++ b/myappvs/src/main/java/com/CourseManagementSystem/myappvs/appointment/AppointmentController.java @@ -0,0 +1,38 @@ +package com.CourseManagementSystem.myappvs.appointment; + +import java.util.List; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +import com.CourseManagementSystem.myappvs.student.Student; + +@RestController +@RequestMapping("/appointments") +public class AppointmentController { + + @Autowired + private AppointmentService service; + + @GetMapping + public List getAppointments(@RequestParam Student Student) { + return service.listByStudent(Student); + } + + @PostMapping + public Appointment save(@RequestBody Appointment appointment) { + return service.save(appointment); + } + + @DeleteMapping("/{id}") + public void delete(@PathVariable Long id) { + service.delete(id); + } +} diff --git a/myappvs/src/main/java/com/CourseManagementSystem/myappvs/appointment/AppointmentRepository.java b/myappvs/src/main/java/com/CourseManagementSystem/myappvs/appointment/AppointmentRepository.java index 54899a2..5903cbb 100644 --- a/myappvs/src/main/java/com/CourseManagementSystem/myappvs/appointment/AppointmentRepository.java +++ b/myappvs/src/main/java/com/CourseManagementSystem/myappvs/appointment/AppointmentRepository.java @@ -9,8 +9,11 @@ public interface AppointmentRepository extends CrudRepository { - List findAllByAdvsior(Advisor advsior); + List findAllByAdvisor(Advisor advisor); List findAllByStudent(Student student); + // List findByStudentId(long studentId); + + List findByAdvisorId(long id); } diff --git a/myappvs/src/main/java/com/CourseManagementSystem/myappvs/appointment/AppointmentService.java b/myappvs/src/main/java/com/CourseManagementSystem/myappvs/appointment/AppointmentService.java new file mode 100644 index 0000000..566ffe2 --- /dev/null +++ b/myappvs/src/main/java/com/CourseManagementSystem/myappvs/appointment/AppointmentService.java @@ -0,0 +1,35 @@ +package com.CourseManagementSystem.myappvs.appointment; + +import java.util.List; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import com.CourseManagementSystem.myappvs.student.Student; + + +@Service +public class AppointmentService { + + @Autowired + private AppointmentRepository appointmentRepo; + + public List listByStudent(Student student) { + List appointments = appointmentRepo.findAllByStudent(student); + return appointments; + } + + public List listByAdvisor(Long advisorId) { + List appointments = appointmentRepo.findByAdvisorId(advisorId); + return appointments; + } + + public Appointment save(Appointment appointment) { + appointmentRepo.save(appointment); + return appointment; + } + + public void delete(long id) { + appointmentRepo.deleteById(id); + } +} diff --git a/myappvs/src/main/java/com/CourseManagementSystem/myappvs/courseCatalog/Catalog.java b/myappvs/src/main/java/com/CourseManagementSystem/myappvs/courseCatalog/Catalog.java index 6bd578d..e418450 100644 --- a/myappvs/src/main/java/com/CourseManagementSystem/myappvs/courseCatalog/Catalog.java +++ b/myappvs/src/main/java/com/CourseManagementSystem/myappvs/courseCatalog/Catalog.java @@ -10,15 +10,13 @@ import jakarta.persistence.JoinColumn; import jakarta.persistence.ManyToOne; import jakarta.persistence.Table; -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.Getter; -import lombok.Setter; +import lombok.*; import lombok.ToString.Exclude; @Data @Entity @AllArgsConstructor +@NoArgsConstructor @Getter @Setter @Table(name="Course_Catalog") @@ -34,7 +32,6 @@ public class Catalog { private String courseDesc; @ManyToOne - @Column(name="Instructor_ID") @JoinColumn(name = "instructorId", referencedColumnName = "instructorId") private Instructor courseIns; // Reference to Instructor entity diff --git a/myappvs/src/main/java/com/CourseManagementSystem/myappvs/courseCatalog/CatalogController.java b/myappvs/src/main/java/com/CourseManagementSystem/myappvs/courseCatalog/CatalogController.java new file mode 100644 index 0000000..20ca80f --- /dev/null +++ b/myappvs/src/main/java/com/CourseManagementSystem/myappvs/courseCatalog/CatalogController.java @@ -0,0 +1,41 @@ +package com.CourseManagementSystem.myappvs.courseCatalog; + +import java.util.List; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RestController; + +import com.CourseManagementSystem.myappvs.student.Studentrepository; + +@RestController +public class CatalogController { + + @Autowired + private CatalogService service; + + @Autowired + private Studentrepository stuRepo; + + + @GetMapping("/getCourses") + private List displayCourses(){ + return service.getAllCourses(); + } + + @GetMapping("/getName") + public String getStudentName() { + Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); + + if (authentication != null && authentication.isAuthenticated()) { + String emailId = authentication.getName(); + return stuRepo.findNameByEmailId(emailId); + } + return "User"; + } + + + +} diff --git a/myappvs/src/main/java/com/CourseManagementSystem/myappvs/courseCatalog/CatalogRespository.java b/myappvs/src/main/java/com/CourseManagementSystem/myappvs/courseCatalog/CatalogRepository.java similarity index 62% rename from myappvs/src/main/java/com/CourseManagementSystem/myappvs/courseCatalog/CatalogRespository.java rename to myappvs/src/main/java/com/CourseManagementSystem/myappvs/courseCatalog/CatalogRepository.java index 4644868..87503bd 100644 --- a/myappvs/src/main/java/com/CourseManagementSystem/myappvs/courseCatalog/CatalogRespository.java +++ b/myappvs/src/main/java/com/CourseManagementSystem/myappvs/courseCatalog/CatalogRepository.java @@ -2,6 +2,6 @@ import org.springframework.data.jpa.repository.JpaRepository; -public interface CatalogRespository extends JpaRepository { +public interface CatalogRepository extends JpaRepository { } diff --git a/myappvs/src/main/java/com/CourseManagementSystem/myappvs/courseCatalog/CatalogService.java b/myappvs/src/main/java/com/CourseManagementSystem/myappvs/courseCatalog/CatalogService.java new file mode 100644 index 0000000..d62a220 --- /dev/null +++ b/myappvs/src/main/java/com/CourseManagementSystem/myappvs/courseCatalog/CatalogService.java @@ -0,0 +1,19 @@ +package com.CourseManagementSystem.myappvs.courseCatalog; + +import java.util.List; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +@Component +public class CatalogService { + + @Autowired + private CatalogRepository repo; + + public List getAllCourses(){ + System.out.println(repo.count()); + return repo.findAll(); + } + +} diff --git a/myappvs/src/main/java/com/CourseManagementSystem/myappvs/courseCatalog/EnrollmentRepository.java b/myappvs/src/main/java/com/CourseManagementSystem/myappvs/courseCatalog/EnrollmentRepository.java deleted file mode 100644 index 5eb6442..0000000 --- a/myappvs/src/main/java/com/CourseManagementSystem/myappvs/courseCatalog/EnrollmentRepository.java +++ /dev/null @@ -1,7 +0,0 @@ -package com.CourseManagementSystem.myappvs.courseCatalog; - -import org.springframework.data.jpa.repository.JpaRepository; - -public interface EnrollmentRepository extends JpaRepository{ - -} diff --git a/myappvs/src/main/java/com/CourseManagementSystem/myappvs/courseCatalog/package-info.java b/myappvs/src/main/java/com/CourseManagementSystem/myappvs/courseCatalog/package-info.java index 3653d78..65c9c72 100644 --- a/myappvs/src/main/java/com/CourseManagementSystem/myappvs/courseCatalog/package-info.java +++ b/myappvs/src/main/java/com/CourseManagementSystem/myappvs/courseCatalog/package-info.java @@ -1,11 +1,21 @@ /** - * This Package consists of Two Entities : a) Catalog b)Enrollment - * Catalog Entity: + * This Package consists : + * 1.Catalog Entity: * This entity represents the table storing all the Courses and its respective information to be displayed to students for them to be able to enroll. * - * Enrollment Entity: - * This represents the table storing all the enrollments per student for each enrolled course - *
  • One to one relationship between student and user. + * 2.Catalog Controller + * This is the controller class which is responsible to get the requests and display the Courses in the courseCatalog page. It displays a table and allows enrollment for each course. + * + * 3.Course Service + * This is the service class where I make use of the repository to write the logic to fetch the data and return it from the H2 Database. + * + * 4.Course Repository + * This is the JPA Repository class which is used to retrieve the course_catalog table information from the H2 DataBase. + * + * 5. courseCatalog.html + * This is the HTML file containing HTML, CSS, Javascript code to send appropriate requests and to handle the responses. + * + * * @author Puneeth Talluri */ diff --git a/myappvs/src/main/java/com/CourseManagementSystem/myappvs/courseDescription/CourseDescription.java b/myappvs/src/main/java/com/CourseManagementSystem/myappvs/courseDescription/CourseDescription.java index 07a2190..43ddb78 100644 --- a/myappvs/src/main/java/com/CourseManagementSystem/myappvs/courseDescription/CourseDescription.java +++ b/myappvs/src/main/java/com/CourseManagementSystem/myappvs/courseDescription/CourseDescription.java @@ -1,106 +1,47 @@ package com.CourseManagementSystem.myappvs.courseDescription; import com.CourseManagementSystem.myappvs.courseCatalog.Catalog; +import com.CourseManagementSystem.myappvs.instructor.Instructor; import jakarta.persistence.*; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; import lombok.ToString.Exclude; import java.sql.Time; import java.util.Date; @Entity +@Getter +@NoArgsConstructor +@AllArgsConstructor @Table(name = "Course_Description") public class CourseDescription { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(unique = true) - private long courseDescriptionId; + private Long courseDescriptionId; @Exclude @OneToOne - @JoinColumn(name = "course_id", referencedColumnName = "courseId") + @JoinColumn(name = "courseId", referencedColumnName = "courseId") private Catalog courseId; @Exclude - @OneToOne + @ManyToOne @JoinColumn(name = "instructorId", referencedColumnName = "instructorId") - private long instructorId; - + private Instructor instructorId; + @Column(name = "room", nullable = false) private String room; - + @Column(name = "date", nullable = false) private Date date; - + @Column(name = "time", nullable = false) private Time time; - + @Column(name = "meeting_info", nullable = false) private String meetingInfo; - + @Column(name = "materials", nullable = false) private String materials; - public CourseDescription() { - // Default constructor required by Hibernate - } - - public CourseDescription(long courseDescriptionId, long instructorId, String room, Date date, Time time, String meetingInfo, String materials){ - this.courseDescriptionId = courseDescriptionId; - this.instructorId = instructorId; - this.room = room; - this.date = date; - this.time = time; - this.meetingInfo = meetingInfo; - this.materials = materials; - } - - public long getCourseId() { return courseDescriptionId; } - - public void setCourseId(long courseId) { - this.courseDescriptionId = courseId; - } - - public Date getDate() { - return date; - } - - public long getInstructorId() { - return instructorId; - } - - public String getMaterials() { - return materials; - } - - public String getRoom() { - return room; - } - - public String getMeetingInfo() { - return meetingInfo; - } - - public Time getTime() { - return time; - } - - public void setDate(Date date) { - this.date = date; - } - - public void setInstructorId(long instructorId) { - this.instructorId = instructorId; - } - - public void setMaterials(String materials) { - this.materials = materials; - } - - public void setMeetingInfo(String meetingInfo) { - this.meetingInfo = meetingInfo; - } - - public void setRoom(String room) { - this.room = room; - } - public void setTime(Time time) { - this.time = time; - } } diff --git a/myappvs/src/main/java/com/CourseManagementSystem/myappvs/courseDescription/CourseDescriptionController.java b/myappvs/src/main/java/com/CourseManagementSystem/myappvs/courseDescription/CourseDescriptionController.java index bd3ca0e..1778e74 100644 --- a/myappvs/src/main/java/com/CourseManagementSystem/myappvs/courseDescription/CourseDescriptionController.java +++ b/myappvs/src/main/java/com/CourseManagementSystem/myappvs/courseDescription/CourseDescriptionController.java @@ -1,32 +1,30 @@ package com.CourseManagementSystem.myappvs.courseDescription; -import com.CourseManagementSystem.myappvs.courseDescription.CourseDescription; +import com.CourseManagementSystem.myappvs.courseCatalog.Catalog; import com.CourseManagementSystem.myappvs.courseDescription.CourseDescriptionService; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.bind.annotation.*; @RestController +@RequestMapping("/api/coursedescription") public class CourseDescriptionController { - @Autowired - private CourseDescriptionService courseDescriptionService; + private com.CourseManagementSystem.myappvs.courseDescription.CourseDescriptionService courseDescriptionService; - public CourseDescriptionController(CourseDescriptionService courseDescriptionService){ + public CourseDescriptionController(CourseDescriptionService courseDescriptionService) { this.courseDescriptionService = courseDescriptionService; } - @GetMapping("/course-descriptions/{id}") - public ResponseEntity getCourseDescriptionById(@PathVariable Long id)throws Exception { - CourseDescription courseDescription = courseDescriptionService.getCourseDescriptionById(id); - if (courseDescription != null) { - return new ResponseEntity(courseDescription, HttpStatus.OK); - } else { - return new ResponseEntity(HttpStatus.NOT_FOUND); - } - } + //Get CourseDetails Rest Api + @GetMapping("/{id}") + public ResponseEntity getCourseDescriptionbyId(@PathVariable Long id){ + try { + CourseDescriptionDto courseDescriptionDto = courseDescriptionService.getCourseDetail(id); + return ResponseEntity.ok(courseDescriptionDto); + } catch (RuntimeException e) { + return ResponseEntity.status(HttpStatus.NOT_FOUND).body(null); // Return 404 Not Found + } +} } diff --git a/myappvs/src/main/java/com/CourseManagementSystem/myappvs/courseDescription/CourseDescriptionDto.java b/myappvs/src/main/java/com/CourseManagementSystem/myappvs/courseDescription/CourseDescriptionDto.java new file mode 100644 index 0000000..8769bb7 --- /dev/null +++ b/myappvs/src/main/java/com/CourseManagementSystem/myappvs/courseDescription/CourseDescriptionDto.java @@ -0,0 +1,28 @@ +package com.CourseManagementSystem.myappvs.courseDescription; + +import com.CourseManagementSystem.myappvs.courseCatalog.Catalog; +import com.CourseManagementSystem.myappvs.instructor.Instructor; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.sql.Time; +import java.util.Date; + +@Data +@AllArgsConstructor +@NoArgsConstructor +public class CourseDescriptionDto { + private Long courseDescriptionId; + private Catalog courseId; + private Instructor instructorId; + private String room; + + private Date date; + + private Time time; + + private String meetingInfo; + + private String materials; +} diff --git a/myappvs/src/main/java/com/CourseManagementSystem/myappvs/courseDescription/CourseDescriptionMapper.java b/myappvs/src/main/java/com/CourseManagementSystem/myappvs/courseDescription/CourseDescriptionMapper.java new file mode 100644 index 0000000..01346c1 --- /dev/null +++ b/myappvs/src/main/java/com/CourseManagementSystem/myappvs/courseDescription/CourseDescriptionMapper.java @@ -0,0 +1,32 @@ +package com.CourseManagementSystem.myappvs.courseDescription; + +import com.CourseManagementSystem.myappvs.courseDescription.CourseDescription; + +public class CourseDescriptionMapper { + public static com.CourseManagementSystem.myappvs.courseDescription.CourseDescription maptoCourseDescription(CourseDescriptionDto courseDescriptionDto){ + com.CourseManagementSystem.myappvs.courseDescription.CourseDescription courseDescription = new com.CourseManagementSystem.myappvs.courseDescription.CourseDescription( + courseDescriptionDto.getCourseDescriptionId(), + courseDescriptionDto.getCourseId(), + courseDescriptionDto.getInstructorId(), + courseDescriptionDto.getRoom(), + courseDescriptionDto.getDate(), + courseDescriptionDto.getTime(), + courseDescriptionDto.getMeetingInfo(), + courseDescriptionDto.getMaterials() + ); + return courseDescription; + } + public static CourseDescriptionDto maptoCourseDescriptionDto(CourseDescription courseDescription){ + CourseDescriptionDto courseDescriptionDto = new CourseDescriptionDto( + courseDescription.getCourseDescriptionId(), + courseDescription.getCourseId(), + courseDescription.getInstructorId(), + courseDescription.getRoom(), + courseDescription.getDate(), + courseDescription.getTime(), + courseDescription.getMeetingInfo(), + courseDescription.getMaterials() + ); + return courseDescriptionDto; + } +} diff --git a/myappvs/src/main/java/com/CourseManagementSystem/myappvs/courseDescription/CourseDescriptionRepository.java b/myappvs/src/main/java/com/CourseManagementSystem/myappvs/courseDescription/CourseDescriptionRepository.java index dedff34..5d5c53e 100644 --- a/myappvs/src/main/java/com/CourseManagementSystem/myappvs/courseDescription/CourseDescriptionRepository.java +++ b/myappvs/src/main/java/com/CourseManagementSystem/myappvs/courseDescription/CourseDescriptionRepository.java @@ -1,11 +1,14 @@ package com.CourseManagementSystem.myappvs.courseDescription; +import com.CourseManagementSystem.myappvs.courseCatalog.Catalog; import com.CourseManagementSystem.myappvs.courseDescription.CourseDescription; import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; import java.util.Optional; +@Repository +public interface CourseDescriptionRepository extends JpaRepository { -public interface CourseDescriptionRepository extends JpaRepository { + Optional findByCourseId_CourseId(Long courseId); - Optional findByCourseId(Long courseId); } diff --git a/myappvs/src/main/java/com/CourseManagementSystem/myappvs/courseDescription/CourseDescriptionService.java b/myappvs/src/main/java/com/CourseManagementSystem/myappvs/courseDescription/CourseDescriptionService.java index d101717..89d82cd 100644 --- a/myappvs/src/main/java/com/CourseManagementSystem/myappvs/courseDescription/CourseDescriptionService.java +++ b/myappvs/src/main/java/com/CourseManagementSystem/myappvs/courseDescription/CourseDescriptionService.java @@ -1,30 +1,8 @@ package com.CourseManagementSystem.myappvs.courseDescription; -import com.CourseManagementSystem.myappvs.courseDescription.CourseDescription; -import com.CourseManagementSystem.myappvs.courseDescription.CourseDescriptionRepository; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Component; +import com.CourseManagementSystem.myappvs.courseCatalog.Catalog; -import java.util.Optional; - -@Component -public class CourseDescriptionService { - - @Autowired - private CourseDescriptionRepository courseDescriptionRepository; - - public CourseDescriptionService(CourseDescriptionRepository courseDescriptionRepository){ - this.courseDescriptionRepository = courseDescriptionRepository; - } - - - public CourseDescription getCourseDescriptionById(Long id) throws Exception { - Optional optionalCourseDescription = courseDescriptionRepository.findByCourseId(id); - - if(!optionalCourseDescription.isPresent()){ - throw new Exception("Course with " +id+" does not exist"); - } - return optionalCourseDescription.orElse(null); - } +public interface CourseDescriptionService { + CourseDescriptionDto getCourseDetail(Long courseId); } diff --git a/myappvs/src/main/java/com/CourseManagementSystem/myappvs/courseDescription/impl/CourseDescriptionServiceImpl.java b/myappvs/src/main/java/com/CourseManagementSystem/myappvs/courseDescription/impl/CourseDescriptionServiceImpl.java new file mode 100644 index 0000000..afa4725 --- /dev/null +++ b/myappvs/src/main/java/com/CourseManagementSystem/myappvs/courseDescription/impl/CourseDescriptionServiceImpl.java @@ -0,0 +1,27 @@ +package com.CourseManagementSystem.myappvs.courseDescription.impl; + + +import com.CourseManagementSystem.myappvs.courseDescription.*; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +@Service +public class CourseDescriptionServiceImpl implements CourseDescriptionService { + + + private CourseDescriptionRepository courseDescriptionRepository; + + @Autowired + public CourseDescriptionServiceImpl(CourseDescriptionRepository courseDescriptionRepository) { + this.courseDescriptionRepository = courseDescriptionRepository; + } + + @Override + public CourseDescriptionDto getCourseDetail(Long courseId) { + CourseDescription courseDescription= courseDescriptionRepository + .findByCourseId_CourseId(courseId) + .orElseThrow(()-> new RuntimeException("Course Doesn't Exist")); + return CourseDescriptionMapper.maptoCourseDescriptionDto(courseDescription); + } +} diff --git a/myappvs/src/main/java/com/CourseManagementSystem/myappvs/courseDescription/package-info.java b/myappvs/src/main/java/com/CourseManagementSystem/myappvs/courseDescription/package-info.java index d5c70b6..498661a 100644 --- a/myappvs/src/main/java/com/CourseManagementSystem/myappvs/courseDescription/package-info.java +++ b/myappvs/src/main/java/com/CourseManagementSystem/myappvs/courseDescription/package-info.java @@ -2,10 +2,43 @@ /** * The courseDescription entity * This entity has detailed information regarding course which can be accessed after enrolling into the course. - * + * The key components include the CourseDescription entity, the CourseDescriptionRepository, + * the CourseDescriptionService interface and its implementation, the CourseDescriptionController, + * the CourseDescriptionDto, and the CourseDescriptionMapper. *
  • One to one relationship between courseDescription and courseCatalog - *
  • One to one relationship between courseDescription and instructor - * + *
  • Many to one relationship between courseDescription and instructor + * + * Entity class (CourseDescription.java): + * Contains fields such as courseDescriptionId, courseId (references Catalog),instructorId (references Instructor), + * room, date, time, meetingInfo, and materials. + * Annotated with JPA annotations to define the table structure and relationships. + * + * Data Transfer Object (CourseDescriptionDto.java): + * Simplifies data exchange between client and server. + * Contains similar fields to CourseDescription entity for ease of mapping and use in the REST API. + * + * Repository Interface (CourseDescriptionRepository.java): + * Extends JpaRepository to provide CRUD operations. + * Contains a custom query method findByCourseId_CourseId(Long courseId) to find course descriptions by course ID. + * + * Service Interface and Implementation (CourseDescriptionService.java and CourseDescriptionServiceImpl.java): + * Defines the service layer interface for business logic related to course descriptions. + * The implementation class provides the logic for fetching course details using the repository. + * + * Controller (CourseDescriptionController.java): + * Exposes REST API endpoints for course descriptions. + * Contains a GET endpoint /api/coursedescription/{id} to fetch course details by ID. + * Handles exceptions and returns appropriate HTTP status codes. + * + * Mapper (CourseDescriptionMapper.java): + * Provides static methods to map between CourseDescription entity and CourseDescriptionDto. + *Ensures a clear separation between entity and DTO for better manageability and data consistency. + * + * For this page there is frontend page which displays details of course which is HTML file courseDescription.html + * demonstrates how to use the REST API to fetch and display course details in a web page. + * + *Error handling is also done i.e. The controller returns a 404 Not Found status if the course details are not found + * The use of DTOs and mappers ensures that the data transfer between layers is consistent and decoupled from the database entity structure. * @author Shivangi Patel */ package com.CourseManagementSystem.myappvs.courseDescription; diff --git a/myappvs/src/main/java/com/CourseManagementSystem/myappvs/enrollments/CourseEnrollmentRequest.java b/myappvs/src/main/java/com/CourseManagementSystem/myappvs/enrollments/CourseEnrollmentRequest.java new file mode 100644 index 0000000..cfda728 --- /dev/null +++ b/myappvs/src/main/java/com/CourseManagementSystem/myappvs/enrollments/CourseEnrollmentRequest.java @@ -0,0 +1,14 @@ +package com.CourseManagementSystem.myappvs.enrollments; + +public class CourseEnrollmentRequest { + private String courseId; + + // Getters and Setters + public String getCourseId() { + return courseId; + } + + public void setCourseId(String courseId) { + this.courseId = courseId; + } +} diff --git a/myappvs/src/main/java/com/CourseManagementSystem/myappvs/courseCatalog/Enrollment.java b/myappvs/src/main/java/com/CourseManagementSystem/myappvs/enrollments/Enrollment.java similarity index 76% rename from myappvs/src/main/java/com/CourseManagementSystem/myappvs/courseCatalog/Enrollment.java rename to myappvs/src/main/java/com/CourseManagementSystem/myappvs/enrollments/Enrollment.java index 4245e50..de558f3 100644 --- a/myappvs/src/main/java/com/CourseManagementSystem/myappvs/courseCatalog/Enrollment.java +++ b/myappvs/src/main/java/com/CourseManagementSystem/myappvs/enrollments/Enrollment.java @@ -1,7 +1,8 @@ -package com.CourseManagementSystem.myappvs.courseCatalog; +package com.CourseManagementSystem.myappvs.enrollments; +import com.CourseManagementSystem.myappvs.courseCatalog.Catalog; import com.CourseManagementSystem.myappvs.student.Student; - +import jakarta.persistence.CascadeType; import jakarta.persistence.Column; import jakarta.persistence.Entity; import jakarta.persistence.GeneratedValue; @@ -12,31 +13,32 @@ import lombok.AllArgsConstructor; import lombok.Data; import lombok.Getter; +import lombok.NoArgsConstructor; import lombok.Setter; +import lombok.ToString; import lombok.ToString.Exclude; @Data @Entity @AllArgsConstructor +@NoArgsConstructor @Getter +@ToString @Setter public class Enrollment { - + @Id @Column(unique = true, name="Enrollment_Id") @GeneratedValue(strategy = GenerationType.IDENTITY) - private Long id; - + private Long id; + @Exclude @ManyToOne @JoinColumn(name = "student_id", referencedColumnName = "studentIdNumber") private Student student; - + @Exclude @ManyToOne @JoinColumn(name = "courseId") private Catalog catalog; - - - } diff --git a/myappvs/src/main/java/com/CourseManagementSystem/myappvs/enrollments/EnrollmentController.java b/myappvs/src/main/java/com/CourseManagementSystem/myappvs/enrollments/EnrollmentController.java new file mode 100644 index 0000000..1279c9d --- /dev/null +++ b/myappvs/src/main/java/com/CourseManagementSystem/myappvs/enrollments/EnrollmentController.java @@ -0,0 +1,86 @@ +package com.CourseManagementSystem.myappvs.enrollments; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.Optional; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RestController; + +import com.CourseManagementSystem.myappvs.student.Student; + +@RestController +@RequestMapping("enroll") +public class EnrollmentController { + + @Autowired + private EnrollmentService enrollmentService; + + @PostMapping("/enrollCourse") + public ResponseEntity> enrollStudentInCourse(@RequestBody CourseEnrollmentRequest request) { + + Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); + + // Check if user is authenticated + if (authentication != null && authentication.isAuthenticated()) { + // Extract user email from authentication principal + String emailId = authentication.getName(); + System.out.println("Email id of student is :" + emailId); + System.out.println("Enrollment Controller triggered"); + + Long id = Long.parseLong(request.getCourseId()); + + enrollmentService.enrollStudent(emailId, id); + return ResponseEntity.ok().build(); + } else { + return ResponseEntity.status(HttpStatus.UNAUTHORIZED).build(); + } + } + + @GetMapping("/test3") + public ResponseEntity testEndpoint() { + return ResponseEntity.ok("Endpoint is working"); + } + + @GetMapping("/showEnrollments") + public List showEnrollments() { + // Retrieve authentication information from SecurityContextHolder + Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); + + // Check if user is authenticated + if (authentication != null && authentication.isAuthenticated()) { + // Extract user email from authentication principal + String emailId = authentication.getName(); + System.out.println("email id the user is "+emailId); + + List currentEnrollments=enrollmentService.getStudentEnrollment(emailId); + return currentEnrollments; + + + } + return null; + } + + @DeleteMapping("/deleteEnrollment/{id}") + public ResponseEntity deleteEnrollment(@PathVariable Long id) { + Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); + + if (authentication != null && authentication.isAuthenticated()) { + enrollmentService.deleteEnrollmentById(id); + return ResponseEntity.ok().build(); + } else { + return ResponseEntity.status(HttpStatus.UNAUTHORIZED).build(); + } + } +} diff --git a/myappvs/src/main/java/com/CourseManagementSystem/myappvs/enrollments/EnrollmentRepository.java b/myappvs/src/main/java/com/CourseManagementSystem/myappvs/enrollments/EnrollmentRepository.java new file mode 100644 index 0000000..5e697a3 --- /dev/null +++ b/myappvs/src/main/java/com/CourseManagementSystem/myappvs/enrollments/EnrollmentRepository.java @@ -0,0 +1,13 @@ +package com.CourseManagementSystem.myappvs.enrollments; + +import java.util.List; +import java.util.Optional; + +import org.springframework.data.jpa.repository.JpaRepository; + +public interface EnrollmentRepository extends JpaRepository{ + + Optional findByStudent_StudentIdNumberAndCatalog_CourseId(Long studentIdNumber, Long courseId); + + List findByStudent_StudentIdNumber(Long studentIdNumber); +} diff --git a/myappvs/src/main/java/com/CourseManagementSystem/myappvs/enrollments/EnrollmentService.java b/myappvs/src/main/java/com/CourseManagementSystem/myappvs/enrollments/EnrollmentService.java new file mode 100644 index 0000000..05f3c75 --- /dev/null +++ b/myappvs/src/main/java/com/CourseManagementSystem/myappvs/enrollments/EnrollmentService.java @@ -0,0 +1,85 @@ +package com.CourseManagementSystem.myappvs.enrollments; + +import java.util.List; +import java.util.Optional; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import com.CourseManagementSystem.myappvs.courseCatalog.Catalog; +import com.CourseManagementSystem.myappvs.courseCatalog.CatalogRepository; +import com.CourseManagementSystem.myappvs.student.Student; +import com.CourseManagementSystem.myappvs.student.Studentrepository; +import jakarta.persistence.EntityManager; + +@Service +public class EnrollmentService { + + @Autowired + private Studentrepository studentRepo; + + @Autowired + private EnrollmentRepository repo; + + @Autowired + private CatalogRepository catalogRepo; + + @Autowired + private EntityManager entityManager; + + @Transactional + public void enrollStudent(String email, Long courseId) { + entityManager.clear(); + Optional op1 = studentRepo.findByEmailId(email); + Student student = op1.get(); + System.out.println(student); + + Optional opt2 = catalogRepo.findById(courseId); + Catalog course = opt2.get(); + System.out.println(course); + + boolean enrollmentExists = repo.findByStudent_StudentIdNumberAndCatalog_CourseId(student.getStudentIdNumber(), course.getCourseId()).isPresent(); + if (enrollmentExists) { + throw new RuntimeException("Enrollment already exists"); + } + + Enrollment enrollment = new Enrollment(); + enrollment.setStudent(student); + enrollment.setCatalog(course); + enrollment.toString(); + + System.out.println(enrollment); + repo.save(enrollment); + } + + public Long getStudentId(String email) { + Optional s = studentRepo.findByEmailId(email); + Student x = s.get(); + long id = x.getStudentIdNumber(); + return id; + } + + public void addSudentEnrollement(Enrollment current) { + repo.save(current); + } + + public List getAllEnrollments() { + return repo.findAll(); + } + + public List getStudentEnrollment(String email) { + Long id = getStudentId(email); + return repo.findByStudent_StudentIdNumber(id); + } + + @Transactional + public void deleteEnrollmentById(Long id) { + Optional enrollmentOpt = repo.findById(id); + if (enrollmentOpt.isPresent()) { + Enrollment enrollment = enrollmentOpt.get(); + enrollment.setStudent(null); // Break relationship + enrollment.setCatalog(null); // Break relationship + repo.delete(enrollment); + } + } +} diff --git a/myappvs/src/main/java/com/CourseManagementSystem/myappvs/enrollments/package-info.java b/myappvs/src/main/java/com/CourseManagementSystem/myappvs/enrollments/package-info.java new file mode 100644 index 0000000..dab4ece --- /dev/null +++ b/myappvs/src/main/java/com/CourseManagementSystem/myappvs/enrollments/package-info.java @@ -0,0 +1,26 @@ +/** + * This Package consists of: + * + * 1.Enrollment Entity: + * This represents the table storing all the enrollments per student for each enrolled course + * + * 2.Enrollment Repository + * This is the JPA Repository class responsible to communicate with enrollment table in the Database. + * + * 3.Enrollment Service + * Service class the fetch student, catalog object and insert an enrollment record into the enrollment table after student enrolls particular course + * + * 4.Enrollment Controller + * Receives the request to post the enrollment of a student. + *
  • One to one relationship between student and user. + * + * 5. CourseEnrollmentRequest + * A DTO object to receive the Enrollment Request + * + * 6. enrollments.html (related Html file in Target folder) + * This is the HTML file containing HTML, CSS, JavaScript code to send appropriate requests and to handle the responses. This is a completely dynamic page. + * + * + * @author Puneeth Talluri + */ +package com.CourseManagementSystem.myappvs.enrollments; \ No newline at end of file diff --git a/myappvs/src/main/java/com/CourseManagementSystem/myappvs/event/Event.java b/myappvs/src/main/java/com/CourseManagementSystem/myappvs/event/Event.java index a423420..abaf662 100644 --- a/myappvs/src/main/java/com/CourseManagementSystem/myappvs/event/Event.java +++ b/myappvs/src/main/java/com/CourseManagementSystem/myappvs/event/Event.java @@ -1,63 +1,26 @@ package com.CourseManagementSystem.myappvs.event; -import com.fasterxml.jackson.annotation.JsonIgnore; - -import jakarta.persistence.Column; -import jakarta.persistence.Entity; -import jakarta.persistence.GeneratedValue; -import jakarta.persistence.Id; -import jakarta.persistence.OneToMany; -import jakarta.persistence.PrimaryKeyJoinColumn; +import org.springframework.data.annotation.Id; +import org.springframework.data.mongodb.core.mapping.Document; -import java.sql.Date; -import java.util.List; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; -import org.springframework.data.mongodb.core.mapping.Document; +import java.time.LocalDate; -@Document(collection = "users") +@Data +@NoArgsConstructor +@AllArgsConstructor +@Document(collection = "events") public class Event { + @Id private String id; - private Date date; - private String title; - private String description; - - public Event(String id, Date date, String title, String description) { - this.id = id; - this.date = date; - this.title = title; - this.description = description; - } - - public String getId() { - return id; - } - - public void setId(String id) { - this.id = id; - } - - public Date getDate() { - return date; - } - - public void setDate(java.util.Date date2) { - this.date = (Date) date2; - } - - public String getTitle() { - return title; - } - - public void setTitle(String title) { - this.title = title; - } - - public String getDescription() { - return description; - } + private LocalDate date; + private String eventName; + private String organizerName; + private String emailId; - public void setDescription(String description) { - this.description = description; - } -} + // Getters and Setters +} \ No newline at end of file diff --git a/myappvs/src/main/java/com/CourseManagementSystem/myappvs/event/EventController.java b/myappvs/src/main/java/com/CourseManagementSystem/myappvs/event/EventController.java index 15c5408..5e291dd 100644 --- a/myappvs/src/main/java/com/CourseManagementSystem/myappvs/event/EventController.java +++ b/myappvs/src/main/java/com/CourseManagementSystem/myappvs/event/EventController.java @@ -1,29 +1,81 @@ package com.CourseManagementSystem.myappvs.event; -import java.util.Date; -import java.util.List; - import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.format.annotation.DateTimeFormat; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestParam; -import org.springframework.web.bind.annotation.RestController; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.security.core.userdetails.UserDetails; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; + +import java.time.LocalDate; +import java.util.List; @RestController +@RequestMapping("/events") public class EventController { @Autowired - private Eventservice eventService; + private Eventrepo eventRepository; + + // Get events by date + @GetMapping("/{date}") + public List getEventsByDate(@PathVariable LocalDate date) { + return eventRepository.findByDate(date); + } + + // Create a new event + @PostMapping + public Event createEvent(@Validated @RequestBody Event event) { + UserDetails userDetails = (UserDetails) SecurityContextHolder.getContext().getAuthentication().getPrincipal(); + event.setEmailId(userDetails.getUsername()); // Set the emailId from the authenticated user + return eventRepository.save(event); + } + + // Update an event + @PutMapping("/{id}") + public ResponseEntity updateEvent(@PathVariable String id, @Validated @RequestBody Event eventDetails) { + UserDetails userDetails = (UserDetails) SecurityContextHolder.getContext().getAuthentication().getPrincipal(); + String authenticatedUserEmail = userDetails.getUsername(); + + Event event = eventRepository.findById(id) + .orElseThrow(() -> new IllegalArgumentException("Event not found")); + + // Check if the authenticated user is the owner of the event + if (!event.getEmailId().equals(authenticatedUserEmail)) { + return ResponseEntity.status(HttpStatus.FORBIDDEN) + .body("You are not authorized to update this event. This event is not hosted by you."); + } + + event.setDate(eventDetails.getDate()); + event.setEventName(eventDetails.getEventName()); + + final Event updatedEvent = eventRepository.save(event); + return ResponseEntity.ok(updatedEvent); + } + + // Delete an event + @DeleteMapping("/{id}") + public ResponseEntity deleteEvent(@PathVariable String id) { + UserDetails userDetails = (UserDetails) SecurityContextHolder.getContext().getAuthentication().getPrincipal(); + String authenticatedUserEmail = userDetails.getUsername(); + + Event event = eventRepository.findById(id) + .orElseThrow(() -> new IllegalArgumentException("Event not found")); + + // Check if the authenticated user is the owner of the event + if (!event.getEmailId().equals(authenticatedUserEmail)) { + return ResponseEntity.status(HttpStatus.FORBIDDEN) + .body("You are not authorized to delete this event. This event is not hosted by you."); + } - @PostMapping("/events") - public Event addEvent(@RequestBody Event event) { - return eventService.saveEvent(event); + eventRepository.delete(event); + return ResponseEntity.ok().build(); } - @GetMapping("/events") - public List getEventsByDate(@RequestBody Date date) { - return eventService.getEventsByDate(date); + // Get all events + @GetMapping + public List getAllEvents() { + return eventRepository.findAll(); } -} +} \ No newline at end of file diff --git a/myappvs/src/main/java/com/CourseManagementSystem/myappvs/event/Eventrepo.java b/myappvs/src/main/java/com/CourseManagementSystem/myappvs/event/Eventrepo.java new file mode 100644 index 0000000..293b976 --- /dev/null +++ b/myappvs/src/main/java/com/CourseManagementSystem/myappvs/event/Eventrepo.java @@ -0,0 +1,12 @@ +package com.CourseManagementSystem.myappvs.event; + +import com.CourseManagementSystem.myappvs.event.Event; +import org.springframework.data.mongodb.repository.MongoRepository; + +import java.time.LocalDate; +import java.util.List; + +public interface Eventrepo extends MongoRepository { + List findByDate(LocalDate date); + +} \ No newline at end of file diff --git a/myappvs/src/main/java/com/CourseManagementSystem/myappvs/event/Eventrepository.java b/myappvs/src/main/java/com/CourseManagementSystem/myappvs/event/Eventrepository.java deleted file mode 100644 index 8d2e53d..0000000 --- a/myappvs/src/main/java/com/CourseManagementSystem/myappvs/event/Eventrepository.java +++ /dev/null @@ -1,14 +0,0 @@ -package com.CourseManagementSystem.myappvs.event; - -import java.util.Date; -import java.util.List; -import java.util.Optional; - -import org.springframework.data.jpa.repository.JpaRepository; -import org.springframework.data.mongodb.repository.MongoRepository; -import org.springframework.stereotype.Repository; - -@Repository -public interface Eventrepository extends MongoRepository { - List findByDate(Date date); -} diff --git a/myappvs/src/main/java/com/CourseManagementSystem/myappvs/event/Eventservice.java b/myappvs/src/main/java/com/CourseManagementSystem/myappvs/event/Eventservice.java index 9356027..0e4b4a2 100644 --- a/myappvs/src/main/java/com/CourseManagementSystem/myappvs/event/Eventservice.java +++ b/myappvs/src/main/java/com/CourseManagementSystem/myappvs/event/Eventservice.java @@ -1,31 +1,16 @@ package com.CourseManagementSystem.myappvs.event; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; -import org.springframework.web.bind.annotation.RequestBody; -import java.util.Date; +import java.time.LocalDate; import java.util.List; -import java.util.Optional; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Component; @Service -public class Eventservice { - @Autowired - private Eventrepository eventRepository; - - public Event saveEvent(@RequestBody Event event) { - // Example validation: Ensure event title is not empty - if (event.getTitle() == null || event.getTitle().isEmpty()) { - throw new IllegalArgumentException("Event title cannot be empty"); - } - - return eventRepository.save(event); - } +public interface Eventservice { + List getEventsByDate(LocalDate date); - public List getEventsByDate(Date date) { - return eventRepository.findByDate(date); - } + Event createEvent(Event event); -} + List getAllEvents(); +} \ No newline at end of file diff --git a/myappvs/src/main/java/com/CourseManagementSystem/myappvs/instructor/Instructor.java b/myappvs/src/main/java/com/CourseManagementSystem/myappvs/instructor/Instructor.java index 967a4e1..e0cf202 100644 --- a/myappvs/src/main/java/com/CourseManagementSystem/myappvs/instructor/Instructor.java +++ b/myappvs/src/main/java/com/CourseManagementSystem/myappvs/instructor/Instructor.java @@ -4,10 +4,16 @@ import jakarta.persistence.Entity; import jakarta.persistence.Id; import jakarta.persistence.Table; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; import java.sql.Time; @Entity +@Getter +@NoArgsConstructor +@AllArgsConstructor @Table(name = "Instructor") public class Instructor { @@ -17,61 +23,11 @@ public class Instructor { private String instructorName; + private String instructorDescription; private Time meetingHours; private String instructorCabinLocation; - public Instructor(){ - - } - - public Instructor(long instructorId, String instructorName, String instructorDescription, Time meetingHours, String instructorCabinLocation){ - this.instructorId = instructorId; - this.instructorName = instructorName; - this.instructorDescription = instructorDescription; - this.meetingHours = meetingHours; - this.instructorCabinLocation = instructorCabinLocation; - } - - public long getInstructorId() { - return instructorId; - } - - public void setInstructorId(long instructorId) { - this.instructorId = instructorId; - } - - public String getInstructorCabinLocation() { - return instructorCabinLocation; - } - - public String getInstructorDescription() { - return instructorDescription; - } - - public String getInstructorName() { - return instructorName; - } - - public Time getMeetingHours() { - return meetingHours; - } - - public void setInstructorCabinLocation(String instructorCabinLocation) { - this.instructorCabinLocation = instructorCabinLocation; - } - - public void setInstructorDescription(String instructorDescription) { - this.instructorDescription = instructorDescription; - } - - public void setInstructorName(String instructorName) { - this.instructorName = instructorName; - } - - public void setMeetingHours(Time meetingHours) { - this.meetingHours = meetingHours; - } -} +} \ No newline at end of file diff --git a/myappvs/src/main/java/com/CourseManagementSystem/myappvs/instructor/InstructorController.java b/myappvs/src/main/java/com/CourseManagementSystem/myappvs/instructor/InstructorController.java new file mode 100644 index 0000000..518f0df --- /dev/null +++ b/myappvs/src/main/java/com/CourseManagementSystem/myappvs/instructor/InstructorController.java @@ -0,0 +1,31 @@ +package com.CourseManagementSystem.myappvs.instructor; + +import com.CourseManagementSystem.myappvs.courseDescription.CourseDescriptionDto; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequestMapping("/api/instructor") +public class InstructorController { + + InstructorService instructorService; + + public InstructorController(InstructorService instructorService) { + this.instructorService = instructorService; + } + //Get Instructor Rest Api + @GetMapping("/{id}") + public ResponseEntity getIndtructorbyId(@PathVariable Long id){ + + try { + InstructorDto instructorDto = instructorService.getInstructorDetail(id); + return ResponseEntity.ok(instructorDto); + } catch (RuntimeException e) { + return ResponseEntity.status(HttpStatus.NOT_FOUND).body(null); // Return 404 Not Found + } + } +} diff --git a/myappvs/src/main/java/com/CourseManagementSystem/myappvs/instructor/InstructorDto.java b/myappvs/src/main/java/com/CourseManagementSystem/myappvs/instructor/InstructorDto.java new file mode 100644 index 0000000..b5b8de3 --- /dev/null +++ b/myappvs/src/main/java/com/CourseManagementSystem/myappvs/instructor/InstructorDto.java @@ -0,0 +1,22 @@ +package com.CourseManagementSystem.myappvs.instructor; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.sql.Time; +@NoArgsConstructor +@AllArgsConstructor +@Data +public class InstructorDto { + private long instructorId; + + private String instructorName; + + + private String instructorDescription; + + private Time meetingHours; + + private String instructorCabinLocation; +} diff --git a/myappvs/src/main/java/com/CourseManagementSystem/myappvs/instructor/InstructorMapper.java b/myappvs/src/main/java/com/CourseManagementSystem/myappvs/instructor/InstructorMapper.java new file mode 100644 index 0000000..9f6a15f --- /dev/null +++ b/myappvs/src/main/java/com/CourseManagementSystem/myappvs/instructor/InstructorMapper.java @@ -0,0 +1,28 @@ +package com.CourseManagementSystem.myappvs.instructor; + +import com.CourseManagementSystem.myappvs.courseDescription.CourseDescription; +import com.CourseManagementSystem.myappvs.courseDescription.CourseDescriptionDto; + +public class InstructorMapper { + public static Instructor maptoInstructor(InstructorDto instructorDto){ + Instructor instructor= new Instructor( + instructorDto.getInstructorId(), + instructorDto.getInstructorName(), + instructorDto.getInstructorDescription(), + instructorDto.getMeetingHours(), + instructorDto.getInstructorCabinLocation() + ); + return instructor; + } + public static InstructorDto maptoInstructorDto(Instructor instructor){ + InstructorDto instructorDto= new InstructorDto( + instructor.getInstructorId(), + instructor.getInstructorName(), + instructor.getInstructorDescription(), + instructor.getMeetingHours(), + instructor.getInstructorCabinLocation() + ); + return instructorDto; + } + +} diff --git a/myappvs/src/main/java/com/CourseManagementSystem/myappvs/instructor/InstructorRepository.java b/myappvs/src/main/java/com/CourseManagementSystem/myappvs/instructor/InstructorRepository.java index 4ad7a52..65cb992 100644 --- a/myappvs/src/main/java/com/CourseManagementSystem/myappvs/instructor/InstructorRepository.java +++ b/myappvs/src/main/java/com/CourseManagementSystem/myappvs/instructor/InstructorRepository.java @@ -1,7 +1,11 @@ package com.CourseManagementSystem.myappvs.instructor; import com.CourseManagementSystem.myappvs.instructor.Instructor; +import com.CourseManagementSystem.myappvs.studentAccounts.StudentAccounts; import org.springframework.data.jpa.repository.JpaRepository; +import java.util.Optional; + public interface InstructorRepository extends JpaRepository { + Optional findByInstructorId(Long instructorId); } diff --git a/myappvs/src/main/java/com/CourseManagementSystem/myappvs/instructor/InstructorService.java b/myappvs/src/main/java/com/CourseManagementSystem/myappvs/instructor/InstructorService.java new file mode 100644 index 0000000..25c5de7 --- /dev/null +++ b/myappvs/src/main/java/com/CourseManagementSystem/myappvs/instructor/InstructorService.java @@ -0,0 +1,19 @@ +package com.CourseManagementSystem.myappvs.instructor; + + +import org.springframework.stereotype.Service; + +@Service +public class InstructorService { + private InstructorRepository instructorRepository; + + public InstructorService(InstructorRepository instructorRepository) { + this.instructorRepository = instructorRepository; + } + public InstructorDto getInstructorDetail(Long instructorId) { + Instructor instructor = instructorRepository + .findByInstructorId(instructorId) + .orElseThrow(()-> new RuntimeException("Instructor Doesn't Exist")); + return InstructorMapper.maptoInstructorDto(instructor); + } +} diff --git a/myappvs/src/main/java/com/CourseManagementSystem/myappvs/instructor/package-info.java b/myappvs/src/main/java/com/CourseManagementSystem/myappvs/instructor/package-info.java index 37730e1..87b24c3 100644 --- a/myappvs/src/main/java/com/CourseManagementSystem/myappvs/instructor/package-info.java +++ b/myappvs/src/main/java/com/CourseManagementSystem/myappvs/instructor/package-info.java @@ -2,7 +2,39 @@ /** * The instructor entity *This entity consist information regarding instructor. + * The key components include the Instructor entity, the InstructorRepository, the InstructorService, + * the InstructorController, the InstructorDto, and the InstructorMapper. * + * This package manages the instructor details, including fetching and displaying detailed information about each instructor + * + * Entity Class (Instructor.java): + * Contains fields such as instructorId, instructorName, instructorDescription, meetingHours, and instructorCabinLocation. + * Annotated with JPA annotations to define the table structure and relationships. + * + * Data Transfer Object (InstructorDto.java): + * Simplifies data exchange between client and server. + * Contains similar fields to Instructor entity for ease of mapping and use in the REST API. + * + * Repository Interface (InstructorRepository.java): + * Extends JpaRepository to provide CRUD operations. + * Contains a custom query method findByInstructorId(Long instructorId) to find instructor details by instructor ID. + * + * Service Class (InstructorService.java): + * Implements the service layer for business logic related to instructor details. + * Provides the logic for fetching instructor details using the repository. + * Throws a RuntimeException if the instructor is not found. + * + * Controller (InstructorController.java): + * Exposes REST API endpoints for instructor details. + * Contains a GET endpoint /api/instructor/{id} to fetch instructor details by ID. + * Handles exceptions and returns appropriate HTTP status codes. + * + * Mapper (InstructorMapper.java): + * + * Provides static methods to map between Instructor entity and InstructorDto. + * Ensures a clear separation between entity and DTO for better manageability and data consistency. + * + * All the instructor details are displayed on course description page so that students are able to access those details. * @author Shivangi Patel */ package com.CourseManagementSystem.myappvs.instructor; diff --git a/myappvs/src/main/java/com/CourseManagementSystem/myappvs/profile/Profilecontroller.java b/myappvs/src/main/java/com/CourseManagementSystem/myappvs/profile/Profilecontroller.java new file mode 100644 index 0000000..ecc6640 --- /dev/null +++ b/myappvs/src/main/java/com/CourseManagementSystem/myappvs/profile/Profilecontroller.java @@ -0,0 +1,106 @@ +package com.CourseManagementSystem.myappvs.profile; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.web.bind.annotation.*; + +import com.CourseManagementSystem.myappvs.student.Student; +import com.CourseManagementSystem.myappvs.student.Studentrepository; + +import java.util.Map; +import java.util.Optional; + +@RestController +@RequestMapping("/api/v1/profile") +public class Profilecontroller { + + @Autowired + private Studentrepository studentRepository; + + @GetMapping + public ResponseEntity> showProfile() { + // Retrieve authentication information from SecurityContextHolder + Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); + + // Check if user is authenticated + if (authentication != null && authentication.isAuthenticated()) { + // Extract user email from authentication principal + String emailId = authentication.getName(); + System.out.println("email id the user is "+emailId); + + + // Fetch user profile using email + Optional student = studentRepository.findByEmailId(emailId); + if (student.isPresent()) { + Student studentOp = student.get(); + // Construct a map to hold the profile data + Map profileData = Map.of( + "emailId", studentOp.getEmailId(), + "name", studentOp.getName(), + "studentIdNumber", studentOp.getStudentIdNumber(), + "number", studentOp.getNumber()); + // Return the profile data as JSON response + return ResponseEntity.ok(profileData); + } else { + return ResponseEntity.notFound().build(); + } + } else { + // User is not authenticated + return ResponseEntity.status(HttpStatus.UNAUTHORIZED).build(); + } + } + + @PutMapping + public ResponseEntity updateProfile(@RequestBody Student updatedStudent) { + // Retrieve authentication information from SecurityContextHolder + Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); + + // Check if user is authenticated + if (authentication != null && authentication.isAuthenticated()) { + // Extract user email from authentication principal + String emailId = authentication.getName(); + + // Fetch user profile using email + Optional existingStudent = studentRepository.findByEmailId(emailId); + if (existingStudent.isPresent()) { + Student student = existingStudent.get(); + student.setName(updatedStudent.getName()); + student.setNumber(updatedStudent.getNumber()); + studentRepository.save(student); + return ResponseEntity.ok().build(); + } else { + return ResponseEntity.notFound().build(); + } + } else { + // User is not authenticated + return ResponseEntity.status(HttpStatus.UNAUTHORIZED).build(); + } + } + + @DeleteMapping + public ResponseEntity deleteProfile() { + // Retrieve authentication information from SecurityContextHolder + Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); + + // Check if user is authenticated + if (authentication != null && authentication.isAuthenticated()) { + // Extract user email from authentication principal + String emailId = authentication.getName(); + + // Fetch user profile using email + Optional student = studentRepository.findByEmailId(emailId); + if (student.isPresent()) { + studentRepository.delete(student.get()); + return ResponseEntity.ok().build(); + } else { + return ResponseEntity.notFound().build(); + } + } else { + // User is not authenticated + return ResponseEntity.status(HttpStatus.UNAUTHORIZED).build(); + } + } +} \ No newline at end of file diff --git a/myappvs/src/main/java/com/CourseManagementSystem/myappvs/profile/package-info.java b/myappvs/src/main/java/com/CourseManagementSystem/myappvs/profile/package-info.java new file mode 100644 index 0000000..184dbb8 --- /dev/null +++ b/myappvs/src/main/java/com/CourseManagementSystem/myappvs/profile/package-info.java @@ -0,0 +1,8 @@ +/** + * This package helps to display the data of the particular user which signed + * in. + * + * @author Jay Rashmitbhai Patel + */ + +package com.CourseManagementSystem.myappvs.profile; diff --git a/myappvs/src/main/java/com/CourseManagementSystem/myappvs/rentals/Equipment.java b/myappvs/src/main/java/com/CourseManagementSystem/myappvs/rentals/Equipment.java new file mode 100644 index 0000000..c96f9ac --- /dev/null +++ b/myappvs/src/main/java/com/CourseManagementSystem/myappvs/rentals/Equipment.java @@ -0,0 +1,47 @@ +package com.CourseManagementSystem.myappvs.rentals; +import com.fasterxml.jackson.annotation.JsonIgnore; + +import jakarta.persistence.CascadeType; +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.FetchType; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.OneToMany; +import jakarta.persistence.OneToOne; +import jakarta.persistence.PrimaryKeyJoinColumn; +import jakarta.persistence.Table; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; +import java.util.List; + +@Entity +@Table(name = "Inventory") +@Data +public class Equipment { + @Id + @GeneratedValue(strategy = GenerationType.AUTO) + @Column(name = "resource_id") + private Long resourceId; + + @Column(name = "resource_name", nullable = false) + private String resourceName; + + @Column(name = "type", nullable = false) + private String type; // E.g., laptop, projector + + @Column(name = "status", nullable = false) + private String status; + + @Column(name = "max_quantity", nullable = false) + private int maxQuantity; + + @Column(name = "available_quantity", nullable = false) + private int availableQuantity; + + @OneToMany(mappedBy = "equipment", fetch = FetchType.LAZY, cascade = CascadeType.ALL) + @JsonIgnore + private List rentals; +} \ No newline at end of file diff --git a/myappvs/src/main/java/com/CourseManagementSystem/myappvs/rentals/EquipmentApiController.java b/myappvs/src/main/java/com/CourseManagementSystem/myappvs/rentals/EquipmentApiController.java new file mode 100644 index 0000000..c98ac62 --- /dev/null +++ b/myappvs/src/main/java/com/CourseManagementSystem/myappvs/rentals/EquipmentApiController.java @@ -0,0 +1,22 @@ +package com.CourseManagementSystem.myappvs.rentals; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import java.util.List; + +@RestController +@RequestMapping("/api/inventory") +public class EquipmentApiController { + + @Autowired + private EquipmentService equipmentService; + + @GetMapping + public List getInventory() { + return equipmentService.findAll(); + } +} + diff --git a/myappvs/src/main/java/com/CourseManagementSystem/myappvs/rentals/EquipmentController.java b/myappvs/src/main/java/com/CourseManagementSystem/myappvs/rentals/EquipmentController.java new file mode 100644 index 0000000..33e7da9 --- /dev/null +++ b/myappvs/src/main/java/com/CourseManagementSystem/myappvs/rentals/EquipmentController.java @@ -0,0 +1,100 @@ +package com.CourseManagementSystem.myappvs.rentals; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.stereotype.Controller; +import org.springframework.ui.Model; +import org.springframework.web.bind.annotation.*; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import java.time.LocalDate; +import java.util.List; + +@Controller +@RequestMapping("/inventory") +public class EquipmentController { + private static final Logger logger = LoggerFactory.getLogger(EquipmentService.class); + + + @Autowired + private EquipmentService equipmentService; + + @Autowired + private RentalService rentalService; + + @GetMapping + public String getInventoryList(Model model) { + List inventoryList = equipmentService.findAll(); + model.addAttribute("inventoryList", inventoryList); + return "inventory"; + } + + @PostMapping(value = "/rent", consumes = "application/json") + public ResponseEntity rentEquipment(@RequestBody RentalRequest request) { + Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); + if (authentication != null && authentication.isAuthenticated()) { + String userEmail = authentication.getName(); + LocalDate rentalDate = LocalDate.parse(request.getRentalDate()); + LocalDate returnDate = LocalDate.parse(request.getReturnDate()); + String message = rentalService.rentEquipment(userEmail, request.getEquipmentId(), rentalDate, returnDate); + if (message.equals("Rental successful!")) { + return ResponseEntity.ok(message); + } else { + return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(message); + } + } else { + return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body("You need to be logged in to rent equipment."); + } + } + + @GetMapping("/rentals") + public String getAllRentals(Model model) { + List rentalList = rentalService.findAllRentals(); + model.addAttribute("rentalList", rentalList); + return "rentals"; + } + + @GetMapping("/userRentals") + public ResponseEntity> getUserRentals() { + Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); + if (authentication != null && authentication.isAuthenticated()) { + String userEmail = authentication.getName(); + List rentals = rentalService.getUserRentals(userEmail); + return ResponseEntity.ok(rentals); + } else { + return ResponseEntity.status(HttpStatus.UNAUTHORIZED).build(); + } + } + + @PostMapping("/add") + public ResponseEntity addEquipment(@RequestBody Equipment equipment) { + logger.info("Creating Equipment"); + Equipment newEquipment = equipmentService.save(equipment); + logger.info("Created Equipment"); + return new ResponseEntity<>(newEquipment, HttpStatus.CREATED); + } + + @GetMapping("/{id}") + public ResponseEntity getEquipmentById(@PathVariable Long id) { + logger.info("Received request to get equipment with id: {}", id); + + Equipment equipment = equipmentService.findById(id).orElse(null); + if (equipment != null) { + logger.info("Sending response for equipment with id: {}", id); + return new ResponseEntity<>(equipment, HttpStatus.OK); + + } else { + return new ResponseEntity<>(HttpStatus.NOT_FOUND); + } + } + + @DeleteMapping("/delete/{id}") + public ResponseEntity deleteEquipment(@PathVariable Long id) { + logger.info("Received request to delete equipment with id: {}", id); + equipmentService.deleteById(id); + logger.info("Deleted equipment with id: {}", id); + return ResponseEntity.ok().build(); + } +} diff --git a/myappvs/src/main/java/com/CourseManagementSystem/myappvs/rentals/EquipmentRepository.java b/myappvs/src/main/java/com/CourseManagementSystem/myappvs/rentals/EquipmentRepository.java new file mode 100644 index 0000000..6d27067 --- /dev/null +++ b/myappvs/src/main/java/com/CourseManagementSystem/myappvs/rentals/EquipmentRepository.java @@ -0,0 +1,11 @@ +package com.CourseManagementSystem.myappvs.rentals; + +import java.util.List; +import java.util.Optional; + +import org.springframework.data.jpa.repository.JpaRepository; + +public interface EquipmentRepository extends JpaRepository { + + List findByStatus(String status); +} \ No newline at end of file diff --git a/myappvs/src/main/java/com/CourseManagementSystem/myappvs/rentals/EquipmentService.java b/myappvs/src/main/java/com/CourseManagementSystem/myappvs/rentals/EquipmentService.java new file mode 100644 index 0000000..738f938 --- /dev/null +++ b/myappvs/src/main/java/com/CourseManagementSystem/myappvs/rentals/EquipmentService.java @@ -0,0 +1,41 @@ +package com.CourseManagementSystem.myappvs.rentals; + +import org.springframework.stereotype.Service; +import org.springframework.web.bind.annotation.RequestBody; + +import java.util.Date; +import java.util.List; +import java.util.Optional; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +@Service +public class EquipmentService { + private static final Logger logger = LoggerFactory.getLogger(EquipmentService.class); + + @Autowired + private EquipmentRepository equipmentRepository; + + public List findAll() { + logger.info("Fetching all equipment"); + return equipmentRepository.findAll(); + } + + public Optional findById(Long id) { + logger.info("Fetching equipment by id: {}", id); + return equipmentRepository.findById(id); + } + + public Equipment save(Equipment equipment) { + logger.info("Saving equipment: {}", equipment); + return equipmentRepository.save(equipment); + } + + public void deleteById(Long id) { + logger.info("Deleting equipment by id: {}", id); + equipmentRepository.deleteById(id); + } + } diff --git a/myappvs/src/main/java/com/CourseManagementSystem/myappvs/rentals/Rental.java b/myappvs/src/main/java/com/CourseManagementSystem/myappvs/rentals/Rental.java new file mode 100644 index 0000000..e26014e --- /dev/null +++ b/myappvs/src/main/java/com/CourseManagementSystem/myappvs/rentals/Rental.java @@ -0,0 +1,64 @@ +package com.CourseManagementSystem.myappvs.rentals; +import jakarta.persistence.*; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; +import java.time.LocalDate; + +@Entity +public class Rental { + @Id + @GeneratedValue(strategy = GenerationType.AUTO) + private Long id; + + @ManyToOne + @JoinColumn(name = "equipment_id") + private Equipment equipment; + + private String userEmail; + private LocalDate rentalDate; + private LocalDate returnDate; + + // Getters and Setters + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public Equipment getEquipment() { + return equipment; + } + + public void setEquipment(Equipment equipment) { + this.equipment = equipment; + } + + public String getUserEmail() { + return userEmail; + } + + public void setUserEmail(String userEmail) { + this.userEmail = userEmail; + } + + public LocalDate getRentalDate() { + return rentalDate; + } + + public void setRentalDate(LocalDate rentalDate) { + this.rentalDate = rentalDate; + } + + public LocalDate getReturnDate() { + return returnDate; + } + + public void setReturnDate(LocalDate returnDate) { + this.returnDate = returnDate; + } +} + + diff --git a/myappvs/src/main/java/com/CourseManagementSystem/myappvs/rentals/RentalController.java b/myappvs/src/main/java/com/CourseManagementSystem/myappvs/rentals/RentalController.java new file mode 100644 index 0000000..7989e76 --- /dev/null +++ b/myappvs/src/main/java/com/CourseManagementSystem/myappvs/rentals/RentalController.java @@ -0,0 +1,74 @@ +package com.CourseManagementSystem.myappvs.rentals; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.web.bind.annotation.*; + +import java.time.LocalDate; +import java.util.List; +@RestController +@RequestMapping("/rentals") +public class RentalController { + private static final Logger logger = LoggerFactory.getLogger(RentalController.class); + + @Autowired + private RentalService rentalService; + + @PostMapping("/rent") + public ResponseEntity rentEquipment(@RequestBody RentalRequest request) { + logger.info("Received rent equipment request: {}", request); + Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); + if (authentication != null && authentication.isAuthenticated()) { + String userEmail = authentication.getName(); + logger.info("User authenticated: {}", userEmail); + LocalDate rentalDate = LocalDate.parse(request.getRentalDate()); + LocalDate returnDate = LocalDate.parse(request.getReturnDate()); + String message = rentalService.rentEquipment(userEmail, request.getEquipmentId(), rentalDate, returnDate); + if (message.equals("Rental successful!")) { + logger.info("Rental successful for user: {}, equipmentId: {}", userEmail, request.getEquipmentId()); + return ResponseEntity.ok().build(); + } else { + logger.warn("Rental failed for user: {}, equipmentId: {}. Reason: {}", userEmail, request.getEquipmentId(), message); + return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(message); + } + } else { + logger.warn("Unauthorized rental attempt."); + return ResponseEntity.status(HttpStatus.UNAUTHORIZED).build(); + } + } + + @GetMapping("/userRentals") + public List getUserRentals() { + logger.info("Received request to get user rentals"); + Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); + if (authentication != null && authentication.isAuthenticated()) { + String userEmail = authentication.getName(); + logger.info("User authenticated: {}", userEmail); + + return rentalService.getUserRentals(userEmail); + } + logger.warn("Unauthorized request to get user rentals"); + return null; + } + + @DeleteMapping("/deleteRental/{id}") + public ResponseEntity deleteRental(@PathVariable Long id) { + logger.info("Received request to delete rental with id: {}", id); + Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); + if (authentication != null && authentication.isAuthenticated()) { + rentalService.deleteRentalById(id); + logger.info("Rental with id: {} deleted successfully", id); + + return ResponseEntity.ok().build(); + } else { + logger.warn("Unauthorized attempt to delete rental with id: {}", id); + + return ResponseEntity.status(HttpStatus.UNAUTHORIZED).build(); + } + } +} \ No newline at end of file diff --git a/myappvs/src/main/java/com/CourseManagementSystem/myappvs/rentals/RentalRepository.java b/myappvs/src/main/java/com/CourseManagementSystem/myappvs/rentals/RentalRepository.java new file mode 100644 index 0000000..30cd4d7 --- /dev/null +++ b/myappvs/src/main/java/com/CourseManagementSystem/myappvs/rentals/RentalRepository.java @@ -0,0 +1,14 @@ +package com.CourseManagementSystem.myappvs.rentals; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; +import com.CourseManagementSystem.myappvs.rentals.Rental; + +import java.time.LocalDate; +import java.util.List; + +@Repository + +public interface RentalRepository extends JpaRepository { + List findByUserEmail(String userEmail); + boolean existsByUserEmailAndEquipmentAndReturnDateAfter(String userEmail, Equipment equipment, LocalDate returnDate); +} diff --git a/myappvs/src/main/java/com/CourseManagementSystem/myappvs/rentals/RentalRequest.java b/myappvs/src/main/java/com/CourseManagementSystem/myappvs/rentals/RentalRequest.java new file mode 100644 index 0000000..92090d4 --- /dev/null +++ b/myappvs/src/main/java/com/CourseManagementSystem/myappvs/rentals/RentalRequest.java @@ -0,0 +1,32 @@ +package com.CourseManagementSystem.myappvs.rentals; + +public class RentalRequest { + private Long equipmentId; + private String rentalDate; + private String returnDate; + + // Getters and Setters + public Long getEquipmentId() { + return equipmentId; + } + + public void setEquipmentId(Long equipmentId) { + this.equipmentId = equipmentId; + } + + public String getRentalDate() { + return rentalDate; + } + + public void setRentalDate(String rentalDate) { + this.rentalDate = rentalDate; + } + + public String getReturnDate() { + return returnDate; + } + + public void setReturnDate(String returnDate) { + this.returnDate = returnDate; + } +} \ No newline at end of file diff --git a/myappvs/src/main/java/com/CourseManagementSystem/myappvs/rentals/RentalService.java b/myappvs/src/main/java/com/CourseManagementSystem/myappvs/rentals/RentalService.java new file mode 100644 index 0000000..2823ef6 --- /dev/null +++ b/myappvs/src/main/java/com/CourseManagementSystem/myappvs/rentals/RentalService.java @@ -0,0 +1,85 @@ +package com.CourseManagementSystem.myappvs.rentals; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import java.util.List; +import java.util.Optional; +import java.time.LocalDate; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.time.LocalDate; +import java.util.List; +import java.util.Optional; + +@Service +public class RentalService { + private static final Logger logger = LoggerFactory.getLogger(RentalService.class); + + @Autowired + private RentalRepository rentalRepository; + + @Autowired + private EquipmentRepository equipmentRepository; + + @Transactional + public String rentEquipment(String userEmail, Long equipmentId, LocalDate rentalDate, LocalDate returnDate) { + logger.info("Received rent equipment request: userEmail: {}, equipmentId: {}, rentalDate: {}, returnDate: {}", userEmail, equipmentId, rentalDate, returnDate); + Optional optionalEquipment = equipmentRepository.findById(equipmentId); + if (optionalEquipment.isPresent()) { + Equipment equipment = optionalEquipment.get(); + + // Check if user already rented this equipment + boolean alreadyRented = rentalRepository.existsByUserEmailAndEquipmentAndReturnDateAfter(userEmail, equipment, LocalDate.now()); + if (alreadyRented) { + return "You have already rented this equipment."; + } + + // Check availability + if (equipment.getAvailableQuantity() > 0) { + equipment.setAvailableQuantity(equipment.getAvailableQuantity() - 1); + equipmentRepository.save(equipment); + + Rental rental = new Rental(); + rental.setEquipment(equipment); + rental.setUserEmail(userEmail); + rental.setRentalDate(rentalDate); + rental.setReturnDate(returnDate); + rentalRepository.save(rental); + logger.info("Rental successful for user: {}, equipmentId: {}", userEmail, equipmentId); + return "Rental successful!"; + } else { + logger.warn("Exceeded limit for rental of item"); + return "No equipment available!"; + } + } else { + logger.warn("Equipment not found"); + return "Equipment not found!"; + } + } + + public List getUserRentals(String userEmail) { + logger.info("Received request to get user rentals for user: {}", userEmail); + return rentalRepository.findByUserEmail(userEmail); + } + + public void deleteRentalById(Long id) { + logger.info("Received request to delete rental with id: {}", id); + rentalRepository.deleteById(id); + } + + public List findAllRentals() { + logger.info("Received request to get all rentals for specific user"); + return rentalRepository.findAll(); + } +} + + + + + diff --git a/myappvs/src/main/java/com/CourseManagementSystem/myappvs/rentals/package-info.java b/myappvs/src/main/java/com/CourseManagementSystem/myappvs/rentals/package-info.java new file mode 100644 index 0000000..388f086 --- /dev/null +++ b/myappvs/src/main/java/com/CourseManagementSystem/myappvs/rentals/package-info.java @@ -0,0 +1,22 @@ +/** + * /** + * + * Added UI elements to display the rental button on the homepage + * Added a new page to display rentals interface and the ability to rent equipment + * Added service to rentals to fetch the data from the tables and display which items are available. + * Will implement service to take out rentals and have them tracked via the rental and Equipment tables + * The rental tables currently are tied to user account info, and are only displayed ot logged-in users + * and keep track of the rentals they have taken out. + * Added One for one between the Rentals repository and the Rental Service + * * Added Logging and unit tests for the Rentals service + * * Added a page to view the user's rentals once they have logged in and rented equipment + * * Used CRUD Operations to create, read, update, and delete rentals + * * Added a page to view all the rentals in the system + * * Added additional finders such as find by status and find by equipment type + * * Added a page to view all the equipment in the system for second repository + * * + * @author Atif Siddiqui + */ + + +package com.CourseManagementSystem.myappvs.rentals; diff --git a/myappvs/src/main/java/com/CourseManagementSystem/myappvs/security/Auth/AuthenticationService.java b/myappvs/src/main/java/com/CourseManagementSystem/myappvs/security/Auth/AuthenticationService.java new file mode 100644 index 0000000..a0ea20e --- /dev/null +++ b/myappvs/src/main/java/com/CourseManagementSystem/myappvs/security/Auth/AuthenticationService.java @@ -0,0 +1,63 @@ +package com.CourseManagementSystem.myappvs.security.Auth; + +import com.CourseManagementSystem.myappvs.security.Controller.AuthenticationResponse; +import com.CourseManagementSystem.myappvs.security.Controller.Authenticationrequest; +import com.CourseManagementSystem.myappvs.security.Controller.Registerrequest; +import com.CourseManagementSystem.myappvs.security.Service.Jwtservice; +import com.CourseManagementSystem.myappvs.student.Student; +import com.CourseManagementSystem.myappvs.student.Studentrepository; +import com.CourseManagementSystem.myappvs.user.Role; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.authentication.AuthenticationManager; +import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; +import org.springframework.security.crypto.password.PasswordEncoder; +import org.springframework.stereotype.Service; +import lombok.RequiredArgsConstructor; + +@Service +@RequiredArgsConstructor +public class AuthenticationService { + + @Autowired + private final Studentrepository srepository; + + @Autowired + private final PasswordEncoder passwordEncoder; + @Autowired + private final Jwtservice jwtService; + @Autowired + private final AuthenticationManager authenticationManager; + + public AuthenticationResponse register(Registerrequest request) { + var student = Student.builder() + .name(request.getName()) + .emailId(request.getEmailId()) + .studentIdNumber(request.getStudentIdNumber()) + .password(passwordEncoder.encode(request.getPassword())) + .role(Role.USER) + .number(request.getNumber()) + .build(); + srepository.save(student); + /* + * var user = User.builder() + * .emailId(request.getEmailId()) + * .password(passwordEncoder.encode(request.getPassword())) + * .role(Role.USER) + * .build(); + * urepository.save(user); + */ + + var jwtToken = jwtService.generateToken(student); + return AuthenticationResponse.builder().token(jwtToken).build(); + } + + public AuthenticationResponse authenticate(Authenticationrequest request) { + authenticationManager.authenticate( + new UsernamePasswordAuthenticationToken(request.getEmailId(), request.getPassword())); + var user = srepository.findByEmailId(request.getEmailId()) + .orElseThrow(() -> new IllegalArgumentException("Invalid email or password.")); + var jwtToken = jwtService.generateToken(user); + return AuthenticationResponse.builder().token(jwtToken).build(); + } +} diff --git a/myappvs/src/main/java/com/CourseManagementSystem/myappvs/security/Auth/JwtAuthresp.java b/myappvs/src/main/java/com/CourseManagementSystem/myappvs/security/Auth/JwtAuthresp.java new file mode 100644 index 0000000..0b5313a --- /dev/null +++ b/myappvs/src/main/java/com/CourseManagementSystem/myappvs/security/Auth/JwtAuthresp.java @@ -0,0 +1,14 @@ +package com.CourseManagementSystem.myappvs.security.Auth; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class JwtAuthresp { + private String token; +} diff --git a/myappvs/src/main/java/com/CourseManagementSystem/myappvs/security/Controller/Authcontrol.java b/myappvs/src/main/java/com/CourseManagementSystem/myappvs/security/Controller/Authcontrol.java new file mode 100644 index 0000000..9efdf5c --- /dev/null +++ b/myappvs/src/main/java/com/CourseManagementSystem/myappvs/security/Controller/Authcontrol.java @@ -0,0 +1,58 @@ +package com.CourseManagementSystem.myappvs.security.Controller; + +import com.CourseManagementSystem.myappvs.security.Auth.AuthenticationService; +import com.CourseManagementSystem.myappvs.security.Service.Jwtservice; +import com.CourseManagementSystem.myappvs.student.Studentrepository; + +import lombok.RequiredArgsConstructor; + +import java.util.HashMap; +import java.util.Map; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.security.authentication.AuthenticationManager; +import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; +import org.springframework.security.core.userdetails.UserDetails; +import org.springframework.web.bind.annotation.*; + +@RestController +@RequestMapping("/api/v1/auth") +@RequiredArgsConstructor +public class Authcontrol { + // private final AuthenticationManager authenticationManager; + // private final Loginservice loginService; + // private final Jwtservice jwtService; + + private final AuthenticationService service; + @Autowired + private Studentrepository studentRepository; + + @PostMapping("/signup") + public ResponseEntity signup(@RequestBody Registerrequest request) { + return ResponseEntity.ok(service.register(request)); + } + + @PostMapping("/login") + public ResponseEntity login(@RequestBody Authenticationrequest request) throws Exception { + return ResponseEntity.ok(service.authenticate(request)); + } + + @GetMapping("/check-email") + public ResponseEntity> checkEmailExists(@RequestParam("email") String email) { + boolean exists = studentRepository.existsByEmailId(email); + Map response = new HashMap<>(); + response.put("exists", exists); + return ResponseEntity.ok(response); + } + + @GetMapping("/check-student-id") + public ResponseEntity> checkStudentIdExists(@RequestParam("studentId") String studentId) { + boolean exists = studentRepository.existsByStudentIdNumber(Long.valueOf(studentId)); + Map response = new HashMap<>(); + response.put("exists", exists); + return ResponseEntity.ok(response); + } + +} \ No newline at end of file diff --git a/myappvs/src/main/java/com/CourseManagementSystem/myappvs/security/Controller/AuthenticationResponse.java b/myappvs/src/main/java/com/CourseManagementSystem/myappvs/security/Controller/AuthenticationResponse.java new file mode 100644 index 0000000..8b24b27 --- /dev/null +++ b/myappvs/src/main/java/com/CourseManagementSystem/myappvs/security/Controller/AuthenticationResponse.java @@ -0,0 +1,14 @@ +package com.CourseManagementSystem.myappvs.security.Controller; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@Builder +@AllArgsConstructor +@NoArgsConstructor +public class AuthenticationResponse { + private String token; +} diff --git a/myappvs/src/main/java/com/CourseManagementSystem/myappvs/security/Controller/Authenticationrequest.java b/myappvs/src/main/java/com/CourseManagementSystem/myappvs/security/Controller/Authenticationrequest.java new file mode 100644 index 0000000..31ade77 --- /dev/null +++ b/myappvs/src/main/java/com/CourseManagementSystem/myappvs/security/Controller/Authenticationrequest.java @@ -0,0 +1,16 @@ +package com.CourseManagementSystem.myappvs.security.Controller; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@Builder +@AllArgsConstructor +@NoArgsConstructor +public class Authenticationrequest { + + private String emailId; + String password; +} diff --git a/myappvs/src/main/java/com/CourseManagementSystem/myappvs/security/Controller/Authoricontrol.java b/myappvs/src/main/java/com/CourseManagementSystem/myappvs/security/Controller/Authoricontrol.java new file mode 100644 index 0000000..d70f38c --- /dev/null +++ b/myappvs/src/main/java/com/CourseManagementSystem/myappvs/security/Controller/Authoricontrol.java @@ -0,0 +1,18 @@ +package com.CourseManagementSystem.myappvs.security.Controller; + +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import lombok.RequiredArgsConstructor; + +@RestController +@RequestMapping("/api/v1/auth/resource") +@RequiredArgsConstructor +public class Authoricontrol { + @GetMapping + public ResponseEntity sayHello() { + return ResponseEntity.ok("Here is your resource"); + } +} diff --git a/myappvs/src/main/java/com/CourseManagementSystem/myappvs/security/Controller/Registerrequest.java b/myappvs/src/main/java/com/CourseManagementSystem/myappvs/security/Controller/Registerrequest.java new file mode 100644 index 0000000..11ace7c --- /dev/null +++ b/myappvs/src/main/java/com/CourseManagementSystem/myappvs/security/Controller/Registerrequest.java @@ -0,0 +1,20 @@ +package com.CourseManagementSystem.myappvs.security.Controller; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@Builder +@AllArgsConstructor +@NoArgsConstructor +public class Registerrequest { + + // For Student table + private String name; + private Long studentIdNumber; + private String emailId; + private String number; + private String password; +} diff --git a/myappvs/src/main/java/com/CourseManagementSystem/myappvs/security/Service/Jwtservice.java b/myappvs/src/main/java/com/CourseManagementSystem/myappvs/security/Service/Jwtservice.java new file mode 100644 index 0000000..8003ccb --- /dev/null +++ b/myappvs/src/main/java/com/CourseManagementSystem/myappvs/security/Service/Jwtservice.java @@ -0,0 +1,71 @@ +package com.CourseManagementSystem.myappvs.security.Service; + +import java.security.Key; +import java.util.Date; +import java.util.HashMap; +import java.util.Map; +import java.util.function.Function; + +import org.springframework.beans.factory.annotation.Value; +import org.springframework.security.core.userdetails.UserDetails; +import org.springframework.stereotype.Service; + +import io.jsonwebtoken.Claims; +import io.jsonwebtoken.Jwts; +import io.jsonwebtoken.SignatureAlgorithm; +import io.jsonwebtoken.io.Decoders; +import io.jsonwebtoken.security.Keys; + +@Service +public class Jwtservice { + + private static final String SECRET_KEY = "cd1ac13dc26636c1bf5c1f8da03432236b53ffb9d0a02b3cfcbeefb6d08a3f5d78fbc75166abf393d967061a78c11b2154d2dce0669d6e1755f2033897b55199"; + + public String extractUserName(String token) { + return extractClaim(token, Claims::getSubject); + }// Done + + public String generateToken(UserDetails userDetails) { + Map claims = new HashMap<>(); + return generateToken(claims, userDetails.getUsername()); + }// Done + + public boolean isTokenValid(String token, UserDetails userDetails) { + final String userName = extractUserName(token); + return userName.equals(userDetails.getUsername()) && !isTokenExpired(token); + }// Done + + private T extractClaim(String token, Function claimsResolvers) { + final Claims claims = extractAllClaims(token); + return claimsResolvers.apply(claims); + }// Done + + private String generateToken(Map claims, String subject) { + return Jwts.builder() + .setClaims(claims) + .setSubject(subject) + .setIssuedAt(new Date(System.currentTimeMillis())) + .setExpiration(new Date(System.currentTimeMillis() + 1000 * 60 * 24)) + .signWith(getSigningKey(), SignatureAlgorithm.HS256) + .compact(); + }// Done + + private boolean isTokenExpired(String token) { + return extractExpiration(token).before(new Date()); + // final Date expiration = extractExpiration(token); + // return expiration.before(new Date()); + }// Done + + private Date extractExpiration(String token) { + return extractClaim(token, Claims::getExpiration); + }// Done + + private Claims extractAllClaims(String token) { + return Jwts.parserBuilder().setSigningKey(getSigningKey()).build().parseClaimsJws(token).getBody(); + }// Done + + private Key getSigningKey() { + byte[] keyBytes = Decoders.BASE64.decode(SECRET_KEY); + return Keys.hmacShaKeyFor(keyBytes); + } // Done +} diff --git a/myappvs/src/main/java/com/CourseManagementSystem/myappvs/security/config/Applicationconfig.java b/myappvs/src/main/java/com/CourseManagementSystem/myappvs/security/config/Applicationconfig.java new file mode 100644 index 0000000..be2179c --- /dev/null +++ b/myappvs/src/main/java/com/CourseManagementSystem/myappvs/security/config/Applicationconfig.java @@ -0,0 +1,58 @@ +package com.CourseManagementSystem.myappvs.security.config; + +import jakarta.persistence.criteria.CriteriaBuilder; +import lombok.RequiredArgsConstructor; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.data.domain.AuditorAware; +import org.springframework.security.authentication.AuthenticationManager; +import org.springframework.security.authentication.AuthenticationProvider; +import org.springframework.security.authentication.dao.DaoAuthenticationProvider; +import org.springframework.security.config.annotation.authentication.configuration.AuthenticationConfiguration; +import org.springframework.security.core.userdetails.UserDetailsService; +import org.springframework.security.core.userdetails.UsernameNotFoundException; +import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; +import org.springframework.security.crypto.password.PasswordEncoder; + +import com.CourseManagementSystem.myappvs.student.Studentrepository; + +@Configuration +@RequiredArgsConstructor +public class Applicationconfig { + + @Autowired + private final Studentrepository srepository; + + @Bean + public UserDetailsService userDetailsService() { + return username -> srepository.findByEmailId(username) + .orElseThrow(() -> new UsernameNotFoundException("User not found")); + } + + @Bean + public AuthenticationProvider authenticationProvider() { + DaoAuthenticationProvider authProvider = new DaoAuthenticationProvider(); + authProvider.setUserDetailsService(userDetailsService()); + authProvider.setPasswordEncoder(passwordEncoder()); + return authProvider; + } + + /* + * @Bean + * public AuditorAware auditorAware() { + * return new ApplicationAuditAware(); + * } + */ + + @Bean + public AuthenticationManager authenticationManager(AuthenticationConfiguration config) throws Exception { + return config.getAuthenticationManager(); + } + + @Bean + public PasswordEncoder passwordEncoder() { + return new BCryptPasswordEncoder(); + } +} diff --git a/myappvs/src/main/java/com/CourseManagementSystem/myappvs/security/config/Jwtauthfilter.java b/myappvs/src/main/java/com/CourseManagementSystem/myappvs/security/config/Jwtauthfilter.java new file mode 100644 index 0000000..2cfea48 --- /dev/null +++ b/myappvs/src/main/java/com/CourseManagementSystem/myappvs/security/config/Jwtauthfilter.java @@ -0,0 +1,62 @@ +package com.CourseManagementSystem.myappvs.security.config; + +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.lang.NonNull; +import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.security.core.userdetails.UserDetails; +import org.springframework.security.core.userdetails.UserDetailsService; +import org.springframework.security.web.authentication.WebAuthenticationDetailsSource; +import org.springframework.stereotype.Component; +import org.springframework.web.filter.OncePerRequestFilter; + +import com.CourseManagementSystem.myappvs.security.Service.Jwtservice; +import com.CourseManagementSystem.myappvs.user.Userservice; + +import jakarta.servlet.FilterChain; +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import lombok.RequiredArgsConstructor; + +import java.io.IOException; + +@Component +@RequiredArgsConstructor +public class Jwtauthfilter extends OncePerRequestFilter { + private final Jwtservice jwtService; + private final Userservice userService; + private final UserDetailsService userDetailsService; + + @Override + protected void doFilterInternal(@NonNull HttpServletRequest request, + @NonNull HttpServletResponse response, + @NonNull FilterChain filterChain) + throws ServletException, IOException { + + final String authHeader = request.getHeader("Authorization"); + final String jwt; + final String userEmail; + + if (StringUtils.isEmpty(authHeader) || !StringUtils.startsWith(authHeader, "Bearer ")) { + filterChain.doFilter(request, response); + return; + } + + jwt = authHeader.substring(7); + userEmail = jwtService.extractUserName(jwt); + + if (StringUtils.isNotEmpty(userEmail) && SecurityContextHolder.getContext().getAuthentication() == null) { + UserDetails userDetails = userService.userDetailsService().loadUserByUsername(userEmail); + + if (jwtService.isTokenValid(jwt, userDetails)) { + UsernamePasswordAuthenticationToken authToken = new UsernamePasswordAuthenticationToken( + userDetails, null, userDetails.getAuthorities()); + authToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(request)); + SecurityContextHolder.getContext().setAuthentication(authToken); + } + } + filterChain.doFilter(request, response); + } +} \ No newline at end of file diff --git a/myappvs/src/main/java/com/CourseManagementSystem/myappvs/security/config/SecurityConfiguration.java b/myappvs/src/main/java/com/CourseManagementSystem/myappvs/security/config/SecurityConfiguration.java new file mode 100644 index 0000000..777e081 --- /dev/null +++ b/myappvs/src/main/java/com/CourseManagementSystem/myappvs/security/config/SecurityConfiguration.java @@ -0,0 +1,56 @@ +package com.CourseManagementSystem.myappvs.security.config; + +import static org.springframework.security.config.http.SessionCreationPolicy.STATELESS; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.security.authentication.AuthenticationManager; +import org.springframework.security.authentication.AuthenticationProvider; +import org.springframework.security.authentication.dao.DaoAuthenticationProvider; +import org.springframework.security.config.annotation.authentication.configuration.AuthenticationConfiguration; +import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; +import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer; +import org.springframework.security.config.http.SessionCreationPolicy; +import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; +import org.springframework.security.crypto.password.PasswordEncoder; +import org.springframework.security.web.SecurityFilterChain; +import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; +import org.springframework.security.web.util.matcher.AntPathRequestMatcher; + +import com.CourseManagementSystem.myappvs.user.Userservice; + +import lombok.RequiredArgsConstructor; + +@Configuration +@EnableWebSecurity +@RequiredArgsConstructor +public class SecurityConfiguration { + private final Jwtauthfilter jwtAuthenticationFilter; + private final AuthenticationProvider authenticationProvider; + + @Bean + public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { + http + .authorizeHttpRequests(auth -> auth + .requestMatchers("/h2-console/**").permitAll()) + .csrf(csrf -> csrf.disable()) + .authorizeHttpRequests(requests -> requests + .requestMatchers("/api/v1/auth/**") + .permitAll() + .requestMatchers("/h2-console/**") + .permitAll() + .requestMatchers("/**") + .permitAll() + .requestMatchers("/index.html") + .permitAll() + .anyRequest() + .authenticated()) + .sessionManagement(management -> management + .sessionCreationPolicy(SessionCreationPolicy.STATELESS)) + .authenticationProvider(authenticationProvider) + .addFilterBefore(jwtAuthenticationFilter, UsernamePasswordAuthenticationFilter.class); + http.headers(headers -> headers.frameOptions(frameOptions -> frameOptions.sameOrigin())); + return http.build(); + + } +} \ No newline at end of file diff --git a/myappvs/src/main/java/com/CourseManagementSystem/myappvs/student/Student.java b/myappvs/src/main/java/com/CourseManagementSystem/myappvs/student/Student.java index 6228b2d..8123939 100644 --- a/myappvs/src/main/java/com/CourseManagementSystem/myappvs/student/Student.java +++ b/myappvs/src/main/java/com/CourseManagementSystem/myappvs/student/Student.java @@ -1,41 +1,71 @@ package com.CourseManagementSystem.myappvs.student; -import com.CourseManagementSystem.myappvs.user.User; -import com.fasterxml.jackson.annotation.JsonIgnore; - -import jakarta.persistence.CascadeType; -import jakarta.persistence.Column; -import jakarta.persistence.Entity; -import jakarta.persistence.FetchType; -import jakarta.persistence.GeneratedValue; -import jakarta.persistence.GenerationType; -import jakarta.persistence.Id; -import jakarta.persistence.OneToMany; -import jakarta.persistence.OneToOne; -import jakarta.persistence.PrimaryKeyJoinColumn; -import jakarta.persistence.Table; +import java.util.Collection; +import java.util.List; + +import org.springframework.security.core.GrantedAuthority; +import org.springframework.security.core.authority.SimpleGrantedAuthority; +import org.springframework.security.core.userdetails.UserDetails; + +import com.CourseManagementSystem.myappvs.user.Role; + +import jakarta.persistence.*; + import lombok.AllArgsConstructor; +import lombok.Builder; import lombok.Data; import lombok.NoArgsConstructor; -import java.util.List; - @Entity @Table(name = "Students") @Data +@Builder +@NoArgsConstructor @AllArgsConstructor -public class Student { - +public class Student implements UserDetails { @Id @Column(unique = true) private Long studentIdNumber; private String name; - + @Column(unique = true) private String emailId; - @OneToOne(mappedBy = "student", cascade = CascadeType.ALL, fetch = FetchType.LAZY) - private User user; + private Student student; private String number; + @Enumerated(EnumType.STRING) + private Role role; + + private String password; + + @Override + public Collection getAuthorities() { + return List.of(new SimpleGrantedAuthority(role.name())); + } + + @Override + public String getUsername() { + return emailId; + } + + @Override + public boolean isAccountNonExpired() { + return true; + } + + @Override + public boolean isAccountNonLocked() { + return true; + } + + @Override + public boolean isCredentialsNonExpired() { + return true; + } + + @Override + public boolean isEnabled() { + return true; + } -} +} \ No newline at end of file diff --git a/myappvs/src/main/java/com/CourseManagementSystem/myappvs/student/Studentrepository.java b/myappvs/src/main/java/com/CourseManagementSystem/myappvs/student/Studentrepository.java index 3fae296..20a1b1e 100644 --- a/myappvs/src/main/java/com/CourseManagementSystem/myappvs/student/Studentrepository.java +++ b/myappvs/src/main/java/com/CourseManagementSystem/myappvs/student/Studentrepository.java @@ -1,11 +1,17 @@ package com.CourseManagementSystem.myappvs.student; import java.util.Optional; - import org.springframework.data.jpa.repository.JpaRepository; - -import com.CourseManagementSystem.myappvs.user.User; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.query.Param; public interface Studentrepository extends JpaRepository { + Optional findByEmailId(String emailId); + + @Query("SELECT s.name FROM Student s WHERE s.emailId = :emailId") + String findNameByEmailId(@Param("emailId") String emailId); + + boolean existsByEmailId(String email); -} + boolean existsByStudentIdNumber(Long studentIdNumber); +} \ No newline at end of file diff --git a/myappvs/src/main/java/com/CourseManagementSystem/myappvs/studentAccounts/StudentAccountDto.java b/myappvs/src/main/java/com/CourseManagementSystem/myappvs/studentAccounts/StudentAccountDto.java new file mode 100644 index 0000000..81bbf8d --- /dev/null +++ b/myappvs/src/main/java/com/CourseManagementSystem/myappvs/studentAccounts/StudentAccountDto.java @@ -0,0 +1,24 @@ +package com.CourseManagementSystem.myappvs.studentAccounts; + +import com.CourseManagementSystem.myappvs.student.Student; +import jakarta.persistence.Column; +import jakarta.persistence.Id; +import jakarta.persistence.JoinColumn; +import jakarta.persistence.OneToOne; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; +import lombok.ToString; + +@Data +@AllArgsConstructor +@NoArgsConstructor +public class StudentAccountDto { + + private Long studentAccountsId; + + private Student studentId; + + private double balance; + +} diff --git a/myappvs/src/main/java/com/CourseManagementSystem/myappvs/studentAccounts/StudentAccountService.java b/myappvs/src/main/java/com/CourseManagementSystem/myappvs/studentAccounts/StudentAccountService.java new file mode 100644 index 0000000..791d672 --- /dev/null +++ b/myappvs/src/main/java/com/CourseManagementSystem/myappvs/studentAccounts/StudentAccountService.java @@ -0,0 +1,23 @@ +package com.CourseManagementSystem.myappvs.studentAccounts; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +@Service +public class StudentAccountService { + + private StudentAccountsRepository studentAccountsRepository; + + @Autowired + public StudentAccountService(StudentAccountsRepository studentAccountsRepository) { + this.studentAccountsRepository = studentAccountsRepository; + } + + + public StudentAccountDto getStudentAccountsDetail(Long studentId) { + StudentAccounts studentAccounts= studentAccountsRepository + .findByStudentId_studentIdNumber(studentId) + .orElseThrow(()-> new RuntimeException("Student Doesn't Exist")); + return StudentAccountsMapper.maptoStudentAccountDto(studentAccounts); + } +} diff --git a/myappvs/src/main/java/com/CourseManagementSystem/myappvs/studentAccounts/StudentAccounts.java b/myappvs/src/main/java/com/CourseManagementSystem/myappvs/studentAccounts/StudentAccounts.java index e2c8aa8..db2871d 100644 --- a/myappvs/src/main/java/com/CourseManagementSystem/myappvs/studentAccounts/StudentAccounts.java +++ b/myappvs/src/main/java/com/CourseManagementSystem/myappvs/studentAccounts/StudentAccounts.java @@ -1,12 +1,17 @@ package com.CourseManagementSystem.myappvs.studentAccounts; - import com.CourseManagementSystem.myappvs.student.Student; import jakarta.persistence.*; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; import lombok.ToString.Exclude; @Entity -@Table(name = "student_accounts") +@Getter +@NoArgsConstructor +@AllArgsConstructor +@Table(name = "Student_Accounts") public class StudentAccounts { @Id @@ -16,43 +21,8 @@ public class StudentAccounts { @Exclude @OneToOne @JoinColumn(name = "student_id", referencedColumnName = "studentIdNumber") - private Student student; - + private Student studentId; private double balance; - - public StudentAccounts(){ - - } - - public StudentAccounts(long studentAccountsId, Student student, double balance){ - this.studentAccountsId = studentAccountsId; - this.student = student; - this.balance = balance; - } - - public void setStudentId(Student student) { - this.student = student; - } - - public long getStudentAccountsId() { - return studentAccountsId; - } - - public void setStudentAccountsId(long studentAccountsId) { - this.studentAccountsId = studentAccountsId; - } - - public Student getStudent() { - return student; - } - - public double getBalance() { - return balance; - } - - public void setBalance(double balance) { - this.balance = balance; - } } diff --git a/myappvs/src/main/java/com/CourseManagementSystem/myappvs/studentAccounts/StudentAccountsMapper.java b/myappvs/src/main/java/com/CourseManagementSystem/myappvs/studentAccounts/StudentAccountsMapper.java new file mode 100644 index 0000000..f252efd --- /dev/null +++ b/myappvs/src/main/java/com/CourseManagementSystem/myappvs/studentAccounts/StudentAccountsMapper.java @@ -0,0 +1,26 @@ +package com.CourseManagementSystem.myappvs.studentAccounts; + +public class StudentAccountsMapper { + + + public static StudentAccounts maptoStudentAccounts(StudentAccountDto studentAccountDto){ + StudentAccounts studentAccounts = new StudentAccounts( + studentAccountDto.getStudentAccountsId(), + studentAccountDto.getStudentId(), + studentAccountDto.getBalance() + ); + return studentAccounts; + } + public static StudentAccountDto maptoStudentAccountDto(StudentAccounts studentAccounts){ + StudentAccountDto studentAccountDto= new StudentAccountDto( + studentAccounts.getStudentAccountsId(), + studentAccounts.getStudentId(), + studentAccounts.getBalance() + + ); + return studentAccountDto; + } +} + + + diff --git a/myappvs/src/main/java/com/CourseManagementSystem/myappvs/studentAccounts/StudentAccountsRepository.java b/myappvs/src/main/java/com/CourseManagementSystem/myappvs/studentAccounts/StudentAccountsRepository.java index 2ce495c..90309d1 100644 --- a/myappvs/src/main/java/com/CourseManagementSystem/myappvs/studentAccounts/StudentAccountsRepository.java +++ b/myappvs/src/main/java/com/CourseManagementSystem/myappvs/studentAccounts/StudentAccountsRepository.java @@ -1,7 +1,13 @@ package com.CourseManagementSystem.myappvs.studentAccounts; -import com.CourseManagementSystem.myappvs.studentAccounts.StudentAccounts; +import com.CourseManagementSystem.myappvs.courseDescription.CourseDescription; import org.springframework.data.jpa.repository.JpaRepository; +import java.util.Optional; + public interface StudentAccountsRepository extends JpaRepository { + Optional findByStudentId_studentIdNumber(Long studentId); + + + } diff --git a/myappvs/src/main/java/com/CourseManagementSystem/myappvs/studentAccounts/package-info.java b/myappvs/src/main/java/com/CourseManagementSystem/myappvs/studentAccounts/package-info.java index a4f8027..5b858a9 100644 --- a/myappvs/src/main/java/com/CourseManagementSystem/myappvs/studentAccounts/package-info.java +++ b/myappvs/src/main/java/com/CourseManagementSystem/myappvs/studentAccounts/package-info.java @@ -2,9 +2,47 @@ /** * The studentAccounts entity * This entity represents the balance of student after enrolling into the course. + * The main components include the StudentAccounts entity, the StudentAccountDto, the StudentAccountsRepository, + * the StudentAccountService,the StudentAccountsController, and the StudentAccountsMapper. *
  • One to one relationship between studentAccounts and student * - * + *This package manages the details of student accounts, including fetching and displaying information about each student’s account + *Entity Class (StudentAccounts.java): + * Contains fields such as studentAccountsId, studentId, and balance. + * Annotated with JPA annotations to define the table structure and relationships. + * The studentId field is a foreign key linked to the Student entity. + * + * Data Transfer Object (StudentAccountDto.java): + * + * Simplifies data exchange between client and server. + * Contains similar fields to the StudentAccounts entity for ease of mapping and use in the REST API. + * Includes fields for studentAccountsId, studentId, and balance. + * + * Repository Interface (StudentAccountsRepository.java): + * + * Extends JpaRepository to provide CRUD operations. + * Contains a custom query method findByStudentId_studentIdNumber(Long studentId) to find student account details by student ID. + * + * Service Class (StudentAccountService.java): + * + * Implements the service layer for business logic related to student account details. + * Provides the logic for fetching student account details using the repository. + * Throws a RuntimeException if the student account is not found. + * + * Controller (StudentAccountsController.java): + * + * Exposes REST API endpoints for student account details. + * Contains a GET endpoint /api/studentaccounts/{id} to fetch student account details by ID. + * Handles exceptions and returns appropriate HTTP status codes. + * + * Mapper (StudentAccountsMapper.java): + * + * Provides static methods to map between StudentAccounts entity and StudentAccountDto. + * Ensures a clear separation between entity and DTO for better manageability and data consistency. + * + * For front-end, the html page is created named studentAccounts.html which displays student accounts. Which can directly accessed using Home page. + * The controller returns a 404 Not Found status if the student account details are not found, ensuring appropriate client feedback. + * * @author Shivangi Patel */ package com.CourseManagementSystem.myappvs.studentAccounts; diff --git a/myappvs/src/main/java/com/CourseManagementSystem/myappvs/studentAccounts/studentAccountsController.java b/myappvs/src/main/java/com/CourseManagementSystem/myappvs/studentAccounts/studentAccountsController.java new file mode 100644 index 0000000..5e5ff4c --- /dev/null +++ b/myappvs/src/main/java/com/CourseManagementSystem/myappvs/studentAccounts/studentAccountsController.java @@ -0,0 +1,32 @@ +package com.CourseManagementSystem.myappvs.studentAccounts; + +import com.CourseManagementSystem.myappvs.courseDescription.CourseDescriptionDto; +import com.CourseManagementSystem.myappvs.studentAccounts.StudentAccountService; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequestMapping("/api/studentaccounts") +public class studentAccountsController { + + private StudentAccountService studentAccountService; + + public studentAccountsController(StudentAccountService studentAccountService) { + this.studentAccountService = studentAccountService; + } + + @GetMapping("/{id}") + public ResponseEntity getstudentAccountsbyId(@PathVariable Long id){ + + try { + StudentAccountDto studentAccountDto = studentAccountService.getStudentAccountsDetail(id); + return ResponseEntity.ok(studentAccountDto); + } catch (RuntimeException e) { + return ResponseEntity.status(HttpStatus.NOT_FOUND).body(null); // Return 404 Not Found + } + } +} diff --git a/myappvs/src/main/java/com/CourseManagementSystem/myappvs/user/Homecontroller.java b/myappvs/src/main/java/com/CourseManagementSystem/myappvs/user/Homecontroller.java new file mode 100644 index 0000000..fbb2bc7 --- /dev/null +++ b/myappvs/src/main/java/com/CourseManagementSystem/myappvs/user/Homecontroller.java @@ -0,0 +1,13 @@ +package com.CourseManagementSystem.myappvs.user; + +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.GetMapping; + +@Controller +public class Homecontroller { + + @GetMapping("/") + public String redirectToIndex() { + return "redirect:/index.html"; + } +} diff --git a/myappvs/src/main/java/com/CourseManagementSystem/myappvs/user/Login.java b/myappvs/src/main/java/com/CourseManagementSystem/myappvs/user/Login.java deleted file mode 100644 index 5af9e3d..0000000 --- a/myappvs/src/main/java/com/CourseManagementSystem/myappvs/user/Login.java +++ /dev/null @@ -1,60 +0,0 @@ -package com.CourseManagementSystem.myappvs.user; - -import java.util.Optional; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.RequestBody; -//import org.springframework.web.bind.annotation.RestController; -import org.springframework.web.bind.annotation.RestController; - -import com.CourseManagementSystem.myappvs.student.Student; - -@RestController -public class Login { - - @Autowired - Loginservice loginservice; - - public Login(Loginservice loginService) { - this.loginservice = loginService; - } - - @PostMapping("/login") - public ResponseEntity login(@RequestBody User user) throws Exception { - - String loginstudent; - try { - loginstudent = loginservice.login(user); - } catch (Exception exception) { - throw exception; - } - - return ResponseEntity.ok("Login successfully by " + loginstudent); - - } - - @PostMapping("/signup") - public ResponseEntity signup(@RequestBody Student student) { - Student saveStudent; - User userData; - try { - saveStudent = loginservice.addStudent(student); - - // Extract data from the student object to create a user object - User user = new User(null, null, saveStudent); - user.setEmailId(student.getEmailId()); - user.setPassword(student.getUser().getPassword()); // Assuming the password is stored in the student's - // associated user object - user.setStudent(saveStudent); - - // Save the user - userData = loginservice.addUser(user); - } catch (RuntimeException exception) { - throw exception; - } - return ResponseEntity.of(Optional.of(saveStudent)); - - } -} diff --git a/myappvs/src/main/java/com/CourseManagementSystem/myappvs/user/Loginservice.java b/myappvs/src/main/java/com/CourseManagementSystem/myappvs/user/Loginservice.java index 4577779..6cae6c9 100644 --- a/myappvs/src/main/java/com/CourseManagementSystem/myappvs/user/Loginservice.java +++ b/myappvs/src/main/java/com/CourseManagementSystem/myappvs/user/Loginservice.java @@ -2,44 +2,54 @@ import com.CourseManagementSystem.myappvs.student.Student; import com.CourseManagementSystem.myappvs.student.Studentrepository; - import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Component; -//import java.util.Optional; +import org.springframework.security.crypto.password.PasswordEncoder; +import org.springframework.stereotype.Service; +import org.springframework.security.core.userdetails.UserDetailsService; -@Component +@Service public class Loginservice { @Autowired private Studentrepository studentRepository; @Autowired - private Userrepository userRepository; + private PasswordEncoder passwordEncoder; + + @Autowired + private Userserviceimpl userService; - public Loginservice(Studentrepository studentRepository) { + public Loginservice(Studentrepository studentRepository, + PasswordEncoder passwordEncoder, Userserviceimpl userService) { this.studentRepository = studentRepository; + this.passwordEncoder = passwordEncoder; + this.userService = userService; } - /* - * public List getStudents() { - * return studentRepository.findAll(); - * } - */ - - public String login(User user) throws Exception { - User existingUser = userRepository.findByEmailIdAndPassword(user.getEmailId(), user.getPassword()) + public String login(Student student) throws Exception { + Student existingUser = studentRepository.findByEmailId(student.getEmailId()) .orElseThrow(() -> new Exception("Invalid credentials")); + if (!passwordEncoder.matches(student.getPassword(), existingUser.getPassword())) { + throw new Exception("Invalid credentials"); + } return existingUser.getStudent().getName(); } public Student addStudent(Student student) { - studentRepository.save(student); - return student; + return studentRepository.save(student); } - public User addUser(User user) { - userRepository.save(user); - return user; + public Student addUser(Student student) { + student.setPassword(passwordEncoder.encode(student.getPassword())); + return studentRepository.save(student); } + public Student getStudentByEmail(String emailId) { + return studentRepository.findByEmailId(emailId) + .orElseThrow(() -> new RuntimeException("Student not found")); + } + + public UserDetailsService userDetailsService() { + return (UserDetailsService) userService; // Return the Userserviceimpl directly + } } diff --git a/myappvs/src/main/java/com/CourseManagementSystem/myappvs/user/Role.java b/myappvs/src/main/java/com/CourseManagementSystem/myappvs/user/Role.java new file mode 100644 index 0000000..5b18657 --- /dev/null +++ b/myappvs/src/main/java/com/CourseManagementSystem/myappvs/user/Role.java @@ -0,0 +1,6 @@ +package com.CourseManagementSystem.myappvs.user; + +public enum Role { + USER, + ADMIN +} diff --git a/myappvs/src/main/java/com/CourseManagementSystem/myappvs/user/User.java b/myappvs/src/main/java/com/CourseManagementSystem/myappvs/user/User.java deleted file mode 100644 index 991b988..0000000 --- a/myappvs/src/main/java/com/CourseManagementSystem/myappvs/user/User.java +++ /dev/null @@ -1,29 +0,0 @@ -package com.CourseManagementSystem.myappvs.user; - -import com.CourseManagementSystem.myappvs.student.Student; - -import jakarta.persistence.Entity; -import jakarta.persistence.FetchType; -import jakarta.persistence.Id; -import jakarta.persistence.JoinColumn; -import jakarta.persistence.OneToOne; -import jakarta.persistence.Table; -import lombok.AllArgsConstructor; -import lombok.Data; - -@Data -@AllArgsConstructor -@Entity -@Table(name = "Users") -public class User { - - @Id - private String emailId; // Primary key - - private String password; - - @OneToOne(fetch = FetchType.LAZY) - @JoinColumn(name = "studentIdNumber") - private Student student; - -} diff --git a/myappvs/src/main/java/com/CourseManagementSystem/myappvs/user/Userrepository.java b/myappvs/src/main/java/com/CourseManagementSystem/myappvs/user/Userrepository.java deleted file mode 100644 index 2465fc1..0000000 --- a/myappvs/src/main/java/com/CourseManagementSystem/myappvs/user/Userrepository.java +++ /dev/null @@ -1,11 +0,0 @@ -package com.CourseManagementSystem.myappvs.user; - -import java.util.Optional; - -import org.springframework.data.jpa.repository.JpaRepository; - -public interface Userrepository extends JpaRepository { - - Optional findByEmailIdAndPassword(String emailId, String password); - -} \ No newline at end of file diff --git a/myappvs/src/main/java/com/CourseManagementSystem/myappvs/user/Userservice.java b/myappvs/src/main/java/com/CourseManagementSystem/myappvs/user/Userservice.java new file mode 100644 index 0000000..a267ad4 --- /dev/null +++ b/myappvs/src/main/java/com/CourseManagementSystem/myappvs/user/Userservice.java @@ -0,0 +1,7 @@ +package com.CourseManagementSystem.myappvs.user; + +import org.springframework.security.core.userdetails.UserDetailsService; + +public interface Userservice { + UserDetailsService userDetailsService(); +} diff --git a/myappvs/src/main/java/com/CourseManagementSystem/myappvs/user/Userserviceimpl.java b/myappvs/src/main/java/com/CourseManagementSystem/myappvs/user/Userserviceimpl.java new file mode 100644 index 0000000..26beb40 --- /dev/null +++ b/myappvs/src/main/java/com/CourseManagementSystem/myappvs/user/Userserviceimpl.java @@ -0,0 +1,27 @@ +package com.CourseManagementSystem.myappvs.user; + +import org.springframework.security.core.userdetails.UserDetails; +import org.springframework.security.core.userdetails.UserDetailsService; +import org.springframework.security.core.userdetails.UsernameNotFoundException; +import org.springframework.stereotype.Service; + +import com.CourseManagementSystem.myappvs.student.Studentrepository; + +import lombok.RequiredArgsConstructor; + +@Service +@RequiredArgsConstructor +public class Userserviceimpl implements Userservice { + private final Studentrepository userRepository; + + @Override + public UserDetailsService userDetailsService() { + return new UserDetailsService() { + @Override + public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { + return userRepository.findByEmailId(username) + .orElseThrow(() -> new UsernameNotFoundException("User not found with email: " + username)); + } + }; + } +} \ No newline at end of file diff --git a/myappvs/src/main/resources/application.properties b/myappvs/src/main/resources/application.properties index de3c7b9..7eb8e99 100644 --- a/myappvs/src/main/resources/application.properties +++ b/myappvs/src/main/resources/application.properties @@ -9,20 +9,24 @@ server.port=8585 #spring.datasource.password=${MYSQL_PASSWORD:password} #spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver spring.datasource.url=jdbc:h2:mem:testdb;DATABASE_TO_UPPER=false;MODE=PostgreSQL +# spring.datasource.url=jdbc:h2:file:./mydatabase;DATABASE_TO_UPPER=false;MODE=PostgreSQL;AUTO_SERVER=TRUE spring.datasource.driverClassName=org.h2.Driver spring.datasource.username=sa spring.datasource.password=password spring.jpa.database-platform=org.hibernate.dialect.H2Dialect spring.jpa.show-sql=true +security.basic.enabled=false spring.jpa.hibernate.ddl-auto=create-drop spring.defer-datasource-initialization=true spring.jpa.properties.hibernate.globally_quoted_identifiers=true spring.h2.console.enabled=true spring.sql.init.mode=always +spring.main.allow-bean-definition-overriding=true -#MongoDB Configuration -spring.data.mongodb.host=localhost -spring.data.mongodb.port=27017 -spring.data.mongodb.database=events +spring.data.mongodb.uri=mongodb+srv://dbUser:Password%40123@coursemanagement.pf6hifa.mongodb.net/?retryWrites=true&w=majority&appName=CourseManagement +spring.data.mongodb.database=CourseManagement + +spring.mvc.view.prefix=/static/ +spring.mvc.view.suffix=.html diff --git a/myappvs/src/main/resources/import.sql b/myappvs/src/main/resources/import.sql index e223781..bb00769 100644 --- a/myappvs/src/main/resources/import.sql +++ b/myappvs/src/main/resources/import.sql @@ -1,17 +1,13 @@ - - - - -- Insert student data -INSERT INTO Students(studentIdNumber, name, emailId, number) VALUES (123456789, 'ABC', 'ABC@example.com', '2246387532'); -INSERT INTO Students(studentIdNumber, name, emailId, number) VALUES (987654321, 'CDE', 'CDE@example.com', '2257865437'); -INSERT INTO Students(studentIdNumber, name, emailId, number) VALUES (214365879, 'FGH', 'FGH@example.com', '2235679043'); -INSERT INTO Students(studentIdNumber, name, emailId, number) VALUES (978563412, 'IJK', 'IJK@example.com', '2247864538'); +INSERT INTO students(student_id_number, name, email_id, number) VALUES (123456789, 'ABC', 'ABC@example.com', '2246387532'); +INSERT INTO students(student_id_number, name, email_id, number) VALUES (987654321, 'CDE', 'CDE@example.com', '2257865437'); +INSERT INTO students(student_id_number, name, email_id, number) VALUES (114365567, 'FGH', 'FGH@example.com', '2235679043'); +INSERT INTO students(student_id_number, name, email_id, number) VALUES (978563412, 'IJK', 'IJK@example.com', '2247864538'); -- Insert user data -INSERT INTO Users(emailId, password) VALUES ('ABC@example.com', 'ABC@123'); +INSERT INTO users(emailId, password) VALUES ('ABC@example.com', 'ABC@123'); INSERT INTO Users(emailId, password) VALUES ('CDE@example.com', 'CDE@123'); INSERT INTO Users(emailId, password) VALUES ('FGH@example.com', 'FGH@123'); INSERT INTO Users(emailId, password) VALUES ('IJK@example.com', 'IJK@123'); @@ -21,13 +17,40 @@ INSERT INTO advisors(name, email) VALUES ('alice', 'alice@test.com') INSERT INTO advisors(name, email) VALUES ('bob', 'bob@test.com') INSERT INTO advisors(name, email) VALUES ('charlie', 'charlie@test.com') --- Insert into Catalog table -INSERT INTO Course_Catalog (courseId, courseName, Course_Description, Course_Instructor, Course_Credits) VALUES (101, 'Database Systems', 'Introduction to Database Design', 21251, 3); -INSERT INTO Course_Catalog (courseId, courseName, Course_Description, Course_Instructor, Course_Credits) VALUES (102, 'Machine Learning', 'Advanced machine learning concepts', 21351, 4); -- Insert into Enrollment table -INSERT INTO Enrollment (Enrollment_Id, student_id, courseId) VALUES (1, 123456789, 101); -INSERT INTO Enrollment (Enrollment_Id, student_id, courseId) VALUES (2, 123456789, 101); -INSERT INTO Enrollment (Enrollment_Id, student_id, courseId) VALUES (3, 987654321, 102); +INSERT INTO Enrollment(Enrollment_Id, student_id, courseId) VALUES (1, 123456789, 101); +INSERT INTO Enrollment(Enrollment_Id, student_id, courseId) VALUES (2, 123456789, 101); +INSERT INTO Enrollment(Enrollment_Id, student_id, courseId) VALUES (3, 987654321, 102); + +-- Insert into instructor table +INSERT INTO Instructor(instructorId, instructorName, instructorDescription, meetingHours, instructorCabinLocation) VALUES (1, 'John Doe', 'Experienced software engineer', '08:00:00', 'Building A, Room 101'); +INSERT INTO Instructor(instructorId, instructorName, instructorDescription, meetingHours, instructorCabinLocation) VALUES (2, 'Alice Smith', 'Data science expert', '10:00:00', 'Building B, Room 201'); +INSERT INTO Instructor(instructorId, instructorName, instructorDescription, meetingHours, instructorCabinLocation) VALUES (3, 'David Brown', 'Network security specialist', '13:00:00', 'Building C, Room 301'); + +INSERT INTO instructor(instructor_id, instructor_name, instructor_description, meeting_hours, instructor_cabin_location) VALUES (201, 'John Doe', 'Experienced software engineer', '08:00:00', 'Building A, Room 101'); +INSERT INTO instructor(instructor_id, instructor_name, instructor_description, meeting_hours, instructor_cabin_location) VALUES (202, 'Alice Smith', 'Data science expert', '10:00:00', 'Building B, Room 201'); +INSERT INTO instructor(instructor_id, instructor_name, instructor_description, meeting_hours, instructor_cabin_location) VALUES (203, 'David Brown', 'Network security specialist', '13:00:00', 'Building C, Room 301'); +-- Insert into Catalog table +INSERT INTO course_catalog(course_id, course_name, course_description, instructor_id, course_credits) VALUES (101, 'Database Systems', 'Introduction to Database Design', 201, 3); +INSERT INTO course_catalog(course_id, course_name, course_description, instructor_id, course_credits) VALUES (102, 'Machine Learning', 'Advanced machine learning concepts', 202, 4); + +-- Insert into Course Description table +INSERT INTO course_description(course_description_id, course_id, instructor_id, room, date, time, meeting_info, materials) VALUES (1, 101, 201, 'Room A', '2024-05-10', '09:00:00', 'Introduction to Programming', 'Lecture Slides'); +INSERT INTO course_description(course_description_id, course_id, instructor_id, room, date, time, meeting_info, materials) VALUES (2, 102, 202, 'Room B', '2024-05-12', '14:00:00', 'Advanced Database Management', 'Textbook, Exercises'); +--INSERT INTO course_description(courseDescriptionId, courseId, instructorId, room, date, time, meeting_info, materials) VALUES (3, 103, 203, 'Room C', '2024-05-15', '11:00:00', 'Machine Learning Fundamentals', 'Online Resources'); + +-- Insert into Student Account table +INSERT INTO student_accounts(student_accounts_id, student_id, balance) VALUES (1, 123456789, 100.00); +INSERT INTO student_accounts(student_accounts_id, student_id, balance) VALUES (2, 987654321, 200.00); +INSERT INTO student_accounts(student_accounts_id, student_id, balance) VALUES (3, 114365567, 150.00); + +-- Insert initial data into the Inventory table +INSERT INTO inventory (resource_id, resource_name, type, status, max_quantity, available_quantity) VALUES (1, 'Laptop', 'Electronics', 'Available', 10, 10); +INSERT INTO inventory (resource_id, resource_name, type, status, max_quantity, available_quantity) VALUES (2, 'Projector', 'Electronics', 'Available', 5, 5); +INSERT INTO inventory (resource_id, resource_name, type, status, max_quantity, available_quantity) VALUES (3, 'Microphone', 'Audio', 'Available', 15, 15); +-- Insert initial data into the Rentals table +INSERT INTO rental (id, equipment_id, user_email, rental_date, return_date) VALUES (1, 2, 'user1@example.com', '2024-04-01', '2024-04-10'); +INSERT INTO rental (id, equipment_id, user_email, rental_date, return_date) VALUES (2, 1, 'user2@example.com', '2024-04-05', '2024-04-15'); \ No newline at end of file diff --git a/myappvs/src/main/resources/js/script.js b/myappvs/src/main/resources/js/script.js new file mode 100644 index 0000000..5435348 --- /dev/null +++ b/myappvs/src/main/resources/js/script.js @@ -0,0 +1,43 @@ +document.getElementById('signupForm').addEventListener('submit', function (e) { + e.preventDefault(); + const email = document.getElementById('email').value; + const password = document.getElementById('password').value; + + fetch('/api/v1/auth/signup', { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify({ email: email, password: password }), + }) + .then(response => response.json()) + .then(data => { + alert('Signup successful!'); + window.location.href = '/login.html'; + }) + .catch(error => { + alert('Error during signup: ' + error.message); + }); +}); + +document.getElementById('loginForm').addEventListener('submit', function (e) { + e.preventDefault(); + const email = document.getElementById('email').value; + const password = document.getElementById('password').value; + + fetch('/api/v1/auth/login', { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify({ email: email, password: password }), + }) + .then(response => response.json()) + .then(data => { + alert('Login successful!'); + // Handle the token, redirect or set up user session here + }) + .catch(error => { + alert('Error during login: ' + error.message); + }); +}); diff --git a/myappvs/src/main/resources/schema.sql b/myappvs/src/main/resources/schema.sql index ece9d4f..d542675 100644 --- a/myappvs/src/main/resources/schema.sql +++ b/myappvs/src/main/resources/schema.sql @@ -10,17 +10,41 @@ CREATE TABLE IF NOT EXISTS Users ( password VARCHAR(255) NOT NULL ); -CREATE TABLE IF NOT EXISTS Course_Catalog ( - courseId INT PRIMARY KEY, - courseName VARCHAR(100) NOT NULL, - Course_Description VARCHAR(255) NOT NULL, - Instructor_ID INT NOT NULL, - Course_Credits INT -); - -CREATE TABLE IF NOT EXISTS Enrollment ( - Enrollment_Id INT PRIMARY KEY, - student_id INT NOT NULL, - courseId INT NOT NULL -); - +--CREATE TABLE IF NOT EXISTS Course_Catalog ( +-- courseId INT PRIMARY KEY, +-- courseName VARCHAR(100) NOT NULL, +-- Course_Description VARCHAR(255) NOT NULL, +-- Instructor_ID INT NOT NULL, +-- Course_Credits INT +--); +-- +--CREATE TABLE IF NOT EXISTS Enrollment ( +-- Enrollment_Id INT PRIMARY KEY, +-- student_id INT NOT NULL, +-- courseId INT NOT NULL +--); +-- +--CREATE TABLE IF NOT EXISTS Course_Description ( +-- courseDescriptionId INT PRIMARY KEY, +-- courseId INT, +-- instructorId INT, +-- room VARCHAR(255), +-- date DATE, +-- time TIME, +-- meetingInfo VARCHAR(255), +-- materials VARCHAR(255) +--); +-- +--CREATE TABLE IF NOT EXISTS Instructor ( +-- instructorId INT PRIMARY KEY, +-- instructorName VARCHAR(255), +-- instructorDescription VARCHAR(255), +-- meetingHours TIME, +-- instructorCabinLocation VARCHAR(255) +--); +-- +--CREATE TABLE IF NOT EXISTS Student_Accounts ( +-- studentAccountsId INT PRIMARY KEY, +-- student_id INT, +-- balance DOUBLE +--); diff --git a/myappvs/src/main/resources/static/courseCatalog.html b/myappvs/src/main/resources/static/courseCatalog.html new file mode 100644 index 0000000..5630475 --- /dev/null +++ b/myappvs/src/main/resources/static/courseCatalog.html @@ -0,0 +1,170 @@ + + + + + + Course Catalog + + + +
    + +
    + Welcome, User +
    +
    +

    Course Catalog

    + + + + + + + + + + + + + +
    Course IDCourse NameDescriptionInstructorCreditsEnroll
    + + + + + diff --git a/myappvs/src/main/resources/static/courseDescription.html b/myappvs/src/main/resources/static/courseDescription.html new file mode 100644 index 0000000..c35e2c5 --- /dev/null +++ b/myappvs/src/main/resources/static/courseDescription.html @@ -0,0 +1,57 @@ + + + + + + Course Description + + + +
    +

    Course Description

    +
    + +
    +
    + + + diff --git a/myappvs/src/main/resources/static/css/courseDescription.css b/myappvs/src/main/resources/static/css/courseDescription.css new file mode 100644 index 0000000..cc0400c --- /dev/null +++ b/myappvs/src/main/resources/static/css/courseDescription.css @@ -0,0 +1,31 @@ +body { + font-family: Arial, sans-serif; + margin: 0; + padding: 0; + background-color: #f4f4f4; +} + +.container { + max-width: 800px; + margin: 50px auto; + padding: 20px; + background-color: #fff; + border-radius: 5px; + box-shadow: 0 0 10px rgba(0, 0, 0, 0.1); +} + +h1 { + text-align: center; +} + +#courseDetails { + margin-top: 20px; +} + +p { + margin-bottom: 10px; +} + +strong { + font-weight: bold; +} diff --git a/myappvs/src/main/resources/static/css/instructor.css b/myappvs/src/main/resources/static/css/instructor.css new file mode 100644 index 0000000..d95c130 --- /dev/null +++ b/myappvs/src/main/resources/static/css/instructor.css @@ -0,0 +1,24 @@ +body { + font-family: Arial, sans-serif; + margin: 0; + padding: 0; + background-color: #f4f4f4; +} + +.container { + max-width: 800px; + margin: 50px auto; + background-color: #fff; + padding: 20px; + border-radius: 8px; + box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); +} + +h1, h2 { + color: #333; +} + +p { + color: #666; +} + diff --git a/myappvs/src/main/resources/static/css/studentAccounts.css b/myappvs/src/main/resources/static/css/studentAccounts.css new file mode 100644 index 0000000..14fe1a6 --- /dev/null +++ b/myappvs/src/main/resources/static/css/studentAccounts.css @@ -0,0 +1,43 @@ +body { + font-family: Arial, sans-serif; + margin: 0; + padding: 0; + background-color: #f4f4f4; +} + +.container { + max-width: 800px; + margin: 50px auto; + background-color: #fff; + padding: 20px; + border-radius: 8px; + box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); +} + +h1 { + color: #333; +} + +p { + color: #666; + margin-bottom: 10px; +} + +table { + width: 100%; + border-collapse: collapse; + margin-top: 20px; +} + +table, th, td { + border: 1px solid black; +} + +th, td { + padding: 8px; + text-align: left; +} + +th { + background-color: #f4f4f4; +} diff --git a/myappvs/src/main/resources/static/css/style.css b/myappvs/src/main/resources/static/css/style.css index 3ec7f0b..75fea3f 100644 --- a/myappvs/src/main/resources/static/css/style.css +++ b/myappvs/src/main/resources/static/css/style.css @@ -1,44 +1,53 @@ -.login-container { - width: 300px; - margin: 0 auto; +body { + font-family: Arial, sans-serif; + background-color: #f4f4f4; + display: flex; + justify-content: center; + align-items: center; + height: 100vh; + margin: 0; +} + +.container { + background: #fff; padding: 20px; - border: 1px solid #ccc; + box-shadow: 0 0 10px rgba(0, 0, 0, 0.1); border-radius: 5px; - background-color: #f9f9f9; + text-align: center; +} + +h1 { + margin-bottom: 20px; } -.form-group { - margin-bottom: 10px; +form { + display: flex; + flex-direction: column; } label { - display: block; + margin: 10px 0 5px; } -input[type="text"], -input[type="password"] { - width: 100%; - padding: 8px; - font-size: 16px; - border-radius: 5px; +input { + padding: 10px; + margin-bottom: 20px; border: 1px solid #ccc; + border-radius: 3px; } -button { - padding: 10px 20px; - font-size: 16px; - border-radius: 5px; - background-color: #007bff; - color: #fff; +.button, button { + padding: 10px; border: none; + background: #007bff; + color: white; + border-radius: 3px; cursor: pointer; + text-decoration: none; + display: inline-block; + margin: 10px; } -button:hover { - background-color: #0056b3; -} - -#login-message { - margin-top: 10px; - color: red; +.button:hover, button:hover { + background: #0056b3; } diff --git a/myappvs/src/main/resources/static/enrollments.html b/myappvs/src/main/resources/static/enrollments.html new file mode 100644 index 0000000..c3f1996 --- /dev/null +++ b/myappvs/src/main/resources/static/enrollments.html @@ -0,0 +1,171 @@ + + + + + + Enrollments + + + +
    + +
    + Welcome, User +
    +
    +

    Enrollments

    +
    +

    +

    +
    + + + + + + + + + + + +
    Enrollment IDCourse NameCourse DescriptionDelete
    + + + + diff --git a/myappvs/src/main/resources/static/events.html b/myappvs/src/main/resources/static/events.html new file mode 100644 index 0000000..19ff078 --- /dev/null +++ b/myappvs/src/main/resources/static/events.html @@ -0,0 +1,193 @@ + + + + Event Calendar + + + + + + + +
    +

    Event Calendar

    + +
    +
    +
    +
    +

    Events

    +
      +

      Save New Event

      + + +
      + + +
      + + +
      + +
      +
      + + \ No newline at end of file diff --git a/myappvs/src/main/resources/static/home.html b/myappvs/src/main/resources/static/home.html new file mode 100644 index 0000000..2578ddf --- /dev/null +++ b/myappvs/src/main/resources/static/home.html @@ -0,0 +1,142 @@ + + + + + + Home Page + + + +
      +
      + Welcome, User +
      + +
      + +
      +

      Welcome to the Home Page

      +
      + + + + + + + + +
      +
      + + + + diff --git a/myappvs/src/main/resources/static/index.html b/myappvs/src/main/resources/static/index.html index 32adb8b..8b39808 100644 --- a/myappvs/src/main/resources/static/index.html +++ b/myappvs/src/main/resources/static/index.html @@ -3,14 +3,16 @@ - Welcome + Course Management System + -

      Welcome to My App

      -

      Please choose an action:

      - +
      +

      Welcome to the Course Management System

      + +
      - + \ No newline at end of file diff --git a/myappvs/src/main/resources/static/instructor.html b/myappvs/src/main/resources/static/instructor.html new file mode 100644 index 0000000..d5af4e2 --- /dev/null +++ b/myappvs/src/main/resources/static/instructor.html @@ -0,0 +1,47 @@ + + + + + + Instructor Details + + + +
      +

      Instructor Details

      +
      + +
      +
      + + + diff --git a/myappvs/src/main/resources/static/login.html b/myappvs/src/main/resources/static/login.html index 8acc683..e1ed2a3 100644 --- a/myappvs/src/main/resources/static/login.html +++ b/myappvs/src/main/resources/static/login.html @@ -7,7 +7,7 @@

      Login

      -
      +
      @@ -17,43 +17,46 @@

      Login

      - Don't have an account? Wanna a Signup
      + +

      Don't have an account? Sign Up

      + - + \ No newline at end of file diff --git a/myappvs/src/main/resources/static/profile.html b/myappvs/src/main/resources/static/profile.html new file mode 100644 index 0000000..60f5e81 --- /dev/null +++ b/myappvs/src/main/resources/static/profile.html @@ -0,0 +1,266 @@ + + + + + + User Profile + + + +
      +

      User Profile

      +

      Email:

      +

      Name:

      +

      Student ID:

      +

      Phone Number:

      + + + + +
      + + + + + + + + + + diff --git a/myappvs/src/main/resources/static/rentals.html b/myappvs/src/main/resources/static/rentals.html new file mode 100644 index 0000000..7a0a1df --- /dev/null +++ b/myappvs/src/main/resources/static/rentals.html @@ -0,0 +1,177 @@ + + + + + + Inventory + + + +
      + +
      + Home +
      +
      +

      Inventory List

      + + + + + + + + + + + + + +
      IDNameTypeStatusAvailable QuantityAction
      + + + + \ No newline at end of file diff --git a/myappvs/src/main/resources/static/signup.html b/myappvs/src/main/resources/static/signup.html index 1784c92..4ce66ae 100644 --- a/myappvs/src/main/resources/static/signup.html +++ b/myappvs/src/main/resources/static/signup.html @@ -4,74 +4,125 @@ Signup Page + -

      Signup

      -
      -
      - - -
      -
      - - -
      -
      - - -
      -
      - - -
      -
      - - -
      - -
      +
      +

      Signup

      +
      +
      + + +
      +
      + + + +
      +
      + + +
      +
      + + + +
      +
      + + + +
      + +
      +
      diff --git a/myappvs/src/main/resources/static/studentAccounts.html b/myappvs/src/main/resources/static/studentAccounts.html new file mode 100644 index 0000000..dc8a887 --- /dev/null +++ b/myappvs/src/main/resources/static/studentAccounts.html @@ -0,0 +1,113 @@ + + + + + + Student Account Details + + + + +
      +

      Student Account Details

      +
      + +
      +
      + + + diff --git a/myappvs/src/main/resources/static/studentNotes.html b/myappvs/src/main/resources/static/studentNotes.html new file mode 100644 index 0000000..185aee9 --- /dev/null +++ b/myappvs/src/main/resources/static/studentNotes.html @@ -0,0 +1,212 @@ + + + + + + Student Notes + + + +
      + +
      + Welcome, User +
      +
      +

      Student Notes

      +
      +

      Add a New Note

      +
      + + + + +
      +
      + + + + + + + + + + + +
      Note TitleNote ContentCourse IDActions
      + + + + diff --git a/myappvs/src/main/resources/static/userRentals.html b/myappvs/src/main/resources/static/userRentals.html new file mode 100644 index 0000000..567948a --- /dev/null +++ b/myappvs/src/main/resources/static/userRentals.html @@ -0,0 +1,125 @@ + + + + + + Your Rentals + + + +
      + +
      + Welcome, User +
      +
      +

      Your Rentals

      + + + + + + + + + + + +
      Equipment NameTypeRental DateReturn Date
      + + + + \ No newline at end of file diff --git a/myappvs/src/test/java/com/CourseManagementSystem/myappvs/courseCatalog/CatalogServiceTest.java b/myappvs/src/test/java/com/CourseManagementSystem/myappvs/courseCatalog/CatalogServiceTest.java new file mode 100644 index 0000000..4ce033c --- /dev/null +++ b/myappvs/src/test/java/com/CourseManagementSystem/myappvs/courseCatalog/CatalogServiceTest.java @@ -0,0 +1,46 @@ +package com.CourseManagementSystem.myappvs.courseCatalog; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.mockito.Mockito.when; + +import java.util.Arrays; +import java.util.List; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; + +@ExtendWith(MockitoExtension.class) +public class CatalogServiceTest { + + @Mock + private CatalogRepository catalogRepository; + + @InjectMocks + private CatalogService catalogService; + + private Catalog catalog1; + private Catalog catalog2; + + @BeforeEach + void setUp() { + catalog1 = new Catalog(1L, "Course 1", "Description 1", null, 3); + catalog2 = new Catalog(2L, "Course 2", "Description 2", null, 4); + } + + @Test + void testGetAllCourses() { + List catalogs = Arrays.asList(catalog1, catalog2); + + when(catalogRepository.findAll()).thenReturn(catalogs); + + List result = catalogService.getAllCourses(); + + assertEquals(2, result.size()); + assertEquals("Course 1", result.get(0).getCourseName()); + assertEquals("Course 2", result.get(1).getCourseName()); + } +} diff --git a/myappvs/src/test/java/com/CourseManagementSystem/myappvs/enrollments/EnrollmentServiceTest.java b/myappvs/src/test/java/com/CourseManagementSystem/myappvs/enrollments/EnrollmentServiceTest.java new file mode 100644 index 0000000..1a36c62 --- /dev/null +++ b/myappvs/src/test/java/com/CourseManagementSystem/myappvs/enrollments/EnrollmentServiceTest.java @@ -0,0 +1,92 @@ +package com.CourseManagementSystem.myappvs.enrollments; + +import static org.junit.jupiter.api.Assertions.*; +import static org.mockito.Mockito.*; + +import java.util.Arrays; +import java.util.List; +import java.util.Optional; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; + +import com.CourseManagementSystem.myappvs.courseCatalog.Catalog; +import com.CourseManagementSystem.myappvs.courseCatalog.CatalogRepository; +import com.CourseManagementSystem.myappvs.student.Student; +import com.CourseManagementSystem.myappvs.student.Studentrepository; + +import jakarta.persistence.EntityManager; + +@ExtendWith(MockitoExtension.class) +public class EnrollmentServiceTest { + + @Mock + private Studentrepository studentRepo; + + @Mock + private EnrollmentRepository enrollmentRepo; + + @Mock + private CatalogRepository catalogRepo; + + @Mock + private EntityManager entityManager; + + @InjectMocks + private EnrollmentService enrollmentService; + + private Student student; + private Catalog catalog; + private Enrollment enrollment; + + @BeforeEach + void setUp() { + student = new Student(); + student.setStudentIdNumber(1L); + student.setEmailId("test@example.com"); + + catalog = new Catalog(); + catalog.setCourseId(1L); + catalog.setCourseName("Test Course"); + + enrollment = new Enrollment(); + enrollment.setId(1L); + enrollment.setStudent(student); + enrollment.setCatalog(catalog); + } + + @Test + void testEnrollStudent() { + when(studentRepo.findByEmailId(anyString())).thenReturn(Optional.of(student)); + when(catalogRepo.findById(anyLong())).thenReturn(Optional.of(catalog)); + when(enrollmentRepo.findByStudent_StudentIdNumberAndCatalog_CourseId(anyLong(), anyLong())).thenReturn(Optional.empty()); + + enrollmentService.enrollStudent("test@example.com", 1L); + + verify(enrollmentRepo, times(1)).save(any(Enrollment.class)); + } + + @Test + void testGetStudentEnrollment() { + when(studentRepo.findByEmailId(anyString())).thenReturn(Optional.of(student)); + when(enrollmentRepo.findByStudent_StudentIdNumber(anyLong())).thenReturn(Arrays.asList(enrollment)); + + List enrollments = enrollmentService.getStudentEnrollment("test@example.com"); + + assertEquals(1, enrollments.size()); + assertEquals("Test Course", enrollments.get(0).getCatalog().getCourseName()); + } + + @Test + void testDeleteEnrollmentById() { + when(enrollmentRepo.findById(anyLong())).thenReturn(Optional.of(enrollment)); + + enrollmentService.deleteEnrollmentById(1L); + + verify(enrollmentRepo, times(1)).delete(any(Enrollment.class)); + } +} diff --git a/myappvs/src/test/java/com/CourseManagementSystem/myappvs/profile/ProfileControllerTest.java b/myappvs/src/test/java/com/CourseManagementSystem/myappvs/profile/ProfileControllerTest.java new file mode 100644 index 0000000..3b3825c --- /dev/null +++ b/myappvs/src/test/java/com/CourseManagementSystem/myappvs/profile/ProfileControllerTest.java @@ -0,0 +1,117 @@ +package com.CourseManagementSystem.myappvs.profile; + +import com.CourseManagementSystem.myappvs.student.Student; +import com.CourseManagementSystem.myappvs.student.Studentrepository; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.context.SecurityContext; +import org.springframework.security.core.context.SecurityContextHolder; + +import java.util.Map; +import java.util.Optional; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.mockito.Mockito.*; + +@ExtendWith(MockitoExtension.class) +public class ProfileControllerTest { + + @InjectMocks + private Profilecontroller profileController; + + @Mock + private Studentrepository studentRepository; + + @Mock + private Authentication authentication; + + @Mock + private SecurityContext securityContext; + + @Test + void testShowProfileAuthenticated() { + when(securityContext.getAuthentication()).thenReturn(authentication); + SecurityContextHolder.setContext(securityContext); + + when(authentication.isAuthenticated()).thenReturn(true); + when(authentication.getName()).thenReturn("test@example.com"); + + Student student = new Student(); + student.setEmailId("test@example.com"); + student.setName("Test User"); + student.setStudentIdNumber((long) 12345); + student.setNumber("1234567890"); + + when(studentRepository.findByEmailId("test@example.com")).thenReturn(Optional.of(student)); + + ResponseEntity> response = profileController.showProfile(); + + assertEquals(HttpStatus.OK, response.getStatusCode()); + assertEquals("test@example.com", response.getBody().get("emailId")); + assertEquals("Test User", response.getBody().get("name")); + } + + @Test + void testShowProfileNotAuthenticated() { + when(securityContext.getAuthentication()).thenReturn(authentication); + SecurityContextHolder.setContext(securityContext); + + when(authentication.isAuthenticated()).thenReturn(false); + + ResponseEntity> response = profileController.showProfile(); + + assertEquals(HttpStatus.UNAUTHORIZED, response.getStatusCode()); + } + + @Test + void testUpdateProfile() { + when(securityContext.getAuthentication()).thenReturn(authentication); + SecurityContextHolder.setContext(securityContext); + + when(authentication.isAuthenticated()).thenReturn(true); + when(authentication.getName()).thenReturn("test@example.com"); + + Student existingStudent = new Student(); + existingStudent.setEmailId("test@example.com"); + existingStudent.setName("Old Name"); + existingStudent.setNumber("1234567890"); + + Student updatedStudent = new Student(); + updatedStudent.setName("New Name"); + updatedStudent.setNumber("0987654321"); + + when(studentRepository.findByEmailId("test@example.com")).thenReturn(Optional.of(existingStudent)); + + ResponseEntity response = profileController.updateProfile(updatedStudent); + + assertEquals(HttpStatus.OK, response.getStatusCode()); + verify(studentRepository).save(existingStudent); + assertEquals("New Name", existingStudent.getName()); + assertEquals("0987654321", existingStudent.getNumber()); + } + + @Test + void testDeleteProfile() { + when(securityContext.getAuthentication()).thenReturn(authentication); + SecurityContextHolder.setContext(securityContext); + + when(authentication.isAuthenticated()).thenReturn(true); + when(authentication.getName()).thenReturn("test@example.com"); + + Student student = new Student(); + student.setEmailId("test@example.com"); + + when(studentRepository.findByEmailId("test@example.com")).thenReturn(Optional.of(student)); + + ResponseEntity response = profileController.deleteProfile(); + + assertEquals(HttpStatus.OK, response.getStatusCode()); + verify(studentRepository).delete(student); + } +} \ No newline at end of file diff --git a/myappvs/src/test/java/com/CourseManagementSystem/myappvs/user/LoginServiceTest.java b/myappvs/src/test/java/com/CourseManagementSystem/myappvs/user/LoginServiceTest.java new file mode 100644 index 0000000..887972f --- /dev/null +++ b/myappvs/src/test/java/com/CourseManagementSystem/myappvs/user/LoginServiceTest.java @@ -0,0 +1,112 @@ +package com.CourseManagementSystem.myappvs.user; + +import com.CourseManagementSystem.myappvs.student.Student; +import com.CourseManagementSystem.myappvs.student.Studentrepository; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.mockito.junit.jupiter.MockitoExtension; +import org.springframework.security.crypto.password.PasswordEncoder; +import org.springframework.security.core.userdetails.UserDetailsService; + +import java.util.Optional; + +import static org.junit.jupiter.api.Assertions.*; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.*; + +@ExtendWith(MockitoExtension.class) +public class LoginServiceTest { + + @Mock + private Studentrepository studentRepository; + + @Mock + private PasswordEncoder passwordEncoder; + + @Mock + private Userserviceimpl userService; + + @InjectMocks + private Loginservice loginservice; + + private Student student; + private Student existingStudent; + + @BeforeEach + void setUp() { + MockitoAnnotations.openMocks(this); + student = new Student(); + student.setEmailId("test@example.com"); + student.setPassword("password"); + + existingStudent = new Student(); + existingStudent.setEmailId("test@example.com"); + existingStudent.setPassword("encodedPassword"); + existingStudent.setName("Test User"); + } + + @Test + void loginInvalidCredentialsTest() { + when(studentRepository.findByEmailId("test@example.com")).thenReturn(Optional.empty()); + + Exception exception = assertThrows(Exception.class, () -> { + loginservice.login(student); + }); + + assertEquals("Invalid credentials", exception.getMessage()); + verify(studentRepository, times(1)).findByEmailId("test@example.com"); + } + + @Test + void addStudentTest() { + when(studentRepository.save(any(Student.class))).thenReturn(student); + + Student savedStudent = loginservice.addStudent(student); + + assertNotNull(savedStudent); + assertEquals("test@example.com", savedStudent.getEmailId()); + verify(studentRepository, times(1)).save(student); + } + + @Test + void addUserTest() { + student.setPassword("rawPassword"); + when(passwordEncoder.encode("rawPassword")).thenReturn("encodedPassword"); + when(studentRepository.save(any(Student.class))).thenReturn(student); + + Student savedStudent = loginservice.addUser(student); + + assertNotNull(savedStudent); + assertEquals("encodedPassword", savedStudent.getPassword()); + verify(passwordEncoder, times(1)).encode("rawPassword"); + verify(studentRepository, times(1)).save(student); + } + + @Test + void getStudentByEmailTest() { + when(studentRepository.findByEmailId("test@example.com")).thenReturn(Optional.of(student)); + + Student foundStudent = loginservice.getStudentByEmail("test@example.com"); + + assertNotNull(foundStudent); + assertEquals("test@example.com", foundStudent.getEmailId()); + verify(studentRepository, times(1)).findByEmailId("test@example.com"); + } + + @Test + void getStudentByEmailNotFoundTest() { + when(studentRepository.findByEmailId("test@example.com")).thenReturn(Optional.empty()); + + RuntimeException exception = assertThrows(RuntimeException.class, () -> { + loginservice.getStudentByEmail("test@example.com"); + }); + + assertEquals("Student not found", exception.getMessage()); + verify(studentRepository, times(1)).findByEmailId("test@example.com"); + } + +}