Browse Source

提交开源任务材料

10.0
LAPTOP-SB56SG4Q\86185 3 years ago
parent
commit
9e445594b2
  1. BIN
      JSD-8539配置使用文档v1.1.docx
  2. BIN
      JSD-8539需求确认书.docx
  3. 5
      README.md
  4. 38
      plugin.xml
  5. 39
      src/main/java/com/fr/plugin/xxxx/xxxx/sso/DelDBAccessProvider.java
  6. 20
      src/main/java/com/fr/plugin/xxxx/xxxx/sso/HandleRequestHandlerBridge.java
  7. 19
      src/main/java/com/fr/plugin/xxxx/xxxx/sso/HandleRequestURLAliasBridge.java
  8. 37
      src/main/java/com/fr/plugin/xxxx/xxxx/sso/LRGT.java
  9. 69
      src/main/java/com/fr/plugin/xxxx/xxxx/sso/PluginConstants.java
  10. 44
      src/main/java/com/fr/plugin/xxxx/xxxx/sso/ScheduleOutputDBAccess.java
  11. 213
      src/main/java/com/fr/plugin/xxxx/xxxx/sso/SsoFilter.java
  12. 102
      src/main/java/com/fr/plugin/xxxx/xxxx/sso/conf/SsoConfig.java
  13. 22
      src/main/java/com/fr/plugin/xxxx/xxxx/sso/dao/EarlyMessageDao.java
  14. 22
      src/main/java/com/fr/plugin/xxxx/xxxx/sso/dao/MessageSendDao.java
  15. 127
      src/main/java/com/fr/plugin/xxxx/xxxx/sso/entity/EarlyMessageAction.java
  16. 153
      src/main/java/com/fr/plugin/xxxx/xxxx/sso/entity/EarlyMessageEntity.java
  17. 83
      src/main/java/com/fr/plugin/xxxx/xxxx/sso/entity/MessageSendEntity.java
  18. 102
      src/main/java/com/fr/plugin/xxxx/xxxx/sso/handle/DeleteHandler.java
  19. 122
      src/main/java/com/fr/plugin/xxxx/xxxx/sso/handle/EarlyMessageHandle.java
  20. 55
      src/main/java/com/fr/plugin/xxxx/xxxx/sso/js/FileDef.java
  21. 22
      src/main/java/com/fr/plugin/xxxx/xxxx/sso/js/FunctionJSProvider.java
  22. 26
      src/main/java/com/fr/plugin/xxxx/xxxx/sso/js/JSCSSBridge.java
  23. 237
      src/main/java/com/fr/plugin/xxxx/xxxx/sso/util/HttpUtil.java
  24. 121
      src/main/java/com/fr/plugin/xxxx/xxxx/sso/util/LogUtils.java
  25. 125
      src/main/java/com/fr/plugin/xxxx/xxxx/sso/util/SsoUtils.java
  26. 50
      src/main/java/com/fr/plugin/xxxx/xxxx/sso/util/WebServiceUtil.java
  27. 20
      src/main/resources/com/fr/plugin/xxxx/xxxx/sso/function.js
  28. 58
      src/main/resources/com/fr/plugin/xxxx/xxxx/sso/theme.js
  29. 9
      src/main/resources/zgts.properties

BIN
JSD-8539配置使用文档v1.1.docx

Binary file not shown.

BIN
JSD-8539需求确认书.docx

Binary file not shown.

5
README.md

@ -1,3 +1,6 @@
# open-JSD-8539 # open-JSD-8539
JSD-8539 单点+用户集成+消息集成+定时推送 JSD-8539 单点+用户集成+消息集成+定时推送\
免责说明:该源码为第三方爱好者提供,不保证源码和方案的可靠性,也不提供任何形式的源码教学指导和协助!\
仅作为开发者学习参考使用!禁止用于任何商业用途!\
为保护开发者隐私,开发者信息已隐去!若原开发者希望公开自己的信息,可联系hugh处理。

38
plugin.xml

@ -0,0 +1,38 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<plugin>
<id>com.fr.plugin.xxxx.xxxx.sso</id>
<main-package>com.fr.plugin.xxxx.xxxx.sso</main-package>
<name><![CDATA[sso]]></name>
<active>yes</active>
<version>1.10</version>
<env-version>10.0</env-version>
<jartime>2018-07-31</jartime>
<vendor>fr.open</vendor>
<description><![CDATA[折叠树导出]]></description>
<change-notes><![CDATA[
[2021-12-03]【1.0】初始化插件。<br/>
[2021-12-09]【1.1】重新打包。<br/>
[2021-12-09]【1.2】单点接口调用修改。<br/>
[2021-12-09]【1.3】放行修改和登出隐藏。<br/>
[2021-12-16]【1.4】修改接口请求方式。<br/>
[2021-12-16]【1.5】报文修改。<br/>
[2021-12-16]【1.6】增加编码适配和推送为待阅。<br/>
[2021-12-16]【1.7】删除问题修改。<br/>
[2021-12-17]【1.8】待办删除类型修改。<br/>
[2021-12-17]【1.9】跳转逻辑修改。<br/>
[2021-12-17]【1.10】定时调度修改。<br/>
]]></change-notes>
<extra-decision>
<GlobalRequestFilterProvider class="com.fr.plugin.xxxx.xxxx.sso.SsoFilter"/>
<WebResourceProvider class="com.fr.plugin.xxxx.xxxx.sso.js.JSCSSBridge"/>
<DecisionDBAccessProvider class="com.fr.plugin.xxxx.xxxx.sso.ScheduleOutputDBAccess"/>
<HttpHandlerProvider class="com.fr.plugin.xxxx.xxxx.sso.HandleRequestHandlerBridge"/>
<URLAliasProvider class="com.fr.plugin.xxxx.xxxx.sso.HandleRequestURLAliasBridge" />
</extra-decision>
<extra-core>
<DBAccessProvider class="com.fr.plugin.xxxx.xxxx.sso.DelDBAccessProvider"/>
<JavaScriptFileHandler class="com.fr.plugin.xxxx.xxxx.sso.js.FunctionJSProvider"/>
</extra-core>
<function-recorder class="com.fr.plugin.xxxx.xxxx.sso.SsoFilter"/>
<lifecycle-monitor class="com.fr.plugin.xxxx.xxxx.sso.LRGT"/>
</plugin>

39
src/main/java/com/fr/plugin/xxxx/xxxx/sso/DelDBAccessProvider.java

@ -0,0 +1,39 @@
package com.fr.plugin.xxxx.xxxx.sso;
import com.fr.db.fun.impl.AbstractDBAccessProvider;
import com.fr.plugin.xxxx.xxxx.sso.dao.MessageSendDao;
import com.fr.plugin.xxxx.xxxx.sso.entity.MessageSendEntity;
import com.fr.stable.db.accessor.DBAccessor;
import com.fr.stable.db.dao.BaseDAO;
import com.fr.stable.db.dao.DAOProvider;
public class DelDBAccessProvider extends AbstractDBAccessProvider {
private static DBAccessor dbAccessor = null;
public static DBAccessor getDbAccessor() {
return dbAccessor;
}
@Override
public DAOProvider<?>[] registerDAO() {
return new DAOProvider[]{
new DAOProvider<MessageSendEntity>() {
@Override
public Class<MessageSendEntity> getEntityClass() {
return MessageSendEntity.class;
}
@Override
public Class<? extends BaseDAO<MessageSendEntity>> getDAOClass() {
return MessageSendDao.class;
}
}
};
}
@Override
public void onDBAvailable(DBAccessor dbAccessor) {
DelDBAccessProvider.dbAccessor = dbAccessor;
}
}

20
src/main/java/com/fr/plugin/xxxx/xxxx/sso/HandleRequestHandlerBridge.java

@ -0,0 +1,20 @@
package com.fr.plugin.xxxx.xxxx.sso;
import com.fr.decision.fun.HttpHandler;
import com.fr.decision.fun.impl.AbstractHttpHandlerProvider;
import com.fr.plugin.xxxx.xxxx.sso.handle.DeleteHandler;
/**
* @Author fr.open
* @Date 2021/11/16
* @Description
**/
public class HandleRequestHandlerBridge extends AbstractHttpHandlerProvider {
@Override
public HttpHandler[] registerHandlers() {
return new HttpHandler[]{
new DeleteHandler(),
};
}
}

