From e98bc42f71aa1cb8dc912bc52e7708e5a2fd1976 Mon Sep 17 00:00:00 2001 From: Longze Chen Date: Thu, 8 Aug 2024 15:56:23 -0400 Subject: [PATCH 1/2] Fix totp secret parsing Now it supports both pre and post python 3.12 upgrade --- src/main/java/io/cos/cas/osf/model/OsfTotp.java | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/main/java/io/cos/cas/osf/model/OsfTotp.java b/src/main/java/io/cos/cas/osf/model/OsfTotp.java index b89c4dfe..7d16ab09 100644 --- a/src/main/java/io/cos/cas/osf/model/OsfTotp.java +++ b/src/main/java/io/cos/cas/osf/model/OsfTotp.java @@ -4,6 +4,7 @@ import lombok.Getter; import lombok.NoArgsConstructor; import lombok.ToString; +import lombok.extern.slf4j.Slf4j; import org.apache.commons.codec.binary.Base32; @@ -28,6 +29,7 @@ @NoArgsConstructor @Getter @ToString +@Slf4j public class OsfTotp extends AbstractOsfModel { @OneToOne @@ -50,8 +52,14 @@ private boolean isDeleted() { } public String getTotpSecretBase32() { - final byte[] bytes = DatatypeConverter.parseHexBinary(totpSecret); - return new Base32().encodeAsString(bytes); + try { + // Handle totpSecret generated before OSF Python 3.12 upgrade + final byte[] bytes = DatatypeConverter.parseHexBinary(totpSecret); + return new Base32().encodeAsString(bytes); + } catch (final IllegalArgumentException e) { + // Handle totpSecret generated after OSF Python 3.12 upgrade + return new Base32().encodeAsString(totpSecret.getBytes()); + } } public boolean isActive() { From 06b41000f74d9c2f81eb0a96eed1ac0e55e2e214 Mon Sep 17 00:00:00 2001 From: Longze Chen Date: Thu, 8 Aug 2024 15:59:21 -0400 Subject: [PATCH 2/2] Fix exception handlling Both types of topt failures are now thown correctly --- .../support/OsfPostgresAuthenticationHandler.java | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/main/java/io/cos/cas/osf/authentication/handler/support/OsfPostgresAuthenticationHandler.java b/src/main/java/io/cos/cas/osf/authentication/handler/support/OsfPostgresAuthenticationHandler.java index e149eb51..3d43cf1d 100644 --- a/src/main/java/io/cos/cas/osf/authentication/handler/support/OsfPostgresAuthenticationHandler.java +++ b/src/main/java/io/cos/cas/osf/authentication/handler/support/OsfPostgresAuthenticationHandler.java @@ -165,14 +165,16 @@ protected final AuthenticationHandlerExecutionResult authenticateOsfPostgresInte if (oneTimePassword == null) { throw new OneTimePasswordRequiredException("2FA TOTP required for user [" + username + "]"); } + final long transformedOneTimePassword = Long.parseLong(oneTimePassword); + boolean checkPassed; try { - final long transformedOneTimePassword = Long.parseLong(oneTimePassword); - if (!TotpUtils.checkCode(osfTotp.getTotpSecretBase32(), transformedOneTimePassword)) { - throw new InvalidOneTimePasswordException("Invalid 2FA TOTP for user [" + username + "] (Type 1)"); - } - } catch (final Exception e) { + checkPassed = TotpUtils.checkCode(osfTotp.getTotpSecretBase32(), transformedOneTimePassword); + } catch (final Exception e){ throw new InvalidOneTimePasswordException("Invalid 2FA TOTP for user [" + username + "] (Type 2)"); } + if (!checkPassed) { + throw new InvalidOneTimePasswordException("Invalid 2FA TOTP for user [" + username + "] (Type 1)"); + } } if (!osfUser.isTermsOfServiceAccepted() && !isTermsOfServiceChecked) {