commit 65480b16a0d7c45383168a1acfddc8f2e0792274 Author: onlyxx Date: Thu Jan 21 20:51:31 2021 +0800 first commit diff --git a/build.gradle b/build.gradle new file mode 100644 index 0000000..1f720d8 --- /dev/null +++ b/build.gradle @@ -0,0 +1,132 @@ +apply plugin: 'java' + + +ext { + /** + * 项目中依赖的jar的路径 + * 1.如果依赖的jar需要打包到zip中,放置在lib根目录下 + * 2.如果依赖的jar仅仅是编译时需要,防止在lib下子目录下即可 + */ + libPath = "$projectDir/../webroot/WEB-INF/lib" + + /** + * 是否对插件的class进行加密保护,防止反编译 + */ + guard = true + + def pluginInfo = getPluginInfo() + pluginPre = "fine-plugin" + pluginName = pluginInfo.id + pluginVersion = pluginInfo.version + + outputPath = "$projectDir/../webroot/WEB-INF/plugins/plugin-" + pluginName + "-1.0/classes" +} + +group = 'com.fr.plugin' +version = '10.0' +sourceCompatibility = '8' + +sourceSets { + main { + java.outputDir = file(outputPath) + output.resourcesDir = file(outputPath) + } +} + +ant.importBuild("encrypt.xml") +//定义ant变量 +ant.projectDir = projectDir +ant.references["compile.classpath"] = ant.path { + fileset(dir: libPath, includes: '**/*.jar') + fileset(dir: ".", includes: "**/*.jar") +} + +tasks.withType(JavaCompile) { + options.encoding = "UTF-8" +} + +classes.dependsOn('clean') + +task copyFiles(type: Copy, dependsOn: 'classes') { + from outputPath + into "$projectDir/classes" +} + +task preJar(type: Copy, dependsOn: guard ? 'compile_encrypt_javas' : 'compile_plain_javas') { + from "$projectDir/classes" + into "$projectDir/transform-classes" + include "**/*.*" +} +jar.dependsOn("preJar") +classes.dependsOn("copyPluginXML") + +task copyPluginXML(type: Copy) { + print "copyed plugin.xml file" + from "$projectDir/plugin.xml" + into file("$projectDir/../webroot/WEB-INF/plugins/plugin-" + pluginName + "-1.0/") +} +task makeJar(type: Jar, dependsOn: preJar) { + from fileTree(dir: "$projectDir/transform-classes") + baseName pluginPre + appendix pluginName + version pluginVersion + destinationDir = file("$buildDir/libs") + + doLast() { + delete file("$projectDir/classes") + delete file("$projectDir/transform-classes") + } +} + +task copyFile(type: Copy, dependsOn: ["makeJar"]) { + from "$buildDir/libs" + from("$projectDir/lib") { + include "*.jar" + } + from "$projectDir/plugin.xml" + into file("$buildDir/temp/plugin") +} + +task zip(type: Zip, dependsOn: ["copyFile"]) { + from "$buildDir/temp/plugin" + destinationDir file("$buildDir/install") + baseName pluginPre + appendix pluginName + version pluginVersion +} + +//控制build时包含哪些文件,排除哪些文件 +processResources { +// exclude everything +// 用*.css没效果 +// exclude '**/*.css' +// except this file +// include 'xx.xml' +} + +/*读取plugin.xml中的version*/ + +def getPluginInfo() { + def xmlFile = file("plugin.xml") + if (!xmlFile.exists()) { + return ["id": "none", "version": "1.0.0"] + } + def plugin = new XmlParser().parse(xmlFile) + def version = plugin.version[0].text() + def id = plugin.id[0].text() + return ["id": id, "version": version] +} + +repositories { + mavenLocal() + maven { + url = uri('http://mvn.finedevelop.com/repository/maven-public/') + } +} + +dependencies { + //使用本地jar + implementation fileTree(dir: 'lib', include: ['**/*.jar']) + implementation fileTree(dir: libPath, include: ['**/*.jar']) +} + diff --git a/doc/插件开发成长计划系列教程-第七章-阶段性实战上.pptx b/doc/插件开发成长计划系列教程-第七章-阶段性实战上.pptx new file mode 100644 index 0000000..8ae8134 Binary files /dev/null and b/doc/插件开发成长计划系列教程-第七章-阶段性实战上.pptx differ diff --git a/doc/插件开发成长计划系列教程-第七章-阶段性实战下.pptx b/doc/插件开发成长计划系列教程-第七章-阶段性实战下.pptx new file mode 100644 index 0000000..6b5b9d7 Binary files /dev/null and b/doc/插件开发成长计划系列教程-第七章-阶段性实战下.pptx differ diff --git a/doc/插件开发成长计划系列教程-第九章.pptx b/doc/插件开发成长计划系列教程-第九章.pptx new file mode 100644 index 0000000..031a2b7 Binary files /dev/null and b/doc/插件开发成长计划系列教程-第九章.pptx differ diff --git a/encrypt.xml b/encrypt.xml new file mode 100644 index 0000000..1401cd1 --- /dev/null +++ b/encrypt.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/lib/gson-2.3.1.jar b/lib/gson-2.3.1.jar new file mode 100644 index 0000000..250132c Binary files /dev/null and b/lib/gson-2.3.1.jar differ diff --git a/lib/report/.gitkeep b/lib/report/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/plugin.xml b/plugin.xml new file mode 100644 index 0000000..1b94d55 --- /dev/null +++ b/plugin.xml @@ -0,0 +1,35 @@ + + + com.fr.plugin.7.mix.project + + yes + 1.0 + 10.0 + 2018-07-31 + author + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/readme.md b/readme.md new file mode 100644 index 0000000..a6ffd32 --- /dev/null +++ b/readme.md @@ -0,0 +1,3 @@ +# 函数插件 + +该函数可以对一组数值求绝对值。 \ No newline at end of file diff --git a/src/main/java/com/fr/plugin/IPTokenPluginDecisionDBAccessProvider.java b/src/main/java/com/fr/plugin/IPTokenPluginDecisionDBAccessProvider.java new file mode 100644 index 0000000..7d6c0d5 --- /dev/null +++ b/src/main/java/com/fr/plugin/IPTokenPluginDecisionDBAccessProvider.java @@ -0,0 +1,63 @@ +package com.fr.plugin; + + +import com.fr.decision.plugin.db.AbstractDecisionDBAccessProvider; +import com.fr.plugin.dao.UserIpRelationDao; +import com.fr.plugin.dao.UserTokenRelationDao; +import com.fr.plugin.entity.UserIpEntity; +import com.fr.plugin.entity.UserTokenEntity; +import com.fr.plugin.transform.ExecuteFunctionRecord; +import com.fr.plugin.transform.FunctionRecorder; +import com.fr.stable.db.accessor.DBAccessor; +import com.fr.stable.db.dao.BaseDAO; +import com.fr.stable.db.dao.DAOProvider; + +//第一步类 继承AbstractDecisionDBAccessProvider +@FunctionRecorder +public class IPTokenPluginDecisionDBAccessProvider extends AbstractDecisionDBAccessProvider { + + //第二步 注册数据库访问类 + @Override + @ExecuteFunctionRecord + public DAOProvider[] registerDAO() { + return new DAOProvider[]{ + //注意这里是匿名类 + new DAOProvider() { + @Override + public Class getEntityClass() { + return UserIpEntity.class; + } + + @Override + public Class getDAOClass() { + return UserIpRelationDao.class; + } + }, + new DAOProvider() { + @Override + public Class getEntityClass() { + return UserTokenEntity.class; + } + + @Override + public Class getDAOClass() { + return UserTokenRelationDao.class; + } + } + }; + } + + //第三步新建一个DBAccessor 静态变量 + private static DBAccessor dbAccessor = null; + + //第四步写一个公开的静态方法去获取DBAccessor + public static DBAccessor getDbAccessor() { + return dbAccessor; + } + + //第五步 重写数据库访问器注入函数(当数据库访问器准备好之后由fr注入到这里) + @Override + public void onDBAvailable(DBAccessor dbAccessor) { + IPTokenPluginDecisionDBAccessProvider.dbAccessor = dbAccessor; + } +} diff --git a/src/main/java/com/fr/plugin/IpTokenHttpProvider.java b/src/main/java/com/fr/plugin/IpTokenHttpProvider.java new file mode 100644 index 0000000..5c21b45 --- /dev/null +++ b/src/main/java/com/fr/plugin/IpTokenHttpProvider.java @@ -0,0 +1,22 @@ +package com.fr.plugin; + +import com.fr.decision.fun.HttpHandler; +import com.fr.decision.fun.impl.AbstractHttpHandlerProvider; +import com.fr.plugin.http.ip.*; +import com.fr.plugin.http.token.*; + +public class IpTokenHttpProvider extends AbstractHttpHandlerProvider { + @Override + public HttpHandler[] registerHandlers() { + return new HttpHandler[]{ + new TokenListApi(), + new TokenAddApi(), + new TokenModApi(), + new TokenDelApi(), + new ListApi(), + new AddApi(), + new ModApi(), + new DelApi() + }; + } +} diff --git a/src/main/java/com/fr/plugin/IpTokenJSCSSBridge.java b/src/main/java/com/fr/plugin/IpTokenJSCSSBridge.java new file mode 100644 index 0000000..f1fbcba --- /dev/null +++ b/src/main/java/com/fr/plugin/IpTokenJSCSSBridge.java @@ -0,0 +1,21 @@ +package com.fr.plugin; + + +import com.fr.decision.fun.impl.AbstractWebResourceProvider; +import com.fr.decision.web.MainComponent; +import com.fr.plugin.components.IPTokenComponent; +import com.fr.web.struct.Atom; + +public class IpTokenJSCSSBridge extends AbstractWebResourceProvider { + @Override + public Atom attach() { + //在平台主组件加载时添加我们自己的组件 + return MainComponent.KEY; + } + + @Override + public Atom client() { + //我们自己要引入的组件 + return IPTokenComponent.KEY; + } +} diff --git a/src/main/java/com/fr/plugin/IpTokenLife.java b/src/main/java/com/fr/plugin/IpTokenLife.java new file mode 100644 index 0000000..1761bf0 --- /dev/null +++ b/src/main/java/com/fr/plugin/IpTokenLife.java @@ -0,0 +1,17 @@ +package com.fr.plugin; + +import com.fr.plugin.config.MySimpleConfig; +import com.fr.plugin.context.PluginContext; +import com.fr.plugin.observer.inner.AbstractPluginLifecycleMonitor; + +public class IpTokenLife extends AbstractPluginLifecycleMonitor { + @Override + public void afterRun(PluginContext pluginContext) { + MySimpleConfig.getInstance(); + } + + @Override + public void beforeStop(PluginContext pluginContext) { + + } +} diff --git a/src/main/java/com/fr/plugin/IpTokenOptionProvider.java b/src/main/java/com/fr/plugin/IpTokenOptionProvider.java new file mode 100644 index 0000000..33ed9c5 --- /dev/null +++ b/src/main/java/com/fr/plugin/IpTokenOptionProvider.java @@ -0,0 +1,45 @@ +package com.fr.plugin; + +import com.fr.decision.fun.impl.AbstractSystemOptionProvider; +import com.fr.decision.web.MainComponent; +import com.fr.plugin.components.IPTokenComponent; +import com.fr.web.struct.Atom; + +public class IpTokenOptionProvider extends AbstractSystemOptionProvider { + /** + * 这个id很重要 + * @return + */ + @Override + public String id() { + return "ipToken-1"; + } + + @Override + public String displayName() { + return "ipToken配置"; + } + + @Override + public int sortIndex() { + return 0; + } + + /** + * 附加在主页后面 + * @return + */ + @Override + public Atom attach() { + return MainComponent.KEY; + } + + /** + * 我们自己的组件申明 + * @return + */ + @Override + public Atom client() { + return IPTokenComponent.KEY; + } +} diff --git a/src/main/java/com/fr/plugin/IpTokenURLAlias2Provider.java b/src/main/java/com/fr/plugin/IpTokenURLAlias2Provider.java new file mode 100644 index 0000000..e407f95 --- /dev/null +++ b/src/main/java/com/fr/plugin/IpTokenURLAlias2Provider.java @@ -0,0 +1,18 @@ +package com.fr.plugin; + +import com.fr.decision.fun.impl.AbstractURLAliasProvider; +import com.fr.decision.webservice.url.alias.URLAlias; +import com.fr.decision.webservice.url.alias.URLAliasFactory; +import com.fr.plugin.transform.ExecuteFunctionRecord; +import com.fr.plugin.transform.FunctionRecorder; + +@FunctionRecorder +public class IpTokenURLAlias2Provider extends AbstractURLAliasProvider { + @Override + @ExecuteFunctionRecord + public URLAlias[] registerAlias() { + return new URLAlias[]{ + URLAliasFactory.createPluginAlias("/pcindex","/index",true), + }; + } +} diff --git a/src/main/java/com/fr/plugin/components/IPTokenComponent.java b/src/main/java/com/fr/plugin/components/IPTokenComponent.java new file mode 100644 index 0000000..1371efa --- /dev/null +++ b/src/main/java/com/fr/plugin/components/IPTokenComponent.java @@ -0,0 +1,55 @@ +package com.fr.plugin.components; + + +import com.fr.web.struct.AssembleComponent; +import com.fr.web.struct.Atom; +import com.fr.web.struct.Component; +import com.fr.web.struct.browser.RequestClient; +import com.fr.web.struct.category.ScriptPath; +import com.fr.web.struct.category.StylePath; + +//这里修改为继承AssembleComponent 支持依赖多个Atom从而注入多个js和css +public class IPTokenComponent extends AssembleComponent { + public static IPTokenComponent KEY = new IPTokenComponent(); + + //这里用私有构造函数避免外部实例化这个类,只能通过KEY这个单例引用 + private IPTokenComponent() { + } + + @Override + public Atom[] refer() { + return new Atom[]{ + //生成一个匿名Component 只实现script 返回我们依赖的script + new Component() { + @Override + public ScriptPath script(RequestClient requestClient) { + return ScriptPath.build("com/fr/plugin/web/table.js"); + } + }, + //生成一个匿名Component 只实现script 返回我们依赖的script + new Component() { + @Override + public ScriptPath script(RequestClient requestClient) { + return ScriptPath.build("com/fr/plugin/web/userIpadd.js"); + } + }, + //生成一个匿名Component 只实现script 返回我们依赖的script + new Component() { + @Override + public ScriptPath script(RequestClient requestClient) { + return ScriptPath.build("com/fr/plugin/web/tokenConfig.js"); + } + } + }; + } + + @Override + public ScriptPath script(RequestClient requestClient) { + return ScriptPath.build("com/fr/plugin/web/ipConfig.js"); + } + + @Override + public StylePath style(RequestClient requestClient) { + return StylePath.build("com/fr/plugin/web/iptoken.css"); + } +} diff --git a/src/main/java/com/fr/plugin/config/MySimpleConfig.java b/src/main/java/com/fr/plugin/config/MySimpleConfig.java new file mode 100644 index 0000000..f07bcc8 --- /dev/null +++ b/src/main/java/com/fr/plugin/config/MySimpleConfig.java @@ -0,0 +1,28 @@ +package com.fr.plugin.config; + +import com.fr.config.*; +import com.fr.config.holder.Conf; +import com.fr.config.holder.factory.Holders; + +@Visualization(category = "ipToken配置") +public class MySimpleConfig extends DefaultConfiguration { + private static volatile MySimpleConfig config = null; + + public static MySimpleConfig getInstance() { + if (config == null) { + config = ConfigContext.getConfigInstance(MySimpleConfig.class); + } + return config; + } + + + @Identifier(value = "openFilter", name = "是否启用拦截器", description = "", status = Status.SHOW) + private Conf openFilter = Holders.simple(true); + + @Override + public Object clone() throws CloneNotSupportedException { + MySimpleConfig cloned = (MySimpleConfig) super.clone(); + cloned.openFilter = (Conf) openFilter.clone(); + return cloned; + } +} diff --git a/src/main/java/com/fr/plugin/dao/UserIpRelationDao.java b/src/main/java/com/fr/plugin/dao/UserIpRelationDao.java new file mode 100644 index 0000000..ac1d24f --- /dev/null +++ b/src/main/java/com/fr/plugin/dao/UserIpRelationDao.java @@ -0,0 +1,18 @@ +package com.fr.plugin.dao; + +import com.fr.plugin.entity.UserIpEntity; +import com.fr.stable.db.dao.BaseDAO; +import com.fr.stable.db.session.DAOSession; + + +public class UserIpRelationDao extends BaseDAO { + + public UserIpRelationDao(DAOSession daoSession) { + super(daoSession); + } + + @Override + protected Class getEntityClass() { + return UserIpEntity.class; + } +} diff --git a/src/main/java/com/fr/plugin/dao/UserTokenRelationDao.java b/src/main/java/com/fr/plugin/dao/UserTokenRelationDao.java new file mode 100644 index 0000000..bcd596c --- /dev/null +++ b/src/main/java/com/fr/plugin/dao/UserTokenRelationDao.java @@ -0,0 +1,18 @@ +package com.fr.plugin.dao; + +import com.fr.plugin.entity.UserTokenEntity; +import com.fr.plugin.entity.UserTokenEntity; +import com.fr.stable.db.dao.BaseDAO; +import com.fr.stable.db.session.DAOSession; + + +public class UserTokenRelationDao extends BaseDAO { + public UserTokenRelationDao(DAOSession daoSession) { + super(daoSession); + } + + @Override + protected Class getEntityClass() { + return UserTokenEntity.class; + } +} diff --git a/src/main/java/com/fr/plugin/entity/UserIpEntity.java b/src/main/java/com/fr/plugin/entity/UserIpEntity.java new file mode 100644 index 0000000..3ad85a3 --- /dev/null +++ b/src/main/java/com/fr/plugin/entity/UserIpEntity.java @@ -0,0 +1,45 @@ +package com.fr.plugin.entity; + +import com.fr.stable.db.entity.BaseEntity; +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; + +//第一步添加这两个注解,特别是table的name属性要唯一,并将类继承到BaseEntity,会自动生产id字段 +@Entity +@Table( + name = "plugin_user_ip_relationship" +) +public class UserIpEntity extends BaseEntity { + + //第二步注册要使用的字段加上@Column注解 + @Column( + name = "userName" + ) + private String userName; + + @Column( + name = "ip" + ) + private String ip; + + + //第三步生成对应的get和set + public String getUserName() { + return userName; + } + + public void setUserName(String userName) { + this.userName = userName; + } + + public String getIp() { + return ip; + } + + public void setIp(String ip) { + this.ip = ip; + } +} diff --git a/src/main/java/com/fr/plugin/entity/UserTokenEntity.java b/src/main/java/com/fr/plugin/entity/UserTokenEntity.java new file mode 100644 index 0000000..72972d5 --- /dev/null +++ b/src/main/java/com/fr/plugin/entity/UserTokenEntity.java @@ -0,0 +1,43 @@ +package com.fr.plugin.entity; + +import com.fr.stable.db.entity.BaseEntity; +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; + +//第一步添加这两个注解,特别是table的name属性要唯一,并将类继承到BaseEntity,会自动生产id字段 +@Entity +@Table( + name = "plugin_user_token_relationship" +) +public class UserTokenEntity extends BaseEntity { + + //第二步注册要使用的字段加上@Column注解 + @Column( + name = "userName" + ) + private String userName; + + @Column( + name = "token" + ) + private String token; + + public String getUserName() { + return userName; + } + + public void setUserName(String userName) { + this.userName = userName; + } + + public String getToken() { + return token; + } + + public void setToken(String token) { + this.token = token; + } +} diff --git a/src/main/java/com/fr/plugin/filter/IpGlobalRequestFilter.java b/src/main/java/com/fr/plugin/filter/IpGlobalRequestFilter.java new file mode 100644 index 0000000..2977617 --- /dev/null +++ b/src/main/java/com/fr/plugin/filter/IpGlobalRequestFilter.java @@ -0,0 +1,99 @@ +package com.fr.plugin.filter; + +import com.fr.decision.authority.data.User; +import com.fr.decision.fun.impl.AbstractGlobalRequestFilterProvider; +import com.fr.decision.webservice.utils.DecisionServiceConstants; +import com.fr.decision.webservice.v10.login.LoginService; +import com.fr.decision.webservice.v10.user.UserService; +import com.fr.plugin.IPTokenPluginDecisionDBAccessProvider; +import com.fr.plugin.dao.UserIpRelationDao; +import com.fr.plugin.dao.UserTokenRelationDao; +import com.fr.plugin.entity.UserIpEntity; +import com.fr.plugin.entity.UserTokenEntity; +import com.fr.stable.StringUtils; +import com.fr.stable.db.accessor.DBAccessor; +import com.fr.stable.query.QueryFactory; +import com.fr.stable.query.restriction.RestrictionFactory; +import com.fr.web.utils.WebUtils; + +import javax.servlet.FilterChain; +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.util.List; + +public class IpGlobalRequestFilter extends AbstractGlobalRequestFilterProvider { + + @Override + public String filterName() { + return "iptoken"; + } + + @Override + public String[] urlPatterns() { + return new String[]{ + "/decision/*" + }; + } + + /** + * @param req + * @param res + * @param filterChain + */ + @Override + public void doFilter(HttpServletRequest req, HttpServletResponse res, FilterChain filterChain) { + try { + //未登录才获取token,这里登录成功或失败都交给下一步去处理 + if (isLogin(req)) { + //使用loginService 获取当前登录的用户名 + String currentUserName = LoginService.getInstance().getCurrentUserNameFromRequestCookie(req); + String currentUserId = UserService.getInstance().getCurrentUserId(currentUserName); + if(!UserService.getInstance().isAdmin(currentUserId)){ + String ip = getIp(req); + if (!checkUserCanLoginOnIp(currentUserName,ip) ) { + WebUtils.printAsString(res,"对不起,您不能在:"+ip+" 登录"); + return; + } + } + } + filterChain.doFilter(req, res); + } catch (IOException | ServletException ignored) { + } catch (Exception e) { + e.printStackTrace(); + } + } + + private String getIp(HttpServletRequest req) { + //这里忽略有前置代理服务器的情况,默认就是直接访问的 + return req.getRemoteAddr(); + } + + /** + * 检查用户是否有权力在这个ip上登录 + * + * @param userName + * @param ip + * @return + * @throws Exception + */ + private boolean checkUserCanLoginOnIp(String userName, String ip) throws Exception { + //获取访问器 + DBAccessor dbAccessor = IPTokenPluginDecisionDBAccessProvider.getDbAccessor(); + //通过dao查询数据库返回的时一个list + List entities = dbAccessor.runQueryAction(daoContext -> + daoContext.getDAO(UserIpRelationDao.class) + .find( + QueryFactory.create() + .addRestriction(RestrictionFactory.eq("ip", ip)) + .addRestriction(RestrictionFactory.eq("userName", userName)) + )); + //如果查询到有对应权限就直接返回允许登录 + return !entities.isEmpty(); + } + + private boolean isLogin(HttpServletRequest request) { + return LoginService.getInstance().isLogged(request); + } +} \ No newline at end of file diff --git a/src/main/java/com/fr/plugin/filter/TokenGlobalRequestFilter.java b/src/main/java/com/fr/plugin/filter/TokenGlobalRequestFilter.java new file mode 100644 index 0000000..32e4a60 --- /dev/null +++ b/src/main/java/com/fr/plugin/filter/TokenGlobalRequestFilter.java @@ -0,0 +1,91 @@ +package com.fr.plugin.filter; + +import com.fr.decision.authority.data.User; +import com.fr.decision.fun.impl.AbstractGlobalRequestFilterProvider; +import com.fr.decision.webservice.utils.DecisionServiceConstants; +import com.fr.decision.webservice.v10.login.LoginService; +import com.fr.decision.webservice.v10.user.UserService; +import com.fr.plugin.IPTokenPluginDecisionDBAccessProvider; +import com.fr.plugin.dao.UserTokenRelationDao; +import com.fr.plugin.entity.UserTokenEntity; +import com.fr.stable.StringUtils; +import com.fr.stable.db.accessor.DBAccessor; +import com.fr.stable.query.QueryFactory; +import com.fr.stable.query.restriction.RestrictionFactory; + +import javax.servlet.FilterChain; +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.util.List; + +public class TokenGlobalRequestFilter extends AbstractGlobalRequestFilterProvider { + + @Override + public String filterName() { + return "TokenFilter"; + } + + @Override + public String[] urlPatterns() { + return new String[]{ + "/decision/*" + }; + } + + /** + * 本章目前只实现了token登录,在下一章我们实现ip拦截 + * + * @param req + * @param res + * @param filterChain + */ + @Override + public void doFilter(HttpServletRequest req, HttpServletResponse res, FilterChain filterChain) { + try { + //未登录才获取token,这里登录成功或失败都交给下一步去处理 + if (!isLogin(req)) { + login(req, res); + } + filterChain.doFilter(req, res); + } catch (IOException | ServletException ignored) { + } catch (Exception e) { + e.printStackTrace(); + } + } + + /** + * 具体登录的逻辑 + * @param req + * @param res + * @throws Exception + */ + private void login(HttpServletRequest req, HttpServletResponse res) throws Exception { + String my_token = req.getParameter("token"); + if (StringUtils.isNotBlank(my_token)) { + String userName = getUserNameByToken(my_token); + User user = UserService.getInstance().getUserByUserName(userName); + if (user != null) { + String loginToken = LoginService.getInstance().login(req, res, userName); + req.setAttribute(DecisionServiceConstants.FINE_AUTH_TOKEN_NAME, loginToken); + } + } + } + + private String getUserNameByToken(String token) throws Exception { + //获取访问器 + DBAccessor dbAccessor = IPTokenPluginDecisionDBAccessProvider.getDbAccessor(); + //通过dao查询数据库返回的时一个list + List entities = dbAccessor.runQueryAction(daoContext -> daoContext.getDAO(UserTokenRelationDao.class).find(QueryFactory.create().addRestriction(RestrictionFactory.eq("token", token)))); + //如果查询到有结果就返回第一个关联的用户 + if (!entities.isEmpty()) { + return entities.get(0).getUserName(); + } + return ""; + } + + private boolean isLogin(HttpServletRequest request) { + return LoginService.getInstance().isLogged(request); + } +} \ No newline at end of file diff --git a/src/main/java/com/fr/plugin/http/HttpUtils.java b/src/main/java/com/fr/plugin/http/HttpUtils.java new file mode 100644 index 0000000..83d9166 --- /dev/null +++ b/src/main/java/com/fr/plugin/http/HttpUtils.java @@ -0,0 +1,52 @@ +package com.fr.plugin.http; + +import com.fr.json.JSONObject; + +import javax.servlet.http.HttpServletRequest; +import java.io.BufferedReader; +import java.io.IOException; + +public class HttpUtils { + public static JSONObject getJSONBody(HttpServletRequest request) throws IOException { + BufferedReader br = request.getReader(); + String str; + StringBuilder wholeStr = new StringBuilder(); + while ((str = br.readLine()) != null) { + wholeStr.append(str); + } + return new JSONObject(wholeStr.toString()); + } + + public final static String getIpAddress(HttpServletRequest request) throws IOException { + // 获取请求主机IP地址,如果通过代理进来,则透过防火墙获取真实IP地址 + String ip = request.getHeader("X-Forwarded-For"); + + if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { + if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { + ip = request.getHeader("Proxy-Client-IP"); + } + if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { + ip = request.getHeader("WL-Proxy-Client-IP"); + } + if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { + ip = request.getHeader("HTTP_CLIENT_IP"); + } + if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { + ip = request.getHeader("HTTP_X_FORWARDED_FOR"); + } + if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { + ip = request.getRemoteAddr(); + } + } else if (ip.length() > 15) { + String[] ips = ip.split(","); + for (int index = 0; index < ips.length; index++) { + String strIp = (String) ips[index]; + if (! ("unknown".equalsIgnoreCase(strIp))) { + ip = strIp; + break; + } + } + } + return ip; + } +} diff --git a/src/main/java/com/fr/plugin/http/ip/AddApi.java b/src/main/java/com/fr/plugin/http/ip/AddApi.java new file mode 100644 index 0000000..756cf1a --- /dev/null +++ b/src/main/java/com/fr/plugin/http/ip/AddApi.java @@ -0,0 +1,77 @@ +package com.fr.plugin.http.ip; + +import com.fr.decision.fun.impl.BaseHttpHandler; +import com.fr.json.JSONObject; +import com.fr.plugin.IPTokenPluginDecisionDBAccessProvider; +import com.fr.plugin.dao.UserIpRelationDao; +import com.fr.plugin.entity.UserIpEntity; +import com.fr.stable.StringUtils; +import com.fr.stable.db.accessor.DBAccessor; +import com.fr.third.springframework.web.bind.annotation.RequestMethod; +import com.fr.web.utils.WebUtils; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.BufferedReader; +import java.io.IOException; +import java.util.UUID; + +public class AddApi extends BaseHttpHandler { + @Override + public RequestMethod getMethod() { + return RequestMethod.POST; + } + + @Override + public String getPath() { + return "/ip/add"; + } + + @Override + public boolean isPublic() { + return false; + } + + @Override + public void handle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws Exception { + DBAccessor dbAccessor = IPTokenPluginDecisionDBAccessProvider.getDbAccessor(); + //通过这两个函数获取的参数可以避免中文乱码和空指针 +// String parameter = httpServletRequest.getParameter(""); +// String userName = WebUtils.getHTTPRequestParameter(httpServletRequest, "userName"); +// String ip = WebUtils.getHTTPRequestParameter(httpServletRequest, "ip"); + String body = getBody(httpServletRequest);//{"userName":"admin","ip":"123345566"} + JSONObject entries = new JSONObject(body); + + String userName =entries.getString("userName"); + String ip =entries.getString("ip"); + if (StringUtils.isBlank(userName)||StringUtils.isBlank(ip)) { + JSONObject jsonObject = new JSONObject(); + jsonObject.put("msg", "user name or ip is black"); + jsonObject.put("code", -1); + WebUtils.printAsJSON(httpServletResponse, jsonObject); + } + UserIpEntity ipEntity = new UserIpEntity(); + ipEntity.setUserName(userName); + ipEntity.setIp(ip); + ipEntity.setId(UUID.randomUUID().toString()); + //执行新增操作 + dbAccessor.runDMLAction(daoContext -> { + daoContext.getDAO(UserIpRelationDao.class).add(ipEntity); + return null; + }); + JSONObject jsonObject = new JSONObject(); + jsonObject.put("msg", "success"); + jsonObject.put("code", 200); + WebUtils.printAsJSON(httpServletResponse, jsonObject); + } + + String getBody(HttpServletRequest request) throws IOException { + BufferedReader br = request.getReader(); + String str; + StringBuilder wholeStr = new StringBuilder(); + while((str = br.readLine()) != null){ + wholeStr.append(str); + } + return wholeStr.toString(); + } +} diff --git a/src/main/java/com/fr/plugin/http/ip/DelApi.java b/src/main/java/com/fr/plugin/http/ip/DelApi.java new file mode 100644 index 0000000..1dcdece --- /dev/null +++ b/src/main/java/com/fr/plugin/http/ip/DelApi.java @@ -0,0 +1,60 @@ +package com.fr.plugin.http.ip; + +import com.fr.decision.fun.impl.BaseHttpHandler; +import com.fr.json.JSONObject; +import com.fr.plugin.IPTokenPluginDecisionDBAccessProvider; +import com.fr.plugin.dao.UserIpRelationDao; +import com.fr.plugin.entity.UserIpEntity; +import com.fr.plugin.http.HttpUtils; +import com.fr.stable.db.accessor.DBAccessor; +import com.fr.stable.query.QueryFactory; +import com.fr.stable.query.restriction.RestrictionFactory; +import com.fr.third.springframework.web.bind.annotation.RequestMethod; +import com.fr.web.utils.WebUtils; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +public class DelApi extends BaseHttpHandler { + @Override + public RequestMethod getMethod() { + return RequestMethod.DELETE; + } + + @Override + public String getPath() { + return "/ip/del"; + } + + @Override + public boolean isPublic() { + return false; + } + + @Override + public void handle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws Exception { + DBAccessor dbAccessor = IPTokenPluginDecisionDBAccessProvider.getDbAccessor(); + //通过这两个函数获取的参数可以避免中文乱码和空指针 + String id = HttpUtils.getJSONBody(httpServletRequest).getString("id"); + //先查找要更新的用户 + UserIpEntity entity = dbAccessor.runQueryAction(daoContext -> daoContext.getDAO(UserIpRelationDao.class) + .findOne(QueryFactory.create().addRestriction(RestrictionFactory.eq("id", id))) + ); + if (entity != null) { + dbAccessor.runDMLAction(daoContext -> { + //执行更新操作 + daoContext.getDAO(UserIpRelationDao.class).remove(QueryFactory.create().addRestriction(RestrictionFactory.eq("id", id))); + return null; + }); + JSONObject jsonObject = new JSONObject(); + jsonObject.put("msg", "success"); + jsonObject.put("code", 200); + WebUtils.printAsJSON(httpServletResponse, jsonObject); + } else { + JSONObject jsonObject = new JSONObject(); + jsonObject.put("msg", "user not find"); + jsonObject.put("code", -1); + WebUtils.printAsJSON(httpServletResponse, jsonObject); + } + } +} diff --git a/src/main/java/com/fr/plugin/http/ip/ListApi.java b/src/main/java/com/fr/plugin/http/ip/ListApi.java new file mode 100644 index 0000000..ecc4153 --- /dev/null +++ b/src/main/java/com/fr/plugin/http/ip/ListApi.java @@ -0,0 +1,53 @@ +package com.fr.plugin.http.ip; + +import com.fr.decision.fun.impl.BaseHttpHandler; +import com.fr.json.JSONArray; +import com.fr.plugin.IPTokenPluginDecisionDBAccessProvider; +import com.fr.plugin.dao.UserIpRelationDao; +import com.fr.plugin.entity.UserIpEntity; +import com.fr.stable.StringUtils; +import com.fr.stable.db.accessor.DBAccessor; +import com.fr.stable.query.QueryFactory; +import com.fr.stable.query.condition.QueryCondition; +import com.fr.stable.query.restriction.RestrictionFactory; +import com.fr.third.springframework.web.bind.annotation.RequestMethod; +import com.fr.web.utils.WebUtils; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.util.List; + +public class ListApi extends BaseHttpHandler { + @Override + public RequestMethod getMethod() { + return RequestMethod.GET; + } + + @Override + public String getPath() { + return "/ip/list"; + } + + @Override + public boolean isPublic() { + return false; + } + + @Override + public void handle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws Exception { + DBAccessor dbAccessor = IPTokenPluginDecisionDBAccessProvider.getDbAccessor(); +// String userName = httpServletRequest.getParameter("userName"); +// int page = WebUtils.getHTTPRequestIntParameter(httpServletRequest, "page", 0); + List entityList = dbAccessor.runQueryAction(daoContext -> { + QueryCondition queryCondition = QueryFactory.create(); +// if (StringUtils.isNotBlank(userName)) { +// queryCondition.addRestriction(RestrictionFactory.eq("userName", userName)); +// } +// queryCondition.setSkip(page * 10); + List entityList1 = daoContext.getDAO(UserIpRelationDao.class).find(queryCondition); + return entityList1; + }); + JSONArray jsonArray = JSONArray.create(entityList); + WebUtils.printAsJSON(httpServletResponse, jsonArray); + } +} diff --git a/src/main/java/com/fr/plugin/http/ip/ModApi.java b/src/main/java/com/fr/plugin/http/ip/ModApi.java new file mode 100644 index 0000000..ad79929 --- /dev/null +++ b/src/main/java/com/fr/plugin/http/ip/ModApi.java @@ -0,0 +1,61 @@ +package com.fr.plugin.http.ip; + +import com.fr.decision.fun.impl.BaseHttpHandler; +import com.fr.json.JSONObject; +import com.fr.plugin.IPTokenPluginDecisionDBAccessProvider; +import com.fr.plugin.dao.UserIpRelationDao; +import com.fr.plugin.entity.UserIpEntity; +import com.fr.stable.db.accessor.DBAccessor; +import com.fr.stable.query.QueryFactory; +import com.fr.stable.query.restriction.RestrictionFactory; +import com.fr.third.springframework.web.bind.annotation.RequestMethod; +import com.fr.web.utils.WebUtils; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +public class ModApi extends BaseHttpHandler { + @Override + public RequestMethod getMethod() { + return null; + } + + @Override + public String getPath() { + return "/ip/mod"; + } + + @Override + public boolean isPublic() { + return true; + } + + @Override + public void handle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws Exception { + DBAccessor dbAccessor = IPTokenPluginDecisionDBAccessProvider.getDbAccessor(); + //通过这两个函数获取的参数可以避免中文乱码和空指针 + String userName = WebUtils.getHTTPRequestParameter(httpServletRequest, "userName"); + String ip = WebUtils.getHTTPRequestParameter(httpServletRequest, "Ip"); + //先查找要更新的用户 + UserIpEntity entity = dbAccessor.runQueryAction(daoContext -> daoContext.getDAO(UserIpRelationDao.class) + .findOne(QueryFactory.create().addRestriction(RestrictionFactory.eq("userName", userName))) + ); + if (entity != null) { + entity.setIp(ip); + dbAccessor.runDMLAction(daoContext -> { + //执行更新操作 + daoContext.getDAO(UserIpRelationDao.class).update(entity); + return null; + }); + JSONObject jsonObject = new JSONObject(); + jsonObject.put("msg", "success"); + jsonObject.put("code", 200); + WebUtils.printAsJSON(httpServletResponse, jsonObject); + } else { + JSONObject jsonObject = new JSONObject(); + jsonObject.put("msg", "user not find"); + jsonObject.put("code", -1); + WebUtils.printAsJSON(httpServletResponse, jsonObject); + } + } +} diff --git a/src/main/java/com/fr/plugin/http/token/TokenAddApi.java b/src/main/java/com/fr/plugin/http/token/TokenAddApi.java new file mode 100644 index 0000000..5eb3d0a --- /dev/null +++ b/src/main/java/com/fr/plugin/http/token/TokenAddApi.java @@ -0,0 +1,54 @@ +package com.fr.plugin.http.token; + +import com.fr.decision.fun.impl.BaseHttpHandler; +import com.fr.json.JSONObject; +import com.fr.plugin.IPTokenPluginDecisionDBAccessProvider; +import com.fr.plugin.dao.UserTokenRelationDao; +import com.fr.plugin.entity.UserTokenEntity; +import com.fr.plugin.http.HttpUtils; +import com.fr.stable.db.accessor.DBAccessor; +import com.fr.third.springframework.web.bind.annotation.RequestMethod; +import com.fr.web.utils.WebUtils; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.util.UUID; + +public class TokenAddApi extends BaseHttpHandler { + @Override + public RequestMethod getMethod() { + return RequestMethod.POST; + } + + @Override + public String getPath() { + return "/token/add"; + } + + @Override + public boolean isPublic() { + return false; + } + + @Override + public void handle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws Exception { + DBAccessor dbAccessor = IPTokenPluginDecisionDBAccessProvider.getDbAccessor(); + JSONObject jsonBody = HttpUtils.getJSONBody(httpServletRequest); + String userName =jsonBody.getString("userName"); + String token =jsonBody.getString("token"); + //使用配置 + UserTokenEntity tokenEntity = new UserTokenEntity(); + tokenEntity.setUserName(userName); + tokenEntity.setToken(token); + tokenEntity.setId(UUID.randomUUID().toString()); + //执行新增操作 + dbAccessor.runDMLAction(daoContext -> { + daoContext.getDAO(UserTokenRelationDao.class).add(tokenEntity); + return null; + }); + JSONObject jsonObject = new JSONObject(); + jsonObject.put("msg", "success"); + jsonObject.put("code", 200); + WebUtils.printAsJSON(httpServletResponse, jsonObject); + } +} diff --git a/src/main/java/com/fr/plugin/http/token/TokenDelApi.java b/src/main/java/com/fr/plugin/http/token/TokenDelApi.java new file mode 100644 index 0000000..d4b6c16 --- /dev/null +++ b/src/main/java/com/fr/plugin/http/token/TokenDelApi.java @@ -0,0 +1,63 @@ +package com.fr.plugin.http.token; + +import com.fr.decision.fun.impl.BaseHttpHandler; +import com.fr.json.JSONObject; +import com.fr.plugin.IPTokenPluginDecisionDBAccessProvider; +import com.fr.plugin.dao.UserIpRelationDao; +import com.fr.plugin.dao.UserTokenRelationDao; +import com.fr.plugin.entity.UserIpEntity; +import com.fr.plugin.entity.UserTokenEntity; +import com.fr.plugin.http.HttpUtils; +import com.fr.stable.db.accessor.DBAccessor; +import com.fr.stable.query.QueryFactory; +import com.fr.stable.query.restriction.RestrictionFactory; +import com.fr.third.springframework.web.bind.annotation.RequestMethod; +import com.fr.web.utils.WebUtils; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +public class TokenDelApi extends BaseHttpHandler { + @Override + public RequestMethod getMethod() { + return RequestMethod.DELETE; + } + + @Override + public String getPath() { + return "/token/del"; + } + + @Override + public boolean isPublic() { + return false; + } + + @Override + public void handle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws Exception { + DBAccessor dbAccessor = IPTokenPluginDecisionDBAccessProvider.getDbAccessor(); + //通过这两个函数获取的参数可以避免中文乱码和空指针 + JSONObject jsonBody = HttpUtils.getJSONBody(httpServletRequest); + String id =jsonBody.getString("id"); + //先查找要更新的用户 + UserTokenEntity entity = dbAccessor.runQueryAction(daoContext -> daoContext.getDAO(UserTokenRelationDao.class) + .findOne(QueryFactory.create().addRestriction(RestrictionFactory.eq("id", id))) + ); + if (entity != null) { + dbAccessor.runDMLAction(daoContext -> { + //执行更新操作 + daoContext.getDAO(UserIpRelationDao.class).remove(QueryFactory.create().addRestriction(RestrictionFactory.eq("id", id))); + return null; + }); + JSONObject jsonObject = new JSONObject(); + jsonObject.put("msg", "success"); + jsonObject.put("code", 200); + WebUtils.printAsJSON(httpServletResponse, jsonObject); + } else { + JSONObject jsonObject = new JSONObject(); + jsonObject.put("msg", "Token not find"); + jsonObject.put("code", -1); + WebUtils.printAsJSON(httpServletResponse, jsonObject); + } + } +} diff --git a/src/main/java/com/fr/plugin/http/token/TokenListApi.java b/src/main/java/com/fr/plugin/http/token/TokenListApi.java new file mode 100644 index 0000000..755d8c1 --- /dev/null +++ b/src/main/java/com/fr/plugin/http/token/TokenListApi.java @@ -0,0 +1,53 @@ +package com.fr.plugin.http.token; + +import com.fr.decision.fun.impl.BaseHttpHandler; +import com.fr.json.JSONArray; +import com.fr.plugin.IPTokenPluginDecisionDBAccessProvider; +import com.fr.plugin.dao.UserIpRelationDao; +import com.fr.plugin.dao.UserTokenRelationDao; +import com.fr.plugin.entity.UserIpEntity; +import com.fr.plugin.entity.UserTokenEntity; +import com.fr.stable.StringUtils; +import com.fr.stable.db.accessor.DBAccessor; +import com.fr.stable.query.QueryFactory; +import com.fr.stable.query.condition.QueryCondition; +import com.fr.stable.query.restriction.RestrictionFactory; +import com.fr.third.springframework.web.bind.annotation.RequestMethod; +import com.fr.web.utils.WebUtils; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.util.List; + +public class TokenListApi extends BaseHttpHandler { + @Override + public RequestMethod getMethod() { + return RequestMethod.GET; + } + + @Override + public String getPath() { + return "/token/list"; + } + + @Override + public boolean isPublic() { + return false; + } + + @Override + public void handle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws Exception { + DBAccessor dbAccessor = IPTokenPluginDecisionDBAccessProvider.getDbAccessor(); + String userName = httpServletRequest.getParameter("userName"); + List entityList = dbAccessor.runQueryAction(daoContext -> { + QueryCondition queryCondition = QueryFactory.create(); + if (StringUtils.isNotBlank(userName)) { + queryCondition.addRestriction(RestrictionFactory.eq("userName", userName)); + } + List entityList1 = daoContext.getDAO(UserTokenRelationDao.class).find(queryCondition); + return entityList1; + }); + JSONArray jsonArray = JSONArray.create(entityList); + WebUtils.printAsJSON(httpServletResponse, jsonArray); + } +} diff --git a/src/main/java/com/fr/plugin/http/token/TokenModApi.java b/src/main/java/com/fr/plugin/http/token/TokenModApi.java new file mode 100644 index 0000000..41ffcab --- /dev/null +++ b/src/main/java/com/fr/plugin/http/token/TokenModApi.java @@ -0,0 +1,64 @@ +package com.fr.plugin.http.token; + +import com.fr.decision.fun.impl.BaseHttpHandler; +import com.fr.json.JSONObject; +import com.fr.plugin.IPTokenPluginDecisionDBAccessProvider; +import com.fr.plugin.dao.UserIpRelationDao; +import com.fr.plugin.dao.UserTokenRelationDao; +import com.fr.plugin.entity.UserTokenEntity; +import com.fr.plugin.http.HttpUtils; +import com.fr.stable.db.accessor.DBAccessor; +import com.fr.stable.query.QueryFactory; +import com.fr.stable.query.restriction.RestrictionFactory; +import com.fr.third.springframework.web.bind.annotation.RequestMethod; +import com.fr.web.utils.WebUtils; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +public class TokenModApi extends BaseHttpHandler { + @Override + public RequestMethod getMethod() { + return RequestMethod.PUT; + } + + @Override + public String getPath() { + return "/token/mod"; + } + + @Override + public boolean isPublic() { + return false; + } + + @Override + public void handle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws Exception { + DBAccessor dbAccessor = IPTokenPluginDecisionDBAccessProvider.getDbAccessor(); + //通过这两个函数获取的参数可以避免中文乱码和空指针 + JSONObject jsonBody = HttpUtils.getJSONBody(httpServletRequest); + String userName =jsonBody.getString("userName"); + String token =jsonBody.getString("token"); + //先查找要更新的用户 + UserTokenEntity entity = dbAccessor.runQueryAction(daoContext -> daoContext.getDAO(UserTokenRelationDao.class) + .findOne(QueryFactory.create().addRestriction(RestrictionFactory.eq("userName", userName))) + ); + if (entity != null) { + entity.setToken(token); + dbAccessor.runDMLAction(daoContext -> { + //执行更新操作 + daoContext.getDAO(UserTokenRelationDao.class).update(entity); + return null; + }); + JSONObject jsonObject = new JSONObject(); + jsonObject.put("msg", "success"); + jsonObject.put("code", 200); + WebUtils.printAsJSON(httpServletResponse, jsonObject); + } else { + JSONObject jsonObject = new JSONObject(); + jsonObject.put("msg", "user not find"); + jsonObject.put("code", -1); + WebUtils.printAsJSON(httpServletResponse, jsonObject); + } + } +} diff --git a/src/main/resources/com/fr/plugin/web/ipConfig.js b/src/main/resources/com/fr/plugin/web/ipConfig.js new file mode 100644 index 0000000..c874a3a --- /dev/null +++ b/src/main/resources/com/fr/plugin/web/ipConfig.js @@ -0,0 +1,117 @@ +!(function () { +//这个菜单是配置ip关系的 +// 对应ppt的注册菜单3 + BI.config("dec.constant.system.tabs", function (items) { + items.push({ + value: "ipToken", + text: BI.i18nText("Ip配置"), // 文字 + cardType: "dec.management.ipConfig" + }); + return items; + }); + // 示例,向menus中加入百度搜索按钮. ppt的注册菜单1 + BI.config("dec.constant.menu.items", function (items) { + items.push({ + value: "baidu", + text: BI.i18nText("百度一下"), + cardType:{ + src:"http://baidu.com" + }, + cls: "analysis-menu-font" + }); + return items; + }); + debugger + //这个是从系统自己实现的中拷贝出来的,进行了一点修改 + function resolvePath(path, isPublic) { + if (!path || path[0] !== '/') { + path = '/' + path; + } + return isPublic === true + ? '/plugin/public/com.fr.plugin.7.mix.project' + path + : '/plugin/private/com.fr.plugin.7.mix.project' + path; + } + // 组件实现,效果为使用绝对布局组件放置了一个iframe + var ipConfig = BI.inherit(BI.Widget, { + props: { + baseCls: "ipConfig" + }, + render: function () { + var self = this; + return { + type: "bi.absolute", + items: [ + { + el: { + type: "bi.button", + text: "添加", + handler: function () { + var id = "addUserPane" + var that = this; + //参考:https://fanruan.design/doc.html?post=df052e5842 + BI.Popovers.create(id, { + type: "bi.bar_popover", + header: "添加ip限制", + size: "small", + body: { + type: "bi.add.userTokenOrIp", + cType:"ip", + ref: function (e) { + that.userIpPane = e; + } + }, + listeners: [{ + eventName: "EVENT_CANCEL", + action: function () { + BI.Msg.toast("点击了取消") + } + }, { + eventName: "EVENT_CONFIRM", + action: function () { + var params = that.userIpPane.getValue(); + console.info(params) + Dec.reqPost(resolvePath("/ip/add", false), { + userName: params.userName, + ip:params.params2 + }, function () { + BI.Msg.toast("保存成功") + self.tableRef.reload(); + }) + } + }] + }).open(id); + } + }, + top: 0, + left: 0, + }, + { + el: { + type: "bi.button", + text: "刷新", + handler: function () { + self.tableRef.reload(); + } + }, + top: 0, + left: 100, + }, + { + el: { + type: "dec.management.iptoken.table", + tableType:"ipTable", + ref: function (e) { + self.tableRef = e; + } + }, + top: 40, + left: 0, + right: 0, + bottom: 0 + } + ] + }; + } + }); + BI.shortcut("dec.management.ipConfig", ipConfig); +}()); \ No newline at end of file diff --git a/src/main/resources/com/fr/plugin/web/iptoken.css b/src/main/resources/com/fr/plugin/web/iptoken.css new file mode 100644 index 0000000..e69de29 diff --git a/src/main/resources/com/fr/plugin/web/table.js b/src/main/resources/com/fr/plugin/web/table.js new file mode 100644 index 0000000..82533ac --- /dev/null +++ b/src/main/resources/com/fr/plugin/web/table.js @@ -0,0 +1,115 @@ +;(function () { + var IpHeader = [[{ + text: "id", + }, { + text: "用户名", + }, { + text: "IP", + }, { + text: "操作" + }]]; + + var TokenHeader = [[{ + text: "id", + }, { + text: "用户名", + }, { + text: "Token", + }, { + text: "操作" + }]]; + function resolvePath(path, isPublic) { + if (!path || path[0] !== '/') { + path = '/' + path; + } + return isPublic === true + ? '/plugin/public/com.fr.plugin.7.mix.project' + path + : '/plugin/private/com.fr.plugin.7.mix.project' + path; + } + + var IPAndTokenTable = BI.inherit(BI.Widget, { + props: { + baseCls: "iptoken-table", + tableType:"ipTable" + }, + beforeInit: function (render) { + //根据组件生命周期,在这个环境初始化组件需要的第一页数据 + var that=this; + this.getData( function (data){ + that.allData =data; + render(); + }) + }, + getData: function ( callBack) { + var that = this; + var url="/token/list"; + if(this.options.tableType === "ipTable"){ + url="/ip/list" + } + //Dec下一共有reqGet,Post,Put,Delete,Patch和后台RequestMethod对应 + Dec.reqGet( + resolvePath(url, false)//第一个参数是要访问的地址 + , {}//第二个参数是请求参数 + , function (data) { //第三个参数是回调成功 + // debugger + var tempData = BI.map(data, function (i, v) { + return BI.map(v, function (ii, vv) { + return { + text: vv, + whiteSpace: "normal" + } + }) + }); + debugger + BI.each(tempData, function (i, v) { + v.push({ + type: "bi.button", + text: "删除", + handler: function (){ + var id=v[0].text; + var url="/token/del"; + if(that.options.tableType === "ipTable"){ + url="/ip/del" + } + Dec.reqDelete(resolvePath(url,false),{ + id:id + },function (){ + that.reload(); + }) + } + }) + }); + callBack(tempData); + }); + //还有一个complete 参数一共4个 + }, + reload: function () { + var that=this; + this.getData(function (data){ + that.tableIns.populate(data) + }) + }, + render: function () { + var that = this; + var header=TokenHeader; + if(this.options.tableType === "ipTable"){ + header=IpHeader; + } + return { + //table_view参考 https://fanruan.design/doc.html?post=5c39511444 + type: "bi.table_view", + width: 600, + height: 400, + ref: function (e) { + that.tableIns = e; + }, + minColumnSize: [100, 100, 100], + columnSize: [100, 100, 100], + regionColumnSize: [300, "fill"], + items: this.allData, + header: header, + } + } + }); + BI.shortcut("dec.management.iptoken.table", IPAndTokenTable); +})(); \ No newline at end of file diff --git a/src/main/resources/com/fr/plugin/web/tokenConfig.js b/src/main/resources/com/fr/plugin/web/tokenConfig.js new file mode 100644 index 0000000..23a92bb --- /dev/null +++ b/src/main/resources/com/fr/plugin/web/tokenConfig.js @@ -0,0 +1,109 @@ +!(function () { + + // 关联wiki:https://wiki.fanruan.com/pages/viewpage.action?pageId=20021612 + // 特别注意,此配置需要配合服务端SystemOptionProvider接口使用,不然会因无权限而不显示节点. + BI.config("dec.constant.management.navigation", function (items) { + items.push({ + value: "iptoekn", // 地址栏显示的hash值 + id: "ipToken-1", // id 这个和java类中的IpTokenOptionProvider 的id要一致 + text: BI.i18nText("Token关系配置"), // 文字 + cardType: "dec.management.tokenConfig", // 组件的shortcut,适用于用fineui开发的页面. + cls: "management-directory-font" // 图标类名 + }); + return items; + }); + + + function resolvePath(path, isPublic) { + if (!path || path[0] !== '/') { + path = '/' + path; + } + return isPublic === true + ? '/plugin/public/com.fr.plugin.7.mix.project' + path + : '/plugin/private/com.fr.plugin.7.mix.project' + path; + } + + // 组件实现,效果为使用绝对布局组件放置了一个iframe + var tokenConfig = BI.inherit(BI.Widget, { + props: { + baseCls: "tokenConfig" + }, + render: function () { + var self = this; + return { + type: "bi.absolute", + items: [ + { + el: { + type: "bi.button", + text: "添加", + handler: function () { + var id = "addUserPane" + var that = this; + //参考:https://fanruan.design/doc.html?post=df052e5842 + BI.Popovers.create(id, { + type: "bi.bar_popover", + header: "添加用户Token关联", + size: "small", + body: { + type: "bi.add.userTokenOrIp", + cType:"token", + ref: function (e) { + that.userIpPane = e; + } + }, + listeners: [{ + eventName: "EVENT_CANCEL", + action: function () { + BI.Msg.toast("点击了取消") + } + }, { + eventName: "EVENT_CONFIRM", + action: function () { + var params = that.userIpPane.getValue(); + console.info(params) + Dec.reqPost(resolvePath("/token/add", false), { + userName: params.userName, + token:params.params2 + }, function () { + BI.Msg.toast("保存成功") + self.tableRef.reload(); + }) + } + }] + }).open(id); + } + }, + top: 0, + left: 0, + }, + { + el: { + type: "bi.button", + text: "刷新", + handler: function () { + self.tableRef.reload(); + } + }, + top: 0, + left: 100, + }, + { + el: { + type: "dec.management.iptoken.table", + tableType:"tokenTable", + ref: function (e) { + self.tableRef = e; + } + }, + top: 40, + left: 0, + right: 0, + bottom: 0 + } + ] + }; + } + }); + BI.shortcut("dec.management.tokenConfig", tokenConfig); +}()); \ No newline at end of file diff --git a/src/main/resources/com/fr/plugin/web/userIpadd.js b/src/main/resources/com/fr/plugin/web/userIpadd.js new file mode 100644 index 0000000..5e3c542 --- /dev/null +++ b/src/main/resources/com/fr/plugin/web/userIpadd.js @@ -0,0 +1,74 @@ +;(function () { + + + function resolvePath(path, isPublic) { + if (!path || path[0] !== '/') { + path = '/' + path; + } + return isPublic === true + ? '/plugin/public/com.fr.plugin.7.mix.project' + path + : '/plugin/private/com.fr.plugin.7.mix.project' + path; + } + + var IPTokenEditorPane = BI.inherit(BI.Widget, { + props: { + baseCls: "iptoken-table", + cType: "token",//可能有token 或者 ip两种 + }, + getValue: function () { + return { + userName:this.inputUserName.getValue(), + params2:this.inputIPOrToken.getValue() + } + }, + render: function () { + var that = this; + var inputIPORTokenText="请输入ip" + if (this.options.cType === "token") { + inputIPORTokenText="请输入Token" + } + return { + type: "bi.vtape", + vgap: 10, + height: 200, + items: [ + { + height: 20, + type: "bi.horizontal_adapt", + columnSize: [140, "fill"], + items: [{ + type: "bi.label", + text: "输入用户名:", + }, { + type: "bi.text_editor", + watermark: "这个不允许为空", + allowBlank: false, + ref:function (e){ + that.inputUserName=e; + }, + errorText: "非空!", + }] + }, + { + height: 20, + type: "bi.horizontal_adapt", + columnSize: [140, "fill"], + items: [{ + type: "bi.label", + text: inputIPORTokenText, + }, { + type: "bi.text_editor", + watermark: "这个不允许为空", + allowBlank: false, + ref:function (e){ + that.inputIPOrToken=e; + }, + errorText: "非空!", + }] + } + ] + } + } + }); + BI.shortcut("bi.add.userTokenOrIp", IPTokenEditorPane); +})(); \ No newline at end of file