Skip to content

Commit 4c8b375

Browse files
committed
bug: fix plugin custom permissions
Plugin permissions wouldn't have the correct value when being shown in settings. This fixes that issue by using a list of permissions rather than a single top level permission.
1 parent 796f250 commit 4c8b375

5 files changed

Lines changed: 43 additions & 22 deletions

File tree

goosebit/__init__.py

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,12 @@
1414
from tortoise.exceptions import ValidationError
1515

1616
from goosebit import api, db, plugins, ui, updater
17-
from goosebit.auth import get_user_from_request, login_user, redirect_if_authenticated
18-
from goosebit.auth.permissions import GOOSEBIT_PERMISSIONS
17+
from goosebit.auth import (
18+
get_user_from_request,
19+
login_user,
20+
permissions,
21+
redirect_if_authenticated,
22+
)
1923
from goosebit.device_manager import DeviceManager
2024
from goosebit.settings import PWD_CXT, config # type: ignore[attr-defined]
2125
from goosebit.ui.nav import nav
@@ -84,8 +88,8 @@ async def lifespan(_: FastAPI) -> AsyncGenerator[None, None]:
8488
DeviceManager.add_update_source(plugin.update_source_hook)
8589
if plugin.config_data_hook is not None:
8690
DeviceManager.add_config_callback(plugin.config_data_hook)
87-
if plugin.permissions is not None and GOOSEBIT_PERMISSIONS.sub_permissions is not None:
88-
GOOSEBIT_PERMISSIONS.sub_permissions.append(plugin.permissions)
91+
if plugin.permissions is not None:
92+
permissions.HANDLER.append(plugin.permissions)
8993

9094

9195
# Custom exception handler for Tortoise ValidationError

goosebit/api/v1/settings/routes.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
from fastapi import APIRouter
22

3-
from goosebit.auth.permissions import GOOSEBIT_PERMISSIONS, Permission
3+
from goosebit.auth.permissions import HANDLER, Permission
44

55
from . import users
66

@@ -10,5 +10,5 @@
1010

1111

1212
@router.get("/permissions", response_model_exclude_none=True)
13-
async def settings_permissions_get() -> Permission:
14-
return GOOSEBIT_PERMISSIONS
13+
async def settings_permissions_get() -> list[Permission]:
14+
return HANDLER.permissions

goosebit/auth/permissions.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,3 +78,17 @@ def parent(self) -> str | None:
7878
description="Full access to GooseBit",
7979
sub_permissions=[DEVICE_PERMISSIONS, SOFTWARE_PERMISSIONS, ROLLOUT_PERMISSIONS, SETTING_PERMISSIONS],
8080
)
81+
82+
83+
class PermissionHandler:
84+
def __init__(self, permissions: list[Permission]):
85+
self.permissions = permissions
86+
87+
def append(self, permission: Permission) -> None:
88+
self.permissions.append(permission)
89+
90+
def extend(self, permissions: list[Permission]) -> None:
91+
self.permissions.extend(permissions)
92+
93+
94+
HANDLER = PermissionHandler([GOOSEBIT_PERMISSIONS])

goosebit/ui/static/js/settings.js

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -196,29 +196,29 @@ function updateUsersList() {
196196
async function createPermissions() {
197197
const permissions = await get_request("/ui/bff/settings/permissions");
198198

199-
innerAccordion = document.createElement("div");
199+
const innerAccordion = document.createElement("div");
200200
innerAccordion.classList = "accordion-body p-0";
201201

202-
for (innerPermission in permissions.sub_permissions) {
203-
dropdown = createPermissionDropdown(permissions.sub_permissions[innerPermission]);
204-
innerAccordion.innerHTML += dropdown;
202+
for (innerPermission in permissions) {
203+
const dropdown = createPermissionDropdown(permissions[innerPermission]);
204+
innerAccordion.insertAdjacentHTML("beforeend", dropdown);
205205
}
206206

207207
return `<div class="input-group d-flex">
208208
<div class="input-group-text p-2 px-3">
209-
<input class="form-check-input mt-0 ignore-validation" type="checkbox" value="${permissions.value}" id="${permissions.value}-checkbox" onchange="permissionCheckOnUpdate(this)">
209+
<input class="form-check-input mt-0 ignore-validation" type="checkbox" value="*" id="all-checkbox" onchange="permissionCheckOnUpdate(this)">
210210
</div>
211211
<div class="d-flex flex-fill accordion rounded-start-0">
212212
<div class="accordion-item w-100 rounded-start-0">
213213
<div class="accordion-header w-100">
214214
<button class="accordion-button collapsed py-2 rounded-start-0"
215215
type="button"
216216
data-bs-toggle="collapse"
217-
data-bs-target="#${permissions.value}">
218-
${permissions.description}
217+
data-bs-target="#all">
218+
Full access to Goosebit and all plugins
219219
</button>
220220
</div>
221-
<div id="${permissions.value}" class="accordion-collapse collapse">
221+
<div id="all" class="accordion-collapse collapse">
222222
${innerAccordion.outerHTML}
223223
</div>
224224
</div>
@@ -238,18 +238,19 @@ function createPermissionDropdown(permission) {
238238
</div>`;
239239
}
240240

241-
subAccordion = document.createElement("div");
241+
const subAccordion = document.createElement("div");
242242
subAccordion.classList = "accordion-body p-0";
243243

244-
for (innerPermission in permission.sub_permissions) {
245-
dropdown = createPermissionDropdown(permission.sub_permissions[innerPermission]);
246-
subAccordion.innerHTML += dropdown;
244+
for (innerPermission of permission.sub_permissions) {
245+
const dropdown = createPermissionDropdown(innerPermission);
246+
subAccordion.insertAdjacentHTML("beforeend", dropdown);
247247
}
248-
permissionId = permission.value.replaceAll(".", "-");
248+
const permissionId = permission.value.replaceAll(".", "-");
249+
const parentPermission = permission.parent ? permission.parent : "*";
249250

250251
return `<div class="input-group d-flex border-top">
251252
<div class="input-group-text p-2 px-3 rounded-0 border-0 border-start">
252-
<input class="form-check-input mt-0" type="checkbox" value="${permission.value}" id="${permissionId}-checkbox" data-permission-parent="${permission.parent}" onchange="permissionCheckOnUpdate(this)">
253+
<input class="form-check-input mt-0" type="checkbox" value="${permission.value}" id="${permissionId}-checkbox" data-permission-parent="${parentPermission}" onchange="permissionCheckOnUpdate(this)">
253254
</div>
254255
<div class="d-flex flex-fill accordion accordion-flush border-start">
255256
<div class="accordion-item w-100 rounded-start-0">

goosebit/ui/templates/settings.html.jinja

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,9 @@
3737
data-bs-dismiss="modal"
3838
aria-label="Close"></button>
3939
</div>
40-
<form id="create-user-form" class="needs-validation" novalidate>
40+
<form id="create-user-form"
41+
class="h-100 overflow-auto needs-validation"
42+
novalidate>
4143
<div class="modal-body">
4244
<div class="input-group mb-3 has-validation">
4345
<span class="input-group-text">Username</span>

0 commit comments

Comments
 (0)