2
0
mirror of https://github.com/inventree/InvenTree.git synced 2025-09-14 14:41:33 +00:00

[Refactor] Users and Groups (#9476)

* Cleanup UserDetail page

* Cleanup display

* Re-use UserTable

* Add 'users' permission role

* Check user roles in "admin center"

* Revert "Add 'users' permission role"

This reverts commit 35b047b2f9.

* Improve display logic

* Expose group rule-sets to API

* Prefetch rule_sets

* Add 'label' to RuleSetSerializer

* Add basic RuleSet table

* Add API endpoints for RuleSet model

* Edit group roles via table

* Refactor user permissions checks

- Remove duplicate function calls
- Refactor permission checks into new file

* Further refactoring

* Even more refactoring

* Fix user settings permission

* Add TransferList component

* Tweak GroupDrawer

* Tweak UserDrawer

* adjust user groups via API / UI

* Allow "users" detail on Group API

* Bump API version

* Enumeration of RuleSet name

* Update

* Add permission check

* Update src/frontend/src/pages/Index/Settings/AdminCenter/UserManagementPanel.tsx

Co-authored-by: Matthias Mair <code@mjmair.com>

* uncomment warning

* Extend enum usage

* More checks

* Bug fix

* Fix permission checks

* Additional testing for user roles endpoint

* Updated permission classes

- RolePermission with read-only fallback
- RolePermission with additional staff requirement

* Do not allow creation of new RuleSet objects

* Cleanup permission checks and unit tests

* Cleanup UI permission checks

* Updated class dostrings

* Cleanup

* Cleanup permission checks for UserTable

* Add playwright tests for "permission" checks

- Basic for now
- Can be extended in the future

* Tweak unit tests

* Adjust layout of warning / error messages

* Tweak group table logic

* Table cleanup

* Display roles associated with a particular group

* Cleanup

* Tweak user detail page

---------

Co-authored-by: Matthias Mair <code@mjmair.com>
This commit is contained in:
Oliver
2025-04-10 15:19:24 +10:00
committed by GitHub
parent dc1acfdacb
commit 15be7ab988
37 changed files with 1978 additions and 979 deletions

View File

@@ -0,0 +1,91 @@
/**
* Tests for UI permissions checks
*/
import test from '@playwright/test';
import { loadTab } from './helpers';
import { doCachedLogin } from './login';
/**
* Test the "admin" account
* - This is a superuser account, so should have *all* permissions available
*/
test('Permissions - Admin', async ({ browser, request }) => {
// Login, and start on the "admin" page
const page = await doCachedLogin(browser, {
username: 'admin',
password: 'inventree',
url: '/settings/admin/'
});
// Check for expected tabs
await loadTab(page, 'Machines');
await loadTab(page, 'Plugins');
await loadTab(page, 'User Management');
// Let's create a new user
await page.getByLabel('action-button-add-user').click();
await page.getByRole('button', { name: 'Submit' }).waitFor();
await page.getByRole('button', { name: 'Cancel' }).click();
});
/**
* Test the "reader" account
* - This account is read-only, but should be able to access *most* pages
*/
test('Permissions - Reader', async ({ browser, request }) => {
// Login, and start on the "admin" page
const page = await doCachedLogin(browser, {
username: 'reader',
password: 'readonly',
url: '/part/category/index/'
});
await loadTab(page, 'Category Details');
await loadTab(page, 'Parts');
// Navigate to a specific part
await page.getByPlaceholder('Search').fill('Blue Chair');
await page
.getByRole('cell', { name: 'Thumbnail Blue Chair' })
.locator('div')
.first()
.click();
await page
.getByLabel('Part Details')
.getByText('A chair - with blue paint')
.waitFor();
// Printing actions *are* available to the reader account
await page.getByLabel('action-menu-printing-actions').waitFor();
// Check that the user *does not* have the part actions menu
const actionsMenuVisible = await page
.getByLabel('action-menu-part-actions')
.isVisible({ timeout: 2500 });
if (actionsMenuVisible) {
throw new Error('Actions menu should not be visible for reader account');
}
// Navigate to the user / group info (via the navigation menu)
await page.getByLabel('navigation-menu').click();
await page.getByRole('button', { name: 'Users' }).click();
await page.getByText('System Overview', { exact: true }).waitFor();
await loadTab(page, 'Users');
await loadTab(page, 'Groups');
await page.getByRole('cell', { name: 'engineering' }).waitFor();
// Go to the user profile page
await page.getByRole('button', { name: 'Ronald Reader' }).click();
await page.getByRole('menuitem', { name: 'Account Settings' }).click();
await loadTab(page, 'Notifications');
await loadTab(page, 'Display Options');
await loadTab(page, 'Security');
await loadTab(page, 'Account');
await page.getByText('Account Details').waitFor();
await page.getByText('Profile Details').waitFor();
});