Coverage for app/venv/lib/python3.14/site-packages/weblate/auth/management/commands/list_permissions.py: 0%
48 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
5from weblate.auth.data import ACL_GROUPS, GLOBAL_PERMISSIONS, GROUPS, PERMISSIONS, ROLES
6from weblate.utils.management.base import BaseCommand
7from weblate.utils.rst import format_table
9GROUP_NAMES = {
10 "announcement": "Announcements",
11 "billing": "Billing (see :ref:`billing`)",
12 "change": "Changes",
13 "comment": "Comments",
14 "component": "Component",
15 "glossary": "Glossary",
16 "machinery": "Automatic suggestions",
17 "memory": "Translation memory",
18 "project": "Projects",
19 "reports": "Reports",
20 "screenshot": "Screenshots",
21 "source": "Source strings",
22 "suggestion": "Suggestions",
23 "translation": "Translations",
24 "upload": "Uploads",
25 "unit": "Strings",
26 "vcs": "VCS",
27}
29PERMISSION_NAMES = dict(GLOBAL_PERMISSIONS)
30PERMISSION_NAMES.update(PERMISSIONS)
33class Command(BaseCommand):
34 help = "List permissions"
36 def handle(self, *args, **options) -> None:
37 """List permissions."""
38 self.stdout.write("""
39Managing per-project access control
40-----------------------------------
42..
43 Partly generated using ./manage.py list_permissions
45""")
47 for name in ACL_GROUPS:
48 self.stdout.write(f"`{name}`\n\n\n")
50 self.stdout.write("""
51List of privileges
52++++++++++++++++++
54..
55 Generated using ./manage.py list_permissions
57""")
59 last = ""
61 table: list[list[str | list[list[str]]]] = []
62 rows: list[list[str]] = []
64 for key, name in PERMISSIONS:
65 base = key.split(".")[0]
66 if base != last:
67 if last:
68 table.append([GROUP_NAMES[last], rows])
69 last = base
70 rows = []
72 rows.append(
73 [
74 name,
75 [
76 [f":guilabel:`{name}`"]
77 for name, permissions in ROLES
78 if key in permissions
79 ],
80 ]
81 )
82 # Fill in blank tables when there is no role
83 for row in rows:
84 if len(row[1]) == 0:
85 row[1].append([""])
86 table.append([GROUP_NAMES[last], rows])
88 rows = [
89 [
90 name,
91 [
92 [f":guilabel:`{name}`"]
93 for name, permissions in ROLES
94 if key in permissions
95 ],
96 ]
97 for key, name in GLOBAL_PERMISSIONS
98 ]
99 # Fill in blank tables when there is no role
100 for row in rows:
101 if len(row[1]) == 0:
102 row[1].append([""])
103 table.append(["Site wide privileges", rows])
105 self.stdout.writelines(
106 format_table(table, ["Scope", "Permission", "Built-in roles"])
107 )
108 self.stdout.write("""
109.. note::
111""")
113 self.stdout.write("""
114List of built-in roles
115++++++++++++++++++++++
117..
118 Generated using ./manage.py list_permissions
120""")
122 self.stdout.write(".. list-table::\n\n")
124 for name, permissions in ROLES:
125 self.stdout.write(f" * - `{name}`")
126 self.stdout.write(" - ", ending="")
127 self.stdout.write(
128 "\n ".join(
129 f"* :guilabel:`{PERMISSION_NAMES[perm]}`"
130 for perm in sorted(permissions)
131 )
132 )
134 self.stdout.write("""
135List of teams
136+++++++++++++
138""")
140 for name, roles, _selection in GROUPS:
141 self.stdout.write(f"`{name}`\n\n\n")
142 if not roles:
143 roles_str = "none"
144 else:
145 roles_str = ", ".join(f"`{role}`" for role in roles)
146 self.stdout.write(f" Default roles: {roles_str}\n\n")