ramackri opened a new pull request, #1000: URL: https://github.com/apache/ranger/pull/1000
## What changes were proposed in this pull request? Implements [RANGER-5627](https://issues.apache.org/jira/browse/RANGER-5627): configuration-based Ranger Admin super users and super groups via `ranger.admin.super.users` and `ranger.admin.super.groups` in `ranger-admin-site.xml`. **Problem addressed:** Externally authenticated users (LDAP/Kerberos/OIDC/SAML) could not be designated as Ranger administrators without Ranger managed DB roles. Deployments relied on shared local `admin` accounts, limiting enterprise IdM integration, SSO/K8s models, and per-user auditability. **Solution:** Matching users receive full admin session flags, Spring Security roles, module permissions, and REST authorization at login **without** changing `x_portal_user_role`. Authentication provider remains independent of the elevation decision. **Backward compatible** when both config properties are empty. Re-login required after config or UserSync group membership changes. **Key changes:** - New `RangerSuperUserConfig`; session elevation in `SessionMgr` / `UserSessionBase` - `UserMgr.getAuthenticationRolesByLoginId()` and profile overrides; `XUserMgr.getSyncedGroupsForUser()` for `super.groups` - REST/biz bypass of ROLE_USER-only paths via `isSingleRoleUserSession()` and `RangerBizUtil.isUserRangerAdmin()` - Jira admin capabilities: services, policies, users/groups, roles, audit, security admin - UI: `XAUtils.js` multi-role check; OpenAPI/Swagger alias fixes for local API testing - Unit tests; Docker E2E scripts under `dev-support/ranger-docker/scripts/admin/`; design docs ## What changes were proposed in this pull request? Implements [RANGER-5627](https://issues.apache.org/jira/browse/RANGER-5627). ### Configuration & template - Add `ranger.admin.super.users` and `ranger.admin.super.groups` to `security-admin/src/main/resources/conf.dist/ranger-admin-site.xml` and `security-admin/scripts/ranger-admin-site-template.xml`. ### New core class - **`RangerSuperUserConfig`** — reads config, `isEnabled()`, `isSuperUser(loginId, groups)`, case-insensitive user match, group membership check, helpers to merge config super-user roles into authentication and profile role lists. ### Session & authentication - **`SessionMgr`** — `applyConfigSuperUserSessionFlags()` at login; sets `userAdmin`, `keyAdmin`, `configSuperUser`; grants all UI modules via `resetUserModulePermission()` when `isEffectiveRangerAdmin()` or key admin. - **`UserSessionBase`** — `configSuperUser` flag; `isEffectiveRangerAdmin()` = `userAdmin || configSuperUser`; `isSingleRoleUserSession()` bypasses ROLE_USER-only restrictions for config super-users. - **`UserMgr`** — `getAuthenticationRolesByLoginId()` for Spring Security; `applyConfigSuperUserProfileOverrides()` on `/user/profile`. - **Auth filters & `RangerAuthenticationProvider`** — use `getAuthenticationRolesByLoginId()` instead of DB-only role lookup. ### Authorization & REST - **`RangerBizUtil`** — `isUserRangerAdmin()`, `isConfigSuperUser()`, `checkUserAccessible()` honor session/config elevation. - **`XUserMgr`** — `getSyncedGroupsForUser()` for login-time group resolution (DAO, no API masking); `getGroupsForUser()` restored for API paths; `isSingleRoleUserSession()` bypass in group search. - **`RoleDBStore`**, **`RoleREST`**, **`ServiceREST`**, **`XUserREST`**, **`AssetREST`** — skip ROLE_USER-only masking when `isSingleRoleUserSession()` or config super-user checks apply. ### UI (minimal) - **`react-webapp/src/utils/XAUtils.js`** — `LoginUser()` uses `roles.includes(role)` instead of `userRoleList[0]` only. **Not changed:** `RoleForm.jsx`, `EditPermission.jsx`, `UserForm.jsx` — stock Add-then-Save UX retained. ### Unit tests - New: `TestRangerSuperUserConfig` - Updated: `TestSessionMgr`, `TestUserMgr`, `TestXUserMgr`, `TestRangerBizUtil`, `TestRoleDBStore`, `TestAssetREST`, `TestServiceREST`, `TestXUserREST`, `TestRangerHeaderPreAuthFilter` ### OpenAPI / Swagger UI (Docker E2E support) - **`distro/src/main/assembly/admin-web.xml`** — ship `swagger.json` as an alias of `openapi.json` in the admin tarball (backward-compatible Swagger UI load path). - **`docs/src/site/resources/index.js`** — Swagger UI loads `openapi.json` instead of `swagger.json` (supports OpenAPI parity scripts and local API docs testing). ## How was this patch tested? ### Prerequisites — minimal Docker stack Only three components are required to validate config super-users (no Hive, HDFS, Kafka, or audit tier needed): | Component | Purpose | |-----------|---------| | **PostgreSQL** (`ranger-postgres`) | Ranger Admin DB | | **Ranger Admin** (`ranger`) | UI + REST at `http://localhost:6080` | | **Ranger UserSync** (`ranger-usersync`) | Syncs users/groups from CSV into `x_user`, `x_group`, `x_group_users` | **One-time setup** (from repo root): ```bash # Build Ranger and stage tarballs for docker mvn clean package -DskipTests cp target/ranger-* dev-support/ranger-docker/dist/ cp target/version dev-support/ranger-docker/dist/ cd dev-support/ranger-docker chmod +x scripts/**/*.sh export RANGER_DB_TYPE=postgres export ENABLE_FILE_SYNC_SOURCE=true ``` **Start minimal stack:** ```bash cd dev-support/ranger-docker export RANGER_DB_TYPE=postgres export ENABLE_FILE_SYNC_SOURCE=true # DB + Admin (includes KDC, ZK, Solr — required by docker-compose.ranger.yml) docker compose -f docker-compose.ranger-db.yml -f docker-compose.ranger.yml up -d # Wait until login page responds (~2–3 min on first boot) curl -sf http://localhost:6080/login.jsp # UserSync — file-based sync from ugsync-file-source.csv docker compose -f docker-compose.ranger-db.yml -f docker-compose.ranger.yml \ -f docker-compose.ranger-usersync.yml up -d ranger-usersync ``` **Super-user config** (must be present before testing; included in this PR’s `ranger-admin-site.xml` template): ```xml <property> <name>ranger.admin.super.users</name> <value>testuser_2</value> </property> <property> <name>ranger.admin.super.groups</name> <value>testgroup_3A</value> </property> ``` After changing config or rebuilding the admin image, recreate the `ranger` container and **re-login** test users. **Default credentials:** `admin` / `rangerR0cks!` · `testuser_*` / `rangerR0cks!` --- ### Dev user/group CSV (`ugsync-file-source.csv`) Path: `dev-support/ranger-docker/scripts/usersync/ugsync-file-source.csv` This file drives **both** first-boot bootstrap and ongoing UserSync membership. It is mounted into the UserSync container and also read by `create-ranger-services.py` when the `ranger` container starts. **Format:** one row per user; first column = login id; remaining columns = group names (comma-separated, no header row). ```csv testuser_1,testgroup_1A,testgroup_1B,testgroup_3A,testgroup_3B, testuser_2,testgroup_2A,testgroup_2B,testgroup_3A,testgroup_3B, testuser_3,testgroup_3A,testgroup_3B,testgroup_3A,testgroup_3B, ... testuser_7,testgroup_7A,testgroup_7B,testgroup_3A,testgroup_3B, ... testuser_10,testgroup_10A,testgroup_10B,testgroup_3A,testgroup_3B, ``` | CSV field | Meaning | |-----------|---------| | Column 1 (`testuser_N`) | Ranger portal login id | | Columns 2+ (`testgroup_*`) | Group memberships synced into Ranger DB | | `testgroup_3A` | Matches `ranger.admin.super.groups` in config — **required for `super.groups` E2E** | | Password | Not in CSV; set to `rangerR0cks!` by `create-ranger-services.py` bootstrap | **Why UserSync matters for `super.groups`:** Config does **not** query LDAP/files at login. It reads group names already stored in Ranger DB (`x_group_users`) by UserSync. Without UserSync (or bootstrap), `testuser_7` would have no `testgroup_3A` membership and would **not** elevate via `super.groups`. --- ### Ranger UserSync — start and verify UserSync runs as container `ranger-usersync` with `ENABLE_FILE_SYNC_SOURCE=true` (see `dev-support/ranger-docker/.env`). The CSV is bind-mounted from `scripts/usersync/ugsync-file-source.csv`. **Start** (if not already up with the stack): ```bash export ENABLE_FILE_SYNC_SOURCE=true docker compose -f docker-compose.ranger-db.yml -f docker-compose.ranger.yml \ -f docker-compose.ranger-usersync.yml up -d ranger-usersync ``` **Wait for first sync cycle** (~60–90 seconds), then check logs: ```bash docker ps --filter name=ranger-usersync docker logs ranger-usersync 2>&1 | tail -40 ``` **Verify membership in DB** (prerequisite for `testuser_7` / `super.groups`): ```bash docker exec ranger-postgres psql -U rangeradmin -d ranger -c \ "SELECT u.user_name, g.group_name FROM x_user u JOIN x_group_users gu ON u.id=gu.user_id JOIN x_group g ON g.id=gu.group_id WHERE u.user_name IN ('testuser_2','testuser_7') AND g.group_name='testgroup_3A' ORDER BY 1;" ``` **Verify in Admin UI** (as `admin`): **Settings → Users/Groups → Users** → open `testuser_7` → **Groups** tab → confirm **`testgroup_3A`**. User roles should still show **`ROLE_USER`** only (config elevation does not change DB roles). **After CSV edits:** restart `ranger-usersync`, wait for sync, confirm membership in UI/DB, then **logout and login** as the affected user. --- ### 1. Unit tests Run from repo root: ```bash mvn test -pl security-admin \ -Dtest=TestRangerSuperUserConfig,TestSessionMgr,TestUserMgr,TestXUserMgr,TestRangerBizUtil,TestRoleDBStore \ -Dfrontend.skip=true ``` **Result:** All targeted unit tests pass. | Test class | Coverage | |------------|----------| | `TestRangerSuperUserConfig` | Config parsing, enable/disable, user/group match | | `TestSessionMgr` | Session flags and module permissions at login | | `TestUserMgr` | Authentication roles and profile overrides | | `TestXUserMgr` | `getSyncedGroupsForUser` vs `getGroupsForUser` | | `TestRangerBizUtil` | `isUserRangerAdmin`, access checks | | `TestRoleDBStore` | Role list bypass for elevated sessions | --- ### 2. Manual UI smoke (required for reviewers) Use **form login** at `http://localhost:6080/login.jsp` (JDBC auth — username + password, not SSO/Kerberos for `testuser_*`). **Important:** Elevation is applied at **login**. After any config or UserSync change, **log out completely** and log in again before checking the UI. #### 3a. Baseline — confirm UserSync data (as `admin`) 1. Log in as **`admin` / `rangerR0cks!`**. 2. Go to **Settings → Users/Groups → Users**. 3. Confirm **`testuser_2`** and **`testuser_7`** exist. 4. Open **`testuser_7`** → **Groups** → confirm **`testgroup_3A`** is listed. 5. Open **`testuser_2`** / **`testuser_7`** → **Roles** → confirm DB role is **`ROLE_USER`** only (not SYS admin). Config super-user does not mutate DB roles. #### 3b. `super.users` path — `testuser_2` 1. Log out. Log in as **`testuser_2` / `rangerR0cks!`**. 2. **Profile (top-right user menu → Profile):** - **Expected:** Roles include **`ROLE_SYS_ADMIN`** and **`ROLE_KEY_ADMIN`**. - **Expected:** No “You do not have privilege” or empty-permissions error. - **Failure sign:** Only `ROLE_USER` shown, or profile page error banner. 3. **Left nav — module tabs:** - **Users/Groups** — list loads; no HTTP 403 in browser Network tab. - **Roles** — role list visible (not empty due to ROLE_USER masking). - **Permissions** — permission list visible. - **Audit** — tab present and loads (not hidden by KMS-only repo filter). - **Key Manager** — accessible. 4. **Resource Based Policies** — service list visible (same general access as admin for read/list operations). #### 3c. `super.groups` path — `testuser_7` 1. Log out. Log in as **`testuser_7` / `rangerR0cks!`**. 2. Repeat the same checks as **3b**. This validates the **`getSyncedGroupsForUser`** fix: elevation via group membership synced by UserSync, not via `super.users`. 3. If **`testuser_7` fails** but **`testuser_2` passes**, check UserSync first (DB query / Groups tab) before assuming an auth bug. #### 3d. Create / edit smoke (stock Add-then-Save UX) Still logged in as **`testuser_2`** or **`testuser_7`**: | Area | Steps | Expected | |------|-------|----------| | **Group** | Settings → Users/Groups → **Add New Group** → enter name → **Save** | Group created; no 403 | | **User** | Add New User → fill fields → **Save** | User created | | **Role** | Access → Roles → **Add New Role** → fill → **Save** | Role created | | **Permission** | Access → Permissions → edit a permission → pick user/group from dropdown → click **+ (Add)** → **Save** | Must use **Add** before **Save** (stock UI); save succeeds without “does not have privilege” | The permission editor is **client-side**: selecting a user/group in the dropdown without clicking **Add** before **Save** will show a validation error — that is expected stock behavior, not a super-user regression. #### 3e. Negative control — no elevation 1. Pick a user **not** in `ranger.admin.super.users` and **not** a member of any group listed in `ranger.admin.super.groups` (edit CSV to remove `testgroup_3A` from one user, re-sync UserSync, or verify in UI). 2. Log in as that user. 3. **Expected:** Profile shows **`ROLE_USER`** only; **Users/Groups**, **Roles**, and admin-only modules are restricted or hidden; no SYS/KEY admin roles on profile. 4. Optional: compare side-by-side with **`admin`** (DB admin) to confirm config super-user matches admin capability without DB role change. #### 3f. Optional DevTools check After login as `testuser_2` or `testuser_7`, open **Network** → `GET /service/users/profile`: - `userRoleList` should contain `ROLE_SYS_ADMIN` and `ROLE_KEY_ADMIN`. - `userPermList` should include `Users/Groups`, `Key Manager`, `Audit`, etc. -- 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]
