diff --git a/JSD-7508配置使用文档.docx b/JSD-7508配置使用文档.docx new file mode 100644 index 0000000..2f60c05 Binary files /dev/null and b/JSD-7508配置使用文档.docx differ diff --git a/JSD-7508需求确认书(对内).docx b/JSD-7508需求确认书(对内).docx new file mode 100644 index 0000000..c5a68ed Binary files /dev/null and b/JSD-7508需求确认书(对内).docx differ diff --git a/README.md b/README.md index fc268ff..fc1e2c7 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,6 @@ # open-JSD-7508 -JSD-7508 OAuth2 + 组织&用户同步 \ No newline at end of file +JSD-7508 OAuth2 + 组织&用户同步\ +免责说明:该源码为第三方爱好者提供,不保证源码和方案的可靠性,也不提供任何形式的源码教学指导和协助!\ +仅作为开发者学习参考使用!禁止用于任何商业用途!\ +为保护开发者隐私,开发者信息已隐去!若原开发者希望公开自己的信息,可联系hugh处理。 \ No newline at end of file diff --git a/lib/finekit-10.0.jar b/lib/finekit-10.0.jar new file mode 100644 index 0000000..f4482fc Binary files /dev/null and b/lib/finekit-10.0.jar differ diff --git a/lib/java-jwt-3.16.0.jar b/lib/java-jwt-3.16.0.jar new file mode 100644 index 0000000..a4e61fb Binary files /dev/null and b/lib/java-jwt-3.16.0.jar differ diff --git a/plugin.xml b/plugin.xml new file mode 100644 index 0000000..d6d5263 --- /dev/null +++ b/plugin.xml @@ -0,0 +1,25 @@ + + + com.fr.plugin.j7508.sso.auth + + yes + 1.1.3 + 10.0 + 2018-07-31 + fr.open + + + com.fr.plugin.j7508.sso + + com.fanruan.api + + + + + + + + + + + \ No newline at end of file diff --git a/src/main/java/com/fr/plugin/j7508/sso/LocaleFinder.java b/src/main/java/com/fr/plugin/j7508/sso/LocaleFinder.java new file mode 100644 index 0000000..cadaf9d --- /dev/null +++ b/src/main/java/com/fr/plugin/j7508/sso/LocaleFinder.java @@ -0,0 +1,37 @@ + /* + * Copyright (C), 2018-2020 + * Project: starter + * FileName: LocaleFinder + * Author: Louis + * Date: 2020/8/31 22:19 + */ + package com.fr.plugin.j7508.sso; + + import com.fr.intelli.record.Focus; +import com.fr.intelli.record.Original; +import com.fr.record.analyzer.EnableMetrics; +import com.fr.stable.fun.impl.AbstractLocaleFinder; + +import static com.fr.plugin.j7508.sso.config.SsoConfig.PLUGIN_ID; + + /** + *
+ * + * + * @author fr.open + * @since 1.0.0 + */ + @EnableMetrics + public class LocaleFinder extends AbstractLocaleFinder { + + @Override + @Focus(id = PLUGIN_ID, text = "Plugin-J7508-Sso", source = Original.PLUGIN) + public String find() { + return "com/fr/plugin/j7508/sso/locale/lang"; + } + + @Override + public int currentAPILevel() { + return CURRENT_LEVEL; + } + } \ No newline at end of file diff --git a/src/main/java/com/fr/plugin/j7508/sso/PluginMonitor.java b/src/main/java/com/fr/plugin/j7508/sso/PluginMonitor.java new file mode 100644 index 0000000..9c68190 --- /dev/null +++ b/src/main/java/com/fr/plugin/j7508/sso/PluginMonitor.java @@ -0,0 +1,49 @@ + /* + * Copyright (C), 2018-2021 + * Project: starter + * FileName: PluginMonitor + * Author: Louis + * Date: 2021/3/30 15:10 + */ + package com.fr.plugin.j7508.sso; + + import com.fanruan.api.log.LogKit; +import com.fr.plugin.context.PluginContext; +import com.fr.plugin.j7508.sso.config.SsoConfig; +import com.fr.plugin.j7508.sso.helper.SsoUserScheduleHelper; +import com.fr.plugin.observer.inner.AbstractPluginLifecycleMonitor; + + import static com.fr.plugin.j7508.sso.helper.SsoUserScheduleHelper.SSO_USER_SCHEDULE_SYN_MEMBER_GROUP; + import static com.fr.plugin.j7508.sso.helper.SsoUserScheduleHelper.SSO_USER_SCHEDULE_SYN_MEMBER_JOB_NAME; + + /** + *
+ * + * + * @author fr.open + * @since 1.0.0 + */ + public class PluginMonitor extends AbstractPluginLifecycleMonitor { + public PluginMonitor() { + } + + @Override + public void afterRun(PluginContext pluginContext) { + SsoConfig.getInstance(); + this.reStartSchedule(); + } + + @Override + public void beforeStop(PluginContext pluginContext) { + SsoUserScheduleHelper.getInstance().stopSchedule(SSO_USER_SCHEDULE_SYN_MEMBER_JOB_NAME, SSO_USER_SCHEDULE_SYN_MEMBER_GROUP); + } + + private void reStartSchedule() { + try { + String cronCondition = SsoConfig.getInstance().getCronCondition(); + SsoUserScheduleHelper.getInstance().startSynMemberSchedule(cronCondition); + } catch (Exception e) { + LogKit.error(e.getMessage(), e); + } + } + } \ No newline at end of file diff --git a/src/main/java/com/fr/plugin/j7508/sso/bean/DataResponse.java b/src/main/java/com/fr/plugin/j7508/sso/bean/DataResponse.java new file mode 100644 index 0000000..d360b13 --- /dev/null +++ b/src/main/java/com/fr/plugin/j7508/sso/bean/DataResponse.java @@ -0,0 +1,99 @@ + /* + * Copyright (C), 2018-2021 + * Project: starter + * FileName: DataResponse + * Author: Louis + * Date: 2021/3/19 11:46 + */ + package com.fr.plugin.j7508.sso.bean; + + import com.fanruan.api.util.StringKit; +import com.fr.decision.webservice.Response; +import com.fr.third.fasterxml.jackson.annotation.JsonInclude; + + /** + *
+ * + * + * @author fr.open + * @since 1.0.0 + */ + @JsonInclude(JsonInclude.Include.NON_DEFAULT) + public class DataResponse extends Response { + private static final long serialVersionUID = -6046189959382243612L; + private String timestamp; + private String code; + private String msg; + + public DataResponse() { + } + + private static DataResponse create() { + return new DataResponse(); + } + + /** + * 相应success结果 + * + * @return + */ + public static DataResponse success() { + return create().code("0").timeStamp(String.valueOf(System.currentTimeMillis())).message("success"); + } + + + /** + * 报错结果 + * + * @param code + * @param message + * @return + */ + public static DataResponse error(String code, String message) { + return create().code(code).message(message).data(StringKit.EMPTY); + } + + public DataResponse timeStamp(String timeStamp) { + this.timestamp = timeStamp; + return this; + } + + public DataResponse code(String code) { + this.code = code; + return this; + } + + public DataResponse message(String message) { + this.msg = message; + return this; + } + + public DataResponse data(Object data) { + this.setData(data); + return this; + } + + public String getTimestamp() { + return timestamp; + } + + public void setTimestamp(String timestamp) { + this.timestamp = timestamp; + } + + public String getCode() { + return code; + } + + public void setCode(String code) { + this.code = code; + } + + public String getMsg() { + return msg; + } + + public void setMsg(String msg) { + this.msg = msg; + } + } \ No newline at end of file diff --git a/src/main/java/com/fr/plugin/j7508/sso/bean/SsoUserJobConstructor.java b/src/main/java/com/fr/plugin/j7508/sso/bean/SsoUserJobConstructor.java new file mode 100644 index 0000000..b483583 --- /dev/null +++ b/src/main/java/com/fr/plugin/j7508/sso/bean/SsoUserJobConstructor.java @@ -0,0 +1,107 @@ + /* + * Copyright (C), 2018-2021 + * Project: starter + * FileName: SsoUserJobConstructor + * Author: Louis + * Date: 2021/4/21 15:58 + */ + package com.fr.plugin.j7508.sso.bean; + + import com.fr.scheduler.job.FineScheduleJob; + + /** + *
+ * + * + * @author fr.open + * @since 1.0.0 + */ + public class SsoUserJobConstructor { + private String cron; + private String jobName; + private String jobGroup; + private String triggerName; + private String triggerGroup; + private Class jobClazz; + + public SsoUserJobConstructor() { + } + + public SsoUserJobConstructor cron(String var1) { + this.setCron(var1); + return this; + } + + public String getCron() { + return this.cron; + } + + public void setCron(String var1) { + this.cron = var1; + } + + public SsoUserJobConstructor jobName(String var1) { + this.setJobName(var1); + return this; + } + + public String getJobName() { + return this.jobName; + } + + public void setJobName(String var1) { + this.jobName = var1; + } + + public SsoUserJobConstructor jobGroup(String var1) { + this.setJobGroup(var1); + return this; + } + + public String getJobGroup() { + return this.jobGroup; + } + + public void setJobGroup(String var1) { + this.jobGroup = var1; + } + + public SsoUserJobConstructor triggerName(String var1) { + this.setTriggerName(var1); + return this; + } + + public String getTriggerName() { + return this.triggerName; + } + + public void setTriggerName(String var1) { + this.triggerName = var1; + } + + public SsoUserJobConstructor triggerGroup(String var1) { + this.setTriggerGroup(var1); + return this; + } + + public String getTriggerGroup() { + return this.triggerGroup; + } + + public void setTriggerGroup(String var1) { + this.triggerGroup = var1; + } + + public SsoUserJobConstructor jobClazz(Class var1) { + this.setJobClazz(var1); + return this; + } + + public Class getJobClazz() { + return this.jobClazz; + } + + public void setJobClazz(Class var1) { + this.jobClazz = var1; + } + } \ No newline at end of file diff --git a/src/main/java/com/fr/plugin/j7508/sso/config/SsoConfig.java b/src/main/java/com/fr/plugin/j7508/sso/config/SsoConfig.java new file mode 100644 index 0000000..9fb96e2 --- /dev/null +++ b/src/main/java/com/fr/plugin/j7508/sso/config/SsoConfig.java @@ -0,0 +1,122 @@ + /* + * Copyright (C), 2018-2021 + * Project: starter + * FileName: OneAccessConfig + * Author: Louis + * Date: 2021/3/30 9:38 + */ + package com.fr.plugin.j7508.sso.config; + + import com.fanruan.api.util.StringKit; + 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; + + /** + *
+ * + * + * @author fr.open + * @since 1.0.0 + */ + @Visualization(category = "Plugin-J7508-Sso_Group") + public class SsoConfig extends DefaultConfiguration { + public static final String PLUGIN_ID = "com.fr.plugin.j7508.sso.auth"; + public static final String BASE_URI = "xxxx"; + public static final String ESB_URI = "xxxx"; + // 每天中午十二点触发 + public static final String CRON_CONDITION = "0 0 12 * * ?"; + + private static volatile SsoConfig config = null; + + @Focus(id = PLUGIN_ID, text = "Plugin-J7508-Sso", source = Original.PLUGIN) + public static SsoConfig getInstance() { + if (config == null) { + config = ConfigContext.getConfigInstance(SsoConfig.class); + } + return config; + } + + @Identifier(value = "frUri", name = "Plugin-J7508-Sso_Config_FrUri", description = "Plugin-J7508-Sso_Config_FrUri_Description", status = Status.SHOW) + private Conf frUri = Holders.simple(StringKit.EMPTY); + @Identifier(value = "uriBase", name = "Plugin-J7508-Sso_Config_UriBase", description = "Plugin-J7508-Sso_Config_UriBase_Description", status = Status.SHOW) + private Conf uriBase = Holders.simple(BASE_URI); + @Identifier(value = "esbUri", name = "Plugin-J7508-Sso_Config_EsbUri", description = "Plugin-J7508-Sso_Config_EsbUri_Description", status = Status.SHOW) + private Conf esbUri = Holders.simple(ESB_URI); + @Identifier(value = "clientId", name = "Plugin-J7508-Sso_Config_ClientId", description = "Plugin-J7508-Sso_Config_ClientId_Description", status = Status.SHOW) + private Conf clientId = Holders.simple(StringKit.EMPTY); + @Identifier(value = "clientSecret", name = "Plugin-J7508-Sso_Config_ClientSecret", description = "Plugin-J7508-Sso_Config_ClientSecret_Description", status = Status.SHOW) + private Conf clientSecret = Holders.simple(StringKit.EMPTY); + @Identifier(value = "cronCondition", name = "Plugin-J7508-Sso_Config_CronCondition", description = "Plugin-J7508-Sso_Config_CronCondition_Description", status = Status.SHOW) + private Conf cronCondition = Holders.simple(CRON_CONDITION); + @Identifier(value = "appID", name = "Plugin-J7508-Sso_Config_AppID", description = "Plugin-J7508-Sso_Config_AppID_Description", status = Status.SHOW) + private Conf appID = Holders.simple(StringKit.EMPTY); + @Identifier(value = "appSecret", name = "Plugin-J7508-Sso_Config_AppSecret", description = "Plugin-J7508-Sso_Config_AppSecret_Description", status = Status.SHOW) + private Conf appSecret = Holders.simple(StringKit.EMPTY); + + public String getFrUri() { + return frUri.get(); + } + + public void setFrUri(String frUri) { + this.frUri.set(frUri); + } + + public String getUriBase() { + return uriBase.get(); + } + + public void setUriBase(String uriBase) { + this.uriBase.set(uriBase); + } + + public String getEsbUri() { + return esbUri.get(); + } + + public void setEsbUri(String esbUri) { + this.esbUri.set(esbUri); + } + + public String getClientId() { + return clientId.get(); + } + + public void setClientId(String clientId) { + this.clientId.set(clientId); + } + + public String getClientSecret() { + return clientSecret.get(); + } + + public void setClientSecret(String clientSecret) { + this.clientSecret.set(clientSecret); + } + + public String getCronCondition() { + return cronCondition.get(); + } + + public void setCronCondition(String cronCondition) { + this.cronCondition.set(cronCondition); + } + + public String getAppID() { + return appID.get(); + } + + public void setAppID(String appID) { + this.appID.set(appID); + } + + public String getAppSecret() { + return appSecret.get(); + } + + public void setAppSecret(String appSecret) { + this.appSecret.set(appSecret); + } + } \ No newline at end of file diff --git a/src/main/java/com/fr/plugin/j7508/sso/helper/SsoUserScheduleHelper.java b/src/main/java/com/fr/plugin/j7508/sso/helper/SsoUserScheduleHelper.java new file mode 100644 index 0000000..0a11f1a --- /dev/null +++ b/src/main/java/com/fr/plugin/j7508/sso/helper/SsoUserScheduleHelper.java @@ -0,0 +1,77 @@ + /* + * Copyright (C), 2018-2021 + * Project: starter + * FileName: DingTalkScheduleHelper + * Author: Louis + * Date: 2021/4/21 15:52 + */ + package com.fr.plugin.j7508.sso.helper; + + import com.fr.plugin.j7508.sso.bean.SsoUserJobConstructor; + import com.fr.plugin.j7508.sso.job.SsoUserSyncMemberJob; + import com.fr.scheduler.ScheduleJobManager; + import com.fr.third.v2.org.quartz.CronScheduleBuilder; + import com.fr.third.v2.org.quartz.TriggerBuilder; + + import java.util.ArrayList; + import java.util.HashMap; + import java.util.TimeZone; + + /** + *
+ * + * + * @author fr.open + * @since 1.0.0 + */ + public class SsoUserScheduleHelper { + public static final String SSO_USER_SCHEDULE_SYN_MEMBER_JOB_NAME = "MqhSsoUserSynDepMemberJob"; + public static final String SSO_USER_SCHEDULE_SYN_MEMBER_TRIGGER_NAME = "MqhSsoUserSynDepMemberTrigger"; + public static final String SSO_USER_SCHEDULE_SYN_MEMBER_GROUP = "MqhSsoUserSynDepMemberGroup"; + public static final String SSO_USER_SCHEDULE_SYN_MEMBER_TRIGGER_GROUP = "MqhSsoUserSynDepMemberTriggerGroup"; + + private SsoUserScheduleHelper() { + } + + public static SsoUserScheduleHelper getInstance() { + return SsoUserScheduleHelper.HOLDER.INSTANCE; + } + + public void startSynMemberSchedule(String cronCondition) throws Exception { + SsoUserJobConstructor jobConstructor = (new SsoUserJobConstructor()) + .cron(cronCondition).jobName(SSO_USER_SCHEDULE_SYN_MEMBER_JOB_NAME) + .jobGroup(SSO_USER_SCHEDULE_SYN_MEMBER_GROUP).triggerName(SSO_USER_SCHEDULE_SYN_MEMBER_TRIGGER_NAME) + .triggerGroup(SSO_USER_SCHEDULE_SYN_MEMBER_TRIGGER_GROUP).jobClazz(SsoUserSyncMemberJob.class); + this.startSchedule(jobConstructor); + } + + public void startSchedule(SsoUserJobConstructor var1) throws Exception { + if (var1 != null) { + String var2 = var1.getCron(); + String var3 = var1.getTriggerName(); + String var4 = var1.getTriggerGroup(); + String var5 = var1.getJobName(); + String var6 = var1.getJobGroup(); + Class var7 = var1.getJobClazz(); + TriggerBuilder var8 = TriggerBuilder.newTrigger(); + var8.withIdentity(var3, var4); + var8.withSchedule(CronScheduleBuilder.cronSchedule(var2).withMisfireHandlingInstructionFireAndProceed().inTimeZone(TimeZone.getTimeZone(TimeZone.getDefault().getID()))).startNow(); + var8.forJob(var5, var6); + ArrayList var9 = new ArrayList(); + var9.add(var8.build()); + ScheduleJobManager.getInstance().removeJob(var5, var6); + ScheduleJobManager.getInstance().addJob(var5, var6, "jobDescription", var7, var9, new HashMap()); + } + } + + public void stopSchedule(String var1, String var2) { + ScheduleJobManager.getInstance().removeJob(var1, var2); + } + + public static class HOLDER { + private static final SsoUserScheduleHelper INSTANCE = new SsoUserScheduleHelper(); + + public HOLDER() { + } + } + } diff --git a/src/main/java/com/fr/plugin/j7508/sso/job/SsoUserSyncMemberJob.java b/src/main/java/com/fr/plugin/j7508/sso/job/SsoUserSyncMemberJob.java new file mode 100644 index 0000000..b4414c2 --- /dev/null +++ b/src/main/java/com/fr/plugin/j7508/sso/job/SsoUserSyncMemberJob.java @@ -0,0 +1,34 @@ + /* + * Copyright (C), 2018-2021 + * Project: starter + * FileName: SsoUserSyncMemberJob + * Author: Louis + * Date: 2021/4/21 16:02 + */ + package com.fr.plugin.j7508.sso.job; + + import com.fanruan.api.log.LogKit; + import com.fr.cluster.core.ClusterNode; + import com.fr.plugin.j7508.sso.user.SsoUserManager; + import com.fr.scheduler.job.FineScheduleJob; + import com.fr.third.v2.org.quartz.JobExecutionContext; + + /** + *
+ * + * + * @author fr.open + * @since 1.0.0 + */ + public class SsoUserSyncMemberJob extends FineScheduleJob { + public SsoUserSyncMemberJob() { + } + + public void run(JobExecutionContext jobExecutionContext, ClusterNode clusterNode) { + try { + SsoUserManager.getInstance().synSSODepartments(); + } catch (Exception e) { + LogKit.error(e.getMessage(), e); + } + } + } \ No newline at end of file diff --git a/src/main/java/com/fr/plugin/j7508/sso/kit/DepartmentServiceKit.java b/src/main/java/com/fr/plugin/j7508/sso/kit/DepartmentServiceKit.java new file mode 100644 index 0000000..d93a636 --- /dev/null +++ b/src/main/java/com/fr/plugin/j7508/sso/kit/DepartmentServiceKit.java @@ -0,0 +1,96 @@ + /* + * Copyright (C), 2018-2021 + * Project: starter + * FileName: DepartmentServiceKit + * Author: Louis + * Date: 2021/5/14 9:38 + */ + package com.fr.plugin.j7508.sso.kit; + + import com.fanruan.api.i18n.I18nKit; + import com.fanruan.api.util.StringKit; + 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.record.OperateMessage; + import com.fr.decision.webservice.exception.general.DuplicatedNameException; + import com.fr.decision.webservice.v10.user.DepartmentService; + import com.fr.general.ComparatorUtils; + import com.fr.intelli.record.MetricRegistry; + import com.fr.stable.StableUtils; + import com.fr.stable.query.QueryFactory; + import com.fr.stable.query.condition.QueryCondition; + import com.fr.stable.query.restriction.Restriction; + import com.fr.stable.query.restriction.RestrictionFactory; + + import java.util.ArrayList; + import java.util.Collections; + import java.util.List; + + import static com.fr.decision.authority.base.AuthorityConstants.DECISION_DEP_ROOT; + + /** + *
+ * + * + * @author fr.open + * @since 1.0.0 + */ + public class DepartmentServiceKit extends DepartmentService { + private static volatile DepartmentServiceKit departmentServiceKit = null; + + public DepartmentServiceKit() { + } + + public static DepartmentServiceKit getInstance() { + if (departmentServiceKit == null) { + departmentServiceKit = new DepartmentServiceKit(); + } + return departmentServiceKit; + } + + public void addDepartment(String id, String pId, String depName) throws Exception { + if (StringKit.equals(pId, DECISION_DEP_ROOT)) { + pId = null; + } + this.checkDuplicatedDepartmentName(pId, depName); + Department department = (new Department()).id(id).name(depName).parentId(pId).creationType(ManualOperationType.KEY).lastOperationType(ManualOperationType.KEY).enable(true); + AuthorityContext.getInstance().getDepartmentController().add(department); + MetricRegistry.getMetric().submit(OperateMessage.build("Dec-Module-User_Manager", "Dec-Department", this.getDepartmentFullPath(pId, depName, "/"), "Dec-Log_Add")); + } + + private void checkDuplicatedDepartmentName(String parentId, String depName) throws Exception { + QueryCondition condition = QueryFactory.create().addRestriction(RestrictionFactory.and(new Restriction[]{RestrictionFactory.eq("name", depName), RestrictionFactory.eq("parentId", parentId)})); + Department sameNameDep = AuthorityContext.getInstance().getDepartmentController().findOne(condition); + if (sameNameDep != null) { + throw new DuplicatedNameException(); + } + } + + private String getDepartmentFullPath(String pId, String depName, String splitter) throws Exception { + List paths = new ArrayList<>(); + paths.add(depName); + while (!ComparatorUtils.equals(pId, DECISION_DEP_ROOT) && pId != null) { + Department parentDepartment = AuthorityContext.getInstance().getDepartmentController().getById(pId); + paths.add(parentDepartment.getName()); + pId = parentDepartment.getParentId(); + } + Collections.reverse(paths); + return StableUtils.join(paths.toArray(new String[0]), splitter); + } + + public void editDepartment(String departmentId, String depName, String pId) throws Exception { + if (StringKit.equals(pId, DECISION_DEP_ROOT)) { + pId = null; + } + Department department = AuthorityContext.getInstance().getDepartmentController().getById(departmentId); + String departmentFullPath = DepartmentService.getInstance().getDepartmentFullPath(departmentId); + if (!ComparatorUtils.equals(department.getName(), depName)) { + this.checkDuplicatedDepartmentName(department.getParentId(), depName); + department.setName(depName); + department.setParentId(pId); + AuthorityContext.getInstance().getDepartmentController().update(department); + } + MetricRegistry.getMetric().submit(OperateMessage.build("Dec-Module-User_Manager", "Dec-Department", DepartmentService.getInstance().getDepartmentFullPath(departmentId), "Dec-Log_Update", I18nKit.getLocText("Fine-Dec_Department") + ":" + departmentFullPath)); + } + } \ No newline at end of file diff --git a/src/main/java/com/fr/plugin/j7508/sso/kit/UserServiceKit.java b/src/main/java/com/fr/plugin/j7508/sso/kit/UserServiceKit.java new file mode 100644 index 0000000..6275d1c --- /dev/null +++ b/src/main/java/com/fr/plugin/j7508/sso/kit/UserServiceKit.java @@ -0,0 +1,169 @@ + /* + * Copyright (C), 2018-2021 + * Project: starter + * FileName: UserServiceKit + * Author: Louis + * Date: 2021/5/14 8:28 + */ + package com.fr.plugin.j7508.sso.kit; + +import com.fanruan.api.log.LogKit; +import com.fanruan.api.util.StringKit; +import com.fr.decision.authority.AuthorityContext; +import com.fr.decision.authority.data.Post; +import com.fr.decision.authority.data.User; +import com.fr.decision.authority.data.personnel.DepRole; +import com.fr.decision.privilege.TransmissionTool; +import com.fr.decision.webservice.bean.user.DepartmentPostBean; +import com.fr.decision.webservice.bean.user.UserBean; +import com.fr.decision.webservice.utils.UserSourceFactory; +import com.fr.decision.webservice.utils.WebServiceUtils; +import com.fr.decision.webservice.v10.user.PositionService; +import com.fr.decision.webservice.v10.user.UserService; + import com.fr.json.JSONObject; + import com.fr.stable.StringUtils; +import com.fr.stable.collections.CollectionUtils; +import com.fr.stable.query.QueryFactory; +import com.fr.stable.query.restriction.RestrictionFactory; + +import java.util.ArrayList; +import java.util.List; + + /** + *
+ * + * + * @author fr.open + * @since 1.0.0 + */ + public class UserServiceKit extends UserService { + private static volatile UserServiceKit userServiceKit = null; + + public UserServiceKit() { + } + + public static UserServiceKit getInstance() { + if (userServiceKit == null) { + userServiceKit = new UserServiceKit(); + } + return userServiceKit; + } + + public UserBean createUserBean(JSONObject account) throws Exception { + UserBean userBean = new UserBean(); + userBean.setUsername(account.getString("uid")); + userBean.setRealName(account.getString("userName")); + userBean.setEnable(StringKit.equals(account.getString("status"), "1")); + userBean.setEmail(account.getString("email")); + userBean.setMobile(account.getString("mobile")); + userBean.setPassword(TransmissionTool.defaultEncrypt(account.getString("uid") + "123456")); + if (StringKit.isNotBlank(account.getString("orgCode"))) { + List departmentPostIds = createDepartmentPostIds(account.getString("orgCode"), account.getString("jobTitle")); + userBean.setDepartmentPostIds(departmentPostIds); + } + return userBean; + } + + /** + * 转为部门职务组合 + * + * @param departmentPostId + * @param title + * @return + * @throws Exception + */ + private List createDepartmentPostIds(String departmentPostId, String title) throws Exception { + List departmentPostIds = new ArrayList<>(); + if (StringKit.isBlank(departmentPostId) || StringKit.equals(departmentPostId, "null")) { + return departmentPostIds; + } + String positionId = positionSynOperation(title, departmentPostId); + if (StringKit.isNotBlank(positionId)) { + departmentPostId = departmentPostId + "@@@" + positionId; + } + departmentPostIds.add(departmentPostId); + return departmentPostIds; + } + + /** + * 职务同步操作 + * + * @param title + * @return + * @throws Exception + */ + private String positionSynOperation(String title, String departmentId) throws Exception { + String position = StringKit.isNotBlank(title) ? title : "职员"; + Post post = AuthorityContext.getInstance().getPostController().findOne(QueryFactory.create().addRestriction(RestrictionFactory.eq("name", position))); + String positionId; + if (post == null) { + positionId = PositionService.getInstance().addPosition(position, position); + } else { + positionId = post.getId(); + } + List departmentPostBeanList = PositionService.getInstance().getPositionsUnderParentDepartment(getAdminUserId(), departmentId, position); + if (departmentPostBeanList == null || departmentPostBeanList.isEmpty()) { + try { + AuthorityContext.getInstance().getPostController().addPostToDepartment(positionId, departmentId); + } catch (Exception e) { + LogKit.info("sso-UserServiceKit-positionSynOperation-addPostToDepartmentFailed-position:{}, departmentId:{}", positionId + position, departmentId); + LogKit.error(e.getMessage(), e); + } + } + return positionId; + } + + /** + * 获取管理员id + * + * @return + * @throws Exception + */ + public String getAdminUserId() throws Exception { + List adminUserIdList = UserService.getInstance().getAdminUserIdList(); + if (adminUserIdList.isEmpty()) { + return "admin"; + } + return StringKit.isNotBlank(adminUserIdList.get(0)) ? adminUserIdList.get(0) : "admin"; + } + + public UserBean updateUserBean(JSONObject account) throws Exception { + User user = UserService.getInstance().getUserByUserName(account.getString("uid")); + if (user == null) { + return null; + } + UserBean userBean = new UserBean(); + userBean.setId(user.getId()); + userBean.setUsername(user.getUserName()); + userBean.setRealName(account.getString("userName")); + userBean.setEnable(StringKit.equals(account.getString("status"), "1")); + userBean.setEmail(account.getString("email")); + userBean.setMobile(account.getString("mobile")); + if (StringKit.isNotBlank(account.getString("orgCode"))) { + List departmentPostIds = createDepartmentPostIds(account.getString("orgCode"), account.getString("jobTitle")); + userBean.setDepartmentPostIds(departmentPostIds); + } + return userBean; + } + + /** + * 增加用户部门关联 + * + * @param userBean + * @throws Exception + */ + public void addUserDepartment(UserBean userBean) throws Exception { + if (CollectionUtils.isEmpty(userBean.getDepartmentPostIds())) { + return; + } + for (String departmentPostId : userBean.getDepartmentPostIds()) { + if (StringUtils.isEmpty(departmentPostId)) { + continue; + } + User user = UserService.getInstance().getUserByUserName(userBean.getUsername()); + DepRole depRole = WebServiceUtils.parseUniqueDepartmentPostId(departmentPostId); + UserSourceFactory.getInstance().checkSource(user, AuthorityContext.getInstance().getDepartmentController().getById(depRole.getDepartmentId())); + AuthorityContext.getInstance().getUserController().addUserToDepartmentAndPost(user.getId(), depRole.getDepartmentId(), depRole.getPostId()); + } + } + } \ No newline at end of file diff --git a/src/main/java/com/fr/plugin/j7508/sso/request/OAuthLogin.java b/src/main/java/com/fr/plugin/j7508/sso/request/OAuthLogin.java new file mode 100644 index 0000000..475e701 --- /dev/null +++ b/src/main/java/com/fr/plugin/j7508/sso/request/OAuthLogin.java @@ -0,0 +1,221 @@ + /* + * Copyright (C), 2018-2021 + * Project: starter + * FileName: OAuthLogin + * Author: Louis + * Date: 2021/3/30 22:09 + */ + package com.fr.plugin.j7508.sso.request; + + import com.fanruan.api.decision.login.LoginKit; +import com.fanruan.api.decision.user.UserKit; +import com.fanruan.api.log.LogKit; +import com.fanruan.api.net.NetworkKit; +import com.fanruan.api.net.http.HttpKit; +import com.fanruan.api.util.StringKit; +import com.fr.decision.fun.impl.AbstractGlobalRequestFilterProvider; +import com.fr.decision.webservice.utils.DecisionServiceConstants; +import com.fr.decision.webservice.v10.login.LoginService; +import com.fr.json.JSONObject; +import com.fr.plugin.j7508.sso.config.SsoConfig; +import com.fr.third.org.apache.http.client.utils.URIBuilder; + +import javax.servlet.FilterChain; +import javax.servlet.FilterConfig; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.net.URISyntaxException; +import java.util.HashMap; +import java.util.Map; + + /** + *
+ * + * + * @author fr.open + * @since 1.0.0 + */ + public class OAuthLogin extends AbstractGlobalRequestFilterProvider { + public static final String REMOTE_DESIGN = "/remote/design"; + public static final String RESOURCES_PATH = "/resources"; + public static final String FILE_PATH = "/file"; + public static final String SYSTEM_INFO = "/system/info"; + public static final String MATERIALS_MIN_JS_MAP = "/materials.min.js.map"; + public static final String LOGIN_PATH = "/login"; + public static final String LOGIN_OTHER = "/login/"; + public static final String LOGOUT_PATH = "/logout"; + public static final String USER_LANGUAGE = "/v10/user/language"; + public static final String ACCOUNT_IAMPUSH = "/account/iamPush"; + + public static final String CODE_URL = "/esc-sso/oauth2.0/authorize"; + public static final String TOKEN_URL = "/esc-sso/oauth2.0/accessToken"; + public static final String USER_URL = "/esc-sso/oauth2.0/profile"; + public static final String CODE = "code"; + + private SsoConfig config; + + /** + * 过滤器名称 + * + * @return + */ + @Override + public String filterName() { + return "J7508Filter"; + } + + /** + * 过滤规则 + * + * @return + */ + @Override + public String[] urlPatterns() { + return new String[]{"/*"}; + } + + /** + * 过滤器初始化 + * + * @param filterConfig + */ + @Override + public void init(FilterConfig filterConfig) { + this.config = SsoConfig.getInstance(); + super.init(filterConfig); + } + + /** + * 过滤器处理 + * + * @param request + * @param response + * @param filterChain + */ + @Override + public void doFilter(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) { + try { + if (operation(request, response)) { + filterChain.doFilter(request, response); + } + } catch (Exception e) { + LogKit.error(e.getMessage(), e); + } + } + + /** + * 用户验证登陆操作 + * + * @param req + * @param res + * @throws Exception + */ + private boolean operation(HttpServletRequest req, HttpServletResponse res) throws Exception { + String pathInfo = (req.getPathInfo() != null) ? req.getPathInfo() : StringKit.EMPTY; + LogKit.info("sso-OAuthLogin-operation-pathInfo:{}", pathInfo); + if (pathInfo.startsWith(REMOTE_DESIGN) || pathInfo.startsWith(LOGIN_OTHER) + || StringKit.equals(LOGIN_PATH, pathInfo) || StringKit.equals(ACCOUNT_IAMPUSH, pathInfo) + || pathInfo.startsWith(RESOURCES_PATH) || pathInfo.startsWith(LOGOUT_PATH) + || pathInfo.startsWith(SYSTEM_INFO) || pathInfo.startsWith(MATERIALS_MIN_JS_MAP) + || pathInfo.startsWith(USER_LANGUAGE) || pathInfo.startsWith(FILE_PATH)) { + return true; + } + // 已登录 + if (LoginService.getInstance().isLogged(req)) { + return true; + } + String code = NetworkKit.getHTTPRequestParameter(req, CODE); + LogKit.info("sso-OAuthLogin-operation-code:{}", code); + if (StringKit.isBlank(code)) { + res.sendRedirect(getLoginUrl(req)); + return false; + } + String accessToken = getAccessToken(code); + if (StringKit.isEmpty(accessToken)) { + res.sendRedirect(getLoginUrl(req)); + return false; + } + String username = getUsername(accessToken); + if (StringKit.isEmpty(username) || !UserKit.existUsername(username)) { + return true; + } + String tokenFR = LoginKit.login(req, res, username); + req.setAttribute(DecisionServiceConstants.FINE_AUTH_TOKEN_NAME, tokenFR); + return true; + } + + /** + * 通过凭证获得username + * + * @param accessToken + * @return + */ + private String getUsername(String accessToken) throws IOException { + Map userInfoParams = new HashMap<>(); + userInfoParams.put("access_token", accessToken); + String userRes = HttpKit.get(this.config.getUriBase() + USER_URL, userInfoParams); + LogKit.info("sso-OAuthLogin-getUsername-userRes:{}", userRes); + return new JSONObject(userRes).getString("id"); + } + + /** + * 获取access_token + * + * @param code + * @return + * @throws Exception + */ + private String getAccessToken(String code) throws Exception { + Map params = new HashMap<>(); + params.put("grant_type", "authorization_code"); + params.put("oauth_timestamp", String.valueOf(System.currentTimeMillis())); + params.put("client_id", this.config.getClientId()); + params.put("client_secret", this.config.getClientSecret()); + params.put("code", code); + params.put("redirect_uri", this.config.getFrUri()); + String url = this.config.getUriBase() + TOKEN_URL; + String res = HttpKit.post(url, params); + LogKit.info("sso-OAuthLogin-getAccessToken-res:{}", res); + if (StringKit.isEmpty(res)) { + return StringKit.EMPTY; + } + String token = new JSONObject(res).getString("access_token"); + if (StringKit.isNotBlank(token)) { + return token; + } + return StringKit.EMPTY; + } + + /** + * 获取login_url + * + * @return + */ + private String getLoginUrl(HttpServletRequest request) { + String url = SsoConfig.getInstance().getUriBase() + CODE_URL; + Map params = new HashMap<>(); + params.put("client_id", SsoConfig.getInstance().getClientId()); + params.put("response_type", "code"); + params.put("redirect_uri", this.config.getFrUri()); + String loginUrl = buildUrl(url, params); + LogKit.info("sso-OAuthLogin-getLoginUrl-loginUrl:{}", loginUrl); + return loginUrl; + } + + private String buildUrl(String url, Map params) { + if (params == null || params.isEmpty()) { + return url; + } + try { + URIBuilder builder = new URIBuilder(url); + for (Map.Entry entry : params.entrySet()) { + builder.setParameter(entry.getKey(), entry.getValue()); + } + return builder.build().toString(); + } catch (URISyntaxException e) { + LogKit.debug("Error to build url, please check the arguments."); + return url; + } + } + } \ No newline at end of file diff --git a/src/main/java/com/fr/plugin/j7508/sso/request/UserControllerBridge.java b/src/main/java/com/fr/plugin/j7508/sso/request/UserControllerBridge.java new file mode 100644 index 0000000..d2db6cd --- /dev/null +++ b/src/main/java/com/fr/plugin/j7508/sso/request/UserControllerBridge.java @@ -0,0 +1,26 @@ + /* + * Copyright (C), 2018-2021 + * Project: starter + * FileName: UserControllerBridge + * Author: Louis + * Date: 2021/3/29 22:30 + */ + package com.fr.plugin.j7508.sso.request; + + import com.fr.decision.fun.impl.AbstractControllerRegisterProvider; + + /** + *
+ * + * + * @author fr.open + * @since 1.0.0 + */ + public class UserControllerBridge extends AbstractControllerRegisterProvider { + @Override + public Class[] getControllers() { + return new Class[]{ + UserPushController.class + }; + } + } \ No newline at end of file diff --git a/src/main/java/com/fr/plugin/j7508/sso/request/UserPushController.java b/src/main/java/com/fr/plugin/j7508/sso/request/UserPushController.java new file mode 100644 index 0000000..7e5aa52 --- /dev/null +++ b/src/main/java/com/fr/plugin/j7508/sso/request/UserPushController.java @@ -0,0 +1,120 @@ + /* + * Copyright (C), 2018-2021 + * Project: starter + * FileName: UserPushController + * Author: Louis + * Date: 2021/3/29 22:36 + */ + package com.fr.plugin.j7508.sso.request; + + import com.fanruan.api.decision.user.UserKit; +import com.fanruan.api.log.LogKit; + import com.fr.decision.authority.data.User; + import com.fr.decision.webservice.annotation.LoginStatusChecker; +import com.fr.decision.webservice.bean.user.UserBean; +import com.fr.decision.webservice.v10.user.UserService; +import com.fr.json.JSONArray; +import com.fr.json.JSONObject; +import com.fr.plugin.j7508.sso.bean.DataResponse; +import com.fr.plugin.j7508.sso.config.SsoConfig; +import com.fr.plugin.j7508.sso.kit.UserServiceKit; +import com.fr.third.springframework.stereotype.Controller; +import com.fr.third.springframework.web.bind.annotation.RequestBody; +import com.fr.third.springframework.web.bind.annotation.RequestMapping; +import com.fr.third.springframework.web.bind.annotation.RequestMethod; +import com.fr.third.springframework.web.bind.annotation.ResponseBody; + +import javax.servlet.http.HttpServletResponse; + + /** + *
+ * + * + * @author fr.open + * @since 1.0.0 + */ + @Controller + @RequestMapping("account/iamPush") + public class UserPushController { + private SsoConfig config; + private String adminName; + + public UserPushController() { + this.config = SsoConfig.getInstance(); + } + + @RequestMapping(method = RequestMethod.POST) + @ResponseBody + @LoginStatusChecker(required = false) + public DataResponse doAction(@RequestBody(required = false) String bodyContent, HttpServletResponse res) { + try { + LogKit.info("sso-UserPushController-doAction-bodyContent:{}", bodyContent); + JSONObject bodyJson = new JSONObject(bodyContent); + JSONArray accounts = bodyJson.getJSONArray("data"); + this.adminName = UserService.getInstance().getAdminUserNameList().get(0); + setHeader(res); + operation(accounts); + return DataResponse.success(); + } catch (Exception e) { + LogKit.error(e.getMessage(), e); + return DataResponse.error("1", "error"); + } + } + + /** + * 企业应用业务事件处理 + * + * @param accounts + * @return + */ + private void operation(JSONArray accounts) throws Exception { + for (int i = 0; i < accounts.size(); i++) { + JSONObject account = accounts.getJSONObject(i); + userSynOperation(account); + } + } + + /** + * 用户同步操作 + * + * @param account + * @throws Exception + */ + private void userSynOperation(JSONObject account) throws Exception { + String userId = account.getString("uid"); + UserBean userBean; + if (UserKit.existUsername(userId)) { + userBean = UserServiceKit.getInstance().updateUserBean(account); + if (userBean == null) { + return; + } + UserService.getInstance().editUser(userBean); + UserService.getInstance().forbidUser(userBean.getId(), userBean.isEnable()); + UserService.getInstance().updateUserDepartmentPost(UserServiceKit.getInstance().getAdminUserId(), userBean); + } else { + userBean = UserServiceKit.getInstance().createUserBean(account); + try { + UserService.getInstance().addUser(userBean); + User user = UserService.getInstance().getUserByUserName(userBean.getUsername()); + UserService.getInstance().forbidUser(user.getId(), userBean.isEnable()); + } catch (Exception e) { + LogKit.error("sso-UserPushController-userSynOperation-Username:{}, RealName:{}, Mobile:{}, Email:{}", + userBean.getUsername(), userBean.getRealName(), userBean.getMobile(), userBean.getEmail()); + LogKit.error(e.getMessage(), e); + } + } + } + + /** + * 解决跨域访问问题 + * + * @param res + */ + private void setHeader(HttpServletResponse res) { + // 跨域设置header + res.setHeader("Access-Control-Allow-Origin", "*"); + res.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE"); + res.setHeader("Access-Control-Max-Age", "3600"); + res.setHeader("Access-Control-Allow-Headers", "x-requested-with"); + } + } \ No newline at end of file diff --git a/src/main/java/com/fr/plugin/j7508/sso/user/SsoUserManager.java b/src/main/java/com/fr/plugin/j7508/sso/user/SsoUserManager.java new file mode 100644 index 0000000..24afe0f --- /dev/null +++ b/src/main/java/com/fr/plugin/j7508/sso/user/SsoUserManager.java @@ -0,0 +1,158 @@ + /* + * Copyright (C), 2018-2021 + * Project: starter + * FileName: SsoUserManager + * Author: Louis + * Date: 2021/4/21 16:18 + */ + package com.fr.plugin.j7508.sso.user; + + import com.auth0.jwt.JWT; + import com.auth0.jwt.JWTCreator; + import com.auth0.jwt.algorithms.Algorithm; + import com.fanruan.api.log.LogKit; + import com.fanruan.api.net.http.HttpKit; + import com.fanruan.api.util.StringKit; + import com.fr.decision.authority.AuthorityContext; + import com.fr.decision.authority.data.Department; + import com.fr.decision.base.util.UUIDUtil; + import com.fr.json.JSONArray; + import com.fr.json.JSONObject; + import com.fr.plugin.j7508.sso.config.SsoConfig; + import com.fr.plugin.j7508.sso.kit.DepartmentServiceKit; + import com.fr.plugin.j7508.sso.utils.SignatureUtil; + import com.fr.third.org.apache.http.entity.StringEntity; + + import java.io.IOException; + import java.util.HashMap; + import java.util.Map; + import java.util.UUID; + + import static com.fr.decision.authority.base.AuthorityConstants.DECISION_DEP_ROOT; + + /** + *
+ * + * + * @author fr.open + * @since 1.0.0 + */ + public final class SsoUserManager { + public static final String ORG_LIST_ALL = "/esb/organization/listAll/api"; + private SsoConfig config; + + public SsoUserManager() { + this.config = SsoConfig.getInstance(); + } + + private static class HOLDER { + private static final SsoUserManager INSTANCE = new SsoUserManager(); + } + public static SsoUserManager getInstance() { + return HOLDER.INSTANCE; + } + + /** + * 同步更新部门 + * + * @throws Exception + */ + public synchronized void synSSODepartments() throws Exception { + LogKit.info("sso-SsoUserManager-synSSODepartments-start"); + // 同步部门和用户信息 + departmentSynLoop(); + LogKit.info("sso-SsoUserManager-synSSODepartments-end"); + } + + /** + * 按部门遍历子部门并同步人员信息 + * + * @throws Exception + */ + private void departmentSynLoop() throws IOException { + JSONArray departmentList = getDepartmentList(); + // 同步部门信息 + for (int i = 0; i < departmentList.size(); i++) { + try { + departmentSynOperation(departmentList.optJSONObject(i)); + } catch (Exception e) { + LogKit.error(e.getMessage(), e); + } + } + } + + /** + * 部门组织的新增更新操作 + * + * @param departmentJo + * @throws Exception + */ + private void departmentSynOperation(JSONObject departmentJo) throws Exception { + LogKit.info("sso-SsoUserManager-departmentSynOperation-departmentJo:{}", departmentJo.encode()); + String departmentId = departmentJo.getString("orgCode"); + if(StringKit.equals(departmentJo.getString("status"),"1")) { + String parentId = departmentJo.getString("parentCode"); + if (StringKit.isBlank(parentId)) { parentId = DECISION_DEP_ROOT; } + String depName = departmentJo.getString("orgName"); + Department department = AuthorityContext.getInstance().getDepartmentController().getById(departmentId); + if (department == null) { + DepartmentServiceKit.getInstance().addDepartment(departmentId, parentId, depName); + } else { + DepartmentServiceKit.getInstance().editDepartment(department.getId(), depName, parentId); + } + } + if (StringKit.equals(departmentJo.getString("status"), "0")) { + DepartmentServiceKit.getInstance().deleteDepartment(departmentId); + } + } + + /** + * 通过接口获取部门列表 + * + * @return + * @throws IOException + */ + private JSONArray getDepartmentList() throws IOException { + Map headers = new HashMap<>(); + headers.put("Content-Type", "application/json;charset=UTF-8"); + headers.put("requestId", UUIDUtil.generate()); + headers.put("sourceSystem", "BI"); + headers.put("serviceName", "S_0004_syncOrgnizeAll_S"); + JSONObject params = JSONObject.create(); + params.put("size", "3000"); + params.put("page", "1"); + params.put("startTime", StringKit.EMPTY); + StringEntity stringEntity = new StringEntity(params.encode(), "UTF-8"); + String response = HttpKit.executeAndParse(com.fanruan.api.net.http.rs.HttpRequest.custom() + .url(this.config.getEsbUri() + ORG_LIST_ALL).post(stringEntity).headers(headers).build()); + LogKit.info("sso-SsoUserManager-getDepartmentList-response:{}", response); + JSONObject responseJo = new JSONObject(response); + if (StringKit.equals(responseJo.getString("code"), "0")) { + return responseJo.getJSONObject("data").getJSONArray("list"); + } + return JSONArray.create(); + } + + /** + * 产生JWT token + * + * @return + */ + private String getJWTToken() { + Map map = new HashMap<>(); + map.put("timestamp", System.currentTimeMillis() + ""); + map.put("noncestr", UUID.randomUUID().toString()); + map.put("secretKey", this.config.getAppSecret()); + String sign = SignatureUtil.getSign(map); + JWTCreator.Builder builder = JWT.create().withAudience(this.config.getAppID()); + map.remove("secretKey"); + for (Map.Entry entry : map.entrySet()) { + builder.withClaim(entry.getKey(), entry.getValue()); + } + String token = builder.sign(Algorithm.HMAC256(sign)); + if (StringKit.isNotBlank(token)) { + return token; + } + return StringKit.EMPTY; + } + } \ No newline at end of file diff --git a/src/main/java/com/fr/plugin/j7508/sso/utils/SignatureUtil.java b/src/main/java/com/fr/plugin/j7508/sso/utils/SignatureUtil.java new file mode 100644 index 0000000..a7d4183 --- /dev/null +++ b/src/main/java/com/fr/plugin/j7508/sso/utils/SignatureUtil.java @@ -0,0 +1,43 @@ +package com.fr.plugin.j7508.sso.utils; + +import com.fanruan.api.util.StringKit; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +public class SignatureUtil { + public static String getSign(Map sortedParams) { + StringBuilder content = new StringBuilder(); + List keys = new ArrayList<>(sortedParams.keySet()); + Collections.sort(keys); + int index = 0; + Iterator var4 = keys.iterator(); + while (var4.hasNext()) { + String key = var4.next(); + String value = sortedParams.get(key); + if (areNotEmpty(new String[] { key, value })) { + content.append((index == 0) ? "" : "&").append(key).append("=").append(value); + index++; + } + } + return content.toString(); + } + + public static boolean areNotEmpty(String... values) { + boolean result = true; + if (values != null && values.length != 0) { + String[] var2 = values; + int var3 = values.length; + for (int var4 = 0; var4 < var3; var4++) { + String value = var2[var4]; + result &= StringKit.isNotEmpty(value); + } + } else { + result = false; + } + return result; + } +} diff --git a/src/main/resources/com/fr/plugin/j7508/sso/locale/lang.properties b/src/main/resources/com/fr/plugin/j7508/sso/locale/lang.properties new file mode 100644 index 0000000..619b427 --- /dev/null +++ b/src/main/resources/com/fr/plugin/j7508/sso/locale/lang.properties @@ -0,0 +1,18 @@ +Plugin-J7508-Sso=Sso Plugin +Plugin-J7508-Sso_Group=Sso Plugin +Plugin-J7508-Sso_Config_FrUri=Fr Uri +Plugin-J7508-Sso_Config_FrUri_Description=Fr Uri +Plugin-J7508-Sso_Config_UriBase=Base Uri +Plugin-J7508-Sso_Config_UriBase_Description=Base Uri +Plugin-J7508-Sso_Config_EsbUri=Esb Uri +Plugin-J7508-Sso_Config_EsbUri_Description=Esb Uri +Plugin-J7508-Sso_Config_ClientId=Client Id +Plugin-J7508-Sso_Config_ClientId_Description=Client Id +Plugin-J7508-Sso_Config_ClientSecret=Client Secret +Plugin-J7508-Sso_Config_ClientSecret_Description=Client Secret +Plugin-J7508-Sso_Config_CronCondition=Cron Condition +Plugin-J7508-Sso_Config_CronCondition_Description=Cron Condition +Plugin-J7508-Sso_Config_AppID=App ID +Plugin-J7508-Sso_Config_AppID_Description=App ID +Plugin-J7508-Sso_Config_AppSecret=App Secret +Plugin-J7508-Sso_Config_AppSecret_Description=App Secret \ No newline at end of file diff --git a/src/main/resources/com/fr/plugin/j7508/sso/locale/lang_zh_CN.properties b/src/main/resources/com/fr/plugin/j7508/sso/locale/lang_zh_CN.properties new file mode 100644 index 0000000..8b1ec8d --- /dev/null +++ b/src/main/resources/com/fr/plugin/j7508/sso/locale/lang_zh_CN.properties @@ -0,0 +1,18 @@ +Plugin-J7508-Sso=\u5355\u70B9\u767B\u9646\u63D2\u4EF6 +Plugin-J7508-Sso_Group=\u5355\u70B9\u767B\u9646\u63D2\u4EF6 +Plugin-J7508-Sso_Config_FrUri=\u51B3\u7B56\u7CFB\u7EDFURL +Plugin-J7508-Sso_Config_FrUri_Description=\u51B3\u7B56\u7CFB\u7EDFURL +Plugin-J7508-Sso_Config_UriBase=\u767B\u9646\u8BA4\u8BC1\u63A5\u53E3 +Plugin-J7508-Sso_Config_UriBase_Description=\u767B\u9646\u8BA4\u8BC1\u63A5\u53E3 +Plugin-J7508-Sso_Config_EsbUri=\u7EC4\u7EC7\u4FE1\u606F\u63A5\u53E3 +Plugin-J7508-Sso_Config_EsbUri_Description=\u7EC4\u7EC7\u4FE1\u606F\u63A5\u53E3 +Plugin-J7508-Sso_Config_ClientId=\u5E94\u7528\u6CE8\u518CID +Plugin-J7508-Sso_Config_ClientId_Description=\u5E94\u7528\u6CE8\u518CID +Plugin-J7508-Sso_Config_ClientSecret=\u5E94\u7528\u6CE8\u518C\u5BC6\u7801 +Plugin-J7508-Sso_Config_ClientSecret_Description=\u5E94\u7528\u6CE8\u518C\u5BC6\u7801 +Plugin-J7508-Sso_Config_CronCondition=Cron\u8868\u8FBE\u5F0F +Plugin-J7508-Sso_Config_CronCondition_Description=Cron\u8868\u8FBE\u5F0F +Plugin-J7508-Sso_Config_AppID=IAM\u7533\u8BF7\u88AB\u63A8App ID +Plugin-J7508-Sso_Config_AppID_Description=idm\u5E94\u7528\u914D\u7F6E\u7533\u8BF7\u7684\u88AB\u63A8App ID +Plugin-J7508-Sso_Config_AppSecret=IAM\u7533\u8BF7\u88AB\u63A8App Secret +Plugin-J7508-Sso_Config_AppSecret_Description=idm\u5E94\u7528\u914D\u7F6E\u7533\u8BF7\u7684\u88AB\u63A8App Secret \ No newline at end of file