mirror of
https://github.com/GSA/notifications-api.git
synced 2026-01-28 21:41:45 -05:00
Merge pull request #126 from GSA/open-api
Add OpenAPI spec for selected api endpoints
This commit is contained in:
2
.github/workflows/checks.yml
vendored
2
.github/workflows/checks.yml
vendored
@@ -107,7 +107,7 @@ jobs:
|
||||
uses: zaproxy/action-api-scan@v0.1.1
|
||||
with:
|
||||
docker_name: 'owasp/zap2docker-stable'
|
||||
target: 'http://localhost:6011/_status'
|
||||
target: 'http://localhost:6011/docs/openapi.yml'
|
||||
fail_action: true
|
||||
allow_issue_writing: false
|
||||
rules_file_name: 'zap.conf'
|
||||
|
||||
2
.github/workflows/daily_checks.yml
vendored
2
.github/workflows/daily_checks.yml
vendored
@@ -76,7 +76,7 @@ jobs:
|
||||
uses: zaproxy/action-api-scan@v0.1.1
|
||||
with:
|
||||
docker_name: 'owasp/zap2docker-weekly'
|
||||
target: 'http://localhost:6011/_status'
|
||||
target: 'http://localhost:6011/docs/openapi.yml'
|
||||
fail_action: true
|
||||
allow_issue_writing: false
|
||||
rules_file_name: 'zap.conf'
|
||||
|
||||
@@ -134,6 +134,7 @@ def register_blueprint(application):
|
||||
)
|
||||
from app.billing.rest import billing_blueprint
|
||||
from app.complaint.complaint_rest import complaint_blueprint
|
||||
from app.docs import docs as docs_blueprint
|
||||
from app.email_branding.rest import email_branding_blueprint
|
||||
from app.events.rest import events as events_blueprint
|
||||
from app.inbound_number.rest import inbound_number_blueprint
|
||||
@@ -193,6 +194,9 @@ def register_blueprint(application):
|
||||
status_blueprint.before_request(requires_no_auth)
|
||||
application.register_blueprint(status_blueprint)
|
||||
|
||||
docs_blueprint.before_request(requires_no_auth)
|
||||
application.register_blueprint(docs_blueprint)
|
||||
|
||||
# delivery receipts
|
||||
ses_callback_blueprint.before_request(requires_no_auth)
|
||||
application.register_blueprint(ses_callback_blueprint)
|
||||
|
||||
@@ -132,8 +132,9 @@ def _decode_jwt_token(auth_token, api_keys, service_id=None):
|
||||
try:
|
||||
decode_jwt_token(auth_token, api_key.secret)
|
||||
except TokenExpiredError:
|
||||
err_msg = "Error: Your system clock must be accurate to within 30 seconds"
|
||||
raise AuthError(err_msg, 403, service_id=service_id, api_key_id=api_key.id)
|
||||
if not current_app.config.get('ALLOW_EXPIRED_API_TOKEN', False):
|
||||
err_msg = "Error: Your system clock must be accurate to within 30 seconds"
|
||||
raise AuthError(err_msg, 403, service_id=service_id, api_key_id=api_key.id)
|
||||
except TokenAlgorithmError:
|
||||
err_msg = "Invalid token: algorithm used is not HS256"
|
||||
raise AuthError(err_msg, 403, service_id=service_id, api_key_id=api_key.id)
|
||||
|
||||
@@ -1,14 +1,15 @@
|
||||
import csv
|
||||
import functools
|
||||
import itertools
|
||||
import os
|
||||
import uuid
|
||||
from datetime import datetime, timedelta
|
||||
from os import getenv
|
||||
|
||||
import click
|
||||
import flask
|
||||
from click_datetime import Datetime as click_dt
|
||||
from flask import current_app, json
|
||||
from notifications_python_client.authentication import create_jwt_token
|
||||
from notifications_utils.recipients import RecipientCSV
|
||||
from notifications_utils.statsd_decorators import statsd
|
||||
from notifications_utils.template import SMSMessageTemplate
|
||||
@@ -86,7 +87,7 @@ class notify_command:
|
||||
|
||||
# in the test environment the app context is already provided and having
|
||||
# another will lead to the test db connection being closed prematurely
|
||||
if os.getenv('NOTIFY_ENVIRONMENT', '') != 'test':
|
||||
if getenv('NOTIFY_ENVIRONMENT', '') != 'test':
|
||||
# with_appcontext ensures the config is loaded, db connected, etc.
|
||||
decorators.insert(0, flask.cli.with_appcontext)
|
||||
|
||||
@@ -111,7 +112,7 @@ def purge_functional_test_data(user_email_prefix):
|
||||
|
||||
users, services, etc. Give an email prefix. Probably "notify-tests-preview".
|
||||
"""
|
||||
if os.getenv('NOTIFY_ENVIRONMENT', '') not in ['development', 'test']:
|
||||
if getenv('NOTIFY_ENVIRONMENT', '') not in ['development', 'test']:
|
||||
current_app.logger.error('Can only be run in development')
|
||||
return
|
||||
|
||||
@@ -726,7 +727,7 @@ def validate_mobile(ctx, param, value):
|
||||
@click.option('-s', '--state', default="active")
|
||||
@click.option('-d', '--admin', default=False, type=bool)
|
||||
def create_test_user(name, email, mobile_number, password, auth_type, state, admin):
|
||||
if os.getenv('NOTIFY_ENVIRONMENT', '') not in ['development', 'test']:
|
||||
if getenv('NOTIFY_ENVIRONMENT', '') not in ['development', 'test']:
|
||||
current_app.logger.error('Can only be run in development')
|
||||
return
|
||||
|
||||
@@ -746,3 +747,22 @@ def create_test_user(name, email, mobile_number, password, auth_type, state, adm
|
||||
except IntegrityError:
|
||||
print("duplicate user", user.name)
|
||||
db.session.rollback()
|
||||
|
||||
|
||||
@notify_command(name='create-admin-jwt')
|
||||
def create_admin_jwt():
|
||||
if getenv('NOTIFY_ENVIRONMENT', '') != 'development':
|
||||
current_app.logger.error('Can only be run in development')
|
||||
return
|
||||
print(create_jwt_token(current_app.config['SECRET_KEY'], current_app.config['ADMIN_CLIENT_ID']))
|
||||
|
||||
|
||||
@notify_command(name='create-user-jwt')
|
||||
@click.option('-t', '--token', required=True, prompt=False)
|
||||
def create_user_jwt(token):
|
||||
if getenv('NOTIFY_ENVIRONMENT', '') != 'development':
|
||||
current_app.logger.error('Can only be run in development')
|
||||
return
|
||||
service_id = token[-73:-37]
|
||||
api_key = token[-36:]
|
||||
print(create_jwt_token(api_key, service_id))
|
||||
|
||||
@@ -80,6 +80,7 @@ class Config(object):
|
||||
('{"%s":["%s"]}' % (ADMIN_CLIENT_ID, getenv('ADMIN_CLIENT_SECRET')))
|
||||
)
|
||||
)
|
||||
ALLOW_EXPIRED_API_TOKEN = False
|
||||
# encyption secret/salt
|
||||
SECRET_KEY = getenv('SECRET_KEY')
|
||||
DANGEROUS_SALT = getenv('DANGEROUS_SALT')
|
||||
@@ -367,6 +368,7 @@ class Development(Config):
|
||||
DANGEROUS_SALT = 'dev-notify-salt'
|
||||
SECRET_KEY = 'dev-notify-secret-key' # nosec B105 - this is only used in development
|
||||
INTERNAL_CLIENT_API_KEYS = {Config.ADMIN_CLIENT_ID: ['dev-notify-secret-key']}
|
||||
ALLOW_EXPIRED_API_TOKEN = getenv('ALLOW_EXPIRED_API_TOKEN', '0') == '1'
|
||||
|
||||
|
||||
class Test(Development):
|
||||
|
||||
11
app/docs/__init__.py
Normal file
11
app/docs/__init__.py
Normal file
@@ -0,0 +1,11 @@
|
||||
from os import path
|
||||
|
||||
from flask import Blueprint, current_app, send_file
|
||||
|
||||
docs = Blueprint('docs', __name__, url_prefix='/docs')
|
||||
|
||||
|
||||
@docs.route('/openapi.yml', methods=['GET'])
|
||||
def send_openapi():
|
||||
openapi_schema = path.join(current_app.root_path, '../docs/openapi.yml')
|
||||
return send_file(openapi_schema, mimetype='text/yaml'), 200
|
||||
@@ -8,3 +8,31 @@ For a usage example, see [our Python demo](https://github.com/GSA/notify-python-
|
||||
|
||||
An API key can be created at https://notifications-admin.app.cloud.gov/services/YOUR_SERVICE_ID/api/keys. However, in order to successfully send messages, you will need to receive a secret header token from the Notify team.
|
||||
|
||||
|
||||
## Using OpenAPI documentation
|
||||
|
||||
### Retrieving a jwt-encoded bearer token for use
|
||||
|
||||
On a mac, run
|
||||
|
||||
#### Admin UI token
|
||||
|
||||
```
|
||||
flask command create-admin-jwt | tail -n 1 | pbcopy
|
||||
```
|
||||
|
||||
#### User token
|
||||
|
||||
```
|
||||
flask command create-user-jwt --token=<USER_API_TOKEN> | tail -n 1 | pbcopy
|
||||
```
|
||||
|
||||
to copy a token to your pasteboard. This token will expire in 30 seconds
|
||||
|
||||
### Disable token expiration checking in development
|
||||
|
||||
Because jwt tokens expire so quickly, the development server can be set to allow tokens older than 30 seconds:
|
||||
|
||||
```
|
||||
env ALLOW_EXPIRED_API_TOKEN=1 make run-flask
|
||||
```
|
||||
|
||||
535
docs/openapi.yml
Normal file
535
docs/openapi.yml
Normal file
@@ -0,0 +1,535 @@
|
||||
openapi: '3.0.2'
|
||||
info:
|
||||
title: Notify API
|
||||
version: '1.0'
|
||||
description: |
|
||||
The following OpenAPI document lists a subset of the available APIs for US Notify.
|
||||
|
||||
We are currently API compatible with GOV.UK Notify. Please visit [their documentation](https://docs.notifications.service.gov.uk/rest-api.html)
|
||||
for more information.
|
||||
|
||||
Authorization uses [a JSON Web Token (JWT) bearer token](https://docs.notifications.service.gov.uk/rest-api.html#authorisation-header). The internal-api
|
||||
methods use the same scheme, but must use a specific key for the Admin UI.
|
||||
servers:
|
||||
- url: https://notify-api.app.cloud.gov
|
||||
description: Production API endpoint
|
||||
- url: https://notify-api-staging.app.cloud.gov
|
||||
description: Staging API endpoint
|
||||
- url: http://localhost:6011
|
||||
description: Local development API endpoint
|
||||
components:
|
||||
securitySchemes:
|
||||
bearerAuth:
|
||||
type: http
|
||||
scheme: bearer
|
||||
bearerFormat: JWT
|
||||
parameters:
|
||||
uuidPath:
|
||||
name: uuid
|
||||
in: path
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
schemas:
|
||||
serviceObject:
|
||||
type: object
|
||||
properties:
|
||||
active:
|
||||
type: boolean
|
||||
billing_contact_email_addresses:
|
||||
type: string
|
||||
billing_contact_names:
|
||||
type: string
|
||||
billing_reference:
|
||||
type: string
|
||||
consent_to_research:
|
||||
type: string
|
||||
contact_link:
|
||||
type: string
|
||||
count_as_live:
|
||||
type: boolean
|
||||
created_by:
|
||||
type: string
|
||||
email_branding:
|
||||
type: string
|
||||
email_from:
|
||||
type: string
|
||||
go_live_at:
|
||||
type: string
|
||||
go_live_user:
|
||||
type: string
|
||||
id:
|
||||
type: string
|
||||
inbound_api:
|
||||
type: array
|
||||
letter_branding:
|
||||
type: string
|
||||
message_limit:
|
||||
type: number
|
||||
name:
|
||||
type: string
|
||||
notes:
|
||||
type: string
|
||||
organisation:
|
||||
type: string
|
||||
organisation_type:
|
||||
type: string
|
||||
enum: ["federal", "state", "other"]
|
||||
default: "federal"
|
||||
permissions:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
prefix_sms:
|
||||
type: boolean
|
||||
purchase_order_number:
|
||||
type: string
|
||||
rate_limit:
|
||||
type: number
|
||||
research_model:
|
||||
type: boolean
|
||||
restricted:
|
||||
type: boolean
|
||||
service_callback_api:
|
||||
type: array
|
||||
volume_email:
|
||||
type: string
|
||||
volume_letter:
|
||||
type: string
|
||||
volume_sms:
|
||||
type: string
|
||||
userObject:
|
||||
type: object
|
||||
properties:
|
||||
auth_type:
|
||||
type: string
|
||||
can_use_webauthn:
|
||||
type: string
|
||||
current_session_id:
|
||||
type: string
|
||||
email_access_validated_at:
|
||||
type: string
|
||||
email_address:
|
||||
type: string
|
||||
failed_login_count:
|
||||
type: number
|
||||
id:
|
||||
type: string
|
||||
logged_in_at:
|
||||
type: string
|
||||
mobile_number:
|
||||
type: string
|
||||
name:
|
||||
type: string
|
||||
organisations:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
password_changed_at:
|
||||
type: string
|
||||
permissions:
|
||||
type: object
|
||||
properties:
|
||||
SERVICE_ID:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
platform_admin:
|
||||
type: boolean
|
||||
services:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
state:
|
||||
type: string
|
||||
enum: ["pending", "active", "inactive"]
|
||||
apiKeyResponse:
|
||||
type: object
|
||||
properties:
|
||||
apiKeys:
|
||||
type: array
|
||||
items:
|
||||
type: object
|
||||
properties:
|
||||
created_by:
|
||||
type: string
|
||||
created_at:
|
||||
type: string
|
||||
expiry_date:
|
||||
type: string
|
||||
id:
|
||||
type: string
|
||||
key_type:
|
||||
type: string
|
||||
name:
|
||||
type: string
|
||||
updated_at:
|
||||
type: string
|
||||
version:
|
||||
type: number
|
||||
paths:
|
||||
/_status?simple=1:
|
||||
get:
|
||||
description: 'Retrieve only an acknowledgement that the server is listening'
|
||||
tags:
|
||||
- public
|
||||
responses:
|
||||
'200':
|
||||
description: OK
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
status:
|
||||
type: string
|
||||
enum: ["ok"]
|
||||
/_status:
|
||||
get:
|
||||
description: 'Retrieve information on the status of the Notify API server'
|
||||
tags:
|
||||
- public
|
||||
responses:
|
||||
'200':
|
||||
description: OK
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
build_time:
|
||||
type: string
|
||||
db_version:
|
||||
type: string
|
||||
git_commit:
|
||||
type: string
|
||||
status:
|
||||
type: string
|
||||
enum: ["ok"]
|
||||
/_status/live-service-and-organisation-counts:
|
||||
get:
|
||||
description: 'Retrieve a count of live services and organizations in the Notify system'
|
||||
tags:
|
||||
- public
|
||||
responses:
|
||||
'200':
|
||||
description: OK
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
services:
|
||||
type: number
|
||||
organisations:
|
||||
type: number
|
||||
/user:
|
||||
get:
|
||||
security:
|
||||
- bearerAuth: []
|
||||
description: 'Retrieve list of all users'
|
||||
tags:
|
||||
- internal-api
|
||||
responses:
|
||||
'200':
|
||||
description: OK
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
data:
|
||||
type: array
|
||||
items:
|
||||
$ref: "#/components/schemas/userObject"
|
||||
/user/{uuid}:
|
||||
get:
|
||||
security:
|
||||
- bearerAuth: []
|
||||
description: 'Retrieve single user details'
|
||||
tags:
|
||||
- internal-api
|
||||
parameters:
|
||||
- $ref: "#/components/parameters/uuidPath"
|
||||
responses:
|
||||
'200':
|
||||
description: OK
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
data:
|
||||
$ref: "#/components/schemas/userObject"
|
||||
/organisations:
|
||||
get:
|
||||
security:
|
||||
- bearerAuth: []
|
||||
description: 'Retrieve organization details'
|
||||
tags:
|
||||
- internal-api
|
||||
responses:
|
||||
'200':
|
||||
description: OK
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: array
|
||||
items:
|
||||
type: object
|
||||
properties:
|
||||
active:
|
||||
type: boolean
|
||||
count_of_live_services:
|
||||
type: number
|
||||
domains:
|
||||
type: array
|
||||
id:
|
||||
type: string
|
||||
name:
|
||||
type: string
|
||||
organisation_type:
|
||||
type: string
|
||||
enum: ["federal", "state", "other"]
|
||||
/service:
|
||||
get:
|
||||
security:
|
||||
- bearerAuth: []
|
||||
description: 'Retrieve all services'
|
||||
tags:
|
||||
- internal-api
|
||||
responses:
|
||||
'200':
|
||||
description: OK
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
data:
|
||||
type: array
|
||||
items:
|
||||
$ref: "#/components/schemas/serviceObject"
|
||||
/service/find-services-by-name:
|
||||
get:
|
||||
security:
|
||||
- bearerAuth: []
|
||||
description: 'Find a service by name'
|
||||
tags:
|
||||
- internal-api
|
||||
parameters:
|
||||
- name: service_name
|
||||
in: query
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
responses:
|
||||
'200':
|
||||
description: OK
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
data:
|
||||
type: array
|
||||
items:
|
||||
type: object
|
||||
properties:
|
||||
active:
|
||||
type: boolean
|
||||
id:
|
||||
type: string
|
||||
name:
|
||||
type: string
|
||||
research_mode:
|
||||
type: boolean
|
||||
restricted:
|
||||
type: boolean
|
||||
/service/live-services-data:
|
||||
get:
|
||||
security:
|
||||
- bearerAuth: []
|
||||
description: 'Unsure'
|
||||
tags:
|
||||
- internal-api
|
||||
responses:
|
||||
'200':
|
||||
description: OK
|
||||
/service/{uuid}:
|
||||
get:
|
||||
security:
|
||||
- bearerAuth: []
|
||||
description: 'Retrieve details of a single service'
|
||||
tags:
|
||||
- internal-api
|
||||
parameters:
|
||||
- $ref: "#/components/parameters/uuidPath"
|
||||
responses:
|
||||
'200':
|
||||
description: OK
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
data:
|
||||
$ref: "#/components/schemas/serviceObject"
|
||||
/service/{uuid}/statistics:
|
||||
get:
|
||||
security:
|
||||
- bearerAuth: []
|
||||
description: 'Retrieve statistics about messages sent by a service'
|
||||
tags:
|
||||
- internal-api
|
||||
parameters:
|
||||
- $ref: "#/components/parameters/uuidPath"
|
||||
responses:
|
||||
'200':
|
||||
description: OK
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
/service/{uuid}/api-keys:
|
||||
get:
|
||||
security:
|
||||
- bearerAuth: []
|
||||
description: 'Retrieve api-keys for a service'
|
||||
tags:
|
||||
- internal-api
|
||||
parameters:
|
||||
- $ref: "#/components/parameters/uuidPath"
|
||||
responses:
|
||||
'200':
|
||||
description: OK
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/apiKeyResponse"
|
||||
/service/{uuid}/api-keys/{key-id}:
|
||||
get:
|
||||
security:
|
||||
- bearerAuth: []
|
||||
description: 'Retrieve details of a single API key'
|
||||
tags:
|
||||
- internal-api
|
||||
parameters:
|
||||
- $ref: "#/components/parameters/uuidPath"
|
||||
- name: key-id
|
||||
in: path
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
responses:
|
||||
'200':
|
||||
description: OK
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/apiKeyResponse"
|
||||
/service/{uuid}/users:
|
||||
get:
|
||||
security:
|
||||
- bearerAuth: []
|
||||
description: 'Retrieve users associated with this service'
|
||||
tags:
|
||||
- internal-api
|
||||
parameters:
|
||||
- $ref: "#/components/parameters/uuidPath"
|
||||
responses:
|
||||
'200':
|
||||
description: OK
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
data:
|
||||
type: array
|
||||
items:
|
||||
$ref: "#/components/schemas/userObject"
|
||||
/v2/notifications/sms:
|
||||
post:
|
||||
security:
|
||||
- bearerAuth: []
|
||||
description: 'Send an SMS message to a single phone number'
|
||||
tags:
|
||||
- external-api
|
||||
requestBody:
|
||||
required: true
|
||||
description: |
|
||||
The request body is a JSON object giving at least the phone nubmer to
|
||||
deliver the message to and the template ID to send to that number.
|
||||
|
||||
If the template has variables, provide them in the `personalisation`
|
||||
object with the variable names as the object keys.
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
required:
|
||||
- phone_number
|
||||
- template_id
|
||||
properties:
|
||||
phone_number:
|
||||
type: string
|
||||
template_id:
|
||||
type: string
|
||||
personalisation:
|
||||
type: object
|
||||
reference:
|
||||
type: string
|
||||
example:
|
||||
phone_number: "5558675309"
|
||||
template_id: "85b58733-7ebf-494e-bee2-a21a4ce17d58"
|
||||
personalisation:
|
||||
variable: "value"
|
||||
responses:
|
||||
'201':
|
||||
description: Sent
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
content:
|
||||
type: object
|
||||
properties:
|
||||
body:
|
||||
type: string
|
||||
from_number:
|
||||
type: string
|
||||
required:
|
||||
- body
|
||||
- from_number
|
||||
additionalProperties: false
|
||||
id:
|
||||
type: string
|
||||
reference:
|
||||
type: string
|
||||
scheduled_for:
|
||||
type: string
|
||||
template:
|
||||
type: object
|
||||
properties:
|
||||
id:
|
||||
type: string
|
||||
uri:
|
||||
type: string
|
||||
version:
|
||||
type: integer
|
||||
required:
|
||||
- id
|
||||
- uri
|
||||
- version
|
||||
additionalProperties: false
|
||||
uri:
|
||||
type: string
|
||||
additionalProperties: false
|
||||
required:
|
||||
- content
|
||||
- id
|
||||
- reference
|
||||
- template
|
||||
- uri
|
||||
@@ -37,5 +37,11 @@ This will run an interactive prompt to create a user, and then mark that user as
|
||||
2. On your host machine run:
|
||||
|
||||
```
|
||||
docker run -v $(pwd):/zap/wrk/:rw --network="notify-network" -t owasp/zap2docker-weekly zap-api-scan.py -t http://dev:6011/_status -f openapi -c zap.conf
|
||||
```
|
||||
docker run -v $(pwd):/zap/wrk/:rw --network="notify-network" -t owasp/zap2docker-weekly zap-api-scan.py -t http://dev:6011/docs/openapi.yml -f openapi -c zap.conf
|
||||
```
|
||||
|
||||
The equivalent command if you are running the API locally:
|
||||
|
||||
```
|
||||
docker run -v $(pwd):/zap/wrk/:rw -t owasp/zap2docker-weekly zap-api-scan.py -t http://host.docker.internal:6011/docs/openapi.yml -f openapi -c zap.conf
|
||||
```
|
||||
|
||||
@@ -6,6 +6,15 @@ _Most of the API endpoints in this repo are for internal use. These are all defi
|
||||
|
||||
Public APIs are intended for use by services and are all located under `app/v2/` to distinguish them from internal endpoints. Originally we did have a "v1" public API, where we tried to reuse / expose existing internal endpoints. The needs for public APIs are sufficiently different that we decided to separate them out. Any "v1" endpoints that remain are now purely internal and no longer exposed to services.
|
||||
|
||||
## Documenting APIs
|
||||
|
||||
New and existing APIs should be documented within [openapi.yml](./openapi.yml). Tools to help
|
||||
with editing this file:
|
||||
|
||||
* [OpenAPI Editor for VSCode](https://marketplace.visualstudio.com/items?itemName=42Crunch.vscode-openapi)
|
||||
* [OpenAPI specification](https://spec.openapis.org/oas/v3.0.2)
|
||||
|
||||
|
||||
## New APIs
|
||||
|
||||
Here are some pointers for how we write public API endpoints.
|
||||
|
||||
Reference in New Issue
Block a user