using Microsoft.AspNetCore.Mvc; using FutureMailAPI.Services; using FutureMailAPI.DTOs; using FutureMailAPI.Models; using FutureMailAPI.Extensions; namespace FutureMailAPI.Controllers { [ApiController] [Route("api/v1/oauth")] public class OAuthController : ControllerBase { private readonly IOAuthService _oauthService; private readonly ILogger _logger; public OAuthController(IOAuthService oauthService, ILogger logger) { _oauthService = oauthService; _logger = logger; } /// /// OAuth登录端点 /// [HttpPost("login")] public async Task Login([FromBody] OAuthLoginDto loginDto) { try { var result = await _oauthService.LoginAsync(loginDto); if (result.Success) { return Ok(result); } return BadRequest(result); } catch (Exception ex) { _logger.LogError(ex, "OAuth登录时发生错误"); return StatusCode(500, new { message = "服务器内部错误" }); } } /// /// 创建OAuth客户端 /// [HttpPost("clients")] public async Task CreateClient([FromBody] OAuthClientCreateDto createDto) { try { // 从OAuth中间件获取当前用户ID var userId = HttpContext.GetCurrentUserId(); if (!userId.HasValue) { return Unauthorized(new { message = "未授权访问" }); } var result = await _oauthService.CreateClientAsync(userId.Value, createDto); if (result.Success) { return Ok(result); } return BadRequest(result); } catch (Exception ex) { _logger.LogError(ex, "创建OAuth客户端时发生错误"); return StatusCode(500, new { message = "服务器内部错误" }); } } /// /// 获取OAuth客户端信息 /// [HttpGet("clients/{clientId}")] public async Task GetClient(string clientId) { try { var result = await _oauthService.GetClientAsync(clientId); if (result.Success) { return Ok(result); } return NotFound(result); } catch (Exception ex) { _logger.LogError(ex, "获取OAuth客户端信息时发生错误"); return StatusCode(500, new { message = "服务器内部错误" }); } } /// /// OAuth授权端点 /// [HttpGet("authorize")] public async Task Authorize([FromQuery] OAuthAuthorizationRequestDto request) { try { // 从OAuth中间件获取当前用户ID var userId = HttpContext.GetCurrentUserId(); if (!userId.HasValue) { // 如果用户未登录,重定向到登录页面 var loginRedirectUri = $"/api/v1/auth/login?redirect_uri={Uri.EscapeDataString(request.RedirectUri)}"; if (!string.IsNullOrEmpty(request.State)) { loginRedirectUri += $"&state={request.State}"; } return Redirect(loginRedirectUri); } var result = await _oauthService.AuthorizeAsync(userId.Value, request); if (result.Success) { // 重定向到客户端,携带授权码 var redirectUri = $"{request.RedirectUri}?code={result.Data.Code}"; if (!string.IsNullOrEmpty(request.State)) { redirectUri += $"&state={request.State}"; } return Redirect(redirectUri); } // 错误重定向 var errorRedirectUri = $"{request.RedirectUri}?error={result.Message}"; if (!string.IsNullOrEmpty(request.State)) { errorRedirectUri += $"&state={request.State}"; } return Redirect(errorRedirectUri); } catch (Exception ex) { _logger.LogError(ex, "OAuth授权时发生错误"); // 错误重定向 var errorRedirectUri = $"{request.RedirectUri}?error=server_error"; if (!string.IsNullOrEmpty(request.State)) { errorRedirectUri += $"&state={request.State}"; } return Redirect(errorRedirectUri); } } /// /// OAuth令牌端点 /// [HttpPost("token")] [Microsoft.AspNetCore.Authorization.AllowAnonymous] public async Task ExchangeToken([FromForm] OAuthTokenRequestDto request) { _logger.LogInformation("OAuth令牌端点被调用"); try { _logger.LogInformation("OAuth令牌交换请求: GrantType={GrantType}, ClientId={ClientId}, Username={Username}", request.GrantType, request.ClientId, request.Username); if (request.GrantType == "authorization_code") { var result = await _oauthService.ExchangeCodeForTokenAsync(request); if (result.Success) { return Ok(result); } return BadRequest(result); } else if (request.GrantType == "refresh_token") { var result = await _oauthService.RefreshTokenAsync(request); if (result.Success) { return Ok(result); } return BadRequest(result); } else if (request.GrantType == "password") { _logger.LogInformation("处理密码授权类型登录请求"); // 创建OAuth登录请求 var loginDto = new OAuthLoginDto { UsernameOrEmail = request.Username, Password = request.Password, ClientId = request.ClientId, ClientSecret = request.ClientSecret, Scope = request.Scope }; var result = await _oauthService.LoginAsync(loginDto); if (result.Success) { _logger.LogInformation("密码授权类型登录成功"); return Ok(result); } _logger.LogWarning("密码授权类型登录失败: {Message}", result.Message); return BadRequest(result); } else { _logger.LogWarning("不支持的授权类型: {GrantType}", request.GrantType); return BadRequest(new { message = "不支持的授权类型" }); } } catch (Exception ex) { _logger.LogError(ex, "OAuth令牌交换时发生错误"); return StatusCode(500, new { message = "服务器内部错误" }); } } /// /// 撤销令牌 /// [HttpPost("revoke")] public async Task RevokeToken([FromForm] string token, [FromForm] string token_type_hint = "access_token") { try { var result = await _oauthService.RevokeTokenAsync(token); if (result.Success) { return Ok(new { message = "令牌已撤销" }); } return BadRequest(result); } catch (Exception ex) { _logger.LogError(ex, "撤销令牌时发生错误"); return StatusCode(500, new { message = "服务器内部错误" }); } } /// /// 验证令牌 /// [HttpPost("introspect")] public async Task IntrospectToken([FromForm] string token) { try { var result = await _oauthService.ValidateTokenAsync(token); if (result.Success) { var accessToken = await _oauthService.GetAccessTokenAsync(token); if (accessToken != null) { return Ok(new { active = true, scope = accessToken.Scopes, client_id = accessToken.Client.ClientId, username = accessToken.User.Email, exp = ((DateTimeOffset)accessToken.ExpiresAt).ToUnixTimeSeconds(), iat = ((DateTimeOffset)accessToken.CreatedAt).ToUnixTimeSeconds() }); } } return Ok(new { active = false }); } catch (Exception ex) { _logger.LogError(ex, "验证令牌时发生错误"); return StatusCode(500, new { message = "服务器内部错误" }); } } } }