From 5fcf87058d38dce9e824bd81faefd04be74ace9c Mon Sep 17 00:00:00 2001 From: pioneer Date: Fri, 23 Sep 2022 14:55:23 +0800 Subject: [PATCH] open --- README.md | 8 ++ doc/JSD-9853-需求确认书V1.docx | Bin 0 -> 60063 bytes plugin.xml | 31 +++++++ src/main/java/com/fr/plugin/AllOutHander.java | 12 +++ .../java/com/fr/plugin/LogMacDBAccess.java | 45 +++++++++ src/main/java/com/fr/plugin/LogMacFilter.java | 78 ++++++++++++++++ .../java/com/fr/plugin/LogMacFunction.java | 87 ++++++++++++++++++ .../plugin/MultiReadHttpServletRequest.java | 60 ++++++++++++ .../java/com/fr/plugin/beans/UserLogBean.java | 32 +++++++ src/main/java/com/fr/plugin/dao/LogDao.java | 15 +++ .../com/fr/plugin/dao/RelationLogDao.java | 15 +++ .../fr/plugin/entitys/AccessLogEntity.java | 59 ++++++++++++ .../fr/plugin/entitys/RelationLogEntity.java | 59 ++++++++++++ .../resources/com/fr/plugin/demo.properties | 1 + .../com/fr/plugin/demo_zh_CN.properties | 1 + 15 files changed, 503 insertions(+) create mode 100644 README.md create mode 100644 doc/JSD-9853-需求确认书V1.docx create mode 100644 plugin.xml create mode 100644 src/main/java/com/fr/plugin/AllOutHander.java create mode 100644 src/main/java/com/fr/plugin/LogMacDBAccess.java create mode 100644 src/main/java/com/fr/plugin/LogMacFilter.java create mode 100644 src/main/java/com/fr/plugin/LogMacFunction.java create mode 100644 src/main/java/com/fr/plugin/MultiReadHttpServletRequest.java create mode 100644 src/main/java/com/fr/plugin/beans/UserLogBean.java create mode 100644 src/main/java/com/fr/plugin/dao/LogDao.java create mode 100644 src/main/java/com/fr/plugin/dao/RelationLogDao.java create mode 100644 src/main/java/com/fr/plugin/entitys/AccessLogEntity.java create mode 100644 src/main/java/com/fr/plugin/entitys/RelationLogEntity.java create mode 100644 src/main/resources/com/fr/plugin/demo.properties create mode 100644 src/main/resources/com/fr/plugin/demo_zh_CN.properties diff --git a/README.md b/README.md new file mode 100644 index 0000000..34f51ff --- /dev/null +++ b/README.md @@ -0,0 +1,8 @@ + +# open-JSD- +9853 + +JSD-9934 记录请求访问的mac地址\ +免责说明:该源码为第三方爱好者提供,不保证源码和方案的可靠性,也不提供任何形式的源码教学指导和协助!\ +仅作为开发者学习参考使用!禁止用于任何商业用途!\ +为保护开发者隐私,开发者信息已隐去!若原开发者希望公开自己的信息,可联系【pioneer】处理。 \ No newline at end of file diff --git a/doc/JSD-9853-需求确认书V1.docx b/doc/JSD-9853-需求确认书V1.docx new file mode 100644 index 0000000000000000000000000000000000000000..fca62c7a1e98f42114061c3c752a408bf91bbbc0 GIT binary patch literal 60063 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 literal 0 HcmV?d00001 diff --git a/plugin.xml b/plugin.xml new file mode 100644 index 0000000..9667f94 --- /dev/null +++ b/plugin.xml @@ -0,0 +1,31 @@ + + + com.fr.plugin.sln3425 + + yes + 1.6.3 + 10.0 + 2019-03-10 + fr.open + + + [2019-6-4]项目启动

+

[2019-6-14]新增deviceName

+

[2022-03-18]修改拦截点 +

