diff --git a/axzo-auth-spring-boot-starter/src/main/java/cn/axzo/framework/auth/annotation/PreBuildContext.java b/axzo-auth-spring-boot-starter/src/main/java/cn/axzo/framework/auth/annotation/PreBuildContext.java index 4f84552..fb8ff14 100644 --- a/axzo-auth-spring-boot-starter/src/main/java/cn/axzo/framework/auth/annotation/PreBuildContext.java +++ b/axzo-auth-spring-boot-starter/src/main/java/cn/axzo/framework/auth/annotation/PreBuildContext.java @@ -7,10 +7,17 @@ import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; import cn.axzo.framework.auth.domain.ContextInfo; +import cn.axzo.framework.auth.domain.contextvalidate.ContextInfoHandler; @Target({ElementType.METHOD, ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface PreBuildContext { Class value() default ContextInfo.class; + + /** + * 针对ContextInfo进行一些定制化处理,会按传入的顺序执行 + * @return + */ + Class[] filter() default {}; } diff --git a/axzo-auth-spring-boot-starter/src/main/java/cn/axzo/framework/auth/constants/AuthConstants.java b/axzo-auth-spring-boot-starter/src/main/java/cn/axzo/framework/auth/constants/AuthConstants.java index 5bf32a0..eb86036 100644 --- a/axzo-auth-spring-boot-starter/src/main/java/cn/axzo/framework/auth/constants/AuthConstants.java +++ b/axzo-auth-spring-boot-starter/src/main/java/cn/axzo/framework/auth/constants/AuthConstants.java @@ -2,7 +2,8 @@ package cn.axzo.framework.auth.constants; public class AuthConstants { private AuthConstants(){} - public static final String ENV_DEV="dev"; + public static final String ENV_DEV = "dev"; + public static final String App_APPID = "appid"; /** * @deprecated 之前传projectId,以后废弃 @@ -16,8 +17,8 @@ public class AuthConstants { public static final String HEADER_SAAS_TENANT_ID = "saasTenantId"; public static final String HEADER_WORKSPACE_ID = "workspaceId"; - public static final String HEADER_OU_ID = "ouId"; - + public static final String HEADER_OU_ID = "ouId"; + public static final String HEADER_TERMINAL = "terminal"; public static final String HEADER_SYSTEM_TYPE = "systemType"; diff --git a/axzo-auth-spring-boot-starter/src/main/java/cn/axzo/framework/auth/domain/SystemAndDeviceInfo.java b/axzo-auth-spring-boot-starter/src/main/java/cn/axzo/framework/auth/domain/SystemAndDeviceInfo.java index cfcb785..7756ba9 100644 --- a/axzo-auth-spring-boot-starter/src/main/java/cn/axzo/framework/auth/domain/SystemAndDeviceInfo.java +++ b/axzo-auth-spring-boot-starter/src/main/java/cn/axzo/framework/auth/domain/SystemAndDeviceInfo.java @@ -14,8 +14,15 @@ public class SystemAndDeviceInfo { private String deviceKind; private String deviceNo; - + private String appVersion; private String ipAddress; + + /** + * 登录的设备,其实是端。模糊了具体的业务类型 + * {@link TerminalInfo#NT_CM_APP_CM_LEADER} 和 {@link TerminalInfo#NT_CM_APP_CM_WORKER} + * 会转换为 {@link TerminalInfo#NT_CM_APP_GENERAL} + */ + private String loginDevice; } diff --git a/axzo-auth-spring-boot-starter/src/main/java/cn/axzo/framework/auth/domain/TerminalInfo.java b/axzo-auth-spring-boot-starter/src/main/java/cn/axzo/framework/auth/domain/TerminalInfo.java index 6451962..63b9f14 100644 --- a/axzo-auth-spring-boot-starter/src/main/java/cn/axzo/framework/auth/domain/TerminalInfo.java +++ b/axzo-auth-spring-boot-starter/src/main/java/cn/axzo/framework/auth/domain/TerminalInfo.java @@ -8,8 +8,13 @@ import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.Set; + +import jdk.nashorn.internal.ir.Terminal; import org.springframework.util.StringUtils; +import java.util.*; +import java.util.Map.Entry; + /** * 安心筑的所有终端的类型定义。 @@ -132,19 +137,43 @@ public class TerminalInfo { @Deprecated public static final String STR_TERMINAL_PL_PREFIX = "pl-"; - private static Map aliasMap = new HashMap<>(); - private static Map> ntLegacyMap = new HashMap<>(); + private static final Map aliasMap = new HashMap<>(); + private static final Map> ntLegacyMap = new HashMap<>(); @Deprecated public static final String STR_TERMINAL_SCREEN = "screen"; - + /** + * MP_WX - 微信小程序。 + * 也不会有产品板块、Feature配置在这个类型的Terminal。 + * 这里只是登录、选择具体的工作台,这一类基础的功能。 + */ + public static final String NT_MP_WX_GENERAL = "NT_MP_WX_GENERAL"; + + static { + aliasMap.put(NT_MP_WX_GENERAL, NT_MP_WX_GENERAL); + } + + + /** + * 是否是小程序 + * + * @return + */ + public boolean isMP() { + if (!StringUtils.hasText(newTerminalString)) { + return false; + } + return newTerminalString.startsWith("NT_MP_"); + } + /** * CMS - Web 还没选择任何具体的工作台。 * 也不会有产品板块、Feature配置在这个类型的Terminal。 * 这里只是登录、选择具体的工作台,这一类基础的功能。 */ public static final String NT_CMS_WEB_GENERAL = "NT_CMS_WEB_GENERAL"; + static { aliasMap.put(NT_CMS_WEB_GENERAL, NT_CMS_WEB_GENERAL); aliasMap.put(STR_TERMINAL_CMS, NT_CMS_WEB_GENERAL); @@ -217,6 +246,8 @@ public class TerminalInfo { public static final String NT_CM_APP_GENERAL = "NT_CM_APP_GENERAL"; static { aliasMap.put(NT_CM_APP_GENERAL, NT_CM_APP_GENERAL); + aliasMap.put(STR_TERMINAL_CM, NT_CM_APP_GENERAL); + aliasMap.put(NUM_TERMINAL_CM, NT_CM_APP_GENERAL); } /** * crafts man leader @@ -236,8 +267,7 @@ public class TerminalInfo { static { aliasMap.put(NT_CM_APP_CM_WORKER, NT_CM_APP_CM_WORKER); aliasMap.put(STR_TERMINAL_CM_WORKER, NT_CM_APP_CM_WORKER); - aliasMap.put(STR_TERMINAL_CM, NT_CM_APP_CM_WORKER); - aliasMap.put(NUM_TERMINAL_CM, NT_CM_APP_CM_WORKER); + // 默认把cm归到工人terminal,但可以guess一下。 } @@ -327,19 +357,19 @@ public class TerminalInfo { } } - private String rawTerminalString; + private final String rawTerminalString; - private String newTerminalString; + private final String newTerminalString; /** * 代表CMS的几个字符串,无法确切的指明一个NewTerminal */ @Deprecated - private boolean ambiguous; + private final boolean ambiguous; @Deprecated - private static Set ambiguousNames = new HashSet<>(); + private static final Set ambiguousNames = new HashSet<>(); static { ambiguousNames.add(STR_TERMINAL_CMS); ambiguousNames.add(NUM_TERMINAL_CMS); @@ -449,10 +479,7 @@ public class TerminalInfo { String legacyNT = aliasMap.get(legacyTerminalString); if (legacyNT == null) return false; - if (legacyNT.equals(this.newTerminalString)) { - return true; - } - return false; + return legacyNT.equals(this.newTerminalString); } @Deprecated @@ -607,39 +634,81 @@ public class TerminalInfo { } return null; } - + //只要端的标识,不需要分的更加的细 + public String getSimpleTerminal() { + String terminalKey = ""; + //产业工人app + if (this.isCM()) { + terminalKey = TerminalInfo.NT_CM_APP_GENERAL; + } + //从业人员app + else if (this.isCMP()) { + terminalKey = TerminalInfo.NT_CMP_APP_GENERAL; + } + //cms + else if (this.isCMS()) { + terminalKey = TerminalInfo.NT_CMS_WEB_GENERAL; + } + //oms + else if (this.isOMS_WEB()) { + terminalKey = TerminalInfo.NT_OMS_WEB; + } + //大屏 + else if (this.isSCREEN()) { + terminalKey = TerminalInfo.NT_SCREEN; + } + //智能面板 + else if (this.isPANEL()) { + terminalKey = TerminalInfo.NT_PANEL; + } //招标 + else if (this.isBID_WEB_ENT()) { + terminalKey = TerminalInfo.NT_BID_WEB_ENT; + } + //投标 + else if (this.isBID_WEB_LEADER()) { + terminalKey = TerminalInfo.NT_BID_WEB_LEADER; + } + else if (this.isMP()) { + terminalKey = TerminalInfo.NT_MP_WX_GENERAL; + } + else { + terminalKey = this.NT(); + } + return terminalKey; + } + public static void main(String[] args) { TerminalInfo tm = new TerminalInfo("proj"); System.out.println(tm.getRawTerminalString()); - System.out.println(tm.toString()); + System.out.println(tm); System.out.println(TerminalInfo.parseLegacyTerminal(tm.getRawTerminalString())); System.out.println(TerminalInfo.parseLegacyTerminalLegacyPerspective(tm.getRawTerminalString(), "proj", "ent")); System.out.println("--------"); tm = new TerminalInfo("cms"); System.out.println(tm.getRawTerminalString()); - System.out.println(tm.toString()); + System.out.println(tm); System.out.println(TerminalInfo.parseLegacyTerminal(tm.getRawTerminalString())); System.out.println(TerminalInfo.parseLegacyTerminalLegacyPerspective(tm.getRawTerminalString(), "proj", "ent")); System.out.println("--------"); tm = new TerminalInfo("ent"); System.out.println(tm.getRawTerminalString()); - System.out.println(tm.toString()); + System.out.println(tm); System.out.println(TerminalInfo.parseLegacyTerminal(tm.getRawTerminalString())); System.out.println(TerminalInfo.parseLegacyTerminalLegacyPerspective(tm.getRawTerminalString(), "proj", "ent")); System.out.println("--------"); tm = new TerminalInfo("cmp"); System.out.println(tm.getRawTerminalString()); - System.out.println(tm.toString()); + System.out.println(tm); System.out.println(TerminalInfo.parseLegacyTerminal(tm.getRawTerminalString())); System.out.println(TerminalInfo.parseLegacyTerminalLegacyPerspective(tm.getRawTerminalString(), "proj", "ent")); System.out.println("--------"); tm = new TerminalInfo(TerminalInfo.NT_CMS_WEB_PROJ); System.out.println(tm.getRawTerminalString()); - System.out.println(tm.toString()); + System.out.println(tm); System.out.println(TerminalInfo.parseLegacyTerminal(tm.getRawTerminalString())); System.out.println(TerminalInfo.parseLegacyTerminalLegacyPerspective(tm.getRawTerminalString(), "proj", "ent")); System.out.println("--------"); diff --git a/axzo-auth-spring-boot-starter/src/main/java/cn/axzo/framework/auth/domain/UserInfo.java b/axzo-auth-spring-boot-starter/src/main/java/cn/axzo/framework/auth/domain/UserInfo.java index 001d3f8..631a901 100644 --- a/axzo-auth-spring-boot-starter/src/main/java/cn/axzo/framework/auth/domain/UserInfo.java +++ b/axzo-auth-spring-boot-starter/src/main/java/cn/axzo/framework/auth/domain/UserInfo.java @@ -1,10 +1,13 @@ package cn.axzo.framework.auth.domain; +import cn.axzo.framework.auth.enums.VerifyStatusEnum; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; import lombok.extern.slf4j.Slf4j; +import java.util.Set; + @Data @Slf4j @AllArgsConstructor @@ -21,17 +24,28 @@ public class UserInfo { */ private Long identityId; + + /** + * 三方中控平台的用户ids + */ + private Set appUserIds; + private Integer identityType; /** - * 账号ID,从原axzoId迁移过来的,是用来登录、发消息、发手机短信等使用的账号。 + * 认证状态 */ - private Long acntId; + private VerifyStatusEnum verifyStatus; /** - * 手机号,是从账号表里取到的,用户登录、短信验证、消息推送都是这个phone - */ - private String phoneNumber; + * 账号ID,从原axzoId迁移过来的,是用来登录、发消息、发手机短信等使用的账号。 + */ + private Long acntId; + + /** + * 手机号,是从账号表里取到的,用户登录、短信验证、消息推送都是这个phone + */ + private String phoneNumber; /** @@ -76,7 +90,7 @@ public class UserInfo { /** * userId=identityId,身份ID * 尽量使用上面的三个ID,identityId、personId、acntId - * + * * 这个值是这样取到的: * Long oldIdentityId = ProfileIdRepair.identityNew2OldId(userInfo.getIdentityId(), userInfo.getIdentityType()); */ @@ -107,7 +121,7 @@ public class UserInfo { @Deprecated private Integer verifiedStatus; - + /** * 原账号ID == 现在的personId @@ -160,12 +174,12 @@ public class UserInfo { // * 身份验证过期时间 // */ // private boolean credentialsNonExpired; - + // /** // * 原来用来传projectId的字段,apollo用的最多 // */ // private Long tenantId; - + // /** // * 分包机构名称 // */ @@ -197,7 +211,7 @@ public class UserInfo { // * 项目一级总包部门Id // */ // private Long totalAgencyId; - + // /** // * level=用户角色类型 // * public interface UserRoleType @@ -211,7 +225,7 @@ public class UserInfo { // * 使用标准的鉴权能力,尽量少用这个字段。 // */ // //private String level; - + // /** // * 1: 工人 2: 班组长 工人身份 // */ @@ -231,9 +245,6 @@ public class UserInfo { // * 拥有权限的url // */ // private List allUrls; - - - } diff --git a/axzo-auth-spring-boot-starter/src/main/java/cn/axzo/framework/auth/domain/contextvalidate/ContextInfoHandler.java b/axzo-auth-spring-boot-starter/src/main/java/cn/axzo/framework/auth/domain/contextvalidate/ContextInfoHandler.java new file mode 100644 index 0000000..38311ee --- /dev/null +++ b/axzo-auth-spring-boot-starter/src/main/java/cn/axzo/framework/auth/domain/contextvalidate/ContextInfoHandler.java @@ -0,0 +1,23 @@ +package cn.axzo.framework.auth.domain.contextvalidate; + +import cn.axzo.framework.auth.domain.ContextInfo; + +/** + * @author tanjie@axzo.cn + * @date 2023/3/29 10:59 + */ +public interface ContextInfoHandler { + + /** + * + * @param contextInfo + * @return + * + * ***一般来说返回null就行, 若返回了非null.则会阻断业务代码运行,直接返回对应的参数给到前端 *** + *
+ * ***谨慎返回*** + * + *
+ */ + Object handler(ContextInfo contextInfo); +} diff --git a/axzo-auth-spring-boot-starter/src/main/java/cn/axzo/framework/auth/domain/contextvalidate/NonWorkspace.java b/axzo-auth-spring-boot-starter/src/main/java/cn/axzo/framework/auth/domain/contextvalidate/NonWorkspace.java new file mode 100644 index 0000000..bccf18c --- /dev/null +++ b/axzo-auth-spring-boot-starter/src/main/java/cn/axzo/framework/auth/domain/contextvalidate/NonWorkspace.java @@ -0,0 +1,31 @@ +package cn.axzo.framework.auth.domain.contextvalidate; + +import cn.axzo.framework.auth.domain.ContextInfo; +import cn.azxo.framework.common.model.CommonResponse; + +import java.lang.reflect.InvocationTargetException; + +/** + * 某些接口必须要这两个参数,校验这两个参数只要有一个字段为0或者null,则不执行业务逻辑 + * @author tanjie@axzo.cn + * @date 2023/3/29 11:33 + */ +public class NonWorkspace implements ContextInfoHandler{ + @Override + public Object handler(ContextInfo contextInfo) { + if (null != contextInfo + && (isZero(contextInfo.getOuId()) || isZero(contextInfo.getWorkspaceId()) )) { + return CommonResponse.success(); + } + return null; + } + + private boolean isZero(Long number) { + if(number == null) + return true; + if(number == 0L) + return true; + return false; + } + +} diff --git a/axzo-auth-spring-boot-starter/src/main/java/cn/axzo/framework/auth/domain/contextvalidate/ValidateVerify.java b/axzo-auth-spring-boot-starter/src/main/java/cn/axzo/framework/auth/domain/contextvalidate/ValidateVerify.java new file mode 100644 index 0000000..0881b1e --- /dev/null +++ b/axzo-auth-spring-boot-starter/src/main/java/cn/axzo/framework/auth/domain/contextvalidate/ValidateVerify.java @@ -0,0 +1,25 @@ +package cn.axzo.framework.auth.domain.contextvalidate; + +import cn.axzo.framework.auth.AuthException; +import cn.axzo.framework.auth.domain.ContextInfo; +import cn.axzo.framework.auth.domain.UserInfo; +import cn.axzo.framework.auth.enums.VerifyStatusEnum; +import cn.hutool.core.lang.Assert; + +/** + * 实名校验 + * @author tanjie@axzo.cn + * @date 2023/3/29 11:12 + */ +public class ValidateVerify implements ContextInfoHandler{ + @Override + public Object handler(ContextInfo contextInfo) { + Assert.isTrue((null != contextInfo && null != contextInfo.getUserInfo() )&& VerifyStatusEnum.VERIFY_SUCCESS.equals(contextInfo.getUserInfo().getVerifyStatus()) + , () -> new AuthException("该功能需要实名认证之后才可使用") + ); + + return null; + } + + +} diff --git a/axzo-auth-spring-boot-starter/src/main/java/cn/axzo/framework/auth/enums/VerifyStatusEnum.java b/axzo-auth-spring-boot-starter/src/main/java/cn/axzo/framework/auth/enums/VerifyStatusEnum.java new file mode 100644 index 0000000..1defbee --- /dev/null +++ b/axzo-auth-spring-boot-starter/src/main/java/cn/axzo/framework/auth/enums/VerifyStatusEnum.java @@ -0,0 +1,43 @@ +package cn.axzo.framework.auth.enums; + +import lombok.Getter; +import lombok.RequiredArgsConstructor; + +import java.util.Arrays; +import java.util.HashMap; +import java.util.Map; +import java.util.function.Function; +import java.util.stream.Collectors; + +/** + * 项目名称:profiles + * 类 名 称:ProfileSourceType + * 类 描 述:TODO + * 创建时间:2022/5/9 21:59 + * 创 建 人:xuyaozuo + */ +@Getter +@RequiredArgsConstructor +public enum VerifyStatusEnum { + //状态 0 - 未激活, 1 - 已激活,2 - 禁用,3- 认证失败 + NOT_VERIFIED(0, "未认证"), + VERIFYING(1, "认证中"), + VERIFY_SUCCESS(2, "认证成功"), + VERIFY_FAILED(3, "认证失败"), + ; + private final Integer code; + private final String message; + + private static Map map; + + public static VerifyStatusEnum codeOf(Integer code) { + if (code == null) { + return null; + } + if (map == null) { + map = new HashMap<>(values().length); + } + map = Arrays.stream(values()).collect(Collectors.toMap(VerifyStatusEnum::getCode, Function.identity())); + return map.get(code); + } +} diff --git a/axzo-auth-spring-boot-starter/src/main/java/cn/axzo/framework/auth/enums/ViewEnum.java b/axzo-auth-spring-boot-starter/src/main/java/cn/axzo/framework/auth/enums/ViewEnum.java new file mode 100644 index 0000000..6accbbb --- /dev/null +++ b/axzo-auth-spring-boot-starter/src/main/java/cn/axzo/framework/auth/enums/ViewEnum.java @@ -0,0 +1,22 @@ +package cn.axzo.framework.auth.enums; + +import lombok.Getter; +import lombok.RequiredArgsConstructor; + +/** + * 项目名称:profiles + * 类 名 称:ProfileSourceType + * 类 描 述:TODO + * 创建时间:2022/5/9 21:59 + * 创 建 人:xuyaozuo + */ +@Getter +@RequiredArgsConstructor +public enum ViewEnum { + WORKER("工人"), + TEAM_LEADER("班组长"), + TEAM_MANAGER("班组管理员"), + + ; + private final String message; +} diff --git a/axzo-auth-spring-boot-starter/src/main/java/cn/axzo/framework/auth/service/ContextInfoBuilderAspect.java b/axzo-auth-spring-boot-starter/src/main/java/cn/axzo/framework/auth/service/ContextInfoBuilderAspect.java index 40de9b8..b5bb74c 100644 --- a/axzo-auth-spring-boot-starter/src/main/java/cn/axzo/framework/auth/service/ContextInfoBuilderAspect.java +++ b/axzo-auth-spring-boot-starter/src/main/java/cn/axzo/framework/auth/service/ContextInfoBuilderAspect.java @@ -11,6 +11,7 @@ import cn.axzo.framework.auth.domain.SystemAndDeviceInfo; import cn.axzo.framework.auth.domain.TerminalInfo; import cn.axzo.framework.auth.domain.UserInfo; import cn.axzo.framework.auth.domain.UserInfoMap; +import cn.axzo.framework.auth.domain.contextvalidate.ContextInfoHandler; import cn.axzo.framework.auth.enums.EnvEnum; import cn.azxo.framework.common.logger.logback.PodNamespacePropertyDefiner; import cn.hutool.core.bean.BeanUtil; @@ -124,7 +125,13 @@ public class ContextInfoBuilderAspect { // 定制一些信息的处理 contextInfo.buildCustomInfo(httpRequest, contextInfo.getUserInfoMap()); - + //针对contextInfo拦截。或修改参数等 + for (Class filter : preBuildContext.filter()) { + Object handler = filter.newInstance().handler(contextInfo); + if (null != handler) { + return handler; + } + } // 把ContextInfo放到ThreadLocal中 ContextInfoHolder.set(contextInfo); Object[] args = parseContextInfoAndReturnArgs(httpRequest, pjp, contextInfo); @@ -309,6 +316,7 @@ public class ContextInfoBuilderAspect { try { fillLegacyGuess(contextInfo, userinfoMap); + contextInfo.getSystemAndDeviceInfo().setLoginDevice(contextInfo.getTerminalInfo().getSimpleTerminal()); } catch (Exception e) { log.warn("fill legacy guess error for user identityId=" + userInfo.getIdentityId(), e); }