Merge branch 'master' into wyh
Change-Id: Ica501a2ec76395d56157f93aa9c36f7ab302d8fb
diff --git a/src/main/java/com/example/g8backend/G8BackendApplication.java b/src/main/java/com/example/g8backend/G8BackendApplication.java
index 3d297cb..e380bb9 100644
--- a/src/main/java/com/example/g8backend/G8BackendApplication.java
+++ b/src/main/java/com/example/g8backend/G8BackendApplication.java
@@ -2,9 +2,8 @@
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
-import org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration;
-@SpringBootApplication(exclude = { SecurityAutoConfiguration.class })
+@SpringBootApplication()
public class G8BackendApplication {
public static void main(String[] args) {
diff --git a/src/main/java/com/example/g8backend/config/SecurityConfig.java b/src/main/java/com/example/g8backend/config/SecurityConfig.java
index d44e6c6..179d95f 100644
--- a/src/main/java/com/example/g8backend/config/SecurityConfig.java
+++ b/src/main/java/com/example/g8backend/config/SecurityConfig.java
@@ -2,13 +2,41 @@
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
+import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
+import com.example.g8backend.filter.JwtAuthenticationFilter;
+import org.springframework.security.authentication.AuthenticationManager;
+import org.springframework.security.config.annotation.authentication.configuration.AuthenticationConfiguration;
+import org.springframework.security.config.annotation.web.builders.HttpSecurity;
+import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
+import org.springframework.security.web.SecurityFilterChain;
+import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
@Configuration
+@EnableWebSecurity
public class SecurityConfig {
@Bean
public BCryptPasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
+
+ private final JwtAuthenticationFilter jwtAuthenticationFilter;
+
+ public SecurityConfig(JwtAuthenticationFilter jwtAuthenticationFilter) {
+ this.jwtAuthenticationFilter = jwtAuthenticationFilter;
+ }
+
+ @Bean
+ public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
+ return http
+ .csrf(AbstractHttpConfigurer::disable)
+ .addFilterBefore(jwtAuthenticationFilter, UsernamePasswordAuthenticationFilter.class)
+ .build();
+ }
+
+ @Bean
+ public AuthenticationManager authenticationManager(AuthenticationConfiguration config) throws Exception {
+ return config.getAuthenticationManager();
+ }
}
diff --git a/src/main/java/com/example/g8backend/controller/AuthController.java b/src/main/java/com/example/g8backend/controller/AuthController.java
index 39183c1..4b3be4b 100644
--- a/src/main/java/com/example/g8backend/controller/AuthController.java
+++ b/src/main/java/com/example/g8backend/controller/AuthController.java
@@ -21,16 +21,12 @@
@Autowired
private IUserService userService;
-
@Autowired
private mailUtil mailUtil;
-
@Autowired
private PasswordEncoder passwordEncoder;
-
@Autowired
private JwtUtil jwtUtil;
-
@Autowired
RedisTemplate<String, Object> redisTemplate;
@@ -79,7 +75,7 @@
if (existingUser == null || !passwordEncoder.matches(user.getPassword(), existingUser.getPassword())) {
return ResponseEntity.badRequest().body("用户名或密码错误");
}
- String token = jwtUtil.generateToken(existingUser.getUserName());
+ String token = jwtUtil.generateToken(existingUser.getUserId());
Map<String, String> response = new HashMap<>();
response.put("token", token);
return ResponseEntity.ok(response);
diff --git a/src/main/java/com/example/g8backend/controller/TrackerController.java b/src/main/java/com/example/g8backend/controller/TrackerController.java
new file mode 100644
index 0000000..7ee9e5a
--- /dev/null
+++ b/src/main/java/com/example/g8backend/controller/TrackerController.java
@@ -0,0 +1,15 @@
+package com.example.g8backend.controller;
+
+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 com.example.g8backend.service.ITrackerService;
+
+@RestController
+@RequestMapping("/announce")
+public class TrackerController {
+
+}
diff --git a/src/main/java/com/example/g8backend/controller/UserController.java b/src/main/java/com/example/g8backend/controller/UserController.java
index 4bffa3c..2665b4c 100644
--- a/src/main/java/com/example/g8backend/controller/UserController.java
+++ b/src/main/java/com/example/g8backend/controller/UserController.java
@@ -3,52 +3,25 @@
import com.example.g8backend.entity.User;
import com.example.g8backend.service.IUserService;
import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.ResponseEntity;
+import org.springframework.security.core.Authentication;
+import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.web.bind.annotation.*;
-import java.util.List;
-
@RestController
-@RequestMapping("/users")
+@RequestMapping("/user")
public class UserController {
@Autowired
private IUserService userService;
- // 获取所有用户
+ // 获取已登录的用户信息
@GetMapping
- public List<User> getUsers() {
- return userService.list();
- }
-
- // 通过ID获取用户
- @GetMapping("/{id}")
- public User getUserById(@PathVariable Long id) {
- return userService.getById(id);
- }
-
- // 通过用户名获取用户
- @GetMapping("/name/{name}")
- public User getUserByName(@PathVariable String name) {
- return userService.getUserByName(name);
- }
-
- // 添加用户
- @PostMapping
- public void addUser(@RequestBody User user) {
-// return userService.save(user);
- userService.registerUser(user);
- }
-
- // 修改用户
- @PutMapping
- public boolean updateUser(@RequestBody User user) {
- return userService.updateById(user);
- }
-
- // 删除用户
- @DeleteMapping("/{id}")
- public boolean deleteUser(@PathVariable Long id) {
- return userService.removeById(id);
+ public ResponseEntity<?> getUserInfo(){
+ Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
+ long userId = (long) authentication.getPrincipal();
+ User user = userService.getById(userId);
+ user.setPassword(null);
+ return ResponseEntity.ok(user);
}
}
-
diff --git a/src/main/java/com/example/g8backend/entity/Peer.java b/src/main/java/com/example/g8backend/entity/Peer.java
index d7d6af5..43302ce 100644
--- a/src/main/java/com/example/g8backend/entity/Peer.java
+++ b/src/main/java/com/example/g8backend/entity/Peer.java
@@ -8,26 +8,12 @@
@Data
@TableName("peers")
public class Peer {
- @TableId(type = IdType.AUTO)
private Long peerId;
-
- private Long userId;
- private Long torrentId;
+ private String info_hash;
+ private Long userId; // passkey from announce
private String ipAddress;
private Integer port;
private Double uploaded;
private Double downloaded;
- @Override
- public String toString() {
- return "Peer{" +
- "peerId=" + peerId +
- ", userId=" + userId +
- ", torrentId=" + torrentId +
- ", ipAddress='" + ipAddress + '\'' +
- ", port=" + port +
- ", uploaded=" + uploaded +
- ", downloaded=" + downloaded +
- '}';
- }
}
diff --git a/src/main/java/com/example/g8backend/filter/JwtAuthenticationFilter.java b/src/main/java/com/example/g8backend/filter/JwtAuthenticationFilter.java
new file mode 100644
index 0000000..d251424
--- /dev/null
+++ b/src/main/java/com/example/g8backend/filter/JwtAuthenticationFilter.java
@@ -0,0 +1,61 @@
+package com.example.g8backend.filter;
+
+import com.example.g8backend.util.JwtUtil;
+import jakarta.servlet.FilterChain;
+import jakarta.servlet.ServletException;
+import jakarta.servlet.http.HttpServletRequest;
+import jakarta.servlet.http.HttpServletResponse;
+import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
+import org.springframework.security.core.context.SecurityContextHolder;
+import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
+import org.springframework.stereotype.Component;
+import org.springframework.web.filter.OncePerRequestFilter;
+
+import java.io.IOException;
+import java.util.Collections;
+
+@Component
+public class JwtAuthenticationFilter extends OncePerRequestFilter {
+
+ private final JwtUtil jwtUtil;
+
+ public JwtAuthenticationFilter(JwtUtil jwtUtil) {
+ this.jwtUtil = jwtUtil;
+ }
+
+ @Override
+ protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
+ throws ServletException, IOException {
+ String path = request.getServletPath();
+ if (path.startsWith("/auth")) {
+ filterChain.doFilter(request, response);
+ return;
+ }
+
+ String authHeader = request.getHeader("Authorization");
+ if (authHeader != null && authHeader.startsWith("Bearer ")) {
+ String token = authHeader.substring(7);
+ try {
+ Long userId = jwtUtil.validateTokenAndGetUserId(token);
+
+ UsernamePasswordAuthenticationToken authentication =
+ new UsernamePasswordAuthenticationToken(userId, null, Collections.emptyList());
+
+ authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
+
+ // 设置用户认证信息到 Security 上下文
+ SecurityContextHolder.getContext().setAuthentication(authentication);
+ } catch (Exception e) {
+ response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
+ response.getWriter().write("Invalid or expired token");
+ return;
+ }
+ } else {
+ response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
+ response.getWriter().write("Authorization header not found");
+ return;
+ }
+
+ filterChain.doFilter(request, response);
+ }
+}
diff --git a/src/main/java/com/example/g8backend/service/ITrackerService.java b/src/main/java/com/example/g8backend/service/ITrackerService.java
new file mode 100644
index 0000000..e522d77
--- /dev/null
+++ b/src/main/java/com/example/g8backend/service/ITrackerService.java
@@ -0,0 +1,6 @@
+package com.example.g8backend.service;
+
+
+public interface ITrackerService {
+
+}
diff --git a/src/main/java/com/example/g8backend/service/TrackerServiceImpl.java b/src/main/java/com/example/g8backend/service/TrackerServiceImpl.java
new file mode 100644
index 0000000..ae12f70
--- /dev/null
+++ b/src/main/java/com/example/g8backend/service/TrackerServiceImpl.java
@@ -0,0 +1,7 @@
+package com.example.g8backend.service;
+
+import org.springframework.stereotype.Service;
+
+@Service
+public class TrackerServiceImpl implements ITrackerService {
+}
diff --git a/src/main/java/com/example/g8backend/util/JwtUtil.java b/src/main/java/com/example/g8backend/util/JwtUtil.java
index 972df1c..f11e678 100644
--- a/src/main/java/com/example/g8backend/util/JwtUtil.java
+++ b/src/main/java/com/example/g8backend/util/JwtUtil.java
@@ -17,12 +17,12 @@
}
// 生成 JWT Token
- public String generateToken(String username) {
+ public String generateToken(long userId) {
Date now = new Date();
Date expiryDate = new Date(now.getTime() + expirationMs);
return Jwts.builder()
- .subject(username)
+ .claim("id", userId)
.issuedAt(now)
.expiration(expiryDate)
.signWith(secretKey, Jwts.SIG.HS256)
@@ -30,14 +30,14 @@
}
// 验证Token并解析用户名
- public String validateTokenAndGetUsername(String token) {
+ public Long validateTokenAndGetUserId(String token) {
try {
Jws<Claims> claims = Jwts.parser()
.verifyWith(secretKey)
.build()
.parseSignedClaims(token);
- return claims.getPayload().getSubject();
+ return claims.getPayload().get("id", Long.class);
} catch (JwtException e) {
throw new RuntimeException("Token无效或过期", e);
}
diff --git a/src/main/java/com/example/g8backend/util/TorrentUtil.java b/src/main/java/com/example/g8backend/util/TorrentUtil.java
new file mode 100644
index 0000000..37ce7da
--- /dev/null
+++ b/src/main/java/com/example/g8backend/util/TorrentUtil.java
@@ -0,0 +1,4 @@
+package com.example.g8backend.util;
+
+public class TorrentUtil {
+}
diff --git a/src/main/resources/schema.sql b/src/main/resources/schema.sql
index 2bd7010..2018117 100644
--- a/src/main/resources/schema.sql
+++ b/src/main/resources/schema.sql
@@ -9,20 +9,20 @@
torrent_id INT AUTO_INCREMENT PRIMARY KEY,
user_id INT NOT NULL,
torrent_name VARCHAR(255) NOT NULL,
- info_hash VARCHAR(255) NOT NULL,
+ info_hash BINARY(20) NOT NULL,
file_size FLOAT NOT NULL,
- created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (user_id) REFERENCES users(user_id)
);
CREATE TABLE IF NOT EXISTS `peers` (
user_id INT NOT NULL,
- torrent_id INT NOT NULL,
- peer_id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
+ info_hash BINARY(20) NOT NULL,
+ peer_id VARCHAR(20) NOT NULL,
ip_address VARCHAR(128) NOT NULL,
port INT NOT NULL,
uploaded FLOAT NOT NULL,
downloaded FLOAT NOT NULL,
+ last_seen TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
FOREIGN KEY (user_id) REFERENCES users(user_id),
- FOREIGN KEY (torrent_id) REFERENCES torrents(torrent_id)
+ PRIMARY KEY (user_id, info_hash, peer_id)
);
diff --git a/src/test/java/com/example/g8backend/util/JwtUtilTest.java b/src/test/java/com/example/g8backend/util/JwtUtilTest.java
index 860acec..1d2374d 100644
--- a/src/test/java/com/example/g8backend/util/JwtUtilTest.java
+++ b/src/test/java/com/example/g8backend/util/JwtUtilTest.java
@@ -25,24 +25,24 @@
@Test
void testGenerateToken() {
- String username = "testUser";
- String token = jwtUtil.generateToken(username);
+ long userId = 1L;
+ String token = jwtUtil.generateToken(userId);
assertNotNull(token);
}
@Test
- void testValidateTokenAndGetUsername() {
- String username = "testUser";
- String token = jwtUtil.generateToken(username);
- String extractedUsername = jwtUtil.validateTokenAndGetUsername(token);
- assertEquals(username, extractedUsername);
+ void testValidateTokenAndGetUserId() {
+ long userId = 1L;
+ String token = jwtUtil.generateToken(userId);
+ long extractedUserId = jwtUtil.validateTokenAndGetUserId(token);
+ assertEquals(userId, extractedUserId);
}
@Test
void testValidateTokenAndGetUsername_InvalidToken() {
String invalidToken = "invalid.token.here";
Exception exception = assertThrows(RuntimeException.class, () ->
- jwtUtil.validateTokenAndGetUsername(invalidToken)
+ jwtUtil.validateTokenAndGetUserId(invalidToken)
);
assertTrue(exception.getMessage().contains("Token无效或过期"));
}