Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[PM-6666] Two factor Validator refactor #13

Open
wants to merge 14 commits into
base: main
Choose a base branch
from

Conversation

lizard-boy
Copy link

@lizard-boy lizard-boy commented Oct 19, 2024

🎟️ Tracking

PM-6666

📔 Objective

Goal of this PR is to create a testable service for TwoFactorAuthentication by refactoring out the TwoFactor logic from the BaseRequestValidator.

There were already TwoFactor integration tests this PR is meant to add Unit Tests.

📸 Screenshots

Two Factor smoke tests to verify refactor hasn't changed core function

firefox_jnYuNYxoGn.mp4

⏰ Reminders before review

  • Contributor guidelines followed
  • All formatters and local linters executed and passed
  • Written new unit and / or integration tests where applicable
  • Protected functional changes with optionality (feature flags)
  • Used internationalization (i18n) for all UI strings
  • CI builds passed
  • Communicated to DevOps any deployment requirements
  • Updated any necessary documentation (Confluence, contributing docs) or informed the documentation team

🦮 Reviewer guidelines

  • 👍 (:+1:) or similar for great changes
  • 📝 (:memo:) or ℹ️ (:information_source:) for notes or general info
  • ❓ (:question:) for questions
  • 🤔 (:thinking:) or 💭 (:thought_balloon:) for more open inquiry that's not quite a confirmed issue and could potentially benefit from discussion
  • 🎨 (:art:) for suggestions / improvements
  • ❌ (:x:) or ⚠️ (:warning:) for more significant problems or concerns needing attention
  • 🌱 (:seedling:) or ♻️ (:recycle:) for future improvements or indications of technical debt
  • ⛏ (:pick:) for minor or nitpick changes

Greptile Summary

This pull request refactors the two-factor authentication logic into a dedicated service, improving testability and separation of concerns.

  • Introduced new TwoFactorAuthenticationValidator class in src/Identity/IdentityServer/TwoFactorValidator.cs
  • Removed two-factor logic from BaseRequestValidator and updated related classes to use the new validator
  • Added comprehensive unit tests in test/Identity.Test/IdentityServer/TwoFactorAuthenticationValidatorTests.cs
  • Created UserManagerTestWrapper in test/Identity.Test/Wrappers/UserManagerTestWrapper.cs to facilitate mocking of two-factor operations
  • Updated ServiceCollectionExtensions to register the new two-factor authentication validator service

Copy link

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

12 file(s) reviewed, 25 comment(s)
Edit PR Review Bot Settings | Greptile

@@ -165,7 +159,6 @@ protected async Task ValidateAsync(T context, ValidatedTokenRequest request,
}
}

// Returns true if can finish validation process
if (await IsValidAuthTypeAsync(user, request.GrantType))
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

style: IsValidAuthTypeAsync might be better named as IsNonSsoAuthTypeAllowedAsync for clarity

/// </summary>
/// <param name="user">The user is assumed NOT null, still going to check though</param>
/// <param name="request">Duende Validated Request that contains the data to create the device object</param>
/// <returns>Returns null if user or device is malformed; The existing device if already in DB; a new device login</returns>
public async Task<Device> SaveDeviceAsync(User user, ValidatedTokenRequest request)
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

style: Consider adding null checks for user and request parameters

IOrganizationUserRepository organizationUserRepository,
IOrganizationRepository organizationRepository,
IDataProtectorTokenFactory<SsoEmail2faSessionTokenable> ssoEmail2faSessionTokeFactory,
ICurrentContext currentContext) : ITwoFactorAuthenticationValidator
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

syntax: There's a typo in the parameter name 'ssoEmail2faSessionTokeFactory'. It should be 'ssoEmail2faSessionTokenFactory'.

private readonly IApplicationCacheService _applicationCacheService = applicationCacheService;
private readonly IOrganizationUserRepository _organizationUserRepository = organizationUserRepository;
private readonly IOrganizationRepository _organizationRepository = organizationRepository;
private readonly IDataProtectorTokenFactory<SsoEmail2faSessionTokenable> _ssoEmail2faSessionTokeFactory = ssoEmail2faSessionTokeFactory;
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

syntax: The typo in the field name '_ssoEmail2faSessionTokeFactory' should be corrected to '_ssoEmail2faSessionTokenFactory'.

Comment on lines +108 to +110
return null;
// await BuildErrorResultAsync("No two-step providers enabled.", false, context, user);
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

style: The commented-out code should be removed or implemented properly. If it's meant to handle the case when no providers are enabled, consider throwing an exception or returning an appropriate error response.

/// <summary>
/// Modify this value to mock the responses from UserManager.GetValidTwoFactorProvidersAsync()
/// </summary>
public IList<string> TWO_FACTOR_PROVIDERS { get; set; } = [];
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

style: Consider using IReadOnlyList for better encapsulation

Comment on lines +59 to +62
public override async Task<bool> GetTwoFactorEnabledAsync(TUser user)
{
return TWO_FACTOR_ENABLED;
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

style: async keyword unnecessary for synchronous method

Comment on lines +69 to +72
public override async Task<IList<string>> GetValidTwoFactorProvidersAsync(TUser user)
{
return TWO_FACTOR_PROVIDERS;
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

style: async keyword unnecessary for synchronous method

Comment on lines +80 to +83
public override async Task<string> GenerateTwoFactorTokenAsync(TUser user, string tokenProvider)
{
return TWO_FACTOR_TOKEN;
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

style: async keyword unnecessary for synchronous method

Comment on lines +92 to +95
public override async Task<bool> VerifyTwoFactorTokenAsync(TUser user, string tokenProvider, string token)
{
return TWO_FACTOR_TOKEN_VERIFIED;
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

style: async keyword unnecessary for synchronous method

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants