diff --git a/CHANGELOG.md b/CHANGELOG.md index eaade2c2a..9bf0c96cd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,9 +7,14 @@ All notable changes to [**GZCTF**](https://github.com/GZTimeWalker/GZCTF) will b ### 🐛 Bug Fixes +- cannot list captured traffic - ([43961e](https://github.com/GZTimeWalker/GZCTF/commit/43961e)) by **GZTime** - cannot enable traffic capture for static container challenge - ([dc8972](https://github.com/GZTimeWalker/GZCTF/commit/dc8972)) by **GZTime** - cannot empty post summary & content - ([3feb43](https://github.com/GZTimeWalker/GZCTF/commit/3feb43)) by **GZTime** +### ⚙️ Miscellaneous Tasks + +- format code - ([9d0da3](https://github.com/GZTimeWalker/GZCTF/commit/9d0da3)) by **GZTime** + --- ## [0.17.4](https://github.com/GZTimeWalker/GZCTF/compare/v0.17.3..v0.17.4) - 2023-09-22 diff --git a/src/GZCTF/Controllers/GameController.cs b/src/GZCTF/Controllers/GameController.cs index 051c451c3..9c71d244f 100644 --- a/src/GZCTF/Controllers/GameController.cs +++ b/src/GZCTF/Controllers/GameController.cs @@ -887,13 +887,13 @@ public async Task CreateContainer([FromRoute] int id, [FromRoute] return await instanceRepository.CreateContainer(instance, context.Participation!.Team, context.User!, context.Game!.ContainerCountLimit, token) switch - { - null or (TaskStatus.Failed, null) => BadRequest(new RequestResponse("题目创建容器失败")), - (TaskStatus.Denied, null) => BadRequest( - new RequestResponse($"队伍容器数目不能超过 {context.Game.ContainerCountLimit}")), - (TaskStatus.Success, var x) => Ok(ContainerInfoModel.FromContainer(x!)), - _ => throw new NotImplementedException() - }; + { + null or (TaskStatus.Failed, null) => BadRequest(new RequestResponse("题目创建容器失败")), + (TaskStatus.Denied, null) => BadRequest( + new RequestResponse($"队伍容器数目不能超过 {context.Game.ContainerCountLimit}")), + (TaskStatus.Success, var x) => Ok(ContainerInfoModel.FromContainer(x!)), + _ => throw new NotImplementedException() + }; } /// diff --git a/src/GZCTF/Middlewares/RateLimiter.cs b/src/GZCTF/Middlewares/RateLimiter.cs index fbcfe39ea..1cd87922b 100644 --- a/src/GZCTF/Middlewares/RateLimiter.cs +++ b/src/GZCTF/Middlewares/RateLimiter.cs @@ -37,29 +37,14 @@ public enum LimitPolicy public static RateLimiterOptions GetRateLimiterOptions() => new RateLimiterOptions + { + RejectionStatusCode = StatusCodes.Status429TooManyRequests, + GlobalLimiter = PartitionedRateLimiter.Create(context => { - RejectionStatusCode = StatusCodes.Status429TooManyRequests, - GlobalLimiter = PartitionedRateLimiter.Create(context => - { - var userId = context?.User.FindFirstValue(ClaimTypes.NameIdentifier); + var userId = context?.User.FindFirstValue(ClaimTypes.NameIdentifier); - if (userId is not null) - return RateLimitPartition.GetSlidingWindowLimiter(userId, - key => new() - { - PermitLimit = 150, - Window = TimeSpan.FromMinutes(1), - QueueLimit = 60, - QueueProcessingOrder = QueueProcessingOrder.OldestFirst, - SegmentsPerWindow = 6 - }); - - IPAddress? address = context?.Connection?.RemoteIpAddress; - - if (address is null || IPAddress.IsLoopback(address)) - return RateLimitPartition.GetNoLimiter(IPAddress.Loopback.ToString()); - - return RateLimitPartition.GetSlidingWindowLimiter(address.ToString(), + if (userId is not null) + return RateLimitPartition.GetSlidingWindowLimiter(userId, key => new() { PermitLimit = 150, @@ -68,24 +53,39 @@ public static RateLimiterOptions GetRateLimiterOptions() => QueueProcessingOrder = QueueProcessingOrder.OldestFirst, SegmentsPerWindow = 6 }); - }), - OnRejected = async (context, cancellationToken) => - { - context.HttpContext.Response.StatusCode = StatusCodes.Status429TooManyRequests; - context.HttpContext.Response.ContentType = MediaTypeNames.Application.Json; - var afterSec = (int)TimeSpan.FromMinutes(1).TotalSeconds; + IPAddress? address = context?.Connection?.RemoteIpAddress; + + if (address is null || IPAddress.IsLoopback(address)) + return RateLimitPartition.GetNoLimiter(IPAddress.Loopback.ToString()); + + return RateLimitPartition.GetSlidingWindowLimiter(address.ToString(), + key => new() + { + PermitLimit = 150, + Window = TimeSpan.FromMinutes(1), + QueueLimit = 60, + QueueProcessingOrder = QueueProcessingOrder.OldestFirst, + SegmentsPerWindow = 6 + }); + }), + OnRejected = async (context, cancellationToken) => + { + context.HttpContext.Response.StatusCode = StatusCodes.Status429TooManyRequests; + context.HttpContext.Response.ContentType = MediaTypeNames.Application.Json; + + var afterSec = (int)TimeSpan.FromMinutes(1).TotalSeconds; - if (context.Lease.TryGetMetadata(MetadataName.RetryAfter, out TimeSpan retryAfter)) - afterSec = (int)retryAfter.TotalSeconds; + if (context.Lease.TryGetMetadata(MetadataName.RetryAfter, out TimeSpan retryAfter)) + afterSec = (int)retryAfter.TotalSeconds; - context.HttpContext.Response.Headers.RetryAfter = afterSec.ToString(NumberFormatInfo.InvariantInfo); - await context.HttpContext.Response.WriteAsJsonAsync( - new RequestResponse($"Too many requests, retry after {afterSec} seconds.", - StatusCodes.Status429TooManyRequests - ), cancellationToken); - } + context.HttpContext.Response.Headers.RetryAfter = afterSec.ToString(NumberFormatInfo.InvariantInfo); + await context.HttpContext.Response.WriteAsJsonAsync( + new RequestResponse($"Too many requests, retry after {afterSec} seconds.", + StatusCodes.Status429TooManyRequests + ), cancellationToken); } + } .AddConcurrencyLimiter(nameof(LimitPolicy.Concurrency), options => { options.PermitLimit = 1; diff --git a/src/GZCTF/Models/Request/Edit/ChallengeEditDetailModel.cs b/src/GZCTF/Models/Request/Edit/ChallengeEditDetailModel.cs index d7810d69a..c0c746c5e 100644 --- a/src/GZCTF/Models/Request/Edit/ChallengeEditDetailModel.cs +++ b/src/GZCTF/Models/Request/Edit/ChallengeEditDetailModel.cs @@ -105,7 +105,7 @@ internal static ChallengeEditDetailModel FromChallenge(Challenge chal) => Attachment = chal.Attachment, TestContainer = chal.TestContainer is null ? null : ContainerInfoModel.FromContainer(chal.TestContainer), Flags = (from flag in chal.Flags - select FlagInfoModel.FromFlagContext(flag)) + select FlagInfoModel.FromFlagContext(flag)) .ToArray() }; diff --git a/src/GZCTF/Program.cs b/src/GZCTF/Program.cs index de4eb9eea..dce9549c8 100644 --- a/src/GZCTF/Program.cs +++ b/src/GZCTF/Program.cs @@ -355,11 +355,12 @@ public static IActionResult InvalidModelStateHandler(ActionContext context) if (context.ModelState.ErrorCount <= 0) return new JsonResult( - new RequestResponse(errors is not null && errors.Length > 0 ? errors : "校验失败,请检查输入。")) { StatusCode = 400 }; + new RequestResponse(errors is not null && errors.Length > 0 ? errors : "校验失败,请检查输入。")) + { StatusCode = 400 }; errors = (from val in context.ModelState.Values - where val.Errors.Count > 0 - select val.Errors.FirstOrDefault()?.ErrorMessage).FirstOrDefault(); + where val.Errors.Count > 0 + select val.Errors.FirstOrDefault()?.ErrorMessage).FirstOrDefault(); return new JsonResult(new RequestResponse(errors is not null && errors.Length > 0 ? errors : "校验失败,请检查输入。")) { StatusCode = 400 }; } diff --git a/src/GZCTF/Repositories/ChallengeRepository.cs b/src/GZCTF/Repositories/ChallengeRepository.cs index 0f2fab007..b96209262 100644 --- a/src/GZCTF/Repositories/ChallengeRepository.cs +++ b/src/GZCTF/Repositories/ChallengeRepository.cs @@ -104,7 +104,9 @@ public async Task UpdateAttachment(Challenge challenge, AttachmentCreateModel mo ? null : new() { - Type = model.AttachmentType, LocalFile = await fileRepository.GetFileByHash(model.FileHash, token), RemoteUrl = model.RemoteUrl + Type = model.AttachmentType, + LocalFile = await fileRepository.GetFileByHash(model.FileHash, token), + RemoteUrl = model.RemoteUrl }; await DeleteAllAttachment(challenge, false, token); diff --git a/src/GZCTF/Repositories/GameRepository.cs b/src/GZCTF/Repositories/GameRepository.cs index 96a5ff517..b8fa331b7 100644 --- a/src/GZCTF/Repositories/GameRepository.cs +++ b/src/GZCTF/Repositories/GameRepository.cs @@ -326,7 +326,8 @@ static IEnumerable GenTimeLine(IEnumerable items) score += i.Score; return new TimeLine { - Score = score, Time = i.SubmitTimeUTC!.Value // 此处不为 null + Score = score, + Time = i.SubmitTimeUTC!.Value // 此处不为 null }; }); } diff --git a/src/GZCTF/Services/ConfigService.cs b/src/GZCTF/Services/ConfigService.cs index 69a265286..d7858782e 100644 --- a/src/GZCTF/Services/ConfigService.cs +++ b/src/GZCTF/Services/ConfigService.cs @@ -78,7 +78,8 @@ async Task SaveConfigInternal(HashSet configs, CancellationToken token = static bool IsArrayLikeInterface(Type type) { - if (!type.IsInterface || !type.IsConstructedGenericType) return false; + if (!type.IsInterface || !type.IsConstructedGenericType) + return false; Type genericTypeDefinition = type.GetGenericTypeDefinition(); return genericTypeDefinition == typeof(IEnumerable<>) diff --git a/src/GZCTF/Services/Container/Manager/DockerManager.cs b/src/GZCTF/Services/Container/Manager/DockerManager.cs index cae3bb272..43dd2d1ea 100644 --- a/src/GZCTF/Services/Container/Manager/DockerManager.cs +++ b/src/GZCTF/Services/Container/Manager/DockerManager.cs @@ -170,7 +170,9 @@ CreateContainerParameters GetCreateContainerParameters(ContainerConfig config) = Env = config.Flag is null ? Array.Empty() : new[] { $"GZCTF_FLAG={config.Flag}" }, HostConfig = new() { - Memory = config.MemoryLimit * 1024 * 1024, CPUPercent = config.CPUCount * 10, NetworkMode = _meta.Config.ChallengeNetwork + Memory = config.MemoryLimit * 1024 * 1024, + CPUPercent = config.CPUCount * 10, + NetworkMode = _meta.Config.ChallengeNetwork } }; } \ No newline at end of file diff --git a/src/GZCTF/Services/Container/Manager/K8sManager.cs b/src/GZCTF/Services/Container/Manager/K8sManager.cs index 8bd76ec57..160ab222e 100644 --- a/src/GZCTF/Services/Container/Manager/K8sManager.cs +++ b/src/GZCTF/Services/Container/Manager/K8sManager.cs @@ -48,7 +48,9 @@ public K8sManager(IContainerProvider provider, ILogger< NamespaceProperty = options.Namespace, Labels = new Dictionary { - ["ctf.gzti.me/ResourceId"] = name, ["ctf.gzti.me/TeamId"] = config.TeamId, ["ctf.gzti.me/UserId"] = config.UserId + ["ctf.gzti.me/ResourceId"] = name, + ["ctf.gzti.me/TeamId"] = config.TeamId, + ["ctf.gzti.me/UserId"] = config.UserId } }, Spec = new V1PodSpec diff --git a/src/GZCTF/Services/Container/Manager/SwarmManager.cs b/src/GZCTF/Services/Container/Manager/SwarmManager.cs index 32c84beca..9a4b95f69 100644 --- a/src/GZCTF/Services/Container/Manager/SwarmManager.cs +++ b/src/GZCTF/Services/Container/Manager/SwarmManager.cs @@ -63,7 +63,7 @@ public async Task DestroyContainerAsync(Models.Data.Container container, Cancell ServiceCreateParameters parameters = GetServiceCreateParameters(config); var retry = 0; ServiceCreateResponse? serviceRes; - CreateContainer: + CreateContainer: try { serviceRes = await _client.Swarm.CreateServiceAsync(parameters, token); diff --git a/src/GZCTF/Services/Container/Provider/DockerProvider.cs b/src/GZCTF/Services/Container/Provider/DockerProvider.cs index 85447b16e..8f86cfee7 100644 --- a/src/GZCTF/Services/Container/Provider/DockerProvider.cs +++ b/src/GZCTF/Services/Container/Provider/DockerProvider.cs @@ -37,7 +37,9 @@ public DockerProvider(IOptions options, IOptions registry, IOptions> type in scoreboard.Challenges) - foreach (ChallengeInfo chall in type.Value) - { - ICell? cell = row.CreateCell(colIndex++); - cell.SetCellValue(chall.Title); - cell.CellStyle = style; - challIds.Add(chall.Id); - } + foreach (ChallengeInfo chall in type.Value) + { + ICell? cell = row.CreateCell(colIndex++); + cell.SetCellValue(chall.Title); + cell.CellStyle = style; + challIds.Add(chall.Id); + } return challIds.ToArray(); } diff --git a/src/GZCTF/Utils/FilePath.cs b/src/GZCTF/Utils/FilePath.cs index 9740a9b11..9d0d6d4d2 100644 --- a/src/GZCTF/Utils/FilePath.cs +++ b/src/GZCTF/Utils/FilePath.cs @@ -20,7 +20,8 @@ internal static void EnsureDirs() foreach (DirType type in Enum.GetValues()) { var path = Path.Combine(Base, type.ToString().ToLower()); - if (!Directory.Exists(path)) Directory.CreateDirectory(path); + if (!Directory.Exists(path)) + Directory.CreateDirectory(path); } }