9 Commits

Author SHA1 Message Date
Sola
56acb22bea Merge branch 'develop' into feature/easter_eggs
* develop:
  fix bypass
  add bypasswechat debug api
2015-12-18 02:22:28 +08:00
Sola
0a966eb0f0 Merge branch 'develop' into feature/easter_eggs 2015-12-17 23:15:22 +08:00
Sola
0aec02ee7f bump code 2015-12-17 23:14:51 +08:00
Sola
1ee1bb607d add yaml test 2015-12-17 23:14:04 +08:00
Sola
782f923763 Merge branch 'develop' into feature/easter_eggs 2015-12-17 10:07:07 +08:00
Sola
f11d343c4e add test 2015-12-17 10:06:45 +08:00
Sola
c43117b7db Merge branch 'develop' into feature/easter_eggs 2015-12-16 16:56:48 +08:00
Sola
a4244f64b8 Merge branch 'develop' into feature/easter_eggs 2015-12-16 15:57:59 +08:00
Sola
2334cf6d68 Merge branch 'develop' into feature/easter_eggs 2015-12-16 02:37:08 +08:00
77 changed files with 1316 additions and 2398 deletions

1
.gitignore vendored
View File

@@ -9,4 +9,5 @@ out/
.DS_Store
.classpath
/target
/src/main/webapp/META-INF/context.xml
.project

316
pom.xml
View File

@@ -1,168 +1,162 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<name>WechatTicketSystem</name>
<groupId>love.sola.netsupport</groupId>
<artifactId>WechatTicketSystem</artifactId>
<version>2.0</version>
<packaging>war</packaging>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<name>WechatTicketSystem</name>
<groupId>love.sola.netsupport</groupId>
<artifactId>WechatTicketSystem</artifactId>
<version>1.1-SNAPSHOT</version>
<packaging>war</packaging>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<java.version>1.8</java.version>
<source>1.8</source>
<target>1.8</target>
</properties>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<java.version>1.8</java.version>
<source>1.8</source>
<target>1.8</target>
</properties>
<scm>
<connection>scm:svn:http://127.0.0.1/dummy</connection>
<developerConnection>scm:svn:https://127.0.0.1/dummy</developerConnection>
<tag>HEAD</tag>
<url>http://127.0.0.1/dummy</url>
</scm>
<scm>
<connection>scm:svn:http://127.0.0.1/dummy</connection>
<developerConnection>scm:svn:https://127.0.0.1/dummy</developerConnection>
<tag>HEAD</tag>
<url>http://127.0.0.1/dummy</url>
</scm>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.3</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>buildnumber-maven-plugin</artifactId>
<version>1.4</version>
<configuration>
<format>{0,number,0000}</format>
<items>
<item>buildNumber0</item>
</items>
<doCheck>false</doCheck>
<doUpdate>false</doUpdate>
<revisionOnScmFailure>unknown</revisionOnScmFailure>
</configuration>
<executions>
<execution>
<phase>validate</phase>
<goals>
<goal>create</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
<finalName>${project.artifactId}##${buildNumber}</finalName>
</build>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.3</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>buildnumber-maven-plugin</artifactId>
<version>1.4</version>
<configuration>
<format>{0,number,0000}</format>
<items>
<item>buildNumber0</item>
</items>
<doCheck>false</doCheck>
<doUpdate>false</doUpdate>
<revisionOnScmFailure>unknown</revisionOnScmFailure>
</configuration>
<executions>
<execution>
<phase>validate</phase>
<goals>
<goal>create</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
<finalName>${project.artifactId}##${buildNumber}</finalName>
</build>
<dependencies>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.16.6</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
<version>1.7.12</version>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>19.0-rc2</version>
</dependency>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.4</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-io</artifactId>
<version>1.3.2</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.4</version>
</dependency>
<dependency>
<groupId>commons-net</groupId>
<artifactId>commons-net</artifactId>
<version>3.3</version>
</dependency>
<dependency>
<groupId>me.chanjar</groupId>
<artifactId>weixin-java-mp</artifactId>
<version>1.3.3</version>
</dependency>
<dependency>
<groupId>com.mchange</groupId>
<artifactId>c3p0</artifactId>
<version>0.9.5.1</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.37</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>5.0.3.Final</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
<version>5.0.3.Final</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-c3p0</artifactId>
<version>5.0.3.Final</version>
</dependency>
<dependency>
<groupId>org.hibernate.javax.persistence</groupId>
<artifactId>hibernate-jpa-2.1-api</artifactId>
<version>1.0.0.Final</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-envers</artifactId>
<version>5.0.3.Final</version>
</dependency>
<dependency>
<groupId>de.svenkubiak</groupId>
<artifactId>jBCrypt</artifactId>
<version>0.4</version>
</dependency>
<dependency>
<groupId>org.yaml</groupId>
<artifactId>snakeyaml</artifactId>
<version>1.16</version>
</dependency>
<dependency>
<groupId>org.reflections</groupId>
<artifactId>reflections</artifactId>
<version>0.9.10</version>
</dependency>
</dependencies>
<dependencies>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.16.6</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
<version>1.7.12</version>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>19.0-rc2</version>
</dependency>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.4</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-io</artifactId>
<version>1.3.2</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.4</version>
</dependency>
<dependency>
<groupId>commons-net</groupId>
<artifactId>commons-net</artifactId>
<version>3.3</version>
</dependency>
<dependency>
<groupId>me.chanjar</groupId>
<artifactId>weixin-java-mp</artifactId>
<version>1.3.1</version>
</dependency>
<dependency>
<groupId>com.mchange</groupId>
<artifactId>c3p0</artifactId>
<version>0.9.5.1</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.37</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>5.0.3.Final</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
<version>5.0.3.Final</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-c3p0</artifactId>
<version>5.0.3.Final</version>
</dependency>
<dependency>
<groupId>org.hibernate.javax.persistence</groupId>
<artifactId>hibernate-jpa-2.1-api</artifactId>
<version>1.0.0.Final</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-envers</artifactId>
<version>5.0.3.Final</version>
</dependency>
<dependency>
<groupId>de.svenkubiak</groupId>
<artifactId>jBCrypt</artifactId>
<version>0.4</version>
</dependency>
<dependency>
<groupId>org.yaml</groupId>
<artifactId>snakeyaml</artifactId>
<version>1.16</version>
</dependency>
</dependencies>
</project>

View File

@@ -26,7 +26,7 @@ public class Index extends HttpServlet {
response.addHeader("Content-type", "text/plain;charset=utf-8");
response.setCharacterEncoding("utf-8");
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 Sola & LiuYue all rights reserved. | Commercial license for ZSC Network Support Department (ZSCNSD).");
out.println("For any problem, Please contact loli@sola.love.");
if (response.getStatus() == HttpServletResponse.SC_NOT_FOUND) {
out.println("\nError 404: Page not found.");

View File

@@ -0,0 +1,34 @@
package love.sola.netsupport;
import love.sola.netsupport.util.RSAUtil;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import static love.sola.netsupport.config.Lang.format;
/**
* ***********************************************
* Created by Sola on 2015/12/12.
* Don't modify this source without my agreement
* ***********************************************
*/
@WebServlet(name = "LoginRedirect", urlPatterns = "/login", loadOnStartup = 2)
public class Login extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setCharacterEncoding("utf-8");
response.setCharacterEncoding("utf-8");
response.sendRedirect(format("Operator_Login_Page", RSAUtil.publicKey_s));
}
}

View File

@@ -1,32 +0,0 @@
package love.sola.netsupport.api;
import love.sola.netsupport.enums.Access;
import love.sola.netsupport.session.WxSession;
import love.sola.netsupport.wechat.Command;
import javax.servlet.http.HttpServletRequest;
/**
* ***********************************************
* Created by Sola on 2016/2/27.
* Don't modify this source without my agreement
* ***********************************************
*/
public abstract class API {
public String url = null; //url
public int access = Access.GOD_MODE; //operator's permission
public Command authorize = null; //session check
protected abstract Object process(HttpServletRequest req, WxSession session) throws Exception;
@Override
public String toString() {
return getClass().getSimpleName() + "{" +
"url='" + url + '\'' +
", access=" + Access.inverseMap.get(access) +
", authorize=" + authorize +
'}';
}
}

View File

@@ -1,126 +0,0 @@
package love.sola.netsupport.api;
import com.google.gson.Gson;
import love.sola.netsupport.enums.Access;
import love.sola.netsupport.enums.Attribute;
import love.sola.netsupport.pojo.Operator;
import love.sola.netsupport.pojo.User;
import love.sola.netsupport.session.WechatSession;
import love.sola.netsupport.session.WxSession;
import love.sola.netsupport.sql.SQLCore;
import org.hibernate.HibernateException;
import org.reflections.Reflections;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.text.ParseException;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
/**
* ***********************************************
* Created by Sola on 2016/2/27.
* Don't modify this source without my agreement
* ***********************************************
*/
@WebServlet(name = "APIRouter", urlPatterns = "/api/*", loadOnStartup = 11)
public class APIRouter extends HttpServlet {
protected static Gson gson = SQLCore.gson;
private Map<String, API> nodes = new HashMap<>();
@Override
public void init() throws ServletException {
super.init();
try {
Reflections reflections = new Reflections(getClass().getPackage().getName());
Set<Class<? extends API>> set = reflections.getSubTypesOf(API.class);
for (Class<? extends API> clz : set) {
try {
System.out.println("Loading API: " + clz.getName());
API obj = clz.newInstance();
System.out.println("Registered API: " + obj);
nodes.put(obj.url, obj);
} catch (InstantiationException | IllegalAccessException e) {
e.printStackTrace();
}
}
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("Total " + nodes.size() + " API(s) loaded.");
}
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.setCharacterEncoding("utf-8");
resp.setCharacterEncoding("utf-8");
resp.addHeader("Content-type", "application/json;charset=utf-8");
resp.addHeader("Access-Control-Allow-Origin", "*");
Object obj = null;
try {
API api = nodes.get(req.getPathInfo());
if (api == null) {
resp.sendError(HttpServletResponse.SC_FORBIDDEN);
return;
}
WxSession session = getSession(req);
if (session == null) {
obj = Error.UNAUTHORIZED;
return;
}
if (api.authorize != null) {
if (session.getAttribute(Attribute.AUTHORIZED) != api.authorize) {
obj = Error.UNAUTHORIZED;
return;
}
if (api.access == Access.USER) {
User u = session.getAttribute(Attribute.USER);
if (u == null) {
obj = Error.UNAUTHORIZED;
return;
}
}
if (api.access < Access.USER) {
Operator op = session.getAttribute(Attribute.OPERATOR);
if (op == null) {
obj = Error.UNAUTHORIZED;
return;
}
if (op.getAccess() > api.access) {
obj = Error.PERMISSION_DENIED;
return;
}
}
}
obj = api.process(req, session);
} catch (ParseException | NumberFormatException e) {
obj = Error.ILLEGAL_PARAMETER;
} catch (HibernateException e) {
e.printStackTrace();
obj = Error.DATABASE_ERROR;
} catch (Exception e) {
e.printStackTrace();
obj = Error.INTERNAL_ERROR;
} finally {
if (!resp.isCommitted()) {
try (PrintWriter out = resp.getWriter()) {
out.println(gson.toJson(obj));
}
}
}
}
private static WxSession getSession(HttpServletRequest req) {
String t = req.getParameter("token");
if (t == null || t.isEmpty()) return null;
return WechatSession.get(t);
}
}

View File

@@ -1,41 +0,0 @@
package love.sola.netsupport.api;
import love.sola.netsupport.enums.Access;
import love.sola.netsupport.enums.Attribute;
import love.sola.netsupport.session.WxSession;
import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.Map;
/**
* ***********************************************
* Created by Sola on 2015/12/21.
* Don't modify this source without my agreement
* ***********************************************
*/
public class CheckSession extends API {
public CheckSession() {
url = "/checksession";
access = Access.GUEST;
authorize = null;
}
@Override
protected Object process(HttpServletRequest req, WxSession session) throws Exception {
String more = req.getParameter("more");
Map<String, Object> result = new HashMap<>();
result.put(Attribute.AUTHORIZED, session.getAttribute(Attribute.AUTHORIZED));
if (more != null) {
switch (more) {
case "1":
result.put(Attribute.USER, session.getAttribute(Attribute.USER));
result.put(Attribute.OPERATOR, session.getAttribute(Attribute.OPERATOR));
break;
}
}
return result;
}
}

View File

@@ -1,45 +0,0 @@
package love.sola.netsupport.api;
import static love.sola.netsupport.config.Lang.lang;
/**
* ***********************************************
* Created by Sola on 2015/11/5.
* Don't modify this source without my agreement
* ***********************************************
*/
public class Error {
public static final Error ALREADY_SUBMITTED = new Error(1);
public static final Object OK = new Object();
public static final Error PARAMETER_REQUIRED = new Error(-1);
public static final Error ILLEGAL_PARAMETER = new Error(-2);
// public static final Error REQUEST_FAILED = new Error(-3); REMOVED
public static final Error LENGTH_LIMIT_EXCEEDED = new Error(-4);
public static final Error INVALID_PARAMETER = new Error(-5);
public static final Error USER_NOT_FOUND = new Error(-11);
public static final Error TICKET_NOT_FOUND = new Error(-12);
public static final Error OPERATOR_NOT_FOUND = new Error(-13);
public static final Error UNAUTHORIZED = new Error(-20);
public static final Error WRONG_PASSWORD = new Error(-22);
public static final Error PERMISSION_DENIED = new Error(-24);
public static final Error INTERNAL_ERROR = new Error(-90);
public static final Error DATABASE_ERROR = new Error(-91);
public int errCode;
public String errMsg;
private Error(int code) {
this(code, lang("ERR_" + code));
}
public Error(int errCode, String errMsg) {
this.errCode = errCode;
this.errMsg = errMsg;
}
public Error withMsg(String msg) {
return new Error(errCode, msg);
}
}

View File

