This is an automated email from the ASF dual-hosted git repository.

collado pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/polaris.git


The following commit(s) were added to refs/heads/main by this push:
     new f5240884 Fix BasePolarisAuthenticator to throw service exception 
during persistence errors (#707)
f5240884 is described below

commit f52408843914a362194c9f4cf854262502e11592
Author: Michael Collado <[email protected]>
AuthorDate: Sun Jan 12 10:03:49 2025 -0800

    Fix BasePolarisAuthenticator to throw service exception during persistence 
errors (#707)
---
 service/common/build.gradle.kts                    |  6 ++
 .../service/auth/BasePolarisAuthenticator.java     |  9 ++-
 .../service/auth/BasePolarisAuthenticatorTest.java | 87 ++++++++++++++++++++++
 3 files changed, 101 insertions(+), 1 deletion(-)

diff --git a/service/common/build.gradle.kts b/service/common/build.gradle.kts
index e027641a..7aad2239 100644
--- a/service/common/build.gradle.kts
+++ b/service/common/build.gradle.kts
@@ -81,4 +81,10 @@ dependencies {
 
   implementation(platform(libs.azuresdk.bom))
   implementation("com.azure:azure-core")
+
+  testImplementation(platform(libs.junit.bom))
+  testImplementation("org.junit.jupiter:junit-jupiter")
+  testImplementation(libs.assertj.core)
+  testImplementation(libs.mockito.core)
+  testRuntimeOnly("org.junit.platform:junit-platform-launcher")
 }
diff --git 
a/service/common/src/main/java/org/apache/polaris/service/auth/BasePolarisAuthenticator.java
 
b/service/common/src/main/java/org/apache/polaris/service/auth/BasePolarisAuthenticator.java
index 28dd9e0e..93c6f664 100644
--- 
a/service/common/src/main/java/org/apache/polaris/service/auth/BasePolarisAuthenticator.java
+++ 
b/service/common/src/main/java/org/apache/polaris/service/auth/BasePolarisAuthenticator.java
@@ -18,6 +18,7 @@
  */
 package org.apache.polaris.service.auth;
 
+import com.google.common.annotations.VisibleForTesting;
 import jakarta.inject.Inject;
 import java.util.Arrays;
 import java.util.HashSet;
@@ -25,6 +26,7 @@ import java.util.Optional;
 import java.util.Set;
 import org.apache.commons.lang3.exception.ExceptionUtils;
 import org.apache.iceberg.exceptions.NotAuthorizedException;
+import org.apache.iceberg.exceptions.ServiceFailureException;
 import org.apache.polaris.core.PolarisCallContext;
 import org.apache.polaris.core.auth.AuthenticatedPolarisPrincipal;
 import org.apache.polaris.core.context.CallContext;
@@ -82,7 +84,7 @@ public abstract class BasePolarisAuthenticator
           .addKeyValue("errMsg", e.getMessage())
           .addKeyValue("stackTrace", ExceptionUtils.getStackTrace(e))
           .log("Unable to authenticate user with token");
-      throw new NotAuthorizedException("Unable to authenticate");
+      throw new ServiceFailureException("Unable to fetch principal entity");
     }
     if (principal == null) {
       LOGGER.warn(
@@ -113,4 +115,9 @@ public abstract class BasePolarisAuthenticator
         .put(CallContext.AUTHENTICATED_PRINCIPAL, authenticatedPrincipal);
     return Optional.of(authenticatedPrincipal);
   }
+
+  @VisibleForTesting
+  void setMetaStoreManagerFactory(MetaStoreManagerFactory 
metaStoreManagerFactory) {
+    this.metaStoreManagerFactory = metaStoreManagerFactory;
+  }
 }
diff --git 
a/service/common/src/test/java/org/apache/polaris/service/auth/BasePolarisAuthenticatorTest.java
 
b/service/common/src/test/java/org/apache/polaris/service/auth/BasePolarisAuthenticatorTest.java
new file mode 100644
index 00000000..f64751d4
--- /dev/null
+++ 
b/service/common/src/test/java/org/apache/polaris/service/auth/BasePolarisAuthenticatorTest.java
@@ -0,0 +1,87 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.polaris.service.auth;
+
+import static org.mockito.Mockito.when;
+
+import org.apache.iceberg.exceptions.NotAuthorizedException;
+import org.apache.iceberg.exceptions.ServiceFailureException;
+import org.apache.polaris.core.PolarisCallContext;
+import org.apache.polaris.core.context.CallContext;
+import org.apache.polaris.core.context.RealmContext;
+import org.apache.polaris.core.persistence.BaseResult;
+import org.apache.polaris.core.persistence.MetaStoreManagerFactory;
+import org.apache.polaris.core.persistence.PolarisMetaStoreManager;
+import org.assertj.core.api.Assertions;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.mockito.Mockito;
+
+public class BasePolarisAuthenticatorTest {
+
+  private BasePolarisAuthenticator authenticator;
+  private PolarisMetaStoreManager metaStoreManager;
+  private PolarisCallContext polarisCallContext;
+  private CallContext callContext;
+
+  @BeforeEach
+  public void setUp() {
+    authenticator = Mockito.spy(BasePolarisAuthenticator.class);
+    MetaStoreManagerFactory metaStoreManagerFactory = 
Mockito.mock(MetaStoreManagerFactory.class);
+    authenticator.setMetaStoreManagerFactory(metaStoreManagerFactory);
+    RealmContext realmContext = Mockito.mock(RealmContext.class);
+    metaStoreManager = Mockito.mock(PolarisMetaStoreManager.class);
+    when(metaStoreManagerFactory.getOrCreateMetaStoreManager(realmContext))
+        .thenReturn(metaStoreManager);
+    polarisCallContext = Mockito.mock(PolarisCallContext.class);
+    callContext = CallContext.of(realmContext, polarisCallContext);
+  }
+
+  @Test
+  public void testFetchPrincipalThrowsServiceExceptionOnMetastoreException() {
+    DecodedToken token = Mockito.mock(DecodedToken.class);
+    long principalId = 100L;
+    when(token.getPrincipalId()).thenReturn(principalId);
+    when(metaStoreManager.loadEntity(polarisCallContext, 0L, principalId))
+        .thenThrow(new RuntimeException("Metastore exception"));
+
+    try (CallContext ctx = CallContext.setCurrentContext(callContext)) {
+      Assertions.assertThatThrownBy(() -> authenticator.getPrincipal(token))
+          .isInstanceOf(ServiceFailureException.class)
+          .hasMessage("Unable to fetch principal entity");
+    }
+  }
+
+  @Test
+  public void testFetchPrincipalThrowsNotAuthorizedWhenNotFound() {
+    DecodedToken token = Mockito.mock(DecodedToken.class);
+    long principalId = 100L;
+    when(token.getPrincipalId()).thenReturn(principalId);
+    when(token.getClientId()).thenReturn("abc");
+    when(metaStoreManager.loadEntity(polarisCallContext, 0L, principalId))
+        .thenReturn(
+            new 
PolarisMetaStoreManager.EntityResult(BaseResult.ReturnStatus.ENTITY_NOT_FOUND, 
""));
+
+    try (CallContext ctx = CallContext.setCurrentContext(callContext)) {
+      Assertions.assertThatThrownBy(() -> authenticator.getPrincipal(token))
+          .isInstanceOf(NotAuthorizedException.class)
+          .hasMessage("Unable to authenticate");
+    }
+  }
+}

Reply via email to