修改login,register逻辑
Change-Id: If07481bce426e50165c4005416fa9911b218aee4
diff --git a/src/main/java/database/DataManagerInterface.java b/src/main/java/database/DataManagerInterface.java
index e737daa..e2fb1fb 100644
--- a/src/main/java/database/DataManagerInterface.java
+++ b/src/main/java/database/DataManagerInterface.java
@@ -11,6 +11,7 @@
//DB1
public int RegisterUser(User userinfo);// 返回状态:0 success,1 邮箱重复,2其他原因
+ public String LoginUser(User userinfo);
public int UpdateInformation(User userinfo);// 返回状态:0 success,1 不存在,2其他原因
public User GetInformation(String userid);// 返回用户的全部基本信息
diff --git a/src/main/java/database/Database1.java b/src/main/java/database/Database1.java
index ed64717..b89dc18 100644
--- a/src/main/java/database/Database1.java
+++ b/src/main/java/database/Database1.java
@@ -19,6 +19,7 @@
import entity.QUser;
import entity.QUserPT;
import entity.QUserStar;
+import entity.QUserInvite;
import entity.Seed;
import entity.User;
import entity.UserPT;
@@ -38,23 +39,85 @@
props.put("javax.persistence.jdbc.password", cfg.SqlPassword);
this.entitymanager = Persistence.createEntityManagerFactory("myPersistenceUnit", props).createEntityManager();
}
+ @Override
+ public String LoginUser(User userinfo){
+ try {
+ // 检查传入的参数是否合法
+ if (userinfo == null || userinfo.password == null) {
+ return null;
+ }
+
+ // 用户名和邮箱应该有且仅有一个不为空
+ boolean hasUsername = userinfo.username != null && !userinfo.username.isEmpty();
+ boolean hasEmail = userinfo.email != null && !userinfo.email.isEmpty();
+
+ // 如果两个都为空或两个都不为空,返回null
+ if ((!hasUsername && !hasEmail) || (hasUsername && hasEmail)) {
+ return null;
+ }
+
+ JPAQuery<User> query = new JPAQuery<>(entitymanager);
+ QUser u = QUser.user;
+ User foundUser = null;
+
+ if (hasUsername) {
+ // 通过用户名和密码查找
+ foundUser = query.select(u)
+ .from(u)
+ .where(u.username.eq(userinfo.username)
+ .and(u.password.eq(userinfo.password)))
+ .fetchOne();
+ } else {
+ // 通过邮箱和密码查找
+ foundUser = query.select(u)
+ .from(u)
+ .where(u.email.eq(userinfo.email)
+ .and(u.password.eq(userinfo.password)))
+ .fetchOne();
+ }
+
+ // 如果找到匹配的用户则返回用户ID,否则返回null
+ return foundUser != null ? foundUser.userid : null;
+
+ } catch (Exception e) {
+ e.printStackTrace();
+ return null;
+ }
+ }
// 返回状态:0 success,1 邮箱重复,2其他原因
@Override
public int RegisterUser(User userinfo){
try{
+ // 首先检查该邮箱是否在UserInvite表中被邀请过
+ JPAQuery<String> inviteQuery = new JPAQuery<>(entitymanager);
+ QUserInvite ui = QUserInvite.userInvite;
+ List<String> invitedEmails = inviteQuery.select(ui.inviterEmail).from(ui).fetch();
+
+ // 如果邮箱不在被邀请列表中,拒绝注册
+ if(!invitedEmails.contains(userinfo.email)){
+ return 2; // 未被邀请
+ }
+
+ // 检查邮箱是否已在User表中存在
JPAQuery<String> query = new JPAQuery<>(entitymanager);
QUser u = QUser.user;
List<String> allEmails = query.select(u.email).from(u).fetch();
if(allEmails.contains(userinfo.email)){
- return 1;
+ return 1; // 邮箱重复
}
+
+ entitymanager.getTransaction().begin();
entitymanager.persist(userinfo);
- return 0;
+ entitymanager.getTransaction().commit();
+ return 0; // 注册成功
}catch(Exception e){
e.printStackTrace();
+ if (entitymanager.getTransaction().isActive()) {
+ entitymanager.getTransaction().rollback();
+ }
return 2;
}
diff --git a/src/main/java/database/Database2.java b/src/main/java/database/Database2.java
index 5152e47..d2d98c7 100644
--- a/src/main/java/database/Database2.java
+++ b/src/main/java/database/Database2.java
@@ -53,6 +53,11 @@
}
@Override
+ public String LoginUser(User userinfo){
+ return null;
+ }
+
+ @Override
public int RegisterUser(User userinfo) {
return 0;
}
diff --git a/src/main/java/entity/UserInvite.java b/src/main/java/entity/UserInvite.java
new file mode 100644
index 0000000..b9c1c3b
--- /dev/null
+++ b/src/main/java/entity/UserInvite.java
@@ -0,0 +1,29 @@
+package entity;
+
+import java.io.Serializable;
+
+import javax.persistence.*;
+import com.querydsl.core.annotations.QueryEntity;
+
+@QueryEntity
+@Entity
+@Table(name = "UserInvite")
+@IdClass(UserInviteId.class)
+public class UserInvite implements Serializable {
+ private static final long serialVersionUID = 1L;
+
+ @Id
+ @Column(name = "user_id")
+ public String userId;
+
+ @Id
+ @Column(name = "inviter_email")
+ public String inviterEmail;
+
+ @Column(name = "inviter_registered")
+ public boolean inviterRegistered;
+
+ @ManyToOne
+ @JoinColumn(name = "user_id", insertable = false, updatable = false)
+ public User user;
+}
diff --git a/src/main/java/entity/UserInviteId.java b/src/main/java/entity/UserInviteId.java
new file mode 100644
index 0000000..adf729a
--- /dev/null
+++ b/src/main/java/entity/UserInviteId.java
@@ -0,0 +1,33 @@
+package entity;
+
+import java.io.Serializable;
+import java.util.Objects;
+
+public class UserInviteId implements Serializable {
+ private static final long serialVersionUID = 1L;
+
+ public String userId;
+ public String inviterEmail;
+
+ public UserInviteId() {
+ }
+
+ public UserInviteId(String userId, String inviterEmail) {
+ this.userId = userId;
+ this.inviterEmail = inviterEmail;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+ UserInviteId that = (UserInviteId) o;
+ return Objects.equals(userId, that.userId) &&
+ Objects.equals(inviterEmail, that.inviterEmail);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(userId, inviterEmail);
+ }
+}
diff --git a/src/main/java/tracker/DataCaptureProxy.java b/src/main/java/tracker/DataCaptureProxy.java
index 4d2737f..be7d9f6 100644
--- a/src/main/java/tracker/DataCaptureProxy.java
+++ b/src/main/java/tracker/DataCaptureProxy.java
@@ -16,10 +16,12 @@
private final String trackerHost;
private final int trackerPort;
+ private final Tracker tracker;
public DataCaptureProxy(String trackerHost, int trackerPort) {
this.trackerHost = trackerHost;
this.trackerPort = trackerPort;
+ this.tracker = new Tracker(); // 初始化Tracker实例
}
@Override
@@ -37,6 +39,27 @@
", passkey=" + passkey
);
+ // 调用Tracker方法更新上传和下载数据
+ if (passkey != null && !passkey.isEmpty()) {
+ try {
+ if (uploaded != null && !uploaded.isEmpty()) {
+ int uploadValue = Integer.parseInt(uploaded);
+ if (uploadValue > 0) {
+ tracker.AddUpLoad(passkey, uploadValue);
+ }
+ }
+
+ if (downloaded != null && !downloaded.isEmpty()) {
+ int downloadValue = Integer.parseInt(downloaded);
+ if (downloadValue > 0) {
+ tracker.AddDownload(passkey, downloadValue);
+ }
+ }
+ } catch (NumberFormatException e) {
+ System.err.println("Error parsing upload/download values: " + e.getMessage());
+ }
+ }
+
// 构造转发 URL
String path = req.getPath().getPath();
String query = req.getQuery().toString();
diff --git a/src/main/resources/META-INF/persistence.xml b/src/main/resources/META-INF/persistence.xml
index e026146..2ae459c 100644
--- a/src/main/resources/META-INF/persistence.xml
+++ b/src/main/resources/META-INF/persistence.xml
@@ -25,6 +25,7 @@
<class>entity.PostReply</class>
<class>entity.TransRecord</class>
<class>entity.SubmitSeed</class>
+ <class>entity.UserInvite</class>
<!-- 数据库连接配置 -->
<properties>
<property name="javax.persistence.jdbc.url" value="${DB_URL}"/>
diff --git a/src/test/java/databasetest/databasesystest.java b/src/test/java/databasetest/databasesystest.java
index f802360..22a9b1e 100644
--- a/src/test/java/databasetest/databasesystest.java
+++ b/src/test/java/databasetest/databasesystest.java
@@ -20,6 +20,8 @@
import org.junit.jupiter.api.DynamicTest;
import org.junit.jupiter.api.TestFactory;
+import entity.UserInvite;
+import entity.QUserInvite;
import database.Database1;
import entity.User;
import entity.config;
@@ -78,50 +80,133 @@
EntityTransaction tx = em.getTransaction();
tx.begin();
try {
- User user = new User();
- String userId = testUserIds.get(i);
- if (userId.length() > 36) userId = userId.substring(0, 36);
- user.userid = userId;
- user.email = testEmails.get(i);
- user.username = "user" + i;
- user.password = "pwd" + i;
- user.sex = "m";
- user.school = "school" + i;
- user.pictureurl = null;
- user.profile = null;
- user.accountstate = false; // 必填
- user.invitetimes = 5; // 必填
- // 关键:补充userPT字段,避免not-null property异常
- entity.UserPT userPT = new entity.UserPT();
- userPT.userid = user.userid;
- userPT.magic = 0;
- userPT.upload = 0L;
- userPT.download = 0L;
- userPT.share = 0.0;
- userPT.farmurl = null;
- userPT.viptime = 0;
- userPT.user = user;
- user.userPT = userPT;
- // 正常注册
- int ret = db.RegisterUser(user);
- Assertions.assertEquals(0, ret, "RegisterUser should return 0 for success");
- // 再次注册同邮箱用户应返回1
- User user2 = new User();
- String userId2 = userId + "_dup";
- if (userId2.length() > 36) userId2 = userId2.substring(0, 36);
- user2.userid = userId2;
- user2.email = testEmails.get(i);
- user2.username = "user_dup" + i;
- user2.password = "pwd_dup" + i;
- user2.sex = "f";
- user2.school = "school_dup" + i;
- user2.pictureurl = null;
- user2.profile = null;
- user2.accountstate = false; // 必填
- user2.invitetimes = 5; // 必填
- int ret2 = db.RegisterUser(user2);
+ // 1. 创建一些用户并将其保存到数据库中
+ List<User> existingUsers = new ArrayList<>();
+ for (int j = 0; j < 3; j++) {
+ User existingUser = new User();
+ String userId = "existing_user_" + i + "_" + j;
+ if (userId.length() > 36) userId = userId.substring(0, 36);
+ existingUser.userid = userId;
+ existingUser.email = "existing_email_" + i + "_" + j + "@example.com";
+ existingUser.username = "existing_user" + i + "_" + j;
+ existingUser.password = "pwd" + i;
+ existingUser.sex = "m";
+ existingUser.school = "school" + i;
+ existingUser.pictureurl = null;
+ existingUser.profile = null;
+ existingUser.accountstate = false;
+ existingUser.invitetimes = 5;
+
+ entity.UserPT existingUserPT = new entity.UserPT();
+ existingUserPT.userid = existingUser.userid;
+ existingUserPT.magic = 0;
+ existingUserPT.upload = 0L;
+ existingUserPT.download = 0L;
+ existingUserPT.share = 0.0;
+ existingUserPT.farmurl = null;
+ existingUserPT.viptime = 0;
+ existingUserPT.user = existingUser;
+ existingUser.userPT = existingUserPT;
+
+ em.persist(existingUser);
+ existingUsers.add(existingUser);
+ }
+ em.flush();
+
+ // 2. 创建邀请记录 - 一些被邀请的邮箱和一些未被邀请的邮箱
+ // 被邀请的邮箱列表
+ List<String> invitedEmails = new ArrayList<>();
+ for (int j = 0; j < 3; j++) {
+ // 生成邀请记录
+ String invitedEmail = "invited_" + i + "_" + j + "@example.com";
+ invitedEmails.add(invitedEmail);
+
+ UserInvite invite = new UserInvite();
+ invite.userId = existingUsers.get(j % existingUsers.size()).userid; // 使用现有用户作为邀请人
+ invite.inviterEmail = invitedEmail;
+ invite.inviterRegistered = false;
+ em.persist(invite);
+ }
+ em.flush();
+
+ // 非邀请邮箱
+ List<String> uninvitedEmails = new ArrayList<>();
+ for (int j = 0; j < 2; j++) {
+ uninvitedEmails.add("uninvited_" + i + "_" + j + "@example.com");
+ }
+
+ // 3. 测试被邀请且首次注册的用户 - 应该成功 (返回0)
+ User invitedUser = new User();
+ String invitedUserId = testUserIds.get(i);
+ if (invitedUserId.length() > 36) invitedUserId = invitedUserId.substring(0, 36);
+ invitedUser.userid = invitedUserId;
+ invitedUser.email = invitedEmails.get(0); // 使用被邀请的邮箱
+ invitedUser.username = "invited_user" + i;
+ invitedUser.password = "pwd" + i;
+ invitedUser.sex = "m";
+ invitedUser.school = "school" + i;
+ invitedUser.pictureurl = null;
+ invitedUser.profile = null;
+ invitedUser.accountstate = false;
+ invitedUser.invitetimes = 5;
+
+ entity.UserPT invitedUserPT = new entity.UserPT();
+ invitedUserPT.userid = invitedUser.userid;
+ invitedUserPT.magic = 0;
+ invitedUserPT.upload = 0L;
+ invitedUserPT.download = 0L;
+ invitedUserPT.share = 0.0;
+ invitedUserPT.farmurl = null;
+ invitedUserPT.viptime = 0;
+ invitedUserPT.user = invitedUser;
+ invitedUser.userPT = invitedUserPT;
+
+ int ret1 = db.RegisterUser(invitedUser);
+ Assertions.assertEquals(0, ret1, "RegisterUser should return 0 for invited user's first registration");
+
+ // 检查用户是否已保存到数据库
+ User checkUser = em.find(User.class, invitedUserId);
+ Assertions.assertNotNull(checkUser, "User should be saved to database when registration succeeds");
+ Assertions.assertEquals(invitedUser.email, checkUser.email);
+
+ // 4. 测试被邀请但重复注册的用户 - 应该失败 (返回1)
+ User duplicateUser = new User();
+ String duplicateUserId = "duplicate_" + i;
+ if (duplicateUserId.length() > 36) duplicateUserId = duplicateUserId.substring(0, 36);
+ duplicateUser.userid = duplicateUserId;
+ duplicateUser.email = invitedEmails.get(0); // 重复使用同一个邮箱
+ duplicateUser.username = "duplicate_user" + i;
+ duplicateUser.password = "pwd_dup" + i;
+ duplicateUser.sex = "f";
+ duplicateUser.school = "school_dup" + i;
+ duplicateUser.pictureurl = null;
+ duplicateUser.profile = null;
+ duplicateUser.accountstate = false;
+ duplicateUser.invitetimes = 5;
+
+ int ret2 = db.RegisterUser(duplicateUser);
Assertions.assertEquals(1, ret2, "RegisterUser should return 1 for duplicate email");
+
+ // 5. 测试未被邀请的用户 - 应该失败 (返回2)
+ User uninvitedUser = new User();
+ String uninvitedUserId = "uninvited_" + i;
+ if (uninvitedUserId.length() > 36) uninvitedUserId = uninvitedUserId.substring(0, 36);
+ uninvitedUser.userid = uninvitedUserId;
+ uninvitedUser.email = uninvitedEmails.get(0); // 使用未被邀请的邮箱
+ uninvitedUser.username = "uninvited_user" + i;
+ uninvitedUser.password = "pwd_uninv" + i;
+ uninvitedUser.sex = "m";
+ uninvitedUser.school = "school_uninv" + i;
+ uninvitedUser.pictureurl = null;
+ uninvitedUser.profile = null;
+ uninvitedUser.accountstate = false;
+ uninvitedUser.invitetimes = 5;
+
+ int ret3 = db.RegisterUser(uninvitedUser);
+ Assertions.assertEquals(2, ret3, "RegisterUser should return 2 for uninvited email");
+
} finally {
+ // 确保回滚所有更改,不影响真实数据库
tx.rollback();
}
})).collect(Collectors.toList());
@@ -1151,4 +1236,92 @@
}
})).collect(Collectors.toList());
}
+
+ @TestFactory
+ Collection<DynamicTest> testLoginUser() {
+ // 查询所有现有用户
+ List<User> allUsers = em.createQuery("SELECT u FROM User u", User.class).getResultList();
+
+ // 为每个用户创建测试
+ return allUsers.stream().map(existingUser ->
+ DynamicTest.dynamicTest("LoginUser test for user: " + existingUser.username, () -> {
+ EntityTransaction tx = em.getTransaction();
+ tx.begin();
+ try {
+ // 测试1:使用用户名登录(成功)
+ User loginWithUsername = new User();
+ loginWithUsername.username = existingUser.username;
+ loginWithUsername.password = existingUser.password;
+ String loginResult1 = db.LoginUser(loginWithUsername);
+ Assertions.assertEquals(existingUser.userid, loginResult1,
+ "Should successfully login with username and correct password for user: " + existingUser.username);
+
+ // 测试2:使用邮箱登录(成功)
+ User loginWithEmail = new User();
+ loginWithEmail.email = existingUser.email;
+ loginWithEmail.password = existingUser.password;
+ String loginResult2 = db.LoginUser(loginWithEmail);
+ Assertions.assertEquals(existingUser.userid, loginResult2,
+ "Should successfully login with email and correct password for user: " + existingUser.email);
+
+ // 测试3:密码错误(失败)
+ User wrongPassword = new User();
+ wrongPassword.username = existingUser.username;
+ wrongPassword.password = "wrong_password_" + UUID.randomUUID();
+ String loginResult3 = db.LoginUser(wrongPassword);
+ Assertions.assertNull(loginResult3,
+ "Should fail with wrong password for user: " + existingUser.username);
+
+ // 测试4:同时提供用户名和邮箱(失败)
+ User bothFields = new User();
+ bothFields.username = existingUser.username;
+ bothFields.email = existingUser.email;
+ bothFields.password = existingUser.password;
+ String loginResult5 = db.LoginUser(bothFields);
+ Assertions.assertNull(loginResult5,
+ "Should fail when both username and email are provided for user: " + existingUser.username);
+
+ } finally {
+ tx.rollback();
+ }
+ })
+ ).collect(Collectors.toList());
+ }
+
+ @TestFactory
+ Collection<DynamicTest> testLoginUserAdditionalCases() {
+ return IntStream.range(0, 3).mapToObj(i -> DynamicTest.dynamicTest("LoginUser additional test #" + i, () -> {
+ EntityTransaction tx = em.getTransaction();
+ tx.begin();
+ try {
+ // 测试1:用户名不存在(失败)
+ User nonExistentUser = new User();
+ nonExistentUser.username = "non_existent_user_" + UUID.randomUUID();
+ nonExistentUser.password = "any_password";
+ String loginResult1 = db.LoginUser(nonExistentUser);
+ Assertions.assertNull(loginResult1, "Should fail with non-existent username");
+
+ // 测试2:邮箱不存在(失败)
+ User nonExistentEmail = new User();
+ nonExistentEmail.email = "non_existent_" + UUID.randomUUID() + "@example.com";
+ nonExistentEmail.password = "any_password";
+ String loginResult2 = db.LoginUser(nonExistentEmail);
+ Assertions.assertNull(loginResult2, "Should fail with non-existent email");
+
+ // 测试3:缺少密码(失败)
+ User noPassword = new User();
+ noPassword.username = "some_username";
+ noPassword.password = null;
+ String loginResult3 = db.LoginUser(noPassword);
+ Assertions.assertNull(loginResult3, "Should fail when password is null");
+
+ // 测试4:null userinfo(失败)
+ String loginResult4 = db.LoginUser(null);
+ Assertions.assertNull(loginResult4, "Should fail when userinfo is null");
+
+ } finally {
+ tx.rollback();
+ }
+ })).collect(Collectors.toList());
+ }
}
\ No newline at end of file