openapi: Specify securityScheme for the API in root level.

We used to specify the securityScheme for each REST operation seperately.
This is unecessary as the securityScheme can be specified in root level
and would be automatically applied to all operations. This also prevents
us accidentally not specifying the securityScheme for some operations and
was the case for /users/me/subscriptions PATCH endpoint. The root level
securityScheme can be also overriden in the operational level when
necessary.

swagger.io/docs/specification/authentication/#security
This commit is contained in:
Vishnu KS
2019-12-04 16:57:15 +05:30
committed by Tim Abbott
parent e08d029dde
commit c8ede33fc3
3 changed files with 29 additions and 90 deletions

View File

@@ -160,8 +160,11 @@ def generate_curl_example(endpoint: str, method: str,
lines = ["```curl"]
operation = endpoint + ":" + method.lower()
operation_entry = openapi_spec.spec()['paths'][endpoint][method.lower()]
global_security = openapi_spec.spec()['security']
operation_params = operation_entry.get("parameters", [])
operation_request_body = operation_entry.get("requestBody", None)
operation_security = operation_entry.get("security", None)
if settings.RUNNING_OPENAPI_CURL_TEST: # nocoverage
from zerver.openapi.curl_param_value_generators import patch_openapi_example_values
@@ -180,7 +183,20 @@ def generate_curl_example(endpoint: str, method: str,
api_url)
lines.append(" ".join(curl_first_line_parts))
authentication_required = operation_entry.get("security", False)
insecure_operations = ['/dev_fetch_api_key:post']
if operation_security is None:
if global_security == [{'basicAuth': []}]:
authentication_required = True
else:
raise AssertionError("Unhandled global securityScheme. Please update the code to handle this scheme.")
elif operation_security == []:
if operation in insecure_operations:
authentication_required = False
else:
raise AssertionError("Unknown operation without a securityScheme. Please update insecure_operations.")
else:
raise AssertionError("Unhandled securityScheme. Please update the code to handle this scheme.")
if authentication_required:
lines.append(" -u %s:%s" % (auth_email, auth_api_key))

View File

@@ -19,7 +19,8 @@ info:
url: https://www.apache.org/licenses/LICENSE-2.0.html
servers:
- url: 'https://your.zulip.server/api/v1'
security:
- basicAuth: []
#######################
# Endpoint definitions
#######################
@@ -38,6 +39,7 @@ paths:
type: string
example: iago@zulip.com
required: true
security: []
responses:
'200':
description: Success.
@@ -78,8 +80,6 @@ paths:
type: boolean
default: false
example: true
security:
- basicAuth: []
responses:
'200':
description: Success.
@@ -171,8 +171,6 @@ paths:
type: string
example: 1375801870:2942
required: true
security:
- basicAuth: []
responses:
'200':
description: Success.
@@ -197,8 +195,6 @@ paths:
type: string
example: Denmark
required: true
security:
- basicAuth: []
responses:
'200':
description: Success.
@@ -234,8 +230,6 @@ paths:
post:
description: Mark all the user's unread messages as read. This is often
called "bankruptcy" in Zulip.
security:
- basicAuth: []
responses:
'200':
description: Success.
@@ -255,8 +249,6 @@ paths:
type: integer
example: 42
required: true
security:
- basicAuth: []
responses:
'200':
description: Success.
@@ -283,8 +275,6 @@ paths:
type: string
example: new coffee machine
required: true
security:
- basicAuth: []
responses:
'200':
description: Success.
@@ -355,8 +345,6 @@ paths:
type: boolean
default: true
example: false
security:
- basicAuth: []
responses:
'200':
description: Success.
@@ -515,8 +503,6 @@ paths:
type: string
example: Hello
required: true
security:
- basicAuth: []
responses:
'200':
description: Success.
@@ -565,8 +551,6 @@ paths:
type: integer
example: 42
required: true
security:
- basicAuth: []
responses:
'200':
description: Success.
@@ -629,8 +613,6 @@ paths:
schema:
type: string
example: Hello
security:
- basicAuth: []
responses:
'200':
description: Success.
@@ -669,8 +651,6 @@ paths:
type: integer
example: 42
required: true
security:
- basicAuth: []
responses:
'200':
description: Success.
@@ -708,8 +688,6 @@ paths:
type: integer
example: 42
required: true
security:
- basicAuth: []
responses:
'200':
description: Success.
@@ -787,8 +765,6 @@ paths:
type: string
example: read
required: true
security:
- basicAuth: []
responses:
'200':
description: Success.
@@ -823,8 +799,6 @@ paths:
type: string
example: '**foo**'
required: true
security:
- basicAuth: []
responses:
'200':
description: Success.
@@ -886,8 +860,6 @@ paths:
type: string
example: '**realm_emoji**'
required: false
security:
- basicAuth: []
responses:
'200':
description: Success.
@@ -949,8 +921,6 @@ paths:
type: string
example: '**realm_emoji**'
required: false
security:
- basicAuth: []
responses:
'200':
description: Success.
@@ -981,8 +951,6 @@ paths:
type: string
format: binary
example: /path/to/file
security:
- basicAuth: []
responses:
'200':
description: Success.
@@ -1021,8 +989,6 @@ paths:
type: boolean
default: false
example: true
security:
- basicAuth: []
responses:
'200':
description: Success.
@@ -1145,8 +1111,6 @@ paths:
type: string
example: newuser
required: true
security:
- basicAuth: []
responses:
'200':
description: Success.
@@ -1178,8 +1142,6 @@ paths:
type: string
example: iago@zulip.com
required: true
security:
- basicAuth: []
responses:
'200':
description: Success.
@@ -1215,8 +1177,6 @@ paths:
/users/me:
get:
description: Get the requesting user's profile data from the backend.
security:
- basicAuth: []
responses:
'200':
description: Success
@@ -1319,8 +1279,6 @@ paths:
}
delete:
description: Delete the requesting user from the realm.
security:
- basicAuth: []
responses:
'200':
description: Bad Request
@@ -1357,8 +1315,6 @@ paths:
type: integer
example: 42
required: true
security:
- basicAuth: []
responses:
'200':
description: Success.
@@ -1425,8 +1381,6 @@ paths:
type: boolean
default: false
example: true
security:
- basicAuth: []
responses:
'200':
description: Success.
@@ -1562,8 +1516,6 @@ paths:
schema:
type: boolean
example: true
security:
- basicAuth: []
responses:
'200_without_principals':
description: Success.
@@ -1696,8 +1648,6 @@ paths:
type: string
default:
example: ['ZOE@zulip.com']
security:
- basicAuth: []
responses:
'200':
description: Success.
@@ -1774,8 +1724,6 @@ paths:
- remove
example: add
required: true
security:
- basicAuth: []
responses:
'200':
description: Success.
@@ -1827,8 +1775,6 @@ paths:
type: string
format: binary
example: /path/to/img.png
security:
- basicAuth: []
responses:
'200':
description: Success.
@@ -1841,8 +1787,6 @@ paths:
/realm/emoji:
get:
description: Get all the custom emoji in the user's realm.
security:
- basicAuth: []
responses:
'200':
description: Success.
@@ -1892,8 +1836,6 @@ paths:
type: object
example: [{"stream_id": 1, "property": "pin_to_top", "value": true}, {"stream_id": 3, "property": "color", "value": '#f00f00'}]
required: true
security:
- basicAuth: []
responses:
'200':
description: Success.
@@ -1929,8 +1871,6 @@ paths:
/realm/filters:
get:
description: Fetch all the filters set up for the user's organization.
security:
- basicAuth: []
responses:
'200':
description: Success.
@@ -1987,8 +1927,6 @@ paths:
type: string
example: https://github.com/zulip/zulip/issues/%(id)s
required: true
security:
- basicAuth: []
responses:
'200':
description: Success.
@@ -2018,8 +1956,6 @@ paths:
type: integer
example: 42
required: true
security:
- basicAuth: []
responses:
'200':
description: Success.
@@ -2111,8 +2047,6 @@ paths:
- type: integer
default: narrow=[]
example: ['stream', 'Denmark']
security:
- basicAuth: []
responses:
'200':
description: Success.
@@ -2153,8 +2087,6 @@ paths:
/server_settings:
get:
description: Fetch global settings for the Zulip server.
security:
- basicAuth: []
responses:
'200':
description: Success.
@@ -2382,8 +2314,6 @@ paths:
schema:
type: boolean
example: true
security:
- basicAuth: []
responses:
'200':
description: Success.
@@ -2489,8 +2419,6 @@ paths:
type: boolean
default: false
example: true
security:
- basicAuth: []
responses:
'200':
description: Success.
@@ -2574,8 +2502,6 @@ paths:
type: integer
example: 42
required: true
security:
- basicAuth: []
responses:
'200':
description: Success.
@@ -2650,8 +2576,6 @@ paths:
example: true
required: false
security:
- basicAuth: []
responses:
'200':
description: Success.
@@ -2705,8 +2629,6 @@ paths:
type: string
example: ["iago@zulip.com", "polonius@zulip.com"]
required: true
security:
- basicAuth: []
responses:
'200':
description: Success.
@@ -2742,8 +2664,6 @@ paths:
type: integer
example: [1, 2, 3, 4]
required: true
security:
- basicAuth: []
responses:
'200':
description: Success.
@@ -2795,8 +2715,6 @@ paths:
type: string
example: The marketing team.
required: true
security:
- basicAuth: []
responses:
'200':
description: Success.
@@ -2834,8 +2752,6 @@ paths:
type: integer
example: 42
required: true
security:
- basicAuth: []
responses:
'200':
description: Success.
@@ -2867,8 +2783,6 @@ paths:
/user_groups:
get:
description: Get all user groups of the realm.
security:
- basicAuth: []
responses:
'200':
description: Success.

