48 Commits

Author SHA1 Message Date
Sola
9e77961666 Merge branch 'release/1.3' 2015-12-27 14:41:04 +08:00
Sola
78beb09ca6 update pom 2015-12-27 14:40:09 +08:00
Sola
caf83b3e70 change block 60,61 to 34,35 2015-12-27 14:37:37 +08:00
Sola
cc3c9d30be Flush cache & some refactors 2015-12-27 11:21:10 +08:00
Sola
710fa28ada fix 'duplicate association path' 2015-12-27 01:06:19 +08:00
Sola
633a3b184a fix 'could not resolve property' 2015-12-27 01:01:33 +08:00
Sola
9c2856e358 add function to query all unsolved 2015-12-27 00:55:07 +08:00
Sola
6483a39b63 fix BM_11 421 room doesn't exists 2015-12-26 17:17:37 +08:00
Sola
ccdffd01d7 add duplicated check for member sign 2015-12-26 15:55:47 +08:00
Sola
1e3a0754a4 fixed issue 'returned null for key' 2015-12-26 15:30:36 +08:00
Sola
1ce14b7d1a member sign 2015-12-26 15:04:44 +08:00
Sola
3e0c907655 improve - subscribe event pop up register links automatically 2015-12-26 00:39:15 +08:00
Sola
a506a7742f better langs 2015-12-23 18:33:20 +08:00
Sola
df0034f2ea refactors 2015-12-23 17:23:54 +08:00
Sola
940bcaad8c update pom 2015-12-23 02:26:29 +08:00
Sola
4ddc2281b4 Merge branch 'feature/ticketpush' into develop 2015-12-23 02:25:59 +08:00
Sola
23f98e1951 ticket push 2015-12-23 02:25:32 +08:00
Sola
25ae59c5e0 Merge branch 'release/1.2' into develop 2015-12-23 02:24:04 +08:00
Sola
e929c69fdb Merge branch 'release/1.2' 2015-12-23 02:23:28 +08:00
Sola
d1956bae82 update pom 2015-12-23 02:21:41 +08:00
Sola
813a4a2b37 update lang 2015-12-23 02:21:16 +08:00
Sola
8f8e9cd620 update lang 2015-12-22 18:14:16 +08:00
Sola
a6cee3a0a6 fix escape issue 2015-12-22 17:56:35 +08:00
Sola
f883c7dbf8 fix aes key 2015-12-22 17:26:37 +08:00
Sola
a7393ea772 update lang 2015-12-22 17:12:01 +08:00
Sola
29cbd4ae86 pre-release 2015-12-22 16:53:22 +08:00
Sola
bad7bdbe45 fix issue that date isn't updated 2015-12-22 16:25:02 +08:00
Sola
0e14911650 add check token api 2015-12-22 01:24:11 +08:00
Sola
37691b71c1 add setpass 2015-12-21 02:30:57 +08:00
Sola
5d4a420a7b fix end date incorrect 2015-12-20 11:56:20 +08:00
Sola
3c4b9bd80a fix java.util.Date cannot be cast to java.lang.Long 2015-12-19 18:58:39 +08:00
Sola
183b3ec8d2 Merge branch 'feature/ticketlog' into develop 2015-12-19 18:44:22 +08:00
Sola
95278ccbb9 ticketlog 2015-12-19 18:41:05 +08:00
Sola
c973f0c63a fix ticket track order 2015-12-19 15:31:35 +08:00
Sola
66c04d42f1 update modify parameter 2015-12-18 20:55:33 +08:00
Sola
b4065be9e1 Merge branch 'develop'
* develop:
  update command modify
2015-12-18 16:31:14 +08:00
Sola
288ac607c8 update command modify 2015-12-18 16:25:40 +08:00
Sola
89f3c5cbca Merge branch 'develop'
* develop:
  update profile link
2015-12-18 16:13:43 +08:00
Sola
6a465ba1e5 update profile link 2015-12-18 16:11:43 +08:00
Sola
05ea96bd9b Merge branch 'develop' 2015-12-18 15:00:16 +08:00
Sola
d85408bcdd Merge branch 'feature/tickettracker' into develop 2015-12-18 14:59:59 +08:00
Sola
def90117e2 tickettracker feature 2015-12-18 14:58:23 +08:00
Sola
a3c36d265c Merge branch 'master' into develop
* master:
  solve 'manage may never expire session' issue
2015-12-18 03:22:50 +08:00
Sola
5ef112711c solve 'manage may never expire session' issue 2015-12-18 03:22:24 +08:00
Sola
b309876428 Merge branch 'develop'
* develop:
  add more information to profile edit
2015-12-18 03:12:40 +08:00
Sola
58381fa3e1 add more information to profile edit 2015-12-18 03:12:20 +08:00
Sola
16135a8158 Merge branch 'develop'
* develop:
  fix incorrect command while submit
2015-12-18 02:49:08 +08:00
Sola
485e80ef5b fix incorrect command while submit 2015-12-18 02:48:40 +08:00
39 changed files with 879 additions and 177 deletions

View File

@@ -4,7 +4,7 @@
<name>WechatTicketSystem</name>
<groupId>love.sola.netsupport</groupId>
<artifactId>WechatTicketSystem</artifactId>
<version>1.1-SNAPSHOT</version>
<version>1.3</version>
<packaging>war</packaging>
<properties>

View File

@@ -0,0 +1,66 @@
package love.sola.netsupport.api;
import com.google.gson.Gson;
import love.sola.netsupport.enums.Attribute;
import love.sola.netsupport.sql.SQLCore;
import love.sola.netsupport.util.ParseUtil;
import love.sola.netsupport.wechat.WechatSession;
import me.chanjar.weixin.common.session.WxSession;
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 java.io.IOException;
import java.io.PrintWriter;
import java.util.HashMap;
import java.util.Map;
/**
* ***********************************************
* Created by Sola on 2015/12/21.
* Don't modify this source without my agreement
* ***********************************************
*/
@WebServlet(name = "CheckSession", urlPatterns = "/api/checksession", loadOnStartup = 11)
public class CheckSession extends HttpServlet {
private Gson gson = SQLCore.gson;
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setCharacterEncoding("utf-8");
response.setCharacterEncoding("utf-8");
response.addHeader("Content-type", "application/json;charset=utf-8");
PrintWriter out = response.getWriter();
String json = gson.toJson(check(request));
out.println(ParseUtil.parseJsonP(request, json));
out.close();
}
private Response check(HttpServletRequest request) {
String t = request.getParameter("token");
if (t == null || t.isEmpty()) return new Response(Response.ResponseCode.UNAUTHORIZED);
WxSession s = WechatSession.get(t, false);
if (s == null) return new Response(Response.ResponseCode.UNAUTHORIZED);
String more = request.getParameter("more");
Map<String, Object> result = new HashMap<>();
result.put(Attribute.AUTHORIZED, s.getAttribute(Attribute.AUTHORIZED));
if (more != null){
switch (more) {
case "1":
result.put(Attribute.USER, s.getAttribute(Attribute.USER));
result.put(Attribute.OPERATOR, s.getAttribute(Attribute.OPERATOR));
break;
}
}
return new Response(Response.ResponseCode.OK, result);
}
}

View File