@@ -0,0 +1,86 @@
package love.sola.netsupport.api;
import com.google.gson.Gson;
import love.sola.netsupport.enums.Attribute;
import love.sola.netsupport.enums.ISP;
import love.sola.netsupport.pojo.User;
import love.sola.netsupport.sql.SQLCore;
import love.sola.netsupport.sql.TableUser;
import love.sola.netsupport.util.Checker;
import love.sola.netsupport.util.ParseUtil;
import love.sola.netsupport.wechat.Command;
import me.chanjar.weixin.common.session.WxSession;
import org.hibernate.exception.ConstraintViolationException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import static love.sola.netsupport.util.Checker.*;
/**
* ***********************************************
* Created by Sola on 2015/12/15.
* Don't modify this source without my agreement
* ***********************************************
*/
@WebServlet(name = "ProfileModify", urlPatterns = "/api/profilemodify", loadOnStartup = 22)
public class ProfileModify extends HttpServlet {
private Gson gson = SQLCore.gson;
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setCharacterEncoding("utf-8");
response.setCharacterEncoding("utf-8");
response.addHeader("Content-type", "application/json;charset=utf-8");
PrintWriter out = response.getWriter();
String json = gson.toJson(process(request));
out.println(ParseUtil.parseJsonP(request, json));
out.close();
}
private Response process(HttpServletRequest request) {
WxSession session = Checker.isAuthorized(request, Command.PROFILE);
if (session == null) {
return new Response(Response.ResponseCode.UNAUTHORIZED);
}
User u = (User) session.getAttribute(Attribute.USER);
if (u == null) return new Response(Response.ResponseCode.UNAUTHORIZED);
ISP isp = checkISP(request.getParameter("isp"));
String netAccount = checkNetAccount(request.getParameter("username"), isp);
int block = checkBlock(request.getParameter("block"));
int room = checkRoom(request.getParameter("room"), block);
long phone = checkPhoneNumber(request.getParameter("phone"));
if (netAccount != null) {
u.setIsp(isp);
u.setNetAccount(netAccount);
}
if (room != -1) {
u.setBlock(block);
u.setRoom(room);
}
if (phone != -1) {
u.setPhone(phone);
}
try {
TableUser.update(u);
} catch (ConstraintViolationException e) {
String dupKey = e.getConstraintName();
return new Response(Response.ResponseCode.REQUEST_FAILED, "Duplicated_" + dupKey.toUpperCase());
} catch (Exception e) {
e.printStackTrace();
return new Response(Response.ResponseCode.INTERNAL_ERROR, e.getMessage());
}
session.invalidate();
return new Response(Response.ResponseCode.OK);
}
}

View File

@@ -0,0 +1,112 @@
package love.sola.netsupport.api;
import com.google.gson.Gson;
import love.sola.netsupport.enums.Attribute;
import love.sola.netsupport.enums.ISP;
import love.sola.netsupport.pojo.User;
import love.sola.netsupport.sql.SQLCore;
import love.sola.netsupport.sql.TableUser;
import love.sola.netsupport.util.Checker;
import love.sola.netsupport.util.ParseUtil;
import love.sola.netsupport.wechat.Command;
import me.chanjar.weixin.common.session.WxSession;
import org.hibernate.exception.ConstraintViolationException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import static love.sola.netsupport.util.Checker.*;
/**
* ***********************************************
* Created by Sola on 2015/11/29.
* Don't modify this source without my agreement
* ***********************************************
*/
@WebServlet(name = "Register", urlPatterns = "/api/register", loadOnStartup = 21)
public class Register extends HttpServlet {
private Gson gson = SQLCore.gson;
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setCharacterEncoding("utf-8");
response.setCharacterEncoding("utf-8");
response.addHeader("Content-type", "application/json;charset=utf-8");
PrintWriter out = response.getWriter();
WxSession session = Checker.isAuthorized(request, Command.REGISTER);
if (session == null) {
printAuthorizeFailed(request, out);
return;
}
String wechat = (String) session.getAttribute(Attribute.WECHAT);
if (wechat == null) {
printAuthorizeFailed(request, out);
return;
}
ISP isp = checkISP(request.getParameter("isp"));
int block = checkBlock(request.getParameter("block"));
String result = register(
checkStudentId(request.getParameter("sid")),
request.getParameter("name"),
isp,
checkNetAccount(request.getParameter("username"), isp),
block,
checkRoom(request.getParameter("room"), block),
checkPhoneNumber(request.getParameter("phone")),
wechat
);
boolean isSuccess = result.equals("Register_Success");
if (isSuccess) {
session.invalidate();
out.println(ParseUtil.parseJsonP(request, gson.toJson(new Response(Response.ResponseCode.OK, result))));
} else {
out.println(ParseUtil.parseJsonP(request, gson.toJson(new Response(Response.ResponseCode.REQUEST_FAILED, result))));
}
out.close();
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doPost(request, response);
}
private String register(long sid, String name, ISP isp, String netAccount, int block, int room, long phone, String wechat) {
if (sid == -1) return "Invalid_Student_Id";
if (name == null) return "Invalid_Name";
if (isp == null) return "Invalid_ISP";
if (netAccount == null) return "Invalid_Account";
if (block == -1) return "Invalid_Block";
if (room == -1) return "Invalid_Room";
if (phone == -1) return "Invalid_Phone_Number";
User user = TableUser.getById(sid);
if (user == null) return "Invalid_Student_Id";
if (!user.getName().equals(name)) return "Invalid_Name";
if (user.getWechatId() != null) return "User_Already_Registered";
user.setIsp(isp);
user.setNetAccount(netAccount);
user.setBlock(block);
user.setRoom(room);
user.setPhone(phone);
user.setWechatId(wechat);
try {
TableUser.update(user);
} catch (ConstraintViolationException e) {
String dupKey = e.getConstraintName();
return "Duplicated_" + dupKey.toUpperCase(); // PHONE ACCOUNT WECHAT
}
return "Register_Success";
}
private void printAuthorizeFailed(HttpServletRequest request, PrintWriter out) {
out.println(ParseUtil.parseJsonP(request, gson.toJson(new Response(Response.ResponseCode.UNAUTHORIZED))));
out.close();
return;
}
}

View File

@@ -0,0 +1,77 @@
package love.sola.netsupport.api;
import lombok.AllArgsConstructor;
import java.util.HashMap;
import java.util.Map;
/**
* ***********************************************
* Created by Sola on 2015/11/5.
* Don't modify this source without my agreement
* ***********************************************
*/
@AllArgsConstructor
public class Response {
public int code;
public String info;
public Object result;
public Response(ResponseCode code) {
this(code, null);
}
public Response(ResponseCode code, Object result) {
this.code = code.id;
this.info = code.name();
this.result = result;
}
public enum ResponseCode {
ALREADY_SUBMITTED(1),
OK(0),
PARAMETER_REQUIRED(-1),
ILLEGAL_PARAMETER(-2),
REQUEST_FAILED(-3),
AUTHORIZE_FAILED(-9),
USER_NOT_FOUND(-11),
TICKET_NOT_FOUND(-12),
OPERATOR_NOT_FOUND(-13),
UNAUTHORIZED(-20),
REQUEST_EXPIRED(-21),
WRONG_PASSWORD(-22),
INCORRECT_WECHAT(-23),
PERMISSION_DENIED(-24),
INTERNAL_ERROR(-90),
DATABASE_ERROR(-91),
;
private static final Map<Integer, ResponseCode> ID_MAP = new HashMap<>();
static {
for (ResponseCode type : values()) {
ID_MAP.put(type.id, type);
}
}
public final int id;
ResponseCode(int id) {
this.id = id;
}
public static ResponseCode fromId(int id) {
return ID_MAP.get(id);
}
@Override
public String toString() {
return name();
}
}
}

View File

@@ -0,0 +1,89 @@
package love.sola.netsupport.api;
import com.google.gson.Gson;
import love.sola.netsupport.enums.Attribute;
import love.sola.netsupport.pojo.Ticket;
import love.sola.netsupport.pojo.User;
import love.sola.netsupport.sql.SQLCore;
import love.sola.netsupport.util.Checker;
import love.sola.netsupport.util.ParseUtil;
import love.sola.netsupport.wechat.Command;
import me.chanjar.weixin.common.session.WxSession;
import org.hibernate.Criteria;
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Restrictions;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
/**
* ***********************************************
* Created by Sola on 2015/12/4.
* Don't modify this source without my agreement
* ***********************************************
*/
@WebServlet(name = "TicketQuery", urlPatterns = "/api/ticketquery", loadOnStartup = 24)
public class TicketQuery extends HttpServlet {
private Gson gson = SQLCore.gson;
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
@SuppressWarnings("Duplicates")
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setCharacterEncoding("utf-8");
response.setCharacterEncoding("utf-8");
response.addHeader("Content-type", "application/json;charset=utf-8");
PrintWriter out = response.getWriter();
String json = gson.toJson(query(request));
out.println(ParseUtil.parseJsonP(request, json));
out.close();
}
private Response query(HttpServletRequest request) {
try (Session s = SQLCore.sf.openSession()) {
WxSession session = Checker.isAuthorized(request, Command.QUERY);
if (session == null) {
return new Response(Response.ResponseCode.UNAUTHORIZED);
}
User u = (User) session.getAttribute(Attribute.USER);
if (u == null) return new Response(Response.ResponseCode.UNAUTHORIZED);
Criteria c = s.createCriteria(Ticket.class);
int first = request.getParameter("offset") == null ? 0 : Integer.parseInt(request.getParameter("offset"));
int limit = request.getParameter("limit") == null ? 5 : Integer.parseInt(request.getParameter("limit"));
c.setFirstResult(first);
c.setMaxResults(limit);
c.addOrder(Order.desc(Ticket.PROPERTY_SUBMIT_TIME));
c.add(Restrictions.eq(Ticket.PROPERTY_USER, u));
if (request.getParameter("status") != null) {
c.add(Restrictions.eq(Ticket.PROPERTY_STATUS, Integer.parseInt(request.getParameter("status"))));
} else if (request.getParameter("statusl") != null && request.getParameter("statush") != null) {
c.add(Restrictions.between(Ticket.PROPERTY_STATUS,
Integer.parseInt(request.getParameter("statusl")),
Integer.parseInt(request.getParameter("statush"))
));
}
return new Response(Response.ResponseCode.OK, c.list());
} catch (NumberFormatException e) {
return new Response(Response.ResponseCode.ILLEGAL_PARAMETER);
} catch (HibernateException e) {
e.printStackTrace();
return new Response(Response.ResponseCode.DATABASE_ERROR, e.getMessage());
} catch (Exception e) {
e.printStackTrace();
return new Response(Response.ResponseCode.INTERNAL_ERROR, e.getMessage());
}
}
}

View File

@@ -0,0 +1,90 @@
package love.sola.netsupport.api;
import com.google.gson.Gson;
import love.sola.netsupport.enums.Attribute;
import love.sola.netsupport.pojo.Ticket;
import love.sola.netsupport.pojo.User;
import love.sola.netsupport.sql.SQLCore;
import love.sola.netsupport.sql.TableTicket;
import love.sola.netsupport.util.Checker;
import love.sola.netsupport.util.ParseUtil;
import love.sola.netsupport.wechat.Command;
import me.chanjar.weixin.common.session.WxSession;
import org.hibernate.HibernateException;
import org.hibernate.Session;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
/**
* ***********************************************
* Created by Sola on 2015/12/6.
* Don't modify this source without my agreement
* ***********************************************
*/
@WebServlet(name = "TicketSubmit", urlPatterns = "/api/ticketsubmit", loadOnStartup = 23)
public class TicketSubmit extends HttpServlet {
private Gson gson = SQLCore.gson;
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setCharacterEncoding("utf-8");
response.setCharacterEncoding("utf-8");
response.addHeader("Content-type", "application/json;charset=utf-8");
PrintWriter out = response.getWriter();
String json = gson.toJson(submit(request));
out.println(ParseUtil.parseJsonP(request, json));
out.close();
}
private Response submit(HttpServletRequest request) {
String desc = request.getParameter("desc");
if (desc == null || desc.isEmpty()) {
return new Response(Response.ResponseCode.PARAMETER_REQUIRED);
}
try (Session s = SQLCore.sf.openSession()) {
WxSession session = Checker.isAuthorized(request, Command.SUBMIT);
if (session == null) {
return new Response(Response.ResponseCode.UNAUTHORIZED);
}
User u = (User) session.getAttribute(Attribute.USER);
if (u == null) return new Response(Response.ResponseCode.UNAUTHORIZED);
if (TableTicket.hasOpen(u)) {
session.invalidate();
return new Response(Response.ResponseCode.ALREADY_SUBMITTED);
}
Ticket t = new Ticket();
t.setUser(u);
t.setDescription(desc);
t.setStatus(0);
s.beginTransaction();
s.save(t);
s.getTransaction().commit();
session.invalidate();
return new Response(Response.ResponseCode.OK, t);
} catch (NumberFormatException e) {
return new Response(Response.ResponseCode.ILLEGAL_PARAMETER);
} catch (HibernateException e) {
e.printStackTrace();
return new Response(Response.ResponseCode.DATABASE_ERROR, e.getMessage());
} catch (Exception e) {
e.printStackTrace();
return new Response(Response.ResponseCode.INTERNAL_ERROR, e.getMessage());
}
}
}

View File

