Merge remote-tracking branch 'origin/develop'

# Conflicts:
#	README.md
This commit is contained in:
Sola
2017-12-15 10:18:28 +08:00
79 changed files with 2842 additions and 2517 deletions

View File

@@ -66,12 +66,6 @@
<version>3.1.0</version> <version>3.1.0</version>
<scope>provided</scope> <scope>provided</scope>
</dependency> </dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.16.6</version>
<scope>provided</scope>
</dependency>
<dependency> <dependency>
<groupId>junit</groupId> <groupId>junit</groupId>
<artifactId>junit</artifactId> <artifactId>junit</artifactId>

View File

@@ -31,21 +31,21 @@ import java.io.PrintWriter;
@WebServlet(name = "Index", urlPatterns = "/index", loadOnStartup = 1) @WebServlet(name = "Index", urlPatterns = "/index", loadOnStartup = 1)
public class Index extends HttpServlet { public class Index extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response); doGet(request, response);
} }
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setCharacterEncoding("utf-8"); request.setCharacterEncoding("utf-8");
response.addHeader("Content-type", "text/plain;charset=utf-8"); response.addHeader("Content-type", "text/plain;charset=utf-8");
response.setCharacterEncoding("utf-8"); response.setCharacterEncoding("utf-8");
PrintWriter out = response.getWriter(); PrintWriter out = response.getWriter();
out.println("Wechat Ticket System (WTS) 0.1 Copyright 2015-2016 Sola & LiuYue all rights reserved. | Commercial license for ZSC Network Support Department (ZSCNSD)."); out.println("Wechat Ticket System (WTS) 0.1 Copyright 2015-2016 Sola & LiuYue all rights reserved. | Commercial license for ZSC Network Support Department (ZSCNSD).");
out.println("For any problem, Please contact loli@sola.love."); out.println("For any problem, Please contact loli@sola.love.");
if (response.getStatus() == HttpServletResponse.SC_NOT_FOUND) { if (response.getStatus() == HttpServletResponse.SC_NOT_FOUND) {
out.println("\nError 404: Page not found."); out.println("\nError 404: Page not found.");
} }
out.close(); out.close();
} }
} }

View File

@@ -31,35 +31,35 @@ import java.util.Date;
*/ */
public abstract class API { public abstract class API {
public String url = null; //url public String url = null; //url
public int access = Access.GOD_MODE; //operator's permission public int access = Access.GOD_MODE; //operator's permission
public Command authorize = null; //session check public Command authorize = null; //session check
protected abstract Object process(HttpServletRequest req, WxSession session) throws Exception; protected abstract Object process(HttpServletRequest req, WxSession session) throws Exception;
@Override @Override
public String toString() { public String toString() {
return getClass().getSimpleName() + "{" + return getClass().getSimpleName() + "{" +
"url='" + url + '\'' + "url='" + url + '\'' +
", access=" + Access.inverseMap.get(access) + ", access=" + Access.inverseMap.get(access) +
", authorize=" + authorize + ", authorize=" + authorize +
'}'; '}';
} }
public static String getParameterWithDefault(String obj, String def) { public static String getParameterWithDefault(String obj, String def) {
return obj == null ? def : obj; return obj == null ? def : obj;
} }
public static Date getParameterAsDate(String obj, Date def) { public static Date getParameterAsDate(String obj, Date def) {
return obj == null ? def : new Date(Long.valueOf(obj)); return obj == null ? def : new Date(Long.valueOf(obj));
} }
public static Date getToday() { public static Date getToday() {
return DateUtils.truncate(new Date(), Calendar.DAY_OF_MONTH); return DateUtils.truncate(new Date(), Calendar.DAY_OF_MONTH);
} }
public static Date getDay(Date date) { public static Date getDay(Date date) {
return DateUtils.truncate(date, Calendar.DAY_OF_MONTH); return DateUtils.truncate(date, Calendar.DAY_OF_MONTH);
} }
} }

View File

@@ -46,107 +46,107 @@ import java.util.Set;
@WebServlet(name = "APIRouter", urlPatterns = "/api/*", loadOnStartup = 11) @WebServlet(name = "APIRouter", urlPatterns = "/api/*", loadOnStartup = 11)
public class APIRouter extends HttpServlet { public class APIRouter extends HttpServlet {
protected static Gson gson = SQLCore.gson; protected static Gson gson = SQLCore.gson;
private Map<String, API> nodes = new HashMap<>(); private Map<String, API> nodes = new HashMap<>();
@Override @Override
public void init() throws ServletException { public void init() throws ServletException {
super.init(); super.init();
try { try {
Reflections reflections = new Reflections(getClass().getPackage().getName()); Reflections reflections = new Reflections(getClass().getPackage().getName());
Set<Class<? extends API>> set = reflections.getSubTypesOf(API.class); Set<Class<? extends API>> set = reflections.getSubTypesOf(API.class);
for (Class<? extends API> clz : set) { for (Class<? extends API> clz : set) {
try { try {
System.out.println("Loading API: " + clz.getName()); System.out.println("Loading API: " + clz.getName());
API obj = clz.newInstance(); API obj = clz.newInstance();
System.out.println("Registered API: " + obj); System.out.println("Registered API: " + obj);
nodes.put(obj.url, obj); nodes.put(obj.url, obj);
} catch (InstantiationException | IllegalAccessException e) { } catch (InstantiationException | IllegalAccessException e) {
e.printStackTrace(); e.printStackTrace();
} }
} }
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
} }
System.out.println("Total " + nodes.size() + " API(s) loaded."); System.out.println("Total " + nodes.size() + " API(s) loaded.");
} }
@Override @Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.setCharacterEncoding("utf-8"); req.setCharacterEncoding("utf-8");
resp.setCharacterEncoding("utf-8"); resp.setCharacterEncoding("utf-8");
resp.addHeader("Content-type", "application/json;charset=utf-8"); resp.addHeader("Content-type", "application/json;charset=utf-8");
resp.addHeader("Access-Control-Allow-Origin", "*"); resp.addHeader("Access-Control-Allow-Origin", "*");
Object obj = null; Object obj = null;
try { try {
API api = nodes.get(req.getPathInfo()); API api = nodes.get(req.getPathInfo());
if (api == null) { if (api == null) {
resp.sendError(HttpServletResponse.SC_FORBIDDEN); resp.sendError(HttpServletResponse.SC_FORBIDDEN);
return; return;
} }
WxSession session = getSession(req); WxSession session = getSession(req);
if (session == null) { if (session == null) {
obj = Error.UNAUTHORIZED; obj = Error.UNAUTHORIZED;
return; return;
} }
if (api.authorize != null) { if (api.authorize != null) {
if (session.getAttribute(Attribute.AUTHORIZED) != api.authorize) { if (session.getAttribute(Attribute.AUTHORIZED) != api.authorize) {
obj = Error.UNAUTHORIZED; obj = Error.UNAUTHORIZED;
return; return;
} }
if (api.access == Access.USER) { if (api.access == Access.USER) {
User u = session.getAttribute(Attribute.USER); User u = session.getAttribute(Attribute.USER);
if (u == null) { if (u == null) {
obj = Error.UNAUTHORIZED; obj = Error.UNAUTHORIZED;
return; return;
} }
} }
if (api.access < Access.USER) { if (api.access < Access.USER) {
Operator op = session.getAttribute(Attribute.OPERATOR); Operator op = session.getAttribute(Attribute.OPERATOR);
if (op == null) { if (op == null) {
obj = Error.UNAUTHORIZED; obj = Error.UNAUTHORIZED;
return; return;
} }
if (op.getAccess() > api.access) { if (op.getAccess() > api.access) {
obj = Error.PERMISSION_DENIED; obj = Error.PERMISSION_DENIED;
return; return;
} }
} }
} }
obj = api.process(req, session); obj = api.process(req, session);
} catch (ParseException | NumberFormatException e) { } catch (ParseException | NumberFormatException e) {
obj = Error.ILLEGAL_PARAMETER; obj = Error.ILLEGAL_PARAMETER;
} catch (HibernateException e) { } catch (HibernateException e) {
e.printStackTrace(); e.printStackTrace();
obj = Error.DATABASE_ERROR; obj = Error.DATABASE_ERROR;
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
obj = Error.INTERNAL_ERROR; obj = Error.INTERNAL_ERROR;
} finally { } finally {
if (!resp.isCommitted()) { if (!resp.isCommitted()) {
try (PrintWriter out = resp.getWriter()) { try (PrintWriter out = resp.getWriter()) {
out.println(gson.toJson(obj)); out.println(gson.toJson(obj));
} }
} }
} }
} }
@Override @Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp); doGet(req, resp);
} }
@Override @Override
protected void doOptions(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { protected void doOptions(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.addHeader("Access-Control-Allow-Method", "POST, GET, OPTIONS"); resp.addHeader("Access-Control-Allow-Method", "POST, GET, OPTIONS");
resp.addHeader("Access-Control-Allow-Origin", "*"); resp.addHeader("Access-Control-Allow-Origin", "*");
resp.setStatus(HttpServletResponse.SC_NO_CONTENT); resp.setStatus(HttpServletResponse.SC_NO_CONTENT);
} }
private static WxSession getSession(HttpServletRequest req) { private static WxSession getSession(HttpServletRequest req) {
String t = req.getParameter("token"); String t = req.getParameter("token");
if (t == null || t.isEmpty()) return null; if (t == null || t.isEmpty()) return null;
return WechatSession.get(t); return WechatSession.get(t);
} }
} }

View File

@@ -30,26 +30,26 @@ import java.util.Map;
*/ */
public class CheckSession extends API { public class CheckSession extends API {
public CheckSession() { public CheckSession() {
url = "/checksession"; url = "/checksession";
access = Access.GUEST; access = Access.GUEST;
authorize = null; authorize = null;
} }
@Override @Override
protected Object process(HttpServletRequest req, WxSession session) throws Exception { protected Object process(HttpServletRequest req, WxSession session) throws Exception {
String more = req.getParameter("more"); String more = req.getParameter("more");
Map<String, Object> result = new HashMap<>(); Map<String, Object> result = new HashMap<>();
result.put(Attribute.AUTHORIZED, session.getAttribute(Attribute.AUTHORIZED)); result.put(Attribute.AUTHORIZED, session.getAttribute(Attribute.AUTHORIZED));
if (more != null) { if (more != null) {
switch (more) { switch (more) {
case "1": case "1":
result.put(Attribute.USER, session.getAttribute(Attribute.USER)); result.put(Attribute.USER, session.getAttribute(Attribute.USER));
result.put(Attribute.OPERATOR, session.getAttribute(Attribute.OPERATOR)); result.put(Attribute.OPERATOR, session.getAttribute(Attribute.OPERATOR));
break; break;
} }
} }
return result; return result;
} }
} }

View File

@@ -24,36 +24,36 @@ import static love.sola.netsupport.config.Lang.lang;
*/ */
public class Error { public class Error {
public static final Error ALREADY_SUBMITTED = new Error(1); public static final Error ALREADY_SUBMITTED = new Error(1);
public static final Object OK = new Object(); public static final Object OK = new Object();
public static final Error PARAMETER_REQUIRED = new Error(-1); public static final Error PARAMETER_REQUIRED = new Error(-1);
public static final Error ILLEGAL_PARAMETER = new Error(-2); public static final Error ILLEGAL_PARAMETER = new Error(-2);
// public static final Error REQUEST_FAILED = new Error(-3); REMOVED // public static final Error REQUEST_FAILED = new Error(-3); REMOVED
public static final Error LENGTH_LIMIT_EXCEEDED = new Error(-4); public static final Error LENGTH_LIMIT_EXCEEDED = new Error(-4);
public static final Error INVALID_PARAMETER = new Error(-5); public static final Error INVALID_PARAMETER = new Error(-5);
public static final Error USER_NOT_FOUND = new Error(-11); public static final Error USER_NOT_FOUND = new Error(-11);
public static final Error TICKET_NOT_FOUND = new Error(-12); public static final Error TICKET_NOT_FOUND = new Error(-12);
public static final Error OPERATOR_NOT_FOUND = new Error(-13); public static final Error OPERATOR_NOT_FOUND = new Error(-13);
public static final Error UNAUTHORIZED = new Error(-20); public static final Error UNAUTHORIZED = new Error(-20);
public static final Error WRONG_PASSWORD = new Error(-22); public static final Error WRONG_PASSWORD = new Error(-22);
public static final Error PERMISSION_DENIED = new Error(-24); public static final Error PERMISSION_DENIED = new Error(-24);
public static final Error INTERNAL_ERROR = new Error(-90); public static final Error INTERNAL_ERROR = new Error(-90);
public static final Error DATABASE_ERROR = new Error(-91); public static final Error DATABASE_ERROR = new Error(-91);
public int errCode; public int errCode;
public String errMsg; public String errMsg;
private Error(int code) { private Error(int code) {
this(code, lang("ERR_" + code)); this(code, lang("ERR_" + code));
} }
public Error(int errCode, String errMsg) { public Error(int errCode, String errMsg) {
this.errCode = errCode; this.errCode = errCode;
this.errMsg = errMsg; this.errMsg = errMsg;
} }
public Error withMsg(String msg) { public Error withMsg(String msg) {
return new Error(errCode, msg); return new Error(errCode, msg);
} }
} }

View File

@@ -46,59 +46,59 @@ import java.io.PrintWriter;
@WebServlet(name = "Login", urlPatterns = "/api/admin/login", loadOnStartup = 12) @WebServlet(name = "Login", urlPatterns = "/api/admin/login", loadOnStartup = 12)
public class Login extends HttpServlet { public class Login extends HttpServlet {
private Gson gson = SQLCore.gson; private Gson gson = SQLCore.gson;
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response); doGet(request, response);
} }
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setCharacterEncoding("utf-8"); request.setCharacterEncoding("utf-8");
response.setCharacterEncoding("utf-8"); response.setCharacterEncoding("utf-8");
response.addHeader("Content-type", "application/json;charset=utf-8"); response.addHeader("Content-type", "application/json;charset=utf-8");
response.addHeader("Access-Control-Allow-Origin", "*"); response.addHeader("Access-Control-Allow-Origin", "*");
PrintWriter out = response.getWriter(); PrintWriter out = response.getWriter();
out.println(gson.toJson(login(request))); out.println(gson.toJson(login(request)));
out.close(); out.close();
} }
private Object login(HttpServletRequest request) { private Object login(HttpServletRequest request) {
try { try {
int oid = Integer.parseInt(request.getParameter("id")); int oid = Integer.parseInt(request.getParameter("id"));
String password = request.getParameter("pass"); String password = request.getParameter("pass");
boolean bypass = request.getParameter("bypass") != null; boolean bypass = request.getParameter("bypass") != null;
Operator op = TableOperator.get(oid); Operator op = TableOperator.get(oid);
if (op == null) if (op == null)
return Error.OPERATOR_NOT_FOUND; return Error.OPERATOR_NOT_FOUND;
else if (op.getAccess() >= Access.NO_LOGIN) else if (op.getAccess() >= Access.NO_LOGIN)
return Error.PERMISSION_DENIED; return Error.PERMISSION_DENIED;
if (!Crypto.check(bypass ? password : RSAUtil.decrypt(password), op.getPassword())) { if (!Crypto.check(bypass ? password : RSAUtil.decrypt(password), op.getPassword())) {
return Error.WRONG_PASSWORD; return Error.WRONG_PASSWORD;
} }
WxSession session = WechatSession.create(); WxSession session = WechatSession.create();
if (bypass) { if (bypass) {
session.setAttribute(Attribute.AUTHORIZED, Command.fromId(Integer.parseInt(request.getParameter("bypass")))); session.setAttribute(Attribute.AUTHORIZED, Command.fromId(Integer.parseInt(request.getParameter("bypass"))));
} else { } else {
session.setAttribute(Attribute.AUTHORIZED, Command.LOGIN); session.setAttribute(Attribute.AUTHORIZED, Command.LOGIN);
} }
session.setAttribute(Attribute.WECHAT, op.getWechat()); session.setAttribute(Attribute.WECHAT, op.getWechat());
session.setAttribute(Attribute.OPERATOR, op); session.setAttribute(Attribute.OPERATOR, op);
if (request.getParameter("bypassuser") != null) { if (request.getParameter("bypassuser") != null) {
User u = TableUser.getById(Long.parseLong(request.getParameter("bypassuser"))); User u = TableUser.getById(Long.parseLong(request.getParameter("bypassuser")));
session.setAttribute(Attribute.USER, u); session.setAttribute(Attribute.USER, u);
session.setAttribute(Attribute.WECHAT, u.getWechatId()); session.setAttribute(Attribute.WECHAT, u.getWechatId());
} }
if (request.getParameter("bypasswechat") != null) { if (request.getParameter("bypasswechat") != null) {
session.setAttribute(Attribute.WECHAT, request.getParameter("bypasswechat")); session.setAttribute(Attribute.WECHAT, request.getParameter("bypasswechat"));
} }
return session.getId(); return session.getId();
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
return Error.INTERNAL_ERROR; return Error.INTERNAL_ERROR;
} }
} }
} }

View File

@@ -32,36 +32,36 @@ import javax.servlet.http.HttpServletRequest;
*/ */
public class GetUser extends API { public class GetUser extends API {
public GetUser() { public GetUser() {
url = "/admin/getuser"; url = "/admin/getuser";
access = Access.LEADER; access = Access.LEADER;
authorize = Command.LOGIN; authorize = Command.LOGIN;
} }
@Override @Override
protected Object process(HttpServletRequest req, WxSession session) throws Exception { protected Object process(HttpServletRequest req, WxSession session) throws Exception {
String id = req.getParameter("id"); String id = req.getParameter("id");
String name = req.getParameter("name"); String name = req.getParameter("name");
if ((id == null || id.isEmpty()) && (name == null || name.isEmpty())) { if ((id == null || id.isEmpty()) && (name == null || name.isEmpty())) {
return Error.PARAMETER_REQUIRED; return Error.PARAMETER_REQUIRED;
} }
if (id != null) { if (id != null) {
try { try {
User u = TableUser.getById(Long.parseLong(id)); User u = TableUser.getById(Long.parseLong(id));
if (u == null) if (u == null)
return Error.USER_NOT_FOUND; return Error.USER_NOT_FOUND;
else else
return u; return u;
} catch (NumberFormatException e) { } catch (NumberFormatException e) {
return Error.ILLEGAL_PARAMETER; return Error.ILLEGAL_PARAMETER;
} }
} else { } else {
User u = TableUser.getByName(name); User u = TableUser.getByName(name);
if (u == null) if (u == null)
return Error.USER_NOT_FOUND; return Error.USER_NOT_FOUND;
else else
return u; return u;
} }
} }
} }

View File

@@ -39,34 +39,34 @@ import javax.servlet.http.HttpServletRequest;
*/ */
public class TicketPush extends API { public class TicketPush extends API {
public TicketPush() { public TicketPush() {
url = "/admin/ticketpush"; url = "/admin/ticketpush";
access = Access.LEADER; access = Access.LEADER;
authorize = Command.LOGIN; authorize = Command.LOGIN;
} }
@Override @Override
protected Object process(HttpServletRequest req, WxSession session) throws Exception { protected Object process(HttpServletRequest req, WxSession session) throws Exception {
String uid = req.getParameter("uid"); String uid = req.getParameter("uid");
String desc = req.getParameter("desc"); String desc = req.getParameter("desc");
if (Checker.hasNull(uid, desc)) { if (Checker.hasNull(uid, desc)) {
return Error.PARAMETER_REQUIRED; return Error.PARAMETER_REQUIRED;
} }
if (desc.length() > Settings.MAX_DESC_LENGTH) { if (desc.length() > Settings.MAX_DESC_LENGTH) {
return Error.LENGTH_LIMIT_EXCEEDED; return Error.LENGTH_LIMIT_EXCEEDED;
} }
Operator op = session.getAttribute(Attribute.OPERATOR); Operator op = session.getAttribute(Attribute.OPERATOR);
try (Session s = SQLCore.sf.openSession()) { try (Session s = SQLCore.sf.openSession()) {
s.beginTransaction(); s.beginTransaction();
User u = s.get(User.class, Long.parseLong(uid)); User u = s.get(User.class, Long.parseLong(uid));
if (u == null) { if (u == null) {
return Error.USER_NOT_FOUND; return Error.USER_NOT_FOUND;
} }
Ticket t = new Ticket(null, u, desc, null, "Pushed By Admin", null, op, Status.UNCHECKED); Ticket t = new Ticket(u, desc, null, "Pushed By Admin", null, op, Status.UNCHECKED);
s.save(t); s.save(t);
s.getTransaction().commit(); s.getTransaction().commit();
return t; return t;
} }
} }
} }

View File

@@ -31,23 +31,23 @@ import java.util.Set;
*/ */
public class DashBoard extends API { public class DashBoard extends API {
public DashBoard() { public DashBoard() {
url = "/root/dashboard"; url = "/root/dashboard";
access = Access.ROOT; access = Access.ROOT;
authorize = Command.LOGIN; authorize = Command.LOGIN;
} }
@Override @Override
protected Object process(HttpServletRequest req, WxSession session) throws Exception { protected Object process(HttpServletRequest req, WxSession session) throws Exception {
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
for (love.sola.netsupport.session.WxSession ws : WechatSession.list()) { for (love.sola.netsupport.session.WxSession ws : WechatSession.list()) {
sb.append("=====").append(ws.getId()).append("=====\n"); sb.append("=====").append(ws.getId()).append("=====\n");
Set<String> e = ws.getAttributeNames(); Set<String> e = ws.getAttributeNames();
for (String key : e) { for (String key : e) {
sb.append(key).append(": ").append(ws.getAttribute(key).toString()).append("\n"); sb.append(key).append(": ").append(ws.getAttribute(key).toString()).append("\n");
} }
} }
return sb.toString(); return sb.toString();
} }
} }

