diff --git a/Back/Spring/backend/pom.xml b/Back/Spring/backend/pom.xml index 01fd0cc7..ce91fa8b 100644 --- a/Back/Spring/backend/pom.xml +++ b/Back/Spring/backend/pom.xml @@ -44,7 +44,15 @@ org.springframework.boot spring-boot-starter-data-jpa - + + org.springframework.boot + spring-boot-starter-thymeleaf + + + org.webjars + bootstrap + 5.1.3 + org.postgresql diff --git a/Back/Spring/backend/src/main/java/pl/zeto/backend/VMC.zip b/Back/Spring/backend/src/main/java/pl/zeto/backend/VMC.zip new file mode 100644 index 00000000..f0b3e594 Binary files /dev/null and b/Back/Spring/backend/src/main/java/pl/zeto/backend/VMC.zip differ diff --git a/Back/Spring/backend/src/main/java/pl/zeto/backend/VMC/config/PasswordEncoderConfig.java b/Back/Spring/backend/src/main/java/pl/zeto/backend/VMC/config/PasswordEncoderConfig.java new file mode 100644 index 00000000..d625f216 --- /dev/null +++ b/Back/Spring/backend/src/main/java/pl/zeto/backend/VMC/config/PasswordEncoderConfig.java @@ -0,0 +1,14 @@ +package pl.zeto.backend.VMC.config; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; + +@Configuration +public class PasswordEncoderConfig { + + @Bean + public BCryptPasswordEncoder passwordEncoder() { + return new BCryptPasswordEncoder(); + } +} \ No newline at end of file diff --git a/Back/Spring/backend/src/main/java/pl/zeto/backend/VMC/config/SecurityConfig.java b/Back/Spring/backend/src/main/java/pl/zeto/backend/VMC/config/SecurityConfig.java index de60241f..9387dc5c 100644 --- a/Back/Spring/backend/src/main/java/pl/zeto/backend/VMC/config/SecurityConfig.java +++ b/Back/Spring/backend/src/main/java/pl/zeto/backend/VMC/config/SecurityConfig.java @@ -1,27 +1,47 @@ package pl.zeto.backend.VMC.config; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; +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 pl.zeto.backend.VMC.service.CustomUserDetailsService; @Configuration @EnableWebSecurity public class SecurityConfig { + @Autowired + @Qualifier("userService") + private UserDetailsService userDetailsService; + @Autowired + public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception { + auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder); + } + + @Autowired + private BCryptPasswordEncoder passwordEncoder; @Bean - SecurityFilterChain filterChain(HttpSecurity http) throws Exception { - http.csrf().disable() // Wyłącza ochronę CSRF - .authorizeHttpRequests(auth -> auth - .anyRequest().permitAll() // Pozwala na dostęp do wszystkich zasobów bez autoryzacji + public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { + http + .authorizeRequests(authorize -> authorize + .requestMatchers("/", "/home", "/register", "/process_register").permitAll() // Dostęp bez autoryzacji + .anyRequest().authenticated() // Wszystkie inne żądania wymagają autoryzacji + ) + .formLogin(login -> login + .loginPage("/login") // Określa stronę logowania + .permitAll() + .defaultSuccessUrl("/", true) + ) + .logout(logout -> logout + .permitAll() // Zezwala wszystkim na dostęp do wylogowania ); return http.build(); } - @Bean - public PasswordEncoder passwordEncoder() { - return new BCryptPasswordEncoder(); - } -} +} \ No newline at end of file diff --git a/Back/Spring/backend/src/main/java/pl/zeto/backend/VMC/controller/AccessDeniedController.java b/Back/Spring/backend/src/main/java/pl/zeto/backend/VMC/controller/AccessDeniedController.java new file mode 100644 index 00000000..61262386 --- /dev/null +++ b/Back/Spring/backend/src/main/java/pl/zeto/backend/VMC/controller/AccessDeniedController.java @@ -0,0 +1,13 @@ +package pl.zeto.backend.VMC.controller; + +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.GetMapping; + +@Controller +public class AccessDeniedController { + + @GetMapping("/access-denied") + public String showAccessDeniedPage() { + return "access-denied"; + } +} \ No newline at end of file diff --git a/Back/Spring/backend/src/main/java/pl/zeto/backend/VMC/controller/HomePage.java b/Back/Spring/backend/src/main/java/pl/zeto/backend/VMC/controller/HomePage.java deleted file mode 100644 index 3f7dabc4..00000000 --- a/Back/Spring/backend/src/main/java/pl/zeto/backend/VMC/controller/HomePage.java +++ /dev/null @@ -1,13 +0,0 @@ -package pl.zeto.backend.VMC.controller; - -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.RestController; - -@RestController -public class HomePage { - - @GetMapping("/") - public String home() { - return "Strona główna Kantoru Walutowego"; - } -} diff --git a/Back/Spring/backend/src/main/java/pl/zeto/backend/VMC/controller/HomePageController.java b/Back/Spring/backend/src/main/java/pl/zeto/backend/VMC/controller/HomePageController.java new file mode 100644 index 00000000..1051dac9 --- /dev/null +++ b/Back/Spring/backend/src/main/java/pl/zeto/backend/VMC/controller/HomePageController.java @@ -0,0 +1,13 @@ +package pl.zeto.backend.VMC.controller; + +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.GetMapping; + +@Controller +public class HomePageController { + + @GetMapping("/") + public String home() { + return "index"; // Nazwa pliku bez rozszerzenia .html z katalogu resources/templates + } +} diff --git a/Back/Spring/backend/src/main/java/pl/zeto/backend/VMC/controller/LoginController.java b/Back/Spring/backend/src/main/java/pl/zeto/backend/VMC/controller/LoginController.java new file mode 100644 index 00000000..67311c46 --- /dev/null +++ b/Back/Spring/backend/src/main/java/pl/zeto/backend/VMC/controller/LoginController.java @@ -0,0 +1,13 @@ +package pl.zeto.backend.VMC.controller; + +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.GetMapping; + +@Controller +public class LoginController { + + @GetMapping("/login") + public String showLoginPage() { + return "login"; + } +} \ No newline at end of file diff --git a/Back/Spring/backend/src/main/java/pl/zeto/backend/VMC/controller/RegisterController.java b/Back/Spring/backend/src/main/java/pl/zeto/backend/VMC/controller/RegisterController.java new file mode 100644 index 00000000..93ae4cf0 --- /dev/null +++ b/Back/Spring/backend/src/main/java/pl/zeto/backend/VMC/controller/RegisterController.java @@ -0,0 +1,47 @@ +package pl.zeto.backend.VMC.controller; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.stereotype.Controller; +import org.springframework.ui.Model; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.ResponseBody; +import pl.zeto.backend.VMC.model.AppUser; +import pl.zeto.backend.VMC.model.Role; +import pl.zeto.backend.VMC.repository.UserRepo; + +@Controller +public class RegisterController { + + @Autowired + private UserRepo userRepo; + @Autowired + private pl.zeto.backend.VMC.service.UserService userService; + + // Zwraca widok HTML + @GetMapping("/register") + public String showSignUpForm(Model model) { + model.addAttribute("user", new AppUser()); + return "register"; + } + + // Przetwarza formularz rejestracji i zwraca stronę HTML + @PostMapping("/process_register") + public String processRegister(AppUser user) { + + userService.addUser(user); + return "register_success"; + } + + // Endpoint API do obsługi rejestracji za pomocą JSON + @PostMapping("/api/register") + @ResponseBody + public ResponseEntity processRegisterApi(@RequestBody AppUser user) { + user.setRole(Role.USER); + userRepo.save(user); + return new ResponseEntity<>("User registered successfully", HttpStatus.CREATED); + } +} \ No newline at end of file diff --git a/Back/Spring/backend/src/main/java/pl/zeto/backend/VMC/dto/CustomUserDetails.java b/Back/Spring/backend/src/main/java/pl/zeto/backend/VMC/dto/CustomUserDetails.java new file mode 100644 index 00000000..abf3b382 --- /dev/null +++ b/Back/Spring/backend/src/main/java/pl/zeto/backend/VMC/dto/CustomUserDetails.java @@ -0,0 +1,56 @@ +package pl.zeto.backend.VMC.dto; + +import org.springframework.security.core.GrantedAuthority; +import org.springframework.security.core.authority.SimpleGrantedAuthority; +import org.springframework.security.core.userdetails.UserDetails; +import pl.zeto.backend.VMC.model.AppAccount; +import pl.zeto.backend.VMC.model.AppUser; + +import java.util.Collection; +import java.util.Collections; + +public class CustomUserDetails implements UserDetails { + + private AppUser appAccount; + + public CustomUserDetails(AppUser account) { + this.appAccount = account; + } + + @Override + public Collection getAuthorities() { + return Collections.singleton(new SimpleGrantedAuthority(appAccount.getRole().name())); + } + + @Override + public String getPassword() { + return appAccount.getPassword(); + } + + @Override + public String getUsername() { + return appAccount.getUsername(); + } + + @Override + public boolean isAccountNonExpired() { + return true; + } + + @Override + public boolean isAccountNonLocked() { + return true; + } + + @Override + public boolean isCredentialsNonExpired() { + return true; + } + + @Override + public boolean isEnabled() { + return true; + } + + // Implementacja pozostałych metod interfejsu UserDetails... +} \ No newline at end of file diff --git a/Back/Spring/backend/src/main/java/pl/zeto/backend/VMC/model/AppUser.java b/Back/Spring/backend/src/main/java/pl/zeto/backend/VMC/model/AppUser.java index 43721066..f3897aa2 100644 --- a/Back/Spring/backend/src/main/java/pl/zeto/backend/VMC/model/AppUser.java +++ b/Back/Spring/backend/src/main/java/pl/zeto/backend/VMC/model/AppUser.java @@ -18,13 +18,14 @@ public class AppUser { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; + private Role role; private String username; private String firstName; private String lastName; private String email; private String password; - private Role role; + @OneToMany(mappedBy = "user", cascade = CascadeType.ALL, fetch = FetchType.LAZY) private Set accounts; diff --git a/Back/Spring/backend/src/main/java/pl/zeto/backend/VMC/repository/AccountRepo.java b/Back/Spring/backend/src/main/java/pl/zeto/backend/VMC/repository/AccountRepo.java index 393d7120..e4a851b3 100644 --- a/Back/Spring/backend/src/main/java/pl/zeto/backend/VMC/repository/AccountRepo.java +++ b/Back/Spring/backend/src/main/java/pl/zeto/backend/VMC/repository/AccountRepo.java @@ -4,4 +4,5 @@ import pl.zeto.backend.VMC.model.AppAccount; public interface AccountRepo extends JpaRepository { + } diff --git a/Back/Spring/backend/src/main/java/pl/zeto/backend/VMC/service/CustomUserDetailsService.java b/Back/Spring/backend/src/main/java/pl/zeto/backend/VMC/service/CustomUserDetailsService.java new file mode 100644 index 00000000..5c75d6ab --- /dev/null +++ b/Back/Spring/backend/src/main/java/pl/zeto/backend/VMC/service/CustomUserDetailsService.java @@ -0,0 +1,28 @@ +package pl.zeto.backend.VMC.service; + +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 pl.zeto.backend.VMC.dto.CustomUserDetails; +import pl.zeto.backend.VMC.model.AppAccount; +import pl.zeto.backend.VMC.model.AppUser; +import pl.zeto.backend.VMC.repository.AccountRepo; +import pl.zeto.backend.VMC.repository.UserRepo; + +@Service +public class CustomUserDetailsService implements UserDetailsService { + + @Autowired + private UserRepo userRepo; + + @Override + public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { + AppUser user = userRepo.findByUsername(username); + if (user == null) { + throw new UsernameNotFoundException("User not found"); + } + return new CustomUserDetails(user); + } +} \ No newline at end of file diff --git a/Back/Spring/backend/src/main/java/pl/zeto/backend/VMC/service/UserService.java b/Back/Spring/backend/src/main/java/pl/zeto/backend/VMC/service/UserService.java index 7543a5ed..a2480c94 100644 --- a/Back/Spring/backend/src/main/java/pl/zeto/backend/VMC/service/UserService.java +++ b/Back/Spring/backend/src/main/java/pl/zeto/backend/VMC/service/UserService.java @@ -5,8 +5,10 @@ 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.bcrypt.BCryptPasswordEncoder; import org.springframework.stereotype.Service; import pl.zeto.backend.VMC.model.AppUser; +import pl.zeto.backend.VMC.model.Role; import pl.zeto.backend.VMC.repository.UserRepo; import java.util.ArrayList; @@ -14,11 +16,24 @@ @Service public class UserService implements UserDetailsService { + private final UserRepo userRepository; + private final BCryptPasswordEncoder passwordEncoder; + @Autowired - private UserRepo userRepository; + public UserService(UserRepo userRepository, BCryptPasswordEncoder passwordEncoder) { + this.userRepository = userRepository; + this.passwordEncoder = passwordEncoder; + } + + public void saveUser(AppUser user) { + user.setPassword(passwordEncoder.encode(user.getPassword())); + userRepository.save(user); + } public AppUser addUser(AppUser user) { // Tutaj można dodać logikę walidacji lub hashowania hasła + user.setRole(Role.USER); + user.setPassword(passwordEncoder.encode(user.getPassword())); return userRepository.save(user); } diff --git a/Back/Spring/backend/src/main/resources/application.properties b/Back/Spring/backend/src/main/resources/application.properties index 679a6886..7fd9ba63 100644 --- a/Back/Spring/backend/src/main/resources/application.properties +++ b/Back/Spring/backend/src/main/resources/application.properties @@ -10,8 +10,8 @@ spring.datasource.driver-class-name=org.postgresql.Driver #Konfiguracja hibernate #przy pierwszym uruchomieniu w innym wypadku wszystkie dane zostan? usuni?te z bazy -spring.jpa.hibernate.ddl-auto=create-drop -#spring.jpa.hibernate.ddl-auto=update +#spring.jpa.hibernate.ddl-auto=create-drop +spring.jpa.hibernate.ddl-auto=update spring.jpa.show-sql=true logging.level.org.hibernate.type=TRACE logging.level.org.hibernate.SQL=DEBUG @@ -29,4 +29,5 @@ spring.thymeleaf.cache=false #konfigruacja springa -spring.main.allow-bean-definition-overriding=true \ No newline at end of file +spring.main.allow-bean-definition-overriding=true +#logging.level.root=DEBUG \ No newline at end of file diff --git a/Back/Spring/backend/src/main/resources/templates/access-denied.html b/Back/Spring/backend/src/main/resources/templates/access-denied.html new file mode 100644 index 00000000..0f2fd3ce --- /dev/null +++ b/Back/Spring/backend/src/main/resources/templates/access-denied.html @@ -0,0 +1,17 @@ + + + + + Brak dostępu + + + + + +
+ +
+ + \ No newline at end of file diff --git a/Back/Spring/backend/src/main/resources/templates/index.html b/Back/Spring/backend/src/main/resources/templates/index.html new file mode 100644 index 00000000..db378941 --- /dev/null +++ b/Back/Spring/backend/src/main/resources/templates/index.html @@ -0,0 +1,11 @@ + + + + + HomePage + + + +

HomePage

+ + \ No newline at end of file diff --git a/Back/Spring/backend/src/main/resources/templates/login.html b/Back/Spring/backend/src/main/resources/templates/login.html new file mode 100644 index 00000000..6a946fc0 --- /dev/null +++ b/Back/Spring/backend/src/main/resources/templates/login.html @@ -0,0 +1,28 @@ + + + + + Logowanie + + + +
+

Logowanie

+
+
+ + +
+
+ + +
+ +
+
+ Nie masz konta? Zarejestruj się +
+ +
+ + diff --git a/Back/Spring/backend/src/main/resources/templates/register.html b/Back/Spring/backend/src/main/resources/templates/register.html new file mode 100644 index 00000000..a36bc880 --- /dev/null +++ b/Back/Spring/backend/src/main/resources/templates/register.html @@ -0,0 +1,43 @@ + + + + + + Formularz rejestracji + + + + +
+

Formularz rejestracji

+
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+ +
+
+ + + + + + + diff --git a/Back/Spring/backend/src/main/resources/templates/register_success.html b/Back/Spring/backend/src/main/resources/templates/register_success.html new file mode 100644 index 00000000..acc4800f --- /dev/null +++ b/Back/Spring/backend/src/main/resources/templates/register_success.html @@ -0,0 +1,16 @@ + + + + + Rejestracja zakończona sukcesem + + + +
+ + Powrót do strony głównej +
+ +