Skip to content
This repository has been archived by the owner on Dec 4, 2023. It is now read-only.

Commit

Permalink
support form validation
Browse files Browse the repository at this point in the history
  • Loading branch information
GCS-ZHN committed Apr 6, 2022
1 parent 2dd7ab3 commit 7cfdc69
Show file tree
Hide file tree
Showing 9 changed files with 127 additions and 18 deletions.
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,8 @@ Fork本项目,在fork后的仓库里”Setttings > Secrets > Actions > New rep
若打卡题目被更新或者你的任何信息情况有变化(如返校),请先手动打卡一次。本项目仅供学习参考。使用时请确保信息的正确性。滥用造成的后果请自行承担。

## 更新记录
### v1.4.3
支持对健康打卡进行表单数据校验,检测健康打卡表单是否更新,当表单校验不通过,意味着健康打卡已经更新,请清除数据缓存`autocard_cache.json`文件并重启打卡程序。例如2022年4月6日浙江大学对表单有所更新。

### v1.4.2
修复了多用户立即打卡时,后续用户无效的问题。支持了通过系统环境变量来配置打卡用户。
Expand Down
Binary file modified action/autocard.jar
Binary file not shown.
3 changes: 2 additions & 1 deletion config/application.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,5 +23,6 @@
"cron":"0 10 0 * * ? *",
"delay":true
}
]
],
"formvalidation": true
}
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

<groupId>org.gcszhn</groupId>
<artifactId>autocard</artifactId>
<version>1.4.2</version>
<version>1.4.3</version>
<packaging>jar</packaging>

<name>Auto Heathy Report for Zhejiang University</name>
Expand Down
57 changes: 49 additions & 8 deletions src/main/java/org/gcszhn/autocard/AppConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,12 @@
package org.gcszhn.autocard;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;

