oauth2 v2 update

This commit is contained in:
Sola
2016-03-27 03:12:58 +08:00
parent 910bdca8a8
commit 850e45a2d8
48 changed files with 799 additions and 422 deletions

1
.gitignore vendored
View File

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

316
pom.xml
View File

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

View File

@@ -1,8 +1,8 @@
package love.sola.netsupport.api; package love.sola.netsupport.api;
import love.sola.netsupport.enums.Access; import love.sola.netsupport.enums.Access;
import love.sola.netsupport.session.WxSession;
import love.sola.netsupport.wechat.Command; import love.sola.netsupport.wechat.Command;
import me.chanjar.weixin.common.session.WxSession;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;

View File

@@ -1,15 +1,15 @@
package love.sola.netsupport.api; package love.sola.netsupport.api;
import com.google.common.reflect.ClassPath;
import com.google.gson.Gson; import com.google.gson.Gson;
import love.sola.netsupport.enums.Access; import love.sola.netsupport.enums.Access;
import love.sola.netsupport.enums.Attribute; import love.sola.netsupport.enums.Attribute;
import love.sola.netsupport.pojo.Operator; import love.sola.netsupport.pojo.Operator;
import love.sola.netsupport.pojo.User; 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.SQLCore;
import love.sola.netsupport.wechat.WechatSession;
import me.chanjar.weixin.common.session.WxSession;
import org.hibernate.HibernateException; import org.hibernate.HibernateException;
import org.reflections.Reflections;
import javax.servlet.ServletException; import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet; import javax.servlet.annotation.WebServlet;
@@ -35,21 +35,20 @@ public class APIRouter extends HttpServlet {
protected static Gson gson = SQLCore.gson; protected static Gson gson = SQLCore.gson;
private Map<String, API> nodes = new HashMap<>(); private Map<String, API> nodes = new HashMap<>();
public APIRouter() { @Override
public void init() throws ServletException {
super.init();
try { try {
ClassPath path = ClassPath.from(getClass().getClassLoader()); Reflections reflections = new Reflections(getClass().getPackage().getName());
Set<ClassPath.ClassInfo> classes = path.getTopLevelClassesRecursive(getClass().getPackage().getName()); Set<Class<? extends API>> set = reflections.getSubTypesOf(API.class);
for (ClassPath.ClassInfo info : classes) { for (Class<? extends API> clz : set) {
Class<?> clz = info.load(); try {
if (!API.class.equals(clz) && API.class.isAssignableFrom(clz)) { System.out.println("Loading API: " + clz.getName());
try { API obj = clz.newInstance();
System.out.print("Loading API: " + clz.getName()); System.out.println("Registered API: " + obj);
API obj = (API) clz.newInstance(); nodes.put(obj.url, obj);
System.out.println("Registered API: " + obj); } catch (InstantiationException | IllegalAccessException e) {
nodes.put(obj.url, obj); e.printStackTrace();
} catch (InstantiationException | IllegalAccessException e) {
e.printStackTrace();
}
} }
} }
} catch (Exception e) { } catch (Exception e) {
@@ -66,7 +65,7 @@ public class APIRouter extends HttpServlet {
resp.addHeader("Access-Control-Allow-Origin", "*"); resp.addHeader("Access-Control-Allow-Origin", "*");
Object obj = null; Object obj = null;
try { try {
API api = nodes.get(req.getRequestURI()); API api = nodes.get(req.getPathInfo());
if (api == null) { if (api == null) {
resp.sendError(HttpServletResponse.SC_FORBIDDEN); resp.sendError(HttpServletResponse.SC_FORBIDDEN);
return; return;
@@ -82,14 +81,14 @@ public class APIRouter extends HttpServlet {
return; return;
} }
if (api.access == Access.USER) { if (api.access == Access.USER) {
User u = (User) session.getAttribute(Attribute.USER); User u = session.getAttribute(Attribute.USER);
if (u == null) { if (u == null) {
obj = Error.UNAUTHORIZED; obj = Error.UNAUTHORIZED;
return; return;
} }
} }
if (api.access < Access.USER) { if (api.access < Access.USER) {
Operator op = (Operator) session.getAttribute(Attribute.OPERATOR); Operator op = session.getAttribute(Attribute.OPERATOR);
if (op == null) { if (op == null) {
obj = Error.UNAUTHORIZED; obj = Error.UNAUTHORIZED;
return; return;
@@ -121,7 +120,7 @@ public class APIRouter extends HttpServlet {
private static WxSession getSession(HttpServletRequest req) { private static WxSession getSession(HttpServletRequest req) {
String t = req.getParameter("token"); String t = req.getParameter("token");
if (t == null || t.isEmpty()) return null; if (t == null || t.isEmpty()) return null;
return WechatSession.get(t, false); return WechatSession.get(t);
} }
} }

View File

@@ -2,7 +2,7 @@ package love.sola.netsupport.api;
import love.sola.netsupport.enums.Access; import love.sola.netsupport.enums.Access;
import love.sola.netsupport.enums.Attribute; import love.sola.netsupport.enums.Attribute;
import me.chanjar.weixin.common.session.WxSession; import love.sola.netsupport.session.WxSession;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import java.util.HashMap; import java.util.HashMap;
@@ -17,7 +17,7 @@ import java.util.Map;
public class CheckSession extends API { public class CheckSession extends API {
public CheckSession() { public CheckSession() {
url = "/api/checksession"; url = "/checksession";
access = Access.GUEST; access = Access.GUEST;
authorize = null; authorize = null;
} }

View File

@@ -5,15 +5,14 @@ import love.sola.netsupport.enums.Access;
import love.sola.netsupport.enums.Attribute; import love.sola.netsupport.enums.Attribute;
import love.sola.netsupport.pojo.Operator; import love.sola.netsupport.pojo.Operator;
import love.sola.netsupport.pojo.User; 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.SQLCore;
import love.sola.netsupport.sql.TableOperator; import love.sola.netsupport.sql.TableOperator;
import love.sola.netsupport.sql.TableUser; import love.sola.netsupport.sql.TableUser;
import love.sola.netsupport.util.Crypto; import love.sola.netsupport.util.Crypto;
import love.sola.netsupport.util.ParseUtil;
import love.sola.netsupport.util.RSAUtil; import love.sola.netsupport.util.RSAUtil;
import love.sola.netsupport.wechat.Command; 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.ServletException;
import javax.servlet.annotation.WebServlet; import javax.servlet.annotation.WebServlet;
@@ -45,8 +44,7 @@ public class Login extends HttpServlet {
response.addHeader("Content-type", "application/json;charset=utf-8"); response.addHeader("Content-type", "application/json;charset=utf-8");
response.addHeader("Access-Control-Allow-Origin", "*"); response.addHeader("Access-Control-Allow-Origin", "*");
PrintWriter out = response.getWriter(); PrintWriter out = response.getWriter();
String json = gson.toJson(login(request)); out.println(gson.toJson(login(request)));
out.println(ParseUtil.parseJsonP(request, json));
out.close(); out.close();
} }
@@ -65,8 +63,7 @@ public class Login extends HttpServlet {
return Error.WRONG_PASSWORD; return Error.WRONG_PASSWORD;
} }
String sid = WechatSession.genId(); WxSession session = WechatSession.create();
WxSession session = WechatSession.get(sid, true);
if (bypass) { if (bypass) {
session.setAttribute(Attribute.AUTHORIZED, Command.fromId(Integer.parseInt(request.getParameter("bypass")))); session.setAttribute(Attribute.AUTHORIZED, Command.fromId(Integer.parseInt(request.getParameter("bypass"))));
} else { } else {
@@ -84,7 +81,7 @@ public class Login extends HttpServlet {
if (request.getParameter("bypasswechat") != null) { if (request.getParameter("bypasswechat") != null) {
session.setAttribute(Attribute.WECHAT, request.getParameter("bypasswechat")); session.setAttribute(Attribute.WECHAT, request.getParameter("bypasswechat"));
} }
return sid; return session.getId();
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
return Error.INTERNAL_ERROR; return Error.INTERNAL_ERROR;

View File

@@ -4,9 +4,9 @@ import love.sola.netsupport.api.API;
import love.sola.netsupport.api.Error; import love.sola.netsupport.api.Error;
import love.sola.netsupport.enums.Access; import love.sola.netsupport.enums.Access;
import love.sola.netsupport.pojo.User; import love.sola.netsupport.pojo.User;
import love.sola.netsupport.session.WxSession;
import love.sola.netsupport.sql.TableUser; import love.sola.netsupport.sql.TableUser;
import love.sola.netsupport.wechat.Command; import love.sola.netsupport.wechat.Command;
import me.chanjar.weixin.common.session.WxSession;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
@@ -19,7 +19,7 @@ import javax.servlet.http.HttpServletRequest;
public class GetUser extends API { public class GetUser extends API {
public GetUser() { public GetUser() {
url = "/api/admin/getuser"; url = "/admin/getuser";
access = Access.LEADER; access = Access.LEADER;
authorize = Command.LOGIN; authorize = Command.LOGIN;
} }

View File

@@ -9,10 +9,10 @@ import love.sola.netsupport.enums.Status;
import love.sola.netsupport.pojo.Operator; import love.sola.netsupport.pojo.Operator;
import love.sola.netsupport.pojo.Ticket; import love.sola.netsupport.pojo.Ticket;
import love.sola.netsupport.pojo.User; import love.sola.netsupport.pojo.User;
import love.sola.netsupport.session.WxSession;
import love.sola.netsupport.sql.SQLCore; import love.sola.netsupport.sql.SQLCore;
import love.sola.netsupport.util.Checker; import love.sola.netsupport.util.Checker;
import love.sola.netsupport.wechat.Command; import love.sola.netsupport.wechat.Command;
import me.chanjar.weixin.common.session.WxSession;
import org.hibernate.Session; import org.hibernate.Session;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
@@ -26,7 +26,7 @@ import javax.servlet.http.HttpServletRequest;
public class TicketPush extends API { public class TicketPush extends API {
public TicketPush() { public TicketPush() {
url = "/api/admin/ticketpush"; url = "/admin/ticketpush";
access = Access.LEADER; access = Access.LEADER;
authorize = Command.LOGIN; authorize = Command.LOGIN;
} }
@@ -41,7 +41,7 @@ public class TicketPush extends API {
if (desc.length() > Settings.MAX_DESC_LENGTH) { if (desc.length() > Settings.MAX_DESC_LENGTH) {
return Error.LENGTH_LIMIT_EXCEEDED; return Error.LENGTH_LIMIT_EXCEEDED;
} }
Operator op = (Operator) session.getAttribute(Attribute.OPERATOR); Operator op = session.getAttribute(Attribute.OPERATOR);
try (Session s = SQLCore.sf.openSession()) { try (Session s = SQLCore.sf.openSession()) {
s.beginTransaction(); s.beginTransaction();
User u = s.get(User.class, Long.parseLong(uid)); User u = s.get(User.class, Long.parseLong(uid));

View File

@@ -2,13 +2,12 @@ package love.sola.netsupport.api.root;
import love.sola.netsupport.api.API; import love.sola.netsupport.api.API;
import love.sola.netsupport.enums.Access; 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 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.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import java.util.Enumeration; import java.util.Set;
/** /**
* *********************************************** * ***********************************************
@@ -19,7 +18,7 @@ import java.util.Enumeration;
public class DashBoard extends API { public class DashBoard extends API {
public DashBoard() { public DashBoard() {
url = "/api/root/dashboard"; url = "/root/dashboard";
access = Access.ROOT; access = Access.ROOT;
authorize = Command.LOGIN; authorize = Command.LOGIN;
} }
@@ -27,13 +26,11 @@ public class DashBoard extends API {
@Override @Override
protected Object process(HttpServletRequest req, WxSession session) throws Exception { protected Object process(HttpServletRequest req, WxSession session) throws Exception {
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
for (InternalSession s : WechatSession.list()) { for (love.sola.netsupport.session.WxSession ws : WechatSession.list()) {
sb.append("=====").append(s.getIdInternal()).append("=====\n"); sb.append("=====").append(ws.getId()).append("=====\n");
WxSession ws = s.getSession(); Set<String> e = ws.getAttributeNames();
Enumeration<String> e = ws.getAttributeNames(); for (String key : e) {
while (e.hasMoreElements()) { sb.append(key).append(": ").append(ws.getAttribute(key).toString()).append("\n");
String key = e.nextElement();
sb.append(key).append(": ").append(ws.getAttribute(key)).append("\n");
} }
} }
return sb.toString(); return sb.toString();

View File

@@ -3,9 +3,9 @@ package love.sola.netsupport.api.root;
import love.sola.netsupport.api.API; import love.sola.netsupport.api.API;
import love.sola.netsupport.api.Error; import love.sola.netsupport.api.Error;
import love.sola.netsupport.enums.Access; import love.sola.netsupport.enums.Access;
import love.sola.netsupport.session.WxSession;
import love.sola.netsupport.sql.TableUser; import love.sola.netsupport.sql.TableUser;
import love.sola.netsupport.wechat.Command; import love.sola.netsupport.wechat.Command;
import me.chanjar.weixin.common.session.WxSession;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
@@ -18,7 +18,7 @@ import javax.servlet.http.HttpServletRequest;
public class FlushCache extends API { public class FlushCache extends API {
public FlushCache() { public FlushCache() {
url = "/api/root/flushcache"; url = "/root/flushcache";
access = Access.ROOT; access = Access.ROOT;
authorize = Command.LOGIN; authorize = Command.LOGIN;
} }

View File

@@ -4,10 +4,10 @@ import love.sola.netsupport.api.API;
import love.sola.netsupport.api.Error; import love.sola.netsupport.api.Error;
import love.sola.netsupport.enums.Access; import love.sola.netsupport.enums.Access;
import love.sola.netsupport.pojo.Operator; import love.sola.netsupport.pojo.Operator;
import love.sola.netsupport.session.WxSession;
import love.sola.netsupport.sql.SQLCore; import love.sola.netsupport.sql.SQLCore;
import love.sola.netsupport.util.Crypto; import love.sola.netsupport.util.Crypto;
import love.sola.netsupport.wechat.Command; import love.sola.netsupport.wechat.Command;
import me.chanjar.weixin.common.session.WxSession;
import org.hibernate.Session; import org.hibernate.Session;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
@@ -21,7 +21,7 @@ import javax.servlet.http.HttpServletRequest;
public class SetPassword extends API { public class SetPassword extends API {
public SetPassword() { public SetPassword() {
url = "/api/root/setpass"; url = "/root/setpass";
access = Access.ROOT; access = Access.ROOT;
authorize = Command.LOGIN; authorize = Command.LOGIN;
} }

View File

@@ -3,10 +3,10 @@ package love.sola.netsupport.api.stuff;
import love.sola.netsupport.api.API; import love.sola.netsupport.api.API;
import love.sola.netsupport.enums.Access; import love.sola.netsupport.enums.Access;
import love.sola.netsupport.pojo.Ticket; import love.sola.netsupport.pojo.Ticket;
import love.sola.netsupport.session.WxSession;
import love.sola.netsupport.sql.SQLCore; import love.sola.netsupport.sql.SQLCore;
import love.sola.netsupport.sql.TableTicket; import love.sola.netsupport.sql.TableTicket;
import love.sola.netsupport.wechat.Command; import love.sola.netsupport.wechat.Command;
import me.chanjar.weixin.common.session.WxSession;
import org.apache.commons.lang3.time.DateUtils; import org.apache.commons.lang3.time.DateUtils;
import org.hibernate.Session; import org.hibernate.Session;
import org.hibernate.envers.AuditReader; import org.hibernate.envers.AuditReader;
@@ -28,7 +28,7 @@ public class TicketLog extends API {
public static SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMdd"); public static SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMdd");
public TicketLog() { public TicketLog() {
url = "/api/admin/ticketlog"; url = "/admin/ticketlog";
access = Access.MEMBER; access = Access.MEMBER;
authorize = Command.LOGIN; authorize = Command.LOGIN;
} }

View File

@@ -4,9 +4,9 @@ import love.sola.netsupport.api.API;
import love.sola.netsupport.enums.Access; import love.sola.netsupport.enums.Access;
import love.sola.netsupport.enums.Attribute; import love.sola.netsupport.enums.Attribute;
import love.sola.netsupport.pojo.Operator; import love.sola.netsupport.pojo.Operator;
import love.sola.netsupport.session.WxSession;
import love.sola.netsupport.sql.TableTicket; import love.sola.netsupport.sql.TableTicket;
import love.sola.netsupport.wechat.Command; import love.sola.netsupport.wechat.Command;
import me.chanjar.weixin.common.session.WxSession;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
@@ -19,14 +19,14 @@ import javax.servlet.http.HttpServletRequest;
public class TicketLookup extends API { public class TicketLookup extends API {
public TicketLookup() { public TicketLookup() {
url = "/api/admin/ticketlookup"; url = "/admin/ticketlookup";
access = Access.MEMBER; access = Access.MEMBER;
authorize = Command.LOGIN; authorize = Command.LOGIN;
} }
@Override @Override
protected Object process(HttpServletRequest req, WxSession session) throws Exception { protected Object process(HttpServletRequest req, WxSession session) throws Exception {
Operator op = (Operator) session.getAttribute(Attribute.OPERATOR); Operator op = session.getAttribute(Attribute.OPERATOR);
int block; int block;
if (req.getParameter("block") != null) { if (req.getParameter("block") != null) {
block = Integer.parseInt(req.getParameter("block")); block = Integer.parseInt(req.getParameter("block"));

View File

@@ -3,9 +3,9 @@ package love.sola.netsupport.api.stuff;
import love.sola.netsupport.api.API; import love.sola.netsupport.api.API;
import love.sola.netsupport.api.Error; import love.sola.netsupport.api.Error;
import love.sola.netsupport.enums.Access; import love.sola.netsupport.enums.Access;
import love.sola.netsupport.session.WxSession;
import love.sola.netsupport.sql.TableTicket; import love.sola.netsupport.sql.TableTicket;
import love.sola.netsupport.wechat.Command; import love.sola.netsupport.wechat.Command;
import me.chanjar.weixin.common.session.WxSession;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
@@ -18,7 +18,7 @@ import javax.servlet.http.HttpServletRequest;
public class TicketTrack extends API { public class TicketTrack extends API {
public TicketTrack() { public TicketTrack() {
url = "/api/admin/tickettrack"; url = "/admin/tickettrack";
access = Access.MEMBER; access = Access.MEMBER;
authorize = Command.LOGIN; authorize = Command.LOGIN;
} }

View File

@@ -6,10 +6,10 @@ import love.sola.netsupport.enums.Access;
import love.sola.netsupport.enums.Attribute; import love.sola.netsupport.enums.Attribute;
import love.sola.netsupport.pojo.Operator; import love.sola.netsupport.pojo.Operator;
import love.sola.netsupport.pojo.Ticket; import love.sola.netsupport.pojo.Ticket;
import love.sola.netsupport.session.WxSession;
import love.sola.netsupport.sql.SQLCore; import love.sola.netsupport.sql.SQLCore;
import love.sola.netsupport.util.Checker; import love.sola.netsupport.util.Checker;
import love.sola.netsupport.wechat.Command; import love.sola.netsupport.wechat.Command;
import me.chanjar.weixin.common.session.WxSession;
import org.hibernate.Session; import org.hibernate.Session;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
@@ -24,7 +24,7 @@ import java.util.Date;
public class TicketUpdate extends API { public class TicketUpdate extends API {
public TicketUpdate() { public TicketUpdate() {
url = "/api/admin/ticketupdate"; url = "/admin/ticketupdate";
access = Access.MEMBER; access = Access.MEMBER;
authorize = Command.LOGIN; authorize = Command.LOGIN;
} }
@@ -36,7 +36,7 @@ public class TicketUpdate extends API {
String status = req.getParameter("status"); String status = req.getParameter("status");
if (Checker.hasNull(ticket, remark, status)) return Error.PARAMETER_REQUIRED; if (Checker.hasNull(ticket, remark, status)) return Error.PARAMETER_REQUIRED;
try (Session s = SQLCore.sf.openSession()) { try (Session s = SQLCore.sf.openSession()) {
Operator op = (Operator) session.getAttribute(Attribute.OPERATOR); Operator op = session.getAttribute(Attribute.OPERATOR);
Ticket t = s.get(Ticket.class, Integer.parseInt(ticket)); Ticket t = s.get(Ticket.class, Integer.parseInt(ticket));
if (t == null) { if (t == null) {
return Error.TICKET_NOT_FOUND; return Error.TICKET_NOT_FOUND;

View File

@@ -6,9 +6,9 @@ import love.sola.netsupport.enums.Access;
import love.sola.netsupport.enums.Attribute; import love.sola.netsupport.enums.Attribute;
import love.sola.netsupport.enums.ISP; import love.sola.netsupport.enums.ISP;
import love.sola.netsupport.pojo.User; import love.sola.netsupport.pojo.User;
import love.sola.netsupport.session.WxSession;
import love.sola.netsupport.sql.TableUser; import love.sola.netsupport.sql.TableUser;
import love.sola.netsupport.wechat.Command; import love.sola.netsupport.wechat.Command;
import me.chanjar.weixin.common.session.WxSession;
import org.hibernate.exception.ConstraintViolationException; import org.hibernate.exception.ConstraintViolationException;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
@@ -24,14 +24,14 @@ import static love.sola.netsupport.util.Checker.*;
public class ProfileModify extends API { public class ProfileModify extends API {
public ProfileModify() { public ProfileModify() {
url = "/api/profilemodify"; url = "/profilemodify";
access = Access.USER; access = Access.USER;
authorize = Command.PROFILE; authorize = Command.PROFILE;
} }
@Override @Override
protected Object process(HttpServletRequest req, WxSession session) throws Exception { protected Object process(HttpServletRequest req, WxSession session) throws Exception {
User u = (User) session.getAttribute(Attribute.USER); User u = session.getAttribute(Attribute.USER);
ISP isp = checkISP(req.getParameter("isp")); ISP isp = checkISP(req.getParameter("isp"));
String netAccount = checkNetAccount(req.getParameter("username"), isp); String netAccount = checkNetAccount(req.getParameter("username"), isp);
int block = checkBlock(req.getParameter("block")); int block = checkBlock(req.getParameter("block"));

View File

@@ -6,12 +6,12 @@ import love.sola.netsupport.enums.Access;
import love.sola.netsupport.enums.Attribute; import love.sola.netsupport.enums.Attribute;
import love.sola.netsupport.enums.ISP; import love.sola.netsupport.enums.ISP;
import love.sola.netsupport.pojo.User; import love.sola.netsupport.pojo.User;
import love.sola.netsupport.session.WxSession;
import love.sola.netsupport.sql.SQLCore; import love.sola.netsupport.sql.SQLCore;
import love.sola.netsupport.sql.TableUser; import love.sola.netsupport.sql.TableUser;
import love.sola.netsupport.wechat.Command; import love.sola.netsupport.wechat.Command;
import love.sola.netsupport.wechat.WxMpServlet; import love.sola.netsupport.wechat.WxMpServlet;
import me.chanjar.weixin.common.exception.WxErrorException; import me.chanjar.weixin.common.exception.WxErrorException;
import me.chanjar.weixin.common.session.WxSession;
import me.chanjar.weixin.mp.bean.WxMpCustomMessage; import me.chanjar.weixin.mp.bean.WxMpCustomMessage;
import org.hibernate.exception.ConstraintViolationException; import org.hibernate.exception.ConstraintViolationException;
@@ -32,14 +32,14 @@ import static love.sola.netsupport.util.Checker.*;
public class Register extends API { public class Register extends API {
public Register() { public Register() {
url = "/api/register"; url = "/register";
access = Access.GUEST; access = Access.GUEST;
authorize = Command.REGISTER; authorize = Command.REGISTER;
} }
@Override @Override
protected Object process(HttpServletRequest req, WxSession session) throws Exception { protected Object process(HttpServletRequest req, WxSession session) throws Exception {
String wechat = (String) session.getAttribute(Attribute.WECHAT); String wechat = session.getAttribute(Attribute.WECHAT);
if (wechat == null) { if (wechat == null) {
return Error.UNAUTHORIZED; return Error.UNAUTHORIZED;
} }

View File

@@ -5,9 +5,9 @@ import love.sola.netsupport.enums.Access;
import love.sola.netsupport.enums.Attribute; import love.sola.netsupport.enums.Attribute;
import love.sola.netsupport.pojo.Ticket; import love.sola.netsupport.pojo.Ticket;
import love.sola.netsupport.pojo.User; import love.sola.netsupport.pojo.User;
import love.sola.netsupport.session.WxSession;
import love.sola.netsupport.sql.SQLCore; import love.sola.netsupport.sql.SQLCore;
import love.sola.netsupport.wechat.Command; import love.sola.netsupport.wechat.Command;
import me.chanjar.weixin.common.session.WxSession;
import org.hibernate.Criteria; import org.hibernate.Criteria;
import org.hibernate.Session; import org.hibernate.Session;
import org.hibernate.criterion.Order; import org.hibernate.criterion.Order;
@@ -24,7 +24,7 @@ import javax.servlet.http.HttpServletRequest;
public class TicketQuery extends API { public class TicketQuery extends API {
public TicketQuery() { public TicketQuery() {
url = "/api/ticketquery"; url = "/ticketquery";
access = Access.USER; access = Access.USER;
authorize = Command.QUERY; authorize = Command.QUERY;
} }
@@ -32,7 +32,7 @@ public class TicketQuery extends API {
@Override @Override
protected Object process(HttpServletRequest req, WxSession session) throws Exception { protected Object process(HttpServletRequest req, WxSession session) throws Exception {
try (Session s = SQLCore.sf.openSession()) { try (Session s = SQLCore.sf.openSession()) {
User u = (User) session.getAttribute(Attribute.USER); User u = session.getAttribute(Attribute.USER);
Criteria c = s.createCriteria(Ticket.class); Criteria c = s.createCriteria(Ticket.class);
int first = req.getParameter("offset") == null ? 0 : Integer.parseInt(req.getParameter("offset")); int first = req.getParameter("offset") == null ? 0 : Integer.parseInt(req.getParameter("offset"));
int limit = req.getParameter("limit") == null ? 5 : Integer.parseInt(req.getParameter("limit")); int limit = req.getParameter("limit") == null ? 5 : Integer.parseInt(req.getParameter("limit"));

View File

@@ -7,10 +7,10 @@ import love.sola.netsupport.enums.Access;
import love.sola.netsupport.enums.Attribute; import love.sola.netsupport.enums.Attribute;
import love.sola.netsupport.pojo.Ticket; import love.sola.netsupport.pojo.Ticket;
import love.sola.netsupport.pojo.User; import love.sola.netsupport.pojo.User;
import love.sola.netsupport.session.WxSession;
import love.sola.netsupport.sql.SQLCore; import love.sola.netsupport.sql.SQLCore;
import love.sola.netsupport.sql.TableTicket; import love.sola.netsupport.sql.TableTicket;
import love.sola.netsupport.wechat.Command; import love.sola.netsupport.wechat.Command;
import me.chanjar.weixin.common.session.WxSession;
import org.hibernate.Session; import org.hibernate.Session;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
@@ -24,7 +24,7 @@ import javax.servlet.http.HttpServletRequest;
public class TicketSubmit extends API { public class TicketSubmit extends API {
public TicketSubmit() { public TicketSubmit() {
url = "/api/ticketsubmit"; url = "/ticketsubmit";
access = Access.USER; access = Access.USER;
authorize = Command.SUBMIT; authorize = Command.SUBMIT;
} }
@@ -40,7 +40,7 @@ public class TicketSubmit extends API {
} }
try (Session s = SQLCore.sf.openSession()) { try (Session s = SQLCore.sf.openSession()) {
User u = (User) session.getAttribute(Attribute.USER); User u = session.getAttribute(Attribute.USER);
if (TableTicket.hasOpen(u)) { if (TableTicket.hasOpen(u)) {
session.invalidate(); session.invalidate();
return Error.ALREADY_SUBMITTED; return Error.ALREADY_SUBMITTED;

View File

@@ -1,12 +1,11 @@
package love.sola.netsupport.auth; 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.util.Checker;
import love.sola.netsupport.wechat.WechatSession;
import love.sola.netsupport.wechat.WxMpServlet; import love.sola.netsupport.wechat.WxMpServlet;
import me.chanjar.weixin.common.session.WxSession;
import me.chanjar.weixin.mp.api.WxMpService; import me.chanjar.weixin.mp.api.WxMpService;
import me.chanjar.weixin.mp.bean.result.WxMpOAuth2AccessToken; import me.chanjar.weixin.mp.bean.result.WxMpOAuth2AccessToken;
import me.chanjar.weixin.mp.bean.result.WxMpUser;
import javax.servlet.AsyncContext; import javax.servlet.AsyncContext;
import javax.servlet.ServletException; import javax.servlet.ServletException;
@@ -15,6 +14,8 @@ import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import java.io.IOException; import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
/** /**
* *********************************************** * ***********************************************
@@ -22,9 +23,20 @@ import java.io.IOException;
* Don't modify this source without my agreement * Don't modify this source without my agreement
* *********************************************** * ***********************************************
*/ */
@WebServlet(name = "OAuth2", urlPatterns = "/oauth2/callback", loadOnStartup = 21) @WebServlet(name = "OAuth2", urlPatterns = "/oauth2/callback", loadOnStartup = 21, asyncSupported = true)
public class OAuth2 extends HttpServlet { public class OAuth2 extends HttpServlet {
private static Map<String, OAuth2Handler> oAuth2HandlerMap = new HashMap<>();
/**
* 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 @Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
AsyncContext acxt = req.startAsync(); AsyncContext acxt = req.startAsync();
@@ -34,13 +46,19 @@ public class OAuth2 extends HttpServlet {
resp.sendError(HttpServletResponse.SC_FORBIDDEN); resp.sendError(HttpServletResponse.SC_FORBIDDEN);
return; return;
} }
OAuth2Handler handler = oAuth2HandlerMap.get(state);
if (handler == null) {
resp.sendError(HttpServletResponse.SC_NOT_IMPLEMENTED);
return;
}
acxt.start(() -> { acxt.start(() -> {
try { try {
WxMpService wxMpService = WxMpServlet.instance.wxMpService; WxMpService wxMpService = WxMpServlet.instance.wxMpService;
WxMpOAuth2AccessToken token = wxMpService.oauth2getAccessToken(code); WxMpOAuth2AccessToken token = wxMpService.oauth2getAccessToken(code);
WxMpUser wxUser = wxMpService.oauth2getUserInfo(token, "zh_CN"); String wechat = token.getOpenId();
String sid = WechatSession.genId(); WxSession session = WechatSession.create();
WxSession session = WechatSession.get(sid, true); handler.onOAuth2(acxt, (HttpServletResponse) acxt.getResponse(), wechat, session);
acxt.complete();
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
} }

View File

@@ -0,0 +1,18 @@
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 acxt, HttpServletResponse resp, String user, WxSession session);
}

View File

@@ -0,0 +1,88 @@
/*
* 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

@@ -0,0 +1,85 @@
/*
* 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

@@ -0,0 +1,32 @@
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

@@ -0,0 +1,22 @@
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

@@ -5,6 +5,7 @@ import com.google.gson.annotations.Expose;
import com.google.gson.reflect.TypeToken; import com.google.gson.reflect.TypeToken;
import com.google.gson.stream.JsonReader; import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonWriter; import com.google.gson.stream.JsonWriter;
import com.mchange.v2.c3p0.ComboPooledDataSource;
import love.sola.netsupport.enums.ISP; import love.sola.netsupport.enums.ISP;
import love.sola.netsupport.wechat.Command; import love.sola.netsupport.wechat.Command;
import org.hibernate.Hibernate; import org.hibernate.Hibernate;
@@ -18,6 +19,7 @@ import org.hibernate.proxy.HibernateProxy;
import org.hibernate.service.ServiceRegistry; import org.hibernate.service.ServiceRegistry;
import javax.naming.InitialContext; import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.sql.DataSource; import javax.sql.DataSource;
import java.io.IOException; import java.io.IOException;
import java.util.Date; import java.util.Date;
@@ -30,7 +32,10 @@ import java.util.Date;
*/ */
public class SQLCore { public class SQLCore {
public static InitialContext ic;
public static DataSource ds; public static DataSource ds;
public static SessionFactory sf;
public static ServiceRegistry sr;
public static Gson gson = new GsonBuilder() public static Gson gson = new GsonBuilder()
.addSerializationExclusionStrategy(new ExclusionStrategy() { .addSerializationExclusionStrategy(new ExclusionStrategy() {
@Override @Override
@@ -64,12 +69,10 @@ public class SQLCore {
.registerTypeAdapter(Command.class, (JsonSerializer<Command>) (src, typeOfSrc, context) -> new JsonPrimitive(src.id)) .registerTypeAdapter(Command.class, (JsonSerializer<Command>) (src, typeOfSrc, context) -> new JsonPrimitive(src.id))
.registerTypeAdapterFactory(HibernateProxyTypeAdapter.FACTORY) .registerTypeAdapterFactory(HibernateProxyTypeAdapter.FACTORY)
.create(); .create();
public static SessionFactory sf;
public static ServiceRegistry sr;
static { static {
try { try {
InitialContext ic = new InitialContext(); ic = new InitialContext();
ds = (DataSource) ic.lookup("java:comp/env/jdbc/netsupport"); ds = (DataSource) ic.lookup("java:comp/env/jdbc/netsupport");
ds.setLoginTimeout(3); ds.setLoginTimeout(3);
@@ -83,6 +86,16 @@ public class SQLCore {
} }
} }
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) { public static AuditReader getAuditReader(Session session) {
return AuditReaderFactory.get(session); return AuditReaderFactory.get(session);
} }

View File

@@ -72,7 +72,7 @@ public class TableUser extends SQLCore {
private static LoadingCache<String, User> cache = CacheBuilder.newBuilder() private static LoadingCache<String, User> cache = CacheBuilder.newBuilder()
.concurrencyLevel(4) .concurrencyLevel(4)
.maximumSize(4096) .maximumSize(4096)
.expireAfterWrite(Settings.I.User_Wechat_Cache_Expire_Time, TimeUnit.SECONDS) .expireAfterAccess(Settings.I.User_Wechat_Cache_Expire_Time, TimeUnit.SECONDS)
.build(new ValueLoader()); .build(new ValueLoader());
private static class ValueLoader extends CacheLoader<String, User> { private static class ValueLoader extends CacheLoader<String, User> {

View File

@@ -1,13 +1,7 @@
package love.sola.netsupport.util; package love.sola.netsupport.util;
import love.sola.netsupport.enums.Attribute;
import love.sola.netsupport.enums.Block; import love.sola.netsupport.enums.Block;
import love.sola.netsupport.enums.ISP; 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;
/** /**
* *********************************************** * ***********************************************
@@ -25,13 +19,6 @@ public class Checker {
return false; 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) { public static long checkStudentId(String studentId) {
if (studentId == null) return -1; if (studentId == null) return -1;
if (studentId.matches(STUDENT_ID_REGEX)) { if (studentId.matches(STUDENT_ID_REGEX)) {

View File

@@ -3,7 +3,6 @@ package love.sola.netsupport.util;
import love.sola.netsupport.enums.Status; import love.sola.netsupport.enums.Status;
import love.sola.netsupport.pojo.Ticket; import love.sola.netsupport.pojo.Ticket;
import javax.servlet.http.HttpServletRequest;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import static love.sola.netsupport.config.Lang.lang; import static love.sola.netsupport.config.Lang.lang;
@@ -30,11 +29,4 @@ public class ParseUtil {
return sb.toString(); 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,5 +1,7 @@
package love.sola.netsupport.util; package love.sola.netsupport.util;
import com.google.common.net.UrlEscapers;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import java.io.IOException; import java.io.IOException;
@@ -13,15 +15,106 @@ import static love.sola.netsupport.config.Lang.lang;
*/ */
public class Redirect { public class Redirect {
public static final String REDIRECT_PAGE = lang("Result_Page"); private static final String REDIRECT_PAGE = lang("Result_Page");
private static final int SUCCESS = 1;
private static final int 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(i18nThenEscape(msg)).append("&");
return this;
}
public RedirectBuilder title(String title) {
sb.append("title=").append(i18nThenEscape(title)).append("&");
return this;
}
public RedirectBuilder noButton() {
sb.append("btn=").append("hide").append("&");
return this;
}
public RedirectBuilder button(String text) {
sb.append("btn=").append(i18nThenEscape(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(i18nThenEscape(url)).append("&");
return this;
}
public void go(HttpServletResponse resp) throws IOException {
resp.sendRedirect(sb.toString());
}
public String toString() {
return sb.toString();
}
private static String i18nThenEscape(String str) {
return UrlEscapers.urlFragmentEscaper().escape(lang(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 void message(HttpServletResponse response, int type, String message) throws IOException {
response.sendRedirect(
response.encodeRedirectURL(REDIRECT_PAGE +
"?msg=" + message +
"&type=" + type
)
);
} }
} }

View File

@@ -1,43 +0,0 @@
package love.sola.netsupport.wechat;
import love.sola.netsupport.config.Settings;
import me.chanjar.weixin.common.session.*;
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) {
WxSession session = manager.getSession(id, create);
if (session != null) {
((StandardSessionFacade) session).getInternalSession().endAccess();
}
return session;
}
public static WxSession get(String id) {
return get(id, true);
}
public static String genId() {
return UUID.randomUUID().toString();
}
public static InternalSession[] list() {
return manager.findSessions();
}
}

View File

@@ -1,6 +1,9 @@
package love.sola.netsupport.wechat; 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.config.Settings;
import love.sola.netsupport.sql.SQLCore;
import love.sola.netsupport.wechat.handler.RegisterHandler; import love.sola.netsupport.wechat.handler.RegisterHandler;
import love.sola.netsupport.wechat.handler.SubscribeHandler; import love.sola.netsupport.wechat.handler.SubscribeHandler;
import love.sola.netsupport.wechat.matcher.CheckSpamMatcher; import love.sola.netsupport.wechat.matcher.CheckSpamMatcher;
@@ -86,6 +89,9 @@ public class WxMpServlet extends HttpServlet {
WxMpMessageHandler handler = c.handler.newInstance(); WxMpMessageHandler handler = c.handler.newInstance();
router.rule().async(false).msgType(WxConsts.XML_MSG_TEXT).rContent(c.regex).handler(handler).end(); router.rule().async(false).msgType(WxConsts.XML_MSG_TEXT).rContent(c.regex).handler(handler).end();
router.rule().async(false).msgType(WxConsts.XML_MSG_EVENT).event(WxConsts.EVT_CLICK).eventKey(c.name()).handler(handler).end(); router.rule().async(false).msgType(WxConsts.XML_MSG_EVENT).event(WxConsts.EVT_CLICK).eventKey(c.name()).handler(handler).end();
if (handler instanceof OAuth2Handler) {
OAuth2.registerOAuth2Handler(c.name(), (OAuth2Handler) handler);
}
} }
} }
@@ -153,4 +159,8 @@ public class WxMpServlet extends HttpServlet {
doPost(req, resp); doPost(req, resp);
} }
@Override
public void destroy() {
SQLCore.destroy();
}
} }

View File

@@ -2,11 +2,11 @@ package love.sola.netsupport.wechat.handler;
import love.sola.netsupport.enums.Attribute; import love.sola.netsupport.enums.Attribute;
import love.sola.netsupport.pojo.User; 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.sql.TableUser;
import love.sola.netsupport.wechat.Command; import love.sola.netsupport.wechat.Command;
import love.sola.netsupport.wechat.WechatSession;
import me.chanjar.weixin.common.exception.WxErrorException; 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.common.session.WxSessionManager;
import me.chanjar.weixin.mp.api.WxMpMessageHandler; import me.chanjar.weixin.mp.api.WxMpMessageHandler;
import me.chanjar.weixin.mp.api.WxMpService; import me.chanjar.weixin.mp.api.WxMpService;
@@ -29,13 +29,12 @@ public class ProfileHandler implements WxMpMessageHandler {
@Override @Override
public WxMpXmlOutMessage handle(WxMpXmlMessage wxMessage, Map<String, Object> context, WxMpService wxMpService, WxSessionManager sessionManager) throws WxErrorException { public WxMpXmlOutMessage handle(WxMpXmlMessage wxMessage, Map<String, Object> context, WxMpService wxMpService, WxSessionManager sessionManager) throws WxErrorException {
User u = TableUser.getByWechat(wxMessage.getFromUserName()); User u = TableUser.getByWechat(wxMessage.getFromUserName());
String id = WechatSession.genId(); WxSession session = WechatSession.create();
WxSession session = WechatSession.get(id, true);
session.setAttribute(Attribute.AUTHORIZED, Command.PROFILE); session.setAttribute(Attribute.AUTHORIZED, Command.PROFILE);
session.setAttribute(Attribute.WECHAT, wxMessage.getFromUserName()); session.setAttribute(Attribute.WECHAT, wxMessage.getFromUserName());
session.setAttribute(Attribute.USER, u); session.setAttribute(Attribute.USER, u);
TextBuilder out = WxMpXmlOutMessage.TEXT().fromUser(wxMessage.getToUserName()).toUser(wxMessage.getFromUserName()); TextBuilder out = WxMpXmlOutMessage.TEXT().fromUser(wxMessage.getToUserName()).toUser(wxMessage.getFromUserName());
out.content(format("Profile_Modify", format("User_Profile_Link", id, u.getName(), u.getIsp().id, u.getNetAccount(), u.getBlock(), u.getRoom(), u.getPhone()))); out.content(format("Profile_Modify", format("User_Profile_Link", session.getId(), u.getName(), u.getIsp().id, u.getNetAccount(), u.getBlock(), u.getRoom(), u.getPhone())));
return out.build(); return out.build();
} }

View File

@@ -3,13 +3,13 @@ package love.sola.netsupport.wechat.handler;
import love.sola.netsupport.enums.Attribute; import love.sola.netsupport.enums.Attribute;
import love.sola.netsupport.pojo.Ticket; import love.sola.netsupport.pojo.Ticket;
import love.sola.netsupport.pojo.User; 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.TableTicket;
import love.sola.netsupport.sql.TableUser; import love.sola.netsupport.sql.TableUser;
import love.sola.netsupport.util.ParseUtil; import love.sola.netsupport.util.ParseUtil;
import love.sola.netsupport.wechat.Command; import love.sola.netsupport.wechat.Command;
import love.sola.netsupport.wechat.WechatSession;
import me.chanjar.weixin.common.exception.WxErrorException; 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.common.session.WxSessionManager;
import me.chanjar.weixin.mp.api.WxMpMessageHandler; import me.chanjar.weixin.mp.api.WxMpMessageHandler;
import me.chanjar.weixin.mp.api.WxMpService; import me.chanjar.weixin.mp.api.WxMpService;
@@ -40,8 +40,7 @@ public class QueryHandler implements WxMpMessageHandler {
return WxMpXmlOutMessage.TEXT().fromUser(wxMessage.getToUserName()).toUser(wxMessage.getFromUserName()) return WxMpXmlOutMessage.TEXT().fromUser(wxMessage.getToUserName()).toUser(wxMessage.getFromUserName())
.content(lang("No_Ticket_Available")).build(); .content(lang("No_Ticket_Available")).build();
} }
String id = WechatSession.genId(); WxSession session = WechatSession.create();
WxSession session = WechatSession.get(id, true);
session.setAttribute(Attribute.AUTHORIZED, Command.QUERY); session.setAttribute(Attribute.AUTHORIZED, Command.QUERY);
session.setAttribute(Attribute.WECHAT, wxMessage.getFromUserName()); session.setAttribute(Attribute.WECHAT, wxMessage.getFromUserName());
session.setAttribute(Attribute.USER, u); session.setAttribute(Attribute.USER, u);
@@ -50,7 +49,7 @@ public class QueryHandler implements WxMpMessageHandler {
WxMpXmlOutNewsMessage.Item item = new WxMpXmlOutNewsMessage.Item(); WxMpXmlOutNewsMessage.Item item = new WxMpXmlOutNewsMessage.Item();
item.setTitle(lang("Query_Title")); item.setTitle(lang("Query_Title"));
item.setDescription(ParseUtil.parseTicket(t) + "\n" + lang("More_Details")); item.setDescription(ParseUtil.parseTicket(t) + "\n" + lang("More_Details"));
item.setUrl(format("User_Query_Link", id)); item.setUrl(format("User_Query_Link", session.getId()));
out.addArticle(item); out.addArticle(item);
return out.build(); 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.enums.Attribute;
import love.sola.netsupport.pojo.User; 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.sql.TableUser;
import love.sola.netsupport.wechat.Command; import love.sola.netsupport.wechat.Command;
import love.sola.netsupport.wechat.WechatSession;
import me.chanjar.weixin.common.exception.WxErrorException; 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.common.session.WxSessionManager;
import me.chanjar.weixin.mp.api.WxMpMessageHandler; import me.chanjar.weixin.mp.api.WxMpMessageHandler;
import me.chanjar.weixin.mp.api.WxMpService; import me.chanjar.weixin.mp.api.WxMpService;
@@ -32,17 +32,16 @@ public class RegisterHandler implements WxMpMessageHandler {
TextBuilder out = WxMpXmlOutMessage.TEXT().fromUser(wxMessage.getToUserName()).toUser(wxMessage.getFromUserName()); TextBuilder out = WxMpXmlOutMessage.TEXT().fromUser(wxMessage.getToUserName()).toUser(wxMessage.getFromUserName());
String fromUser = wxMessage.getFromUserName(); String fromUser = wxMessage.getFromUserName();
User u = TableUser.getByWechat(fromUser); User u = TableUser.getByWechat(fromUser);
String id = WechatSession.genId(); WxSession session = WechatSession.create();
WxSession session = WechatSession.get(id, true);
if (u != null) { if (u != null) {
session.setAttribute(Attribute.AUTHORIZED, Command.PROFILE); session.setAttribute(Attribute.AUTHORIZED, Command.PROFILE);
session.setAttribute(Attribute.WECHAT, fromUser); session.setAttribute(Attribute.WECHAT, fromUser);
session.setAttribute(Attribute.USER, u); session.setAttribute(Attribute.USER, u);
out.content(format("Already_Registered", format("User_Profile_Link", id, u.getName(), u.getIsp().id, u.getNetAccount(), u.getBlock(), u.getRoom(), u.getPhone()))); out.content(format("Already_Registered", format("User_Profile_Link", session.getId(), u.getName(), u.getIsp().id, u.getNetAccount(), u.getBlock(), u.getRoom(), u.getPhone())));
} else { } else {
session.setAttribute(Attribute.AUTHORIZED, Command.REGISTER); session.setAttribute(Attribute.AUTHORIZED, Command.REGISTER);
session.setAttribute(Attribute.WECHAT, fromUser); session.setAttribute(Attribute.WECHAT, fromUser);
out.content(format("User_Register", format("User_Register_Link", id))); out.content(format("User_Register", format("User_Register_Link", session.getId())));
} }
return out.build(); 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.enums.Attribute;
import love.sola.netsupport.pojo.User; 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.TableTicket;
import love.sola.netsupport.sql.TableUser; import love.sola.netsupport.sql.TableUser;
import love.sola.netsupport.wechat.Command; import love.sola.netsupport.wechat.Command;
import love.sola.netsupport.wechat.WechatSession;
import me.chanjar.weixin.common.exception.WxErrorException; 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.common.session.WxSessionManager;
import me.chanjar.weixin.mp.api.WxMpMessageHandler; import me.chanjar.weixin.mp.api.WxMpMessageHandler;
import me.chanjar.weixin.mp.api.WxMpService; import me.chanjar.weixin.mp.api.WxMpService;
@@ -36,8 +36,7 @@ public class SubmitHandler implements WxMpMessageHandler {
return WxMpXmlOutMessage.TEXT().fromUser(wxMessage.getToUserName()).toUser(wxMessage.getFromUserName()) return WxMpXmlOutMessage.TEXT().fromUser(wxMessage.getToUserName()).toUser(wxMessage.getFromUserName())
.content(lang("Already_Opening_Ticket")).build(); .content(lang("Already_Opening_Ticket")).build();
} }
String id = WechatSession.genId(); WxSession session = WechatSession.create();
WxSession session = WechatSession.get(id, true);
session.setAttribute(Attribute.AUTHORIZED, Command.SUBMIT); session.setAttribute(Attribute.AUTHORIZED, Command.SUBMIT);
session.setAttribute(Attribute.WECHAT, wxMessage.getFromUserName()); session.setAttribute(Attribute.WECHAT, wxMessage.getFromUserName());
session.setAttribute(Attribute.USER, u); session.setAttribute(Attribute.USER, u);
@@ -46,7 +45,7 @@ public class SubmitHandler implements WxMpMessageHandler {
WxMpXmlOutNewsMessage.Item item = new WxMpXmlOutNewsMessage.Item(); WxMpXmlOutNewsMessage.Item item = new WxMpXmlOutNewsMessage.Item();
item.setTitle(lang("Submit_Title")); item.setTitle(lang("Submit_Title"));
item.setDescription(lang("Submit_Desc")); item.setDescription(lang("Submit_Desc"));
item.setUrl(format("User_Submit_Link", id, u.getName(), u.getIsp().id, u.getRoom(), u.getBlock(), u.getPhone())); item.setUrl(format("User_Submit_Link", session.getId(), u.getName(), u.getIsp().id, u.getRoom(), u.getBlock(), u.getPhone()));
out.addArticle(item); out.addArticle(item);
return out.build(); return out.build();
} }

View File

@@ -4,12 +4,12 @@ import love.sola.netsupport.api.user.Register;
import love.sola.netsupport.enums.Attribute; import love.sola.netsupport.enums.Attribute;
import love.sola.netsupport.pojo.Operator; import love.sola.netsupport.pojo.Operator;
import love.sola.netsupport.pojo.User; 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.TableOperator;
import love.sola.netsupport.sql.TableUser; import love.sola.netsupport.sql.TableUser;
import love.sola.netsupport.wechat.Command; import love.sola.netsupport.wechat.Command;
import love.sola.netsupport.wechat.WechatSession;
import me.chanjar.weixin.common.exception.WxErrorException; 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.common.session.WxSessionManager;
import me.chanjar.weixin.mp.api.WxMpMessageHandler; import me.chanjar.weixin.mp.api.WxMpMessageHandler;
import me.chanjar.weixin.mp.api.WxMpService; import me.chanjar.weixin.mp.api.WxMpService;
@@ -34,13 +34,12 @@ public class SubscribeHandler implements WxMpMessageHandler {
TextBuilder out = WxMpXmlOutMessage.TEXT().fromUser(wxMessage.getToUserName()).toUser(wxMessage.getFromUserName()); TextBuilder out = WxMpXmlOutMessage.TEXT().fromUser(wxMessage.getToUserName()).toUser(wxMessage.getFromUserName());
String fromUser = wxMessage.getFromUserName(); String fromUser = wxMessage.getFromUserName();
User u = TableUser.getByWechat(fromUser); User u = TableUser.getByWechat(fromUser);
String id = WechatSession.genId(); WxSession session = WechatSession.create();
WxSession session = WechatSession.get(id, true);
if (u != null) { if (u != null) {
session.setAttribute(Attribute.AUTHORIZED, Command.PROFILE); session.setAttribute(Attribute.AUTHORIZED, Command.PROFILE);
session.setAttribute(Attribute.WECHAT, fromUser); session.setAttribute(Attribute.WECHAT, fromUser);
session.setAttribute(Attribute.USER, u); session.setAttribute(Attribute.USER, u);
out.content(format("Event_Subscribe", format("Already_Registered", format("User_Profile_Link", id, u.getName(), u.getIsp().id, u.getNetAccount(), u.getBlock(), u.getRoom(), u.getPhone())))); out.content(format("Event_Subscribe", format("Already_Registered", format("User_Profile_Link", session.getId(), u.getName(), u.getIsp().id, u.getNetAccount(), u.getBlock(), u.getRoom(), u.getPhone()))));
Operator op = TableOperator.get(fromUser); Operator op = TableOperator.get(fromUser);
if (op != null) { if (op != null) {
@@ -51,7 +50,7 @@ public class SubscribeHandler implements WxMpMessageHandler {
} else { } else {
session.setAttribute(Attribute.AUTHORIZED, Command.REGISTER); session.setAttribute(Attribute.AUTHORIZED, Command.REGISTER);
session.setAttribute(Attribute.WECHAT, fromUser); session.setAttribute(Attribute.WECHAT, fromUser);
out.content(format("Event_Subscribe", format("User_Register", format("User_Register_Link", id)))); out.content(format("Event_Subscribe", format("User_Register", format("User_Register_Link", session.getId()))));
} }
return out.build(); return out.build();
} }

View File

@@ -1,13 +1,15 @@
package love.sola.netsupport.wechat.handler.admin; package love.sola.netsupport.wechat.handler.admin;
import love.sola.netsupport.auth.OAuth2Handler;
import love.sola.netsupport.enums.Access; import love.sola.netsupport.enums.Access;
import love.sola.netsupport.enums.Attribute; import love.sola.netsupport.enums.Attribute;
import love.sola.netsupport.pojo.Operator; 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.sql.TableOperator;
import love.sola.netsupport.util.Redirect;
import love.sola.netsupport.wechat.Command; import love.sola.netsupport.wechat.Command;
import love.sola.netsupport.wechat.WechatSession;
import me.chanjar.weixin.common.exception.WxErrorException; 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.common.session.WxSessionManager;
import me.chanjar.weixin.mp.api.WxMpMessageHandler; import me.chanjar.weixin.mp.api.WxMpMessageHandler;
import me.chanjar.weixin.mp.api.WxMpService; import me.chanjar.weixin.mp.api.WxMpService;
@@ -15,6 +17,8 @@ import me.chanjar.weixin.mp.bean.WxMpXmlMessage;
import me.chanjar.weixin.mp.bean.WxMpXmlOutMessage; import me.chanjar.weixin.mp.bean.WxMpXmlOutMessage;
import me.chanjar.weixin.mp.bean.outxmlbuilder.TextBuilder; import me.chanjar.weixin.mp.bean.outxmlbuilder.TextBuilder;
import javax.servlet.AsyncContext;
import javax.servlet.http.HttpServletResponse;
import java.util.Map; import java.util.Map;
import static love.sola.netsupport.config.Lang.format; import static love.sola.netsupport.config.Lang.format;
@@ -26,7 +30,7 @@ import static love.sola.netsupport.config.Lang.lang;
* Don't modify this source without my agreement * Don't modify this source without my agreement
* *********************************************** * ***********************************************
*/ */
public class LoginHandler implements WxMpMessageHandler { public class LoginHandler implements WxMpMessageHandler, OAuth2Handler {
@Override @Override
public WxMpXmlOutMessage handle(WxMpXmlMessage wxMessage, Map<String, Object> context, WxMpService wxMpService, WxSessionManager sessionManager) throws WxErrorException { public WxMpXmlOutMessage handle(WxMpXmlMessage wxMessage, Map<String, Object> context, WxMpService wxMpService, WxSessionManager sessionManager) throws WxErrorException {
@@ -38,14 +42,12 @@ public class LoginHandler implements WxMpMessageHandler {
else if (operator.getAccess() >= Access.NO_LOGIN) { else if (operator.getAccess() >= Access.NO_LOGIN) {
out.content(lang("No_Login")); out.content(lang("No_Login"));
} else { } else {
String id = WechatSession.genId(); WxSession session = WechatSession.create();
WxSession session = WechatSession.get(id, true);
session.setAttribute(Attribute.AUTHORIZED, Command.LOGIN); session.setAttribute(Attribute.AUTHORIZED, Command.LOGIN);
session.setAttribute(Attribute.WECHAT, wxMessage.getFromUserName()); session.setAttribute(Attribute.WECHAT, wxMessage.getFromUserName());
session.setAttribute(Attribute.OPERATOR, operator); session.setAttribute(Attribute.OPERATOR, operator);
out.content(format("Operator_Home_Page", id)); out.content(format("Home_Page_Msg", format("Operator_Home_Page", session.getId())));
} }
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
out.content(lang("Login_Error")); out.content(lang("Login_Error"));
@@ -53,4 +55,28 @@ public class LoginHandler implements WxMpMessageHandler {
return out.build(); return out.build();
} }
@Override
public void onOAuth2(AsyncContext acxt, HttpServletResponse resp, String user, WxSession session) {
try {
Operator operator = TableOperator.get(user);
if (operator == null) {
Redirect.error().icon(Redirect.WeUIIcon.WARN_SAFE).noButton()
.title("Not_Operator").msg("Not_Operator_OAuth2").go(resp);
return;
}
if (operator.getAccess() >= Access.NO_LOGIN) {
Redirect.error().icon(Redirect.WeUIIcon.WAITING).noButton()
.title("Left_Operator_Title").msg("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

@@ -43,15 +43,19 @@ Cancel_Failed: '取消失败。'
#Modify #Modify
Profile_Modify: '<a href="{0}">> 点此修改资料 <</a>' Profile_Modify: '<a href="{0}">> 点此修改资料 <</a>'
#Login #Login
Home_Page_Msg: '<a href="{0}">CLICK HERE</a>'
Not_Operator: '嘟嘟嘟……' Not_Operator: '嘟嘟嘟……'
Not_Operator_OAuth2: '看起来你并不是我们网维大家族的一员,但我们随时都欢迎你的加入哦!'
No_Login: 'Permission Denied.' No_Login: 'Permission Denied.'
Left_Operator_Title: '一路上有你'
Left_Operator: '网络维护科的茁壮成长离不开每一位成员的陪伴。一路上有你,感谢你对网络维护科的贡献!'
Internal_Error: '啊哦,登录失败了哦。' Internal_Error: '啊哦,登录失败了哦。'
#Operator_Info #Operator_Info
Operator_Info: | Operator_Info: |
网维成员资料: 网维成员资料:
网维ID: {0,number,#} 网维ID: {0,number,#}
姓名: {1} 姓名: {1}
岗位: {2,choice,0#'Administrator >ω<'|3#值班组长|6#正式成员|7#实习成员|} 岗位: {2,choice,0#'Administrator >ω<'|3#值班组长|6#正式成员|7#实习成员|9#'曾经的一员(TдT)'}
值班片区: {3,choice,0#'全图 >ω<'|1#岐头片区|2#北门片区|3#东门片区|4#香灰片区|5#凤翔片区} 值班片区: {3,choice,0#'全图 >ω<'|1#岐头片区|2#北门片区|3#东门片区|4#香灰片区|5#凤翔片区}
值班日: {4,choice,0#'2月30日 >ω<'|1#周一|2#周二|3#周三|4#周四|5#周五|6#周六|7#周日} 值班日: {4,choice,0#'2月30日 >ω<'|1#周一|2#周二|3#周三|4#周四|5#周五|6#周六|7#周日}
@@ -62,7 +66,7 @@ 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_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,#}' 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' Result_Page: 'http://topaz.sinaapp.com/nm/v2/result.html'
Operator_Home_Page: '<a href="http://topaz.sinaapp.com/nm/v2/man/home.html?token={0}">CLICK HERE</a>' 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}' Operator_Login_Page: 'http://topaz.sinaapp.com/nm/v2/man/login.html?pkey={0}'
#Localized #Localized

View File

@@ -34,9 +34,9 @@
"key": "OPERATOR_INFO" "key": "OPERATOR_INFO"
}, },
{ {
"type": "click", "type": "view",
"name": "后台登录", "name": "后台登录",
"key": "LOGIN" "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"
} }
] ]
} }

View File

@@ -0,0 +1,48 @@
<?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,34 +1,23 @@
package love.sola.netsupport.api; package love.sola.netsupport.api;
import com.google.common.reflect.ClassPath;
import org.junit.Test; import org.junit.Test;
import org.reflections.Reflections;
import java.io.IOException;
import java.util.Set; import java.util.Set;
/** /**
* *********************************************** * ***********************************************
* Created by Sola on 2014/8/20. * Created by Sola on 2016/3/26.
* Don't modify this source without my agreement * Don't modify this source without my agreement
* *********************************************** * ***********************************************
*/ */
public class ReflectionTest { public class ReflectionTest {
@Test @Test
public void test() throws IOException, IllegalAccessException, InstantiationException { public void test() {
int count = 0; Reflections reflections = new Reflections(getClass().getPackage().getName());
ClassPath path = ClassPath.from(getClass().getClassLoader()); Set<Class<? extends API>> set = reflections.getSubTypesOf(API.class);
Set<ClassPath.ClassInfo> classes = path.getTopLevelClassesRecursive(getClass().getPackage().getName()); assert set.size() == 14;
for (ClassPath.ClassInfo info : classes) {
Class<?> clz = info.load();
if (!API.class.equals(clz) && API.class.isAssignableFrom(clz)) {
System.out.println("Loading API: " + clz.getName());
API obj = (API) clz.newInstance();
System.out.println("Registered API: " + obj);
count++;
}
}
System.out.println("Total " + count + " API(s) loaded.");
} }
} }

View File

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

View File

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

View File

@@ -1,6 +1,5 @@
package love.sola.netsupport.wechat; package love.sola.netsupport.util;
import love.sola.netsupport.util.RSAUtil;
import org.apache.commons.codec.binary.Base64; import org.apache.commons.codec.binary.Base64;
import org.junit.Test; import org.junit.Test;
import org.mindrot.jbcrypt.BCrypt; import org.mindrot.jbcrypt.BCrypt;
@@ -16,7 +15,7 @@ import java.security.spec.X509EncodedKeySpec;
* Don't modify this source without my agreement * Don't modify this source without my agreement
* *********************************************** * ***********************************************
*/ */
public class TestEncrypt { public class EncryptTest {
@Test @Test
public void testBCrypt() { public void testBCrypt() {

View File

@@ -1,11 +1,9 @@
package love.sola.netsupport.wechat; package love.sola.netsupport.util;
import com.google.gson.*; import com.google.gson.*;
import love.sola.netsupport.config.Lang;
import love.sola.netsupport.enums.ISP; import love.sola.netsupport.enums.ISP;
import org.junit.Test; import org.junit.Test;
import java.text.MessageFormat;
import java.util.Date; import java.util.Date;
/** /**
@@ -14,12 +12,7 @@ import java.util.Date;
* Don't modify this source without my agreement * Don't modify this source without my agreement
* *********************************************** * ***********************************************
*/ */
public class TestMessageFormat { public class GsonTest {
@Test
public void testLang() {
assert Lang.messages != null;
}
@Test @Test
public void testJsonDate() { public void testJsonDate() {
@@ -35,14 +28,4 @@ public class TestMessageFormat {
assert gson.toJson(ISP.TELECOM).equals("1"); assert gson.toJson(ISP.TELECOM).equals("1");
} }
@Test
public void testLong() {
assert "15838838438".equals(MessageFormat.format("{0,number,#}", 15838838438L));
}
@Test
public void testOpInfo() {
assert !Lang.format("Operator_Info", 1541, "Sola", 0, 0, 4).isEmpty();
}
} }

View File

@@ -0,0 +1,34 @@
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,21 +0,0 @@
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);
}
}