Commit b3ab1d9285be30ec00d8f62e14b1294b17e888d8
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 "system_oauth2_client" ( | @@ -482,9 +482,9 @@ CREATE TABLE IF NOT EXISTS "system_oauth2_client" ( | ||
| 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%" |