Repository: salesforce/policy_sentry
Pull request #261 (2020-10-18 08:26:28)

Add `--resource-type` flag to `policy_sentry query action-table` command
## What does this PR do?

**Address https://github.com/salesforce/policy_sentry/issues/255 with the Bonus Points**

[//]: # (Required: Describe the effects of your pull request in detail. If
multiple changes are involved, a bulleted list is often useful.)

1. Adding **--resource-type** flag to `policy_sentry query action-table`
2. Removing **--wildcard-only** flag from `policy_sentry query action-table`
3. Adding method `get_actions_matching_arn_type`
4. Modifying method `get_actions_with_arn_type_and_access_level` 
4. Adding unit tests for the new methods added and methods modified
5. Adding integration tests for new -`-resource-type` flag

## What gif best describes this PR or how it makes you feel?

[//]: # (Encouraged: Insert an appropriate gif/meme to brighten up your reviewer's day.)
![ALT](https://media.giphy.com/media/l41Ye5dhLPqILtT2w/giphy.gif)

## Completion checklist

- [x] CHANGELOG.md has been updated to reflect the changes
- [x] Additions and changes have unit tests
- [x] [Unit tests, Pylint, security testing, and Integration tests are passing.](https://github.com/salesforce/policy_sentry/actions). GitHub actions does this automatically
- [x] The pull request has been appropriately labeled using the provided PR labels


reetasingh: @kmcquade let me know your thoughts on this PR
reetasingh: OutPut:
```
(venv) reetasingh-ltm8:policy_sentry reetasingh$ policy_sentry query action-table  --help
Usage: policy_sentry query action-table [OPTIONS]

  Query the Action Table from the Policy Sentry database

Options:
  --service TEXT                  Filter according to AWS service.  [required]
  --name TEXT                     The name of IAM Action. For example, if the
                                  action is "iam:ListUsers", supply
                                  "ListUsers" here.

  --access-level [read|write|list|tagging|permissions-management]
                                  Filter according to CRUD levels. Acceptable
                                  values are read, write, list, tagging,
                                  permissions-management

  --condition TEXT                Supply a condition key to show a list of all
                                  IAM actions that support the condition key.

  --resource-type TEXT            Supply a resource type to show a list of all
                                  IAM actions that support the resource type.

  --fmt [yaml|json]               Format output as YAML or JSON. Defaults to
                                  "yaml"

  -v, --verbosity LVL             Either CRITICAL, ERROR, WARNING, INFO or
                                  DEBUG

  --help                          Show this message and exit.
(venv) reetasingh-ltm8:policy_sentry reetasingh$ 
```
reetasingh: ```
(venv) reetasingh-ltm8:policy_sentry reetasingh$ policy_sentry query action-table --service ssm --access-level write --resource-type parameter
Using the Local IAM definition: /Users/reetasingh/.policy_sentry/iam-definition.json. To leverage the bundled definition instead, remove the folder $HOME/.policy_sentry/
ssm WRITE actions that have the resource type PARAMETER:
[
    "ssm:DeleteParameter",
    "ssm:DeleteParameters",
    "ssm:LabelParameterVersion",
    "ssm:PutParameter"
]
(venv) reetasingh-ltm8:policy_sentry reetasingh$ policy_sentry query action-table --service secretsmanager --access-level list --resource-type '*'
Using the Local IAM definition: /Users/reetasingh/.policy_sentry/iam-definition.json. To leverage the bundled definition instead, remove the folder $HOME/.policy_sentry/
secretsmanager LIST actions that have the resource type *:
[
    "secretsmanager:ListSecrets"
]
```
reetasingh: ```
(venv) reetasingh-ltm8:policy_sentry reetasingh$ policy_sentry query action-table --service secretsmanager  --resource-type '*'
Using the Local IAM definition: /Users/reetasingh/.policy_sentry/iam-definition.json. To leverage the bundled definition instead, remove the folder $HOME/.policy_sentry/
IAM actions under secretsmanager service that have the resource type *:
[
    "secretsmanager:GetRandomPassword",
    "secretsmanager:ListSecrets"
]
(venv) reetasingh-ltm8:policy_sentry reetasingh$ 
```
reetasingh: ```
(venv) reetasingh-ltm8:policy_sentry reetasingh$ policy_sentry query action-table --service secretsmanager  --resource-type '*' --access-level read
Using the Local IAM definition: /Users/reetasingh/.policy_sentry/iam-definition.json. To leverage the bundled definition instead, remove the folder $HOME/.policy_sentry/
secretsmanager READ actions that have the resource type *:
[
    "secretsmanager:GetRandomPassword"
]

```
reetasingh: ```
venv) reetasingh-ltm8:policy_sentry reetasingh$ policy_sentry query action-table --service ssm --resource-type parameter
Using the Local IAM definition: /Users/reetasingh/.policy_sentry/iam-definition.json. To leverage the bundled definition instead, remove the folder $HOME/.policy_sentry/
IAM actions under ssm service that have the resource type parameter:
[
    "ssm:AddTagsToResource",
    "ssm:DeleteParameter",
    "ssm:DeleteParameters",
    "ssm:GetParameter",
    "ssm:GetParameterHistory",
    "ssm:GetParameters",
    "ssm:GetParametersByPath",
    "ssm:LabelParameterVersion",
    "ssm:ListTagsForResource",
    "ssm:PutParameter",
    "ssm:RemoveTagsFromResource"
]

```
kmcquade: @reetasingh this looks awesome!

I'm good to merge this. But first - can you modify your PR so it updates the documentation for the `query action-table` section? https://policy-sentry.readthedocs.io/en/latest/querying/action-table/
reetasingh: > https://policy-sentry.readthedocs.io/en/latest/querying/action-table/

@kmcquade updated docs https://github.com/salesforce/policy_sentry/pull/261/commits/f81e27c106be5c0995a4b900d4727c933a0335e4

Patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 4039b707..c06e23f1 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -4,7 +4,7 @@
 * write-policy:
   * Minimization is improved by grouping results based on ARNs (#252)
 * query:
-  * `--resource-type` flag is added to `policy_sentry query action-table` command
+  * `--resource-type` flag added to `policy_sentry query action-table` command (Fixes #255)
 * Backend methods:
   * Added some utility functions (`get_statement_from_policy_using_sid`, `get_sid_names_from_policy` to make it easier to future-proof unit tests that rely on the ever-changing AWS IAM data.
   * Bug fix for `get_actions_for_service` (Fixes #245)
diff --git a/docs/querying/action-table.md b/docs/querying/action-table.md
index 23afafa9..6d5d741f 100644
--- a/docs/querying/action-table.md
+++ b/docs/querying/action-table.md
@@ -5,10 +5,13 @@ Action table
 # NOTE: Use --fmt yaml or --fmt json to change the output format. Defaults to json for querying
 
 # Get a list of actions that do not support resource constraints
-policy_sentry query action-table --service s3 --wildcard-only --fmt yaml
+policy_sentry query action-table --service s3 --resource-type '*' --fmt yaml
 
 # Get a list of actions at the "Read" level in S3 that do not support resource constraints
-policy_sentry query action-table --service s3 --access-level read --wildcard-only --fmt yaml
+policy_sentry query action-table --service s3 --access-level read --resource-type '*' --fmt yaml
+
+# Get a list of actions at the "Write" level in SSM service for resource type "parameter"
+policy_sentry query action-table --service ssm --access-level write --resource-type parameter
 
 # Get a list of all IAM Actions available to the RAM service
 policy_sentry query action-table --service ram
@@ -21,6 +24,7 @@ policy_sentry query action-table --service ram --access-level permissions-manage
 
 # Get a list of all IAM actions under the SES service that support the `ses:FeedbackAddress` condition key.
 policy_sentry query action-table --service ses --condition ses:FeedbackAddress
+
 ```
 
 Options
@@ -42,10 +46,8 @@ Options:
   --condition TEXT                If action table is chosen, you can supply a
                                   condition key to show a list of all IAM
                                   actions that support the condition key.
-  --wildcard-only                 If action table is chosen, show the IAM
-                                  actions that only support wildcard resources
-                                  - i.e., cannot support ARNs in the resource
-                                  block.
+  --resource-type TEXT            Supply a resource type to show a list of all
+                                  IAM actions that support the resource type.
   --fmt [yaml|json]               Format output as YAML or JSON. Defaults to
                                   "yaml"
   --v                             Set the logging level. Choices are CRITICAL, ERROR, WARNING, INFO, or DEBUG. Defaults to INFO
@@ -624,7 +626,7 @@ All IAM actions under the s3 service that have the access level permissions-mana
 ### Actions for S3 service at Write access level that only support wildcard resources (*)
 
 <details open>
-<summary>policy_sentry query action-table --service s3 --access-level read --wildcard-only --fmt yaml</summary>
+<summary>policy_sentry query action-table --service s3 --access-level read --resource-type '*' --fmt yaml</summary>
 <br>
 <pre>
 <code>
@@ -640,7 +642,7 @@ s3 READ actions that must use wildcards in the resources block:
 ### Actions for S3 service at any access level that only support wildcard resources (*)
 
 <details open>
-<summary>policy_sentry query action-table --service s3 --wildcard-only --fmt yaml</summary>
+<summary>policy_sentry query action-table --service s3 --resource-type '*' --fmt yaml</summary>
 <br>
 <pre>
 <code>
diff --git a/policy_sentry/command/query.py b/policy_sentry/command/query.py
index 3b6d005d..b223547f 100644
--- a/policy_sentry/command/query.py
+++ b/policy_sentry/command/query.py
@@ -18,9 +18,9 @@ from policy_sentry.querying.actions import (
     get_actions_for_service,
     get_actions_with_access_level,
     get_action_data,
-    get_actions_that_support_wildcard_arns_only,
     get_actions_matching_condition_key,
-    get_actions_at_access_level_that_support_wildcard_arns_only,
+    get_actions_with_arn_type_and_access_level,
+    get_actions_matching_arn_type
 )
 from policy_sentry.querying.conditions import (
     get_condition_keys_for_service,
@@ -65,11 +65,10 @@ def query():
     help="Supply a condition key to show a list of all IAM actions that support the condition key.",
 )
 @click.option(
-    "--wildcard-only",
-    is_flag=True,
+    "--resource-type",
+    type=str,
     required=False,
-    help="Show the IAM actions that only support "
-    "wildcard resources - i.e., cannot support ARNs in the resource block.",
+    help="Supply a resource type to show a list of all IAM actions that support the resource type.",
 )
 @click.option(
     "--fmt",
@@ -79,13 +78,13 @@ def query():
     help='Format output as YAML or JSON. Defaults to "yaml"',
 )
 @click_log.simple_verbosity_option(logger)
-def action_table(name, service, access_level, condition, wildcard_only, fmt):
+def action_table(name, service, access_level, condition, resource_type, fmt):
     """Query the Action Table from the Policy Sentry database"""
-    query_action_table(name, service, access_level, condition, wildcard_only, fmt)
+    query_action_table(name, service, access_level, condition, resource_type, fmt)
 
 
 def query_action_table(
-    name, service, access_level, condition, wildcard_only, fmt="json"
+    name, service, access_level, condition, resource_type, fmt="json"
 ):
     """Query the Action Table from the Policy Sentry database.
     Use this one when leveraging Policy Sentry as a library."""
@@ -114,7 +113,7 @@ def query_action_table(
             print(yaml.dump(output)) if fmt == "yaml" else [
                 print(item) for item in output
             ]
-    elif name is None and access_level and not wildcard_only:
+    elif name is None and access_level and not resource_type:
         print(
             f"All IAM actions under the {service} service that have the access level {access_level}:"
         )
@@ -123,14 +122,12 @@ def query_action_table(
         print(yaml.dump(output)) if fmt == "yaml" else [
             print(json.dumps(output, indent=4))
         ]
-    elif name is None and access_level and wildcard_only:
+    elif name is None and access_level and resource_type:
         print(
-            f"{service} {access_level.upper()} actions that must use wildcards in the resources block:"
+            f"{service} {access_level.upper()} actions that have the resource type {resource_type.upper()}:"
         )
         access_level = transform_access_level_text(access_level)
-        output = get_actions_at_access_level_that_support_wildcard_arns_only(
-            service, access_level
-        )
+        output = get_actions_with_arn_type_and_access_level(service, resource_type, access_level)
         print(yaml.dump(output)) if fmt == "yaml" else [
             print(json.dumps(output, indent=4))
         ]
@@ -145,11 +142,11 @@ def query_action_table(
         ]
     # Get a list of IAM Actions under the service that only support resources = "*"
     # (i.e., you cannot restrict it according to ARN)
-    elif wildcard_only:
+    elif resource_type:
         print(
-            f"IAM actions under {service} service that support wildcard resource values only:"
+            f"IAM actions under {service} service that have the resource type {resource_type}:"
         )
-        output = get_actions_that_support_wildcard_arns_only(service)
+        output = get_actions_matching_arn_type(service, resource_type)
         print(yaml.dump(output)) if fmt == "yaml" else [
             print(json.dumps(output, indent=4))
         ]
diff --git a/policy_sentry/querying/actions.py b/policy_sentry/querying/actions.py
index 306c7620..77d8afb1 100644
--- a/policy_sentry/querying/actions.py
+++ b/policy_sentry/querying/actions.py
@@ -95,33 +95,29 @@ def get_action_data(service, action_name):
     # raise Exception("Unknown action {}:{}".format(service, action_name))
 
 
-def get_actions_that_support_wildcard_arns_only(service_prefix):
+def get_actions_with_access_level(service_prefix, access_level):
     """
-    Get a list of actions that do not support restricting the action to resource ARNs.
-    Set service to "all" to get a list of actions across all services.
+    Get a list of actions in a service under different access levels.
 
     Arguments:
         service_prefix: A single AWS service prefix, like `s3` or `kms`
+        access_level: An access level as it is written in the database, such as 'Read', 'Write', 'List', 'Permisssions management', or 'Tagging'
 
     Returns:
-        List: A list of actions that do not support resource ARN constraints
+        List: A list of actions with that access level and service prefix
     """
     results = []
     if service_prefix == "all":
         for some_prefix in all_service_prefixes:
             service_prefix_data = get_service_prefix_data(some_prefix)
             for action_name, action_data in service_prefix_data["privileges"].items():
-                if len(action_data["resource_types"].keys()) == 1:
-                    for resource_type in action_data["resource_types"]:
-                        if resource_type == '':
-                            results.append(f"{service_prefix}:{action_name}")
+                if action_data["access_level"] == access_level:
+                    results.append(f"{some_prefix}:{action_data['privilege']}")
     else:
         service_prefix_data = get_service_prefix_data(service_prefix)
         for action_name, action_data in service_prefix_data["privileges"].items():
-            if len(action_data["resource_types"].keys()) == 1:
-                for resource_type in action_data["resource_types"]:
-                    if resource_type == '':
-                        results.append(f"{service_prefix}:{action_name}")
+            if action_data["access_level"] == access_level:
+                results.append(f"{service_prefix}:{action_data['privilege']}")
     return results
 
 
@@ -161,50 +157,103 @@ def get_actions_at_access_level_that_support_wildcard_arns_only(
     return results
 
 
-def get_actions_with_access_level(service_prefix, access_level):
+def get_actions_with_arn_type_and_access_level(
+    service_prefix, resource_type_name, access_level
+):
     """
-    Get a list of actions in a service under different access levels.
+    Get a list of actions in a service under different access levels, specific to an ARN format.
+
+    Arguments:
+        service_prefix: A single AWS service prefix, like `s3` or `kms`
+        resource_type_name: The ARN type name, like `bucket` or `key`
+        access_level: Access level like "Read" or "List" or "Permissions management"
+    Return:
+        List: A list of actions that have that ARN type and Access level
+    """
+    service_prefix_data = get_service_prefix_data(service_prefix)
+    results = []
+
+    if resource_type_name == '*':
+        return get_actions_at_access_level_that_support_wildcard_arns_only(service_prefix, access_level)
+
+    if service_prefix == "all":
+        for some_prefix in all_service_prefixes:
+            service_prefix_data = get_service_prefix_data(some_prefix)
+            for action_name, action_data in service_prefix_data["privileges"].items():
+                if action_data["access_level"] == access_level:
+                    for resource_name, resource_data in action_data["resource_types"].items():
+                        this_resource_type = resource_data["resource_type"].strip("*")
+                        if this_resource_type.lower() == resource_type_name.lower():
+                            results.append(f"{service_prefix}:{action_data['privilege']}")
+                            break
+    else:
+        for action_name, action_data in service_prefix_data["privileges"].items():
+            if action_data["access_level"] == access_level:
+                for resource_name, resource_data in action_data["resource_types"].items():
+                    this_resource_type = resource_data["resource_type"].strip("*")
+                    if this_resource_type.lower() == resource_type_name.lower():
+                        results.append(f"{service_prefix}:{action_data['privilege']}")
+                        break
+    return results
+
+
+def get_actions_that_support_wildcard_arns_only(service_prefix):
+    """
+    Get a list of actions that do not support restricting the action to resource ARNs.
+    Set service to "all" to get a list of actions across all services.
 
     Arguments:
         service_prefix: A single AWS service prefix, like `s3` or `kms`
-        access_level: An access level as it is written in the database, such as 'Read', 'Write', 'List', 'Permisssions management', or 'Tagging'
 
     Returns:
-        List: A list of actions with that access level and service prefix
+        List: A list of actions that do not support resource ARN constraints
     """
     results = []
     if service_prefix == "all":
         for some_prefix in all_service_prefixes:
             service_prefix_data = get_service_prefix_data(some_prefix)
             for action_name, action_data in service_prefix_data["privileges"].items():
-                if action_data["access_level"] == access_level:
-                    results.append(f"{some_prefix}:{action_data['privilege']}")
+                if len(action_data["resource_types"].keys()) == 1:
+                    for resource_type in action_data["resource_types"]:
+                        if resource_type == '':
+                            results.append(f"{service_prefix}:{action_name}")
     else:
         service_prefix_data = get_service_prefix_data(service_prefix)
         for action_name, action_data in service_prefix_data["privileges"].items():
-            if action_data["access_level"] == access_level:
-                results.append(f"{service_prefix}:{action_data['privilege']}")
+            if len(action_data["resource_types"].keys()) == 1:
+                for resource_type in action_data["resource_types"]:
+                    if resource_type == '':
+                        results.append(f"{service_prefix}:{action_name}")
     return results
 
 
-def get_actions_with_arn_type_and_access_level(
-    service_prefix, resource_type_name, access_level
-):
+def get_actions_matching_arn_type(service_prefix, resource_type_name):
     """
-    Get a list of actions in a service under different access levels, specific to an ARN format.
+    Get a list of actions in a service specific to ARN type.
 
     Arguments:
         service_prefix: A single AWS service prefix, like `s3` or `kms`
         resource_type_name: The ARN type name, like `bucket` or `key`
-        access_level: Access level like "Read" or "List" or "Permissions management"
     Return:
-        List: A list of actions that have that ARN type and Access level
+        List: A list of actions that have that ARN type
     """
+    if resource_type_name == '*':
+        return get_actions_that_support_wildcard_arns_only(service_prefix)
+
     service_prefix_data = get_service_prefix_data(service_prefix)
     results = []
 
-    for action_name, action_data in service_prefix_data["privileges"].items():
-        if action_data["access_level"] == access_level:
+    if service_prefix == "all":
+        for some_prefix in all_service_prefixes:
+            service_prefix_data = get_service_prefix_data(some_prefix)
+            for action_name, action_data in service_prefix_data["privileges"].items():
+                for resource_name, resource_data in action_data["resource_types"].items():
+                    this_resource_type = resource_data["resource_type"].strip("*")
+                    if this_resource_type.lower() == resource_type_name.lower():
+                        results.append(f"{service_prefix}:{action_data['privilege']}")
+                        break
+    else:
+        for action_name, action_data in service_prefix_data["privileges"].items():
             for resource_name, resource_data in action_data["resource_types"].items():
                 this_resource_type = resource_data["resource_type"].strip("*")
                 if this_resource_type.lower() == resource_type_name.lower():
diff --git a/tasks.py b/tasks.py
index bd5c02df..bb60e8e6 100755
--- a/tasks.py
+++ b/tasks.py
@@ -154,6 +154,10 @@ def query(c):
         c.run('./policy_sentry/bin/cli.py query action-table --service ram --name tagresource', pty=True)
         c.run('./policy_sentry/bin/cli.py query action-table '
               '--service ram --access-level permissions-management', pty=True)
+        c.run('./policy_sentry/bin/cli.py query action-table --service ssm --resource-type parameter', pty=True)
+        c.run('./policy_sentry/bin/cli.py query action-table --service ssm --access-level write '
+              '--resource-type parameter', pty=True)
+        c.run('policy_sentry query action-table --service ssm --resource-type parameter', pty=True)
         c.run('./policy_sentry/bin/cli.py query action-table --service ses --condition ses:FeedbackAddress', pty=True)
         c.run('echo "Querying the ARN table"', pty=True)
         c.run('./policy_sentry/bin/cli.py query arn-table --service ssm', pty=True)


Test patch:
diff --git a/test/querying/test_query_actions.py b/test/querying/test_query_actions.py
index fcd94574..a54770ce 100644
--- a/test/querying/test_query_actions.py
+++ b/test/querying/test_query_actions.py
@@ -15,7 +15,8 @@ from policy_sentry.querying.actions import (
     get_dependent_actions,
     remove_actions_that_are_not_wildcard_arn_only,
     get_actions_matching_condition_key,
-    get_actions_matching_arn
+    get_actions_matching_arn,
+    get_actions_matching_arn_type
     # get_actions_matching_condition_crud_and_arn
 )
 from policy_sentry.writing.validate import check
@@ -202,7 +203,7 @@ class QueryActionsTestCase(unittest.TestCase):
         # )
         # print(output)
 
-    def test_get_actions_with_arn_type_and_access_level(self):
+    def test_get_actions_with_arn_type_and_access_level_case_1(self):
         """querying.actions.get_actions_with_arn_type_and_access_level"""
         desired_output = [
             's3:DeleteBucketPolicy',
@@ -217,6 +218,77 @@ class QueryActionsTestCase(unittest.TestCase):
         self.maxDiff = None
         self.assertListEqual(desired_output, output)
 
+    def test_get_actions_with_arn_type_and_access_level_case_2(self):
+        """querying.actions.get_actions_with_arn_type_and_access_level with arn type"""
+        desired_output = [
+            'ssm:DeleteParameter',
+            'ssm:DeleteParameters',
+            'ssm:LabelParameterVersion',
+            'ssm:PutParameter'
+]
+        output = get_actions_with_arn_type_and_access_level(
+            "ssm", "parameter", "Write"
+        )
+        self.assertListEqual(desired_output, output)
+
+    def test_get_actions_with_arn_type_and_access_level_case_3(self):
+        """querying.actions.get_actions_with_arn_type_and_access_level with arn type"""
+        desired_output = [
+            's3:PutAccountPublicAccessBlock'
+        ]
+        output = get_actions_with_arn_type_and_access_level(
+            # "ram", "resource-share", "Write"
+            "s3", "*", "Permissions management"
+        )
+        self.assertListEqual(desired_output, output)
+
+    def test_get_actions_with_arn_type_and_access_level_case_4(self):
+        """querying.actions.get_actions_with_arn_type_and_access_level with arn type"""
+        desired_output = [
+            'secretsmanager:ListSecrets'
+        ]
+        output = get_actions_with_arn_type_and_access_level(
+            "secretsmanager", "*", "List"
+        )
+        self.assertListEqual(desired_output, output)
+
+    def test_get_actions_with_arn_type_and_access_level_case_5(self):
+        """querying.actions.get_actions_with_arn_type_and_access_level with arn type"""
+
+        output = get_actions_with_arn_type_and_access_level(
+            "all", "object", "List"
+        )
+
+        self.assertTrue(len(output) == 2)
+
+    def test_get_actions_matching_arn_type_case_1(self):
+        """querying.actions.get_actions_matching_arn_type"""
+        output = get_actions_matching_arn_type('ecr', '*')
+        self.assertEqual(output, ["ecr:GetAuthorizationToken"])
+
+    def test_get_actions_matching_arn_type_case_2(self):
+        """querying.actions.get_actions_matching_arn_type"""
+        output = get_actions_matching_arn_type('all', 'object')
+        self.assertTrue('all:AbortMultipartUpload' in output)
+
+    def test_get_actions_matching_arn_type_case_3(self):
+        """querying.actions.get_actions_matching_arn_type"""
+        output = get_actions_matching_arn_type('rds', 'object')
+        self.assertTrue(len(output) == 0)
+
+    def test_get_actions_matching_arn_type_case_4(self):
+        """querying.actions.get_actions_matching_arn_type"""
+
+        desired_output = [
+            'codestar:CreateUserProfile',
+            'codestar:DeleteUserProfile',
+            'codestar:UpdateUserProfile'
+        ]
+
+        output = get_actions_matching_arn_type("codestar", "user")
+
+        self.assertTrue(output, desired_output)
+
     def test_get_actions_matching_condition_key(self):
         """querying.actions.get_actions_matching_condition_key"""
 
@@ -281,7 +353,6 @@ class QueryActionsTestCase(unittest.TestCase):
     #     )
     #     self.assertListEqual(desired_results, results)
 
-
     def test_remove_actions_not_matching_access_level(self):
         # TODO: This method normalized the access level unnecessarily. Make sure to change that in the final iteration
         """querying.actions.remove_actions_not_matching_access_level"""