mirror of
				https://github.com/NginxProxyManager/nginx-proxy-manager.git
				synced 2025-10-31 15:53:33 +00:00 
			
		
		
		
	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:
		
							
								
								
									
										74
									
								
								backend/schema/paths/users/get.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										74
									
								
								backend/schema/paths/users/get.json
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,74 @@ | ||||
| { | ||||
| 	"operationId": "getUsers", | ||||
| 	"summary": "Get all users", | ||||
| 	"tags": ["Users"], | ||||
| 	"security": [ | ||||
| 		{ | ||||
| 			"BearerAuth": ["users"] | ||||
| 		} | ||||
| 	], | ||||
| 	"parameters": [ | ||||
| 		{ | ||||
| 			"in": "query", | ||||
| 			"name": "expand", | ||||
| 			"description": "Expansions", | ||||
| 			"schema": { | ||||
| 				"type": "string", | ||||
| 				"enum": ["permissions"] | ||||
| 			} | ||||
| 		} | ||||
| 	], | ||||
| 	"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"] | ||||
| 								} | ||||
| 							] | ||||
| 						}, | ||||
| 						"withPermissions": { | ||||
| 							"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"], | ||||
| 									"permissions": { | ||||
| 										"visibility": "all", | ||||
| 										"proxy_hosts": "manage", | ||||
| 										"redirection_hosts": "manage", | ||||
| 										"dead_hosts": "manage", | ||||
| 										"streams": "manage", | ||||
| 										"access_lists": "manage", | ||||
| 										"certificates": "manage" | ||||
| 									} | ||||
| 								} | ||||
| 							] | ||||
| 						} | ||||
| 					}, | ||||
| 					"schema": { | ||||
| 						"$ref": "../../components/user-list.json" | ||||
| 					} | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
							
								
								
									
										88
									
								
								backend/schema/paths/users/post.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										88
									
								
								backend/schema/paths/users/post.json
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,88 @@ | ||||
| { | ||||
| 	"operationId": "createUser", | ||||
| 	"summary": "Create a User", | ||||
| 	"tags": ["Users"], | ||||
| 	"security": [ | ||||
| 		{ | ||||
| 			"BearerAuth": ["users"] | ||||
| 		} | ||||
| 	], | ||||
| 	"requestBody": { | ||||
| 		"description": "User Payload", | ||||
| 		"required": true, | ||||
| 		"content": { | ||||
| 			"application/json": { | ||||
| 				"schema": { | ||||
| 					"type": "object", | ||||
| 					"additionalProperties": false, | ||||
| 					"required": ["name", "nickname", "email"], | ||||
| 					"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" | ||||
| 						}, | ||||
| 						"auth": { | ||||
| 							"type": "object", | ||||
| 							"description": "Auth Credentials", | ||||
| 							"example": { | ||||
| 								"type": "password", | ||||
| 								"secret": "bigredhorsebanana" | ||||
| 							} | ||||
| 						} | ||||
| 					} | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
| 	}, | ||||
| 	"responses": { | ||||
| 		"201": { | ||||
| 			"description": "201 response", | ||||
| 			"content": { | ||||
| 				"application/json": { | ||||
| 					"examples": { | ||||
| 						"default": { | ||||
| 							"value": { | ||||
| 								"id": 2, | ||||
| 								"created_on": "2020-01-30T09:41:04.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"], | ||||
| 								"permissions": { | ||||
| 									"id": 3, | ||||
| 									"created_on": "2020-01-30T09:41:04.000Z", | ||||
| 									"modified_on": "2020-01-30T09:41:04.000Z", | ||||
| 									"user_id": 2, | ||||
| 									"visibility": "user", | ||||
| 									"proxy_hosts": "manage", | ||||
| 									"redirection_hosts": "manage", | ||||
| 									"dead_hosts": "manage", | ||||
| 									"streams": "manage", | ||||
| 									"access_lists": "manage", | ||||
| 									"certificates": "manage" | ||||
| 								} | ||||
| 							} | ||||
| 						} | ||||
| 					}, | ||||
| 					"schema": { | ||||
| 						"$ref": "../../components/user-object.json" | ||||
| 					} | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
							
								
								
									
										79
									
								
								backend/schema/paths/users/userID/auth/put.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										79
									
								
								backend/schema/paths/users/userID/auth/put.json
									
									
									
									
									
										Normal 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" | ||||
| 					} | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
							
								
								
									
										40
									
								
								backend/schema/paths/users/userID/delete.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										40
									
								
								backend/schema/paths/users/userID/delete.json
									
									
									
									
									
										Normal 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" | ||||
| 					} | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
							
								
								
									
										58
									
								
								backend/schema/paths/users/userID/get.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										58
									
								
								backend/schema/paths/users/userID/get.json
									
									
									
									
									
										Normal 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" | ||||
| 					} | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
							
								
								
									
										73
									
								
								backend/schema/paths/users/userID/login/post.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										73
									
								
								backend/schema/paths/users/userID/login/post.json
									
									
									
									
									
										Normal 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" | ||||
| 							} | ||||
| 						} | ||||
| 					} | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
							
								
								
									
										51
									
								
								backend/schema/paths/users/userID/permissions/put.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										51
									
								
								backend/schema/paths/users/userID/permissions/put.json
									
									
									
									
									
										Normal 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" | ||||
| 					} | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
							
								
								
									
										88
									
								
								backend/schema/paths/users/userID/put.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										88
									
								
								backend/schema/paths/users/userID/put.json
									
									
									
									
									
										Normal 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" | ||||
| 					} | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
		Reference in New Issue
	
	Block a user