mirror of
https://github.com/ipnet-mesh/meshcore-hub.git
synced 2026-08-07 09:23:07 +02:00
fix(profiles): restore admin ability to edit other users' profiles
The update_profile endpoint used RequireUserOwner which returns only the
caller's user_id — no role information. The ownership check blocked ALL
non-owner edits with 403, including admins. This regressed in d37b30a
when the old Member model (RequireAdmin) was replaced with UserProfile.
Backend: read X-User-Roles header directly in update_profile (same
pattern as node_tags.py / routes.py) and bypass the ownership check when
the admin role is present. Regular members editing their own profiles
are unaffected — RequireUserOwner stays as the dependency.
Frontend: extract ProfileEditForm component (with data-testids) from
OwnProfileView. PublicProfileView now shows an inline edit form when an
admin views another user's profile. Owner still gets the existing edit
link; non-admins see nothing.
Tests:
- Backend: test_update_profile_admin_can_edit_other (admin edits other
user's profile, asserts 200 + all fields updated)
- Vitest: 4 new tests — admin button visibility, non-admin hidden,
owner link vs admin button, form submission to correct endpoint
- E2E: admin-profile-edit.spec.ts (admin edits Mem South's profile,
verifies persistence; admin on own profile sees no admin button);
members.spec.ts negative assertion (member sees no admin button)
This commit is contained in:
@@ -28,6 +28,10 @@ NO_ROLES_HEADERS = {
|
||||
"X-User-Id": TEST_USER_ID,
|
||||
"X-User-Roles": "",
|
||||
}
|
||||
ADMIN_HEADERS = {
|
||||
"X-User-Id": OTHER_USER_ID,
|
||||
"X-User-Roles": "admin",
|
||||
}
|
||||
|
||||
|
||||
class TestListProfiles:
|
||||
@@ -383,6 +387,27 @@ class TestUpdateProfile:
|
||||
)
|
||||
assert response.status_code == 403
|
||||
|
||||
def test_update_profile_admin_can_edit_other(
|
||||
self, client_no_auth, sample_user_profile
|
||||
):
|
||||
"""Test that an admin can update another user's profile."""
|
||||
response = client_no_auth.put(
|
||||
f"/api/v1/user/profile/{sample_user_profile.id}",
|
||||
json={
|
||||
"name": "Admin Edited",
|
||||
"callsign": "ADM1",
|
||||
"description": "Admin revised this",
|
||||
"url": "https://example.com/admin",
|
||||
},
|
||||
headers=ADMIN_HEADERS,
|
||||
)
|
||||
assert response.status_code == 200
|
||||
data = response.json()
|
||||
assert data["name"] == "Admin Edited"
|
||||
assert data["callsign"] == "ADM1"
|
||||
assert data["description"] == "Admin revised this"
|
||||
assert data["url"] == "https://example.com/admin"
|
||||
|
||||
def test_update_profile_rejects_missing_user_id(
|
||||
self, client_no_auth, sample_user_profile
|
||||
):
|
||||
|
||||
Reference in New Issue
Block a user