View File

@@ -31,16 +31,16 @@ import javax.servlet.http.HttpServletRequest;
*/ */
public class FlushCache extends API { public class FlushCache extends API {
public FlushCache() { public FlushCache() {
url = "/root/flushcache"; url = "/root/flushcache";
access = Access.ROOT; access = Access.ROOT;
authorize = Command.LOGIN; authorize = Command.LOGIN;
} }
@Override @Override
protected Object process(HttpServletRequest req, WxSession session) throws Exception { protected Object process(HttpServletRequest req, WxSession session) throws Exception {
TableUser.flushCache(); TableUser.flushCache();
return Error.OK; return Error.OK;
} }
} }

View File

@@ -34,30 +34,30 @@ import javax.servlet.http.HttpServletRequest;
*/ */
public class SetPassword extends API { public class SetPassword extends API {
public SetPassword() { public SetPassword() {
url = "/root/setpass"; url = "/root/setpass";
access = Access.ROOT; access = Access.ROOT;
authorize = Command.LOGIN; authorize = Command.LOGIN;
} }
@Override @Override
protected Object process(HttpServletRequest req, WxSession session) throws Exception { protected Object process(HttpServletRequest req, WxSession session) throws Exception {
String id = req.getParameter("id"); String id = req.getParameter("id");
String pass = req.getParameter("pass"); String pass = req.getParameter("pass");
if (pass == null || pass.length() < 8) { if (pass == null || pass.length() < 8) {
return Error.INVALID_PARAMETER; return Error.INVALID_PARAMETER;
} }
try (Session s = SQLCore.sf.openSession()) { try (Session s = SQLCore.sf.openSession()) {
s.beginTransaction(); s.beginTransaction();
Operator op = s.get(Operator.class, Integer.parseInt(id)); Operator op = s.get(Operator.class, Integer.parseInt(id));
if (op == null) { if (op == null) {
return Error.OPERATOR_NOT_FOUND; return Error.OPERATOR_NOT_FOUND;
} }
op.setPassword(Crypto.hash(pass)); op.setPassword(Crypto.hash(pass));
s.update(op); s.update(op);
s.getTransaction().commit(); s.getTransaction().commit();
return Error.OK; return Error.OK;
} }
} }
} }

View File

@@ -38,35 +38,35 @@ import java.util.Date;
*/ */
public class TicketLog extends API { public class TicketLog extends API {
public static SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMdd"); public static SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMdd");
public TicketLog() { public TicketLog() {
url = "/admin/ticketlog"; url = "/admin/ticketlog";
access = Access.MEMBER; access = Access.MEMBER;
authorize = Command.LOGIN; authorize = Command.LOGIN;
} }
@Override @Override
protected Object process(HttpServletRequest req, WxSession session) throws Exception { protected Object process(HttpServletRequest req, WxSession session) throws Exception {
int first; int first;
int limit; int limit;
Date start; Date start;
Date end; Date end;
first = req.getParameter("first") == null ? 0 : Integer.parseInt(req.getParameter("first")); first = req.getParameter("first") == null ? 0 : Integer.parseInt(req.getParameter("first"));
limit = req.getParameter("limit") == null ? 20 : Integer.parseInt(req.getParameter("limit")); limit = req.getParameter("limit") == null ? 20 : Integer.parseInt(req.getParameter("limit"));
start = req.getParameter("start") == null ? getToday() : dateFormat.parse(req.getParameter("start")); start = req.getParameter("start") == null ? getToday() : dateFormat.parse(req.getParameter("start"));
end = req.getParameter("end") == null ? getToday() : dateFormat.parse(req.getParameter("end")); end = req.getParameter("end") == null ? getToday() : dateFormat.parse(req.getParameter("end"));
end = DateUtils.addDays(end, 1); end = DateUtils.addDays(end, 1);
try (Session s = SQLCore.sf.openSession()) { try (Session s = SQLCore.sf.openSession()) {
AuditReader reader = TableTicket.getAuditReader(s); AuditReader reader = TableTicket.getAuditReader(s);
return reader.createQuery() return reader.createQuery()
.forRevisionsOfEntity(Ticket.class, false, true) .forRevisionsOfEntity(Ticket.class, false, true)
.addOrder(AuditEntity.revisionNumber().desc()) .addOrder(AuditEntity.revisionNumber().desc())
.add(AuditEntity.revisionProperty("timestamp").between(start.getTime(), end.getTime())) .add(AuditEntity.revisionProperty("timestamp").between(start.getTime(), end.getTime()))
.setFirstResult(first) .setFirstResult(first)
.setMaxResults(limit) .setMaxResults(limit)
.getResultList(); .getResultList();
} }
} }
} }

View File

@@ -32,22 +32,22 @@ import javax.servlet.http.HttpServletRequest;
*/ */
public class TicketLookup extends API { public class TicketLookup extends API {
public TicketLookup() { public TicketLookup() {
url = "/admin/ticketlookup"; url = "/admin/ticketlookup";
access = Access.MEMBER; access = Access.MEMBER;
authorize = Command.LOGIN; authorize = Command.LOGIN;
} }
@Override @Override
protected Object process(HttpServletRequest req, WxSession session) throws Exception { protected Object process(HttpServletRequest req, WxSession session) throws Exception {
Operator op = session.getAttribute(Attribute.OPERATOR); Operator op = session.getAttribute(Attribute.OPERATOR);
int block; int block;
if (req.getParameter("block") != null) { if (req.getParameter("block") != null) {
block = Integer.parseInt(req.getParameter("block")); block = Integer.parseInt(req.getParameter("block"));
} else { } else {
block = op.getBlock(); block = op.getBlock();
} }
return TableTicket.unsolvedByBlock(block); return TableTicket.unsolvedByBlock(block);
} }
} }

View File

@@ -31,19 +31,19 @@ import javax.servlet.http.HttpServletRequest;
*/ */
public class TicketTrack extends API { public class TicketTrack extends API {
public TicketTrack() { public TicketTrack() {
url = "/admin/tickettrack"; url = "/admin/tickettrack";
access = Access.MEMBER; access = Access.MEMBER;
authorize = Command.LOGIN; authorize = Command.LOGIN;
} }
@Override @Override
protected Object process(HttpServletRequest req, WxSession session) throws Exception { protected Object process(HttpServletRequest req, WxSession session) throws Exception {
String tid = req.getParameter("id"); String tid = req.getParameter("id");
if (tid == null) { if (tid == null) {
return Error.PARAMETER_REQUIRED; return Error.PARAMETER_REQUIRED;
} }
return TableTicket.track(Integer.parseInt(tid)); return TableTicket.track(Integer.parseInt(tid));
} }
} }

View File

@@ -37,32 +37,32 @@ import java.util.Date;
*/ */
public class TicketUpdate extends API { public class TicketUpdate extends API {
public TicketUpdate() { public TicketUpdate() {
url = "/admin/ticketupdate"; url = "/admin/ticketupdate";
access = Access.MEMBER; access = Access.MEMBER;
authorize = Command.LOGIN; authorize = Command.LOGIN;
} }
@Override @Override
protected Object process(HttpServletRequest req, WxSession session) throws Exception { protected Object process(HttpServletRequest req, WxSession session) throws Exception {
String ticket = req.getParameter("ticket"); String ticket = req.getParameter("ticket");
String remark = req.getParameter("remark"); String remark = req.getParameter("remark");
String status = req.getParameter("status"); String status = req.getParameter("status");
if (Checker.hasNull(ticket, remark, status)) return Error.PARAMETER_REQUIRED; if (Checker.hasNull(ticket, remark, status)) return Error.PARAMETER_REQUIRED;
try (Session s = SQLCore.sf.openSession()) { try (Session s = SQLCore.sf.openSession()) {
Operator op = session.getAttribute(Attribute.OPERATOR); Operator op = session.getAttribute(Attribute.OPERATOR);
Ticket t = s.get(Ticket.class, Integer.parseInt(ticket)); Ticket t = s.get(Ticket.class, Integer.parseInt(ticket));
if (t == null) { if (t == null) {
return Error.TICKET_NOT_FOUND; return Error.TICKET_NOT_FOUND;
} }
t.setOperator(op); t.setOperator(op);
t.setRemark(remark); t.setRemark(remark);
t.setStatus(Integer.parseInt(status)); t.setStatus(Integer.parseInt(status));
t.setUpdateTime(new Date()); t.setUpdateTime(new Date());
s.beginTransaction(); s.beginTransaction();
s.update(t); s.update(t);
s.getTransaction().commit(); s.getTransaction().commit();
return t; return t;
} }
} }
} }

View File

@@ -41,64 +41,62 @@ import java.util.Date;
*/ */
public class ToolsCheck extends API { public class ToolsCheck extends API {
public ToolsCheck() { public ToolsCheck() {
url = "/admin/toolscheck"; url = "/admin/toolscheck";
access = Access.MEMBER; access = Access.MEMBER;
authorize = Command.LOGIN; authorize = Command.LOGIN;
} }
@Override @Override
protected Object process(HttpServletRequest req, WxSession session) throws Exception { protected Object process(HttpServletRequest req, WxSession session) throws Exception {
if (req.getMethod().equals("GET")) { if (req.getMethod().equals("GET")) {
return query(req, session); return query(req, session);
} else if (req.getMethod().equals("POST")) { } else if (req.getMethod().equals("POST")) {
return submit(req, session); return submit(req, session);
} }
return null; return null;
} }
private Object submit(HttpServletRequest req, WxSession session) { private Object submit(HttpServletRequest req, WxSession session) {
Operator op = session.getAttribute(Attribute.OPERATOR); Operator op = session.getAttribute(Attribute.OPERATOR);
int status = Integer.valueOf(getParameterWithDefault(req.getParameter("status"), "0")); int status = Integer.valueOf(getParameterWithDefault(req.getParameter("status"), "0"));
String remark = req.getParameter("remark"); String remark = req.getParameter("remark");
if (status != 0 && StringUtils.isBlank(remark)) { if (status != 0 && StringUtils.isBlank(remark)) {
return Error.PARAMETER_REQUIRED; return Error.PARAMETER_REQUIRED;
} }
try (Session s = SQLCore.sf.openSession()) { try (Session s = SQLCore.sf.openSession()) {
s.beginTransaction(); s.beginTransaction();
s.save(new love.sola.netsupport.pojo.ToolsCheck( s.save(new love.sola.netsupport.pojo.ToolsCheck(
null, op,
op, op.getBlock(),
op.getBlock(), new Date(),
new Date(), status,
status, remark
remark ));
) s.getTransaction().commit();
); return Error.OK;
s.getTransaction().commit(); }
return Error.OK; }
}
}
private Object query(HttpServletRequest req, WxSession session) { private Object query(HttpServletRequest req, WxSession session) {
int status = Integer.valueOf(getParameterWithDefault(req.getParameter("status"), "0")); int status = Integer.valueOf(getParameterWithDefault(req.getParameter("status"), "0"));
Date after = getDay(getParameterAsDate(req.getParameter("after"), getToday())); Date after = getDay(getParameterAsDate(req.getParameter("after"), getToday()));
Date before = getDay(getParameterAsDate(req.getParameter("before"), getToday())); Date before = getDay(getParameterAsDate(req.getParameter("before"), getToday()));
before = DateUtils.addDays(before, 1); before = DateUtils.addDays(before, 1);
int block = Integer.valueOf(getParameterWithDefault(req.getParameter("block"), "0")); int block = Integer.valueOf(getParameterWithDefault(req.getParameter("block"), "0"));
try (Session s = SQLCore.sf.openSession()) { try (Session s = SQLCore.sf.openSession()) {
Criteria query = s.createCriteria(love.sola.netsupport.pojo.ToolsCheck.class); Criteria query = s.createCriteria(love.sola.netsupport.pojo.ToolsCheck.class);
query.add( query.add(
Restrictions.sqlRestriction( Restrictions.sqlRestriction(
"{alias}.status & ? = ?", "{alias}.status & ? = ?",
new Object[]{status, status}, new Object[]{status, status},
new Type[]{IntegerType.INSTANCE, IntegerType.INSTANCE} new Type[]{IntegerType.INSTANCE, IntegerType.INSTANCE}
) )
); );
query.add(Restrictions.between("checkTime", after, before)); query.add(Restrictions.between("checkTime", after, before));
if (block != 0) query.add(Restrictions.eq("block", block)); if (block != 0) query.add(Restrictions.eq("block", block));
return query.list(); return query.list();
} }
} }
} }

View File

@@ -37,39 +37,39 @@ import static love.sola.netsupport.util.Checker.*;
*/ */
public class ProfileModify extends API { public class ProfileModify extends API {
public ProfileModify() { public ProfileModify() {
url = "/profilemodify"; url = "/profilemodify";
access = Access.USER; access = Access.USER;
authorize = Command.PROFILE; authorize = Command.PROFILE;
} }
@Override @Override
protected Object process(HttpServletRequest req, WxSession session) throws Exception { protected Object process(HttpServletRequest req, WxSession session) throws Exception {
User u = session.getAttribute(Attribute.USER); User u = session.getAttribute(Attribute.USER);
ISP isp = checkISP(req.getParameter("isp")); ISP isp = checkISP(req.getParameter("isp"));
String netAccount = checkNetAccount(req.getParameter("username"), isp); String netAccount = checkNetAccount(req.getParameter("username"), isp);
int block = checkBlock(req.getParameter("block")); int block = checkBlock(req.getParameter("block"));
int room = checkRoom(req.getParameter("room"), block); int room = checkRoom(req.getParameter("room"), block);
long phone = checkPhoneNumber(req.getParameter("phone")); long phone = checkPhoneNumber(req.getParameter("phone"));
if (room == -1) if (room == -1)
return Error.INVALID_PARAMETER.withMsg("Invalid_Room"); return Error.INVALID_PARAMETER.withMsg("Invalid_Room");
if (phone == -1) if (phone == -1)
return Error.INVALID_PARAMETER.withMsg("Invalid_Phone_Number"); return Error.INVALID_PARAMETER.withMsg("Invalid_Phone_Number");
if (netAccount == null) if (netAccount == null)
return Error.INVALID_PARAMETER.withMsg("Invalid_Account"); return Error.INVALID_PARAMETER.withMsg("Invalid_Account");
u.setIsp(isp); u.setIsp(isp);
u.setNetAccount(netAccount); u.setNetAccount(netAccount);
u.setBlock(block); u.setBlock(block);
u.setRoom(room); u.setRoom(room);
u.setPhone(phone); u.setPhone(phone);
try { try {
TableUser.update(u); TableUser.update(u);
} catch (ConstraintViolationException e) { } catch (ConstraintViolationException e) {
String dupKey = e.getConstraintName(); String dupKey = e.getConstraintName();
return Error.INVALID_PARAMETER.withMsg("Duplicated_" + dupKey.toUpperCase()); return Error.INVALID_PARAMETER.withMsg("Duplicated_" + dupKey.toUpperCase());
} }
session.invalidate(); session.invalidate();
return Error.OK; return Error.OK;
} }
} }

View File

@@ -37,56 +37,56 @@ import static love.sola.netsupport.util.Checker.*;
*/ */
public class Register extends API { public class Register extends API {
public Register() { public Register() {
url = "/register"; url = "/register";
access = Access.GUEST; access = Access.GUEST;
authorize = Command.REGISTER; authorize = Command.REGISTER;
} }
@Override @Override
protected Object process(HttpServletRequest req, WxSession session) throws Exception { protected Object process(HttpServletRequest req, WxSession session) throws Exception {
String wechat = session.getAttribute(Attribute.WECHAT); String wechat = session.getAttribute(Attribute.WECHAT);
if (wechat == null) { if (wechat == null) {
return Error.UNAUTHORIZED; return Error.UNAUTHORIZED;
} }
ISP isp = checkISP(req.getParameter("isp")); ISP isp = checkISP(req.getParameter("isp"));
int block = checkBlock(req.getParameter("block")); int block = checkBlock(req.getParameter("block"));
return register( return register(
checkStudentId(req.getParameter("sid")), checkStudentId(req.getParameter("sid")),
req.getParameter("name"), req.getParameter("name"),
isp, isp,
checkNetAccount(req.getParameter("username"), isp), checkNetAccount(req.getParameter("username"), isp),
block, block,
checkRoom(req.getParameter("room"), block), checkRoom(req.getParameter("room"), block),
checkPhoneNumber(req.getParameter("phone")), checkPhoneNumber(req.getParameter("phone")),
wechat); wechat);
} }
private Object register(long sid, String name, ISP isp, String netAccount, int block, int room, long phone, String wechat) { private Object register(long sid, String name, ISP isp, String netAccount, int block, int room, long phone, String wechat) {
if (sid == -1) return Error.INVALID_PARAMETER.withMsg("Invalid_Student_Id"); if (sid == -1) return Error.INVALID_PARAMETER.withMsg("Invalid_Student_Id");
if (name == null) return Error.INVALID_PARAMETER.withMsg("Invalid_Name"); if (name == null) return Error.INVALID_PARAMETER.withMsg("Invalid_Name");
if (isp == null) return Error.INVALID_PARAMETER.withMsg("Invalid_ISP"); if (isp == null) return Error.INVALID_PARAMETER.withMsg("Invalid_ISP");
if (netAccount == null) return Error.INVALID_PARAMETER.withMsg("Invalid_Account"); if (netAccount == null) return Error.INVALID_PARAMETER.withMsg("Invalid_Account");
if (block == -1) return Error.INVALID_PARAMETER.withMsg("Invalid_Block"); if (block == -1) return Error.INVALID_PARAMETER.withMsg("Invalid_Block");
if (room == -1) return Error.INVALID_PARAMETER.withMsg("Invalid_Room"); if (room == -1) return Error.INVALID_PARAMETER.withMsg("Invalid_Room");
if (phone == -1) return Error.INVALID_PARAMETER.withMsg("Invalid_Phone_Number"); if (phone == -1) return Error.INVALID_PARAMETER.withMsg("Invalid_Phone_Number");
User user = TableUser.getById(sid); User user = TableUser.getById(sid);
if (user == null) return Error.INVALID_PARAMETER.withMsg("Invalid_Student_Id"); if (user == null) return Error.INVALID_PARAMETER.withMsg("Invalid_Student_Id");
if (!user.getName().equals(name)) return Error.INVALID_PARAMETER.withMsg("Invalid_Name"); if (!user.getName().equals(name)) return Error.INVALID_PARAMETER.withMsg("Invalid_Name");
if (user.getWechatId() != null) return Error.INVALID_PARAMETER.withMsg("User_Already_Registered"); if (user.getWechatId() != null) return Error.INVALID_PARAMETER.withMsg("User_Already_Registered");
user.setIsp(isp); user.setIsp(isp);
user.setNetAccount(netAccount); user.setNetAccount(netAccount);
user.setBlock(block); user.setBlock(block);
user.setRoom(room); user.setRoom(room);
user.setPhone(phone); user.setPhone(phone);
user.setWechatId(wechat); user.setWechatId(wechat);
try { try {
TableUser.update(user); TableUser.update(user);
} catch (ConstraintViolationException e) { } catch (ConstraintViolationException e) {
String dupKey = e.getConstraintName(); String dupKey = e.getConstraintName();
return Error.INVALID_PARAMETER.withMsg("Duplicated_" + dupKey.toUpperCase()); // PHONE ACCOUNT WECHAT return Error.INVALID_PARAMETER.withMsg("Duplicated_" + dupKey.toUpperCase()); // PHONE ACCOUNT WECHAT
} }
return Error.OK; return Error.OK;
} }
} }

View File

@@ -37,33 +37,33 @@ import javax.servlet.http.HttpServletRequest;
*/ */
public class TicketQuery extends API { public class TicketQuery extends API {
public TicketQuery() { public TicketQuery() {
url = "/ticketquery"; url = "/ticketquery";
access = Access.USER; access = Access.USER;
authorize = Command.QUERY; authorize = Command.QUERY;
} }
@Override @Override
protected Object process(HttpServletRequest req, WxSession session) throws Exception { protected Object process(HttpServletRequest req, WxSession session) throws Exception {
try (Session s = SQLCore.sf.openSession()) { try (Session s = SQLCore.sf.openSession()) {
User u = session.getAttribute(Attribute.USER); User u = session.getAttribute(Attribute.USER);
Criteria c = s.createCriteria(Ticket.class); Criteria c = s.createCriteria(Ticket.class);
int first = req.getParameter("offset") == null ? 0 : Integer.parseInt(req.getParameter("offset")); int first = req.getParameter("offset") == null ? 0 : Integer.parseInt(req.getParameter("offset"));
int limit = req.getParameter("limit") == null ? 5 : Integer.parseInt(req.getParameter("limit")); int limit = req.getParameter("limit") == null ? 5 : Integer.parseInt(req.getParameter("limit"));
c.setFirstResult(first); c.setFirstResult(first);
c.setMaxResults(limit); c.setMaxResults(limit);
c.addOrder(Order.desc(Ticket.PROPERTY_SUBMIT_TIME)); c.addOrder(Order.desc(Ticket.PROPERTY_SUBMIT_TIME));
c.add(Restrictions.eq(Ticket.PROPERTY_USER, u)); c.add(Restrictions.eq(Ticket.PROPERTY_USER, u));
if (req.getParameter("status") != null) { if (req.getParameter("status") != null) {
c.add(Restrictions.eq(Ticket.PROPERTY_STATUS, Integer.parseInt(req.getParameter("status")))); c.add(Restrictions.eq(Ticket.PROPERTY_STATUS, Integer.parseInt(req.getParameter("status"))));
} else if (req.getParameter("statusl") != null && req.getParameter("statush") != null) { } else if (req.getParameter("statusl") != null && req.getParameter("statush") != null) {
c.add(Restrictions.between(Ticket.PROPERTY_STATUS, c.add(Restrictions.between(Ticket.PROPERTY_STATUS,
Integer.parseInt(req.getParameter("statusl")), Integer.parseInt(req.getParameter("statusl")),
Integer.parseInt(req.getParameter("statush")) Integer.parseInt(req.getParameter("statush"))
)); ));
} }
return c.list(); return c.list();
} }
} }
} }

