Skip to content

Commit 403c216

Browse files
committed
Check user permissions in config tool
Check permissions in tree viewer
1 parent a6ffa60 commit 403c216

4 files changed

Lines changed: 20 additions & 8 deletions

File tree

specifyweb/backend/setup_tool/views.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
from django.db import transaction
1010
from specifyweb.backend.setup_tool.utils import normalize_keys
1111
from specifyweb.backend.setup_tool.setup_tasks import create_discipline_and_trees_task
12+
from specifyweb.backend.permissions.permissions import check_table_permissions
1213

1314
import logging
1415
logger = logging.getLogger(__name__)
@@ -135,6 +136,11 @@ def create_specifyuser_view(request):
135136
@require_POST
136137
@transaction.atomic
137138
def create_discipline_and_trees(request):
139+
from specifyweb.specify.models import Discipline, Taxontreedef, Geographytreedef
140+
check_table_permissions(request.specify_collection, request.specify_user_agent, Discipline, "create")
141+
check_table_permissions(request.specify_collection, request.specify_user_agent, Taxontreedef, "create")
142+
check_table_permissions(request.specify_collection, request.specify_user_agent, Geographytreedef, "create")
143+
138144
raw_data = json.loads(request.body)
139145
data = normalize_keys(raw_data)
140146

specifyweb/frontend/js_src/lib/components/SystemConfigurationTool/Hierarchy.tsx

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ import { Submit } from '../Atoms/Submit';
2525
import { LoadingContext } from '../Core/Contexts';
2626
import type { SpecifyResource } from '../DataModel/legacyTypes';
2727
import { tables } from '../DataModel/tables';
28+
import { Tables } from '../DataModel/types';
2829
import { getSystemInfo } from '../InitialContext/systemInfo';
2930
import { Dialog, LoadingScreen } from '../Molecules/Dialog';
3031
import { ResourceLink } from '../Molecules/ResourceLink';
@@ -40,6 +41,7 @@ import { nestAllResources } from '../SetupTool/utils';
4041
import type { TaxonFileDefaultDefinition } from '../TreeView/CreateTree';
4142
import { CollapsibleSection } from './CollapsibleSection';
4243
import type { InstitutionData } from './Utils';
44+
import { hasTablePermission } from '../Permissions/helpers';
4345

4446
type HierarchyNodeKind =
4547
| 'collection'
@@ -392,6 +394,7 @@ const handleEditResource = (
392394
resource: SpecifyResource<any>,
393395
refreshAllInfo: () => Promise<void>
394396
) => (
397+
hasTablePermission(resource.specifyTable.name, 'update') ?
395398
<div className="flex items-center">
396399
<ResourceLink
397400
component={Link.Default}
@@ -409,13 +412,14 @@ const handleEditResource = (
409412
{icons.pencil}
410413
{commonText.edit()}
411414
</ResourceLink>
412-
</div>
415+
</div> : null
413416
);
414417

415418
const addButton = (
416419
createResource: () => void,
417-
tableName: string
420+
table: typeof tables[keyof typeof tables]
418421
): JSX.Element => (
422+
hasTablePermission(table.name, 'create') ?
419423
<Button.LikeLink
420424
className="flex items-center gap-2 mb-2"
421425
onClick={() => {
@@ -424,9 +428,9 @@ const addButton = (
424428
>
425429
<span className="flex items-center gap-1">
426430
{icons.plus}
427-
{`${setupToolText.hierarchyAddNew()} ${tableName}`}
431+
{`${setupToolText.hierarchyAddNew()} ${tableLabel(table.name)}`}
428432
</span>
429-
</Button.LikeLink>
433+
</Button.LikeLink> : null
430434
);
431435

432436
export function Hierarchy({
@@ -561,7 +565,7 @@ export function Hierarchy({
561565
);
562566
handleNewResource();
563567
void refreshAllInfo();
564-
}, tableLabel('Collection'))}
568+
}, tables.Collection)}
565569
</div>
566570
)}
567571
{/* DISCIPLINE CONFIG DIALOGS */}
@@ -698,7 +702,7 @@ export function Hierarchy({
698702
openDisciplineCreation();
699703
setDisciplineStep(0);
700704
},
701-
`${tableLabel('Discipline')}`
705+
tables.Discipline
702706
)}
703707
</div>
704708
</CollapsibleSection>
@@ -743,7 +747,7 @@ export function Hierarchy({
743747
setNewResource(new tables.Division.Resource());
744748
handleNewResource();
745749
void refreshAllInfo();
746-
}, tableLabel('Division'))}
750+
}, tables.Division)}
747751
</div>
748752
</CollapsibleSection>
749753
</li>

specifyweb/frontend/js_src/lib/components/TreeView/Tree.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ import { ImportTree } from './CreateTree';
3131
import type { Conformations, Row, Stats } from './helpers';
3232
import { fetchStats } from './helpers';
3333
import { TreeRow } from './Row';
34+
import { userInformation } from '../InitialContext/userInformation';
3435

3536
const treeToPref = {
3637
Geography: 'geography',
@@ -284,7 +285,7 @@ export function Tree<
284285
</div>
285286
) : (
286287
<>
287-
{rows.length === 0 ? (
288+
{userInformation.isadmin && rows.length === 0 ? (
288289
<div className="flex flex-col gap-2 p-2">
289290
<Button.LikeLink
290291
aria-label={treeText.initializeEmptyTree()}

specifyweb/specify/api/crud.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ def create_obj(collection, agent, model, data: dict[str, Any], parent_obj=None,
5959
# Redirect to a dedicated object creation function for the model
6060
model_name = model.__name__.lower()
6161
if model_name in CREATE_MODEL_REDIRECTS:
62+
check_table_permissions(collection, agent, model, "create")
6263
result = CREATE_MODEL_REDIRECTS[model_name](normalize_keys(data))
6364
return model.objects.filter(id=result[f'{model_name}_id']).first()
6465

0 commit comments

Comments
 (0)