From 5937135d8eb0462d8cd66ac32fa6a17c94de2419 Mon Sep 17 00:00:00 2001 From: lensferno Date: Sun, 15 May 2022 16:55:38 +0800 Subject: [PATCH] =?UTF-8?q?=E8=83=BD=E8=B7=91=EF=BC=8C=E4=BD=86=E6=98=AF?= =?UTF-8?q?=E5=9D=91=E5=B7=A8=E5=A4=9A=EF=BC=8C=E8=BF=98=E6=9C=89=E5=BE=88?= =?UTF-8?q?=E5=A4=9A=E4=B8=9C=E8=A5=BF=E6=B2=A1=E5=81=9A=E5=AE=8C...?= =?UTF-8?q?=E5=AD=98=E6=A1=A3=E5=AD=98=E6=A1=A3=E4=B8=80=E4=B8=8B=E5=90=A7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pom.xml | 18 ++--- .../littlebusters/api/v1/Register.java | 51 +++--------- .../v1/beans/requests/LoginRequestBody.java | 31 +++++++ .../beans/requests/RegisterRequestBody.java | 31 +++++++ .../responses/LoginResponseData.java | 21 +++-- .../responses/ProfileResponseData.java | 2 +- .../responses/RegisterResponseData.java | 2 +- .../responses/general/ErrorResponse.java | 4 +- .../responses/general/ResponseBase.java | 2 +- .../api/v1/config/ConfigLoader.java | 57 +++++++++++++ .../api/v1/config/GlobalConfig.java | 12 +++ .../littlebusters/api/v1/dao/KeyDatabase.java | 9 +++ .../api/v1/dao/UserInformation.java | 10 --- .../{UserRegister.java => UserOperators.java} | 7 +- .../ConfigureFileInvalidException.java | 11 +++ .../littlebusters/api/v1/login/Login.java | 81 +++++++++---------- .../api/v1/login/LoginIdentify.java | 24 ------ .../littlebusters/api/v1/pojos/StoredKey.java | 13 +++ .../api/v1/pojos/UserInformation.java | 26 ++++++ .../api/v1/pojos/UserResult.java | 2 +- .../littlebusters/api/v1/utils/IOUtil.java | 50 ++++++++++++ .../littlebusters/api/v1/utils/Time.java | 13 +++ .../v1/utils/{ => database}/MyBatisUtil.java | 4 +- .../api/v1/utils/database/User.java | 14 ++++ .../api/v1/utils/jwt/JWTManager.java | 55 +++++++++++++ .../api/v1/utils/key/KeyManager.java | 4 + .../mappers/DatabaseInitSqlMapper.xml | 50 ++++++++++++ src/main/resources/mappers/KeySqlMapper.xml | 19 +++++ src/main/resources/mappers/LoginSqlMapper.xml | 4 +- .../resources/mappers/RegisterSqlMapper.xml | 2 +- .../lensfrex/littlebusters/DefaultConfig.conf | 8 ++ 31 files changed, 490 insertions(+), 147 deletions(-) create mode 100644 src/main/java/me/lensfrex/littlebusters/api/v1/beans/requests/LoginRequestBody.java create mode 100644 src/main/java/me/lensfrex/littlebusters/api/v1/beans/requests/RegisterRequestBody.java rename src/main/java/me/lensfrex/littlebusters/api/v1/{ => beans}/responses/LoginResponseData.java (65%) rename src/main/java/me/lensfrex/littlebusters/api/v1/{ => beans}/responses/ProfileResponseData.java (86%) rename src/main/java/me/lensfrex/littlebusters/api/v1/{ => beans}/responses/RegisterResponseData.java (90%) rename src/main/java/me/lensfrex/littlebusters/api/v1/{ => beans}/responses/general/ErrorResponse.java (72%) rename src/main/java/me/lensfrex/littlebusters/api/v1/{ => beans}/responses/general/ResponseBase.java (88%) create mode 100644 src/main/java/me/lensfrex/littlebusters/api/v1/config/ConfigLoader.java create mode 100644 src/main/java/me/lensfrex/littlebusters/api/v1/config/GlobalConfig.java create mode 100644 src/main/java/me/lensfrex/littlebusters/api/v1/dao/KeyDatabase.java delete mode 100644 src/main/java/me/lensfrex/littlebusters/api/v1/dao/UserInformation.java rename src/main/java/me/lensfrex/littlebusters/api/v1/dao/{UserRegister.java => UserOperators.java} (59%) create mode 100644 src/main/java/me/lensfrex/littlebusters/api/v1/exceptions/ConfigureFileInvalidException.java delete mode 100644 src/main/java/me/lensfrex/littlebusters/api/v1/login/LoginIdentify.java create mode 100644 src/main/java/me/lensfrex/littlebusters/api/v1/pojos/StoredKey.java create mode 100644 src/main/java/me/lensfrex/littlebusters/api/v1/pojos/UserInformation.java create mode 100644 src/main/java/me/lensfrex/littlebusters/api/v1/utils/IOUtil.java create mode 100644 src/main/java/me/lensfrex/littlebusters/api/v1/utils/Time.java rename src/main/java/me/lensfrex/littlebusters/api/v1/utils/{ => database}/MyBatisUtil.java (78%) create mode 100644 src/main/java/me/lensfrex/littlebusters/api/v1/utils/database/User.java create mode 100644 src/main/java/me/lensfrex/littlebusters/api/v1/utils/jwt/JWTManager.java create mode 100644 src/main/java/me/lensfrex/littlebusters/api/v1/utils/key/KeyManager.java create mode 100644 src/main/resources/mappers/DatabaseInitSqlMapper.xml create mode 100644 src/main/resources/mappers/KeySqlMapper.xml create mode 100644 src/main/resources/me/lensfrex/littlebusters/DefaultConfig.conf diff --git a/pom.xml b/pom.xml index 73c70ad..5d362c2 100644 --- a/pom.xml +++ b/pom.xml @@ -24,18 +24,7 @@ 4.0.1 provided - - org.junit.jupiter - junit-jupiter-api - ${junit.version} - test - - - org.junit.jupiter - junit-jupiter-engine - ${junit.version} - test - + org.glassfish.jersey.core jersey-server @@ -98,6 +87,11 @@ 3.0.4 + + commons-io + commons-io + 2.11.0 + diff --git a/src/main/java/me/lensfrex/littlebusters/api/v1/Register.java b/src/main/java/me/lensfrex/littlebusters/api/v1/Register.java index dff5ea9..b5a0531 100644 --- a/src/main/java/me/lensfrex/littlebusters/api/v1/Register.java +++ b/src/main/java/me/lensfrex/littlebusters/api/v1/Register.java @@ -1,18 +1,17 @@ package me.lensfrex.littlebusters.api.v1; import com.google.gson.Gson; -import com.google.gson.annotations.SerializedName; import jakarta.ws.rs.POST; import jakarta.ws.rs.Path; import jakarta.ws.rs.Produces; import jakarta.ws.rs.core.MediaType; -import me.lensfrex.littlebusters.api.v1.dao.UserInformation; -import me.lensfrex.littlebusters.api.v1.dao.UserRegister; -import me.lensfrex.littlebusters.api.v1.responses.RegisterResponseData; -import me.lensfrex.littlebusters.api.v1.responses.general.ErrorResponse; -import me.lensfrex.littlebusters.api.v1.responses.general.ResponseBase; +import me.lensfrex.littlebusters.api.v1.beans.requests.RegisterRequestBody; +import me.lensfrex.littlebusters.api.v1.dao.UserOperators; +import me.lensfrex.littlebusters.api.v1.beans.responses.RegisterResponseData; +import me.lensfrex.littlebusters.api.v1.beans.responses.general.ErrorResponse; +import me.lensfrex.littlebusters.api.v1.beans.responses.general.ResponseBase; import me.lensfrex.littlebusters.api.v1.utils.InputChecker; -import me.lensfrex.littlebusters.api.v1.utils.MyBatisUtil; +import me.lensfrex.littlebusters.api.v1.utils.database.MyBatisUtil; import org.apache.ibatis.session.SqlSession; import org.mindrot.jbcrypt.BCrypt; @@ -29,8 +28,8 @@ public class Register { RegisterRequestBody registerRequestBody; try { registerRequestBody = gson.fromJson(request, RegisterRequestBody.class); - if (InputChecker.hasInvalidChar(registerRequestBody.userName) || - InputChecker.hasInvisibleChar(registerRequestBody.password)) { + if (InputChecker.hasInvalidChar(registerRequestBody.getUserName()) || + InputChecker.hasInvisibleChar(registerRequestBody.getPassword())) { ErrorResponse errorResponse = new ErrorResponse(1, "用户名或密码非法"); return gson.toJson(errorResponse); @@ -43,44 +42,16 @@ public class Register { } String userUUID = UUID.randomUUID().toString(); - String userBcryptPasswd = BCrypt.hashpw(registerRequestBody.password, BCrypt.gensalt()); + String userBcryptPasswd = BCrypt.hashpw(registerRequestBody.getPassword(), BCrypt.gensalt()); SqlSession sqlSession = MyBatisUtil.getSqlSession(true); - UserRegister userRegister = sqlSession.getMapper(UserRegister.class); + UserOperators userOperators = sqlSession.getMapper(UserOperators.class); - userRegister.addRegisterInfoIntoDb(userUUID, registerRequestBody.userName, userBcryptPasswd); + userOperators.addRegisterInfoIntoDb(userUUID, registerRequestBody.getUserName(), userBcryptPasswd); RegisterResponseData registerResponseBody = new RegisterResponseData(10101, userUUID, userBcryptPasswd); ResponseBase response = new ResponseBase<>(200, "success", registerResponseBody); return gson.toJson(response); } - - public static class RegisterRequestBody { - @SerializedName("user_name") - private String userName; - - private String password; - - public RegisterRequestBody(String userName, String password) { - this.userName = userName; - this.password = password; - } - - public String getUserName() { - return userName; - } - - public void setUserName(String userName) { - this.userName = userName; - } - - public String getPassword() { - return password; - } - - public void setPassword(String password) { - this.password = password; - } - } } \ No newline at end of file diff --git a/src/main/java/me/lensfrex/littlebusters/api/v1/beans/requests/LoginRequestBody.java b/src/main/java/me/lensfrex/littlebusters/api/v1/beans/requests/LoginRequestBody.java new file mode 100644 index 0000000..6bc3bc3 --- /dev/null +++ b/src/main/java/me/lensfrex/littlebusters/api/v1/beans/requests/LoginRequestBody.java @@ -0,0 +1,31 @@ +package me.lensfrex.littlebusters.api.v1.beans.requests; + +import com.google.gson.annotations.SerializedName; + +public class LoginRequestBody { + @SerializedName("user_name") + private String userName; + + private String password; + + public LoginRequestBody(String userName, String password) { + this.userName = userName; + this.password = password; + } + + public String getUserName() { + return userName; + } + + public void setUserName(String userName) { + this.userName = userName; + } + + public String getPassword() { + return password; + } + + public void setPassword(String password) { + this.password = password; + } +} diff --git a/src/main/java/me/lensfrex/littlebusters/api/v1/beans/requests/RegisterRequestBody.java b/src/main/java/me/lensfrex/littlebusters/api/v1/beans/requests/RegisterRequestBody.java new file mode 100644 index 0000000..7903b34 --- /dev/null +++ b/src/main/java/me/lensfrex/littlebusters/api/v1/beans/requests/RegisterRequestBody.java @@ -0,0 +1,31 @@ +package me.lensfrex.littlebusters.api.v1.beans.requests; + +import com.google.gson.annotations.SerializedName; + +public class RegisterRequestBody { + @SerializedName("user_name") + private String userName; + + private String password; + + public RegisterRequestBody(String userName, String password) { + this.userName = userName; + this.password = password; + } + + public String getUserName() { + return userName; + } + + public void setUserName(String userName) { + this.userName = userName; + } + + public String getPassword() { + return password; + } + + public void setPassword(String password) { + this.password = password; + } +} diff --git a/src/main/java/me/lensfrex/littlebusters/api/v1/responses/LoginResponseData.java b/src/main/java/me/lensfrex/littlebusters/api/v1/beans/responses/LoginResponseData.java similarity index 65% rename from src/main/java/me/lensfrex/littlebusters/api/v1/responses/LoginResponseData.java rename to src/main/java/me/lensfrex/littlebusters/api/v1/beans/responses/LoginResponseData.java index 2250add..cde9974 100644 --- a/src/main/java/me/lensfrex/littlebusters/api/v1/responses/LoginResponseData.java +++ b/src/main/java/me/lensfrex/littlebusters/api/v1/beans/responses/LoginResponseData.java @@ -1,4 +1,4 @@ -package me.lensfrex.littlebusters.api.v1.responses; +package me.lensfrex.littlebusters.api.v1.beans.responses; import com.google.gson.annotations.SerializedName; @@ -9,7 +9,9 @@ public class LoginResponseData { /** * 登录用户的uid */ - private int uid; + private long uid; + + private String uuid; /** * 用户本次登录得到的token @@ -23,20 +25,29 @@ public class LoginResponseData { @SerializedName("expired_at") private String expiredAt; - public LoginResponseData(int uid, String accessToken, String expiredAt) { + public LoginResponseData(long uid, String uuid, String accessToken, String expiredAt) { this.uid = uid; + this.uuid = uuid; this.accessToken = accessToken; this.expiredAt = expiredAt; } - public int getUid() { + public long getUid() { return uid; } - public void setUid(int uid) { + public void setUid(long uid) { this.uid = uid; } + public String getUuid() { + return uuid; + } + + public void setUuid(String uuid) { + this.uuid = uuid; + } + public String getAccessToken() { return accessToken; } diff --git a/src/main/java/me/lensfrex/littlebusters/api/v1/responses/ProfileResponseData.java b/src/main/java/me/lensfrex/littlebusters/api/v1/beans/responses/ProfileResponseData.java similarity index 86% rename from src/main/java/me/lensfrex/littlebusters/api/v1/responses/ProfileResponseData.java rename to src/main/java/me/lensfrex/littlebusters/api/v1/beans/responses/ProfileResponseData.java index 4854faf..27bcdb3 100644 --- a/src/main/java/me/lensfrex/littlebusters/api/v1/responses/ProfileResponseData.java +++ b/src/main/java/me/lensfrex/littlebusters/api/v1/beans/responses/ProfileResponseData.java @@ -1,4 +1,4 @@ -package me.lensfrex.littlebusters.api.v1.responses; +package me.lensfrex.littlebusters.api.v1.beans.responses; import me.lensfrex.littlebusters.api.v1.beans.ProfileItem; diff --git a/src/main/java/me/lensfrex/littlebusters/api/v1/responses/RegisterResponseData.java b/src/main/java/me/lensfrex/littlebusters/api/v1/beans/responses/RegisterResponseData.java similarity index 90% rename from src/main/java/me/lensfrex/littlebusters/api/v1/responses/RegisterResponseData.java rename to src/main/java/me/lensfrex/littlebusters/api/v1/beans/responses/RegisterResponseData.java index 42d03bf..0b2309e 100644 --- a/src/main/java/me/lensfrex/littlebusters/api/v1/responses/RegisterResponseData.java +++ b/src/main/java/me/lensfrex/littlebusters/api/v1/beans/responses/RegisterResponseData.java @@ -1,4 +1,4 @@ -package me.lensfrex.littlebusters.api.v1.responses; +package me.lensfrex.littlebusters.api.v1.beans.responses; import com.google.gson.annotations.SerializedName; diff --git a/src/main/java/me/lensfrex/littlebusters/api/v1/responses/general/ErrorResponse.java b/src/main/java/me/lensfrex/littlebusters/api/v1/beans/responses/general/ErrorResponse.java similarity index 72% rename from src/main/java/me/lensfrex/littlebusters/api/v1/responses/general/ErrorResponse.java rename to src/main/java/me/lensfrex/littlebusters/api/v1/beans/responses/general/ErrorResponse.java index 393f983..c0b71ba 100644 --- a/src/main/java/me/lensfrex/littlebusters/api/v1/responses/general/ErrorResponse.java +++ b/src/main/java/me/lensfrex/littlebusters/api/v1/beans/responses/general/ErrorResponse.java @@ -1,4 +1,4 @@ -package me.lensfrex.littlebusters.api.v1.responses.general; +package me.lensfrex.littlebusters.api.v1.beans.responses.general; /** * 错误响应类。 @@ -11,6 +11,6 @@ public class ErrorResponse extends ResponseBase { class ErrorData {} -class ErrorCode { +class ErrorCodes { public static final int REQUEST_PARAM_INVALID = 100; } \ No newline at end of file diff --git a/src/main/java/me/lensfrex/littlebusters/api/v1/responses/general/ResponseBase.java b/src/main/java/me/lensfrex/littlebusters/api/v1/beans/responses/general/ResponseBase.java similarity index 88% rename from src/main/java/me/lensfrex/littlebusters/api/v1/responses/general/ResponseBase.java rename to src/main/java/me/lensfrex/littlebusters/api/v1/beans/responses/general/ResponseBase.java index 5851cff..ba3657c 100644 --- a/src/main/java/me/lensfrex/littlebusters/api/v1/responses/general/ResponseBase.java +++ b/src/main/java/me/lensfrex/littlebusters/api/v1/beans/responses/general/ResponseBase.java @@ -1,4 +1,4 @@ -package me.lensfrex.littlebusters.api.v1.responses.general; +package me.lensfrex.littlebusters.api.v1.beans.responses.general; import com.google.gson.annotations.SerializedName; diff --git a/src/main/java/me/lensfrex/littlebusters/api/v1/config/ConfigLoader.java b/src/main/java/me/lensfrex/littlebusters/api/v1/config/ConfigLoader.java new file mode 100644 index 0000000..5f1dc8d --- /dev/null +++ b/src/main/java/me/lensfrex/littlebusters/api/v1/config/ConfigLoader.java @@ -0,0 +1,57 @@ +package me.lensfrex.littlebusters.api.v1.config; + +import me.lensfrex.littlebusters.api.v1.exceptions.ConfigureFileInvalidException; +import me.lensfrex.littlebusters.api.v1.utils.IOUtil; + +import java.io.*; +import java.nio.charset.StandardCharsets; + +public class ConfigLoader { + + + + private final String globalConfigFilePath; + + public ConfigLoader(String globalConfigFilePath) { + this.globalConfigFilePath = globalConfigFilePath; + } + + public static String toSpecificPathForm(String uniformFilepath) { + return uniformFilepath.replace("/", File.separator); + } + + // todo: 脑子有点乱了,等以后再去重写一遍吧 + public void load() throws ConfigureFileInvalidException { + try { + File globalConfigFile = new File(globalConfigFilePath); + if (!globalConfigFile.exists()) { + globalConfigFile.getParentFile().mkdirs(); + globalConfigFile.createNewFile(); + + InputStream defaultConfigInoutStream = getClass().getResourceAsStream("me/lensfrex/littlebusters/DefaultConfig.conf"); + if (defaultConfigInoutStream == null) { + throw new NullPointerException("Can't find the default config file in program."); + } + + GlobalConfig.configProperties.load(defaultConfigInoutStream); + + String defaultConfig = IOUtil.inputStreamToString(defaultConfigInoutStream, StandardCharsets.UTF_8); + IOUtil.writeFile(defaultConfig.getBytes(StandardCharsets.UTF_8), globalConfigFile); + + return; + } + FileInputStream configFileInputStream = new FileInputStream(globalConfigFile); + GlobalConfig.configProperties.load(configFileInputStream); + + } catch (FileNotFoundException e) { + // todo: 这里应该换成使用日志输出 + System.err.printf("Error: Config file: %s doesn't exists.%n", globalConfigFilePath); + e.printStackTrace(); + } catch (Exception e) { + // todo: 这里应该换成使用日志输出 + System.err.printf("Error: Some errors happened while reading config file: %s %n", globalConfigFilePath); + System.err.printf("Error: %s%n", e.getMessage()); + e.printStackTrace(); + } + } +} diff --git a/src/main/java/me/lensfrex/littlebusters/api/v1/config/GlobalConfig.java b/src/main/java/me/lensfrex/littlebusters/api/v1/config/GlobalConfig.java new file mode 100644 index 0000000..ce44b4a --- /dev/null +++ b/src/main/java/me/lensfrex/littlebusters/api/v1/config/GlobalConfig.java @@ -0,0 +1,12 @@ +package me.lensfrex.littlebusters.api.v1.config; + +import java.util.Properties; + +public class GlobalConfig { + protected static final Properties configProperties = new Properties(); + private GlobalConfig() {} + + public static String get(String key) { + return configProperties.getProperty(key); + } +} diff --git a/src/main/java/me/lensfrex/littlebusters/api/v1/dao/KeyDatabase.java b/src/main/java/me/lensfrex/littlebusters/api/v1/dao/KeyDatabase.java new file mode 100644 index 0000000..f5cb74a --- /dev/null +++ b/src/main/java/me/lensfrex/littlebusters/api/v1/dao/KeyDatabase.java @@ -0,0 +1,9 @@ +package me.lensfrex.littlebusters.api.v1.dao; + +import me.lensfrex.littlebusters.api.v1.pojos.StoredKey; + +public interface KeyDatabase { + StoredKey getKeyContentByKeyName(String keyName); + + int addKeyIntoDatabase(String keyContent, String keyName, int keyType); +} diff --git a/src/main/java/me/lensfrex/littlebusters/api/v1/dao/UserInformation.java b/src/main/java/me/lensfrex/littlebusters/api/v1/dao/UserInformation.java deleted file mode 100644 index cde05a9..0000000 --- a/src/main/java/me/lensfrex/littlebusters/api/v1/dao/UserInformation.java +++ /dev/null @@ -1,10 +0,0 @@ -package me.lensfrex.littlebusters.api.v1.dao; - -import org.apache.ibatis.annotations.Param; - -import java.util.Map; - -public interface UserInformation { - - Map getBasicInfoByUserName(@Param("userName") String userName); -} diff --git a/src/main/java/me/lensfrex/littlebusters/api/v1/dao/UserRegister.java b/src/main/java/me/lensfrex/littlebusters/api/v1/dao/UserOperators.java similarity index 59% rename from src/main/java/me/lensfrex/littlebusters/api/v1/dao/UserRegister.java rename to src/main/java/me/lensfrex/littlebusters/api/v1/dao/UserOperators.java index 77c2a2a..73d8da5 100644 --- a/src/main/java/me/lensfrex/littlebusters/api/v1/dao/UserRegister.java +++ b/src/main/java/me/lensfrex/littlebusters/api/v1/dao/UserOperators.java @@ -1,9 +1,12 @@ package me.lensfrex.littlebusters.api.v1.dao; +import me.lensfrex.littlebusters.api.v1.pojos.UserInformation; import org.apache.ibatis.annotations.Param; -public interface UserRegister { +public interface UserOperators { int addRegisterInfoIntoDb(@Param("uuid") String UUID, @Param("userName") String userName, @Param("password") String password); -} + + UserInformation getBasicInfoByUserName(@Param("userName") String userName); +} \ No newline at end of file diff --git a/src/main/java/me/lensfrex/littlebusters/api/v1/exceptions/ConfigureFileInvalidException.java b/src/main/java/me/lensfrex/littlebusters/api/v1/exceptions/ConfigureFileInvalidException.java new file mode 100644 index 0000000..2204c62 --- /dev/null +++ b/src/main/java/me/lensfrex/littlebusters/api/v1/exceptions/ConfigureFileInvalidException.java @@ -0,0 +1,11 @@ +package me.lensfrex.littlebusters.api.v1.exceptions; + +public class ConfigureFileInvalidException extends Exception { + public ConfigureFileInvalidException() { + super("Error: Some errors happened while parsing configure file."); + } + + public ConfigureFileInvalidException(String message) { + super(message); + } +} diff --git a/src/main/java/me/lensfrex/littlebusters/api/v1/login/Login.java b/src/main/java/me/lensfrex/littlebusters/api/v1/login/Login.java index 6ddce40..18667cc 100644 --- a/src/main/java/me/lensfrex/littlebusters/api/v1/login/Login.java +++ b/src/main/java/me/lensfrex/littlebusters/api/v1/login/Login.java @@ -2,29 +2,28 @@ package me.lensfrex.littlebusters.api.v1.login; import com.google.gson.Gson; import com.google.gson.JsonParseException; -import com.google.gson.annotations.SerializedName; -import com.sun.org.apache.xalan.internal.xsltc.trax.XSLTCSource; import jakarta.ws.rs.POST; import jakarta.ws.rs.Path; import jakarta.ws.rs.Produces; import jakarta.ws.rs.core.MediaType; -import me.lensfrex.littlebusters.api.v1.dao.UserInformation; -import me.lensfrex.littlebusters.api.v1.responses.LoginResponseData; -import me.lensfrex.littlebusters.api.v1.responses.general.ErrorResponse; -import me.lensfrex.littlebusters.api.v1.responses.general.ResponseBase; +import me.lensfrex.littlebusters.api.v1.beans.requests.LoginRequestBody; +import me.lensfrex.littlebusters.api.v1.beans.responses.LoginResponseData; +import me.lensfrex.littlebusters.api.v1.beans.responses.general.ErrorResponse; +import me.lensfrex.littlebusters.api.v1.beans.responses.general.ResponseBase; +import me.lensfrex.littlebusters.api.v1.pojos.UserInformation; import me.lensfrex.littlebusters.api.v1.utils.InputChecker; -import me.lensfrex.littlebusters.api.v1.utils.MyBatisUtil; -import org.apache.ibatis.session.SqlSession; +import me.lensfrex.littlebusters.api.v1.utils.database.User; +import me.lensfrex.littlebusters.api.v1.utils.jwt.JWTManager; import org.mindrot.jbcrypt.BCrypt; -import java.math.BigInteger; -import java.time.LocalDate; -import java.util.HashMap; -import java.util.Map; +import java.time.LocalDateTime; @Path("/login") public class Login { + private final static int TOKEN_EXPIRE_DAY = 15; private final static Gson gson = new Gson(); + private final static JWTManager jwtManager = new JWTManager(); + User userTools = new User(); @POST @Produces(MediaType.APPLICATION_JSON) @@ -32,15 +31,35 @@ public class Login { LoginRequestBody loginRequestBody; try { loginRequestBody = gson.fromJson(request, LoginRequestBody.class); - if (InputChecker.hasInvalidChar(loginRequestBody.userName) || - InputChecker.hasInvisibleChar(loginRequestBody.password)) { + if (InputChecker.hasInvalidChar(loginRequestBody.getUserName()) || + InputChecker.hasInvisibleChar(loginRequestBody.getPassword())) { ErrorResponse errorResponse = new ErrorResponse(100, "请求的用户名或密码非法"); return gson.toJson(errorResponse); } - if () - LoginResponseData loginResponseData = new LoginResponseData(((BigInteger) selectResult.get("uid")).intValue(), (String) selectResult.get("password"), LocalDate.now().toString()); + UserInformation userDatabaseInformation = userTools.getUser(loginRequestBody.getUserName()); + + // todo 这些情况用异常处理会好点吧 分散在代码里面很难看 + // 过会改改 + if (userDatabaseInformation == null) { + ErrorResponse errorResponse = new ErrorResponse(400, "用户名或密码错误"); + return gson.toJson(errorResponse); + } + + if (!identifyPassword(loginRequestBody.getPassword(), userDatabaseInformation.password)) { + ErrorResponse errorResponse = new ErrorResponse(400, "用户名或密码错误"); + return gson.toJson(errorResponse); + } + + String userToken = jwtManager.createNewJWT("login", loginRequestBody.getUserName(), TOKEN_EXPIRE_DAY); + + LoginResponseData loginResponseData = new LoginResponseData( + userDatabaseInformation.uid, + userDatabaseInformation.uuid, + userToken, + LocalDateTime.now().plusDays(TOKEN_EXPIRE_DAY).toString()); + ResponseBase response = new ResponseBase<>(200, "success", loginResponseData); return gson.toJson(response); @@ -54,36 +73,12 @@ public class Login { System.err.println(request); System.err.println(e.getMessage()); - ErrorResponse errorResponse = new ErrorResponse(400, "服务器内部错误,请联系那个背锅的家伙。"); + ErrorResponse errorResponse = new ErrorResponse(400, "服务器内部错误,请联系那个背锅的家伙"); return gson.toJson(errorResponse); } } - public static class LoginRequestBody { - @SerializedName("user_name") - private String userName; - - private String password; - - public LoginRequestBody(String userName, String password) { - this.userName = userName; - this.password = password; - } - - public String getUserName() { - return userName; - } - - public void setUserName(String userName) { - this.userName = userName; - } - - public String getPassword() { - return password; - } - - public void setPassword(String password) { - this.password = password; - } + public boolean identifyPassword(String originPassword, String bcryptPassword) { + return BCrypt.checkpw(originPassword, bcryptPassword); } } \ No newline at end of file diff --git a/src/main/java/me/lensfrex/littlebusters/api/v1/login/LoginIdentify.java b/src/main/java/me/lensfrex/littlebusters/api/v1/login/LoginIdentify.java deleted file mode 100644 index 5afc94b..0000000 --- a/src/main/java/me/lensfrex/littlebusters/api/v1/login/LoginIdentify.java +++ /dev/null @@ -1,24 +0,0 @@ -package me.lensfrex.littlebusters.api.v1.login; - -import me.lensfrex.littlebusters.api.v1.dao.UserInformation; -import me.lensfrex.littlebusters.api.v1.utils.MyBatisUtil; -import org.apache.ibatis.session.SqlSession; -import org.mindrot.jbcrypt.BCrypt; - - -import java.util.Map; - -public class LoginIdentify { - - public boolean identifyLoginUserName(String userName, String passwordSHA256) { - SqlSession sqlSession = MyBatisUtil.getSqlSession(true); - - UserInformation mapper = sqlSession.getMapper(UserInformation.class); - Map selectResult = mapper.getBasicInfoByUserName(userName); - if (selectResult == null) { - return false; - } - - return BCrypt.checkpw(passwordSHA256, (String) selectResult.get("password")); - } -} diff --git a/src/main/java/me/lensfrex/littlebusters/api/v1/pojos/StoredKey.java b/src/main/java/me/lensfrex/littlebusters/api/v1/pojos/StoredKey.java new file mode 100644 index 0000000..feb5de3 --- /dev/null +++ b/src/main/java/me/lensfrex/littlebusters/api/v1/pojos/StoredKey.java @@ -0,0 +1,13 @@ +package me.lensfrex.littlebusters.api.v1.pojos; + +public class StoredKey { + public String keyContent; + public String keyName; + public int keyType; + + public StoredKey(String keyContent, String keyName, int keyType) { + this.keyContent = keyContent; + this.keyName = keyName; + this.keyType = keyType; + } +} diff --git a/src/main/java/me/lensfrex/littlebusters/api/v1/pojos/UserInformation.java b/src/main/java/me/lensfrex/littlebusters/api/v1/pojos/UserInformation.java new file mode 100644 index 0000000..4ea8ddd --- /dev/null +++ b/src/main/java/me/lensfrex/littlebusters/api/v1/pojos/UserInformation.java @@ -0,0 +1,26 @@ +package me.lensfrex.littlebusters.api.v1.pojos; + +public class UserInformation { + public long uid; + public String uuid; + public String userName; + public String password; + public int accountStatus; + public int accountType; + public String phoneNumber; + public boolean deleted; + + public UserInformation(long uid, String uuid, String userName, String password, int accountStatus, + int accountType, String phoneNumber, boolean deleted) { + this.uid = uid; + this.uuid = uuid; + this.userName = userName; + this.password = password; + this.accountStatus = accountStatus; + this.accountType = accountType; + this.phoneNumber = phoneNumber; + this.deleted = deleted; + } + + public UserInformation() {} +} diff --git a/src/main/java/me/lensfrex/littlebusters/api/v1/pojos/UserResult.java b/src/main/java/me/lensfrex/littlebusters/api/v1/pojos/UserResult.java index a43436f..241918e 100644 --- a/src/main/java/me/lensfrex/littlebusters/api/v1/pojos/UserResult.java +++ b/src/main/java/me/lensfrex/littlebusters/api/v1/pojos/UserResult.java @@ -14,4 +14,4 @@ public class UserResult { this.deleted = deleted; this.accountStatus = accountStatus; } -} +} \ No newline at end of file diff --git a/src/main/java/me/lensfrex/littlebusters/api/v1/utils/IOUtil.java b/src/main/java/me/lensfrex/littlebusters/api/v1/utils/IOUtil.java new file mode 100644 index 0000000..74f3841 --- /dev/null +++ b/src/main/java/me/lensfrex/littlebusters/api/v1/utils/IOUtil.java @@ -0,0 +1,50 @@ +package me.lensfrex.littlebusters.api.v1.utils; + + +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.FileOutputStream; +import java.io.InputStream; +import java.nio.charset.Charset; + +public class IOUtil { + public static String inputStreamToString(InputStream inputStream, Charset charSet) { + byte[] bytes = readDataFromInputStream(inputStream); + if (bytes != null) { + return new String(bytes, charSet); + } else { + return null; + } + } + + public static byte[] readDataFromInputStream(InputStream inputStream) { + return readDataFromInputStream(inputStream, 5);// read every 5kb in default + } + + public static byte[] readDataFromInputStream(InputStream inputStream, int byteAllocation) { + try { + ByteArrayOutputStream byteArrayInputStream = new ByteArrayOutputStream(); + byte[] bytes = new byte[1024 * byteAllocation]; + + for (int length; (length = inputStream.read(bytes)) != -1; ) { + byteArrayInputStream.write(bytes, 0, length); + } + + byteArrayInputStream.flush(); + + inputStream.close(); + byteArrayInputStream.close(); + + return byteArrayInputStream.toByteArray(); + } catch (Exception e) { + e.printStackTrace(); + return null; + } + } + + public static void writeFile(byte[] bytes, File file) throws Exception { + FileOutputStream fileOutputStream = new FileOutputStream(file); + fileOutputStream.write(bytes); + fileOutputStream.close(); + } +} diff --git a/src/main/java/me/lensfrex/littlebusters/api/v1/utils/Time.java b/src/main/java/me/lensfrex/littlebusters/api/v1/utils/Time.java new file mode 100644 index 0000000..251f6a9 --- /dev/null +++ b/src/main/java/me/lensfrex/littlebusters/api/v1/utils/Time.java @@ -0,0 +1,13 @@ +package me.lensfrex.littlebusters.api.v1.utils; + +import java.time.LocalDateTime; + +public class Time { + public static LocalDateTime getNowDayTime() { + return LocalDateTime.now(); + } + + public static LocalDateTime getDateTimeAfterDays(int day) { + return LocalDateTime.now().plusDays(day); + } +} diff --git a/src/main/java/me/lensfrex/littlebusters/api/v1/utils/MyBatisUtil.java b/src/main/java/me/lensfrex/littlebusters/api/v1/utils/database/MyBatisUtil.java similarity index 78% rename from src/main/java/me/lensfrex/littlebusters/api/v1/utils/MyBatisUtil.java rename to src/main/java/me/lensfrex/littlebusters/api/v1/utils/database/MyBatisUtil.java index 8e6b03a..960646a 100644 --- a/src/main/java/me/lensfrex/littlebusters/api/v1/utils/MyBatisUtil.java +++ b/src/main/java/me/lensfrex/littlebusters/api/v1/utils/database/MyBatisUtil.java @@ -1,4 +1,4 @@ -package me.lensfrex.littlebusters.api.v1.utils; +package me.lensfrex.littlebusters.api.v1.utils.database; import org.apache.ibatis.io.Resources; import org.apache.ibatis.session.SqlSession; @@ -9,11 +9,11 @@ import java.io.IOException; import java.io.InputStream; public class MyBatisUtil { - private static SqlSessionFactory sqlSessionFactory; static { try { + // todo: 读入配置文件来初始化MyBatis,但是应为配置文件加载部分还没好所以就只能先这样了 String resource = "mybatis-config.xml"; InputStream inputStream = Resources.getResourceAsStream(resource); sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); diff --git a/src/main/java/me/lensfrex/littlebusters/api/v1/utils/database/User.java b/src/main/java/me/lensfrex/littlebusters/api/v1/utils/database/User.java new file mode 100644 index 0000000..ed9f670 --- /dev/null +++ b/src/main/java/me/lensfrex/littlebusters/api/v1/utils/database/User.java @@ -0,0 +1,14 @@ +package me.lensfrex.littlebusters.api.v1.utils.database; + +import me.lensfrex.littlebusters.api.v1.dao.UserOperators; +import me.lensfrex.littlebusters.api.v1.pojos.UserInformation; +import org.apache.ibatis.session.SqlSession; + +public class User { + public UserInformation getUser(String userName) { + SqlSession sqlSession = MyBatisUtil.getSqlSession(true); + + UserOperators mapper = sqlSession.getMapper(UserOperators.class); + return mapper.getBasicInfoByUserName(userName); + } +} diff --git a/src/main/java/me/lensfrex/littlebusters/api/v1/utils/jwt/JWTManager.java b/src/main/java/me/lensfrex/littlebusters/api/v1/utils/jwt/JWTManager.java new file mode 100644 index 0000000..d1d8037 --- /dev/null +++ b/src/main/java/me/lensfrex/littlebusters/api/v1/utils/jwt/JWTManager.java @@ -0,0 +1,55 @@ +package me.lensfrex.littlebusters.api.v1.utils.jwt; + +import io.jsonwebtoken.*; +import io.jsonwebtoken.security.Keys; +import io.jsonwebtoken.security.SignatureException; +import me.lensfrex.littlebusters.api.v1.utils.Time; + +import java.security.Key; +import java.time.LocalDateTime; +import java.util.HashMap; +import java.util.Map; + +public class JWTManager { + // todo 时间有限先这样写能跑起来吧 + private final static Key key = Keys.secretKeyFor(SignatureAlgorithm.HS256); + + public String createNewJWT(String subject, String user, int invalidDays) { + Map header = new HashMap<>(); + header.put("alg", "HS256"); + header.put("typ", "JWT"); + + LocalDateTime now = Time.getNowDayTime(); + Map payload = new HashMap<>(); + payload.put("user", user); + payload.put("start", now.toString()); + payload.put("exp", now.plusDays(invalidDays).toString()); + payload.put("api_ver", "1"); +// payload.put("iss", machineId); + + return Jwts.builder() + .setHeader(header) + .setClaims(payload) + .signWith(key) + .compact(); + + // 这里生成token之后还是放在redis里边缓存一下吧 + // 但是考虑到各种因素就先不实现吧(懒) + } + + public boolean verifyToken(String token) { + try { + Jws jws = Jwts.parserBuilder() + .setSigningKey(key) + .build() + .parseClaimsJws(token); + + System.out.println(jws); + } catch (JwtException e) { + System.err.println("Error: token is wrong: " + e.getMessage()); + return false; + } + + return true; + } +} diff --git a/src/main/java/me/lensfrex/littlebusters/api/v1/utils/key/KeyManager.java b/src/main/java/me/lensfrex/littlebusters/api/v1/utils/key/KeyManager.java new file mode 100644 index 0000000..6fb192e --- /dev/null +++ b/src/main/java/me/lensfrex/littlebusters/api/v1/utils/key/KeyManager.java @@ -0,0 +1,4 @@ +package me.lensfrex.littlebusters.api.v1.utils.key; + +public class KeyManager { +} diff --git a/src/main/resources/mappers/DatabaseInitSqlMapper.xml b/src/main/resources/mappers/DatabaseInitSqlMapper.xml new file mode 100644 index 0000000..414e4ae --- /dev/null +++ b/src/main/resources/mappers/DatabaseInitSqlMapper.xml @@ -0,0 +1,50 @@ + + + + + + + CREATE TABLE `account_basic` ( + `uid` int(18) unsigned unique NOT NULL AUTO_INCREMENT COMMENT '用户id,1起,给人看的', + `uuid` varchar(36) unique NOT NULL COMMENT '用户uuid,给某些api用的,目前并没有这些api', + `user_name` varchar(32) unique NOT NULL COMMENT '用户名,可用于登录,最长不超过32位', + `passwd` varchar(60) NOT NULL COMMENT '用户密码,明文密码经前端两次sha256初步加密后再经过后端进行bcrypt加密存储(round 10)\r\nbcrypto长度不应超过72位', + `account_status` tinyint(1) unsigned NOT NULL DEFAULT 1 COMMENT '账户状态,分为 正常(0), 未激活(1), 已封禁(2)', + `account_type` tinyint(1) NOT NULL DEFAULT 0 COMMENT '账号类型', + `phone_number` varchar(11) DEFAULT NULL COMMENT '注册时使用的电话信息,目前暂不使用,可空,默认11位数字', + `deleted` tinyint(1) NOT NULL DEFAULT 0 COMMENT '账号是否注销', + `create_time` datetime NOT NULL DEFAULT current_timestamp() COMMENT '注册日期', + `edit_time` datetime NOT NULL DEFAULT current_timestamp() ON UPDATE current_timestamp() COMMENT '账号信息修改时间', + PRIMARY KEY (`uid`,`uuid`) USING BTREE, + UNIQUE KEY `user_name` (`user_name`), + UNIQUE KEY `uid` (`uid`), + UNIQUE KEY `uuid` (`uuid`) + ) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb4; + + CREATE TABLE `account_info` ( + `uid` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '用户id,1000000起', + `nick_name` varchar(16) NOT NULL COMMENT '用户昵称,长度限制为16个字', + `desc` varchar(255) DEFAULT NULL COMMENT '用户留言信息', + `sign` varchar(16) DEFAULT NULL COMMENT '用户的“个性签名”', + `birthday` date DEFAULT NULL COMMENT '用户生日', + `sex` int(1) DEFAULT NULL COMMENT '用户性别,null:未指定,1:男,2:女,其他值当未指定', + `email` varchar(255) DEFAULT NULL COMMENT '注册时使用的电子邮件,仅用于展示,不用做登录使用,可空', + `create_time` datetime NOT NULL COMMENT '用户信息创建时间', + `edit_time` datetime NOT NULL COMMENT '用户信息修改时间', + PRIMARY KEY (`uid`), + UNIQUE KEY `uid` (`uid`) USING BTREE + ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; + + CREATE TABLE `keys` ( + `id` int(11) NOT NULL, + `key` varchar(4028) NOT NULL, + `key_name` varchar(255) NOT NULL, + `create_time` datetime NOT NULL DEFAULT current_timestamp(), + `edit_time` datetime NOT NULL DEFAULT current_timestamp() ON UPDATE current_timestamp(), + `key_type` tinyint(1) NOT NULL, + PRIMARY KEY (`id`) + ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; + + \ No newline at end of file diff --git a/src/main/resources/mappers/KeySqlMapper.xml b/src/main/resources/mappers/KeySqlMapper.xml new file mode 100644 index 0000000..a660d75 --- /dev/null +++ b/src/main/resources/mappers/KeySqlMapper.xml @@ -0,0 +1,19 @@ + + + + + + + + + insert into `LittleBusters`.`keys` (`key_content`, `key_name`, `key_type`) + values (#{keyContent}, #{keyName}, #{keyType}); + + \ No newline at end of file diff --git a/src/main/resources/mappers/LoginSqlMapper.xml b/src/main/resources/mappers/LoginSqlMapper.xml index 1436b1b..d82f9d0 100644 --- a/src/main/resources/mappers/LoginSqlMapper.xml +++ b/src/main/resources/mappers/LoginSqlMapper.xml @@ -4,8 +4,8 @@ PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> - - select uid, uuid, passwd as password, deleted, account_status as accountStstus from `account_basic` where user_name = #{userName} diff --git a/src/main/resources/mappers/RegisterSqlMapper.xml b/src/main/resources/mappers/RegisterSqlMapper.xml index 6c309ad..689f8ff 100644 --- a/src/main/resources/mappers/RegisterSqlMapper.xml +++ b/src/main/resources/mappers/RegisterSqlMapper.xml @@ -4,7 +4,7 @@ PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> - + insert into `LittleBusters`.`account_basic` (`uuid`, `user_name`, `passwd`) values (#{uuid}, #{userName}, #{password}) diff --git a/src/main/resources/me/lensfrex/littlebusters/DefaultConfig.conf b/src/main/resources/me/lensfrex/littlebusters/DefaultConfig.conf new file mode 100644 index 0000000..d855150 --- /dev/null +++ b/src/main/resources/me/lensfrex/littlebusters/DefaultConfig.conf @@ -0,0 +1,8 @@ +# 数据库的类型,目前仅支持mysql和mariadb两种sql服务器 +database.dbType = "mariadb" +database.url = "jdbc:mariadb://localhost:3386/LittleBusters?characterEncoding=utf-8" +database.userName = "root" +database.password = "321654mid" + +JWT.signAlgo = "HS256" +JWT.secretKey = "asdifusaydiuasdczxcvmnbvamhdfgasjdhfuweygfiwqueygf"