Repository navigation
Conversation
|
FYI: @gracechen09 @sungwy : this is still WIP, but please feel free to post early review comments. |
ca1c1b9 to
b27c77e
Compare
| when(resolutionManifest.resolveAll()).thenReturn(successStatus); | ||
| when(resolutionManifest.getPrimaryResolverStatusOrThrow()).thenReturn(successStatus); | ||
| when(resolutionManifest.getIsPassthroughFacade()).thenReturn(false); | ||
| doAnswer( |
There was a problem hiding this comment.
This mock happens to be unnecessary 🤷
1aa359b to
49d87e4
Compare
| public void resolve() { | ||
| if (selections.isEmpty()) { | ||
| resolutionManifest.resolveAll(); |
There was a problem hiding this comment.
I find this semantic a bit confusing - can we just have the Authorizer selectAll() before resolving?
There was a problem hiding this comment.
The built-in Authorizer does that.
For OPA and Ranger some selections come from the authorizer, others from PolarisAdminService.authorizeBasicTopLevelEntityOperationOrThrow(), but we can (should) only resolve once.
I guess we can lose the "select all" flag if selectAll() is called first, and select(X) later... I'll fix that.
| import org.jspecify.annotations.NonNull; | ||
|
|
||
| /** | ||
| * Utility class for processing {@linke AuthorizationRequest} in context that do not involve |
There was a problem hiding this comment.
nit: typo
| * Utility class for processing {@linke AuthorizationRequest} in context that do not involve | |
| * Utility class for processing {@linke AuthorizationRequest} in contexts that do not involve |
| if (intent instanceof TargetlessAuthorizationIntent) { | ||
| authzState.select(REQUESTED_TOP_LEVEL_ENTITIES); | ||
| } else { | ||
| intent.visitSecurables((securable) -> mergeSelections(authzState, securable)); |
There was a problem hiding this comment.
I like the consumer based approach 👍
| import org.junit.jupiter.api.BeforeAll; | ||
|
|
||
| @QuarkusTest | ||
| @TestProfile(Profiles.RestCatalogFileIntegrationProfile.class) |
There was a problem hiding this comment.
Would it be worth a variant where the test principal has no Polaris grants at all (skip makeAdmin), so we prove loadTable doesn't depend on RBAC state anywhere?
To my understanding PolarisRestCatalogIntegrationBase creates the principal, principal role and the grants prior to the tests. It would be worthwhile having a variation of this without the principal and grants
Also okay to keep this out of scope
There was a problem hiding this comment.
Good point. It increases the test matrix a bit, because I think we still have to test with internal principals too (mixed auth mode), but it's worth having that coverage - will add.
There was a problem hiding this comment.
Actually, I looks like ExternalPrincipalKeycloakOpaIT covers that case... WDYT?
There was a problem hiding this comment.
From the name it sounds like it should, but I see that it creates a test Principal:
But this does feel like an enormous scope creep. I feel this would be good to write for what you have planned for step2 - I think having this test that relies on an external Authenticator that avoids creating a Principal will help us identify if there's a gap, or if the forced grant loading in the resolver doesn't result in errors anymore.
There was a problem hiding this comment.
Updated this test to not create / use local principals at all. In fact, it did not rely on local principals before, auth type and credential-mode were "external"... but now it does not event create them :)
| PolarisResolutionManifest resolutionManifest = newResolutionManifest(referenceCatalogName); | ||
| resolutionManifest.addTopLevelName(topLevelEntityName, entityType, false /* isOptional */); | ||
| AuthorizationState authorizationState = new AuthorizationState(resolutionManifest); | ||
| if (referenceCatalogName != null) { |
There was a problem hiding this comment.
Out of curiosity, couldn't we change the authorization intent to include the catalog as a securable? Wouldn't it be resolved automatically in that case?
There was a problem hiding this comment.
The use case coming from listCatalogRolesForPrincipalRole() is asymmetric. The authZ check does not need the catalog, but later service code needs it.
To make it symmetric, we'll need to authorize LIST_CATALOG_ROLES_FOR_PRINCIPAL_ROLE on the catalog (as a securable), which will require extra grants in the native RBAC, AFAIK.
I'm open to doing that, if you think it makes sense.
There was a problem hiding this comment.
I think it makes sense conceptually to require the catalog to be a securable when authorizing listing catalog roles. However, let's defer this work until after this PR is merged.
| AuthorizationIntentResolver.resolve(resolutionManifest, intent, prependRootContainer); | ||
| authorizeRangerOrThrow( | ||
| polarisPrincipal, | ||
| resolutionManifest.getAllActivatedCatalogRoleAndPrincipalRoles(), |
There was a problem hiding this comment.
Since we never resolve CALLER_PRINCIPAL_ROLES or CALLER_CATALOG_ROLES, this is now unused it seems, and will always return empty. Should we just remove this parameter?
There was a problem hiding this comment.
(it's only used for logging anyways)
There was a problem hiding this comment.
Makes sense... Yet, I'd like to keep the scope of this PR narrow. Let's do that change separately. Would that work?
| @Test | ||
| void resolveAuthorizationInputsResolvesAll() { | ||
| void resolveAuthorizationInputsResolvesSelections() { | ||
| // resolveAll() is intentionally used for compatibility and is expected |
| @@ -133,14 +131,6 @@ void setUp() throws Exception { | |||
| when(resolutionManifest.resolveAll()).thenReturn(successStatus); | |||
There was a problem hiding this comment.
I wonder if we still need this stubbing?
| - Minor adjustment to the semantics of `PolarisAuthorizer.resolveAuthorizationInputs()`. | ||
| Existing implementations that used to call `PolarisResolutionManifest.resolveAll()` | ||
| are expected to be compatible with the new Polaris code. Still, adjustments are recommended as | ||
| noted in javadoc. |
There was a problem hiding this comment.
The note is a bit cryptic imho. It doesn't say what changed, and where the "adjustments" should be found (which javadoc?).
There was a problem hiding this comment.
I'll redo the CHANGELOG entry when I open this PR for the next review round.
| * delegate to {@link PolarisResolutionManifest#resolveSelections(Set)}, otherwise it will | ||
| * delegate to {@link PolarisResolutionManifest#resolveAll()}. | ||
| */ | ||
| public void resolve() { |
There was a problem hiding this comment.
resolveSelections(Set) is public and takes its selections as a parameter. If a caller injects
selectors via select(...), an implementation that calls resolveSelections(...) on the
manifest would drop the caller's selectors.
Is going through AuthorizationState.resolve() intended to be required once the PR is merged?
There was a problem hiding this comment.
@gracechen09 : I'm not sure where the "drop" can happen. Right now the logic is cumulative... unless I missed something 🤔
There was a problem hiding this comment.
PolarisResolutionManifest can (and probably should) only be resolved once.
Also, according to the dev thread about multi-entity changes, I believe we should aim at having at most one PolarisResolutionManifest object per request.
https://lists.apache.org/thread/qm60lz3xtnv15swwfb3w6xc1stmflsv3
c0203de to
90bfa2c
Compare
90bfa2c to
a4f32a7
Compare
|
I had to squash to simplify conflict resolution during rebase - PTAL. The commit message is a mess. Please refer to the PR description for change summary. |
Relates to apache#5476 Restore resolveAuthorizationInputs Restore resolveAuthorizationInputs mocks Rename AuthorizationState.resolve() resolveAuthorizationInputsResolvesSelections() Add CHANGELOG typo review: Clarify selectAll / resolve logic review: fold ExampleNonRBACAuthorizer into TestPolarisAuthorizer review: rename BasicResolutionSemantics to NonRBACResolutionSemantics review: authorizer javadoc review: remove irrelevant comment review: Do not create local principals in ExternalPrincipalKeycloakOpaIT add CHANGELOG entry (breaking changes)
a4f32a7 to
8b042b7
Compare
Migrate OPA and Ranger to using
.resolveSelections()Use
AuthorizationStateas the accumulator ofResolvableselectors shared between service endpoint implementations and AuthorizersThe only non-trivial case of using selectors outside of Authorizer code is in
PolarisAdminService.authorizeBasicTopLevelEntityOperationOrThrow()Ranger Auth always uses
REQUESTED_TOP_LEVEL_ENTITIESdue to its reliance on the synthetic root container.Extract common selection code into
NonRBACResolutionSemanticsUpdate
TestPolarisAuthorizerto represent general-purpose non-Polaris (external) behaviours in tests.Relates to #5476
Checklist
CHANGELOG.md(if needed)site/content/in-dev/unreleased(if needed)