From b3ab1d9285be30ec00d8f62e14b1294b17e888d8 Mon Sep 17 00:00:00 2001 From: YunaiV Date: Tue, 24 May 2022 10:13:05 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AE=8C=E5=96=84=20OAuth2ClientServiceImplTes?= =?UTF-8?q?t=20=E5=8D=95=E5=85=83=E6=B5=8B=E8=AF=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../admin/oauth2/OAuth2OpenController.http | 15 ---- .../admin/oauth2/OAuth2OpenController.java | 54 +------------ .../admin/oauth2/OAuth2UserController.http | 14 ++++ .../admin/oauth2/OAuth2UserController.java | 80 +++++++++++++++++++ .../OAuth2UserInfoRespVO.java} | 6 +- .../OAuth2UserUpdateReqVO.java} | 6 +- .../convert/oauth2/OAuth2OpenConvert.java | 14 ---- .../convert/oauth2/OAuth2UserConvert.java | 25 ++++++ .../oauth2/OAuth2ClientServiceImpl.java | 10 ++- .../OAuth2ClientServiceImplTest.java | 69 ++++++++++++++-- .../src/test/resources/sql/create_tables.sql | 2 +- yudao-ui-admin/src/views/sso.vue | 2 +- 12 files changed, 198 insertions(+), 99 deletions(-) create mode 100644 yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/oauth2/OAuth2UserController.http create mode 100644 yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/oauth2/OAuth2UserController.java rename yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/oauth2/vo/{open/user/OAuth2OpenUserInfoRespVO.java => user/OAuth2UserInfoRespVO.java} (93%) rename yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/oauth2/vo/{open/user/OAuth2OpenUserUpdateReqVO.java => user/OAuth2UserUpdateReqVO.java} (89%) create mode 100644 yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/convert/oauth2/OAuth2UserConvert.java rename yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/{auth => oauth2}/OAuth2ClientServiceImplTest.java (66%) diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/oauth2/OAuth2OpenController.http b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/oauth2/OAuth2OpenController.http index e11aee721..725a5d4f5 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/oauth2/OAuth2OpenController.http +++ b/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}} POST {{baseUrl}}/system/oauth2/check-token?token=620d307c5b4148df8a98dd6c6c547106 Authorization: Basic ZGVmYXVsdDphZG1pbjEyMw== tenant-id: {{adminTenentId}} - -### 请求 /system/oauth2/user/get 接口 => 成功 -GET {{baseUrl}}/system/oauth2/user/get -Authorization: Bearer 9502bd7a768a4ade920b90f41e2efd5c -tenant-id: {{adminTenentId}} - -### 请求 /system/oauth2/user/update 接口 => 成功 -PUT {{baseUrl}}/system/oauth2/user/update -Content-Type: application/json -Authorization: Bearer 9502bd7a768a4ade920b90f41e2efd5c -tenant-id: {{adminTenentId}} - -{ - "nickname": "芋道源码" -} diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/oauth2/OAuth2OpenController.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/oauth2/OAuth2OpenController.java index 6034c6096..2e7408aa1 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/oauth2/OAuth2OpenController.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/oauth2/OAuth2OpenController.java @@ -1,6 +1,5 @@ package cn.iocoder.yudao.module.system.controller.admin.oauth2; -import cn.hutool.core.collection.CollUtil; import cn.hutool.core.lang.Assert; import cn.hutool.core.util.ArrayUtil; import cn.hutool.core.util.ObjectUtil; @@ -13,36 +12,26 @@ import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog; import cn.iocoder.yudao.module.system.controller.admin.oauth2.vo.open.OAuth2OpenAccessTokenRespVO; import cn.iocoder.yudao.module.system.controller.admin.oauth2.vo.open.OAuth2OpenAuthorizeInfoRespVO; import cn.iocoder.yudao.module.system.controller.admin.oauth2.vo.open.OAuth2OpenCheckTokenRespVO; -import cn.iocoder.yudao.module.system.controller.admin.oauth2.vo.open.user.OAuth2OpenUserInfoRespVO; -import cn.iocoder.yudao.module.system.controller.admin.oauth2.vo.open.user.OAuth2OpenUserUpdateReqVO; import cn.iocoder.yudao.module.system.convert.oauth2.OAuth2OpenConvert; -import cn.iocoder.yudao.module.system.dal.dataobject.dept.DeptDO; -import cn.iocoder.yudao.module.system.dal.dataobject.dept.PostDO; import cn.iocoder.yudao.module.system.dal.dataobject.oauth2.OAuth2AccessTokenDO; import cn.iocoder.yudao.module.system.dal.dataobject.oauth2.OAuth2ApproveDO; import cn.iocoder.yudao.module.system.dal.dataobject.oauth2.OAuth2ClientDO; -import cn.iocoder.yudao.module.system.dal.dataobject.user.AdminUserDO; import cn.iocoder.yudao.module.system.enums.auth.OAuth2GrantTypeEnum; -import cn.iocoder.yudao.module.system.service.dept.DeptService; -import cn.iocoder.yudao.module.system.service.dept.PostService; import cn.iocoder.yudao.module.system.service.oauth2.OAuth2ApproveService; import cn.iocoder.yudao.module.system.service.oauth2.OAuth2ClientService; import cn.iocoder.yudao.module.system.service.oauth2.OAuth2GrantService; import cn.iocoder.yudao.module.system.service.oauth2.OAuth2TokenService; -import cn.iocoder.yudao.module.system.service.user.AdminUserService; import cn.iocoder.yudao.module.system.util.oauth2.OAuth2Utils; import io.swagger.annotations.Api; import io.swagger.annotations.ApiImplicitParam; import io.swagger.annotations.ApiImplicitParams; import io.swagger.annotations.ApiOperation; import lombok.extern.slf4j.Slf4j; -import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; import javax.annotation.Resource; import javax.servlet.http.HttpServletRequest; -import javax.validation.Valid; import java.util.Collections; import java.util.List; import java.util.Map; @@ -61,7 +50,9 @@ import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUti * 另外,一个公司如果有多个管理后台,它们 client_id 产生的 access token 相互之间是无法互通的,即无法访问它们系统的 API 接口,直到两个 client_id 产生信任授权。 * * 考虑到【本系统】暂时不想做的过于复杂,默认只有获取到 access token 之后,可以访问【本系统】管理后台的 /system-api/* 所有接口,除非手动添加 scope 控制。 - * scope 的使用示例,可见当前类的 getUserInfo 和 updateUserInfo 方法,上面有 @PreAuthorize("@ss.hasScope('user.read')") 和 @PreAuthorize("@ss.hasScope('user.write')") 注解 + * scope 的使用示例,可见 {@link OAuth2UserController} 类 + * + * * * @author 芋道源码 */ @@ -306,43 +297,4 @@ public class OAuth2OpenController { return clientIdAndSecret; } - // ============ 用户操作的示例,展示 scope 的使用 ============ - - @Resource - private AdminUserService userService; - @Resource - private DeptService deptService; - @Resource - private PostService postService; - - @GetMapping("/user/get") - @ApiOperation("获得用户基本信息") - @PreAuthorize("@ss.hasScope('user.read')") - public CommonResult getUserInfo() { - // 获得用户基本信息 - AdminUserDO user = userService.getUser(getLoginUserId()); - OAuth2OpenUserInfoRespVO resp = OAuth2OpenConvert.INSTANCE.convert(user); - // 获得部门信息 - if (user.getDeptId() != null) { - DeptDO dept = deptService.getDept(user.getDeptId()); - resp.setDept(OAuth2OpenConvert.INSTANCE.convert(dept)); - } - // 获得岗位信息 - if (CollUtil.isNotEmpty(user.getPostIds())) { - List posts = postService.getPosts(user.getPostIds()); - resp.setPosts(OAuth2OpenConvert.INSTANCE.convertList(posts)); - } - return success(resp); - } - - @PutMapping("/user/update") - @ApiOperation("更新用户基本信息") - @PreAuthorize("@ss.hasScope('user.write')") - public CommonResult updateUserInfo(@Valid @RequestBody OAuth2OpenUserUpdateReqVO reqVO) { - // 这里将 UserProfileUpdateReqVO =》UserProfileUpdateReqVO 对象,实现接口的复用。 - // 主要是,AdminUserService 没有自己的 BO 对象,所以复用只能这么做 - userService.updateUserProfile(getLoginUserId(), OAuth2OpenConvert.INSTANCE.convert(reqVO)); - return success(true); - } - } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/oauth2/OAuth2UserController.http b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/oauth2/OAuth2UserController.http new file mode 100644 index 000000000..13c8545bd --- /dev/null +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/oauth2/OAuth2UserController.http @@ -0,0 +1,14 @@ +### 请求 /system/oauth2/user/get 接口 => 成功 +GET {{baseUrl}}/system/oauth2/user/get +Authorization: Bearer 47f9c74ec11041f193b777ebb95c3b0d +tenant-id: {{adminTenentId}} + +### 请求 /system/oauth2/user/update 接口 => 成功 +PUT {{baseUrl}}/system/oauth2/user/update +Content-Type: application/json +Authorization: Bearer 47f9c74ec11041f193b777ebb95c3b0d +tenant-id: {{adminTenentId}} + +{ + "nickname": "芋道源码" +} diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/oauth2/OAuth2UserController.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/oauth2/OAuth2UserController.java new file mode 100644 index 000000000..39b6125ab --- /dev/null +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/oauth2/OAuth2UserController.java @@ -0,0 +1,80 @@ +package cn.iocoder.yudao.module.system.controller.admin.oauth2; + +import cn.hutool.core.collection.CollUtil; +import cn.iocoder.yudao.framework.common.pojo.CommonResult; +import cn.iocoder.yudao.module.system.controller.admin.oauth2.vo.user.OAuth2UserInfoRespVO; +import cn.iocoder.yudao.module.system.controller.admin.oauth2.vo.user.OAuth2UserUpdateReqVO; +import cn.iocoder.yudao.module.system.convert.oauth2.OAuth2UserConvert; +import cn.iocoder.yudao.module.system.dal.dataobject.dept.DeptDO; +import cn.iocoder.yudao.module.system.dal.dataobject.dept.PostDO; +import cn.iocoder.yudao.module.system.dal.dataobject.user.AdminUserDO; +import cn.iocoder.yudao.module.system.service.dept.DeptService; +import cn.iocoder.yudao.module.system.service.dept.PostService; +import cn.iocoder.yudao.module.system.service.user.AdminUserService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import lombok.extern.slf4j.Slf4j; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; + +import javax.annotation.Resource; +import javax.validation.Valid; +import java.util.List; + +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; +import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId; + +/** + * 提供给外部应用调用为主 + * + * 1. 在 getUserInfo 方法上,添加 @PreAuthorize("@ss.hasScope('user.read')") 注解,声明需要满足 scope = user.read + * 2. 在 updateUserInfo 方法上,添加 @PreAuthorize("@ss.hasScope('user.write')") 注解,声明需要满足 scope = user.write + * + * @author 芋道源码 + */ +@Api(tags = "管理后台 - OAuth2.0 用户") +@RestController +@RequestMapping("/system/oauth2/user") +@Validated +@Slf4j +public class OAuth2UserController { + + @Resource + private AdminUserService userService; + @Resource + private DeptService deptService; + @Resource + private PostService postService; + + @GetMapping("/get") + @ApiOperation("获得用户基本信息") + @PreAuthorize("@ss.hasScope('user.read')") // + public CommonResult getUserInfo() { + // 获得用户基本信息 + AdminUserDO user = userService.getUser(getLoginUserId()); + OAuth2UserInfoRespVO resp = OAuth2UserConvert.INSTANCE.convert(user); + // 获得部门信息 + if (user.getDeptId() != null) { + DeptDO dept = deptService.getDept(user.getDeptId()); + resp.setDept(OAuth2UserConvert.INSTANCE.convert(dept)); + } + // 获得岗位信息 + if (CollUtil.isNotEmpty(user.getPostIds())) { + List posts = postService.getPosts(user.getPostIds()); + resp.setPosts(OAuth2UserConvert.INSTANCE.convertList(posts)); + } + return success(resp); + } + + @PutMapping("/update") + @ApiOperation("更新用户基本信息") + @PreAuthorize("@ss.hasScope('user.write')") + public CommonResult updateUserInfo(@Valid @RequestBody OAuth2UserUpdateReqVO reqVO) { + // 这里将 UserProfileUpdateReqVO =》UserProfileUpdateReqVO 对象,实现接口的复用。 + // 主要是,AdminUserService 没有自己的 BO 对象,所以复用只能这么做 + userService.updateUserProfile(getLoginUserId(), OAuth2UserConvert.INSTANCE.convert(reqVO)); + return success(true); + } + +} diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/oauth2/vo/open/user/OAuth2OpenUserInfoRespVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/oauth2/vo/user/OAuth2UserInfoRespVO.java similarity index 93% rename from yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/oauth2/vo/open/user/OAuth2OpenUserInfoRespVO.java rename to yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/oauth2/vo/user/OAuth2UserInfoRespVO.java index 00df1f11c..b513fc3da 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/oauth2/vo/open/user/OAuth2OpenUserInfoRespVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/oauth2/vo/user/OAuth2UserInfoRespVO.java @@ -1,4 +1,4 @@ -package cn.iocoder.yudao.module.system.controller.admin.oauth2.vo.open.user; +package cn.iocoder.yudao.module.system.controller.admin.oauth2.vo.user; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; @@ -8,11 +8,11 @@ import lombok.NoArgsConstructor; import java.util.List; -@ApiModel("管理后台 - 【开放接口】获得用户基本信息 Response VO") +@ApiModel("管理后台 - OAuth2.0 获得用户基本信息 Response VO") @Data @NoArgsConstructor @AllArgsConstructor -public class OAuth2OpenUserInfoRespVO { +public class OAuth2UserInfoRespVO { @ApiModelProperty(value = "用户编号", required = true, example = "1") private Long id; diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/oauth2/vo/open/user/OAuth2OpenUserUpdateReqVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/oauth2/vo/user/OAuth2UserUpdateReqVO.java similarity index 89% rename from yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/oauth2/vo/open/user/OAuth2OpenUserUpdateReqVO.java rename to yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/oauth2/vo/user/OAuth2UserUpdateReqVO.java index 4c7b784d9..991c88a99 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/oauth2/vo/open/user/OAuth2OpenUserUpdateReqVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/oauth2/vo/user/OAuth2UserUpdateReqVO.java @@ -1,4 +1,4 @@ -package cn.iocoder.yudao.module.system.controller.admin.oauth2.vo.open.user; +package cn.iocoder.yudao.module.system.controller.admin.oauth2.vo.user; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; @@ -10,11 +10,11 @@ import org.hibernate.validator.constraints.Length; import javax.validation.constraints.Email; import javax.validation.constraints.Size; -@ApiModel("管理后台 - 【开放接口】更新用户基本信息 Request VO") +@ApiModel("管理后台 - OAuth2.0 更新用户基本信息 Request VO") @Data @NoArgsConstructor @AllArgsConstructor -public class OAuth2OpenUserUpdateReqVO { +public class OAuth2UserUpdateReqVO { @ApiModelProperty(value = "用户昵称", required = true, example = "芋艿") @Size(max = 30, message = "用户昵称长度不能超过 30 个字符") diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/convert/oauth2/OAuth2OpenConvert.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/convert/oauth2/OAuth2OpenConvert.java index 90907d606..fd5100303 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/convert/oauth2/OAuth2OpenConvert.java +++ b/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; import cn.iocoder.yudao.module.system.controller.admin.oauth2.vo.open.OAuth2OpenAccessTokenRespVO; import cn.iocoder.yudao.module.system.controller.admin.oauth2.vo.open.OAuth2OpenAuthorizeInfoRespVO; import cn.iocoder.yudao.module.system.controller.admin.oauth2.vo.open.OAuth2OpenCheckTokenRespVO; -import cn.iocoder.yudao.module.system.controller.admin.oauth2.vo.open.user.OAuth2OpenUserInfoRespVO; -import cn.iocoder.yudao.module.system.controller.admin.oauth2.vo.open.user.OAuth2OpenUserUpdateReqVO; -import cn.iocoder.yudao.module.system.controller.admin.user.vo.profile.UserProfileUpdateReqVO; -import cn.iocoder.yudao.module.system.dal.dataobject.dept.DeptDO; -import cn.iocoder.yudao.module.system.dal.dataobject.dept.PostDO; import cn.iocoder.yudao.module.system.dal.dataobject.oauth2.OAuth2AccessTokenDO; import cn.iocoder.yudao.module.system.dal.dataobject.oauth2.OAuth2ApproveDO; import cn.iocoder.yudao.module.system.dal.dataobject.oauth2.OAuth2ClientDO; -import cn.iocoder.yudao.module.system.dal.dataobject.user.AdminUserDO; import cn.iocoder.yudao.module.system.util.oauth2.OAuth2Utils; import org.mapstruct.Mapper; import org.mapstruct.factory.Mappers; @@ -46,14 +40,6 @@ public interface OAuth2OpenConvert { } OAuth2OpenCheckTokenRespVO convert3(OAuth2AccessTokenDO bean); - // ============ 用户操作的示例 ============ - - OAuth2OpenUserInfoRespVO convert(AdminUserDO bean); - OAuth2OpenUserInfoRespVO.Dept convert(DeptDO dept); - List convertList(List list); - - UserProfileUpdateReqVO convert(OAuth2OpenUserUpdateReqVO bean); - default OAuth2OpenAuthorizeInfoRespVO convert(OAuth2ClientDO client, List approves) { // 构建 scopes List> scopes = new ArrayList<>(client.getScopes().size()); diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/convert/oauth2/OAuth2UserConvert.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/convert/oauth2/OAuth2UserConvert.java new file mode 100644 index 000000000..b2610565a --- /dev/null +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/convert/oauth2/OAuth2UserConvert.java @@ -0,0 +1,25 @@ +package cn.iocoder.yudao.module.system.convert.oauth2; + +import cn.iocoder.yudao.module.system.controller.admin.oauth2.vo.user.OAuth2UserInfoRespVO; +import cn.iocoder.yudao.module.system.controller.admin.oauth2.vo.user.OAuth2UserUpdateReqVO; +import cn.iocoder.yudao.module.system.controller.admin.user.vo.profile.UserProfileUpdateReqVO; +import cn.iocoder.yudao.module.system.dal.dataobject.dept.DeptDO; +import cn.iocoder.yudao.module.system.dal.dataobject.dept.PostDO; +import cn.iocoder.yudao.module.system.dal.dataobject.user.AdminUserDO; +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; + +import java.util.List; + +@Mapper +public interface OAuth2UserConvert { + + OAuth2UserConvert INSTANCE = Mappers.getMapper(OAuth2UserConvert.class); + + OAuth2UserInfoRespVO convert(AdminUserDO bean); + OAuth2UserInfoRespVO.Dept convert(DeptDO dept); + List convertList(List list); + + UserProfileUpdateReqVO convert(OAuth2UserUpdateReqVO bean); + +} diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/oauth2/OAuth2ClientServiceImpl.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/oauth2/OAuth2ClientServiceImpl.java index 390282c47..a01cafdbf 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/oauth2/OAuth2ClientServiceImpl.java +++ b/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; import cn.iocoder.yudao.module.system.mq.producer.auth.OAuth2ClientProducer; import com.google.common.annotations.VisibleForTesting; import lombok.Getter; +import lombok.Setter; import lombok.extern.slf4j.Slf4j; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Service; @@ -51,7 +52,8 @@ public class OAuth2ClientServiceImpl implements OAuth2ClientService { * * 这里声明 volatile 修饰的原因是,每次刷新时,直接修改指向 */ - @Getter + @Getter // 解决单测 + @Setter // 解决单测 private volatile Map clientCache; /** * 缓存角色的最大更新时间,用于后续的增量轮询,判断是否有更新 @@ -151,7 +153,7 @@ public class OAuth2ClientServiceImpl implements OAuth2ClientService { } @VisibleForTesting - public void validateClientIdExists(Long id, String clientId) { + void validateClientIdExists(Long id, String clientId) { OAuth2ClientDO client = oauth2ClientMapper.selectByClientId(clientId); if (client == null) { return; @@ -160,7 +162,7 @@ public class OAuth2ClientServiceImpl implements OAuth2ClientService { if (id == null) { throw exception(OAUTH2_CLIENT_EXISTS); } - if (!client.getClientId().equals(clientId)) { + if (!client.getId().equals(id)) { throw exception(OAUTH2_CLIENT_EXISTS); } } @@ -189,7 +191,7 @@ public class OAuth2ClientServiceImpl implements OAuth2ClientService { // 校验客户端密钥 if (StrUtil.isNotEmpty(clientSecret) && ObjectUtil.notEqual(client.getSecret(), clientSecret)) { - throw exception(OAUTH2_CLIENT_CLIENT_SECRET_ERROR, clientSecret); + throw exception(OAUTH2_CLIENT_CLIENT_SECRET_ERROR); } // 校验授权方式 if (StrUtil.isNotEmpty(authorizedGrantType) && !CollUtil.contains(client.getAuthorizedGrantTypes(), authorizedGrantType)) { diff --git a/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/auth/OAuth2ClientServiceImplTest.java b/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/oauth2/OAuth2ClientServiceImplTest.java similarity index 66% rename from yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/auth/OAuth2ClientServiceImplTest.java rename to yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/oauth2/OAuth2ClientServiceImplTest.java index ef10f2419..c7d4ce578 100755 --- a/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/auth/OAuth2ClientServiceImplTest.java +++ b/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/oauth2/OAuth2ClientServiceImplTest.java @@ -1,5 +1,6 @@ -package cn.iocoder.yudao.module.system.service.auth; +package cn.iocoder.yudao.module.system.service.oauth2; +import cn.hutool.core.map.MapUtil; import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; import cn.iocoder.yudao.framework.common.pojo.PageResult; 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 import cn.iocoder.yudao.module.system.dal.dataobject.oauth2.OAuth2ClientDO; import cn.iocoder.yudao.module.system.dal.mysql.oauth2.OAuth2ClientMapper; import cn.iocoder.yudao.module.system.mq.producer.auth.OAuth2ClientProducer; -import cn.iocoder.yudao.module.system.service.oauth2.OAuth2ClientServiceImpl; -import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; import org.springframework.boot.test.mock.mockito.MockBean; import org.springframework.context.annotation.Import; import javax.annotation.Resource; +import java.util.Collections; import java.util.Map; 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; import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals; import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertServiceException; import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.*; -import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.OAUTH2_CLIENT_NOT_EXISTS; +import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.*; import static org.junit.jupiter.api.Assertions.*; import static org.mockito.Mockito.verify; @@ -132,7 +132,31 @@ public class OAuth2ClientServiceImplTest extends BaseDbUnitTest { } @Test - @Disabled + public void testValidateClientIdExists_withId() { + // mock 数据 + OAuth2ClientDO client = randomPojo(OAuth2ClientDO.class).setClientId("tudou"); + oauth2ClientMapper.insert(client); + // 准备参数 + Long id = randomLongId(); + String clientId = "tudou"; + + // 调用,不会报错 + assertServiceException(() -> oauth2ClientService.validateClientIdExists(id, clientId), OAUTH2_CLIENT_EXISTS); + } + + @Test + public void testValidateClientIdExists_noId() { + // mock 数据 + OAuth2ClientDO client = randomPojo(OAuth2ClientDO.class).setClientId("tudou"); + oauth2ClientMapper.insert(client); + // 准备参数 + String clientId = "tudou"; + + // 调用,不会报错 + assertServiceException(() -> oauth2ClientService.validateClientIdExists(null, clientId), OAUTH2_CLIENT_EXISTS); + } + + @Test public void testGetOAuth2ClientPage() { // mock 数据 OAuth2ClientDO dbOAuth2Client = randomPojo(OAuth2ClientDO.class, o -> { // 等会查询到 @@ -143,10 +167,10 @@ public class OAuth2ClientServiceImplTest extends BaseDbUnitTest { // 测试 name 不匹配 oauth2ClientMapper.insert(cloneIgnoreId(dbOAuth2Client, o -> o.setName("凤凰"))); // 测试 status 不匹配 - oauth2ClientMapper.insert(cloneIgnoreId(dbOAuth2Client, o -> o.setStatus(CommonStatusEnum.ENABLE.getStatus()))); + oauth2ClientMapper.insert(cloneIgnoreId(dbOAuth2Client, o -> o.setStatus(CommonStatusEnum.DISABLE.getStatus()))); // 准备参数 OAuth2ClientPageReqVO reqVO = new OAuth2ClientPageReqVO(); - reqVO.setName("long"); + reqVO.setName("龙"); reqVO.setStatus(CommonStatusEnum.ENABLE.getStatus()); // 调用 @@ -157,4 +181,35 @@ public class OAuth2ClientServiceImplTest extends BaseDbUnitTest { assertPojoEquals(dbOAuth2Client, pageResult.getList().get(0)); } + @Test + public void testValidOAuthClientFromCache() { + // mock 方法 + OAuth2ClientDO client = randomPojo(OAuth2ClientDO.class).setClientId("default") + .setStatus(CommonStatusEnum.ENABLE.getStatus()); + OAuth2ClientDO client02 = randomPojo(OAuth2ClientDO.class).setClientId("disable") + .setStatus(CommonStatusEnum.DISABLE.getStatus()); + Map clientCache = MapUtil.builder() + .put(client.getClientId(), client) + .put(client02.getClientId(), client02).build(); + oauth2ClientService.setClientCache(clientCache); + + // 调用,并断言 + assertServiceException(() -> oauth2ClientService.validOAuthClientFromCache(randomString(), + null, null, null, null), OAUTH2_CLIENT_NOT_EXISTS); + assertServiceException(() -> oauth2ClientService.validOAuthClientFromCache("disable", + null, null, null, null), OAUTH2_CLIENT_DISABLE); + assertServiceException(() -> oauth2ClientService.validOAuthClientFromCache("default", + randomString(), null, null, null), OAUTH2_CLIENT_CLIENT_SECRET_ERROR); + assertServiceException(() -> oauth2ClientService.validOAuthClientFromCache("default", + null, randomString(), null, null), OAUTH2_CLIENT_AUTHORIZED_GRANT_TYPE_NOT_EXISTS); + assertServiceException(() -> oauth2ClientService.validOAuthClientFromCache("default", + null, null, Collections.singleton(randomString()), null), OAUTH2_CLIENT_SCOPE_OVER); + assertServiceException(() -> oauth2ClientService.validOAuthClientFromCache("default", + null, null, null, "test"), OAUTH2_CLIENT_REDIRECT_URI_NOT_MATCH, "test"); + // 成功调用 + OAuth2ClientDO result = oauth2ClientService.validOAuthClientFromCache(client.getClientId(), client.getSecret(), + client.getAuthorizedGrantTypes().get(0), client.getScopes(), client.getRedirectUris().get(0)); + assertPojoEquals(client, result); + } + } diff --git a/yudao-module-system/yudao-module-system-biz/src/test/resources/sql/create_tables.sql b/yudao-module-system/yudao-module-system-biz/src/test/resources/sql/create_tables.sql index 3cc860101..b9f9bca86 100644 --- a/yudao-module-system/yudao-module-system-biz/src/test/resources/sql/create_tables.sql +++ b/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" ( "access_token_validity_seconds" int NOT NULL, "refresh_token_validity_seconds" int NOT NULL, "redirect_uris" varchar NOT NULL, - "auto_approve" bit NOT NULL DEFAULT FALSE, "authorized_grant_types" varchar NOT NULL, "scopes" varchar NOT NULL DEFAULT '', + "auto_approve_scopes" varchar NOT NULL DEFAULT '', "authorities" varchar NOT NULL DEFAULT '', "resource_ids" varchar NOT NULL DEFAULT '', "additional_information" varchar NOT NULL DEFAULT '', diff --git a/yudao-ui-admin/src/views/sso.vue b/yudao-ui-admin/src/views/sso.vue index 043010901..2a21e0af9 100644 --- a/yudao-ui-admin/src/views/sso.vue +++ b/yudao-ui-admin/src/views/sso.vue @@ -37,7 +37,7 @@ - 统一授权 + 同意授权 授 权 中...