19
src/main/java/com/fr/plugin/xxxx/xxxx/sso/HandleRequestURLAliasBridge.java

@ -0,0 +1,19 @@
package com.fr.plugin.xxxx.xxxx.sso;
import com.fr.decision.fun.impl.AbstractURLAliasProvider;
import com.fr.decision.webservice.url.alias.URLAlias;
import com.fr.decision.webservice.url.alias.URLAliasFactory;
/**
* @Author fr.open
* @Date 2021/11/16
* @Description
**/
public class HandleRequestURLAliasBridge extends AbstractURLAliasProvider {
@Override
public URLAlias[] registerAlias() {
return new URLAlias[]{
URLAliasFactory.createPluginAlias("/del", "/del", true),
};
}
}

37
src/main/java/com/fr/plugin/xxxx/xxxx/sso/LRGT.java

@ -0,0 +1,37 @@
package com.fr.plugin.xxxx.xxxx.sso;
import com.fr.plugin.context.PluginContext;
import com.fr.plugin.xxxx.xxxx.sso.conf.SsoConfig;
import com.fr.plugin.xxxx.xxxx.sso.entity.EarlyMessageAction;
import com.fr.plugin.xxxx.xxxx.sso.entity.EarlyMessageEntity;
import com.fr.plugin.xxxx.xxxx.sso.handle.EarlyMessageHandle;
import com.fr.plugin.observer.inner.AbstractPluginLifecycleMonitor;
import com.fr.schedule.feature.ScheduleOutputActionEntityRegister;
import com.fr.schedule.feature.output.OutputActionHandler;
/**
* 配置信息初始化
*/
public class LRGT extends AbstractPluginLifecycleMonitor {
@Override
public void afterRun(PluginContext pluginContext) {
SsoConfig.getInstance();
OutputActionHandler.registerHandler(new EarlyMessageHandle(), EarlyMessageAction.class.getName());
ScheduleOutputActionEntityRegister.getInstance().addClass(EarlyMessageEntity.class);
}
@Override
public void beforeStop(PluginContext pluginContext) {
OutputActionHandler.removeOutputHandler(EarlyMessageAction.class.getName());
ScheduleOutputActionEntityRegister.getInstance().removeClass(EarlyMessageEntity.class);
}
@Override
public void beforeUninstall(PluginContext pluginContext) {
}
@Override
public void afterInstall(PluginContext var1) {
}
}

69
src/main/java/com/fr/plugin/xxxx/xxxx/sso/PluginConstants.java

@ -0,0 +1,69 @@
package com.fr.plugin.xxxx.xxxx.sso;
/**
* @Author fr.open
* @Date 2020/12/05
* @Description
**/
public class PluginConstants {
public static final String PLUGIN_ID = "com.fr.plugin.xxxx.xxxx.sso";
public static final String PLUGIN_NAME = "Oauth2单点";
public final static String SEND_DATA = "<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:web=\"http://webservice.notify.sys.kmss.landray.com/\">\n" +
" <soapenv:Header/>\n" +
" <soapenv:Body>\n" +
" <web:sendTodo>\n" +
" <!--Optional:-->\n" +
" <arg0>\n" +
" <!--Optional:-->\n" +
" <appName>${appName}</appName>\n" +
" <!--Optional:-->\n" +
" <createTime>${createTime}</createTime>\n" +
" <!--Optional:-->\n" +
" <docCreator>{\"PersonNo\":\"${create}\"}</docCreator>\n" +
" <!--Optional:-->\n" +
" <key></key>\n" +
" <!--Optional:-->\n" +
" <link><![CDATA[${pcUrl}]]></link>\n" +
" <!--Optional:-->\n" +
" <mobileLink><![CDATA[${mobileUrl}]]></mobileLink>\n" +
" <!--Optional:-->\n" +
" <modelId>${id}</modelId>\n" +
" <!--Optional:-->\n" +
" <modelName>${modelName}</modelName>\n" +
" <padLink><![CDATA[${mobileUrl}]]></padLink>\n" +
" <!--Optional:-->\n" +
" <subject>${title}</subject>\n" +
" <!--Optional:-->\n" +
" <targets>${target}</targets>\n" +
" <!--Optional:-->\n" +
" <type>2</type>\n" +
" </arg0>\n" +
" </web:sendTodo>\n" +
" </soapenv:Body>\n" +
"</soapenv:Envelope>";
public final static String DEL_DATA = "<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:web=\"http://webservice.notify.sys.kmss.landray.com/\">\n" +
" <soapenv:Header/>\n" +
" <soapenv:Body>\n" +
" <web:deleteTodo>\n" +
" <!--Optional:-->\n" +
" <arg0>\n" +
" <!--Optional:-->\n" +
" <appName>${appName}</appName>\n" +
" <!--Optional:-->\n" +
" <key></key>\n" +
" <!--Optional:-->\n" +
" <modelId>${id}</modelId>\n" +
" <!--Optional:-->\n" +
" <modelName>${modelName}</modelName>\n" +
" <optType>1</optType>\n" +
" <targets></targets>\n" +
" <type>2</type>\n" +
" </arg0>\n" +
" </web:deleteTodo>\n" +
" </soapenv:Body>\n" +
"</soapenv:Envelope>";
}

44
src/main/java/com/fr/plugin/xxxx/xxxx/sso/ScheduleOutputDBAccess.java

@ -0,0 +1,44 @@
package com.fr.plugin.xxxx.xxxx.sso;
import com.fr.decision.plugin.db.AbstractDecisionDBAccessProvider;
import com.fr.plugin.xxxx.xxxx.sso.dao.EarlyMessageDao;
import com.fr.plugin.xxxx.xxxx.sso.entity.EarlyMessageEntity;
import com.fr.stable.db.accessor.DBAccessor;
import com.fr.stable.db.dao.BaseDAO;
import com.fr.stable.db.dao.DAOProvider;
/**
* @Author fr.open
* @Date 2020/12/05
* @Description
**/
public class ScheduleOutputDBAccess extends AbstractDecisionDBAccessProvider {
private static DBAccessor dbAccessor;
public DBAccessor getDbAccessor() {
return dbAccessor;
}
@Override
public DAOProvider[] registerDAO() {
return new DAOProvider[]{
new DAOProvider() {
@Override
public Class getEntityClass() {
return EarlyMessageEntity.class;
}
@Override
public Class<? extends BaseDAO> getDAOClass() {
return EarlyMessageDao.class;
}
}
};
}
@Override
public void onDBAvailable(DBAccessor dbAccessor) {
ScheduleOutputDBAccess.dbAccessor = dbAccessor;
}
}

213
src/main/java/com/fr/plugin/xxxx/xxxx/sso/SsoFilter.java

