Skip to content

[#10411] feat(core): Extend metadata object owner to support group#10848

Merged
roryqi merged 2 commits intoapache:mainfrom
bharos:feat/extend-owner-support-group
Apr 24, 2026
Merged

[#10411] feat(core): Extend metadata object owner to support group#10848
roryqi merged 2 commits intoapache:mainfrom
bharos:feat/extend-owner-support-group

Conversation

@bharos
Copy link
Copy Markdown
Contributor

@bharos bharos commented Apr 22, 2026

What changes were proposed in this pull request?

Remove the USER-only restriction in OwnerManager.setOwner() and add GROUP support to notifyOwnerChange(), enabling groups to be set as metadata object owners.

Changes:

  • Remove Preconditions.checkArgument(ownerType == Owner.Type.USER) guard in OwnerManager.setOwner()
  • Extend notifyOwnerChange() to resolve group entity IDs
  • Fix GroupEntity namespace in test (was using ofUserNamespace, corrected to ofGroupNamespace)
  • Replace testGroupTypeOwnerNotSupported with tests that verify group ownership works

Why are the changes needed?

The owner field was implicitly assumed to point to a User. In practice, the logical owner of a resource (Schema, Table, etc.) is often a team (Group) rather than an individual. The downstream layers (REST API, DTOs, relational store) already support GROUP — only OwnerManager had a guard blocking it.

Fix: #10411

Does this PR introduce any user-facing change?

Yes. The setOwner API now accepts Owner.Type.GROUP in addition to Owner.Type.USER.

How was this patch tested?

Unit tests in TestOwnerManager:

  • testGroupTypeOwner: Sets group as owner, verifies, then replaces with user owner (exercises notifyOwnerChange GROUP path)
  • testSetNonExistentGroupAsOwner: Verifies NotFoundException for non-existent group

@bharos bharos force-pushed the feat/extend-owner-support-group branch from e09a718 to 290bb94 Compare April 22, 2026 22:23
import org.junit.jupiter.api.TestMethodOrder;
import org.mockito.Mockito;

@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The tests share a single in-memory H2 entity store that persists state across methods. testOwner() asserts the metalake has no owner initially, but testGroupTypeOwner() sets an owner on the same metalake. Without ordering, JUnit could run them in any order, causing testOwner() to fail if it runs second.

@bharos bharos requested a review from roryqi April 22, 2026 22:24
@bharos bharos marked this pull request as ready for review April 22, 2026 22:24
@bharos bharos force-pushed the feat/extend-owner-support-group branch from 290bb94 to d54eca6 Compare April 22, 2026 22:37
@github-actions
Copy link
Copy Markdown

github-actions Bot commented Apr 22, 2026

Code Coverage Report

Overall Project 65.38% 🟢
Files changed 64.49% 🟢

Module Coverage
aliyun 1.73% 🔴
api 47.27% 🟢
authorization-common 85.96% 🟢
aws 1.1% 🔴
azure 2.6% 🔴
catalog-common 10.2% 🔴
catalog-fileset 80.02% 🟢
catalog-glue 91.48% 🟢
catalog-hive 81.83% 🟢
catalog-jdbc-clickhouse 79.06% 🟢
catalog-jdbc-common 43.93% 🟢
catalog-jdbc-doris 80.28% 🟢
catalog-jdbc-hologres 54.03% 🟢
catalog-jdbc-mysql 79.23% 🟢
catalog-jdbc-oceanbase 78.38% 🟢
catalog-jdbc-postgresql 82.05% 🟢
catalog-jdbc-starrocks 78.27% 🟢
catalog-kafka 77.01% 🟢
catalog-lakehouse-generic 45.07% 🟢
catalog-lakehouse-hudi 79.1% 🟢
catalog-lakehouse-iceberg 87.16% 🟢
catalog-lakehouse-paimon 77.71% 🟢
catalog-model 77.72% 🟢
cli 44.51% 🟢
client-java 77.63% 🟢
common 48.67% 🟢
core 81.55% -0.08% 🟢
filesystem-hadoop3 76.97% 🟢
flink 40.55% 🟢
flink-runtime 0.0% 🔴
gcp 14.2% 🔴
hadoop-common 10.39% 🔴
hive-metastore-common 46.14% 🟢
iceberg-common 55.2% 🟢
iceberg-rest-server 67.25% 🟢
integration-test-common 0.0% 🔴
jobs 66.17% 🟢
lance-common 23.88% 🔴
lance-rest-server 57.84% 🟢
lineage 53.02% 🟢
optimizer 82.95% 🟢
optimizer-api 21.95% 🔴
server 85.62% 🟢
server-common 69.76% 🟢
spark 32.79% 🔴
spark-common 39.09% 🔴
trino-connector 34.27% 🔴
Files
Module File Coverage
core OwnerManager.java 64.49% 🟢

…cting it

The PR extends owner support to groups, but testOwnerDrop() still asserted
that setting a GROUP owner throws IllegalArgumentException. Updated the test
to set a group owner, verify ownership, drop the group, and confirm the
owner is removed.
Copy link
Copy Markdown
Contributor

@roryqi roryqi left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM.

@roryqi roryqi merged commit 584890d into apache:main Apr 24, 2026
29 checks passed
@bharos bharos self-assigned this Apr 24, 2026
roryqi pushed a commit that referenced this pull request Apr 25, 2026
…rizer (#10867)

### What changes were proposed in this pull request?

Extend `JcasbinAuthorizer` to recognize group-based ownership. When a
metadata object is owned by a group, all members of that group are now
treated as owners and granted owner privileges.

Key changes:
- **`OwnerInfo` inner class**: Replaces the raw `Long` owner ID in the
cache with a struct that stores `id`, `type` (USER/GROUP), and `name`.
- **`ownerRel` cache type**: Changed from `Cache<Long, Optional<Long>>`
to `Cache<Long, Optional<OwnerInfo>>`.
- **`loadOwnerPolicy()`**: Now handles `GroupEntity` alongside
`UserEntity` when populating the owner cache.
- **`checkOwnership()`**: New method that resolves both user and group
owners — for USER owners it compares entity IDs, for GROUP owners it
checks whether the principal's groups include the owning group.
- **`isOwner()` and `authorizeByJcasbin()`**: Refactored to delegate to
`checkOwnership()`, eliminating duplicated ownership logic.
- **Documentation**: Removed "group ownership not supported" info boxes
from `docs/security/access-control.md` and added group ownership bullet.

### Why are the changes needed?

Currently, when a metadata object's owner is set to a group (supported
since #10848), the `JcasbinAuthorizer` does not recognize group
ownership — only individual user ownership is checked. This means group
members are denied owner privileges even when the group is the
registered owner.

This PR is part 2 of a 3-PR series for #10412:
1. **#10848** — Core/API: `OwnerManager.setOwner` accepts GROUP
(**merged**)
2. **This PR** — Enforcement: `JcasbinAuthorizer` recognizes group
ownership
3. **Planned** — Role inheritance: `loadRolePrivilege` queries
`ROLE_GROUP_REL`

Fix: #10412

### Does this PR introduce _any_ user-facing change?

Yes. Users who assign group ownership to metadata objects will now have
all group members recognized as owners by the JCasbin authorization
plugin.

### How was this patch tested?

Unit tests in `TestJcasbinAuthorizer`:
- `testAuthorizeByGroupOwner`: Verifies a principal whose groups include
the owning group is recognized as owner, a non-member group is denied,
and clearing ownership returns false.
- Existing tests (`testIsOwner`, `testOwnerCacheInvalidation`,
`testCacheInitialization`) updated for `OwnerInfo` type.
- All 8 tests pass: `./gradlew :server-common:test --tests
"...TestJcasbinAuthorizer"`
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Subtask] Extend metadata object owner to support group

2 participants