Example #1
0
def test_is_literal():
    assert is_literal(True) is True
    assert is_literal(False) is True
    assert is_literal(A) is True
    assert is_literal(~A) is True
    assert is_literal(Or(A, B)) is False
    assert is_literal(Q.zero(A)) is True
    assert is_literal(Not(Q.zero(A))) is True
    assert is_literal(Or(A, B)) is False
    assert is_literal(And(Q.zero(A), Q.zero(B))) is False
Example #2
0
def test_is_literal():
    assert is_literal(True) is True
    assert is_literal(False) is True
    assert is_literal(A) is True
    assert is_literal(~A) is True
    assert is_literal(Or(A, B)) is False
    assert is_literal(Q.zero(A)) is True
    assert is_literal(Not(Q.zero(A))) is True
    assert is_literal(Or(A, B)) is False
    assert is_literal(And(Q.zero(A), Q.zero(B))) is False
Example #3
0
    def convert_disjunction_try_split(self, expr):
        try:
            return self.convert_disjunction(expr)

        except CannotRepresentRule:
            access_rules = [self.convert_literal(e) if boolalg.is_literal(e) else self.convert_conjunction(e) for e in expr.args]
            access_rules_flat = [r for rules in access_rules for r in rules]
            return access_rules_flat
Example #4
0
    def convert_disjunction_try_split(self, expr):
        try:
            return self.convert_disjunction(expr)

        except CannotRepresentRule:
            access_rules = [
                self.convert_literal(e)
                if boolalg.is_literal(e) else self.convert_conjunction(e)
                for e in expr.args
            ]
            access_rules_flat = [r for rules in access_rules for r in rules]
            return access_rules_flat
Example #5
0
    def convert_conjunction(self, expr):
        group_ids = None
        invert_group = False
        dateranges = None
        invert_date = False
        subnets = None
        invert_subnet = False

        if expr.is_Not:
            expr = ~expr
            invert = True
        else:
            invert = False

        for arg in expr.args:
            if not boolalg.is_literal(arg):
                raise CannotRepresentRule(expr, "conjunction can only contain literals")

            acl_cond, invert = self.get_acl_cond_for_literal(arg)

            if isinstance(acl_cond, ACLGroupCondition):
                if group_ids:
                    raise CannotRepresentRule(expr, "conjunction can only contain one group / user rule")
                group_ids = [self.get_group_id_from_cond(acl_cond)]
                invert_group = invert

            elif isinstance(acl_cond, ACLUserCondition):
                if group_ids:
                    raise CannotRepresentRule(expr, "conjunction can only contain one group / user rule")
                group_ids = [self.get_private_user_group_id_from_cond(acl_cond)]
                invert_group = invert

            elif isinstance(acl_cond, (ACLDateBeforeClause, ACLDateAfterClause)):
                if dateranges:
                    raise CannotRepresentRule(expr, "conjunction can only contain one date rule")
                dateranges = [make_open_daterange_from_rule(acl_cond)]
                invert_date = invert

            elif isinstance(acl_cond, ACLIPCondition):
                if subnets and not invert:
                    raise CannotRepresentRule(expr, "conjunction can only contain one ip / iplist rule")
                subnets = [make_ipnetwork_from_rule(acl_cond)]
                invert_subnet = invert

            elif isinstance(acl_cond, ACLIPListCondition):
                if subnets and not invert:
                    raise CannotRepresentRule(expr, "conjunction can only contain one ip / iplist rule")
                subnets = get_iplist_from_cond(acl_cond)
                invert_subnet = invert

        return ((AccessRule(group_ids=group_ids, subnets=subnets, dateranges=dateranges,
                   invert_date=invert_date, invert_subnet=invert_subnet, invert_group=invert_group), invert), )
Example #6
0
    def convert_symbolic_rule(self, expr):
        # cached value? boolalg.true and boolalg.false are always returned from here
        if expr in self.symbolic_rule_to_access_rules:
            logg.info("convert: known rule: %s", expr)
            return self.symbolic_rule_to_access_rules[expr]

        elif boolalg.is_literal(expr):
            return self.convert_literal(expr)

        elif expr.func is And:
            return self.convert_conjunction_try_flip(expr)

        elif expr.func is Or:
            return self.convert_disjunction_try_split(expr)

        else:
            raise CannotRepresentRule(expr, "unknown")
