Browse Source

提交开源任务材料

10.0
LAPTOP-SB56SG4Q\86185 3 years ago
parent
commit
96460f2af1
  1. BIN
      JSD-8253配置使用文档.docx
  2. BIN
      JSD-8253需求确认书.docx
  3. 5
      README.md
  4. BIN
      lib/finekit-10.0.jar
  5. 25
      plugin.xml
  6. 34
      src/main/java/com/fr/plugin/sso/LifeCycleMonitorImpl.java
  7. 37
      src/main/java/com/fr/plugin/sso/LocaleFinder.java
  8. 94
      src/main/java/com/fr/plugin/sso/bean/DataResponse.java
  9. 79
      src/main/java/com/fr/plugin/sso/config/SsoConfig.java
  10. 301
      src/main/java/com/fr/plugin/sso/kit/UserServiceKit.java
  11. 26
      src/main/java/com/fr/plugin/sso/request/ControllerRegister.java
  12. 221
      src/main/java/com/fr/plugin/sso/request/OAuthLogin.java
  13. 343
      src/main/java/com/fr/plugin/sso/request/UserController.java
  14. 10
      src/main/resources/com/fr/plugin/sso/locale/lang.properties
  15. 10
      src/main/resources/com/fr/plugin/sso/locale/lang_zh_CN.properties

BIN
JSD-8253配置使用文档.docx

Binary file not shown.

BIN
JSD-8253需求确认书.docx

Binary file not shown.

5
README.md

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

BIN
lib/finekit-10.0.jar

Binary file not shown.

25
plugin.xml

@ -0,0 +1,25 @@
<?xml version="1.0" encoding="UTF-8"?>
<plugin>
<id>com.fr.plugin.sso.auth</id>
<name><![CDATA[单点登陆jsd8253]]></name>
<active>yes</active>
<version>1.0</version>
<env-version>10.0</env-version>
<jartime>2018-07-31</jartime>
<vendor>mqh</vendor>
<description><![CDATA[单点登陆jsd8253]]></description>
<change-notes><![CDATA[单点登陆jsd8253]]></change-notes>
<main-package>com.fr.plugin.sso</main-package>
<prefer-packages>
<prefer-package>com.fanruan.api</prefer-package>
</prefer-packages>
<lifecycle-monitor class="com.fr.plugin.sso.LifeCycleMonitorImpl"/>
<extra-core>
<LocaleFinder class="com.fr.plugin.sso.LocaleFinder"/>
</extra-core>
<extra-decision>
<GlobalRequestFilterProvider class="com.fr.plugin.sso.request.OAuthLogin"/>
<ControllerRegisterProvider class="com.fr.plugin.sso.request.ControllerRegister"/>
</extra-decision>
<function-recorder class="com.fr.plugin.sso.LocaleFinder"/>
</plugin>

34
src/main/java/com/fr/plugin/sso/LifeCycleMonitorImpl.java

@ -0,0 +1,34 @@
/*
* Copyright (C), 2018-2021
* Project: starter
* FileName: LifeCycleMonitorImpl
* Author: Louis
* Date: 2021/3/30 15:10
*/
package com.fr.plugin.sso;
import com.fr.plugin.context.PluginContext;
import com.fr.plugin.observer.inner.AbstractPluginLifecycleMonitor;
import com.fr.plugin.sso.config.SsoConfig;
/**
* <Function Description><br>
* <LifeCycleMonitorImpl>
*
* @author fr.open
* @since 1.0.0
*/
public class LifeCycleMonitorImpl extends AbstractPluginLifecycleMonitor {
public LifeCycleMonitorImpl() {
}
@Override
public void afterRun(PluginContext pluginContext) {
SsoConfig.getInstance();
}
@Override
public void beforeStop(PluginContext pluginContext) {
}
}

37
src/main/java/com/fr/plugin/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.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.sso.config.SsoConfig.PLUGIN_ID;
/**
* <Function Description><br>
* <LocaleFinder>
*
* @author fr.open
* @since 1.0.0
*/
@EnableMetrics
public class LocaleFinder extends AbstractLocaleFinder {
@Override
@Focus(id = PLUGIN_ID, text = "Plugin-Sso", source = Original.PLUGIN)
public String find() {
return "com/fr/plugin/sso/locale/lang";
}
@Override
public int currentAPILevel() {
return CURRENT_LEVEL;
}
}

