fengling-console/src/Controllers/OAuthClientsController.cs
movingsam c50615d8d1 refactor: 将项目文件迁移到 src 目录并创建 slnx 解决方案
- 将 Controllers, Services, Models, Properties 等目录移至 src/ 下
- 创建 Fengling.Console.slnx Rider 解决方案文件
- 更新 csproj 中的项目引用路径
- 修复 CI/CD 配置:
  - build.yml: 更新项目路径为 src/Fengling.Console.csproj
  - docker.yml: 添加 Dockerfile 路径指向 src/Dockerfile
  - Dockerfile: 修复 COPY 路径以匹配新的目录结构

Closes #重构项目结构
2026-02-28 18:04:16 +08:00

223 lines
8.2 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

namespace Fengling.Console.Controllers;
/// <summary>
/// OAuth客户端管理控制器
/// </summary>
[ApiController]
[Route("api/console/[controller]")]
[Authorize(AuthenticationSchemes = OpenIddictValidationAspNetCoreDefaults.AuthenticationScheme)]
public class OAuthClientsController : ControllerBase
{
private readonly IOAuthClientService _service;
private readonly ILogger<OAuthClientsController> _logger;
public OAuthClientsController(
IOAuthClientService service,
ILogger<OAuthClientsController> logger)
{
_service = service;
_logger = logger;
}
/// <summary>
/// 获取OAuth客户端列表
/// </summary>
/// <param name="query">分页查询参数支持按显示名称、客户端ID和状态筛选</param>
/// <returns>分页的OAuth客户端列表包含总数量、分页信息和客户端详情</returns>
/// <response code="200">成功返回OAuth客户端分页列表</response>
/// <response code="500">服务器内部错误</response>
[HttpGet]
[Produces("application/json")]
[ProducesResponseType(typeof(OAuthClientListDto), StatusCodes.Status200OK)]
[ProducesResponseType(typeof(object), StatusCodes.Status500InternalServerError)]
public async Task<ActionResult<OAuthClientListDto>> GetClients([FromQuery] OAuthClientQueryDto query)
{
try
{
var (items, totalCount) = await _service.GetClientsAsync(query.Page, query.PageSize, query.DisplayName, query.ClientId, query.Status);
var result = new OAuthClientListDto
{
Items = items.ToList(),
TotalCount = totalCount,
Page = query.Page,
PageSize = query.PageSize
};
return Ok(result);
}
catch (Exception ex)
{
_logger.LogError(ex, "Error getting clients");
return StatusCode(500, new { message = ex.Message });
}
}
/// <summary>
/// 获取OAuth客户端选项
/// </summary>
/// <returns>包含客户端类型、授权类型、授权范围等可选值的配置选项</returns>
/// <response code="200">成功返回客户端配置选项</response>
[HttpGet("options")]
[Produces("application/json")]
[ProducesResponseType(typeof(object), StatusCodes.Status200OK)]
public ActionResult<object> GetClientOptions()
{
return Ok(_service.GetClientOptions());
}
/// <summary>
/// 获取单个OAuth客户端详情
/// </summary>
/// <param name="id">客户端唯一标识符</param>
/// <returns>OAuth客户端的完整配置信息</returns>
/// <response code="200">成功返回客户端详情</response>
/// <response code="404">客户端不存在</response>
/// <response code="500">服务器内部错误</response>
[HttpGet("{id}")]
[Produces("application/json")]
[ProducesResponseType(typeof(OAuthClientDto), StatusCodes.Status200OK)]
[ProducesResponseType(typeof(object), StatusCodes.Status404NotFound)]
[ProducesResponseType(typeof(object), StatusCodes.Status500InternalServerError)]
public async Task<ActionResult<OAuthClientDto>> GetClient(string id)
{
try
{
var client = await _service.GetClientAsync(id);
if (client == null)
{
return NotFound();
}
return Ok(client);
}
catch (Exception ex)
{
_logger.LogError(ex, "Error getting client {Id}", id);
return StatusCode(500, new { message = ex.Message });
}
}
/// <summary>
/// 创建新的OAuth客户端
/// </summary>
/// <param name="dto">创建客户端所需的配置信息</param>
/// <returns>创建的OAuth客户端详情</returns>
/// <response code="201">成功创建客户端</response>
/// <response code="400">请求参数无效或客户端ID已存在</response>
/// <response code="500">服务器内部错误</response>
[HttpPost]
[Produces("application/json")]
[ProducesResponseType(typeof(OAuthClientDto), StatusCodes.Status201Created)]
[ProducesResponseType(typeof(object), StatusCodes.Status400BadRequest)]
[ProducesResponseType(typeof(object), StatusCodes.Status500InternalServerError)]
public async Task<ActionResult<OAuthClientDto>> CreateClient([FromBody] CreateClientDto dto)
{
try
{
var result = await _service.CreateClientAsync(dto);
return StatusCode(201, result);
}
catch (InvalidOperationException ex)
{
return BadRequest(new { message = ex.Message });
}
catch (Exception ex)
{
_logger.LogError(ex, "Error creating client");
return StatusCode(500, new { message = ex.Message });
}
}
/// <summary>
/// 为指定客户端生成新的密钥
/// </summary>
/// <param name="id">客户端唯一标识符</param>
/// <returns>包含新生成的客户端密钥信息</returns>
/// <response code="200">成功生成新密钥</response>
/// <response code="404">客户端不存在</response>
/// <response code="500">服务器内部错误</response>
[HttpPost("{id}/generate-secret")]
[Produces("application/json")]
[ProducesResponseType(typeof(object), StatusCodes.Status200OK)]
[ProducesResponseType(typeof(object), StatusCodes.Status404NotFound)]
[ProducesResponseType(typeof(object), StatusCodes.Status500InternalServerError)]
public async Task<ActionResult> GenerateSecret(string id)
{
try
{
var result = await _service.GenerateSecretAsync(id);
return Ok(result);
}
catch (KeyNotFoundException ex)
{
return NotFound(new { message = ex.Message });
}
catch (Exception ex)
{
_logger.LogError(ex, "Error generating secret for client {Id}", id);
return StatusCode(500, new { message = ex.Message });
}
}
/// <summary>
/// 删除指定的OAuth客户端
/// </summary>
/// <param name="id">客户端唯一标识符</param>
/// <returns>无内容响应</returns>
/// <response code="204">成功删除客户端</response>
/// <response code="404">客户端不存在</response>
/// <response code="500">服务器内部错误</response>
[HttpDelete("{id}")]
[ProducesResponseType(StatusCodes.Status204NoContent)]
[ProducesResponseType(typeof(object), StatusCodes.Status404NotFound)]
[ProducesResponseType(typeof(object), StatusCodes.Status500InternalServerError)]
public async Task<IActionResult> DeleteClient(string id)
{
try
{
await _service.DeleteClientAsync(id);
return NoContent();
}
catch (KeyNotFoundException ex)
{
return NotFound(new { message = ex.Message });
}
catch (Exception ex)
{
_logger.LogError(ex, "Error deleting client {Id}", id);
return StatusCode(500, new { message = ex.Message });
}
}
/// <summary>
/// 更新指定的OAuth客户端
/// </summary>
/// <param name="id">客户端唯一标识符</param>
/// <param name="dto">需要更新的客户端配置信息</param>
/// <returns>无内容响应</returns>
/// <response code="204">成功更新客户端</response>
/// <response code="404">客户端不存在</response>
/// <response code="500">服务器内部错误</response>
[HttpPut("{id}")]
[ProducesResponseType(StatusCodes.Status204NoContent)]
[ProducesResponseType(typeof(object), StatusCodes.Status404NotFound)]
[ProducesResponseType(typeof(object), StatusCodes.Status500InternalServerError)]
public async Task<IActionResult> UpdateClient(string id, [FromBody] UpdateClientDto dto)
{
try
{
await _service.UpdateClientAsync(id, dto);
return NoContent();
}
catch (KeyNotFoundException ex)
{
return NotFound(new { message = ex.Message });
}
catch (Exception ex)
{
_logger.LogError(ex, "Error updating client {Id}", id);
return StatusCode(500, new { message = ex.Message });
}
}
}