136 lines
7.2 KiB
Java
136 lines
7.2 KiB
Java
package com.baiyue.auth.controller;
|
|
|
|
import com.baiyue.auth.dto.AccountManagementDtos.*;
|
|
import com.baiyue.auth.service.AccountManagementService;
|
|
import com.baiyue.auth.service.AuthService;
|
|
import com.baiyue.auth.service.OverseasSessionValidationService;
|
|
import com.baiyue.auth.dto.OverseasSessionValidationDtos;
|
|
import com.baiyue.common.core.api.ApiResponse;
|
|
import com.baiyue.common.core.api.ResultCode;
|
|
import com.baiyue.common.core.exception.BizException;
|
|
import jakarta.annotation.PostConstruct;
|
|
import jakarta.annotation.Resource;
|
|
import jakarta.validation.Valid;
|
|
import io.swagger.v3.oas.annotations.Operation;
|
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
|
import org.springframework.beans.factory.annotation.Value;
|
|
import org.springframework.web.bind.annotation.*;
|
|
|
|
import java.nio.charset.StandardCharsets;
|
|
import java.security.MessageDigest;
|
|
|
|
/** 仅供可信内部服务调用的账号管理接口。 */
|
|
@RestController
|
|
@RequestMapping("/internal/auth/accounts")
|
|
@Tag(name = "Internal Auth / 内部认证", description = "Service-token protected internal account and overseas PDA session APIs")
|
|
public class InternalAccountController {
|
|
@Resource
|
|
private AccountManagementService service;
|
|
@Resource
|
|
private AuthService authService;
|
|
@Resource
|
|
private OverseasSessionValidationService overseasSessionValidationService;
|
|
|
|
@Value("${baiyue.security.internal-service-token}")
|
|
private String configuredToken;
|
|
private byte[] tokenBytes;
|
|
|
|
@PostConstruct
|
|
void init() {
|
|
byte[] configured = configuredToken == null
|
|
? new byte[0] : configuredToken.getBytes(StandardCharsets.UTF_8);
|
|
if (configured.length < 32) {
|
|
throw new IllegalStateException("INTERNAL_SERVICE_TOKEN 至少需要 32 字节");
|
|
}
|
|
tokenBytes = configured;
|
|
}
|
|
|
|
@PostMapping
|
|
public ApiResponse<AccountSummary> create(@RequestHeader(value="X-Internal-Service-Token", required=false) String token,
|
|
@Valid @RequestBody CreateAccountRequest request) {
|
|
verify(token); return ApiResponse.success(service.create(request));
|
|
}
|
|
@GetMapping("/availability")
|
|
public ApiResponse<Boolean> availability(@RequestHeader(value="X-Internal-Service-Token", required=false) String token,
|
|
@RequestParam String username) {
|
|
verify(token); return ApiResponse.success(service.usernameAvailable(username));
|
|
}
|
|
@GetMapping("/{id}")
|
|
public ApiResponse<AccountSummary> summary(@RequestHeader(value="X-Internal-Service-Token", required=false) String token,
|
|
@PathVariable Long id) {
|
|
verify(token); return ApiResponse.success(service.summary(id));
|
|
}
|
|
@PutMapping("/{id}/status")
|
|
public ApiResponse<Void> status(@RequestHeader(value="X-Internal-Service-Token", required=false) String token,
|
|
@PathVariable Long id, @Valid @RequestBody UpdateAccountStatusRequest request) {
|
|
verify(token); service.updateStatus(id, request); return ApiResponse.success(null);
|
|
}
|
|
@PostMapping("/sessions/revoke")
|
|
public ApiResponse<Void> revokeSessions(
|
|
@RequestHeader(value="X-Internal-Service-Token", required=false) String token,
|
|
@Valid @RequestBody RevokeAccountSessionsRequest request) {
|
|
verify(token); service.revokeSessions(request.accountIds()); return ApiResponse.success(null);
|
|
}
|
|
@PostMapping("/overseas-session/validate")
|
|
@Operation(summary = "Validate verified overseas PDA claims / 校验已验签的海外PDA声明",
|
|
description = "Accepts only claims extracted after Gateway JWT verification; raw tokens and user credentials are forbidden.")
|
|
public ApiResponse<OverseasSessionValidationDtos.Response> validateOverseasSession(
|
|
@RequestHeader(value="X-Internal-Service-Token", required=false) String token,
|
|
@Valid @RequestBody OverseasSessionValidationDtos.Request request) {
|
|
verify(token);
|
|
return ApiResponse.success(overseasSessionValidationService.validate(request));
|
|
}
|
|
@PutMapping("/{id}/profile")
|
|
public ApiResponse<Void> profile(@RequestHeader(value="X-Internal-Service-Token", required=false) String token,
|
|
@PathVariable Long id, @Valid @RequestBody UpdateAccountProfileRequest request) {
|
|
verify(token); service.updateProfile(id, request); return ApiResponse.success(null);
|
|
}
|
|
@PutMapping("/{id}/login-identifiers")
|
|
public ApiResponse<AccountSummary> loginIdentifiers(
|
|
@RequestHeader(value="X-Internal-Service-Token", required=false) String token,
|
|
@PathVariable Long id, @Valid @RequestBody ChangeLoginIdentifiersRequest request) {
|
|
verify(token);
|
|
return ApiResponse.success(service.changeLoginIdentifiers(id, request));
|
|
}
|
|
@PutMapping("/{id}/phone")
|
|
public ApiResponse<Void> phone(@RequestHeader(value="X-Internal-Service-Token", required=false) String token,
|
|
@PathVariable Long id, @Valid @RequestBody UpdateAccountPhoneRequest request) {
|
|
verify(token);
|
|
service.updatePhone(id, request);
|
|
return ApiResponse.success(null);
|
|
}
|
|
@PutMapping("/{id}/password")
|
|
public ApiResponse<Void> reset(@RequestHeader(value="X-Internal-Service-Token", required=false) String token,
|
|
@PathVariable Long id, @Valid @RequestBody ResetPasswordRequest request) {
|
|
verify(token); service.resetPassword(id, request, request.forceChange()); return ApiResponse.success(null);
|
|
}
|
|
|
|
@PostMapping("/impersonation-tickets")
|
|
public ApiResponse<ImpersonationTicketResponse> impersonationTicket(
|
|
@RequestHeader(value="X-Internal-Service-Token", required=false) String token,
|
|
@Valid @RequestBody ImpersonationTicketRequest request) {
|
|
verify(token); return ApiResponse.success(authService.createImpersonationTicket(request));
|
|
}
|
|
|
|
@PutMapping("/tenant/{tenantId}/archive")
|
|
public ApiResponse<Void> archiveTenant(@RequestHeader(value="X-Internal-Service-Token", required=false) String token,
|
|
@PathVariable Long tenantId) {
|
|
verify(token); service.archiveTenant(tenantId); return ApiResponse.success(null);
|
|
}
|
|
@PutMapping("/{id}/scope")
|
|
public ApiResponse<Void> scope(@RequestHeader(value="X-Internal-Service-Token", required=false) String token,
|
|
@PathVariable Long id, @Valid @RequestBody UpdateAccountScopeRequest request) {
|
|
verify(token); service.updateScope(id, request); return ApiResponse.success(null);
|
|
}
|
|
@DeleteMapping("/{id}/compensation")
|
|
public ApiResponse<Void> compensate(@RequestHeader(value="X-Internal-Service-Token", required=false) String token,
|
|
@PathVariable Long id) {
|
|
verify(token); service.compensateDelete(id); return ApiResponse.success(null);
|
|
}
|
|
|
|
private void verify(String supplied) {
|
|
byte[] value = supplied == null ? new byte[0] : supplied.getBytes(StandardCharsets.UTF_8);
|
|
if (!MessageDigest.isEqual(tokenBytes, value)) throw new BizException(ResultCode.FORBIDDEN, "内部服务令牌无效");
|
|
}
|
|
}
|