getAllBorrowingsOfMember(int memberId, Pageable pagea
*/
- public Borrowings DtoToEntity(BorrowingsDto borrowingsDto){
+ public Borrowings DtoToEntity(BorrowingsDto borrowingsDto) {
Borrowings borrowings = new Borrowings();
borrowings.setBorrowDate(borrowingsDto.getBorrowDate());
borrowings.setMember(memberService.DtoEntity(borrowingsDto.getMember()));
@@ -322,6 +323,7 @@ public Borrowings DtoToEntity(BorrowingsDto borrowingsDto){
borrowings.setBorrowingId(borrowingsDto.getBorrowingId());
return borrowings;
}
+
/**
* Converts a Borrowings entity to a BorrowingsDto object.
*
@@ -336,7 +338,7 @@ public Borrowings DtoToEntity(BorrowingsDto borrowingsDto){
*/
- public BorrowingsDto EntityToDto(Borrowings borrowings){
+ public BorrowingsDto EntityToDto(Borrowings borrowings) {
BorrowingsDto borrowingsDto = new BorrowingsDto();
borrowingsDto.setBorrowingId(borrowings.getBorrowingId());
borrowingsDto.setFine(borrowings.getFine());
diff --git a/src/main/java/com/libraryman_api/borrowing/Borrowings.java b/src/main/java/com/libraryman_api/borrowing/Borrowings.java
index 547f1ac..cff70dd 100644
--- a/src/main/java/com/libraryman_api/borrowing/Borrowings.java
+++ b/src/main/java/com/libraryman_api/borrowing/Borrowings.java
@@ -30,7 +30,7 @@ public class Borrowings {
@JoinColumn(name = "member_id", nullable = false)
private Members member;
- @Column(name = "borrow_date",nullable = false)
+ @Column(name = "borrow_date", nullable = false)
private Date borrowDate;
@Column(name = "due_date", nullable = false)
@@ -63,6 +63,10 @@ public int getBorrowingId() {
return borrowingId;
}
+ public void setBorrowingId(int borrowingId) {
+ this.borrowingId = borrowingId;
+ }
+
public Book getBook() {
return book;
}
@@ -75,8 +79,6 @@ public Members getMember() {
return member;
}
- public void setBorrowingId(int borrowingId) {this.borrowingId = borrowingId;}
-
public void setMember(Members member) {
this.member = member;
}
diff --git a/src/main/java/com/libraryman_api/borrowing/BorrowingsDto.java b/src/main/java/com/libraryman_api/borrowing/BorrowingsDto.java
index 7c1b392..af9c859 100644
--- a/src/main/java/com/libraryman_api/borrowing/BorrowingsDto.java
+++ b/src/main/java/com/libraryman_api/borrowing/BorrowingsDto.java
@@ -9,23 +9,14 @@
public class BorrowingsDto {
private int borrowingId;
-
-
private BookDto book;
-
-
private Fines fine;
-
-
private MembersDto member;
-
private Date borrowDate;
-
-
private Date dueDate;
+ private Date returnDate;
- private Date returnDate;
public BorrowingsDto(int borrowingId, BookDto book, Fines fine, MembersDto member, Date borrowDate, Date dueDate, Date returnDate) {
this.borrowingId = borrowingId;
diff --git a/src/main/java/com/libraryman_api/email/EmailService.java b/src/main/java/com/libraryman_api/email/EmailService.java
index 288723f..f5f80b3 100644
--- a/src/main/java/com/libraryman_api/email/EmailService.java
+++ b/src/main/java/com/libraryman_api/email/EmailService.java
@@ -1,15 +1,18 @@
package com.libraryman_api.email;
+import com.libraryman_api.notification.NotificationRepository;
import com.libraryman_api.notification.NotificationStatus;
import com.libraryman_api.notification.Notifications;
-import com.libraryman_api.notification.NotificationRepository;
+
import jakarta.mail.MessagingException;
import jakarta.mail.internet.MimeMessage;
+import org.springframework.mail.javamail.JavaMailSender;
+import org.springframework.mail.javamail.MimeMessageHelper;
+
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+
import org.springframework.beans.factory.annotation.Value;
-import org.springframework.mail.javamail.JavaMailSender;
-import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
@@ -20,11 +23,9 @@
@Service
public class EmailService implements EmailSender {
+ private static final Logger LOGGER = LoggerFactory.getLogger(EmailService.class);
private final NotificationRepository notificationRepository;
private final JavaMailSender mailSender;
-
- private static final Logger LOGGER = LoggerFactory.getLogger(EmailService.class);
-
@Value("${spring.mail.properties.domain_name}")
private String domainName;
@@ -32,7 +33,7 @@ public class EmailService implements EmailSender {
* Constructs a new {@code EmailService} with the specified {@link NotificationRepository} and {@link JavaMailSender}.
*
* @param notificationRepository the repository for managing notification entities
- * @param mailSender the mail sender for sending email messages
+ * @param mailSender the mail sender for sending email messages
*/
public EmailService(NotificationRepository notificationRepository, JavaMailSender mailSender) {
this.notificationRepository = notificationRepository;
@@ -44,9 +45,9 @@ public EmailService(NotificationRepository notificationRepository, JavaMailSende
* If the email is successfully sent, the notification status is updated to SENT.
* If the email fails to send, the notification status is updated to FAILED and an exception is thrown.
*
- * @param to the recipient's email address
- * @param email the content of the email to send
- * @param subject the subject of the email
+ * @param to the recipient's email address
+ * @param email the content of the email to send
+ * @param subject the subject of the email
* @param notification the {@link Notifications} object representing the email notification
*/
@Override
diff --git a/src/main/java/com/libraryman_api/exception/ErrorDetails.java b/src/main/java/com/libraryman_api/exception/ErrorDetails.java
index 29e6112..b0055cd 100644
--- a/src/main/java/com/libraryman_api/exception/ErrorDetails.java
+++ b/src/main/java/com/libraryman_api/exception/ErrorDetails.java
@@ -12,7 +12,7 @@
* An equals() method that checks for equality based on the components.
* A hashCode() method that calculates a hash code based on the components.
*
- *
+ *
* For the ErrorDetails record, the compiler will automatically generate the following members:
*
* Private final fields:
diff --git a/src/main/java/com/libraryman_api/exception/GlobalExceptionHandler.java b/src/main/java/com/libraryman_api/exception/GlobalExceptionHandler.java
index 6e637e7..3ef1ca0 100644
--- a/src/main/java/com/libraryman_api/exception/GlobalExceptionHandler.java
+++ b/src/main/java/com/libraryman_api/exception/GlobalExceptionHandler.java
@@ -16,57 +16,57 @@
@ControllerAdvice
public class GlobalExceptionHandler {
- /**
- * Handles {@link ResourceNotFoundException} exceptions. This method is
- * triggered when a {@code ResourceNotFoundException} is thrown in the
- * application. It constructs an {@link ErrorDetails} object containing the
- * exception details and returns a {@link ResponseEntity} with an HTTP status of
- * {@code 404 Not Found}.
- *
- * @param ex the exception that was thrown.
- * @param request the current web request in which the exception was thrown.
- * @return a {@link ResponseEntity} containing the {@link ErrorDetails} and an
- * HTTP status of {@code 404 Not Found}.
- */
- @ExceptionHandler(ResourceNotFoundException.class)
- public ResponseEntity> resourceNotFoundException(ResourceNotFoundException ex, WebRequest request) {
- ErrorDetails errorDetails = new ErrorDetails(new Date(), ex.getMessage(), request.getDescription(false));
- return new ResponseEntity<>(errorDetails, HttpStatus.NOT_FOUND);
- }
+ /**
+ * Handles {@link ResourceNotFoundException} exceptions. This method is
+ * triggered when a {@code ResourceNotFoundException} is thrown in the
+ * application. It constructs an {@link ErrorDetails} object containing the
+ * exception details and returns a {@link ResponseEntity} with an HTTP status of
+ * {@code 404 Not Found}.
+ *
+ * @param ex the exception that was thrown.
+ * @param request the current web request in which the exception was thrown.
+ * @return a {@link ResponseEntity} containing the {@link ErrorDetails} and an
+ * HTTP status of {@code 404 Not Found}.
+ */
+ @ExceptionHandler(ResourceNotFoundException.class)
+ public ResponseEntity> resourceNotFoundException(ResourceNotFoundException ex, WebRequest request) {
+ ErrorDetails errorDetails = new ErrorDetails(new Date(), ex.getMessage(), request.getDescription(false));
+ return new ResponseEntity<>(errorDetails, HttpStatus.NOT_FOUND);
+ }
- /**
- * Handles {@link InvalidSortFieldException} exceptions. This method is
- * triggered when an {@code InvalidSortFieldException} is thrown in the
- * application. It constructs an {@link ErrorDetails} object containing the
- * exception details and returns a {@link ResponseEntity} with an HTTP status of
- * {@code 400 Bad Request}.
- *
- * @param ex the exception that was thrown.
- * @param request the current web request in which the exception was thrown.
- * @return a {@link ResponseEntity} containing the {@link ErrorDetails} and an
- * HTTP status of {@code 400 Bad Request}.
- */
- @ExceptionHandler(InvalidSortFieldException.class)
- public ResponseEntity> invalidSortFieldException(InvalidSortFieldException ex, WebRequest request) {
- ErrorDetails errorDetails = new ErrorDetails(new Date(), ex.getMessage(), request.getDescription(false));
- return new ResponseEntity<>(errorDetails, HttpStatus.BAD_REQUEST);
- }
+ /**
+ * Handles {@link InvalidSortFieldException} exceptions. This method is
+ * triggered when an {@code InvalidSortFieldException} is thrown in the
+ * application. It constructs an {@link ErrorDetails} object containing the
+ * exception details and returns a {@link ResponseEntity} with an HTTP status of
+ * {@code 400 Bad Request}.
+ *
+ * @param ex the exception that was thrown.
+ * @param request the current web request in which the exception was thrown.
+ * @return a {@link ResponseEntity} containing the {@link ErrorDetails} and an
+ * HTTP status of {@code 400 Bad Request}.
+ */
+ @ExceptionHandler(InvalidSortFieldException.class)
+ public ResponseEntity> invalidSortFieldException(InvalidSortFieldException ex, WebRequest request) {
+ ErrorDetails errorDetails = new ErrorDetails(new Date(), ex.getMessage(), request.getDescription(false));
+ return new ResponseEntity<>(errorDetails, HttpStatus.BAD_REQUEST);
+ }
- /**
- * Handles {@link InvalidPasswordException} exceptions. This method is triggered
- * when an {@code InvalidPasswordException} is thrown in the application. It
- * constructs an {@link ErrorDetails} object containing the exception details
- * and returns a {@link ResponseEntity} with an HTTP status of
- * {@code 400 Bad Request}.
- *
- * @param ex the exception that was thrown.
- * @param request the current web request in which the exception was thrown.
- * @return a {@link ResponseEntity} containing the {@link ErrorDetails} and an
- * HTTP status of {@code 400 Bad Request}.
- */
- @ExceptionHandler(InvalidPasswordException.class)
- public ResponseEntity> invalidPasswordException(InvalidPasswordException ex, WebRequest request) {
- ErrorDetails errorDetails = new ErrorDetails(new Date(), ex.getMessage(), request.getDescription(false));
- return new ResponseEntity<>(errorDetails, HttpStatus.BAD_REQUEST);
- }
+ /**
+ * Handles {@link InvalidPasswordException} exceptions. This method is triggered
+ * when an {@code InvalidPasswordException} is thrown in the application. It
+ * constructs an {@link ErrorDetails} object containing the exception details
+ * and returns a {@link ResponseEntity} with an HTTP status of
+ * {@code 400 Bad Request}.
+ *
+ * @param ex the exception that was thrown.
+ * @param request the current web request in which the exception was thrown.
+ * @return a {@link ResponseEntity} containing the {@link ErrorDetails} and an
+ * HTTP status of {@code 400 Bad Request}.
+ */
+ @ExceptionHandler(InvalidPasswordException.class)
+ public ResponseEntity> invalidPasswordException(InvalidPasswordException ex, WebRequest request) {
+ ErrorDetails errorDetails = new ErrorDetails(new Date(), ex.getMessage(), request.getDescription(false));
+ return new ResponseEntity<>(errorDetails, HttpStatus.BAD_REQUEST);
+ }
}
diff --git a/src/main/java/com/libraryman_api/exception/InvalidPasswordException.java b/src/main/java/com/libraryman_api/exception/InvalidPasswordException.java
index 27013c0..2b4a5a8 100644
--- a/src/main/java/com/libraryman_api/exception/InvalidPasswordException.java
+++ b/src/main/java/com/libraryman_api/exception/InvalidPasswordException.java
@@ -13,15 +13,15 @@ public class InvalidPasswordException extends RuntimeException {
* The {@code serialVersionUID} is a unique identifier for each version of a serializable class.
* It is used during the deserialization process to verify that the sender and receiver of a
* serialized object have loaded classes for that object that are compatible with each other.
- *
+ *
* The {@code serialVersionUID} field is important for ensuring that a serialized class
* (especially when transmitted over a network or saved to disk) can be successfully deserialized,
* even if the class definition changes in later versions. If the {@code serialVersionUID} does not
* match during deserialization, an {@code InvalidClassException} is thrown.
- *
+ *
* This field is optional, but it is good practice to explicitly declare it to prevent
* automatic generation, which could lead to compatibility issues when the class structure changes.
- *
+ *
* The {@code @Serial} annotation is used here to indicate that this field is related to
* serialization. This annotation is available starting from Java 14 and helps improve clarity
* regarding the purpose of this field.
diff --git a/src/main/java/com/libraryman_api/exception/InvalidSortFieldException.java b/src/main/java/com/libraryman_api/exception/InvalidSortFieldException.java
index e757a40..03d89f4 100644
--- a/src/main/java/com/libraryman_api/exception/InvalidSortFieldException.java
+++ b/src/main/java/com/libraryman_api/exception/InvalidSortFieldException.java
@@ -14,15 +14,15 @@ public class InvalidSortFieldException extends RuntimeException {
* The {@code serialVersionUID} is a unique identifier for each version of a serializable class.
* It is used during the deserialization process to verify that the sender and receiver of a
* serialized object have loaded classes for that object that are compatible with each other.
- *
+ *
* The {@code serialVersionUID} field is important for ensuring that a serialized class
* (especially when transmitted over a network or saved to disk) can be successfully deserialized,
* even if the class definition changes in later versions. If the {@code serialVersionUID} does not
* match during deserialization, an {@code InvalidClassException} is thrown.
- *
+ *
* This field is optional, but it is good practice to explicitly declare it to prevent
* automatic generation, which could lead to compatibility issues when the class structure changes.
- *
+ *
* The {@code @Serial} annotation is used here to indicate that this field is related to
* serialization. This annotation is available starting from Java 14 and helps improve clarity
* regarding the purpose of this field.
diff --git a/src/main/java/com/libraryman_api/exception/ResourceNotFoundException.java b/src/main/java/com/libraryman_api/exception/ResourceNotFoundException.java
index 56a5840..a0242c3 100644
--- a/src/main/java/com/libraryman_api/exception/ResourceNotFoundException.java
+++ b/src/main/java/com/libraryman_api/exception/ResourceNotFoundException.java
@@ -14,15 +14,15 @@ public class ResourceNotFoundException extends RuntimeException {
* The {@code serialVersionUID} is a unique identifier for each version of a serializable class.
* It is used during the deserialization process to verify that the sender and receiver of a
* serialized object have loaded classes for that object that are compatible with each other.
- *
+ *
* The {@code serialVersionUID} field is important for ensuring that a serialized class
* (especially when transmitted over a network or saved to disk) can be successfully deserialized,
* even if the class definition changes in later versions. If the {@code serialVersionUID} does not
* match during deserialization, an {@code InvalidClassException} is thrown.
- *
+ *
* This field is optional, but it is good practice to explicitly declare it to prevent
* automatic generation, which could lead to compatibility issues when the class structure changes.
- *
+ *
* The {@code @Serial} annotation is used here to indicate that this field is related to
* serialization. This annotation is available starting from Java 14 and helps improve clarity
* regarding the purpose of this field.
diff --git a/src/main/java/com/libraryman_api/fine/Fines.java b/src/main/java/com/libraryman_api/fine/Fines.java
index 48e06c2..ca0a674 100644
--- a/src/main/java/com/libraryman_api/fine/Fines.java
+++ b/src/main/java/com/libraryman_api/fine/Fines.java
@@ -15,11 +15,12 @@ public class Fines {
@Column(name = "fine_id")
private int fineId;
-/**
- * precision = 10 means the total number of digits (including decimal places) is 10.
- * scale = 2 means the number of decimal places is 2.
- * @Column(nullable = false, precision = 10, scale = 2)
- * */
+ /**
+ * precision = 10 means the total number of digits (including decimal places) is 10.
+ * scale = 2 means the number of decimal places is 2.
+ *
+ * @Column(nullable = false, precision = 10, scale = 2)
+ */
@Column(nullable = false, scale = 2)
private BigDecimal amount;
@@ -29,9 +30,7 @@ public class Fines {
public Fines() {
}
-
- public Fines( BigDecimal amount, boolean paid) {
-
+ public Fines(BigDecimal amount, boolean paid) {
this.amount = amount;
this.paid = paid;
}
diff --git a/src/main/java/com/libraryman_api/member/MemberController.java b/src/main/java/com/libraryman_api/member/MemberController.java
index 20a729a..a628d80 100644
--- a/src/main/java/com/libraryman_api/member/MemberController.java
+++ b/src/main/java/com/libraryman_api/member/MemberController.java
@@ -1,5 +1,9 @@
package com.libraryman_api.member;
+import com.libraryman_api.exception.ResourceNotFoundException;
+import com.libraryman_api.member.dto.MembersDto;
+import com.libraryman_api.member.dto.UpdateMembersDto;
+import com.libraryman_api.member.dto.UpdatePasswordDto;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
@@ -7,19 +11,7 @@
import org.springframework.data.web.PageableDefault;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
-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.PutMapping;
-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.libraryman_api.exception.ResourceNotFoundException;
-import com.libraryman_api.member.dto.MembersDto;
-import com.libraryman_api.member.dto.UpdateMembersDto;
-import com.libraryman_api.member.dto.UpdatePasswordDto;
+import org.springframework.web.bind.annotation.*;
/**
* REST controller for managing library members.
@@ -44,28 +36,28 @@ public MemberController(MemberService memberService) {
* Retrieves a paginated and sorted list of all library members.
*
* @param pageable contains pagination information (page number, size, and sorting).
- * @param sortBy (optional) the field by which to sort the results.
- * @param sortDir (optional) the direction of sorting (asc or desc). Defaults to ascending.
+ * @param sortBy (optional) the field by which to sort the results.
+ * @param sortDir (optional) the direction of sorting (asc or desc). Defaults to ascending.
* @return a {@link Page} of {@link Members} representing all members in the library.
- * The results are sorted by name by default and limited to 5 members per page.
+ * The results are sorted by name by default and limited to 5 members per page.
*/
@GetMapping
@PreAuthorize("hasRole('LIBRARIAN') or hasRole('ADMIN')")
- public Page getAllMembers(@PageableDefault(page=0, size=5, sort="name") Pageable pageable,
- @RequestParam(required = false) String sortBy,
- @RequestParam(required = false) String sortDir) {
-
- // Adjust the pageable based on dynamic sorting parameters
- if(sortBy!=null && !sortBy.isEmpty()) {
- Sort.Direction direction= Sort.Direction.ASC; // Default direction
-
- if(sortDir!=null && sortDir.equalsIgnoreCase("desc")) {
- direction = Sort.Direction.DESC;
- }
+ public Page getAllMembers(@PageableDefault(page = 0, size = 5, sort = "name") Pageable pageable,
+ @RequestParam(required = false) String sortBy,
+ @RequestParam(required = false) String sortDir) {
+
+ // Adjust the pageable based on dynamic sorting parameters
+ if (sortBy != null && !sortBy.isEmpty()) {
+ Sort.Direction direction = Sort.Direction.ASC; // Default direction
+
+ if (sortDir != null && sortDir.equalsIgnoreCase("desc")) {
+ direction = Sort.Direction.DESC;
+ }
+
+ pageable = PageRequest.of(pageable.getPageNumber(), pageable.getPageSize(), Sort.by(direction, sortBy));
+ }
- pageable = PageRequest.of(pageable.getPageNumber(), pageable.getPageSize(), Sort.by(direction, sortBy)) ;
- }
-
return memberService.getAllMembers(pageable);
}
@@ -88,7 +80,7 @@ public ResponseEntity getMemberById(@PathVariable int id) {
* Updates an existing library member.
* If the member is not found, a {@link ResourceNotFoundException} is thrown.
*
- * @param id the ID of the member to update
+ * @param id the ID of the member to update
* @param membersDtoDetails the {@link Members} object containing the updated details
* @return the updated {@link Members} object
*/
@@ -109,19 +101,19 @@ public MembersDto updateMember(@PathVariable int id, @RequestBody UpdateMembersD
public void deleteMember(@PathVariable int id) {
memberService.deleteMember(id);
}
-
+
/**
* Updates the password for a library member.
* If the member is not found or the update fails, an appropriate exception will be thrown.
*
- * @param id the ID of the member whose password is to be updated
+ * @param id the ID of the member whose password is to be updated
* @param updatePasswordDto the {@link UpdatePasswordDto} object containing the password details
* @return a {@link ResponseEntity} containing a success message indicating the password was updated successfully
*/
@PutMapping("/{id}/password")
@PreAuthorize("#id == authentication.principal.memberId")
- public ResponseEntity> updatePassword(@PathVariable int id,
- @RequestBody UpdatePasswordDto updatePasswordDto) {
+ public ResponseEntity> updatePassword(@PathVariable int id,
+ @RequestBody UpdatePasswordDto updatePasswordDto) {
memberService.updatePassword(id, updatePasswordDto);
return ResponseEntity.ok("Password updated successfully.");
}
diff --git a/src/main/java/com/libraryman_api/member/MemberService.java b/src/main/java/com/libraryman_api/member/MemberService.java
index 8f053c8..553d650 100644
--- a/src/main/java/com/libraryman_api/member/MemberService.java
+++ b/src/main/java/com/libraryman_api/member/MemberService.java
@@ -1,14 +1,5 @@
package com.libraryman_api.member;
-import java.util.Optional;
-
-import org.springframework.cache.annotation.CacheEvict;
-import org.springframework.cache.annotation.Cacheable;
-import org.springframework.data.domain.Page;
-import org.springframework.data.domain.Pageable;
-import org.springframework.data.mapping.PropertyReferenceException;
-import org.springframework.stereotype.Service;
-
import com.libraryman_api.exception.InvalidPasswordException;
import com.libraryman_api.exception.InvalidSortFieldException;
import com.libraryman_api.exception.ResourceNotFoundException;
@@ -17,7 +8,14 @@
import com.libraryman_api.member.dto.UpdatePasswordDto;
import com.libraryman_api.notification.NotificationService;
import com.libraryman_api.security.config.PasswordEncoder;
+import org.springframework.cache.annotation.CacheEvict;
+import org.springframework.cache.annotation.Cacheable;
+import org.springframework.data.domain.Page;
+import org.springframework.data.domain.Pageable;
+import org.springframework.data.mapping.PropertyReferenceException;
+import org.springframework.stereotype.Service;
+import java.util.Optional;
/**
@@ -45,7 +43,7 @@ public class MemberService {
/**
* Constructs a new {@code MemberService} with the specified repositories and services.
*
- * @param memberRepository the repository for managing member records
+ * @param memberRepository the repository for managing member records
* @param notificationService the service for sending notifications related to member activities
*/
public MemberService(MemberRepository memberRepository, NotificationService notificationService, PasswordEncoder passwordEncoder) {
@@ -96,7 +94,7 @@ public Optional getMemberById(int memberId) {
public MembersDto addMember(MembersDto membersDto) {
Members member = DtoEntity(membersDto);
Members currentMember = memberRepository.save(member);
- if(currentMember!=null)
+ if (currentMember != null)
notificationService.accountCreatedNotification(currentMember);
return EntityToDto(currentMember);
@@ -109,7 +107,7 @@ public MembersDto addMember(MembersDto membersDto) {
* {@link ResourceNotFoundException} if the member is not found. After updating,
* a notification about the account details update is sent.
*
- * @param memberId the ID of the member to update
+ * @param memberId the ID of the member to update
* @param membersDtoDetails the updated member details
* @return the updated member record
* @throws ResourceNotFoundException if the member is not found
@@ -123,7 +121,7 @@ public MembersDto updateMember(int memberId, UpdateMembersDto membersDtoDetails)
member.setUsername(membersDtoDetails.getUsername());
member.setEmail(membersDtoDetails.getEmail());
member = memberRepository.save(member);
- if(member!=null)
+ if (member != null)
notificationService.accountDetailsUpdateNotification(member);
return EntityToDto(member);
}
@@ -149,31 +147,31 @@ public void deleteMember(int memberId) {
notificationService.accountDeletionNotification(member);
memberRepository.delete(member);
}
-
+
/**
* Updates the password for a library member.
*
- * This method verifies the current password provided by the member, checks if the
- * new password is different, and then updates the member's password in the database.
- * If the current password is incorrect or the new password is the same as the current
+ *
This method verifies the current password provided by the member, checks if the
+ * new password is different, and then updates the member's password in the database.
+ * If the current password is incorrect or the new password is the same as the current
* password, an {@link InvalidPasswordException} is thrown.
*
- * @param memberId the ID of the member whose password is to be updated
+ * @param memberId the ID of the member whose password is to be updated
* @param updatePasswordDto the {@link UpdatePasswordDto} object containing the password details
* @throws ResourceNotFoundException if the member with the specified ID is not found
- * @throws InvalidPasswordException if the current password is incorrect or the new password is the same as the current password
+ * @throws InvalidPasswordException if the current password is incorrect or the new password is the same as the current password
*/
public void updatePassword(int memberId, UpdatePasswordDto updatePasswordDto) {
Members member = memberRepository.findById(memberId)
.orElseThrow(() -> new ResourceNotFoundException("Member not found"));
// Check the current password
- String currentAuthPassword = member.getPassword();
+ String currentAuthPassword = member.getPassword();
if (!passwordEncoder.bCryptPasswordEncoder().matches(updatePasswordDto.getCurrentPassword(), currentAuthPassword)) {
throw new InvalidPasswordException("Current password is incorrect");
}
-
+
// Check if new password is different from old password
if (updatePasswordDto.getCurrentPassword().equals(updatePasswordDto.getNewPassword())) {
throw new InvalidPasswordException("New password must be different from the old password");
@@ -182,7 +180,7 @@ public void updatePassword(int memberId, UpdatePasswordDto updatePasswordDto) {
member.setPassword(passwordEncoder.bCryptPasswordEncoder().encode(updatePasswordDto.getNewPassword()));
memberRepository.save(member);
}
-
+
/**
* Converts a MembersDto object to a Members entity.
*
@@ -193,8 +191,8 @@ public void updatePassword(int memberId, UpdatePasswordDto updatePasswordDto) {
* @param membersDto the DTO object containing member information
* @return a Members entity with data populated from the DTO
*/
- public Members DtoEntity(MembersDto membersDto){
- Members members= new Members();
+ public Members DtoEntity(MembersDto membersDto) {
+ Members members = new Members();
members.setMemberId(membersDto.getMemberId());
members.setRole(membersDto.getRole());
members.setName(membersDto.getName());
@@ -204,7 +202,7 @@ public Members DtoEntity(MembersDto membersDto){
members.setMembershipDate(membersDto.getMembershipDate());
return members;
}
-
+
/**
* Converts a Members entity to a MembersDto object.
*
@@ -216,8 +214,8 @@ public Members DtoEntity(MembersDto membersDto){
* @param members the entity object containing member information
* @return a MembersDto object with data populated from the entity
*/
- public MembersDto EntityToDto(Members members){
- MembersDto membersDto= new MembersDto();
+ public MembersDto EntityToDto(Members members) {
+ MembersDto membersDto = new MembersDto();
membersDto.setMemberId(members.getMemberId());
membersDto.setName(members.getName());
membersDto.setUsername(members.getUsername());
@@ -225,6 +223,6 @@ public MembersDto EntityToDto(Members members){
membersDto.setEmail(members.getEmail());
membersDto.setPassword(members.getPassword());
membersDto.setMembershipDate(members.getMembershipDate());
- return membersDto;
+ return membersDto;
}
}
diff --git a/src/main/java/com/libraryman_api/member/Members.java b/src/main/java/com/libraryman_api/member/Members.java
index aabdad3..f967f82 100644
--- a/src/main/java/com/libraryman_api/member/Members.java
+++ b/src/main/java/com/libraryman_api/member/Members.java
@@ -1,18 +1,17 @@
package com.libraryman_api.member;
import jakarta.persistence.*;
+import org.springframework.security.core.GrantedAuthority;
+import org.springframework.security.core.authority.SimpleGrantedAuthority;
+import org.springframework.security.core.userdetails.UserDetails;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
-import org.springframework.security.core.GrantedAuthority;
-import org.springframework.security.core.authority.SimpleGrantedAuthority;
-import org.springframework.security.core.userdetails.UserDetails;
-
@Entity
-public class Members implements UserDetails{
+public class Members implements UserDetails {
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE,
@@ -28,7 +27,7 @@ public class Members implements UserDetails{
@Column(name = "username")
private String username;
-
+
@Column(unique = true, nullable = false)
private String email;
@@ -42,8 +41,6 @@ public class Members implements UserDetails{
@Column(name = "membership_date")
private Date membershipDate;
-
-
public Members() {
}
@@ -60,6 +57,10 @@ public int getMemberId() {
return memberId;
}
+ public void setMemberId(int memberId) {
+ this.memberId = memberId;
+ }
+
public String getName() {
return name;
}
@@ -80,8 +81,6 @@ public String getPassword() {
return password;
}
- public void setMemberId(int memberId) {this.memberId = memberId;}
-
public void setPassword(String password) {
this.password = password;
}
@@ -102,18 +101,18 @@ public void setMembershipDate(Date membershipDate) {
this.membershipDate = membershipDate;
}
- public String getUsername() {
- return username;
- }
+ public String getUsername() {
+ return username;
+ }
+
+ public void setUsername(String username) {
+ this.username = username;
+ }
- public void setUsername(String username) {
- this.username = username;
- }
+ @Override
+ public Collection extends GrantedAuthority> getAuthorities() {
+ // TODO Auto-generated method stub
+ return Collections.singletonList(new SimpleGrantedAuthority("ROLE_" + role.name()));
+ }
- @Override
- public Collection extends GrantedAuthority> getAuthorities() {
- // TODO Auto-generated method stub
- return Collections.singletonList(new SimpleGrantedAuthority("ROLE_"+role.name()));
- }
-
}
diff --git a/src/main/java/com/libraryman_api/member/Role.java b/src/main/java/com/libraryman_api/member/Role.java
index e92e5a6..732332d 100644
--- a/src/main/java/com/libraryman_api/member/Role.java
+++ b/src/main/java/com/libraryman_api/member/Role.java
@@ -1,5 +1,5 @@
package com.libraryman_api.member;
public enum Role {
- ADMIN, LIBRARIAN, USER
+ ADMIN, LIBRARIAN, USER
}
diff --git a/src/main/java/com/libraryman_api/member/dto/MembersDto.java b/src/main/java/com/libraryman_api/member/dto/MembersDto.java
index 7f97d8a..c08d655 100644
--- a/src/main/java/com/libraryman_api/member/dto/MembersDto.java
+++ b/src/main/java/com/libraryman_api/member/dto/MembersDto.java
@@ -1,25 +1,17 @@
package com.libraryman_api.member.dto;
-import java.util.Date;
-
import com.libraryman_api.member.Role;
+import java.util.Date;
+
public class MembersDto {
private int memberId;
-
private String name;
-
private String username;
-
private String email;
-
private String password;
-
-
private Role role;
-
-
private Date membershipDate;
public MembersDto(int memberId, String name, String username, String email, String password, Role role, Date membershipDate) {
@@ -46,15 +38,15 @@ public void setMemberId(int memberId) {
public String getName() {
return name;
}
-
- public String getUsername() {
- return username;
- }
public void setName(String name) {
this.name = name;
}
-
+
+ public String getUsername() {
+ return username;
+ }
+
public void setUsername(String username) {
this.username = username;
}
diff --git a/src/main/java/com/libraryman_api/member/dto/UpdateMembersDto.java b/src/main/java/com/libraryman_api/member/dto/UpdateMembersDto.java
index 8859bb3..f76b715 100644
--- a/src/main/java/com/libraryman_api/member/dto/UpdateMembersDto.java
+++ b/src/main/java/com/libraryman_api/member/dto/UpdateMembersDto.java
@@ -3,9 +3,7 @@
public class UpdateMembersDto {
private String name;
-
private String username;
-
private String email;
public UpdateMembersDto(String name, String username, String email) {
@@ -20,15 +18,15 @@ public UpdateMembersDto() {
public String getName() {
return name;
}
-
- public String getUsername() {
- return username;
- }
public void setName(String name) {
this.name = name;
}
-
+
+ public String getUsername() {
+ return username;
+ }
+
public void setUsername(String username) {
this.username = username;
}
diff --git a/src/main/java/com/libraryman_api/member/dto/UpdatePasswordDto.java b/src/main/java/com/libraryman_api/member/dto/UpdatePasswordDto.java
index a7be20a..00a124f 100644
--- a/src/main/java/com/libraryman_api/member/dto/UpdatePasswordDto.java
+++ b/src/main/java/com/libraryman_api/member/dto/UpdatePasswordDto.java
@@ -3,38 +3,37 @@
public class UpdatePasswordDto {
private String currentPassword;
-
private String newPassword;
public UpdatePasswordDto(String currentPassword, String newPassword) {
- this.currentPassword = currentPassword;
- this.newPassword = newPassword;
- }
+ this.currentPassword = currentPassword;
+ this.newPassword = newPassword;
+ }
public UpdatePasswordDto() {
}
-
+
public String getCurrentPassword() {
- return currentPassword;
- }
+ return currentPassword;
+ }
- public void setCurrentPassword(String currentPassword) {
- this.currentPassword = currentPassword;
- }
+ public void setCurrentPassword(String currentPassword) {
+ this.currentPassword = currentPassword;
+ }
- public String getNewPassword() {
- return newPassword;
- }
+ public String getNewPassword() {
+ return newPassword;
+ }
- public void setNewPassword(String newPassword) {
- this.newPassword = newPassword;
- }
+ public void setNewPassword(String newPassword) {
+ this.newPassword = newPassword;
+ }
- @Override
+ @Override
public String toString() {
return "UpdatePasswordDto{" +
- "currentPassword='" + currentPassword + '\'' +
- ", newPassword='" + newPassword + '\'' +
- '}';
+ "currentPassword='" + currentPassword + '\'' +
+ ", newPassword='" + newPassword + '\'' +
+ '}';
}
}
diff --git a/src/main/java/com/libraryman_api/newsletter/NewsletterSubscriber.java b/src/main/java/com/libraryman_api/newsletter/NewsletterSubscriber.java
index 75412b5..aa099c0 100644
--- a/src/main/java/com/libraryman_api/newsletter/NewsletterSubscriber.java
+++ b/src/main/java/com/libraryman_api/newsletter/NewsletterSubscriber.java
@@ -1,6 +1,7 @@
package com.libraryman_api.newsletter;
import jakarta.persistence.*;
+
import java.util.UUID;
@Entity
diff --git a/src/main/java/com/libraryman_api/notification/NotificationService.java b/src/main/java/com/libraryman_api/notification/NotificationService.java
index a79b04b..cfb3d30 100644
--- a/src/main/java/com/libraryman_api/notification/NotificationService.java
+++ b/src/main/java/com/libraryman_api/notification/NotificationService.java
@@ -5,6 +5,8 @@
import com.libraryman_api.exception.ResourceNotFoundException;
import com.libraryman_api.member.MemberRepository;
import com.libraryman_api.member.Members;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
@@ -16,8 +18,6 @@
import java.util.Date;
import java.util.List;
import java.util.Optional;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
/**
@@ -29,10 +29,10 @@
*/
@Service
public class NotificationService {
+ private static final Logger LOGGER = LoggerFactory.getLogger(NotificationService.class);
private final EmailSender emailSender;
private final NotificationRepository notificationRepository;
private final MemberRepository memberRepository;
- private static final Logger LOGGER = LoggerFactory.getLogger(NotificationService.class);
/**
* Constructs a new {@code NotificationService} with the specified {@link EmailSender},
@@ -206,7 +206,7 @@ public void bookReturnedNotification(Borrowings borrowing) {
*/
private void sendNotification(Notifications notification) {
emailSender.send(
- notification.getMember().getEmail(),
+ notification.getMember().getEmail(),
buildEmail(
subject(notification.getNotificationType()),
notification.getMember().getName(),
@@ -220,7 +220,7 @@ private void sendNotification(Notifications notification) {
// Scheduled method to send reminders for books due in 2 days
@Scheduled(cron = "0 0 10 * * ?") // Runs every day at 10 AM
- public void sendDueDateReminders(){
+ public void sendDueDateReminders() {
Calendar calendar = Calendar.getInstance();
// Get today's date
@@ -237,10 +237,10 @@ public void sendDueDateReminders(){
for (Borrowings borrowing : borrowingsDueSoon) {
try {
Optional member = memberRepository.findByMemberId(borrowing.getMember().getMemberId());
- if(member.isPresent())
- reminderNotification(borrowing);
+ if (member.isPresent())
+ reminderNotification(borrowing);
} catch (ResourceNotFoundException e) {
- LOGGER.error("Member not found for memberId: " + borrowing.getMember().getMemberId(), e);
+ LOGGER.error("Member not found for memberId: " + borrowing.getMember().getMemberId(), e);
}
}
}
diff --git a/src/main/java/com/libraryman_api/notification/NotificationType.java b/src/main/java/com/libraryman_api/notification/NotificationType.java
index f2d4dc3..3dfdd41 100644
--- a/src/main/java/com/libraryman_api/notification/NotificationType.java
+++ b/src/main/java/com/libraryman_api/notification/NotificationType.java
@@ -5,27 +5,43 @@
* Represents the types of notifications available in the system.
*/
public enum NotificationType {
- /** Used for account creation notifications. */
+ /**
+ * Used for account creation notifications.
+ */
ACCOUNT_CREATED,
- /** Used for account deletion notifications. */
+ /**
+ * Used for account deletion notifications.
+ */
ACCOUNT_DELETED,
- /** Sent when a user borrows a book. */
+ /**
+ * Sent when a user borrows a book.
+ */
BORROW,
- /** Sent to remind user for due date */
+ /**
+ * Sent to remind user for due date
+ */
REMINDER,
- /** Indicates that a user has paid a fine. */
+ /**
+ * Indicates that a user has paid a fine.
+ */
PAID,
- /** Imposed when a user incurs a fine. */
+ /**
+ * Imposed when a user incurs a fine.
+ */
FINE,
- /** Used when updating user details. */
+ /**
+ * Used when updating user details.
+ */
UPDATE,
- /** Sent when a user returns a borrowed book. */
+ /**
+ * Sent when a user returns a borrowed book.
+ */
RETURNED
}
diff --git a/src/main/java/com/libraryman_api/notification/Notifications.java b/src/main/java/com/libraryman_api/notification/Notifications.java
index 3ef9cb6..a7b948e 100644
--- a/src/main/java/com/libraryman_api/notification/Notifications.java
+++ b/src/main/java/com/libraryman_api/notification/Notifications.java
@@ -2,6 +2,7 @@
import com.libraryman_api.member.Members;
import jakarta.persistence.*;
+
import java.sql.Timestamp;
@Entity
@@ -31,7 +32,6 @@ public class Notifications {
private NotificationStatus notificationStatus;
-
public Notifications() {
}
diff --git a/src/main/java/com/libraryman_api/security/config/WebConfiguration.java b/src/main/java/com/libraryman_api/security/config/WebConfiguration.java
index 47d2d60..61b4002 100644
--- a/src/main/java/com/libraryman_api/security/config/WebConfiguration.java
+++ b/src/main/java/com/libraryman_api/security/config/WebConfiguration.java
@@ -1,8 +1,8 @@
package com.libraryman_api.security.config;
+import com.libraryman_api.security.jwt.JwtAuthenticationFilter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
-
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.configuration.AuthenticationConfiguration;
import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity;
@@ -16,41 +16,42 @@
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;
-import com.libraryman_api.security.jwt.JwtAuthenticationFilter;
-
import static org.springframework.security.config.Customizer.withDefaults;
import static org.springframework.security.config.http.SessionCreationPolicy.STATELESS;
@Configuration
-@EnableWebSecurity(debug = true) // Do not use (debug=true) in a production system! as this contain sensitive information.
+@EnableWebSecurity(debug = true)
+// Do not use (debug=true) in a production system! as this contain sensitive information.
@EnableMethodSecurity(prePostEnabled = true)
public class WebConfiguration {
- private JwtAuthenticationFilter jwtFilter;
-
- public WebConfiguration(JwtAuthenticationFilter jwtFilter) {
- this.jwtFilter=jwtFilter;
- }
+ private final JwtAuthenticationFilter jwtFilter;
+
+ public WebConfiguration(JwtAuthenticationFilter jwtFilter) {
+ this.jwtFilter = jwtFilter;
+ }
+
@Bean
public SecurityFilterChain web(HttpSecurity http) throws Exception {
http
.csrf(AbstractHttpConfigurer::disable)
.authorizeHttpRequests((request) -> request
- // make sure it is in order to access the proper Url
+ // make sure it is in order to access the proper Url
- .requestMatchers("/api/signup").permitAll()
- .requestMatchers("/api/login").permitAll()
- .requestMatchers("/api/logout").permitAll()
- .anyRequest().authenticated()
+ .requestMatchers("/api/signup").permitAll()
+ .requestMatchers("/api/login").permitAll()
+ .requestMatchers("/api/logout").permitAll()
+ .anyRequest().authenticated()
)
- .logout(logout->logout
- .deleteCookies("LibraryManCookie"))
+ .logout(logout -> logout
+ .deleteCookies("LibraryManCookie"))
.sessionManagement(session -> session.sessionCreationPolicy(STATELESS))
.formLogin(withDefaults());
-
+
http.addFilterBefore(jwtFilter, UsernamePasswordAuthenticationFilter.class)
- .httpBasic(httpBasic -> {});
-
+ .httpBasic(httpBasic -> {
+ });
+
http.oauth2Login(withDefaults());
return http.build();
}
@@ -59,6 +60,7 @@ public SecurityFilterChain web(HttpSecurity http) throws Exception {
public AuthenticationManager authenticationManager(AuthenticationConfiguration builder) throws Exception {
return builder.getAuthenticationManager();
}
+
@Bean
public CorsConfigurationSource corsConfigurationSource() {
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
diff --git a/src/main/java/com/libraryman_api/security/controllers/LoginController.java b/src/main/java/com/libraryman_api/security/controllers/LoginController.java
index aed0c1e..20ee825 100644
--- a/src/main/java/com/libraryman_api/security/controllers/LoginController.java
+++ b/src/main/java/com/libraryman_api/security/controllers/LoginController.java
@@ -1,17 +1,15 @@
package com.libraryman_api.security.controllers;
-import org.springframework.http.HttpStatus;
-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 com.libraryman_api.security.model.LoginRequest;
import com.libraryman_api.security.model.LoginResponse;
import com.libraryman_api.security.services.LoginService;
-
import jakarta.servlet.http.Cookie;
import jakarta.servlet.http.HttpServletResponse;
+import org.springframework.http.HttpStatus;
+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;
@RestController
public class LoginController {
@@ -26,7 +24,7 @@ public LoginController(LoginService loginService) {
public ResponseEntity login(@RequestBody LoginRequest loginRequest, HttpServletResponse response) {
LoginResponse loginResponse = loginService.login(loginRequest);
- if (loginResponse != null) {
+ if (loginResponse != null) {
setAuthCookie(response);
return new ResponseEntity<>(loginResponse, HttpStatus.OK);
} else {
@@ -37,7 +35,7 @@ public ResponseEntity login(@RequestBody LoginRequest loginReques
private void setAuthCookie(HttpServletResponse response) {
Cookie cookie = new Cookie("LibraryManCookie", "libraryman_cookie");
cookie.setMaxAge(3600); // (3600 seconds)
- cookie.setPath("/");
+ cookie.setPath("/");
response.addCookie(cookie);
}
}
diff --git a/src/main/java/com/libraryman_api/security/controllers/LogoutController.java b/src/main/java/com/libraryman_api/security/controllers/LogoutController.java
index 20d4a92..03bb45c 100644
--- a/src/main/java/com/libraryman_api/security/controllers/LogoutController.java
+++ b/src/main/java/com/libraryman_api/security/controllers/LogoutController.java
@@ -3,7 +3,6 @@
import jakarta.servlet.http.Cookie;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
-
import org.springframework.http.ResponseEntity;
import org.springframework.security.core.Authentication;
import org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler;
@@ -19,14 +18,14 @@ public ResponseEntity logout(HttpServletRequest request, HttpServletResp
new SecurityContextLogoutHandler().logout(request, response, authentication);
}
removeAuthCookie(response);
-
+
return ResponseEntity.ok("Successfully logged out.");
}
private void removeAuthCookie(HttpServletResponse response) {
Cookie cookie = new Cookie("LibraryManCookie", null);
- cookie.setMaxAge(0);
- cookie.setPath("/");
+ cookie.setMaxAge(0);
+ cookie.setPath("/");
cookie.setHttpOnly(true);
cookie.setSecure(true);
response.addCookie(cookie);
diff --git a/src/main/java/com/libraryman_api/security/controllers/SignupController.java b/src/main/java/com/libraryman_api/security/controllers/SignupController.java
index a1f6891..c7376d2 100644
--- a/src/main/java/com/libraryman_api/security/controllers/SignupController.java
+++ b/src/main/java/com/libraryman_api/security/controllers/SignupController.java
@@ -1,36 +1,37 @@
package com.libraryman_api.security.controllers;
+import com.libraryman_api.member.Members;
+import com.libraryman_api.security.services.SignupService;
import org.springframework.security.access.prepost.PreAuthorize;
-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.RestController;
-import com.libraryman_api.member.Members;
-import com.libraryman_api.security.services.SignupService;
-
@RestController
public class SignupController {
-
- private SignupService signupService;
- public SignupController(SignupService signupService) {
- this.signupService=signupService;
- }
-
- @PostMapping("/api/signup")
- public void signup(@RequestBody Members members) {
- this.signupService.signup(members);
-
- }
- @PostMapping("/api/signup/admin")
- @PreAuthorize("hasRole('ADMIN')")
- public void signupAdmin(@RequestBody Members members) {
- this.signupService.signupAdmin(members);
- }
- @PostMapping("/api/signup/librarian")
- @PreAuthorize("hasRole('LIBRARIAN') or hasRole('ADMIN')")
- public void signupLibrarian(@RequestBody Members members) {
- this.signupService.signupLibrarian(members);
- }
+
+ private final SignupService signupService;
+
+ public SignupController(SignupService signupService) {
+ this.signupService = signupService;
+ }
+
+ @PostMapping("/api/signup")
+ public void signup(@RequestBody Members members) {
+ this.signupService.signup(members);
+
+ }
+
+ @PostMapping("/api/signup/admin")
+ @PreAuthorize("hasRole('ADMIN')")
+ public void signupAdmin(@RequestBody Members members) {
+ this.signupService.signupAdmin(members);
+ }
+
+ @PostMapping("/api/signup/librarian")
+ @PreAuthorize("hasRole('LIBRARIAN') or hasRole('ADMIN')")
+ public void signupLibrarian(@RequestBody Members members) {
+ this.signupService.signupLibrarian(members);
+ }
}
diff --git a/src/main/java/com/libraryman_api/security/jwt/JwtAuthenticationFilter.java b/src/main/java/com/libraryman_api/security/jwt/JwtAuthenticationFilter.java
index 875779b..f48ab45 100644
--- a/src/main/java/com/libraryman_api/security/jwt/JwtAuthenticationFilter.java
+++ b/src/main/java/com/libraryman_api/security/jwt/JwtAuthenticationFilter.java
@@ -1,9 +1,10 @@
package com.libraryman_api.security.jwt;
-import java.io.IOException;
-
-import org.springframework.beans.factory.annotation.Autowired;
+import jakarta.servlet.FilterChain;
+import jakarta.servlet.ServletException;
+import jakarta.servlet.http.HttpServletRequest;
+import jakarta.servlet.http.HttpServletResponse;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
@@ -12,51 +13,45 @@
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;
-import jakarta.servlet.FilterChain;
-import jakarta.servlet.ServletException;
-import jakarta.servlet.http.HttpServletRequest;
-import jakarta.servlet.http.HttpServletResponse;
+import java.io.IOException;
@Component
public class JwtAuthenticationFilter extends OncePerRequestFilter {
-
- private JwtAuthenticationHelper jwtHelper;
-
- private UserDetailsService userDetailsService;
-
- public JwtAuthenticationFilter(JwtAuthenticationHelper jwtHelper,UserDetailsService userDetailsService) {
- this.jwtHelper=jwtHelper;
- this.userDetailsService=userDetailsService;
- }
-
- @Override
- protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
- throws ServletException, IOException {
-
- String requestHeader=request.getHeader("Authorization");
- String username=null;
- String token=null;
- if(requestHeader!=null && requestHeader.startsWith("Bearer ")) {
- token=requestHeader.substring(7);
- username=jwtHelper.getUsernameFromToken(token);
- if(username!=null && SecurityContextHolder.getContext().getAuthentication() == null) {
- UserDetails userDetails=userDetailsService.loadUserByUsername(username);
- if(!(jwtHelper.isTokenExpired(token))) {
- UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken=new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities());
- usernamePasswordAuthenticationToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
- SecurityContextHolder.getContext().setAuthentication(usernamePasswordAuthenticationToken);
-
- }
- else {
- System.out.println("Token is expired or user details not found.");
- }
- }
-
- }
- filterChain.doFilter(request, response);
- }
-
-
-
-
+
+ private final JwtAuthenticationHelper jwtHelper;
+
+ private final UserDetailsService userDetailsService;
+
+ public JwtAuthenticationFilter(JwtAuthenticationHelper jwtHelper, UserDetailsService userDetailsService) {
+ this.jwtHelper = jwtHelper;
+ this.userDetailsService = userDetailsService;
+ }
+
+ @Override
+ protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
+ throws ServletException, IOException {
+
+ String requestHeader = request.getHeader("Authorization");
+ String username = null;
+ String token = null;
+ if (requestHeader != null && requestHeader.startsWith("Bearer ")) {
+ token = requestHeader.substring(7);
+ username = jwtHelper.getUsernameFromToken(token);
+ if (username != null && SecurityContextHolder.getContext().getAuthentication() == null) {
+ UserDetails userDetails = userDetailsService.loadUserByUsername(username);
+ if (!(jwtHelper.isTokenExpired(token))) {
+ UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken = new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities());
+ usernamePasswordAuthenticationToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
+ SecurityContextHolder.getContext().setAuthentication(usernamePasswordAuthenticationToken);
+
+ } else {
+ System.out.println("Token is expired or user details not found.");
+ }
+ }
+
+ }
+ filterChain.doFilter(request, response);
+ }
+
+
}
diff --git a/src/main/java/com/libraryman_api/security/jwt/JwtAuthenticationHelper.java b/src/main/java/com/libraryman_api/security/jwt/JwtAuthenticationHelper.java
index b44e446..d9dcc01 100644
--- a/src/main/java/com/libraryman_api/security/jwt/JwtAuthenticationHelper.java
+++ b/src/main/java/com/libraryman_api/security/jwt/JwtAuthenticationHelper.java
@@ -1,49 +1,48 @@
package com.libraryman_api.security.jwt;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.Map;
-
-import javax.crypto.spec.SecretKeySpec;
-
+import io.jsonwebtoken.Claims;
+import io.jsonwebtoken.Jwts;
+import io.jsonwebtoken.SignatureAlgorithm;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.stereotype.Component;
-import io.jsonwebtoken.Claims;
-import io.jsonwebtoken.Jwts;
-import io.jsonwebtoken.SignatureAlgorithm;
+import javax.crypto.spec.SecretKeySpec;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Map;
@Component
public class JwtAuthenticationHelper {
- private static final long JWT_TOKEN_VALIDITY=60*60;
- @Value("${jwt.secretKey}")
- private String secret;
- public String getUsernameFromToken(String token) {
- String username=getClaimsFromToken(token).getSubject();
- return username;
- }
-
- public Claims getClaimsFromToken(String token) {
- Claims claims=Jwts.parserBuilder()
- .setSigningKey(secret.getBytes())
- .build().parseClaimsJws(token).getBody();
- return claims;
- }
-
- public Boolean isTokenExpired(String token) {
- Claims claims=getClaimsFromToken(token);
- Date expDate=claims.getExpiration();
- return expDate.before(new Date());
- }
-
- public String generateToken(UserDetails userDetails) {
- Map claims=new HashMap<>();
- return Jwts.builder().setClaims(claims).setSubject(userDetails.getUsername())
- .setIssuedAt(new Date(System.currentTimeMillis()))
- .setExpiration(new Date(System.currentTimeMillis()+JWT_TOKEN_VALIDITY*1000))
- .signWith(new SecretKeySpec(secret.getBytes(),SignatureAlgorithm.HS512.getJcaName()),SignatureAlgorithm.HS512)
- .compact();
- }
+ private static final long JWT_TOKEN_VALIDITY = 60 * 60;
+ @Value("${jwt.secretKey}")
+ private String secret;
+
+ public String getUsernameFromToken(String token) {
+ String username = getClaimsFromToken(token).getSubject();
+ return username;
+ }
+
+ public Claims getClaimsFromToken(String token) {
+ Claims claims = Jwts.parserBuilder()
+ .setSigningKey(secret.getBytes())
+ .build().parseClaimsJws(token).getBody();
+ return claims;
+ }
+
+ public Boolean isTokenExpired(String token) {
+ Claims claims = getClaimsFromToken(token);
+ Date expDate = claims.getExpiration();
+ return expDate.before(new Date());
+ }
+
+ public String generateToken(UserDetails userDetails) {
+ Map claims = new HashMap<>();
+ return Jwts.builder().setClaims(claims).setSubject(userDetails.getUsername())
+ .setIssuedAt(new Date(System.currentTimeMillis()))
+ .setExpiration(new Date(System.currentTimeMillis() + JWT_TOKEN_VALIDITY * 1000))
+ .signWith(new SecretKeySpec(secret.getBytes(), SignatureAlgorithm.HS512.getJcaName()), SignatureAlgorithm.HS512)
+ .compact();
+ }
}
diff --git a/src/main/java/com/libraryman_api/security/model/LoginRequest.java b/src/main/java/com/libraryman_api/security/model/LoginRequest.java
index e77d1cd..126e032 100644
--- a/src/main/java/com/libraryman_api/security/model/LoginRequest.java
+++ b/src/main/java/com/libraryman_api/security/model/LoginRequest.java
@@ -2,27 +2,26 @@
public class LoginRequest {
- private String username;
-
- private String password;
+ private String username;
-
+ private String password;
- public String getUsername() {
- return username;
- }
- public void setUsername(String username) {
- this.username = username;
- }
+ public String getUsername() {
+ return username;
+ }
+
+ public void setUsername(String username) {
+ this.username = username;
+ }
+
+ public String getPassword() {
+ return password;
+ }
+
+ public void setPassword(String password) {
+ this.password = password;
+ }
- public String getPassword() {
- return password;
- }
- public void setPassword(String password) {
- this.password = password;
- }
-
-
}
diff --git a/src/main/java/com/libraryman_api/security/model/LoginResponse.java b/src/main/java/com/libraryman_api/security/model/LoginResponse.java
index 2b53d41..a3730bf 100644
--- a/src/main/java/com/libraryman_api/security/model/LoginResponse.java
+++ b/src/main/java/com/libraryman_api/security/model/LoginResponse.java
@@ -3,19 +3,19 @@
public class LoginResponse {
- private String token;
-
- public LoginResponse(String token) {
- this.token=token;
- }
- public String getToken() {
- return token;
- }
-
- public void setToken(String token) {
- this.token = token;
- }
-
-
-
+ private String token;
+
+ public LoginResponse(String token) {
+ this.token = token;
+ }
+
+ public String getToken() {
+ return token;
+ }
+
+ public void setToken(String token) {
+ this.token = token;
+ }
+
+
}
diff --git a/src/main/java/com/libraryman_api/security/services/CustomUserDetailsService.java b/src/main/java/com/libraryman_api/security/services/CustomUserDetailsService.java
index 2c66c82..dbd525f 100644
--- a/src/main/java/com/libraryman_api/security/services/CustomUserDetailsService.java
+++ b/src/main/java/com/libraryman_api/security/services/CustomUserDetailsService.java
@@ -1,22 +1,22 @@
package com.libraryman_api.security.services;
+import com.libraryman_api.member.MemberRepository;
import org.springframework.beans.factory.annotation.Autowired;
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.libraryman_api.member.MemberRepository;
@Service
-public class CustomUserDetailsService implements UserDetailsService{
+public class CustomUserDetailsService implements UserDetailsService {
+
+ @Autowired
+ MemberRepository memberRepository;
+
+ @Override
+ public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
- @Autowired
- MemberRepository memberRepository;
-
- @Override
- public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
-
- return memberRepository.findByUsername(username).orElseThrow(()-> new UsernameNotFoundException("Username not Found"));
- }
+ return memberRepository.findByUsername(username).orElseThrow(() -> new UsernameNotFoundException("Username not Found"));
+ }
}
diff --git a/src/main/java/com/libraryman_api/security/services/LoginService.java b/src/main/java/com/libraryman_api/security/services/LoginService.java
index c255c4e..8666cec 100644
--- a/src/main/java/com/libraryman_api/security/services/LoginService.java
+++ b/src/main/java/com/libraryman_api/security/services/LoginService.java
@@ -1,5 +1,9 @@
package com.libraryman_api.security.services;
+import com.libraryman_api.member.MemberRepository;
+import com.libraryman_api.security.jwt.JwtAuthenticationHelper;
+import com.libraryman_api.security.model.LoginRequest;
+import com.libraryman_api.security.model.LoginResponse;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
@@ -7,45 +11,39 @@
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.stereotype.Service;
-import com.libraryman_api.member.MemberRepository;
-import com.libraryman_api.security.jwt.JwtAuthenticationHelper;
-import com.libraryman_api.security.model.LoginRequest;
-import com.libraryman_api.security.model.LoginResponse;
-
@Service
public class LoginService {
- private AuthenticationManager authenticationManager;
-
- private UserDetailsService userDetailsService;
-
- private JwtAuthenticationHelper jwtHelper;
-
- private MemberRepository memberRepository;
-
- public LoginService(AuthenticationManager authenticationManager,UserDetailsService userDetailsService,JwtAuthenticationHelper jwtHelper,MemberRepository memberRepository) {
- this.authenticationManager=authenticationManager;
- this.userDetailsService=userDetailsService;
- this.jwtHelper=jwtHelper;
- this.memberRepository=memberRepository;
- }
-
- public LoginResponse login(LoginRequest loginRequest) {
- Authenticate(loginRequest.getUsername(), loginRequest.getPassword());
- UserDetails userDetails=userDetailsService.loadUserByUsername(loginRequest.getUsername());
- String token=jwtHelper.generateToken(userDetails);
- LoginResponse loginResponse=new LoginResponse(token);
- return loginResponse;
- }
-
- public void Authenticate(String username,String password) {
- UsernamePasswordAuthenticationToken authenticateToken=new UsernamePasswordAuthenticationToken(username, password);
- try {
- authenticationManager.authenticate(authenticateToken);
- }
- catch(BadCredentialsException e){
- throw new BadCredentialsException("Invalid Username or Password");
- }
- }
+ private final AuthenticationManager authenticationManager;
+
+ private final UserDetailsService userDetailsService;
+
+ private final JwtAuthenticationHelper jwtHelper;
+
+ private final MemberRepository memberRepository;
+
+ public LoginService(AuthenticationManager authenticationManager, UserDetailsService userDetailsService, JwtAuthenticationHelper jwtHelper, MemberRepository memberRepository) {
+ this.authenticationManager = authenticationManager;
+ this.userDetailsService = userDetailsService;
+ this.jwtHelper = jwtHelper;
+ this.memberRepository = memberRepository;
+ }
+
+ public LoginResponse login(LoginRequest loginRequest) {
+ Authenticate(loginRequest.getUsername(), loginRequest.getPassword());
+ UserDetails userDetails = userDetailsService.loadUserByUsername(loginRequest.getUsername());
+ String token = jwtHelper.generateToken(userDetails);
+ LoginResponse loginResponse = new LoginResponse(token);
+ return loginResponse;
+ }
+
+ public void Authenticate(String username, String password) {
+ UsernamePasswordAuthenticationToken authenticateToken = new UsernamePasswordAuthenticationToken(username, password);
+ try {
+ authenticationManager.authenticate(authenticateToken);
+ } catch (BadCredentialsException e) {
+ throw new BadCredentialsException("Invalid Username or Password");
+ }
+ }
}
diff --git a/src/main/java/com/libraryman_api/security/services/SignupService.java b/src/main/java/com/libraryman_api/security/services/SignupService.java
index 33ff122..cb7bb64 100644
--- a/src/main/java/com/libraryman_api/security/services/SignupService.java
+++ b/src/main/java/com/libraryman_api/security/services/SignupService.java
@@ -1,88 +1,87 @@
package com.libraryman_api.security.services;
-import java.util.Date;
-import java.util.Optional;
-
-import org.springframework.beans.factory.annotation.Value;
-import org.springframework.stereotype.Service;
-
-
import com.libraryman_api.exception.ResourceNotFoundException;
import com.libraryman_api.member.MemberRepository;
import com.libraryman_api.member.Members;
import com.libraryman_api.member.Role;
import com.libraryman_api.security.config.PasswordEncoder;
+import org.springframework.stereotype.Service;
+
+import java.util.Date;
+import java.util.Optional;
@Service
public class SignupService {
- private MemberRepository memberRepository;
+ private final MemberRepository memberRepository;
+
+ private final PasswordEncoder passwordEncoder;
+
+
+ public SignupService(MemberRepository memberRepository, PasswordEncoder passwordEncoder) {
+ this.memberRepository = memberRepository;
+ this.passwordEncoder = passwordEncoder;
+ }
+
+ public void signup(Members members) {
+ Optional memberOptId = memberRepository.findById(members.getMemberId());
+ Optional memberOptUsername = memberRepository.findByUsername(members.getUsername());
+ if (memberOptId.isPresent()) {
+ throw new ResourceNotFoundException("User already Exists");
+ }
+ if (memberOptUsername.isPresent()) {
+ throw new ResourceNotFoundException("User already Exists");
+ }
+ String encoded_password = passwordEncoder.bCryptPasswordEncoder().encode(members.getPassword());
+ Members new_members = new Members();
+ new_members.setEmail(members.getEmail());
+ new_members.setName(members.getName());
+ new_members.setPassword(encoded_password);
+ new_members.setRole(Role.USER);
+ new_members.setMembershipDate(new Date());
+ new_members.setUsername(members.getUsername());
+ memberRepository.save(new_members);
+ }
+
+ public void signupAdmin(Members members) {
+ Optional memberOptId = memberRepository.findById(members.getMemberId());
+ Optional memberOptUsername = memberRepository.findByUsername(members.getUsername());
+ if (memberOptId.isPresent()) {
+ throw new ResourceNotFoundException("User already Exists");
+ }
+ if (memberOptUsername.isPresent()) {
+ throw new ResourceNotFoundException("User already Exists");
+ }
+
+ String encoded_password = passwordEncoder.bCryptPasswordEncoder().encode(members.getPassword());
+ Members new_members = new Members();
+ new_members.setEmail(members.getEmail());
+ new_members.setName(members.getName());
+ new_members.setPassword(encoded_password);
+ new_members.setRole(Role.ADMIN);
+ new_members.setMembershipDate(new Date());
+ new_members.setUsername(members.getUsername());
+ memberRepository.save(new_members);
+
+ }
- private PasswordEncoder passwordEncoder;
-
-
- public SignupService(MemberRepository memberRepository,PasswordEncoder passwordEncoder) {
- this.memberRepository=memberRepository;
- this.passwordEncoder=passwordEncoder;
- }
- public void signup(Members members) {
- Optional memberOptId=memberRepository.findById(members.getMemberId());
- Optional memberOptUsername=memberRepository.findByUsername(members.getUsername());
- if(memberOptId.isPresent()) {
- throw new ResourceNotFoundException("User already Exists");
- }
- if(memberOptUsername.isPresent()) {
- throw new ResourceNotFoundException("User already Exists");
- }
- String encoded_password=passwordEncoder.bCryptPasswordEncoder().encode(members.getPassword());
- Members new_members=new Members();
- new_members.setEmail(members.getEmail());
- new_members.setName(members.getName());
- new_members.setPassword(encoded_password);
- new_members.setRole(Role.USER);
- new_members.setMembershipDate(new Date());
- new_members.setUsername(members.getUsername());
- memberRepository.save(new_members);
- }
-
- public void signupAdmin(Members members) {
- Optional memberOptId=memberRepository.findById(members.getMemberId());
- Optional memberOptUsername=memberRepository.findByUsername(members.getUsername());
- if(memberOptId.isPresent()) {
- throw new ResourceNotFoundException("User already Exists");
- }
- if(memberOptUsername.isPresent()) {
- throw new ResourceNotFoundException("User already Exists");
- }
-
- String encoded_password=passwordEncoder.bCryptPasswordEncoder().encode(members.getPassword());
- Members new_members=new Members();
- new_members.setEmail(members.getEmail());
- new_members.setName(members.getName());
- new_members.setPassword(encoded_password);
- new_members.setRole(Role.ADMIN);
- new_members.setMembershipDate(new Date());
- new_members.setUsername(members.getUsername());
- memberRepository.save(new_members);
-
- }
- public void signupLibrarian(Members members) {
- Optional memberOptId=memberRepository.findById(members.getMemberId());
- Optional memberOptUsername=memberRepository.findByUsername(members.getUsername());
- if(memberOptId.isPresent()) {
- throw new ResourceNotFoundException("User already Exists");
- }
- if(memberOptUsername.isPresent()) {
- throw new ResourceNotFoundException("User already Exists");
- }
- String encoded_password=passwordEncoder.bCryptPasswordEncoder().encode(members.getPassword());
- Members new_members=new Members();
- new_members.setEmail(members.getEmail());
- new_members.setName(members.getName());
- new_members.setPassword(encoded_password);
- new_members.setRole(Role.LIBRARIAN);
- new_members.setMembershipDate(new Date());
- new_members.setUsername(members.getUsername());
- memberRepository.save(new_members);
- }
+ public void signupLibrarian(Members members) {
+ Optional memberOptId = memberRepository.findById(members.getMemberId());
+ Optional memberOptUsername = memberRepository.findByUsername(members.getUsername());
+ if (memberOptId.isPresent()) {
+ throw new ResourceNotFoundException("User already Exists");
+ }
+ if (memberOptUsername.isPresent()) {
+ throw new ResourceNotFoundException("User already Exists");
+ }
+ String encoded_password = passwordEncoder.bCryptPasswordEncoder().encode(members.getPassword());
+ Members new_members = new Members();
+ new_members.setEmail(members.getEmail());
+ new_members.setName(members.getName());
+ new_members.setPassword(encoded_password);
+ new_members.setRole(Role.LIBRARIAN);
+ new_members.setMembershipDate(new Date());
+ new_members.setUsername(members.getUsername());
+ memberRepository.save(new_members);
+ }
}
diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties
index 9cd73f6..3fce839 100644
--- a/src/main/resources/application.properties
+++ b/src/main/resources/application.properties
@@ -1,3 +1,3 @@
spring.application.name=libraryman-api
-spring.profiles.active=${ENV:development}
+spring.profiles.active=${ENV:dev}
jwt.secretKey=${YOUR_JWT_SECRET_KEY}
\ No newline at end of file