94
src/main/java/com/fr/plugin/sso/bean/DataResponse.java

@ -0,0 +1,94 @@
/*
* Copyright (C), 2018-2021
* Project: starter
* FileName: DataResponse
* Author: Louis
* Date: 2021/3/19 11:46
*/
package com.fr.plugin.sso.bean;
import com.fr.decision.webservice.Response;
import com.fr.stable.StringUtils;
import com.fr.third.fasterxml.jackson.annotation.JsonInclude;
/**
* <Function Description><br>
* <DataResponse>
*
* @author fr.open
* @since 1.0.0
*/
@JsonInclude(JsonInclude.Include.NON_DEFAULT)
public class DataResponse extends Response {
private static final long serialVersionUID = -6470353731188369521L;
private String code;
private String message;
public DataResponse() {
}
public DataResponse code(String code) {
this.code = code;
return this;
}
public DataResponse message(String message) {
this.message = message;
return this;
}
public DataResponse data(Object data) {
this.setData(data);
return this;
}
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
private static DataResponse create() {
return new DataResponse();
}
/**
* 操作结果
*
* @return
*/
public static DataResponse success() {
return create().code("0").message("success");
}
/**
* 操作结果
*
* @param data
* @return
*/
public static DataResponse operation(String data) {
return create().code("200").message("success").data(data);
}
/**
* 报错结果
*
* @param code
* @param message
* @return
*/
public static DataResponse error(String code, String message) {
return create().code(code).message(message).data(StringUtils.EMPTY);
}
}

79
src/main/java/com/fr/plugin/sso/config/SsoConfig.java

@ -0,0 +1,79 @@
/*
* Copyright (C), 2018-2021
* Project: starter
* FileName: OneAccessConfig
* Author: Louis
* Date: 2021/3/30 9:38
*/
package com.fr.plugin.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;
/**
* <Function Description><br>
* <SsoConfig>
*
* @author fr.open
* @since 1.0.0
*/
@Visualization(category = "Plugin-Sso_Group")
public class SsoConfig extends DefaultConfiguration {
public static final String PLUGIN_ID = "com.fr.plugin.sso.auth";
public static final String BASE_URI = "http://xxxx:8882";
private static volatile SsoConfig config = null;
@Focus(id = PLUGIN_ID, text = "Plugin-Sso", source = Original.PLUGIN)
public static SsoConfig getInstance() {
if (config == null) {
config = ConfigContext.getConfigInstance(SsoConfig.class);
}
return config;
}
@Identifier(value = "clientId", name = "Plugin-Sso_Config_ClientId", description = "Plugin-Sso_Config_ClientId_Description", status = Status.SHOW)
private Conf<String> clientId = Holders.simple(StringKit.EMPTY);
@Identifier(value = "clientSecret", name = "Plugin-Sso_Config_ClientSecret", description = "Plugin-Sso_Config_ClientSecret_Description", status = Status.SHOW)
private Conf<String> clientSecret = Holders.simple(StringKit.EMPTY);
@Identifier(value = "uriBase", name = "Plugin-Sso_Config_UriBase", description = "Plugin-Sso_Config_UriBase_Description", status = Status.SHOW)
private Conf<String> uriBase = Holders.simple(BASE_URI);
@Identifier(value = "frUri", name = "Plugin-Sso_Config_FrUri", description = "Plugin-Sso_Config_FrUri_Description", status = Status.SHOW)
private Conf<String> frUri = Holders.simple(StringKit.EMPTY);
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 getUriBase() {
return uriBase.get();
}
public void setUriBase(String uriBase) {
this.uriBase.set(uriBase);
}
public String getFrUri() {
return frUri.get();
}
public void setFrUri(String frUri) {
this.frUri.set(frUri);
}
}

301
src/main/java/com/fr/plugin/sso/kit/UserServiceKit.java

