Commit 878445a238cd2f47c6cdfbe6735a16bbdd9c653f
1 parent
89df5b3c
重构社交登录,完善单元测试
Showing
8 changed files
with
109 additions
and
186 deletions
yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/enums/social/SocialTypeEnum.java
| @@ -23,33 +23,33 @@ public enum SocialTypeEnum implements IntArrayValuable { | @@ -23,33 +23,33 @@ public enum SocialTypeEnum implements IntArrayValuable { | ||
| 23 | * Gitee | 23 | * Gitee |
| 24 | * 文档链接:https://gitee.com/api/v5/oauth_doc#/ | 24 | * 文档链接:https://gitee.com/api/v5/oauth_doc#/ |
| 25 | */ | 25 | */ |
| 26 | - GITEE(10, 1, "GITEE"), | 26 | + GITEE(10, "GITEE"), |
| 27 | /** | 27 | /** |
| 28 | * 钉钉 | 28 | * 钉钉 |
| 29 | * 文档链接:https://developers.dingtalk.com/document/app/obtain-identity-credentials | 29 | * 文档链接:https://developers.dingtalk.com/document/app/obtain-identity-credentials |
| 30 | */ | 30 | */ |
| 31 | - DINGTALK(20, 2, "DINGTALK"), | 31 | + DINGTALK(20, "DINGTALK"), |
| 32 | 32 | ||
| 33 | /** | 33 | /** |
| 34 | * 企业微信 | 34 | * 企业微信 |
| 35 | * 文档链接:https://xkcoding.com/2019/08/06/use-justauth-integration-wechat-enterprise.html | 35 | * 文档链接:https://xkcoding.com/2019/08/06/use-justauth-integration-wechat-enterprise.html |
| 36 | */ | 36 | */ |
| 37 | - WECHAT_ENTERPRISE(30, 3, "WECHAT_ENTERPRISE"), | 37 | + WECHAT_ENTERPRISE(30, "WECHAT_ENTERPRISE"), |
| 38 | /** | 38 | /** |
| 39 | * 微信公众平台 - 移动端 H5 | 39 | * 微信公众平台 - 移动端 H5 |
| 40 | * 文档链接:https://www.cnblogs.com/juewuzhe/p/11905461.html | 40 | * 文档链接:https://www.cnblogs.com/juewuzhe/p/11905461.html |
| 41 | */ | 41 | */ |
| 42 | - WECHAT_MP(31, 3, "WECHAT_MP"), | 42 | + WECHAT_MP(31, "WECHAT_MP"), |
| 43 | /** | 43 | /** |
| 44 | * 微信开放平台 - 网站应用 PC 端扫码授权登录 | 44 | * 微信开放平台 - 网站应用 PC 端扫码授权登录 |
| 45 | * 文档链接:https://justauth.wiki/guide/oauth/wechat_open/#_2-申请开发者资质认证 | 45 | * 文档链接:https://justauth.wiki/guide/oauth/wechat_open/#_2-申请开发者资质认证 |
| 46 | */ | 46 | */ |
| 47 | - WECHAT_OPEN(32, 3, "WECHAT_OPEN"), | 47 | + WECHAT_OPEN(32, "WECHAT_OPEN"), |
| 48 | /** | 48 | /** |
| 49 | * 微信小程序 | 49 | * 微信小程序 |
| 50 | * 文档链接:https://developers.weixin.qq.com/miniprogram/dev/framework/open-ability/login.html | 50 | * 文档链接:https://developers.weixin.qq.com/miniprogram/dev/framework/open-ability/login.html |
| 51 | */ | 51 | */ |
| 52 | - WECHAT_MINI_PROGRAM(33, 3, "WECHAT_MINI_PROGRAM"), | 52 | + WECHAT_MINI_PROGRAM(33, "WECHAT_MINI_PROGRAM"), |
| 53 | ; | 53 | ; |
| 54 | 54 | ||
| 55 | public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(SocialTypeEnum::getType).toArray(); | 55 | public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(SocialTypeEnum::getType).toArray(); |
| @@ -59,12 +59,6 @@ public enum SocialTypeEnum implements IntArrayValuable { | @@ -59,12 +59,6 @@ public enum SocialTypeEnum implements IntArrayValuable { | ||
| 59 | */ | 59 | */ |
| 60 | private final Integer type; | 60 | private final Integer type; |
| 61 | /** | 61 | /** |
| 62 | - * 平台 | ||
| 63 | - * | ||
| 64 | - * 例如说,微信平台下,有企业微信、公众平台、开放平台、小程序等 | ||
| 65 | - */ | ||
| 66 | - private final Integer platform; | ||
| 67 | - /** | ||
| 68 | * 类型的标识 | 62 | * 类型的标识 |
| 69 | */ | 63 | */ |
| 70 | private final String source; | 64 | private final String source; |
| @@ -78,11 +72,4 @@ public enum SocialTypeEnum implements IntArrayValuable { | @@ -78,11 +72,4 @@ public enum SocialTypeEnum implements IntArrayValuable { | ||
| 78 | return ArrayUtil.firstMatch(o -> o.getType().equals(type), values()); | 72 | return ArrayUtil.firstMatch(o -> o.getType().equals(type), values()); |
| 79 | } | 73 | } |
| 80 | 74 | ||
| 81 | - public static Set<Integer> getTypes(Collection<Integer> platforms) { | ||
| 82 | - return Arrays.stream(values()) | ||
| 83 | - .filter(socialTypeEnum -> platforms.contains(socialTypeEnum.getPlatform())) | ||
| 84 | - .map(SocialTypeEnum::getType) | ||
| 85 | - .collect(Collectors.toSet()); | ||
| 86 | - } | ||
| 87 | - | ||
| 88 | } | 75 | } |
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/social/SocialUserBindDO.java
| @@ -22,6 +22,8 @@ public class SocialUserBindDO extends BaseDO { | @@ -22,6 +22,8 @@ public class SocialUserBindDO extends BaseDO { | ||
| 22 | 22 | ||
| 23 | /** | 23 | /** |
| 24 | * 关联的用户编号 | 24 | * 关联的用户编号 |
| 25 | + * | ||
| 26 | + * 关联 UserDO 的编号 | ||
| 25 | */ | 27 | */ |
| 26 | private Long userId; | 28 | private Long userId; |
| 27 | /** | 29 | /** |
| @@ -32,14 +34,16 @@ public class SocialUserBindDO extends BaseDO { | @@ -32,14 +34,16 @@ public class SocialUserBindDO extends BaseDO { | ||
| 32 | private Integer userType; | 34 | private Integer userType; |
| 33 | 35 | ||
| 34 | /** | 36 | /** |
| 35 | - * 社交平台 | 37 | + * 社交平台的用户编号 |
| 36 | * | 38 | * |
| 37 | - * 枚举 {@link SocialTypeEnum#getPlatform()} | 39 | + * 关联 {@link SocialUserDO#getId()} |
| 38 | */ | 40 | */ |
| 39 | - private Integer platform; | 41 | + private Long socialUserId; |
| 40 | /** | 42 | /** |
| 41 | - * 社交的全局编号 | 43 | + * 社交平台的类型 |
| 44 | + * | ||
| 45 | + * 冗余 {@link SocialUserDO#getType()} | ||
| 42 | */ | 46 | */ |
| 43 | - private String unionId; | 47 | + private Integer socialType; |
| 44 | 48 | ||
| 45 | } | 49 | } |
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/social/SocialUserDO.java
| 1 | package cn.iocoder.yudao.module.system.dal.dataobject.social; | 1 | package cn.iocoder.yudao.module.system.dal.dataobject.social; |
| 2 | 2 | ||
| 3 | -import cn.iocoder.yudao.module.system.dal.dataobject.user.AdminUserDO; | ||
| 4 | -import cn.iocoder.yudao.framework.common.enums.UserTypeEnum; | ||
| 5 | import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; | 3 | import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; |
| 6 | import cn.iocoder.yudao.module.system.enums.social.SocialTypeEnum; | 4 | import cn.iocoder.yudao.module.system.enums.social.SocialTypeEnum; |
| 7 | import com.baomidou.mybatisplus.annotation.TableId; | 5 | import com.baomidou.mybatisplus.annotation.TableId; |
| @@ -10,7 +8,6 @@ import lombok.*; | @@ -10,7 +8,6 @@ import lombok.*; | ||
| 10 | 8 | ||
| 11 | /** | 9 | /** |
| 12 | * 社交用户 | 10 | * 社交用户 |
| 13 | - * 通过 {@link SocialUserDO#getUserId()} 关联到对应的 {@link AdminUserDO} | ||
| 14 | * | 11 | * |
| 15 | * @author weir | 12 | * @author weir |
| 16 | */ | 13 | */ |
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/social/SocialUserBindMapper.java
| @@ -10,26 +10,23 @@ import java.util.List; | @@ -10,26 +10,23 @@ import java.util.List; | ||
| 10 | @Mapper | 10 | @Mapper |
| 11 | public interface SocialUserBindMapper extends BaseMapperX<SocialUserBindDO> { | 11 | public interface SocialUserBindMapper extends BaseMapperX<SocialUserBindDO> { |
| 12 | 12 | ||
| 13 | - default void deleteByUserTypeAndUserIdAndUnionId(Integer userType, Long userId, Integer platform) { | 13 | + default void deleteByUserTypeAndUserIdAndSocialType(Integer userType, Long userId, Integer socialType) { |
| 14 | delete(new LambdaQueryWrapperX<SocialUserBindDO>() | 14 | delete(new LambdaQueryWrapperX<SocialUserBindDO>() |
| 15 | .eq(SocialUserBindDO::getUserType, userType) | 15 | .eq(SocialUserBindDO::getUserType, userType) |
| 16 | .eq(SocialUserBindDO::getUserId, userId) | 16 | .eq(SocialUserBindDO::getUserId, userId) |
| 17 | - .eq(SocialUserBindDO::getPlatform, platform)); | 17 | + .eq(SocialUserBindDO::getSocialType, socialType)); |
| 18 | } | 18 | } |
| 19 | 19 | ||
| 20 | - default void deleteByUserTypeAndPlatformAndUnionId(Integer userType, Integer platform, String unionId) { | 20 | + default void deleteByUserTypeAndSocialUserId(Integer userType, Long socialUserId) { |
| 21 | delete(new LambdaQueryWrapperX<SocialUserBindDO>() | 21 | delete(new LambdaQueryWrapperX<SocialUserBindDO>() |
| 22 | .eq(SocialUserBindDO::getUserType, userType) | 22 | .eq(SocialUserBindDO::getUserType, userType) |
| 23 | - .eq(SocialUserBindDO::getPlatform, platform) | ||
| 24 | - .eq(SocialUserBindDO::getUnionId, unionId)); | 23 | + .eq(SocialUserBindDO::getSocialUserId, socialUserId)); |
| 25 | } | 24 | } |
| 26 | 25 | ||
| 27 | - default SocialUserBindDO selectByUserTypeAndPlatformAndUnionId(Integer userType, | ||
| 28 | - Integer platform, String unionId) { | 26 | + default SocialUserBindDO selectByUserTypeAndSocialUserId(Integer userType, Long socialUserId) { |
| 29 | return selectOne(new LambdaQueryWrapperX<SocialUserBindDO>() | 27 | return selectOne(new LambdaQueryWrapperX<SocialUserBindDO>() |
| 30 | .eq(SocialUserBindDO::getUserType, userType) | 28 | .eq(SocialUserBindDO::getUserType, userType) |
| 31 | - .eq(SocialUserBindDO::getPlatform, platform) | ||
| 32 | - .eq(SocialUserBindDO::getUnionId, unionId)); | 29 | + .eq(SocialUserBindDO::getSocialUserId, socialUserId)); |
| 33 | } | 30 | } |
| 34 | 31 | ||
| 35 | default List<SocialUserBindDO> selectListByUserIdAndUserType(Long userId, Integer userType) { | 32 | default List<SocialUserBindDO> selectListByUserIdAndUserType(Long userId, Integer userType) { |
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/social/SocialUserMapper.java
| @@ -22,13 +22,7 @@ public interface SocialUserMapper extends BaseMapperX<SocialUserDO> { | @@ -22,13 +22,7 @@ public interface SocialUserMapper extends BaseMapperX<SocialUserDO> { | ||
| 22 | default SocialUserDO selectByTypeAndOpenid(Integer type, String openid) { | 22 | default SocialUserDO selectByTypeAndOpenid(Integer type, String openid) { |
| 23 | return selectOne(new LambdaQueryWrapper<SocialUserDO>() | 23 | return selectOne(new LambdaQueryWrapper<SocialUserDO>() |
| 24 | .eq(SocialUserDO::getType, type) | 24 | .eq(SocialUserDO::getType, type) |
| 25 | - .eq(SocialUserDO::getCode, openid)); | ||
| 26 | - } | ||
| 27 | - | ||
| 28 | - default List<SocialUserDO> selectListByUnionIdAndType(Collection<String> unionIds, Collection<Integer> types) { | ||
| 29 | - return selectList(new LambdaQueryWrapper<SocialUserDO>() | ||
| 30 | - .in(SocialUserDO::getUnionId, unionIds) | ||
| 31 | - .in(SocialUserDO::getType, types)); | 25 | + .eq(SocialUserDO::getOpenid, openid)); |
| 32 | } | 26 | } |
| 33 | 27 | ||
| 34 | } | 28 | } |
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/social/SocialUserServiceImpl.java
| @@ -2,8 +2,6 @@ package cn.iocoder.yudao.module.system.service.social; | @@ -2,8 +2,6 @@ package cn.iocoder.yudao.module.system.service.social; | ||
| 2 | 2 | ||
| 3 | import cn.hutool.core.collection.CollUtil; | 3 | import cn.hutool.core.collection.CollUtil; |
| 4 | import cn.hutool.core.lang.Assert; | 4 | import cn.hutool.core.lang.Assert; |
| 5 | -import cn.hutool.core.util.StrUtil; | ||
| 6 | -import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; | ||
| 7 | import cn.iocoder.yudao.framework.common.util.http.HttpUtils; | 5 | import cn.iocoder.yudao.framework.common.util.http.HttpUtils; |
| 8 | import cn.iocoder.yudao.module.system.api.social.dto.SocialUserBindReqDTO; | 6 | import cn.iocoder.yudao.module.system.api.social.dto.SocialUserBindReqDTO; |
| 9 | import cn.iocoder.yudao.module.system.dal.dataobject.social.SocialUserBindDO; | 7 | import cn.iocoder.yudao.module.system.dal.dataobject.social.SocialUserBindDO; |
| @@ -25,9 +23,9 @@ import org.springframework.validation.annotation.Validated; | @@ -25,9 +23,9 @@ import org.springframework.validation.annotation.Validated; | ||
| 25 | import javax.annotation.Resource; | 23 | import javax.annotation.Resource; |
| 26 | import java.util.Collections; | 24 | import java.util.Collections; |
| 27 | import java.util.List; | 25 | import java.util.List; |
| 28 | -import java.util.Set; | ||
| 29 | 26 | ||
| 30 | import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; | 27 | import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; |
| 28 | +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet; | ||
| 31 | import static cn.iocoder.yudao.framework.common.util.json.JsonUtils.toJsonString; | 29 | import static cn.iocoder.yudao.framework.common.util.json.JsonUtils.toJsonString; |
| 32 | import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.*; | 30 | import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.*; |
| 33 | 31 | ||
| @@ -78,7 +76,6 @@ public class SocialUserServiceImpl implements SocialUserService { | @@ -78,7 +76,6 @@ public class SocialUserServiceImpl implements SocialUserService { | ||
| 78 | } | 76 | } |
| 79 | socialUser.setType(type).setCode(code).setState(state) // 需要保存 code + state 字段,保证后续可查询 | 77 | socialUser.setType(type).setCode(code).setState(state) // 需要保存 code + state 字段,保证后续可查询 |
| 80 | .setOpenid(authUser.getUuid()).setToken(authUser.getToken().getAccessToken()).setRawTokenInfo((toJsonString(authUser.getToken()))) | 78 | .setOpenid(authUser.getUuid()).setToken(authUser.getToken().getAccessToken()).setRawTokenInfo((toJsonString(authUser.getToken()))) |
| 81 | - .setUnionId(StrUtil.blankToDefault(authUser.getToken().getUnionId(), authUser.getUuid())) // unionId 识别多个用户 | ||
| 82 | .setNickname(authUser.getNickname()).setAvatar(authUser.getAvatar()).setRawUserInfo(toJsonString(authUser.getRawUserInfo())); | 79 | .setNickname(authUser.getNickname()).setAvatar(authUser.getAvatar()).setRawUserInfo(toJsonString(authUser.getRawUserInfo())); |
| 83 | if (socialUser.getId() == null) { | 80 | if (socialUser.getId() == null) { |
| 84 | socialUserMapper.insert(socialUser); | 81 | socialUserMapper.insert(socialUser); |
| @@ -96,9 +93,7 @@ public class SocialUserServiceImpl implements SocialUserService { | @@ -96,9 +93,7 @@ public class SocialUserServiceImpl implements SocialUserService { | ||
| 96 | return Collections.emptyList(); | 93 | return Collections.emptyList(); |
| 97 | } | 94 | } |
| 98 | // 获得社交用户 | 95 | // 获得社交用户 |
| 99 | - Set<Integer> platforms = CollectionUtils.convertSet(socialUserBinds, SocialUserBindDO::getPlatform); | ||
| 100 | - return socialUserMapper.selectListByUnionIdAndType(CollectionUtils.convertSet(socialUserBinds, SocialUserBindDO::getUnionId), | ||
| 101 | - SocialTypeEnum.getTypes(platforms)); | 96 | + return socialUserMapper.selectBatchIds(convertSet(socialUserBinds, SocialUserBindDO::getSocialUserId)); |
| 102 | } | 97 | } |
| 103 | 98 | ||
| 104 | @Override | 99 | @Override |
| @@ -108,19 +103,17 @@ public class SocialUserServiceImpl implements SocialUserService { | @@ -108,19 +103,17 @@ public class SocialUserServiceImpl implements SocialUserService { | ||
| 108 | SocialUserDO socialUser = authSocialUser(reqDTO.getType(), reqDTO.getCode(), reqDTO.getState()); | 103 | SocialUserDO socialUser = authSocialUser(reqDTO.getType(), reqDTO.getCode(), reqDTO.getState()); |
| 109 | Assert.notNull(socialUser, "社交用户不能为空"); | 104 | Assert.notNull(socialUser, "社交用户不能为空"); |
| 110 | 105 | ||
| 111 | - // 如果 unionId 之前被绑定过,需要进行解绑 | ||
| 112 | - Integer platform = SocialTypeEnum.valueOfType(socialUser.getType()).getPlatform(); | ||
| 113 | - socialUserBindMapper.deleteByUserTypeAndPlatformAndUnionId(reqDTO.getUserType(), platform, | ||
| 114 | - socialUser.getUnionId()); | 106 | + // 社交用户可能之前绑定过别的用户,需要进行解绑 |
| 107 | + socialUserBindMapper.deleteByUserTypeAndSocialUserId(reqDTO.getUserType(), socialUser.getId()); | ||
| 115 | 108 | ||
| 116 | - // 如果 userId 之前绑定过该 type 的其它账号,需要进行解绑 | ||
| 117 | - socialUserBindMapper.deleteByUserTypeAndUserIdAndUnionId(reqDTO.getUserType(), reqDTO.getUserId(), | ||
| 118 | - socialUser.getUnionId()); | 109 | + // 用户可能之前已经绑定过该社交类型,需要进行解绑 |
| 110 | + socialUserBindMapper.deleteByUserTypeAndUserIdAndSocialType(reqDTO.getUserType(), reqDTO.getUserId(), | ||
| 111 | + socialUser.getType()); | ||
| 119 | 112 | ||
| 120 | // 绑定当前登录的社交用户 | 113 | // 绑定当前登录的社交用户 |
| 121 | SocialUserBindDO socialUserBind = SocialUserBindDO.builder() | 114 | SocialUserBindDO socialUserBind = SocialUserBindDO.builder() |
| 122 | .userId(reqDTO.getUserId()).userType(reqDTO.getUserType()) | 115 | .userId(reqDTO.getUserId()).userType(reqDTO.getUserType()) |
| 123 | - .platform(platform).unionId(socialUser.getUnionId()).build(); | 116 | + .socialUserId(socialUser.getId()).socialType(socialUser.getType()).build(); |
| 124 | socialUserBindMapper.insert(socialUserBind); | 117 | socialUserBindMapper.insert(socialUserBind); |
| 125 | } | 118 | } |
| 126 | 119 | ||
| @@ -133,8 +126,7 @@ public class SocialUserServiceImpl implements SocialUserService { | @@ -133,8 +126,7 @@ public class SocialUserServiceImpl implements SocialUserService { | ||
| 133 | } | 126 | } |
| 134 | 127 | ||
| 135 | // 获得对应的社交绑定关系 | 128 | // 获得对应的社交绑定关系 |
| 136 | - socialUserBindMapper.deleteByUserTypeAndUserIdAndPlatformAndUnionId(userType, userId, | ||
| 137 | - SocialTypeEnum.valueOfType(socialUser.getType()).getPlatform(), socialUser.getUnionId()); | 129 | + socialUserBindMapper.deleteByUserTypeAndUserIdAndSocialType(userType, userId, socialUser.getType()); |
| 138 | } | 130 | } |
| 139 | 131 | ||
| 140 | @Override | 132 | @Override |
| @@ -144,8 +136,8 @@ public class SocialUserServiceImpl implements SocialUserService { | @@ -144,8 +136,8 @@ public class SocialUserServiceImpl implements SocialUserService { | ||
| 144 | Assert.notNull(socialUser, "社交用户不能为空"); | 136 | Assert.notNull(socialUser, "社交用户不能为空"); |
| 145 | 137 | ||
| 146 | // 如果未绑定的社交用户,则无法自动登录,进行报错 | 138 | // 如果未绑定的社交用户,则无法自动登录,进行报错 |
| 147 | - SocialUserBindDO socialUserBind = socialUserBindMapper.selectByUserTypeAndPlatformAndUnionId(userType, | ||
| 148 | - SocialTypeEnum.valueOfType(socialUser.getType()).getPlatform(), socialUser.getUnionId()); | 139 | + SocialUserBindDO socialUserBind = socialUserBindMapper.selectByUserTypeAndSocialUserId(userType, |
| 140 | + socialUser.getId()); | ||
| 149 | if (socialUserBind == null) { | 141 | if (socialUserBind == null) { |
| 150 | throw exception(AUTH_THIRD_LOGIN_NOT_BIND); | 142 | throw exception(AUTH_THIRD_LOGIN_NOT_BIND); |
| 151 | } | 143 | } |
yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/social/SocialUserServiceTest.java
| 1 | package cn.iocoder.yudao.module.system.service.social; | 1 | package cn.iocoder.yudao.module.system.service.social; |
| 2 | 2 | ||
| 3 | import cn.iocoder.yudao.framework.common.enums.UserTypeEnum; | 3 | import cn.iocoder.yudao.framework.common.enums.UserTypeEnum; |
| 4 | -import cn.iocoder.yudao.framework.test.core.util.AssertUtils; | ||
| 5 | -import cn.iocoder.yudao.framework.test.core.util.RandomUtils; | 4 | +import cn.iocoder.yudao.framework.test.core.ut.BaseDbAndRedisUnitTest; |
| 6 | import cn.iocoder.yudao.module.system.api.social.dto.SocialUserBindReqDTO; | 5 | import cn.iocoder.yudao.module.system.api.social.dto.SocialUserBindReqDTO; |
| 7 | import cn.iocoder.yudao.module.system.dal.dataobject.social.SocialUserBindDO; | 6 | import cn.iocoder.yudao.module.system.dal.dataobject.social.SocialUserBindDO; |
| 8 | import cn.iocoder.yudao.module.system.dal.dataobject.social.SocialUserDO; | 7 | import cn.iocoder.yudao.module.system.dal.dataobject.social.SocialUserDO; |
| 9 | import cn.iocoder.yudao.module.system.dal.mysql.social.SocialUserBindMapper; | 8 | import cn.iocoder.yudao.module.system.dal.mysql.social.SocialUserBindMapper; |
| 10 | import cn.iocoder.yudao.module.system.dal.mysql.social.SocialUserMapper; | 9 | import cn.iocoder.yudao.module.system.dal.mysql.social.SocialUserMapper; |
| 11 | -import cn.iocoder.yudao.framework.test.core.ut.BaseDbAndRedisUnitTest; | ||
| 12 | import cn.iocoder.yudao.module.system.enums.social.SocialTypeEnum; | 10 | import cn.iocoder.yudao.module.system.enums.social.SocialTypeEnum; |
| 13 | -import com.baomidou.mybatisplus.core.toolkit.PluginUtils; | ||
| 14 | import com.xkcoding.justauth.AuthRequestFactory; | 11 | import com.xkcoding.justauth.AuthRequestFactory; |
| 15 | import me.zhyd.oauth.enums.AuthResponseStatus; | 12 | import me.zhyd.oauth.enums.AuthResponseStatus; |
| 16 | import me.zhyd.oauth.model.AuthCallback; | 13 | import me.zhyd.oauth.model.AuthCallback; |
| @@ -19,16 +16,15 @@ import me.zhyd.oauth.model.AuthUser; | @@ -19,16 +16,15 @@ import me.zhyd.oauth.model.AuthUser; | ||
| 19 | import me.zhyd.oauth.request.AuthRequest; | 16 | import me.zhyd.oauth.request.AuthRequest; |
| 20 | import me.zhyd.oauth.utils.AuthStateUtils; | 17 | import me.zhyd.oauth.utils.AuthStateUtils; |
| 21 | import org.junit.jupiter.api.Test; | 18 | import org.junit.jupiter.api.Test; |
| 22 | -import org.junit.jupiter.api.function.Executable; | ||
| 23 | import org.mockito.MockedStatic; | 19 | import org.mockito.MockedStatic; |
| 24 | import org.springframework.boot.test.mock.mockito.MockBean; | 20 | import org.springframework.boot.test.mock.mockito.MockBean; |
| 25 | import org.springframework.context.annotation.Import; | 21 | import org.springframework.context.annotation.Import; |
| 26 | 22 | ||
| 27 | import javax.annotation.Resource; | 23 | import javax.annotation.Resource; |
| 28 | - | ||
| 29 | import java.util.List; | 24 | import java.util.List; |
| 30 | 25 | ||
| 31 | -import static cn.hutool.core.util.RandomUtil.*; | 26 | +import static cn.hutool.core.util.RandomUtil.randomLong; |
| 27 | +import static cn.hutool.core.util.RandomUtil.randomString; | ||
| 32 | import static cn.iocoder.yudao.framework.common.util.json.JsonUtils.toJsonString; | 28 | import static cn.iocoder.yudao.framework.common.util.json.JsonUtils.toJsonString; |
| 33 | import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals; | 29 | import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals; |
| 34 | import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertServiceException; | 30 | import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertServiceException; |
| @@ -157,24 +153,22 @@ public class SocialUserServiceTest extends BaseDbAndRedisUnitTest { | @@ -157,24 +153,22 @@ public class SocialUserServiceTest extends BaseDbAndRedisUnitTest { | ||
| 157 | assertEquals(toJsonString(authUser.getRawUserInfo()), socialUser.getRawUserInfo()); | 153 | assertEquals(toJsonString(authUser.getRawUserInfo()), socialUser.getRawUserInfo()); |
| 158 | assertEquals(type, socialUser.getType()); | 154 | assertEquals(type, socialUser.getType()); |
| 159 | assertEquals(authUser.getUuid(), socialUser.getOpenid()); | 155 | assertEquals(authUser.getUuid(), socialUser.getOpenid()); |
| 160 | - assertEquals(authUser.getToken().getUnionId(), socialUser.getUnionId()); | ||
| 161 | } | 156 | } |
| 162 | 157 | ||
| 163 | @Test | 158 | @Test |
| 164 | public void testGetSocialUserList() { | 159 | public void testGetSocialUserList() { |
| 165 | Long userId = 1L; | 160 | Long userId = 1L; |
| 166 | Integer userType = UserTypeEnum.ADMIN.getValue(); | 161 | Integer userType = UserTypeEnum.ADMIN.getValue(); |
| 167 | - // mock 获得绑定 | ||
| 168 | - socialUserBindMapper.insert(randomPojo(SocialUserBindDO.class) // 可被查询到 | ||
| 169 | - .setUserId(userId).setUserType(userType).setPlatform(SocialTypeEnum.GITEE.getPlatform()) | ||
| 170 | - .setUnionId("test_unionId")); | ||
| 171 | - socialUserBindMapper.insert(randomPojo(SocialUserBindDO.class) // 不可被查询到 | ||
| 172 | - .setUserId(2L).setUserType(userType).setPlatform(SocialTypeEnum.DINGTALK.getPlatform())); | ||
| 173 | // mock 获得社交用户 | 162 | // mock 获得社交用户 |
| 174 | - SocialUserDO socialUser = randomPojo(SocialUserDO.class).setType(SocialTypeEnum.GITEE.getType()) | ||
| 175 | - .setUnionId("test_unionId"); | 163 | + SocialUserDO socialUser = randomPojo(SocialUserDO.class).setType(SocialTypeEnum.GITEE.getType()); |
| 176 | socialUserMapper.insert(socialUser); // 可被查到 | 164 | socialUserMapper.insert(socialUser); // 可被查到 |
| 177 | socialUserMapper.insert(randomPojo(SocialUserDO.class)); // 不可被查到 | 165 | socialUserMapper.insert(randomPojo(SocialUserDO.class)); // 不可被查到 |
| 166 | + // mock 获得绑定 | ||
| 167 | + socialUserBindMapper.insert(randomPojo(SocialUserBindDO.class) // 可被查询到 | ||
| 168 | + .setUserId(userId).setUserType(userType).setSocialType(SocialTypeEnum.GITEE.getType()) | ||
| 169 | + .setSocialUserId(socialUser.getId())); | ||
| 170 | + socialUserBindMapper.insert(randomPojo(SocialUserBindDO.class) // 不可被查询到 | ||
| 171 | + .setUserId(2L).setUserType(userType).setSocialType(SocialTypeEnum.DINGTALK.getType())); | ||
| 178 | 172 | ||
| 179 | // 调用 | 173 | // 调用 |
| 180 | List<SocialUserDO> result = socialUserService.getSocialUserList(userId, userType); | 174 | List<SocialUserDO> result = socialUserService.getSocialUserList(userId, userType); |
| @@ -184,120 +178,79 @@ public class SocialUserServiceTest extends BaseDbAndRedisUnitTest { | @@ -184,120 +178,79 @@ public class SocialUserServiceTest extends BaseDbAndRedisUnitTest { | ||
| 184 | } | 178 | } |
| 185 | 179 | ||
| 186 | @Test | 180 | @Test |
| 187 | - public void testBindSocialUser_create() { | 181 | + public void testBindSocialUser() { |
| 188 | // 准备参数 | 182 | // 准备参数 |
| 189 | SocialUserBindReqDTO reqDTO = new SocialUserBindReqDTO() | 183 | SocialUserBindReqDTO reqDTO = new SocialUserBindReqDTO() |
| 190 | .setUserId(1L).setUserType(UserTypeEnum.ADMIN.getValue()) | 184 | .setUserId(1L).setUserType(UserTypeEnum.ADMIN.getValue()) |
| 191 | .setType(SocialTypeEnum.GITEE.getType()).setCode("test_code").setState("test_state"); | 185 | .setType(SocialTypeEnum.GITEE.getType()).setCode("test_code").setState("test_state"); |
| 192 | // mock 数据:获得社交用户 | 186 | // mock 数据:获得社交用户 |
| 193 | SocialUserDO socialUser = randomPojo(SocialUserDO.class).setType(reqDTO.getType()) | 187 | SocialUserDO socialUser = randomPojo(SocialUserDO.class).setType(reqDTO.getType()) |
| 194 | - .setCode(reqDTO.getCode()).setState(reqDTO.getState()).setUnionId("test_unionId"); | 188 | + .setCode(reqDTO.getCode()).setState(reqDTO.getState()); |
| 195 | socialUserMapper.insert(socialUser); | 189 | socialUserMapper.insert(socialUser); |
| 196 | - // mock 数据:解绑其它账号 | 190 | + // mock 数据:用户可能之前已经绑定过该社交类型 |
| 197 | socialUserBindMapper.insert(randomPojo(SocialUserBindDO.class).setUserId(1L).setUserType(UserTypeEnum.ADMIN.getValue()) | 191 | socialUserBindMapper.insert(randomPojo(SocialUserBindDO.class).setUserId(1L).setUserType(UserTypeEnum.ADMIN.getValue()) |
| 198 | - .setPlatform(SocialTypeEnum.GITEE.getPlatform()).setUnionId("test_delete_unionId")); | 192 | + .setSocialType(SocialTypeEnum.GITEE.getType()).setSocialUserId(-1L)); |
| 193 | + // mock 数据:社交用户可能之前绑定过别的用户 | ||
| 194 | + socialUserBindMapper.insert(randomPojo(SocialUserBindDO.class).setUserType(UserTypeEnum.ADMIN.getValue()) | ||
| 195 | + .setSocialType(SocialTypeEnum.GITEE.getType()).setSocialUserId(socialUser.getId())); | ||
| 199 | 196 | ||
| 200 | // 调用 | 197 | // 调用 |
| 201 | socialUserService.bindSocialUser(reqDTO); | 198 | socialUserService.bindSocialUser(reqDTO); |
| 202 | // 断言 | 199 | // 断言 |
| 203 | List<SocialUserBindDO> socialUserBinds = socialUserBindMapper.selectList(); | 200 | List<SocialUserBindDO> socialUserBinds = socialUserBindMapper.selectList(); |
| 204 | assertEquals(1, socialUserBinds.size()); | 201 | assertEquals(1, socialUserBinds.size()); |
| 202 | + } | ||
| 205 | 203 | ||
| 204 | + @Test | ||
| 205 | + public void testUnbindSocialUser_success() { | ||
| 206 | + // 准备参数 | ||
| 207 | + Long userId = 1L; | ||
| 208 | + Integer userType = UserTypeEnum.ADMIN.getValue(); | ||
| 209 | + Integer type = SocialTypeEnum.GITEE.getType(); | ||
| 210 | + String openid = "test_openid"; | ||
| 211 | + // mock 数据:社交用户 | ||
| 212 | + SocialUserDO socialUser = randomPojo(SocialUserDO.class).setType(type).setOpenid(openid); | ||
| 213 | + socialUserMapper.insert(socialUser); | ||
| 214 | + // mock 数据:社交绑定关系 | ||
| 215 | + SocialUserBindDO socialUserBind = randomPojo(SocialUserBindDO.class).setUserType(userType) | ||
| 216 | + .setUserId(userId).setSocialType(type); | ||
| 217 | + socialUserBindMapper.insert(socialUserBind); | ||
| 218 | + | ||
| 219 | + // 调用 | ||
| 220 | + socialUserService.unbindSocialUser(userId, userType, type, openid); | ||
| 221 | + // 断言 | ||
| 222 | + assertEquals(0, socialUserBindMapper.selectCount(null).intValue()); | ||
| 223 | + } | ||
| 224 | + | ||
| 225 | + @Test | ||
| 226 | + public void testUnbindSocialUser_notFound() { | ||
| 227 | + // 调用,并断言 | ||
| 228 | + assertServiceException( | ||
| 229 | + () -> socialUserService.unbindSocialUser(randomLong(), UserTypeEnum.ADMIN.getValue(), | ||
| 230 | + SocialTypeEnum.GITEE.getType(), "test_openid"), | ||
| 231 | + SOCIAL_USER_NOT_FOUND); | ||
| 206 | } | 232 | } |
| 207 | -// | ||
| 208 | -// /** | ||
| 209 | -// * 情况二,更新 SocialUserDO 的情况 | ||
| 210 | -// */ | ||
| 211 | -// @Test | ||
| 212 | -// public void testBindSocialUser_update() { | ||
| 213 | -// // mock 数据 | ||
| 214 | -// SocialUserDO dbSocialUser = randomPojo(SocialUserDO.class, socialUserDO -> { | ||
| 215 | -// socialUserDO.setUserType(UserTypeEnum.ADMIN.getValue()); | ||
| 216 | -// socialUserDO.setType(randomEle(SocialTypeEnum.values()).getType()); | ||
| 217 | -// }); | ||
| 218 | -// socialUserMapper.insert(dbSocialUser); | ||
| 219 | -// // 准备参数 | ||
| 220 | -// Long userId = dbSocialUser.getUserId(); | ||
| 221 | -// Integer type = dbSocialUser.getType(); | ||
| 222 | -// AuthUser authUser = randomPojo(AuthUser.class); | ||
| 223 | -// // mock 方法 | ||
| 224 | -// | ||
| 225 | -// // 调用 | ||
| 226 | -// socialService.bindSocialUser(userId, UserTypeEnum.ADMIN.getValue(), type, authUser); | ||
| 227 | -// // 断言 | ||
| 228 | -// List<SocialUserDO> socialUsers = socialUserMapper.selectList("user_id", userId); | ||
| 229 | -// assertEquals(1, socialUsers.size()); | ||
| 230 | -// assertBindSocialUser(socialUsers.get(0), authUser, userId, type); | ||
| 231 | -// } | ||
| 232 | -// | ||
| 233 | -// /** | ||
| 234 | -// * 情况一和二都存在的,逻辑二的场景 | ||
| 235 | -// */ | ||
| 236 | -// @Test | ||
| 237 | -// public void testBindSocialUser_userId() { | ||
| 238 | -// // mock 数据 | ||
| 239 | -// SocialUserDO dbSocialUser = randomPojo(SocialUserDO.class, socialUserDO -> { | ||
| 240 | -// socialUserDO.setUserType(UserTypeEnum.ADMIN.getValue()); | ||
| 241 | -// socialUserDO.setType(randomEle(SocialTypeEnum.values()).getType()); | ||
| 242 | -// }); | ||
| 243 | -// socialUserMapper.insert(dbSocialUser); | ||
| 244 | -// // 准备参数 | ||
| 245 | -// Long userId = randomLongId(); | ||
| 246 | -// Integer type = dbSocialUser.getType(); | ||
| 247 | -// AuthUser authUser = randomPojo(AuthUser.class); | ||
| 248 | -// // mock 方法 | ||
| 249 | -// | ||
| 250 | -// // 调用 | ||
| 251 | -// socialService.bindSocialUser(userId, UserTypeEnum.ADMIN.getValue(), type, authUser); | ||
| 252 | -// // 断言 | ||
| 253 | -// List<SocialUserDO> socialUsers = socialUserMapper.selectList("user_id", userId); | ||
| 254 | -// assertEquals(1, socialUsers.size()); | ||
| 255 | -// } | ||
| 256 | 233 | ||
| 257 | -// | ||
| 258 | -// /** | ||
| 259 | -// * 情况一,如果新老的 unionId 是一致的,无需解绑 | ||
| 260 | -// */ | ||
| 261 | -// @Test | ||
| 262 | -// public void testUnbindOldSocialUser_no() { | ||
| 263 | -// // mock 数据 | ||
| 264 | -// SocialUserDO oldSocialUser = randomPojo(SocialUserDO.class, socialUserDO -> { | ||
| 265 | -// socialUserDO.setUserType(UserTypeEnum.ADMIN.getValue()); | ||
| 266 | -// socialUserDO.setType(randomEle(SocialTypeEnum.values()).getType()); | ||
| 267 | -// }); | ||
| 268 | -// socialUserMapper.insert(oldSocialUser); | ||
| 269 | -// // 准备参数 | ||
| 270 | -// Long userId = oldSocialUser.getUserId(); | ||
| 271 | -// Integer type = oldSocialUser.getType(); | ||
| 272 | -// String newUnionId = oldSocialUser.getUnionId(); | ||
| 273 | -// | ||
| 274 | -// // 调用 | ||
| 275 | -// socialService.unbindOldSocialUser(userId, UserTypeEnum.ADMIN.getValue(), type, newUnionId); | ||
| 276 | -// // 断言 | ||
| 277 | -// assertEquals(1L, socialUserMapper.selectCount(null).longValue()); | ||
| 278 | -// } | ||
| 279 | -// | ||
| 280 | -// | ||
| 281 | -// /** | ||
| 282 | -// * 情况二,如果新老的 unionId 不一致的,需解绑 | ||
| 283 | -// */ | ||
| 284 | -// @Test | ||
| 285 | -// public void testUnbindOldSocialUser_yes() { | ||
| 286 | -// // mock 数据 | ||
| 287 | -// SocialUserDO oldSocialUser = randomPojo(SocialUserDO.class, socialUserDO -> { | ||
| 288 | -// socialUserDO.setUserType(UserTypeEnum.ADMIN.getValue()); | ||
| 289 | -// socialUserDO.setType(randomEle(SocialTypeEnum.values()).getType()); | ||
| 290 | -// }); | ||
| 291 | -// socialUserMapper.insert(oldSocialUser); | ||
| 292 | -// // 准备参数 | ||
| 293 | -// Long userId = oldSocialUser.getUserId(); | ||
| 294 | -// Integer type = oldSocialUser.getType(); | ||
| 295 | -// String newUnionId = randomString(10); | ||
| 296 | -// | ||
| 297 | -// // 调用 | ||
| 298 | -// socialService.unbindOldSocialUser(userId, UserTypeEnum.ADMIN.getValue(), type, newUnionId); | ||
| 299 | -// // 断言 | ||
| 300 | -// assertEquals(0L, socialUserMapper.selectCount(null).longValue()); | ||
| 301 | -// } | 234 | + @Test |
| 235 | + public void testGetBindUserId() { | ||
| 236 | + // 准备参数 | ||
| 237 | + Integer userType = UserTypeEnum.ADMIN.getValue(); | ||
| 238 | + Integer type = SocialTypeEnum.GITEE.getType(); | ||
| 239 | + String code = "tudou"; | ||
| 240 | + String state = "yuanma"; | ||
| 241 | + // mock 社交用户 | ||
| 242 | + SocialUserDO socialUser = randomPojo(SocialUserDO.class).setType(type).setCode(code).setState(state); | ||
| 243 | + socialUserMapper.insert(socialUser); | ||
| 244 | + // mock 社交用户的绑定 | ||
| 245 | + Long userId = randomLong(); | ||
| 246 | + SocialUserBindDO socialUserBind = randomPojo(SocialUserBindDO.class).setUserType(userType).setUserId(userId) | ||
| 247 | + .setSocialType(type).setSocialUserId(socialUser.getId()); | ||
| 248 | + socialUserBindMapper.insert(socialUserBind); | ||
| 249 | + | ||
| 250 | + // 调用 | ||
| 251 | + Long result = socialUserService.getBindUserId(userType, type, code, state); | ||
| 252 | + // 断言 | ||
| 253 | + assertEquals(userId, result); | ||
| 254 | + } | ||
| 302 | 255 | ||
| 303 | } | 256 | } |
yudao-module-system/yudao-module-system-biz/src/test/resources/sql/create_tables.sql
| @@ -381,7 +381,6 @@ CREATE TABLE IF NOT EXISTS "system_social_user" ( | @@ -381,7 +381,6 @@ CREATE TABLE IF NOT EXISTS "system_social_user" ( | ||
| 381 | "type" tinyint NOT NULL, | 381 | "type" tinyint NOT NULL, |
| 382 | "openid" varchar(64) NOT NULL, | 382 | "openid" varchar(64) NOT NULL, |
| 383 | "token" varchar(256) DEFAULT NULL, | 383 | "token" varchar(256) DEFAULT NULL, |
| 384 | - "union_id" varchar(64) NOT NULL, | ||
| 385 | "raw_token_info" varchar(1024) NOT NULL, | 384 | "raw_token_info" varchar(1024) NOT NULL, |
| 386 | "nickname" varchar(32) NOT NULL, | 385 | "nickname" varchar(32) NOT NULL, |
| 387 | "avatar" varchar(255) DEFAULT NULL, | 386 | "avatar" varchar(255) DEFAULT NULL, |
| @@ -399,15 +398,15 @@ CREATE TABLE IF NOT EXISTS "system_social_user" ( | @@ -399,15 +398,15 @@ CREATE TABLE IF NOT EXISTS "system_social_user" ( | ||
| 399 | CREATE TABLE IF NOT EXISTS "system_social_user_bind" ( | 398 | CREATE TABLE IF NOT EXISTS "system_social_user_bind" ( |
| 400 | "id" number NOT NULL GENERATED BY DEFAULT AS IDENTITY, | 399 | "id" number NOT NULL GENERATED BY DEFAULT AS IDENTITY, |
| 401 | "user_id" bigint NOT NULL, | 400 | "user_id" bigint NOT NULL, |
| 402 | - "user_type" tinyint NOT NULL DEFAULT '0', | ||
| 403 | - "platform" tinyint NOT NULL, | ||
| 404 | - "union_id" varchar(64) NOT NULL, | ||
| 405 | - "creator" varchar(64) DEFAULT '', | ||
| 406 | - "create_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, | ||
| 407 | - "updater" varchar(64) DEFAULT '', | ||
| 408 | - "update_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, | ||
| 409 | - "deleted" bit NOT NULL DEFAULT FALSE, | ||
| 410 | - PRIMARY KEY ("id") | 401 | + "user_type" tinyint NOT NULL, |
| 402 | + "social_type" tinyint NOT NULL, | ||
| 403 | + "social_user_id" number NOT NULL, | ||
| 404 | + "creator" varchar(64) DEFAULT '', | ||
| 405 | + "create_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, | ||
| 406 | + "updater" varchar(64) DEFAULT '', | ||
| 407 | + "update_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, | ||
| 408 | + "deleted" bit NOT NULL DEFAULT FALSE, | ||
| 409 | + PRIMARY KEY ("id") | ||
| 411 | ) COMMENT '社交用户的绑定'; | 410 | ) COMMENT '社交用户的绑定'; |
| 412 | 411 | ||
| 413 | CREATE TABLE IF NOT EXISTS "system_tenant" ( | 412 | CREATE TABLE IF NOT EXISTS "system_tenant" ( |