rusackas commented on code in PR #44857:
URL: https://github.com/apache/superset/pull/44857#discussion_r4153065458
##########
UPDATING.md:
##########
@@ -376,14 +376,25 @@ routes answer 404, and the "Reset Password" and "Reset my
password" buttons on
the legacy FAB user pages that led to them are gone. `superset init` no longer
assigns their permissions (`can this form get/post on ResetPasswordView` and
`ResetMyPasswordView`, plus the `resetpasswords` and `resetmypassword` actions
on
-`UserDBModelView`) to any role. Every flow they served lives in the SPA:
-administrators reset a user's password from the "New password" fields in the
-Users list edit modal (`PUT /api/v1/security/users/<id>`), users change their
-own from the "Reset my password" modal on their profile page (`PUT
-/api/v1/me/`, which requires `current_password` when the account already has
one), and a pending forced password
-change (`ENABLE_FORCE_PASSWORD_CHANGE`) now redirects to that profile page
-instead of the removed form. Deployments that link to either legacy route
should
-point at `/user_info/` or the Users list instead.
+`UserDBModelView`) to the built-in Admin/Alpha/Gamma/sql_lab roles, and a data
+migration removes those same permissions from every other (operator-defined)
+role that already held them, so no role on any upgraded install retains them.
+Every flow they served lives in the SPA: administrators reset a user's
+password from the "New password" fields in the Users list edit modal (`PUT
+/api/v1/security/users/<id>`), users change their own from the "Reset my
+password" modal on their profile page (`PUT /api/v1/me/`, which requires
+`current_password` when the account already has one), and a pending forced
+password change (`ENABLE_FORCE_PASSWORD_CHANGE`) now redirects to that profile
+page instead of the removed form. Deployments that link to either legacy route
+should point at `/user_info/` or the Users list instead.
+
+Reaching the profile page requires `can_read` on `user`, which the built-in
+Admin/Alpha/Gamma roles hold by default but a custom role is not guaranteed
+to. A user whose only role lacks it and who gets redirected there by a forced
+password change is now redirected to logout with an explanatory message
+instead, so they are never trapped in a redirect loop; grant that permission
+to any custom role whose members may have `ENABLE_FORCE_PASSWORD_CHANGE`
Review Comment:
Good point, added the CurrentUserRestApi read/write grants and split
password_must_change out from ENABLE_FORCE_PASSWORD_CHANGE in the UPDATING.md
note.
##########
superset/security/password_change.py:
##########
@@ -206,30 +236,27 @@ def _enforce_password_change() -> Any: # pylint:
disable=unused-variable
return None
flash(__("You must change your password before continuing."),
"warning")
- # Resolve the SPA profile page. If that endpoint can't be resolved
- # (e.g. a deployment that does not register ``UserInfoView``), fall
- # back to logout, which is always exempt from this enforcement. The
- # logout endpoint is derived from the *registered* auth view so the
- # fallback works for non-DB auth backends (LDAP, OAuth, remote-user)
- # too, with ``AuthDBView.logout`` as a last resort. We must NOT fall
- # back to "/" or any other non-exempt route: the index re-runs this
- # same hook and would trap the user in an infinite 302 loop. If no
- # exempt target can be resolved at all, return an error response rather
- # than redirect, so a flagged user can never get stuck looping.
- candidates = [_PROFILE_PAGE_ENDPOINT]
- auth_view = getattr(
- getattr(getattr(current_app, "appbuilder", None), "sm", None),
- "auth_view",
- None,
- )
- # Only redirect to the registered auth view's logout if that view is
- # itself exempt from this hook; otherwise the redirect would loop.
- if (
- auth_view is not None
- and getattr(auth_view, "endpoint", None) in _EXEMPT_VIEW_CLASSES
- ):
- candidates.append(f"{auth_view.endpoint}.logout")
- candidates.append("AuthDBView.logout")
+ # Resolve the SPA profile page, if the user can actually reach it, with
+ # logout as the fallback -- which is always exempt from this
+ # enforcement. We must NOT fall back to "/" or any other non-exempt
+ # route: the index re-runs this same hook and would trap the user in
+ # an infinite 302 loop. If no exempt target can be resolved at all,
+ # return an error response rather than redirect, so a flagged user can
+ # never get stuck looping.
+ security_manager = getattr(getattr(current_app, "appbuilder", None),
"sm", None)
+ candidates = []
+ if _profile_page_reachable(security_manager):
+ candidates.append(_PROFILE_PAGE_ENDPOINT)
+ else:
+ flash(
+ __(
+ "Your role does not have access to the profile page "
Review Comment:
Fixed, regenerated messages.pot and the catalogs with babel_update.sh.
--
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]
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]