@@ -1,18 +1,20 @@
package love.sola.netsupport.api;
package love.sola.netsupport.api.admin;
import com.google.gson.Gson;
import love.sola.netsupport.api.Response;
import love.sola.netsupport.enums.Access;
import love.sola.netsupport.enums.Attribute;
import love.sola.netsupport.pojo.Operator;
import love.sola.netsupport.pojo.User;
import love.sola.netsupport.session.WechatSession;
import love.sola.netsupport.session.WxSession;
import love.sola.netsupport.sql.SQLCore;
import love.sola.netsupport.sql.TableOperator;
import love.sola.netsupport.sql.TableUser;
import love.sola.netsupport.util.Crypto;
import love.sola.netsupport.util.ParseUtil;
import love.sola.netsupport.util.RSAUtil;
import love.sola.netsupport.wechat.Command;
import love.sola.netsupport.wechat.WechatSession;
import me.chanjar.weixin.common.session.WxSession;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
@@ -29,7 +31,7 @@ import java.io.PrintWriter;
* ***********************************************
*/
@WebServlet(name = "Login", urlPatterns = "/api/admin/login", loadOnStartup = 12)
@WebServlet(name = "Login", urlPatterns = "/api/admin/login", loadOnStartup = 31)
public class Login extends HttpServlet {
private Gson gson = SQLCore.gson;
@@ -42,28 +44,29 @@ public class Login extends HttpServlet {
request.setCharacterEncoding("utf-8");
response.setCharacterEncoding("utf-8");
response.addHeader("Content-type", "application/json;charset=utf-8");
response.addHeader("Access-Control-Allow-Origin", "*");
PrintWriter out = response.getWriter();
out.println(gson.toJson(login(request)));
String json = gson.toJson(login(request));
out.println(ParseUtil.parseJsonP(request, json));
out.close();
}
private Object login(HttpServletRequest request) {
private Response login(HttpServletRequest request) {
try {
int oid = Integer.parseInt(request.getParameter("id"));
String password = request.getParameter("pass");
boolean bypass = request.getParameter("bypass") != null;
Operator op = TableOperator.get(oid);
if (op == null)
return Error.OPERATOR_NOT_FOUND;
else if (op.getAccess() >= Access.NO_LOGIN)
return Error.PERMISSION_DENIED;
return new Response(Response.ResponseCode.OPERATOR_NOT_FOUND);
else if (op.getAccess() == Access.NOLOGIN)
return new Response(Response.ResponseCode.PERMISSION_DENIED);
if (!Crypto.check(bypass ? password : RSAUtil.decrypt(password), op.getPassword())) {
return Error.WRONG_PASSWORD;
return new Response(Response.ResponseCode.WRONG_PASSWORD);
}
WxSession session = WechatSession.create();
String sid = WechatSession.genId();
WxSession session = WechatSession.get(sid, true);
if (bypass) {
session.setAttribute(Attribute.AUTHORIZED, Command.fromId(Integer.parseInt(request.getParameter("bypass"))));
} else {
@@ -81,10 +84,10 @@ public class Login extends HttpServlet {
if (request.getParameter("bypasswechat") != null) {
session.setAttribute(Attribute.WECHAT, request.getParameter("bypasswechat"));
}
return session.getId();
return new Response(Response.ResponseCode.OK, sid);
} catch (Exception e) {
e.printStackTrace();
return Error.INTERNAL_ERROR;
return new Response(Response.ResponseCode.REQUEST_FAILED, e);
}
}
}

View File

@@ -0,0 +1,76 @@
package love.sola.netsupport.api.admin;
import com.google.gson.Gson;
import love.sola.netsupport.api.Response;
import love.sola.netsupport.enums.Attribute;
import love.sola.netsupport.pojo.Operator;
import love.sola.netsupport.pojo.Ticket;
import love.sola.netsupport.sql.SQLCore;
import love.sola.netsupport.sql.TableTicket;
import love.sola.netsupport.util.Checker;
import love.sola.netsupport.util.ParseUtil;
import love.sola.netsupport.wechat.Command;
import me.chanjar.weixin.common.session.WxSession;
import org.hibernate.HibernateException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.List;
/**
* ***********************************************
* Created by Sola on 2015/12/13.
* Don't modify this source without my agreement
* ***********************************************
*/
@WebServlet(name = "TicketLookup", urlPatterns = "/api/admin/ticketlookup", loadOnStartup = 24)
public class TicketLookup extends HttpServlet {
private Gson gson = SQLCore.gson;
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setCharacterEncoding("utf-8");
response.setCharacterEncoding("utf-8");
response.addHeader("Content-type", "application/json;charset=utf-8");
PrintWriter out = response.getWriter();
String json = gson.toJson(lookup(request));
out.println(ParseUtil.parseJsonP(request, json));
out.close();
}
private Response lookup(HttpServletRequest request) {
WxSession session = Checker.isAuthorized(request, Command.LOGIN);
if (session == null) {
return new Response(Response.ResponseCode.UNAUTHORIZED);
}
try {
Operator op = (Operator) session.getAttribute(Attribute.OPERATOR);
int block;
if (request.getParameter("block") != null) {
block = Integer.parseInt(request.getParameter("block"));
} else {
block = op.getBlock();
}
List<Ticket> list = TableTicket.unsolvedByBlock(block);
return new Response(Response.ResponseCode.OK, list);
} catch (NumberFormatException e) {
return new Response(Response.ResponseCode.ILLEGAL_PARAMETER);
} catch (HibernateException e) {
e.printStackTrace();
return new Response(Response.ResponseCode.DATABASE_ERROR, e.getMessage());
} catch (Exception e) {
e.printStackTrace();
return new Response(Response.ResponseCode.INTERNAL_ERROR, e.getMessage());
}
}
}

View File

@@ -0,0 +1,82 @@
package love.sola.netsupport.api.admin;
import com.google.gson.Gson;
import love.sola.netsupport.api.Response;
import love.sola.netsupport.enums.Attribute;
import love.sola.netsupport.pojo.Operator;
import love.sola.netsupport.pojo.Ticket;
import love.sola.netsupport.sql.SQLCore;
import love.sola.netsupport.util.Checker;
import love.sola.netsupport.util.ParseUtil;
import love.sola.netsupport.wechat.Command;
import me.chanjar.weixin.common.session.WxSession;
import org.hibernate.HibernateException;
import org.hibernate.Session;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
/**
* ***********************************************
* Created by Sola on 2015/12/13.
* Don't modify this source without my agreement
* ***********************************************
*/
@WebServlet(name = "TicketUpdate", urlPatterns = "/api/admin/ticketupdate", loadOnStartup = 32)
public class TicketUpdate extends HttpServlet {
private Gson gson = SQLCore.gson;
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setCharacterEncoding("utf-8");
response.setCharacterEncoding("utf-8");
response.addHeader("Content-type", "application/json;charset=utf-8");
PrintWriter out = response.getWriter();
String json = gson.toJson(update(request));
out.println(ParseUtil.parseJsonP(request, json));
out.close();
}
private Response update(HttpServletRequest request) {
String ticket = request.getParameter("ticket");
String remark = request.getParameter("remark");
String status = request.getParameter("status");
if (Checker.hasNull(ticket, remark, status)) return new Response(Response.ResponseCode.PARAMETER_REQUIRED);
WxSession session = Checker.isAuthorized(request, Command.LOGIN);
if (session == null) {
return new Response(Response.ResponseCode.UNAUTHORIZED);
}
try (Session s = SQLCore.sf.openSession()) {
Operator op = (Operator) session.getAttribute(Attribute.OPERATOR);
Ticket t = s.get(Ticket.class, Integer.parseInt(ticket));
if (t == null) {
return new Response(Response.ResponseCode.TICKET_NOT_FOUND);
}
t.setOperator(op);
t.setRemark(remark);
t.setStatus(Integer.parseInt(status));
s.beginTransaction();
s.update(t);
s.getTransaction().commit();
return new Response(Response.ResponseCode.OK, t);
} catch (NumberFormatException e) {
return new Response(Response.ResponseCode.ILLEGAL_PARAMETER);
} catch (HibernateException e) {
e.printStackTrace();
return new Response(Response.ResponseCode.DATABASE_ERROR, e.getMessage());
} catch (Exception e) {
e.printStackTrace();
return new Response(Response.ResponseCode.INTERNAL_ERROR, e.getMessage());
}
}
}

View File

@@ -0,0 +1,72 @@
package love.sola.netsupport.api.admin.root;
import com.google.gson.Gson;
import love.sola.netsupport.enums.Access;
import love.sola.netsupport.enums.Attribute;
import love.sola.netsupport.pojo.Operator;
import love.sola.netsupport.sql.SQLCore;
import love.sola.netsupport.util.Checker;
import love.sola.netsupport.wechat.Command;
import love.sola.netsupport.wechat.WechatSession;
import me.chanjar.weixin.common.session.InternalSession;
import me.chanjar.weixin.common.session.WxSession;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Enumeration;
/**
* ***********************************************
* Created by Sola on 2015/12/15.
* Don't modify this source without my agreement
* ***********************************************
*/
@WebServlet(name = "Dashboard", urlPatterns = "/api/admin/dashboard", loadOnStartup = 41)
public class DashBoard extends HttpServlet {
private Gson gson = SQLCore.gson;
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setCharacterEncoding("utf-8");
response.setCharacterEncoding("utf-8");
response.addHeader("Content-type", "text/plain;charset=utf-8");
PrintWriter out = response.getWriter();
print(request, out);
out.close();
}
private void print(HttpServletRequest request, PrintWriter out) {
WxSession session = Checker.isAuthorized(request, Command.LOGIN);
if (session == null) {
out.println("Unauthorized");
return;
}
Operator op = (Operator) session.getAttribute(Attribute.OPERATOR);
if (op.getAccess() != Access.ROOT) {
out.println("Unauthorized");
return;
}
for (InternalSession s : WechatSession.list()) {
out.println("=====" + s.getIdInternal() + "=====");
WxSession ws = s.getSession();
Enumeration<String> e = ws.getAttributeNames();
while (e.hasMoreElements()) {
String key = e.nextElement();
out.println(key + ": " + ws.getAttribute(key));
}
}
}
}

View File

@@ -0,0 +1,90 @@
package love.sola.netsupport.api.admin.root;
import com.google.gson.Gson;
import love.sola.netsupport.api.Response;
import love.sola.netsupport.enums.Access;
import love.sola.netsupport.enums.Attribute;
import love.sola.netsupport.pojo.Operator;
import love.sola.netsupport.pojo.User;
import love.sola.netsupport.sql.SQLCore;
import love.sola.netsupport.sql.TableUser;
import love.sola.netsupport.util.Checker;
import love.sola.netsupport.util.ParseUtil;
import love.sola.netsupport.wechat.Command;
import me.chanjar.weixin.common.session.WxSession;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
/**
* ***********************************************
* Created by Sola on 2014/8/20.
* Don't modify this source without my agreement
* ***********************************************
*/
@WebServlet(name = "GetUser",urlPatterns = "/api/admin/getuser",loadOnStartup = 42)
public class GetUser extends HttpServlet {
private Gson gson = SQLCore.gson;
@Override
public void init(ServletConfig config) throws ServletException {
super.init(config);
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
@SuppressWarnings("Duplicates")
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setCharacterEncoding("utf-8");
response.setCharacterEncoding("utf-8");
response.addHeader("Content-type", "application/json;charset=utf-8");
PrintWriter out = response.getWriter();
String json = gson.toJson(query(request));
out.println(ParseUtil.parseJsonP(request, json));
out.close();
}
private Response query(HttpServletRequest request) {
WxSession session = Checker.isAuthorized(request, Command.LOGIN);
if (session == null) {
return new Response(Response.ResponseCode.UNAUTHORIZED);
}
Operator op = (Operator) session.getAttribute(Attribute.OPERATOR);
if (op.getAccess() != Access.ROOT) {
return new Response(Response.ResponseCode.PERMISSION_DENIED);
}
String id = request.getParameter("id");
String name = request.getParameter("name");
if ((id == null || id.isEmpty()) && (name == null || name.isEmpty())) {
return new Response(Response.ResponseCode.PARAMETER_REQUIRED);
}
if (id != null) {
try {
User u = TableUser.getById(Long.parseLong(id));
if (u == null)
return new Response(Response.ResponseCode.USER_NOT_FOUND);
else
return new Response(Response.ResponseCode.OK, u);
} catch (NumberFormatException e) {
return new Response(Response.ResponseCode.ILLEGAL_PARAMETER);
}
} else {
User u = TableUser.getByName(name);
if (u == null)
return new Response(Response.ResponseCode.USER_NOT_FOUND);
else
return new Response(Response.ResponseCode.OK, u);
}
}
}

View File

@@ -1,53 +0,0 @@
package love.sola.netsupport.api.manager;
import love.sola.netsupport.api.API;
import love.sola.netsupport.api.Error;
import love.sola.netsupport.enums.Access;
import love.sola.netsupport.pojo.User;
import love.sola.netsupport.session.WxSession;
import love.sola.netsupport.sql.TableUser;
import love.sola.netsupport.wechat.Command;
import javax.servlet.http.HttpServletRequest;
/**
* ***********************************************
* Created by Sola on 2014/8/20.
* Don't modify this source without my agreement
* ***********************************************
*/
public class GetUser extends API {
public GetUser() {
url = "/admin/getuser";
access = Access.LEADER;
authorize = Command.LOGIN;
}
@Override
protected Object process(HttpServletRequest req, WxSession session) throws Exception {
String id = req.getParameter("id");
String name = req.getParameter("name");
if ((id == null || id.isEmpty()) && (name == null || name.isEmpty())) {
return Error.PARAMETER_REQUIRED;
}
if (id != null) {
try {
User u = TableUser.getById(Long.parseLong(id));
if (u == null)
return Error.USER_NOT_FOUND;
else
return u;
} catch (NumberFormatException e) {
return Error.ILLEGAL_PARAMETER;
}
} else {
User u = TableUser.getByName(name);
if (u == null)
return Error.USER_NOT_FOUND;
else
return u;
}
}
}

View File

