diff --git a/server/skillhub-auth/src/main/java/com/iflytek/skillhub/auth/identity/ProviderAuthorityStateTransaction.java b/server/skillhub-auth/src/main/java/com/iflytek/skillhub/auth/identity/ProviderAuthorityStateTransaction.java index e4434110..75e08b17 100644 --- a/server/skillhub-auth/src/main/java/com/iflytek/skillhub/auth/identity/ProviderAuthorityStateTransaction.java +++ b/server/skillhub-auth/src/main/java/com/iflytek/skillhub/auth/identity/ProviderAuthorityStateTransaction.java @@ -106,6 +106,20 @@ class ProviderAuthorityStateTransaction { .orElse(new AuthorityLockEvaluation( IdentityProviderStatus.MISCONFIGURED, null)); + if (authority.ready() + && !expectedFingerprint.equals( + authority.persistedFingerprint())) { + stateRepository.markAuthorityMismatch( + descriptor.providerCode(), + descriptor.protocol(), + expectedFingerprint); + authority = stateRepository + .findById(descriptor.providerCode()) + .map(this::evaluation) + .orElse(new AuthorityLockEvaluation( + IdentityProviderStatus.MISCONFIGURED, + null)); + } boolean recovered = updated == 1 && authority.ready() && expectedFingerprint.equals( diff --git a/server/skillhub-auth/src/test/java/com/iflytek/skillhub/auth/identity/ProviderAuthorityStateTransactionTest.java b/server/skillhub-auth/src/test/java/com/iflytek/skillhub/auth/identity/ProviderAuthorityStateTransactionTest.java index 7dacf63d..8a180a0a 100644 --- a/server/skillhub-auth/src/test/java/com/iflytek/skillhub/auth/identity/ProviderAuthorityStateTransactionTest.java +++ b/server/skillhub-auth/src/test/java/com/iflytek/skillhub/auth/identity/ProviderAuthorityStateTransactionTest.java @@ -346,6 +346,59 @@ class ProviderAuthorityStateTransactionTest { org.mockito.ArgumentMatchers.any()); } + @Test + void readyStateWithDifferentFingerprintIsPersistedAsMismatch() { + String differentFingerprint = "a".repeat(64); + IdentityProviderState staleReady = IdentityProviderState.ready( + "github", + "oauth2-github", + "https://github.example", + differentFingerprint, + NOW); + IdentityProviderState mismatch = + IdentityProviderState.authorityMismatch( + "github", + "oauth2-github", + "https://github.example", + differentFingerprint, + NOW); + when(stateRepository.recoverSameAuthority( + "github", + "oauth2-github", + FINGERPRINT)).thenReturn(0); + when(stateRepository.findById("github")) + .thenReturn( + Optional.of(staleReady), + Optional.of(mismatch)); + when(stateRepository.markAuthorityMismatch( + "github", + "oauth2-github", + FINGERPRINT)).thenReturn(1); + + SameAuthorityRecoveryEvaluation recovery = + transaction.recoverSameAuthority( + GITHUB, + FINGERPRINT, + recoveryContext()); + + assertThat(recovery.recovered()).isFalse(); + assertThat(recovery.authority().state()) + .isEqualTo(IdentityProviderStatus.AUTHORITY_MISMATCH); + verify(stateRepository).markAuthorityMismatch( + "github", + "oauth2-github", + FINGERPRINT); + verify(auditLogService, never()).record( + org.mockito.ArgumentMatchers.any(), + org.mockito.ArgumentMatchers.any(), + org.mockito.ArgumentMatchers.any(), + org.mockito.ArgumentMatchers.any(), + org.mockito.ArgumentMatchers.any(), + org.mockito.ArgumentMatchers.any(), + org.mockito.ArgumentMatchers.any(), + org.mockito.ArgumentMatchers.any()); + } + private static ProviderDescriptor githubDescriptor() { return new ProviderDescriptor( "github",