UserController.java
package com.student_loan.controller;
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 org.springframework.web.server.ResponseStatusException;
import com.student_loan.model.Item;
import com.student_loan.model.User;
import com.student_loan.service.ItemService;
import com.student_loan.service.UserService;
import com.student_loan.dtos.UserRecord;
import com.student_loan.dtos.CredentialsDTO;
import com.student_loan.dtos.LoanAndItemDto;
import com.student_loan.dtos.RegistrationRecord;
import com.student_loan.dtos.UserDTO;
import java.util.ArrayList;
import java.util.List;
/**
* Controller class for managing users in the system. Handles HTTP requests
* related to user operations such as creating, updating, deleting, and
* retrieving users.
*/
@RestController
@RequestMapping("/users")
public class UserController {
private UserService userService;
private ItemService itemService;
/**
* Constructor for UserController.
*
* @param userService Service for user operations.
*/
public UserController(UserService userService, ItemService itemService) {
this.userService = userService;
this.itemService = itemService;
}
/**
* Retrieves all users in the system.
*
* @param token The authentication token.
* @return ResponseEntity containing a list of all users.
*/
@GetMapping
public ResponseEntity<List<User>> getAllUsers(@RequestParam("token") String token) {
User user = userService.getUserByToken(token);
if (user == null || user.getAdmin()==false) {
return new ResponseEntity<>(new ArrayList<>(),HttpStatus.UNAUTHORIZED);
}
return new ResponseEntity<>(userService.getAllUsers(), HttpStatus.OK);
}
/**
* Authenticates a user and generates a token.
*
* @param credentials The user's credentials.
* @return ResponseEntity containing the authentication token or an error message.
*/
@PostMapping("/login")
public ResponseEntity<?> login(@RequestBody CredentialsDTO credentials) {
String token = userService.login(credentials);
if (token.equals("Invalid credentials")) {
return ResponseEntity.status(401).body("Invalid credentials");
}
return ResponseEntity.ok().body("{\"token\": \"" + token + "\"}");
}
/**
* Logs out a user by invalidating their token.
*
* @param token The authentication token.
* @return ResponseEntity indicating the result of the operation.
*/
@PostMapping("/logout")
public ResponseEntity<String> logout(@RequestParam("token") String token) {
if (userService.logout(token)) {
return new ResponseEntity<>(HttpStatus.OK);
} else {
return new ResponseEntity<>(HttpStatus.UNAUTHORIZED);
}
}
/**
* Retrieves a user by their ID.
*
* @param id The ID of the user.
* @return ResponseEntity containing the user data.
*/
@GetMapping("/{id}")
public ResponseEntity<UserDTO> getUserById(@PathVariable Long id) {
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
String email = authentication.getName();
User user = userService.getUserByEmail(email);
if (user == null) {
return new ResponseEntity<>(HttpStatus.UNAUTHORIZED);
}
User retrievedUser = userService.getUserById(id).get();
UserDTO userDTO = new UserDTO(retrievedUser.getId(), retrievedUser.getName(), retrievedUser.getEmail());
return new ResponseEntity<>(userDTO, HttpStatus.OK);
}
/**
* Retrieves a user by their ID (versión completa usando UserRecord).
*
* GET /users/{id}/record
*
* @param id The ID of the user.
* @return ResponseEntity containing el UserRecord con todos los campos.
*/
@GetMapping("/{id}/record")
public ResponseEntity<UserRecord> getUserRecordById(@PathVariable Long id) {
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
String email = authentication.getName();
User requester = userService.getUserByEmail(email);
if (requester == null) {
return new ResponseEntity<>(HttpStatus.UNAUTHORIZED);
}
User target = userService.getUserById(id)
.orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND));
return ResponseEntity.ok(userToUserRecord(target));
}
// Ítems prestados por un usuario
@GetMapping("/{userId}/items/lent")
public ResponseEntity<List<LoanAndItemDto>> getItemsLentByUser(@PathVariable Long userId) {
List<LoanAndItemDto> items = itemService.getItemsLentByUserWithActiveLoans(userId);
return ResponseEntity.ok(items);
}
// Ítems tomados prestados por un usuario
@GetMapping("/{userId}/items/borrowed")
public ResponseEntity<List<LoanAndItemDto>> getItemsBorrowedByUser(@PathVariable Long userId) {
List<LoanAndItemDto> items = itemService.getItemsBorrowedByUserWithActiveLoans(userId);
return ResponseEntity.ok(items);
}
/**
* Updates a user by their ID.
*
* @param id The ID of the user.
* @param userData The updated user data.
* @param token The authentication token.
* @return ResponseEntity containing the updated user or an error status.
*/
@PutMapping("/{id}")
public ResponseEntity<User> updateUser(@PathVariable Long id, @RequestBody UserRecord userData, @RequestParam("token") String token) {
User user = userService.getUserByToken(token);
if (user == null || user.getAdmin() == false && user.getId() != id) {
return new ResponseEntity<>(HttpStatus.UNAUTHORIZED);
}
try {
User updatedUser = userService.updateUser(id, userRecordToUser(userData));
return new ResponseEntity<>(updatedUser, HttpStatus.OK);
} catch (RuntimeException e) {
return new ResponseEntity<>(HttpStatus.NOT_FOUND);
}
}
/**
* Registers a new user.
*
* @param userDTO The registration data.
* @return ResponseEntity indicating the result of the operation.
*/
//Register
@PostMapping("/register")
public ResponseEntity<String> register(@RequestBody RegistrationRecord userDTO) {
if (userService.register(registerRecordToUser(userDTO))) {
return ResponseEntity.ok("User registered correctly");
} else {
return ResponseEntity.badRequest().body("The user already exists");
}
}
/**
* Deletes a user by their ID.
*
* @param id The ID of the user.
* @param token The authentication token.
* @return ResponseEntity indicating the result of the operation.
*/
@DeleteMapping("/{id}")
public ResponseEntity<String> deleteUser(@PathVariable Long id, @RequestParam("token") String token) {
User user = userService.getUserByToken(token);
if (user == null || user.getAdmin() == false && user.getId() != id) {
return new ResponseEntity<>(HttpStatus.UNAUTHORIZED);
}
userService.deleteUser(id);
return new ResponseEntity<>(HttpStatus.OK);
}
/**
* Converts a RegistrationRecord to a User entity.
*
* @param data The registration record.
* @return The converted User entity.
*/
public User registerRecordToUser(RegistrationRecord data) {
User user = new User();
user.setName(data.name() + " " + data.lastName() );
user.setEmail(data.email());
user.setPassword(data.password());
user.setTelephoneNumber(data.telephoneNumber());
user.setAddress(data.address());
user.setDegreeType(User.DegreeType.valueOf(data.degreeType()));
user.setDegreeYear(data.degreeYear());
user.setPenalties(0);
user.setAverageRating(0.0);
user.setAdmin(false);
return user;
}
/**
* Converts a UserRecord to a User entity.
*
* @param userDTO The user record.
* @return The converted User entity.
*/
public User userRecordToUser(UserRecord userDTO) {
User user = new User();
user.setName(userDTO.name()+" "+userDTO.lastName());
user.setEmail(userDTO.email());
user.setPassword(userDTO.password());
user.setTelephoneNumber(userDTO.telephoneNumber());
user.setAddress(userDTO.address());
user.setDegreeType(User.DegreeType.UNIVERSITY_DEGREE);
user.setDegreeYear(userDTO.degreeYear());
user.setPenalties(userDTO.penalties());
user.setAverageRating(userDTO.averageRating());
user.setAdmin(userDTO.admin());
return user;
}
public UserRecord userToUserRecord(User user) {
String[] nameParts = user.getName().split(" ");
String firstName = nameParts[0];
String lastName = nameParts.length > 1 ? nameParts[nameParts.length - 1] : "";
return new UserRecord(
firstName,
lastName,
user.getEmail(),
user.getPassword(),
user.getTelephoneNumber(),
user.getAddress(),
user.getDegreeType().name(),
user.getDegreeYear(),
user.getPenalties(),
user.getAverageRating(),
user.getAdmin()
);
}
}