Example #7
0
    def convert_symbolic_rule(self, expr):
        # cached value? boolalg.true and boolalg.false are always returned from here
        if expr in self.symbolic_rule_to_access_rules:
            logg.info("convert: known rule: %s", expr)
            return self.symbolic_rule_to_access_rules[expr]

        elif boolalg.is_literal(expr):
            return self.convert_literal(expr)

        elif expr.func is And:
            return self.convert_conjunction_try_flip(expr)

        elif expr.func is Or:
            return self.convert_disjunction_try_split(expr)

        else:
            raise CannotRepresentRule(expr, "unknown")
Example #8
0
    def convert_disjunction(self, expr):
        access_rules = []
        group_ids = set()
        subnets = set()
        dateranges = set()
        invert_group = False
        invert_subnet = False
        invert_date = False

        def check_inversion(invert_flag, inversion_state, already_found):
            if not invert_flag and inversion_state:
                raise CannotRepresentRule(expr)
            # only one negated element allowed
            if already_found and (invert_flag or inversion_state):
                raise CannotRepresentRule(expr, "negated subrules can only contain a single element")
            return invert_flag

        for arg in expr.args:
            if arg.func is And:
                access_rules.extend(self.convert_conjunction_try_flip(arg))
            else:
                if not boolalg.is_literal(arg):
                    raise CannotRepresentRule(expr, "illegal nesting in disjunction")
                acl_cond, invert = self.get_acl_cond_for_literal(arg)

                if isinstance(acl_cond, ACLGroupCondition):
                    invert_group = check_inversion(invert, invert_group, group_ids)
                    group_id = self.get_group_id_from_cond(acl_cond)
                    group_ids.add(group_id)

                if isinstance(acl_cond, ACLUserCondition):
                    invert_group = check_inversion(invert, invert_group, group_ids)
                    group_id = self.get_private_user_group_id_from_cond(acl_cond)
                    group_ids.add(group_id)

                elif isinstance(acl_cond, ACLIPCondition):
                    invert_subnet = check_inversion(invert, invert_subnet, subnets)
                    subnet = make_ipnetwork_from_rule(acl_cond)
                    subnets.add(subnet)

                elif isinstance(acl_cond, ACLIPListCondition):
                    invert_subnet = check_inversion(invert, invert_subnet, subnets)
                    rule_subnets = get_iplist_from_cond(acl_cond)
                    subnets.update(rule_subnets)

                elif isinstance(acl_cond, (ACLDateAfterClause, ACLDateBeforeClause)):
                    invert_date = check_inversion(invert, invert_date, dateranges)
                    daterange = make_open_daterange_from_rule(acl_cond)
                    dateranges.add(daterange)

        # some after conversion check for disjunctions that cannot be represented properly

        if (group_ids and (subnets or dateranges)
         or subnets and (group_ids or dateranges)
         or dateranges and (group_ids or subnets)):
            raise CannotRepresentRule(expr)

        access_rules.append((AccessRule(
            group_ids=group_ids or None, dateranges=dateranges or None, subnets=subnets or None, invert_group=invert_group,
            invert_subnet=invert_subnet, invert_date=invert_date), False))

        return tuple(access_rules)
