using System.Security.Claims; using Bit.Core.AdminConsole.Entities; using Bit.Core.AdminConsole.Services; using Bit.Core.Auth.Identity; using Bit.Core.Auth.Models.Business.Tokenables; using Bit.Core.Auth.Repositories; using Bit.Core.Context; using Bit.Core.Entities; using Bit.Core.Repositories; using Bit.Core.Services; using Bit.Core.Settings; using Bit.Core.Tokens; using Bit.Identity.IdentityServer; using Duende.IdentityServer.Models; using Duende.IdentityServer.Validation; using Microsoft.AspNetCore.Identity; using Microsoft.Extensions.Logging; namespace Bit.Identity.Test.Wrappers; public class BaseRequestValidationContextFake { public ValidatedTokenRequest ValidatedTokenRequest; public CustomValidatorRequestContext CustomValidatorRequestContext; public GrantValidationResult GrantResult; public BaseRequestValidationContextFake( ValidatedTokenRequest tokenRequest, CustomValidatorRequestContext customValidatorRequestContext, GrantValidationResult grantResult) { ValidatedTokenRequest = tokenRequest; CustomValidatorRequestContext = customValidatorRequestContext; GrantResult = grantResult; } } interface IBaseRequestValidatorTestWrapper { Task ValidateAsync(BaseRequestValidationContextFake context); } public class BaseRequestValidatorTestWrapper : BaseRequestValidator<BaseRequestValidationContextFake>, IBaseRequestValidatorTestWrapper { /* * Some of the logic trees call `ValidateContextAsync`. Since this is a test wrapper, we set the return value * of ValidateContextAsync() to whatever we need for the specific test case. */ public bool isValid { get; set; } public BaseRequestValidatorTestWrapper( UserManager<User> userManager, IUserService userService, IEventService eventService, IDeviceValidator deviceValidator, IOrganizationDuoWebTokenProvider organizationDuoWebTokenProvider, ITemporaryDuoWebV4SDKService duoWebV4SDKService, IOrganizationRepository organizationRepository, IOrganizationUserRepository organizationUserRepository, IApplicationCacheService applicationCacheService, IMailService mailService, ILogger logger, ICurrentContext currentContext, GlobalSettings globalSettings, IUserRepository userRepository, IPolicyService policyService, IDataProtectorTokenFactory<SsoEmail2faSessionTokenable> tokenDataFactory, IFeatureService featureService, ISsoConfigRepository ssoConfigRepository, IUserDecryptionOptionsBuilder userDecryptionOptionsBuilder) : base( userManager, userService, eventService, deviceValidator, organizationDuoWebTokenProvider, duoWebV4SDKService, organizationRepository, organizationUserRepository, applicationCacheService, mailService, logger, currentContext, globalSettings, userRepository, policyService, tokenDataFactory, featureService, ssoConfigRepository, userDecryptionOptionsBuilder) { } public async Task ValidateAsync( BaseRequestValidationContextFake context) { await ValidateAsync(context, context.ValidatedTokenRequest, context.CustomValidatorRequestContext); } public async Task<Tuple<bool, Organization>> TestRequiresTwoFactorAsync( User user, ValidatedTokenRequest context) { return await RequiresTwoFactorAsync(user, context); } protected override ClaimsPrincipal GetSubject( BaseRequestValidationContextFake context) { return context.ValidatedTokenRequest.Subject ?? new ClaimsPrincipal(); } protected override void SetErrorResult( BaseRequestValidationContextFake context, Dictionary<string, object> customResponse) { context.GrantResult = new GrantValidationResult(TokenRequestErrors.InvalidGrant, customResponse: customResponse); } protected override void SetSsoResult( BaseRequestValidationContextFake context, Dictionary<string, object> customResponse) { context.GrantResult = new GrantValidationResult( TokenRequestErrors.InvalidGrant, "Sso authentication required.", customResponse); } protected override Task SetSuccessResult( BaseRequestValidationContextFake context, User user, List<Claim> claims, Dictionary<string, object> customResponse) { context.GrantResult = new GrantValidationResult(customResponse: customResponse); return Task.CompletedTask; } protected override void SetTwoFactorResult( BaseRequestValidationContextFake context, Dictionary<string, object> customResponse) { } protected override Task<bool> ValidateContextAsync( BaseRequestValidationContextFake context, CustomValidatorRequestContext validatorContext) { return Task.FromResult(isValid); } }