Coverage for src/backend/InvenTree/users/ruleset.py: 89%
26 statements
« prev ^ index » next coverage.py v7.15.2, created at 2026-10-07 17:47 +0000
« prev ^ index » next coverage.py v7.15.2, created at 2026-10-07 17:47 +0000
1"""Ruleset definitions which control the InvenTree user permissions."""
3from django.conf import settings
4from django.utils.translation import gettext_lazy as _
6from generic.enums import StringEnum
9class RuleSetEnum(StringEnum):
10 """Enumeration of ruleset names."""
12 ADMIN = 'admin'
13 PART_CATEGORY = 'part_category'
14 PART = 'part'
15 BOM = 'bom'
16 STOCK_LOCATION = 'stock_location'
17 STOCK = 'stock'
18 BUILD = 'build'
19 PURCHASE_ORDER = 'purchase_order'
20 SALES_ORDER = 'sales_order'
21 RETURN_ORDER = 'return_order'
22 TRANSFER_ORDER = 'transfer_order'
25# This is a list of all the ruleset choices available in the system.
26# These are used to determine the permissions available to a group of users.
27RULESET_CHOICES = [
28 (RuleSetEnum.ADMIN, _('Admin')),
29 (RuleSetEnum.PART_CATEGORY, _('Part Categories')),
30 (RuleSetEnum.PART, _('Parts')),
31 (RuleSetEnum.BOM, _('Bills of Material')),
32 (RuleSetEnum.STOCK_LOCATION, _('Stock Locations')),
33 (RuleSetEnum.STOCK, _('Stock Items')),
34 (RuleSetEnum.BUILD, _('Build Orders')),
35 (RuleSetEnum.PURCHASE_ORDER, _('Purchase Orders')),
36 (RuleSetEnum.SALES_ORDER, _('Sales Orders')),
37 (RuleSetEnum.RETURN_ORDER, _('Return Orders')),
38 (RuleSetEnum.TRANSFER_ORDER, _('Transfer Orders')),
39]
41# Ruleset names available in the system.
42RULESET_NAMES = [choice[0] for choice in RULESET_CHOICES]
44# Permission types available for each ruleset.
45RULESET_PERMISSIONS = ['view', 'add', 'change', 'delete']
47RULESET_CHANGE_INHERIT = [('part', 'bomitem')]
50def get_ruleset_models() -> dict:
51 """Return a dictionary of models associated with each ruleset.
53 This function maps particular database models to each ruleset.
54 """
55 ruleset_models = {
56 RuleSetEnum.ADMIN: [
57 'auth_group',
58 'auth_user',
59 'auth_permission',
60 'users_apitoken',
61 'users_ruleset',
62 'report_labeltemplate',
63 'report_reportasset',
64 'report_reportsnippet',
65 'report_reporttemplate',
66 'account_emailaddress',
67 'account_emailconfirmation',
68 'socialaccount_socialaccount',
69 'socialaccount_socialapp',
70 'socialaccount_socialtoken',
71 'otp_totp_totpdevice',
72 'otp_static_statictoken',
73 'otp_static_staticdevice',
74 'mfa_authenticator',
75 # Oauth
76 'oauth2_provider_application',
77 'oauth2_provider_grant',
78 'oauth2_provider_idtoken',
79 'oauth2_provider_accesstoken',
80 'oauth2_provider_refreshtoken',
81 'oauth2_provider_devicegrant',
82 # Plugins
83 'plugin_pluginconfig',
84 'plugin_pluginsetting',
85 'plugin_pluginusersetting',
86 # Misc
87 'common_barcodescanresult',
88 'common_newsfeedentry',
89 'taggit_tag',
90 'taggit_taggeditem',
91 'flags_flagstate',
92 'machine_machineconfig',
93 'machine_machinesetting',
94 # common / comms
95 'common_emailmessage',
96 'common_emailthread',
97 'django_mailbox_mailbox',
98 'django_mailbox_messageattachment',
99 'django_mailbox_message',
100 ],
101 RuleSetEnum.BOM: ['part_bomitem', 'part_bomitemsubstitute'],
102 RuleSetEnum.BUILD: [
103 'part_part',
104 'part_partcategory',
105 'part_bomitem',
106 'part_bomitemsubstitute',
107 'build_build',
108 'build_builditem',
109 'build_buildline',
110 'stock_stockitem',
111 'stock_stocklocation',
112 ],
113 RuleSetEnum.PART_CATEGORY: [
114 'part_partcategory',
115 'part_partcategoryparametertemplate',
116 'part_partcategorystar',
117 ],
118 RuleSetEnum.PART: [
119 'part_part',
120 'part_partpricing',
121 'part_partsellpricebreak',
122 'part_partinternalpricebreak',
123 'part_parttesttemplate',
124 'part_partrelated',
125 'part_partstar',
126 'part_partstocktake',
127 'part_partcategorystar',
128 'company_supplierpart',
129 'company_manufacturerpart',
130 ],
131 RuleSetEnum.STOCK_LOCATION: ['stock_stocklocation', 'stock_stocklocationtype'],
132 RuleSetEnum.STOCK: [
133 'stock_stockitem',
134 'stock_stockitemtracking',
135 'stock_stockitemtestresult',
136 ],
137 RuleSetEnum.PURCHASE_ORDER: [
138 'company_company',
139 'company_contact',
140 'company_address',
141 'company_manufacturerpart',
142 'company_supplierpart',
143 'company_supplierpricebreak',
144 'order_purchaseorder',
145 'order_purchaseorderlineitem',
146 'order_purchaseorderextraline',
147 ],
148 RuleSetEnum.SALES_ORDER: [
149 'company_company',
150 'company_contact',
151 'company_address',
152 'order_salesorder',
153 'order_salesorderallocation',
154 'order_salesorderlineitem',
155 'order_salesorderextraline',
156 'order_salesordershipment',
157 ],
158 RuleSetEnum.RETURN_ORDER: [
159 'company_company',
160 'company_contact',
161 'company_address',
162 'order_returnorder',
163 'order_returnorderlineitem',
164 'order_returnorderextraline',
165 ],
166 RuleSetEnum.TRANSFER_ORDER: [
167 'order_transferorder',
168 'order_transferorderallocation',
169 'order_transferorderlineitem',
170 ],
171 }
173 if settings.SITE_MULTI: 173 ↛ 174line 173 didn't jump to line 174 because the condition on line 173 was never true
174 ruleset_models['admin'].append('sites_site')
176 return ruleset_models
179def get_ruleset_ignore() -> list[str]:
180 """Return a list of database tables which do not require permissions."""
181 return [
182 # Core django models (not user configurable)
183 'admin_logentry',
184 'contenttypes_contenttype',
185 # Models which currently do not require permissions
186 'common_attachment',
187 'common_parametertemplate',
188 'common_parameter',
189 'common_customunit',
190 'common_dataoutput',
191 'common_inventreesetting',
192 'common_inventreeusersetting',
193 'common_notificationentry',
194 'common_notificationmessage',
195 'common_notesimage',
196 'common_projectcode',
197 'common_webhookendpoint',
198 'common_webhookmessage',
199 'common_inventreecustomuserstatemodel',
200 'common_selectionlistentry',
201 'common_selectionlist',
202 'users_owner',
203 'users_userprofile', # User profile is handled in the serializer - only own user can change
204 # Third-party tables
205 'error_report_error',
206 'exchange_rate',
207 'exchange_exchangebackend',
208 'usersessions_usersession',
209 'sessions_session',
210 # Django-q
211 'django_q_ormq',
212 'django_q_failure',
213 'django_q_task',
214 'django_q_schedule',
215 'django_q_success',
216 # Importing
217 'importer_dataimportsession',
218 'importer_dataimportcolumnmap',
219 'importer_dataimportrow',
220 ]