UI viewer role (#16978)

* db migration

* db model

* assign admin role on password reset

* add role to jwt and api responses

* don't restrict api access for admins yet

* use json response

* frontend auth context

* update auth form for profile endpoint

* add access denied page

* add protected routes

* auth hook

* dialogs

* user settings view

* restrict viewer access to settings

* restrict camera functions for viewer role

* add password dialog to account menu

* spacing tweak

* migrator default to admin

* escape quotes in migrator

* ui tweaks

* tweaks

* colors

* colors

* fix merge conflict

* fix icons

* add api layer enforcement

* ui tweaks

* fix error message

* debug

* clean up

* remove print

* guard apis for admin only

* fix tests

* fix review tests

* use correct error responses from api in toasts

* add role to account menu
This commit is contained in:
Josh Hawkins
2025-03-08 10:01:08 -06:00
committed by GitHub
parent 6f9d9cd5a8
commit 74ca009b0b
50 changed files with 1951 additions and 732 deletions
+13 -5
View File
@@ -504,7 +504,7 @@ class TestHttpReview(BaseTestHttp):
def test_post_reviews_delete_no_body(self):
with TestClient(self.app) as client:
super().insert_mock_review_segment("123456.random")
response = client.post("/reviews/delete")
response = client.post("/reviews/delete", headers={"remote-role": "admin"})
# Missing ids
assert response.status_code == 422
@@ -512,7 +512,9 @@ class TestHttpReview(BaseTestHttp):
with TestClient(self.app) as client:
super().insert_mock_review_segment("123456.random")
body = {"ids": [""]}
response = client.post("/reviews/delete", json=body)
response = client.post(
"/reviews/delete", json=body, headers={"remote-role": "admin"}
)
# Missing ids
assert response.status_code == 422
@@ -521,7 +523,9 @@ class TestHttpReview(BaseTestHttp):
id = "123456.random"
super().insert_mock_review_segment(id)
body = {"ids": ["1"]}
response = client.post("/reviews/delete", json=body)
response = client.post(
"/reviews/delete", json=body, headers={"remote-role": "admin"}
)
assert response.status_code == 200
response_json = response.json()
assert response_json["success"] == True
@@ -536,7 +540,9 @@ class TestHttpReview(BaseTestHttp):
id = "123456.random"
super().insert_mock_review_segment(id)
body = {"ids": [id]}
response = client.post("/reviews/delete", json=body)
response = client.post(
"/reviews/delete", json=body, headers={"remote-role": "admin"}
)
assert response.status_code == 200
response_json = response.json()
assert response_json["success"] == True
@@ -558,7 +564,9 @@ class TestHttpReview(BaseTestHttp):
assert len(recordings_ids_in_db_before) == 2
body = {"ids": ids}
response = client.post("/reviews/delete", json=body)
response = client.post(
"/reviews/delete", json=body, headers={"remote-role": "admin"}
)
assert response.status_code == 200
response_json = response.json()
assert response_json["success"] == True
+6 -3
View File
@@ -172,7 +172,7 @@ class TestHttp(unittest.TestCase):
event = client.get(f"/events/{id}").json()
assert event
assert event["id"] == id
client.delete(f"/events/{id}")
client.delete(f"/events/{id}", headers={"remote-role": "admin"})
event = client.get(f"/events/{id}").json()
assert event == "Event not found"
@@ -192,12 +192,12 @@ class TestHttp(unittest.TestCase):
with TestClient(app) as client:
_insert_mock_event(id)
client.post(f"/events/{id}/retain")
client.post(f"/events/{id}/retain", headers={"remote-role": "admin"})
event = client.get(f"/events/{id}").json()
assert event
assert event["id"] == id
assert event["retain_indefinitely"] is True
client.delete(f"/events/{id}/retain")
client.delete(f"/events/{id}/retain", headers={"remote-role": "admin"})
event = client.get(f"/events/{id}").json()
assert event
assert event["id"] == id
@@ -262,6 +262,7 @@ class TestHttp(unittest.TestCase):
new_sub_label_response = client.post(
f"/events/{id}/sub_label",
json={"subLabel": sub_label},
headers={"remote-role": "admin"},
)
assert new_sub_label_response.status_code == 200
event = client.get(f"/events/{id}").json()
@@ -271,6 +272,7 @@ class TestHttp(unittest.TestCase):
empty_sub_label_response = client.post(
f"/events/{id}/sub_label",
json={"subLabel": ""},
headers={"remote-role": "admin"},
)
assert empty_sub_label_response.status_code == 200
event = client.get(f"/events/{id}").json()
@@ -298,6 +300,7 @@ class TestHttp(unittest.TestCase):
client.post(
f"/events/{id}/sub_label",
json={"subLabel": sub_label},
headers={"remote-role": "admin"},
)
sub_labels = client.get("/sub_labels").json()
assert sub_labels