Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@
import com.google.common.collect.HashMultimap;
import com.google.common.collect.Multimap;
import jakarta.annotation.Nullable;
import jakarta.ws.rs.core.SecurityContext;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
Expand Down Expand Up @@ -52,7 +51,7 @@ public class PolarisResolutionManifest implements PolarisResolutionManifestCatal
private static final Logger LOGGER = LoggerFactory.getLogger(PolarisResolutionManifest.class);

private final ResolverFactory resolverFactory;
private final SecurityContext securityContext;
private final PolarisPrincipal principal;
private final RealmContext realmContext;
private final String catalogName;
private final Resolver primaryResolver;
Expand All @@ -73,20 +72,15 @@ public PolarisResolutionManifest(
PolarisDiagnostics diagnostics,
RealmContext realmContext,
ResolverFactory resolverFactory,
SecurityContext securityContext,
PolarisPrincipal principal,
String catalogName) {
this.realmContext = realmContext;
this.resolverFactory = resolverFactory;
this.catalogName = catalogName;
this.primaryResolver = resolverFactory.createResolver(securityContext, catalogName);
this.diagnostics = diagnostics;
this.diagnostics.checkNotNull(securityContext, "null_security_context_for_resolution_manifest");
this.securityContext = securityContext;
diagnostics.check(
securityContext.getUserPrincipal() instanceof PolarisPrincipal,
"invalid_principal_type_for_resolution_manifest",
"principal={}",
securityContext.getUserPrincipal());
this.diagnostics.checkNotNull(principal, "null_principal_for_resolution_manifest");
this.principal = principal;
this.primaryResolver = resolverFactory.createResolver(principal, catalogName);

// TODO: Make the rootContainer lookup no longer optional in the persistence store.
// For now, we'll try to resolve the rootContainer as "optional", and only if we fail to find
Expand Down Expand Up @@ -186,7 +180,7 @@ public PolarisResolvedPathWrapper getPassthroughResolvedPath(Object key) {
ResolverPath requestedPath = passthroughPaths.get(key);

// Run a single-use Resolver for this path.
Resolver passthroughResolver = resolverFactory.createResolver(securityContext, catalogName);
Resolver passthroughResolver = resolverFactory.createResolver(principal, catalogName);
passthroughResolver.addPath(requestedPath);
ResolverStatus status = passthroughResolver.resolveAll();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,11 @@

import jakarta.annotation.Nonnull;
import jakarta.annotation.Nullable;
import jakarta.ws.rs.core.SecurityContext;
import org.apache.polaris.core.auth.PolarisPrincipal;

public interface ResolutionManifestFactory {

@Nonnull
PolarisResolutionManifest createResolutionManifest(
@Nonnull SecurityContext securityContext, @Nullable String referenceCatalogName);
@Nonnull PolarisPrincipal principal, @Nullable String referenceCatalogName);
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@

import jakarta.annotation.Nonnull;
import jakarta.annotation.Nullable;
import jakarta.ws.rs.core.SecurityContext;
import org.apache.polaris.core.PolarisDiagnostics;
import org.apache.polaris.core.auth.PolarisPrincipal;
import org.apache.polaris.core.context.RealmContext;

public class ResolutionManifestFactoryImpl implements ResolutionManifestFactory {
Expand All @@ -43,8 +43,8 @@ public ResolutionManifestFactoryImpl(
@Nonnull
@Override
public PolarisResolutionManifest createResolutionManifest(
@Nonnull SecurityContext securityContext, @Nullable String referenceCatalogName) {
@Nonnull PolarisPrincipal principal, @Nullable String referenceCatalogName) {
return new PolarisResolutionManifest(
diagnostics, realmContext, resolverFactory, securityContext, referenceCatalogName);
diagnostics, realmContext, resolverFactory, principal, referenceCatalogName);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@

import jakarta.annotation.Nonnull;
import jakarta.annotation.Nullable;
import jakarta.ws.rs.core.SecurityContext;
import java.util.AbstractSet;
import java.util.ArrayList;
import java.util.HashMap;
Expand Down Expand Up @@ -116,7 +115,7 @@ public class Resolver {
*
* @param polarisCallContext the polaris call context
* @param polarisMetaStoreManager meta store manager
* @param securityContext The {@link SecurityContext} for the current request
* @param principal The {@link PolarisPrincipal} for the current request
* @param cache shared entity cache
* @param referenceCatalogName if not null, specifies the name of the reference catalog. The
* reference catalog is the catalog used to resolve catalog roles and catalog path. Also, if a
Expand All @@ -130,7 +129,7 @@ public Resolver(
@Nonnull PolarisDiagnostics diagnostics,
@Nonnull PolarisCallContext polarisCallContext,
@Nonnull PolarisMetaStoreManager polarisMetaStoreManager,
@Nonnull SecurityContext securityContext,
@Nonnull PolarisPrincipal principal,
@Nullable EntityCache cache,
@Nullable String referenceCatalogName) {
this.polarisCallContext = polarisCallContext;
Expand All @@ -143,16 +142,9 @@ public Resolver(
this.diagnostics.checkNotNull(polarisCallContext, "unexpected_null_polarisCallContext");
this.diagnostics.checkNotNull(
polarisMetaStoreManager, "unexpected_null_polarisMetaStoreManager");
this.diagnostics.checkNotNull(securityContext, "security_context_must_be_specified");
this.diagnostics.checkNotNull(
securityContext.getUserPrincipal(), "principal_must_be_specified");
this.diagnostics.check(
securityContext.getUserPrincipal() instanceof PolarisPrincipal,
"unexpected_principal_type",
"class={}",
securityContext.getUserPrincipal().getClass().getName());
this.diagnostics.checkNotNull(principal, "principal_must_be_specified");

this.polarisPrincipal = (PolarisPrincipal) securityContext.getUserPrincipal();
this.polarisPrincipal = principal;
// paths to resolve
this.pathsToResolve = new ArrayList<>();
this.resolvedPaths = new ArrayList<>();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,9 @@

import jakarta.annotation.Nonnull;
import jakarta.annotation.Nullable;
import jakarta.ws.rs.core.SecurityContext;
import org.apache.polaris.core.auth.PolarisPrincipal;

public interface ResolverFactory {
Resolver createResolver(
@Nonnull SecurityContext securityContext, @Nullable String referenceCatalogName);
@Nonnull PolarisPrincipal principal, @Nullable String referenceCatalogName);
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,6 @@

import jakarta.annotation.Nonnull;
import jakarta.annotation.Nullable;
import jakarta.ws.rs.core.SecurityContext;
import java.security.Principal;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.Iterator;
Expand Down Expand Up @@ -442,29 +440,7 @@ private Resolver allocateResolver(
diagServices,
callCtx(),
metaStoreManager(),
new SecurityContext() {
@Override
public Principal getUserPrincipal() {
return authenticatedPrincipal;
}

@Override
public boolean isUserInRole(String role) {
return roleEntities
.map(l -> l.stream().map(PrincipalRoleEntity::getName).anyMatch(role::equals))
.orElse(allRoles);
}

@Override
public boolean isSecure() {
return false;
}

@Override
public String getAuthenticationScheme() {
return "";
}
},
authenticatedPrincipal,
this.shouldUseCache ? this.cache : null,
referenceCatalogName);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@
import jakarta.annotation.Nullable;
import jakarta.enterprise.context.RequestScoped;
import jakarta.inject.Inject;
import jakarta.ws.rs.core.SecurityContext;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
Expand All @@ -47,7 +46,6 @@
import org.apache.iceberg.exceptions.NotFoundException;
import org.apache.iceberg.exceptions.ValidationException;
import org.apache.polaris.core.PolarisCallContext;
import org.apache.polaris.core.PolarisDiagnostics;
import org.apache.polaris.core.admin.model.AuthenticationParameters;
import org.apache.polaris.core.admin.model.BearerAuthenticationParameters;
import org.apache.polaris.core.admin.model.Catalog;
Expand Down Expand Up @@ -146,7 +144,6 @@ public class PolarisAdminService {
private final CallContext callContext;
private final RealmConfig realmConfig;
private final ResolutionManifestFactory resolutionManifestFactory;
private final SecurityContext securityContext;
private final PolarisPrincipal polarisPrincipal;
private final PolarisAuthorizer authorizer;
private final PolarisMetaStoreManager metaStoreManager;
Expand All @@ -156,28 +153,19 @@ public class PolarisAdminService {

@Inject
public PolarisAdminService(
@Nonnull PolarisDiagnostics diagnostics,
@Nonnull CallContext callContext,
@Nonnull ResolutionManifestFactory resolutionManifestFactory,
@Nonnull PolarisMetaStoreManager metaStoreManager,
@Nonnull UserSecretsManager userSecretsManager,
@Nonnull ServiceIdentityProvider serviceIdentityProvider,
@Nonnull SecurityContext securityContext,
@Nonnull PolarisPrincipal principal,
@Nonnull PolarisAuthorizer authorizer,
@Nonnull ReservedProperties reservedProperties) {
this.callContext = callContext;
this.realmConfig = callContext.getRealmConfig();
this.resolutionManifestFactory = resolutionManifestFactory;
this.metaStoreManager = metaStoreManager;
this.securityContext = securityContext;
diagnostics.checkNotNull(securityContext, "null_security_context");
diagnostics.checkNotNull(securityContext.getUserPrincipal(), "null_security_context");
diagnostics.check(
securityContext.getUserPrincipal() instanceof PolarisPrincipal,
"unexpected_principal_type",
"class={}",
securityContext.getUserPrincipal().getClass().getName());
this.polarisPrincipal = (PolarisPrincipal) securityContext.getUserPrincipal();
this.polarisPrincipal = principal;
this.authorizer = authorizer;
this.userSecretsManager = userSecretsManager;
this.serviceIdentityProvider = serviceIdentityProvider;
Expand All @@ -197,7 +185,7 @@ private ServiceIdentityProvider getServiceIdentityProvider() {
}

private PolarisResolutionManifest newResolutionManifest(@Nullable String catalogName) {
return resolutionManifestFactory.createResolutionManifest(securityContext, catalogName);
return resolutionManifestFactory.createResolutionManifest(polarisPrincipal, catalogName);
}

private static PrincipalEntity getPrincipalByName(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,11 @@ default Namespace decodeNamespace(String namespace) {
return RESTUtil.decodeNamespace(URLEncoder.encode(namespace, Charset.defaultCharset()));
}

default void validatePrincipal(SecurityContext securityContext) {
var authenticatedPrincipal = (PolarisPrincipal) securityContext.getUserPrincipal();
if (authenticatedPrincipal == null) {
throw new NotAuthorizedException("Failed to find authenticatedPrincipal in SecurityContext");
default PolarisPrincipal validatePrincipal(SecurityContext securityContext) {
var authenticatedPrincipal = securityContext.getUserPrincipal();
if (authenticatedPrincipal instanceof PolarisPrincipal polarisPrincipal) {
return polarisPrincipal;
}
throw new NotAuthorizedException("Failed to find authenticatedPrincipal in SecurityContext");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@
import static org.apache.polaris.core.entity.PolarisEntitySubType.ICEBERG_TABLE;

import jakarta.enterprise.inject.Instance;
import jakarta.ws.rs.core.SecurityContext;
import java.util.Arrays;
import java.util.EnumSet;
import java.util.List;
Expand Down Expand Up @@ -70,13 +69,12 @@ public abstract class CatalogHandler {
protected final CallContext callContext;
protected final RealmConfig realmConfig;
protected final PolarisPrincipal polarisPrincipal;
protected final SecurityContext securityContext;

public CatalogHandler(
PolarisDiagnostics diagnostics,
CallContext callContext,
ResolutionManifestFactory resolutionManifestFactory,
SecurityContext securityContext,
PolarisPrincipal principal,
String catalogName,
PolarisAuthorizer authorizer,
PolarisCredentialManager credentialManager,
Expand All @@ -86,14 +84,7 @@ public CatalogHandler(
this.realmConfig = callContext.getRealmConfig();
this.resolutionManifestFactory = resolutionManifestFactory;
this.catalogName = catalogName;
diagnostics.checkNotNull(securityContext, "null_security_context");
diagnostics.checkNotNull(securityContext.getUserPrincipal(), "null_user_principal");
diagnostics.check(
securityContext.getUserPrincipal() instanceof PolarisPrincipal,
"invalid_principal_type",
"Principal must be a PolarisPrincipal");
this.securityContext = securityContext;
this.polarisPrincipal = (PolarisPrincipal) securityContext.getUserPrincipal();
this.polarisPrincipal = principal;
this.authorizer = authorizer;
this.credentialManager = credentialManager;
this.externalCatalogFactories = externalCatalogFactories;
Expand All @@ -104,7 +95,7 @@ protected PolarisCredentialManager getPolarisCredentialManager() {
}

protected PolarisResolutionManifest newResolutionManifest() {
return resolutionManifestFactory.createResolutionManifest(securityContext, catalogName);
return resolutionManifestFactory.createResolutionManifest(polarisPrincipal, catalogName);
}

/** Initialize the catalog once authorized. Called after all `authorize...` methods. */
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
import org.apache.iceberg.catalog.TableIdentifier;
import org.apache.polaris.core.PolarisDiagnostics;
import org.apache.polaris.core.auth.PolarisAuthorizer;
import org.apache.polaris.core.auth.PolarisPrincipal;
import org.apache.polaris.core.catalog.ExternalCatalogFactory;
import org.apache.polaris.core.config.FeatureConfiguration;
import org.apache.polaris.core.config.RealmConfig;
Expand Down Expand Up @@ -92,14 +93,14 @@ private GenericTableCatalogHandler newHandlerWrapper(
SecurityContext securityContext, String prefix) {
FeatureConfiguration.enforceFeatureEnabledOrThrow(
realmConfig, FeatureConfiguration.ENABLE_GENERIC_TABLES);
validatePrincipal(securityContext);
PolarisPrincipal principal = validatePrincipal(securityContext);

return new GenericTableCatalogHandler(
diagnostics,
callContext,
resolutionManifestFactory,
metaStoreManager,
securityContext,
principal,
prefixParser.prefixToCatalogName(realmContext, prefix),
polarisAuthorizer,
polarisCredentialManager,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,14 @@

import io.smallrye.common.annotation.Identifier;
import jakarta.enterprise.inject.Instance;
import jakarta.ws.rs.core.SecurityContext;
import java.util.LinkedHashSet;
import java.util.Map;
import org.apache.iceberg.catalog.Namespace;
import org.apache.iceberg.catalog.TableIdentifier;
import org.apache.polaris.core.PolarisDiagnostics;
import org.apache.polaris.core.auth.PolarisAuthorizableOperation;
import org.apache.polaris.core.auth.PolarisAuthorizer;
import org.apache.polaris.core.auth.PolarisPrincipal;
import org.apache.polaris.core.catalog.ExternalCatalogFactory;
import org.apache.polaris.core.catalog.GenericTableCatalog;
import org.apache.polaris.core.config.FeatureConfiguration;
Expand Down Expand Up @@ -59,7 +59,7 @@ public GenericTableCatalogHandler(
CallContext callContext,
ResolutionManifestFactory resolutionManifestFactory,
PolarisMetaStoreManager metaStoreManager,
SecurityContext securityContext,
PolarisPrincipal principal,
String catalogName,
PolarisAuthorizer authorizer,
PolarisCredentialManager polarisCredentialManager,
Expand All @@ -68,7 +68,7 @@ public GenericTableCatalogHandler(
diagnostics,
callContext,
resolutionManifestFactory,
securityContext,
principal,
catalogName,
authorizer,
polarisCredentialManager,
Expand Down
Loading