Coverage for app/venv/lib/python3.14/site-packages/weblate/auth/data.py: 100%
21 statements
« prev ^ index » next coverage.py v7.15.2, created at 2026-10-07 07:15 +0000
« prev ^ index » next coverage.py v7.15.2, created at 2026-10-07 07:15 +0000
1# Copyright © Michal Čihař <michal@weblate.org>
2#
3# SPDX-License-Identifier: GPL-3.0-or-later
5"""Definition of permissions and default roles and groups."""
7from __future__ import annotations
9from django.utils.translation import gettext_noop
11from weblate.utils.translation import pgettext_noop
13SELECTION_MANUAL = 0
14SELECTION_ALL = 1
15SELECTION_COMPONENT_LIST = 2
16SELECTION_ALL_PUBLIC = 3
17SELECTION_ALL_PROTECTED = 4
19PERMISSIONS = (
20 # Translators: Permission name
21 ("billing.view", gettext_noop("View billing info")),
22 # Translators: Permission name
23 ("change.download", gettext_noop("Download changes")),
24 # Translators: Permission name
25 ("comment.add", gettext_noop("Post comment")),
26 # Translators: Permission name
27 ("comment.delete", gettext_noop("Delete comment")),
28 # Translators: Permission name
29 ("comment.resolve", gettext_noop("Resolve comment")),
30 # Translators: Permission name
31 ("component.edit", gettext_noop("Edit component settings")),
32 # Translators: Permission name
33 ("component.lock", gettext_noop("Lock component, preventing translations")),
34 # Translators: Permission name
35 ("glossary.add", gettext_noop("Add glossary entry")),
36 # Translators: Permission name
37 ("glossary.terminology", gettext_noop("Add glossary terminology")),
38 # Translators: Permission name
39 ("glossary.edit", gettext_noop("Edit glossary entry")),
40 # Translators: Permission name
41 ("glossary.delete", gettext_noop("Delete glossary entry")),
42 # Translators: Permission name
43 ("glossary.upload", gettext_noop("Upload glossary entries")),
44 # Translators: Permission name
45 ("machinery.view", gettext_noop("Use automatic suggestions")),
46 # Translators: Permission name
47 ("memory.edit", gettext_noop("Edit translation memory")),
48 # Translators: Permission name
49 ("memory.delete", gettext_noop("Delete translation memory")),
50 # Translators: Permission name
51 ("project.edit", gettext_noop("Edit project settings")),
52 # Translators: Permission name
53 ("project.permissions", gettext_noop("Manage project access")),
54 # Translators: Permission name
55 ("reports.view", gettext_noop("Download reports")),
56 # Translators: Permission name
57 ("screenshot.add", gettext_noop("Add screenshot")),
58 # Translators: Permission name
59 ("screenshot.edit", gettext_noop("Edit screenshot")),
60 # Translators: Permission name
61 ("screenshot.delete", gettext_noop("Delete screenshot")),
62 # Translators: Permission name
63 ("source.edit", gettext_noop("Edit additional string info")),
64 # Translators: Permission name
65 ("unit.add", gettext_noop("Add new string")),
66 # Translators: Permission name
67 ("unit.delete", gettext_noop("Remove a string")),
68 # Translators: Permission name
69 ("unit.check", gettext_noop("Dismiss failing check")),
70 # Translators: Permission name
71 ("unit.edit", gettext_noop("Edit strings")),
72 # Translators: Permission name
73 ("unit.review", gettext_noop("Review strings")),
74 # Translators: Permission name
75 ("unit.bulk_edit", gettext_noop("Bulk edit strings")),
76 # Translators: Permission name
77 ("unit.override", gettext_noop("Edit string when suggestions are enforced")),
78 # Translators: Permission name
79 ("unit.template", gettext_noop("Edit source strings")),
80 # Translators: Permission name
81 ("suggestion.accept", gettext_noop("Accept suggestion")),
82 # Translators: Permission name
83 ("suggestion.add", gettext_noop("Add suggestion")),
84 # Translators: Permission name
85 ("suggestion.delete", gettext_noop("Delete suggestion")),
86 # Translators: Permission name
87 ("suggestion.vote", gettext_noop("Vote on suggestion")),
88 # Translators: Permission name
89 ("translation.add", gettext_noop("Add language for translation")),
90 # Translators: Permission name
91 ("translation.auto", gettext_noop("Perform automatic translation")),
92 # Translators: Permission name
93 ("translation.delete", gettext_noop("Delete existing translation")),
94 # Translators: Permission name
95 ("translation.download", gettext_noop("Download translation file")),
96 # Translators: Permission name
97 ("translation.add_more", gettext_noop("Add several languages for translation")),
98 # Translators: Permission name
99 ("upload.authorship", gettext_noop("Define author of uploaded translation")),
100 # Translators: Permission name
101 ("upload.overwrite", gettext_noop("Overwrite existing strings with upload")),
102 # Translators: Permission name
103 ("upload.perform", gettext_noop("Upload translations")),
104 # Translators: Permission name
105 ("vcs.access", gettext_noop("Access the internal repository")),
106 # Translators: Permission name
107 ("vcs.commit", gettext_noop("Commit changes to the internal repository")),
108 # Translators: Permission name
109 ("vcs.push", gettext_noop("Push change from the internal repository")),
110 # Translators: Permission name
111 ("vcs.reset", gettext_noop("Reset changes in the internal repository")),
112 # Translators: Permission name
113 ("vcs.view", gettext_noop("View upstream repository location")),
114 # Translators: Permission name
115 ("vcs.update", gettext_noop("Update the internal repository")),
116 # Translators: Permission name
117 ("announcement.add", gettext_noop("Post announcements")),
118)
120PERMISSION_NAMES = {perm[0] for perm in PERMISSIONS}
122# Permissions which are not scoped per project
123GLOBAL_PERMISSIONS = (
124 # Translators: Permission name
125 ("management.use", gettext_noop("Use management interface")),
126 # Translators: Permission name
127 ("project.add", gettext_noop("Add new projects")),
128 # Translators: Permission name
129 ("language.add", gettext_noop("Add language definitions")),
130 # Translators: Permission name
131 ("language.edit", gettext_noop("Manage language definitions")),
132 # Translators: Permission name
133 ("group.edit", gettext_noop("Manage teams")),
134 # Translators: Permission name
135 ("group.view", gettext_noop("View team info")),
136 # Translators: Permission name
137 ("user.edit", gettext_noop("Manage users")),
138 # Translators: Permission name
139 ("user.view", gettext_noop("View user info")),
140 # Translators: Permission name
141 ("role.edit", gettext_noop("Manage roles")),
142 # Translators: Permission name
143 ("role.view", gettext_noop("View role info")),
144 # Translators: Permission name
145 ("announcement.edit", gettext_noop("Manage announcements")),
146 # Translators: Permission name
147 ("memory.manage", gettext_noop("Manage translation memory")),
148 # Translators: Permission name
149 ("machinery.edit", gettext_noop("Manage machinery")),
150 # Translators: Permission name
151 ("componentlist.edit", gettext_noop("Manage component lists")),
152 # Translators: Permission name
153 ("billing.manage", gettext_noop("Manage billing")),
154 # Translators: Permission name
155 ("management.addons", gettext_noop("Manage site-wide add-ons")),
156)
158GLOBAL_PERM_NAMES = {perm[0] for perm in GLOBAL_PERMISSIONS}
161def filter_perms(prefix: str, exclude: set | None = None):
162 """Filter permission based on prefix."""
163 result = {perm[0] for perm in PERMISSIONS if perm[0].startswith(prefix)}
164 if exclude:
165 result = result.difference(exclude)
166 return result
169# Translator permissions
170TRANSLATE_PERMS = {
171 "comment.add",
172 "suggestion.accept",
173 "suggestion.add",
174 "suggestion.vote",
175 "unit.check",
176 "unit.edit",
177 "translation.download",
178 "upload.overwrite",
179 "upload.perform",
180 "machinery.view",
181}
183# Default set of roles
184ROLES = (
185 (
186 pgettext_noop("Access-control role", "Administration"),
187 [x[0] for x in PERMISSIONS],
188 ),
189 (
190 pgettext_noop("Access-control role", "Edit source"),
191 TRANSLATE_PERMS | {"unit.template", "source.edit"},
192 ),
193 (pgettext_noop("Access-control role", "Add suggestion"), {"suggestion.add"}),
194 (
195 pgettext_noop("Access-control role", "Access repository"),
196 {"translation.download", "vcs.access", "vcs.view"},
197 ),
198 (
199 pgettext_noop("Access-control role", "Manage glossary"),
200 filter_perms("glossary."),
201 ),
202 (
203 pgettext_noop("Access-control role", "Power user"),
204 TRANSLATE_PERMS
205 | {
206 "translation.add",
207 "unit.template",
208 "suggestion.delete",
209 "vcs.access",
210 "vcs.view",
211 }
212 | filter_perms("glossary.", {"glossary.terminology"}),
213 ),
214 (
215 pgettext_noop("Access-control role", "Translation coordinator"),
216 TRANSLATE_PERMS
217 | {
218 "announcement.add",
219 "translation.add",
220 "unit.template",
221 "suggestion.delete",
222 "vcs.access",
223 "vcs.view",
224 "unit.review",
225 "unit.override",
226 "comment.resolve",
227 }
228 | filter_perms("glossary.")
229 | filter_perms("screenshot."),
230 ),
231 (
232 pgettext_noop("Access-control role", "Review strings"),
233 TRANSLATE_PERMS | {"unit.review", "unit.override", "comment.resolve"},
234 ),
235 (pgettext_noop("Access-control role", "Translate"), TRANSLATE_PERMS),
236 (
237 pgettext_noop("Access-control role", "Manage languages"),
238 filter_perms("translation.", {"translation.auto"}),
239 ),
240 (
241 pgettext_noop("Access-control role", "Bulk editing"),
242 {"unit.bulk_edit"},
243 ),
244 (
245 pgettext_noop("Access-control role", "Automatic translation"),
246 {"translation.auto"},
247 ),
248 (
249 pgettext_noop("Access-control role", "Manage translation memory"),
250 filter_perms("memory."),
251 ),
252 (
253 pgettext_noop("Access-control role", "Manage screenshots"),
254 filter_perms("screenshot."),
255 ),
256 (
257 pgettext_noop("Access-control role", "Manage repository"),
258 filter_perms("vcs.") | {"component.lock"},
259 ),
260 (pgettext_noop("Access-control role", "Billing"), filter_perms("billing.")),
261 (pgettext_noop("Access-control role", "Add new projects"), {"project.add"}),
262)
264# Default set of roles for groups
265GROUPS = (
266 (
267 pgettext_noop("Access-control team name", "Guests"),
268 ("Add suggestion", "Access repository"),
269 SELECTION_ALL_PUBLIC,
270 ),
271 (pgettext_noop("Access-control team name", "Viewers"), (), SELECTION_ALL_PROTECTED),
272 (
273 pgettext_noop("Access-control team name", "Users"),
274 ("Power user",),
275 SELECTION_ALL_PUBLIC,
276 ),
277 (
278 pgettext_noop("Access-control team name", "Reviewers"),
279 ("Review strings",),
280 SELECTION_ALL,
281 ),
282 (
283 pgettext_noop("Access-control team name", "Managers"),
284 ("Administration",),
285 SELECTION_ALL,
286 ),
287 (
288 pgettext_noop("Access-control team name", "Project creators"),
289 ("Add new projects",),
290 SELECTION_ALL,
291 ),
292)
294# Per project group definitions
295ACL_GROUPS = {
296 pgettext_noop(
297 "Per-project access-control team name", "Administration"
298 ): "Administration",
299 pgettext_noop("Per-project access-control team name", "Review"): "Review strings",
300 pgettext_noop("Per-project access-control team name", "Translate"): "Translate",
301 pgettext_noop("Per-project access-control team name", "Sources"): "Edit source",
302 pgettext_noop(
303 "Per-project access-control team name", "Languages"
304 ): "Manage languages",
305 pgettext_noop(
306 "Per-project access-control team name", "Glossary"
307 ): "Manage glossary",
308 pgettext_noop(
309 "Per-project access-control team name", "Memory"
310 ): "Manage translation memory",
311 pgettext_noop(
312 "Per-project access-control team name", "Screenshots"
313 ): "Manage screenshots",
314 pgettext_noop(
315 "Per-project access-control team name", "Bulk editing"
316 ): "Bulk editing",
317 pgettext_noop(
318 "Per-project access-control team name", "Automatic translation"
319 ): "Automatic translation",
320 pgettext_noop("Per-project access-control team name", "VCS"): "Manage repository",
321 pgettext_noop("Per-project access-control team name", "Billing"): "Billing",
322}