Example #9
0
    def convert_disjunction(self, expr):
        access_rules = []
        group_ids = set()
        subnets = set()
        dateranges = set()
        invert_group = False
        invert_subnet = False
        invert_date = False

        def check_inversion(invert_flag, inversion_state, already_found):
            if not invert_flag and inversion_state:
                raise CannotRepresentRule(expr)
            # only one negated element allowed
            if already_found and (invert_flag or inversion_state):
                raise CannotRepresentRule(
                    expr, "negated subrules can only contain a single element")
            return invert_flag

        for arg in expr.args:
            if arg.func is And:
                access_rules.extend(self.convert_conjunction_try_flip(arg))
            else:
                if not boolalg.is_literal(arg):
                    raise CannotRepresentRule(
                        expr, "illegal nesting in disjunction")
                acl_cond, invert = self.get_acl_cond_for_literal(arg)

                if isinstance(acl_cond, ACLGroupCondition):
                    invert_group = check_inversion(invert, invert_group,
                                                   group_ids)
                    group_id = self.get_group_id_from_cond(acl_cond)
                    group_ids.add(group_id)

                if isinstance(acl_cond, ACLUserCondition):
                    invert_group = check_inversion(invert, invert_group,
                                                   group_ids)
                    group_id = self.get_private_user_group_id_from_cond(
                        acl_cond)
                    group_ids.add(group_id)

                elif isinstance(acl_cond, ACLIPCondition):
                    invert_subnet = check_inversion(invert, invert_subnet,
                                                    subnets)
                    subnet = make_ipnetwork_from_rule(acl_cond)
                    subnets.add(subnet)

                elif isinstance(acl_cond, ACLIPListCondition):
                    invert_subnet = check_inversion(invert, invert_subnet,
                                                    subnets)
                    rule_subnets = get_iplist_from_cond(acl_cond)
                    subnets.update(rule_subnets)

                elif isinstance(acl_cond,
                                (ACLDateAfterClause, ACLDateBeforeClause)):
                    invert_date = check_inversion(invert, invert_date,
                                                  dateranges)
                    daterange = make_open_daterange_from_rule(acl_cond)
                    dateranges.add(daterange)

        # some after conversion check for disjunctions that cannot be represented properly

        if (group_ids and (subnets or dateranges)
                or subnets and (group_ids or dateranges)
                or dateranges and (group_ids or subnets)):
            raise CannotRepresentRule(expr)

        access_rules.append((AccessRule(group_ids=group_ids or None,
                                        dateranges=dateranges or None,
                                        subnets=subnets or None,
                                        invert_group=invert_group,
                                        invert_subnet=invert_subnet,
                                        invert_date=invert_date), False))

        return tuple(access_rules)
Example #10
0
    def convert_conjunction(self, expr):
        group_ids = None
        invert_group = False
        dateranges = None
        invert_date = False
        subnets = None
        invert_subnet = False

        if expr.is_Not:
            expr = ~expr
            invert = True
        else:
            invert = False

        for arg in expr.args:
            if not boolalg.is_literal(arg):
                raise CannotRepresentRule(
                    expr, "conjunction can only contain literals")

            acl_cond, invert = self.get_acl_cond_for_literal(arg)

            if isinstance(acl_cond, ACLGroupCondition):
                if group_ids:
                    raise CannotRepresentRule(
                        expr,
                        "conjunction can only contain one group / user rule")
                group_ids = [self.get_group_id_from_cond(acl_cond)]
                invert_group = invert

            elif isinstance(acl_cond, ACLUserCondition):
                if group_ids:
                    raise CannotRepresentRule(
                        expr,
                        "conjunction can only contain one group / user rule")
                group_ids = [
                    self.get_private_user_group_id_from_cond(acl_cond)
                ]
                invert_group = invert

            elif isinstance(acl_cond,
                            (ACLDateBeforeClause, ACLDateAfterClause)):
                if dateranges:
                    raise CannotRepresentRule(
                        expr, "conjunction can only contain one date rule")
                dateranges = [make_open_daterange_from_rule(acl_cond)]
                invert_date = invert

            elif isinstance(acl_cond, ACLIPCondition):
                if subnets and not invert:
                    raise CannotRepresentRule(
                        expr,
                        "conjunction can only contain one ip / iplist rule")
                subnets = [make_ipnetwork_from_rule(acl_cond)]
                invert_subnet = invert

            elif isinstance(acl_cond, ACLIPListCondition):
                if subnets and not invert:
                    raise CannotRepresentRule(
                        expr,
                        "conjunction can only contain one ip / iplist rule")
                subnets = get_iplist_from_cond(acl_cond)
                invert_subnet = invert

        return ((AccessRule(group_ids=group_ids,
                            subnets=subnets,
                            dateranges=dateranges,
                            invert_date=invert_date,
                            invert_subnet=invert_subnet,
                            invert_group=invert_group), invert), )