Commit b3ab1d9285be30ec00d8f62e14b1294b17e888d8

Authored by YunaiV
1 parent 66855135

完善 OAuth2ClientServiceImplTest 单元测试

Showing 12 changed files with 198 additions and 99 deletions
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/oauth2/OAuth2OpenController.http
@@ -52,18 +52,3 @@ tenant-id: {{adminTenentId}} @@ -52,18 +52,3 @@ tenant-id: {{adminTenentId}}
52 POST {{baseUrl}}/system/oauth2/check-token?token=620d307c5b4148df8a98dd6c6c547106 52 POST {{baseUrl}}/system/oauth2/check-token?token=620d307c5b4148df8a98dd6c6c547106
53 Authorization: Basic ZGVmYXVsdDphZG1pbjEyMw== 53 Authorization: Basic ZGVmYXVsdDphZG1pbjEyMw==
54 tenant-id: {{adminTenentId}} 54 tenant-id: {{adminTenentId}}
55 -  
56 -### 请求 /system/oauth2/user/get 接口 => 成功  
57 -GET {{baseUrl}}/system/oauth2/user/get  
58 -Authorization: Bearer 9502bd7a768a4ade920b90f41e2efd5c  
59 -tenant-id: {{adminTenentId}}  
60 -  
61 -### 请求 /system/oauth2/user/update 接口 => 成功  
62 -PUT {{baseUrl}}/system/oauth2/user/update  
63 -Content-Type: application/json  
64 -Authorization: Bearer 9502bd7a768a4ade920b90f41e2efd5c  
65 -tenant-id: {{adminTenentId}}  
66 -  
67 -{  
68 - "nickname": "芋道源码"  
69 -}  
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/oauth2/OAuth2OpenController.java
1 package cn.iocoder.yudao.module.system.controller.admin.oauth2; 1 package cn.iocoder.yudao.module.system.controller.admin.oauth2;
2 2
3 -import cn.hutool.core.collection.CollUtil;  
4 import cn.hutool.core.lang.Assert; 3 import cn.hutool.core.lang.Assert;
5 import cn.hutool.core.util.ArrayUtil; 4 import cn.hutool.core.util.ArrayUtil;
6 import cn.hutool.core.util.ObjectUtil; 5 import cn.hutool.core.util.ObjectUtil;
@@ -13,36 +12,26 @@ import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog; @@ -13,36 +12,26 @@ import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog;
13 import cn.iocoder.yudao.module.system.controller.admin.oauth2.vo.open.OAuth2OpenAccessTokenRespVO; 12 import cn.iocoder.yudao.module.system.controller.admin.oauth2.vo.open.OAuth2OpenAccessTokenRespVO;
14 import cn.iocoder.yudao.module.system.controller.admin.oauth2.vo.open.OAuth2OpenAuthorizeInfoRespVO; 13 import cn.iocoder.yudao.module.system.controller.admin.oauth2.vo.open.OAuth2OpenAuthorizeInfoRespVO;
15 import cn.iocoder.yudao.module.system.controller.admin.oauth2.vo.open.OAuth2OpenCheckTokenRespVO; 14 import cn.iocoder.yudao.module.system.controller.admin.oauth2.vo.open.OAuth2OpenCheckTokenRespVO;
16 -import cn.iocoder.yudao.module.system.controller.admin.oauth2.vo.open.user.OAuth2OpenUserInfoRespVO;  
17 -import cn.iocoder.yudao.module.system.controller.admin.oauth2.vo.open.user.OAuth2OpenUserUpdateReqVO;  
18 import cn.iocoder.yudao.module.system.convert.oauth2.OAuth2OpenConvert; 15 import cn.iocoder.yudao.module.system.convert.oauth2.OAuth2OpenConvert;
19 -import cn.iocoder.yudao.module.system.dal.dataobject.dept.DeptDO;  
20 -import cn.iocoder.yudao.module.system.dal.dataobject.dept.PostDO;  
21 import cn.iocoder.yudao.module.system.dal.dataobject.oauth2.OAuth2AccessTokenDO; 16 import cn.iocoder.yudao.module.system.dal.dataobject.oauth2.OAuth2AccessTokenDO;
22 import cn.iocoder.yudao.module.system.dal.dataobject.oauth2.OAuth2ApproveDO; 17 import cn.iocoder.yudao.module.system.dal.dataobject.oauth2.OAuth2ApproveDO;
23 import cn.iocoder.yudao.module.system.dal.dataobject.oauth2.OAuth2ClientDO; 18 import cn.iocoder.yudao.module.system.dal.dataobject.oauth2.OAuth2ClientDO;
24 -import cn.iocoder.yudao.module.system.dal.dataobject.user.AdminUserDO;  
25 import cn.iocoder.yudao.module.system.enums.auth.OAuth2GrantTypeEnum; 19 import cn.iocoder.yudao.module.system.enums.auth.OAuth2GrantTypeEnum;
26 -import cn.iocoder.yudao.module.system.service.dept.DeptService;  
27 -import cn.iocoder.yudao.module.system.service.dept.PostService;  
28 import cn.iocoder.yudao.module.system.service.oauth2.OAuth2ApproveService; 20 import cn.iocoder.yudao.module.system.service.oauth2.OAuth2ApproveService;
29 import cn.iocoder.yudao.module.system.service.oauth2.OAuth2ClientService; 21 import cn.iocoder.yudao.module.system.service.oauth2.OAuth2ClientService;
30 import cn.iocoder.yudao.module.system.service.oauth2.OAuth2GrantService; 22 import cn.iocoder.yudao.module.system.service.oauth2.OAuth2GrantService;
31 import cn.iocoder.yudao.module.system.service.oauth2.OAuth2TokenService; 23 import cn.iocoder.yudao.module.system.service.oauth2.OAuth2TokenService;
32 -import cn.iocoder.yudao.module.system.service.user.AdminUserService;  
33 import cn.iocoder.yudao.module.system.util.oauth2.OAuth2Utils; 24 import cn.iocoder.yudao.module.system.util.oauth2.OAuth2Utils;
34 import io.swagger.annotations.Api; 25 import io.swagger.annotations.Api;
35 import io.swagger.annotations.ApiImplicitParam; 26 import io.swagger.annotations.ApiImplicitParam;
36 import io.swagger.annotations.ApiImplicitParams; 27 import io.swagger.annotations.ApiImplicitParams;
37 import io.swagger.annotations.ApiOperation; 28 import io.swagger.annotations.ApiOperation;
38 import lombok.extern.slf4j.Slf4j; 29 import lombok.extern.slf4j.Slf4j;
39 -import org.springframework.security.access.prepost.PreAuthorize;  
40 import org.springframework.validation.annotation.Validated; 30 import org.springframework.validation.annotation.Validated;
41 import org.springframework.web.bind.annotation.*; 31 import org.springframework.web.bind.annotation.*;
42 32
43 import javax.annotation.Resource; 33 import javax.annotation.Resource;
44 import javax.servlet.http.HttpServletRequest; 34 import javax.servlet.http.HttpServletRequest;
45 -import javax.validation.Valid;  
46 import java.util.Collections; 35 import java.util.Collections;
47 import java.util.List; 36 import java.util.List;
48 import java.util.Map; 37 import java.util.Map;
@@ -61,7 +50,9 @@ import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUti @@ -61,7 +50,9 @@ import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUti
61 * 另外,一个公司如果有多个管理后台,它们 client_id 产生的 access token 相互之间是无法互通的,即无法访问它们系统的 API 接口,直到两个 client_id 产生信任授权。 50 * 另外,一个公司如果有多个管理后台,它们 client_id 产生的 access token 相互之间是无法互通的,即无法访问它们系统的 API 接口,直到两个 client_id 产生信任授权。
62 * 51 *
63 * 考虑到【本系统】暂时不想做的过于复杂,默认只有获取到 access token 之后,可以访问【本系统】管理后台的 /system-api/* 所有接口,除非手动添加 scope 控制。 52 * 考虑到【本系统】暂时不想做的过于复杂,默认只有获取到 access token 之后,可以访问【本系统】管理后台的 /system-api/* 所有接口,除非手动添加 scope 控制。
64 - * scope 的使用示例,可见当前类的 getUserInfo 和 updateUserInfo 方法,上面有 @PreAuthorize("@ss.hasScope('user.read')") 和 @PreAuthorize("@ss.hasScope('user.write')") 注解 53 + * scope 的使用示例,可见 {@link OAuth2UserController} 类
  54 + *
  55 + *
65 * 56 *
66 * @author 芋道源码 57 * @author 芋道源码
67 */ 58 */
@@ -306,43 +297,4 @@ public class OAuth2OpenController { @@ -306,43 +297,4 @@ public class OAuth2OpenController {
306 return clientIdAndSecret; 297 return clientIdAndSecret;
307 } 298 }
308 299
309 - // ============ 用户操作的示例,展示 scope 的使用 ============  
310 -  
311 - @Resource  
312 - private AdminUserService userService;  
313 - @Resource  
314 - private DeptService deptService;  
315 - @Resource  
316 - private PostService postService;  
317 -  
318 - @GetMapping("/user/get")  
319 - @ApiOperation("获得用户基本信息")  
320 - @PreAuthorize("@ss.hasScope('user.read')")  
321 - public CommonResult<OAuth2OpenUserInfoRespVO> getUserInfo() {  
322 - // 获得用户基本信息  
323 - AdminUserDO user = userService.getUser(getLoginUserId());  
324 - OAuth2OpenUserInfoRespVO resp = OAuth2OpenConvert.INSTANCE.convert(user);  
325 - // 获得部门信息  
326 - if (user.getDeptId() != null) {  
327 - DeptDO dept = deptService.getDept(user.getDeptId());  
328 - resp.setDept(OAuth2OpenConvert.INSTANCE.convert(dept));  
329 - }  
330 - // 获得岗位信息  
331 - if (CollUtil.isNotEmpty(user.getPostIds())) {  
332 - List<PostDO> posts = postService.getPosts(user.getPostIds());  
333 - resp.setPosts(OAuth2OpenConvert.INSTANCE.convertList(posts));  
334 - }  
335 - return success(resp);  
336 - }  
337 -  
338 - @PutMapping("/user/update")  
339 - @ApiOperation("更新用户基本信息")  
340 - @PreAuthorize("@ss.hasScope('user.write')")  
341 - public CommonResult<Boolean> updateUserInfo(@Valid @RequestBody OAuth2OpenUserUpdateReqVO reqVO) {  
342 - // 这里将 UserProfileUpdateReqVO =》UserProfileUpdateReqVO 对象,实现接口的复用。  
343 - // 主要是,AdminUserService 没有自己的 BO 对象,所以复用只能这么做  
344 - userService.updateUserProfile(getLoginUserId(), OAuth2OpenConvert.INSTANCE.convert(reqVO));  
345 - return success(true);  
346 - }  
347 -  
348 } 300 }
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/oauth2/OAuth2UserController.http 0 → 100644
  1 +### 请求 /system/oauth2/user/get 接口 => 成功
  2 +GET {{baseUrl}}/system/oauth2/user/get
  3 +Authorization: Bearer 47f9c74ec11041f193b777ebb95c3b0d
  4 +tenant-id: {{adminTenentId}}
  5 +
  6 +### 请求 /system/oauth2/user/update 接口 => 成功
  7 +PUT {{baseUrl}}/system/oauth2/user/update
  8 +Content-Type: application/json
  9 +Authorization: Bearer 47f9c74ec11041f193b777ebb95c3b0d
  10 +tenant-id: {{adminTenentId}}
  11 +
  12 +{
  13 + "nickname": "芋道源码"
  14 +}
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/oauth2/OAuth2UserController.java 0 → 100644
  1 +package cn.iocoder.yudao.module.system.controller.admin.oauth2;
  2 +
  3 +import cn.hutool.core.collection.CollUtil;
  4 +import cn.iocoder.yudao.framework.common.pojo.CommonResult;
  5 +import cn.iocoder.yudao.module.system.controller.admin.oauth2.vo.user.OAuth2UserInfoRespVO;
  6 +import cn.iocoder.yudao.module.system.controller.admin.oauth2.vo.user.OAuth2UserUpdateReqVO;
  7 +import cn.iocoder.yudao.module.system.convert.oauth2.OAuth2UserConvert;
  8 +import cn.iocoder.yudao.module.system.dal.dataobject.dept.DeptDO;
  9 +import cn.iocoder.yudao.module.system.dal.dataobject.dept.PostDO;
  10 +import cn.iocoder.yudao.module.system.dal.dataobject.user.AdminUserDO;
  11 +import cn.iocoder.yudao.module.system.service.dept.DeptService;
  12 +import cn.iocoder.yudao.module.system.service.dept.PostService;
  13 +import cn.iocoder.yudao.module.system.service.user.AdminUserService;
  14 +import io.swagger.annotations.Api;
  15 +import io.swagger.annotations.ApiOperation;
  16 +import lombok.extern.slf4j.Slf4j;
  17 +import org.springframework.security.access.prepost.PreAuthorize;
  18 +import org.springframework.validation.annotation.Validated;
  19 +import org.springframework.web.bind.annotation.*;
  20 +
  21 +import javax.annotation.Resource;
  22 +import javax.validation.Valid;
  23 +import java.util.List;
  24 +
  25 +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
  26 +import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
  27 +
  28 +/**
  29 + * 提供给外部应用调用为主
  30 + *
  31 + * 1. 在 getUserInfo 方法上,添加 @PreAuthorize("@ss.hasScope('user.read')") 注解,声明需要满足 scope = user.read
  32 + * 2. 在 updateUserInfo 方法上,添加 @PreAuthorize("@ss.hasScope('user.write')") 注解,声明需要满足 scope = user.write
  33 + *
  34 + * @author 芋道源码
  35 + */
  36 +@Api(tags = "管理后台 - OAuth2.0 用户")
  37 +@RestController
  38 +@RequestMapping("/system/oauth2/user")
  39 +@Validated
  40 +@Slf4j
  41 +public class OAuth2UserController {
  42 +
  43 + @Resource
  44 + private AdminUserService userService;
  45 + @Resource
  46 + private DeptService deptService;
  47 + @Resource
  48 + private PostService postService;
  49 +
  50 + @GetMapping("/get")
  51 + @ApiOperation("获得用户基本信息")
  52 + @PreAuthorize("@ss.hasScope('user.read')") //
  53 + public CommonResult<OAuth2UserInfoRespVO> getUserInfo() {
  54 + // 获得用户基本信息
  55 + AdminUserDO user = userService.getUser(getLoginUserId());
  56 + OAuth2UserInfoRespVO resp = OAuth2UserConvert.INSTANCE.convert(user);
  57 + // 获得部门信息
  58 + if (user.getDeptId() != null) {
  59 + DeptDO dept = deptService.getDept(user.getDeptId());
  60 + resp.setDept(OAuth2UserConvert.INSTANCE.convert(dept));
  61 + }
  62 + // 获得岗位信息
  63 + if (CollUtil.isNotEmpty(user.getPostIds())) {
  64 + List<PostDO> posts = postService.getPosts(user.getPostIds());
  65 + resp.setPosts(OAuth2UserConvert.INSTANCE.convertList(posts));
  66 + }
  67 + return success(resp);
  68 + }
  69 +
  70 + @PutMapping("/update")
  71 + @ApiOperation("更新用户基本信息")
  72 + @PreAuthorize("@ss.hasScope('user.write')")
  73 + public CommonResult<Boolean> updateUserInfo(@Valid @RequestBody OAuth2UserUpdateReqVO reqVO) {
  74 + // 这里将 UserProfileUpdateReqVO =》UserProfileUpdateReqVO 对象,实现接口的复用。
  75 + // 主要是,AdminUserService 没有自己的 BO 对象,所以复用只能这么做
  76 + userService.updateUserProfile(getLoginUserId(), OAuth2UserConvert.INSTANCE.convert(reqVO));
  77 + return success(true);
  78 + }
  79 +
  80 +}
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/oauth2/vo/open/user/OAuth2OpenUserInfoRespVO.java renamed to yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/oauth2/vo/user/OAuth2UserInfoRespVO.java
1 -package cn.iocoder.yudao.module.system.controller.admin.oauth2.vo.open.user; 1 +package cn.iocoder.yudao.module.system.controller.admin.oauth2.vo.user;
2 2
3 import io.swagger.annotations.ApiModel; 3 import io.swagger.annotations.ApiModel;
4 import io.swagger.annotations.ApiModelProperty; 4 import io.swagger.annotations.ApiModelProperty;
@@ -8,11 +8,11 @@ import lombok.NoArgsConstructor; @@ -8,11 +8,11 @@ import lombok.NoArgsConstructor;
8 8
9 import java.util.List; 9 import java.util.List;
10 10
11 -@ApiModel("管理后台 - 【开放接口】获得用户基本信息 Response VO") 11 +@ApiModel("管理后台 - OAuth2.0 获得用户基本信息 Response VO")
12 @Data 12 @Data
13 @NoArgsConstructor 13 @NoArgsConstructor
14 @AllArgsConstructor 14 @AllArgsConstructor
15 -public class OAuth2OpenUserInfoRespVO { 15 +public class OAuth2UserInfoRespVO {
16 16
17 @ApiModelProperty(value = "用户编号", required = true, example = "1") 17 @ApiModelProperty(value = "用户编号", required = true, example = "1")
18 private Long id; 18 private Long id;
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/oauth2/vo/open/user/OAuth2OpenUserUpdateReqVO.java renamed to yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/oauth2/vo/user/OAuth2UserUpdateReqVO.java
1 -package cn.iocoder.yudao.module.system.controller.admin.oauth2.vo.open.user; 1 +package cn.iocoder.yudao.module.system.controller.admin.oauth2.vo.user;
2 2
3 import io.swagger.annotations.ApiModel; 3 import io.swagger.annotations.ApiModel;
4 import io.swagger.annotations.ApiModelProperty; 4 import io.swagger.annotations.ApiModelProperty;
@@ -10,11 +10,11 @@ import org.hibernate.validator.constraints.Length; @@ -10,11 +10,11 @@ import org.hibernate.validator.constraints.Length;
10 import javax.validation.constraints.Email; 10 import javax.validation.constraints.Email;
11 import javax.validation.constraints.Size; 11 import javax.validation.constraints.Size;
12 12
13 -@ApiModel("管理后台 - 【开放接口】更新用户基本信息 Request VO") 13 +@ApiModel("管理后台 - OAuth2.0 更新用户基本信息 Request VO")
14 @Data 14 @Data
15 @NoArgsConstructor 15 @NoArgsConstructor
16 @AllArgsConstructor 16 @AllArgsConstructor
17 -public class OAuth2OpenUserUpdateReqVO { 17 +public class OAuth2UserUpdateReqVO {
18 18
19 @ApiModelProperty(value = "用户昵称", required = true, example = "芋艿") 19 @ApiModelProperty(value = "用户昵称", required = true, example = "芋艿")
20 @Size(max = 30, message = "用户昵称长度不能超过 30 个字符") 20 @Size(max = 30, message = "用户昵称长度不能超过 30 个字符")
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/convert/oauth2/OAuth2OpenConvert.java
@@ -7,15 +7,9 @@ import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils; @@ -7,15 +7,9 @@ import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils;
7 import cn.iocoder.yudao.module.system.controller.admin.oauth2.vo.open.OAuth2OpenAccessTokenRespVO; 7 import cn.iocoder.yudao.module.system.controller.admin.oauth2.vo.open.OAuth2OpenAccessTokenRespVO;
8 import cn.iocoder.yudao.module.system.controller.admin.oauth2.vo.open.OAuth2OpenAuthorizeInfoRespVO; 8 import cn.iocoder.yudao.module.system.controller.admin.oauth2.vo.open.OAuth2OpenAuthorizeInfoRespVO;
9 import cn.iocoder.yudao.module.system.controller.admin.oauth2.vo.open.OAuth2OpenCheckTokenRespVO; 9 import cn.iocoder.yudao.module.system.controller.admin.oauth2.vo.open.OAuth2OpenCheckTokenRespVO;
10 -import cn.iocoder.yudao.module.system.controller.admin.oauth2.vo.open.user.OAuth2OpenUserInfoRespVO;  
11 -import cn.iocoder.yudao.module.system.controller.admin.oauth2.vo.open.user.OAuth2OpenUserUpdateReqVO;  
12 -import cn.iocoder.yudao.module.system.controller.admin.user.vo.profile.UserProfileUpdateReqVO;  
13 -import cn.iocoder.yudao.module.system.dal.dataobject.dept.DeptDO;  
14 -import cn.iocoder.yudao.module.system.dal.dataobject.dept.PostDO;  
15 import cn.iocoder.yudao.module.system.dal.dataobject.oauth2.OAuth2AccessTokenDO; 10 import cn.iocoder.yudao.module.system.dal.dataobject.oauth2.OAuth2AccessTokenDO;
16 import cn.iocoder.yudao.module.system.dal.dataobject.oauth2.OAuth2ApproveDO; 11 import cn.iocoder.yudao.module.system.dal.dataobject.oauth2.OAuth2ApproveDO;
17 import cn.iocoder.yudao.module.system.dal.dataobject.oauth2.OAuth2ClientDO; 12 import cn.iocoder.yudao.module.system.dal.dataobject.oauth2.OAuth2ClientDO;
18 -import cn.iocoder.yudao.module.system.dal.dataobject.user.AdminUserDO;  
19 import cn.iocoder.yudao.module.system.util.oauth2.OAuth2Utils; 13 import cn.iocoder.yudao.module.system.util.oauth2.OAuth2Utils;
20 import org.mapstruct.Mapper; 14 import org.mapstruct.Mapper;
21 import org.mapstruct.factory.Mappers; 15 import org.mapstruct.factory.Mappers;
@@ -46,14 +40,6 @@ public interface OAuth2OpenConvert { @@ -46,14 +40,6 @@ public interface OAuth2OpenConvert {
46 } 40 }
47 OAuth2OpenCheckTokenRespVO convert3(OAuth2AccessTokenDO bean); 41 OAuth2OpenCheckTokenRespVO convert3(OAuth2AccessTokenDO bean);
48 42
49 - // ============ 用户操作的示例 ============  
50 -  
51 - OAuth2OpenUserInfoRespVO convert(AdminUserDO bean);  
52 - OAuth2OpenUserInfoRespVO.Dept convert(DeptDO dept);  
53 - List<OAuth2OpenUserInfoRespVO.Post> convertList(List<PostDO> list);  
54 -  
55 - UserProfileUpdateReqVO convert(OAuth2OpenUserUpdateReqVO bean);  
56 -  
57 default OAuth2OpenAuthorizeInfoRespVO convert(OAuth2ClientDO client, List<OAuth2ApproveDO> approves) { 43 default OAuth2OpenAuthorizeInfoRespVO convert(OAuth2ClientDO client, List<OAuth2ApproveDO> approves) {
58 // 构建 scopes 44 // 构建 scopes
59 List<KeyValue<String, Boolean>> scopes = new ArrayList<>(client.getScopes().size()); 45 List<KeyValue<String, Boolean>> scopes = new ArrayList<>(client.getScopes().size());
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/convert/oauth2/OAuth2UserConvert.java 0 → 100644
  1 +package cn.iocoder.yudao.module.system.convert.oauth2;
  2 +
  3 +import cn.iocoder.yudao.module.system.controller.admin.oauth2.vo.user.OAuth2UserInfoRespVO;
  4 +import cn.iocoder.yudao.module.system.controller.admin.oauth2.vo.user.OAuth2UserUpdateReqVO;
  5 +import cn.iocoder.yudao.module.system.controller.admin.user.vo.profile.UserProfileUpdateReqVO;
  6 +import cn.iocoder.yudao.module.system.dal.dataobject.dept.DeptDO;
  7 +import cn.iocoder.yudao.module.system.dal.dataobject.dept.PostDO;
  8 +import cn.iocoder.yudao.module.system.dal.dataobject.user.AdminUserDO;
  9 +import org.mapstruct.Mapper;
  10 +import org.mapstruct.factory.Mappers;
  11 +
  12 +import java.util.List;
  13 +
  14 +@Mapper
  15 +public interface OAuth2UserConvert {
  16 +
  17 + OAuth2UserConvert INSTANCE = Mappers.getMapper(OAuth2UserConvert.class);
  18 +
  19 + OAuth2UserInfoRespVO convert(AdminUserDO bean);
  20 + OAuth2UserInfoRespVO.Dept convert(DeptDO dept);
  21 + List<OAuth2UserInfoRespVO.Post> convertList(List<PostDO> list);
  22 +
  23 + UserProfileUpdateReqVO convert(OAuth2UserUpdateReqVO bean);
  24 +
  25 +}
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/oauth2/OAuth2ClientServiceImpl.java
@@ -15,6 +15,7 @@ import cn.iocoder.yudao.module.system.dal.mysql.oauth2.OAuth2ClientMapper; @@ -15,6 +15,7 @@ import cn.iocoder.yudao.module.system.dal.mysql.oauth2.OAuth2ClientMapper;
15 import cn.iocoder.yudao.module.system.mq.producer.auth.OAuth2ClientProducer; 15 import cn.iocoder.yudao.module.system.mq.producer.auth.OAuth2ClientProducer;
16 import com.google.common.annotations.VisibleForTesting; 16 import com.google.common.annotations.VisibleForTesting;
17 import lombok.Getter; 17 import lombok.Getter;
  18 +import lombok.Setter;
18 import lombok.extern.slf4j.Slf4j; 19 import lombok.extern.slf4j.Slf4j;
19 import org.springframework.scheduling.annotation.Scheduled; 20 import org.springframework.scheduling.annotation.Scheduled;
20 import org.springframework.stereotype.Service; 21 import org.springframework.stereotype.Service;
@@ -51,7 +52,8 @@ public class OAuth2ClientServiceImpl implements OAuth2ClientService { @@ -51,7 +52,8 @@ public class OAuth2ClientServiceImpl implements OAuth2ClientService {
51 * 52 *
52 * 这里声明 volatile 修饰的原因是,每次刷新时,直接修改指向 53 * 这里声明 volatile 修饰的原因是,每次刷新时,直接修改指向
53 */ 54 */
54 - @Getter 55 + @Getter // 解决单测
  56 + @Setter // 解决单测
55 private volatile Map<String, OAuth2ClientDO> clientCache; 57 private volatile Map<String, OAuth2ClientDO> clientCache;
56 /** 58 /**
57 * 缓存角色的最大更新时间,用于后续的增量轮询,判断是否有更新 59 * 缓存角色的最大更新时间,用于后续的增量轮询,判断是否有更新
@@ -151,7 +153,7 @@ public class OAuth2ClientServiceImpl implements OAuth2ClientService { @@ -151,7 +153,7 @@ public class OAuth2ClientServiceImpl implements OAuth2ClientService {
151 } 153 }
152 154
153 @VisibleForTesting 155 @VisibleForTesting
154 - public void validateClientIdExists(Long id, String clientId) { 156 + void validateClientIdExists(Long id, String clientId) {
155 OAuth2ClientDO client = oauth2ClientMapper.selectByClientId(clientId); 157 OAuth2ClientDO client = oauth2ClientMapper.selectByClientId(clientId);
156 if (client == null) { 158 if (client == null) {
157 return; 159 return;
@@ -160,7 +162,7 @@ public class OAuth2ClientServiceImpl implements OAuth2ClientService { @@ -160,7 +162,7 @@ public class OAuth2ClientServiceImpl implements OAuth2ClientService {
160 if (id == null) { 162 if (id == null) {
161 throw exception(OAUTH2_CLIENT_EXISTS); 163 throw exception(OAUTH2_CLIENT_EXISTS);
162 } 164 }
163 - if (!client.getClientId().equals(clientId)) { 165 + if (!client.getId().equals(id)) {
164 throw exception(OAUTH2_CLIENT_EXISTS); 166 throw exception(OAUTH2_CLIENT_EXISTS);
165 } 167 }
166 } 168 }
@@ -189,7 +191,7 @@ public class OAuth2ClientServiceImpl implements OAuth2ClientService { @@ -189,7 +191,7 @@ public class OAuth2ClientServiceImpl implements OAuth2ClientService {
189 191
190 // 校验客户端密钥 192 // 校验客户端密钥
191 if (StrUtil.isNotEmpty(clientSecret) && ObjectUtil.notEqual(client.getSecret(), clientSecret)) { 193 if (StrUtil.isNotEmpty(clientSecret) && ObjectUtil.notEqual(client.getSecret(), clientSecret)) {
192 - throw exception(OAUTH2_CLIENT_CLIENT_SECRET_ERROR, clientSecret); 194 + throw exception(OAUTH2_CLIENT_CLIENT_SECRET_ERROR);
193 } 195 }
194 // 校验授权方式 196 // 校验授权方式
195 if (StrUtil.isNotEmpty(authorizedGrantType) && !CollUtil.contains(client.getAuthorizedGrantTypes(), authorizedGrantType)) { 197 if (StrUtil.isNotEmpty(authorizedGrantType) && !CollUtil.contains(client.getAuthorizedGrantTypes(), authorizedGrantType)) {
yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/auth/OAuth2ClientServiceImplTest.java renamed to yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/oauth2/OAuth2ClientServiceImplTest.java
1 -package cn.iocoder.yudao.module.system.service.auth; 1 +package cn.iocoder.yudao.module.system.service.oauth2;
2 2
  3 +import cn.hutool.core.map.MapUtil;
3 import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; 4 import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
4 import cn.iocoder.yudao.framework.common.pojo.PageResult; 5 import cn.iocoder.yudao.framework.common.pojo.PageResult;
5 import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest; 6 import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest;
@@ -9,13 +10,12 @@ import cn.iocoder.yudao.module.system.controller.admin.oauth2.vo.client.OAuth2Cl @@ -9,13 +10,12 @@ import cn.iocoder.yudao.module.system.controller.admin.oauth2.vo.client.OAuth2Cl
9 import cn.iocoder.yudao.module.system.dal.dataobject.oauth2.OAuth2ClientDO; 10 import cn.iocoder.yudao.module.system.dal.dataobject.oauth2.OAuth2ClientDO;
10 import cn.iocoder.yudao.module.system.dal.mysql.oauth2.OAuth2ClientMapper; 11 import cn.iocoder.yudao.module.system.dal.mysql.oauth2.OAuth2ClientMapper;
11 import cn.iocoder.yudao.module.system.mq.producer.auth.OAuth2ClientProducer; 12 import cn.iocoder.yudao.module.system.mq.producer.auth.OAuth2ClientProducer;
12 -import cn.iocoder.yudao.module.system.service.oauth2.OAuth2ClientServiceImpl;  
13 -import org.junit.jupiter.api.Disabled;  
14 import org.junit.jupiter.api.Test; 13 import org.junit.jupiter.api.Test;
15 import org.springframework.boot.test.mock.mockito.MockBean; 14 import org.springframework.boot.test.mock.mockito.MockBean;
16 import org.springframework.context.annotation.Import; 15 import org.springframework.context.annotation.Import;
17 16
18 import javax.annotation.Resource; 17 import javax.annotation.Resource;
  18 +import java.util.Collections;
19 import java.util.Map; 19 import java.util.Map;
20 20
21 import static cn.iocoder.yudao.framework.common.util.object.ObjectUtils.cloneIgnoreId; 21 import static cn.iocoder.yudao.framework.common.util.object.ObjectUtils.cloneIgnoreId;
@@ -23,7 +23,7 @@ import static cn.iocoder.yudao.framework.common.util.object.ObjectUtils.max; @@ -23,7 +23,7 @@ import static cn.iocoder.yudao.framework.common.util.object.ObjectUtils.max;
23 import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals; 23 import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals;
24 import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertServiceException; 24 import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertServiceException;
25 import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.*; 25 import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.*;
26 -import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.OAUTH2_CLIENT_NOT_EXISTS; 26 +import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.*;
27 import static org.junit.jupiter.api.Assertions.*; 27 import static org.junit.jupiter.api.Assertions.*;
28 import static org.mockito.Mockito.verify; 28 import static org.mockito.Mockito.verify;
29 29
@@ -132,7 +132,31 @@ public class OAuth2ClientServiceImplTest extends BaseDbUnitTest { @@ -132,7 +132,31 @@ public class OAuth2ClientServiceImplTest extends BaseDbUnitTest {
132 } 132 }
133 133
134 @Test 134 @Test
135 - @Disabled 135 + public void testValidateClientIdExists_withId() {
  136 + // mock 数据
  137 + OAuth2ClientDO client = randomPojo(OAuth2ClientDO.class).setClientId("tudou");
  138 + oauth2ClientMapper.insert(client);
  139 + // 准备参数
  140 + Long id = randomLongId();
  141 + String clientId = "tudou";
  142 +
  143 + // 调用,不会报错
  144 + assertServiceException(() -> oauth2ClientService.validateClientIdExists(id, clientId), OAUTH2_CLIENT_EXISTS);
  145 + }
  146 +
  147 + @Test
  148 + public void testValidateClientIdExists_noId() {
  149 + // mock 数据
  150 + OAuth2ClientDO client = randomPojo(OAuth2ClientDO.class).setClientId("tudou");
  151 + oauth2ClientMapper.insert(client);
  152 + // 准备参数
  153 + String clientId = "tudou";
  154 +
  155 + // 调用,不会报错
  156 + assertServiceException(() -> oauth2ClientService.validateClientIdExists(null, clientId), OAUTH2_CLIENT_EXISTS);
  157 + }
  158 +
  159 + @Test
136 public void testGetOAuth2ClientPage() { 160 public void testGetOAuth2ClientPage() {
137 // mock 数据 161 // mock 数据
138 OAuth2ClientDO dbOAuth2Client = randomPojo(OAuth2ClientDO.class, o -> { // 等会查询到 162 OAuth2ClientDO dbOAuth2Client = randomPojo(OAuth2ClientDO.class, o -> { // 等会查询到
@@ -143,10 +167,10 @@ public class OAuth2ClientServiceImplTest extends BaseDbUnitTest { @@ -143,10 +167,10 @@ public class OAuth2ClientServiceImplTest extends BaseDbUnitTest {
143 // 测试 name 不匹配 167 // 测试 name 不匹配
144 oauth2ClientMapper.insert(cloneIgnoreId(dbOAuth2Client, o -> o.setName("凤凰"))); 168 oauth2ClientMapper.insert(cloneIgnoreId(dbOAuth2Client, o -> o.setName("凤凰")));
145 // 测试 status 不匹配 169 // 测试 status 不匹配
146 - oauth2ClientMapper.insert(cloneIgnoreId(dbOAuth2Client, o -> o.setStatus(CommonStatusEnum.ENABLE.getStatus()))); 170 + oauth2ClientMapper.insert(cloneIgnoreId(dbOAuth2Client, o -> o.setStatus(CommonStatusEnum.DISABLE.getStatus())));
147 // 准备参数 171 // 准备参数
148 OAuth2ClientPageReqVO reqVO = new OAuth2ClientPageReqVO(); 172 OAuth2ClientPageReqVO reqVO = new OAuth2ClientPageReqVO();
149 - reqVO.setName("long"); 173 + reqVO.setName("龙");
150 reqVO.setStatus(CommonStatusEnum.ENABLE.getStatus()); 174 reqVO.setStatus(CommonStatusEnum.ENABLE.getStatus());
151 175
152 // 调用 176 // 调用
@@ -157,4 +181,35 @@ public class OAuth2ClientServiceImplTest extends BaseDbUnitTest { @@ -157,4 +181,35 @@ public class OAuth2ClientServiceImplTest extends BaseDbUnitTest {
157 assertPojoEquals(dbOAuth2Client, pageResult.getList().get(0)); 181 assertPojoEquals(dbOAuth2Client, pageResult.getList().get(0));
158 } 182 }
159 183
  184 + @Test
  185 + public void testValidOAuthClientFromCache() {
  186 + // mock 方法
  187 + OAuth2ClientDO client = randomPojo(OAuth2ClientDO.class).setClientId("default")
  188 + .setStatus(CommonStatusEnum.ENABLE.getStatus());
  189 + OAuth2ClientDO client02 = randomPojo(OAuth2ClientDO.class).setClientId("disable")
  190 + .setStatus(CommonStatusEnum.DISABLE.getStatus());
  191 + Map<String, OAuth2ClientDO> clientCache = MapUtil.<String, OAuth2ClientDO>builder()
  192 + .put(client.getClientId(), client)
  193 + .put(client02.getClientId(), client02).build();
  194 + oauth2ClientService.setClientCache(clientCache);
  195 +
  196 + // 调用,并断言
  197 + assertServiceException(() -> oauth2ClientService.validOAuthClientFromCache(randomString(),
  198 + null, null, null, null), OAUTH2_CLIENT_NOT_EXISTS);
  199 + assertServiceException(() -> oauth2ClientService.validOAuthClientFromCache("disable",
  200 + null, null, null, null), OAUTH2_CLIENT_DISABLE);
  201 + assertServiceException(() -> oauth2ClientService.validOAuthClientFromCache("default",
  202 + randomString(), null, null, null), OAUTH2_CLIENT_CLIENT_SECRET_ERROR);
  203 + assertServiceException(() -> oauth2ClientService.validOAuthClientFromCache("default",
  204 + null, randomString(), null, null), OAUTH2_CLIENT_AUTHORIZED_GRANT_TYPE_NOT_EXISTS);
  205 + assertServiceException(() -> oauth2ClientService.validOAuthClientFromCache("default",
  206 + null, null, Collections.singleton(randomString()), null), OAUTH2_CLIENT_SCOPE_OVER);
  207 + assertServiceException(() -> oauth2ClientService.validOAuthClientFromCache("default",
  208 + null, null, null, "test"), OAUTH2_CLIENT_REDIRECT_URI_NOT_MATCH, "test");
  209 + // 成功调用
  210 + OAuth2ClientDO result = oauth2ClientService.validOAuthClientFromCache(client.getClientId(), client.getSecret(),
  211 + client.getAuthorizedGrantTypes().get(0), client.getScopes(), client.getRedirectUris().get(0));
  212 + assertPojoEquals(client, result);
  213 + }
  214 +
160 } 215 }
yudao-module-system/yudao-module-system-biz/src/test/resources/sql/create_tables.sql
@@ -482,9 +482,9 @@ CREATE TABLE IF NOT EXISTS &quot;system_oauth2_client&quot; ( @@ -482,9 +482,9 @@ CREATE TABLE IF NOT EXISTS &quot;system_oauth2_client&quot; (
482 "access_token_validity_seconds" int NOT NULL, 482 "access_token_validity_seconds" int NOT NULL,
483 "refresh_token_validity_seconds" int NOT NULL, 483 "refresh_token_validity_seconds" int NOT NULL,
484 "redirect_uris" varchar NOT NULL, 484 "redirect_uris" varchar NOT NULL,
485 - "auto_approve" bit NOT NULL DEFAULT FALSE,  
486 "authorized_grant_types" varchar NOT NULL, 485 "authorized_grant_types" varchar NOT NULL,
487 "scopes" varchar NOT NULL DEFAULT '', 486 "scopes" varchar NOT NULL DEFAULT '',
  487 + "auto_approve_scopes" varchar NOT NULL DEFAULT '',
488 "authorities" varchar NOT NULL DEFAULT '', 488 "authorities" varchar NOT NULL DEFAULT '',
489 "resource_ids" varchar NOT NULL DEFAULT '', 489 "resource_ids" varchar NOT NULL DEFAULT '',
490 "additional_information" varchar NOT NULL DEFAULT '', 490 "additional_information" varchar NOT NULL DEFAULT '',
yudao-ui-admin/src/views/sso.vue
@@ -37,7 +37,7 @@ @@ -37,7 +37,7 @@
37 <el-form-item style="width:100%;"> 37 <el-form-item style="width:100%;">
38 <el-button :loading="loading" size="medium" type="primary" style="width:60%;" 38 <el-button :loading="loading" size="medium" type="primary" style="width:60%;"
39 @click.native.prevent="handleAuthorize(true)"> 39 @click.native.prevent="handleAuthorize(true)">
40 - <span v-if="!loading">统一授权</span> 40 + <span v-if="!loading">同意授权</span>
41 <span v-else>授 权 中...</span> 41 <span v-else>授 权 中...</span>
42 </el-button> 42 </el-button>
43 <el-button size="medium" style="width:36%" 43 <el-button size="medium" style="width:36%"