View File

@@ -37,37 +37,37 @@ import javax.servlet.http.HttpServletRequest;
*/ */
public class TicketSubmit extends API { public class TicketSubmit extends API {
public TicketSubmit() { public TicketSubmit() {
url = "/ticketsubmit"; url = "/ticketsubmit";
access = Access.USER; access = Access.USER;
authorize = Command.SUBMIT; authorize = Command.SUBMIT;
} }
@Override @Override
protected Object process(HttpServletRequest req, WxSession session) throws Exception { protected Object process(HttpServletRequest req, WxSession session) throws Exception {
String desc = req.getParameter("desc"); String desc = req.getParameter("desc");
if (desc == null || desc.isEmpty()) { if (desc == null || desc.isEmpty()) {
return Error.PARAMETER_REQUIRED; return Error.PARAMETER_REQUIRED;
} }
if (desc.length() > Settings.MAX_DESC_LENGTH) { if (desc.length() > Settings.MAX_DESC_LENGTH) {
return Error.LENGTH_LIMIT_EXCEEDED; return Error.LENGTH_LIMIT_EXCEEDED;
} }
try (Session s = SQLCore.sf.openSession()) { try (Session s = SQLCore.sf.openSession()) {
User u = session.getAttribute(Attribute.USER); User u = session.getAttribute(Attribute.USER);
if (TableTicket.hasOpen(u)) { if (TableTicket.hasOpen(u)) {
session.invalidate(); session.invalidate();
return Error.ALREADY_SUBMITTED; return Error.ALREADY_SUBMITTED;
} }
Ticket t = new Ticket(); Ticket t = new Ticket();
t.setUser(u); t.setUser(u);
t.setDescription(desc); t.setDescription(desc);
t.setStatus(0); t.setStatus(0);
s.beginTransaction(); s.beginTransaction();
s.save(t); s.save(t);
s.getTransaction().commit(); s.getTransaction().commit();
session.invalidate(); session.invalidate();
return Error.OK; return Error.OK;
} }
} }
} }

View File

@@ -40,45 +40,45 @@ import java.util.Map;
@WebServlet(name = "OAuth2", urlPatterns = "/oauth2/callback", loadOnStartup = 21, asyncSupported = true) @WebServlet(name = "OAuth2", urlPatterns = "/oauth2/callback", loadOnStartup = 21, asyncSupported = true)
public class OAuth2 extends HttpServlet { public class OAuth2 extends HttpServlet {
private static Map<String, OAuth2Handler> oAuth2HandlerMap = new HashMap<>(); private static Map<String, OAuth2Handler> oAuth2HandlerMap = new HashMap<>();
/** /**
* for {@link love.sola.netsupport.wechat.WxMpServlet#registerCommands} * for {@link love.sola.netsupport.wechat.WxMpServlet#registerCommands}
* *
* @param state the state key from open platform callback. * @param state the state key from open platform callback.
* @param handler handler * @param handler handler
*/ */
public static void registerOAuth2Handler(String state, OAuth2Handler handler) { public static void registerOAuth2Handler(String state, OAuth2Handler handler) {
oAuth2HandlerMap.put(state, handler); oAuth2HandlerMap.put(state, handler);
} }
@Override @Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
AsyncContext actx = req.startAsync(); AsyncContext actx = req.startAsync();
String code = req.getParameter("code"); String code = req.getParameter("code");
String state = req.getParameter("state"); String state = req.getParameter("state");
if (Checker.hasNull(code, state)) { if (Checker.hasNull(code, state)) {
resp.sendError(HttpServletResponse.SC_FORBIDDEN); resp.sendError(HttpServletResponse.SC_FORBIDDEN);
return; return;
} }
OAuth2Handler handler = oAuth2HandlerMap.get(state); OAuth2Handler handler = oAuth2HandlerMap.get(state);
if (handler == null) { if (handler == null) {
resp.sendError(HttpServletResponse.SC_NOT_IMPLEMENTED); resp.sendError(HttpServletResponse.SC_NOT_IMPLEMENTED);
return; return;
} }
actx.start(() -> { actx.start(() -> {
try { try {
WxMpService wxMpService = WxMpServlet.instance.wxMpService; WxMpService wxMpService = WxMpServlet.instance.wxMpService;
WxMpOAuth2AccessToken token = wxMpService.oauth2getAccessToken(code); WxMpOAuth2AccessToken token = wxMpService.oauth2getAccessToken(code);
String wechat = token.getOpenId(); String wechat = token.getOpenId();
WxSession session = WechatSession.create(); WxSession session = WechatSession.create();
handler.onOAuth2(actx, (HttpServletResponse) actx.getResponse(), wechat, session); handler.onOAuth2(actx, (HttpServletResponse) actx.getResponse(), wechat, session);
actx.complete(); actx.complete();
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
} }
}); });
} }
} }

View File

@@ -27,6 +27,6 @@ import javax.servlet.http.HttpServletResponse;
*/ */
public interface OAuth2Handler { public interface OAuth2Handler {
void onOAuth2(AsyncContext actx, HttpServletResponse resp, String user, WxSession session); void onOAuth2(AsyncContext actx, HttpServletResponse resp, String user, WxSession session);
} }

View File

@@ -17,7 +17,6 @@
package love.sola.netsupport.config; package love.sola.netsupport.config;
import lombok.Data;
import org.yaml.snakeyaml.Yaml; import org.yaml.snakeyaml.Yaml;
import java.io.InputStream; import java.io.InputStream;
@@ -30,27 +29,31 @@ import java.util.regex.Pattern;
*/ */
public class Cortana { public class Cortana {
public static List<Compiled> entries; public static List<Compiled> entries;
public static void load() { public static void load() {
InputStream in = Lang.class.getClassLoader().getResourceAsStream("cortana.yml"); InputStream in = Lang.class.getClassLoader().getResourceAsStream("cortana.yml");
RawConfig root = new Yaml().loadAs(in, RawConfig.class); RawConfig root = new Yaml().loadAs(in, RawConfig.class);
} }
static class Compiled { static class Compiled {
Pattern[] patterns; Pattern[] patterns;
String[] replies; String[] replies;
} }
@Data public static class Rule {
public static class Rule { String[] regexp;
String[] regexp; String[] replies;
String[] replies;
}
@Data public Rule() {
public static class RawConfig { }
Map<String, Rule> rules; }
}
public static class RawConfig {
Map<String, Rule> rules;
public RawConfig() {
}
}
} }

View File

@@ -29,29 +29,29 @@ import java.util.Map;
*/ */
public class Lang { public class Lang {
public static Map<String, String> messages; public static Map<String, String> messages;
public static Map<String, MessageFormat> format_cache = new HashMap<>(32); public static Map<String, MessageFormat> format_cache = new HashMap<>(32);
static { static {
InputStream in = Lang.class.getClassLoader().getResourceAsStream("lang.yml"); InputStream in = Lang.class.getClassLoader().getResourceAsStream("lang.yml");
//noinspection unchecked //noinspection unchecked
messages = new Yaml().loadAs(in, Map.class); messages = new Yaml().loadAs(in, Map.class);
} }
public static String lang(String key) { public static String lang(String key) {
String value = messages.get(key); String value = messages.get(key);
return value == null ? "!!" + key + "!!" : value; return value == null ? "!!" + key + "!!" : value;
} }
public static String format(String key, Object... args) { public static String format(String key, Object... args) {
MessageFormat cache = format_cache.get(key); MessageFormat cache = format_cache.get(key);
if (cache != null) { if (cache != null) {
return cache.format(args); return cache.format(args);
} else { } else {
cache = new MessageFormat(lang(key)); cache = new MessageFormat(lang(key));
format_cache.put(key, cache); format_cache.put(key, cache);
return cache.format(args); return cache.format(args);
} }
} }
} }

View File

@@ -17,40 +17,48 @@
package love.sola.netsupport.config; package love.sola.netsupport.config;
import lombok.ToString;
import love.sola.netsupport.sql.TableConfig; import love.sola.netsupport.sql.TableConfig;
/** /**
* @author Sola {@literal <dev@sola.love>} * @author Sola {@literal <dev@sola.love>}
*/ */
@ToString
public class Settings { public class Settings {
public static final int MAX_DESC_LENGTH = 255; public static final int MAX_DESC_LENGTH = 255;
public static Settings I; public static Settings I;
static { static {
I = TableConfig.getSettings(); I = TableConfig.getSettings();
} }
// -------------------------------------------- // public String Wechat_AppId;
// CONFIGURATIONS public String Wechat_Secret;
// -------------------------------------------- // public String Wechat_Token;
public String Wechat_AppId; public String Wechat_AesKey;
public String Wechat_Secret;
public String Wechat_Token;
public String Wechat_AesKey;
public int Check_Spam_Cache_Expire_Time; public int Check_Spam_Cache_Expire_Time;
public int Check_Spam_Interval; public int Check_Spam_Interval;
public int User_Session_Max_Inactive; public int User_Session_Max_Inactive;
public int User_Wechat_Cache_Expire_Time; public int User_Wechat_Cache_Expire_Time;
//No arg constructor for Yaml.loadAs //No arg constructor for Yaml.loadAs
public Settings() { public Settings() {
I = this; I = this;
} }
@Override
public String toString() {
return "Settings{" +
"Wechat_AppId='" + Wechat_AppId + '\'' +
", Wechat_Secret='" + Wechat_Secret + '\'' +
", Wechat_Token='" + Wechat_Token + '\'' +
", Wechat_AesKey='" + Wechat_AesKey + '\'' +
", Check_Spam_Cache_Expire_Time=" + Check_Spam_Cache_Expire_Time +
", Check_Spam_Interval=" + Check_Spam_Interval +
", User_Session_Max_Inactive=" + User_Session_Max_Inactive +
", User_Wechat_Cache_Expire_Time=" + User_Wechat_Cache_Expire_Time +
'}';
}
} }

View File

@@ -19,7 +19,6 @@ package love.sola.netsupport.config;
import com.thoughtworks.xstream.XStream; import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.annotations.XStreamAlias; import com.thoughtworks.xstream.annotations.XStreamAlias;
import lombok.ToString;
import me.chanjar.weixin.common.util.xml.XStreamInitializer; import me.chanjar.weixin.common.util.xml.XStreamInitializer;
import me.chanjar.weixin.mp.api.WxMpInMemoryConfigStorage; import me.chanjar.weixin.mp.api.WxMpInMemoryConfigStorage;
@@ -29,15 +28,14 @@ import java.io.InputStream;
* @author chanjarster * @author chanjarster
*/ */
@XStreamAlias("wechat-config") @XStreamAlias("wechat-config")
@ToString
public class WxMpXmlInMemoryConfigStorage extends WxMpInMemoryConfigStorage { public class WxMpXmlInMemoryConfigStorage extends WxMpInMemoryConfigStorage {
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public static <T> T fromXml(Class<T> clazz, InputStream is) { public static <T> T fromXml(Class<T> clazz, InputStream is) {
XStream xstream = XStreamInitializer.getInstance(); XStream xstream = XStreamInitializer.getInstance();
xstream.alias("wechat-config", clazz); xstream.alias("wechat-config", clazz);
xstream.processAnnotations(clazz); xstream.processAnnotations(clazz);
return (T) xstream.fromXML(is); return (T) xstream.fromXML(is);
} }
} }

View File

@@ -28,40 +28,40 @@ import static love.sola.netsupport.config.Lang.lang;
*/ */
public class Access { public class Access {
public static final int GOD_MODE = -1; public static final int GOD_MODE = -1;
public static final int ROOT = 0; public static final int ROOT = 0;
public static final int MANAGER = 1; public static final int MANAGER = 1;
public static final int CO_MANAGER = 2; public static final int CO_MANAGER = 2;
public static final int LEADER = 3; public static final int LEADER = 3;
public static final int CO_LEADER = 4; public static final int CO_LEADER = 4;
public static final int ELITE = 5; public static final int ELITE = 5;
public static final int ELDER = 6; public static final int ELDER = 6;
public static final int MEMBER = 7; public static final int MEMBER = 7;
public static final int PRE_MEMBER = 8; public static final int PRE_MEMBER = 8;
public static final int NO_LOGIN = 9; public static final int NO_LOGIN = 9;
public static final int USER = 10; public static final int USER = 10;
public static final int GUEST = 11; public static final int GUEST = 11;
public static final Map<Integer, String> inverseMap = new HashMap<>(); public static final Map<Integer, String> inverseMap = new HashMap<>();
static { static {
System.out.println("Loading Access..."); System.out.println("Loading Access...");
for (Field field : Access.class.getDeclaredFields()) { for (Field field : Access.class.getDeclaredFields()) {
if (field.getType().isAssignableFrom(Integer.TYPE)) { if (field.getType().isAssignableFrom(Integer.TYPE)) {
try { try {
inverseMap.put((Integer) field.get(null), field.getName()); inverseMap.put((Integer) field.get(null), field.getName());
} catch (IllegalAccessException e) { } catch (IllegalAccessException e) {
e.printStackTrace(); e.printStackTrace();
} }
} }
} }
} }
public static String getLocalized(int access) { public static String getLocalized(int access) {
if (inverseMap.containsKey(access)) { if (inverseMap.containsKey(access)) {
return lang("ACCESS_" + inverseMap.get(access)); return lang("ACCESS_" + inverseMap.get(access));
} }
return null; return null;
} }
} }

View File

@@ -22,9 +22,9 @@ package love.sola.netsupport.enums;
*/ */
public class Attribute { public class Attribute {
public static final String AUTHORIZED = "authorized"; public static final String AUTHORIZED = "authorized";
public static final String WECHAT = "wechat"; public static final String WECHAT = "wechat";
public static final String OPERATOR = "operator"; public static final String OPERATOR = "operator";
public static final String USER = "user"; public static final String USER = "user";
} }

View File