@ -0,0 +1,213 @@
package com.fr.plugin.xxxx.xxxx.sso;
import com.fr.base.TemplateUtils;
import com.fr.decision.fun.impl.AbstractGlobalRequestFilterProvider;
import com.fr.decision.webservice.bean.authentication.OriginUrlResponseBean;
import com.fr.decision.webservice.utils.DecisionStatusService;
import com.fr.decision.webservice.utils.WebServiceUtils;
import com.fr.general.PropertiesUtils;
import com.fr.intelli.record.Focus;
import com.fr.intelli.record.Original;
import com.fr.json.JSONObject;
import com.fr.locale.InterProviderFactory;
import com.fr.log.FineLoggerFactory;
import com.fr.plugin.context.PluginContexts;
import com.fr.plugin.xxxx.xxxx.sso.util.HttpUtil;
import com.fr.plugin.xxxx.xxxx.sso.util.LogUtils;
import com.fr.plugin.xxxx.xxxx.sso.util.SsoUtils;
import com.fr.plugin.transform.FunctionRecorder;
import com.fr.stable.StringUtils;
import com.fr.stable.fun.Authorize;
import com.fr.web.utils.WebUtils;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
import java.util.UUID;
/**
* @author fr.open
* @since 2021/12/04
*/
@FunctionRecorder
@Authorize(callSignKey = PluginConstants.PLUGIN_ID)
public class SsoFilter extends AbstractGlobalRequestFilterProvider {
private String apiClientId;
private String apiClientSecret;
private String apiAuthorize;
private String apiGetToken;
private String apiGetUser;
private void initParams() {
Properties props = PropertiesUtils.getProperties("zgts");
this.apiClientId = SsoUtils.getProperty(props, "api.client_id", "");
this.apiClientSecret = SsoUtils.getProperty(props, "api.client_secret", "");
this.apiAuthorize = SsoUtils.getProperty(props, "api.authorize", "");
this.apiGetToken = SsoUtils.getProperty(props, "api.get-token", "");
this.apiGetUser = SsoUtils.getProperty(props, "api.get-user", "");
}
@Override
public void init(FilterConfig filterConfig) {
super.init(filterConfig);
initParams();
}
@Override
public void doFilter(HttpServletRequest request, HttpServletResponse response, FilterChain chain) {
if (isAccept(request)|| SsoUtils.isLogin(request)) {
SsoUtils.next(request, response, chain);
return;
}
try {
//登录页面跳转地址拦截
String origin = WebUtils.getHTTPRequestParameter(request, "origin");
if (request.getRequestURI().endsWith("decision/login")) {
try {
if ("get".equalsIgnoreCase(request.getMethod()) && StringUtils.isNotBlank(origin)) {
OriginUrlResponseBean path = DecisionStatusService.originUrlStatusService().get(origin);
if (path != null) {
String currentPath = String.format("%s://%s:%s%s",request.getScheme(),request.getServerName(),request.getServerPort(),path.getOriginUrl());
jumpAuthorize(request, response, currentPath);
return;
}
}
} catch (Exception e) {
LogUtils.error(e.getMessage(), e);
}
SsoUtils.next(request, response, chain);
return;
}
String code = request.getParameter("code");
if (StringUtils.isBlank(code)) {
jumpAuthorize(request, response, "");
return;
}
String username = getUsername(getToken(code));
SsoUtils.login(username, request, response);
String state = request.getParameter("state");
if (StringUtils.isNotBlank(state)) {
String accessURL = SsoUtils.getCachedParam(state, "accessURL");
if (StringUtils.isNotBlank(accessURL)) {
response.sendRedirect(accessURL);
return;
}
}
SsoUtils.next(request, response, chain);
} catch (Exception e) {
LogUtils.error("oauth2单点登陆处理失败, Cause by: ", e);
setError(response, e.getMessage());
}
}
private String getUsername(String token) throws IOException {
String address = String.format("%s?access_token=%s&client_id=%s", apiGetUser, token, apiClientId);
HashMap<String, Object> params = new HashMap<>();
params.put("access_token", token);
String res = HttpUtil.sendGet(address,null, null);
LogUtils.debug4plugin("请求用户信息返回的内容 >>> [{}]", res);
JSONObject body = new JSONObject(res);
if (body.has("loginName")) {
return body.getString("loginName");
}
throw new RuntimeException("获取用户信息失败,Cause by: " + res);
}
private String getToken(String code) throws IOException {
String address = String.format("%s?client_id=%s&grant_type=authorization_code&code=%s&client_secret=%s", apiGetToken, apiClientId, code, apiClientSecret);
HashMap<String, Object> params = new HashMap<>();
params.put("client_id", apiClientId);
params.put("client_secret", apiClientSecret);
params.put("code", code);
params.put("grant_type", "authorization_code");
String res = HttpUtil.sendPost(address,null,JSONObject.create());
LogUtils.debug4plugin("请求 Token 接口返回的内容 >>> [{}]", res);
JSONObject body = new JSONObject(res);
if (body.has("access_token")) {
return body.getString("access_token");
}
throw new RuntimeException("获取access_token失败,Cause by: " + res);
}
private void jumpAuthorize(HttpServletRequest request, HttpServletResponse response, String originUrl) throws Exception {
String state = UUID.randomUUID().toString();
String accessURL = request.getRequestURL().toString();
Map<String, String> params = new HashMap<>();
if (StringUtils.isNotBlank(originUrl)) {
accessURL = String.format("%s://%s:%s%s",request.getScheme(),request.getServerName(),request.getServerPort(), TemplateUtils.render("${fineServletURL}"));;
params.put("accessURL", originUrl);
} else {
if (StringUtils.isNotBlank(request.getQueryString())) {
accessURL += "?" + request.getQueryString();
}
params.put("accessURL", accessURL);
}
SsoUtils.cacheParams(state, params);
String address = String.format("%s?redirect_uri=%s&state=%s&client_id=%s&response_type=code", apiAuthorize, URLEncoder.encode(accessURL, "UTF-8"), state, apiClientId);
LogUtils.debug4plugin("请求中不包含code值,跳转到登陆页面 >>> \"{}\"", address);
response.sendRedirect(address);
}
@Override
public String filterName() {
return "sso";
}
@Override
@Focus(id = PluginConstants.PLUGIN_ID, text = PluginConstants.PLUGIN_NAME, source = Original.PLUGIN)
public String[] urlPatterns() {
if (!PluginContexts.currentContext().isAvailable()) {
return new String[0];
}
return new String[]{
"/decision/",
"/decision/login",
"/decision",
"/decision/view/report",
"/decision/view/form",
//"/decision/schedule/result"
};
}
private boolean isAccept(HttpServletRequest request) {
if (request.getRequestURI().endsWith("/view/form") || request.getRequestURI().endsWith("/view/report")) {
if (StringUtils.isNotBlank(WebUtils.getHTTPRequestParameter(request, "code"))) {
return false;
}
return true;
}
return false;
}
private void setError(HttpServletResponse res, String reason) {
try {
PrintWriter printWriter = WebUtils.createPrintWriter(res);
Map<String, Object> map = new HashMap<>();
map.put("result", InterProviderFactory.getProvider().getLocText("Fine-Engine_Error_Page_Result"));
map.put("reason", reason);
map.put("solution", InterProviderFactory.getProvider().getLocText("Fine-Engine_Please_Contact_Platform_Admin"));
String page = WebServiceUtils.parseWebPageResourceSafe("com/fr/web/controller/decision/entrance/resources/unavailable.html", map);
printWriter.write(page);
printWriter.flush();
printWriter.close();
} catch (Exception e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
}
}
}

102
src/main/java/com/fr/plugin/xxxx/xxxx/sso/conf/SsoConfig.java

@ -0,0 +1,102 @@
package com.fr.plugin.xxxx.xxxx.sso.conf;
import com.fr.config.*;
import com.fr.config.holder.Conf;
import com.fr.config.holder.factory.Holders;
/**
* @author fr.open
* @since 2021/12/04
*/
@Visualization(category = "待办推送配置")
public class SsoConfig extends DefaultConfiguration {
private static volatile SsoConfig config = null;
public static SsoConfig getInstance() {
if (config == null) {
config = ConfigContext.getConfigInstance(SsoConfig.class);
}
return config;
}
@Identifier(value = "debugSwitch", name = "插件调试开关", description = "日志调试模式", status = Status.SHOW)
private Conf<Boolean> debugSwitch = Holders.simple(true);
@Identifier(value = "idSwitch", name = "启用编码", description = "推送消息启用编码字段", status = Status.SHOW)
private Conf<Boolean> idSwitch = Holders.simple(false);
public Boolean getIdSwitch() {
return this.idSwitch.get();
}
public void setIdSwitch(Boolean idSwitch) {
this.idSwitch.set(idSwitch);
}
public Boolean getDebugSwitch() {
return this.debugSwitch.get();
}
public void setDebugSwitch(Boolean debugSwitch) {
this.debugSwitch.set(debugSwitch);
}
@Identifier(value = "sendNotify", name = "推送地址", description = "推送待办地址", status = Status.SHOW)
private Conf<String> sendNotify = Holders.simple("");
public String getSendNotify() {
return sendNotify.get();
}
public void setSendNotify(String sendNotify) {
this.sendNotify.set(sendNotify);
}
@Identifier(value = "delNotify", name = "删除推送地址", description = "删除推送地址", status = Status.SHOW)
private Conf<String> delNotify = Holders.simple("");
public String getDelNotify() {
return delNotify.get();
}
public void setDelNotify(String delNotify) {
this.delNotify.set(delNotify);
}
@Identifier(value = "appName", name = "待办来源", description = "待办来源", status = Status.SHOW)
private Conf<String> appName = Holders.simple("");
public String getAppName() {
return appName.get();
}
public void setAppName(String appName) {
this.appName.set(appName);
}
@Identifier(value = "modelName", name = "模块名", description = "模块名", status = Status.SHOW)
private Conf<String> modelName = Holders.simple("");
public String getModelName() {
return modelName.get();
}
public void setModelName(String modelName) {
this.modelName.set(modelName);
}
@Override
public Object clone() throws CloneNotSupportedException {
SsoConfig cloned = (SsoConfig) super.clone();
cloned.debugSwitch = (Conf<Boolean>) debugSwitch.clone();
cloned.sendNotify = (Conf<String>) sendNotify.clone();
cloned.delNotify = (Conf<String>) delNotify.clone();
cloned.appName = (Conf<String>) appName.clone();
cloned.modelName = (Conf<String>) modelName.clone();
return cloned;
}
}

