Repository: salesforce/policy_sentry (python)

Issue:
Missing condition keys for s3 
Was doing some investigative work on condition keys for s3:

The following returns nothing:

```policy_sentry query condition-table --service s3```

but according to [the docs](https://docs.aws.amazon.com/IAM/latest/UserGuide/list_amazons3.html), it should return many.

This is version 0.8.7 and after having done a ```policy_sentry initialize --fetch --build```

Pull request description:
Fixes #225 - S3 conditions querying
## What does this PR do?

Fixes #225 - condition keys querying was not returning all possible results. 

## What gif best describes this PR or how it makes you feel?

![image](https://user-images.githubusercontent.com/3422255/93287972-d64a9580-f7a8-11ea-88b7-77b3e84fbdd7.png)

## Completion checklist

- [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


Patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 786b8f43..43afee0f 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,9 @@
 # Changelog
 
+## 0.8.8 (2020-09-15)
+* Fixes issue with querying condition keys (#225)
+* Adds get_region_from_arn back for our friends at Netflix :)
+
 ## 0.8.7 (2020-09-06)
 * Fixes elasticache query issue #223
 
diff --git a/policy_sentry/bin/cli.py b/policy_sentry/bin/cli.py
index 840f96f6..d7a57e71 100755
--- a/policy_sentry/bin/cli.py
+++ b/policy_sentry/bin/cli.py
@@ -2,7 +2,7 @@
 """
     Policy Sentry is a tool for generating least-privilege IAM Policies.
 """
-__version__ = "0.8.7"
+__version__ = "0.8.8"
 import click
 from policy_sentry import command
 
diff --git a/policy_sentry/querying/conditions.py b/policy_sentry/querying/conditions.py
index 462850d9..531da77b 100644
--- a/policy_sentry/querying/conditions.py
+++ b/policy_sentry/querying/conditions.py
@@ -23,8 +23,8 @@ def get_condition_keys_for_service(service_prefix):
     """
     results = []
     service_prefix_data = get_service_prefix_data(service_prefix)
-    for resource in service_prefix_data["resources"]:
-        results.extend(resource["condition_keys"])
+    for condition_key_entry in service_prefix_data["conditions"]:
+        results.append(condition_key_entry["condition"])
     results = list(dict.fromkeys(results))
     return results
 
diff --git a/policy_sentry/util/arns.py b/policy_sentry/util/arns.py
index cf2321dc..730a0a4e 100644
--- a/policy_sentry/util/arns.py
+++ b/policy_sentry/util/arns.py
@@ -163,6 +163,17 @@ def get_service_from_arn(arn):
     return result["service"]
 
 
+def get_region_from_arn(arn):
+    """Given an ARN, return the region in the ARN, if it is available. In certain cases like S3 it is not"""
+    result = parse_arn(arn)
+    # Support S3 buckets with no values under region
+    if result["region"] is None:
+        result = ""
+    else:
+        result = result["region"]
+    return result
+
+
 def get_account_from_arn(arn):
     """Given an ARN, return the account ID in the ARN, if it is available. In certain cases like S3 it is not"""
     result = parse_arn(arn)


Test patch:
diff --git a/test/querying/test_query_conditions.py b/test/querying/test_query_conditions.py
index 281d6c7b..e1d769e1 100644
--- a/test/querying/test_query_conditions.py
+++ b/test/querying/test_query_conditions.py
@@ -1,4 +1,5 @@
 import unittest
+import json
 from policy_sentry.querying.conditions import (
     get_condition_keys_for_service,
     get_condition_key_details,
@@ -12,14 +13,21 @@ class QueryConditionsTestCase(unittest.TestCase):
     def test_get_condition_keys_for_service(self):
         """querying.conditions.get_condition_keys_for_service test"""
         expected_results = [
-            'aws:ResourceTag/${TagKey}',
-            'ram:AllowsExternalPrincipals',
-            'ram:ResourceShareName',
-            'ram:PermissionArn'
+            "aws:RequestTag/${TagKey}",
+            "aws:ResourceTag/${TagKey}",
+            "aws:TagKeys",
+            "ram:AllowsExternalPrincipals",
+            "ram:PermissionArn",
+            "ram:Principal",
+            "ram:RequestedAllowsExternalPrincipals",
+            "ram:RequestedResourceType",
+            "ram:ResourceArn",
+            "ram:ResourceShareName",
+            "ram:ShareOwnerAccountId"
         ]
-        result = get_condition_keys_for_service("ram")
-        self.assertEqual(result, expected_results)
-
+        results = get_condition_keys_for_service("ram")
+        # print(json.dumps(results, indent=4))
+        self.assertEqual(results, expected_results)
 
     def test_get_condition_keys_available_to_raw_arn(self):
         expected_results = [
@@ -71,3 +79,52 @@ class QueryConditionsTestCase(unittest.TestCase):
         self.maxDiff = None
         # print(result)
         self.assertEqual(desired_result, result)
+
+    def test_gh_225_s3_conditions(self):
+        """querying.actions.get_actions_matching_condition_key"""
+        results = get_condition_keys_for_service("s3")
+        # print(json.dumps(results, indent=4))
+        expected_results = [
+            "aws:RequestTag/${TagKey}",
+            "aws:ResourceTag/${TagKey}",
+            "aws:TagKeys",
+            "s3:AccessPointNetworkOrigin",
+            "s3:DataAccessPointAccount",
+            "s3:DataAccessPointArn",
+            "s3:ExistingJobOperation",
+            "s3:ExistingJobPriority",
+            "s3:ExistingObjectTag/<key>",
+            "s3:JobSuspendedCause",
+            "s3:LocationConstraint",
+            "s3:RequestJobOperation",
+            "s3:RequestJobPriority",
+            "s3:RequestObjectTag/<key>",
+            "s3:RequestObjectTagKeys",
+            "s3:VersionId",
+            "s3:authType",
+            "s3:delimiter",
+            "s3:locationconstraint",
+            "s3:max-keys",
+            "s3:object-lock-legal-hold",
+            "s3:object-lock-mode",
+            "s3:object-lock-remaining-retention-days",
+            "s3:object-lock-retain-until-date",
+            "s3:prefix",
+            "s3:signatureAge",
+            "s3:signatureversion",
+            "s3:versionid",
+            "s3:x-amz-acl",
+            "s3:x-amz-content-sha256",
+            "s3:x-amz-copy-source",
+            "s3:x-amz-grant-full-control",
+            "s3:x-amz-grant-read",
+            "s3:x-amz-grant-read-acp",
+            "s3:x-amz-grant-write",
+            "s3:x-amz-grant-write-acp",
+            "s3:x-amz-metadata-directive",
+            "s3:x-amz-server-side-encryption",
+            "s3:x-amz-server-side-encryption-aws-kms-key-id",
+            "s3:x-amz-storage-class",
+            "s3:x-amz-website-redirect-location"
+        ]
+        self.assertListEqual(results, expected_results)