@@ -1,58 +0,0 @@
package love.sola.netsupport.api.manager;
import love.sola.netsupport.api.API;
import love.sola.netsupport.api.Error;
import love.sola.netsupport.config.Settings;
import love.sola.netsupport.enums.Access;
import love.sola.netsupport.enums.Attribute;
import love.sola.netsupport.enums.Status;
import love.sola.netsupport.pojo.Operator;
import love.sola.netsupport.pojo.Ticket;
import love.sola.netsupport.pojo.User;
import love.sola.netsupport.session.WxSession;
import love.sola.netsupport.sql.SQLCore;
import love.sola.netsupport.util.Checker;
import love.sola.netsupport.wechat.Command;
import org.hibernate.Session;
import javax.servlet.http.HttpServletRequest;
/**
* ***********************************************
* Created by Sola on 2015/12/22.
* Don't modify this source without my agreement
* ***********************************************
*/
public class TicketPush extends API {
public TicketPush() {
url = "/admin/ticketpush";
access = Access.LEADER;
authorize = Command.LOGIN;
}
@Override
protected Object process(HttpServletRequest req, WxSession session) throws Exception {
String uid = req.getParameter("uid");
String desc = req.getParameter("desc");
if (Checker.hasNull(uid, desc)) {
return Error.PARAMETER_REQUIRED;
}
if (desc.length() > Settings.MAX_DESC_LENGTH) {
return Error.LENGTH_LIMIT_EXCEEDED;
}
Operator op = session.getAttribute(Attribute.OPERATOR);
try (Session s = SQLCore.sf.openSession()) {
s.beginTransaction();
User u = s.get(User.class, Long.parseLong(uid));
if (u == null) {
return Error.USER_NOT_FOUND;
}
Ticket t = new Ticket(null, u, desc, null, "Pushed By Admin", null, op, Status.UNCHECKED);
s.save(t);
s.getTransaction().commit();
return t;
}
}
}

View File

@@ -1,39 +0,0 @@
package love.sola.netsupport.api.root;
import love.sola.netsupport.api.API;
import love.sola.netsupport.enums.Access;
import love.sola.netsupport.session.WechatSession;
import love.sola.netsupport.session.WxSession;
import love.sola.netsupport.wechat.Command;
import javax.servlet.http.HttpServletRequest;
import java.util.Set;
/**
* ***********************************************
* Created by Sola on 2015/12/15.
* Don't modify this source without my agreement
* ***********************************************
*/
public class DashBoard extends API {
public DashBoard() {
url = "/root/dashboard";
access = Access.ROOT;
authorize = Command.LOGIN;
}
@Override
protected Object process(HttpServletRequest req, WxSession session) throws Exception {
StringBuilder sb = new StringBuilder();
for (love.sola.netsupport.session.WxSession ws : WechatSession.list()) {
sb.append("=====").append(ws.getId()).append("=====\n");
Set<String> e = ws.getAttributeNames();
for (String key : e) {
sb.append(key).append(": ").append(ws.getAttribute(key).toString()).append("\n");
}
}
return sb.toString();
}
}

View File

@@ -1,32 +0,0 @@
package love.sola.netsupport.api.root;
import love.sola.netsupport.api.API;
import love.sola.netsupport.api.Error;
import love.sola.netsupport.enums.Access;
import love.sola.netsupport.session.WxSession;
import love.sola.netsupport.sql.TableUser;
import love.sola.netsupport.wechat.Command;
import javax.servlet.http.HttpServletRequest;
/**
* ***********************************************
* Created by Sola on 2015/12/15.
* Don't modify this source without my agreement
* ***********************************************
*/
public class FlushCache extends API {
public FlushCache() {
url = "/root/flushcache";
access = Access.ROOT;
authorize = Command.LOGIN;
}
@Override
protected Object process(HttpServletRequest req, WxSession session) throws Exception {
TableUser.flushCache();
return Error.OK;
}
}

View File

@@ -1,49 +0,0 @@
package love.sola.netsupport.api.root;
import love.sola.netsupport.api.API;
import love.sola.netsupport.api.Error;
import love.sola.netsupport.enums.Access;
import love.sola.netsupport.pojo.Operator;
import love.sola.netsupport.session.WxSession;
import love.sola.netsupport.sql.SQLCore;
import love.sola.netsupport.util.Crypto;
import love.sola.netsupport.wechat.Command;
import org.hibernate.Session;
import javax.servlet.http.HttpServletRequest;
/**
* ***********************************************
* Created by Sola on 2015/12/20.
* Don't modify this source without my agreement
* ***********************************************
*/
public class SetPassword extends API {
public SetPassword() {
url = "/root/setpass";
access = Access.ROOT;
authorize = Command.LOGIN;
}
@Override
protected Object process(HttpServletRequest req, WxSession session) throws Exception {
String id = req.getParameter("id");
String pass = req.getParameter("pass");
if (pass == null || pass.length() < 8) {
return Error.INVALID_PARAMETER;
}
try (Session s = SQLCore.sf.openSession()) {
s.beginTransaction();
Operator op = s.get(Operator.class, Integer.parseInt(id));
if (op == null) {
return Error.OPERATOR_NOT_FOUND;
}
op.setPassword(Crypto.hash(pass));
s.update(op);
s.getTransaction().commit();
return Error.OK;
}
}
}

View File

@@ -1,63 +0,0 @@
package love.sola.netsupport.api.stuff;
import love.sola.netsupport.api.API;
import love.sola.netsupport.enums.Access;
import love.sola.netsupport.pojo.Ticket;
import love.sola.netsupport.session.WxSession;
import love.sola.netsupport.sql.SQLCore;
import love.sola.netsupport.sql.TableTicket;
import love.sola.netsupport.wechat.Command;
import org.apache.commons.lang3.time.DateUtils;
import org.hibernate.Session;
import org.hibernate.envers.AuditReader;
import org.hibernate.envers.query.AuditEntity;
import javax.servlet.http.HttpServletRequest;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
/**
* ***********************************************
* Created by Sola on 2015/12/18.
* Don't modify this source without my agreement
* ***********************************************
*/
public class TicketLog extends API {
public static SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMdd");
public TicketLog() {
url = "/admin/ticketlog";
access = Access.MEMBER;
authorize = Command.LOGIN;
}
@Override
protected Object process(HttpServletRequest req, WxSession session) throws Exception {
int first;
int limit;
Date start;
Date end;
first = req.getParameter("first") == null ? 0 : Integer.parseInt(req.getParameter("first"));
limit = req.getParameter("limit") == null ? 20 : Integer.parseInt(req.getParameter("limit"));
start = req.getParameter("start") == null ? getToday() : dateFormat.parse(req.getParameter("start"));
end = req.getParameter("end") == null ? getToday() : dateFormat.parse(req.getParameter("end"));
end = DateUtils.addDays(end, 1);
try (Session s = SQLCore.sf.openSession()) {
AuditReader reader = TableTicket.getAuditReader(s);
return reader.createQuery()
.forRevisionsOfEntity(Ticket.class, false, true)
.addOrder(AuditEntity.revisionNumber().desc())
.add(AuditEntity.revisionProperty("timestamp").between(start.getTime(), end.getTime()))
.setFirstResult(first)
.setMaxResults(limit)
.getResultList();
}
}
private static Date getToday() {
return DateUtils.truncate(new Date(), Calendar.DAY_OF_MONTH);
}
}

View File

@@ -1,39 +0,0 @@
package love.sola.netsupport.api.stuff;
import love.sola.netsupport.api.API;
import love.sola.netsupport.enums.Access;
import love.sola.netsupport.enums.Attribute;
import love.sola.netsupport.pojo.Operator;
import love.sola.netsupport.session.WxSession;
import love.sola.netsupport.sql.TableTicket;
import love.sola.netsupport.wechat.Command;
import javax.servlet.http.HttpServletRequest;
/**
* ***********************************************
* Created by Sola on 2015/12/13.
* Don't modify this source without my agreement
* ***********************************************
*/
public class TicketLookup extends API {
public TicketLookup() {
url = "/admin/ticketlookup";
access = Access.MEMBER;
authorize = Command.LOGIN;
}
@Override
protected Object process(HttpServletRequest req, WxSession session) throws Exception {
Operator op = session.getAttribute(Attribute.OPERATOR);
int block;
if (req.getParameter("block") != null) {
block = Integer.parseInt(req.getParameter("block"));
} else {
block = op.getBlock();
}
return TableTicket.unsolvedByBlock(block);
}
}

View File

@@ -1,35 +0,0 @@
package love.sola.netsupport.api.stuff;
import love.sola.netsupport.api.API;
import love.sola.netsupport.api.Error;
import love.sola.netsupport.enums.Access;
import love.sola.netsupport.session.WxSession;
import love.sola.netsupport.sql.TableTicket;
import love.sola.netsupport.wechat.Command;
import javax.servlet.http.HttpServletRequest;
/**
* ***********************************************
* Created by Sola on 2015/12/18.
* Don't modify this source without my agreement
* ***********************************************
*/
public class TicketTrack extends API {
public TicketTrack() {
url = "/admin/tickettrack";
access = Access.MEMBER;
authorize = Command.LOGIN;
}
@Override
protected Object process(HttpServletRequest req, WxSession session) throws Exception {
String tid = req.getParameter("id");
if (tid == null) {
return Error.PARAMETER_REQUIRED;
}
return TableTicket.track(Integer.parseInt(tid));
}
}

View File

@@ -1,54 +0,0 @@
package love.sola.netsupport.api.stuff;
import love.sola.netsupport.api.API;
import love.sola.netsupport.api.Error;
import love.sola.netsupport.enums.Access;
import love.sola.netsupport.enums.Attribute;
import love.sola.netsupport.pojo.Operator;
import love.sola.netsupport.pojo.Ticket;
import love.sola.netsupport.session.WxSession;
import love.sola.netsupport.sql.SQLCore;
import love.sola.netsupport.util.Checker;
import love.sola.netsupport.wechat.Command;
import org.hibernate.Session;
import javax.servlet.http.HttpServletRequest;
import java.util.Date;
/**
* ***********************************************
* Created by Sola on 2015/12/13.
* Don't modify this source without my agreement
* ***********************************************
*/
public class TicketUpdate extends API {
public TicketUpdate() {
url = "/admin/ticketupdate";
access = Access.MEMBER;
authorize = Command.LOGIN;
}
@Override
protected Object process(HttpServletRequest req, WxSession session) throws Exception {
String ticket = req.getParameter("ticket");
String remark = req.getParameter("remark");
String status = req.getParameter("status");
if (Checker.hasNull(ticket, remark, status)) return Error.PARAMETER_REQUIRED;
try (Session s = SQLCore.sf.openSession()) {
Operator op = session.getAttribute(Attribute.OPERATOR);
Ticket t = s.get(Ticket.class, Integer.parseInt(ticket));
if (t == null) {
return Error.TICKET_NOT_FOUND;
}
t.setOperator(op);
t.setRemark(remark);
t.setStatus(Integer.parseInt(status));
t.setUpdateTime(new Date());
s.beginTransaction();
s.update(t);
s.getTransaction().commit();
return t;
}
}
}

View File

@@ -1,61 +0,0 @@
package love.sola.netsupport.api.user;
import love.sola.netsupport.api.API;
import love.sola.netsupport.api.Error;
import love.sola.netsupport.enums.Access;
import love.sola.netsupport.enums.Attribute;
import love.sola.netsupport.enums.ISP;
import love.sola.netsupport.pojo.User;
import love.sola.netsupport.session.WxSession;
import love.sola.netsupport.sql.TableUser;
import love.sola.netsupport.wechat.Command;
import org.hibernate.exception.ConstraintViolationException;
import javax.servlet.http.HttpServletRequest;
import static love.sola.netsupport.util.Checker.*;
/**
* ***********************************************
* Created by Sola on 2015/12/15.
* Don't modify this source without my agreement
* ***********************************************
*/
public class ProfileModify extends API {
public ProfileModify() {
url = "/profilemodify";
access = Access.USER;
authorize = Command.PROFILE;
}
@Override
protected Object process(HttpServletRequest req, WxSession session) throws Exception {
User u = session.getAttribute(Attribute.USER);
ISP isp = checkISP(req.getParameter("isp"));
String netAccount = checkNetAccount(req.getParameter("username"), isp);
int block = checkBlock(req.getParameter("block"));
int room = checkRoom(req.getParameter("room"), block);
long phone = checkPhoneNumber(req.getParameter("phone"));
if (room == -1)
return Error.INVALID_PARAMETER.withMsg("Invalid_Room");
if (phone == -1)
return Error.INVALID_PARAMETER.withMsg("Invalid_Phone_Number");
if (netAccount == null)
return Error.INVALID_PARAMETER.withMsg("Invalid_Account");
u.setIsp(isp);
u.setNetAccount(netAccount);
u.setBlock(block);
u.setRoom(room);
u.setPhone(phone);
try {
TableUser.update(u);
} catch (ConstraintViolationException e) {
String dupKey = e.getConstraintName();
return Error.INVALID_PARAMETER.withMsg("Duplicated_" + dupKey.toUpperCase());
}
session.invalidate();
return Error.OK;
}
}

View File