View File

@@ -611,6 +611,7 @@ class ModifyExampleGenerationTestCase(ZulipTestCase):
class TestCurlExampleGeneration(ZulipTestCase):
spec_mock_without_examples = {
"security": [{"basicAuth": []}],
"paths": {
"/mark_stream_as_read": {
"post": {
@@ -641,6 +642,7 @@ class TestCurlExampleGeneration(ZulipTestCase):
}
spec_mock_with_invalid_method = {
"security": [{"basicAuth": []}],
"paths": {
"/endpoint": {
"brew": {} # the data is irrelevant as is should be rejected.
@@ -649,6 +651,7 @@ class TestCurlExampleGeneration(ZulipTestCase):
} # type: Dict[str, object]
spec_mock_using_object = {
"security": [{"basicAuth": []}],
"paths": {
"/endpoint": {
"get": {
@@ -673,6 +676,7 @@ class TestCurlExampleGeneration(ZulipTestCase):
}
spec_mock_using_param_in_path = {
"security": [{"basicAuth": []}],
"paths": {
"/endpoint/{param1}": {
"get": {
@@ -707,6 +711,7 @@ class TestCurlExampleGeneration(ZulipTestCase):
}
spec_mock_using_object_without_example = {
"security": [{"basicAuth": []}],
"paths": {
"/endpoint": {
"get": {
@@ -728,6 +733,7 @@ class TestCurlExampleGeneration(ZulipTestCase):
}
spec_mock_using_array_without_example = {
"security": [{"basicAuth": []}],
"paths": {
"/endpoint": {
"get": {
@@ -786,6 +792,7 @@ class TestCurlExampleGeneration(ZulipTestCase):
expected_curl_example = [
"```curl",
"curl -sSX POST http://localhost:9991/api/v1/mark_stream_as_read \\",
" -u BOT_EMAIL_ADDRESS:BOT_API_KEY \\",
" -d 'stream_id=1' \\",
" -d 'bool_param=false'",
"```"
@@ -822,6 +829,7 @@ class TestCurlExampleGeneration(ZulipTestCase):
expected_curl_example = [
'```curl',
'curl -sSX GET -G http://localhost:9991/api/v1/endpoint \\',
' -u BOT_EMAIL_ADDRESS:BOT_API_KEY \\',
' --data-urlencode param1=\'{"key": "value"}\'',
'```'
]
@@ -846,6 +854,7 @@ class TestCurlExampleGeneration(ZulipTestCase):
expected_curl_example = [
'```curl',
'curl -sSX GET -G http://localhost:9991/api/v1/endpoint/35 \\',
' -u BOT_EMAIL_ADDRESS:BOT_API_KEY \\',
' --data-urlencode param2=\'{"key": "value"}\'',
'```'
]