diff --git a/data/hotel.sqlite b/data/hotel.sqlite index edcf485..9c93398 100644 Binary files a/data/hotel.sqlite and b/data/hotel.sqlite differ diff --git a/src/main/java/com/mallardromain/hotel/config/DatabaseSeeder.java b/src/main/java/com/mallardromain/hotel/config/DatabaseSeeder.java new file mode 100644 index 0000000..a0ec5c1 --- /dev/null +++ b/src/main/java/com/mallardromain/hotel/config/DatabaseSeeder.java @@ -0,0 +1,27 @@ +package com.mallardromain.hotel.config; +import org.springframework.boot.CommandLineRunner; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.security.crypto.password.PasswordEncoder; + +import com.mallardromain.hotel.model.User; +import com.mallardromain.hotel.repository.UserRepository; + +import io.jsonwebtoken.security.Password; + +@Configuration +public class DatabaseSeeder { + + @Bean + public CommandLineRunner seedDatabase(UserRepository userRepository, PasswordEncoder passwordEncoder) { + return args -> { + if (userRepository.count() == 0) { + User testUser1 = new User("test1", passwordEncoder.encode("password1")); + User testUser2 = new User("test2", passwordEncoder.encode("password2")); + + userRepository.save(testUser1); + userRepository.save(testUser2); + } + }; + } +} diff --git a/src/main/java/com/mallardromain/hotel/config/SecurityConfig.java b/src/main/java/com/mallardromain/hotel/config/SecurityConfig.java index 14877df..73a264a 100644 --- a/src/main/java/com/mallardromain/hotel/config/SecurityConfig.java +++ b/src/main/java/com/mallardromain/hotel/config/SecurityConfig.java @@ -2,8 +2,15 @@ package com.mallardromain.hotel.config; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +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.web.builders.HttpSecurity; import org.springframework.security.config.http.SessionCreationPolicy; +import org.springframework.security.core.userdetails.UserDetailsService; +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; @@ -39,4 +46,24 @@ public class SecurityConfig { return http.build(); } + + @Bean + public PasswordEncoder passwordEncoder() { + return new BCryptPasswordEncoder(); + } + + @Bean + public AuthenticationManager authenticationManager( + AuthenticationConfiguration config, + UserDetailsService userDetailsService, + PasswordEncoder passwordEncoder + ) throws Exception { + + DaoAuthenticationProvider authProvider = new DaoAuthenticationProvider(userDetailsService); + authProvider.setPasswordEncoder(passwordEncoder); + + return new ProviderManager(authProvider); + } + + } diff --git a/src/main/java/com/mallardromain/hotel/controller/AuthController.java b/src/main/java/com/mallardromain/hotel/controller/AuthController.java index 07db939..0837805 100644 --- a/src/main/java/com/mallardromain/hotel/controller/AuthController.java +++ b/src/main/java/com/mallardromain/hotel/controller/AuthController.java @@ -1,6 +1,11 @@ package com.mallardromain.hotel.controller; +import org.springframework.security.core.AuthenticationException; +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.Authentication; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; @@ -15,39 +20,34 @@ import com.mallardromain.hotel.service.JWTService; public class AuthController { private final JWTService jwtService; + private final AuthenticationManager authenticationManager; - public AuthController(JWTService jwtService){ + public AuthController(JWTService jwtService, AuthenticationManager authenticationManager){ this.jwtService = jwtService; + this.authenticationManager = authenticationManager; } @PostMapping("/login") public ResponseEntity login( @RequestBody LoginRequest request ){ - //temps test1/2 - if ( - request.getUsername().equals("test1") - && - request.getPassword().equals("password1") - ) { - String token = jwtService - .generateToken(request.getUsername()); + try{ + /// NEW SECURE TOKEN LOGIN + Authentication authentication = authenticationManager.authenticate( + new UsernamePasswordAuthenticationToken( + request.getUsername(), + request.getPassword() + ) + ); + + String token = jwtService.generateToken(authentication.getName()); return ResponseEntity.ok(token); + + } catch (AuthenticationException e) { + return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body("Invalid username/password"); } - - if ( - request.getUsername().equals("test2") - && - request.getPassword().equals("password2") - ) { - String token = jwtService - .generateToken(request.getUsername()); - - return ResponseEntity.ok(token); - } - - return ResponseEntity.status(401).body("Invalid username/password"); + } diff --git a/src/main/java/com/mallardromain/hotel/model/User.java b/src/main/java/com/mallardromain/hotel/model/User.java new file mode 100644 index 0000000..da36a7e --- /dev/null +++ b/src/main/java/com/mallardromain/hotel/model/User.java @@ -0,0 +1,49 @@ +package com.mallardromain.hotel.model; + +import jakarta.persistence.*; + +@Entity +@Table(name = "users") +public class User { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Integer id; + + private String username; + + private String password; + + public User(){ + + } + + public User(String username, String password ){ + this.username = username; + this.password = password; + } + + public Integer getId(){ + return id; + } + + public void setId(Integer id){ + this.id = id; + } + + 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; + } +} diff --git a/src/main/java/com/mallardromain/hotel/repository/UserRepository.java b/src/main/java/com/mallardromain/hotel/repository/UserRepository.java new file mode 100644 index 0000000..f897e10 --- /dev/null +++ b/src/main/java/com/mallardromain/hotel/repository/UserRepository.java @@ -0,0 +1,14 @@ +package com.mallardromain.hotel.repository; + +import java.util.Optional; + +import org.springframework.data.jpa.repository.JpaRepository; + +import com.mallardromain.hotel.model.User; + +public interface UserRepository extends JpaRepository { + + Optional findByUsername(String username); + + +} diff --git a/src/main/java/com/mallardromain/hotel/service/UserService.java b/src/main/java/com/mallardromain/hotel/service/UserService.java new file mode 100644 index 0000000..8b7b153 --- /dev/null +++ b/src/main/java/com/mallardromain/hotel/service/UserService.java @@ -0,0 +1,48 @@ +package com.mallardromain.hotel.service; + +import org.springframework.security.core.userdetails.UserDetails; +import org.springframework.security.core.userdetails.UserDetailsService; +import org.springframework.security.core.userdetails.UsernameNotFoundException; +import org.springframework.security.crypto.password.PasswordEncoder; +import org.springframework.stereotype.Service; + +import com.mallardromain.hotel.model.User; +import com.mallardromain.hotel.repository.UserRepository; + +import jakarta.persistence.*; + + +@Service +public class UserService implements UserDetailsService { + + private final PasswordEncoder passwordEncoder; + + private final UserRepository repo; + + public UserService(UserRepository repo, PasswordEncoder passwordEncoder){ + this.repo = repo; + this.passwordEncoder = passwordEncoder; + } + + public User registerNewUser(String username, String rawPassword) { + User newUser = new User(); + newUser.setUsername(username); + + String hashedPassword = passwordEncoder.encode(rawPassword); + newUser.setPassword(hashedPassword); + + return repo.save(newUser); + } + + @Override + public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { + return repo.findByUsername(username) + .map(user -> org.springframework.security.core.userdetails.User + .withUsername(user.getUsername()) + .password(user.getPassword()) + .authorities("USER") // Default role + .build() + ) + .orElseThrow(() -> new UsernameNotFoundException("User not found in DB")); + } +} diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 8a78733..1247654 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -2,6 +2,7 @@ spring.application.name=hotel spring.datasource.url=jdbc:sqlite:hotel/data/hotel.sqlite spring.datasource.driver-class-name=org.sqlite.JDBC +spring.jpa.hibernate.ddl-auto=update spring.jpa.database-platform=org.hibernate.community.dialect.SQLiteDialect