22
src/main/java/com/fr/plugin/xxxx/xxxx/sso/dao/EarlyMessageDao.java

@ -0,0 +1,22 @@
package com.fr.plugin.xxxx.xxxx.sso.dao;
import com.fr.plugin.xxxx.xxxx.sso.entity.EarlyMessageEntity;
import com.fr.stable.db.dao.BaseDAO;
import com.fr.stable.db.session.DAOSession;
/**
* @Author fr.open
* @Date 2020/12/05
* @Description
**/
public class EarlyMessageDao extends BaseDAO<EarlyMessageEntity> {
public EarlyMessageDao(DAOSession daoSession) {
super(daoSession);
}
@Override
protected Class<EarlyMessageEntity> getEntityClass() {
return EarlyMessageEntity.class;
}
}

22
src/main/java/com/fr/plugin/xxxx/xxxx/sso/dao/MessageSendDao.java

@ -0,0 +1,22 @@
package com.fr.plugin.xxxx.xxxx.sso.dao;
import com.fr.plugin.xxxx.xxxx.sso.entity.MessageSendEntity;
import com.fr.stable.db.dao.BaseDAO;
import com.fr.stable.db.session.DAOSession;
/**
* @Author fr.open
* @Date 2020/12/05
* @Description
**/
public class MessageSendDao extends BaseDAO<MessageSendEntity> {
public MessageSendDao(DAOSession daoSession) {
super(daoSession);
}
@Override
protected Class<MessageSendEntity> getEntityClass() {
return MessageSendEntity.class;
}
}

127
src/main/java/com/fr/plugin/xxxx/xxxx/sso/entity/EarlyMessageAction.java