+ ]]> +
+ com.fr.plugin + + + + + + + + + + +
+ diff --git a/src/main/java/com/fr/plugin/AllOutHander.java b/src/main/java/com/fr/plugin/AllOutHander.java new file mode 100644 index 0000000..ee74616 --- /dev/null +++ b/src/main/java/com/fr/plugin/AllOutHander.java @@ -0,0 +1,12 @@ +package com.fr.plugin; + +import com.fr.decision.fun.HttpHandler; +import com.fr.decision.fun.impl.AbstractHttpHandlerProvider; + +public class AllOutHander extends AbstractHttpHandlerProvider { + @Override + public HttpHandler[] registerHandlers() { + return new HttpHandler[]{ + }; + } +} diff --git a/src/main/java/com/fr/plugin/LogMacDBAccess.java b/src/main/java/com/fr/plugin/LogMacDBAccess.java new file mode 100644 index 0000000..c24dec8 --- /dev/null +++ b/src/main/java/com/fr/plugin/LogMacDBAccess.java @@ -0,0 +1,45 @@ +package com.fr.plugin; + +import com.fr.plugin.dao.LogDao; +import com.fr.plugin.dao.RelationLogDao; +import com.fr.plugin.db.AbstractDBAccessProvider; +import com.fr.plugin.entitys.AccessLogEntity; +import com.fr.plugin.entitys.RelationLogEntity; +import com.fr.stable.db.accessor.DBAccessor; +import com.fr.stable.db.dao.BaseDAO; +import com.fr.stable.db.dao.DAOProvider; + +public class LogMacDBAccess extends AbstractDBAccessProvider { + private static DBAccessor accessor; + public static DBAccessor getAccessor() { + return accessor; + } + @Override + public DAOProvider[] registerDAO() { + return new DAOProvider[]{ + new DAOProvider() { + public Class getEntityClass() { + return RelationLogEntity.class; + } + + public Class getDAOClass() { + return LogDao.class; + } + }, + new DAOProvider() { + public Class getEntityClass() { + return AccessLogEntity.class; + } + + public Class getDAOClass() { + return RelationLogDao.class; + } + } + }; + } + + @Override + public void onDBAvailable(DBAccessor dbAccessor) { + accessor = dbAccessor; + } +} \ No newline at end of file diff --git a/src/main/java/com/fr/plugin/LogMacFilter.java b/src/main/java/com/fr/plugin/LogMacFilter.java new file mode 100644 index 0000000..4740232 --- /dev/null +++ b/src/main/java/com/fr/plugin/LogMacFilter.java @@ -0,0 +1,78 @@ +package com.fr.plugin; + +import com.fr.decision.fun.impl.AbstractGlobalRequestFilterProvider; +import com.fr.decision.webservice.v10.login.LoginService; +import com.fr.json.JSONObject; +import com.fr.log.FineLoggerFactory; +import com.fr.plugin.beans.UserLogBean; +import com.fr.plugin.entitys.RelationLogEntity; +import com.fr.stable.StringUtils; + +import javax.servlet.FilterChain; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.util.stream.Collectors; + +public class LogMacFilter extends AbstractGlobalRequestFilterProvider { + @Override + public String filterName() { + return "logMac"; + } + + @Override + public String[] urlPatterns() { + return new String[]{ + "/decision/login", + "/decision/v10/entry/access/*" + }; + } + + @Override + public void doFilter(HttpServletRequest req, HttpServletResponse res, FilterChain filterChain) { + try { + MultiReadHttpServletRequest request = new MultiReadHttpServletRequest(req); + LogMacFunction myFunction = new LogMacFunction(); + String uri = req.getRequestURI(); + if (uri.contains("v10/entry/access")) { + String terminal = req.getHeader("terminal"); + String op = req.getParameter("op"); + String cmd = req.getParameter("cmd"); + if ("APP".equals(terminal) && StringUtils.equals(op, "fs_main") && StringUtils.equals(cmd, "entry_report")) { + String name = LoginService.getInstance().getCurrentUserNameFromRequest(request); + RelationLogEntity relation = myFunction.findRelation(name); + if (relation != null) { + myFunction.addLoginHistory(relation); + FineLoggerFactory.getLogger().info("login app access log success " + relation.getUserName() + " " + relation.getMacAddr()); + } else { + FineLoggerFactory.getLogger().info("login not find mac relation"); + } + } + } else { + if ("POST".equalsIgnoreCase(req.getMethod())) { + String terminal = req.getHeader("terminal"); + if ("APP".equals(terminal)) { + String body = request.getReader().lines().collect(Collectors.joining(System.lineSeparator())); + JSONObject json = new JSONObject(body); + UserLogBean bean = new UserLogBean(); + if (json.has("username")) { + bean.setName(json.getString("username")); + } + if (json.has("deviceName")) { + bean.setDeviceName(json.getString("deviceName")); + } + if (json.has("macAddress")) { + bean.setMac(json.getString("macAddress")); + } + + myFunction.save(bean); + } + FineLoggerFactory.getLogger().info("login with" + req.getHeaderNames()); + } + } + filterChain.doFilter(request, res); + } catch (Exception e) { + e.printStackTrace(); + FineLoggerFactory.getLogger().error(e.getMessage(), e); + } + } +} diff --git a/src/main/java/com/fr/plugin/LogMacFunction.java b/src/main/java/com/fr/plugin/LogMacFunction.java new file mode 100644 index 0000000..d0c05b0 --- /dev/null +++ b/src/main/java/com/fr/plugin/LogMacFunction.java @@ -0,0 +1,87 @@ +package com.fr.plugin; + +import com.fr.plugin.beans.UserLogBean; +import com.fr.plugin.dao.LogDao; +import com.fr.plugin.dao.RelationLogDao; +import com.fr.plugin.entitys.AccessLogEntity; +import com.fr.plugin.entitys.RelationLogEntity; +import com.fr.plugin.transform.ExecuteFunctionRecord; +import com.fr.plugin.transform.FunctionRecorder; +import com.fr.stable.db.accessor.DBAccessor; +import com.fr.stable.db.action.DBAction; +import com.fr.stable.db.dao.DAOContext; +import com.fr.stable.query.QueryFactory; +import com.fr.stable.query.condition.QueryCondition; +import com.fr.stable.query.restriction.RestrictionFactory; +import com.fr.third.org.apache.commons.lang3.time.DateFormatUtils; + +import java.util.Date; +import java.util.List; +import java.util.UUID; + +@FunctionRecorder(localeKey = "logmac") +public class LogMacFunction { + @ExecuteFunctionRecord + public void save(UserLogBean bean) throws Exception { + DBAccessor accessor = LogMacDBAccess.getAccessor(); + RelationLogEntity logEntity = new RelationLogEntity(); + logEntity.setTime(DateFormatUtils.format(new Date(), "yyyy-MM-dd HH:mm:ss")); + logEntity.setMacAddr(bean.getMac()); + logEntity.setUserName(bean.getName()); + logEntity.setDeviceName(bean.getDeviceName()); + logEntity.setId(UUID.randomUUID().toString()); + final RelationLogEntity count = accessor.runQueryAction(new DBAction() { + public RelationLogEntity run(DAOContext content) throws Exception { + QueryCondition queryCondition = QueryFactory.create(); + queryCondition.addRestriction(RestrictionFactory.eq("userName", logEntity.getUserName())); + return content.getDAO(RelationLogDao.class).findOne(queryCondition); + } + }); + accessor.runDMLAction(new DBAction() { + public RelationLogEntity run(DAOContext content) throws Exception { + if (count != null) { + count.setMacAddr(bean.getMac()); + count.setDeviceName(bean.getDeviceName()); + content.getDAO(RelationLogDao.class).update(count); + } else { + content.getDAO(RelationLogDao.class).add(logEntity); + } + return null; + } + }); + } + + public RelationLogEntity findRelation(String name) throws Exception { + DBAccessor accessor = LogMacDBAccess.getAccessor(); + return accessor.runQueryAction(new DBAction() { + public RelationLogEntity run(DAOContext content) throws Exception { + QueryCondition queryCondition = QueryFactory.create(); + queryCondition.addRestriction(RestrictionFactory.eq("userName", name)); + return content.getDAO(RelationLogDao.class).findOne(queryCondition); + } + }); + } + + public void addLoginHistory(RelationLogEntity relation) throws Exception { + AccessLogEntity logEntity = new AccessLogEntity(); + logEntity.setMacAddr(relation.getMacAddr()); + logEntity.setUserName(relation.getUserName()); + logEntity.setDeviceName(relation.getDeviceName()); + logEntity.setId(UUID.randomUUID().toString()); + logEntity.setTime(DateFormatUtils.format(new Date(), "yyyy-MM-dd")); + DBAccessor accessor = LogMacDBAccess.getAccessor(); + accessor.runDMLAction(new DBAction() { + public RelationLogEntity run(DAOContext content) throws Exception { + LogDao dao = content.getDAO(LogDao.class); + QueryCondition queryCondition = QueryFactory.create(); + queryCondition.addRestriction(RestrictionFactory.eq("time", logEntity.getTime())).addRestriction(RestrictionFactory.eq("macAddr", logEntity.getMacAddr())).addRestriction(RestrictionFactory.eq("userName", logEntity.getUserName())); + List accessLogEntities = dao.find(queryCondition); + //如果不存在则插入,保障一天,一个用户,一个MAC只插入1条 + if (accessLogEntities.isEmpty()) { + dao.add(logEntity); + } + return null; + } + }); + } +} diff --git a/src/main/java/com/fr/plugin/MultiReadHttpServletRequest.java b/src/main/java/com/fr/plugin/MultiReadHttpServletRequest.java new file mode 100644 index 0000000..9e11176 --- /dev/null +++ b/src/main/java/com/fr/plugin/MultiReadHttpServletRequest.java @@ -0,0 +1,60 @@ +package com.fr.plugin; + +import javax.servlet.ReadListener; +import javax.servlet.ServletInputStream; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletRequestWrapper; +import java.io.BufferedReader; +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.InputStreamReader; + +/** + * 二次封装请求,避免获取了body之后,无法继续处理请求 + */ +public class MultiReadHttpServletRequest extends HttpServletRequestWrapper { + public String _body; + + public MultiReadHttpServletRequest(HttpServletRequest request) throws IOException { + super(request); + StringBuffer sBuffer = new StringBuffer(); + BufferedReader bufferedReader = request.getReader(); + String line; + while ((line = bufferedReader.readLine()) != null) { + sBuffer.append(line); + } + _body = sBuffer.toString(); + + } + + @Override + public ServletInputStream getInputStream() { + final ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(_body.getBytes()); + return new ServletInputStream() { + @Override + public int read() { + return byteArrayInputStream.read(); + } + + @Override + public boolean isFinished() { + return false; + } + + @Override + public boolean isReady() { + return false; + } + + @Override + public void setReadListener(ReadListener listener) { + + } + }; + } + + @Override + public BufferedReader getReader() { + return new BufferedReader(new InputStreamReader(this.getInputStream())); + } +} diff --git a/src/main/java/com/fr/plugin/beans/UserLogBean.java b/src/main/java/com/fr/plugin/beans/UserLogBean.java new file mode 100644 index 0000000..7cb9cf5 --- /dev/null +++ b/src/main/java/com/fr/plugin/beans/UserLogBean.java @@ -0,0 +1,32 @@ +package com.fr.plugin.beans; + +import java.io.Serializable; + +public class UserLogBean implements Serializable { + private String name; + private String mac; + private String deviceName; + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getMac() { + return mac; + } + + public void setMac(String mac) { + this.mac = mac; + } + + public String getDeviceName() { + return deviceName; + } + + public void setDeviceName(String deviceName) { + this.deviceName = deviceName; + } +} diff --git a/src/main/java/com/fr/plugin/dao/LogDao.java b/src/main/java/com/fr/plugin/dao/LogDao.java new file mode 100644 index 0000000..fd46232 --- /dev/null +++ b/src/main/java/com/fr/plugin/dao/LogDao.java @@ -0,0 +1,15 @@ +package com.fr.plugin.dao; + +import com.fr.plugin.entitys.AccessLogEntity; +import com.fr.stable.db.dao.BaseDAO; +import com.fr.stable.db.session.DAOSession; + +public class LogDao extends BaseDAO { + public LogDao(DAOSession daoSession) { + super(daoSession); + } + + protected Class getEntityClass() { + return AccessLogEntity.class; + } +} diff --git a/src/main/java/com/fr/plugin/dao/RelationLogDao.java b/src/main/java/com/fr/plugin/dao/RelationLogDao.java new file mode 100644 index 0000000..949f816 --- /dev/null +++ b/src/main/java/com/fr/plugin/dao/RelationLogDao.java @@ -0,0 +1,15 @@ +package com.fr.plugin.dao; + +import com.fr.plugin.entitys.RelationLogEntity; +import com.fr.stable.db.dao.BaseDAO; +import com.fr.stable.db.session.DAOSession; + +public class RelationLogDao extends BaseDAO { + public RelationLogDao(DAOSession daoSession) { + super(daoSession); + } + + protected Class getEntityClass() { + return RelationLogEntity.class; + } +} diff --git a/src/main/java/com/fr/plugin/entitys/AccessLogEntity.java b/src/main/java/com/fr/plugin/entitys/AccessLogEntity.java new file mode 100644 index 0000000..9f8ef3f --- /dev/null +++ b/src/main/java/com/fr/plugin/entitys/AccessLogEntity.java @@ -0,0 +1,59 @@ +package com.fr.plugin.entitys; + +import com.fr.stable.db.entity.BaseEntity; +import com.fr.stable.db.entity.TableAssociation; +import com.fr.third.javax.persistence.Column; +import com.fr.third.javax.persistence.Entity; +import com.fr.third.javax.persistence.Table; + +@Entity +@Table( + name = "fine_access_log" +) +@TableAssociation( + associated = true +) +public class AccessLogEntity extends BaseEntity { + @Column(name = "userName") + private String userName = ""; + @Column(name = "macAddr") + private String macAddr = ""; + @Column(name = "deviceName") + private String deviceName = ""; + @Column(name = "createTime") + private String time = ""; + + public String getDeviceName() { + return deviceName; + } + + public void setDeviceName(String deviceName) { + this.deviceName = deviceName; + } + + public String getUserName() { + return userName; + } + + public void setUserName(String userName) { + this.userName = userName; + } + + public String getMacAddr() { + return macAddr; + } + + public void setMacAddr(String macAddr) { + this.macAddr = macAddr; + } + + + + public String getTime() { + return time; + } + + public void setTime(String time) { + this.time = time; + } +} diff --git a/src/main/java/com/fr/plugin/entitys/RelationLogEntity.java b/src/main/java/com/fr/plugin/entitys/RelationLogEntity.java new file mode 100644 index 0000000..9a2c02c --- /dev/null +++ b/src/main/java/com/fr/plugin/entitys/RelationLogEntity.java @@ -0,0 +1,59 @@ +package com.fr.plugin.entitys; + +import com.fr.stable.db.entity.BaseEntity; +import com.fr.stable.db.entity.TableAssociation; +import com.fr.third.javax.persistence.Column; +import com.fr.third.javax.persistence.Entity; +import com.fr.third.javax.persistence.Table; + +import java.util.Date; + +@Entity +@Table( + name = "fine_user_mac_relation" +) +@TableAssociation( + associated = true +) +public class RelationLogEntity extends BaseEntity { + @Column(name = "userName") + private String userName = ""; + @Column(name = "macAddr") + private String macAddr = ""; + @Column(name = "deviceName") + private String deviceName = ""; + @Column(name = "createTime") + private String time = ""; + + public String getUserName() { + return userName; + } + + public void setUserName(String userName) { + this.userName = userName; + } + + public String getMacAddr() { + return macAddr; + } + + public void setMacAddr(String macAddr) { + this.macAddr = macAddr; + } + + public String getDeviceName() { + return deviceName; + } + + public void setDeviceName(String deviceName) { + this.deviceName = deviceName; + } + + public String getTime() { + return time; + } + + public void setTime(String time) { + this.time = time; + } +} diff --git a/src/main/resources/com/fr/plugin/demo.properties b/src/main/resources/com/fr/plugin/demo.properties new file mode 100644 index 0000000..9bc5f29 --- /dev/null +++ b/src/main/resources/com/fr/plugin/demo.properties @@ -0,0 +1 @@ +Plugin-Test_Function_Abs=Test ABS \ No newline at end of file diff --git a/src/main/resources/com/fr/plugin/demo_zh_CN.properties b/src/main/resources/com/fr/plugin/demo_zh_CN.properties new file mode 100644 index 0000000..aa910e8 --- /dev/null +++ b/src/main/resources/com/fr/plugin/demo_zh_CN.properties @@ -0,0 +1 @@ +Plugin-Test_Function_Abs=测试ABS函数 \ No newline at end of file