diff --git a/pom.xml b/pom.xml
index 72cca5b..5c395b4 100644
--- a/pom.xml
+++ b/pom.xml
@@ -144,6 +144,10 @@
1.0.0.Final
+ org.hibernate
+ hibernate-envers
+ 5.0.3.Final
+
de.svenkubiak
jBCrypt
0.4
diff --git a/src/main/java/love/sola/netsupport/api/Authorize.java b/src/main/java/love/sola/netsupport/api/Authorize.java
index e5ea65c..4fca2b4 100644
--- a/src/main/java/love/sola/netsupport/api/Authorize.java
+++ b/src/main/java/love/sola/netsupport/api/Authorize.java
@@ -62,7 +62,7 @@ public class Authorize extends HttpServlet {
l = System.currentTimeMillis();
}
- if (!Checker.nonNull(c, l)) {
+ if (Checker.hasNull(c, l)) {
return new Response(Response.ResponseCode.AUTHORIZE_FAILED);
}
if (l < System.currentTimeMillis() - Settings.I.User_Command_Timeout * 1000) {
diff --git a/src/main/java/love/sola/netsupport/api/TicketQuery.java b/src/main/java/love/sola/netsupport/api/TicketQuery.java
index 05cf35e..9cbc024 100644
--- a/src/main/java/love/sola/netsupport/api/TicketQuery.java
+++ b/src/main/java/love/sola/netsupport/api/TicketQuery.java
@@ -28,7 +28,7 @@ import java.io.PrintWriter;
* Don't modify this source without my agreement
* ***********************************************
*/
-@WebServlet(name = "QueryTicket", urlPatterns = "/api/ticketquery", loadOnStartup = 24)
+@WebServlet(name = "TicketQuery", urlPatterns = "/api/ticketquery", loadOnStartup = 24)
public class TicketQuery extends HttpServlet {
private Gson gson = SQLCore.gson;
diff --git a/src/main/java/love/sola/netsupport/api/admin/Login.java b/src/main/java/love/sola/netsupport/api/admin/Login.java
index 38234a6..62ec7b6 100644
--- a/src/main/java/love/sola/netsupport/api/admin/Login.java
+++ b/src/main/java/love/sola/netsupport/api/admin/Login.java
@@ -49,7 +49,7 @@ public class Login extends HttpServlet {
String wechat = request.getParameter("wechat");
String opId = request.getParameter("op");
String password = request.getParameter("pass");
- if (Checker.nonNull(wechat, opId, password)) return new Response(Response.ResponseCode.PARAMETER_REQUIRED);
+ if (Checker.hasNull(wechat, opId, password)) return new Response(Response.ResponseCode.PARAMETER_REQUIRED);
try (Session s = SQLCore.sf.openSession()) {
Operator operator = s.get(Operator.class, Integer.parseInt(opId));
@@ -63,7 +63,7 @@ public class Login extends HttpServlet {
HttpSession httpSession = request.getSession(true);
httpSession.setAttribute("wechat", wechat);
httpSession.setAttribute("operator", operator);
- return new Response(Response.ResponseCode.OK);
+ return new Response(Response.ResponseCode.OK, operator);
} catch (NumberFormatException e) {
return new Response(Response.ResponseCode.ILLEGAL_PARAMETER);
} catch (HibernateException e) {
diff --git a/src/main/java/love/sola/netsupport/api/admin/TicketQuery.java b/src/main/java/love/sola/netsupport/api/admin/TicketQuery.java
new file mode 100644
index 0000000..8819791
--- /dev/null
+++ b/src/main/java/love/sola/netsupport/api/admin/TicketQuery.java
@@ -0,0 +1,10 @@
+package love.sola.netsupport.api.admin;
+
+/**
+ * ***********************************************
+ * Created by Sola on 2015/12/13.
+ * Don't modify this source without my agreement
+ * ***********************************************
+ */
+public class TicketQuery {
+}
diff --git a/src/main/java/love/sola/netsupport/api/admin/TicketUpdate.java b/src/main/java/love/sola/netsupport/api/admin/TicketUpdate.java
new file mode 100644
index 0000000..7bcb6ac
--- /dev/null
+++ b/src/main/java/love/sola/netsupport/api/admin/TicketUpdate.java
@@ -0,0 +1,82 @@
+package love.sola.netsupport.api.admin;
+
+import com.google.gson.Gson;
+import love.sola.netsupport.api.Response;
+import love.sola.netsupport.pojo.Operator;
+import love.sola.netsupport.pojo.Ticket;
+import love.sola.netsupport.sql.SQLCore;
+import love.sola.netsupport.util.Checker;
+import love.sola.netsupport.util.ParseUtil;
+import org.hibernate.HibernateException;
+import org.hibernate.Session;
+
+import javax.servlet.ServletException;
+import javax.servlet.annotation.WebServlet;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.servlet.http.HttpSession;
+import java.io.IOException;
+import java.io.PrintWriter;
+
+/**
+ * ***********************************************
+ * Created by Sola on 2015/12/13.
+ * Don't modify this source without my agreement
+ * ***********************************************
+ */
+@WebServlet(name = "TicketUpdate", urlPatterns = "/api/ticketupdate", loadOnStartup = 32)
+public class TicketUpdate extends HttpServlet {
+
+ private Gson gson = SQLCore.gson;
+
+ protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
+ doGet(request, response);
+ }
+
+ @SuppressWarnings("Duplicates")
+ protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
+ request.setCharacterEncoding("utf-8");
+ response.setCharacterEncoding("utf-8");
+ response.addHeader("Content-type", "text/json;charset=utf-8");
+ PrintWriter out = response.getWriter();
+ String json = gson.toJson(update(request));
+ out.println(ParseUtil.parseJsonP(request, json));
+ out.close();
+ }
+
+ private Response update(HttpServletRequest request) {
+ String ticket = request.getParameter("ticket");
+ String remark = request.getParameter("remark");
+ String status = request.getParameter("status");
+ if (Checker.hasNull(ticket, remark, status)) return new Response(Response.ResponseCode.PARAMETER_REQUIRED);
+
+ try (Session s = SQLCore.sf.openSession()) {
+ HttpSession httpSession = request.getSession(false);
+ if (!Checker.operator(httpSession)) {
+ return new Response(Response.ResponseCode.UNAUTHORIZED);
+ }
+ Operator op = (Operator) httpSession.getAttribute("operator");
+ Ticket t = s.get(Ticket.class, Integer.parseInt(ticket));
+ if (t == null) {
+ return new Response(Response.ResponseCode.TICKET_NOT_FOUND);
+ }
+ t.setOperator(op);
+ t.setRemark(remark);
+ t.setStatus(Integer.parseInt(status));
+ s.beginTransaction();
+ s.update(t);
+ s.getTransaction().commit();
+ return new Response(Response.ResponseCode.OK, t);
+ } catch (NumberFormatException e) {
+ return new Response(Response.ResponseCode.ILLEGAL_PARAMETER);
+ } catch (HibernateException e) {
+ e.printStackTrace();
+ return new Response(Response.ResponseCode.DATABASE_ERROR, e);
+ } catch (Exception e) {
+ e.printStackTrace();
+ return new Response(Response.ResponseCode.INTERNAL_ERROR, e);
+ }
+ }
+
+}
diff --git a/src/main/java/love/sola/netsupport/pojo/Ticket.java b/src/main/java/love/sola/netsupport/pojo/Ticket.java
index be840a9..931255f 100644
--- a/src/main/java/love/sola/netsupport/pojo/Ticket.java
+++ b/src/main/java/love/sola/netsupport/pojo/Ticket.java
@@ -4,6 +4,8 @@ import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import love.sola.netsupport.sql.TableTicket;
+import org.hibernate.envers.Audited;
+import org.hibernate.envers.RelationTargetAuditMode;
import javax.persistence.*;
import java.util.Date;
@@ -19,6 +21,7 @@ import java.util.Date;
@NoArgsConstructor
@Entity
@Table(name = "tickets")
+@Audited(targetAuditMode = RelationTargetAuditMode.NOT_AUDITED)
public class Ticket {
public static final String PROPERTY_USER = "user";
diff --git a/src/main/java/love/sola/netsupport/util/AESUtil.java b/src/main/java/love/sola/netsupport/util/AESUtil.java
deleted file mode 100644
index 856e217..0000000
--- a/src/main/java/love/sola/netsupport/util/AESUtil.java
+++ /dev/null
@@ -1,51 +0,0 @@
-package love.sola.netsupport.util;
-
-import org.apache.commons.codec.binary.Base64;
-
-import javax.crypto.Cipher;
-import javax.crypto.spec.IvParameterSpec;
-import javax.crypto.spec.SecretKeySpec;
-import java.nio.charset.StandardCharsets;
-
-public class AESUtil {
-
- public static final byte[] initVector = "RandomInitVector".getBytes(StandardCharsets.UTF_8);
- public static final byte[] key = "$bitch@sola.love".getBytes(StandardCharsets.UTF_8);
-
- public static String encrypt(String value) {
- try {
- IvParameterSpec iv = new IvParameterSpec(initVector);
- SecretKeySpec skeySpec = new SecretKeySpec(key, "AES");
-
- Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING");
- cipher.init(Cipher.ENCRYPT_MODE, skeySpec, iv);
-
- byte[] encrypted = cipher.doFinal(value.getBytes());
-
- return Base64.encodeBase64String(encrypted);
- } catch (Exception ex) {
- ex.printStackTrace();
- }
-
- return null;
- }
-
- public static String decrypt(String encrypted) {
- try {
- IvParameterSpec iv = new IvParameterSpec(initVector);
- SecretKeySpec skeySpec = new SecretKeySpec(key, "AES");
-
- Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING");
- cipher.init(Cipher.DECRYPT_MODE, skeySpec, iv);
-
- byte[] original = cipher.doFinal(Base64.decodeBase64(encrypted));
-
- return new String(original);
- } catch (Exception ex) {
- ex.printStackTrace();
- }
-
- return null;
- }
-
-}
\ No newline at end of file
diff --git a/src/main/java/love/sola/netsupport/util/Checker.java b/src/main/java/love/sola/netsupport/util/Checker.java
index 1f6b4ad..c947cb8 100644
--- a/src/main/java/love/sola/netsupport/util/Checker.java
+++ b/src/main/java/love/sola/netsupport/util/Checker.java
@@ -12,13 +12,17 @@ import javax.servlet.http.HttpSession;
*/
public class Checker {
- public static boolean nonNull(Object... v) {
- for (Object o : v) if (o == null) return false;
- return true;
+ public static boolean hasNull(Object... v) {
+ for (Object o : v) if (o == null) return true;
+ return false;
}
public static boolean authorized(HttpSession s, Command c) {
return s != null && s.getAttribute("authorized") == c;
}
+ public static boolean operator(HttpSession s) {
+ return s != null && s.getAttribute("operator") != null;
+ }
+
}
diff --git a/src/main/java/love/sola/netsupport/util/Crypto.java b/src/main/java/love/sola/netsupport/util/Crypto.java
index 024e8c4..6a5fc13 100644
--- a/src/main/java/love/sola/netsupport/util/Crypto.java
+++ b/src/main/java/love/sola/netsupport/util/Crypto.java
@@ -15,7 +15,7 @@ public class Crypto {
}
public static boolean check(String plain, String hash) {
- return BCrypt.checkpw(AESUtil.decrypt(plain), hash);
+ return BCrypt.checkpw(RSAUtil.decrypt(plain), hash);
}
}
diff --git a/src/main/java/love/sola/netsupport/util/ParseUtil.java b/src/main/java/love/sola/netsupport/util/ParseUtil.java
index 1508ff7..55aba13 100644
--- a/src/main/java/love/sola/netsupport/util/ParseUtil.java
+++ b/src/main/java/love/sola/netsupport/util/ParseUtil.java
@@ -23,11 +23,9 @@ public class ParseUtil {
.append(lang("Ticket_Info_Id")).append(t.getId()).append("\n")
.append(lang("Ticket_Info_Desc")).append(t.getDescription()).append("\n")
.append(lang("Ticket_Info_Submit_Time")).append(dateFormat.format(t.getSubmitTime())).append("\n");
- if (t.getUpdateTime() != null) {
- sb.append(lang("Ticket_Info_Operator")).append(t.getOperator().getId()).append("\n");
- sb.append(lang("Ticket_Info_Remark")).append(t.getRemark()).append("\n");
- sb.append(lang("Ticket_Info_Update_Time")).append(dateFormat.format(t.getUpdateTime())).append("\n");
- }
+ if (t.getOperator() != null) sb.append(lang("Ticket_Info_Operator")).append(t.getOperator().getId()).append("\n");
+ if (t.getRemark() != null) sb.append(lang("Ticket_Info_Remark")).append(t.getRemark()).append("\n");
+ if (t.getUpdateTime() != null) sb.append(lang("Ticket_Info_Update_Time")).append(dateFormat.format(t.getUpdateTime())).append("\n");
sb.append(lang("Ticket_Info_Status")).append(Status.getLocalized(t.getStatus()));
return sb.toString();
}
diff --git a/src/main/java/love/sola/netsupport/util/RSAUtil.java b/src/main/java/love/sola/netsupport/util/RSAUtil.java
new file mode 100644
index 0000000..25ce40b
--- /dev/null
+++ b/src/main/java/love/sola/netsupport/util/RSAUtil.java
@@ -0,0 +1,61 @@
+package love.sola.netsupport.util;
+
+import org.apache.commons.codec.binary.Base64;
+
+import javax.crypto.Cipher;
+import java.nio.charset.StandardCharsets;
+import java.security.Key;
+import java.security.KeyPair;
+import java.security.KeyPairGenerator;
+
+public class RSAUtil {
+
+
+ public static Key publicKey;
+ public static Key privateKey;
+ public static String publicKey_s;
+ public static String privateKey_s;
+
+ static {
+ genKeyPair();
+ }
+
+ public static void genKeyPair() {
+ try {
+ KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA");
+ kpg.initialize(1024);
+ KeyPair kp = kpg.genKeyPair();
+ publicKey = kp.getPublic();
+ privateKey = kp.getPrivate();
+ publicKey_s = Base64.encodeBase64String(publicKey.getEncoded());
+ privateKey_s = Base64.encodeBase64String(privateKey.getEncoded());
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ public static String encrypt(String value) {
+ try {
+ Cipher cipher = Cipher.getInstance("RSA");
+ cipher.init(Cipher.ENCRYPT_MODE, publicKey);
+ byte[] encrypted = cipher.doFinal(value.getBytes(StandardCharsets.UTF_8));
+ return Base64.encodeBase64String(encrypted);
+ } catch (Exception ex) {
+ ex.printStackTrace();
+ }
+ return null;
+ }
+
+ public static String decrypt(String encrypted) {
+ try {
+ Cipher cipher = Cipher.getInstance("RSA");
+ cipher.init(Cipher.DECRYPT_MODE, privateKey);
+ byte[] original = cipher.doFinal(Base64.decodeBase64(encrypted));
+ return new String(original, StandardCharsets.UTF_8);
+ } catch (Exception ex) {
+ ex.printStackTrace();
+ }
+ return null;
+ }
+
+}
\ No newline at end of file
diff --git a/src/main/java/love/sola/netsupport/wechat/handler/LoginHandler.java b/src/main/java/love/sola/netsupport/wechat/handler/LoginHandler.java
index cd48f4d..c1f0280 100644
--- a/src/main/java/love/sola/netsupport/wechat/handler/LoginHandler.java
+++ b/src/main/java/love/sola/netsupport/wechat/handler/LoginHandler.java
@@ -1,6 +1,7 @@
package love.sola.netsupport.wechat.handler;
import love.sola.netsupport.sql.TableOperator;
+import love.sola.netsupport.util.RSAUtil;
import me.chanjar.weixin.common.exception.WxErrorException;
import me.chanjar.weixin.common.session.WxSessionManager;
import me.chanjar.weixin.mp.api.WxMpMessageHandler;
@@ -28,7 +29,7 @@ public class LoginHandler implements WxMpMessageHandler {
if (!TableOperator.has(wxMessage.getFromUserName())) {
return out.content(lang("Not_Operator")).build();
} else {
- return out.content(format("Operator_Login_Link", wxMessage.getFromUserName())).build();
+ return out.content(format("Operator_Login_Link", wxMessage.getFromUserName(), RSAUtil.publicKey_s)).build();
}
}
diff --git a/src/main/resources/lang.yml b/src/main/resources/lang.yml
index 5a27ec9..a2165ca 100644
--- a/src/main/resources/lang.yml
+++ b/src/main/resources/lang.yml
@@ -40,10 +40,10 @@ Not_Operator: '嘟嘟嘟……'
#URL
User_Register_Link: "您尚未进行微信绑定, 请点击这里进行微信绑定操作。"
-User_Query_Link: 'http://topaz.sinaapp.com/nm/v1/query.php?wechatid={0}'
+User_Query_Link: 'http://topaz.sinaapp.com/nm/v1/query.html?wechatid={0}'
User_Submit_Link: 'http://topaz.sinaapp.com/nm/v1/rrepair.html?wechatid={0}&name={1}&isp={2}&room={3}&block={4}&phone={5}'
Result_Page: 'http://topaz.sinaapp.com/nm/v1/result.html'
-Operator_Login_Link: 'CLICK HERE'
+Operator_Login_Link: 'CLICK HERE'
#Localized
#Status
diff --git a/src/test/java/love/sola/netsupport/wechat/TestEncrypt.java b/src/test/java/love/sola/netsupport/wechat/TestEncrypt.java
index e2682b0..5350044 100644
--- a/src/test/java/love/sola/netsupport/wechat/TestEncrypt.java
+++ b/src/test/java/love/sola/netsupport/wechat/TestEncrypt.java
@@ -1,6 +1,6 @@
package love.sola.netsupport.wechat;
-import love.sola.netsupport.util.AESUtil;
+import love.sola.netsupport.util.RSAUtil;
import org.junit.Test;
import org.mindrot.jbcrypt.BCrypt;
@@ -19,9 +19,9 @@ public class TestEncrypt {
}
@Test
- public void testAES() {
- assert "Hello World".equals(AESUtil.decrypt(AESUtil.encrypt("Hello World")));
- assert "Encrypt".equals(AESUtil.decrypt(AESUtil.encrypt("Encrypt")));
+ public void testRSA() {
+ assert "Hello World".equals(RSAUtil.decrypt(RSAUtil.encrypt("Hello World")));
+ assert "Encrypt".equals(RSAUtil.decrypt(RSAUtil.encrypt("Encrypt")));
}
}