@@ -26,61 +26,61 @@ import java.util.Map;
*/ */
public class Block { public class Block {
public static final int QT_18 = 10; public static final int QT_18 = 10;
public static final int QT_19 = 11; public static final int QT_19 = 11;
public static final int QT_16 = 12; public static final int QT_16 = 12;
public static final int QT_17 = 13; public static final int QT_17 = 13;
public static final int BM_7 = 20; public static final int BM_7 = 20;
public static final int BM_8 = 21; public static final int BM_8 = 21;
public static final int BM_9 = 22; public static final int BM_9 = 22;
public static final int BM_10 = 23; public static final int BM_10 = 23;
public static final int BM_11 = 24; public static final int BM_11 = 24;
public static final int DM_12 = 30; public static final int DM_12 = 30;
public static final int DM_13 = 31; public static final int DM_13 = 31;
public static final int DM_14 = 32; public static final int DM_14 = 32;
public static final int DM_15 = 33; public static final int DM_15 = 33;
public static final int DM_20 = 34; public static final int DM_20 = 34;
public static final int DM_21 = 35; public static final int DM_21 = 35;
public static final int XH_A = 40; public static final int XH_A = 40;
public static final int XH_B = 41; public static final int XH_B = 41;
public static final int XH_C = 42; public static final int XH_C = 42;
public static final int XH_D = 43; public static final int XH_D = 43;
public static final int FX_1 = 50; public static final int FX_1 = 50;
public static final int FX_2 = 51; public static final int FX_2 = 51;
public static final int FX_3 = 52; public static final int FX_3 = 52;
public static final int FX_4 = 53; public static final int FX_4 = 53;
public static final int FX_5 = 54; public static final int FX_5 = 54;
public static final int FX_6 = 55; public static final int FX_6 = 55;
public static final int BS_1 = 60; public static final int BS_1 = 60;
public static final int BS_2 = 61; public static final int BS_2 = 61;
public static final int BS_3 = 62; public static final int BS_3 = 62;
public static final int BS_4 = 63; public static final int BS_4 = 63;
public static final int BS_5 = 64; public static final int BS_5 = 64;
public static final int BS_6 = 65; public static final int BS_6 = 65;
public static final int BS_7 = 66; public static final int BS_7 = 66;
public static final int BS_8 = 67; public static final int BS_8 = 67;
public static final int BS_9 = 68; public static final int BS_9 = 68;
public static final int ZH = 80; public static final int ZH = 80;
public static final Map<Integer, String> inverseMap = new HashMap<>(); public static final Map<Integer, String> inverseMap = new HashMap<>();
static { static {
System.out.println("Loading Blocks..."); System.out.println("Loading Blocks...");
for (Field field : Block.class.getDeclaredFields()) { for (Field field : Block.class.getDeclaredFields()) {
if (field.getType().isAssignableFrom(Integer.TYPE)) { if (field.getType().isAssignableFrom(Integer.TYPE)) {
try { try {
inverseMap.put((Integer) field.get(null), field.getName()); inverseMap.put((Integer) field.get(null), field.getName());
} catch (IllegalAccessException e) { } catch (IllegalAccessException e) {
e.printStackTrace(); e.printStackTrace();
} }
} }
} }
} }
private static final int[][] AVAILABLE = new int[100][0]; private static final int[][] AVAILABLE = new int[100][0];
static { static {
// @formatter:off // @formatter:off
// -------------------------------------------- // // -------------------------------------------- //
// THANKS DATA PROVIDED BY Lai Juncheng // THANKS DATA PROVIDED BY Lai Juncheng
// -------------------------------------------- // // -------------------------------------------- //
@@ -120,14 +120,14 @@ public class Block {
AVAILABLE[BS_9] = new int[]{103, 203, 302}; AVAILABLE[BS_9] = new int[]{103, 203, 302};
AVAILABLE[ZH] = new int[]{199, 299, 399, 499, 599, 699, 799, 899, 999, 1099, 1199, 1299, 1399}; AVAILABLE[ZH] = new int[]{199, 299, 399, 499, 599, 699, 799, 899, 999, 1099, 1199, 1299, 1399};
// @formatter:on // @formatter:on
} }
public static boolean checkRoom(int block, int room) { public static boolean checkRoom(int block, int room) {
int floor = room / 100; int floor = room / 100;
if (floor == 0 || room % 100 == 0) return false; if (floor == 0 || room % 100 == 0) return false;
if (block < 0 || block >= AVAILABLE.length) return false; if (block < 0 || block >= AVAILABLE.length) return false;
if (AVAILABLE[block].length < floor) return false; if (AVAILABLE[block].length < floor) return false;
return room <= AVAILABLE[block][floor - 1]; return room <= AVAILABLE[block][floor - 1];
} }
} }

View File

@@ -27,49 +27,49 @@ import static love.sola.netsupport.config.Lang.lang;
*/ */
public enum ISP { public enum ISP {
TELECOM(1, "^1[3|4|5|7|8][0-9]{9}$"), TELECOM(1, "^1[3|4|5|7|8][0-9]{9}$"),
UNICOM(2, "ZSZJLAN[0-9]{10}@16900\\.gd"), UNICOM(2, "ZSZJLAN[0-9]{10}@16900\\.gd"),
CHINAMOBILE(3, "^1[3|4|5|7|8][0-9]{9}@139\\.gd$"), CHINAMOBILE(3, "^1[3|4|5|7|8][0-9]{9}@139\\.gd$"),
OTHER(4, ".*"),; OTHER(4, ".*"),;
private static final Map<String, ISP> NAME_MAP = new HashMap<>(); private static final Map<String, ISP> NAME_MAP = new HashMap<>();
private static final Map<Integer, ISP> ID_MAP = new HashMap<>(); private static final Map<Integer, ISP> ID_MAP = new HashMap<>();
static { static {
for (ISP type : values()) { for (ISP type : values()) {
if (type.name != null) { if (type.name != null) {
NAME_MAP.put(type.name.toLowerCase(), type); NAME_MAP.put(type.name.toLowerCase(), type);
} }
if (type.id > 0) { if (type.id > 0) {
ID_MAP.put(type.id, type); ID_MAP.put(type.id, type);
} }
} }
} }
public final int id; public final int id;
public final String name; public final String name;
public final String accountRegex; public final String accountRegex;
ISP(int id, String accountRegex) { ISP(int id, String accountRegex) {
this.id = id; this.id = id;
this.name = lang("ISP_" + name()); this.name = lang("ISP_" + name());
this.accountRegex = accountRegex; this.accountRegex = accountRegex;
} }
public static ISP fromName(String name) { public static ISP fromName(String name) {
if (name == null) { if (name == null) {
return null; return null;
} }
return NAME_MAP.get(name.toLowerCase()); return NAME_MAP.get(name.toLowerCase());
} }
public static ISP fromId(int id) { public static ISP fromId(int id) {
return ID_MAP.get(id); return ID_MAP.get(id);
} }
@Override @Override
public String toString() { public String toString() {
return name; return name;
} }
} }

View File

@@ -26,20 +26,20 @@ import javax.persistence.Converter;
@Converter @Converter
public class ISPConverter implements AttributeConverter<ISP, Integer> { public class ISPConverter implements AttributeConverter<ISP, Integer> {
@Override @Override
public Integer convertToDatabaseColumn(ISP attribute) { public Integer convertToDatabaseColumn(ISP attribute) {
if (attribute == null) { if (attribute == null) {
return null; return null;
} }
return attribute.id; return attribute.id;
} }
@Override @Override
public ISP convertToEntityAttribute(Integer dbData) { public ISP convertToEntityAttribute(Integer dbData) {
if (dbData == null) { if (dbData == null) {
return null; return null;
} }
return ISP.fromId(dbData); return ISP.fromId(dbData);
} }
} }

View File

@@ -28,33 +28,33 @@ import static love.sola.netsupport.config.Lang.lang;
*/ */
public class Status { public class Status {
public static final int UNCHECKED = 0; public static final int UNCHECKED = 0;
public static final int ARRANGED = 1; public static final int ARRANGED = 1;
public static final int PUTOFF = 2; public static final int PUTOFF = 2;
public static final int REPORTED = 4; public static final int REPORTED = 4;
public static final int ISP_HANDLED = 7; public static final int ISP_HANDLED = 7;
public static final int SOLVED = 9; public static final int SOLVED = 9;
public static final Map<Integer, String> inverseMap = new HashMap<>(); public static final Map<Integer, String> inverseMap = new HashMap<>();
static { static {
System.out.println("Loading Status..."); System.out.println("Loading Status...");
for (Field field : Status.class.getDeclaredFields()) { for (Field field : Status.class.getDeclaredFields()) {
if (field.getType().isAssignableFrom(Integer.TYPE)) { if (field.getType().isAssignableFrom(Integer.TYPE)) {
try { try {
inverseMap.put((Integer) field.get(null), field.getName()); inverseMap.put((Integer) field.get(null), field.getName());
} catch (IllegalAccessException e) { } catch (IllegalAccessException e) {
e.printStackTrace(); e.printStackTrace();
} }
} }
} }
} }
public static String getLocalized(int status) { public static String getLocalized(int status) {
if (inverseMap.containsKey(status)) { if (inverseMap.containsKey(status)) {
return lang("STATUS_" + inverseMap.get(status)); return lang("STATUS_" + inverseMap.get(status));
} }
return null; return null;
} }
} }

View File

@@ -18,10 +18,6 @@
package love.sola.netsupport.pojo; package love.sola.netsupport.pojo;
import com.google.gson.annotations.Expose; import com.google.gson.annotations.Expose;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.ToString;
import javax.persistence.Column; import javax.persistence.Column;
import javax.persistence.Entity; import javax.persistence.Entity;
@@ -31,35 +27,109 @@ import javax.persistence.Table;
/** /**
* @author Sola {@literal <dev@sola.love>} * @author Sola {@literal <dev@sola.love>}
*/ */
@Data
@ToString(exclude = "password")
@AllArgsConstructor
@NoArgsConstructor
@Entity @Entity
@Table(name = "operators") @Table(name = "operators")
public class Operator { public class Operator {
public static final String PROPERTY_WECHAT = "wechat"; public static final String PROPERTY_WECHAT = "wechat";
@Id //System Accounts
@Column(name = "id", nullable = false, insertable = false, updatable = false) public static Operator USER_SELF;
private Integer id; public static Operator ADMIN;
@Column(name = "name", nullable = false, insertable = false, updatable = false)
private String name;
@Column(name = "access", nullable = false, insertable = false, updatable = false)
private Integer access;
@Column(name = "wechat", insertable = false, updatable = false)
@Expose(serialize = false)
private String wechat;
private Integer block;
private Integer week;
@Expose(serialize = false)
private String password;
@Id
@Column(name = "id", nullable = false, insertable = false, updatable = false)
private Integer id;
@Column(name = "name", nullable = false, insertable = false, updatable = false)
private String name;
@Column(name = "access", nullable = false, insertable = false, updatable = false)
private Integer access;
@Column(name = "wechat", insertable = false, updatable = false)
@Expose(serialize = false)
private String wechat;
private Integer block;
private Integer week;
@Expose(serialize = false)
private String password;
//System Accounts public Operator(Integer id, String name, Integer access, String wechat, Integer block, Integer week, String password) {
public static Operator USER_SELF; this.id = id;
public static Operator ADMIN; this.name = name;
this.access = access;
this.wechat = wechat;
this.block = block;
this.week = week;
this.password = password;
}
public Operator() {
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAccess() {
return access;
}
public void setAccess(Integer access) {
this.access = access;
}
public String getWechat() {
return wechat;
}
public void setWechat(String wechat) {
this.wechat = wechat;
}
public Integer getBlock() {
return block;
}
public void setBlock(Integer block) {
this.block = block;
}
public Integer getWeek() {
return week;
}
public void setWeek(Integer week) {
this.week = week;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
@Override
public String toString() {
return "Operator{" +
"id=" + id +
", name='" + name + '\'' +
", access=" + access +
", wechat='" + wechat + '\'' +
", block=" + block +
", week=" + week +
'}';
}
} }

View File

@@ -17,9 +17,6 @@
package love.sola.netsupport.pojo; package love.sola.netsupport.pojo;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import love.sola.netsupport.sql.TableTicket; import love.sola.netsupport.sql.TableTicket;
import org.hibernate.envers.Audited; import org.hibernate.envers.Audited;
import org.hibernate.envers.RelationTargetAuditMode; import org.hibernate.envers.RelationTargetAuditMode;
@@ -30,32 +27,119 @@ import java.util.Date;
/** /**
* @author Sola {@literal <dev@sola.love>} * @author Sola {@literal <dev@sola.love>}
*/ */
@Data
@AllArgsConstructor
@NoArgsConstructor
@Entity @Entity
@Table(name = "tickets") @Table(name = "tickets")
@Audited(targetAuditMode = RelationTargetAuditMode.NOT_AUDITED) @Audited(targetAuditMode = RelationTargetAuditMode.NOT_AUDITED)
public class Ticket { public class Ticket {
public static final String PROPERTY_USER = "user"; public static final String PROPERTY_USER = "user";
public static final String PROPERTY_STATUS = "status"; public static final String PROPERTY_STATUS = "status";
public static final String PROPERTY_SUBMIT_TIME = "submitTime"; public static final String PROPERTY_SUBMIT_TIME = "submitTime";
@Id @Id
@GeneratedValue(strategy = GenerationType.IDENTITY) @GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id; private Integer id;
@ManyToOne(optional = false) @ManyToOne(optional = false)
@JoinColumn(name = TableTicket.COLUMN_SID) @JoinColumn(name = TableTicket.COLUMN_SID)
private User user; private User user;
private String description; private String description;
@Column(name = TableTicket.COLUMN_SUBMIT_TIME, insertable = false, updatable = false) @Column(name = TableTicket.COLUMN_SUBMIT_TIME, insertable = false, updatable = false)
private Date submitTime; private Date submitTime;
private String remark; private String remark;
private Date updateTime; private Date updateTime;
@ManyToOne(optional = true) @ManyToOne(optional = true)
@JoinColumn(name = TableTicket.COLUMN_OPSID) @JoinColumn(name = TableTicket.COLUMN_OPSID)
private Operator operator; private Operator operator;
private Integer status; private Integer status;
public Ticket() {
}
public Ticket(User user, String description, Date submitTime, String remark, Date updateTime, Operator operator, Integer status) {
this.user = user;
this.description = description;
this.submitTime = submitTime;
this.remark = remark;
this.updateTime = updateTime;
this.operator = operator;
this.status = status;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public Date getSubmitTime() {
return submitTime;
}
public void setSubmitTime(Date submitTime) {
this.submitTime = submitTime;
}
public String getRemark() {
return remark;
}
public void setRemark(String remark) {
this.remark = remark;
}
public Date getUpdateTime() {
return updateTime;
}
public void setUpdateTime(Date updateTime) {
this.updateTime = updateTime;
}
public Operator getOperator() {
return operator;
}
public void setOperator(Operator operator) {
this.operator = operator;
}
public Integer getStatus() {
return status;
}
public void setStatus(Integer status) {
this.status = status;
}
@Override
public String toString() {
return "Ticket{" +
"id=" + id +
", user=" + user +
", description='" + description + '\'' +
", submitTime=" + submitTime +
", remark='" + remark + '\'' +
", updateTime=" + updateTime +
", operator=" + operator +
", status=" + status +
'}';
}
} }

View File

@@ -1,8 +1,5 @@
package love.sola.netsupport.pojo; package love.sola.netsupport.pojo;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.hibernate.annotations.ColumnDefault; import org.hibernate.annotations.ColumnDefault;
import org.hibernate.annotations.DynamicInsert; import org.hibernate.annotations.DynamicInsert;
@@ -12,29 +9,97 @@ import java.util.Date;
/** /**
* @author Sola {@literal <dev@sola.love>} * @author Sola {@literal <dev@sola.love>}
*/ */
@Data
@AllArgsConstructor
@NoArgsConstructor
@Entity @Entity
@Table(name = "toolschk", indexes = { @Table(name = "toolschk", indexes = {
@Index(columnList = "block,chktime,status"), @Index(columnList = "block,chktime,status"),
@Index(columnList = "chktime,status") @Index(columnList = "chktime,status")
}) })
@DynamicInsert @DynamicInsert
public class ToolsCheck { public class ToolsCheck {
@Id @Id
@GeneratedValue(strategy = GenerationType.IDENTITY) @GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id; private Integer id;
@ManyToOne(optional = false) @ManyToOne(optional = false)
@JoinColumn(name = "opsid", nullable = false) @JoinColumn(name = "opsid", nullable = false)
private Operator operator; private Operator operator;
@Column(nullable = false) @Column(nullable = false)
private Integer block; private Integer block;
@Column(name = "chktime", nullable = false) @Column(name = "chktime", nullable = false)
private Date checkTime = new Date(); private Date checkTime = new Date();
@ColumnDefault("0") @ColumnDefault("0")
private Integer status = 0; private Integer status = 0;
private String remark; private String remark;
public ToolsCheck() {
}
public ToolsCheck(Operator operator, Integer block, Date checkTime, Integer status, String remark) {
this.operator = operator;
this.block = block;
this.checkTime = checkTime;
this.status = status;
this.remark = remark;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public Operator getOperator() {
return operator;
}
public void setOperator(Operator operator) {
this.operator = operator;
}
public Integer getBlock() {
return block;
}
public void setBlock(Integer block) {
this.block = block;
}
public Date getCheckTime() {
return checkTime;
}
public void setCheckTime(Date checkTime) {
this.checkTime = checkTime;
}
public Integer getStatus() {
return status;
}
public void setStatus(Integer status) {
this.status = status;
}
public String getRemark() {
return remark;
}
public void setRemark(String remark) {
this.remark = remark;
}
@Override
public String toString() {
return "ToolsCheck{" +
"id=" + id +
", operator=" + operator +
", block=" + block +
", checkTime=" + checkTime +
", status=" + status +
", remark='" + remark + '\'' +
'}';
}
} }

View File

@@ -18,9 +18,6 @@
package love.sola.netsupport.pojo; package love.sola.netsupport.pojo;
import com.google.gson.annotations.Expose; import com.google.gson.annotations.Expose;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import love.sola.netsupport.enums.ISP; import love.sola.netsupport.enums.ISP;
import love.sola.netsupport.enums.ISPConverter; import love.sola.netsupport.enums.ISPConverter;
@@ -29,37 +26,124 @@ import javax.persistence.*;
/** /**
* @author Sola {@literal <dev@sola.love>} * @author Sola {@literal <dev@sola.love>}
*/ */
@Data
@AllArgsConstructor
@NoArgsConstructor
@Entity @Entity
@Table(name = "users") @Table(name = "users")
public class User { public class User {
public static final String PROPERTY_NAME = "name"; //System Accounts
public static final String PROPERTY_WECHAT = "wechatId"; public static User OFFICIAL_CHINA_UNICOM_XH;
public static final String PROPERTY_BLOCK = "block"; public static User OFFICIAL_CHINA_MOBILE_XH;
public static User OFFICIAL_CHINA_MOBILE_FX;
@Id public static final String PROPERTY_NAME = "name";
@Column(name = "id", updatable = false, nullable = false) public static final String PROPERTY_WECHAT = "wechatId";
private Long id; public static final String PROPERTY_BLOCK = "block";
@Column(name = "name", updatable = false, nullable = false)
private String name;
@Convert(converter = ISPConverter.class)
private ISP isp;
@Column(name = "netaccount")
private String netAccount;
@Expose(serialize = false)
@Column(name = "wechat")
private String wechatId;
private Integer block;
private Integer room;
private Long phone;
@Id
@Column(name = "id", updatable = false, nullable = false)
private Long id;
@Column(name = "name", updatable = false, nullable = false)
private String name;
@Convert(converter = ISPConverter.class)
private ISP isp;
@Column(name = "netaccount")
private String netAccount;
@Expose(serialize = false)
@Column(name = "wechat")
private String wechatId;
private Integer block;
private Integer room;
private Long phone;
//System Accounts public User() {
public static User OFFICIAL_CHINA_UNICOM_XH; }
public static User OFFICIAL_CHINA_MOBILE_XH;
public static User OFFICIAL_CHINA_MOBILE_FX;
public User(Long id, String name, ISP isp, String netAccount, String wechatId, Integer block, Integer room, Long phone) {
this.id = id;
this.name = name;
this.isp = isp;
this.netAccount = netAccount;
this.wechatId = wechatId;
this.block = block;
this.room = room;
this.phone = phone;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public ISP getIsp() {
return isp;
}
public void setIsp(ISP isp) {
this.isp = isp;
}
public String getNetAccount() {
return netAccount;
}
public void setNetAccount(String netAccount) {
this.netAccount = netAccount;
}
public String getWechatId() {
return wechatId;
}
public void setWechatId(String wechatId) {
this.wechatId = wechatId;
}
public Integer getBlock() {
return block;
}
public void setBlock(Integer block) {
this.block = block;
}
public Integer getRoom() {
return room;
}
public void setRoom(Integer room) {
this.room = room;
}
public Long getPhone() {
return phone;
}
public void setPhone(Long phone) {
this.phone = phone;
}
@Override
public String toString() {
return "User{" +
"id=" + id +
", name='" + name + '\'' +
", isp=" + isp +
", netAccount='" + netAccount + '\'' +
", wechatId='" + wechatId + '\'' +
", block=" + block +
", room=" + room +
", phone=" + phone +
'}';
}
} }

View File

@@ -32,74 +32,95 @@
*/ */
package love.sola.netsupport.session; package love.sola.netsupport.session;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;
import java.io.Serializable; import java.io.Serializable;
import java.util.HashMap; import java.util.*;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
/** /**
* @author Sola {@literal <dev@sola.love>} * @author Sola {@literal <dev@sola.love>}
*/ */
@EqualsAndHashCode(of = "id")
public final class MapSession implements WxSession, Serializable { public final class MapSession implements WxSession, Serializable {
@Getter private final String id;
private final String id; private Map<String, Object> sessionAttrs = new HashMap<String, Object>();
private Map<String, Object> sessionAttrs = new HashMap<String, Object>(); private long creationTime = System.currentTimeMillis();
@Getter private long lastAccessedTime = creationTime;
private long creationTime = System.currentTimeMillis(); private boolean invalidated = false;
@Getter
@Setter
private long lastAccessedTime = creationTime;
@Getter
private boolean invalidated = false;
/** /**
* Creates a new instance with a secure randomly generated identifier. * Creates a new instance with a secure randomly generated identifier.
*/ */
public MapSession() { public MapSession() {
this(UUID.randomUUID().toString()); this(UUID.randomUUID().toString());
} }
/** /**
* Creates a new instance with the specified id. This is preferred to the * Creates a new instance with the specified id. This is preferred to the
* default constructor when the id is known to prevent unnecessary consumption on * default constructor when the id is known to prevent unnecessary consumption on
* entropy which can be slow. * entropy which can be slow.
* *
* @param id the identifier to use * @param id the identifier to use
*/ */
public MapSession(String id) { public MapSession(String id) {
this.id = id; this.id = id;
} }
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public <T> T getAttribute(String attributeName) { public <T> T getAttribute(String attributeName) {
return (T) sessionAttrs.get(attributeName); return (T) sessionAttrs.get(attributeName);
} }
public Set<String> getAttributeNames() { public Set<String> getAttributeNames() {
return sessionAttrs.keySet(); return sessionAttrs.keySet();
} }
public void setAttribute(String attributeName, Object attributeValue) { public void setAttribute(String attributeName, Object attributeValue) {
if (attributeValue == null) { if (attributeValue == null) {
removeAttribute(attributeName); removeAttribute(attributeName);
} else { } else {
sessionAttrs.put(attributeName, attributeValue); sessionAttrs.put(attributeName, attributeValue);
} }
} }
public void removeAttribute(String attributeName) { public void removeAttribute(String attributeName) {
sessionAttrs.remove(attributeName); sessionAttrs.remove(attributeName);
} }
public void invalidate() { public void invalidate() {
invalidated = true; invalidated = true;
} }
public long getLastAccessedTime() {
return lastAccessedTime;
}
public void setLastAccessedTime(long lastAccessedTime) {
this.lastAccessedTime = lastAccessedTime;
}
@Override
public String getId() {
return id;
}
public long getCreationTime() {
return creationTime;
}
public boolean isInvalidated() {
return invalidated;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof MapSession)) return false;
MapSession that = (MapSession) o;
return Objects.equals(id, that.id);
}
@Override
public int hashCode() {
return Objects.hash(id);
}
} }

View File

@@ -47,56 +47,56 @@ import java.util.concurrent.TimeUnit;
*/ */
public class MapSessionRepository { public class MapSessionRepository {
private final LoadingCache<String, MapSession> sessions; private final LoadingCache<String, MapSession> sessions;
public MapSessionRepository() { public MapSessionRepository() {
this(CacheBuilder.newBuilder() this(CacheBuilder.newBuilder()
.concurrencyLevel(4) .concurrencyLevel(4)
.maximumSize(65535) .maximumSize(65535)
.expireAfterAccess(Settings.I.User_Session_Max_Inactive, TimeUnit.SECONDS) .expireAfterAccess(Settings.I.User_Session_Max_Inactive, TimeUnit.SECONDS)
.build(new CacheLoader<String, MapSession>() { .build(new CacheLoader<String, MapSession>() {
@Override @Override
public MapSession load(@Nonnull String key) throws Exception { public MapSession load(@Nonnull String key) throws Exception {
return new MapSession(key); return new MapSession(key);
} }
} }
) )
); );
} }
public MapSessionRepository(LoadingCache<String, MapSession> sessions) { public MapSessionRepository(LoadingCache<String, MapSession> sessions) {
Validate.notNull(sessions); Validate.notNull(sessions);
this.sessions = sessions; this.sessions = sessions;
} }
public void save(MapSession session) { public void save(MapSession session) {
sessions.put(session.getId(), session); sessions.put(session.getId(), session);
} }
public MapSession getSession(String id) { public MapSession getSession(String id) {
MapSession saved = sessions.getIfPresent(id); MapSession saved = sessions.getIfPresent(id);
if (saved == null) { if (saved == null) {
return null; return null;
} }
if (saved.isInvalidated()) { if (saved.isInvalidated()) {
delete(saved.getId()); delete(saved.getId());
return null; return null;
} }
return saved; return saved;
} }
public void delete(String id) { public void delete(String id) {
sessions.invalidate(id); sessions.invalidate(id);
} }
public MapSession createSession() { public MapSession createSession() {
MapSession session = new MapSession(); MapSession session = new MapSession();
save(session); save(session);
return session; return session;
} }
public Map<String, MapSession> asMap() { public Map<String, MapSession> asMap() {
return sessions.asMap(); return sessions.asMap();
} }
} }

View File

@@ -25,22 +25,22 @@ import java.util.Collection;
*/ */
public class WechatSession { public class WechatSession {
private static MapSessionRepository repository; private static MapSessionRepository repository;
static { static {
repository = new MapSessionRepository(); repository = new MapSessionRepository();
} }
public static WxSession get(String id) { public static WxSession get(String id) {
return repository.getSession(id); return repository.getSession(id);
} }
public static WxSession create() { public static WxSession create() {
return repository.createSession(); return repository.createSession();
} }
public static Collection<? extends WxSession> list() { public static Collection<? extends WxSession> list() {
return repository.asMap().values(); return repository.asMap().values();
} }
} }

View File

@@ -24,16 +24,16 @@ import java.util.Set;
*/ */
public interface WxSession { public interface WxSession {
String getId(); String getId();
<T> T getAttribute(String name); <T> T getAttribute(String name);
Set<String> getAttributeNames(); Set<String> getAttributeNames();
void setAttribute(String name, Object value); void setAttribute(String name, Object value);
void removeAttribute(String name); void removeAttribute(String name);
void invalidate(); void invalidate();
} }

View File

@@ -46,111 +46,111 @@ import java.util.Date;
*/ */
public class SQLCore { public class SQLCore {
public static InitialContext ic; public static InitialContext ic;
public static DataSource ds; public static DataSource ds;
public static SessionFactory sf; public static SessionFactory sf;
public static ServiceRegistry sr; public static ServiceRegistry sr;
public static Gson gson = new GsonBuilder() public static Gson gson = new GsonBuilder()
.addSerializationExclusionStrategy(new ExclusionStrategy() { .addSerializationExclusionStrategy(new ExclusionStrategy() {
@Override @Override
public boolean shouldSkipField(FieldAttributes fieldAttributes) { public boolean shouldSkipField(FieldAttributes fieldAttributes) {
final Expose expose = fieldAttributes.getAnnotation(Expose.class); final Expose expose = fieldAttributes.getAnnotation(Expose.class);
return expose != null && !expose.serialize(); return expose != null && !expose.serialize();
} }
@Override @Override
public boolean shouldSkipClass(Class<?> aClass) { public boolean shouldSkipClass(Class<?> aClass) {
return false; return false;
} }
}) })
.addDeserializationExclusionStrategy(new ExclusionStrategy() { .addDeserializationExclusionStrategy(new ExclusionStrategy() {
@Override @Override
public boolean shouldSkipField(FieldAttributes fieldAttributes) { public boolean shouldSkipField(FieldAttributes fieldAttributes) {
final Expose expose = fieldAttributes.getAnnotation(Expose.class); final Expose expose = fieldAttributes.getAnnotation(Expose.class);
return expose != null && !expose.deserialize(); return expose != null && !expose.deserialize();
} }
@Override @Override
public boolean shouldSkipClass(Class<?> aClass) { public boolean shouldSkipClass(Class<?> aClass) {
return false; return false;
} }
}) })
.registerTypeAdapter(Date.class, (JsonDeserializer<Date>) (json, typeOfT, context) -> new Date(json.getAsJsonPrimitive().getAsLong())) .registerTypeAdapter(Date.class, (JsonDeserializer<Date>) (json, typeOfT, context) -> new Date(json.getAsJsonPrimitive().getAsLong()))
.registerTypeAdapter(Date.class, (JsonSerializer<Date>) (src, typeOfSrc, context) -> new JsonPrimitive(src.getTime())) .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, (JsonDeserializer<ISP>) (json, typeOfT, context) -> ISP.fromId(json.getAsJsonPrimitive().getAsInt()))
.registerTypeAdapter(ISP.class, (JsonSerializer<ISP>) (src, typeOfSrc, context) -> new JsonPrimitive(src.id)) .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, (JsonDeserializer<Command>) (json, typeOfT, context) -> Command.fromId(json.getAsJsonPrimitive().getAsInt()))
.registerTypeAdapter(Command.class, (JsonSerializer<Command>) (src, typeOfSrc, context) -> new JsonPrimitive(src.id)) .registerTypeAdapter(Command.class, (JsonSerializer<Command>) (src, typeOfSrc, context) -> new JsonPrimitive(src.id))
.registerTypeAdapterFactory(HibernateProxyTypeAdapter.FACTORY) .registerTypeAdapterFactory(HibernateProxyTypeAdapter.FACTORY)
.create(); .create();
static { static {
try { try {
ic = new InitialContext(); ic = new InitialContext();
ds = (DataSource) ic.lookup("java:comp/env/jdbc/netsupport"); ds = (DataSource) ic.lookup("java:comp/env/jdbc/netsupport");
ds.setLoginTimeout(3); ds.setLoginTimeout(3);
sr = new StandardServiceRegistryBuilder().configure().build(); sr = new StandardServiceRegistryBuilder().configure().build();
sf = new MetadataSources(sr).buildMetadata().buildSessionFactory(); sf = new MetadataSources(sr).buildMetadata().buildSessionFactory();
TableUser.init(); TableUser.init();
TableOperator.init(); TableOperator.init();
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
} }
} }
public static void destroy() { public static void destroy() {
try { try {
SQLCore.sf.close(); SQLCore.sf.close();
((ComboPooledDataSource) SQLCore.ds).close(); ((ComboPooledDataSource) SQLCore.ds).close();
SQLCore.ic.close(); SQLCore.ic.close();
} catch (NamingException e) { } catch (NamingException e) {
e.printStackTrace(); e.printStackTrace();
} }
} }
public static AuditReader getAuditReader(Session session) { public static AuditReader getAuditReader(Session session) {
return AuditReaderFactory.get(session); return AuditReaderFactory.get(session);
} }
public static class HibernateProxyTypeAdapter extends TypeAdapter<HibernateProxy> { public static class HibernateProxyTypeAdapter extends TypeAdapter<HibernateProxy> {
public static final TypeAdapterFactory FACTORY = new TypeAdapterFactory() { public static final TypeAdapterFactory FACTORY = new TypeAdapterFactory() {
@Override @Override
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> type) { public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> type) {
return (HibernateProxy.class.isAssignableFrom(type.getRawType()) ? (TypeAdapter<T>) new HibernateProxyTypeAdapter(gson) : null); return (HibernateProxy.class.isAssignableFrom(type.getRawType()) ? (TypeAdapter<T>) new HibernateProxyTypeAdapter(gson) : null);
} }
}; };
private final Gson context; private final Gson context;
private HibernateProxyTypeAdapter(Gson context) { private HibernateProxyTypeAdapter(Gson context) {
this.context = context; this.context = context;
} }
@Override @Override
public HibernateProxy read(JsonReader in) throws IOException { public HibernateProxy read(JsonReader in) throws IOException {
throw new UnsupportedOperationException("Not supported"); throw new UnsupportedOperationException("Not supported");
} }
@SuppressWarnings({"rawtypes", "unchecked"}) @SuppressWarnings({"rawtypes", "unchecked"})
@Override @Override
public void write(JsonWriter out, HibernateProxy value) throws IOException { public void write(JsonWriter out, HibernateProxy value) throws IOException {
if (value == null) { if (value == null) {
out.nullValue(); out.nullValue();
return; return;
} }
// Retrieve the original (not proxy) class // Retrieve the original (not proxy) class
Class<?> baseType = Hibernate.getClass(value); Class<?> baseType = Hibernate.getClass(value);
// Get the TypeAdapter of the original class, to delegate the serialization // Get the TypeAdapter of the original class, to delegate the serialization
TypeAdapter delegate = context.getAdapter(TypeToken.get(baseType)); TypeAdapter delegate = context.getAdapter(TypeToken.get(baseType));
// Get a filled instance of the original class // Get a filled instance of the original class
Object unproxiedValue = ((HibernateProxy) value).getHibernateLazyInitializer() Object unproxiedValue = ((HibernateProxy) value).getHibernateLazyInitializer()
.getImplementation(); .getImplementation();
// Serialize the value // Serialize the value
delegate.write(out, unproxiedValue); delegate.write(out, unproxiedValue);
} }
} }
} }

