mirror of
				https://github.com/inventree/InvenTree.git
				synced 2025-10-31 13:15:43 +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:
		
							
								
								
									
										91
									
								
								src/frontend/tests/pui_permissions.spec.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										91
									
								
								src/frontend/tests/pui_permissions.spec.ts
									
									
									
									
									
										Normal 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(); | ||||
| }); | ||||
		Reference in New Issue
	
	Block a user