1
0
mirror of https://github.com/bitwarden/server synced 2026-01-28 23:36:12 +00:00

fix(redirect): [PM-30810] Https Redirection for Cloud Users - Used reflection instead of change the interface.

This commit is contained in:
Patrick Pimentel
2026-01-23 18:04:26 -05:00
parent 0f3fcd81dd
commit 26fcfef235
2 changed files with 21 additions and 18 deletions

View File

@@ -77,15 +77,6 @@ public interface IDuoUniversalTokenService
/// <param name="provider">TwoFactorProvider Duo or OrganizationDuo</param>
/// <returns>Duo.Client object or null</returns>
Task<Duo.Client> BuildDuoTwoFactorClientAsync(TwoFactorProvider provider);
/// <summary>
/// Builds the redirect URI for Duo authentication based on the client type and request context.
/// Mobile clients include a deeplinkScheme parameter (https for cloud, bitwarden for self-hosted).
/// Desktop clients always use the bitwarden scheme.
/// Other clients (web, browser, cli) do not include the deeplinkScheme parameter.
/// </summary>
/// <returns>The redirect URI to be used for Duo authentication</returns>
string BuildDuoTwoFactorRedirectUri();
}
public class DuoUniversalTokenService(
@@ -220,7 +211,7 @@ public class DuoUniversalTokenService(
return Enum.TryParse<DuoDeeplinkScheme>(candidate, ignoreCase: true, out var scheme) ? scheme : null;
}
public string BuildDuoTwoFactorRedirectUri()
private string BuildDuoTwoFactorRedirectUri()
{
// Fetch Client name from header value since duo auth can be initiated from multiple clients and we want
// to redirect back to the initiating client

View File

@@ -1,4 +1,5 @@
using Bit.Core.Auth.Identity.TokenProviders;
using System.Reflection;
using Bit.Core.Auth.Identity.TokenProviders;
using Bit.Core.Auth.Models;
using Bit.Core.Context;
using Bit.Test.Common.AutoFixture;
@@ -13,6 +14,17 @@ namespace Bit.Core.Test.Auth.Services;
[SutProviderCustomize]
public class DuoUniversalTokenServiceTests
{
/// <summary>
/// Helper method to invoke the private BuildDuoTwoFactorRedirectUri method via reflection.
/// </summary>
private static string InvokeBuildDuoTwoFactorRedirectUri(DuoUniversalTokenService sut)
{
var method = typeof(DuoUniversalTokenService).GetMethod(
"BuildDuoTwoFactorRedirectUri",
BindingFlags.NonPublic | BindingFlags.Instance);
return (string)method!.Invoke(sut, null)!;
}
[Theory]
[BitAutoData("", "ClientId", "ClientSecret")]
[BitAutoData("api-valid.duosecurity.com", "", "ClientSecret")]
@@ -113,7 +125,7 @@ public class DuoUniversalTokenServiceTests
var sut = new DuoUniversalTokenService(currentContext, globalSettings);
// Act
var result = sut.BuildDuoTwoFactorRedirectUri();
var result = InvokeBuildDuoTwoFactorRedirectUri(sut);
// Assert
Assert.Contains("client=mobile", result);
@@ -143,7 +155,7 @@ public class DuoUniversalTokenServiceTests
var sut = new DuoUniversalTokenService(currentContext, globalSettings);
// Act
var result = sut.BuildDuoTwoFactorRedirectUri();
var result = InvokeBuildDuoTwoFactorRedirectUri(sut);
// Assert
Assert.Contains("client=mobile", result);
@@ -169,7 +181,7 @@ public class DuoUniversalTokenServiceTests
var sut = new DuoUniversalTokenService(currentContext, globalSettings);
// Act
var result = sut.BuildDuoTwoFactorRedirectUri();
var result = InvokeBuildDuoTwoFactorRedirectUri(sut);
// Assert
Assert.Contains("client=desktop", result);
@@ -199,7 +211,7 @@ public class DuoUniversalTokenServiceTests
var sut = new DuoUniversalTokenService(currentContext, globalSettings);
// Act
var result = sut.BuildDuoTwoFactorRedirectUri();
var result = InvokeBuildDuoTwoFactorRedirectUri(sut);
// Assert
Assert.Contains($"client={clientName}", result);
@@ -225,7 +237,7 @@ public class DuoUniversalTokenServiceTests
var sut = new DuoUniversalTokenService(currentContext, globalSettings);
// Act
var result = sut.BuildDuoTwoFactorRedirectUri();
var result = InvokeBuildDuoTwoFactorRedirectUri(sut);
// Assert
Assert.Contains("client=web", result);
@@ -254,7 +266,7 @@ public class DuoUniversalTokenServiceTests
var sut = new DuoUniversalTokenService(currentContext, globalSettings);
// Act
var result = sut.BuildDuoTwoFactorRedirectUri();
var result = InvokeBuildDuoTwoFactorRedirectUri(sut);
// Assert
Assert.Contains("client=web", result);
@@ -284,7 +296,7 @@ public class DuoUniversalTokenServiceTests
var sut = new DuoUniversalTokenService(currentContext, globalSettings);
// Act
var result = sut.BuildDuoTwoFactorRedirectUri();
var result = InvokeBuildDuoTwoFactorRedirectUri(sut);
// Assert
Assert.Contains("client=mobile", result);