View File

@@ -26,29 +26,29 @@ import java.sql.*;
*/ */
public class TableConfig extends SQLCore { public class TableConfig extends SQLCore {
public static final String KEY_SYS = "sys"; public static final String KEY_SYS = "sys";
public static Settings getSettings() { public static Settings getSettings() {
try (Connection conn = ds.getConnection()) { try (Connection conn = ds.getConnection()) {
Statement st = conn.createStatement(); Statement st = conn.createStatement();
ResultSet rs = st.executeQuery("SELECT * FROM settings WHERE type='" + KEY_SYS + "'"); ResultSet rs = st.executeQuery("SELECT * FROM settings WHERE type='" + KEY_SYS + "'");
if (rs.next()) { if (rs.next()) {
return gson.fromJson(rs.getString("data"), Settings.class); return gson.fromJson(rs.getString("data"), Settings.class);
} }
} catch (SQLException e) { } catch (SQLException e) {
} }
return null; return null;
} }
public static int saveSettings(Settings obj) { public static int saveSettings(Settings obj) {
try (Connection conn = ds.getConnection()) { try (Connection conn = ds.getConnection()) {
PreparedStatement ps = conn.prepareStatement("UPDATE settings SET data=? WHERE type=?"); PreparedStatement ps = conn.prepareStatement("UPDATE settings SET data=? WHERE type=?");
ps.setString(1, gson.toJson(obj)); ps.setString(1, gson.toJson(obj));
ps.setString(2, KEY_SYS); ps.setString(2, KEY_SYS);
return ps.executeUpdate(); return ps.executeUpdate();
} catch (SQLException e) { } catch (SQLException e) {
} }
return -1; return -1;
} }
} }

View File

@@ -27,35 +27,35 @@ import org.hibernate.criterion.Restrictions;
*/ */
public class TableOperator extends SQLCore { public class TableOperator extends SQLCore {
public static boolean has(String wechat) { public static boolean has(String wechat) {
try (Session s = SQLCore.sf.openSession()) { try (Session s = SQLCore.sf.openSession()) {
return (long) s.createCriteria(Operator.class) return (long) s.createCriteria(Operator.class)
.add(Restrictions.eq(Operator.PROPERTY_WECHAT, wechat)) .add(Restrictions.eq(Operator.PROPERTY_WECHAT, wechat))
.setProjection(Projections.rowCount()) .setProjection(Projections.rowCount())
.uniqueResult() > 0; .uniqueResult() > 0;
} }
} }
public static Operator get(String wechat) { public static Operator get(String wechat) {
try (Session s = SQLCore.sf.openSession()) { try (Session s = SQLCore.sf.openSession()) {
return (Operator) s.createCriteria(Operator.class) return (Operator) s.createCriteria(Operator.class)
.add(Restrictions.eq(Operator.PROPERTY_WECHAT, wechat)) .add(Restrictions.eq(Operator.PROPERTY_WECHAT, wechat))
.uniqueResult(); .uniqueResult();
} }
} }
public static Operator get(int id) { public static Operator get(int id) {
try (Session s = SQLCore.sf.openSession()) { try (Session s = SQLCore.sf.openSession()) {
return s.get(Operator.class, id); return s.get(Operator.class, id);
} }
} }
protected static void init() { protected static void init() {
try (Session s = SQLCore.sf.openSession()) { try (Session s = SQLCore.sf.openSession()) {
Operator.USER_SELF = s.get(Operator.class, -1); Operator.USER_SELF = s.get(Operator.class, -1);
Operator.ADMIN = s.get(Operator.class, 0); Operator.ADMIN = s.get(Operator.class, 0);
} }
} }
} }

View File

@@ -34,83 +34,83 @@ import java.util.List;
*/ */
public class TableTicket extends SQLCore { public class TableTicket extends SQLCore {
public static final String COLUMN_ID = "id"; public static final String COLUMN_ID = "id";
public static final String COLUMN_SID = "sid"; public static final String COLUMN_SID = "sid";
public static final String COLUMN_DESC = "description"; public static final String COLUMN_DESC = "description";
public static final String COLUMN_SUBMIT_TIME = "submittime"; public static final String COLUMN_SUBMIT_TIME = "submittime";
public static final String COLUMN_REMARK = "remark"; public static final String COLUMN_REMARK = "remark";
public static final String COLUMN_UPDATE_TIME = "updatetime"; public static final String COLUMN_UPDATE_TIME = "updatetime";
public static final String COLUMN_OPSID = "opsid"; public static final String COLUMN_OPSID = "opsid";
public static final String COLUMN_STATUS = "status"; public static final String COLUMN_STATUS = "status";
public static Ticket latestOpen(User u) { public static Ticket latestOpen(User u) {
try (Session s = SQLCore.sf.openSession()) { try (Session s = SQLCore.sf.openSession()) {
return (Ticket) s.createCriteria(Ticket.class) return (Ticket) s.createCriteria(Ticket.class)
.addOrder(Order.desc(Ticket.PROPERTY_SUBMIT_TIME)) .addOrder(Order.desc(Ticket.PROPERTY_SUBMIT_TIME))
.add(Restrictions.eq(Ticket.PROPERTY_USER, u)) .add(Restrictions.eq(Ticket.PROPERTY_USER, u))
.add(Restrictions.ne(Ticket.PROPERTY_STATUS, Status.SOLVED)) .add(Restrictions.ne(Ticket.PROPERTY_STATUS, Status.SOLVED))
.setMaxResults(1) .setMaxResults(1)
.uniqueResult(); .uniqueResult();
} }
} }
public static Ticket latest(User u) { public static Ticket latest(User u) {
try (Session s = SQLCore.sf.openSession()) { try (Session s = SQLCore.sf.openSession()) {
return (Ticket) s.createCriteria(Ticket.class) return (Ticket) s.createCriteria(Ticket.class)
.addOrder(Order.desc(Ticket.PROPERTY_SUBMIT_TIME)) .addOrder(Order.desc(Ticket.PROPERTY_SUBMIT_TIME))
.add(Restrictions.eq(Ticket.PROPERTY_USER, u)) .add(Restrictions.eq(Ticket.PROPERTY_USER, u))
.setMaxResults(1) .setMaxResults(1)
.uniqueResult(); .uniqueResult();
} }
} }
public static boolean hasOpen(User u) { public static boolean hasOpen(User u) {
try (Session s = SQLCore.sf.openSession()) { try (Session s = SQLCore.sf.openSession()) {
return (long) s.createCriteria(Ticket.class) return (long) s.createCriteria(Ticket.class)
.add(Restrictions.eq(Ticket.PROPERTY_USER, u)) .add(Restrictions.eq(Ticket.PROPERTY_USER, u))
.add(Restrictions.ne(Ticket.PROPERTY_STATUS, Status.SOLVED)) .add(Restrictions.ne(Ticket.PROPERTY_STATUS, Status.SOLVED))
.setProjection(Projections.rowCount()) .setProjection(Projections.rowCount())
.uniqueResult() > 0; .uniqueResult() > 0;
} }
} }
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public static List<Ticket> unsolvedByBlock(int b) { public static List<Ticket> unsolvedByBlock(int b) {
if (b == 0) return unsolved(); if (b == 0) return unsolved();
try (Session s = SQLCore.sf.openSession()) { try (Session s = SQLCore.sf.openSession()) {
return s.createCriteria(Ticket.class) return s.createCriteria(Ticket.class)
.addOrder(Order.desc(Ticket.PROPERTY_SUBMIT_TIME)) .addOrder(Order.desc(Ticket.PROPERTY_SUBMIT_TIME))
.add(Restrictions.ne(Ticket.PROPERTY_STATUS, Status.SOLVED)) .add(Restrictions.ne(Ticket.PROPERTY_STATUS, Status.SOLVED))
.createCriteria(Ticket.PROPERTY_USER) .createCriteria(Ticket.PROPERTY_USER)
.add(Restrictions.between(User.PROPERTY_BLOCK, b * 10, (b + 1) * 10 - 1)) .add(Restrictions.between(User.PROPERTY_BLOCK, b * 10, (b + 1) * 10 - 1))
.list(); .list();
} }
} }
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public static List<Ticket> unsolved() { public static List<Ticket> unsolved() {
try (Session s = SQLCore.sf.openSession()) { try (Session s = SQLCore.sf.openSession()) {
return s.createCriteria(Ticket.class) return s.createCriteria(Ticket.class)
.createAlias(Ticket.PROPERTY_USER, "u") .createAlias(Ticket.PROPERTY_USER, "u")
.addOrder(Order.asc("u." + User.PROPERTY_BLOCK)) .addOrder(Order.asc("u." + User.PROPERTY_BLOCK))
.addOrder(Order.desc(Ticket.PROPERTY_SUBMIT_TIME)) .addOrder(Order.desc(Ticket.PROPERTY_SUBMIT_TIME))
.add(Restrictions.ne(Ticket.PROPERTY_STATUS, Status.SOLVED)) .add(Restrictions.ne(Ticket.PROPERTY_STATUS, Status.SOLVED))
.list(); .list();
} }
} }
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public static List<Object[]> track(int tid) { public static List<Object[]> track(int tid) {
try (Session s = SQLCore.sf.openSession()) { try (Session s = SQLCore.sf.openSession()) {
AuditReader reader = getAuditReader(s); AuditReader reader = getAuditReader(s);
return reader.createQuery() return reader.createQuery()
.forRevisionsOfEntity(Ticket.class, false, true) .forRevisionsOfEntity(Ticket.class, false, true)
.addOrder(AuditEntity.revisionNumber().desc()) .addOrder(AuditEntity.revisionNumber().desc())
.add(AuditEntity.id().eq(tid)) .add(AuditEntity.id().eq(tid))
.getResultList() .getResultList()
; ;
} }
} }
} }

View File

@@ -34,79 +34,79 @@ import java.util.concurrent.TimeUnit;
@SuppressWarnings("Duplicates") @SuppressWarnings("Duplicates")
public class TableUser extends SQLCore { public class TableUser extends SQLCore {
public static final String COLUMN_ID = "id"; public static final String COLUMN_ID = "id";
public static final String COLUMN_NAME = "name"; public static final String COLUMN_NAME = "name";
public static final String COLUMN_ISP = "isp"; public static final String COLUMN_ISP = "isp";
public static final String COLUMN_NET_ACCOUNT = "netaccount"; public static final String COLUMN_NET_ACCOUNT = "netaccount";
public static final String COLUMN_WECHAT = "wechat"; public static final String COLUMN_WECHAT = "wechat";
public static final String COLUMN_BLOCK = "block"; public static final String COLUMN_BLOCK = "block";
public static final String COLUMN_ROOM = "room"; public static final String COLUMN_ROOM = "room";
public static final String COLUMN_PHONE = "phone"; public static final String COLUMN_PHONE = "phone";
public static User getById(long id) { public static User getById(long id) {
try (Session s = sf.openSession()) { try (Session s = sf.openSession()) {
return s.get(User.class, id); return s.get(User.class, id);
} }
} }
public static User getByName(String name) { public static User getByName(String name) {
try (Session s = sf.openSession()) { try (Session s = sf.openSession()) {
return (User) s.createCriteria(User.class).add(Restrictions.eq(User.PROPERTY_NAME, name)).uniqueResult(); return (User) s.createCriteria(User.class).add(Restrictions.eq(User.PROPERTY_NAME, name)).uniqueResult();
} }
} }
public static User getByWechat(String wechat) { public static User getByWechat(String wechat) {
try { try {
User u = cache.get(wechat); User u = cache.get(wechat);
return u == NULL_USER ? null : u; return u == NULL_USER ? null : u;
} catch (ExecutionException e) { } catch (ExecutionException e) {
e.printStackTrace(); e.printStackTrace();
return null; return null;
} }
} }
public static int update(User user) { public static int update(User user) {
try (Session s = sf.openSession()) { try (Session s = sf.openSession()) {
s.beginTransaction(); s.beginTransaction();
s.update(user); s.update(user);
s.getTransaction().commit(); s.getTransaction().commit();
cache.put(user.getWechatId(), user); cache.put(user.getWechatId(), user);
return 1; return 1;
} }
} }
protected static void init() { protected static void init() {
try (Session s = SQLCore.sf.openSession()) { try (Session s = SQLCore.sf.openSession()) {
User.OFFICIAL_CHINA_UNICOM_XH = s.get(User.class, 100104L); User.OFFICIAL_CHINA_UNICOM_XH = s.get(User.class, 100104L);
User.OFFICIAL_CHINA_MOBILE_XH = s.get(User.class, 100864L); User.OFFICIAL_CHINA_MOBILE_XH = s.get(User.class, 100864L);
User.OFFICIAL_CHINA_MOBILE_FX = s.get(User.class, 100865L); User.OFFICIAL_CHINA_MOBILE_FX = s.get(User.class, 100865L);
} }
} }
private static LoadingCache<String, User> cache = CacheBuilder.newBuilder() private static LoadingCache<String, User> cache = CacheBuilder.newBuilder()
.concurrencyLevel(4) .concurrencyLevel(4)
.maximumSize(4096) .maximumSize(4096)
.expireAfterAccess(Settings.I.User_Wechat_Cache_Expire_Time, TimeUnit.SECONDS) .expireAfterAccess(Settings.I.User_Wechat_Cache_Expire_Time, TimeUnit.SECONDS)
.build(new ValueLoader()); .build(new ValueLoader());
private static class ValueLoader extends CacheLoader<String, User> { private static class ValueLoader extends CacheLoader<String, User> {
@Override @Override
public User load(String key) throws Exception { public User load(String key) throws Exception {
User u = TableUser.getByWechat0(key); User u = TableUser.getByWechat0(key);
return u == null ? NULL_USER : u; return u == null ? NULL_USER : u;
} }
} }
private static final User NULL_USER = new User(); private static final User NULL_USER = new User();
public static void flushCache() { public static void flushCache() {
cache.invalidateAll(); cache.invalidateAll();
} }
private static User getByWechat0(String wechat) { private static User getByWechat0(String wechat) {
try (Session s = sf.openSession()) { try (Session s = sf.openSession()) {
return (User) s.createCriteria(User.class).add(Restrictions.eq(User.PROPERTY_WECHAT, wechat)).uniqueResult(); return (User) s.createCriteria(User.class).add(Restrictions.eq(User.PROPERTY_WECHAT, wechat)).uniqueResult();
} }
} }
} }

View File

@@ -25,76 +25,76 @@ import love.sola.netsupport.enums.ISP;
*/ */
public class Checker { public class Checker {
public static final String STUDENT_ID_REGEX = "^(2014|2015|2016|2017)[0-9]{9}$"; public static final String STUDENT_ID_REGEX = "^(2014|2015|2016|2017)[0-9]{9}$";
public static final String PHONE_NUMBER_REGEX = "^1[34578][0-9]{9}$"; public static final String PHONE_NUMBER_REGEX = "^1[34578][0-9]{9}$";
public static boolean hasNull(Object... v) { public static boolean hasNull(Object... v) {
for (Object o : v) if (o == null) return true; for (Object o : v) if (o == null) return true;
return false; return false;
} }
public static long checkStudentId(String studentId) { public static long checkStudentId(String studentId) {
if (studentId == null) return -1; if (studentId == null) return -1;
if (studentId.matches(STUDENT_ID_REGEX)) { if (studentId.matches(STUDENT_ID_REGEX)) {
try { try {
return Long.parseLong(studentId); return Long.parseLong(studentId);
} catch (NumberFormatException ignored) { } catch (NumberFormatException ignored) {
} }
} }
return -1; return -1;
} }
public static long checkPhoneNumber(String phone) { public static long checkPhoneNumber(String phone) {
if (phone == null) return -1; if (phone == null) return -1;
if (!phone.matches(PHONE_NUMBER_REGEX)) return -1; if (!phone.matches(PHONE_NUMBER_REGEX)) return -1;
try { try {
return Long.parseLong(phone); return Long.parseLong(phone);
} catch (NumberFormatException ignored) { } catch (NumberFormatException ignored) {
} }
return -1; return -1;
} }
public static ISP checkISP(String isp) { public static ISP checkISP(String isp) {
if (isp == null) return null; if (isp == null) return null;
try { try {
return ISP.fromId(Integer.parseInt(isp)); return ISP.fromId(Integer.parseInt(isp));
} catch (NumberFormatException ignored) { } catch (NumberFormatException ignored) {
} }
return null; return null;
} }
public static String checkNetAccount(String account, ISP isp) { public static String checkNetAccount(String account, ISP isp) {
if (isp == null) return null; if (isp == null) return null;
if (account == null) return null; if (account == null) return null;
if (!account.matches(isp.accountRegex)) return null; if (!account.matches(isp.accountRegex)) return null;
return account; return account;
} }
public static int checkBlock(String block) { public static int checkBlock(String block) {
if (block == null) return -1; if (block == null) return -1;
try { try {
int b = Integer.parseInt(block); int b = Integer.parseInt(block);
if (Block.inverseMap.containsKey(b)) if (Block.inverseMap.containsKey(b))
return b; return b;
else else
return -1; return -1;
} catch (NumberFormatException ignored) { } catch (NumberFormatException ignored) {
} }
return -1; return -1;
} }
public static int checkRoom(String room, int block) { public static int checkRoom(String room, int block) {
if (block == -1) return -1; if (block == -1) return -1;
if (room == null) return -1; if (room == null) return -1;
try { try {
Integer i = Integer.parseInt(room); Integer i = Integer.parseInt(room);
if (Block.checkRoom(block, i)) if (Block.checkRoom(block, i))
return i; return i;
else else
return -1; return -1;
} catch (NumberFormatException ignored) { } catch (NumberFormatException ignored) {
} }
return -1; return -1;
} }
} }

