forked from RyanGoodwill/backend
1
This commit is contained in:
parent
4f132490c6
commit
94a7b1bc13
23
pom.xml
23
pom.xml
@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
@ -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>
|
||||
@ -210,4 +199,4 @@
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
</project>
|
||||
</project>
|
||||
@ -1,5 +1,4 @@
|
||||
package org.cmh.backend.Config;
|
||||
// CorsConfig.java
|
||||
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
@ -14,13 +13,12 @@ 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);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
54
src/main/java/org/cmh/backend/Config/SecurityConfig.java
Normal file
54
src/main/java/org/cmh/backend/Config/SecurityConfig.java
Normal 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());
|
||||
}
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
@ -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);
|
||||
return ResponseEntity.ok(user);
|
||||
@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();
|
||||
}
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
@ -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);
|
||||
}
|
||||
@ -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);
|
||||
}
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
7
src/test/application-test.properties
Normal file
7
src/test/application-test.properties
Normal 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
|
||||
@ -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() {
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user