Expand All @@ -43,20 +45,29 @@
public class AppConfig implements EnvironmentAware {
/**默认字符集 */
public static final Charset APP_CHARSET = StandardCharsets.UTF_8;
/**APP缓存文件 */
private static final String APP_CACHE = "autocard_cache.json";
/**应用缓存 */
private JSONObject appCache;
/**JSON配置文件 */
private JSONObject jsonConfig;
private JSONObject appConfig;
/**是否为测试模式 */
private @Getter boolean testMode = false;
public AppConfig() {
LogUtils.printMessage("Test mode is " + testMode, LogUtils.Level.DEBUG);
try (FileInputStream fis = new FileInputStream(APP_CACHE)) {
appCache = JSON.parseObject(new String(fis.readAllBytes(), APP_CHARSET));
} catch (Exception e) {
appCache = new JSONObject();
}
}
/**
* SpringBoot 2.x无法在Configuration中使用@Value,因此需要获取springboot环境
*/
@Override
public void setEnvironment(Environment env) {
loadJSONConfig(env.getProperty("app.autoCard.config"));
testMode = jsonConfig.getBooleanValue("testmode");
testMode = appConfig.getBooleanValue("testmode");

// 通过系统环境变量添加单个打卡用户

Expand All @@ -71,7 +82,7 @@ public void setEnvironment(Environment env) {
global_user.put("dingtalkurl", System.getenv("AUTOCARD_DINGTALK_URL"));
global_user.put("dingtalksecret", System.getenv("AUTOCARD_DINGTALK_SECRET"));
global_user.put("delay", System.getenv("AUTOCARD_DELAY") != null);
jsonConfig.getJSONArray("jobs").add(global_user);
appConfig.getJSONArray("jobs").add(global_user);
}

}
Expand All @@ -91,11 +102,11 @@ public void loadJSONConfig(String configSource) {
jsonString = configSource.substring(7);
}
if (jsonString != null) {
jsonConfig = JSONObject.parseObject(jsonString);
appConfig = JSONObject.parseObject(jsonString);
LogUtils.printMessage("用户配置已加载");
} else {
jsonConfig = new JSONObject();
jsonConfig.put("jobs", new JSONArray());
appConfig = new JSONObject();
appConfig.put("jobs", new JSONArray());
}
}
catch (Exception e) {
Expand All @@ -111,7 +122,7 @@ public void loadJSONConfig(String configSource) {
*/
@Bean
public MailService registerMailService(ConfigurableEnvironment env) {
JSONObject mailConfig = jsonConfig.getJSONObject("mail");
JSONObject mailConfig = appConfig.getJSONObject("mail");
MailService mailService = new MailService();
if (mailConfig != null){
String nickname = mailConfig.getString("nickname");
Expand All @@ -133,7 +144,37 @@ public MailService registerMailService(ConfigurableEnvironment env) {
* @return 用户任务
*/
public JSONArray getUserJobs() {
JSONArray jsonArray = jsonConfig.getJSONArray("jobs");
JSONArray jsonArray = appConfig.getJSONArray("jobs");
return jsonArray==null?new JSONArray():jsonArray;
}

public void addCacheItem(String key, Object value) {
appCache.put(key, value);
cache();
}

public <T> T getCacheItem(String key, Class<T> type) {
return appCache.getObject(key, type);
}

public String getCacheItem(String key) {
return appCache.getObject(key, String.class);
}

public void removeCacheItem(String key) {
appCache.remove(key);
cache();
}

public void cache() {
try {
JSON.writeJSONString(new FileOutputStream(APP_CACHE), APP_CHARSET, appCache);
} catch (Exception e) {
LogUtils.printMessage("保存缓存失败", LogUtils.Level.ERROR);
}
}

public <T> T getConfigItem(String key, Class<T> type) {
return appConfig.getObject(key, type);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ public static void execute(
}
}
} catch (Exception e) {
e.printStackTrace();
LogUtils.printMessage(e.getMessage(), LogUtils.Level.ERROR);
}
}
Expand Down
66 changes: 61 additions & 5 deletions src/main/java/org/gcszhn/autocard/service/ClockinService.java
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,13 @@

import org.apache.http.NameValuePair;
import org.apache.http.message.BasicNameValuePair;
import org.gcszhn.autocard.AppConfig;
import org.gcszhn.autocard.utils.DigestUtils;
import org.gcszhn.autocard.utils.LogUtils;
import org.gcszhn.autocard.utils.StatusCode;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Scope;
Expand All @@ -41,6 +46,10 @@
@Scope("prototype")
@Service
public class ClockinService implements Closeable {
/**时间格式化 */
private static final SimpleDateFormat SDF = new SimpleDateFormat("yyyyMMdd");
/**表达校验数据缓存关键字 */
private static final String FORM_MD5_VALUE= "FORM_MD5_VALUE";
/**打卡信息网址 */
@Value("${app.autoCard.reportUrl}")
/**打卡提交网址 */
Expand All @@ -50,8 +59,9 @@ public class ClockinService implements Closeable {
/**浙大通行证客户端 */
@Autowired
private ZJUClientService client;
/**时间格式化 */
private SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
/**应用配置实例 */
@Autowired
private AppConfig appConfig;
/**
* 用于访问打卡页面
* @param username 用户名
Expand All @@ -60,10 +70,55 @@ public class ClockinService implements Closeable {
*/
public String getPage(String username, String password) {
if(client.login(username, password)) {
return client.doGetText(reportUrl);
String page1 = client.doGetText(reportUrl);
Boolean formvalidation = appConfig.getConfigItem("formvalidation", Boolean.class);
if (formvalidation!=null && !formvalidation) {
return page1;
}
String page2 = client.doGetText(reportUrl);
boolean page1Flag = formValidation(page1);
boolean page2Flag = formValidation(page2);
if ( page1Flag == (page1!=null) && page2Flag == (page2!=null)) {
LogUtils.printMessage("表单校验通过", LogUtils.Level.INFO);
return page1;
} else if (page1 != null && page2 != null && page1Flag != page2Flag) {
// 意味着两次获取的页面表单是变化的,无法作为校验依据
LogUtils.printMessage("表单校验功能失效,已忽略校验,请联系作者", LogUtils.Level.ERROR);
return page1;
} else {
LogUtils.printMessage("表单校验失败,请检查健康打卡页面是否更新或等待一会再次尝试,若更新请删除缓存文件并重启打卡程序", LogUtils.Level.ERROR);
}
}
return null;
}
/**
* 表单数据的MD5校验,浙大健康打卡时常更新,但后端验证不够及时,因此进行前端验证
* @param html 表单的html页面
* @return true为验证通过
*/
public boolean formValidation(String html) {
try {
if (html != null) {
Document document = Jsoup.parse(html);
Element form = document.getElementsByClass("form-detail2").last();
if (form != null) {
String digest = DigestUtils.digest(form.html(), "MD5");
if (appConfig.getCacheItem(FORM_MD5_VALUE) == null) {
appConfig.addCacheItem(FORM_MD5_VALUE, digest);
}
if (appConfig.getCacheItem(FORM_MD5_VALUE).equals(digest)) {
return true;
}
} else {
LogUtils.printMessage("未捕获表单信息,捕获信息如下", LogUtils.Level.ERROR);
System.out.println(html);
}
}
} catch (Exception e) {
LogUtils.printMessage(e.getMessage(), e, LogUtils.Level.ERROR);
}
return false;
}
/**
* 用于提取已有提交信息
* @param username 用户名
Expand Down Expand Up @@ -107,7 +162,7 @@ public ArrayList<NameValuePair> getOldInfo(String username, String password) {
infoJsonObject1.putAll(oldInfoJson);
infoJsonObject1.forEach((String name, Object value)->{
switch (name) {
case "date" : value=sdf.format(new Date());break;
case "date" : value=SDF.format(new Date());break;
case "bztcyy": value="";break; //地区变更需要手动打卡一次,过滤上一次的地区变更原因
}
// fix bug for "是否从下列地区返回浙江错误"
Expand Down Expand Up @@ -135,7 +190,7 @@ public StatusCode submit(String username, String password) {
ArrayList<NameValuePair> info = getOldInfo(username, password);
if (info==null) {
LogUtils.printMessage("打卡信息获取失败", LogUtils.Level.ERROR);
statusCode.setMessage(username+", 打卡信息获取失败");
statusCode.setMessage(username+"的打卡信息获取失败,可能是打卡更新了或网络不稳定,请查看后台打卡日志输出");
statusCode.setStatus(-1);
return statusCode;
}
Expand Down Expand Up @@ -163,6 +218,7 @@ public StatusCode submit(String username, String password) {
public void close() {
try {
client.close();

} catch (Exception e) {
LogUtils.printMessage(null, e, LogUtils.Level.ERROR);
}
Expand Down
4 changes: 2 additions & 2 deletions src/test/java/org/gcszhn/autocard/AppTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,6 @@
@RunWith(SpringRunner.class)
@SpringBootTest
public abstract class AppTest {
protected static final String trueZjuPassPortUser = "***";
protected static final String trueZjuPassPortPass = "***";
protected static final String trueZjuPassPortUser = "****";
protected static final String trueZjuPassPortPass = "****";
}
10 changes: 9 additions & 1 deletion src/test/java/org/gcszhn/autocard/AutoClockinTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,15 @@ public void afterTest() {
}
@Test
public void getPageTest() {
Assert.assertNotNull(autoCard.getPage(trueZjuPassPortUser, trueZjuPassPortPass));
try {
for (int i = 0; i < 2; i++) {
String page = autoCard.getPage(trueZjuPassPortUser, trueZjuPassPortPass);
Assert.assertNotNull(page);
Assert.assertTrue(autoCard.formValidation(page));
}
} catch (Exception e) {
e.printStackTrace();
}
}
@Test
public void getOldInfoTest() {
Expand Down

0 comments on commit 7cfdc69

Please sign in to comment.