View File

@@ -24,12 +24,12 @@ import org.mindrot.jbcrypt.BCrypt;
*/ */
public class Crypto { public class Crypto {
public static String hash(String pw) { public static String hash(String pw) {
return BCrypt.hashpw(pw, BCrypt.gensalt()); return BCrypt.hashpw(pw, BCrypt.gensalt());
} }
public static boolean check(String plain, String hash) { public static boolean check(String plain, String hash) {
return BCrypt.checkpw(plain, hash); return BCrypt.checkpw(plain, hash);
} }
} }

View File

@@ -29,20 +29,20 @@ import static love.sola.netsupport.config.Lang.lang;
*/ */
public class ParseUtil { public class ParseUtil {
public static SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm EEE"); public static SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm EEE");
public static String parseTicket(Ticket t) { public static String parseTicket(Ticket t) {
StringBuilder sb = new StringBuilder() StringBuilder sb = new StringBuilder()
.append(lang("Ticket_Info_Id")).append(t.getId()).append("\n") .append(lang("Ticket_Info_Id")).append(t.getId()).append("\n")
.append(lang("Ticket_Info_Desc")).append(t.getDescription()).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"); .append(lang("Ticket_Info_Submit_Time")).append(dateFormat.format(t.getSubmitTime())).append("\n");
if (t.getOperator() != null) if (t.getOperator() != null)
sb.append(lang("Ticket_Info_Operator")).append(t.getOperator().getId()).append("\n"); 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.getRemark() != null) sb.append(lang("Ticket_Info_Remark")).append(t.getRemark()).append("\n");
if (t.getUpdateTime() != null) if (t.getUpdateTime() != null)
sb.append(lang("Ticket_Info_Update_Time")).append(dateFormat.format(t.getUpdateTime())).append("\n"); 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())); sb.append(lang("Ticket_Info_Status")).append(Status.getLocalized(t.getStatus()));
return sb.toString(); return sb.toString();
} }
} }

View File

@@ -31,51 +31,51 @@ import java.security.KeyPairGenerator;
public class RSAUtil { public class RSAUtil {
public static Key publicKey; public static Key publicKey;
public static Key privateKey; public static Key privateKey;
public static String publicKey_s; public static String publicKey_s;
public static String privateKey_s; public static String privateKey_s;
static { static {
genKeyPair(); genKeyPair();
} }
public static void genKeyPair() { public static void genKeyPair() {
try { try {
KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA"); KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA");
kpg.initialize(1024); kpg.initialize(1024);
KeyPair kp = kpg.genKeyPair(); KeyPair kp = kpg.genKeyPair();
publicKey = kp.getPublic(); publicKey = kp.getPublic();
privateKey = kp.getPrivate(); privateKey = kp.getPrivate();
publicKey_s = Base64.encodeBase64String(publicKey.getEncoded()); publicKey_s = Base64.encodeBase64String(publicKey.getEncoded());
privateKey_s = Base64.encodeBase64String(privateKey.getEncoded()); privateKey_s = Base64.encodeBase64String(privateKey.getEncoded());
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
} }
} }
public static String encrypt(String value) { public static String encrypt(String value) {
try { try {
Cipher cipher = Cipher.getInstance("RSA"); Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.ENCRYPT_MODE, publicKey); cipher.init(Cipher.ENCRYPT_MODE, publicKey);
byte[] encrypted = cipher.doFinal(value.getBytes(StandardCharsets.UTF_8)); byte[] encrypted = cipher.doFinal(value.getBytes(StandardCharsets.UTF_8));
return Base64.encodeBase64String(encrypted); return Base64.encodeBase64String(encrypted);
} catch (Exception ex) { } catch (Exception ex) {
ex.printStackTrace(); ex.printStackTrace();
} }
return null; return null;
} }
public static String decrypt(String encrypted) { public static String decrypt(String encrypted) {
try { try {
Cipher cipher = Cipher.getInstance("RSA"); Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.DECRYPT_MODE, privateKey); cipher.init(Cipher.DECRYPT_MODE, privateKey);
byte[] original = cipher.doFinal(Base64.decodeBase64(encrypted)); byte[] original = cipher.doFinal(Base64.decodeBase64(encrypted));
return new String(original, StandardCharsets.UTF_8); return new String(original, StandardCharsets.UTF_8);
} catch (Exception ex) { } catch (Exception ex) {
ex.printStackTrace(); ex.printStackTrace();
} }
return null; return null;
} }
} }

View File

@@ -29,105 +29,105 @@ import static love.sola.netsupport.config.Lang.lang;
*/ */
public class Redirect { public class Redirect {
private static final String REDIRECT_PAGE = lang("Result_Page"); private static final String REDIRECT_PAGE = lang("Result_Page");
private static final int SUCCESS = 1; private static final int SUCCESS = 1;
private static final int ERROR = 0; private static final int ERROR = 0;
private static final int WARNING = -1; private static final int WARNING = -1;
private static final int NON_WECHAT = 88; private static final int NON_WECHAT = 88;
public static RedirectBuilder success() { public static RedirectBuilder success() {
return new RedirectBuilder(SUCCESS); return new RedirectBuilder(SUCCESS);
} }
public static RedirectBuilder error() { public static RedirectBuilder error() {
return new RedirectBuilder(ERROR); return new RedirectBuilder(ERROR);
} }
public static class RedirectBuilder { public static class RedirectBuilder {
private StringBuilder sb; private StringBuilder sb;
RedirectBuilder(int type) { RedirectBuilder(int type) {
sb = new StringBuilder(REDIRECT_PAGE).append("?"); sb = new StringBuilder(REDIRECT_PAGE).append("?");
type(type); type(type);
} }
private RedirectBuilder type(int type) { private RedirectBuilder type(int type) {
sb.append("type=").append(type).append("&"); sb.append("type=").append(type).append("&");
return this; return this;
} }
public RedirectBuilder msg(String msg) { public RedirectBuilder msg(String msg) {
sb.append("msg=").append(escape(msg)).append("&"); sb.append("msg=").append(escape(msg)).append("&");
return this; return this;
} }
public RedirectBuilder title(String title) { public RedirectBuilder title(String title) {
sb.append("title=").append(escape(title)).append("&"); sb.append("title=").append(escape(title)).append("&");
return this; return this;
} }
public RedirectBuilder noButton() { public RedirectBuilder noButton() {
sb.append("btn=").append("hide").append("&"); sb.append("btn=").append("hide").append("&");
return this; return this;
} }
public RedirectBuilder button(String text) { public RedirectBuilder button(String text) {
sb.append("btn=").append(escape(text)).append("&"); sb.append("btn=").append(escape(text)).append("&");
return this; return this;
} }
public RedirectBuilder icon(WeUIIcon icon) { public RedirectBuilder icon(WeUIIcon icon) {
sb.append("icon=").append(icon.toString()).append("&"); sb.append("icon=").append(icon.toString()).append("&");
return this; return this;
} }
public RedirectBuilder to(String url) { public RedirectBuilder to(String url) {
sb.append("redirect=").append(escape(url)).append("&"); sb.append("redirect=").append(escape(url)).append("&");
return this; return this;
} }
public void go(HttpServletResponse resp) throws IOException { public void go(HttpServletResponse resp) throws IOException {
resp.sendRedirect(sb.toString()); resp.sendRedirect(sb.toString());
} }
public String toString() { public String toString() {
return sb.toString(); return sb.toString();
} }
private static String escape(String str) { private static String escape(String str) {
return UrlEscapers.urlFragmentEscaper().escape(str); return UrlEscapers.urlFragmentEscaper().escape(str);
} }
} }
public enum WeUIIcon { public enum WeUIIcon {
SUCCESS("weui_icon_success"), SUCCESS("weui_icon_success"),
SUCCESS_CIRCLE("weui_icon_success_circle"), SUCCESS_CIRCLE("weui_icon_success_circle"),
SUCCESS_NO_CIRCLE("weui_icon_success_no_circle"), SUCCESS_NO_CIRCLE("weui_icon_success_no_circle"),
SUCCESS_SAFE("weui_icon_safe_success"), SUCCESS_SAFE("weui_icon_safe_success"),
INFO("weui_icon_info"), INFO("weui_icon_info"),
INFO_CIRCLE("weui_icon_info_circle"), INFO_CIRCLE("weui_icon_info_circle"),
WAITING("weui_icon_waiting"), WAITING("weui_icon_waiting"),
WAITING_CIRCLE("weui_icon_waiting_circle"), WAITING_CIRCLE("weui_icon_waiting_circle"),
CIRCLE("weui_icon_circle"), CIRCLE("weui_icon_circle"),
WARN("weui_icon_warn"), WARN("weui_icon_warn"),
WARN_SAFE("weui_icon_safe_warn"), WARN_SAFE("weui_icon_safe_warn"),
DOWNLOAD("weui_icon_download"), DOWNLOAD("weui_icon_download"),
CANCEL("weui_icon_cancel"),; CANCEL("weui_icon_cancel"),;
private String value; private String value;
WeUIIcon(String value) { WeUIIcon(String value) {
this.value = value; this.value = value;
} }
@Override @Override
public String toString() { public String toString() {
return value; return value;
} }
} }
} }

View File

@@ -33,43 +33,43 @@ import static love.sola.netsupport.config.Lang.lang;
*/ */
public enum Command { public enum Command {
REGISTER(0, RegisterHandler.class), REGISTER(0, RegisterHandler.class),
QUERY(1, QueryHandler.class), QUERY(1, QueryHandler.class),
SUBMIT(2, SubmitHandler.class), SUBMIT(2, SubmitHandler.class),
CANCEL(3, CancelHandler.class), CANCEL(3, CancelHandler.class),
PROFILE(4, ProfileHandler.class), PROFILE(4, ProfileHandler.class),
LOGIN(10, LoginHandler.class), LOGIN(10, LoginHandler.class),
OPERATOR_INFO(11, OperatorInfoHandler.class), OPERATOR_INFO(11, OperatorInfoHandler.class),
SIGN(12, SignHandler.class), //FIXME SIGN(12, SignHandler.class), //FIXME
; ;
private static final Map<Integer, Command> ID_MAP = new HashMap<>(); private static final Map<Integer, Command> ID_MAP = new HashMap<>();
static { static {
for (Command type : values()) { for (Command type : values()) {
if (type.id >= 0) { if (type.id >= 0) {
ID_MAP.put(type.id, type); ID_MAP.put(type.id, type);
} }
} }
} }
public final String regex; public final String regex;
public final Class<? extends WxMpMessageHandler> handler; public final Class<? extends WxMpMessageHandler> handler;
public final int id; public final int id;
Command(int id, Class<? extends WxMpMessageHandler> handler) { Command(int id, Class<? extends WxMpMessageHandler> handler) {
this.id = id; this.id = id;
this.regex = lang("REGEX_" + name()); this.regex = lang("REGEX_" + name());
this.handler = handler; this.handler = handler;
} }
public static Command fromId(int id) { public static Command fromId(int id) {
return ID_MAP.get(id); return ID_MAP.get(id);
} }
@Override @Override
public String toString() { public String toString() {
return name(); return name();
} }
} }

View File

@@ -46,94 +46,94 @@ import static love.sola.netsupport.config.Lang.lang;
@WebServlet(name = "WxMpServlet", urlPatterns = "/wechat", loadOnStartup = 99) @WebServlet(name = "WxMpServlet", urlPatterns = "/wechat", loadOnStartup = 99)
public class WxMpServlet extends HttpServlet { public class WxMpServlet extends HttpServlet {
public static WxMpServlet instance; public static WxMpServlet instance;
protected WxMpInMemoryConfigStorage config; protected WxMpInMemoryConfigStorage config;
public WxMpService wxMpService; public WxMpService wxMpService;
protected WxMpMessageRouter wxMpMessageRouter; protected WxMpMessageRouter wxMpMessageRouter;
protected CheckSpamMatcher checkSpamMatcher; protected CheckSpamMatcher checkSpamMatcher;
public WxMpServlet() { public WxMpServlet() {
instance = this; instance = this;
} }
@Override @Override
public void init() throws ServletException { public void init() throws ServletException {
super.init(); super.init();
config = new WxMpInMemoryConfigStorage(); config = new WxMpInMemoryConfigStorage();
config.setAppId(Settings.I.Wechat_AppId); config.setAppId(Settings.I.Wechat_AppId);
config.setSecret(Settings.I.Wechat_Secret); config.setSecret(Settings.I.Wechat_Secret);
config.setToken(Settings.I.Wechat_Token); config.setToken(Settings.I.Wechat_Token);
config.setAesKey(Settings.I.Wechat_AesKey); config.setAesKey(Settings.I.Wechat_AesKey);
wxMpService = new WxMpServiceImpl(); wxMpService = new WxMpServiceImpl();
wxMpService.setWxMpConfigStorage(config); wxMpService.setWxMpConfigStorage(config);
checkSpamMatcher = new CheckSpamMatcher(); checkSpamMatcher = new CheckSpamMatcher();
wxMpMessageRouter = new WxMpMessageRouter(wxMpService); wxMpMessageRouter = new WxMpMessageRouter(wxMpService);
wxMpMessageRouter.rule() wxMpMessageRouter.rule()
.async(false) .async(false)
.msgType(WxConsts.XML_MSG_EVENT) .msgType(WxConsts.XML_MSG_EVENT)
.event(WxConsts.EVT_SUBSCRIBE) .event(WxConsts.EVT_SUBSCRIBE)
.handler(new SubscribeHandler()) .handler(new SubscribeHandler())
.end(); .end();
wxMpMessageRouter.rule() wxMpMessageRouter.rule()
.async(false) .async(false)
.matcher(new CheckSpamMatcher()) .matcher(new CheckSpamMatcher())
.handler((wxMessage, context, wxMpService1, sessionManager) .handler((wxMessage, context, wxMpService1, sessionManager)
-> WxMpXmlOutMessage.TEXT() -> WxMpXmlOutMessage.TEXT()
.fromUser(wxMessage.getToUserName()) .fromUser(wxMessage.getToUserName())
.toUser(wxMessage.getFromUserName()) .toUser(wxMessage.getFromUserName())
.content(lang("Message_Spam")).build()) .content(lang("Message_Spam")).build())
.end(); .end();
wxMpMessageRouter.rule() wxMpMessageRouter.rule()
.async(false) .async(false)
.matcher(new RegisterMatcher()) .matcher(new RegisterMatcher())
.handler(new RegisterHandler()) .handler(new RegisterHandler())
.end(); .end();
try { try {
registerCommands(wxMpMessageRouter); registerCommands(wxMpMessageRouter);
} catch (IllegalAccessException | InstantiationException e) { } catch (IllegalAccessException | InstantiationException e) {
throw new ServletException(e); throw new ServletException(e);
} }
} }
public static void registerCommands(WxMpMessageRouter router) throws IllegalAccessException, InstantiationException { public static void registerCommands(WxMpMessageRouter router) throws IllegalAccessException, InstantiationException {
for (Command c : Command.values()) { for (Command c : Command.values()) {
WxMpMessageHandler handler = c.handler.newInstance(); WxMpMessageHandler handler = c.handler.newInstance();
router.rule().async(false).msgType(WxConsts.XML_MSG_TEXT).rContent(c.regex).handler(handler).end(); router.rule().async(false).msgType(WxConsts.XML_MSG_TEXT).rContent(c.regex).handler(handler).end();
router.rule().async(false).msgType(WxConsts.XML_MSG_EVENT).event(WxConsts.EVT_CLICK).eventKey(c.name()).handler(handler).end(); router.rule().async(false).msgType(WxConsts.XML_MSG_EVENT).event(WxConsts.EVT_CLICK).eventKey(c.name()).handler(handler).end();
if (handler instanceof OAuth2Handler) { if (handler instanceof OAuth2Handler) {
OAuth2.registerOAuth2Handler(c.name(), (OAuth2Handler) handler); OAuth2.registerOAuth2Handler(c.name(), (OAuth2Handler) handler);
} }
} }
} }
@Override @Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException { throws ServletException, IOException {
response.setContentType("text/html;charset=utf-8"); response.setContentType("text/html;charset=utf-8");
response.setStatus(HttpServletResponse.SC_OK); response.setStatus(HttpServletResponse.SC_OK);
String signature = request.getParameter("signature"); String signature = request.getParameter("signature");
String nonce = request.getParameter("nonce"); String nonce = request.getParameter("nonce");
String timestamp = request.getParameter("timestamp"); String timestamp = request.getParameter("timestamp");
if (!wxMpService.checkSignature(timestamp, nonce, signature)) { if (!wxMpService.checkSignature(timestamp, nonce, signature)) {
// Signature fail // Signature fail
response.getWriter().println(lang("Access_Denied")); response.getWriter().println(lang("Access_Denied"));
return; return;
} }
String echostr = request.getParameter("echostr"); String echostr = request.getParameter("echostr");
if (StringUtils.isNotBlank(echostr)) { if (StringUtils.isNotBlank(echostr)) {
// validate request // validate request
response.getWriter().println(echostr); response.getWriter().println(echostr);
return; return;
} }
String encryptType = StringUtils.isBlank(request.getParameter("encrypt_type")) ? "raw" : request.getParameter("encrypt_type"); String encryptType = StringUtils.isBlank(request.getParameter("encrypt_type")) ? "raw" : request.getParameter("encrypt_type");
// if ("raw".equals(encryptType)) { // if ("raw".equals(encryptType)) {
// WxMpXmlMessage inMessage = WxMpXmlMessage.fromXml(request.getInputStream()); // WxMpXmlMessage inMessage = WxMpXmlMessage.fromXml(request.getInputStream());
@@ -149,32 +149,32 @@ public class WxMpServlet extends HttpServlet {
// return; // return;
// } // }
if ("aes".equals(encryptType)) { if ("aes".equals(encryptType)) {
String msgSignature = request.getParameter("msg_signature"); String msgSignature = request.getParameter("msg_signature");
WxMpXmlMessage inMessage = WxMpXmlMessage.fromEncryptedXml(request.getInputStream(), config, timestamp, nonce, msgSignature); WxMpXmlMessage inMessage = WxMpXmlMessage.fromEncryptedXml(request.getInputStream(), config, timestamp, nonce, msgSignature);
WxMpXmlOutMessage outMessage = wxMpMessageRouter.route(inMessage); WxMpXmlOutMessage outMessage = wxMpMessageRouter.route(inMessage);
if (outMessage == null) { if (outMessage == null) {
outMessage = WxMpXmlOutMessage.TEXT() outMessage = WxMpXmlOutMessage.TEXT()
.fromUser(inMessage.getToUserName()) .fromUser(inMessage.getToUserName())
.toUser(inMessage.getFromUserName()) .toUser(inMessage.getFromUserName())
.content(lang("Invalid_Operation")) .content(lang("Invalid_Operation"))
.build(); .build();
} }
response.getWriter().write(outMessage.toEncryptedXml(config)); response.getWriter().write(outMessage.toEncryptedXml(config));
return; return;
} }
response.getWriter().println(lang("Unknown_Encrypt_Type")); response.getWriter().println(lang("Unknown_Encrypt_Type"));
return; return;
} }
@Override @Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doPost(req, resp); doPost(req, resp);
} }
@Override @Override
public void destroy() { public void destroy() {
SQLCore.destroy(); SQLCore.destroy();
} }
} }

View File

@@ -31,10 +31,10 @@ import java.util.Map;
*/ */
public class AutoReplyHandler implements WxMpMessageHandler { public class AutoReplyHandler implements WxMpMessageHandler {
@Override @Override
public WxMpXmlOutMessage handle(WxMpXmlMessage wxMessage, Map<String, Object> context, WxMpService wxMpService, WxSessionManager sessionManager) throws WxErrorException { public WxMpXmlOutMessage handle(WxMpXmlMessage wxMessage, Map<String, Object> context, WxMpService wxMpService, WxSessionManager sessionManager) throws WxErrorException {
//TODO auto reply //TODO auto reply
return null; return null;
} }
} }

View File

@@ -45,33 +45,33 @@ import static love.sola.netsupport.config.Lang.lang;
*/ */
public class CancelHandler implements WxMpMessageHandler { public class CancelHandler implements WxMpMessageHandler {
@Override @Override
public WxMpXmlOutMessage handle(WxMpXmlMessage wxMessage, Map<String, Object> context, WxMpService wxMpService, WxSessionManager sessionManager) throws WxErrorException { public WxMpXmlOutMessage handle(WxMpXmlMessage wxMessage, Map<String, Object> context, WxMpService wxMpService, WxSessionManager sessionManager) throws WxErrorException {
User u = TableUser.getByWechat(wxMessage.getFromUserName()); User u = TableUser.getByWechat(wxMessage.getFromUserName());
Ticket t = TableTicket.latestOpen(u); Ticket t = TableTicket.latestOpen(u);
if (t == null) { if (t == null) {
return WxMpXmlOutMessage.TEXT().fromUser(wxMessage.getToUserName()).toUser(wxMessage.getFromUserName()) return WxMpXmlOutMessage.TEXT().fromUser(wxMessage.getToUserName()).toUser(wxMessage.getFromUserName())
.content(lang("No_Open_Ticket_Available")).build(); .content(lang("No_Open_Ticket_Available")).build();
} }
try (Session s = SQLCore.sf.openSession()) { try (Session s = SQLCore.sf.openSession()) {
t.setOperator(Operator.USER_SELF); t.setOperator(Operator.USER_SELF);
t.setUpdateTime(new Date()); t.setUpdateTime(new Date());
t.setRemark(lang("User_Cancel_Remark")); t.setRemark(lang("User_Cancel_Remark"));
t.setStatus(Status.SOLVED); t.setStatus(Status.SOLVED);
s.beginTransaction(); s.beginTransaction();
s.update(t); s.update(t);
s.getTransaction().commit(); s.getTransaction().commit();
NewsBuilder out = WxMpXmlOutMessage.NEWS().fromUser(wxMessage.getToUserName()).toUser(wxMessage.getFromUserName()); NewsBuilder out = WxMpXmlOutMessage.NEWS().fromUser(wxMessage.getToUserName()).toUser(wxMessage.getFromUserName());
WxMpXmlOutNewsMessage.Item item = new WxMpXmlOutNewsMessage.Item(); WxMpXmlOutNewsMessage.Item item = new WxMpXmlOutNewsMessage.Item();
item.setTitle(lang("Cancel_Title")); item.setTitle(lang("Cancel_Title"));
item.setDescription(ParseUtil.parseTicket(t)); item.setDescription(ParseUtil.parseTicket(t));
out.addArticle(item); out.addArticle(item);
return out.build(); return out.build();
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
return WxMpXmlOutMessage.TEXT().fromUser(wxMessage.getToUserName()).toUser(wxMessage.getFromUserName()) return WxMpXmlOutMessage.TEXT().fromUser(wxMessage.getToUserName()).toUser(wxMessage.getFromUserName())
.content(lang("Cancel_Failed")).build(); .content(lang("Cancel_Failed")).build();
} }
} }
} }

View File

@@ -45,37 +45,37 @@ import static love.sola.netsupport.config.Lang.lang;
*/ */
public class ProfileHandler implements WxMpMessageHandler, OAuth2Handler { public class ProfileHandler implements WxMpMessageHandler, OAuth2Handler {
@Override @Override
public WxMpXmlOutMessage handle(WxMpXmlMessage wxMessage, Map<String, Object> context, WxMpService wxMpService, WxSessionManager sessionManager) throws WxErrorException { public WxMpXmlOutMessage handle(WxMpXmlMessage wxMessage, Map<String, Object> context, WxMpService wxMpService, WxSessionManager sessionManager) throws WxErrorException {
User u = TableUser.getByWechat(wxMessage.getFromUserName()); User u = TableUser.getByWechat(wxMessage.getFromUserName());
WxSession session = WechatSession.create(); WxSession session = WechatSession.create();
session.setAttribute(Attribute.AUTHORIZED, Command.PROFILE); session.setAttribute(Attribute.AUTHORIZED, Command.PROFILE);
session.setAttribute(Attribute.WECHAT, wxMessage.getFromUserName()); session.setAttribute(Attribute.WECHAT, wxMessage.getFromUserName());
session.setAttribute(Attribute.USER, u); session.setAttribute(Attribute.USER, u);
TextBuilder out = WxMpXmlOutMessage.TEXT().fromUser(wxMessage.getToUserName()).toUser(wxMessage.getFromUserName()); TextBuilder out = WxMpXmlOutMessage.TEXT().fromUser(wxMessage.getToUserName()).toUser(wxMessage.getFromUserName());
out.content(format("Profile_Modify", format("User_Profile_Link", session.getId(), u.getName(), u.getIsp().id, u.getNetAccount(), u.getBlock(), u.getRoom(), u.getPhone()))); out.content(format("Profile_Modify", format("User_Profile_Link", session.getId(), u.getName(), u.getIsp().id, u.getNetAccount(), u.getBlock(), u.getRoom(), u.getPhone())));
return out.build(); return out.build();
} }
@Override @Override
public void onOAuth2(AsyncContext actx, HttpServletResponse resp, String user, WxSession session) { public void onOAuth2(AsyncContext actx, HttpServletResponse resp, String user, WxSession session) {
try { try {
User u = TableUser.getByWechat(user); User u = TableUser.getByWechat(user);
if (u == null) { if (u == null) {
session.setAttribute(Attribute.AUTHORIZED, Command.REGISTER); session.setAttribute(Attribute.AUTHORIZED, Command.REGISTER);
session.setAttribute(Attribute.WECHAT, user); session.setAttribute(Attribute.WECHAT, user);
Redirect.error().icon(Redirect.WeUIIcon.INFO).noButton() Redirect.error().icon(Redirect.WeUIIcon.INFO).noButton()
.title(lang("Need_Register_Title")).msg(lang("Need_Register")) .title(lang("Need_Register_Title")).msg(lang("Need_Register"))
.to(format("User_Register_Link", session.getId())).go(resp); .to(format("User_Register_Link", session.getId())).go(resp);
return; return;
} }
session.setAttribute(Attribute.AUTHORIZED, Command.PROFILE); session.setAttribute(Attribute.AUTHORIZED, Command.PROFILE);
session.setAttribute(Attribute.WECHAT, user); session.setAttribute(Attribute.WECHAT, user);
session.setAttribute(Attribute.USER, u); session.setAttribute(Attribute.USER, u);
resp.sendRedirect(format("User_Profile_Link", session.getId(), u.getName(), u.getIsp().id, u.getNetAccount(), u.getBlock(), u.getRoom(), u.getPhone())); resp.sendRedirect(format("User_Profile_Link", session.getId(), u.getName(), u.getIsp().id, u.getNetAccount(), u.getBlock(), u.getRoom(), u.getPhone()));
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
} }
} }
} }

View File

@@ -46,26 +46,26 @@ import static love.sola.netsupport.config.Lang.lang;
public class QueryHandler implements WxMpMessageHandler { public class QueryHandler implements WxMpMessageHandler {
@Override @Override
public WxMpXmlOutMessage handle(WxMpXmlMessage wxMessage, Map<String, Object> context, WxMpService wxMpService, WxSessionManager sessionManager) throws WxErrorException { public WxMpXmlOutMessage handle(WxMpXmlMessage wxMessage, Map<String, Object> context, WxMpService wxMpService, WxSessionManager sessionManager) throws WxErrorException {
User u = TableUser.getByWechat(wxMessage.getFromUserName()); User u = TableUser.getByWechat(wxMessage.getFromUserName());
Ticket t = TableTicket.latest(u); Ticket t = TableTicket.latest(u);
if (t == null) { if (t == null) {
return WxMpXmlOutMessage.TEXT().fromUser(wxMessage.getToUserName()).toUser(wxMessage.getFromUserName()) return WxMpXmlOutMessage.TEXT().fromUser(wxMessage.getToUserName()).toUser(wxMessage.getFromUserName())
.content(lang("No_Ticket_Available")).build(); .content(lang("No_Ticket_Available")).build();
} }
WxSession session = WechatSession.create(); WxSession session = WechatSession.create();
session.setAttribute(Attribute.AUTHORIZED, Command.QUERY); session.setAttribute(Attribute.AUTHORIZED, Command.QUERY);
session.setAttribute(Attribute.WECHAT, wxMessage.getFromUserName()); session.setAttribute(Attribute.WECHAT, wxMessage.getFromUserName());
session.setAttribute(Attribute.USER, u); session.setAttribute(Attribute.USER, u);
NewsBuilder out = WxMpXmlOutMessage.NEWS().fromUser(wxMessage.getToUserName()).toUser(wxMessage.getFromUserName()); NewsBuilder out = WxMpXmlOutMessage.NEWS().fromUser(wxMessage.getToUserName()).toUser(wxMessage.getFromUserName());
WxMpXmlOutNewsMessage.Item item = new WxMpXmlOutNewsMessage.Item(); WxMpXmlOutNewsMessage.Item item = new WxMpXmlOutNewsMessage.Item();
item.setTitle(lang("Query_Title")); item.setTitle(lang("Query_Title"));
item.setDescription(ParseUtil.parseTicket(t) + "\n" + lang("More_Details")); item.setDescription(ParseUtil.parseTicket(t) + "\n" + lang("More_Details"));
item.setUrl(format("User_Query_Link", session.getId())); item.setUrl(format("User_Query_Link", session.getId()));
out.addArticle(item); out.addArticle(item);
return out.build(); return out.build();
} }
} }

View File

@@ -40,24 +40,24 @@ import static love.sola.netsupport.config.Lang.format;
*/ */
public class RegisterHandler implements WxMpMessageHandler { public class RegisterHandler implements WxMpMessageHandler {
@Override @Override
public WxMpXmlOutMessage handle(WxMpXmlMessage wxMessage, Map<String, Object> context, WxMpService wxMpService, WxSessionManager sessionManager) public WxMpXmlOutMessage handle(WxMpXmlMessage wxMessage, Map<String, Object> context, WxMpService wxMpService, WxSessionManager sessionManager)
throws WxErrorException { throws WxErrorException {
TextBuilder out = WxMpXmlOutMessage.TEXT().fromUser(wxMessage.getToUserName()).toUser(wxMessage.getFromUserName()); TextBuilder out = WxMpXmlOutMessage.TEXT().fromUser(wxMessage.getToUserName()).toUser(wxMessage.getFromUserName());
String fromUser = wxMessage.getFromUserName(); String fromUser = wxMessage.getFromUserName();
User u = TableUser.getByWechat(fromUser); User u = TableUser.getByWechat(fromUser);
WxSession session = WechatSession.create(); WxSession session = WechatSession.create();
if (u != null) { if (u != null) {
session.setAttribute(Attribute.AUTHORIZED, Command.PROFILE); session.setAttribute(Attribute.AUTHORIZED, Command.PROFILE);
session.setAttribute(Attribute.WECHAT, fromUser); session.setAttribute(Attribute.WECHAT, fromUser);
session.setAttribute(Attribute.USER, u); session.setAttribute(Attribute.USER, u);
out.content(format("Already_Registered", format("User_Profile_Link", session.getId(), u.getName(), u.getIsp().id, u.getNetAccount(), u.getBlock(), u.getRoom(), u.getPhone()))); out.content(format("Already_Registered", format("User_Profile_Link", session.getId(), u.getName(), u.getIsp().id, u.getNetAccount(), u.getBlock(), u.getRoom(), u.getPhone())));
} else { } else {
session.setAttribute(Attribute.AUTHORIZED, Command.REGISTER); session.setAttribute(Attribute.AUTHORIZED, Command.REGISTER);
session.setAttribute(Attribute.WECHAT, fromUser); session.setAttribute(Attribute.WECHAT, fromUser);
out.content(format("User_Register", format("User_Register_Link", session.getId()))); out.content(format("User_Register", format("User_Register_Link", session.getId())));
} }
return out.build(); return out.build();
} }
} }

View File

@@ -43,25 +43,25 @@ import static love.sola.netsupport.config.Lang.lang;
*/ */
public class SubmitHandler implements WxMpMessageHandler { public class SubmitHandler implements WxMpMessageHandler {
@Override @Override
public WxMpXmlOutMessage handle(WxMpXmlMessage wxMessage, Map<String, Object> context, WxMpService wxMpService, WxSessionManager sessionManager) throws WxErrorException { public WxMpXmlOutMessage handle(WxMpXmlMessage wxMessage, Map<String, Object> context, WxMpService wxMpService, WxSessionManager sessionManager) throws WxErrorException {
User u = TableUser.getByWechat(wxMessage.getFromUserName()); User u = TableUser.getByWechat(wxMessage.getFromUserName());
if (TableTicket.hasOpen(u)) { if (TableTicket.hasOpen(u)) {
return WxMpXmlOutMessage.TEXT().fromUser(wxMessage.getToUserName()).toUser(wxMessage.getFromUserName()) return WxMpXmlOutMessage.TEXT().fromUser(wxMessage.getToUserName()).toUser(wxMessage.getFromUserName())
.content(lang("Already_Opening_Ticket")).build(); .content(lang("Already_Opening_Ticket")).build();
} }
WxSession session = WechatSession.create(); WxSession session = WechatSession.create();
session.setAttribute(Attribute.AUTHORIZED, Command.SUBMIT); session.setAttribute(Attribute.AUTHORIZED, Command.SUBMIT);
session.setAttribute(Attribute.WECHAT, wxMessage.getFromUserName()); session.setAttribute(Attribute.WECHAT, wxMessage.getFromUserName());
session.setAttribute(Attribute.USER, u); session.setAttribute(Attribute.USER, u);
NewsBuilder out = WxMpXmlOutMessage.NEWS().fromUser(wxMessage.getToUserName()).toUser(wxMessage.getFromUserName()); NewsBuilder out = WxMpXmlOutMessage.NEWS().fromUser(wxMessage.getToUserName()).toUser(wxMessage.getFromUserName());
WxMpXmlOutNewsMessage.Item item = new WxMpXmlOutNewsMessage.Item(); WxMpXmlOutNewsMessage.Item item = new WxMpXmlOutNewsMessage.Item();
item.setTitle(lang("Submit_Title")); item.setTitle(lang("Submit_Title"));
item.setDescription(lang("Submit_Desc")); item.setDescription(lang("Submit_Desc"));
item.setUrl(format("User_Submit_Link", session.getId(), u.getName(), u.getIsp().id, u.getRoom(), u.getBlock(), u.getPhone())); item.setUrl(format("User_Submit_Link", session.getId(), u.getName(), u.getIsp().id, u.getRoom(), u.getBlock(), u.getPhone()));
out.addArticle(item); out.addArticle(item);
return out.build(); return out.build();
} }
} }

View File

@@ -42,28 +42,28 @@ import static love.sola.netsupport.config.Lang.format;
*/ */
public class SubscribeHandler implements WxMpMessageHandler { public class SubscribeHandler implements WxMpMessageHandler {
@Override @Override
public WxMpXmlOutMessage handle(WxMpXmlMessage wxMessage, Map<String, Object> context, WxMpService wxMpService, WxSessionManager sessionManager) throws WxErrorException { 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()); TextBuilder out = WxMpXmlOutMessage.TEXT().fromUser(wxMessage.getToUserName()).toUser(wxMessage.getFromUserName());
String fromUser = wxMessage.getFromUserName(); String fromUser = wxMessage.getFromUserName();
User u = TableUser.getByWechat(fromUser); User u = TableUser.getByWechat(fromUser);
WxSession session = WechatSession.create(); WxSession session = WechatSession.create();
if (u != null) { if (u != null) {
session.setAttribute(Attribute.AUTHORIZED, Command.PROFILE); session.setAttribute(Attribute.AUTHORIZED, Command.PROFILE);
session.setAttribute(Attribute.WECHAT, fromUser); session.setAttribute(Attribute.WECHAT, fromUser);
session.setAttribute(Attribute.USER, u); session.setAttribute(Attribute.USER, u);
out.content(format("Event_Subscribe", format("Already_Registered", format("User_Profile_Link", session.getId(), u.getName(), u.getIsp().id, u.getNetAccount(), u.getBlock(), u.getRoom(), u.getPhone())))); out.content(format("Event_Subscribe", format("Already_Registered", format("User_Profile_Link", session.getId(), u.getName(), u.getIsp().id, u.getNetAccount(), u.getBlock(), u.getRoom(), u.getPhone()))));
Operator op = TableOperator.get(fromUser); Operator op = TableOperator.get(fromUser);
if (op != null) { if (op != null) {
wxMpService.userUpdateGroup(fromUser, 100L); wxMpService.userUpdateGroup(fromUser, 100L);
} }
} else { } else {
session.setAttribute(Attribute.AUTHORIZED, Command.REGISTER); session.setAttribute(Attribute.AUTHORIZED, Command.REGISTER);
session.setAttribute(Attribute.WECHAT, fromUser); session.setAttribute(Attribute.WECHAT, fromUser);
out.content(format("Event_Subscribe", format("User_Register", format("User_Register_Link", session.getId())))); out.content(format("Event_Subscribe", format("User_Register", format("User_Register_Link", session.getId()))));
} }
return out.build(); return out.build();
} }
} }

View File

@@ -46,51 +46,51 @@ import static love.sola.netsupport.config.Lang.lang;
*/ */
public class LoginHandler implements WxMpMessageHandler, OAuth2Handler { public class LoginHandler implements WxMpMessageHandler, OAuth2Handler {
@Override @Override
public WxMpXmlOutMessage handle(WxMpXmlMessage wxMessage, Map<String, Object> context, WxMpService wxMpService, WxSessionManager sessionManager) throws WxErrorException { 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()); TextBuilder out = WxMpXmlOutMessage.TEXT().fromUser(wxMessage.getToUserName()).toUser(wxMessage.getFromUserName());
try { try {
Operator operator = TableOperator.get(wxMessage.getFromUserName()); Operator operator = TableOperator.get(wxMessage.getFromUserName());
if (operator == null) if (operator == null)
out.content(lang("Not_Operator")); out.content(lang("Not_Operator"));
else if (operator.getAccess() >= Access.NO_LOGIN) { else if (operator.getAccess() >= Access.NO_LOGIN) {
out.content(lang("No_Login")); out.content(lang("No_Login"));
} else { } else {
WxSession session = WechatSession.create(); WxSession session = WechatSession.create();
session.setAttribute(Attribute.AUTHORIZED, Command.LOGIN); session.setAttribute(Attribute.AUTHORIZED, Command.LOGIN);
session.setAttribute(Attribute.WECHAT, wxMessage.getFromUserName()); session.setAttribute(Attribute.WECHAT, wxMessage.getFromUserName());
session.setAttribute(Attribute.OPERATOR, operator); session.setAttribute(Attribute.OPERATOR, operator);
out.content(format("Home_Page_Msg", format("Operator_Home_Page", session.getId()))); out.content(format("Home_Page_Msg", format("Operator_Home_Page", session.getId())));
} }
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
out.content(lang("Login_Error")); out.content(lang("Login_Error"));
} }
return out.build(); return out.build();
} }
@Override @Override
public void onOAuth2(AsyncContext actx, HttpServletResponse resp, String user, WxSession session) { public void onOAuth2(AsyncContext actx, HttpServletResponse resp, String user, WxSession session) {
try { try {
Operator operator = TableOperator.get(user); Operator operator = TableOperator.get(user);
if (operator == null) { if (operator == null) {
Redirect.error().icon(Redirect.WeUIIcon.WARN_SAFE).noButton() Redirect.error().icon(Redirect.WeUIIcon.WARN_SAFE).noButton()
.title(lang("Not_Operator")).msg(lang("Not_Operator_OAuth2")).go(resp); .title(lang("Not_Operator")).msg(lang("Not_Operator_OAuth2")).go(resp);
return; return;
} }
if (operator.getAccess() >= Access.NO_LOGIN) { if (operator.getAccess() >= Access.NO_LOGIN) {
Redirect.error().icon(Redirect.WeUIIcon.WAITING).noButton() Redirect.error().icon(Redirect.WeUIIcon.WAITING).noButton()
.title(lang("Left_Operator_Title")).msg(lang("Left_Operator")).go(resp); .title(lang("Left_Operator_Title")).msg(lang("Left_Operator")).go(resp);
return; return;
} }
session.setAttribute(Attribute.AUTHORIZED, Command.LOGIN); session.setAttribute(Attribute.AUTHORIZED, Command.LOGIN);
session.setAttribute(Attribute.WECHAT, user); session.setAttribute(Attribute.WECHAT, user);
session.setAttribute(Attribute.OPERATOR, operator); session.setAttribute(Attribute.OPERATOR, operator);
resp.sendRedirect(format("Operator_Home_Page", session.getId())); resp.sendRedirect(format("Operator_Home_Page", session.getId()));
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
} }
} }
} }

View File

@@ -37,23 +37,23 @@ import static love.sola.netsupport.config.Lang.lang;
*/ */
public class OperatorInfoHandler implements WxMpMessageHandler { public class OperatorInfoHandler implements WxMpMessageHandler {
@Override @Override
public WxMpXmlOutMessage handle(WxMpXmlMessage wxMessage, Map<String, Object> context, WxMpService wxMpService, WxSessionManager sessionManager) throws WxErrorException { 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()); TextBuilder out = WxMpXmlOutMessage.TEXT().fromUser(wxMessage.getToUserName()).toUser(wxMessage.getFromUserName());
try { try {
Operator op = TableOperator.get(wxMessage.getFromUserName()); Operator op = TableOperator.get(wxMessage.getFromUserName());
if (op == null) { if (op == null) {
out.content(lang("Not_Operator")); out.content(lang("Not_Operator"));
// } else if (op.getAccess() >= Access.NO_LOGIN) { // } else if (op.getAccess() >= Access.NO_LOGIN) {
// out.content(lang("No_Login")); // out.content(lang("No_Login"));
} else { } else {
out.content(format("Operator_Info", op.getId(), op.getName(), op.getAccess(), op.getBlock(), op.getWeek())); out.content(format("Operator_Info", op.getId(), op.getName(), op.getAccess(), op.getBlock(), op.getWeek()));
} }
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
out.content(lang("Login_Error")); out.content(lang("Login_Error"));
} }
return out.build(); return out.build();
} }
} }

View File

