Repository: aws/chalice (Python)

Issue:
Builtin-auth to root url does not work
The same auth handler works for any URL except `/`'.  

```
$ cat app.py
from chalice import Chalice, AuthResponse, UnauthorizedError, AuthRoute

app = Chalice(app_name='myapp')

@app.authorizer(ttl_seconds=300)
def dummy_auth(auth_request):
    return AuthResponse(
        routes=['/', '/builtin-auth'],
        principal_id='foo'
    )


@app.route('/builtin-auth', authorizer=dummy_auth)
def builtin_auth():
    return {'success': True}


@app.route('/', authorizer=dummy_auth)
def root_url():
    return {'success': True}

$ http https://rbq7d9os7h.execute-api.us-west-2.amazonaws.com/api/builtin-auth 'Authorization: yes'
HTTP/1.1 200 OK
Connection: keep-alive
Content-Length: 16
Content-Type: application/json
Date: Wed, 09 Oct 2019 19:30:47 GMT
Via: 1.1 ddc77da3ee14d939006f8adaf09d8aa5.cloudfront.net (CloudFront)
X-Amz-Cf-Id: AswySvRvN8PmsadFqomGmm_HPCYOi7yAlfwKr4_EKkXtvv8ixAyJYg==
X-Amz-Cf-Pop: HIO51-C1
X-Amzn-Trace-Id: Root=1-5d9e3567-e146bdce8b3fc3d4f7055da5;Sampled=0
X-Cache: Miss from cloudfront
x-amz-apigw-id: BT1IIHpsPHcFwDw=
x-amzn-RequestId: 1b173744-2627-4a2e-a90a-9407dd3ea155

{
    "success": true
}

$ http https://rbq7d9os7h.execute-api.us-west-2.amazonaws.com/api/ 'Authorization: yes'
HTTP/1.1 403 Forbidden
Connection: keep-alive
Content-Length: 60
Content-Type: application/json
Date: Wed, 09 Oct 2019 19:30:52 GMT
Via: 1.1 ddc77da3ee14d939006f8adaf09d8aa5.cloudfront.net (CloudFront)
X-Amz-Cf-Id: G785M-4Wfoh5O8zeSVFhDITxxorENhSWG2cK7LS98TF8ZOr9YUHQWQ==
X-Amz-Cf-Pop: HIO51-C1
X-Cache: Error from cloudfront
x-amz-apigw-id: BT1I6Fi2PHcFyKw=
x-amzn-ErrorType: AccessDeniedException
x-amzn-RequestId: ade1520b-ea56-4729-bc33-6f3a58bbbb4f

{
    "Message": "User is not authorized to access this resource"
}
```


In 1e60f9a180b9cdf1b7dcfc64aedbea7dce31b7eb we added code to workaround a quirk of API Gateway.  My hunch is that this quirk has been fixed so we can remove this special case.

https://github.com/aws/chalice/blob/6bbe063e884417335f971b0067e162eb2496758c/chalice/app.py#L1279-L1284


Discussion:

Patch:
diff --git a/.changes/next-release/19507148882-bugfix-Auth-75903.json b/.changes/next-release/19507148882-bugfix-Auth-75903.json
new file mode 100644
index 000000000..c51977b32
--- /dev/null
+++ b/.changes/next-release/19507148882-bugfix-Auth-75903.json
@@ -0,0 +1,5 @@
+{
+  "type": "bugfix",
+  "category": "Auth",
+  "description": "Fix special case processing for root URL auth (#1271)"
+}
diff --git a/chalice/app.py b/chalice/app.py
index 7c8f0a98d..c2cc09d3a 100644
--- a/chalice/app.py
+++ b/chalice/app.py
@@ -1326,11 +1326,9 @@ def _generate_arn(self, route, request, method='*'):
         # '/'.join(...)'d properly.
         base.extend([method, route[1:]])
         last_arn_segment = '/'.join(base)
-        if route in ['/', '*']:
-            # We have to special case the '/' case.  For whatever
-            # reason, API gateway adds an extra '/' to the method_arn
-            # of the auth request, so we need to do the same thing.
-            # We also have to handle the '*' case which is for wildcards
+        if route == '*':
+            # We also have to handle the '*' case which matches
+            # all routes.
             last_arn_segment += route
         final_arn = '%s:%s' % (parts[0], last_arn_segment)
         return final_arn


Test patch:
diff --git a/tests/unit/test_app.py b/tests/unit/test_app.py
index 82f25765b..b03ea3844 100644
--- a/tests/unit/test_app.py
+++ b/tests/unit/test_app.py
@@ -1460,14 +1460,11 @@ def test_can_mix_auth_routes_and_strings(auth_request):
     }
 
 
-def test_special_cased_root_resource(auth_request):
-    # Not sure why, but API gateway uses `//` for the root
-    # resource.  I've confirmed it doesn't do this for non-root
-    # URLs.  We don't to let that leak out to the APIs we expose.
+def test_root_resource(auth_request):
     auth_request.method_arn = (
-        "arn:aws:execute-api:us-west-2:123:rest-api-id/dev/GET//")
+        "arn:aws:execute-api:us-west-2:123:rest-api-id/dev/GET/")
     expected = [
-        "arn:aws:execute-api:us-west-2:123:rest-api-id/dev/GET//"
+        "arn:aws:execute-api:us-west-2:123:rest-api-id/dev/GET/"
     ]
     response = app.AuthResponse(
         [app.AuthRoute('/', ['GET'])],