mirror of
https://github.com/JustArchiNET/ArchiSteamFarm
synced 2024-11-10 23:24:36 +00:00
Make custom swagger limitations more generic to use
This commit is contained in:
parent
ccc7a3ed32
commit
0060e76829
8 changed files with 205 additions and 115 deletions
|
@ -1,87 +0,0 @@
|
|||
// _ _ _ ____ _ _____
|
||||
// / \ _ __ ___ | |__ (_)/ ___| | |_ ___ __ _ _ __ ___ | ___|__ _ _ __ _ __ ___
|
||||
// / _ \ | '__|/ __|| '_ \ | |\___ \ | __|/ _ \ / _` || '_ ` _ \ | |_ / _` || '__|| '_ ` _ \
|
||||
// / ___ \ | | | (__ | | | || | ___) || |_| __/| (_| || | | | | || _|| (_| || | | | | | | |
|
||||
// /_/ \_\|_| \___||_| |_||_||____/ \__|\___| \__,_||_| |_| |_||_| \__,_||_| |_| |_| |_|
|
||||
// |
|
||||
// Copyright 2015-2021 Ł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.Linq;
|
||||
using ArchiSteamFarm.Steam.Storage;
|
||||
using JetBrains.Annotations;
|
||||
using Microsoft.OpenApi.Any;
|
||||
using Microsoft.OpenApi.Extensions;
|
||||
using Microsoft.OpenApi.Models;
|
||||
using SteamKit2;
|
||||
using Swashbuckle.AspNetCore.SwaggerGen;
|
||||
|
||||
namespace ArchiSteamFarm.IPC.Integration {
|
||||
[UsedImplicitly]
|
||||
internal sealed class BotConfigSchemaFilter : ISchemaFilter {
|
||||
public void Apply(OpenApiSchema schema, SchemaFilterContext context) {
|
||||
if (schema == null) {
|
||||
throw new ArgumentNullException(nameof(schema));
|
||||
}
|
||||
|
||||
if (context == null) {
|
||||
throw new ArgumentNullException(nameof(context));
|
||||
}
|
||||
|
||||
if (context.MemberInfo?.DeclaringType != typeof(BotConfig)) {
|
||||
return;
|
||||
}
|
||||
|
||||
OpenApiArray validValues;
|
||||
|
||||
switch (context.MemberInfo.Name) {
|
||||
case nameof(BotConfig.CompleteTypesToSend):
|
||||
validValues = new OpenApiArray();
|
||||
|
||||
validValues.AddRange(BotConfig.AllowedCompleteTypesToSend.Select(type => new OpenApiInteger((int) type)));
|
||||
|
||||
// Note, we'd love to add this to schema.Items, but since items are ref to the enum, it's not possible to add it that way
|
||||
schema.AddExtension("x-valid-values", validValues);
|
||||
|
||||
break;
|
||||
case nameof(BotConfig.GamesPlayedWhileIdle):
|
||||
schema.Items.Minimum = 1;
|
||||
schema.Items.Maximum = uint.MaxValue;
|
||||
|
||||
break;
|
||||
case nameof(BotConfig.SteamMasterClanID):
|
||||
schema.Minimum = new SteamID(1, EUniverse.Public, EAccountType.Clan);
|
||||
schema.Maximum = new SteamID(uint.MaxValue, EUniverse.Public, EAccountType.Clan);
|
||||
|
||||
validValues = new OpenApiArray();
|
||||
|
||||
validValues.Add(new OpenApiInteger(0));
|
||||
|
||||
schema.AddExtension("x-valid-values", validValues);
|
||||
|
||||
break;
|
||||
case nameof(BotConfig.SteamParentalCode):
|
||||
validValues = new OpenApiArray();
|
||||
|
||||
validValues.Add(new OpenApiString("0"));
|
||||
|
||||
schema.AddExtension("x-valid-values", validValues);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -20,17 +20,14 @@
|
|||
// limitations under the License.
|
||||
|
||||
using System;
|
||||
using ArchiSteamFarm.Storage;
|
||||
using System.Reflection;
|
||||
using JetBrains.Annotations;
|
||||
using Microsoft.OpenApi.Any;
|
||||
using Microsoft.OpenApi.Extensions;
|
||||
using Microsoft.OpenApi.Models;
|
||||
using SteamKit2;
|
||||
using Swashbuckle.AspNetCore.SwaggerGen;
|
||||
|
||||
namespace ArchiSteamFarm.IPC.Integration {
|
||||
[UsedImplicitly]
|
||||
internal sealed class GlobalConfigSchemaFilter : ISchemaFilter {
|
||||
internal sealed class CustomAttributesSchemaFilter : ISchemaFilter {
|
||||
public void Apply(OpenApiSchema schema, SchemaFilterContext context) {
|
||||
if (schema == null) {
|
||||
throw new ArgumentNullException(nameof(schema));
|
||||
|
@ -40,28 +37,13 @@ namespace ArchiSteamFarm.IPC.Integration {
|
|||
throw new ArgumentNullException(nameof(context));
|
||||
}
|
||||
|
||||
if (context.MemberInfo?.DeclaringType != typeof(GlobalConfig)) {
|
||||
if (context.MemberInfo == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
switch (context.MemberInfo.Name) {
|
||||
case nameof(GlobalConfig.Blacklist):
|
||||
schema.Items.Minimum = 1;
|
||||
schema.Items.Maximum = uint.MaxValue;
|
||||
|
||||
break;
|
||||
case nameof(GlobalConfig.SteamOwnerID):
|
||||
schema.Minimum = new SteamID(1, EUniverse.Public, EAccountType.Individual);
|
||||
schema.Maximum = new SteamID(uint.MaxValue, EUniverse.Public, EAccountType.Individual);
|
||||
|
||||
OpenApiArray validValues = new();
|
||||
|
||||
validValues.Add(new OpenApiInteger(0));
|
||||
|
||||
schema.AddExtension("x-valid-values", validValues);
|
||||
|
||||
break;
|
||||
}
|
||||
context.MemberInfo.GetCustomAttribute<SwaggerItemsMinMaxAttribute>()?.Apply(schema);
|
||||
context.MemberInfo.GetCustomAttribute<SwaggerSteamIdentifierAttribute>()?.Apply(schema);
|
||||
context.MemberInfo.GetCustomAttribute<SwaggerValidValuesAttribute>()?.Apply(schema);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,62 @@
|
|||
// _ _ _ ____ _ _____
|
||||
// / \ _ __ ___ | |__ (_)/ ___| | |_ ___ __ _ _ __ ___ | ___|__ _ _ __ _ __ ___
|
||||
// / _ \ | '__|/ __|| '_ \ | |\___ \ | __|/ _ \ / _` || '_ ` _ \ | |_ / _` || '__|| '_ ` _ \
|
||||
// / ___ \ | | | (__ | | | || | ___) || |_| __/| (_| || | | | | || _|| (_| || | | | | | | |
|
||||
// /_/ \_\|_| \___||_| |_||_||____/ \__|\___| \__,_||_| |_| |_||_| \__,_||_| |_| |_| |_|
|
||||
// |
|
||||
// Copyright 2015-2021 Ł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.ComponentModel.DataAnnotations;
|
||||
using JetBrains.Annotations;
|
||||
using Microsoft.OpenApi.Models;
|
||||
|
||||
namespace ArchiSteamFarm.IPC.Integration {
|
||||
[AttributeUsage(AttributeTargets.Field | AttributeTargets.Parameter | AttributeTargets.Property | AttributeTargets.Struct)]
|
||||
[PublicAPI]
|
||||
public sealed class SwaggerItemsMinMaxAttribute : ValidationAttribute {
|
||||
public uint MaximumUint {
|
||||
get => BackingMaximum.HasValue ? decimal.ToUInt32(BackingMaximum.Value) : default(uint);
|
||||
set => BackingMaximum = value;
|
||||
}
|
||||
|
||||
public uint MinimumUint {
|
||||
get => BackingMinimum.HasValue ? decimal.ToUInt32(BackingMinimum.Value) : default(uint);
|
||||
set => BackingMinimum = value;
|
||||
}
|
||||
|
||||
private decimal? BackingMaximum;
|
||||
private decimal? BackingMinimum;
|
||||
|
||||
public void Apply(OpenApiSchema schema) {
|
||||
if (schema == null) {
|
||||
throw new ArgumentNullException(nameof(schema));
|
||||
}
|
||||
|
||||
if (schema.Items == null) {
|
||||
throw new InvalidOperationException(nameof(schema.Items));
|
||||
}
|
||||
|
||||
if (BackingMinimum.HasValue) {
|
||||
schema.Items.Minimum = BackingMinimum.Value;
|
||||
}
|
||||
|
||||
if (BackingMaximum.HasValue) {
|
||||
schema.Items.Maximum = BackingMaximum.Value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,46 @@
|
|||
// _ _ _ ____ _ _____
|
||||
// / \ _ __ ___ | |__ (_)/ ___| | |_ ___ __ _ _ __ ___ | ___|__ _ _ __ _ __ ___
|
||||
// / _ \ | '__|/ __|| '_ \ | |\___ \ | __|/ _ \ / _` || '_ ` _ \ | |_ / _` || '__|| '_ ` _ \
|
||||
// / ___ \ | | | (__ | | | || | ___) || |_| __/| (_| || | | | | || _|| (_| || | | | | | | |
|
||||
// /_/ \_\|_| \___||_| |_||_||____/ \__|\___| \__,_||_| |_| |_||_| \__,_||_| |_| |_| |_|
|
||||
// |
|
||||
// Copyright 2015-2021 Ł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.ComponentModel.DataAnnotations;
|
||||
using JetBrains.Annotations;
|
||||
using Microsoft.OpenApi.Models;
|
||||
using SteamKit2;
|
||||
|
||||
namespace ArchiSteamFarm.IPC.Integration {
|
||||
[AttributeUsage(AttributeTargets.Field | AttributeTargets.Parameter | AttributeTargets.Property | AttributeTargets.Struct)]
|
||||
[PublicAPI]
|
||||
public sealed class SwaggerSteamIdentifierAttribute : ValidationAttribute {
|
||||
public EAccountType AccountType { get; set; } = EAccountType.Individual;
|
||||
public uint MaximumAccountID { get; set; } = uint.MaxValue;
|
||||
public uint MinimumAccountID { get; set; } = 1;
|
||||
public EUniverse Universe { get; set; } = EUniverse.Public;
|
||||
|
||||
public void Apply(OpenApiSchema schema) {
|
||||
if (schema == null) {
|
||||
throw new ArgumentNullException(nameof(schema));
|
||||
}
|
||||
|
||||
schema.Minimum = new SteamID(MinimumAccountID, Universe, AccountType);
|
||||
schema.Maximum = new SteamID(MaximumAccountID, Universe, AccountType);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,59 @@
|
|||
// _ _ _ ____ _ _____
|
||||
// / \ _ __ ___ | |__ (_)/ ___| | |_ ___ __ _ _ __ ___ | ___|__ _ _ __ _ __ ___
|
||||
// / _ \ | '__|/ __|| '_ \ | |\___ \ | __|/ _ \ / _` || '_ ` _ \ | |_ / _` || '__|| '_ ` _ \
|
||||
// / ___ \ | | | (__ | | | || | ___) || |_| __/| (_| || | | | | || _|| (_| || | | | | | | |
|
||||
// /_/ \_\|_| \___||_| |_||_||____/ \__|\___| \__,_||_| |_| |_||_| \__,_||_| |_| |_| |_|
|
||||
// |
|
||||
// Copyright 2015-2021 Ł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.ComponentModel.DataAnnotations;
|
||||
using System.Linq;
|
||||
using JetBrains.Annotations;
|
||||
using Microsoft.OpenApi.Any;
|
||||
using Microsoft.OpenApi.Extensions;
|
||||
using Microsoft.OpenApi.Models;
|
||||
|
||||
namespace ArchiSteamFarm.IPC.Integration {
|
||||
[AttributeUsage(AttributeTargets.Field | AttributeTargets.Parameter | AttributeTargets.Property | AttributeTargets.Struct)]
|
||||
[PublicAPI]
|
||||
public sealed class SwaggerValidValuesAttribute : ValidationAttribute {
|
||||
public int[]? ValidIntValues { get; set; }
|
||||
public string[]? ValidStringValues { get; set; }
|
||||
|
||||
public void Apply(OpenApiSchema schema) {
|
||||
if (schema == null) {
|
||||
throw new ArgumentNullException(nameof(schema));
|
||||
}
|
||||
|
||||
OpenApiArray validValues = new();
|
||||
|
||||
if (ValidIntValues != null) {
|
||||
validValues.AddRange(ValidIntValues.Select(type => new OpenApiInteger(type)));
|
||||
}
|
||||
|
||||
if (ValidStringValues != null) {
|
||||
validValues.AddRange(ValidStringValues.Select(type => new OpenApiString(type)));
|
||||
}
|
||||
|
||||
if (schema.Items is { Reference: null }) {
|
||||
schema.Items.AddExtension("x-valid-values", validValues);
|
||||
} else {
|
||||
schema.AddExtension("x-valid-values", validValues);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -217,9 +217,8 @@ namespace ArchiSteamFarm.IPC {
|
|||
options.CustomSchemaIds(type => type.GetUnifiedName());
|
||||
options.EnableAnnotations(true, true);
|
||||
|
||||
options.SchemaFilter<BotConfigSchemaFilter>();
|
||||
options.SchemaFilter<CustomAttributesSchemaFilter>();
|
||||
options.SchemaFilter<EnumSchemaFilter>();
|
||||
options.SchemaFilter<GlobalConfigSchemaFilter>();
|
||||
|
||||
options.SwaggerDoc(
|
||||
SharedInfo.ASF, new OpenApiInfo {
|
||||
|
|
|
@ -32,9 +32,11 @@ using System.ComponentModel.DataAnnotations;
|
|||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Threading.Tasks;
|
||||
using ArchiSteamFarm.Core;
|
||||
using ArchiSteamFarm.Helpers;
|
||||
using ArchiSteamFarm.IPC.Integration;
|
||||
using ArchiSteamFarm.Localization;
|
||||
using ArchiSteamFarm.Steam.Data;
|
||||
using ArchiSteamFarm.Steam.Integration;
|
||||
|
@ -156,6 +158,7 @@ namespace ArchiSteamFarm.Steam.Storage {
|
|||
public EBotBehaviour BotBehaviour { get; private set; } = DefaultBotBehaviour;
|
||||
|
||||
[JsonProperty(Required = Required.DisallowNull)]
|
||||
[SwaggerValidValues(ValidIntValues = new[] { (int) Asset.EType.TradingCard, (int) Asset.EType.FoilTradingCard })]
|
||||
public ImmutableHashSet<Asset.EType> CompleteTypesToSend { get; private set; } = DefaultCompleteTypesToSend;
|
||||
|
||||
[JsonProperty]
|
||||
|
@ -175,6 +178,7 @@ namespace ArchiSteamFarm.Steam.Storage {
|
|||
|
||||
[JsonProperty(Required = Required.DisallowNull)]
|
||||
[MaxLength(ArchiHandler.MaxGamesPlayedConcurrently)]
|
||||
[SwaggerItemsMinMax(MinimumUint = 1, MaximumUint = uint.MaxValue)]
|
||||
public ImmutableHashSet<uint> GamesPlayedWhileIdle { get; private set; } = DefaultGamesPlayedWhileIdle;
|
||||
|
||||
[JsonProperty(Required = Required.DisallowNull)]
|
||||
|
@ -223,11 +227,14 @@ namespace ArchiSteamFarm.Steam.Storage {
|
|||
}
|
||||
|
||||
[JsonProperty(Required = Required.DisallowNull)]
|
||||
[SwaggerSteamIdentifier(AccountType = EAccountType.Clan)]
|
||||
[SwaggerValidValues(ValidIntValues = new[] { 0 })]
|
||||
public ulong SteamMasterClanID { get; private set; } = DefaultSteamMasterClanID;
|
||||
|
||||
[JsonProperty]
|
||||
[MaxLength(SteamParentalCodeLength)]
|
||||
[MinLength(SteamParentalCodeLength)]
|
||||
[SwaggerValidValues(ValidStringValues = new[] { "0" })]
|
||||
public string? SteamParentalCode {
|
||||
get => BackingSteamParentalCode;
|
||||
|
||||
|
@ -387,8 +394,26 @@ namespace ArchiSteamFarm.Steam.Storage {
|
|||
return (false, string.Format(CultureInfo.CurrentCulture, Strings.ErrorConfigPropertyInvalid, nameof(LootableTypes), lootableType));
|
||||
}
|
||||
|
||||
foreach (Asset.EType completableType in CompleteTypesToSend.Where(completableType => !Enum.IsDefined(typeof(Asset.EType), completableType) || !AllowedCompleteTypesToSend.Contains(completableType))) {
|
||||
return (false, string.Format(CultureInfo.CurrentCulture, Strings.ErrorConfigPropertyInvalid, nameof(CompleteTypesToSend), completableType));
|
||||
HashSet<Asset.EType>? completeTypesToSendValidTypes = null;
|
||||
|
||||
foreach (Asset.EType completableType in CompleteTypesToSend) {
|
||||
if (!Enum.IsDefined(typeof(Asset.EType), completableType)) {
|
||||
return (false, string.Format(CultureInfo.CurrentCulture, Strings.ErrorConfigPropertyInvalid, nameof(CompleteTypesToSend), completableType));
|
||||
}
|
||||
|
||||
if (completeTypesToSendValidTypes == null) {
|
||||
SwaggerValidValuesAttribute? completeTypesToSendValidValues = typeof(BotConfig).GetProperty(nameof(CompleteTypesToSend))?.GetCustomAttribute<SwaggerValidValuesAttribute>();
|
||||
|
||||
if (completeTypesToSendValidValues?.ValidIntValues == null) {
|
||||
throw new InvalidOperationException(nameof(completeTypesToSendValidValues));
|
||||
}
|
||||
|
||||
completeTypesToSendValidTypes = completeTypesToSendValidValues.ValidIntValues.Select(value => (Asset.EType) value).ToHashSet();
|
||||
}
|
||||
|
||||
if (!completeTypesToSendValidTypes.Contains(completableType)) {
|
||||
return (false, string.Format(CultureInfo.CurrentCulture, Strings.ErrorConfigPropertyInvalid, nameof(CompleteTypesToSend), completableType));
|
||||
}
|
||||
}
|
||||
|
||||
foreach (Asset.EType matchableType in MatchableTypes.Where(matchableType => !Enum.IsDefined(typeof(Asset.EType), matchableType))) {
|
||||
|
|
|
@ -30,6 +30,7 @@ using System.Net;
|
|||
using System.Threading.Tasks;
|
||||
using ArchiSteamFarm.Core;
|
||||
using ArchiSteamFarm.Helpers;
|
||||
using ArchiSteamFarm.IPC.Integration;
|
||||
using ArchiSteamFarm.Localization;
|
||||
using ArchiSteamFarm.Steam.Integration;
|
||||
using JetBrains.Annotations;
|
||||
|
@ -178,6 +179,7 @@ namespace ArchiSteamFarm.Storage {
|
|||
public bool AutoRestart { get; private set; } = DefaultAutoRestart;
|
||||
|
||||
[JsonProperty(Required = Required.DisallowNull)]
|
||||
[SwaggerItemsMinMax(MinimumUint = 1, MaximumUint = uint.MaxValue)]
|
||||
public ImmutableHashSet<uint> Blacklist { get; private set; } = DefaultBlacklist;
|
||||
|
||||
[JsonProperty]
|
||||
|
@ -248,6 +250,8 @@ namespace ArchiSteamFarm.Storage {
|
|||
public string? SteamMessagePrefix { get; private set; } = DefaultSteamMessagePrefix;
|
||||
|
||||
[JsonProperty(Required = Required.DisallowNull)]
|
||||
[SwaggerSteamIdentifier]
|
||||
[SwaggerValidValues(ValidIntValues = new[] { 0 })]
|
||||
public ulong SteamOwnerID { get; private set; } = DefaultSteamOwnerID;
|
||||
|
||||
[JsonProperty(Required = Required.DisallowNull)]
|
||||
|
|
Loading…
Reference in a new issue