-
-
Notifications
You must be signed in to change notification settings - Fork 10.2k
提供一个创建用户的OpenAPI #5554
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
提供一个创建用户的OpenAPI #5554
Changes from 10 commits
23d4c21
3c2d02b
4c70231
a70c64e
d0f1ecc
d44c22c
e918b53
ef06d0b
e870483
61bdf7c
1c874ff
eadd028
ce468f0
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,77 @@ | ||
| /* | ||
| * Copyright 2025 Apollo Authors | ||
| * | ||
| * Licensed under the Apache License, Version 2.0 (the "License"); | ||
| * you may not use this file except in compliance with the License. | ||
| * You may obtain a copy of the License at | ||
| * | ||
| * http://www.apache.org/licenses/LICENSE-2.0 | ||
| * | ||
| * Unless required by applicable law or agreed to in writing, software | ||
| * distributed under the License is distributed on an "AS IS" BASIS, | ||
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| * See the License for the specific language governing permissions and | ||
| * limitations under the License. | ||
| * | ||
| */ | ||
| package com.ctrip.framework.apollo.openapi.dto; | ||
|
|
||
| /** | ||
| * Open API User DTO for user management operations. | ||
| * | ||
| * @author dreamweaver | ||
| */ | ||
| public class OpenUserDTO { | ||
|
|
||
| private String username; | ||
| private String userDisplayName; | ||
| private String password; | ||
| private String email; | ||
| private Integer enabled; | ||
|
|
||
| public String getUsername() { | ||
| return username; | ||
| } | ||
|
|
||
| public void setUsername(String username) { | ||
| this.username = username; | ||
| } | ||
|
|
||
| public String getUserDisplayName() { | ||
| return userDisplayName; | ||
| } | ||
|
|
||
| public void setUserDisplayName(String userDisplayName) { | ||
| this.userDisplayName = userDisplayName; | ||
| } | ||
|
|
||
| public String getPassword() { | ||
| return password; | ||
| } | ||
|
|
||
| public void setPassword(String password) { | ||
| this.password = password; | ||
| } | ||
|
|
||
| public String getEmail() { | ||
| return email; | ||
| } | ||
|
|
||
| public void setEmail(String email) { | ||
| this.email = email; | ||
| } | ||
|
|
||
| public Integer getEnabled() { | ||
| return enabled; | ||
| } | ||
|
|
||
| public void setEnabled(Integer enabled) { | ||
| this.enabled = enabled; | ||
| } | ||
|
|
||
| @Override | ||
| public String toString() { | ||
| return "OpenUserDTO{" + "username='" + username + '\'' + ", userDisplayName='" + userDisplayName | ||
| + '\'' + ", email='" + email + '\'' + ", enabled=" + enabled + '}'; | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,163 @@ | ||
| /* | ||
| * Copyright 2025 Apollo Authors | ||
| * | ||
| * Licensed under the Apache License, Version 2.0 (the "License"); | ||
| * you may not use this file except in compliance with the License. | ||
| * You may obtain a copy of the License at | ||
| * | ||
| * http://www.apache.org/licenses/LICENSE-2.0 | ||
| * | ||
| * Unless required by applicable law or agreed to in writing, software | ||
| * distributed under the License is distributed on an "AS IS" BASIS, | ||
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| * See the License for the specific language governing permissions and | ||
| * limitations under the License. | ||
| * | ||
| */ | ||
| package com.ctrip.framework.apollo.openapi.v1.controller; | ||
|
|
||
| import com.ctrip.framework.apollo.audit.annotation.ApolloAuditLog; | ||
| import com.ctrip.framework.apollo.audit.annotation.OpType; | ||
| import com.ctrip.framework.apollo.common.exception.BadRequestException; | ||
| import com.ctrip.framework.apollo.core.utils.StringUtils; | ||
| import com.ctrip.framework.apollo.openapi.dto.OpenUserDTO; | ||
| import com.ctrip.framework.apollo.portal.entity.bo.UserInfo; | ||
| import com.ctrip.framework.apollo.portal.entity.po.UserPO; | ||
| import com.ctrip.framework.apollo.portal.spi.UserService; | ||
| import com.ctrip.framework.apollo.portal.spi.springsecurity.SpringSecurityUserService; | ||
| import com.ctrip.framework.apollo.portal.util.checker.AuthUserPasswordChecker; | ||
| import com.ctrip.framework.apollo.portal.util.checker.CheckResult; | ||
| import org.springframework.http.ResponseEntity; | ||
| import org.springframework.security.access.prepost.PreAuthorize; | ||
| import org.springframework.web.bind.annotation.GetMapping; | ||
| import org.springframework.web.bind.annotation.PathVariable; | ||
| import org.springframework.web.bind.annotation.PostMapping; | ||
| import org.springframework.web.bind.annotation.RequestBody; | ||
| import org.springframework.web.bind.annotation.RequestMapping; | ||
| import org.springframework.web.bind.annotation.RequestParam; | ||
| import org.springframework.web.bind.annotation.RestController; | ||
| import org.springframework.web.servlet.support.ServletUriComponentsBuilder; | ||
|
|
||
| import java.net.URI; | ||
| import java.util.List; | ||
|
|
||
| /** | ||
| * OpenAPI User Management Controller Provides RESTful APIs for user management operations through | ||
| * OpenAPI | ||
| * | ||
| * @author dreamweaver | ||
| */ | ||
| @RestController("openapiUserController") | ||
| @RequestMapping("/openapi/v1") | ||
| public class UserController { | ||
|
|
||
| private static final int DEFAULT_USER_ENABLED = 1; | ||
|
|
||
| private final UserService userService; | ||
| private final AuthUserPasswordChecker passwordChecker; | ||
|
|
||
| public UserController(final UserService userService, | ||
| final AuthUserPasswordChecker passwordChecker) { | ||
| this.userService = userService; | ||
| this.passwordChecker = passwordChecker; | ||
| } | ||
|
|
||
| /** | ||
| * Create a new user | ||
| * | ||
| * @param openUserDTO user information to create | ||
| * @return ResponseEntity with created user information | ||
| */ | ||
| @PreAuthorize(value = "@unifiedPermissionValidator.hasCreateUserPermission()") | ||
| @ApolloAuditLog(name = "OpenAPI.createUser", type = OpType.CREATE, | ||
| description = "Create user via OpenAPI") | ||
| @PostMapping("/users") | ||
| public ResponseEntity<UserInfo> createUser(@RequestBody OpenUserDTO openUserDTO) { | ||
| // Validate required fields | ||
| if (StringUtils.isContainEmpty(openUserDTO.getUsername(), openUserDTO.getPassword())) { | ||
| throw new BadRequestException("Username and password cannot be empty."); | ||
| } | ||
|
|
||
| if (StringUtils.isEmpty(openUserDTO.getEmail())) { | ||
| throw new BadRequestException("Email cannot be empty."); | ||
| } | ||
|
|
||
| // Check password strength | ||
| CheckResult pwdCheckRes = passwordChecker.checkWeakPassword(openUserDTO.getPassword()); | ||
| if (!pwdCheckRes.isSuccess()) { | ||
| throw new BadRequestException(pwdCheckRes.getMessage()); | ||
| } | ||
|
|
||
| // Check if UserService supports user creation | ||
| if (!(userService instanceof SpringSecurityUserService)) { | ||
| throw new UnsupportedOperationException( | ||
| "Create user operation is not supported with current user service implementation"); | ||
| } | ||
|
|
||
| // Convert DTO to PO and set defaults | ||
| UserPO userPO = new UserPO(); | ||
| userPO.setUsername(openUserDTO.getUsername()); | ||
| userPO.setPassword(openUserDTO.getPassword()); | ||
| userPO.setEmail(openUserDTO.getEmail()); | ||
| userPO.setUserDisplayName( | ||
| openUserDTO.getUserDisplayName() != null ? openUserDTO.getUserDisplayName() | ||
| : openUserDTO.getUsername()); | ||
| userPO.setEnabled( | ||
| openUserDTO.getEnabled() != null ? openUserDTO.getEnabled() : DEFAULT_USER_ENABLED); | ||
|
|
||
| // Create user | ||
| ((SpringSecurityUserService) userService).create(userPO); | ||
|
Comment on lines
+107
to
+128
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧩 Analysis chain🏁 Script executed: #!/bin/bash
# Find and examine UserService interface definition
echo "=== Searching for UserService interface ==="
rg -n 'interface UserService' --type=java -A 20
echo -e "\n=== Classes implementing UserService ==="
rg -n 'implements UserService' --type=java
echo -e "\n=== Find UserService file location ==="
fd -n 'UserService.java' --type fRepository: apolloconfig/apollo Length of output: 1843 🏁 Script executed: #!/bin/bash
# Get full UserService interface definition
echo "=== Full UserService interface ==="
cat -n apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/spi/UserService.java
echo -e "\n=== SpringSecurityUserService create method ==="
rg -n 'create\(' apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/spi/springsecurity/SpringSecurityUserService.java -A 5
echo -e "\n=== Check for exception handlers in UserController ==="
rg -n '@ExceptionHandler|@ControllerAdvice' apollo-portal/src/main/java/com/ctrip/framework/apollo/openapi/v1/controller/UserController.java
echo -e "\n=== Check UserController class definition for exception handling ==="
rg -n 'class UserController' apollo-portal/src/main/java/com/ctrip/framework/apollo/openapi/v1/controller/UserController.java -A 5Repository: apolloconfig/apollo Length of output: 2035 🏁 Script executed: #!/bin/bash
# Check for global exception handling
echo "=== Search for exception handlers (RestControllerAdvice/ControllerAdvice) ==="
rg -n '@RestControllerAdvice|@ControllerAdvice' apollo-portal/src/main/java --type=java
echo -e "\n=== Check how UnsupportedOperationException is handled ==="
rg -n 'UnsupportedOperationException' apollo-portal/src/main/java --type=java
echo -e "\n=== Check searchUsers method in SpringSecurityUserService ==="
rg -n 'searchUsers' apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/spi/springsecurity/SpringSecurityUserService.java -A 15
echo -e "\n=== Check UserController searchUsers method (around lines 141-157) ==="
sed -n '135,160p' apollo-portal/src/main/java/com/ctrip/framework/apollo/openapi/v1/controller/UserController.java | cat -nRepository: apolloconfig/apollo Length of output: 4152 Tight coupling to The controller depends on the Additionally, Proposed approachAdd a - // Check if UserService supports user creation
- if (!(userService instanceof SpringSecurityUserService)) {
- throw new UnsupportedOperationException(
- "Create user operation is not supported with current user service implementation");
- }
-
// Convert DTO to PO and set defaults
...
// Create user
- ((SpringSecurityUserService) userService).create(userPO);
+ userService.create(userPO);In default void create(UserPO user) {
throw new UnsupportedOperationException(
"Create user operation is not supported with current user service implementation");
}🤖 Prompt for AI Agents |
||
|
|
||
| // Retrieve and return the created user information | ||
| UserInfo createdUser = userService.findByUserId(openUserDTO.getUsername()); | ||
| URI location = ServletUriComponentsBuilder.fromCurrentRequest() | ||
| .replacePath("/openapi/v1/users/{userId}").buildAndExpand(createdUser.getUserId()).toUri(); | ||
| return ResponseEntity.created(location).body(createdUser); | ||
| } | ||
|
coderabbitai[bot] marked this conversation as resolved.
|
||
|
|
||
| /** | ||
| * Get user information by user ID | ||
| * | ||
| * @param userId the user ID to query | ||
| * @return UserInfo object | ||
| */ | ||
| @PreAuthorize(value = "@unifiedPermissionValidator.hasCreateUserPermission()") | ||
| @GetMapping("/users/{userId}") | ||
|
Comment on lines
+142
to
+143
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧩 Analysis chain🏁 Script executed: #!/bin/bash
# Search for permission validator and user-related permissions
echo "=== UnifiedPermissionValidator class with permission methods ==="
rg -n 'class UnifiedPermissionValidator' --type=java -A 30
echo -e "\n=== All hasXxxUserPermission methods ==="
rg -n 'has.*UserPermission|hasPermission' --type=java | grep -i user
echo -e "\n=== UserController.java content around lines 126-127 and 145-146 ==="
fd 'UserController.java' --type=f -x cat -n {}Repository: apolloconfig/apollo Length of output: 22105 🏁 Script executed: #!/bin/bash
# More targeted search for permission methods
echo "=== hasCreateUserPermission definition ==="
rg -n 'hasCreateUserPermission' --type=java -B 2 -A 8
echo -e "\n=== hasViewUserPermission or similar ==="
rg -n 'hasViewUser|hasReadUser|hasListUser|hasGetUser' --type=javaRepository: apolloconfig/apollo Length of output: 19078 🏁 Script executed: #!/bin/bash
# Check if there are other permission types defined (READ_USER, VIEW_USER, etc.)
echo "=== All PermissionType constants ==="
rg -n 'PermissionType\.' --type=java | grep -i user | head -20
echo -e "\n=== Check if other controllers have read/write permission separation ==="
rg -n '@GetMapping|@PostMapping' --type=java -B 2 | grep -A 2 'PreAuthorize' | head -40Repository: apolloconfig/apollo Length of output: 6148 GET endpoints Both read-only endpoints at lines 124 and 143 require 🤖 Prompt for AI Agents |
||
| public ResponseEntity<UserInfo> getUserByUserId(@PathVariable String userId) { | ||
| UserInfo userInfo = userService.findByUserId(userId); | ||
| if (userInfo == null) { | ||
| throw new BadRequestException("User not found: " + userId); | ||
| } | ||
| return ResponseEntity.ok(userInfo); | ||
| } | ||
|
Comment on lines
+145
to
+152
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. User not found should return HTTP 404, not 400.
🤖 Prompt for AI Agents |
||
|
|
||
| /** | ||
| * Search users by keyword | ||
| * | ||
| * @param keyword keyword to search (searches in username and display name) | ||
| * @param includeInactiveUsers whether to include inactive users | ||
| * @param offset pagination offset | ||
| * @param limit pagination limit | ||
| * @return list of UserInfo objects | ||
| */ | ||
| @PreAuthorize(value = "@unifiedPermissionValidator.hasCreateUserPermission()") | ||
| @GetMapping("/users") | ||
| public ResponseEntity<List<UserInfo>> searchUsers( | ||
| @RequestParam(value = "keyword", required = false, defaultValue = "") String keyword, | ||
| @RequestParam(value = "includeInactiveUsers", | ||
| defaultValue = "false") boolean includeInactiveUsers, | ||
| @RequestParam(value = "offset", defaultValue = "0") int offset, | ||
| @RequestParam(value = "limit", defaultValue = "10") int limit) { | ||
|
|
||
| if (limit <= 0 || limit > 100) { | ||
| throw new BadRequestException("Limit must be between 1 and 100"); | ||
| } | ||
|
|
||
| if (offset < 0) { | ||
| throw new BadRequestException("Offset must be non-negative"); | ||
| } | ||
|
|
||
| List<UserInfo> users = userService.searchUsers(keyword, offset, limit, includeInactiveUsers); | ||
| return ResponseEntity.ok(users); | ||
|
Comment on lines
+166
to
+185
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧩 Analysis chain🏁 Script executed: #!/bin/bash
# Find SpringSecurityUserService class
find . -name "*SpringSecurityUserService*" -type fRepository: apolloconfig/apollo Length of output: 176 🏁 Script executed: #!/bin/bash
# Read the SpringSecurityUserService file
cat -n ./apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/spi/springsecurity/SpringSecurityUserService.javaRepository: apolloconfig/apollo Length of output: 6717 Pagination parameters The Implement actual pagination in 🤖 Prompt for AI Agents |
||
| } | ||
| } | ||
Uh oh!
There was an error while loading. Please reload this page.