This commit is contained in:
Chester.X 2024-07-02 16:40:45 +08:00
parent 4f132490c6
commit 94a7b1bc13
13 changed files with 245 additions and 78 deletions

19
pom.xml
View File

@ -50,10 +50,10 @@
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<!-- <dependency>-->
<!-- <groupId>org.springframework.boot</groupId>-->
<!-- <artifactId>spring-boot-starter-security</artifactId>-->
<!-- </dependency>-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
@ -62,27 +62,16 @@
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web-services</artifactId>
</dependency>
<!-- <dependency>-->
<!-- <groupId>org.mybatis.spring.boot</groupId>-->
<!-- <artifactId>mybatis-spring-boot-starter</artifactId>-->
<!-- <version>3.0.3</version>-->
<!-- </dependency>-->
<dependency>
<groupId>org.springframework.session</groupId>
<artifactId>spring-session-jdbc</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<!-- <dependency>-->
<!-- <groupId>com.h2database</groupId>-->
<!-- <artifactId>h2</artifactId>-->
<!-- <scope>runtime</scope>-->
<!-- </dependency>-->
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>

View File

@ -1,5 +1,4 @@
package org.cmh.backend.Config;
// CorsConfig.java
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@ -14,8 +13,8 @@ public class CorsConfig {
return new WebMvcConfigurer() {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedOrigins("http://localhost:8080")
registry.addMapping("/api/**")
.allowedOrigins("http://localhost:3000")
.allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS")
.allowedHeaders("*")
.allowCredentials(true);
@ -23,4 +22,3 @@ public class CorsConfig {
};
}
}

View File

@ -0,0 +1,54 @@
package org.cmh.backend.Config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;
import java.util.List;
@Configuration
@EnableWebSecurity
public class SecurityConfig {
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http
.csrf(csrf -> csrf.disable())
.cors(cors -> cors.configurationSource(corsConfigurationSource()))
.authorizeHttpRequests(authorize -> authorize
.requestMatchers("/api/auth/register", "/api/auth/login").permitAll()
.anyRequest().authenticated()
);
return http.build();
}
@Bean
public UrlBasedCorsConfigurationSource corsConfigurationSource() {
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
CorsConfiguration config = new CorsConfiguration();
config.setAllowCredentials(true);
config.setAllowedOrigins(List.of("http://localhost:3000"));
config.setAllowedHeaders(List.of("*"));
config.setAllowedMethods(List.of("GET", "POST", "PUT", "DELETE", "OPTIONS"));
source.registerCorsConfiguration("/**", config);
return source;
}
@Bean
public CorsFilter corsFilter() {
return new CorsFilter(corsConfigurationSource());
}
}

View File

