diff --git a/ArchiSteamFarm/ArchiSteamFarm.csproj b/ArchiSteamFarm/ArchiSteamFarm.csproj index 8280155183810..95541f9b9c55b 100644 --- a/ArchiSteamFarm/ArchiSteamFarm.csproj +++ b/ArchiSteamFarm/ArchiSteamFarm.csproj @@ -16,8 +16,7 @@ - - + diff --git a/ArchiSteamFarm/IPC/ArchiKestrel.cs b/ArchiSteamFarm/IPC/ArchiKestrel.cs index dadca2e52f699..d0677c518ae3f 100644 --- a/ArchiSteamFarm/IPC/ArchiKestrel.cs +++ b/ArchiSteamFarm/IPC/ArchiKestrel.cs @@ -36,7 +36,6 @@ using ArchiSteamFarm.IPC.Controllers.Api; using ArchiSteamFarm.IPC.Integration; using ArchiSteamFarm.IPC.OpenApi; -using ArchiSteamFarm.IPC.Swashbuckle; using ArchiSteamFarm.Localization; using ArchiSteamFarm.NLog; using ArchiSteamFarm.NLog.Targets; @@ -54,7 +53,6 @@ using Microsoft.Extensions.FileProviders; using Microsoft.Extensions.Logging; using Microsoft.Net.Http.Headers; -using Microsoft.OpenApi.Models; using NLog.Web; using IPNetwork = Microsoft.AspNetCore.HttpOverrides.IPNetwork; @@ -257,11 +255,7 @@ private static void ConfigureApp([SuppressMessage("ReSharper", "SuggestBaseTypeF app.MapControllers(); // Add support for OpenAPI, responsible for automatic API documentation generation, this should be on the end, once we're done with API - if (Program.UseOpenApi) { - app.MapOpenApi("/swagger/{documentName}/swagger.json"); - } else { - app.UseSwagger(); - } + app.MapOpenApi("/swagger/{documentName}/swagger.json"); // Add support for swagger UI, this should be after swagger, obviously app.UseSwaggerUI( @@ -338,71 +332,13 @@ private static void ConfigureServices([SuppressMessage("ReSharper", "SuggestBase } // Add support for OpenAPI, responsible for automatic API documentation generation - if (Program.UseOpenApi) { - services.AddOpenApi( - SharedInfo.ASF, static options => { - options.AddDocumentTransformer(); - options.AddOperationTransformer(); - options.AddSchemaTransformer(); - } - ); - } else { - services.AddSwaggerGen( - static options => { - options.AddSecurityDefinition( - nameof(GlobalConfig.IPCPassword), new OpenApiSecurityScheme { - Description = $"{nameof(GlobalConfig.IPCPassword)} authentication using request headers. Check {SharedInfo.ProjectURL}/wiki/IPC#authentication for more info.", - In = ParameterLocation.Header, - Name = ApiAuthenticationMiddleware.HeadersField, - Type = SecuritySchemeType.ApiKey - } - ); - - options.AddSecurityRequirement( - new OpenApiSecurityRequirement { - { - new OpenApiSecurityScheme { - Reference = new OpenApiReference { - Id = nameof(GlobalConfig.IPCPassword), - Type = ReferenceType.SecurityScheme - } - }, - - [] - } - } - ); - - // We require custom schema IDs due to conflicting type names, choosing the proper one is tricky as there is no good answer and any kind of convention has a potential to create conflict - // FullName and Name both do, ToString() for unknown to me reason doesn't, and I don't have courage to call our WebUtilities.GetUnifiedName() better than what .NET ships with (because it isn't) - // Let's use ToString() until we find a good enough reason to change it, also, the name must pass ^[a-zA-Z0-9.-_]+$ regex - options.CustomSchemaIds(static type => type.ToString().Replace('+', '-')); - - options.EnableAnnotations(true, true); - - options.SchemaFilter(); - options.SchemaFilter(); - options.SchemaFilter(); - - options.SwaggerDoc( - SharedInfo.ASF, new OpenApiInfo { - Contact = new OpenApiContact { - Name = SharedInfo.GithubRepo, - Url = new Uri(SharedInfo.ProjectURL) - }, - - License = new OpenApiLicense { - Name = SharedInfo.LicenseName, - Url = new Uri(SharedInfo.LicenseURL) - }, - - Title = $"{SharedInfo.AssemblyName} API", - Version = SharedInfo.Version.ToString() - } - ); - } - ); - } + services.AddOpenApi( + SharedInfo.ASF, static options => { + options.AddDocumentTransformer(); + options.AddOperationTransformer(); + options.AddSchemaTransformer(); + } + ); // Add support for optional health-checks services.AddHealthChecks(); diff --git a/ArchiSteamFarm/IPC/Swashbuckle/CustomAttributesSchemaFilter.cs b/ArchiSteamFarm/IPC/Swashbuckle/CustomAttributesSchemaFilter.cs deleted file mode 100644 index dd81a1a8ac40d..0000000000000 --- a/ArchiSteamFarm/IPC/Swashbuckle/CustomAttributesSchemaFilter.cs +++ /dev/null @@ -1,53 +0,0 @@ -// ---------------------------------------------------------------------------------------------- -// _ _ _ ____ _ _____ -// / \ _ __ ___ | |__ (_)/ ___| | |_ ___ __ _ _ __ ___ | ___|__ _ _ __ _ __ ___ -// / _ \ | '__|/ __|| '_ \ | |\___ \ | __|/ _ \ / _` || '_ ` _ \ | |_ / _` || '__|| '_ ` _ \ -// / ___ \ | | | (__ | | | || | ___) || |_| __/| (_| || | | | | || _|| (_| || | | | | | | | -// /_/ \_\|_| \___||_| |_||_||____/ \__|\___| \__,_||_| |_| |_||_| \__,_||_| |_| |_| |_| -// ---------------------------------------------------------------------------------------------- -// | -// Copyright 2015-2025 Łukasz "JustArchi" Domeradzki -// Contact: JustArchi@JustArchi.net -// | -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// | -// http://www.apache.org/licenses/LICENSE-2.0 -// | -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -using System; -using System.Reflection; -using ArchiSteamFarm.IPC.Integration; -using JetBrains.Annotations; -using Microsoft.OpenApi.Models; -using Swashbuckle.AspNetCore.SwaggerGen; - -namespace ArchiSteamFarm.IPC.Swashbuckle; - -[UsedImplicitly] -internal sealed class CustomAttributesSchemaFilter : ISchemaFilter { - public void Apply(OpenApiSchema schema, SchemaFilterContext context) { - ArgumentNullException.ThrowIfNull(schema); - ArgumentNullException.ThrowIfNull(context); - - ICustomAttributeProvider attributesProvider; - - if (context.MemberInfo != null) { - attributesProvider = context.MemberInfo; - } else if (context.ParameterInfo != null) { - attributesProvider = context.ParameterInfo; - } else { - return; - } - - foreach (CustomSwaggerAttribute customSwaggerAttribute in attributesProvider.GetCustomAttributes(typeof(CustomSwaggerAttribute), true)) { - customSwaggerAttribute.Apply(schema); - } - } -} diff --git a/ArchiSteamFarm/IPC/Swashbuckle/EnumSchemaFilter.cs b/ArchiSteamFarm/IPC/Swashbuckle/EnumSchemaFilter.cs deleted file mode 100644 index 8884bb51bddf7..0000000000000 --- a/ArchiSteamFarm/IPC/Swashbuckle/EnumSchemaFilter.cs +++ /dev/null @@ -1,107 +0,0 @@ -// ---------------------------------------------------------------------------------------------- -// _ _ _ ____ _ _____ -// / \ _ __ ___ | |__ (_)/ ___| | |_ ___ __ _ _ __ ___ | ___|__ _ _ __ _ __ ___ -// / _ \ | '__|/ __|| '_ \ | |\___ \ | __|/ _ \ / _` || '_ ` _ \ | |_ / _` || '__|| '_ ` _ \ -// / ___ \ | | | (__ | | | || | ___) || |_| __/| (_| || | | | | || _|| (_| || | | | | | | | -// /_/ \_\|_| \___||_| |_||_||____/ \__|\___| \__,_||_| |_| |_||_| \__,_||_| |_| |_| |_| -// ---------------------------------------------------------------------------------------------- -// | -// Copyright 2015-2025 Łukasz "JustArchi" Domeradzki -// Contact: JustArchi@JustArchi.net -// | -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// | -// http://www.apache.org/licenses/LICENSE-2.0 -// | -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -using System; -using System.Globalization; -using JetBrains.Annotations; -using Microsoft.OpenApi.Any; -using Microsoft.OpenApi.Extensions; -using Microsoft.OpenApi.Models; -using Swashbuckle.AspNetCore.SwaggerGen; - -namespace ArchiSteamFarm.IPC.Swashbuckle; - -[UsedImplicitly] -internal sealed class EnumSchemaFilter : ISchemaFilter { - public void Apply(OpenApiSchema schema, SchemaFilterContext context) { - ArgumentNullException.ThrowIfNull(schema); - ArgumentNullException.ThrowIfNull(context); - - if (context.Type is not { IsEnum: true }) { - return; - } - - if (context.Type.IsDefined(typeof(FlagsAttribute), false)) { - schema.Format = "flags"; - } - - OpenApiObject definition = new(); - - foreach (object? enumValue in context.Type.GetEnumValues()) { - if (enumValue == null) { - throw new InvalidOperationException(nameof(enumValue)); - } - - string? enumName = Enum.GetName(context.Type, enumValue); - - if (string.IsNullOrEmpty(enumName)) { - // Fallback - enumName = enumValue.ToString(); - - if (string.IsNullOrEmpty(enumName)) { - throw new InvalidOperationException(nameof(enumName)); - } - } - - if (definition.ContainsKey(enumName)) { - // This is possible if we have multiple names for the same enum value, we'll ignore additional ones - continue; - } - - IOpenApiPrimitive enumObject; - - if (TryCast(enumValue, out int intValue)) { - enumObject = new OpenApiInteger(intValue); - } else if (TryCast(enumValue, out long longValue)) { - enumObject = new OpenApiLong(longValue); - } else if (TryCast(enumValue, out ulong ulongValue)) { - // OpenApi spec doesn't support ulongs as of now - enumObject = new OpenApiString(ulongValue.ToString(CultureInfo.InvariantCulture)); - } else { - throw new InvalidOperationException(nameof(enumValue)); - } - - definition.Add(enumName, enumObject); - } - - schema.AddExtension("x-definition", definition); - } - - private static bool TryCast(object value, out T typedValue) where T : struct { - ArgumentNullException.ThrowIfNull(value); - - try { - typedValue = (T) Convert.ChangeType(value, typeof(T), CultureInfo.InvariantCulture); - - return true; - } catch (InvalidCastException) { - typedValue = default(T); - - return false; - } catch (OverflowException) { - typedValue = default(T); - - return false; - } - } -} diff --git a/ArchiSteamFarm/IPC/Swashbuckle/ReadOnlyFixesSchemaFilter.cs b/ArchiSteamFarm/IPC/Swashbuckle/ReadOnlyFixesSchemaFilter.cs deleted file mode 100644 index cdd418324e6a0..0000000000000 --- a/ArchiSteamFarm/IPC/Swashbuckle/ReadOnlyFixesSchemaFilter.cs +++ /dev/null @@ -1,42 +0,0 @@ -// ---------------------------------------------------------------------------------------------- -// _ _ _ ____ _ _____ -// / \ _ __ ___ | |__ (_)/ ___| | |_ ___ __ _ _ __ ___ | ___|__ _ _ __ _ __ ___ -// / _ \ | '__|/ __|| '_ \ | |\___ \ | __|/ _ \ / _` || '_ ` _ \ | |_ / _` || '__|| '_ ` _ \ -// / ___ \ | | | (__ | | | || | ___) || |_| __/| (_| || | | | | || _|| (_| || | | | | | | | -// /_/ \_\|_| \___||_| |_||_||____/ \__|\___| \__,_||_| |_| |_||_| \__,_||_| |_| |_| |_| -// ---------------------------------------------------------------------------------------------- -// | -// Copyright 2015-2025 Łukasz "JustArchi" Domeradzki -// Contact: JustArchi@JustArchi.net -// | -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// | -// http://www.apache.org/licenses/LICENSE-2.0 -// | -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -using System; -using System.Reflection; -using JetBrains.Annotations; -using Microsoft.OpenApi.Models; -using Swashbuckle.AspNetCore.SwaggerGen; - -namespace ArchiSteamFarm.IPC.Swashbuckle; - -[UsedImplicitly] -internal sealed class ReadOnlyFixesSchemaFilter : ISchemaFilter { - public void Apply(OpenApiSchema schema, SchemaFilterContext context) { - ArgumentNullException.ThrowIfNull(schema); - ArgumentNullException.ThrowIfNull(context); - - if (schema.ReadOnly && context.MemberInfo is PropertyInfo { CanWrite: true }) { - schema.ReadOnly = false; - } - } -} diff --git a/ArchiSteamFarm/Program.cs b/ArchiSteamFarm/Program.cs index 4124058182889..ddc247b5d333c 100644 --- a/ArchiSteamFarm/Program.cs +++ b/ArchiSteamFarm/Program.cs @@ -59,7 +59,6 @@ internal static class Program { internal static bool Service { get; private set; } internal static bool ShutdownSequenceInitialized { get; private set; } internal static bool SteamParentalGeneration { get; private set; } = true; - internal static bool UseOpenApi { get; private set; } private static readonly Dictionary RegisteredPosixSignals = new(); private static readonly TaskCompletionSource ShutdownResetEvent = new(); @@ -611,10 +610,6 @@ private static async Task ParseArgs(IReadOnlyCollection args) { case "--SYSTEM-REQUIRED" when noArgumentValueNext(): SystemRequired = true; - break; - case "--USE-OPENAPI" when noArgumentValueNext(): - UseOpenApi = true; - break; default: if (cryptKeyNext) { diff --git a/Directory.Packages.props b/Directory.Packages.props index 6937477f9449f..1e52fc4d18661 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -17,8 +17,7 @@ - - +