@@ -1,7 +1,6 @@
package love.sola.netsupport.api.admin;
package love.sola.netsupport.api;
import com.google.gson.Gson;
import love.sola.netsupport.api.Response;
import love.sola.netsupport.enums.Access;
import love.sola.netsupport.enums.Attribute;
import love.sola.netsupport.pojo.Operator;
@@ -31,7 +30,7 @@ import java.io.PrintWriter;
* ***********************************************
*/
@WebServlet(name = "Login", urlPatterns = "/api/admin/login", loadOnStartup = 31)
@WebServlet(name = "Login", urlPatterns = "/api/admin/login", loadOnStartup = 12)
public class Login extends HttpServlet {
private Gson gson = SQLCore.gson;

View File

@@ -36,14 +36,12 @@ public class Response {
PARAMETER_REQUIRED(-1),
ILLEGAL_PARAMETER(-2),
REQUEST_FAILED(-3),
AUTHORIZE_FAILED(-9),
LENGTH_LIMIT_EXCEEDED(-4),
USER_NOT_FOUND(-11),
TICKET_NOT_FOUND(-12),
OPERATOR_NOT_FOUND(-13),
UNAUTHORIZED(-20),
REQUEST_EXPIRED(-21),
WRONG_PASSWORD(-22),
INCORRECT_WECHAT(-23),
PERMISSION_DENIED(-24),
INTERNAL_ERROR(-90),
DATABASE_ERROR(-91),

View File

@@ -1,4 +1,4 @@
package love.sola.netsupport.api.admin.root;
package love.sola.netsupport.api.manager;
import com.google.gson.Gson;
import love.sola.netsupport.api.Response;
@@ -28,7 +28,7 @@ import java.io.PrintWriter;
* Don't modify this source without my agreement
* ***********************************************
*/
@WebServlet(name = "GetUser",urlPatterns = "/api/admin/getuser",loadOnStartup = 42)
@WebServlet(name = "GetUser",urlPatterns = "/api/admin/getuser",loadOnStartup = 41)
public class GetUser extends HttpServlet {
private Gson gson = SQLCore.gson;
@@ -59,7 +59,7 @@ public class GetUser extends HttpServlet {
return new Response(Response.ResponseCode.UNAUTHORIZED);
}
Operator op = (Operator) session.getAttribute(Attribute.OPERATOR);
if (op.getAccess() != Access.ROOT) {
if (op.getAccess() > Access.LEADER) {
return new Response(Response.ResponseCode.PERMISSION_DENIED);
}

View File

@@ -0,0 +1,93 @@
package love.sola.netsupport.api.manager;
import com.google.gson.Gson;
import love.sola.netsupport.api.Response;
import love.sola.netsupport.config.Settings;
import love.sola.netsupport.enums.Access;
import love.sola.netsupport.enums.Attribute;
import love.sola.netsupport.enums.Status;
import love.sola.netsupport.pojo.Operator;
import love.sola.netsupport.pojo.Ticket;
import love.sola.netsupport.pojo.User;
import love.sola.netsupport.sql.SQLCore;
import love.sola.netsupport.util.Checker;
import love.sola.netsupport.util.ParseUtil;
import love.sola.netsupport.wechat.Command;
import me.chanjar.weixin.common.session.WxSession;
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 java.io.IOException;
import java.io.PrintWriter;
/**
* ***********************************************
* Created by Sola on 2015/12/22.
* Don't modify this source without my agreement
* ***********************************************
*/
@WebServlet(name = "TicketPush",urlPatterns = "/api/admin/ticketpush",loadOnStartup = 42)
public class TicketPush extends HttpServlet{
private Gson gson = SQLCore.gson;
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setCharacterEncoding("utf-8");
response.setCharacterEncoding("utf-8");
response.addHeader("Content-type", "application/json;charset=utf-8");
PrintWriter out = response.getWriter();
String json = gson.toJson(push(request));
out.println(ParseUtil.parseJsonP(request, json));
out.close();
}
private Response push(HttpServletRequest request) {
String uid = request.getParameter("uid");
String desc = request.getParameter("desc");
if (Checker.hasNull(uid, desc)) {
return new Response(Response.ResponseCode.PARAMETER_REQUIRED);
}
if (desc.length() > Settings.MAX_DESC_LENGTH) {
return new Response(Response.ResponseCode.LENGTH_LIMIT_EXCEEDED);
}
WxSession session = Checker.isAuthorized(request, Command.LOGIN);
if (session == null) {
return new Response(Response.ResponseCode.UNAUTHORIZED);
}
Operator op = (Operator) session.getAttribute(Attribute.OPERATOR);
if (op.getAccess() > Access.LEADER) {
return new Response(Response.ResponseCode.PERMISSION_DENIED);
}
try (Session s = SQLCore.sf.openSession()) {
s.beginTransaction();
User u = s.get(User.class, Long.parseLong(uid));
if (u == null) {
return new Response(Response.ResponseCode.USER_NOT_FOUND);
}
Ticket t = new Ticket(null, u, desc, null, "Pushed By Admin", null, op, Status.UNCHECKED);
s.save(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.getMessage());
} catch (Exception e) {
e.printStackTrace();
return new Response(Response.ResponseCode.INTERNAL_ERROR, e.getMessage());
}
}
}

View File

@@ -1,10 +1,8 @@
package love.sola.netsupport.api.admin.root;
package love.sola.netsupport.api.root;
import com.google.gson.Gson;
import love.sola.netsupport.enums.Access;
import love.sola.netsupport.enums.Attribute;
import love.sola.netsupport.pojo.Operator;
import love.sola.netsupport.sql.SQLCore;
import love.sola.netsupport.util.Checker;
import love.sola.netsupport.wechat.Command;
import love.sola.netsupport.wechat.WechatSession;
@@ -27,25 +25,24 @@ import java.util.Enumeration;
* ***********************************************
*/
@WebServlet(name = "Dashboard", urlPatterns = "/api/admin/dashboard", loadOnStartup = 41)
@WebServlet(name = "Dashboard", urlPatterns = "/api/root/dashboard", loadOnStartup = 51)
public class DashBoard 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/plain;charset=utf-8");
PrintWriter out = response.getWriter();
print(request, out);
process(request, out);
out.close();
}
private void print(HttpServletRequest request, PrintWriter out) {
private void process(HttpServletRequest request, PrintWriter out) {
WxSession session = Checker.isAuthorized(request, Command.LOGIN);
if (session == null) {
out.println("Unauthorized");

View File

@@ -0,0 +1,59 @@
package love.sola.netsupport.api.root;
import love.sola.netsupport.enums.Access;
import love.sola.netsupport.enums.Attribute;
import love.sola.netsupport.pojo.Operator;
import love.sola.netsupport.sql.TableUser;
import love.sola.netsupport.util.Checker;
import love.sola.netsupport.wechat.Command;
import me.chanjar.weixin.common.session.WxSession;
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 java.io.IOException;
import java.io.PrintWriter;
/**
* ***********************************************
* Created by Sola on 2015/12/15.
* Don't modify this source without my agreement
* ***********************************************
*/
@WebServlet(name = "FlushCache", urlPatterns = "/api/root/flushcache", loadOnStartup = 52)
public class FlushCache extends HttpServlet {
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/plain;charset=utf-8");
PrintWriter out = response.getWriter();
process(request, out);
out.close();
}
private void process(HttpServletRequest request, PrintWriter out) {
WxSession session = Checker.isAuthorized(request, Command.LOGIN);
if (session == null) {
out.println("Unauthorized");
return;
}
Operator op = (Operator) session.getAttribute(Attribute.OPERATOR);
if (op.getAccess() != Access.ROOT) {
out.println("Unauthorized");
return;
}
TableUser.flushCache();
out.println("Flushed wechat cache");
}
}

View File

@@ -0,0 +1,80 @@
package love.sola.netsupport.api.root;
import love.sola.netsupport.enums.Access;
import love.sola.netsupport.enums.Attribute;
import love.sola.netsupport.pojo.Operator;
import love.sola.netsupport.sql.SQLCore;
import love.sola.netsupport.util.Checker;
import love.sola.netsupport.util.Crypto;
import love.sola.netsupport.wechat.Command;
import me.chanjar.weixin.common.session.WxSession;
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 java.io.IOException;
import java.io.PrintWriter;
/**
* ***********************************************
* Created by Sola on 2015/12/20.
* Don't modify this source without my agreement
* ***********************************************
*/
@WebServlet(name = "SetPassword",urlPatterns = "/api/root/setpass",loadOnStartup = 53)
public class SetPassword extends HttpServlet{
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/plain;charset=utf-8");
PrintWriter out = response.getWriter();
process(request, out);
out.close();
}
private void process(HttpServletRequest request, PrintWriter out) {
WxSession session = Checker.isAuthorized(request, Command.LOGIN);
if (session == null) {
out.println("Unauthorized");
return;
}
Operator op = (Operator) session.getAttribute(Attribute.OPERATOR);
if (op.getAccess() != Access.ROOT) {
out.println("Unauthorized");
return;
}
String id = request.getParameter("id");
String pass = request.getParameter("pass");
if (pass == null || pass.length() < 8) {
out.println("Invalid pass");
return;
}
try (Session s = SQLCore.sf.openSession()) {
s.beginTransaction();
op = s.get(Operator.class, Integer.parseInt(id));
if (op == null) {
out.println("Invalid user");
return;
}
op.setPassword(Crypto.hash(pass));
s.update(op);
s.getTransaction().commit();
out.println("Operation success");
} catch (NumberFormatException e) {
out.println("Invalid id");
return;
}
}
}

View File

@@ -0,0 +1,98 @@
package love.sola.netsupport.api.stuff;
import com.google.gson.Gson;
import love.sola.netsupport.api.Response;
import love.sola.netsupport.pojo.Ticket;
import love.sola.netsupport.sql.SQLCore;
import love.sola.netsupport.sql.TableTicket;
import love.sola.netsupport.util.Checker;
import love.sola.netsupport.util.ParseUtil;
import love.sola.netsupport.wechat.Command;
import me.chanjar.weixin.common.session.WxSession;
import org.apache.commons.lang3.time.DateUtils;
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.envers.AuditReader;
import org.hibernate.envers.query.AuditEntity;
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 java.io.IOException;
import java.io.PrintWriter;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
/**
* ***********************************************
* Created by Sola on 2015/12/18.
* Don't modify this source without my agreement
* ***********************************************
*/
@WebServlet(name = "TicketLog", urlPatterns = "/api/admin/ticketlog", loadOnStartup = 35)
public class TicketLog extends HttpServlet {
public static SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMdd");
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", "application/json;charset=utf-8");
PrintWriter out = response.getWriter();
String json = gson.toJson(query(request));
out.println(ParseUtil.parseJsonP(request, json));
out.close();
}
private Response query(HttpServletRequest request) {
WxSession session = Checker.isAuthorized(request, Command.LOGIN);
if (session == null) {
return new Response(Response.ResponseCode.UNAUTHORIZED);
}
int first;
int limit;
Date start;
Date end;
try {
first = request.getParameter("first") == null ? 0 : Integer.parseInt(request.getParameter("first"));
limit = request.getParameter("limit") == null ? 20 : Integer.parseInt(request.getParameter("limit"));
start = request.getParameter("start") == null ? getToday() : dateFormat.parse(request.getParameter("start"));
end = request.getParameter("end") == null ? getToday() : dateFormat.parse(request.getParameter("end"));
end = DateUtils.addDays(end, 1);
} catch (ParseException | NumberFormatException e) {
return new Response(Response.ResponseCode.ILLEGAL_PARAMETER);
}
try (Session s = SQLCore.sf.openSession()) {
AuditReader reader = TableTicket.getAuditReader(s);
Object obj = reader.createQuery()
.forRevisionsOfEntity(Ticket.class, false, true)
.addOrder(AuditEntity.revisionNumber().asc())
.add(AuditEntity.revisionProperty("timestamp").between(start.getTime(), end.getTime()))
.setFirstResult(first)
.setMaxResults(limit)
.getResultList();
return new Response(Response.ResponseCode.OK, obj);
} catch (HibernateException e) {
e.printStackTrace();
return new Response(Response.ResponseCode.DATABASE_ERROR, e.getMessage());
} catch (Exception e) {
e.printStackTrace();
return new Response(Response.ResponseCode.INTERNAL_ERROR, e.getMessage());
}
}
private static Date getToday() {
return DateUtils.truncate(new Date(), Calendar.DAY_OF_MONTH);
}
}

View File

@@ -1,4 +1,4 @@
package love.sola.netsupport.api.admin;
package love.sola.netsupport.api.stuff;
import com.google.gson.Gson;
import love.sola.netsupport.api.Response;
@@ -28,7 +28,7 @@ import java.util.List;
* Don't modify this source without my agreement
* ***********************************************
*/
@WebServlet(name = "TicketLookup", urlPatterns = "/api/admin/ticketlookup", loadOnStartup = 24)
@WebServlet(name = "TicketLookup", urlPatterns = "/api/admin/ticketlookup", loadOnStartup = 33)
public class TicketLookup extends HttpServlet {
private Gson gson = SQLCore.gson;

View File

@@ -0,0 +1,70 @@
package love.sola.netsupport.api.stuff;
import com.google.gson.Gson;
import love.sola.netsupport.api.Response;
import love.sola.netsupport.sql.SQLCore;
import love.sola.netsupport.sql.TableTicket;
import love.sola.netsupport.util.Checker;
import love.sola.netsupport.util.ParseUtil;
import love.sola.netsupport.wechat.Command;
import me.chanjar.weixin.common.session.WxSession;
import org.hibernate.HibernateException;
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 java.io.IOException;
import java.io.PrintWriter;
/**
* ***********************************************
* Created by Sola on 2015/12/18.
* Don't modify this source without my agreement
* ***********************************************
*/
@WebServlet(name = "TicketTrack", urlPatterns = "/api/admin/tickettrack", loadOnStartup = 34)
public class TicketTrack extends HttpServlet{
private Gson gson = SQLCore.gson;
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setCharacterEncoding("utf-8");
response.setCharacterEncoding("utf-8");
response.addHeader("Content-type", "application/json;charset=utf-8");
PrintWriter out = response.getWriter();
String json = gson.toJson(track(request));
out.println(ParseUtil.parseJsonP(request, json));
out.close();
}
private Response track(HttpServletRequest request) {
String tid = request.getParameter("id");
if (tid == null) {
return new Response(Response.ResponseCode.PARAMETER_REQUIRED);
}
WxSession session = Checker.isAuthorized(request, Command.LOGIN);
if (session == null) {
return new Response(Response.ResponseCode.UNAUTHORIZED);
}
try {
return new Response(Response.ResponseCode.OK, TableTicket.track(Integer.parseInt(tid)));
} catch (NumberFormatException e) {
return new Response(Response.ResponseCode.ILLEGAL_PARAMETER);
} catch (HibernateException e) {
e.printStackTrace();
return new Response(Response.ResponseCode.DATABASE_ERROR, e.getMessage());
} catch (Exception e) {
e.printStackTrace();
return new Response(Response.ResponseCode.INTERNAL_ERROR, e.getMessage());
}
}
}

View File

@@ -1,4 +1,4 @@
package love.sola.netsupport.api.admin;
package love.sola.netsupport.api.stuff;
import com.google.gson.Gson;
import love.sola.netsupport.api.Response;
@@ -20,6 +20,7 @@ import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Date;
/**
* ***********************************************
@@ -64,6 +65,7 @@ public class TicketUpdate extends HttpServlet {
t.setOperator(op);
t.setRemark(remark);
t.setStatus(Integer.parseInt(status));
t.setUpdateTime(new Date());
s.beginTransaction();
s.update(t);
s.getTransaction().commit();

View File

@@ -1,6 +1,7 @@
package love.sola.netsupport.api;
package love.sola.netsupport.api.user;
import com.google.gson.Gson;
import love.sola.netsupport.api.Response;
import love.sola.netsupport.enums.Attribute;
import love.sola.netsupport.enums.ISP;
import love.sola.netsupport.pojo.User;
@@ -60,17 +61,18 @@ public class ProfileModify extends HttpServlet {
int block = checkBlock(request.getParameter("block"));
int room = checkRoom(request.getParameter("room"), block);
long phone = checkPhoneNumber(request.getParameter("phone"));
if (netAccount != null) {
if (room == -1)
return new Response(Response.ResponseCode.REQUEST_FAILED, "Invalid_Room");
if (phone == -1)
return new Response(Response.ResponseCode.REQUEST_FAILED, "Invalid_Phone_Number");
if (netAccount == null)
return new Response(Response.ResponseCode.REQUEST_FAILED, "Invalid_Account");
u.setIsp(isp);
u.setNetAccount(netAccount);
}
if (room != -1) {
u.setBlock(block);
u.setRoom(room);
}
if (phone != -1) {
u.setPhone(phone);
}
try {
TableUser.update(u);
} catch (ConstraintViolationException e) {

View File

@@ -1,6 +1,7 @@
package love.sola.netsupport.api;
package love.sola.netsupport.api.user;
import com.google.gson.Gson;
import love.sola.netsupport.api.Response;
import love.sola.netsupport.enums.Attribute;
import love.sola.netsupport.enums.ISP;
import love.sola.netsupport.pojo.User;

View File

@@ -1,6 +1,7 @@
package love.sola.netsupport.api;
package love.sola.netsupport.api.user;
import com.google.gson.Gson;
import love.sola.netsupport.api.Response;
import love.sola.netsupport.enums.Attribute;
import love.sola.netsupport.pojo.Ticket;
import love.sola.netsupport.pojo.User;

View File

@@ -1,6 +1,8 @@
package love.sola.netsupport.api;
package love.sola.netsupport.api.user;
import com.google.gson.Gson;
import love.sola.netsupport.api.Response;
import love.sola.netsupport.config.Settings;
import love.sola.netsupport.enums.Attribute;
import love.sola.netsupport.pojo.Ticket;
import love.sola.netsupport.pojo.User;
@@ -51,6 +53,9 @@ public class TicketSubmit extends HttpServlet {
if (desc == null || desc.isEmpty()) {
return new Response(Response.ResponseCode.PARAMETER_REQUIRED);
}
if (desc.length() > Settings.MAX_DESC_LENGTH) {
return new Response(Response.ResponseCode.LENGTH_LIMIT_EXCEEDED);
}
try (Session s = SQLCore.sf.openSession()) {

View File

@@ -1,15 +1,11 @@
package love.sola.netsupport.config;
import lombok.AllArgsConstructor;
import lombok.Data;
import org.yaml.snakeyaml.Yaml;
import java.io.IOException;
import java.io.InputStream;
import java.text.MessageFormat;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Pattern;
/**
* ***********************************************
@@ -20,16 +16,12 @@ import java.util.regex.Pattern;
public class Lang {
public static Map<String, String> messages;
public static Map<String, AutoReply> replies;
public static Map<String, MessageFormat> format_cache = new HashMap<>(32);
static {
try (InputStream in = Lang.class.getClassLoader().getResourceAsStream("lang.yml")) {
InputStream in = Lang.class.getClassLoader().getResourceAsStream("lang.yml");
//noinspection unchecked
messages = new Yaml().loadAs(in, Map.class);
} catch (IOException e) {
e.printStackTrace();
}
}
public static String lang(String key) {
@@ -48,21 +40,4 @@ public class Lang {
}
}
public static void loadReplies() {
try (InputStream in = Lang.class.getClassLoader().getResourceAsStream("replies.yml")) {
Map<String, Object> yaml = (Map<String, Object>) new Yaml().load(in);
} catch (IOException e) {
e.printStackTrace();
}
}
@Data
@AllArgsConstructor
public static class AutoReply {
Pattern[] regex;
String[] replies;
}
}

View File

@@ -12,6 +12,8 @@ import love.sola.netsupport.sql.TableConfig;
@ToString
public class Settings {
public static final int MAX_DESC_LENGTH = 255;
public static Settings I;
static {
@@ -29,9 +31,8 @@ public class Settings {
public int Check_Spam_Cache_Expire_Time;
public int Check_Spam_Interval;
public int User_Caching_Time;
public int User_Session_Max_Inactive;
public int User_Wechat_Cache_Expire_Time;
//No arg constructor for Yaml.loadAs
public Settings() { I = this; }

View File

@@ -15,6 +15,14 @@ import static love.sola.netsupport.config.Lang.lang;
public class Access {
public static final int ROOT = 0;
public static final int MANAGER = 1;
public static final int CO_MANAGER = 2;
public static final int LEADER = 3;
public static final int CO_LEADER = 4;
public static final int ELITE = 5;
public static final int ELDER = 6;
public static final int MEMBER = 7;
public static final int PRE_MEMBER = 8;
public static final int NOLOGIN = 9;
public static final Map<Integer, String> inverseMap = new HashMap<>();

View File

@@ -25,6 +25,8 @@ public class Block {
public static final int DM_13 = 31;
public static final int DM_14 = 32;
public static final int DM_15 = 33;
public static final int DM_20 = 34;
public static final int DM_21 = 35;
public static final int XH_A = 40;
public static final int XH_B = 41;
public static final int XH_C = 42;
@@ -35,8 +37,6 @@ public class Block {
public static final int FX_4 = 53;
public static final int FX_5 = 54;
public static final int FX_6 = 55;
public static final int DM_20 = 60;
public static final int DM_21 = 61;
public static final Map<Integer, String> inverseMap = new HashMap<>();
@@ -68,7 +68,7 @@ public class Block {
AVAILABLE[BM_8] = new int[]{100, 221, 321, 421, 521, 621, 721};
AVAILABLE[BM_9] = new int[]{100, 221, 321, 421, 521, 621};
AVAILABLE[BM_10] = new int[]{111, 239, 339, 439, 558, 658, 758, 858};
AVAILABLE[BM_11] = new int[]{100, 220, 320, 420, 520, 620, 720, 820};
AVAILABLE[BM_11] = new int[]{100, 213, 321, 421, 521, 621, 721, 821};
AVAILABLE[DM_12] = new int[]{119, 221, 321, 421, 521, 621, 720};
AVAILABLE[DM_13] = new int[]{120, 222, 322, 422, 522, 622, 722};
AVAILABLE[DM_14] = new int[]{100, 230, 330, 430, 530, 630, 730};

View File

@@ -17,6 +17,8 @@ public class Status {
public static final int UNCHECKED = 0;
public static final int ARRANGED = 1;
public static final int PUTOFF = 2;
public static final int REPORTED = 4;
public static final int ISP_HANDLED = 7;
public static final int SOLVED = 9;
public static final Map<Integer, String> inverseMap = new HashMap<>();

View File

@@ -42,4 +42,10 @@ public class User {
private Integer room;
private Long phone;
//System Accounts
public static User OFFICIAL_CHINA_UNICOM_XH;
public static User OFFICIAL_CHINA_MOBILE_XH;
public static User OFFICIAL_CHINA_MOBILE_FX;
}

View File

@@ -2,14 +2,24 @@ package love.sola.netsupport.sql;
import com.google.gson.*;
import com.google.gson.annotations.Expose;
import com.google.gson.reflect.TypeToken;
import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonWriter;
import love.sola.netsupport.enums.ISP;
import love.sola.netsupport.wechat.Command;
import org.hibernate.Hibernate;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.boot.MetadataSources;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.envers.AuditReader;
import org.hibernate.envers.AuditReaderFactory;
import org.hibernate.proxy.HibernateProxy;
import org.hibernate.service.ServiceRegistry;
import javax.naming.InitialContext;
import javax.sql.DataSource;
import java.io.IOException;
import java.util.Date;
/**
@@ -50,6 +60,9 @@ public class SQLCore {
.registerTypeAdapter(Date.class, (JsonSerializer<Date>) (src, typeOfSrc, context) -> new JsonPrimitive(src.getTime()))
.registerTypeAdapter(ISP.class, (JsonDeserializer<ISP>) (json, typeOfT, context) -> ISP.fromId(json.getAsJsonPrimitive().getAsInt()))
.registerTypeAdapter(ISP.class, (JsonSerializer<ISP>) (src, typeOfSrc, context) -> new JsonPrimitive(src.id))
.registerTypeAdapter(Command.class, (JsonDeserializer<Command>) (json, typeOfT, context) -> Command.fromId(json.getAsJsonPrimitive().getAsInt()))
.registerTypeAdapter(Command.class, (JsonSerializer<Command>) (src, typeOfSrc, context) -> new JsonPrimitive(src.id))
.registerTypeAdapterFactory(HibernateProxyTypeAdapter.FACTORY)
.create();
public static SessionFactory sf;
public static ServiceRegistry sr;
@@ -63,10 +76,54 @@ public class SQLCore {
sr = new StandardServiceRegistryBuilder().configure().build();
sf = new MetadataSources(sr).buildMetadata().buildSessionFactory();
TableUser.init();
TableOperator.init();
} catch (Exception e) {
e.printStackTrace();
}
}
public static AuditReader getAuditReader(Session session) {
return AuditReaderFactory.get(session);
}
public static class HibernateProxyTypeAdapter extends TypeAdapter<HibernateProxy> {
public static final TypeAdapterFactory FACTORY = new TypeAdapterFactory() {
@Override
@SuppressWarnings("unchecked")
public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> type) {
return (HibernateProxy.class.isAssignableFrom(type.getRawType()) ? (TypeAdapter<T>) new HibernateProxyTypeAdapter(gson) : null);
}
};
private final Gson context;
private HibernateProxyTypeAdapter(Gson context) {
this.context = context;
}
@Override
public HibernateProxy read(JsonReader in) throws IOException {
throw new UnsupportedOperationException("Not supported");
}
@SuppressWarnings({"rawtypes", "unchecked"})
@Override
public void write(JsonWriter out, HibernateProxy value) throws IOException {
if (value == null) {
out.nullValue();
return;
}
// Retrieve the original (not proxy) class
Class<?> baseType = Hibernate.getClass(value);
// Get the TypeAdapter of the original class, to delegate the serialization
TypeAdapter delegate = context.getAdapter(TypeToken.get(baseType));
// Get a filled instance of the original class
Object unproxiedValue = ((HibernateProxy) value).getHibernateLazyInitializer()
.getImplementation();
// Serialize the value
delegate.write(out, unproxiedValue);
}
}
}

View File

@@ -7,6 +7,8 @@ import org.hibernate.Session;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Projections;
import org.hibernate.criterion.Restrictions;
import org.hibernate.envers.AuditReader;
import org.hibernate.envers.query.AuditEntity;
import java.util.List;
@@ -61,8 +63,10 @@ public class TableTicket extends SQLCore {
@SuppressWarnings("unchecked")
public static List<Ticket> unsolvedByBlock(int b) {
if (b == 0) return unsolved();
try (Session s = SQLCore.sf.openSession()) {
return s.createCriteria(Ticket.class)
.addOrder(Order.desc(Ticket.PROPERTY_SUBMIT_TIME))
.add(Restrictions.ne(Ticket.PROPERTY_STATUS, Status.SOLVED))
.createCriteria(Ticket.PROPERTY_USER)
.add(Restrictions.between(User.PROPERTY_BLOCK, b * 10, (b + 1) * 10 - 1))
@@ -70,4 +74,29 @@ public class TableTicket extends SQLCore {
}
}
@SuppressWarnings("unchecked")
public static List<Ticket> unsolved() {
try (Session s = SQLCore.sf.openSession()) {
return s.createCriteria(Ticket.class)
.createAlias(Ticket.PROPERTY_USER, "u")
.addOrder(Order.asc("u." + User.PROPERTY_BLOCK))
.addOrder(Order.desc(Ticket.PROPERTY_SUBMIT_TIME))
.add(Restrictions.ne(Ticket.PROPERTY_STATUS, Status.SOLVED))
.list();
}
}
@SuppressWarnings("unchecked")
public static List<Object[]> track(int tid) {
try (Session s = SQLCore.sf.openSession()) {
AuditReader reader = getAuditReader(s);
return reader.createQuery()
.forRevisionsOfEntity(Ticket.class, false, true)
.addOrder(AuditEntity.revisionNumber().asc())
.add(AuditEntity.id().eq(tid))
.getResultList()
;
}
}
}

View File

@@ -1,9 +1,16 @@
package love.sola.netsupport.sql;
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import love.sola.netsupport.config.Settings;
import love.sola.netsupport.pojo.User;
import org.hibernate.Session;
import org.hibernate.criterion.Restrictions;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
/**
* ***********************************************
* Created by Sola on 2015/11/10.
@@ -28,26 +35,64 @@ public class TableUser extends SQLCore {
}
}
public static User getByWechat(String wechat) {
try (Session s = sf.openSession()) {
return (User) s.createCriteria(User.class).add(Restrictions.eq(User.PROPERTY_WECHAT, wechat)).uniqueResult();
}
}
public static User getByName(String name) {
try (Session s = sf.openSession()) {
return (User) s.createCriteria(User.class).add(Restrictions.eq(User.PROPERTY_NAME, name)).uniqueResult();
}
}
public static User getByWechat(String wechat) {
try {
User u = cache.get(wechat);
return u == NULL_USER ? null : u;
} catch (ExecutionException e) {
e.printStackTrace();
return null;
}
}
public static int update(User user) {
try (Session s = sf.openSession()) {
s.beginTransaction();
s.update(user);
s.getTransaction().commit();
cache.put(user.getWechatId(), user);
return 1;
}
}
protected static void init() {
try (Session s = SQLCore.sf.openSession()) {
User.OFFICIAL_CHINA_UNICOM_XH = s.get(User.class, 100104L);
User.OFFICIAL_CHINA_MOBILE_XH = s.get(User.class, 100864L);
User.OFFICIAL_CHINA_MOBILE_FX = s.get(User.class, 100865L);
}
}
private static LoadingCache<String, User> cache = CacheBuilder.newBuilder()
.concurrencyLevel(4)
.maximumSize(4096)
.expireAfterWrite(Settings.I.User_Wechat_Cache_Expire_Time, TimeUnit.SECONDS)
.build(new ValueLoader());
private static class ValueLoader extends CacheLoader<String, User> {
@Override
public User load(String key) throws Exception {
User u = TableUser.getByWechat0(key);
return u == null ? NULL_USER : u;
}
}
private static final User NULL_USER = new User();
public static void flushCache() {
cache.invalidateAll();
}
private static User getByWechat0(String wechat) {
try (Session s = sf.openSession()) {
return (User) s.createCriteria(User.class).add(Restrictions.eq(User.PROPERTY_WECHAT, wechat)).uniqueResult();
}
}
}

View File

@@ -34,13 +34,11 @@ public enum Command {
}
}
public final String name;
public final String regex;
public final Class<? extends WxMpMessageHandler> handler;
public final int id;
Command(int id, Class<? extends WxMpMessageHandler> handler) {
this.name = lang("CMD_" + name());
this.id = id;
this.regex = lang("REGEX_" + name());
this.handler = handler;
@@ -52,7 +50,7 @@ public enum Command {
@Override
public String toString() {
return name;
return name();
}
}

View File

@@ -1,9 +1,7 @@
package love.sola.netsupport.wechat;
import love.sola.netsupport.config.Settings;
import me.chanjar.weixin.common.session.InternalSession;
import me.chanjar.weixin.common.session.StandardSessionManager;
import me.chanjar.weixin.common.session.WxSession;
import me.chanjar.weixin.common.session.*;
import java.util.UUID;
@@ -23,11 +21,15 @@ public class WechatSession {
}
public static WxSession get(String id, boolean create) {
return manager.getSession(id, create);
WxSession session = manager.getSession(id, create);
if (session != null) {
((StandardSessionFacade) session).getInternalSession().endAccess();
}
return session;
}
public static WxSession get(String id) {
return manager.getSession(id);
return get(id, true);
}
public static String genId() {

View File

@@ -2,8 +2,9 @@ package love.sola.netsupport.wechat;
import love.sola.netsupport.config.Settings;
import love.sola.netsupport.wechat.handler.RegisterHandler;
import love.sola.netsupport.wechat.handler.SpamHandler;
import love.sola.netsupport.wechat.matcher.SpamMatcher;
import love.sola.netsupport.wechat.handler.SignHandler;
import love.sola.netsupport.wechat.handler.SubscribeHandler;
import love.sola.netsupport.wechat.matcher.CheckSpamMatcher;
import love.sola.netsupport.wechat.matcher.RegisterMatcher;
import me.chanjar.weixin.common.util.StringUtils;
import me.chanjar.weixin.mp.api.*;
@@ -25,13 +26,14 @@ import static love.sola.netsupport.config.Lang.lang;
* Don't modify this source without my agreement
* ***********************************************
*/
@WebServlet(name = "WxMpServlet", urlPatterns = "/wechattest", loadOnStartup = 99)
@WebServlet(name = "WxMpServlet", urlPatterns = "/wechat", loadOnStartup = 99)
public class WxMpServlet extends HttpServlet {
public static WxMpServlet instance;
protected WxMpInMemoryConfigStorage config;
protected WxMpService wxMpService;
protected WxMpMessageRouter wxMpMessageRouter;
protected CheckSpamMatcher checkSpamMatcher;
public WxMpServlet() {
instance = this;
@@ -45,27 +47,28 @@ public class WxMpServlet extends HttpServlet {
config.setAppId(Settings.I.Wechat_AppId);
config.setSecret(Settings.I.Wechat_Secret);
config.setToken(Settings.I.Wechat_Token);
config.setAesKey(Settings.I.Wechat_Token);
config.setAesKey(Settings.I.Wechat_AesKey);
wxMpService = new WxMpServiceImpl();
wxMpService.setWxMpConfigStorage(config);
checkSpamMatcher = new CheckSpamMatcher();
wxMpMessageRouter = new WxMpMessageRouter(wxMpService);
wxMpMessageRouter.rule()
.async(false)
.msgType("event")
.event("subscribe")
.handler((wxMessage, context, wxMpService1, sessionManager)
-> WxMpXmlOutMessage.TEXT()
.fromUser(wxMessage.getToUserName())
.toUser(wxMessage.getFromUserName())
.content(lang("Event_Subscribe")).build())
.handler(new SubscribeHandler())
.end();
wxMpMessageRouter.rule()
.async(false)
.msgType("text")
.matcher(new SpamMatcher())
.handler(new SpamHandler())
.matcher(new CheckSpamMatcher())
.handler((wxMessage, context, wxMpService1, sessionManager)
-> WxMpXmlOutMessage.TEXT()
.fromUser(wxMessage.getToUserName())
.toUser(wxMessage.getFromUserName())
.content(lang("Message_Spam")).build())
.end();
wxMpMessageRouter.rule()
.async(false)
@@ -78,6 +81,7 @@ public class WxMpServlet extends HttpServlet {
} catch (IllegalAccessException | InstantiationException e) {
throw new ServletException(e);
}
wxMpMessageRouter.rule().async(false).msgType("text").rContent("(?i)^Auth \\d{4}").handler(new SignHandler()).end();
}
public static void registerCommands(WxMpMessageRouter router) throws IllegalAccessException, InstantiationException {

View File

@@ -35,7 +35,7 @@ public class ProfileHandler implements WxMpMessageHandler {
session.setAttribute(Attribute.WECHAT, wxMessage.getFromUserName());
session.setAttribute(Attribute.USER, u);
TextBuilder out = WxMpXmlOutMessage.TEXT().fromUser(wxMessage.getToUserName()).toUser(wxMessage.getFromUserName());
out.content(format("User_Profile_Link", id, u.getName(), u.getIsp().id, u.getNetAccount(), u.getBlock(), u.getRoom(), u.getPhone()));
out.content(format("Profile_Modify", format("User_Profile_Link", id, u.getName(), u.getIsp().id, u.getNetAccount(), u.getBlock(), u.getRoom(), u.getPhone())));
return out.build();
}

View File

@@ -17,7 +17,6 @@ import me.chanjar.weixin.mp.bean.outxmlbuilder.TextBuilder;
import java.util.Map;
import static love.sola.netsupport.config.Lang.format;
import static love.sola.netsupport.config.Lang.lang;
/**
* ***********************************************
@@ -33,14 +32,17 @@ public class RegisterHandler implements WxMpMessageHandler {
TextBuilder out = WxMpXmlOutMessage.TEXT().fromUser(wxMessage.getToUserName()).toUser(wxMessage.getFromUserName());
String fromUser = wxMessage.getFromUserName();
User u = TableUser.getByWechat(fromUser);
if (u != null) {
out.content(lang("Already_Registered"));
} else {
String id = WechatSession.genId();
WxSession session = WechatSession.get(id, true);
if (u != null) {
session.setAttribute(Attribute.AUTHORIZED, Command.PROFILE);
session.setAttribute(Attribute.WECHAT, fromUser);
session.setAttribute(Attribute.USER, u);
out.content(format("Already_Registered", format("User_Profile_Link", id, u.getName(), u.getIsp().id, u.getNetAccount(), u.getBlock(), u.getRoom(), u.getPhone())));
} else {
session.setAttribute(Attribute.AUTHORIZED, Command.REGISTER);
session.setAttribute(Attribute.WECHAT, wxMessage.getFromUserName());
out.content(format("User_Register_Link", id));
session.setAttribute(Attribute.WECHAT, fromUser);
out.content(format("User_Register", format("User_Register_Link", id)));
}
return out.build();
}

View File

@@ -0,0 +1,88 @@
package love.sola.netsupport.wechat.handler;
import love.sola.netsupport.sql.SQLCore;
import me.chanjar.weixin.common.exception.WxErrorException;
import me.chanjar.weixin.common.session.WxSessionManager;
import me.chanjar.weixin.mp.api.WxMpMessageHandler;
import me.chanjar.weixin.mp.api.WxMpService;
import me.chanjar.weixin.mp.bean.WxMpXmlMessage;
import me.chanjar.weixin.mp.bean.WxMpXmlOutMessage;
import me.chanjar.weixin.mp.bean.outxmlbuilder.TextBuilder;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* ***********************************************
* Created by Sola on 2015/12/26.
* Don't modify this source without my agreement
* ***********************************************
*/
public class SignHandler implements WxMpMessageHandler {
public static Pattern pat = Pattern.compile("(?i)^Auth (\\d{4})");
@Override
public WxMpXmlOutMessage handle(WxMpXmlMessage wxMessage, Map<String, Object> context, WxMpService wxMpService, WxSessionManager sessionManager) throws WxErrorException {
String msg = wxMessage.getContent();
TextBuilder out = WxMpXmlOutMessage.TEXT().toUser(wxMessage.getFromUserName()).fromUser(wxMessage.getToUserName());
Matcher mat = pat.matcher(msg);
root:
if (mat.find()) {
int id = Integer.parseInt(mat.group(1));
try (Connection conn = SQLCore.ds.getConnection()) {
switch (checkID(conn, id)) {
case -1:
out.content("无效ID。");
break root;
case -2:
out.content("该ID已登记过。");
break root;
}
if (checkDuplicated(conn, wxMessage.getFromUserName())) {
out.content("你的微信已经登记过。");
break root;
}
PreparedStatement ps = conn.prepareStatement("UPDATE auth SET wechat=? WHERE id=?");
ps.setString(1, wxMessage.getFromUserName());
ps.setInt(2, id);
if (ps.executeUpdate() == 1) {
out.content("登记成功。");
} else {
out.content("登记失败,请联系管理员。");
}
} catch (SQLException e) {
e.printStackTrace();
out.content("系统异常,请联系管理员。");
}
} else {
out.content("无效ID。");
}
return out.build();
}
private static int checkID(Connection conn, int id) throws SQLException {
PreparedStatement ps = conn.prepareStatement("SELECT wechat FROM auth WHERE id=?");
ps.setInt(1, id);
ResultSet rs = ps.executeQuery();
if (rs.next()) {
return rs.getString("wechat") != null ? -2 : 0;
} else {
return -1;
}
}
private static boolean checkDuplicated(Connection conn, String wechat) throws SQLException {
PreparedStatement ps = conn.prepareStatement("SELECT wechat FROM auth WHERE wechat=?");
ps.setString(1, wechat);
ResultSet rs = ps.executeQuery();
return rs.next();
}
}

View File

@@ -1,30 +0,0 @@
package love.sola.netsupport.wechat.handler;
import me.chanjar.weixin.common.exception.WxErrorException;
import me.chanjar.weixin.common.session.WxSessionManager;
import me.chanjar.weixin.mp.api.WxMpMessageHandler;
import me.chanjar.weixin.mp.api.WxMpService;
import me.chanjar.weixin.mp.bean.WxMpXmlMessage;
import me.chanjar.weixin.mp.bean.WxMpXmlOutMessage;
import me.chanjar.weixin.mp.bean.outxmlbuilder.TextBuilder;
import java.util.Map;
/**
* ***********************************************
* Created by Sola on 2015/12/17.
* Don't modify this source without my agreement
* ***********************************************
*/
public class SpamHandler implements WxMpMessageHandler {
@Override
public WxMpXmlOutMessage handle(WxMpXmlMessage wxMessage, Map<String, Object> context, WxMpService wxMpService, WxSessionManager sessionManager) throws WxErrorException {
TextBuilder out = WxMpXmlOutMessage.TEXT()
.fromUser(wxMessage.getToUserName())
.toUser(wxMessage.getFromUserName());
return out.build();
}
}

View File

@@ -38,7 +38,7 @@ public class SubmitHandler implements WxMpMessageHandler {
}
String id = WechatSession.genId();
WxSession session = WechatSession.get(id, true);
session.setAttribute(Attribute.AUTHORIZED, Command.QUERY);
session.setAttribute(Attribute.AUTHORIZED, Command.SUBMIT);
session.setAttribute(Attribute.WECHAT, wxMessage.getFromUserName());
session.setAttribute(Attribute.USER, u);

View File

@@ -0,0 +1,48 @@
package love.sola.netsupport.wechat.handler;
import love.sola.netsupport.enums.Attribute;
import love.sola.netsupport.pojo.User;
import love.sola.netsupport.sql.TableUser;
import love.sola.netsupport.wechat.Command;
import love.sola.netsupport.wechat.WechatSession;
import me.chanjar.weixin.common.exception.WxErrorException;
import me.chanjar.weixin.common.session.WxSession;
import me.chanjar.weixin.common.session.WxSessionManager;
import me.chanjar.weixin.mp.api.WxMpMessageHandler;
import me.chanjar.weixin.mp.api.WxMpService;
import me.chanjar.weixin.mp.bean.WxMpXmlMessage;
import me.chanjar.weixin.mp.bean.WxMpXmlOutMessage;
import me.chanjar.weixin.mp.bean.outxmlbuilder.TextBuilder;
import java.util.Map;
import static love.sola.netsupport.config.Lang.format;
/**
* ***********************************************
* Created by Sola on 2015/12/25.
* Don't modify this source without my agreement
* ***********************************************
*/
public class SubscribeHandler implements WxMpMessageHandler {
@Override
public WxMpXmlOutMessage handle(WxMpXmlMessage wxMessage, Map<String, Object> context, WxMpService wxMpService, WxSessionManager sessionManager) throws WxErrorException {
TextBuilder out = WxMpXmlOutMessage.TEXT().fromUser(wxMessage.getToUserName()).toUser(wxMessage.getFromUserName());
String fromUser = wxMessage.getFromUserName();
User u = TableUser.getByWechat(fromUser);
String id = WechatSession.genId();
WxSession session = WechatSession.get(id, true);
if (u != null) {
session.setAttribute(Attribute.AUTHORIZED, Command.PROFILE);
session.setAttribute(Attribute.WECHAT, fromUser);
session.setAttribute(Attribute.USER, u);
out.content(format("Event_Subscribe", format("Already_Registered", format("User_Profile_Link", id, u.getName(), u.getIsp().id, u.getNetAccount(), u.getBlock(), u.getRoom(), u.getPhone()))));
} else {
session.setAttribute(Attribute.AUTHORIZED, Command.REGISTER);
session.setAttribute(Attribute.WECHAT, fromUser);
out.content(format("Event_Subscribe", format("User_Register", format("User_Register_Link", id))));
}
return out.build();
}
}

View File

@@ -15,7 +15,7 @@ import java.util.concurrent.TimeUnit;
* Don't modify this source without my agreement
* ***********************************************
*/
public class SpamMatcher implements WxMpMessageMatcher {
public class CheckSpamMatcher implements WxMpMessageMatcher {
private class ValueLoader extends CacheLoader<String, Long> {
@Override
@@ -26,7 +26,6 @@ public class SpamMatcher implements WxMpMessageMatcher {
private LoadingCache<String, Long> cache = CacheBuilder.newBuilder()
.concurrencyLevel(4)
.weakKeys()
.maximumSize(4096)
.expireAfterWrite(Settings.I.Check_Spam_Cache_Expire_Time, TimeUnit.SECONDS)
.build(new ValueLoader());

View File

@@ -6,46 +6,51 @@ Unknown_Encrypt_Type: 'Unknown encrypt-type.'
#Command Regex
REGEX_QUERY: '^(?i)(Query)|(查询)|(cx)$'
REGEX_REGISTER: '^(?i)(Reg(ister)?)|(注册)|(绑定)|(zc)|(bd)$'
REGEX_SUBMIT: '^(?i)(Submit)|(报修)|(bx)$'
REGEX_SUBMIT: '^(?i)(Submit)|(报修)|(保修)|(bx)$'
REGEX_CANCEL: '^(?i)(Cancel)|(取消)|(撤销)|(qx)|(cx)$'
REGEX_LOGIN: '^(?i)Authme$'
REGEX_PROFILE: '^(?i)(EditProfile)|(修改资料)|(xgzl)$'
REGEX_PROFILE: '^(?i)(EditProfile)|(修改资料)|(修改信息)|(xgzl)|(xgxx)$'
#Event
Event_Subscribe: "欢迎使用电子科技大学中山学院网络维护科微信自助报修平台。\n如您在使用中遇到任何问题请将投诉或建议邮件至loli@sola.love.\n\n请发送'绑定'进行微信绑定"
#Misc
Invalid_Operation: 'Whoops报修姬找不到你想要的东西啦 (╯‵□′)╯︵┻━┻。'
Message_Spam: '你的打字速度太快了喝一杯82年的Java压压惊吧。'
#Subscribe
Event_Subscribe: "欢迎使用电子科技大学中山学院网络维护科微信自助报修平台。\n\n{0}"
#Register
Already_Registered: "您进行微信绑定。如果需要更改个人信息,请发送 '修改资料' 。"
User_Register: "您尚未进行微信绑定。\n<a href=\"{0}\">>点击这里进行微信绑定操作<</a>"
Already_Registered: '您已进行过微信绑定。若是需要更改个人信息,请<a href="{0}"> >点击此处<</a>。'
#Query
Query_Title: '最近一次报修记录:'
More_Details: '查询更早的报修信息,请点击 >'
More_Details: '>>> 查询更早的报修信息,请点击 <<<'
No_Ticket_Available: '您尚未提交过任何报修。'
#Submit
Already_Opening_Ticket: "您上次提交的报修单仍在处理中. 若需要查询报修单状态,请发送 '查询' 。"
Submit_Title: '在网维工作人员上门解决您的问题之前...'
Submit_Desc: "在网维工作人员上门解决您的问题之前,您可以尝试以下方法来更有效地解决您的问题:\n
重新插拔您电脑的网线以及墙上的端口。\n
尝试卸载掉您的wifi共享软件并重启电脑。\n
请您检查一下您的账号是否余额充足。\n
若您的电脑出现明显异常,请尝试使用他人的电脑能否正常登录,网维的工作成员主要负责网络的维护工作,可能无法解决您的个人电脑问题。\n
\n
若以上步骤对您没有帮助,请点此提交报修表单。"
Submit_Desc: |
在网维工作人员上门解决您的问题之前,您可以尝试以下方法来更有效地解决您的问题:
- 重新插拔您电脑的网线以及墙上的端口。
- 尝试卸载掉您的wifi共享软件并重启电脑。
- 请您检查一下您的账号是否余额充足。
- 若您的电脑出现明显异常,请尝试使用他人的电脑能否正常登录,网维的工作成员主要负责网络的维护工作,可能无法解决您的个人电脑问题。
若以上步骤对您没有帮助,请点此提交报修表单。
#Cancel
No_Open_Ticket_Available: '您当前没有未解决的报修表单。'
Cancel_Title: '报修已取消:'
User_Cancel_Remark: '用户手动取消报修。'
Cancel_Failed: '取消失败。'
#Modify
Profile_Modify: '<a href="{0}">> 点此修改资料 <</a>'
#Login
Not_Operator: '嘟嘟嘟……'
No_Login: 'Permission Denied.'
Internal_Error: '啊哦,登录失败了哦。'
#URL
User_Register_Link: '您尚未进行微信绑定, 请<a href="http://topaz.sinaapp.com/nm/v1/reg.html?token={0}">点击这里</a>进行微信绑定操作。'
User_Register_Link: 'http://topaz.sinaapp.com/nm/v1/reg.html?token={0}'
User_Query_Link: 'http://topaz.sinaapp.com/nm/v1/list.html?token={0}'
User_Submit_Link: 'http://topaz.sinaapp.com/nm/v1/rrepair.html?token={0}&name={1}&isp={2}&room={3}&block={4}&phone={5,number,#}'
User_Profile_Link: 'http://topaz.sinaapp.com/nm/v1/profile.html?token={0}&name={1}&isp={2}&account={3}&block={4}&room={5}&phone={6,number,#}'
User_Profile_Link: 'http://topaz.sinaapp.com/nm/v1/modi.html?token={0}&name={1}&isp={2}&username={3}&block={4}&room={5}&phone={6,number,#}'
Result_Page: 'http://topaz.sinaapp.com/nm/v1/result.html'
Operator_Home_Page: '<a href="http://topaz.sinaapp.com/nm/v1/man/home.html?token={0}">CLICK HERE</a>'
Operator_Login_Page: 'http://topaz.sinaapp.com/nm/v1/man/login.html?pkey={0}'
@@ -56,7 +61,7 @@ STATUS_UNCHECKED: '待处理'
STATUS_SOLVED: '已解决'
#Ticket
Ticket_Info_Id: '报修单号: '
Ticket_Info_Desc: '报修描述: '
Ticket_Info_Desc: ''
Ticket_Info_Submit_Time: '提交时间: '
Ticket_Info_Operator: '操作员: '
Ticket_Info_Remark: '维修描述: '

View File

@@ -1,9 +1,15 @@
package love.sola.netsupport.wechat;
import love.sola.netsupport.util.RSAUtil;
import org.apache.commons.codec.binary.Base64;
import org.junit.Test;
import org.mindrot.jbcrypt.BCrypt;
import java.security.KeyFactory;
import java.security.NoSuchAlgorithmException;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.X509EncodedKeySpec;
/**
* ***********************************************
* Created by Sola on 2015/12/6.
@@ -24,4 +30,16 @@ public class TestEncrypt {
assert "Encrypt".equals(RSAUtil.decrypt(RSAUtil.encrypt("Encrypt")));
}
// @Test
public void testRSASpecKey() throws NoSuchAlgorithmException, InvalidKeySpecException {
System.out.println("RSAUtil.privateKey_s = " + RSAUtil.privateKey_s);
System.out.println("RSAUtil.publicKey_s = " + RSAUtil.publicKey_s);
// String pkey = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCA0qyARvHSCIUQ6YM6K+e/QgiZ+dc/MpVz5DIFwQab5iiifruQiaoA74ilHOOiq5i0ToR1VxNhCUZcAy2saHNifoYKTauMOUSV6IoP4X5jp691PlI9yxNx328mSlPNM9+7BgOzrUP1pR71d+T4LDn0o4J6Ad82vVIe7yWszzF4qQIDAQAB";
String pkey = RSAUtil.publicKey_s;
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
X509EncodedKeySpec keySpec = new X509EncodedKeySpec(Base64.decodeBase64(pkey));
RSAUtil.publicKey = keyFactory.generatePublic(keySpec);
System.out.println("RSAUtil.encrypt(\"233\") = " + RSAUtil.encrypt("233"));
}
}

View File

@@ -1,19 +1,12 @@
package love.sola.netsupport.wechat;
import com.google.gson.*;
import lombok.AllArgsConstructor;
import lombok.Data;
import love.sola.netsupport.config.Lang;
import love.sola.netsupport.enums.ISP;
import org.junit.Test;
import org.yaml.snakeyaml.DumperOptions;
import org.yaml.snakeyaml.Yaml;
import org.yaml.snakeyaml.nodes.Tag;
import java.text.MessageFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
/**
* ***********************************************
@@ -47,23 +40,4 @@ public class TestMessageFormat {
assert "15838838438".equals(MessageFormat.format("{0,number,#}", 15838838438L));
}
@Test
public void testYaml() {
assert new Yaml().loadAs("array: \n - \"err\"\n - \"ee\"", TestArray.class).array.length == 2;
}
@Test
public void testYamlDump() {
Map<String, TestArray> map = new HashMap<>();
map.put("fuck", new TestArray(new String[]{"one", "two", "three"}));
map.put("you", new TestArray(new String[]{"one", "two", "three"}));
System.out.println(new Yaml().dumpAs(map, new Tag(map.getClass()), DumperOptions.FlowStyle.BLOCK));
}
@Data
@AllArgsConstructor
public static class TestArray {
String[] array;
}
}