FEAT: deleteRoom endpoint and ResponseEntity usage

This commit is contained in:
2026-06-18 18:44:18 +02:00
parent 835ad93bac
commit 1bd62ff3ca
10 changed files with 109 additions and 53 deletions

Binary file not shown.

View File

@@ -0,0 +1,16 @@
package com.mallardromain.hotel.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
@Configuration
public class AppConfig {
// By putting this here, UserService can grab it WITHOUT triggering SecurityConfig!
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
}

View File

@@ -18,9 +18,12 @@ public class DatabaseSeeder {
if (userRepository.count() == 0) {
User testUser1 = new User("test1", passwordEncoder.encode("password1"));
User testUser2 = new User("test2", passwordEncoder.encode("password2"));
User adminUser1 = new User("admin1", passwordEncoder.encode("password1"));
adminUser1.setRole("ADMIN");
userRepository.save(testUser1);
userRepository.save(testUser2);
userRepository.save(adminUser1);
}
};
}

View File

@@ -6,6 +6,7 @@ import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.ProviderManager;
import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
import org.springframework.security.config.annotation.authentication.configuration.AuthenticationConfiguration;
import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.core.userdetails.UserDetailsService;
@@ -17,7 +18,9 @@ import org.springframework.security.web.authentication.UsernamePasswordAuthentic
import com.mallardromain.hotel.security.JWTFilter;
@Configuration
@EnableMethodSecurity
public class SecurityConfig {
private final JWTFilter jwtFilter;
public SecurityConfig(JWTFilter jwtFilter) {
@@ -46,12 +49,6 @@ public class SecurityConfig {
return http.build();
}
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
@Bean
public AuthenticationManager authenticationManager(
AuthenticationConfiguration config,

View File

@@ -2,6 +2,10 @@ package com.mallardromain.hotel.controller;
import java.util.List;
import org.springframework.http.HttpStatus;
import org.springframework.http.HttpStatusCode;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import com.mallardromain.hotel.model.Room;
@@ -19,27 +23,57 @@ public class RoomController {
}
@GetMapping
public List<Room> getRooms() {
return service.findAll();
public ResponseEntity<?> getRooms() {
try{
List<Room> roomList = service.findAll();
return ResponseEntity.ok(roomList);
} catch(RuntimeException e) {
return ResponseEntity.status(HttpStatus.NOT_FOUND).body(e.getMessage());
}
@PostMapping
public Room createRoom(@RequestBody Room room){
return service.createRoom(room);
}
@PostMapping("/create")
@PreAuthorize("hasRole('ADMIN')")
public ResponseEntity<?> createRoom(@RequestBody Room room){
try{
Room createdRoom = service.createRoom(room);
return ResponseEntity.ok(createdRoom);
} catch(RuntimeException e){
return ResponseEntity.status(HttpStatus.NOT_FOUND).body(e.getMessage());
}
}
@PutMapping("/{id}/clean")
public Room setRoomClean(
@PathVariable Integer id
){
return service.setRoomClean(id);
public ResponseEntity<?> setRoomClean(@PathVariable Integer id){
try{
Room updatedRoom = service.setRoomClean(id);
return ResponseEntity.ok(updatedRoom);
} catch (RuntimeException e) {
return ResponseEntity.status(HttpStatus.NOT_FOUND).body(e.getMessage());
}
}
@PutMapping("/{id}/dirty")
public Room setRoomDirty(
@PathVariable Integer id
){
return service.setRoomDirty(id);
public ResponseEntity setRoomDirty(@PathVariable Integer id) {
try {
Room updatedRoom = service.setRoomDirty(id);
return ResponseEntity.ok(updatedRoom);
} catch (RuntimeException e){
return ResponseEntity.status(HttpStatus.NOT_FOUND).body(e.getMessage());
}
}
@DeleteMapping("/delete/{id}")
@PreAuthorize("hasRole('ADMIN')") // Keep the boss door locked!
public ResponseEntity<?> deleteRoom(@PathVariable Integer id) {
try{
service.deleteRoom(id);
return ResponseEntity.ok("Room successfully deleted!");
} catch (RuntimeException e) {
return ResponseEntity.status(HttpStatus.NOT_FOUND).body(e.getMessage());
}
}
}

View File

@@ -19,7 +19,7 @@ public class Room {
}
public Room(Integer id, String number, String status){
public Room(String number, String status){
//this.id = id; id is/should be generated by the DB
this.number = number;
this.status = status;

View File

@@ -14,6 +14,9 @@ public class User {
private String password;
@Column(nullable = false)
private String role = "USER";
public User(){
}
@@ -46,4 +49,13 @@ public class User {
public void setPassword(String password){
this.password = password;
}
public String getRole(){
return role;
}
public void setRole(String role){
this.role = role;
}
}

View File

@@ -5,6 +5,8 @@ import java.util.Collections;
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.UsernamePasswordAuthenticationFilter;
import org.springframework.security.web.authentication.WebAuthenticationDetails;
import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
@@ -23,9 +25,11 @@ import jakarta.servlet.http.HttpServletResponse;
public class JWTFilter extends OncePerRequestFilter {
private final JWTService jwtService;
private final UserDetailsService userDetailsService;
public JWTFilter(JWTService jwtService){
public JWTFilter(JWTService jwtService, UserDetailsService userDetailsService){
this.jwtService = jwtService;
this.userDetailsService = userDetailsService;
}
@Override
@@ -35,14 +39,9 @@ public class JWTFilter extends OncePerRequestFilter {
FilterChain filterChain
) throws ServletException, IOException {
String authHeader = request
.getHeader("Authorization");
if ( authHeader == null
||
!authHeader.startsWith("Bearer ")
) {
String authHeader = request.getHeader("Authorization");
if ( authHeader == null || !authHeader.startsWith("Bearer ") ) {
filterChain.doFilter(request, response);
return;
}
@@ -51,23 +50,18 @@ public class JWTFilter extends OncePerRequestFilter {
if (jwtService.isTockenValid(token)){
String username = jwtService
.extractUsername(token);
String username = jwtService.extractUsername(token);
UsernamePasswordAuthenticationToken auth =
new UsernamePasswordAuthenticationToken(
username,
UserDetails userDetails = userDetailsService.loadUserByUsername(username);
UsernamePasswordAuthenticationToken auth = new UsernamePasswordAuthenticationToken(
userDetails,
null,
Collections.emptyList()
userDetails.getAuthorities()
);
auth.setDetails(
new WebAuthenticationDetailsSource()
.buildDetails(request)
);
SecurityContextHolder.getContext()
.setAuthentication(auth);
auth.setDetails(new WebAuthenticationDetailsSource().buildDetails(request) );
SecurityContextHolder.getContext().setAuthentication(auth);
}
filterChain.doFilter(request, response);

View File

@@ -22,14 +22,7 @@ public class RoomService {
return repo.findAll();
}
public Room createRoomTest() {
Room room = new Room(
666,
"test",
"clean"
);
public Room createRoomTest(Room room) {
return repo.save(room);
}
@@ -57,4 +50,11 @@ public class RoomService {
return repo.save(room);
}
public void deleteRoom(Integer id) {
if (!repo.existsById(id)) {
throw new RuntimeException("Room with ID " + id + " not found");
}
repo.deleteById(id);
}
}

View File

@@ -40,7 +40,7 @@ public class UserService implements UserDetailsService {
.map(user -> org.springframework.security.core.userdetails.User
.withUsername(user.getUsername())
.password(user.getPassword())
.authorities("USER") // Default role
.authorities("ROLE_" + user.getRole().toUpperCase()) // Default role
.build()
)
.orElseThrow(() -> new UsernameNotFoundException("User not found in DB"));