@@ -1,127 +0,0 @@
package love.sola.netsupport.api.user;
import love.sola.netsupport.api.API;
import love.sola.netsupport.api.Error;
import love.sola.netsupport.enums.Access;
import love.sola.netsupport.enums.Attribute;
import love.sola.netsupport.enums.ISP;
import love.sola.netsupport.pojo.User;
import love.sola.netsupport.session.WxSession;
import love.sola.netsupport.sql.SQLCore;
import love.sola.netsupport.sql.TableUser;
import love.sola.netsupport.wechat.Command;
import love.sola.netsupport.wechat.WxMpServlet;
import me.chanjar.weixin.common.exception.WxErrorException;
import me.chanjar.weixin.mp.bean.WxMpCustomMessage;
import org.hibernate.exception.ConstraintViolationException;
import javax.servlet.http.HttpServletRequest;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import static love.sola.netsupport.util.Checker.*;
/**
* ***********************************************
* Created by Sola on 2015/11/29.
* Don't modify this source without my agreement
* ***********************************************
*/
public class Register extends API {
public Register() {
url = "/register";
access = Access.GUEST;
authorize = Command.REGISTER;
}
@Override
protected Object process(HttpServletRequest req, WxSession session) throws Exception {
String wechat = session.getAttribute(Attribute.WECHAT);
if (wechat == null) {
return Error.UNAUTHORIZED;
}
ISP isp = checkISP(req.getParameter("isp"));
int block = checkBlock(req.getParameter("block"));
return register(
checkStudentId(req.getParameter("sid")),
req.getParameter("name"),
isp,
checkNetAccount(req.getParameter("username"), isp),
block,
checkRoom(req.getParameter("room"), block),
checkPhoneNumber(req.getParameter("phone")),
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 (name == null) return Error.INVALID_PARAMETER.withMsg("Invalid_Name");
if (isp == null) return Error.INVALID_PARAMETER.withMsg("Invalid_ISP");
if (netAccount == null) return Error.INVALID_PARAMETER.withMsg("Invalid_Account");
if (block == -1) return Error.INVALID_PARAMETER.withMsg("Invalid_Block");
if (room == -1) return Error.INVALID_PARAMETER.withMsg("Invalid_Room");
if (phone == -1) return Error.INVALID_PARAMETER.withMsg("Invalid_Phone_Number");
User user = TableUser.getById(sid);
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.getWechatId() != null) return Error.INVALID_PARAMETER.withMsg("User_Already_Registered");
user.setIsp(isp);
user.setNetAccount(netAccount);
user.setBlock(block);
user.setRoom(room);
user.setPhone(phone);
user.setWechatId(wechat);
try {
TableUser.update(user);
} catch (ConstraintViolationException e) {
String dupKey = e.getConstraintName();
return Error.INVALID_PARAMETER.withMsg("Duplicated_" + dupKey.toUpperCase()); // PHONE ACCOUNT WECHAT
}
// FIXME: 2015/12/30 Temporary converter
converterWithRetry(user);
return Error.OK;
}
public static void converterWithRetry(User u) {
Throwable last = null;
for (int i = 0; i < 3; i++) {
try {
converter(u);
return;
} catch (WxErrorException | SQLException e) {
last = e;
}
}
last.printStackTrace();
try {
WxMpServlet.instance.wxMpService.customMessageSend(WxMpCustomMessage.TEXT().toUser(u.getWechatId()).content("数据转换失败").build());
} catch (WxErrorException e) {
e.printStackTrace();
}
}
public static void converter(User u) throws WxErrorException, SQLException {
try (Connection conn = SQLCore.ds.getConnection()) {
PreparedStatement ps = conn.prepareStatement("SELECT wechat FROM `convert` WHERE id=?");
ps.setLong(1, u.getId());
ResultSet rs = ps.executeQuery();
if (rs.next()) {
WxMpServlet.instance.wxMpService
.userUpdateGroup(u.getWechatId(), 100L);
String old = rs.getString(1);
ps = conn.prepareStatement("UPDATE `operators` SET wechat=? WHERE wechat=?");
ps.setString(1, u.getWechatId());
ps.setString(2, old);
if (ps.executeUpdate() == 1) {
WxMpServlet.instance.wxMpService.customMessageSend(WxMpCustomMessage.TEXT().toUser(u.getWechatId()).content("数据转换成功").build());
} else {
WxMpServlet.instance.wxMpService.customMessageSend(WxMpCustomMessage.TEXT().toUser(u.getWechatId()).content("已进行过数据转换").build());
}
}
}
}
}

View File

@@ -1,55 +0,0 @@
package love.sola.netsupport.api.user;
import love.sola.netsupport.api.API;
import love.sola.netsupport.enums.Access;
import love.sola.netsupport.enums.Attribute;
import love.sola.netsupport.pojo.Ticket;
import love.sola.netsupport.pojo.User;
import love.sola.netsupport.session.WxSession;
import love.sola.netsupport.sql.SQLCore;
import love.sola.netsupport.wechat.Command;
import org.hibernate.Criteria;
import org.hibernate.Session;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Restrictions;
import javax.servlet.http.HttpServletRequest;
/**
* ***********************************************
* Created by Sola on 2015/12/4.
* Don't modify this source without my agreement
* ***********************************************
*/
public class TicketQuery extends API {
public TicketQuery() {
url = "/ticketquery";
access = Access.USER;
authorize = Command.QUERY;
}
@Override
protected Object process(HttpServletRequest req, WxSession session) throws Exception {
try (Session s = SQLCore.sf.openSession()) {
User u = session.getAttribute(Attribute.USER);
Criteria c = s.createCriteria(Ticket.class);
int first = req.getParameter("offset") == null ? 0 : Integer.parseInt(req.getParameter("offset"));
int limit = req.getParameter("limit") == null ? 5 : Integer.parseInt(req.getParameter("limit"));
c.setFirstResult(first);
c.setMaxResults(limit);
c.addOrder(Order.desc(Ticket.PROPERTY_SUBMIT_TIME));
c.add(Restrictions.eq(Ticket.PROPERTY_USER, u));
if (req.getParameter("status") != null) {
c.add(Restrictions.eq(Ticket.PROPERTY_STATUS, Integer.parseInt(req.getParameter("status"))));
} else if (req.getParameter("statusl") != null && req.getParameter("statush") != null) {
c.add(Restrictions.between(Ticket.PROPERTY_STATUS,
Integer.parseInt(req.getParameter("statusl")),
Integer.parseInt(req.getParameter("statush"))
));
}
return c.list();
}
}
}

View File

@@ -1,59 +0,0 @@
package love.sola.netsupport.api.user;
import love.sola.netsupport.api.API;
import love.sola.netsupport.api.Error;
import love.sola.netsupport.config.Settings;
import love.sola.netsupport.enums.Access;
import love.sola.netsupport.enums.Attribute;
import love.sola.netsupport.pojo.Ticket;
import love.sola.netsupport.pojo.User;
import love.sola.netsupport.session.WxSession;
import love.sola.netsupport.sql.SQLCore;
import love.sola.netsupport.sql.TableTicket;
import love.sola.netsupport.wechat.Command;
import org.hibernate.Session;
import javax.servlet.http.HttpServletRequest;
/**
* ***********************************************
* Created by Sola on 2015/12/6.
* Don't modify this source without my agreement
* ***********************************************
*/
public class TicketSubmit extends API {
public TicketSubmit() {
url = "/ticketsubmit";
access = Access.USER;
authorize = Command.SUBMIT;
}
@Override
protected Object process(HttpServletRequest req, WxSession session) throws Exception {
String desc = req.getParameter("desc");
if (desc == null || desc.isEmpty()) {
return Error.PARAMETER_REQUIRED;
}
if (desc.length() > Settings.MAX_DESC_LENGTH) {
return Error.LENGTH_LIMIT_EXCEEDED;
}
try (Session s = SQLCore.sf.openSession()) {
User u = session.getAttribute(Attribute.USER);
if (TableTicket.hasOpen(u)) {
session.invalidate();
return Error.ALREADY_SUBMITTED;
}
Ticket t = new Ticket();
t.setUser(u);
t.setDescription(desc);
t.setStatus(0);
s.beginTransaction();
s.save(t);
s.getTransaction().commit();
session.invalidate();
return Error.OK;
}
}
}

View File

@@ -1,69 +0,0 @@
package love.sola.netsupport.auth;
import love.sola.netsupport.session.WechatSession;
import love.sola.netsupport.session.WxSession;
import love.sola.netsupport.util.Checker;
import love.sola.netsupport.wechat.WxMpServlet;
import me.chanjar.weixin.mp.api.WxMpService;
import me.chanjar.weixin.mp.bean.result.WxMpOAuth2AccessToken;
import javax.servlet.AsyncContext;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
/**
* ***********************************************
* Created by Sola on 2014/8/20.
* Don't modify this source without my agreement
* ***********************************************
*/
@WebServlet(name = "OAuth2", urlPatterns = "/oauth2/callback", loadOnStartup = 21, asyncSupported = true)
public class OAuth2 extends HttpServlet {
private static Map<String, OAuth2Handler> oAuth2HandlerMap = new HashMap<>();
/**
* for {@link love.sola.netsupport.wechat.WxMpServlet#registerCommands}
* @param state the state key from open platform callback.
* @param handler handler
*/
public static void registerOAuth2Handler(String state, OAuth2Handler handler) {
oAuth2HandlerMap.put(state, handler);
}
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
AsyncContext actx = req.startAsync();
String code = req.getParameter("code");
String state = req.getParameter("state");
if (Checker.hasNull(code, state)) {
resp.sendError(HttpServletResponse.SC_FORBIDDEN);
return;
}
OAuth2Handler handler = oAuth2HandlerMap.get(state);
if (handler == null) {
resp.sendError(HttpServletResponse.SC_NOT_IMPLEMENTED);
return;
}
actx.start(() -> {
try {
WxMpService wxMpService = WxMpServlet.instance.wxMpService;
WxMpOAuth2AccessToken token = wxMpService.oauth2getAccessToken(code);
String wechat = token.getOpenId();
WxSession session = WechatSession.create();
handler.onOAuth2(actx, (HttpServletResponse) actx.getResponse(), wechat, session);
actx.complete();
} catch (Exception e) {
e.printStackTrace();
}
});
}
}

View File

@@ -1,18 +0,0 @@
package love.sola.netsupport.auth;
import love.sola.netsupport.session.WxSession;
import javax.servlet.AsyncContext;
import javax.servlet.http.HttpServletResponse;
/**
* ***********************************************
* Created by Sola on 2016/3/26.
* Don't modify this source without my agreement
* ***********************************************
*/
public interface OAuth2Handler {
void onOAuth2(AsyncContext actx, HttpServletResponse resp, String user, WxSession session);
}

View File

