Skip to content

Commit

Permalink
Use an exact type match to consider base type as unsupported
Browse files Browse the repository at this point in the history
  • Loading branch information
boarnoah committed Jul 8, 2024
1 parent 19413d4 commit b57bf15
Show file tree
Hide file tree
Showing 3 changed files with 19 additions and 20 deletions.
4 changes: 2 additions & 2 deletions src/D2L.Bmx/ConsolePrompter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ internal interface IConsolePrompter {
int? PromptDuration();
string PromptAccount( string[] accounts );
string PromptRole( string[] roles );
OktaMfaFactor SelectMfa( OktaMfaFactor[] mfaOptions );
UnsupportedOktaMfaFactor SelectMfa( UnsupportedOktaMfaFactor[] mfaOptions );
string GetMfaResponse( string mfaInputPrompt, bool maskInput );
}

Expand Down Expand Up @@ -122,7 +122,7 @@ string IConsolePrompter.PromptRole( string[] roles ) {
return roles[index - 1];
}

OktaMfaFactor IConsolePrompter.SelectMfa( OktaMfaFactor[] mfaOptions ) {
UnsupportedOktaMfaFactor IConsolePrompter.SelectMfa( UnsupportedOktaMfaFactor[] mfaOptions ) {
Console.Error.WriteLine( "MFA Required" );

if( mfaOptions.Length == 0 ) {
Expand Down
27 changes: 13 additions & 14 deletions src/D2L.Bmx/Okta/Models/AuthenticateResponse.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
namespace D2L.Bmx.Okta.Models;

internal abstract record AuthenticateResponse {
public record MfaRequired( string StateToken, OktaMfaFactor[] Factors ) : AuthenticateResponse;
public record MfaRequired( string StateToken, UnsupportedOktaMfaFactor[] Factors ) : AuthenticateResponse;
public record Success( string SessionToken ) : AuthenticateResponse;
}

Expand All @@ -18,36 +18,35 @@ internal record AuthenticateResponseRaw(
);

internal record AuthenticateResponseEmbedded(
OktaMfaFactor[]? Factors
UnsupportedOktaMfaFactor[]? Factors
);

[JsonPolymorphic(
TypeDiscriminatorPropertyName = "factorType",
IgnoreUnrecognizedTypeDiscriminators = true
)]
[JsonDerivedType( typeof( OktaMfaQuestionFactor ), OktaMfaQuestionFactor.FactorType )]
[JsonDerivedType( typeof( UnsupportedOktaMfaQuestionFactor ), UnsupportedOktaMfaQuestionFactor.FactorType )]
[JsonDerivedType( typeof( OktaMfaTokenFactor ), OktaMfaTokenFactor.FactorType )]
[JsonDerivedType( typeof( OktaMfaHardwareTokenFactor ), OktaMfaHardwareTokenFactor.FactorType )]
[JsonDerivedType( typeof( OktaMfaSoftwareTotpFactor ), OktaMfaSoftwareTotpFactor.FactorType )]
[JsonDerivedType( typeof( OktaMfaHotpFactor ), OktaMfaHotpFactor.FactorType )]
[JsonDerivedType( typeof( OktaMfaSmsFactor ), OktaMfaSmsFactor.FactorType )]
[JsonDerivedType( typeof( OktaMfaCallFactor ), OktaMfaCallFactor.FactorType )]
[JsonDerivedType( typeof( OktaMfaEmailFactor ), OktaMfaEmailFactor.FactorType )]
internal record OktaMfaFactor {
internal abstract record UnsupportedOktaMfaFactor {
public required string Id { get; set; }
public required string Provider { get; set; }
public required string VendorName { get; set; }

public const string FactorType = "unknown";
[JsonIgnore]
public virtual string FactorName => "unknown";
[JsonIgnore]
public virtual bool RequireChallengeIssue => false;
}

internal record OktaMfaQuestionFactor(
internal record UnsupportedOktaMfaQuestionFactor(
OktaMfaQuestionProfile Profile
) : OktaMfaFactor {
) : UnsupportedOktaMfaFactor {
public const string FactorType = "question";
public override string FactorName => "Security Question";
}
Expand All @@ -56,39 +55,39 @@ internal record OktaMfaQuestionProfile(
string QuestionText
);

internal record OktaMfaTokenFactor() : OktaMfaFactor {
internal record OktaMfaTokenFactor : UnsupportedOktaMfaFactor {
public const string FactorType = "token";
public override string FactorName => "Token";
}

internal record OktaMfaHardwareTokenFactor() : OktaMfaFactor {
internal record OktaMfaHardwareTokenFactor : UnsupportedOktaMfaFactor {
public const string FactorType = "token:hardware";
public override string FactorName => "Hardware Token";
}

internal record OktaMfaSoftwareTotpFactor() : OktaMfaFactor {
internal record OktaMfaSoftwareTotpFactor : UnsupportedOktaMfaFactor {
public const string FactorType = "token:software:totp";
public override string FactorName => "Software TOTP";
}

internal record OktaMfaHotpFactor() : OktaMfaFactor {
internal record OktaMfaHotpFactor : UnsupportedOktaMfaFactor {
public const string FactorType = "token:hotp";
public override string FactorName => "HOTP";
}

internal record OktaMfaSmsFactor() : OktaMfaFactor {
internal record OktaMfaSmsFactor : UnsupportedOktaMfaFactor {
public const string FactorType = "sms";
public override string FactorName => "SMS";
public override bool RequireChallengeIssue => true;
}

internal record OktaMfaCallFactor() : OktaMfaFactor {
internal record OktaMfaCallFactor : UnsupportedOktaMfaFactor {
public const string FactorType = "call";
public override string FactorName => "Call";
public override bool RequireChallengeIssue => true;
}

internal record OktaMfaEmailFactor() : OktaMfaFactor {
internal record OktaMfaEmailFactor : UnsupportedOktaMfaFactor {
public const string FactorType = "email";
public override string FactorName => "Email";
public override bool RequireChallengeIssue => true;
Expand Down
8 changes: 4 additions & 4 deletions src/D2L.Bmx/OktaAuthenticator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -55,9 +55,9 @@ bool ignoreCache
var authnResponse = await oktaApi.AuthenticateAsync( user, password );

if( authnResponse is AuthenticateResponse.MfaRequired mfaInfo ) {
OktaMfaFactor mfaFactor = consolePrompter.SelectMfa( mfaInfo.Factors );
UnsupportedOktaMfaFactor mfaFactor = consolePrompter.SelectMfa( mfaInfo.Factors );

if( mfaFactor.FactorName == OktaMfaFactor.FactorType ) {
if (mfaFactor.GetType() == typeof(UnsupportedOktaMfaFactor)) {
throw new BmxException( "Selected MFA not supported by BMX" );
}

Expand All @@ -67,8 +67,8 @@ bool ignoreCache
}

string mfaResponse = consolePrompter.GetMfaResponse(
mfaFactor is OktaMfaQuestionFactor questionFactor ? questionFactor.Profile.QuestionText : "PassCode",
mfaFactor is OktaMfaQuestionFactor // Security question factor is a static value
mfaFactor is UnsupportedOktaMfaQuestionFactor questionFactor ? questionFactor.Profile.QuestionText : "PassCode",
mfaFactor is UnsupportedOktaMfaQuestionFactor // Security question factor is a static value
);

authnResponse = await oktaApi.VerifyMfaChallengeResponseAsync( mfaInfo.StateToken, mfaFactor.Id, mfaResponse );
Expand Down

0 comments on commit b57bf15

Please sign in to comment.