summaryrefslogtreecommitdiffstats
path: root/makeaci
blob: ab823558dd022865507c204a1918bd3c3de89a80 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
#!/usr/bin/python2
# Authors:
#   Petr Viktorin <pviktori@redhat.com>
#   John Dennis <jdennis@redhat.com>
#   Martin Kosek <mkosek@redhat.com>
#
# Copyright (C) 2011  Red Hat
# see file 'COPYING' for use and warranty information
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.

# Test the managed permission ACIs against a known-good ACI list
# to ensure that changes aren't made lightly.
# Can either regenerate ACI.txt, or validate against it.

import sys
import difflib
from argparse import ArgumentParser

from ipalib import api
from ipapython.dn import DN
from ipapython.ipaldap import LDAPEntry, IPASimpleLDAPObject, LDAPClient


class FakeLDAPClient(LDAPClient):
    """A LDAP client that can't do any LDAP operations

    Used to create and manipulate entries without an LDAP connection.
    """
    def _init_connection(self):
        self.conn = IPASimpleLDAPObject('', False, no_schema=True)


def parse_options():
    parser = ArgumentParser()
    parser.add_argument('--validate', dest='validate', action='store_true',
        default=False, help='Validate the API vs the stored API')
    parser.add_argument('filename', nargs='?', default='ACI.txt',
        help='File to create or validate, default: ACI.txt')

    options = parser.parse_args()
    return options


def generate_aci_lines(api):
    """Yields ACI lines as they appear in ACI.txt, with trailing newline"""
    update_plugin = api.Updater['update_managed_permissions']
    perm_plugin = api.Object['permission']
    fake_ldap = FakeLDAPClient('')
    for name, template, obj in update_plugin.get_templates():
        dn = perm_plugin.get_dn(name)
        entry = fake_ldap.make_entry(dn)
        update_plugin.update_entry(
            obj=obj,
            entry=entry,
            template=template,
            anonymous_read_aci=None,
            is_new=True,
        )
        aci = perm_plugin.make_aci(entry)
        yield 'dn: %s\n' % dn
        yield 'aci: %s\n' % aci


def main(options):
    api.bootstrap(
        context='cli',
        in_server=False,
        debug=False,
        verbose=0,
        validate_api=True,
        enable_ra=True,
        mode='developer',
        plugins_on_demand=False,
        basedn=DN('dc=ipa,dc=example'),
        realm='IPA.EXAMPLE',
    )
    from ipaserver.install.plugins.update_managed_permissions import (
        update_managed_permissions)
    from ipalib.plugins.permission import permission
    api.finalize()

    output_lines = list(generate_aci_lines(api))

    if options.validate:
        with open(options.filename) as file:
            file_lines = file.readlines()
        if file_lines != output_lines:
            diff = list(difflib.unified_diff(
                file_lines,
                output_lines,
                fromfile='existing %s' % options.filename,
                tofile='new result',
            ))
            for line in diff:
                print line,
            print>>sys.stderr
            print>>sys.stderr, 'Managed permission ACI validation failed.'
            print>>sys.stderr, 'Re-check permission changes and run `makeaci`.'
            exit('%s validation failed' % options.filename)
    else:
        with open(options.filename, 'w') as file:
            file.writelines(output_lines)


if __name__ == '__main__':
    options = parse_options()
    main(options)