@@ -1,33 +0,0 @@
package love.sola.netsupport.config;
import org.yaml.snakeyaml.Yaml;
import java.io.InputStream;
import java.util.List;
import java.util.Map;
import java.util.regex.Pattern;
/**
* ***********************************************
* Created by Sola on 2015/12/29.
* Don't modify this source without my agreement
* ***********************************************
*/
public class Cortana {
public static List<Compiled> entries;
public static void load() {
InputStream in = Lang.class.getClassLoader().getResourceAsStream("cortana.yml");
Map<String, Object> root = (Map<String, Object>) new Yaml().load(in);
}
public static class Compiled {
Pattern[] patterns;
String[] replies;
}
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -1,88 +0,0 @@
/*
* Copyright 2002-2015 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package love.sola.netsupport.session;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;
import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
/**
* @author Sola
*/
@EqualsAndHashCode(of = "id")
public final class MapSession implements WxSession, Serializable {
@Getter
private final String id;
private Map<String, Object> sessionAttrs = new HashMap<String, Object>();
@Getter
private long creationTime = System.currentTimeMillis();
@Getter
@Setter
private long lastAccessedTime = creationTime;
@Getter
private boolean invalidated = false;
/**
* Creates a new instance with a secure randomly generated identifier.
*/
public MapSession() {
this(UUID.randomUUID().toString());
}
/**
* 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
* entropy which can be slow.
*
* @param id the identifier to use
*/
public MapSession(String id) {
this.id = id;
}
@SuppressWarnings("unchecked")
public <T> T getAttribute(String attributeName) {
return (T) sessionAttrs.get(attributeName);
}
public Set<String> getAttributeNames() {
return sessionAttrs.keySet();
}
public void setAttribute(String attributeName, Object attributeValue) {
if (attributeValue == null) {
removeAttribute(attributeName);
} else {
sessionAttrs.put(attributeName, attributeValue);
}
}
public void removeAttribute(String attributeName) {
sessionAttrs.remove(attributeName);
}
public void invalidate() {
invalidated = true;
}
}

View File

@@ -1,85 +0,0 @@
/*
* Copyright 2002-2015 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package love.sola.netsupport.session;
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import love.sola.netsupport.config.Settings;
import org.apache.commons.lang3.Validate;
import javax.annotation.Nonnull;
import java.util.Map;
import java.util.concurrent.TimeUnit;
/**
* @author Sola
*/
public class MapSessionRepository {
private final LoadingCache<String, MapSession> sessions;
public MapSessionRepository() {
this(CacheBuilder.newBuilder()
.concurrencyLevel(4)
.maximumSize(65535)
.expireAfterAccess(Settings.I.User_Session_Max_Inactive, TimeUnit.SECONDS)
.build(new CacheLoader<String, MapSession>() {
@Override
public MapSession load(@Nonnull String key) throws Exception {
return new MapSession(key);
}
}
)
);
}
public MapSessionRepository(LoadingCache<String, MapSession> sessions) {
Validate.notNull(sessions);
this.sessions = sessions;
}
public void save(MapSession session) {
sessions.put(session.getId(), session);
}
public MapSession getSession(String id) {
MapSession saved = sessions.getIfPresent(id);
if (saved == null) {
return null;
}
if (saved.isInvalidated()) {
delete(saved.getId());
return null;
}
return saved;
}
public void delete(String id) {
sessions.invalidate(id);
}
public MapSession createSession() {
MapSession session = new MapSession();
save(session);
return session;
}
public Map<String, MapSession> asMap() {
return sessions.asMap();
}
}

View File

@@ -1,32 +0,0 @@
package love.sola.netsupport.session;
import java.util.Collection;
/**
* ***********************************************
* Created by Sola on 2015/12/14.
* Don't modify this source without my agreement
* ***********************************************
*/
public class WechatSession {
private static MapSessionRepository repository;
static {
repository = new MapSessionRepository();
}
public static WxSession get(String id) {
return repository.getSession(id);
}
public static WxSession create() {
return repository.createSession();
}
public static Collection<? extends WxSession> list() {
return repository.asMap().values();
}
}

View File

@@ -1,22 +0,0 @@
package love.sola.netsupport.session;
import java.util.Set;
/**
* @author Sola
*/
public interface WxSession {
String getId();
<T> T getAttribute(String name);
Set<String> getAttributeNames();
void setAttribute(String name, Object value);
void removeAttribute(String name);
void invalidate();
}

View File

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

View File

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

View File

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

View File

@@ -1,7 +1,13 @@
package love.sola.netsupport.util;
import love.sola.netsupport.enums.Attribute;
import love.sola.netsupport.enums.Block;
import love.sola.netsupport.enums.ISP;
import love.sola.netsupport.wechat.Command;
import love.sola.netsupport.wechat.WechatSession;
import me.chanjar.weixin.common.session.WxSession;
import javax.servlet.http.HttpServletRequest;
/**
* ***********************************************
@@ -19,6 +25,13 @@ public class Checker {
return false;
}
public static WxSession isAuthorized(HttpServletRequest r, Command c) {
String t = r.getParameter("token");
if (t == null || t.isEmpty()) return null;
WxSession s = WechatSession.get(t, false);
return s == null ? null : s.getAttribute(Attribute.AUTHORIZED) == c ? s : null;
}
public static long checkStudentId(String studentId) {
if (studentId == null) return -1;
if (studentId.matches(STUDENT_ID_REGEX)) {

View File

@@ -3,6 +3,7 @@ package love.sola.netsupport.util;
import love.sola.netsupport.enums.Status;
import love.sola.netsupport.pojo.Ticket;
import javax.servlet.http.HttpServletRequest;
import java.text.SimpleDateFormat;
import static love.sola.netsupport.config.Lang.lang;
@@ -29,4 +30,11 @@ public class ParseUtil {
return sb.toString();
}
public static String parseJsonP(HttpServletRequest request, String json) {
String jsonp = request.getParameter("jsonp");
if (jsonp == null || jsonp.isEmpty())
return json;
else
return jsonp.replace("{0}", json);
}
}

View File

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

View File

@@ -1,8 +1,6 @@
package love.sola.netsupport.wechat;
import love.sola.netsupport.wechat.handler.*;
import love.sola.netsupport.wechat.handler.admin.LoginHandler;
import love.sola.netsupport.wechat.handler.admin.OperatorInfoHandler;
import me.chanjar.weixin.mp.api.WxMpMessageHandler;
import java.util.HashMap;
@@ -24,7 +22,6 @@ public enum Command {
CANCEL(3, CancelHandler.class),
PROFILE(4, ProfileHandler.class),
LOGIN(10, LoginHandler.class),
OPERATOR_INFO(11, OperatorInfoHandler.class),
;
private static final Map<Integer, Command> ID_MAP = new HashMap<>();
@@ -37,11 +34,13 @@ public enum Command {
}
}
public final String name;
public final String regex;
public final Class<? extends WxMpMessageHandler> handler;
public final int id;
Command(int id, Class<? extends WxMpMessageHandler> handler) {
this.name = lang("CMD_" + name());
this.id = id;
this.regex = lang("REGEX_" + name());
this.handler = handler;
@@ -53,7 +52,7 @@ public enum Command {
@Override
public String toString() {
return name();
return name;
}
}

View File

@@ -0,0 +1,41 @@
package love.sola.netsupport.wechat;
import love.sola.netsupport.config.Settings;
import me.chanjar.weixin.common.session.InternalSession;
import me.chanjar.weixin.common.session.StandardSessionManager;
import me.chanjar.weixin.common.session.WxSession;
import java.util.UUID;
/**
* ***********************************************
* Created by Sola on 2015/12/14.
* Don't modify this source without my agreement
* ***********************************************
*/
public class WechatSession {
private static StandardSessionManager manager;
static{
manager = new StandardSessionManager();
manager.setMaxInactiveInterval(Settings.I.User_Session_Max_Inactive);
}
public static WxSession get(String id, boolean create) {
return manager.getSession(id, create);
}
public static WxSession get(String id) {
return manager.getSession(id);
}
public static String genId() {
return UUID.randomUUID().toString();
}
public static InternalSession[] list() {
return manager.findSessions();
}
}

View File

@@ -1,14 +1,10 @@
package love.sola.netsupport.wechat;
import love.sola.netsupport.auth.OAuth2;
import love.sola.netsupport.auth.OAuth2Handler;
import love.sola.netsupport.config.Settings;
import love.sola.netsupport.sql.SQLCore;
import love.sola.netsupport.wechat.handler.RegisterHandler;
import love.sola.netsupport.wechat.handler.SubscribeHandler;
import love.sola.netsupport.wechat.matcher.CheckSpamMatcher;
import love.sola.netsupport.wechat.handler.SpamHandler;
import love.sola.netsupport.wechat.matcher.SpamMatcher;
import love.sola.netsupport.wechat.matcher.RegisterMatcher;
import me.chanjar.weixin.common.api.WxConsts;
import me.chanjar.weixin.common.util.StringUtils;
import me.chanjar.weixin.mp.api.*;
import me.chanjar.weixin.mp.bean.WxMpXmlMessage;
@@ -29,14 +25,13 @@ import static love.sola.netsupport.config.Lang.lang;
* Don't modify this source without my agreement
* ***********************************************
*/
@WebServlet(name = "WxMpServlet", urlPatterns = "/wechat", loadOnStartup = 99)
@WebServlet(name = "WxMpServlet", urlPatterns = "/wechattest", loadOnStartup = 99)
public class WxMpServlet extends HttpServlet {
public static WxMpServlet instance;
protected WxMpInMemoryConfigStorage config;
public WxMpService wxMpService;
protected WxMpService wxMpService;
protected WxMpMessageRouter wxMpMessageRouter;
protected CheckSpamMatcher checkSpamMatcher;
public WxMpServlet() {
instance = this;
@@ -50,30 +45,31 @@ public class WxMpServlet extends HttpServlet {
config.setAppId(Settings.I.Wechat_AppId);
config.setSecret(Settings.I.Wechat_Secret);
config.setToken(Settings.I.Wechat_Token);
config.setAesKey(Settings.I.Wechat_AesKey);
config.setAesKey(Settings.I.Wechat_Token);
wxMpService = new WxMpServiceImpl();
wxMpService.setWxMpConfigStorage(config);
checkSpamMatcher = new CheckSpamMatcher();
wxMpMessageRouter = new WxMpMessageRouter(wxMpService);
wxMpMessageRouter.rule()
.async(false)
.msgType(WxConsts.XML_MSG_EVENT)
.event(WxConsts.EVT_SUBSCRIBE)
.handler(new SubscribeHandler())
.end();
wxMpMessageRouter.rule()
.async(false)
.matcher(new CheckSpamMatcher())
.msgType("event")
.event("subscribe")
.handler((wxMessage, context, wxMpService1, sessionManager)
-> WxMpXmlOutMessage.TEXT()
.fromUser(wxMessage.getToUserName())
.toUser(wxMessage.getFromUserName())
.content(lang("Message_Spam")).build())
.content(lang("Event_Subscribe")).build())
.end();
wxMpMessageRouter.rule()
.async(false)
.msgType("text")
.matcher(new SpamMatcher())
.handler(new SpamHandler())
.end();
wxMpMessageRouter.rule()
.async(false)
.msgType("text")
.matcher(new RegisterMatcher())
.handler(new RegisterHandler())
.end();
@@ -87,11 +83,7 @@ public class WxMpServlet extends HttpServlet {
public static void registerCommands(WxMpMessageRouter router) throws IllegalAccessException, InstantiationException {
for (Command c : Command.values()) {
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_EVENT).event(WxConsts.EVT_CLICK).eventKey(c.name()).handler(handler).end();
if (handler instanceof OAuth2Handler) {
OAuth2.registerOAuth2Handler(c.name(), (OAuth2Handler) handler);
}
router.rule().async(false).msgType("text").rContent(c.regex).handler(handler).end();
}
}
@@ -121,19 +113,19 @@ public class WxMpServlet extends HttpServlet {
String encryptType = StringUtils.isBlank(request.getParameter("encrypt_type")) ? "raw" : request.getParameter("encrypt_type");
// if ("raw".equals(encryptType)) {
// WxMpXmlMessage inMessage = WxMpXmlMessage.fromXml(request.getInputStream());
// WxMpXmlOutMessage outMessage = wxMpMessageRouter.route(inMessage);
// if (outMessage == null) {
// outMessage = WxMpXmlOutMessage.TEXT()
// .fromUser(inMessage.getToUserName())
// .toUser(inMessage.getFromUserName())
// .content(lang("Invalid_Operation"))
// .build();
// }
// response.getWriter().write(outMessage.toXml());
// return;
// }
if ("raw".equals(encryptType)) {
WxMpXmlMessage inMessage = WxMpXmlMessage.fromXml(request.getInputStream());
WxMpXmlOutMessage outMessage = wxMpMessageRouter.route(inMessage);
if (outMessage == null) {
outMessage = WxMpXmlOutMessage.TEXT()
.fromUser(inMessage.getToUserName())
.toUser(inMessage.getFromUserName())
.content(lang("Invalid_Operation"))
.build();
}
response.getWriter().write(outMessage.toXml());
return;
}
if ("aes".equals(encryptType)) {
String msgSignature = request.getParameter("msg_signature");
@@ -159,8 +151,4 @@ public class WxMpServlet extends HttpServlet {
doPost(req, resp);
}
@Override
public void destroy() {
SQLCore.destroy();
}
}

View File

@@ -1,8 +1,13 @@
package love.sola.netsupport.wechat.handler.admin;
package love.sola.netsupport.wechat.handler;
import love.sola.netsupport.enums.Access;
import love.sola.netsupport.enums.Attribute;
import love.sola.netsupport.pojo.Operator;
import love.sola.netsupport.sql.TableOperator;
import love.sola.netsupport.wechat.Command;
import love.sola.netsupport.wechat.WechatSession;
import me.chanjar.weixin.common.exception.WxErrorException;
import me.chanjar.weixin.common.session.WxSession;
import me.chanjar.weixin.common.session.WxSessionManager;
import me.chanjar.weixin.mp.api.WxMpMessageHandler;
import me.chanjar.weixin.mp.api.WxMpService;
@@ -17,24 +22,30 @@ import static love.sola.netsupport.config.Lang.lang;
/**
* ***********************************************
* Created by Sola on 2015/12/28.
* Created by Sola on 2015/12/12.
* Don't modify this source without my agreement
* ***********************************************
*/
public class OperatorInfoHandler implements WxMpMessageHandler {
public class LoginHandler implements WxMpMessageHandler {
@Override
public WxMpXmlOutMessage handle(WxMpXmlMessage wxMessage, Map<String, Object> context, WxMpService wxMpService, WxSessionManager sessionManager) throws WxErrorException {
TextBuilder out = WxMpXmlOutMessage.TEXT().fromUser(wxMessage.getToUserName()).toUser(wxMessage.getFromUserName());
try {
Operator op = TableOperator.get(wxMessage.getFromUserName());
if (op == null) {
Operator operator = TableOperator.get(wxMessage.getFromUserName());
if (operator == null)
out.content(lang("Not_Operator"));
// } else if (op.getAccess() >= Access.NO_LOGIN) {
// out.content(lang("No_Login"));
else if (operator.getAccess() == Access.NOLOGIN) {
out.content(lang("No_Login"));
} else {
out.content(format("Operator_Info", op.getId(), op.getName(), op.getAccess(), op.getBlock(), op.getWeek()));
String id = WechatSession.genId();
WxSession session = WechatSession.get(id, true);
session.setAttribute(Attribute.AUTHORIZED, Command.LOGIN);
session.setAttribute(Attribute.WECHAT, wxMessage.getFromUserName());
session.setAttribute(Attribute.OPERATOR, operator);
out.content(format("Operator_Home_Page", id));
}
} catch (Exception e) {
e.printStackTrace();
out.content(lang("Login_Error"));

View File

@@ -1,14 +1,12 @@
package love.sola.netsupport.wechat.handler;
import love.sola.netsupport.auth.OAuth2Handler;
import love.sola.netsupport.enums.Attribute;
import love.sola.netsupport.pojo.User;
import love.sola.netsupport.session.WechatSession;
import love.sola.netsupport.session.WxSession;
import love.sola.netsupport.sql.TableUser;
import love.sola.netsupport.util.Redirect;
import love.sola.netsupport.wechat.Command;
import love.sola.netsupport.wechat.WechatSession;
import me.chanjar.weixin.common.exception.WxErrorException;
import me.chanjar.weixin.common.session.WxSession;
import me.chanjar.weixin.common.session.WxSessionManager;
import me.chanjar.weixin.mp.api.WxMpMessageHandler;
import me.chanjar.weixin.mp.api.WxMpService;
@@ -16,12 +14,9 @@ import me.chanjar.weixin.mp.bean.WxMpXmlMessage;
import me.chanjar.weixin.mp.bean.WxMpXmlOutMessage;
import me.chanjar.weixin.mp.bean.outxmlbuilder.TextBuilder;
import javax.servlet.AsyncContext;
import javax.servlet.http.HttpServletResponse;
import java.util.Map;
import static love.sola.netsupport.config.Lang.format;
import static love.sola.netsupport.config.Lang.lang;
/**
* ***********************************************
@@ -29,39 +24,19 @@ import static love.sola.netsupport.config.Lang.lang;
* Don't modify this source without my agreement
* ***********************************************
*/
public class ProfileHandler implements WxMpMessageHandler, OAuth2Handler {
public class ProfileHandler implements WxMpMessageHandler {
@Override
public WxMpXmlOutMessage handle(WxMpXmlMessage wxMessage, Map<String, Object> context, WxMpService wxMpService, WxSessionManager sessionManager) throws WxErrorException {
User u = TableUser.getByWechat(wxMessage.getFromUserName());
WxSession session = WechatSession.create();
String id = WechatSession.genId();
WxSession session = WechatSession.get(id, true);
session.setAttribute(Attribute.AUTHORIZED, Command.PROFILE);
session.setAttribute(Attribute.WECHAT, wxMessage.getFromUserName());
session.setAttribute(Attribute.USER, u);
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("User_Profile_Link", id, u.getName(), u.getIsp().id, u.getNetAccount(), u.getBlock(), u.getRoom(), u.getPhone()));
return out.build();
}
@Override
public void onOAuth2(AsyncContext actx, HttpServletResponse resp, String user, WxSession session) {
try {
User u = TableUser.getByWechat(user);
if (u == null) {
session.setAttribute(Attribute.AUTHORIZED, Command.REGISTER);
session.setAttribute(Attribute.WECHAT, user);
Redirect.error().icon(Redirect.WeUIIcon.INFO).noButton()
.title(lang("Need_Register_Title")).msg(lang("Need_Register"))
.to(format("User_Register_Link", session.getId())).go(resp);
return;
}
session.setAttribute(Attribute.AUTHORIZED, Command.PROFILE);
session.setAttribute(Attribute.WECHAT, user);
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()));
} catch (Exception e) {
e.printStackTrace();
}
}
}

View File

@@ -3,13 +3,13 @@ package love.sola.netsupport.wechat.handler;
import love.sola.netsupport.enums.Attribute;
import love.sola.netsupport.pojo.Ticket;
import love.sola.netsupport.pojo.User;
import love.sola.netsupport.session.WechatSession;
import love.sola.netsupport.session.WxSession;
import love.sola.netsupport.sql.TableTicket;
import love.sola.netsupport.sql.TableUser;
import love.sola.netsupport.util.ParseUtil;
import love.sola.netsupport.wechat.Command;
import love.sola.netsupport.wechat.WechatSession;
import me.chanjar.weixin.common.exception.WxErrorException;
import me.chanjar.weixin.common.session.WxSession;
import me.chanjar.weixin.common.session.WxSessionManager;
import me.chanjar.weixin.mp.api.WxMpMessageHandler;
import me.chanjar.weixin.mp.api.WxMpService;
@@ -40,7 +40,8 @@ public class QueryHandler implements WxMpMessageHandler {
return WxMpXmlOutMessage.TEXT().fromUser(wxMessage.getToUserName()).toUser(wxMessage.getFromUserName())
.content(lang("No_Ticket_Available")).build();
}
WxSession session = WechatSession.create();
String id = WechatSession.genId();
WxSession session = WechatSession.get(id, true);
session.setAttribute(Attribute.AUTHORIZED, Command.QUERY);
session.setAttribute(Attribute.WECHAT, wxMessage.getFromUserName());
session.setAttribute(Attribute.USER, u);
@@ -49,7 +50,7 @@ public class QueryHandler implements WxMpMessageHandler {
WxMpXmlOutNewsMessage.Item item = new WxMpXmlOutNewsMessage.Item();
item.setTitle(lang("Query_Title"));
item.setDescription(ParseUtil.parseTicket(t) + "\n" + lang("More_Details"));
item.setUrl(format("User_Query_Link", session.getId()));
item.setUrl(format("User_Query_Link", id));
out.addArticle(item);
return out.build();
}

View File

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

View File

@@ -6,21 +6,25 @@ import me.chanjar.weixin.mp.api.WxMpMessageHandler;
import me.chanjar.weixin.mp.api.WxMpService;
import me.chanjar.weixin.mp.bean.WxMpXmlMessage;
import me.chanjar.weixin.mp.bean.WxMpXmlOutMessage;
import me.chanjar.weixin.mp.bean.outxmlbuilder.TextBuilder;
import java.util.Map;
/**
* ***********************************************
* Created by Sola on 2015/12/29.
* Created by Sola on 2015/12/17.
* Don't modify this source without my agreement
* ***********************************************
*/
public class AutoReplyHandler implements WxMpMessageHandler {
public class SpamHandler implements WxMpMessageHandler {
@Override
public WxMpXmlOutMessage handle(WxMpXmlMessage wxMessage, Map<String, Object> context, WxMpService wxMpService, WxSessionManager sessionManager) throws WxErrorException {
//TODO auto reply
return null;
TextBuilder out = WxMpXmlOutMessage.TEXT()
.fromUser(wxMessage.getToUserName())
.toUser(wxMessage.getFromUserName());
return out.build();
}
}

View File

@@ -2,12 +2,12 @@ package love.sola.netsupport.wechat.handler;
import love.sola.netsupport.enums.Attribute;
import love.sola.netsupport.pojo.User;
import love.sola.netsupport.session.WechatSession;
import love.sola.netsupport.session.WxSession;
import love.sola.netsupport.sql.TableTicket;
import love.sola.netsupport.sql.TableUser;
import love.sola.netsupport.wechat.Command;
import love.sola.netsupport.wechat.WechatSession;
import me.chanjar.weixin.common.exception.WxErrorException;
import me.chanjar.weixin.common.session.WxSession;
import me.chanjar.weixin.common.session.WxSessionManager;
import me.chanjar.weixin.mp.api.WxMpMessageHandler;
import me.chanjar.weixin.mp.api.WxMpService;
@@ -36,8 +36,9 @@ public class SubmitHandler implements WxMpMessageHandler {
return WxMpXmlOutMessage.TEXT().fromUser(wxMessage.getToUserName()).toUser(wxMessage.getFromUserName())
.content(lang("Already_Opening_Ticket")).build();
}
WxSession session = WechatSession.create();
session.setAttribute(Attribute.AUTHORIZED, Command.SUBMIT);
String id = WechatSession.genId();
WxSession session = WechatSession.get(id, true);
session.setAttribute(Attribute.AUTHORIZED, Command.QUERY);
session.setAttribute(Attribute.WECHAT, wxMessage.getFromUserName());
session.setAttribute(Attribute.USER, u);
@@ -45,7 +46,7 @@ public class SubmitHandler implements WxMpMessageHandler {
WxMpXmlOutNewsMessage.Item item = new WxMpXmlOutNewsMessage.Item();
item.setTitle(lang("Submit_Title"));
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", id, u.getName(), u.getIsp().id, u.getRoom(), u.getBlock(), u.getPhone()));
out.addArticle(item);
return out.build();
}

View File

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

View File

@@ -1,82 +0,0 @@
package love.sola.netsupport.wechat.handler.admin;
import love.sola.netsupport.auth.OAuth2Handler;
import love.sola.netsupport.enums.Access;
import love.sola.netsupport.enums.Attribute;
import love.sola.netsupport.pojo.Operator;
import love.sola.netsupport.session.WechatSession;
import love.sola.netsupport.session.WxSession;
import love.sola.netsupport.sql.TableOperator;
import love.sola.netsupport.util.Redirect;
import love.sola.netsupport.wechat.Command;
import me.chanjar.weixin.common.exception.WxErrorException;
import me.chanjar.weixin.common.session.WxSessionManager;
import me.chanjar.weixin.mp.api.WxMpMessageHandler;
import me.chanjar.weixin.mp.api.WxMpService;
import me.chanjar.weixin.mp.bean.WxMpXmlMessage;
import me.chanjar.weixin.mp.bean.WxMpXmlOutMessage;
import me.chanjar.weixin.mp.bean.outxmlbuilder.TextBuilder;
import javax.servlet.AsyncContext;
import javax.servlet.http.HttpServletResponse;
import java.util.Map;
import static love.sola.netsupport.config.Lang.format;
import static love.sola.netsupport.config.Lang.lang;
/**
* ***********************************************
* Created by Sola on 2015/12/12.
* Don't modify this source without my agreement
* ***********************************************
*/
public class LoginHandler implements WxMpMessageHandler, OAuth2Handler {
@Override
public WxMpXmlOutMessage handle(WxMpXmlMessage wxMessage, Map<String, Object> context, WxMpService wxMpService, WxSessionManager sessionManager) throws WxErrorException {
TextBuilder out = WxMpXmlOutMessage.TEXT().fromUser(wxMessage.getToUserName()).toUser(wxMessage.getFromUserName());
try {
Operator operator = TableOperator.get(wxMessage.getFromUserName());
if (operator == null)
out.content(lang("Not_Operator"));
else if (operator.getAccess() >= Access.NO_LOGIN) {
out.content(lang("No_Login"));
} else {
WxSession session = WechatSession.create();
session.setAttribute(Attribute.AUTHORIZED, Command.LOGIN);
session.setAttribute(Attribute.WECHAT, wxMessage.getFromUserName());
session.setAttribute(Attribute.OPERATOR, operator);
out.content(format("Home_Page_Msg", format("Operator_Home_Page", session.getId())));
}
} catch (Exception e) {
e.printStackTrace();
out.content(lang("Login_Error"));
}
return out.build();
}
@Override
public void onOAuth2(AsyncContext actx, HttpServletResponse resp, String user, WxSession session) {
try {
Operator operator = TableOperator.get(user);
if (operator == null) {
Redirect.error().icon(Redirect.WeUIIcon.WARN_SAFE).noButton()
.title(lang("Not_Operator")).msg(lang("Not_Operator_OAuth2")).go(resp);
return;
}
if (operator.getAccess() >= Access.NO_LOGIN) {
Redirect.error().icon(Redirect.WeUIIcon.WAITING).noButton()
.title(lang("Left_Operator_Title")).msg(lang("Left_Operator")).go(resp);
return;
}
session.setAttribute(Attribute.AUTHORIZED, Command.LOGIN);
session.setAttribute(Attribute.WECHAT, user);
session.setAttribute(Attribute.OPERATOR, operator);
resp.sendRedirect(format("Operator_Home_Page", session.getId()));
} catch (Exception e) {
e.printStackTrace();
}
}
}

View File

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

View File

@@ -1,9 +1,13 @@
package love.sola.netsupport.wechat.matcher;
import love.sola.netsupport.pojo.User;
import love.sola.netsupport.sql.TableUser;
import me.chanjar.weixin.mp.api.WxMpMessageMatcher;
import me.chanjar.weixin.mp.bean.WxMpXmlMessage;
import java.util.HashSet;
import java.util.Set;
/**
* ***********************************************
* Created by Sola on 2015/11/26.
@@ -12,9 +16,18 @@ import me.chanjar.weixin.mp.bean.WxMpXmlMessage;
*/
public class RegisterMatcher implements WxMpMessageMatcher {
public static Set<String> registered = new HashSet<>();
@Override
public boolean match(WxMpXmlMessage message) {
return TableUser.getByWechat(message.getFromUserName()) == null;
String fromUser = message.getFromUserName();
if (registered.contains(fromUser)) {
return false;
} else {
User u = TableUser.getByWechat(fromUser);
if (u != null) registered.add(u.getWechatId());
return u == null;
}
}
}

View File

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

View File

@@ -6,70 +6,49 @@ Unknown_Encrypt_Type: 'Unknown encrypt-type.'
#Command Regex
REGEX_QUERY: '^(?i)(Query)|(查询)|(cx)$'
REGEX_REGISTER: '^(?i)(Reg(ister)?)|(注册)|(绑定)|(zc)|(bd)$'
REGEX_SUBMIT: '^(?i)(Submit)|(报修)|(保修)|(bx)$'
REGEX_SUBMIT: '^(?i)(Submit)|(报修)|(bx)$'
REGEX_CANCEL: '^(?i)(Cancel)|(取消)|(撤销)|(qx)|(cx)$'
REGEX_LOGIN: '^(?i)Authme$'
REGEX_PROFILE: '^(?i)(EditProfile)|(修改资料)|(修改信息)|(xgzl)|(xgxx)$'
REGEX_OPERATOR_INFO: '^(?i)(OpInfo)|(网维资料)|(wwzl)$'
REGEX_PROFILE: '^(?i)(EditProfile)|(修改资料)|(xgzl)$'
#Misc
#Event
Event_Subscribe: "欢迎使用电子科技大学中山学院网络维护科微信自助报修平台。\n如您在使用中遇到任何问题请将投诉或建议邮件至loli@sola.love.\n\n请发送'绑定'进行微信绑定"
Invalid_Operation: 'Whoops报修姬找不到你想要的东西啦 (╯‵□′)╯︵┻━┻。'
Message_Spam: '你的打字速度太快了喝一杯82年的Java压压惊吧。'
#Subscribe
Event_Subscribe: "欢迎使用电子科技大学中山学院网络维护科微信自助报修平台。\n\n{0}"
#Register
User_Register: "您尚未进行微信绑定。\n<a href=\"{0}\">>点击这里进行微信绑定操作<</a>"
Already_Registered: '您已进行过微信绑定。若是需要更改个人信息,请<a href="{0}"> >点击此处<</a>。'
Already_Registered: "您进行微信绑定。如果需要更改个人信息,请发送 '修改资料' 。"
#Query
Query_Title: '最近一次报修记录:'
More_Details: '>>> 查询更早的报修信息,请点击 <<<'
More_Details: '查询更早的报修信息,请点击 >'
No_Ticket_Available: '您尚未提交过任何报修。'
#Submit
Already_Opening_Ticket: "您上次提交的报修单仍在处理中. 若需要查询报修单状态,请发送 '查询' 。"
Submit_Title: '在网维工作人员上门解决您的问题之前...'
Submit_Desc: |
在网维工作人员上门解决您的问题之前,您可以尝试以下方法来更有效地解决您的问题:
- 重新插拔您电脑的网线以及墙上的端口。
- 尝试卸载掉您的wifi共享软件并重启电脑。
- 请您检查一下您的账号是否余额充足。
- 若您的电脑出现明显异常,请尝试使用他人的电脑能否正常登录,网维的工作成员主要负责网络的维护工作,可能无法解决您的个人电脑问题。
若以上步骤对您没有帮助,请点此提交报修表单。
Submit_Desc: "在网维工作人员上门解决您的问题之前,您可以尝试以下方法来更有效地解决您的问题:\n
重新插拔您电脑的网线以及墙上的端口。\n
尝试卸载掉您的wifi共享软件并重启电脑。\n
请您检查一下您的账号是否余额充足。\n
若您的电脑出现明显异常,请尝试使用他人的电脑能否正常登录,网维的工作成员主要负责网络的维护工作,可能无法解决您的个人电脑问题。\n
\n
若以上步骤对您没有帮助,请点此提交报修表单。"
#Cancel
No_Open_Ticket_Available: '您当前没有未解决的报修表单。'
Cancel_Title: '报修已取消:'
User_Cancel_Remark: '用户手动取消报修。'
Cancel_Failed: '取消失败。'
#Modify
Profile_Modify: '<a href="{0}">> 点此修改资料 <</a>'
Need_Register_Title: '尚未进行微信绑定'
Need_Register: '您尚未进行微信绑定3秒后将自动跳转至微信绑定页面。'
#Login
Home_Page_Msg: '<a href="{0}">CLICK HERE</a>'
Not_Operator: '嘟嘟嘟……'
Not_Operator_OAuth2: '看起来你并不是我们网维大家族的一员,但我们随时都欢迎你的加入哦!'
No_Login: 'Permission Denied.'
Left_Operator_Title: '一路上有你'
Left_Operator: '网络维护科的茁壮成长离不开每一位成员的陪伴。一路上有你,感谢你对网络维护科的贡献!'
Internal_Error: '啊哦,登录失败了哦。'
#Operator_Info
Operator_Info: |
网维成员资料:
网维ID: {0,number,#}
姓名: {1}
岗位: {2,choice,0#'Administrator >ω<'|3#值班组长|6#正式成员|7#实习成员|9#'曾经的一员(TдT)'}
值班片区: {3,choice,0#'全图 >ω<'|1#岐头片区|2#北门片区|3#东门片区|4#香灰片区|5#凤翔片区}
值班日: {4,choice,0#'2月30日 >ω<'|1#周一|2#周二|3#周三|4#周四|5#周五|6#周六|7#周日}
若以上信息有误,请及时联系@15-沙子森。
#URL
User_Register_Link: 'http://topaz.sinaapp.com/nm/v2/user/reg.html?token={0}'
User_Query_Link: 'http://topaz.sinaapp.com/nm/v2/user/list.html?token={0}'
User_Submit_Link: 'http://topaz.sinaapp.com/nm/v2/user/rrepair.html?token={0}&name={1}&isp={2}&room={3}&block={4}&phone={5,number,#}'
User_Profile_Link: 'http://topaz.sinaapp.com/nm/v2/user/modi.html?token={0}&name={1}&isp={2}&username={3}&block={4}&room={5}&phone={6,number,#}'
Result_Page: 'http://topaz.sinaapp.com/nm/v2/result.html'
Operator_Home_Page: 'http://topaz.sinaapp.com/nm/v2/man/home.html?token={0}'
Operator_Login_Page: 'http://topaz.sinaapp.com/nm/v2/man/login.html?pkey={0}'
User_Register_Link: '您尚未进行微信绑定, 请<a href="http://topaz.sinaapp.com/nm/v1/reg.html?token={0}">点击这里</a>进行微信绑定操作。'
User_Query_Link: 'http://topaz.sinaapp.com/nm/v1/list.html?token={0}'
User_Submit_Link: 'http://topaz.sinaapp.com/nm/v1/rrepair.html?token={0}&name={1}&isp={2}&room={3}&block={4}&phone={5,number,#}'
User_Profile_Link: 'http://topaz.sinaapp.com/nm/v1/profile.html?token={0}&name={1}&isp={2}&account={3}&block={4}&room={5}&phone={6,number,#}'
Result_Page: 'http://topaz.sinaapp.com/nm/v1/result.html'
Operator_Home_Page: '<a href="http://topaz.sinaapp.com/nm/v1/man/home.html?token={0}">CLICK HERE</a>'
Operator_Login_Page: 'http://topaz.sinaapp.com/nm/v1/man/login.html?pkey={0}'
#Localized
#Status
@@ -77,7 +56,7 @@ STATUS_UNCHECKED: '待处理'
STATUS_SOLVED: '已解决'
#Ticket
Ticket_Info_Id: '报修单号: '
Ticket_Info_Desc: ''
Ticket_Info_Desc: '报修描述: '
Ticket_Info_Submit_Time: '提交时间: '
Ticket_Info_Operator: '操作员: '
Ticket_Info_Remark: '维修描述: '

View File

@@ -1,47 +0,0 @@
{
"button": [
{
"name": "我要",
"sub_button": [
{
"type": "click",
"name": "提交报修",
"key": "SUBMIT"
},
{
"type": "click",
"name": "查询报修",
"key": "QUERY"
},
{
"type": "click",
"name": "撤销报修",
"key": "CANCEL"
},
{
"type": "view",
"name": "修改资料",
"url": "https://open.weixin.qq.com/connect/oauth2/authorize?appid=wxb7a8b799e494b053&redirect_uri=http%3a%2f%2fwcs.sola.love%2foauth2%2fcallback&response_type=code&scope=snsapi_base&state=PROFILE#wechat_redirect"
}
]
},
{
"name": "OP",
"sub_button": [
{
"type": "click",
"name": "网维资料",
"key": "OPERATOR_INFO"
},
{
"type": "view",
"name": "后台登录",
"url": "https://open.weixin.qq.com/connect/oauth2/authorize?appid=wxb7a8b799e494b053&redirect_uri=http%3a%2f%2fwcs.sola.love%2foauth2%2fcallback&response_type=code&scope=snsapi_base&state=LOGIN#wechat_redirect"
}
]
}
],
"matchrule": {
"group_id": "100"
}
}

View File

@@ -1,29 +0,0 @@
{
"button": [
{
"name": "我要",
"sub_button": [
{
"type": "click",
"name": "提交报修",
"key": "SUBMIT"
},
{
"type": "click",
"name": "查询报修",
"key": "QUERY"
},
{
"type": "click",
"name": "撤销报修",
"key": "CANCEL"
},
{
"type": "view",
"name": "修改资料",
"url": "https://open.weixin.qq.com/connect/oauth2/authorize?appid=wxb7a8b799e494b053&redirect_uri=http%3a%2f%2fwcs.sola.love%2foauth2%2fcallback&response_type=code&scope=snsapi_base&state=PROFILE#wechat_redirect"
}
]
}
]
}

View File

@@ -1,48 +0,0 @@
<?xml version='1.0' encoding='utf-8'?>
<!--
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<!-- The contents of this file will be loaded for each web application -->
<Context swallowOutput="false" antiResourceLocking="true">
<!-- Default set of monitored resources -->
<WatchedResource>WEB-INF/web.xml</WatchedResource>
<!-- Uncomment this to disable session persistence across Tomcat restarts -->
<!--
<Manager pathname="" />
-->
<Resource auth="Container"
description="C3P0 database connection pool"
driverClass="com.mysql.jdbc.Driver"
maxPoolSize="10"
minPoolSize="2"
acquireIncrement="1"
maxIdleTime="3600"
idleConnectionTestPeriod="1800"
name="jdbc/netsupport"
user="root"
password=""
factory="org.apache.naming.factory.BeanFactory"
type="com.mchange.v2.c3p0.ComboPooledDataSource"
jdbcUrl="jdbc:mysql://localhost:3306/netsupport?autoReconnect=true&amp;characterEncoding=utf8" />
<!-- Uncomment this to enable Comet connection tacking (provides events
on session expiration as well as webapp lifecycle) -->
<!--
<Valve className="org.apache.catalina.valves.CometConnectionManagerValve" />
-->
</Context>

View File

@@ -1,23 +0,0 @@
package love.sola.netsupport.api;
import org.junit.Test;
import org.reflections.Reflections;
import java.util.Set;
/**
* ***********************************************
* Created by Sola on 2016/3/26.
* Don't modify this source without my agreement
* ***********************************************
*/
public class ReflectionTest {
@Test
public void test() {
Reflections reflections = new Reflections(getClass().getPackage().getName());
Set<Class<? extends API>> set = reflections.getSubTypesOf(API.class);
assert set.size() == 14;
}
}

View File

@@ -1,44 +0,0 @@
package love.sola.netsupport.util;
import org.apache.commons.codec.binary.Base64;
import org.junit.Test;
import org.mindrot.jbcrypt.BCrypt;
import java.security.KeyFactory;
import java.security.NoSuchAlgorithmException;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.X509EncodedKeySpec;
/**
* ***********************************************
* Created by Sola on 2015/12/6.
* Don't modify this source without my agreement
* ***********************************************
*/
public class EncryptTest {
@Test
public void testBCrypt() {
String hash = BCrypt.hashpw("mypasswordhere", BCrypt.gensalt());
assert BCrypt.checkpw("mypasswordhere", hash);
}
@Test
public void testRSA() {
assert "Hello World".equals(RSAUtil.decrypt(RSAUtil.encrypt("Hello World")));
assert "Encrypt".equals(RSAUtil.decrypt(RSAUtil.encrypt("Encrypt")));
}
// @Test
public void testRSASpecKey() throws NoSuchAlgorithmException, InvalidKeySpecException {
System.out.println("RSAUtil.privateKey_s = " + RSAUtil.privateKey_s);
System.out.println("RSAUtil.publicKey_s = " + RSAUtil.publicKey_s);
// String pkey = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCA0qyARvHSCIUQ6YM6K+e/QgiZ+dc/MpVz5DIFwQab5iiifruQiaoA74ilHOOiq5i0ToR1VxNhCUZcAy2saHNifoYKTauMOUSV6IoP4X5jp691PlI9yxNx328mSlPNM9+7BgOzrUP1pR71d+T4LDn0o4J6Ad82vVIe7yWszzF4qQIDAQAB";
String pkey = RSAUtil.publicKey_s;
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
X509EncodedKeySpec keySpec = new X509EncodedKeySpec(Base64.decodeBase64(pkey));
RSAUtil.publicKey = keyFactory.generatePublic(keySpec);
System.out.println("RSAUtil.encrypt(\"233\") = " + RSAUtil.encrypt("233"));
}
}

View File

@@ -1,34 +0,0 @@
package love.sola.netsupport.util;
import com.google.common.net.UrlEscapers;
import org.junit.Test;
import java.io.UnsupportedEncodingException;
import static org.hamcrest.CoreMatchers.equalTo;
import static org.junit.Assert.assertThat;
/**
* ***********************************************
* Created by Sola on 2016/3/26.
* Don't modify this source without my agreement
* ***********************************************
*/
public class URLEncodeTest {
@Test
public void testEncode() throws UnsupportedEncodingException {
assertThat(
UrlEscapers.urlFragmentEscaper().escape("Test Title"),
equalTo("Test%20Title")
);
assertThat(
Redirect.success()
.title("Test Title")
.msg("Test Message")
.toString(),
equalTo("http://topaz.sinaapp.com/nm/v2/result.html?type=1&title=Test%20Title&msg=Test%20Message&")
);
}
}

View File

@@ -1,18 +1,20 @@
package love.sola.netsupport.config;
package love.sola.netsupport.wechat;
import org.junit.Test;
import java.util.Date;
/**
* ***********************************************
* Created by Sola on 2016/3/26.
* Created by Sola on 2015/12/3.
* Don't modify this source without my agreement
* ***********************************************
*/
public class ReflectionTest {
public class TestDate {
@Test
public void testLang() {
assert Lang.messages != null;
public void test() {
System.out.println(new Date());
}
}

View File

@@ -0,0 +1,27 @@
package love.sola.netsupport.wechat;
import love.sola.netsupport.util.RSAUtil;
import org.junit.Test;
import org.mindrot.jbcrypt.BCrypt;
/**
* ***********************************************
* Created by Sola on 2015/12/6.
* Don't modify this source without my agreement
* ***********************************************
*/
public class TestEncrypt {
@Test
public void testBCrypt() {
String hash = BCrypt.hashpw("mypasswordhere", BCrypt.gensalt());
assert BCrypt.checkpw("mypasswordhere", hash);
}
@Test
public void testRSA() {
assert "Hello World".equals(RSAUtil.decrypt(RSAUtil.encrypt("Hello World")));
assert "Encrypt".equals(RSAUtil.decrypt(RSAUtil.encrypt("Encrypt")));
}
}

View File

@@ -1,10 +1,19 @@
package love.sola.netsupport.util;
package love.sola.netsupport.wechat;
import com.google.gson.*;
import lombok.AllArgsConstructor;
import lombok.Data;
import love.sola.netsupport.config.Lang;
import love.sola.netsupport.enums.ISP;
import org.junit.Test;
import org.yaml.snakeyaml.DumperOptions;
import org.yaml.snakeyaml.Yaml;
import org.yaml.snakeyaml.nodes.Tag;
import java.text.MessageFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
/**
* ***********************************************
@@ -12,7 +21,12 @@ import java.util.Date;
* Don't modify this source without my agreement
* ***********************************************
*/
public class GsonTest {
public class TestMessageFormat {
@Test
public void testLang() {
assert Lang.messages != null;
}
@Test
public void testJsonDate() {
@@ -28,4 +42,28 @@ public class GsonTest {
assert gson.toJson(ISP.TELECOM).equals("1");
}
@Test
public void testLong() {
assert "15838838438".equals(MessageFormat.format("{0,number,#}", 15838838438L));
}
@Test
public void testYaml() {
assert new Yaml().loadAs("array: \n - \"err\"\n - \"ee\"", TestArray.class).array.length == 2;
}
@Test
public void testYamlDump() {
Map<String, TestArray> map = new HashMap<>();
map.put("fuck", new TestArray(new String[]{"one", "two", "three"}));
map.put("you", new TestArray(new String[]{"one", "two", "three"}));
System.out.println(new Yaml().dumpAs(map, new Tag(map.getClass()), DumperOptions.FlowStyle.BLOCK));
}
@Data
@AllArgsConstructor
public static class TestArray {
String[] array;
}
}

View File

@@ -1,5 +1,6 @@
package love.sola.netsupport.enums;
package love.sola.netsupport.wechat;
import love.sola.netsupport.enums.Block;
import org.junit.Test;
/**
@@ -8,21 +9,11 @@ import org.junit.Test;
* Don't modify this source without my agreement
* ***********************************************
*/
public class ReflectionTest {
public class TestReflection {
@Test
public void testBlock() {
assert Block.inverseMap != null;
}
@Test
public void testAccess() {
assert Access.inverseMap != null;
}
@Test
public void testStatus() {
assert Status.inverseMap != null;
}
}

View File

@@ -0,0 +1,21 @@
package love.sola.netsupport.wechat;
import org.junit.Test;
/**
* ***********************************************
* Created by Sola on 2015/11/26.
* Don't modify this source without my agreement
* ***********************************************
*/
public class TestRegex {
public static final String STUDENT_ID_REGEX = "^(2012|2013|2014|2015)[0-9]{9}";
@Test
public void testStudentId() {
assert !"2011130201233".matches(STUDENT_ID_REGEX);
assert "2015130201233".matches(STUDENT_ID_REGEX);
}
}