commit d0fd3597f35a524e1f17f040069364ace1501a06 Author: pioneer Date: Thu Nov 24 11:03:20 2022 +0800 open diff --git a/README.md b/README.md new file mode 100644 index 0000000..6bde4cd --- /dev/null +++ b/README.md @@ -0,0 +1,6 @@ +# open-JSD-10138 + +JSD-10138 竹云单点登录(PC+移动端)+用户同步\ +免责说明:该源码为第三方爱好者提供,不保证源码和方案的可靠性,也不提供任何形式的源码教学指导和协助!\ +仅作为开发者学习参考使用!禁止用于任何商业用途!\ +为保护开发者隐私,开发者信息已隐去!若原开发者希望公开自己的信息,可联系【pioneer】处理。 \ No newline at end of file diff --git a/lib/banboocloud_Codec-0.0.1.jar b/lib/banboocloud_Codec-0.0.1.jar new file mode 100644 index 0000000..79476d9 Binary files /dev/null and b/lib/banboocloud_Codec-0.0.1.jar differ diff --git a/plugin.xml b/plugin.xml new file mode 100644 index 0000000..a0a770e --- /dev/null +++ b/plugin.xml @@ -0,0 +1,33 @@ + + com.fr.plugin.xx.gxkg + + yes + 1.8 + 10.0 + 2018-07-31 + fr.open + + + [2022-07-27]【1.1】去掉报文加密。
+ [2022-07-29]【1.2】兼容空加密密码。
+ [2022-07-29]【1.3】移除签名认证。
+ [2022-07-29]【1.4】接口返回字段修改。
+ [2022-08-03]【1.5】接口字段交互定义。
+ [2022-08-05]【1.6】部门同步逻辑修改。
+ [2022-08-05]【1.7】部门用户状态修改。
+ [2022-08-08]【1.8】更新逻辑调整+单点接口路径调整。
+ ]]>
+ + + + + + + + + + + + +
\ No newline at end of file diff --git a/src/main/java/com/fr/plugin/xx/gxkg/PluginConstants.java b/src/main/java/com/fr/plugin/xx/gxkg/PluginConstants.java new file mode 100644 index 0000000..60af0af --- /dev/null +++ b/src/main/java/com/fr/plugin/xx/gxkg/PluginConstants.java @@ -0,0 +1,13 @@ +package com.fr.plugin.xx.gxkg; + +/** + * @author xx + * @since 2021/12/04 + */ +public class PluginConstants { + + public static final String PLUGIN_ID = "com.fr.plugin.xx.gxkg"; + + public static final String PLUGIN_NAME = "国新控股单点"; + +} diff --git a/src/main/java/com/fr/plugin/xx/gxkg/bean/AttributeEntity.java b/src/main/java/com/fr/plugin/xx/gxkg/bean/AttributeEntity.java new file mode 100644 index 0000000..5afef8f --- /dev/null +++ b/src/main/java/com/fr/plugin/xx/gxkg/bean/AttributeEntity.java @@ -0,0 +1,40 @@ +package com.fr.plugin.xx.gxkg.bean; + +public class AttributeEntity { + private String name; + private String type; + private boolean isRequired; + private boolean isMultivalued; + + public String getName() { + return this.name; + } + + public void setName(String name) { + this.name = name; + } + + public String getType() { + return this.type; + } + + public void setType(String type) { + this.type = type; + } + + public boolean isRequired() { + return this.isRequired; + } + + public void setRequired(boolean isRequired) { + this.isRequired = isRequired; + } + + public boolean isMultivalued() { + return this.isMultivalued; + } + + public void setMultivalued(boolean isMultivalued) { + this.isMultivalued = isMultivalued; + } +} \ No newline at end of file diff --git a/src/main/java/com/fr/plugin/xx/gxkg/bean/ResponseEntity.java b/src/main/java/com/fr/plugin/xx/gxkg/bean/ResponseEntity.java new file mode 100644 index 0000000..1571435 --- /dev/null +++ b/src/main/java/com/fr/plugin/xx/gxkg/bean/ResponseEntity.java @@ -0,0 +1,97 @@ +package com.fr.plugin.xx.gxkg.bean; + +import java.util.UUID; + +/** + * 方法执行成功后的响应对象 + */ +public class ResponseEntity { + + private String message; + + private String resultCode; + + private String guid; + + private boolean success; + + private String uid; + + public ResponseEntity() { + + } + + public static ResponseEntity ok() { + return new ResponseEntity("success", "0", UUID.randomUUID().toString(), true); + } + + public static ResponseEntity error(String message) { + return new ResponseEntity(message, "-1", UUID.randomUUID().toString(), true); + } + + + public ResponseEntity(String message, String code, String guid, boolean success) { + this.message = message; + this.resultCode = code; + this.guid = guid; + this.success = success; + } + + public ResponseEntity(String message, String code, String guid, boolean success, String uid) { + this.message = message; + this.resultCode = code; + this.guid = guid; + this.success = success; + this.uid = uid; + } + + public static ResponseEntity ok(String id) { + return new ResponseEntity("success", "0", UUID.randomUUID().toString(), true, id); + } + + public String getUid() { + return uid; + } + + public void setUid(String uid) { + this.uid = uid; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public String getResultCode() { + return resultCode; + } + + public void setResultCode(String resultCode) { + this.resultCode = resultCode; + } + + public String getGuid() { + return guid; + } + + public void setGuid(String guid) { + this.guid = guid; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + @Override + public String toString() { + return "ServiceResponse [message=" + message + ", resultCode=" + resultCode + + ", success=" + success + "]"; + } +} diff --git a/src/main/java/com/fr/plugin/xx/gxkg/bean/SchemaEntity.java b/src/main/java/com/fr/plugin/xx/gxkg/bean/SchemaEntity.java new file mode 100644 index 0000000..018841c --- /dev/null +++ b/src/main/java/com/fr/plugin/xx/gxkg/bean/SchemaEntity.java @@ -0,0 +1,28 @@ +package com.fr.plugin.xx.gxkg.bean; + +import java.util.List; + +public class SchemaEntity { + + private String objectClass ; + + private List attrs ; + + public String getObjectClass() { + return objectClass; + } + + public void setObjectClass(String objectClass) { + this.objectClass = objectClass; + } + + public List getAttrs() { + return attrs; + } + + public void setAttrs(List attrs) { + this.attrs = attrs; + } + + +} diff --git a/src/main/java/com/fr/plugin/xx/gxkg/conf/GxkgSsoConfig.java b/src/main/java/com/fr/plugin/xx/gxkg/conf/GxkgSsoConfig.java new file mode 100644 index 0000000..735898d --- /dev/null +++ b/src/main/java/com/fr/plugin/xx/gxkg/conf/GxkgSsoConfig.java @@ -0,0 +1,164 @@ +package com.fr.plugin.xx.gxkg.conf; + +import com.fr.config.*; +import com.fr.config.holder.Conf; +import com.fr.config.holder.factory.Holders; +import com.fr.intelli.record.Focus; +import com.fr.intelli.record.Original; +import com.fr.record.analyzer.EnableMetrics; +import com.fr.stable.StringUtils; + +/** + * @author xx + * @date 2021/11/04 + */ +@Visualization(category = "国新控股单点配置") +@EnableMetrics +public class GxkgSsoConfig extends DefaultConfiguration { + + private static volatile GxkgSsoConfig config = null; + + @Focus(id="com.fr.plugin.sso.sykg.extra", text = "SYKG-SSO配置", source = Original.PLUGIN) + public static GxkgSsoConfig getInstance() { + if (config == null) { + config = ConfigContext.getConfigInstance(GxkgSsoConfig.class); + } + return config; + } + + @Identifier(value = "debugSwitch", name = "日志调试模式", description = "日志调试模式", status = Status.SHOW) + private Conf debugSwitch = Holders.simple(true); + + public Boolean getdebugSwitch() { return debugSwitch.get(); } + + public void setdebugSwitch(Boolean debugSwitch) { this.debugSwitch.set(debugSwitch); } + + @Identifier(value = "redirect", name = "帆软服务回跳地址", description = "帆软服务回跳地址,http://ip:port/webroot/decision", status = Status.SHOW) + private Conf redirect = Holders.simple(StringUtils.EMPTY); + + public String getRedirect() { + return redirect.get(); + } + + public void setRedirect(String redirect) { + this.redirect.set(redirect); + } + + @Identifier(value = "loginUrl", name = "跳转登录地址", description = "跳转登录地址,http://ip:port/idp/authCenter/authenticate", status = Status.SHOW) + private Conf loginUrl = Holders.simple(StringUtils.EMPTY); + + public String getLoginUrl() { + return loginUrl.get(); + } + + public void setLoginUrl(String loginUrl) { + this.loginUrl.set(loginUrl); + } + + @Identifier(value = "tokenUrl", name = "获取token地址", description = "获取token地址,http://ip:port/bam-protocol-service/oauth2/getToken", status = Status.SHOW) + private Conf tokenUrl = Holders.simple(StringUtils.EMPTY); + + public String getTokenUrl() { + return tokenUrl.get(); + } + + public void setTokenUrl(String tokenUrl) { + this.tokenUrl.set(tokenUrl); + } + + @Identifier(value = "userUrl", name = "获取用户信息地址", description = "获取用户信息地址,http://ip:port/bam-protocol-service/oauth2/getUserInfo", status = Status.SHOW) + private Conf userUrl = Holders.simple(StringUtils.EMPTY); + + public String getUserUrl() { + return userUrl.get(); + } + + + @Identifier(value = "logoutUrl", name = "登出路径地址", description = "登出路径地址,http://ip:port/idp/authCenter/GLO", status = Status.SHOW) + private Conf logoutUrl = Holders.simple(StringUtils.EMPTY); + + public String getLogoutUrl() { + return logoutUrl.get(); + } + + public void setLogoutUrl(String logoutUrl) { + this.logoutUrl.set(logoutUrl); + } + + @Identifier(value = "clientId", name = "clientId", description = "clientId", status = Status.SHOW) + private Conf clientId = Holders.simple(StringUtils.EMPTY); + + public String getClientId() { + return clientId.get(); + } + + public void setClientId(String clientId) { + this.clientId.set(clientId); + } + + @Identifier(value = "clientSecret", name = "clientSecret", description = "clientSecret", status = Status.SHOW) + private Conf clientSecret = Holders.simple(StringUtils.EMPTY); + + public String getClientSecret() { + return clientSecret.get(); + } + + public void setClientSecret(String clientSecret) { + this.clientSecret.set(clientSecret); + } + + @Identifier(value = "decodePwd", name = "报文解密秘钥", description = "报文解密秘钥", status = Status.SHOW) + private Conf decodePwd = Holders.simple(StringUtils.EMPTY); + + public String getDecodePwd() { + return decodePwd.get(); + } + + public void setDecodePwd(String decodePwd) { + this.decodePwd.set(decodePwd); + } + + @Identifier(value = "syncUser", name = "同步授权用户", description = "同步授权用户", status = Status.SHOW) + private Conf syncUser = Holders.simple(StringUtils.EMPTY); + + public String getSyncUser() { + return syncUser.get(); + } + + public void setSyncUser(String syncUser) { + this.syncUser.set(syncUser); + } + + @Identifier(value = "syncPass", name = "同步授权用户密码", description = "同步授权用户密码", status = Status.SHOW) + private Conf syncPass = Holders.simple(StringUtils.EMPTY); + + public String getSyncPass() { + return syncPass.get(); + } + + public void setSyncPass(String syncPass) { + this.syncPass.set(syncPass); + } + + @Identifier(value = "defaultPost", name = "默认职位", description = "默认职位", status = Status.SHOW) + private Conf defaultPost = Holders.simple("部门成员"); + + public String getDefaultPost() { + return defaultPost.get(); + } + + public void setDefaultPost(String defaultPost) { + this.defaultPost.set(defaultPost); + } + + @Override + public Object clone() throws CloneNotSupportedException { + GxkgSsoConfig cloned = (GxkgSsoConfig) super.clone(); + + cloned.debugSwitch = (Conf) debugSwitch.clone(); + + return cloned; + } + + +} diff --git a/src/main/java/com/fr/plugin/xx/gxkg/handler/AbstractSyncHandler.java b/src/main/java/com/fr/plugin/xx/gxkg/handler/AbstractSyncHandler.java new file mode 100644 index 0000000..0e55480 --- /dev/null +++ b/src/main/java/com/fr/plugin/xx/gxkg/handler/AbstractSyncHandler.java @@ -0,0 +1,124 @@ +package com.fr.plugin.xx.gxkg.handler; + +import com.banboocloud.Codec.BamboocloudFacade; +import com.fr.decision.authority.AuthorityContext; +import com.fr.decision.authority.base.constant.type.operation.ManualOperationType; +import com.fr.decision.authority.data.Department; +import com.fr.decision.authority.data.User; +import com.fr.decision.fun.impl.BaseHttpHandler; +import com.fr.decision.webservice.bean.user.DepartmentPostBean; +import com.fr.decision.webservice.v10.user.PositionService; +import com.fr.decision.webservice.v10.user.UserService; +import com.fr.json.JSONObject; +import com.fr.plugin.xx.gxkg.bean.ResponseEntity; +import com.fr.plugin.xx.gxkg.conf.GxkgSsoConfig; +import com.fr.plugin.xx.gxkg.utils.BamboocloudUtils; +import com.fr.plugin.xx.gxkg.utils.LogUtils; +import com.fr.stable.StringUtils; +import com.fr.web.utils.WebUtils; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.util.List; + +/** + * @Author xx + * @Date 2022/7/7 + * @Description + **/ +public abstract class AbstractSyncHandler extends BaseHttpHandler { + + private String requestId; + + @Override + public void handle(HttpServletRequest req, HttpServletResponse res) throws Exception { + GxkgSsoConfig config = GxkgSsoConfig.getInstance(); + if (StringUtils.isBlank(config.getSyncUser()) || StringUtils.isBlank(config.getSyncPass())) { + setResult(res, JSONObject.mapFrom(ResponseEntity.error("配置为空"))); + return; + } + String bodyparam = BamboocloudUtils.getRequestBody(req); + if (StringUtils.isBlank(bodyparam)) { + setResult(res, JSONObject.mapFrom(ResponseEntity.error("报文为空"))); + return; + } + if(StringUtils.isNotBlank(config.getDecodePwd())){ + bodyparam = BamboocloudUtils.getPlaintext(bodyparam, config.getDecodePwd(), "AES"); + } + JSONObject body = new JSONObject(bodyparam); + /*if (!BamboocloudUtils.verify(body.getMap(), "MD5").booleanValue()) { + setResult(res, JSONObject.mapFrom(ResponseEntity.error("报文签名认证失败"))); + return; + }*/ + requestId = body.getString("bimRequestId"); + String username = body.getString("bimRemoteUser"); + String password = body.getString("bimRemotePwd"); + if (!BamboocloudUtils.checkUsernamePassword(username, password)) { + setResult(res, JSONObject.mapFrom(ResponseEntity.error("同步用户认证失败"))); + return; + } + try { + LogUtils.debug4plugin("current url is {}, body is {}", req.getRequestURL(), body); + setResult(res, syncHandle(body)); + } catch (Exception e) { + setResult(res, JSONObject.mapFrom(ResponseEntity.error("同步失败:" + e.getMessage()))); + return; + } + } + + protected void setResult(HttpServletResponse res, JSONObject result) { + try { + result.put("bimRequestId",requestId); + String body = result.toString(); + if (StringUtils.isNotBlank(GxkgSsoConfig.getInstance().getDecodePwd())) { + body = BamboocloudFacade.encrypt(result.toString(), GxkgSsoConfig.getInstance().getDecodePwd(), "AES"); + } + WebUtils.printAsString(res, body); + } catch (Exception e) { + LogUtils.error(e.getMessage(), e); + } + } + + protected abstract JSONObject syncHandle(JSONObject body) throws Exception; + + + protected User cover2User(JSONObject body) { + return (new User()).id(body.getString("bimUid")).password(body.getString("password")).userName(body.getString("oaAccount")) + .realName(body.getString("fullName")).creationType(ManualOperationType.KEY) + .lastOperationType(ManualOperationType.KEY).enable(body.getBoolean("__ENABLE__")); + } + + protected String generateDefaultPosition(String depID) throws Exception { + String positionName = GxkgSsoConfig.getInstance().getDefaultPost(); + String adminId = UserService.getInstance().getAdminUserIdList().get(0); + List postBeanList = PositionService.getInstance().getPositionsUnderParentDepartment(adminId, depID, null); + boolean hasDefaultPosition = false; + String positionId = ""; + for (DepartmentPostBean postBean : postBeanList) { + if (StringUtils.equals(positionName, postBean.getText())) { + return postBean.getId(); + } + } + List postBeans = PositionService.getInstance().getPositions(adminId, null); + for (DepartmentPostBean postBean : postBeans) { + if (StringUtils.equals(positionName, postBean.getText())) { + hasDefaultPosition = true; + positionId = postBean.getId(); + } + } + if (!hasDefaultPosition) { + positionId = PositionService.getInstance().addPosition(positionName).getId(); + } + AuthorityContext.getInstance().getPostController().addPostToDepartment(positionId, depID); + return positionId; + } + + protected Department cover2Dept(JSONObject body) { + String parent = body.getString("parOrgId"); + if (StringUtils.isBlank(parent)) { + parent = null; + } + String id = StringUtils.isBlank(body.getString("bimOrgId"))?body.getString("orgCode"):body.getString("bimOrgId"); + return (new Department()).id(id).name(body.getString("orgName")).parentId(parent).creationType(ManualOperationType.KEY).lastOperationType(ManualOperationType.KEY).enable(body.getBoolean("__ENABLE__")); + } +} diff --git a/src/main/java/com/fr/plugin/xx/gxkg/handler/HRGT.java b/src/main/java/com/fr/plugin/xx/gxkg/handler/HRGT.java new file mode 100644 index 0000000..247b0f9 --- /dev/null +++ b/src/main/java/com/fr/plugin/xx/gxkg/handler/HRGT.java @@ -0,0 +1,31 @@ +package com.fr.plugin.xx.gxkg.handler; + +import com.fr.decision.fun.HttpHandler; +import com.fr.decision.fun.impl.AbstractHttpHandlerProvider; +import com.fr.plugin.xx.gxkg.handler.action.SchemaHandler; +import com.fr.plugin.xx.gxkg.handler.action.org.CreateOrgHandler; +import com.fr.plugin.xx.gxkg.handler.action.org.DeleteOrgHandler; +import com.fr.plugin.xx.gxkg.handler.action.org.UpdateOrgHandler; +import com.fr.plugin.xx.gxkg.handler.action.user.CreateUserHandler; +import com.fr.plugin.xx.gxkg.handler.action.user.DeleteUserHandler; +import com.fr.plugin.xx.gxkg.handler.action.user.UpdateUserHandler; + +/** + * @Author xx + * @Date 2021/11/27 + * @Description + **/ +public class HRGT extends AbstractHttpHandlerProvider { + @Override + public HttpHandler[] registerHandlers() { + return new HttpHandler[]{ + new SchemaHandler(), + new CreateUserHandler(), + new UpdateUserHandler(), + new DeleteUserHandler(), + new CreateOrgHandler(), + new DeleteOrgHandler(), + new UpdateOrgHandler(), + }; + } +} diff --git a/src/main/java/com/fr/plugin/xx/gxkg/handler/URGT.java b/src/main/java/com/fr/plugin/xx/gxkg/handler/URGT.java new file mode 100644 index 0000000..7016ded --- /dev/null +++ b/src/main/java/com/fr/plugin/xx/gxkg/handler/URGT.java @@ -0,0 +1,27 @@ +package com.fr.plugin.xx.gxkg.handler; + +import com.fr.decision.fun.impl.AbstractURLAliasProvider; +import com.fr.decision.webservice.url.alias.URLAlias; +import com.fr.decision.webservice.url.alias.URLAliasFactory; + +/** + * @Author xx + * @Date 2021/11/27 + * @Description + **/ +public class URGT extends AbstractURLAliasProvider { + @Override + public URLAlias[] registerAlias() { + return new URLAlias[]{ + URLAliasFactory.createPluginAlias("/sync/SchemaService", "/sync/SchemaService", true), + + URLAliasFactory.createPluginAlias("/sync/UserCreateService", "/sync/UserCreateService", true), + URLAliasFactory.createPluginAlias("/sync/UserUpdateService", "/sync/UserUpdateService", true), + URLAliasFactory.createPluginAlias("/sync/UserDeleteService", "/sync/UserDeleteService", true), + + URLAliasFactory.createPluginAlias("/sync/OrgCreateService", "/sync/OrgCreateService", true), + URLAliasFactory.createPluginAlias("/sync/OrgUpdateService", "/sync/OrgUpdateService", true), + URLAliasFactory.createPluginAlias("/sync/OrgDeleteService", "/sync/OrgDeleteService", true), + }; + } +} diff --git a/src/main/java/com/fr/plugin/xx/gxkg/handler/action/SchemaHandler.java b/src/main/java/com/fr/plugin/xx/gxkg/handler/action/SchemaHandler.java new file mode 100644 index 0000000..d6bd4d4 --- /dev/null +++ b/src/main/java/com/fr/plugin/xx/gxkg/handler/action/SchemaHandler.java @@ -0,0 +1,129 @@ +package com.fr.plugin.xx.gxkg.handler.action; + +import com.fr.json.JSONObject; +import com.fr.plugin.xx.gxkg.bean.AttributeEntity; +import com.fr.plugin.xx.gxkg.handler.AbstractSyncHandler; +import com.fr.third.springframework.web.bind.annotation.RequestMethod; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * @Author xx + * @Date 2021/11/27 + * @Description + **/ +public class SchemaHandler extends AbstractSyncHandler { + @Override + public RequestMethod getMethod() { + return RequestMethod.POST; + } + + @Override + public String getPath() { + return "/sync/SchemaService"; + } + + @Override + public boolean isPublic() { + return true; + } + + @Override + protected JSONObject syncHandle(JSONObject body) { + Map schema = new HashMap(); + List accountAttrList = new ArrayList(); + + AttributeEntity attr1 = new AttributeEntity(); + attr1.setType("String"); + attr1.setName("oaAccount"); + attr1.setRequired(true); + attr1.setMultivalued(false); + accountAttrList.add(attr1); + + AttributeEntity attr2 = new AttributeEntity(); + attr2.setType("String"); + attr2.setName("orgId"); + attr2.setRequired(true); + attr2.setMultivalued(false); + accountAttrList.add(attr2); + + AttributeEntity attr3 = new AttributeEntity(); + attr3.setType("String"); + attr3.setName("fullName"); + attr3.setRequired(true); + attr3.setMultivalued(false); + accountAttrList.add(attr3); + + AttributeEntity attr4 = new AttributeEntity(); + attr4.setType("String"); + attr4.setName("bimUid"); + attr4.setRequired(true); + attr4.setMultivalued(false); + accountAttrList.add(attr4); + + AttributeEntity attr5 = new AttributeEntity(); + attr5.setType("Boolean"); + attr5.setName("state"); + attr5.setRequired(true); + attr5.setMultivalued(false); + accountAttrList.add(attr5); + + AttributeEntity attr6 = new AttributeEntity(); + attr6.setType("String"); + attr6.setName("password"); + attr6.setRequired(true); + attr6.setMultivalued(false); + accountAttrList.add(attr6); + + AttributeEntity attr7 = new AttributeEntity(); + attr7.setType("Boolean"); + attr7.setName("__ENABLE__"); + attr7.setRequired(true); + attr7.setMultivalued(false); + accountAttrList.add(attr7); + + schema.put("account", accountAttrList); + + List orgattrlist = new ArrayList(); + AttributeEntity org1 = new AttributeEntity(); + org1.setType("String"); + org1.setName("orgName"); + org1.setRequired(true); + org1.setMultivalued(false); + orgattrlist.add(org1); + + AttributeEntity org3 = new AttributeEntity(); + org3.setType("String"); + org3.setName("parOrgId"); + org3.setRequired(true); + org3.setMultivalued(false); + orgattrlist.add(org3); + + AttributeEntity org4 = new AttributeEntity(); + org4.setType("Boolean"); + org4.setName("__ENABLE__"); + org4.setRequired(true); + org4.setMultivalued(false); + orgattrlist.add(org4); + + AttributeEntity org5 = new AttributeEntity(); + org5.setType("String"); + org5.setName("bimOrgId"); + org5.setRequired(true); + org5.setMultivalued(false); + orgattrlist.add(org5); + + AttributeEntity org6 = new AttributeEntity(); + org6.setType("String"); + org6.setName("orgCode"); + org6.setRequired(true); + org6.setMultivalued(false); + orgattrlist.add(org6); + + schema.put("organization", orgattrlist); + return new JSONObject(schema); + } +} diff --git a/src/main/java/com/fr/plugin/xx/gxkg/handler/action/org/CreateOrgHandler.java b/src/main/java/com/fr/plugin/xx/gxkg/handler/action/org/CreateOrgHandler.java new file mode 100644 index 0000000..93d8a65 --- /dev/null +++ b/src/main/java/com/fr/plugin/xx/gxkg/handler/action/org/CreateOrgHandler.java @@ -0,0 +1,44 @@ +package com.fr.plugin.xx.gxkg.handler.action.org; + +import com.fr.decision.authority.AuthorityContext; +import com.fr.decision.authority.data.Department; +import com.fr.json.JSONObject; +import com.fr.plugin.xx.gxkg.bean.ResponseEntity; +import com.fr.plugin.xx.gxkg.handler.AbstractSyncHandler; +import com.fr.stable.query.QueryFactory; +import com.fr.stable.query.restriction.RestrictionFactory; +import com.fr.third.springframework.web.bind.annotation.RequestMethod; + +/** + * @Author xx + * @Date 2021/11/27 + * @Description + **/ +public class CreateOrgHandler extends AbstractSyncHandler { + @Override + public RequestMethod getMethod() { + return RequestMethod.POST; + } + + @Override + public String getPath() { + return "/sync/OrgCreateService"; + } + + @Override + public boolean isPublic() { + return true; + } + + @Override + protected JSONObject syncHandle(JSONObject body) throws Exception { + Department department = super.cover2Dept(body); + department.setEnable(true); + Department query = AuthorityContext.getInstance().getDepartmentController().findOne(QueryFactory.create().addRestriction(RestrictionFactory.eq("id", department.getId()))); + if (query != null) { + return JSONObject.mapFrom(ResponseEntity.error("部门已存在")); + } + AuthorityContext.getInstance().getDepartmentController().add(department); + return JSONObject.mapFrom(ResponseEntity.ok(department.getId())); + } +} diff --git a/src/main/java/com/fr/plugin/xx/gxkg/handler/action/org/DeleteOrgHandler.java b/src/main/java/com/fr/plugin/xx/gxkg/handler/action/org/DeleteOrgHandler.java new file mode 100644 index 0000000..b2ba860 --- /dev/null +++ b/src/main/java/com/fr/plugin/xx/gxkg/handler/action/org/DeleteOrgHandler.java @@ -0,0 +1,43 @@ +package com.fr.plugin.xx.gxkg.handler.action.org; + +import com.fr.decision.authority.AuthorityContext; +import com.fr.decision.authority.data.Department; +import com.fr.json.JSONObject; +import com.fr.plugin.xx.gxkg.bean.ResponseEntity; +import com.fr.plugin.xx.gxkg.handler.AbstractSyncHandler; +import com.fr.stable.query.QueryFactory; +import com.fr.stable.query.restriction.RestrictionFactory; +import com.fr.third.springframework.web.bind.annotation.RequestMethod; + +/** + * @Author xx + * @Date 2021/11/27 + * @Description + **/ +public class DeleteOrgHandler extends AbstractSyncHandler { + @Override + public RequestMethod getMethod() { + return RequestMethod.POST; + } + + @Override + public String getPath() { + return "/sync/OrgDeleteService"; + } + + @Override + public boolean isPublic() { + return true; + } + + @Override + protected JSONObject syncHandle(JSONObject body) throws Exception { + String department = body.getString("bimOrgId"); + Department query = AuthorityContext.getInstance().getDepartmentController().findOne(QueryFactory.create().addRestriction(RestrictionFactory.eq("id", department))); + if (query == null) { + return JSONObject.mapFrom(ResponseEntity.error("部门不存在")); + } + AuthorityContext.getInstance().getDepartmentController().remove(department); + return JSONObject.mapFrom(ResponseEntity.ok()); + } +} diff --git a/src/main/java/com/fr/plugin/xx/gxkg/handler/action/org/UpdateOrgHandler.java b/src/main/java/com/fr/plugin/xx/gxkg/handler/action/org/UpdateOrgHandler.java new file mode 100644 index 0000000..8844794 --- /dev/null +++ b/src/main/java/com/fr/plugin/xx/gxkg/handler/action/org/UpdateOrgHandler.java @@ -0,0 +1,58 @@ +package com.fr.plugin.xx.gxkg.handler.action.org; + +import com.fr.decision.authority.AuthorityContext; +import com.fr.decision.authority.data.Department; +import com.fr.json.JSONObject; +import com.fr.plugin.xx.gxkg.bean.ResponseEntity; +import com.fr.plugin.xx.gxkg.handler.AbstractSyncHandler; +import com.fr.stable.StringUtils; +import com.fr.stable.query.QueryFactory; +import com.fr.stable.query.restriction.RestrictionFactory; +import com.fr.third.springframework.web.bind.annotation.RequestMethod; + +/** + * @Author xx + * @Date 2021/11/27 + * @Description + **/ +public class UpdateOrgHandler extends AbstractSyncHandler { + @Override + public RequestMethod getMethod() { + return RequestMethod.POST; + } + + @Override + public String getPath() { + return "/sync/OrgUpdateService"; + } + + @Override + public boolean isPublic() { + return true; + } + + @Override + protected JSONObject syncHandle(JSONObject body) throws Exception { + + String id = StringUtils.isBlank(body.getString("bimOrgId")) ? body.getString("orgCode") : body.getString("bimOrgId"); + Department department = AuthorityContext.getInstance().getDepartmentController().findOne(QueryFactory.create().addRestriction(RestrictionFactory.eq("id", id))); + if (department == null) { + return JSONObject.mapFrom(ResponseEntity.error("部门不存在")); + } + if (body.has("orgName") && StringUtils.isNotBlank(body.getString("orgName"))) { + department.setName(body.getString("orgName")); + } + if (body.has("__ENABLE__") && StringUtils.isNotBlank(body.getString("__ENABLE__"))) { + department.setEnable(body.getBoolean("__ENABLE__")); + } + if (body.has("parOrgId")) { + String parent = body.getString("parOrgId"); + if (StringUtils.isBlank(parent)) { + parent = null; + } + department.setParentId(parent); + } + AuthorityContext.getInstance().getDepartmentController().update(department); + return JSONObject.mapFrom(ResponseEntity.ok()); + } +} diff --git a/src/main/java/com/fr/plugin/xx/gxkg/handler/action/user/CreateUserHandler.java b/src/main/java/com/fr/plugin/xx/gxkg/handler/action/user/CreateUserHandler.java new file mode 100644 index 0000000..21f337d --- /dev/null +++ b/src/main/java/com/fr/plugin/xx/gxkg/handler/action/user/CreateUserHandler.java @@ -0,0 +1,66 @@ +package com.fr.plugin.xx.gxkg.handler.action.user; + +import com.fr.decision.authority.AuthorityContext; +import com.fr.decision.authority.base.constant.type.operation.ManualOperationType; +import com.fr.decision.authority.data.Department; +import com.fr.decision.authority.data.User; +import com.fr.decision.base.util.UUIDUtil; +import com.fr.decision.privilege.encrpt.PasswordValidator; +import com.fr.decision.webservice.bean.user.DepPostUserUpdateBean; +import com.fr.decision.webservice.utils.UserSourceFactory; +import com.fr.decision.webservice.v10.user.UserService; +import com.fr.json.JSONObject; +import com.fr.plugin.xx.gxkg.bean.ResponseEntity; +import com.fr.plugin.xx.gxkg.handler.AbstractSyncHandler; +import com.fr.plugin.xx.gxkg.utils.LogUtils; +import com.fr.third.springframework.web.bind.annotation.RequestMethod; + +/** + * @Author xx + * @Date 2021/11/27 + * @Description + **/ +public class CreateUserHandler extends AbstractSyncHandler { + @Override + public RequestMethod getMethod() { + return RequestMethod.POST; + } + + @Override + public String getPath() { + return "/sync/UserCreateService"; + } + + @Override + public boolean isPublic() { + return true; + } + + @Override + protected JSONObject syncHandle(JSONObject body) throws Exception { + User user = super.cover2User(body); + String uuid = UUIDUtil.generate(); + user.setEnable(true); + PasswordValidator validator = UserSourceFactory.getInstance().getUserSource(ManualOperationType.KEY).getPasswordValidator(); + user.password(validator.encode(user.getPassword(), uuid, uuid)).salt(uuid); + User userByUserName = UserService.getInstance().getUserByUserName(user.getUserName()); + if (userByUserName != null) { + return JSONObject.mapFrom(ResponseEntity.error("用户名重复")); + } + AuthorityContext.getInstance().getUserController().add(user); + String uid = body.getString("orgId"); + Department query = AuthorityContext.getInstance().getDepartmentController().getById(uid); + if (query != null) { + String postId = super.generateDefaultPosition(uid); + DepPostUserUpdateBean bean = new DepPostUserUpdateBean(); + bean.setDepartmentId(uid); + bean.setPostId(postId); + bean.setAddUserIds(new String[]{user.getId()}); + LogUtils.debug4plugin("create user {} to dep-[{}] post-[{}]", user.getUserName(), uid, postId); + UserService.getInstance().updateDepartmentPostUsers(uid, postId, bean); + } else { + LogUtils.debug4plugin("org {} not exist", uid); + } + return JSONObject.mapFrom(ResponseEntity.ok(user.getId())); + } +} diff --git a/src/main/java/com/fr/plugin/xx/gxkg/handler/action/user/DeleteUserHandler.java b/src/main/java/com/fr/plugin/xx/gxkg/handler/action/user/DeleteUserHandler.java new file mode 100644 index 0000000..6410e14 --- /dev/null +++ b/src/main/java/com/fr/plugin/xx/gxkg/handler/action/user/DeleteUserHandler.java @@ -0,0 +1,43 @@ +package com.fr.plugin.xx.gxkg.handler.action.user; + +import com.fr.decision.authority.data.User; +import com.fr.decision.webservice.bean.user.UserUpdateBean; +import com.fr.decision.webservice.v10.user.UserService; +import com.fr.json.JSONObject; +import com.fr.plugin.xx.gxkg.bean.ResponseEntity; +import com.fr.plugin.xx.gxkg.handler.AbstractSyncHandler; +import com.fr.third.springframework.web.bind.annotation.RequestMethod; + +/** + * @Author xx + * @Date 2021/11/27 + * @Description + **/ +public class DeleteUserHandler extends AbstractSyncHandler { + @Override + public RequestMethod getMethod() { + return RequestMethod.POST; + } + + @Override + public String getPath() { + return "/sync/UserDeleteService"; + } + + @Override + public boolean isPublic() { + return true; + } + + @Override + protected JSONObject syncHandle(JSONObject body) throws Exception { + User user = UserService.getInstance().getUserByUserId(body.getString("bimUid")); + if (user == null) { + return JSONObject.mapFrom(ResponseEntity.error("用户不存在")); + } + UserUpdateBean userUpdateBean = new UserUpdateBean(); + userUpdateBean.setRemoveUserIds(new String[]{user.getId()}); + UserService.getInstance().deleteUsers(userUpdateBean); + return JSONObject.mapFrom(ResponseEntity.ok()); + } +} diff --git a/src/main/java/com/fr/plugin/xx/gxkg/handler/action/user/UpdateUserHandler.java b/src/main/java/com/fr/plugin/xx/gxkg/handler/action/user/UpdateUserHandler.java new file mode 100644 index 0000000..ed9ff17 --- /dev/null +++ b/src/main/java/com/fr/plugin/xx/gxkg/handler/action/user/UpdateUserHandler.java @@ -0,0 +1,78 @@ +package com.fr.plugin.xx.gxkg.handler.action.user; + +import com.fr.decision.authority.AuthorityContext; +import com.fr.decision.authority.base.constant.type.operation.ManualOperationType; +import com.fr.decision.authority.data.Department; +import com.fr.decision.authority.data.User; +import com.fr.decision.base.util.UUIDUtil; +import com.fr.decision.privilege.encrpt.PasswordValidator; +import com.fr.decision.webservice.bean.user.DepPostUserUpdateBean; +import com.fr.decision.webservice.utils.UserSourceFactory; +import com.fr.decision.webservice.v10.user.UserService; +import com.fr.json.JSONObject; +import com.fr.plugin.xx.gxkg.bean.ResponseEntity; +import com.fr.plugin.xx.gxkg.handler.AbstractSyncHandler; +import com.fr.plugin.xx.gxkg.utils.LogUtils; +import com.fr.stable.StringUtils; +import com.fr.third.springframework.web.bind.annotation.RequestMethod; + +/** + * @Author xx + * @Date 2021/11/27 + * @Description + **/ +public class UpdateUserHandler extends AbstractSyncHandler { + @Override + public RequestMethod getMethod() { + return RequestMethod.POST; + } + + @Override + public String getPath() { + return "/sync/UserUpdateService"; + } + + @Override + public boolean isPublic() { + return true; + } + + @Override + protected JSONObject syncHandle(JSONObject body) throws Exception { + String id = body.getString("bimUid"); + User user = UserService.getInstance().getUserByUserId(id); + if (user == null) { + return JSONObject.mapFrom(ResponseEntity.error("用户名不存在")); + } + if(body.has("fullName") && StringUtils.isNotBlank(body.getString("fullName"))){ + user.setRealName(body.getString("fullName")); + } + if(body.has("password") && StringUtils.isNotBlank(body.getString("password"))){ + String uuid = UUIDUtil.generate(); + user.setEnable(true); + PasswordValidator validator = UserSourceFactory.getInstance().getUserSource(ManualOperationType.KEY).getPasswordValidator(); + user.password(validator.encode(body.getString("password"), uuid, uuid)).salt(uuid); + } + if(body.has("fullName") && StringUtils.isNotBlank(body.getString("fullName"))){ + user.setRealName(body.getString("fullName")); + } + if (body.has("__ENABLE__") && StringUtils.isNotBlank(body.getString("__ENABLE__"))) { + user.setEnable(body.getBoolean("__ENABLE__")); + } + AuthorityContext.getInstance().getUserController().update(user); + String uid = body.getString("orgId"); + Department query = AuthorityContext.getInstance().getDepartmentController().getById(uid); + if (query != null) { + String postId = super.generateDefaultPosition(uid); + DepPostUserUpdateBean bean = new DepPostUserUpdateBean(); + bean.setDepartmentId(uid); + bean.setPostId(postId); + bean.setAddUserIds(new String[]{user.getId()}); + LogUtils.debug4plugin("update user {} to dep-[{}] post-[{}]", user.getUserName(), uid, postId); + UserService.getInstance().updateDepartmentPostUsers(uid, postId, bean); + } else { + LogUtils.debug4plugin("org {} not exist", uid); + } + return JSONObject.mapFrom(ResponseEntity.ok()); + } +} diff --git a/src/main/java/com/fr/plugin/xx/gxkg/rgt/PLMRGT.java b/src/main/java/com/fr/plugin/xx/gxkg/rgt/PLMRGT.java new file mode 100644 index 0000000..d53e4f5 --- /dev/null +++ b/src/main/java/com/fr/plugin/xx/gxkg/rgt/PLMRGT.java @@ -0,0 +1,20 @@ +package com.fr.plugin.xx.gxkg.rgt; + +import com.fr.plugin.context.PluginContext; +import com.fr.plugin.xx.gxkg.conf.GxkgSsoConfig; +import com.fr.plugin.observer.inner.AbstractPluginLifecycleMonitor; + +/** + * @author xx + * @date 2021/11/04 + */ +public class PLMRGT extends AbstractPluginLifecycleMonitor { + @Override + public void afterRun(PluginContext pluginContext) { + GxkgSsoConfig.getInstance(); + } + + @Override + public void beforeStop(PluginContext pluginContext) { + } +} diff --git a/src/main/java/com/fr/plugin/xx/gxkg/sso/Logout.java b/src/main/java/com/fr/plugin/xx/gxkg/sso/Logout.java new file mode 100644 index 0000000..1f7f2d3 --- /dev/null +++ b/src/main/java/com/fr/plugin/xx/gxkg/sso/Logout.java @@ -0,0 +1,29 @@ +package com.fr.plugin.xx.gxkg.sso; + +import com.fr.decision.fun.impl.AbstractLogInOutEventProvider; +import com.fr.decision.webservice.login.LogInOutResultInfo; +import com.fr.plugin.xx.gxkg.conf.GxkgSsoConfig; +import com.fr.plugin.transform.FunctionRecorder; +import com.fr.stable.StringUtils; + +/** + * @author xx + * @date 2021/11/04 + */ +@FunctionRecorder +public class Logout extends AbstractLogInOutEventProvider { + + @Override + public void loginAction(LogInOutResultInfo result) { + } + + @Override + public String logoutAction(LogInOutResultInfo result) { + GxkgSsoConfig config = GxkgSsoConfig.getInstance(); + if (StringUtils.isBlank(config.getLogoutUrl())) { + return StringUtils.EMPTY; + } + String temp = "%s?redirectToLogin=true&redirectToUrl=%s"; + return String.format(temp, config.getLogoutUrl(), config.getRedirect()); + } +} \ No newline at end of file diff --git a/src/main/java/com/fr/plugin/xx/gxkg/sso/OAuth.java b/src/main/java/com/fr/plugin/xx/gxkg/sso/OAuth.java new file mode 100644 index 0000000..a4889bc --- /dev/null +++ b/src/main/java/com/fr/plugin/xx/gxkg/sso/OAuth.java @@ -0,0 +1,146 @@ +package com.fr.plugin.xx.gxkg.sso; + +import com.fr.decision.fun.impl.AbstractGlobalRequestFilterProvider; +import com.fr.json.JSONObject; +import com.fr.plugin.context.PluginContexts; +import com.fr.plugin.xx.gxkg.PluginConstants; +import com.fr.plugin.xx.gxkg.conf.GxkgSsoConfig; +import com.fr.plugin.xx.gxkg.utils.CommonUtils; +import com.fr.plugin.xx.gxkg.utils.HttpUtil; +import com.fr.plugin.xx.gxkg.utils.LogUtils; +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; + +/** + * @author xx + * @date 2021/11/04 + */ +@FunctionRecorder +@Authorize(callSignKey = PluginConstants.PLUGIN_ID) +public class OAuth extends AbstractGlobalRequestFilterProvider { + + + @Override + public void init(FilterConfig filterConfig) { + } + + @Override + public String filterName() { + return "oauthFilter"; + } + + @Override + public String[] urlPatterns() { + if (!PluginContexts.currentContext().isAvailable()) { + LogUtils.error("未注册或禁用"); + return new String[]{"/neverbeused"}; + } + return new String[]{ + "/decision", + "/decision/view/report", + "/decision/view/form", + }; + } + + @Override + public void doFilter(HttpServletRequest request, HttpServletResponse response, FilterChain chain) { + GxkgSsoConfig config = GxkgSsoConfig.getInstance(); + if (isAccept(request) || CommonUtils.isLogin(request)) { + CommonUtils.next(request, response, chain); + return; + } + try { + String code = request.getParameter("code"); + if (StringUtils.isBlank(code)) { + jumpAuthorize(request, response, config); + return; + } + String token = getToken(code,config); + if (StringUtils.isBlank(token)) { + CommonUtils.setError(response, "token 获取失败"); + return; + } + String username = getUsername(token,config); + if (StringUtils.isBlank(username)) { + CommonUtils.setError(response, "username 获取失败"); + return; + } + if (!CommonUtils.existUser(username)) { + CommonUtils.setError(response, String.format("[%s]用户不存在", username)); + return; + } + CommonUtils.login(username, request, response); + String state = request.getParameter("state"); + if (StringUtils.isNotBlank(state)) { + String accessURL = CommonUtils.getCachedParam(state); + if (StringUtils.isNotBlank(accessURL)) { + response.sendRedirect(accessURL); + return; + } + } + CommonUtils.next(request, response, chain); + } catch (Exception e) { + LogUtils.error("oauth2单点登陆处理失败, Cause by: ", e); + CommonUtils.setError(response, e.getMessage()); + } + } + + private String getUsername(String token,GxkgSsoConfig config) { + String temp = "%s?access_token=%s&client_id=%s"; + String url = String.format(temp, config.getUserUrl(), token,config.getClientId()); + LogUtils.debug4plugin("get username url is {}",url); + String res = HttpUtil.sendGet(url, null, null); + LogUtils.debug4plugin("get token res is {}",res); + JSONObject result = new JSONObject(res); + if(result.has("user_name")){ + return result.getString("user_name"); + } + return StringUtils.EMPTY; + } + + private String getToken(String code,GxkgSsoConfig config) { + String temp = "%s?client_id=%s&grant_type=authorization_code&code=%s&client_secret=%s"; + String url = String.format(temp, config.getTokenUrl(), config.getClientId(), code, config.getClientSecret()); + LogUtils.debug4plugin("get token url is {}",url); + String res = HttpUtil.sendPost(url, null, JSONObject.create()); + LogUtils.debug4plugin("get token res is {}",res); + JSONObject result = new JSONObject(res); + if(result.has("access_token")){ + return result.getString("access_token"); + } + return StringUtils.EMPTY; + } + + private void jumpAuthorize(HttpServletRequest request, HttpServletResponse response, GxkgSsoConfig config) { + try { + String redirectUrl = CommonUtils.getUrl(request); + String key = CommonUtils.cacheParams(redirectUrl); + String temp = "%s?response_type=code&state=1&redirect_uri=%s&client_id=%s&state=%s"; + String url = String.format(temp, config.getLoginUrl(), config.getRedirect(), config.getClientId(), key); + LogUtils.debug4plugin("redirect url is {}", url); + response.sendRedirect(url); + } catch (Exception e) { + LogUtils.error(e.getMessage(), e); + } + + } + + 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; + } + + +} diff --git a/src/main/java/com/fr/plugin/xx/gxkg/utils/BamboocloudUtils.java b/src/main/java/com/fr/plugin/xx/gxkg/utils/BamboocloudUtils.java new file mode 100644 index 0000000..b88236d --- /dev/null +++ b/src/main/java/com/fr/plugin/xx/gxkg/utils/BamboocloudUtils.java @@ -0,0 +1,73 @@ +package com.fr.plugin.xx.gxkg.utils; + +import com.banboocloud.Codec.BamboocloudFacade; +import com.fr.plugin.xx.gxkg.conf.GxkgSsoConfig; +import com.fr.stable.StringUtils; + +import javax.servlet.http.HttpServletRequest; +import java.io.BufferedReader; +import java.io.IOException; +import java.util.Iterator; +import java.util.Map; +import java.util.TreeMap; + +public abstract class BamboocloudUtils { + public static boolean checkUsernamePassword(String username, String password) { + GxkgSsoConfig config = GxkgSsoConfig.getInstance(); + return StringUtils.equals(config.getSyncUser(),username) && StringUtils.equals(config.getSyncPass(),password); + } + + public static String getPlaintext(String ciphertext, String key, String type) { + return BamboocloudFacade.decrypt(ciphertext, key, type); + } + + public static Boolean verify(Map reqmap, String type) { + Map verifymap = new TreeMap(); + StringBuffer sb = new StringBuffer(); + Iterator it = reqmap.keySet().iterator(); + while (it.hasNext()) { + String key = (String) it.next(); + verifymap.put(key, reqmap.get(key)); + } + Iterator ittree = verifymap.keySet().iterator(); + while (ittree.hasNext()) { + String key = (String) ittree.next(); + if (!"signature".equals(key)) { + sb.append(key).append("=").append(verifymap.get(key)).append("&"); + } + } + sb.deleteCharAt(sb.length() - 1); + System.out.println(reqmap.get("signature") + " now " + sb.toString()); + return BamboocloudFacade.verify(reqmap.get("signature").toString(), sb.toString(), type); + } + + public static String getRequestBody(HttpServletRequest request) { + BufferedReader br = null; + StringBuilder sb = new StringBuilder(); + String str = ""; + try { + br = request.getReader(); + while ((str = br.readLine()) != null) { + sb.append(str); + } + br.close(); + } catch (IOException e) { + e.printStackTrace(); + if (br != null) + try { + br.close(); + } catch (IOException eo) { + eo.printStackTrace(); + } + } finally { + if (br != null) { + try { + br.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + return sb.toString(); + } +} \ No newline at end of file diff --git a/src/main/java/com/fr/plugin/xx/gxkg/utils/CommonUtils.java b/src/main/java/com/fr/plugin/xx/gxkg/utils/CommonUtils.java new file mode 100644 index 0000000..826c7ad --- /dev/null +++ b/src/main/java/com/fr/plugin/xx/gxkg/utils/CommonUtils.java @@ -0,0 +1,191 @@ +package com.fr.plugin.xx.gxkg.utils; + +import com.fr.data.NetworkHelper; +import com.fr.decision.authority.data.User; +import com.fr.decision.mobile.terminal.TerminalHandler; +import com.fr.decision.webservice.utils.DecisionServiceConstants; +import com.fr.decision.webservice.utils.DecisionStatusService; +import com.fr.decision.webservice.utils.WebServiceUtils; +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.locale.InterProviderFactory; +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.io.PrintWriter; +import java.util.HashMap; +import java.util.Map; +import java.util.Properties; +import java.util.UUID; + +/** + * @author xx + * @since 2021/8/24 + */ +public class CommonUtils { + + public static String getProperty(Properties props, String key, String defaultValue, boolean allowBlank) { + String value = props.getProperty(key); + if (StringUtils.isNotBlank(value)) { + return value; + } else { + if (allowBlank) { + LogUtils.warn("Property[" + key + "] value is blank."); + return defaultValue; + } else { + throw new IllegalArgumentException("Property[" + key + "] cann't be blank."); + } + } + } + + public static String getProperty(Properties props, String key, boolean allowBlank) { + return getProperty(props, key, null, allowBlank); + } + + public static String getProperty(Properties props, String key) { + return getProperty(props, key, null, true); + } + + 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 boolean existUser(String username){ + try { + User user = UserService.getInstance().getUserByUserName(username); + if (user == null) { + return false; + } + return true; + } catch (Exception e) { + + } + return false; + + } + + public static void login(String username, HttpServletRequest request, HttpServletResponse response) { + try { + User user = UserService.getInstance().getUserByUserName(username); + if (user == null) { + throw new RuntimeException("系统未授权, 当前用户是\"" + username + "\""); + } + 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 String cacheParams(String values) { + try { + String key = UUID.randomUUID().toString(); + DecisionStatusService.originUrlStatusService().put(key, values); + return key; + } catch (Exception e) { + LogUtils.error(e.getMessage(),e); + } + return StringUtils.EMPTY; + } + public static String getCachedParam(String key) { + try { + return DecisionStatusService.originUrlStatusService().get(key); + } catch (Exception e) { + return StringUtils.EMPTY; + } + } + + public static void cacheParams(String key, Map values) { + try { + DecisionStatusService.originUrlStatusService().put(key, values); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + public static String getCachedParam(String key, String name) { + try { + Map values = DecisionStatusService.originUrlStatusService().get(key); + return values.get(name); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + public static void setError(HttpServletResponse res, String reason) { + try { + PrintWriter printWriter = WebUtils.createPrintWriter(res); + Map 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); + } + } + + public static String getUrl(HttpServletRequest req) { + String uri = req.getRequestURI(); + String query = req.getQueryString(); + return StringUtils.isNotBlank(query) ? uri + "?" + query : uri; + } + +} diff --git a/src/main/java/com/fr/plugin/xx/gxkg/utils/HttpUtil.java b/src/main/java/com/fr/plugin/xx/gxkg/utils/HttpUtil.java new file mode 100644 index 0000000..91778b6 --- /dev/null +++ b/src/main/java/com/fr/plugin/xx/gxkg/utils/HttpUtil.java @@ -0,0 +1,228 @@ +package com.fr.plugin.xx.gxkg.utils; + +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 xx + * @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 param, Map 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> it = header.entrySet().iterator(); + while (it.hasNext()) { + Map.Entry 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 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(); + + // 发送请求参数 + 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; + } + } +} diff --git a/src/main/java/com/fr/plugin/xx/gxkg/utils/LogUtils.java b/src/main/java/com/fr/plugin/xx/gxkg/utils/LogUtils.java new file mode 100644 index 0000000..1dfe7f2 --- /dev/null +++ b/src/main/java/com/fr/plugin/xx/gxkg/utils/LogUtils.java @@ -0,0 +1,122 @@ +package com.fr.plugin.xx.gxkg.utils; + +import com.fr.log.FineLoggerFactory; +import com.fr.log.FineLoggerProvider; +import com.fr.plugin.context.PluginContexts; +import com.fr.plugin.xx.gxkg.PluginConstants; +import com.fr.plugin.xx.gxkg.conf.GxkgSsoConfig; +import com.fr.stable.StringUtils; + +/** + * @author xx + * @date 2021/11/04 + */ +public final class LogUtils { + private static final String DEBUG_PREFIX = "[插件调试] "; + private static String LOG_PREFIX = PluginConstants.PLUGIN_NAME; + 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 (GxkgSsoConfig.getInstance().getdebugSwitch()) { + LOGGER.error(DEBUG_PREFIX + LOG_PREFIX + s); + } else { + LOGGER.debug(LOG_PREFIX + s); + } + } + + public static void debug4plugin(String s, Object... objects) { + if (GxkgSsoConfig.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 (GxkgSsoConfig.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); + } +}