yavsc/src/Yavsc.Org.Tests/Mandatory/Remoting.cs

127 lines
4.7 KiB
C#
Raw Normal View History

2026-04-19 16:02:50 +01:00
using System.Security.Cryptography.X509Certificates;
using System.Net.Security;
2025-07-30 15:52:01 +01:00
using IdentityModel.Client;
2018-07-15 00:29:06 +02:00
2026-06-19 19:59:15 +01:00
namespace Yavsc.Org.Tests
2018-07-15 00:29:06 +02:00
{
2025-07-16 00:47:50 +01:00
[Collection("Yavsc Server")]
2021-01-04 00:11:27 +00:00
[Trait("regression", "oui")]
2025-07-13 18:13:04 +01:00
public class Remoting : BaseTestContext, IClassFixture<WebServerFixture>
2018-07-15 00:29:06 +02:00
{
private readonly ITestOutputHelper _output;
2025-07-13 18:13:04 +01:00
public Remoting(WebServerFixture serverFixture, ITestOutputHelper output)
2018-08-02 12:28:13 +02:00
: base(output, serverFixture)
2018-07-21 16:15:54 +02:00
{
_output = output;
2018-07-21 16:15:54 +02:00
}
2018-07-15 00:29:06 +02:00
2025-07-30 15:52:01 +01:00
[Fact]
public async Task ObtainServiceToken()
2026-04-19 16:02:50 +01:00
{
var serverUrl = GetServerUrl();
var cancellationToken = TestContext.Current.CancellationToken;
2026-04-19 17:15:10 +01:00
2026-04-19 16:02:50 +01:00
HttpClient client = NewHttpClient();
var tokenEndpoint = await ResolveTokenEndpointAsync(client, serverUrl, cancellationToken);
2026-04-19 16:02:50 +01:00
var response = await client.RequestClientCredentialsTokenAsync(new ClientCredentialsTokenRequest
{
Address = tokenEndpoint,
ClientId = RequireNonEmpty(_serverFixture.TestClientId, nameof(_serverFixture.TestClientId)),
ClientSecret = RequireNonEmpty(_serverFixture.TestClientSecret, nameof(_serverFixture.TestClientSecret)),
2026-04-19 16:02:50 +01:00
Scope = "test",
GrantType = "client_credentials"
}, cancellationToken);
2026-04-19 16:02:50 +01:00
if (response.IsError) throw new Exception(response.Error);
}
2025-07-15 17:35:14 +01:00
2026-04-19 17:15:10 +01:00
private static HttpClient NewHttpClient()
{
return new HttpClient(new BypassSslValidationHandler());
}
2025-07-16 00:47:50 +01:00
2026-04-19 16:02:50 +01:00
[Fact]
2025-07-30 15:52:01 +01:00
public async Task ObtainResourceOwnerPasswordToken()
{
var serverUrl = GetServerUrl();
var cancellationToken = TestContext.Current.CancellationToken;
2026-04-19 17:15:10 +01:00
2026-03-09 02:07:09 +00:00
var client = NewHttpClient();
var tokenEndpoint = await ResolveTokenEndpointAsync(client, serverUrl, cancellationToken);
2018-07-15 00:29:06 +02:00
2025-07-30 15:52:01 +01:00
var response = await client.RequestPasswordTokenAsync(new PasswordTokenRequest
2026-04-19 16:02:50 +01:00
{
Address = tokenEndpoint,
ClientId = RequireNonEmpty(_serverFixture.TestClientId, nameof(_serverFixture.TestClientId)),
ClientSecret = RequireNonEmpty(_serverFixture.TestClientSecret, nameof(_serverFixture.TestClientSecret)),
UserName = RequireNonEmpty(_serverFixture.TestingUserName, nameof(_serverFixture.TestingUserName)),
Password = RequireNonEmpty(_serverFixture.TestingUserPassword, nameof(_serverFixture.TestingUserPassword)),
2026-04-19 16:02:50 +01:00
Scope = "test",
Parameters =
2018-08-02 12:28:13 +02:00
{
2025-07-30 15:52:01 +01:00
{ "acr_values", "tenant:custom_account_store1 foo bar quux" }
}
}, cancellationToken);
2025-07-30 15:52:01 +01:00
if (response.IsError) throw new Exception(response.Error);
2018-07-15 00:29:06 +02:00
}
2018-08-02 12:28:13 +02:00
2025-07-16 00:47:50 +01:00
public static IEnumerable<object[]> GetLoginIntentData()
2025-07-13 18:13:04 +01:00
{
2025-07-16 00:47:50 +01:00
return new object[][] { new object[] { "testuser", "test" } };
2025-07-13 18:13:04 +01:00
}
2025-07-30 15:52:01 +01:00
private async Task<string> ResolveTokenEndpointAsync(HttpClient client, string serverUrl, CancellationToken cancellationToken)
{
var disco = await client.GetDiscoveryDocumentAsync(serverUrl, cancellationToken);
if (!disco.IsError && !string.IsNullOrWhiteSpace(disco.TokenEndpoint))
{
return disco.TokenEndpoint;
}
// Some full-suite runs intermittently return 500 on the OIDC
// discovery document while /connect/token remains available.
var fallback = new Uri(new Uri(serverUrl), "/connect/token").ToString();
_output.WriteLine($"WARNING: OIDC discovery failed ({disco.Error}). Fallback token endpoint: {fallback}");
return fallback;
}
private string GetServerUrl()
{
return RequireNonEmpty(_serverFixture.SiteSettings?.Authority, "SiteSettings.Authority");
}
private static string RequireNonEmpty(string? value, string name)
{
if (string.IsNullOrWhiteSpace(value))
{
throw new InvalidOperationException($"Missing required test setting: {name}");
}
return value;
}
2018-07-15 00:29:06 +02:00
}
2026-03-09 02:07:09 +00:00
2026-04-19 17:15:10 +01:00
internal class BypassSslValidationHandler : HttpClientHandler
2026-03-09 02:07:09 +00:00
{
2026-04-19 17:15:10 +01:00
public BypassSslValidationHandler()
{
// Override validation for this handler only
ServerCertificateCustomValidationCallback = ValidateCertificate;
}
private bool ValidateCertificate(
HttpRequestMessage request,
X509Certificate2? certificate,
X509Chain? chain,
SslPolicyErrors errors)
{
// Accept all certificates (bypass validation)
return true;
}
2026-03-09 02:07:09 +00:00
}
}