示例#1
0
def create_policy_sid_namespace(service,
                                access_level,
                                resource_type_name,
                                condition_block=None):
    """
    Simply generates the SID name. The SID groups ARN types that share an access level.

    For example, S3 objects vs. SSM Parameter have different ARN types - as do S3 objects vs S3 buckets. That's how we
    choose to group them.

    Arguments:
        service: `ssm`
        access_level: `Read`
        resource_type_name: `parameter`
        condition_block: `{"condition_key_string": "ec2:ResourceTag/purpose", "condition_type_string": "StringEquals", "condition_value": "test"}`

    Returns:
        String: A string like `SsmReadParameter`
    """
    # Sanitize the resource_type_name; otherwise we hit some list conversion
    # errors
    resource_type_name = re.sub("[^A-Za-z0-9]+", "", resource_type_name)
    # Also remove the space from the Access level, if applicable. This only
    # applies for "Permissions management"
    access_level = re.sub("[^A-Za-z0-9]+", "", access_level)
    sid_namespace_prefix = (
        capitalize_first_character(strip_special_characters(service)) +
        capitalize_first_character(access_level) +
        capitalize_first_character(resource_type_name))

    if condition_block:
        condition_key_namespace = re.sub(
            "[^A-Za-z0-9]+", "", condition_block["condition_key_string"])
        condition_type_namespace = condition_block["condition_type_string"]
        condition_value_namespace = re.sub("[^A-Za-z0-9]+", "",
                                           condition_block["condition_value"])
        sid_namespace_condition_suffix = (
            f"{capitalize_first_character(condition_key_namespace)}"
            f"{capitalize_first_character(condition_type_namespace)}"
            f"{capitalize_first_character(condition_value_namespace)}")
        sid_namespace = sid_namespace_prefix + sid_namespace_condition_suffix
    else:
        sid_namespace = sid_namespace_prefix
    return sid_namespace
示例#2
0
    def get_rendered_policy(self, minimize=None):
        """
        Get the JSON rendered policy

        Arguments:
            minimize: Reduce the character count of policies without creating overlap with other action names
        Returns:
            Dictionary: The IAM Policy JSON
        """
        statements = []
        # Only set the actions to lowercase if minimize is provided
        all_actions = get_all_actions(lowercase=True)

        # render the policy
        sids_to_be_changed = []
        for sid in self.sids:
            temp_actions = self.sids[sid]["actions"]
            if len(temp_actions) == 0:
                logger.debug(f"No actions for sid {sid}")
                continue
            actions = []
            if self.exclude_actions:
                for temp_action in temp_actions:
                    if temp_action.lower() in self.exclude_actions:
                        logger.debug(f"\tExcluded action: {temp_action}")
                    else:
                        if temp_action not in actions:
                            actions.append(temp_action)
            else:
                actions = temp_actions
            # temp_actions.clear()
            match_found = False
            if minimize is not None and isinstance(minimize, int):
                logger.debug("Minimizing statements...")
                actions = minimize_statement_actions(actions,
                                                     all_actions,
                                                     minchars=minimize)
                # searching in the existing statements
                # further minimizing the the output
                for stmt in statements:
                    if stmt["Resource"] == self.sids[sid]["arn"]:
                        stmt["Action"].extend(actions)
                        match_found = True
                        sids_to_be_changed.append(stmt["Sid"])
                        break
            logger.debug(f"Adding statement with SID {sid}")
            logger.debug(f"{sid} SID has the actions: {actions}")
            logger.debug(
                f"{sid} SID has the resources: {self.sids[sid]['arn']}")

            if not match_found:
                statements.append({
                    "Sid": sid,
                    "Effect": "Allow",
                    "Action": actions,
                    "Resource": self.sids[sid]["arn"],
                })

        if sids_to_be_changed:
            for stmt in statements:
                if stmt['Sid'] in sids_to_be_changed:
                    arn_details = parse_arn(stmt['Resource'][0])
                    resource_path = arn_details.get("resource_path")
                    resource_sid_segment = strip_special_characters(
                        f"{arn_details['resource']}{resource_path}")
                    stmt['Sid'] = create_policy_sid_namespace(
                        arn_details['service'], "Mult", resource_sid_segment)

        policy = {"Version": POLICY_LANGUAGE_VERSION, "Statement": statements}
        return policy