Skip to content

Commit 3c42f70

Browse files
authored
Merge pull request #105 from nebulabroadcast/v6_0_8-clean-up
Quality of life improvements for version 6.0.8
2 parents dfdaf44 + 06db471 commit 3c42f70

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

71 files changed

+1820
-1370
lines changed

backend/api/delete.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,8 +64,7 @@ async def handle(
6464
)
6565

6666
case ObjectType.ASSET | ObjectType.EVENT:
67-
# TODO: ACL HERE?
68-
# In general, normal users don't need to
67+
# normal users don't need to
6968
# delete assets or events directly
7069
if not user.is_admin:
7170
raise nebula.ForbiddenException(

backend/api/init/init_request.py

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
from typing import Annotated, Any
1+
from typing import Annotated, Any, get_args
22

33
import fastapi
44
from pydantic import Field
@@ -111,10 +111,18 @@ async def handle(
111111
experimental=nebula.config.enable_experimental or None,
112112
)
113113

114-
# TODO: get preferred user language
115-
lang: LanguageCode = user.language
114+
# User preferred language
115+
116+
lang: LanguageCode = "en"
117+
accept_language = request.headers.get("Accept-Language", "en")
118+
preferred_language = accept_language.split(",")[0].strip().lower()
119+
if len(preferred_language) > 2:
120+
preferred_language = preferred_language[:2]
121+
if preferred_language in get_args(LanguageCode):
122+
lang = user.meta.get("language") or preferred_language # type: ignore
116123

117124
# Construct client settings
125+
118126
client_settings = await get_client_settings(lang)
119127
client_settings.server_url = f"{request.url.scheme}://{request.url.netloc}"
120128
plugins = get_frontend_plugins()

backend/api/playout/playout_request.py

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,10 @@ def handle(
2323
if not channel:
2424
raise nebula.NotFoundException("Channel not found")
2525

26-
# TODO: Check if user has access to this channel
26+
if not user.can("mcr", channel.id):
27+
raise nebula.ForbiddenException(
28+
"You are not allowed to control this channel"
29+
)
2730

2831
# For dummy engine, return empty response
2932
if channel.engine == "dummy":
@@ -35,13 +38,6 @@ def handle(
3538

3639
controller_url = f"http://{channel.controller_host}:{channel.controller_port}"
3740

38-
# async with httpx.AsyncClient() as client:
39-
# response = await client.post(
40-
# f"{controller_url}/{request.action.value}",
41-
# json=request.payload,
42-
# timeout=4,
43-
# )
44-
4541
# HTTPx stopped working for some reason, raising asyncio.CancelledError
4642
# when trying to send a request. Using requests for now.
4743

backend/api/rundown/get_rundown.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,7 @@ async def get_rundown(request: RundownRequestModel) -> RundownResponseModel:
197197
item_role=imeta.get("item_role"),
198198
title=item["title"],
199199
subtitle=item["subtitle"],
200+
note=item["note"] or None,
200201
id_asset=id_asset,
201202
id_bin=id_bin,
202203
id_event=id_event,

backend/api/rundown/models.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ class RundownRow(ResponseModel):
2525

2626
title: str | None = Field(None)
2727
subtitle: str | None = Field(None)
28+
note: str | None = Field(None)
2829
id_asset: int | None = Field(None)
2930
id_folder: int | None = Field(None)
3031
asset_mtime: float | None = Field(None)

backend/api/services.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,21 +63,34 @@ async def handle(
6363
request: ServiceRequestModel,
6464
user: CurrentUser,
6565
) -> ServicesResponseModel:
66+
if not user.can("service_control", anyval=True):
67+
msg = "You do not have permission to list or control services"
68+
raise nebula.ForbiddenException(msg)
69+
6670
if request.stop:
71+
if not user.can("service_control", request.stop):
72+
msg = f"You do not have permission to stop service {request.stop}"
73+
raise nebula.ForbiddenException(msg)
6774
nebula.log.info(f"Stopping service {request.stop}", user=user.name)
6875
await nebula.db.execute(
6976
"UPDATE services SET state = $1 WHERE id = $2",
7077
ServiceState.STOPPING,
7178
request.stop,
7279
)
7380
if request.start:
81+
if not user.can("service_control", request.start):
82+
msg = f"You do not have permission to start service {request.start}"
83+
raise nebula.ForbiddenException(msg)
7484
nebula.log.info(f"Starting service {request.start}", user=user.name)
7585
await nebula.db.execute(
7686
"UPDATE services SET state = $1 WHERE id = $2",
7787
ServiceState.STARTING,
7888
request.start,
7989
)
8090
if request.auto:
91+
if not user.can("service_control", request.auto):
92+
msg = f"You do not have permission to toggle service {request.start}"
93+
raise nebula.ForbiddenException(msg)
8194
nebula.log.info(
8295
f"Toggling autostart for service {request.auto}", user=user.name
8396
)

backend/api/set.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,16 @@ async def can_modify_object(obj: BaseObject, user: nebula.User) -> None:
145145
acl = user.get("can/rundown_edit", False)
146146
if not acl:
147147
raise nebula.ForbiddenException("You are not allowed to edit rundown")
148+
elif isinstance(acl, list):
149+
q = "SELECT id_channel FROM events WHERE id_magic = $1"
150+
res = await nebula.db.fetch(q, obj["id_bin"])
151+
if not res:
152+
raise nebula.NotFoundException("Bin not found")
153+
if res[0]["id_channel"] not in acl:
154+
raise nebula.ForbiddenException(
155+
"You are not allowed to edit rundown for this channel"
156+
)
157+
148158
# TODO: Check if user can edit rundown for this channel
149159

150160
elif isinstance(obj, nebula.Bin):

backend/api/users/save_user_request.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import nebula
44
from server.dependencies import CurrentUser
55
from server.request import APIRequest
6+
from server.session import Session
67

78
from .user_model import UserModel
89

@@ -14,10 +15,10 @@ class SaveUserRequest(APIRequest):
1415
title = "Save user data"
1516
responses = [204, 201]
1617

17-
async def handle(self, user: CurrentUser, payload: UserModel) -> Response:
18+
async def handle(self, current_user: CurrentUser, payload: UserModel) -> Response:
1819
new_user = payload.id is None
1920

20-
if not user.is_admin:
21+
if not current_user.is_admin:
2122
raise nebula.ForbiddenException("You are not allowed to edit users")
2223

2324
meta = payload.dict()
@@ -46,6 +47,9 @@ async def handle(self, user: CurrentUser, payload: UserModel) -> Response:
4647

4748
await user.save()
4849

50+
async for session in Session.list(user_name=user.name):
51+
await Session.update(session.token, user)
52+
4953
if new_user:
5054
return Response(status_code=201)
5155
else:

backend/api/users/user_model.py

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -44,13 +44,18 @@ class UserModel(ResponseModel):
4444
title="Can edit rundown",
4545
description="List of channel IDs user can edit. Use 'true' for all channels",
4646
)
47+
can_mcr: bool | list[int] = Field(
48+
False,
49+
title="Can control playout",
50+
description="List of channel IDs user can control",
51+
)
4752
can_job_control: bool | list[int] = Field(
4853
False,
4954
title="Can control jobs",
5055
description="Use list of action IDs to grant access to specific actions",
5156
)
52-
can_mcr: bool | list[int] = Field(
57+
can_service_control: bool | list[int] = Field(
5358
False,
54-
title="Can control playout",
55-
description="List of channel IDs user can control",
59+
title="Can control services",
60+
description="List of service IDs user can control",
5661
)

backend/nebula/settings/common.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,4 +7,4 @@ class SettingsModel(BaseModel):
77
pass
88

99

10-
LanguageCode = Literal["en", "cs", "fi"]
10+
LanguageCode = Literal["en", "cs"]

0 commit comments

Comments
 (0)