@ -0,0 +1,127 @@
package com.fr.plugin.xxxx.xxxx.sso.entity;
import com.fr.schedule.base.bean.output.BaseOutputAction;
import com.fr.schedule.base.entity.AbstractScheduleEntity;
import com.fr.schedule.base.type.RunType;
import com.fr.third.fasterxml.jackson.annotation.JsonSubTypes;
/**
* @Author fr.open
* @Date 2020/12/05
* @Description
**/
@JsonSubTypes.Type(value = EarlyMessageAction.class, name = "EarlyMessageAction")
public class EarlyMessageAction extends BaseOutputAction {
private static final long serialVersionUID = -7083270486682938571L;
private int terminal = 32;
private String subject;
private String content;
private int type;
private int linkOpenType = -1;
private String mediaId;
private String customizeLink;
private int runType = RunType.CLIENT_NOTIFICATION.getValue();
@Override
public boolean willExecuteByUser() {
return true;
}
@Override
public RunType runType() {
return RunType.CLIENT_NOTIFICATION;
}
@Override
public Class<? extends AbstractScheduleEntity> outputActionEntityClass() {
return EarlyMessageEntity.class;
}
@Override
public EarlyMessageEntity createOutputActionEntity() {
EarlyMessageEntity entity = new EarlyMessageEntity();
entity.setId(this.getId());
entity.setContent(this.getContent());
entity.setSubject(this.getSubject());
entity.setTerminal(this.getTerminal());
entity.setType(this.getType());
entity.setLinkOpenType(this.getLinkOpenType());
entity.setCustomizeLink(this.getCustomizeLink());
entity.setMediaId(this.getMediaId());
return entity;
}
public int getTerminal() {
return terminal;
}
public void setTerminal(int terminal) {
this.terminal = terminal;
}
public String getSubject() {
return subject;
}
public void setSubject(String subject) {
this.subject = subject;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
public int getType() {
return type;
}
public void setType(int type) {
this.type = type;
}
public int getLinkOpenType() {
return linkOpenType;
}
public void setLinkOpenType(int linkOpenType) {
this.linkOpenType = linkOpenType;
}
public String getCustomizeLink() {
return customizeLink;
}
public void setCustomizeLink(String customizeLink) {
this.customizeLink = customizeLink;
}
public String getMediaId() {
return mediaId;
}
public void setMediaId(String mediaId) {
this.mediaId = mediaId;
}
public int getRunType() {
return runType;
}
public void setRunType(int runType) {
this.runType = runType;
}
}

153
src/main/java/com/fr/plugin/xxxx/xxxx/sso/entity/EarlyMessageEntity.java

@ -0,0 +1,153 @@
package com.fr.plugin.xxxx.xxxx.sso.entity;
import com.fr.schedule.base.entity.AbstractScheduleEntity;
import com.fr.stable.db.constant.EntityConstant;
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;
/**
* @Author fr.open
* @Date 2020/12/05
* @Description
**/
@Entity
@Table(name = "fine_early_message") //表名
@TableAssociation(associated = true)
public class EarlyMessageEntity extends AbstractScheduleEntity {
private static final String COLUMN_TERMINAL = "terminal";
private static final String COLUMN_AGENTID = "agentId";
private static final String COLUMN_SUBJECT = "subject";
private static final String COLUMN_CONTENT = "content";
private static final String COLUMN_LINK_OPEN_TYPE = "linkOpenType";
private static final String COLUMN_CUSTOMIZE_LINK = "customizeLink";
private static final String COLUMN_TYPE = "type";
private static final String COLUMN_MEDIA_ID = "mediaId";
private static final String COLUMN_ADDRESSEE = "addressee";
private static final String COLUMN_CHAT_GROUPS = "chatGroups";
@Column(name = COLUMN_TERMINAL)
private int terminal = 32;
@Column(name = COLUMN_AGENTID)
private String agentId = null;
@Column(name = COLUMN_SUBJECT, length = EntityConstant.STRING_LONG_SIZE)
private String subject;
@Column(name = COLUMN_CONTENT, length = EntityConstant.STRING_LONG_SIZE)
private String content;
@Column(name = COLUMN_LINK_OPEN_TYPE)
private int linkOpenType = -1;
@Column(name = COLUMN_CUSTOMIZE_LINK, length = EntityConstant.STRING_LONG_SIZE)
private String customizeLink;
@Column(name = COLUMN_TYPE)
private int type;
@Column(name = COLUMN_MEDIA_ID)
private String mediaId;
@Column(name = COLUMN_ADDRESSEE)
private int[] addressee;
@Column(name = COLUMN_CHAT_GROUPS, length = EntityConstant.STRING_LONG_SIZE)
private String[] chatGroups;
@Override
public EarlyMessageAction createBean() {
EarlyMessageAction bean = new EarlyMessageAction();
bean.setId(this.getId());
bean.setTerminal(this.getTerminal());
bean.setSubject(this.getSubject());
bean.setContent(this.getContent());
bean.setLinkOpenType(this.getLinkOpenType());
bean.setCustomizeLink(this.getCustomizeLink());
bean.setType(this.getType());
bean.setMediaId(this.getMediaId());
return bean;
}
public String getAgentId() {
return agentId;
}
public void setAgentId(String agentId) {
this.agentId = agentId;
}
public int getTerminal() {
return terminal;
}
public void setTerminal(int terminal) {
this.terminal = terminal;
}
public String getSubject() {
return subject;
}
public void setSubject(String subject) {
this.subject = subject;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
public int getLinkOpenType() {
return linkOpenType;
}
public void setLinkOpenType(int linkOpenType) {
this.linkOpenType = linkOpenType;
}
public String getCustomizeLink() {
return customizeLink;
}
public void setCustomizeLink(String customizeLink) {
this.customizeLink = customizeLink;
}
public int getType() {
return type;
}
public void setType(int type) {
this.type = type;
}
public String getMediaId() {
return mediaId;
}
public void setMediaId(String mediaId) {
this.mediaId = mediaId;
}
public int[] getAddressee() {
return addressee;
}
public void setAddressee(int[] addressee) {
this.addressee = addressee;
}
public String[] getChatGroups() {
return chatGroups;
}
public void setChatGroups(String[] chatGroups) {
this.chatGroups = chatGroups;
}
}

83
src/main/java/com/fr/plugin/xxxx/xxxx/sso/entity/MessageSendEntity.java

@ -0,0 +1,83 @@
package com.fr.plugin.xxxx.xxxx.sso.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;
/**
* @Author fr.open
* @Date 2020/12/05
* @Description
**/
@Entity
@Table(name = "plugin_early_send") //表名
public class MessageSendEntity extends BaseEntity {
@Column(name = "model_id")
private String modelId;
@Column(name = "task_name")
private String taskName;
@Column(name = "tag")
private int tag;
@Column(name = "send_time")
private Date sendTime;
@Column(name = "del_time")
private Date delTime;
@Column(name = "del_user")
private String delUser;
public MessageSendEntity() {
this.tag = 0;
}
public String getTaskName() {
return taskName;
}
public void setTaskName(String taskName) {
this.taskName = taskName;
}
public Date getSendTime() {
return sendTime;
}
public void setSendTime(Date sendTime) {
this.sendTime = sendTime;
}
public String getModelId() {
return modelId;
}
public void setModelId(String modelId) {
this.modelId = modelId;
}
public int getTag() {
return tag;
}
public void setTag(int tag) {
this.tag = tag;
}
public Date getDelTime() {
return delTime;
}
public void setDelTime(Date delTime) {
this.delTime = delTime;
}
public String getDelUser() {
return delUser;
}
public void setDelUser(String delUser) {
this.delUser = delUser;
}
}

102
src/main/java/com/fr/plugin/xxxx/xxxx/sso/handle/DeleteHandler.java

@ -0,0 +1,102 @@
package com.fr.plugin.xxxx.xxxx.sso.handle;
import com.fr.decision.fun.impl.BaseHttpHandler;
import com.fr.decision.webservice.Response;
import com.fr.decision.webservice.v10.user.UserService;
import com.fr.json.JSONObject;
import com.fr.plugin.xxxx.xxxx.sso.DelDBAccessProvider;
import com.fr.plugin.xxxx.xxxx.sso.PluginConstants;
import com.fr.plugin.xxxx.xxxx.sso.conf.SsoConfig;
import com.fr.plugin.xxxx.xxxx.sso.dao.MessageSendDao;
import com.fr.plugin.xxxx.xxxx.sso.entity.MessageSendEntity;
import com.fr.plugin.xxxx.xxxx.sso.util.LogUtils;
import com.fr.plugin.xxxx.xxxx.sso.util.WebServiceUtil;
import com.fr.stable.StringUtils;
import com.fr.stable.db.action.DBAction;
import com.fr.stable.db.dao.DAOContext;
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.Date;
/**
* @Author fr.open
* @Date 2021/11/16
* @Description
**/
public class DeleteHandler extends BaseHttpHandler {
@Override
public RequestMethod getMethod() {
return RequestMethod.GET;
}
@Override
public String getPath() {
return "/del";
}
@Override
public boolean isPublic() {
return true;
}
@Override
public void handle(HttpServletRequest req, HttpServletResponse res) throws Exception {
String id = req.getParameter("id");
LogUtils.debug4plugin("get id is {}", id);
Response response;
if (StringUtils.isBlank(id)) {
response = Response.error("entity_is_not_null", "id不能为空");
WebUtils.printAsJSON(res, JSONObject.mapFrom(response));
return;
}
String delNotify = SsoConfig.getInstance().getDelNotify();
if (StringUtils.isBlank(delNotify)) {
response = Response.error("delNotify_is_not_null", "删除地址配置不能为空");
WebUtils.printAsJSON(res, JSONObject.mapFrom(response));
return;
}
MessageSendEntity entity = DelDBAccessProvider.getDbAccessor().runDMLAction(new DBAction<MessageSendEntity>() {
@Override
public MessageSendEntity run(DAOContext daoContext) throws Exception {
return daoContext.getDAO(MessageSendDao.class).getById(id);
}
});
String userId = UserService.getInstance().getCurrentUserIdFromCookie(req);
if (entity != null) {
if(entity.getTag() == 1){
response = Response.error("entity_is_deleted", "当前消息已删除");
WebUtils.printAsJSON(res, JSONObject.mapFrom(response));
return;
}
String body = PluginConstants.DEL_DATA.replace("${id}", entity.getId())
.replace("${appName}", SsoConfig.getInstance().getAppName())
.replace("${modelName}", SsoConfig.getInstance().getModelName());
LogUtils.debug4plugin("send url is {} body is {}", delNotify, body);
String xml = WebServiceUtil.sendWebService(delNotify, body);
LogUtils.debug4plugin("send delete res is {}",xml);
if(StringUtils.isBlank(xml)){
response = Response.error("del_todo_fail", "删除失败");
WebUtils.printAsJSON(res, JSONObject.mapFrom(response));
return;
}
entity.setDelTime(new Date());
entity.setDelUser(userId);
entity.setTag(1);
DelDBAccessProvider.getDbAccessor().runDMLAction(new DBAction() {
@Override
public MessageSendEntity run(DAOContext daoContext) throws Exception {
daoContext.getDAO(MessageSendDao.class).update(entity);
return entity;
}
});
response = Response.ok("success");
} else {
response = Response.error("entity_is_null", "删除记录不存在");
}
WebUtils.printAsJSON(res, JSONObject.mapFrom(response));
}
}

122
src/main/java/com/fr/plugin/xxxx/xxxx/sso/handle/EarlyMessageHandle.java

@ -0,0 +1,122 @@
package com.fr.plugin.xxxx.xxxx.sso.handle;
import com.fr.base.Formula;
import com.fr.decision.authority.data.User;
import com.fr.decision.webservice.v10.user.UserService;
import com.fr.plugin.xxxx.xxxx.sso.DelDBAccessProvider;
import com.fr.plugin.xxxx.xxxx.sso.PluginConstants;
import com.fr.plugin.xxxx.xxxx.sso.conf.SsoConfig;
import com.fr.plugin.xxxx.xxxx.sso.dao.MessageSendDao;
import com.fr.plugin.xxxx.xxxx.sso.entity.EarlyMessageAction;
import com.fr.plugin.xxxx.xxxx.sso.entity.MessageSendEntity;
import com.fr.plugin.xxxx.xxxx.sso.util.LogUtils;
import com.fr.plugin.xxxx.xxxx.sso.util.WebServiceUtil;
import com.fr.schedule.base.constant.ScheduleConstants;
import com.fr.schedule.feature.output.OutputActionHandler;
import com.fr.stable.CodeUtils;
import com.fr.stable.StringUtils;
import com.fr.stable.db.action.DBAction;
import com.fr.stable.db.dao.DAOContext;
import com.fr.third.org.apache.commons.lang3.time.DateFormatUtils;
import org.json.JSONArray;
import org.json.JSONObject;
import java.util.*;
/**
* @Author fr.open
* @Date 2020/12/05
* @Description
**/
public class EarlyMessageHandle extends OutputActionHandler<EarlyMessageAction> {
@Override
public void doAction(EarlyMessageAction output, Map<String, Object> map) throws Exception {
String[] users = (String[]) map.get(ScheduleConstants.USERNAMES);
String taskName = CodeUtils.encodeURIComponent((String) map.get(ScheduleConstants.TASK_NAME));
String path = CodeUtils.encodeURIComponent((String) map.get(ScheduleConstants.SAVE_DIRECTORY));
path = path.replaceAll("\\+", "%20");
String showType = (String) map.get(ScheduleConstants.SHOW_TYPE);
int taskType = (Integer) map.get(ScheduleConstants.TASK_TYPE);
String scheduleUsername = (String) map.get(ScheduleConstants.USERNAME);
Set<String> userSet = new HashSet();
if (StringUtils.isNotBlank(scheduleUsername)) {
userSet.add(scheduleUsername);
} else {
userSet.addAll(Arrays.asList(users));
}
LogUtils.debug4plugin("send schedule user is {}", userSet);
String pcUrl = output.getResultURL() + "/schedule/result?taskName=" + taskName + "&username=" + scheduleUsername + "&path=" + path + "&showType=" + showType + "&taskType=" + taskType;
LogUtils.debug4plugin("get pc result is {}", pcUrl);
String mobileUrl = output.getResultURL() + "/url/mobile/schedule/result?taskName=" + taskName + "&username=" + scheduleUsername + "&path=" + path + "&showType=" + showType + "&taskType=" + taskType;
LogUtils.debug4plugin("get mobile url is {}", mobileUrl);
Iterator<String> it = userSet.iterator();
JSONArray array = new JSONArray();
while (it.hasNext()) {
String user = it.next();
JSONObject object = new JSONObject();
object.put("PersonNo", getCode(user));
array.put(object);
}
String title = StringUtils.isNotBlank(output.getSubject()) ? output.getSubject() : getParam(map, "title");
String id = UUID.randomUUID().toString();
String sendNotify = SsoConfig.getInstance().getSendNotify();
String create = (String) map.get(ScheduleConstants.TASK_CREATOR);
String body = PluginConstants.SEND_DATA.replace("${title}", title)
.replace("${create}", getCode(create))
.replace("${appName}", SsoConfig.getInstance().getAppName())
.replace("${target}", array.toString())
.replace("${modelName}", SsoConfig.getInstance().getModelName())
.replace("${createTime}", DateFormatUtils.format(new Date(), "yyyy-MM-dd HH:mm:ss"))
.replace("${pcUrl}", pcUrl)
.replaceAll("\\$\\{mobileUrl}", mobileUrl)
.replace("${id}", id)
.replace("${mobileUrl}", mobileUrl);
LogUtils.debug4plugin("send url is {} body is {}", sendNotify, body);
String res = WebServiceUtil.sendWebService(sendNotify, body);
LogUtils.debug4plugin("send add res is {}", res);
if (StringUtils.isNotBlank(res)) {
MessageSendEntity entity = new MessageSendEntity();
entity.setId(id);
entity.setSendTime(new Date());
entity.setTaskName((String) map.get(ScheduleConstants.TASK_NAME));
DelDBAccessProvider.getDbAccessor().runDMLAction(new DBAction() {
@Override
public Object run(DAOContext daoContext) throws Exception {
daoContext.getDAO(MessageSendDao.class).add(entity);
return null;
}
});
}
}
private String getCode(String userName) {
if (SsoConfig.getInstance().getIdSwitch()) {
try {
User user = UserService.getInstance().getUserByUserName(userName);
if (user != null && StringUtils.isNotBlank(user.getId())) {
return user.getId();
}
} catch (Exception e) {
e.printStackTrace();
}
}
return userName;
}
private String getParam(Map<String, Object> map, String p) {
List<Map> list = (List) map.get(ScheduleConstants.RECORD_LIST);
Object title = StringUtils.EMPTY;
Object param = list.get(0).get(p);
if (param instanceof Formula) {
Formula formula = (Formula) param;
title = formula.getResult();
} else {
if (param != null) {
title = param.toString();
}
}
return title.toString();
}
}

55
src/main/java/com/fr/plugin/xxxx/xxxx/sso/js/FileDef.java

@ -0,0 +1,55 @@
package com.fr.plugin.xxxx.xxxx.sso.js;
import com.fr.plugin.transform.ExecuteFunctionRecord;
import com.fr.web.struct.Component;
import com.fr.web.struct.Filter;
import com.fr.web.struct.browser.RequestClient;
import com.fr.web.struct.category.ScriptPath;
import com.fr.web.struct.category.StylePath;
/**
* @Author fr.open
* @Date 2020/12/05
* @Description
**/
public class FileDef extends Component {
public static final FileDef KEY = new FileDef();
private FileDef(){}
/**
* 返回需要引入的JS脚本路径
* @param client 请求客户端描述
* @return JS脚本路径
*/
@Override
public ScriptPath script(RequestClient client ) {
//如果不需要就直接返回 ScriptPath.EMPTY
return ScriptPath.build("com/fr/plugin/xxxx/xxxx/sso/theme.js");
}
/**
* 返回需要引入的CSS样式路径
* @param client 请求客户端描述
* @return CSS样式路径
*/
@Override
public StylePath style(RequestClient client ) {
//如果不需要就直接返回 StylePath.EMPTY;
return StylePath.EMPTY;
}
/**
* 通过给定的资源过滤器控制是否加载这个资源
* @return 资源过滤器
*/
@ExecuteFunctionRecord
@Override
public Filter filter() {
return new Filter(){
@Override
public boolean accept() {
//任何情况下我们都在平台组件加载时加载我们的组件
return true;
}
};
}
}

22
src/main/java/com/fr/plugin/xxxx/xxxx/sso/js/FunctionJSProvider.java

@ -0,0 +1,22 @@
package com.fr.plugin.xxxx.xxxx.sso.js;
import com.fr.stable.fun.impl.AbstractJavaScriptFileHandler;
/**
* @Author fr.open
* @Date 2020/12/05
* @Description
**/
public class FunctionJSProvider extends AbstractJavaScriptFileHandler {
@Override
public String[] pathsForFiles() {
return new String[]{
"/com/fr/plugin/xxxx/xxxx/sso/function.js"
};
}
@Override
public String encode() {
return "UTF-8";
}
}

26
src/main/java/com/fr/plugin/xxxx/xxxx/sso/js/JSCSSBridge.java

@ -0,0 +1,26 @@
package com.fr.plugin.xxxx.xxxx.sso.js;
import com.fr.decision.fun.impl.AbstractWebResourceProvider;
import com.fr.decision.web.MainComponent;
import com.fr.plugin.transform.FunctionRecorder;
import com.fr.web.struct.Atom;
/**
* @Author fr.open
* @Date 2020/12/05
* @Description
**/
@FunctionRecorder
public class JSCSSBridge extends AbstractWebResourceProvider {
@Override
public Atom attach() {
//在平台主组件加载时添加我们自己的组件
return MainComponent.KEY;
}
@Override
public Atom client() {
//我们自己要引入的组件
return FileDef.KEY;
}
}

237
src/main/java/com/fr/plugin/xxxx/xxxx/sso/util/HttpUtil.java

@ -0,0 +1,237 @@
package com.fr.plugin.xxxx.xxxx.sso.util;
import com.fr.json.JSONObject;
import com.fr.log.FineLoggerFactory;
import com.fr.stable.StringUtils;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLSession;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.util.Iterator;
import java.util.Map;
import java.util.stream.Collectors;
/**
* @Author fr.open
* @Date 2020/12/05
* @Description
**/
public class HttpUtil {
private static HostnameVerifier hv = new HostnameVerifier() {
@Override
public boolean verify(String urlHostName, SSLSession session) {
System.out.println("Warning: URL Host: " + urlHostName + " vs. "
+ session.getPeerHost());
return true;
}
};
/**
* 发送get请求
*
* @param url
* @param param
* @param header
* @return
* @throws IOException
*/
public static String sendGet(String url, Map<String, String> param, Map<String, String> header) {
String result = "";
BufferedReader in = null;
String urlNameString = url;
try {
if (param != null) {
urlNameString += "?";
urlNameString += param.entrySet()
.stream()
.map(entry -> entry.getKey() + "=" + entry.getValue())
.collect(Collectors.joining("&"));
}
URL realUrl = new URL(urlNameString);
// 打开和URL之间的连接
HttpURLConnection connection;
if (url.startsWith("https")) {
trustAllHttpsCertificates();
HttpsURLConnection.setDefaultHostnameVerifier(hv);
connection = (HttpURLConnection) realUrl.openConnection();
} else {
connection = (HttpURLConnection) realUrl.openConnection();
}
//设置超时时间
connection.setDoInput(true);
connection.setRequestMethod("GET");
connection.setConnectTimeout(5000);
connection.setReadTimeout(15000);
// 设置通用的请求属性
if (header != null) {
Iterator<Map.Entry<String, String>> it = header.entrySet().iterator();
while (it.hasNext()) {
Map.Entry<String, String> entry = it.next();
System.out.println(entry.getKey() + ":::" + entry.getValue());
connection.setRequestProperty(entry.getKey(), entry.getValue());
}
}
connection.setRequestProperty("accept", "*/*");
connection.setRequestProperty("connection", "Keep-Alive");
connection.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
// 建立实际的连接
connection.connect();
// 定义 BufferedReader输入流来读取URL的响应,设置utf8防止中文乱码
in = new BufferedReader(new InputStreamReader(connection.getInputStream(), "utf-8"));
String line;
while ((line = in.readLine()) != null) {
result += line;
}
if (in != null) {
in.close();
}
}catch (Exception e){
FineLoggerFactory.getLogger().error(e,"get url error ,url is:{},error is {}",urlNameString,e.getMessage());
}
return result;
}
public static String sendPost(String url,Map<String,String> header, JSONObject body) {
PrintWriter out = null;
BufferedReader in = null;
String result = StringUtils.EMPTY;
String res = StringUtils.EMPTY;
try {
String urlNameString = url;
URL realUrl = new URL(urlNameString);
// 打开和URL之间的连接
HttpURLConnection conn;
if (url.startsWith("https")) {
trustAllHttpsCertificates();
HttpsURLConnection.setDefaultHostnameVerifier(hv);
conn = (HttpURLConnection) realUrl.openConnection();
} else {
conn = (HttpURLConnection) realUrl.openConnection();
}
// 设置通用的请求属性
conn.setRequestProperty("accept", "*/*");
conn.setRequestProperty("connection", "Keep-Alive");
conn.setRequestProperty("user-agent",
"Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
conn.setRequestProperty("Content-Type","application/json;;charset=UTF-8");
//conn.setRequestProperty("Content-Type", "multipart/form-data; boundary=----footfoodapplicationrequestnetwork");
if(header != null){
header.forEach((k, v) -> {
conn.setRequestProperty(k, v);
});
}
// 发送POST请求必须设置如下两行
conn.setDoOutput(true);
conn.setDoInput(true);
//获取请求头
// 获取URLConnection对象对应的输出流
out = new PrintWriter(conn.getOutputStream());
StringBuffer buffer = new StringBuffer();
/*param.forEach((k,v)->{
buffer.append("------footfoodapplicationrequestnetwork\r\n");
buffer.append("Content-Disposition: form-data; name=\"");
buffer.append(k);
buffer.append("\"\r\n\r\n");
buffer.append(v);
buffer.append("\r\n");
});
buffer.append("------footfoodapplicationrequestnetwork--\r\n");
out.print(buffer.toString());*/
// 发送请求参数
if(body != null){
out.print(body.toString());
}
// flush输出流的缓冲
out.flush();
// 定义BufferedReader输入流来读取URL的响应
in = new BufferedReader(
new InputStreamReader(conn.getInputStream()));
String line;
while ((line = in.readLine()) != null) {
result += line;
}
res = result;
} catch (Exception e) {
FineLoggerFactory.getLogger().error(e.getMessage(),e);
}
//使用finally块来关闭输出流、输入流
finally{
try{
if(out!=null){
out.close();
}
if(in!=null){
in.close();
}
}
catch(IOException e){
FineLoggerFactory.getLogger().error(e.getMessage(),e);
}
}
return res;
}
private static void trustAllHttpsCertificates() throws Exception {
javax.net.ssl.TrustManager[] trustAllCerts = new javax.net.ssl.TrustManager[1];
javax.net.ssl.TrustManager tm = new miTM();
trustAllCerts[0] = tm;
javax.net.ssl.SSLContext sc = javax.net.ssl.SSLContext.getInstance("SSL","SunJSSE");
sc.init(null, trustAllCerts, null);
HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
}
/**
* encode url by UTF-8
* @param url url before encoding
* @return url after encoding
*/
public static String encodeUrl(String url){
String eurl = url;
try {
eurl = URLEncoder.encode(url,"UTF-8");
} catch (UnsupportedEncodingException e) {
}
return eurl;
}
private static class miTM implements javax.net.ssl.TrustManager,
javax.net.ssl.X509TrustManager {
@Override
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
return null;
}
public boolean isServerTrusted(
java.security.cert.X509Certificate[] certs) {
return true;
}
public boolean isClientTrusted(
java.security.cert.X509Certificate[] certs) {
return true;
}
@Override
public void checkServerTrusted(
java.security.cert.X509Certificate[] certs, String authType)
throws java.security.cert.CertificateException {
return;
}
@Override
public void checkClientTrusted(
java.security.cert.X509Certificate[] certs, String authType)
throws java.security.cert.CertificateException {
return;
}
}
}

121
src/main/java/com/fr/plugin/xxxx/xxxx/sso/util/LogUtils.java

@ -0,0 +1,121 @@
package com.fr.plugin.xxxx.xxxx.sso.util;
import com.fr.log.FineLoggerFactory;
import com.fr.log.FineLoggerProvider;
import com.fr.plugin.context.PluginContexts;
import com.fr.plugin.xxxx.xxxx.sso.conf.SsoConfig;
import com.fr.stable.StringUtils;
/**
* @author fr.open
* @since 2021/12/04
*/
public final class LogUtils {
private static final String DEBUG_PREFIX = "[插件调试] ";
private static String LOG_PREFIX = "[OAUTH2单点登陆] ";
private static final String PLUGIN_VERSION;
private static final FineLoggerProvider LOGGER = FineLoggerFactory.getLogger();
static {
String version = PluginContexts.currentContext().getMarker().getVersion();
if (StringUtils.isNotBlank(version)) {
PLUGIN_VERSION = "[v" + version + "] ";
} else {
PLUGIN_VERSION = "[unknown version] ";
}
LOG_PREFIX = LOG_PREFIX + PLUGIN_VERSION;
}
public static void setPrefix(String prefix) {
if (prefix != null) {
LOG_PREFIX = prefix;
}
}
public static boolean isDebugEnabled() {
return LOGGER.isDebugEnabled();
}
public static void debug(String s) {
LOGGER.debug(LOG_PREFIX + s);
}
public static void debug(String s, Object... objects) {
LOGGER.debug(LOG_PREFIX + s, objects);
}
public static void debug(String s, Throwable throwable) {
LOGGER.debug(LOG_PREFIX + s, throwable);
}
public static void debug4plugin(String s) {
if (SsoConfig.getInstance().getDebugSwitch()) {
LOGGER.error(DEBUG_PREFIX + LOG_PREFIX + s);
} else {
LOGGER.debug(LOG_PREFIX + s);
}
}
public static void debug4plugin(String s, Object... objects) {
if (SsoConfig.getInstance().getDebugSwitch()) {
LOGGER.error(DEBUG_PREFIX + LOG_PREFIX + s, objects);
} else {
LOGGER.debug(LOG_PREFIX + s, objects);
}
}
public static void debug4plugin(String s, Throwable throwable) {
if (SsoConfig.getInstance().getDebugSwitch()) {
LOGGER.error(DEBUG_PREFIX + LOG_PREFIX + s, throwable);
} else {
LOGGER.debug(LOG_PREFIX + s, throwable);
}
}
public static boolean isInfoEnabled() {
return LOGGER.isInfoEnabled();
}
public static void info(String s) {
LOGGER.info(LOG_PREFIX + s);
}
public static void info(String s, Object... objects) {
LOGGER.info(LOG_PREFIX + s, objects);
}
public static void warn(String s) {
LOGGER.warn(LOG_PREFIX + s);
}
public static void warn(String s, Object... objects) {
LOGGER.warn(LOG_PREFIX + s, objects);
}
public static void warn(String s, Throwable throwable) {
LOGGER.warn(LOG_PREFIX + s, throwable);
}
public static void warn(Throwable throwable, String s, Object... objects) {
LOGGER.warn(throwable, LOG_PREFIX + s, objects);
}
public static void error(String s) {
LOGGER.error(LOG_PREFIX + s);
}
public static void error(String s, Object... objects) {
LOGGER.error(LOG_PREFIX + s, objects);
}
public static void error(String s, Throwable throwable) {
LOGGER.error(LOG_PREFIX + s, throwable);
}
public static void error(Throwable throwable, String s, Object... objects) {
LOGGER.error(throwable, LOG_PREFIX + s, objects);
}
}

125
src/main/java/com/fr/plugin/xxxx/xxxx/sso/util/SsoUtils.java

@ -0,0 +1,125 @@
package com.fr.plugin.xxxx.xxxx.sso.util;
import com.fr.data.NetworkHelper;
import com.fr.decision.authority.data.User;
import com.fr.decision.mobile.terminal.TerminalHandler;
import com.fr.decision.webservice.exception.user.UserNotExistException;
import com.fr.decision.webservice.utils.DecisionServiceConstants;
import com.fr.decision.webservice.utils.DecisionStatusService;
import com.fr.decision.webservice.v10.login.LoginService;
import com.fr.decision.webservice.v10.login.TokenResource;
import com.fr.decision.webservice.v10.user.UserService;
import com.fr.log.FineLoggerFactory;
import com.fr.stable.StringUtils;
import com.fr.stable.web.Device;
import com.fr.web.utils.WebUtils;
import javax.servlet.FilterChain;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Map;
import java.util.Properties;
/**
* @Author fr.open
* @Date 2020/12/05
* @Description
**/
public class SsoUtils {
public static String getProperty(Properties props, String key, String defaultValue) {
String value = props.getProperty(key);
if (StringUtils.isNotBlank(value)) {
return value;
}
return defaultValue;
}
public static String getProperty(Properties props, String key) {
return getProperty(props, key, null);
}
public static boolean isLogin(HttpServletRequest request) {
String oldToken = TokenResource.COOKIE.getToken(request);
return oldToken != null && checkTokenValid(request, (String) oldToken);
}
private static boolean checkTokenValid(HttpServletRequest req, String token) {
try {
Device device = NetworkHelper.getDevice(req);
LoginService.getInstance().loginStatusValid(token, TerminalHandler.getTerminal(req, device));
return true;
} catch (Exception ignore) {
}
return false;
}
/**
* 跳转到过滤器链中的下一个过滤器
*
* @param request
* @param response
* @param chain
*/
public static void next(HttpServletRequest request, HttpServletResponse response, FilterChain chain) {
try {
chain.doFilter(request, response);
} catch (Exception e) {
FineLoggerFactory.getLogger().error(e.getMessage(),e);
}
}
public static void login(String username, HttpServletRequest request, HttpServletResponse response) {
try {
User user = UserService.getInstance().getUserByUserName(username);
if (user == null) {
throw new UserNotExistException();
}
String token = LoginService.getInstance().login(request, response, user.getUserName());
request.setAttribute(DecisionServiceConstants.FINE_AUTH_TOKEN_NAME, token);
} catch (Exception e) {
FineLoggerFactory.getLogger().error("sso >> Failed to login with[" + username + "]", e);
throw new RuntimeException("用户\"" + username + "\"登录失败");
}
}
public static boolean isMobileDevice(HttpServletRequest request) {
if (WebUtils.getDevice(request).isMobile()) {
LogUtils.debug4plugin("current request is is mobile request ,url is {}", request.getRequestURI());
return true;
}
String requestHeader = request.getHeader("user-agent");
String[] deviceArray = new String[]{"android", "iphone", "ipad", "ios", "windows phone", "wechat"};
if (requestHeader == null) {
return false;
}
requestHeader = requestHeader.toLowerCase();
for (int i = 0; i < deviceArray.length; i++) {
if (requestHeader.toLowerCase().contains(deviceArray[i])) {
LogUtils.debug4plugin("current request:{} is mobile request!", request.getRequestURI());
return true;
}
}
String op = WebUtils.getHTTPRequestParameter(request, "op");
return StringUtils.isNotBlank(op) && StringUtils.equals("h5", op);
}
public static void cacheParams(String key, Map<String, String> values) {
try {
DecisionStatusService.originUrlStatusService().put(key, values);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
public static String getCachedParam(String key, String name) {
try {
Map<String, String> values = DecisionStatusService.originUrlStatusService().get(key);
return values.get(name);
} catch (Exception e) {
}
return "";
}
}

50
src/main/java/com/fr/plugin/xxxx/xxxx/sso/util/WebServiceUtil.java

@ -0,0 +1,50 @@
package com.fr.plugin.xxxx.xxxx.sso.util;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;
/**
* @Author fr.open
* @Date 2021/12/7
* @Description
**/
public class WebServiceUtil {
public static String sendWebService(String send, String body) {
StringBuffer sb = new StringBuffer();
try {
URL url = new URL(send);
URLConnection conn = url.openConnection();
HttpURLConnection con = (HttpURLConnection) conn;
con.setDoInput(true);
con.setDoOutput(true);
con.setRequestMethod("POST");
con.setRequestProperty("content-type", "text/xml;charset=UTF-8");
OutputStream out = con.getOutputStream();
out.write(body.getBytes());
out.close();
int code = con.getResponseCode();
if (code == 200) {
InputStream is = con.getInputStream();
byte[] b = new byte[1024];
int len = 0;
while ((len = is.read(b)) != -1) {
String str = new String(b, 0, len, "UTF-8");
sb.append(str);
}
is.close();
}
con.disconnect();
} catch (Exception e) {
LogUtils.debug4plugin(e.getMessage(),e);
}
return sb.toString();
}
}

20
src/main/resources/com/fr/plugin/xxxx/xxxx/sso/function.js

@ -0,0 +1,20 @@
$.extend(FR, {
notifyTodoDelete: function (id) {
if (FR.isEmpty(id)) {
FR.Msg.alert("", "id不能为空");
return;
}
FR.ajax({
url:FR.fineServletURL + "/url/del?id=" + id,
timeout: 10000,
success:function(data){
var res = FR.jsonDecode(data);
if (FR.equals(res.data, "success")) {
FR.Msg.toast("删除成功");
} else {
FR.Msg.alert("", res.errorMsg);
}
}
});
}
});

58
src/main/resources/com/fr/plugin/xxxx/xxxx/sso/theme.js

@ -0,0 +1,58 @@
!(function () {
BI.config("dec.constant.account.items",function( items ){
//把type: "dec.user.account.setting.item"的去掉
debugger;
items.splice(2,1)
return items;
});
var TodoTerminalType = 32;
Dec.Plugin.OutPutActionProvider.items.push({
version: 1.0,
terminalType: TodoTerminalType,
terminalText: BI.i18nText("待办消息推送"),
getItem: function () {
var self = this;
return {
type: "bi.label",
text: BI.i18nText("提示:勾选待办消息推送"),
textAlign: "left",
cls: "bi-disabled",
height: 24,
ref: function (_ref) {
self.welinkItem = _ref;
}
}
},
setValue: function (v) {
if (v.terminal && v.terminal === TodoTerminalType) {
this.value = v;
}
},
getValue: function () {
var self = this;
// actionName最后一个点后面的类名要和这个return的json的字段名一致
// console.log(123);
return {
EarlyMessageAction: BI.extend(self.value, {
"@class": "com.fr.plugin.xxxx.xxxx.sso.entity.EarlyMessageAction",
actionName: "com.fr.plugin.xxxx.xxxx.sso.entity.EarlyMessageAction",
terminal: TodoTerminalType
})
}
},
checkValid: function () {
return this.getValue()?true:false;
},
fireEvent: function (v) {
}
});
}) ();

9
src/main/resources/zgts.properties

@ -0,0 +1,9 @@
##Oauth2配置
api.client_id=xxxxxx
api.client_secret=xxxxxx
##跳转登录地址
api.authorize=https://127.0.0.1:8080/idp/oauth2/authorize
##获取token地址
api.get-token=https://127.0.0.1:8080/idp/oauth2/getToken
##解析用户地址
api.get-user=https://127.0.0.1:8080/idp/oauth2/getUserInfo
Loading…
Cancel
Save