Refactor API Schema and validation

- /schema now returns full openapi/swagger schema
- That schema is used to validate incoming requests
- And used as a contract in future integration tests
- Moved route files up one level
- Fixed incorrect 404 reponses when getting objects
- Fixed saving new objects and passing jsonschemavalidation
This commit is contained in:
Jamie Curnow
2024-10-09 18:05:15 +10:00
parent 63d06da8a8
commit dfe2588523
123 changed files with 5363 additions and 2574 deletions

View File

@ -0,0 +1,79 @@
{
"operationId": "updateUserAuth",
"summary": "Update a User's Authentication",
"tags": ["Users"],
"security": [
{
"BearerAuth": ["users"]
}
],
"parameters": [
{
"in": "path",
"name": "userID",
"schema": {
"oneOf": [
{
"type": "string",
"pattern": "^me$"
},
{
"type": "integer",
"minimum": 1
}
]
},
"required": true,
"description": "User ID or 'me' for yourself",
"example": 2
}
],
"requestBody": {
"description": "Auth Payload",
"required": true,
"content": {
"application/json": {
"schema": {
"type": "object",
"required": ["type", "secret"],
"properties": {
"type": {
"type": "string",
"pattern": "^password$",
"example": "password"
},
"current": {
"type": "string",
"minLength": 1,
"maxLength": 64,
"example": "changeme"
},
"secret": {
"type": "string",
"minLength": 8,
"maxLength": 64,
"example": "mySuperN3wP@ssword!"
}
}
}
}
}
},
"responses": {
"200": {
"description": "200 response",
"content": {
"application/json": {
"examples": {
"default": {
"value": true
}
},
"schema": {
"type": "boolean"
}
}
}
}
}
}

View File

@ -0,0 +1,40 @@
{
"operationId": "deleteUser",
"summary": "Delete a User",
"tags": ["Users"],
"security": [
{
"BearerAuth": ["users"]
}
],
"parameters": [
{
"in": "path",
"name": "userID",
"schema": {
"type": "integer",
"minimum": 1
},
"required": true,
"description": "User ID",
"example": 2
}
],
"responses": {
"200": {
"description": "200 response",
"content": {
"application/json": {
"examples": {
"default": {
"value": true
}
},
"schema": {
"type": "boolean"
}
}
}
}
}
}

View File

@ -0,0 +1,58 @@
{
"operationId": "getUser",
"summary": "Get a user",
"tags": ["Users"],
"security": [
{
"BearerAuth": ["users"]
}
],
"parameters": [
{
"in": "path",
"name": "userID",
"schema": {
"oneOf": [
{
"type": "string",
"pattern": "^me$"
},
{
"type": "integer",
"minimum": 1
}
]
},
"required": true,
"description": "User ID or 'me' for yourself",
"example": 1
}
],
"responses": {
"200": {
"description": "200 response",
"content": {
"application/json": {
"examples": {
"default": {
"value": {
"id": 1,
"created_on": "2020-01-30T09:36:08.000Z",
"modified_on": "2020-01-30T09:41:04.000Z",
"is_disabled": 0,
"email": "jc@jc21.com",
"name": "Jamie Curnow",
"nickname": "James",
"avatar": "//www.gravatar.com/avatar/6193176330f8d38747f038c170ddb193?default=mm",
"roles": ["admin"]
}
}
},
"schema": {
"$ref": "../../../components/user-object.json"
}
}
}
}
}
}

View File

@ -0,0 +1,73 @@
{
"operationId": "loginAsUser",
"summary": "Login as this user",
"tags": ["Users"],
"security": [
{
"BearerAuth": ["users"]
}
],
"parameters": [
{
"in": "path",
"name": "userID",
"schema": {
"type": "integer",
"minimum": 1
},
"required": true,
"description": "User ID",
"example": 2
}
],
"responses": {
"200": {
"description": "200 response",
"content": {
"application/json": {
"examples": {
"default": {
"value": {
"token": "eyJhbGciOiJSUzI1NiIsInR...16OjT8B3NLyXg",
"expires": "2020-01-31T10:56:23.239Z",
"user": {
"id": 1,
"created_on": "2020-01-30T10:43:44.000Z",
"modified_on": "2020-01-30T10:43:44.000Z",
"is_disabled": 0,
"email": "jc@jc21.com",
"name": "Jamie Curnow",
"nickname": "James",
"avatar": "//www.gravatar.com/avatar/3c8d73f45fd8763f827b964c76e6032a?default=mm",
"roles": ["admin"]
}
}
}
},
"schema": {
"type": "object",
"description": "Login object",
"required": ["expires", "token", "user"],
"additionalProperties": false,
"properties": {
"expires": {
"description": "Token Expiry Unix Time",
"example": 1566540249,
"minimum": 1,
"type": "number"
},
"token": {
"description": "JWT Token",
"example": "eyJhbGciOiJSUzUxMiIsInR5cCI6IkpXVCJ9.ey...xaHKYr3Kk6MvkUjcC4",
"type": "string"
},
"user": {
"$ref": "../../../../components/user-object.json"
}
}
}
}
}
}
}
}

View File

@ -0,0 +1,51 @@
{
"operationId": "updateUserPermissions",
"summary": "Update a User's Permissions",
"tags": ["Users"],
"security": [
{
"BearerAuth": ["users"]
}
],
"parameters": [
{
"in": "path",
"name": "userID",
"schema": {
"type": "integer",
"minimum": 1
},
"required": true,
"description": "User ID",
"example": 2
}
],
"requestBody": {
"description": "Permissions Payload",
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "../../../../components/permission-object.json"
}
}
}
},
"responses": {
"200": {
"description": "200 response",
"content": {
"application/json": {
"examples": {
"default": {
"value": true
}
},
"schema": {
"type": "boolean"
}
}
}
}
}
}

View File

@ -0,0 +1,88 @@
{
"operationId": "updateUser",
"summary": "Update a User",
"tags": ["Users"],
"security": [
{
"BearerAuth": ["users"]
}
],
"parameters": [
{
"in": "path",
"name": "userID",
"schema": {
"oneOf": [
{
"type": "string",
"pattern": "^me$"
},
{
"type": "integer",
"minimum": 1
}
]
},
"required": true,
"description": "User ID or 'me' for yourself",
"example": 2
}
],
"requestBody": {
"description": "User Payload",
"required": true,
"content": {
"application/json": {
"schema": {
"type": "object",
"additionalProperties": false,
"minProperties": 1,
"properties": {
"name": {
"$ref": "../../../components/user-object.json#/properties/name"
},
"nickname": {
"$ref": "../../../components/user-object.json#/properties/nickname"
},
"email": {
"$ref": "../../../components/user-object.json#/properties/email"
},
"roles": {
"$ref": "../../../components/user-object.json#/properties/roles"
},
"is_disabled": {
"$ref": "../../../components/user-object.json#/properties/is_disabled"
}
}
}
}
}
},
"responses": {
"200": {
"description": "200 response",
"content": {
"application/json": {
"examples": {
"default": {
"value": {
"id": 2,
"created_on": "2020-01-30T09:36:08.000Z",
"modified_on": "2020-01-30T09:41:04.000Z",
"is_disabled": 0,
"email": "jc@jc21.com",
"name": "Jamie Curnow",
"nickname": "James",
"avatar": "//www.gravatar.com/avatar/6193176330f8d38747f038c170ddb193?default=mm",
"roles": ["admin"]
}
}
},
"schema": {
"$ref": "../../../components/user-object.json"
}
}
}
}
}
}