Skip to content

Commit

Permalink
fix(api): response type declaration
Browse files Browse the repository at this point in the history
  • Loading branch information
GZTimeWalker committed Dec 31, 2023
1 parent 8c2706f commit a0c4cd1
Show file tree
Hide file tree
Showing 3 changed files with 74 additions and 71 deletions.
62 changes: 31 additions & 31 deletions src/GZCTF/ClientApp/src/Api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1688,20 +1688,6 @@ export interface PostInfoModel {
time: string;
}

/** 签名校验 */
export interface SignatureVerifyModel {
/**
* 队伍 Token
* @minLength 1
*/
teamToken: string;
/**
* 比赛公钥,Base64 编码
* @minLength 1
*/
publicKey: string;
}

/** 验证码配置 */
export interface ClientCaptchaInfoModel {
/** 验证码类型 */
Expand Down Expand Up @@ -1739,6 +1725,20 @@ export interface TeamTransferModel {
newCaptainId: string;
}

/** 签名校验 */
export interface SignatureVerifyModel {
/**
* 队伍 Token
* @minLength 1
*/
teamToken: string;
/**
* 比赛公钥,Base64 编码
* @minLength 1
*/
publicKey: string;
}

import type {AxiosInstance, AxiosRequestConfig, AxiosResponse, HeadersDefaults, ResponseType} from "axios";
import axios from "axios";
import useSWR, {mutate, MutatorOptions, SWRConfiguration} from "swr";
Expand Down Expand Up @@ -4574,23 +4574,6 @@ export class Api<SecurityDataType extends unknown> extends HttpClient<SecurityDa
*/
mutateInfoGetPosts: (data?: PostInfoModel[] | Promise<PostInfoModel[]>, options?: MutatorOptions) =>
mutate<PostInfoModel[]>(`/api/posts`, data, options),

/**
* @description 进行签名校验
*
* @tags Info
* @name InfoVerifySignature
* @summary 进行签名校验
* @request GET:/api/verify
*/
infoVerifySignature: (data: SignatureVerifyModel, params: RequestParams = {}) =>
this.request<void, ProblemDetails>({
path: `/api/verify`,
method: "GET",
body: data,
type: ContentType.Json,
...params,
}),
};
proxy = {
/**
Expand Down Expand Up @@ -4893,6 +4876,23 @@ export class Api<SecurityDataType extends unknown> extends HttpClient<SecurityDa
format: "json",
...params,
}),

/**
* @description 进行签名校验
*
* @tags Team
* @name TeamVerifySignature
* @summary 进行签名校验
* @request POST:/api/team/verify
*/
teamVerifySignature: (data: SignatureVerifyModel, params: RequestParams = {}) =>
this.request<void, RequestResponse>({
path: `/api/team/verify`,
method: "POST",
body: data,
type: ContentType.Json,
...params,
}),
};
}

Expand Down
40 changes: 0 additions & 40 deletions src/GZCTF/Controllers/InfoController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Localization;
using Microsoft.Extensions.Options;
using Org.BouncyCastle.Crypto.Parameters;

namespace GZCTF.Controllers;

Expand Down Expand Up @@ -82,45 +81,6 @@ public async Task<IActionResult> GetPost(string id, CancellationToken token)
[ProducesResponseType(typeof(GlobalConfig), StatusCodes.Status200OK)]
public IActionResult GetGlobalConfig() => Ok(globalConfig.Value);

/// <summary>
/// 进行签名校验
/// </summary>
/// <remarks>
/// 进行签名校验
/// </remarks>
/// <response code="200">签名有效</response>
/// <response code="400">输入格式错误</response>
/// <response code="401">签名无效</response>
[HttpGet("Verify")]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
public IActionResult VerifySignature(SignatureVerifyModel model)
{
// Token: <id>:<signature>
// Data: $"GZCTF_TEAM_{team.Id}"

var pk = Codec.Base64.DecodeToBytes(model.PublicKey);

if (pk.Length != 32)
return BadRequest(new RequestResponse(localizer[nameof(Resources.Program.Signature_Invalid)]));

var pos = model.TeamToken.IndexOf(':');

if (pos == -1)
return BadRequest(new RequestResponse(localizer[nameof(Resources.Program.Signature_Invalid)]));

var id = model.TeamToken[..pos];
var sign = model.TeamToken[(pos + 1)..];

Ed25519PublicKeyParameters publicKey = new(pk, 0);

if (DigitalSignature.VerifySignature($"GZCTF_TEAM_{id}", sign, publicKey, SignAlgorithm.Ed25519))
return Ok();

return Unauthorized(new RequestResponse(localizer[nameof(Resources.Program.Signature_Invalid)]));
}

/// <summary>
/// 获取 Captcha 配置
/// </summary>
Expand Down
43 changes: 43 additions & 0 deletions src/GZCTF/Controllers/TeamController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Storage;
using Microsoft.Extensions.Localization;
using Org.BouncyCastle.Crypto.Parameters;

namespace GZCTF.Controllers;

Expand Down Expand Up @@ -550,4 +551,46 @@ public async Task<IActionResult> DeleteTeam(int id, CancellationToken token)

return Ok();
}

/// <summary>
/// 进行签名校验
/// </summary>
/// <remarks>
/// 进行签名校验
/// </remarks>
/// <response code="200">签名有效</response>
/// <response code="400">输入格式错误</response>
/// <response code="401">签名无效</response>
[HttpPost("Verify")]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(typeof(RequestResponse), StatusCodes.Status400BadRequest)]
[ProducesResponseType(typeof(RequestResponse), StatusCodes.Status401Unauthorized)]
public IActionResult VerifySignature(SignatureVerifyModel model)
{
// Token: <id>:<signature>
// Data: $"GZCTF_TEAM_{team.Id}"

var pk = Codec.Base64.DecodeToBytes(model.PublicKey);

if (pk.Length != 32)
return BadRequest(new RequestResponse(localizer[nameof(Resources.Program.Signature_Invalid)]));

var pos = model.TeamToken.IndexOf(':');

if (pos == -1)
return BadRequest(new RequestResponse(localizer[nameof(Resources.Program.Signature_Invalid)]));

var id = model.TeamToken[..pos];
var sign = model.TeamToken[(pos + 1)..];

if (!int.TryParse(id, out _) || string.IsNullOrEmpty(sign))
return BadRequest(new RequestResponse(localizer[nameof(Resources.Program.Signature_Invalid)]));

Ed25519PublicKeyParameters publicKey = new(pk, 0);

if (DigitalSignature.VerifySignature($"GZCTF_TEAM_{id}", sign, publicKey, SignAlgorithm.Ed25519))
return Ok();

return Unauthorized(new RequestResponse(localizer[nameof(Resources.Program.Signature_Invalid)]));
}
}

0 comments on commit a0c4cd1

Please sign in to comment.