@ -0,0 +1,301 @@
/*
* Copyright (C), 2018-2021
* Project: starter
* FileName: UserServiceKit
* Author: Louis
* Date: 2021/6/7 10:00
*/
package com.fr.plugin.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.base.constant.SoftRoleType;
import com.fr.decision.authority.base.constant.type.operation.ManualOperationType;
import com.fr.decision.authority.data.BaseUserDataRecord;
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.privilege.encrpt.PasswordValidator;
import com.fr.decision.webservice.bean.user.DepartmentPostBean;
import com.fr.decision.webservice.bean.user.UserBean;
import com.fr.decision.webservice.bean.user.UserUpdateBean;
import com.fr.decision.webservice.exception.general.DuplicatedNameException;
import com.fr.decision.webservice.exception.general.SpecialCharProhibitException;
import com.fr.decision.webservice.exception.user.UserNotExistException;
import com.fr.decision.webservice.utils.CharLimitType;
import com.fr.decision.webservice.utils.UserSourceFactory;
import com.fr.decision.webservice.utils.WebServiceUtils;
import com.fr.decision.webservice.v10.login.kickout.KickOutConfig;
import com.fr.decision.webservice.v10.login.kickout.KickOutUserEvent;
import com.fr.decision.webservice.v10.user.PositionService;
import com.fr.decision.webservice.v10.user.UserService;
import com.fr.event.EventDispatcher;
import com.fr.general.ComparatorUtils;
import com.fr.json.JSONObject;
import com.fr.stable.ArrayUtils;
import com.fr.stable.StringUtils;
import com.fr.stable.collections.CollectionUtils;
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.Iterator;
import java.util.List;
/**
* <Function Description><br>
* <UserServiceKit>
* 适配jar版本20210526
*
* @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 int deleteUsers(UserUpdateBean var1) throws Exception {
String[] var2 = var1.getRemoveUserIds();
int var3 = 0;
if (var2 != null) {
String[] var4 = var2;
int var5 = var2.length;
for (int var6 = 0; var6 < var5; ++var6) {
String var7 = var4[var6];
User var8 = (User) AuthorityContext.getInstance().getUserController().getById(var7);
EventDispatcher.fire(KickOutUserEvent.KickOutUser, new KickOutConfig(new UserNotExistException(), new String[]{var8.getUserName()}));
AuthorityContext.getInstance().getUserController().remove(var7);
++var3;
// MetricRegistry.getMetric().submit(OperateMessage.build("Dec-Module-User_Manager", "Dec-User", var8.getDisplayName(), "Dec-Log_Delete"));
}
}
return var3;
}
public void addUser(UserBean var1) throws Exception {
String var2 = var1.getUsername();
String var3 = var1.getMobile();
String var4 = var1.getEmail();
String var5 = TransmissionTool.decrypt(var1.getPassword());
this.checkUsernameLegal(var2, CharLimitType.USER_LIMIT);
this.checkNonRequiredField(var3, CharLimitType.MOBILE_LIMIT);
this.checkNonRequiredField(var4, CharLimitType.EMAIL_LIMIT);
this.checkDuplicatedUser(var2);
String[] var6 = var1.getRoleIds();
PasswordValidator var7 = UserSourceFactory.getInstance().getUserSource(ManualOperationType.KEY).getPasswordValidator();
User var8 = (new User()).userName(var2).realName(var1.getRealName()).password(var7.encode(var2, var5)).email(var1.getEmail()).mobile(var1.getMobile()).creationType(ManualOperationType.KEY).lastOperationType(ManualOperationType.KEY).enable(true);
AuthorityContext.getInstance().getUserController().add(var8);
this.deleteSoftData(var8.getUserName());
String var9 = var8.getId();
if (ArrayUtils.isNotEmpty(var6)) {
String[] var10 = var6;
int var11 = var6.length;
for (int var12 = 0; var12 < var11; ++var12) {
String var13 = var10[var12];
UserSourceFactory.getInstance().checkSource(var8, (BaseUserDataRecord) AuthorityContext.getInstance().getCustomRoleController().getById(var13));
AuthorityContext.getInstance().getUserController().addUserToCustomRole(var9, var13);
}
}
if (!CollectionUtils.isEmpty(var1.getDepartmentPostIds())) {
Iterator var14 = var1.getDepartmentPostIds().iterator();
while (var14.hasNext()) {
String var15 = (String) var14.next();
if (StringUtils.isNotEmpty(var15)) {
DepRole var16 = WebServiceUtils.parseUniqueDepartmentPostId(var15);
UserSourceFactory.getInstance().checkSource(var8, (BaseUserDataRecord) AuthorityContext.getInstance().getDepartmentController().getById(var16.getDepartmentId()));
AuthorityContext.getInstance().getUserController().addUserToDepartmentAndPost(var9, var16.getDepartmentId(), var16.getPostId());
}
}
}
// MetricRegistry.getMetric().submit(OperateMessage.build("Dec-Module-User_Manager", "Dec-User", var8.getDisplayName(), "Dec-Log_Add"));
}
public void editUserInfo(UserBean var1) throws Exception {
User var2 = (User) AuthorityContext.getInstance().getUserController().getById(var1.getId());
String var3 = var1.getUsername();
String var4 = var2.getUserName();
String var5 = var1.getRealName();
String var6 = var1.getEmail();
String var7 = var1.getMobile();
this.checkNonRequiredField(var7, CharLimitType.MOBILE_LIMIT);
this.checkNonRequiredField(var6, CharLimitType.EMAIL_LIMIT);
if (StringUtils.isNotEmpty(var3) && !ComparatorUtils.equals(var4, var3)) {
this.checkDuplicatedUser(var3);
}
if (StringUtils.isNotEmpty(var5)) {
var2.setRealName(var5);
}
var2.setEmail(var6);
var2.setMobile(var7);
AuthorityContext.getInstance().getUserController().update(var2.lastOperationType(ManualOperationType.KEY));
this.deleteSoftData(var2.getUserName());
// MetricRegistry.getMetric().submit(OperateMessage.build("Dec-Module-User_Manager", "Dec-User", var2.getDisplayName(), "Dec-Log_Update"));
}
public UserBean createUserBean(JSONObject params) throws Exception {
UserBean userBean = new UserBean();
userBean.setUsername(params.getString("username"));
userBean.setEnable(!params.getBoolean("disabled"));
if (params.has("name")) {
userBean.setRealName(params.getString("name"));
}
if (params.has("mobile")) {
userBean.setMobile(params.getString("mobile"));
}
if (params.has("email")) {
userBean.setEmail(params.getString("email"));
}
userBean.setPassword(TransmissionTool.defaultEncrypt(params.getString("username") + "123456"));
if (params.has("organizationId") || params.has("organizationid")) {
String organizationId = params.has("organizationId") ? params.getString("organizationId") : params.getString("organizationid", StringUtils.EMPTY);
List<String> departmentPostIds = createDepartmentPostIds(organizationId, params.getString("position"));
userBean.setDepartmentPostIds(departmentPostIds);
}
return userBean;
}
/**
* 部门id转为部门职务组合list
*
* @param departmentPostId
* @param title
* @return
* @throws Exception
*/
private List<String> createDepartmentPostIds(String departmentPostId, String title) throws Exception {
List<String> departmentPostIds = new ArrayList<>();
// 职务处理
String positionId = positionSynOperation(title, departmentPostId);
if (StringKit.isNotBlank(positionId)) {
departmentPostId = departmentPostId + "@@@" + positionId;
}
departmentPostIds.add(departmentPostId);
return departmentPostIds;
}
/**
* 职务同步操作
*
* @param title
* @return
* @throws Exception
*/
public 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<DepartmentPostBean> departmentPostBeanList = PositionService.getInstance().getPositionsUnderParentDepartment(getAdminUserId(), departmentId, position);
if (departmentPostBeanList == null || departmentPostBeanList.isEmpty()) {
try {
AuthorityContext.getInstance().getPostController().addPostToDepartment(positionId, departmentId);
} catch (Exception e) {
LogKit.info("oneaccess-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<String> adminUserIdList = UserService.getInstance().getAdminUserIdList();
if (adminUserIdList.isEmpty()) {
return "admin";
}
return StringKit.isNotBlank(adminUserIdList.get(0)) ? adminUserIdList.get(0) : "admin";
}
@Override
public void editUser(UserBean userBean) throws Exception {
super.editUser(userBean);
this.updateUserRoles(this.getAdminUserId(), userBean);
this.updateUserDepartmentPost(this.getAdminUserId(), userBean);
}
public UserBean updateUserBean(JSONObject params) throws Exception {
User user = this.getUserByUserId(params.getString("id"));
if (user == null) {
return null;
}
UserBean userBean = new UserBean();
userBean.setId(params.getString("id"));
userBean.setUsername(params.getString("username"));
userBean.setEnable(!params.getBoolean("disabled"));
if (params.has("name")) {
userBean.setRealName(params.getString("name"));
} else {
userBean.setRealName(user.getRealName());
}
if (params.has("mobile")) {
userBean.setMobile(params.getString("mobile"));
} else {
userBean.setMobile(user.getMobile());
}
if (params.has("email")) {
userBean.setEmail(params.getString("email"));
} else {
userBean.setEmail(user.getEmail());
}
if (params.has("organizationId")) {
List<String> departmentPostIds = createDepartmentPostIds(params.getString("organizationId"), params.getString("position"));
userBean.setDepartmentPostIds(departmentPostIds);
}
return userBean;
}
private void checkNonRequiredField(String var1, CharLimitType var2) {
if (StringUtils.isNotEmpty(var1) && WebServiceUtils.containIllegalChars(var2, var1)) {
throw new SpecialCharProhibitException();
}
}
private void checkDuplicatedUser(String var1) throws Exception {
User var2 = this.getUserByUserName(var1);
if (var2 != null) {
throw new DuplicatedNameException();
}
}
private void deleteSoftData(String var1) throws Exception {
QueryCondition var2 = QueryFactory.create().addRestriction(RestrictionFactory.and(new Restriction[]{RestrictionFactory.eq("deletedName", var1), RestrictionFactory.eq("type", SoftRoleType.USER)}));
AuthorityContext.getInstance().getSoftDataController().remove(var2);
}
private void checkUsernameLegal(String var1, CharLimitType var2) throws SpecialCharProhibitException {
if (WebServiceUtils.containSQLChars(var1) || WebServiceUtils.containIllegalChars(var2, var1)) {
throw new SpecialCharProhibitException();
}
}
}

26
src/main/java/com/fr/plugin/sso/request/ControllerRegister.java

@ -0,0 +1,26 @@
/*
* Copyright (C), 2018-2021
* Project: starter
* FileName: ControllerRegister
* Author: Louis
* Date: 2021/3/29 22:30
*/
package com.fr.plugin.sso.request;
import com.fr.decision.fun.impl.AbstractControllerRegisterProvider;
/**
* <Function Description><br>
* <ControllerRegister>
*
* @author Louis
* @since 1.0.0
*/
public class ControllerRegister extends AbstractControllerRegisterProvider {
@Override
public Class<?>[] getControllers() {
return new Class[]{
UserController.class
};
}
}

221
src/main/java/com/fr/plugin/sso/request/OAuthLogin.java

@ -0,0 +1,221 @@
/*
* Copyright (C), 2018-2021
* Project: starter
* FileName: TokenLogin
* Author: Louis
* Date: 2021/3/30 22:09
*/
package com.fr.plugin.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.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;
/**
* <Function Description><br>
* <TokenLogin>
*
* @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 USER_SYN = "/syn";
public static final String CODE_URL = "/sso/oauth/authorize";
public static final String TOKEN_URL = "/sso/oauth/accessToken";
public static final String USER_URL = "/sso/oauth/userInfo";
public static final String CODE = "code";
private SsoConfig config;
/**
* 过滤器名称
*
* @return
*/
@Override
public String filterName() {
return "SsoFilter";
}
/**
* 过滤规则
*
* @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) || pathInfo.startsWith(USER_SYN)
|| 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<String, String> 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("loginName");
}
/**
* 获取access_token
*
* @param code
* @return
* @throws Exception
*/
private String getAccessToken(String code) throws Exception {
Map<String, String> params = new HashMap<>();
params.put("client_id", this.config.getClientId());
params.put("client_secret", this.config.getClientSecret());
params.put("grant_type", "authorization_code");
params.put("oauth_timestamp", String.valueOf(System.currentTimeMillis()));
params.put("redirect_uri", this.config.getFrUri());
params.put("code", code);
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<String, String> params = new HashMap<>();
params.put("response_type", "code");
params.put("client_id", SsoConfig.getInstance().getClientId());
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<String, String> params) {
if (params == null || params.isEmpty()) {
return url;
}
try {
URIBuilder builder = new URIBuilder(url);
for (Map.Entry<String, String> 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;
}
}
}

343
src/main/java/com/fr/plugin/sso/request/UserController.java

@ -0,0 +1,343 @@
/*
* Copyright (C), 2018-2021
* Project: starter
* FileName: UserController
* Author: Louis
* Date: 2021/3/29 22:36
*/
package com.fr.plugin.sso.request;
import com.fanruan.api.i18n.I18nKit;
import com.fanruan.api.log.LogKit;
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.webservice.annotation.LoginStatusChecker;
import com.fr.decision.webservice.bean.user.DepartmentPostBean;
import com.fr.decision.webservice.bean.user.UserBean;
import com.fr.decision.webservice.bean.user.UserUpdateBean;
import com.fr.decision.webservice.exception.general.DuplicatedNameException;
import com.fr.decision.webservice.v10.login.LoginService;
import com.fr.decision.webservice.v10.user.DepartmentService;
import com.fr.decision.webservice.v10.user.UserService;
import com.fr.general.ComparatorUtils;
import com.fr.json.JSONObject;
import com.fr.plugin.sso.bean.DataResponse;
import com.fr.plugin.sso.config.SsoConfig;
import com.fr.plugin.sso.kit.UserServiceKit;
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 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.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
/**
* <Function Description><br>
* <UserController>
*
* @author fr.open
* @since 1.0.0
*/
@Controller
@RequestMapping("/syn")
public class UserController {
public static final String CREATE_USER = "CREATE_USER";
public static final String UPDATE_USER = "UPDATE_USER";
public static final String DELETE_USER = "DELETE_USER";
public static final String CREATE_ORGANIZATION = "CREATE_ORGANIZATION";
public static final String UPDATE_ORGANIZATION = "UPDATE_ORGANIZATION";
public static final String DELETE_ORGANIZATION = "DELETE_ORGANIZATION";
private String adminName;
public UserController() {
SsoConfig.getInstance();
try {
this.adminName = UserService.getInstance().getAdminUserNameList().get(0);
} catch (Exception e) {
LogKit.error(e.getMessage(), e);
}
}
@RequestMapping(value = "/UserCreateService", method = RequestMethod.POST)
@ResponseBody
@LoginStatusChecker(required = false)
public DataResponse createUser(@RequestBody String paramBody, HttpServletRequest req, HttpServletResponse res) {
try {
setHeader(req, res);
return operation(CREATE_USER, paramBody);
} catch (Exception e) {
LogKit.error(e.getMessage(), e);
return DataResponse.error("500", e.getMessage());
}
}
@RequestMapping(value = "/UserUpdateService", method = RequestMethod.POST)
@ResponseBody
@LoginStatusChecker(required = false)
public DataResponse updateUser(@RequestBody String paramBody, HttpServletRequest req, HttpServletResponse res) {
try {
setHeader(req, res);
return operation(UPDATE_USER, paramBody);
} catch (Exception e) {
LogKit.error(e.getMessage(), e);
return DataResponse.error("500", e.getMessage());
}
}
@RequestMapping(value = "/UserDeleteService", method = RequestMethod.POST)
@ResponseBody
@LoginStatusChecker(required = false)
public DataResponse deleteUser(@RequestBody String paramBody, HttpServletRequest req, HttpServletResponse res) {
try {
setHeader(req, res);
return operation(DELETE_USER, paramBody);
} catch (Exception e) {
LogKit.error(e.getMessage(), e);
return DataResponse.error("500", e.getMessage());
}
}
@RequestMapping(value = "/OrgCreateService", method = RequestMethod.POST)
@ResponseBody
@LoginStatusChecker(required = false)
public DataResponse createOrg(@RequestBody String paramBody, HttpServletRequest req, HttpServletResponse res) {
try {
setHeader(req, res);
return operation(CREATE_ORGANIZATION, paramBody);
} catch (Exception e) {
LogKit.error(e.getMessage(), e);
return DataResponse.error("500", e.getMessage());
}
}
@RequestMapping(value = "/OrgUpdateService", method = RequestMethod.POST)
@ResponseBody
@LoginStatusChecker(required = false)
public DataResponse updateOrg(@RequestBody String paramBody, HttpServletRequest req, HttpServletResponse res) {
try {
setHeader(req, res);
return operation(UPDATE_ORGANIZATION, paramBody);
} catch (Exception e) {
LogKit.error(e.getMessage(), e);
return DataResponse.error("500", e.getMessage());
}
}
@RequestMapping(value = "/OrgDeleteService", method = RequestMethod.POST)
@ResponseBody
@LoginStatusChecker(required = false)
public DataResponse deleteOrg(@RequestBody String paramBody, HttpServletRequest req, HttpServletResponse res) {
try {
setHeader(req, res);
return operation(DELETE_ORGANIZATION, paramBody);
} catch (Exception e) {
LogKit.error(e.getMessage(), e);
return DataResponse.error("500", e.getMessage());
}
}
/**
* 企业应用业务事件处理
*
* @param eventType
* @param paramBody
* @return
*/
private DataResponse operation(String eventType, String paramBody) throws Exception {
DataResponse dataResponse = null;
JSONObject requestData = new JSONObject(paramBody);
LogKit.info("sso-CallBackController-operation-eventType:{}, requestData:{}", eventType, requestData);
switch (eventType) {
case CREATE_ORGANIZATION:
dataResponse = createOrganization(requestData);
break;
case UPDATE_ORGANIZATION:
dataResponse = updateOrganization(requestData);
break;
case DELETE_ORGANIZATION:
dataResponse = deleteOrganization(requestData);
break;
case CREATE_USER:
dataResponse = createUser(requestData);
break;
case UPDATE_USER:
dataResponse = updateUser(requestData);
break;
case DELETE_USER:
dataResponse = deleteUser(requestData);
break;
}
return dataResponse;
}
/**
* 新增组织事件
*
* @param requestData
* @return
*/
private DataResponse createOrganization(JSONObject requestData) throws Exception {
String code = requestData.getString("code");
String parentId = requestData.has("parentId") ? requestData.getString("parentId") : requestData.getString("parentid");
String depName = requestData.getString("name");
DepartmentPostBean departmentPostBean = this.addDepartment(code, parentId, depName);
return DataResponse.operation(responseDataJSON(departmentPostBean.getId()));
}
private DepartmentPostBean addDepartment(String id, String pId, String depName) throws Exception {
if (ComparatorUtils.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"));
return new DepartmentPostBean(department.getId(), false, false, department.getParentId(), "", department.getName());
}
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 = (Department) AuthorityContext.getInstance().getDepartmentController().findOne(condition);
if (sameNameDep != null) {
throw new DuplicatedNameException();
}
}
private String getDepartmentFullPath(String pId, String depName, String splitter) throws Exception {
List<String> paths = new ArrayList();
paths.add(depName);
while (!ComparatorUtils.equals(pId, "decision-dep-root") && pId != null) {
Department parentDepartment = (Department) AuthorityContext.getInstance().getDepartmentController().getById(pId);
paths.add(parentDepartment.getName());
pId = parentDepartment.getParentId();
}
Collections.reverse(paths);
return StableUtils.join(paths.toArray(new String[0]), splitter);
}
/**
* 更新组织事件
*
* @param requestData
* @return
*/
private DataResponse updateOrganization(JSONObject requestData) throws Exception {
String departmentId = requestData.getString("id");
String depName = requestData.getString("name");
String parentId = requestData.has("parentId") ? requestData.getString("parentId") : requestData.getString("parentid");
this.editDepartment(departmentId, depName, parentId);
return DataResponse.operation(responseDataJSON(departmentId));
}
private void editDepartment(String departmentId, String depName, String pId) throws Exception {
if (ComparatorUtils.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", InterProviderFactory.getProvider().getLocText("Fine-Dec_Department") + ":" + departmentFullPath));
}
/**
* 删除组织事件
*
* @param requestData
* @return
*/
private DataResponse deleteOrganization(JSONObject requestData) throws Exception {
String departmentId = requestData.getString("id");
DepartmentService.getInstance().deleteDepartment(departmentId);
return DataResponse.success();
}
/**
* 新增用户事件
*
* @param requestData
* @return
*/
private DataResponse createUser(JSONObject requestData) throws Exception {
UserBean userBean = UserServiceKit.getInstance().createUserBean(requestData);
UserServiceKit.getInstance().addUser(userBean);
String userId = UserService.getInstance().getUserByUserName(userBean.getUsername()).getId();
return DataResponse.operation(responseDataJSON(userId));
}
/**
* 更新用户事件
*
* @param requestData
* @return
*/
private DataResponse updateUser(JSONObject requestData) throws Exception {
UserBean userBean = UserServiceKit.getInstance().updateUserBean(requestData);
if (userBean == null) {
return DataResponse.error("500", I18nKit.getLocText("Plugin-OneAccess_Error_500"));
}
UserServiceKit.getInstance().editUser(userBean);
return DataResponse.operation(responseDataJSON(userBean.getId()));
}
/**
* 更新用户事件
*
* @param requestData
* @return
*/
private DataResponse deleteUser(JSONObject requestData) throws Exception {
String[] removeUserIds = new String[]{requestData.getString("id")};
UserUpdateBean userUpdateBean = new UserUpdateBean();
userUpdateBean.setRemoveUserIds(removeUserIds);
int flag = UserServiceKit.getInstance().deleteUsers(userUpdateBean);
if (flag > 0) {
return DataResponse.success();
} else {
return DataResponse.error("404", "error");
}
}
/**
* 设定相应结果
*
* @param id
* @return
*/
private String responseDataJSON(String id) {
JSONObject responseData = new JSONObject();
responseData.put("id", id);
return responseData.encode();
}
/**
* 解决跨域访问问题
*
* @param res
*/
private void setHeader(HttpServletRequest req, HttpServletResponse res) throws Exception {
LoginService.getInstance().login(req, res, this.adminName);
// 跨域设置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");
}
}

10
src/main/resources/com/fr/plugin/sso/locale/lang.properties

@ -0,0 +1,10 @@
Plugin-Sso=Sso Plugin
Plugin-Sso_Group=Sso Plugin
Plugin-Sso_Config_ClientId=Client Id
Plugin-Sso_Config_ClientId_Description=Client Id
Plugin-Sso_Config_ClientSecret=Client Secret
Plugin-Sso_Config_ClientSecret_Description=Client Secret
Plugin-Sso_Config_UriBase= Uri Base
Plugin-Sso_Config_UriBase_Description=Uri Base
Plugin-Sso_Config_FrUri=FR Uri
Plugin-Sso_Config_FrUri_Description=FR Uri

10
src/main/resources/com/fr/plugin/sso/locale/lang_zh_CN.properties

@ -0,0 +1,10 @@
Plugin-Sso=\u5355\u70B9\u767B\u9646\u63D2\u4EF6
Plugin-Sso_Group=\u5355\u70B9\u767B\u9646\u63D2\u4EF6
Plugin-Sso_Config_ClientId=\u5E06\u8F6F\u7CFB\u7EDFClient Id
Plugin-Sso_Config_ClientId_Description=\u5E06\u8F6F\u7CFB\u7EDFClient Id
Plugin-Sso_Config_ClientSecret=\u5E06\u8F6F\u7CFB\u7EDFClient Secret
Plugin-Sso_Config_ClientSecret_Description=\u5E06\u8F6F\u7CFB\u7EDFClient Secret
Plugin-Sso_Config_UriBase=\u63A5\u53E3\u5730\u5740
Plugin-Sso_Config_UriBase_Description=\u63A5\u53E3\u5730\u5740
Plugin-Sso_Config_FrUri=\u5E06\u8F6F\u7CFB\u7EDFurl
Plugin-Sso_Config_FrUri_Description=\u5E06\u8F6F\u7CFB\u7EDFurl
Loading…
Cancel
Save