This is an automated email from the ASF dual-hosted git repository.

gcruz pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/allura.git

commit f6c97a8f2507a93ed74eb24c53a1458f056a08d6
Author: Dave Brondsema <dbronds...@slashdotmedia.com>
AuthorDate: Wed May 29 15:46:21 2024 -0400

    [#7272] do not permit tokens in URL for oauth2
---
 Allura/allura/controllers/rest.py           |  3 +++
 Allura/allura/tests/functional/test_rest.py |  3 +++
 Allura/docs/api-rest/docs.md                | 17 ++++++++---------
 Allura/docs/api-rest/securitySchemes.yaml   |  4 ++--
 Allura/docs/api-rest/traits.yaml            |  3 ---
 scripts/new_ticket.py                       |  3 +--
 scripts/project_export                      |  6 +++---
 7 files changed, 20 insertions(+), 19 deletions(-)

diff --git a/Allura/allura/controllers/rest.py 
b/Allura/allura/controllers/rest.py
index 9cb8ca180..b42605eca 100644
--- a/Allura/allura/controllers/rest.py
+++ b/Allura/allura/controllers/rest.py
@@ -80,6 +80,9 @@ class RestController:
                 if not self._is_oauth2_enabled():
                     raise
 
+                if params_auth:
+                    raise exc.HTTPUnauthorized('Do not use tokens in URL, 
instead use header Authorization: Bearer $TOKEN')
+
                 access_token = self.oauth2._authenticate()
                 if not access_token:
                     raise
diff --git a/Allura/allura/tests/functional/test_rest.py 
b/Allura/allura/tests/functional/test_rest.py
index d3b896b8e..21d260254 100644
--- a/Allura/allura/tests/functional/test_rest.py
+++ b/Allura/allura/tests/functional/test_rest.py
@@ -443,6 +443,9 @@ class TestRestHome(TestRestApiBase):
         r = self.api_post('/rest/p/test/wiki/Home', params=params)
         assert r.status_int == 200
 
+        r = self.app.get('/rest/p/test/wiki/Home', params={'access_token': 
token.access_token}, status=401)
+        assert b'Do not use tokens in URL' in r.body
+
     @td.with_wiki
     @mock.patch.dict(config, {'auth.oauth2.enabled': True})
     def test_oauth2_expired_token_authentication(self):
diff --git a/Allura/docs/api-rest/docs.md b/Allura/docs/api-rest/docs.md
index 35db1ae64..dfd25c1db 100755
--- a/Allura/docs/api-rest/docs.md
+++ b/Allura/docs/api-rest/docs.md
@@ -41,20 +41,18 @@ The following tools have API support:
 
 In order to use the API for authenticated actions, you should use the OAuth 
account page to create a consumer key for your application.  Once you have a 
consumer key, you must have a site user (e.g. your own account, if you're 
writing a single script) authorize your application to act on his or her behalf.
 
-You can also use your normal browser session as authentication for the API.  
This is useful for manually testing API calls or for in-browser applications 
(such as extensions or user-scripts).  It is not recommended for programatic 
access, however, as it would require you to store your account username and 
password, and thus cannot be easily managed or revoked.
+You can also use your normal browser session as authentication for the API.  
This is useful for manually testing API calls or for in-browser applications 
(such as extensions or user-scripts).  It is not recommended for programmatic 
access, however, as it would require you to store your account username and 
password, and thus cannot be easily managed or revoked.
 
 Without authentication, all API requests have the permissions of an anonymous 
visitor.  To view or change anything that requires a login, you must 
authenticate to the API using OAuth.  You must first register for an OAuth 
consumer token at <https://forge-allura.apache.org/auth/oauth/>.  Once you have 
registered, you will be be able to see your consumer key and consumer secret, 
or generate a bearer token, at <https://forge-allura.apache.org/auth/oauth/>.
 
 
 ### OAuth With Bearer Tokens
 
-The easiest way to use the API with your own account is to use a bearer token. 
 Once you have generated a bearer token at 
<https://forge-allura.apache.org.net/auth/oauth/>, you just include it in the 
request to the API via the `access_token` URL parameter, `access_token` POST 
form field, or http header like `Authorization: Bearer MY_BEARER_TOKEN`.
-
-Note, however, that to use bearer tokens, you *must* use HTTPS/SSL for the 
request.
+The easiest way to use the API with your own account is to use a bearer token. 
 Once you have generated a bearer token at 
<https://forge-allura.apache.org.net/auth/oauth/>, you just include it in the 
request to the API via a http header like `Authorization: Bearer 
MY_BEARER_TOKEN`.
 
 Simple URL example to access a private ticket:
 
-https://forge-allura.apache.org/rest/p/allura/tickets/35/?access_token=MY_BEARER_TOKEN
+curl -H 'Authorization: Bearer MY_BEARER_TOKEN' 
https://forge-allura.apache.org/rest/p/allura/tickets/35/
 
 Python code example to create a new ticket:
 
@@ -63,8 +61,9 @@ Python code example to create a new ticket:
 
     BEARER_TOKEN = '<bearer token from oauth page>'
 
-    r = 
requests.post('https://forge-allura.apache.org/rest/p/test-project/tickets/new',
 params={
-            'access_token': BEARER_TOKEN,
+    r = 
requests.post('https://forge-allura.apache.org/rest/p/test-project/tickets/new',
+          headers={'Authorization': f'Bearer {BEARER_TOKEN}'}
+          params={
             'ticket_form.summary': 'Test ticket',
             'ticket_form.description': 'This is a test ticket',
             'ticket_form.labels': 'test',
@@ -156,7 +155,7 @@ You can then use your access token with the REST API.  For 
instance script to cr
     print("Done.  Response was:")
     print(response)
 
-### OAuth2 Authorization
+### OAuth2 Authorization (Third-Party Apps)
 
 Another option for authorizing your apps is to use the OAuth2 workflow. This 
is accomplished by authorizing the application which generates an 
`authorization_code` that can be later exchanged for an `access_token`
 
@@ -290,4 +289,4 @@ It requires `user` and `perm` parameters and will return 
JSON dict with `result`
 
 Project information is available in DOAP format with additional custom RDF 
fields at /rest/p/{project}?doap
 
-This is separate from the normal JSON API at /rest/p/{project}
\ No newline at end of file
+This is separate from the normal JSON API at /rest/p/{project}
diff --git a/Allura/docs/api-rest/securitySchemes.yaml 
b/Allura/docs/api-rest/securitySchemes.yaml
index 60a56f4e2..a5484cd6f 100755
--- a/Allura/docs/api-rest/securitySchemes.yaml
+++ b/Allura/docs/api-rest/securitySchemes.yaml
@@ -39,7 +39,7 @@
 
 - oauth_2_0:
     description: |
-        OAuth 2.0 may also be used to authenticate API requests.
+        OAuth 2.0 may be used to authenticate API requests.
 
         First authorize your application at 
https://forge-allura.apache.org/auth/oauth2/authorize with following
         query string parameters:
@@ -64,7 +64,7 @@
 
         Use the access token in an HTTP header like:
 
-        `Authorization: Bearer MY_BEARER_TOKEN``
+        `Authorization: Bearer MY_BEARER_TOKEN`
     type: OAuth 2.0
     settings:
       authorizationUri: https://forge-allura.apache.org/auth/oauth2/authorize
diff --git a/Allura/docs/api-rest/traits.yaml b/Allura/docs/api-rest/traits.yaml
index d3f17a4f7..9e1b9170f 100755
--- a/Allura/docs/api-rest/traits.yaml
+++ b/Allura/docs/api-rest/traits.yaml
@@ -73,9 +73,6 @@
         required: true
         description: The username to check
 - bearerAuth:
-    # This can also be done with ?access_token=
-    # But it's simpler in the docs / Try It interface to just show one option
-    # and using the header method keeps it separate from query params that the 
individual API endpoints use
     headers:
       Authorization:
         description: |
diff --git a/scripts/new_ticket.py b/scripts/new_ticket.py
index 6dbf5cc73..3f67ff976 100755
--- a/scripts/new_ticket.py
+++ b/scripts/new_ticket.py
@@ -47,8 +47,7 @@ if __name__ == '__main__':
     description = sys.stdin.read()
     print('-----------------------------------------------')
 
-    r = requests.post(opts.url, params={
-        'access_token': access_token,
+    r = requests.post(opts.url, headers={'Authorization': f'Bearer 
{access_token}'}, params={
         'ticket_form.summary': summary,
         'ticket_form.description': description,
     }, timeout=30)
diff --git a/scripts/project_export b/scripts/project_export
index 160688000..9cea96605 100755
--- a/scripts/project_export
+++ b/scripts/project_export
@@ -96,11 +96,11 @@ $VERBOSE && curl_s=''
 URL="https://$HOST/rest/p/$PROJECT/admin/export";
 
 function json() {
-    python -c "import sys, json;  print json.load(sys.stdin)['$1']"
+    python3 -c "import sys, json;  print(json.load(sys.stdin)['$1'])"
 }
 
 $VERBOSE && echo "Posting to $URL"
-curl $curl_s -D $HEADERS -o $BODY --data 
"access_token=$ACCESS_TOKEN&tools=$TOOLS" "$URL" || error "Running curl failed"
+curl $curl_s -H "Authorization: Bearer $ACCESS_TOKEN" -D $HEADERS -o $BODY 
--data "tools=$TOOLS" "$URL" || error "Running curl failed"
 head -n1 $HEADERS | grep 400 && error "Invalid or missing tool"
 head -n1 $HEADERS | grep 503 && error "Export already in progress"
 head -n1 $HEADERS | grep -v 200 && error "Error: $(head -n1 $HEADERS)"
@@ -110,7 +110,7 @@ filename=`cat $BODY | json filename`
 minutes=0
 while true; do
     $VERBOSE && echo "Checking $URL_status"
-    curl $curl_s -D $HEADERS -o $BODY 
"${URL}_status?access_token=$ACCESS_TOKEN" || error "Running curl failed"
+    curl $curl_s -H "Authorization: Bearer $ACCESS_TOKEN" -D $HEADERS -o $BODY 
"${URL}_status" || error "Running curl failed"
     head -n1 $HEADERS | grep -v 200 && error "Error: $(head -n1 $HEADERS)"
     status=`cat $BODY | json status`
     $VERBOSE && echo "Status: $status"

Reply via email to