@@ -35,72 +35,72 @@ import java.util.regex.Matcher;
import java.util.regex.Pattern; import java.util.regex.Pattern;
/** /**
* @deprecated limited time only
* @author Sola {@literal <dev@sola.love>} * @author Sola {@literal <dev@sola.love>}
* @deprecated limited time only
*/ */
@Deprecated @Deprecated
public class SignHandler implements WxMpMessageHandler { public class SignHandler implements WxMpMessageHandler {
public static Pattern pat = Pattern.compile("^(?i)Auth (\\d{4})"); public static Pattern pat = Pattern.compile("^(?i)Auth (\\d{4})");
public static final int INVALID_ID = -1; public static final int INVALID_ID = -1;
public static final int SIGNED_ID = -2; public static final int SIGNED_ID = -2;
@Override @Override
public WxMpXmlOutMessage handle(WxMpXmlMessage wxMessage, Map<String, Object> context, WxMpService wxMpService, WxSessionManager sessionManager) throws WxErrorException { public WxMpXmlOutMessage handle(WxMpXmlMessage wxMessage, Map<String, Object> context, WxMpService wxMpService, WxSessionManager sessionManager) throws WxErrorException {
String msg = wxMessage.getContent(); String msg = wxMessage.getContent();
TextBuilder out = WxMpXmlOutMessage.TEXT().toUser(wxMessage.getFromUserName()).fromUser(wxMessage.getToUserName()); TextBuilder out = WxMpXmlOutMessage.TEXT().toUser(wxMessage.getFromUserName()).fromUser(wxMessage.getToUserName());
Matcher mat = pat.matcher(msg); Matcher mat = pat.matcher(msg);
root: root:
if (mat.find()) { if (mat.find()) {
int id = Integer.parseInt(mat.group(1)); int id = Integer.parseInt(mat.group(1));
try (Connection conn = SQLCore.ds.getConnection()) { try (Connection conn = SQLCore.ds.getConnection()) {
switch (checkID(conn, id)) { switch (checkID(conn, id)) {
case INVALID_ID: case INVALID_ID:
out.content("无效ID。"); out.content("无效ID。");
break root; break root;
case SIGNED_ID: case SIGNED_ID:
out.content("该ID已登记过。"); out.content("该ID已登记过。");
break root; break root;
} }
if (checkDuplicated(conn, wxMessage.getFromUserName())) { if (checkDuplicated(conn, wxMessage.getFromUserName())) {
out.content("你的微信已经登记过。"); out.content("你的微信已经登记过。");
break root; break root;
} }
PreparedStatement ps = conn.prepareStatement("UPDATE auth SET wechat=? WHERE id=?"); PreparedStatement ps = conn.prepareStatement("UPDATE auth SET wechat=? WHERE id=?");
ps.setString(1, wxMessage.getFromUserName()); ps.setString(1, wxMessage.getFromUserName());
ps.setInt(2, id); ps.setInt(2, id);
if (ps.executeUpdate() == 1) { if (ps.executeUpdate() == 1) {
out.content("登记成功。"); out.content("登记成功。");
} else { } else {
out.content("登记失败,请联系管理员。"); out.content("登记失败,请联系管理员。");
} }
} catch (SQLException e) { } catch (SQLException e) {
e.printStackTrace(); e.printStackTrace();
out.content("系统异常,请联系管理员。"); out.content("系统异常,请联系管理员。");
} }
} else { } else {
out.content("无效ID。"); out.content("无效ID。");
} }
return out.build(); return out.build();
} }
private static int checkID(Connection conn, int id) throws SQLException { private static int checkID(Connection conn, int id) throws SQLException {
PreparedStatement ps = conn.prepareStatement("SELECT wechat FROM auth WHERE id=?"); PreparedStatement ps = conn.prepareStatement("SELECT wechat FROM auth WHERE id=?");
ps.setInt(1, id); ps.setInt(1, id);
ResultSet rs = ps.executeQuery(); ResultSet rs = ps.executeQuery();
if (rs.next()) { if (rs.next()) {
return rs.getString("wechat") != null ? SIGNED_ID : 0; return rs.getString("wechat") != null ? SIGNED_ID : 0;
} else { } else {
return INVALID_ID; return INVALID_ID;
} }
} }
private static boolean checkDuplicated(Connection conn, String wechat) throws SQLException { private static boolean checkDuplicated(Connection conn, String wechat) throws SQLException {
PreparedStatement ps = conn.prepareStatement("SELECT wechat FROM auth WHERE wechat=?"); PreparedStatement ps = conn.prepareStatement("SELECT wechat FROM auth WHERE wechat=?");
ps.setString(1, wechat); ps.setString(1, wechat);
ResultSet rs = ps.executeQuery(); ResultSet rs = ps.executeQuery();
return rs.next(); return rs.next();
} }
} }

View File

@@ -31,27 +31,27 @@ import java.util.concurrent.TimeUnit;
*/ */
public class CheckSpamMatcher implements WxMpMessageMatcher { public class CheckSpamMatcher implements WxMpMessageMatcher {
private class ValueLoader extends CacheLoader<String, Long> { private class ValueLoader extends CacheLoader<String, Long> {
@Override @Override
public Long load(String key) throws Exception { public Long load(String key) throws Exception {
return System.currentTimeMillis() + Settings.I.Check_Spam_Interval; return System.currentTimeMillis() + Settings.I.Check_Spam_Interval;
} }
} }
private LoadingCache<String, Long> cache = CacheBuilder.newBuilder() private LoadingCache<String, Long> cache = CacheBuilder.newBuilder()
.concurrencyLevel(4) .concurrencyLevel(4)
.maximumSize(4096) .maximumSize(4096)
.expireAfterWrite(Settings.I.Check_Spam_Cache_Expire_Time, TimeUnit.SECONDS) .expireAfterWrite(Settings.I.Check_Spam_Cache_Expire_Time, TimeUnit.SECONDS)
.build(new ValueLoader()); .build(new ValueLoader());
@Override @Override
public boolean match(WxMpXmlMessage wxMessage) { public boolean match(WxMpXmlMessage wxMessage) {
Long l = cache.getIfPresent(wxMessage.getFromUserName()); Long l = cache.getIfPresent(wxMessage.getFromUserName());
if (l != null && l > System.currentTimeMillis()) { if (l != null && l > System.currentTimeMillis()) {
return true; return true;
} }
cache.refresh(wxMessage.getFromUserName()); cache.refresh(wxMessage.getFromUserName());
return false; return false;
} }
} }

View File

@@ -29,22 +29,22 @@ import java.util.concurrent.ConcurrentHashMap;
*/ */
public class CommandMatcher implements WxMpMessageMatcher { public class CommandMatcher implements WxMpMessageMatcher {
public static Map<String, Command> inCmdUsers = new ConcurrentHashMap<>(); public static Map<String, Command> inCmdUsers = new ConcurrentHashMap<>();
Command command; Command command;
public CommandMatcher(Command command) { public CommandMatcher(Command command) {
this.command = command; this.command = command;
} }
@Override @Override
public boolean match(WxMpXmlMessage message) { public boolean match(WxMpXmlMessage message) {
String fromUser = message.getFromUserName(); String fromUser = message.getFromUserName();
if (inCmdUsers.containsKey(fromUser)) { if (inCmdUsers.containsKey(fromUser)) {
return command == inCmdUsers.get(fromUser); return command == inCmdUsers.get(fromUser);
} else { } else {
return message.getContent().matches(command.regex); return message.getContent().matches(command.regex);
} }
} }
} }

View File

@@ -26,9 +26,9 @@ import me.chanjar.weixin.mp.bean.WxMpXmlMessage;
*/ */
public class RegisterMatcher implements WxMpMessageMatcher { public class RegisterMatcher implements WxMpMessageMatcher {
@Override @Override
public boolean match(WxMpXmlMessage message) { public boolean match(WxMpXmlMessage message) {
return TableUser.getByWechat(message.getFromUserName()) == null; return TableUser.getByWechat(message.getFromUserName()) == null;
} }
} }

View File

@@ -6,42 +6,42 @@
~ See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>. ~ See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
--> -->
<!DOCTYPE hibernate-configuration PUBLIC <!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN" "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd"> "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration> <hibernate-configuration>
<session-factory> <session-factory>
<!-- Database connection settings --> <!-- Database connection settings -->
<!--<property name="jndi.class">org.apache.naming.factory.BeanFactory</property>--> <!--<property name="jndi.class">org.apache.naming.factory.BeanFactory</property>-->
<property name="connection.datasource">java:comp/env/jdbc/netsupport</property> <property name="connection.datasource">java:comp/env/jdbc/netsupport</property>
<!--<property name="connection.driver_class">com.mysql.jdbc.Driver</property>--> <!--<property name="connection.driver_class">com.mysql.jdbc.Driver</property>-->
<!--<property name="connection.url">jdbc:mysql://localhost:3306/***?autoReconnect=true&amp;characterEncoding=utf8</property>--> <!--<property name="connection.url">jdbc:mysql://localhost:3306/***?autoReconnect=true&amp;characterEncoding=utf8</property>-->
<!--<property name="connection.username">***</property>--> <!--<property name="connection.username">***</property>-->
<!--<property name="connection.password">***</property>--> <!--<property name="connection.password">***</property>-->
<!-- JDBC connection pool (use the built-in) --> <!-- JDBC connection pool (use the built-in) -->
<!--<property name="connection.pool_size">50</property>--> <!--<property name="connection.pool_size">50</property>-->
<!-- SQL dialect --> <!-- SQL dialect -->
<property name="dialect">org.hibernate.dialect.MySQL5InnoDBDialect</property> <property name="dialect">org.hibernate.dialect.MySQL5InnoDBDialect</property>
<!-- Disable the second-level cache --> <!-- Disable the second-level cache -->
<property name="cache.provider_class">org.hibernate.cache.internal.NoCacheProvider</property> <property name="cache.provider_class">org.hibernate.cache.internal.NoCacheProvider</property>
<!-- Echo all executed SQL to stdout --> <!-- Echo all executed SQL to stdout -->
<property name="show_sql">true</property> <property name="show_sql">true</property>
<!-- Drop and re-create the database schema on startup --> <!-- Drop and re-create the database schema on startup -->
<property name="hbm2ddl.auto">validate</property> <property name="hbm2ddl.auto">validate</property>
<!-- Names the annotated entity class --> <!-- Names the annotated entity class -->
<mapping class="love.sola.netsupport.pojo.User"/> <mapping class="love.sola.netsupport.pojo.User"/>
<mapping class="love.sola.netsupport.pojo.Ticket"/> <mapping class="love.sola.netsupport.pojo.Ticket"/>
<mapping class="love.sola.netsupport.pojo.Operator"/> <mapping class="love.sola.netsupport.pojo.Operator"/>
<mapping class="love.sola.netsupport.pojo.ToolsCheck"/> <mapping class="love.sola.netsupport.pojo.ToolsCheck"/>
</session-factory> </session-factory>
</hibernate-configuration> </hibernate-configuration>

View File

@@ -1,6 +1,6 @@
<wechat-config> <wechat-config>
<appId>****</appId> <appId>****</appId>
<secret>****</secret> <secret>****</secret>
<token>****</token> <token>****</token>
<aesKey>****</aesKey> <aesKey>****</aesKey>
</wechat-config> </wechat-config>

View File

@@ -19,31 +19,31 @@
<!-- Don't swallowOutput for debugging, true for logging(production) --> <!-- Don't swallowOutput for debugging, true for logging(production) -->
<Context antiResourceLocking="true"> <Context antiResourceLocking="true">
<!-- Default set of monitored resources --> <!-- Default set of monitored resources -->
<WatchedResource>WEB-INF/web.xml</WatchedResource> <WatchedResource>WEB-INF/web.xml</WatchedResource>
<!-- Uncomment this to disable session persistence across Tomcat restarts --> <!-- Uncomment this to disable session persistence across Tomcat restarts -->
<!-- <!--
<Manager pathname="" /> <Manager pathname="" />
--> -->
<Resource auth="Container" <Resource auth="Container"
description="C3P0 database connection pool" description="C3P0 database connection pool"
driverClass="com.mysql.jdbc.Driver" driverClass="com.mysql.jdbc.Driver"
maxPoolSize="10" maxPoolSize="10"
minPoolSize="2" minPoolSize="2"
acquireIncrement="1" acquireIncrement="1"
maxIdleTime="3600" maxIdleTime="3600"
idleConnectionTestPeriod="1800" idleConnectionTestPeriod="1800"
name="jdbc/netsupport" name="jdbc/netsupport"
user="root" user="root"
password="" password=""
factory="org.apache.naming.factory.BeanFactory" factory="org.apache.naming.factory.BeanFactory"
type="com.mchange.v2.c3p0.ComboPooledDataSource" type="com.mchange.v2.c3p0.ComboPooledDataSource"
jdbcUrl="jdbc:mysql://localhost:3306/netsupport?autoReconnect=true&amp;characterEncoding=utf8"/> jdbcUrl="jdbc:mysql://localhost:3306/netsupport?autoReconnect=true&amp;characterEncoding=utf8"/>
<!-- Uncomment this to enable Comet connection tacking (provides events <!-- Uncomment this to enable Comet connection tacking (provides events
on session expiration as well as webapp lifecycle) --> on session expiration as well as webapp lifecycle) -->
<!-- <!--
<Valve className="org.apache.catalina.valves.CometConnectionManagerValve" /> <Valve className="org.apache.catalina.valves.CometConnectionManagerValve" />
--> -->
</Context> </Context>

View File

@@ -5,22 +5,22 @@
http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
version="3.1"> version="3.1">
<!-- General description of your web application --> <!-- General description of your web application -->
<display-name>Network Support Application</display-name> <display-name>Network Support Application</display-name>
<description> <description>
If you have any problem, please contact loli@sola.love . If you have any problem, please contact loli@sola.love .
</description> </description>
<welcome-file-list> <welcome-file-list>
<welcome-file>index</welcome-file> <welcome-file>index</welcome-file>
</welcome-file-list> </welcome-file-list>
<error-page> <error-page>
<location>/index</location> <location>/index</location>
</error-page> </error-page>
<session-config> <session-config>
<session-timeout>10</session-timeout> <!-- 30 minutes --> <session-timeout>10</session-timeout> <!-- 30 minutes -->
</session-config> </session-config>
</web-app> </web-app>

View File

@@ -10,11 +10,11 @@ import java.util.Set;
*/ */
public class ReflectionTest { public class ReflectionTest {
@Test @Test
public void test() { public void test() {
Reflections reflections = new Reflections(getClass().getPackage().getName()); Reflections reflections = new Reflections(getClass().getPackage().getName());
Set<Class<? extends API>> set = reflections.getSubTypesOf(API.class); Set<Class<? extends API>> set = reflections.getSubTypesOf(API.class);
assert set.size() == 15; assert set.size() == 15;
} }
} }

View File

@@ -7,9 +7,9 @@ import org.junit.Test;
*/ */
public class CortanaTest { public class CortanaTest {
@Test @Test
public void load() throws Exception { public void load() throws Exception {
Cortana.load(); Cortana.load();
} }
} }

View File

@@ -7,9 +7,9 @@ import org.junit.Test;
*/ */
public class ReflectionTest { public class ReflectionTest {
@Test @Test
public void testLang() { public void testLang() {
assert Lang.messages != null; assert Lang.messages != null;
} }
} }

View File

@@ -7,19 +7,19 @@ import org.junit.Test;
*/ */
public class ReflectionTest { public class ReflectionTest {
@Test @Test
public void testBlock() { public void testBlock() {
assert Block.inverseMap != null; assert Block.inverseMap != null;
} }
@Test @Test
public void testAccess() { public void testAccess() {
assert Access.inverseMap != null; assert Access.inverseMap != null;
} }
@Test @Test
public void testStatus() { public void testStatus() {
assert Status.inverseMap != null; assert Status.inverseMap != null;
} }
} }

View File

@@ -14,28 +14,28 @@ import java.security.spec.X509EncodedKeySpec;
*/ */
public class EncryptTest { public class EncryptTest {
@Test @Test
public void testBCrypt() { public void testBCrypt() {
String hash = BCrypt.hashpw("mypasswordhere", BCrypt.gensalt()); String hash = BCrypt.hashpw("mypasswordhere", BCrypt.gensalt());
assert BCrypt.checkpw("mypasswordhere", hash); assert BCrypt.checkpw("mypasswordhere", hash);
} }
@Test @Test
public void testRSA() { public void testRSA() {
assert "Hello World".equals(RSAUtil.decrypt(RSAUtil.encrypt("Hello World"))); assert "Hello World".equals(RSAUtil.decrypt(RSAUtil.encrypt("Hello World")));
assert "Encrypt".equals(RSAUtil.decrypt(RSAUtil.encrypt("Encrypt"))); assert "Encrypt".equals(RSAUtil.decrypt(RSAUtil.encrypt("Encrypt")));
} }
// @Test // @Test
public void testRSASpecKey() throws NoSuchAlgorithmException, InvalidKeySpecException { public void testRSASpecKey() throws NoSuchAlgorithmException, InvalidKeySpecException {
System.out.println("RSAUtil.privateKey_s = " + RSAUtil.privateKey_s); System.out.println("RSAUtil.privateKey_s = " + RSAUtil.privateKey_s);
System.out.println("RSAUtil.publicKey_s = " + RSAUtil.publicKey_s); System.out.println("RSAUtil.publicKey_s = " + RSAUtil.publicKey_s);
// String pkey = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCA0qyARvHSCIUQ6YM6K+e/QgiZ+dc/MpVz5DIFwQab5iiifruQiaoA74ilHOOiq5i0ToR1VxNhCUZcAy2saHNifoYKTauMOUSV6IoP4X5jp691PlI9yxNx328mSlPNM9+7BgOzrUP1pR71d+T4LDn0o4J6Ad82vVIe7yWszzF4qQIDAQAB"; // String pkey = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCA0qyARvHSCIUQ6YM6K+e/QgiZ+dc/MpVz5DIFwQab5iiifruQiaoA74ilHOOiq5i0ToR1VxNhCUZcAy2saHNifoYKTauMOUSV6IoP4X5jp691PlI9yxNx328mSlPNM9+7BgOzrUP1pR71d+T4LDn0o4J6Ad82vVIe7yWszzF4qQIDAQAB";
String pkey = RSAUtil.publicKey_s; String pkey = RSAUtil.publicKey_s;
KeyFactory keyFactory = KeyFactory.getInstance("RSA"); KeyFactory keyFactory = KeyFactory.getInstance("RSA");
X509EncodedKeySpec keySpec = new X509EncodedKeySpec(Base64.decodeBase64(pkey)); X509EncodedKeySpec keySpec = new X509EncodedKeySpec(Base64.decodeBase64(pkey));
RSAUtil.publicKey = keyFactory.generatePublic(keySpec); RSAUtil.publicKey = keyFactory.generatePublic(keySpec);
System.out.println("RSAUtil.encrypt(\"233\") = " + RSAUtil.encrypt("233")); System.out.println("RSAUtil.encrypt(\"233\") = " + RSAUtil.encrypt("233"));
} }
} }

View File

@@ -11,18 +11,18 @@ import java.util.Date;
*/ */
public class GsonTest { public class GsonTest {
@Test @Test
public void testJsonDate() { public void testJsonDate() {
Gson gson = new GsonBuilder() Gson gson = new GsonBuilder()
.registerTypeAdapter(Date.class, (JsonDeserializer<Date>) (json, typeOfT, context) -> new Date(json.getAsJsonPrimitive().getAsLong())) .registerTypeAdapter(Date.class, (JsonDeserializer<Date>) (json, typeOfT, context) -> new Date(json.getAsJsonPrimitive().getAsLong()))
.registerTypeAdapter(Date.class, (JsonSerializer<Date>) (src, typeOfSrc, context) -> new JsonPrimitive(src.getTime())) .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, (JsonDeserializer<ISP>) (json, typeOfT, context) -> ISP.fromId(json.getAsJsonPrimitive().getAsInt()))
.registerTypeAdapter(ISP.class, (JsonSerializer<ISP>) (src, typeOfSrc, context) -> new JsonPrimitive(src.id)) .registerTypeAdapter(ISP.class, (JsonSerializer<ISP>) (src, typeOfSrc, context) -> new JsonPrimitive(src.id))
.create(); .create();
Date date = new Date(); Date date = new Date();
assert gson.fromJson(gson.toJson(date), Date.class).compareTo(date) == 0; assert gson.fromJson(gson.toJson(date), Date.class).compareTo(date) == 0;
assert gson.fromJson(gson.toJson(ISP.TELECOM), ISP.class) == ISP.TELECOM; assert gson.fromJson(gson.toJson(ISP.TELECOM), ISP.class) == ISP.TELECOM;
assert gson.toJson(ISP.TELECOM).equals("1"); assert gson.toJson(ISP.TELECOM).equals("1");
} }
} }

View File

@@ -13,19 +13,19 @@ import static org.junit.Assert.assertThat;
*/ */
public class URLEncodeTest { public class URLEncodeTest {
@Test @Test
public void testEncode() throws UnsupportedEncodingException { public void testEncode() throws UnsupportedEncodingException {
assertThat( assertThat(
UrlEscapers.urlFragmentEscaper().escape("Test Title"), UrlEscapers.urlFragmentEscaper().escape("Test Title"),
equalTo("Test%20Title") equalTo("Test%20Title")
); );
assertThat( assertThat(
Redirect.success() Redirect.success()
.title("Test Title") .title("Test Title")
.msg("Test Message") .msg("Test Message")
.toString(), .toString(),
equalTo("http://s.wts.sola.love/nm/v2/result.html?type=1&title=Test%20Title&msg=Test%20Message&") equalTo("http://s.wts.sola.love/nm/v2/result.html?type=1&title=Test%20Title&msg=Test%20Message&")
); );
} }
} }