@ -1,13 +1,45 @@
package org.cmh.backend.authentication.controller;
import org.cmh.backend.authentication.model.User;
import org.cmh.backend.authentication.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.HashMap;
import java.util.Map;
@RestController
class AuthenticationController {
@RequestMapping("/api/auth")
public class AuthenticationController {
@Autowired
private UserService userService;
@PostMapping("/register")
public User register(@RequestBody User user) {
return userService.register(user);
}
@PostMapping("/login")
public ResponseEntity<Map<String, Object>> login(@RequestBody User loginRequest) {
User user = userService.login(loginRequest.getUsername(), loginRequest.getPassword());
if (user == null) {
throw new RuntimeException("Invalid username or password");
}
Map<String, Object> response = new HashMap<>();
response.put("userId", user.getId());
response.put("user", user);
return ResponseEntity.ok(response);
}
@GetMapping("/hello")
public String hello(){
return "Hello SpringBoot!";
}
@PostMapping("/getVerificationCode")
public String getVerificationCode(@RequestBody String contact) {
return "Verification code sent to " + contact;
}
}

View File

@ -4,20 +4,52 @@ import org.cmh.backend.authentication.model.User;
import org.cmh.backend.authentication.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.*;
@RestController
@RequestMapping("/users")
public class UserController {
@Autowired
private UserService userService;
@GetMapping("/{username}")
public ResponseEntity<User> getUser(@PathVariable String username) {
User user = userService.getUserByUsername(username);
@CrossOrigin(origins = "http://localhost:3000")
@PostMapping("/register")
public ResponseEntity<User> register(@RequestBody User user) {
User registeredUser = userService.register(user);
return ResponseEntity.ok(registeredUser);
}
@PostMapping("/login")
public ResponseEntity<User> login(@RequestParam String username, @RequestParam String password) {
User user = userService.login(username, password);
if (user != null) {
return ResponseEntity.ok(user);
}
return ResponseEntity.status(401).build();
}
@PutMapping("/update")
public ResponseEntity<User> updateUserInfo(@RequestBody User user) {
User updatedUser = userService.updateUserInfo(user);
return ResponseEntity.ok(updatedUser);
}
@PutMapping("/changePassword")
public ResponseEntity<?> changePassword(@RequestParam Long userId, @RequestParam String oldPassword, @RequestParam String newPassword) {
boolean isChanged = userService.changePassword(userId, oldPassword, newPassword);
if (isChanged) {
return ResponseEntity.ok("Password changed successfully");
}
return ResponseEntity.status(400).body("Old password is incorrect");
}
@GetMapping("/{userId}")
public ResponseEntity<User> getUserInfo(@PathVariable Long userId) {
User user = userService.findById(userId).orElse(null);
if (user != null) {
return ResponseEntity.ok(user);
}
return ResponseEntity.status(404).build();
}
}

View File

@ -1,39 +1,34 @@
// User.java
package org.cmh.backend.authentication.model;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import lombok.Data;
import jakarta.persistence.*;
import java.time.LocalDateTime;
@Data
@Entity
@Table(name = "Chester")
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(nullable = false, unique = true)
private String username;
@Column(nullable = false)
private String password;
public Long getId() {
return id;
}
@Column(nullable = false)
private String email;
public void setId(Long id) {
this.id = id;
}
@Column(nullable = false)
private String role;
public String getUsername() {
return username;
}
private String phoneNumber;
private String company;
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
@Column(nullable = false)
private LocalDateTime createdDate;
}

View File

@ -2,7 +2,13 @@ package org.cmh.backend.authentication.repository;
import org.cmh.backend.authentication.model.User;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
import java.util.Optional;
@Repository
public interface UserRepository extends JpaRepository<User, Long> {
User findByUsername(String username);
Optional<User> findById(Long id);
User save(User user);
}

View File

@ -1,16 +1,14 @@
package org.cmh.backend.authentication.service;
import org.cmh.backend.authentication.model.User;
import org.cmh.backend.authentication.repository.UserRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class UserService {
@Autowired
private UserRepository userRepository;
import java.util.Optional;
public User getUserByUsername(String username) {
return userRepository.findByUsername(username);
}
// UserService.java
public interface UserService {
User register(User user);
User login(String username, String password);
User updateUserInfo(User user);
boolean changePassword(Long userId, String oldPassword, String newPassword);
Optional<User> findById(Long id);
}

View File

@ -0,0 +1,58 @@
package org.cmh.backend.authentication.service;
import org.cmh.backend.authentication.model.User;
import org.cmh.backend.authentication.repository.UserRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import java.time.LocalDateTime;
import java.util.Optional;
// UserServiceImpl.java
@Service
public class UserServiceImpl implements UserService {
@Autowired
private UserRepository userRepository;
@Autowired
private PasswordEncoder passwordEncoder;
@Override
public User register(User user) {
user.setPassword(passwordEncoder.encode(user.getPassword()));
user.setCreatedDate(LocalDateTime.now());
return userRepository.save(user);
}
@Override
public User login(String username, String password) {
User user = userRepository.findByUsername(username);
if (user != null && passwordEncoder.matches(password, user.getPassword())) {
return user;
}
return null;
}
@Override
public User updateUserInfo(User user) {
return userRepository.save(user);
}
@Override
public boolean changePassword(Long userId, String oldPassword, String newPassword) {
User user = userRepository.findById(userId).orElse(null);
if (user != null && passwordEncoder.matches(oldPassword, user.getPassword())) {
user.setPassword(passwordEncoder.encode(newPassword));
userRepository.save(user);
return true;
}
return false;
}
@Override
public Optional<User> findById(Long id) {
return userRepository.findById(id);
}
}

View File

@ -0,0 +1,7 @@
spring.datasource.url=jdbc:h2:mem:testdb
spring.datasource.driverClassName=org.h2.Driver
spring.datasource.username=sa
spring.datasource.password=password
spring.jpa.database-platform=org.hibernate.dialect.H2Dialect
spring.jpa.hibernate.ddl-auto=update
spring.h2.console.enabled=true

View File

@ -2,14 +2,11 @@ package org.cmh.backend;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.context.annotation.Import;
@Import(TestcontainersConfiguration.class)
@SpringBootTest
class BackendApplicationTests {
public class BackendApplicationTests {
@Test
void contextLoads() {
}
}

View File

@ -1,11 +1,12 @@
package org.cmh.backend;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class TestBackendApplication {
public static void main(String[] args) {
SpringApplication.from(BackendApplication::main).with(TestcontainersConfiguration.class).run(args);
SpringApplication.run(TestBackendApplication.class, args);
}
}