laserninja opened a new pull request, #12867: URL: https://github.com/apache/gravitino/pull/12867
### What changes were proposed in this pull request? Adds the authorization layer for Semantic Models, following the "Authorization and Governance" section of `design-docs/gravitino-semantic-model-design.md`. **Privileges** (`api`) - `CREATE_SEMANTIC_MODEL`, `SELECT_SEMANTIC_MODEL`, and `MODIFY_SEMANTIC_MODEL` in `Privilege.Name`, plus the matching `Privileges` classes and `allow`/`deny` resolution. - Binding rules: `CREATE_SEMANTIC_MODEL` binds to METALAKE, CATALOG, and SCHEMA (the scope it creates into); `SELECT_SEMANTIC_MODEL` and `MODIFY_SEMANTIC_MODEL` additionally bind to SEMANTIC_MODEL. - `SecurableObjects.ofSemanticModel(...)`, and `SEMANTIC_MODEL` added to `ManageGrants` bindings so grant management can be delegated per Semantic Model, as it already can for every other schema-level object. - `AuthorizationUtils.checkPrivilege` rejects the new privileges on non-relational catalogs, matching `SemanticModelOperationDispatcher`, which only serves relational catalogs. **Ownership** (`core`) - New `SemanticModelHookDispatcher` sets the creator as owner after a successful create. - The dispatcher chain becomes `SemanticModelHookDispatcher -> SemanticModelNormalizeDispatcher -> SemanticModelOperationDispatcher`, with a TODO marking where #12595's event dispatcher belongs. - The hook rebuilds the stored identifier as normalized-namespace plus the created model's own name. `SemanticModelNormalizeDispatcher` case-folds only the parent namespace against the catalog capability and applies Gravitino-owned naming to the model name, so reusing `applyCapabilities(ident, scope, catalogManager)` the way `ModelHookDispatcher` does would attach the owner to a case-folded name the store never used. - `SEMANTIC_MODEL` added to `AuthorizationUtils.SKIP_APPLY_TYPES`: Semantic Models exist only in Gravitino, so there is nothing for a catalog authorization plugin to grant, revoke, or rename. **Authorization plumbing** - LOAD, CREATE, MODIFY, DROP, and FILTER expressions in `AuthorizationExpressionConstants`. Drop deliberately requires ownership rather than `MODIFY_SEMANTIC_MODEL`, per the design doc. - `ANY_CREATE_SEMANTIC_MODEL`, `ANY_SELECT_SEMANTIC_MODEL`, and `ANY_MODIFY_SEMANTIC_MODEL` token expansion in `AuthorizationExpressionConverter`, with deny taking precedence at every scope. - `SEMANTIC_MODEL` in `CAN_ACCESS_METADATA`, so the owner API accepts Semantic Model objects. - `MetadataObjectUtil.checkMetadataObject`, `EntityClassMapper`, `MetadataIdConverter` case-sensitivity scope, and `JcasbinAuthorizationCacheKeys` all handle `SEMANTIC_MODEL`. **Docs** - `docs/security/access-control.md`: object tree, privilege table, and required-privileges table. ### Why are the changes needed? Semantic Models are new securable metadata objects. Without privileges and an ownership hook they would be created with no owner and no way to grant access, so the REST APIs in #12607 and #12608 have nothing to enforce. Fix: #12594 ### Does this PR introduce _any_ user-facing change? Yes, additive only: - Three new privilege names usable in role grants: `CREATE_SEMANTIC_MODEL`, `SELECT_SEMANTIC_MODEL`, `MODIFY_SEMANTIC_MODEL`. - `SecurableObjects.ofSemanticModel(...)` in the public API. - `SEMANTIC_MODEL` accepted by the owner API and as a `MANAGE_GRANTS` target. No existing privilege, wire format, or config default changes. ### Follow-up Two items in the issue's checklist depend on `SemanticModelMetaMapper` and `SemanticModelPO`, which land in #12602/#12603, and are deferred to a follow-up PR: - `MetadataObjectService.TYPE_TO_FULLNAME_FUNCTION_MAP` needs a `getSemanticModelObjectsFullName` entry to resolve a Semantic Model ID back to a full name when listing owned objects. - `OrphanedMetadataObjectRelationService.ENTITY_TABLES` needs a Semantic Model entry so owner relation rows are cleaned up after a hard delete. Neither is reachable on `main` today: `JDBCBackend` still stubs Semantic Model persistence, so no Semantic Model, and therefore no owner relation, can exist yet. ### How was this patch tested? New tests: - `TestSemanticModelHookDispatcher`: owner assignment, namespace normalization versus Gravitino-owned naming, pass-through when the owner dispatcher is disabled, propagation when `setOwner` fails, and no owner interaction on list/load/alter/drop. - `TestSemanticModelAuthorizationExpression`: create, load, filter, alter, and drop expressions, covering owner paths, the `USE_CATALOG` + `USE_SCHEMA` chain, deny precedence, and the two negative cases that matter, namely `SELECT_SEMANTIC_MODEL` not permitting alter and `MODIFY_SEMANTIC_MODEL` not permitting drop. Extended: `TestSecurableObjects` (binding matrix, allow/deny resolution, name-length validation), `TestAuthorizationUtils` (plugin is not notified for Semantic Models), `TestMetadataIdConverter`, `TestJcasbinAuthorizationCacheKeys`. Local verification with JDK 17: ```bash ./gradlew :api:test :server-common:test :core:test --tests "org.apache.gravitino.hook.*" --tests "org.apache.gravitino.authorization.*" --tests "org.apache.gravitino.utils.*" :server:test --tests "org.apache.gravitino.server.web.rest.authorization.*" -PskipITs ``` All green, plus `spotlessCheck` and `javadoc` clean on `:api`, `:core`, `:server-common`, and `:server`. -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: [email protected] For queries about this service, please contact Infrastructure at: [email protected]
