|
2 | 2 | title: 'Upgrading to DefectDojo Version 2.58.x' |
3 | 3 | toc_hide: true |
4 | 4 | weight: -20260504 |
5 | | -description: Authorized Users panel replaces Members/Groups under legacy authorization; Notification .tpl templates relocated under dojo/notifications/ |
| 5 | +description: Legacy authorization UI / API rewrite (Open Source); Notification .tpl templates relocated under dojo/notifications/ |
6 | 6 | --- |
7 | 7 |
|
8 | | -## Authorized Users panel replaces Members/Groups under legacy authorization |
| 8 | +## Legacy authorization rewrite — UI and API |
9 | 9 |
|
10 | | -Open Source DefectDojo uses the legacy (pre-2020) authorization model: access to a Product is granted by `Product.authorized_users` (with cascade via `Product_Type.authorized_users`), and `is_staff` / `is_superuser` bypass everything. The classic Django-template UI previously rendered "Members" and "Groups" panels driven by the RBAC tables (`Product_Member`, `Product_Type_Member`, `Product_Group`, `Product_Type_Group`), which legacy authorization does not consult — making those panels read-only and the "Add Users" / "Add Groups" actions a silent failure. They wrote rows to the RBAC tables but did not grant any access. |
11 | | - |
12 | | -In 2.58 the classic UI replaces both panels with a single **"Authorized Users"** panel on the Product and Product Type detail pages. The panel reads from and writes to `Product.authorized_users` / `Product_Type.authorized_users` directly, so adding a user actually grants them the access the UI suggests it does. The "Groups" entry has also been removed from the **Users** dropdown in the left navigation, since `Dojo_Group` is inert under legacy authorization. |
13 | | - |
14 | | -This applies to both the Bootstrap (Classic) and Tailwind opt-in UI trees. |
15 | | - |
16 | | -### New endpoints |
17 | | - |
18 | | -- `GET/POST /product/<pid>/authorized_users/add` — list / add users to `Product.authorized_users` |
19 | | -- `POST /product/<pid>/authorized_users/<user_id>/delete` — remove a user |
20 | | -- `GET/POST /product/type/<ptid>/authorized_users/add` — same for `Product_Type.authorized_users` |
21 | | -- `POST /product/type/<ptid>/authorized_users/<user_id>/delete` |
22 | | - |
23 | | -Both endpoints are gated on `Permissions.Product_Manage_Members` / `Permissions.Product_Type_Manage_Members`, which under legacy authorization map to `Action.StaffOnly` — so only `is_staff` / `is_superuser` users can add or remove. Non-staff users see the panel but no management actions. |
| 10 | +DefectDojo Open Source uses the legacy (pre-2020) authorization model: |
| 11 | +access to a Product is granted by `Product.authorized_users` (with cascade |
| 12 | +via `Product_Type.authorized_users`), and `is_staff` / `is_superuser` bypass |
| 13 | +everything. The RBAC tables (`Product_Member`, `Product_Type_Member`, |
| 14 | +`Product_Group`, `Product_Type_Group`, `Dojo_Group_Member`, `Global_Role`) |
| 15 | +remain in the schema for forward-compatibility with DefectDojo Pro but are |
| 16 | +inert in OS deployments. |
| 17 | + |
| 18 | +Prior to 2.58, the classic Django-template UI and the v2 REST API still |
| 19 | +surfaced these inert RBAC tables — Members/Groups panels that always |
| 20 | +returned "No members found", "Add Users" hamburgers that wrote `Product_Member` |
| 21 | +rows nobody consulted, role dropdowns, etc. The 2.58 rewrite aligns the UI |
| 22 | +and API with the legacy contract: surfaces that drive `authorized_users` |
| 23 | +stay (or get added), surfaces that drive RBAC tables are stripped from OS |
| 24 | +and exposed as `{% block %}` hooks for Pro to override. All template |
| 25 | +changes apply to **both** the Bootstrap (Classic) and Tailwind opt-in UI |
| 26 | +trees. |
| 27 | + |
| 28 | +### Authorized Users panel on Product and Product Type detail |
| 29 | + |
| 30 | +Replaces the inert Members/Groups panels on `view_product_details.html` and |
| 31 | +`view_product_type.html`. The new panel reads from and writes to |
| 32 | +`Product.authorized_users` / `Product_Type.authorized_users` directly. |
| 33 | + |
| 34 | +New endpoints (gated on `Permissions.Product_Manage_Members` / |
| 35 | +`Permissions.Product_Type_Manage_Members`, which under legacy map to |
| 36 | +`Action.StaffOnly`): |
| 37 | + |
| 38 | +| Method | Path | Action | |
| 39 | +| --- | --- | --- | |
| 40 | +| GET/POST | `/product/<pid>/authorized_users/add` | List form / add users to `authorized_users` | |
| 41 | +| POST | `/product/<pid>/authorized_users/<user_id>/delete` | Remove user | |
| 42 | +| GET/POST | `/product/type/<ptid>/authorized_users/add` | Same for `Product_Type.authorized_users` | |
| 43 | +| POST | `/product/type/<ptid>/authorized_users/<user_id>/delete` | Remove user | |
| 44 | + |
| 45 | +The old `add_product_member` / `add_product_type_member` URLs and views |
| 46 | +still exist (Pro uses them) but no longer have an OS UI entry. |
| 47 | + |
| 48 | +### View User read-only access listing + legacy authorize/revoke |
| 49 | + |
| 50 | +The "Product Types this User can access" and "Products this User can |
| 51 | +access" panels on `/user/<id>/` now iterate `authorized_users`-backed data |
| 52 | +under OS: |
| 53 | + |
| 54 | +* Listing: `Product_Type.objects.filter(authorized_users=user)` and the |
| 55 | + product cascade (direct membership *or* product_type membership). |
| 56 | +* Add hamburger (staff only) → multi-select form, **no role dropdown**. |
| 57 | +* Per-row trash button (staff only) → revokes the user from the row's |
| 58 | + `authorized_users` (no `Product_Member` writes). |
| 59 | + |
| 60 | +New endpoints (all gated on `is_staff`): |
| 61 | + |
| 62 | +| Method | Path | Action | |
| 63 | +| --- | --- | --- | |
| 64 | +| GET/POST | `/user/<uid>/authorize_products` | Add user to one or more `Product.authorized_users` | |
| 65 | +| GET/POST | `/user/<uid>/authorize_product_types` | Add user to one or more `Product_Type.authorized_users` | |
| 66 | +| POST | `/user/<uid>/revoke_product/<pid>` | Remove user from `product.authorized_users` | |
| 67 | +| POST | `/user/<uid>/revoke_product_type/<ptid>` | Remove user from `product_type.authorized_users` | |
| 68 | + |
| 69 | +The OS forms have no role field. Under legacy, access is binary |
| 70 | +membership; "role" is RBAC-only. |
| 71 | + |
| 72 | +### Stripped RBAC surfaces (now `{% block %}` hooks) |
| 73 | + |
| 74 | +The following RBAC-only UI is removed from OS templates and replaced with |
| 75 | +empty `{% block %}` placeholders that Pro overrides via |
| 76 | +`pro/templates/dojo/...`: |
| 77 | + |
| 78 | +| Template | Block(s) | |
| 79 | +| --- | --- | |
| 80 | +| `view_product_details.html` | `rbac_members_panel`, `rbac_groups_panel` | |
| 81 | +| `view_product_type.html` | `rbac_members_panel`, `rbac_groups_panel` | |
| 82 | +| `base.html` (left nav, "Users" dropdown) | `groups_submenu_link` | |
| 83 | +| `view_user.html` (RBAC view) | `user_product_types_panel`, `user_products_panel`, `user_groups_panel` | |
| 84 | +| `profile.html` (Global Role fieldset + Groups) | `global_role_form`, `profile_groups_panel` | |
| 85 | +| `add_user.html` (Global Role fieldset) | `global_role_form` | |
| 86 | + |
| 87 | +Re-apply any in-tree patch / Docker mount overrides against the new block |
| 88 | +structure. |
| 89 | + |
| 90 | +### System Settings — RBAC defaults removed |
| 91 | + |
| 92 | +`SystemSettingsForm` and `SystemSettingsSerializer` now `Meta.exclude` the |
| 93 | +three RBAC-only auto-assignment fields: |
| 94 | + |
| 95 | +* `default_group` |
| 96 | +* `default_group_role` |
| 97 | +* `default_group_email_pattern` |
| 98 | + |
| 99 | +These auto-add new users to a `Dojo_Group` at login — `Dojo_Group_Member` |
| 100 | +is inert under legacy, so the fields drove nothing. The model fields |
| 101 | +remain so Pro can subclass the form/serializer to re-add them. |
| 102 | + |
| 103 | +### V2 REST API — RBAC endpoints removed from OS |
| 104 | + |
| 105 | +Eight RBAC `v2_api.register(...)` calls in `dojo/urls.py` and four alias |
| 106 | +registrations in `dojo/asset/api/urls.py` / `dojo/organization/api/urls.py` |
| 107 | +are removed. ViewSets and serializers stay in `dojo/api_v2/{views,serializers}.py` |
| 108 | +so Pro can keep subclassing them. |
| 109 | + |
| 110 | +| Removed prefix | Pro replacement | |
| 111 | +| --- | --- | |
| 112 | +| `/api/v2/dojo_groups/` | `pro/groups` | |
| 113 | +| `/api/v2/dojo_group_members/` | `pro/group_members` | |
| 114 | +| `/api/v2/global_roles/` | `pro/global_roles` | |
| 115 | +| `/api/v2/product_groups/` | `pro/product_groups` | |
| 116 | +| `/api/v2/product_members/` | `pro/product_members` | |
| 117 | +| `/api/v2/product_type_groups/` | `pro/product_type_groups` | |
| 118 | +| `/api/v2/product_type_members/` | `pro/product_type_members` | |
| 119 | +| `/api/v2/roles/` | `pro/roles` | |
| 120 | +| `/api/v2/asset_groups/`, `/api/v2/asset_members/` | (Removed; aliases for `product_groups` / `product_members`) | |
| 121 | +| `/api/v2/organization_groups/`, `/api/v2/organization_members/` | (Removed; aliases for `product_type_groups` / `product_type_members`) | |
| 122 | + |
| 123 | +The corresponding test classes were removed from |
| 124 | +`unittests/test_rest_framework.py`; equivalent coverage lives in |
| 125 | +`dojo-pro/dojo-pro/unit_tests/api/<endpoint>/`. |
| 126 | + |
| 127 | +**Required action for OS API consumers:** if you call any of the removed |
| 128 | +endpoints, you have three options: (1) install Pro, which re-registers |
| 129 | +all eight, (2) drive access exclusively through |
| 130 | +`/api/v2/users/` writes to `is_staff` plus the new |
| 131 | +`Product.authorized_users` / `Product_Type.authorized_users` endpoints |
| 132 | +above, or (3) maintain a local fork that keeps the registrations. |
| 133 | + |
| 134 | +### Authorization helper — `is_staff` bypass for configuration permissions |
| 135 | + |
| 136 | +`dojo.authorization.authorization.user_has_configuration_permission` now |
| 137 | +honors the `is_superuser` / `is_staff` bypass at the top of the function, |
| 138 | +matching the rest of the legacy authorization contract (`user_has_permission` |
| 139 | +and `user_has_global_permission` already had it). Django's |
| 140 | +`user.has_perm(permission)` is consulted as a fallback so explicit grants |
| 141 | +on non-staff users keep working. |
| 142 | + |
| 143 | +This means a non-superuser staff user no longer needs explicit `auth.X` |
| 144 | +grants to reach UI/API surfaces gated on configuration permissions |
| 145 | +(`/user`, `/group`, `/api/v2/users/`, etc.). |
| 146 | + |
| 147 | +### `is_staff` is now editable through the UI and API |
| 148 | + |
| 149 | +* `UserSerializer.Meta.fields` adds `is_staff`. `/api/v2/users/` is already |
| 150 | + superuser-only (via `UserHasConfigurationPermissionSuperuser`), so the |
| 151 | + field doesn't open a privilege-escalation hole. |
| 152 | +* `AddDojoUserForm` and `EditDojoUserForm` add `is_staff`. The widget is |
| 153 | + `disabled` for non-superusers; the views `add_user` / `edit_user` reject |
| 154 | + the save with an error message if a non-superuser tries to grant or |
| 155 | + revoke staff. |
24 | 156 |
|
25 | 157 | ### Required actions |
26 | 158 |
|
27 | | -- **No data migration required.** Migration `dojo.0267_backfill_authorized_users` (shipped in 2.57) already populated `authorized_users` from the prior RBAC tables, so existing access is preserved. |
28 | | -- **If you have a Docker volume mount or in-tree patch overriding `dojo/templates_classic/dojo/view_product_details.html`, `view_product_type.html`, or `base.html`:** the Members/Groups panel HTML and the Groups submenu link were removed from these files and replaced with `{% block rbac_members_panel %}{% endblock %}`, `{% block rbac_groups_panel %}{% endblock %}`, `{% block authorized_users_panel %}{% endblock %}`, and `{% block groups_submenu_link %}{% endblock %}` placeholders. Re-apply your override against the new structure, or override the relevant blocks. |
29 | | -- **If you customized `add_product_member` / `add_product_type_member` URL views:** those URLs still exist and are unchanged; they just no longer have a corresponding entry in the classic UI. |
| 159 | +* **No data migration required.** Migration `dojo.0267_backfill_authorized_users` |
| 160 | + (shipped in 2.57) already populated `authorized_users` from the prior RBAC |
| 161 | + tables, so existing access is preserved. |
| 162 | +* **If you have a Docker volume mount or in-tree patch overriding any of |
| 163 | + the listed templates** (`view_product_details.html`, |
| 164 | + `view_product_type.html`, `base.html`, `view_user.html`, `profile.html`, |
| 165 | + `add_user.html`): re-apply against the new `{% block %}` structure, or |
| 166 | + override the relevant blocks from a parent template. |
| 167 | +* **If you call removed v2 API endpoints**: see the table above. |
| 168 | +* **If you customized `SystemSettingsForm` / `SystemSettingsSerializer`**: |
| 169 | + the three default-group fields are gone; re-add via subclass. |
| 170 | +* **If you depend on `auth.X` configuration grants on non-staff users**: |
| 171 | + no change. `user.has_perm(permission)` is still consulted. |
30 | 172 |
|
31 | 173 | ### Pro customers are not impacted |
32 | 174 |
|
33 | | -DefectDojo Pro deployments retain full RBAC. The Pro app overrides the new template blocks (`rbac_members_panel`, `rbac_groups_panel`, `groups_submenu_link`) to re-render the Members and Groups panels and the Groups link, and overrides `authorized_users_panel` to empty so the new panel does not appear. The Pro UX is unchanged — same Members/Groups management surface as before. |
| 175 | +DefectDojo Pro retains full RBAC. Pro overrides every new `{% block %}` |
| 176 | +hook to re-render the RBAC-driven panels, restores the Groups left-nav |
| 177 | +link, re-registers all eight RBAC v2 API endpoints (plus a new |
| 178 | +`pro/roles/api` for `/api/v2/roles/`), and runtime-shadows |
| 179 | +`user_has_permission` / `user_has_global_permission` / |
| 180 | +`user_has_configuration_permission` so configuration permissions follow Pro |
| 181 | +RBAC rather than the OS `is_staff` bypass. The Pro UX and API are |
| 182 | +unchanged. |
34 | 183 |
|
35 | 184 | ## Notification `.tpl` templates relocated |
36 | 185 |
|
|
0 commit comments