1# -*- coding: utf-8 -*-
2#
3# Copyright (C) 2009-2021 Edgewall Software
4# All rights reserved.
5#
6# This software is licensed as described in the file COPYING, which
7# you should have received as part of this distribution. The terms
8# are also available at https://trac.edgewall.org/wiki/TracLicense.
9#
10# This software consists of voluntary contributions made by many
11# individuals. For the exact contribution history, see the revision
12# history and logs, available at https://trac.edgewall.org/log/.
13
14from trac.core import *
15from trac.config import ConfigSection
16from trac.perm import IPermissionRequestor
17
18
19class ExtraPermissionsProvider(Component):
20    """Define arbitrary permissions.
21
22    Documentation can be found on the [wiki:TracIni#extra-permissions-section]
23    page after enabling the component."""
24
25    implements(IPermissionRequestor)
26
27    extra_permissions_section = ConfigSection('extra-permissions',
28        doc="""This section provides a way to add arbitrary permissions to a
29        Trac environment. This can be useful for adding new permissions to use
30        for workflow actions, for example.
31
32        To add new permissions, create a new section `[extra-permissions]` in
33        your `trac.ini`. Every entry in that section defines a meta-permission
34        and a comma-separated list of permissions. For example:
35        {{{#!ini
36        [extra-permissions]
37        EXTRA_ADMIN = EXTRA_VIEW, EXTRA_MODIFY, EXTRA_DELETE
38        }}}
39        This entry will define three new permissions `EXTRA_VIEW`,
40        `EXTRA_MODIFY` and `EXTRA_DELETE`, as well as a meta-permissions
41        `EXTRA_ADMIN` that grants all three permissions.
42
43        The permissions are created in upper-case characters regardless of
44        the casing of the definitions in `trac.ini`. For example, the
45        definition `extra_view` would create the permission `EXTRA_VIEW`.
46
47        If you don't want a meta-permission, start the meta-name with an
48        underscore (`_`):
49        {{{#!ini
50        [extra-permissions]
51        _perms = EXTRA_VIEW, EXTRA_MODIFY
52        }}}
53        """)
54
55    def get_permission_actions(self):
56        permissions = {}
57        for meta, perms in self.extra_permissions_section.options():
58            perms = [each.strip().upper() for each in perms.split(',')]
59            for perm in perms:
60                permissions.setdefault(perm, [])
61            meta = meta.strip().upper()
62            if meta and not meta.startswith('_'):
63                permissions.setdefault(meta, []).extend(perms)
64        return [(k, v) if v else k for k, v in permissions.items()]
65