Skip to content
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/sonarcloud.yml
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ jobs:
CoverletOutputFormat: "opencover" # https://github.com/microsoft/vstest/issues/4014#issuecomment-1307913682
shell: pwsh
run: |
./.sonar/scanner/dotnet-sonarscanner begin /k:"microsoft_OpenApi.ApiManifest" /o:"microsoft" /d:sonar.login="${{ secrets.SONAR_TOKEN }}" /d:sonar.host.url="https://sonarcloud.io" /d:sonar.cs.opencover.reportsPaths="src/tests/**/coverage.opencover.xml"
./.sonar/scanner/dotnet-sonarscanner begin /k:"microsoft_OpenApi.ApiManifest" /o:"microsoft" /d:sonar.login="${{ secrets.SONAR_TOKEN }}" /d:sonar.host.url="https://sonarcloud.io" /d:sonar.cs.opencover.reportsPaths="tests/**/coverage.opencover.xml"
dotnet build
dotnet test apimanifest.sln --no-build --verbosity normal /p:CollectCoverage=true /p:CoverletOutputFormat=opencover
./.sonar/scanner/dotnet-sonarscanner end /d:sonar.login="${{ secrets.SONAR_TOKEN }}"
29 changes: 17 additions & 12 deletions apimanifest.sln
Original file line number Diff line number Diff line change
Expand Up @@ -5,27 +5,22 @@ VisualStudioVersion = 17.0.31903.59
MinimumVisualStudioVersion = 10.0.40219.1
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{39495B7F-9E1F-4DBE-AAA1-C9C9620675AA}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "tests", "src\tests\tests.csproj", "{02EFB22C-FF50-4D4C-8F83-A394597E11E6}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "apimanifest", "src\lib\apimanifest.csproj", "{3B4ACF87-6364-48A2-94B8-0EB3201D922E}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "apimanifest", "src\lib\apimanifest.csproj", "{3B4ACF87-6364-48A2-94B8-0EB3201D922E}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "tool", "src\tool\tool.csproj", "{DCFFC5B9-253A-4BFE-9CBE-0DAAE822E3EB}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "tool", "src\tool\tool.csproj", "{DCFFC5B9-253A-4BFE-9CBE-0DAAE822E3EB}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "benchmark", "src\benchmark\benchmark.csproj", "{24B7722C-4FE9-4B52-9AA3-5D2FBCDA2DFA}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "benchmark", "src\benchmark\benchmark.csproj", "{24B7722C-4FE9-4B52-9AA3-5D2FBCDA2DFA}"
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{13E6B8EB-7EA6-4CAD-A9A2-3473307EB30F}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ApiManifest.Tests", "tests\ApiManifest.Tests\ApiManifest.Tests.csproj", "{10411C2B-C1AC-44FC-AF46-E0264438E797}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{02EFB22C-FF50-4D4C-8F83-A394597E11E6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{02EFB22C-FF50-4D4C-8F83-A394597E11E6}.Debug|Any CPU.Build.0 = Debug|Any CPU
{02EFB22C-FF50-4D4C-8F83-A394597E11E6}.Release|Any CPU.ActiveCfg = Release|Any CPU
{02EFB22C-FF50-4D4C-8F83-A394597E11E6}.Release|Any CPU.Build.0 = Release|Any CPU
{3B4ACF87-6364-48A2-94B8-0EB3201D922E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{3B4ACF87-6364-48A2-94B8-0EB3201D922E}.Debug|Any CPU.Build.0 = Debug|Any CPU
{3B4ACF87-6364-48A2-94B8-0EB3201D922E}.Release|Any CPU.ActiveCfg = Release|Any CPU
Expand All @@ -38,11 +33,21 @@ Global
{24B7722C-4FE9-4B52-9AA3-5D2FBCDA2DFA}.Debug|Any CPU.Build.0 = Debug|Any CPU
{24B7722C-4FE9-4B52-9AA3-5D2FBCDA2DFA}.Release|Any CPU.ActiveCfg = Release|Any CPU
{24B7722C-4FE9-4B52-9AA3-5D2FBCDA2DFA}.Release|Any CPU.Build.0 = Release|Any CPU
{10411C2B-C1AC-44FC-AF46-E0264438E797}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{10411C2B-C1AC-44FC-AF46-E0264438E797}.Debug|Any CPU.Build.0 = Debug|Any CPU
{10411C2B-C1AC-44FC-AF46-E0264438E797}.Release|Any CPU.ActiveCfg = Release|Any CPU
{10411C2B-C1AC-44FC-AF46-E0264438E797}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{02EFB22C-FF50-4D4C-8F83-A394597E11E6} = {39495B7F-9E1F-4DBE-AAA1-C9C9620675AA}
{3B4ACF87-6364-48A2-94B8-0EB3201D922E} = {39495B7F-9E1F-4DBE-AAA1-C9C9620675AA}
{DCFFC5B9-253A-4BFE-9CBE-0DAAE822E3EB} = {39495B7F-9E1F-4DBE-AAA1-C9C9620675AA}
{24B7722C-4FE9-4B52-9AA3-5D2FBCDA2DFA} = {39495B7F-9E1F-4DBE-AAA1-C9C9620675AA}
{10411C2B-C1AC-44FC-AF46-E0264438E797} = {13E6B8EB-7EA6-4CAD-A9A2-3473307EB30F}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {6A91121B-DC65-413C-8635-B32B30C30A6F}
EndGlobalSection
EndGlobal
5 changes: 4 additions & 1 deletion src/lib/Extensions.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license.

using System.Text.Json;
using System.Text.Json.Nodes;

Expand All @@ -14,7 +17,7 @@ public static Extensions Load(JsonElement value)
{
if (property.Value.ValueKind != JsonValueKind.Null)
{
var extensionValue = JsonSerializer.Deserialize<JsonObject>(property.Value.GetRawText());
var extensionValue = JsonSerializer.Deserialize<JsonNode>(property.Value.GetRawText());
extensions.Add(property.Name, extensionValue);
}
}
Expand Down
3 changes: 3 additions & 0 deletions src/lib/OpenAI/Api.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@

// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license.

using System.Text.Json;

namespace Microsoft.OpenApi.ApiManifest.OpenAI;
Expand Down
47 changes: 47 additions & 0 deletions src/lib/OpenAI/Auth/BaseManifestAuth.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license.

using Microsoft.OpenApi.ApiManifest.OpenAI.Auth;
using System.Text.Json;

namespace Microsoft.OpenApi.ApiManifest.OpenAI;

public abstract class BaseManifestAuth
{
public string? Type { get; set; }
public string? Instructions { get; set; }

public static BaseManifestAuth? Load(JsonElement value)
{
BaseManifestAuth? auth = null;

switch (value.GetProperty("type").GetString())
{
case "none":
auth = new ManifestNoAuth();
ParsingHelpers.ParseMap(value, (ManifestNoAuth)auth, ManifestNoAuth.handlers);
break;
case "user_http":
var authorizationType = value.GetProperty("authorization_type").GetString();
auth = new ManifestUserHttpAuth(authorizationType);
ParsingHelpers.ParseMap(value, (ManifestUserHttpAuth)auth, ManifestUserHttpAuth.handlers);
break;
case "service_http":
var verificationTokens = value.GetProperty("verification_tokens");
auth = new ManifestServiceHttpAuth(VerificationTokens.Load(verificationTokens));
ParsingHelpers.ParseMap(value, (ManifestServiceHttpAuth)auth, ManifestServiceHttpAuth.handlers);
break;
case "oauth":
auth = new ManifestOAuthAuth();
ParsingHelpers.ParseMap(value, (ManifestOAuthAuth)auth, ManifestOAuthAuth.handlers);
break;
}

return auth;
}

// Create handlers FixedFieldMap for ManifestAuth

public virtual void Write(Utf8JsonWriter writer) { }

}
28 changes: 28 additions & 0 deletions src/lib/OpenAI/Auth/ManifestNoAuth.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license.

using System.Text.Json;

namespace Microsoft.OpenApi.ApiManifest.OpenAI;

public class ManifestNoAuth : BaseManifestAuth
{
public ManifestNoAuth()
{
Type = "none";
}

internal static readonly FixedFieldMap<ManifestNoAuth> handlers = new()
{
{ "type", (o,v) => {o.Type = v.GetString(); } },
{ "instructions", (o,v) => {o.Instructions = v.GetString(); } },
};

public override void Write(Utf8JsonWriter writer)
{
writer.WriteStartObject();
writer.WriteString("type", Type);
if (Instructions != null) writer.WriteString("instructions", Instructions);
writer.WriteEndObject();
}
}
49 changes: 49 additions & 0 deletions src/lib/OpenAI/Auth/ManifestOAuthAuth.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license.

using Microsoft.OpenApi.ApiManifest.OpenAI.Auth;
using System.Text.Json;

namespace Microsoft.OpenApi.ApiManifest.OpenAI;

public class ManifestOAuthAuth : BaseManifestAuth
{
public string? ClientUrl { get; set; }
public string? Scope { get; set; }
public string? AuthorizationUrl { get; set; }
public string? AuthorizationContentType { get; set; }
public VerificationTokens VerificationTokens { get; set; } = new VerificationTokens();

public ManifestOAuthAuth()
{
Type = "oauth";
}
internal static readonly FixedFieldMap<ManifestOAuthAuth> handlers = new()
{
{ "type", (o,v) => {o.Type = v.GetString(); } },
{ "instructions", (o,v) => {o.Instructions = v.GetString(); } },
{ "client_url", (o,v) => {o.ClientUrl = v.GetString(); } },
{ "scope", (o,v) => {o.Scope = v.GetString(); } },
{ "authorization_url", (o,v) => {o.AuthorizationUrl = v.GetString(); } },
{ "authorization_content_type", (o,v) => {o.AuthorizationContentType = v.GetString(); } },
{ "verification_tokens", (o,v) => { o.VerificationTokens = VerificationTokens.Load(v); } },
};

public override void Write(Utf8JsonWriter writer)
{
writer.WriteStartObject();
writer.WriteString("type", Type);

if (Instructions != null) writer.WriteString("instructions", Instructions);
if (ClientUrl != null) writer.WriteString("client_url", ClientUrl);
if (Scope != null) writer.WriteString("scope", Scope);
if (AuthorizationUrl != null) writer.WriteString("authorization_url", AuthorizationUrl);
if (AuthorizationContentType != null) writer.WriteString("authorization_content_type", AuthorizationContentType);
if (VerificationTokens.Any())
{
writer.WritePropertyName("verification_tokens");
VerificationTokens.Write(writer);
}
writer.WriteEndObject();
}
}
43 changes: 43 additions & 0 deletions src/lib/OpenAI/Auth/ManifestServiceHttpAuth.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license.

using Microsoft.OpenApi.ApiManifest.OpenAI.Auth;
using System.Text.Json;

namespace Microsoft.OpenApi.ApiManifest.OpenAI;

public class ManifestServiceHttpAuth : BaseManifestAuth
{
public string? AuthorizationType { get; set; }
public VerificationTokens VerificationTokens { get; set; }
public ManifestServiceHttpAuth(VerificationTokens verificationTokens)
{
if (verificationTokens == null || !verificationTokens.Any())
{
// Reference: https://platform.openai.com/docs/plugins/authentication/service-level
throw new ArgumentException($"{nameof(verificationTokens)} must be have at least one verification token.");
}
Type = "service_http";
AuthorizationType = "bearer";
VerificationTokens = verificationTokens;
}

internal static readonly FixedFieldMap<ManifestServiceHttpAuth> handlers = new()
{
{ "type", (o,v) => {o.Type = v.GetString(); } },
{ "authorization_type", (o,v) => {o.AuthorizationType = v.GetString(); } },
{ "instructions", (o,v) => {o.Instructions = v.GetString(); } },
{ "verification_tokens", (o, v) => { o.VerificationTokens = VerificationTokens.Load(v); } }
};

public override void Write(Utf8JsonWriter writer)
{
writer.WriteStartObject();
writer.WriteString("type", Type);
writer.WriteString("authorization_type", AuthorizationType);
if (Instructions != null) writer.WriteString("instructions", Instructions);
writer.WritePropertyName("verification_tokens");
VerificationTokens.Write(writer);
writer.WriteEndObject();
}
}
36 changes: 36 additions & 0 deletions src/lib/OpenAI/Auth/ManifestUserHttpAuth.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license.

using System.Text.Json;

namespace Microsoft.OpenApi.ApiManifest.OpenAI;

public class ManifestUserHttpAuth : BaseManifestAuth
{
public string? AuthorizationType { get; set; }
public ManifestUserHttpAuth(string? authorizationType)
{
if (string.IsNullOrWhiteSpace(authorizationType) || (authorizationType != "basic" && authorizationType != "bearer"))
{
// Reference: https://platform.openai.com/docs/plugins/authentication/user-level
throw new ArgumentException($"{nameof(authorizationType)} must be either 'basic' or 'bearer'.");
}
Type = "user_http";
AuthorizationType = authorizationType;
}

internal static readonly FixedFieldMap<ManifestUserHttpAuth> handlers = new()
{
{ "type", (o,v) => {o.Type = v.GetString(); } },
{ "authorization_type", (o,v) => {o.AuthorizationType = v.GetString(); } },
{ "instructions", (o,v) => {o.Instructions = v.GetString(); } },
};
public override void Write(Utf8JsonWriter writer)
{
writer.WriteStartObject();
writer.WriteString("type", Type);
writer.WriteString("authorization_type", AuthorizationType);
if (Instructions != null) writer.WriteString("instructions", Instructions);
writer.WriteEndObject();
}
}
28 changes: 28 additions & 0 deletions src/lib/OpenAI/Auth/VerificationTokens.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@

// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license.

using System.Text.Json;

namespace Microsoft.OpenApi.ApiManifest.OpenAI.Auth;

public class VerificationTokens : Dictionary<string, string>
{
public VerificationTokens(IDictionary<string, string> dictionary) : base(dictionary, StringComparer.OrdinalIgnoreCase) { }
public VerificationTokens() : base(StringComparer.OrdinalIgnoreCase) { }

internal static VerificationTokens Load(JsonElement value)
{
return new VerificationTokens(ParsingHelpers.GetMapOfString(value));
}

public void Write(Utf8JsonWriter writer)
{
writer.WriteStartObject();
foreach (var verificationToken in this)
{
writer.WriteString(verificationToken.Key, verificationToken.Value);
}
writer.WriteEndObject();
}
}
Loading