diff --git a/eng/Generate.ps1 b/eng/Generate.ps1 index 640b38ac0e1..00820758514 100644 --- a/eng/Generate.ps1 +++ b/eng/Generate.ps1 @@ -255,6 +255,7 @@ $cadlRanchProjectDirectory = Join-Path $repoRoot 'test' 'CadlRanchProjects' $cadlRanchProjectPaths = 'authentication/api-key', 'authentication/oauth2', + 'authentication/union', 'models/property-optional', 'models/property-types', 'models/usage' diff --git a/src/AutoRest.CSharp/Properties/launchSettings.json b/src/AutoRest.CSharp/Properties/launchSettings.json index b9104aac9db..0c325d8402d 100644 --- a/src/AutoRest.CSharp/Properties/launchSettings.json +++ b/src/AutoRest.CSharp/Properties/launchSettings.json @@ -172,6 +172,10 @@ "commandName": "Project", "commandLineArgs": "--standalone $(SolutionDir)\\test\\CadlRanchProjects\\authentication\\oauth2\\Generated" }, + "cadl-authentication/union": { + "commandName": "Project", + "commandLineArgs": "--standalone $(SolutionDir)\\test\\CadlRanchProjects\\authentication\\union\\Generated" + }, "cadl-models/property-optional": { "commandName": "Project", "commandLineArgs": "--standalone $(SolutionDir)\\test\\CadlRanchProjects\\models\\property-optional\\Generated" diff --git a/test/CadlRanchProjects.Tests/OAuth2TestHelper.cs b/test/CadlRanchProjects.Tests/OAuth2TestHelper.cs new file mode 100644 index 00000000000..376d8758c23 --- /dev/null +++ b/test/CadlRanchProjects.Tests/OAuth2TestHelper.cs @@ -0,0 +1,102 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using Azure.Core.Pipeline; +using Azure.Core; +using System.Collections.Generic; +using System.Net; +using System.Reflection; +using System.Threading.Tasks; +using System.Threading; +using System; + +namespace CadlRanchProjects.Tests +{ + public class OAuth2TestHelper + { + public class MockCredential : TokenCredential + { + public override ValueTask GetTokenAsync(TokenRequestContext requestContext, CancellationToken cancellationToken) + { + return new(GetToken(requestContext, cancellationToken)); + } + + public override AccessToken GetToken(TokenRequestContext requestContext, CancellationToken cancellationToken) + { + return new AccessToken(string.Join(" ", requestContext.Scopes), DateTimeOffset.MaxValue); + } + } + + // Only for bypassing HTTPS check purpose + public class MockBearerTokenAuthenticationPolicy : BearerTokenAuthenticationPolicy + { + private readonly HttpPipelineTransport _transport; + + public MockBearerTokenAuthenticationPolicy(TokenCredential credential, IEnumerable scopes, HttpPipelineTransport transport) : base(credential, scopes) + { + _transport = transport; + } + + public override ValueTask ProcessAsync(HttpMessage message, ReadOnlyMemory pipeline) + { + return ProcessAsync(message, pipeline, true); + } + + public override void Process(HttpMessage message, ReadOnlyMemory pipeline) + { + ProcessAsync(message, pipeline, false).EnsureCompleted(); + } + + protected new async ValueTask ProcessNextAsync(HttpMessage message, ReadOnlyMemory pipeline) + { + await _transport.ProcessAsync(message).ConfigureAwait(false); + + var response = message.Response; + Type responseType = response.GetType(); + PropertyInfo propInfo = responseType.GetProperty("IsError", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); + propInfo.SetValue(response, message.ResponseClassifier.IsErrorResponse(message)); + } + + protected new void ProcessNext(HttpMessage message, ReadOnlyMemory pipeline) + { + _transport.Process(message); + } + + private async ValueTask ProcessAsync(HttpMessage message, ReadOnlyMemory pipeline, bool async) + { + if (async) + { + await AuthorizeRequestAsync(message).ConfigureAwait(false); + await ProcessNextAsync(message, pipeline).ConfigureAwait(false); + } + else + { + AuthorizeRequest(message); + ProcessNext(message, pipeline); + } + + // Check if we have received a challenge or we have not yet issued the first request. + if (message.Response.Status == (int)HttpStatusCode.Unauthorized && message.Response.Headers.Contains(HttpHeader.Names.WwwAuthenticate)) + { + // Attempt to get the TokenRequestContext based on the challenge. + // If we fail to get the context, the challenge was not present or invalid. + // If we succeed in getting the context, authenticate the request and pass it up the policy chain. + if (async) + { + if (await AuthorizeRequestOnChallengeAsync(message).ConfigureAwait(false)) + { + await ProcessNextAsync(message, pipeline).ConfigureAwait(false); + } + } + else + { + if (AuthorizeRequestOnChallenge(message)) + { + ProcessNext(message, pipeline); + } + } + } + } + } + } +} diff --git a/test/CadlRanchProjects.Tests/authentication-oauth2.cs b/test/CadlRanchProjects.Tests/authentication-oauth2.cs index 1e5ff57501a..27e4e923227 100644 --- a/test/CadlRanchProjects.Tests/authentication-oauth2.cs +++ b/test/CadlRanchProjects.Tests/authentication-oauth2.cs @@ -6,14 +6,9 @@ using Azure; using NUnit.Framework; using Authentication.OAuth2; -using Azure.Core.Pipeline; using Azure.Core; -using System.Collections.Generic; -using System.Net; -using System.Threading; -using System; -using System.Reflection; using NUnit.Framework.Internal; +using static CadlRanchProjects.Tests.OAuth2TestHelper; namespace CadlRanchProjects.Tests { @@ -38,90 +33,5 @@ public Task Authentication_OAuth2_invalid() => Test((host) => Assert.AreEqual(403, exception.Status); return Task.CompletedTask; }); - - public class MockCredential : TokenCredential - { - public override ValueTask GetTokenAsync(TokenRequestContext requestContext, CancellationToken cancellationToken) - { - return new(GetToken(requestContext, cancellationToken)); - } - - public override AccessToken GetToken(TokenRequestContext requestContext, CancellationToken cancellationToken) - { - return new AccessToken(string.Join(" ", requestContext.Scopes), DateTimeOffset.MaxValue); - } - } - - // Only for bypassing HTTPS check purpose - public class MockBearerTokenAuthenticationPolicy : BearerTokenAuthenticationPolicy - { - private readonly HttpPipelineTransport _transport; - - public MockBearerTokenAuthenticationPolicy(TokenCredential credential, IEnumerable scopes, HttpPipelineTransport transport) : base(credential, scopes) - { - _transport = transport; - } - - public override ValueTask ProcessAsync(HttpMessage message, ReadOnlyMemory pipeline) - { - return ProcessAsync(message, pipeline, true); - } - - public override void Process(HttpMessage message, ReadOnlyMemory pipeline) - { - ProcessAsync(message, pipeline, false).EnsureCompleted(); - } - - protected new async ValueTask ProcessNextAsync(HttpMessage message, ReadOnlyMemory pipeline) - { - await _transport.ProcessAsync(message).ConfigureAwait(false); - - var response = message.Response; - Type responseType = response.GetType(); - PropertyInfo propInfo = responseType.GetProperty("IsError", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); - propInfo.SetValue(response, message.ResponseClassifier.IsErrorResponse(message)); - } - - protected new void ProcessNext(HttpMessage message, ReadOnlyMemory pipeline) - { - _transport.Process(message); - } - - private async ValueTask ProcessAsync(HttpMessage message, ReadOnlyMemory pipeline, bool async) - { - if (async) - { - await AuthorizeRequestAsync(message).ConfigureAwait(false); - await ProcessNextAsync(message, pipeline).ConfigureAwait(false); - } - else - { - AuthorizeRequest(message); - ProcessNext(message, pipeline); - } - - // Check if we have received a challenge or we have not yet issued the first request. - if (message.Response.Status == (int)HttpStatusCode.Unauthorized && message.Response.Headers.Contains(HttpHeader.Names.WwwAuthenticate)) - { - // Attempt to get the TokenRequestContext based on the challenge. - // If we fail to get the context, the challenge was not present or invalid. - // If we succeed in getting the context, authenticate the request and pass it up the policy chain. - if (async) - { - if (await AuthorizeRequestOnChallengeAsync(message).ConfigureAwait(false)) - { - await ProcessNextAsync(message, pipeline).ConfigureAwait(false); - } - } - else - { - if (AuthorizeRequestOnChallenge(message)) - { - ProcessNext(message, pipeline); - } - } - } - } - } } } diff --git a/test/CadlRanchProjects.Tests/authentication-union.cs b/test/CadlRanchProjects.Tests/authentication-union.cs new file mode 100644 index 00000000000..8d284bb54b9 --- /dev/null +++ b/test/CadlRanchProjects.Tests/authentication-union.cs @@ -0,0 +1,32 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using System.Threading.Tasks; +using Authentication.Union; +using AutoRest.TestServer.Tests.Infrastructure; +using Azure; +using Azure.Core; +using NUnit.Framework; +using static CadlRanchProjects.Tests.OAuth2TestHelper; + +namespace CadlRanchProjects.Tests +{ + public class AuthenticationUnionTests : CadlRanchTestBase + { + [Test] + public Task Authentication_Union_validKey() => Test(async (host) => + { + Response response = await new UnionClient(new AzureKeyCredential("valid-key"), host, null).ValidKeyAsync(); + Assert.AreEqual(204, response.Status); + }); + + [Test] + public Task Authentication_Union_validToken() => Test(async (host) => + { + var options = new UnionClientOptions(); + options.AddPolicy(new MockBearerTokenAuthenticationPolicy(new MockCredential(), UnionClient.TokenScopes, options.Transport), HttpPipelinePosition.PerCall); + Response response = await new UnionClient(new MockCredential(), host, options).ValidTokenAsync(); + Assert.AreEqual(204, response.Status); + }); + } +} diff --git a/test/CadlRanchProjects.Tests/models-property-optional.cs b/test/CadlRanchProjects.Tests/models-property-optional.cs index bfc2764e6d5..ea0bfb89876 100644 --- a/test/CadlRanchProjects.Tests/models-property-optional.cs +++ b/test/CadlRanchProjects.Tests/models-property-optional.cs @@ -93,7 +93,6 @@ public Task Models_Property_Optional_Datetime_getDefault() => Test(async (host) }); [Test] - [Ignore("Need cadl ranch fix")] public Task Models_Property_Optional_Datetime_putAll() => Test(async (host) => { DatetimeProperty data = new() @@ -210,5 +209,42 @@ public Task Models_Property_Optional_CollectionsModel_putDefault() => Test(async Response response = await new OptionalClient(host, null).GetCollectionsModelClient().PutDefaultAsync(new CollectionsModelProperty().ToRequestContent()); Assert.AreEqual(204, response.Status); }); + + [Test] + public Task Models_Property_Optional_RequiredAndOptional_getAll() => Test(async (host) => + { + Response response = await new OptionalClient(host, null).GetRequiredAndOptionalClient().GetAllAsync(); + var result = RequiredAndOptionalProperty.FromResponse(response); + Assert.AreEqual("hello", result.OptionalProperty); + Assert.AreEqual(42, result.RequiredProperty); + }); + + [Test] + public Task Models_Property_Optional_RequiredAndOptional_getRequiredOnly() => Test(async (host) => + { + Response response = await new OptionalClient(host, null).GetRequiredAndOptionalClient().GetRequiredOnlyAsync(); + var result = RequiredAndOptionalProperty.FromResponse(response); + Assert.AreEqual(null, result.OptionalProperty); + Assert.AreEqual(42, result.RequiredProperty); + }); + + [Test] + public Task Models_Property_Optional_RequiredAndOptional_putAll() => Test(async (host) => + { + var content = new RequiredAndOptionalProperty(42) + { + OptionalProperty = "hello" + }; + + Response response = await new OptionalClient(host, null).GetRequiredAndOptionalClient().PutAllAsync(content.ToRequestContent()); + Assert.AreEqual(204, response.Status); + }); + + [Test] + public Task Models_Property_Optional_RequiredAndOptional_putRequiredOnly() => Test(async (host) => + { + Response response = await new OptionalClient(host, null).GetRequiredAndOptionalClient().PutRequiredOnlyAsync(new RequiredAndOptionalProperty(42)); + Assert.AreEqual(204, response.Status); + }); } } diff --git a/test/CadlRanchProjects.Tests/models-property-types.cs b/test/CadlRanchProjects.Tests/models-property-types.cs index 1d680e43212..424c95112a3 100644 --- a/test/CadlRanchProjects.Tests/models-property-types.cs +++ b/test/CadlRanchProjects.Tests/models-property-types.cs @@ -214,5 +214,20 @@ public Task Models_Property_Types_DictionaryString_put() => Test(async (host) => Response response = await new TypesClient(host, null).GetDictionaryStringClient().PutAsync(new DictionaryStringProperty(new Dictionary { ["k1"] = "hello", ["k2"] = "world" }).ToRequestContent()); Assert.AreEqual(204, response.Status); }); + + [Test] + public Task Models_Property_Types_Never_get() => Test(async (host) => + { + Response response = await new TypesClient(host, null).GetNeverClient().GetNeverAsync(); + var result = NeverProperty.FromResponse(response); + Assert.NotNull(result); + }); + + [Test] + public Task Models_Property_Types_Never_put() => Test(async (host) => + { + Response response = await new TypesClient(host, null).GetNeverClient().PutAsync(new NeverProperty().ToRequestContent()); + Assert.AreEqual(204, response.Status); + }); } } diff --git a/test/CadlRanchProjects/authentication/union/Generated/Configuration.json b/test/CadlRanchProjects/authentication/union/Generated/Configuration.json new file mode 100644 index 00000000000..39bc85a4b37 --- /dev/null +++ b/test/CadlRanchProjects/authentication/union/Generated/Configuration.json @@ -0,0 +1,10 @@ +{ + "OutputFolder": ".", + "Namespace": "Authentication.Union", + "LibraryName": null, + "SharedSourceFolders": [ + "../../../../../artifacts/bin/AutoRest.CSharp/Debug/net6.0/Generator.Shared", + "../../../../../artifacts/bin/AutoRest.CSharp/Debug/net6.0/Azure.Core.Shared" + ], + "unreferenced-types-handling": "keepAll" +} diff --git a/test/CadlRanchProjects/authentication/union/Generated/Docs/UnionClient.xml b/test/CadlRanchProjects/authentication/union/Generated/Docs/UnionClient.xml new file mode 100644 index 00000000000..12fb0091009 --- /dev/null +++ b/test/CadlRanchProjects/authentication/union/Generated/Docs/UnionClient.xml @@ -0,0 +1,53 @@ + + + + + +This sample shows how to call ValidKeyAsync. +"); +var client = new UnionClient(credential); + +Response response = await client.ValidKeyAsync(); +Console.WriteLine(response.Status); +]]> + + + + +This sample shows how to call ValidKey. +"); +var client = new UnionClient(credential); + +Response response = client.ValidKey(); +Console.WriteLine(response.Status); +]]> + + + + +This sample shows how to call ValidTokenAsync. +"); +var client = new UnionClient(credential); + +Response response = await client.ValidTokenAsync(); +Console.WriteLine(response.Status); +]]> + + + + +This sample shows how to call ValidToken. +"); +var client = new UnionClient(credential); + +Response response = client.ValidToken(); +Console.WriteLine(response.Status); +]]> + + + + \ No newline at end of file diff --git a/test/CadlRanchProjects/authentication/union/Generated/UnionClient.cs b/test/CadlRanchProjects/authentication/union/Generated/UnionClient.cs new file mode 100644 index 00000000000..6da57e09ab4 --- /dev/null +++ b/test/CadlRanchProjects/authentication/union/Generated/UnionClient.cs @@ -0,0 +1,204 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.Threading.Tasks; +using Azure; +using Azure.Core; +using Azure.Core.Pipeline; + +namespace Authentication.Union +{ + // Data plane generated client. + /// Illustrates clients generated with ApiKey and OAuth2 authentication. + public partial class UnionClient + { + private const string AuthorizationHeader = "x-ms-api-key"; + private readonly AzureKeyCredential _keyCredential; + private static readonly string[] AuthorizationScopes = new string[] { "https://security.microsoft.com/.default" }; + private readonly TokenCredential _tokenCredential; + private readonly HttpPipeline _pipeline; + private readonly Uri _endpoint; + private readonly string _apiVersion; + + /// The ClientDiagnostics is used to provide tracing support for the client library. + internal ClientDiagnostics ClientDiagnostics { get; } + + /// The HTTP pipeline for sending and receiving REST requests and responses. + public virtual HttpPipeline Pipeline => _pipeline; + + /// Initializes a new instance of UnionClient for mocking. + protected UnionClient() + { + } + + /// Initializes a new instance of UnionClient. + /// A credential used to authenticate to an Azure Service. + /// is null. + public UnionClient(AzureKeyCredential credential) : this(credential, new Uri("http://localhost:3000"), new UnionClientOptions()) + { + } + + /// Initializes a new instance of UnionClient. + /// A credential used to authenticate to an Azure Service. + /// is null. + public UnionClient(TokenCredential credential) : this(credential, new Uri("http://localhost:3000"), new UnionClientOptions()) + { + } + + /// Initializes a new instance of UnionClient. + /// A credential used to authenticate to an Azure Service. + /// TestServer endpoint. + /// The options for configuring the client. + /// or is null. + public UnionClient(AzureKeyCredential credential, Uri endpoint, UnionClientOptions options) + { + Argument.AssertNotNull(credential, nameof(credential)); + Argument.AssertNotNull(endpoint, nameof(endpoint)); + options ??= new UnionClientOptions(); + + ClientDiagnostics = new ClientDiagnostics(options, true); + _keyCredential = credential; + _pipeline = HttpPipelineBuilder.Build(options, Array.Empty(), new HttpPipelinePolicy[] { new AzureKeyCredentialPolicy(_keyCredential, AuthorizationHeader) }, new ResponseClassifier()); + _endpoint = endpoint; + _apiVersion = options.Version; + } + + /// Initializes a new instance of UnionClient. + /// A credential used to authenticate to an Azure Service. + /// TestServer endpoint. + /// The options for configuring the client. + /// or is null. + public UnionClient(TokenCredential credential, Uri endpoint, UnionClientOptions options) + { + Argument.AssertNotNull(credential, nameof(credential)); + Argument.AssertNotNull(endpoint, nameof(endpoint)); + options ??= new UnionClientOptions(); + + ClientDiagnostics = new ClientDiagnostics(options, true); + _tokenCredential = credential; + _pipeline = HttpPipelineBuilder.Build(options, Array.Empty(), new HttpPipelinePolicy[] { new BearerTokenAuthenticationPolicy(_tokenCredential, AuthorizationScopes) }, new ResponseClassifier()); + _endpoint = endpoint; + _apiVersion = options.Version; + } + + /// Check whether client is authenticated. + /// The request context, which can override default behaviors of the client pipeline on a per-call basis. + /// Service returned a non-success status code. + /// The response returned from the service. + /// + public virtual async Task ValidKeyAsync(RequestContext context = null) + { + using var scope = ClientDiagnostics.CreateScope("UnionClient.ValidKey"); + scope.Start(); + try + { + using HttpMessage message = CreateValidKeyRequest(context); + return await _pipeline.ProcessMessageAsync(message, context).ConfigureAwait(false); + } + catch (Exception e) + { + scope.Failed(e); + throw; + } + } + + /// Check whether client is authenticated. + /// The request context, which can override default behaviors of the client pipeline on a per-call basis. + /// Service returned a non-success status code. + /// The response returned from the service. + /// + public virtual Response ValidKey(RequestContext context = null) + { + using var scope = ClientDiagnostics.CreateScope("UnionClient.ValidKey"); + scope.Start(); + try + { + using HttpMessage message = CreateValidKeyRequest(context); + return _pipeline.ProcessMessage(message, context); + } + catch (Exception e) + { + scope.Failed(e); + throw; + } + } + + /// Check whether client is authenticated. + /// The request context, which can override default behaviors of the client pipeline on a per-call basis. + /// Service returned a non-success status code. + /// The response returned from the service. + /// + public virtual async Task ValidTokenAsync(RequestContext context = null) + { + using var scope = ClientDiagnostics.CreateScope("UnionClient.ValidToken"); + scope.Start(); + try + { + using HttpMessage message = CreateValidTokenRequest(context); + return await _pipeline.ProcessMessageAsync(message, context).ConfigureAwait(false); + } + catch (Exception e) + { + scope.Failed(e); + throw; + } + } + + /// Check whether client is authenticated. + /// The request context, which can override default behaviors of the client pipeline on a per-call basis. + /// Service returned a non-success status code. + /// The response returned from the service. + /// + public virtual Response ValidToken(RequestContext context = null) + { + using var scope = ClientDiagnostics.CreateScope("UnionClient.ValidToken"); + scope.Start(); + try + { + using HttpMessage message = CreateValidTokenRequest(context); + return _pipeline.ProcessMessage(message, context); + } + catch (Exception e) + { + scope.Failed(e); + throw; + } + } + + internal HttpMessage CreateValidKeyRequest(RequestContext context) + { + var message = _pipeline.CreateMessage(context, ResponseClassifier204); + var request = message.Request; + request.Method = RequestMethod.Get; + var uri = new RawRequestUriBuilder(); + uri.Reset(_endpoint); + uri.AppendPath("/authentication/union/validkey", false); + uri.AppendQuery("api-version", _apiVersion, true); + request.Uri = uri; + request.Headers.Add("Accept", "application/json"); + return message; + } + + internal HttpMessage CreateValidTokenRequest(RequestContext context) + { + var message = _pipeline.CreateMessage(context, ResponseClassifier204); + var request = message.Request; + request.Method = RequestMethod.Get; + var uri = new RawRequestUriBuilder(); + uri.Reset(_endpoint); + uri.AppendPath("/authentication/union/validtoken", false); + uri.AppendQuery("api-version", _apiVersion, true); + request.Uri = uri; + request.Headers.Add("Accept", "application/json"); + return message; + } + + private static ResponseClassifier _responseClassifier204; + private static ResponseClassifier ResponseClassifier204 => _responseClassifier204 ??= new StatusCodeClassifier(stackalloc ushort[] { 204 }); + } +} diff --git a/test/CadlRanchProjects/authentication/union/Generated/UnionClientOptions.cs b/test/CadlRanchProjects/authentication/union/Generated/UnionClientOptions.cs new file mode 100644 index 00000000000..a7bd7b5f9bb --- /dev/null +++ b/test/CadlRanchProjects/authentication/union/Generated/UnionClientOptions.cs @@ -0,0 +1,37 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using Azure.Core; + +namespace Authentication.Union +{ + /// Client options for UnionClient. + public partial class UnionClientOptions : ClientOptions + { + private const ServiceVersion LatestVersion = ServiceVersion.V1_0_0; + + /// The version of the service to use. + public enum ServiceVersion + { + /// Service version "1.0.0". + V1_0_0 = 1, + } + + internal string Version { get; } + + /// Initializes new instance of UnionClientOptions. + public UnionClientOptions(ServiceVersion version = LatestVersion) + { + Version = version switch + { + ServiceVersion.V1_0_0 => "1.0.0", + _ => throw new NotSupportedException() + }; + } + } +} diff --git a/test/CadlRanchProjects/authentication/union/Generated/cadl.json b/test/CadlRanchProjects/authentication/union/Generated/cadl.json new file mode 100644 index 00000000000..7650b6bb082 --- /dev/null +++ b/test/CadlRanchProjects/authentication/union/Generated/cadl.json @@ -0,0 +1,210 @@ +{ + "$id": "1", + "Name": "Authentication.Union", + "Description": "Illustrates clients generated with ApiKey and OAuth2 authentication.", + "ApiVersions": [ + "1.0.0" + ], + "Enums": [], + "Models": [], + "Clients": [ + { + "$id": "2", + "Name": "UnionClient", + "Description": "Illustrates clients generated with ApiKey and OAuth2 authentication.", + "Operations": [ + { + "$id": "3", + "Name": "validKey", + "ResourceName": "Union", + "Description": "Check whether client is authenticated", + "Parameters": [ + { + "$id": "4", + "Name": "host", + "NameInRequest": "host", + "Description": "TestServer endpoint", + "Type": { + "$id": "5", + "Name": "String", + "Kind": "String", + "IsNullable": false + }, + "Location": "Uri", + "IsApiVersion": false, + "IsResourceParameter": false, + "IsContentType": false, + "IsRequired": true, + "IsEndpoint": true, + "SkipUrlEncoding": false, + "Explode": false, + "Kind": "Client", + "DefaultValue": { + "$id": "6", + "Type": { + "$id": "7", + "Name": "String", + "Kind": "String", + "IsNullable": false + }, + "Value": "http://localhost:3000" + } + }, + { + "$id": "8", + "Name": "accept", + "NameInRequest": "Accept", + "Type": { + "$id": "9", + "Name": "String", + "Kind": "String", + "IsNullable": false + }, + "Location": "Header", + "IsApiVersion": false, + "IsResourceParameter": false, + "IsContentType": false, + "IsRequired": true, + "IsEndpoint": false, + "SkipUrlEncoding": false, + "Explode": false, + "Kind": "Constant", + "DefaultValue": { + "$id": "10", + "Type": { + "$ref": "9" + }, + "Value": "application/json" + } + }, + { + "$id": "11", + "Name": "apiVersion", + "NameInRequest": "api-version", + "Description": "", + "Type": { + "$id": "12", + "Name": "String", + "Kind": "String", + "IsNullable": false + }, + "Location": "Query", + "IsRequired": true, + "IsApiVersion": true, + "IsContentType": false, + "IsEndpoint": false, + "IsResourceParameter": false, + "SkipUrlEncoding": false, + "Explode": false, + "Kind": "Client", + "DefaultValue": { + "$id": "13", + "Type": { + "$id": "14", + "Name": "String", + "Kind": "String", + "IsNullable": false + }, + "Value": "1.0.0" + } + } + ], + "Responses": [ + { + "$id": "15", + "StatusCodes": [ + 204 + ], + "BodyMediaType": "Json", + "Headers": [], + "IsErrorResponse": false + } + ], + "HttpMethod": "GET", + "RequestBodyMediaType": "Json", + "Uri": "{host}", + "Path": "/authentication/union/validkey", + "BufferResponse": true, + "GenerateProtocolMethod": true, + "GenerateConvenienceMethod": true + }, + { + "$id": "16", + "Name": "validToken", + "ResourceName": "Union", + "Description": "Check whether client is authenticated", + "Parameters": [ + { + "$ref": "4" + }, + { + "$id": "17", + "Name": "accept", + "NameInRequest": "Accept", + "Type": { + "$id": "18", + "Name": "String", + "Kind": "String", + "IsNullable": false + }, + "Location": "Header", + "IsApiVersion": false, + "IsResourceParameter": false, + "IsContentType": false, + "IsRequired": true, + "IsEndpoint": false, + "SkipUrlEncoding": false, + "Explode": false, + "Kind": "Constant", + "DefaultValue": { + "$id": "19", + "Type": { + "$ref": "18" + }, + "Value": "application/json" + } + }, + { + "$ref": "11" + } + ], + "Responses": [ + { + "$id": "20", + "StatusCodes": [ + 204 + ], + "BodyMediaType": "Json", + "Headers": [], + "IsErrorResponse": false + } + ], + "HttpMethod": "GET", + "RequestBodyMediaType": "Json", + "Uri": "{host}", + "Path": "/authentication/union/validtoken", + "BufferResponse": true, + "GenerateProtocolMethod": true, + "GenerateConvenienceMethod": true + } + ], + "Protocol": { + "$id": "21" + }, + "Creatable": true + } + ], + "Auth": { + "$id": "22", + "ApiKey": { + "$id": "23", + "Name": "x-ms-api-key" + }, + "OAuth2": { + "$id": "24", + "Scopes": [ + "https://security.microsoft.com/.default" + ] + } + } +} diff --git a/test/CadlRanchProjects/authentication/union/Union.csproj b/test/CadlRanchProjects/authentication/union/Union.csproj new file mode 100644 index 00000000000..c605e2030ae --- /dev/null +++ b/test/CadlRanchProjects/authentication/union/Union.csproj @@ -0,0 +1,20 @@ + + + + netstandard2.0 + true + annotations + + + + $(DefineConstants);EXPERIMENTAL + + + + + + + + + + diff --git a/test/CadlRanchProjects/authentication/union/UnionClient.cs b/test/CadlRanchProjects/authentication/union/UnionClient.cs new file mode 100644 index 00000000000..0d9a0be6943 --- /dev/null +++ b/test/CadlRanchProjects/authentication/union/UnionClient.cs @@ -0,0 +1,10 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +namespace Authentication.Union +{ + public partial class UnionClient + { + public static string[] TokenScopes => AuthorizationScopes; + } +}