From 70e1fd18634731d3e22f93e3da9106f5a6388576 Mon Sep 17 00:00:00 2001 From: mateuscelio Date: Thu, 1 Dec 2022 20:10:50 -0300 Subject: [PATCH 1/2] Add authorization bearer token auth method --- auth/authentication.go | 23 +++++++++++++++++--- auth/authentication_test.go | 43 ++++++++++++++++++++++++++++--------- 2 files changed, 53 insertions(+), 13 deletions(-) diff --git a/auth/authentication.go b/auth/authentication.go index fbe183d..397d077 100644 --- a/auth/authentication.go +++ b/auth/authentication.go @@ -2,10 +2,10 @@ package auth import ( "errors" - "github.com/gin-gonic/gin" "github.com/gotify/server/v2/auth/password" "github.com/gotify/server/v2/model" + "strings" ) const ( @@ -82,7 +82,9 @@ func (a *Auth) RequireApplicationToken() gin.HandlerFunc { func (a *Auth) tokenFromQueryOrHeader(ctx *gin.Context) string { if token := a.tokenFromQuery(ctx); token != "" { return token - } else if token := a.tokenFromHeader(ctx); token != "" { + } else if token := a.tokenFromXGotifyHeader(ctx); token != "" { + return token + } else if token := a.tokenFromAuthorizationHeader(ctx); token != "" { return token } return "" @@ -92,10 +94,25 @@ func (a *Auth) tokenFromQuery(ctx *gin.Context) string { return ctx.Request.URL.Query().Get("token") } -func (a *Auth) tokenFromHeader(ctx *gin.Context) string { +func (a *Auth) tokenFromXGotifyHeader(ctx *gin.Context) string { return ctx.Request.Header.Get(headerName) } +func (a *Auth) tokenFromAuthorizationHeader(ctx *gin.Context) string { + const prefix = "Bearer " + + authHeader := ctx.Request.Header.Get("Authorization") + if authHeader == "" { + return "" + } + + if len(authHeader) < len(prefix) || !strings.EqualFold(prefix, authHeader[:len(prefix)]) { + return "" + } + + return authHeader[len(prefix):] +} + func (a *Auth) userFromBasicAuth(ctx *gin.Context) (*model.User, error) { if name, pass, ok := ctx.Request.BasicAuth(); ok { if user, err := a.DB.GetUserByName(name); err != nil { diff --git a/auth/authentication_test.go b/auth/authentication_test.go index 84a260b..374f63d 100644 --- a/auth/authentication_test.go +++ b/auth/authentication_test.go @@ -104,16 +104,6 @@ func (s *AuthenticationSuite) TestHeaderApiKeyToken() { s.assertHeaderRequest("X-Gotify-Key", "ergerogerg", s.auth.RequireClient, 401) s.assertHeaderRequest("X-Gotify-Key", "ergerogerg", s.auth.RequireAdmin, 401) - // no authentication schema - s.assertHeaderRequest("Authorization", "ergerogerg", s.auth.RequireApplicationToken, 401) - s.assertHeaderRequest("Authorization", "ergerogerg", s.auth.RequireClient, 401) - s.assertHeaderRequest("Authorization", "ergerogerg", s.auth.RequireAdmin, 401) - - // wrong authentication schema - s.assertHeaderRequest("Authorization", "ApiKeyx clienttoken", s.auth.RequireApplicationToken, 401) - s.assertHeaderRequest("Authorization", "ApiKeyx clienttoken", s.auth.RequireClient, 401) - s.assertHeaderRequest("Authorization", "ApiKeyx clienttoken", s.auth.RequireAdmin, 401) - // not existing key s.assertHeaderRequest("X-Gotify-Keyx", "clienttoken", s.auth.RequireApplicationToken, 401) s.assertHeaderRequest("X-Gotify-Keyx", "clienttoken", s.auth.RequireClient, 401) @@ -136,6 +126,39 @@ func (s *AuthenticationSuite) TestHeaderApiKeyToken() { s.assertHeaderRequest("X-Gotify-Key", "clienttoken_admin", s.auth.RequireAdmin, 200) } +func (s *AuthenticationSuite) TestAuthorizationHeaderApiKeyToken() { + // not existing token + s.assertHeaderRequest("Authorization", "Bearer ergerogerg", s.auth.RequireApplicationToken, 401) + s.assertHeaderRequest("Authorization", "Bearer ergerogerg", s.auth.RequireClient, 401) + s.assertHeaderRequest("Authorization", "Bearer ergerogerg", s.auth.RequireAdmin, 401) + + // no authentication schema + s.assertHeaderRequest("Authorization", "ergerogerg", s.auth.RequireApplicationToken, 401) + s.assertHeaderRequest("Authorization", "ergerogerg", s.auth.RequireClient, 401) + s.assertHeaderRequest("Authorization", "ergerogerg", s.auth.RequireAdmin, 401) + + // wrong authentication schema + s.assertHeaderRequest("Authorization", "ApiKeyx clienttoken", s.auth.RequireApplicationToken, 401) + s.assertHeaderRequest("Authorization", "ApiKeyx clienttoken", s.auth.RequireClient, 401) + s.assertHeaderRequest("Authorization", "ApiKeyx clienttoken", s.auth.RequireAdmin, 401) + + // Authorization Bearer apptoken + s.assertHeaderRequest("Authorization", "Bearer apptoken", s.auth.RequireApplicationToken, 200) + s.assertHeaderRequest("Authorization", "Bearer apptoken", s.auth.RequireClient, 401) + s.assertHeaderRequest("Authorization", "Bearer apptoken", s.auth.RequireAdmin, 401) + s.assertHeaderRequest("Authorization", "Bearer apptoken_admin", s.auth.RequireApplicationToken, 200) + s.assertHeaderRequest("Authorization", "Bearer apptoken_admin", s.auth.RequireClient, 401) + s.assertHeaderRequest("Authorization", "Bearer apptoken_admin", s.auth.RequireAdmin, 401) + + // Authorization Bearer clienttoken + s.assertHeaderRequest("Authorization", "Bearer clienttoken", s.auth.RequireApplicationToken, 401) + s.assertHeaderRequest("Authorization", "Bearer clienttoken", s.auth.RequireClient, 200) + s.assertHeaderRequest("Authorization", "Bearer clienttoken", s.auth.RequireAdmin, 403) + s.assertHeaderRequest("Authorization", "bearer clienttoken_admin", s.auth.RequireApplicationToken, 401) + s.assertHeaderRequest("Authorization", "bearer clienttoken_admin", s.auth.RequireClient, 200) + s.assertHeaderRequest("Authorization", "bearer clienttoken_admin", s.auth.RequireAdmin, 200) +} + func (s *AuthenticationSuite) TestBasicAuth() { s.assertHeaderRequest("Authorization", "Basic ergerogerg", s.auth.RequireApplicationToken, 401) s.assertHeaderRequest("Authorization", "Basic ergerogerg", s.auth.RequireClient, 401) From 0fb584d7f7607b2d01fbddb6fdb2a3c35e1c9dcd Mon Sep 17 00:00:00 2001 From: mateuscelio Date: Thu, 1 Dec 2022 20:11:06 -0300 Subject: [PATCH 2/2] Update docs --- api/application.go | 10 ++-- api/client.go | 8 ++-- api/message.go | 12 ++--- api/plugin.go | 12 ++--- api/stream/stream.go | 2 +- api/user.go | 14 +++--- auth/authentication.go | 3 +- docs/package.go | 17 ++++++- docs/spec.json | 103 ++++++++++++++++++++++++++++++++++++++++- 9 files changed, 147 insertions(+), 34 deletions(-) diff --git a/api/application.go b/api/application.go index a169cdb..ff64075 100644 --- a/api/application.go +++ b/api/application.go @@ -54,7 +54,7 @@ type ApplicationParams struct { // --- // consumes: [application/json] // produces: [application/json] -// security: [clientTokenHeader: [], clientTokenQuery: [], basicAuth: []] +// security: [clientTokenAuthorizationHeader: [], clientTokenHeader: [], clientTokenQuery: [], basicAuth: []] // parameters: // - name: body // in: body @@ -105,7 +105,7 @@ func (a *ApplicationAPI) CreateApplication(ctx *gin.Context) { // --- // consumes: [application/json] // produces: [application/json] -// security: [clientTokenHeader: [], clientTokenQuery: [], basicAuth: []] +// security: [clientTokenAuthorizationHeader: [], clientTokenHeader: [], clientTokenQuery: [], basicAuth: []] // responses: // 200: // description: Ok @@ -148,7 +148,7 @@ func (a *ApplicationAPI) GetApplications(ctx *gin.Context) { // required: true // type: integer // format: int64 -// security: [clientTokenHeader: [], clientTokenQuery: [], basicAuth: []] +// security: [clientTokenAuthorizationHeader: [], clientTokenHeader: [], clientTokenQuery: [], basicAuth: []] // responses: // 200: // description: Ok @@ -199,7 +199,7 @@ func (a *ApplicationAPI) DeleteApplication(ctx *gin.Context) { // --- // consumes: [application/json] // produces: [application/json] -// security: [clientTokenHeader: [], clientTokenQuery: [], basicAuth: []] +// security: [clientTokenAuthorizationHeader: [], clientTokenHeader: [], clientTokenQuery: [], basicAuth: []] // parameters: // - name: body // in: body @@ -266,7 +266,7 @@ func (a *ApplicationAPI) UpdateApplication(ctx *gin.Context) { // consumes: // - multipart/form-data // produces: [application/json] -// security: [clientTokenHeader: [], clientTokenQuery: [], basicAuth: []] +// security: [clientTokenAuthorizationHeader: [], clientTokenHeader: [], clientTokenQuery: [], basicAuth: []] // parameters: // - name: file // in: formData diff --git a/api/client.go b/api/client.go index 143b493..f32a989 100644 --- a/api/client.go +++ b/api/client.go @@ -33,7 +33,7 @@ type ClientAPI struct { // --- // consumes: [application/json] // produces: [application/json] -// security: [clientTokenHeader: [], clientTokenQuery: [], basicAuth: []] +// security: [clientTokenAuthorizationHeader: [], clientTokenHeader: [], clientTokenQuery: [], basicAuth: []] // parameters: // - name: body // in: body @@ -98,7 +98,7 @@ func (a *ClientAPI) UpdateClient(ctx *gin.Context) { // --- // consumes: [application/json] // produces: [application/json] -// security: [clientTokenHeader: [], clientTokenQuery: [], basicAuth: []] +// security: [clientTokenAuthorizationHeader: [], clientTokenHeader: [], clientTokenQuery: [], basicAuth: []] // parameters: // - name: body // in: body @@ -143,7 +143,7 @@ func (a *ClientAPI) CreateClient(ctx *gin.Context) { // --- // consumes: [application/json] // produces: [application/json] -// security: [clientTokenHeader: [], clientTokenQuery: [], basicAuth: []] +// security: [clientTokenAuthorizationHeader: [], clientTokenHeader: [], clientTokenQuery: [], basicAuth: []] // responses: // 200: // description: Ok @@ -183,7 +183,7 @@ func (a *ClientAPI) GetClients(ctx *gin.Context) { // required: true // type: integer // format: int64 -// security: [clientTokenHeader: [], clientTokenQuery: [], basicAuth: []] +// security: [clientTokenAuthorizationHeader: [], clientTokenHeader: [], clientTokenQuery: [], basicAuth: []] // responses: // 200: // description: Ok diff --git a/api/message.go b/api/message.go index 5d95466..4b3c37d 100644 --- a/api/message.go +++ b/api/message.go @@ -52,7 +52,7 @@ type pagingParams struct { // // --- // produces: [application/json] -// security: [clientTokenHeader: [], clientTokenQuery: [], basicAuth: []] +// security: [clientTokenAuthorizationHeader: [], clientTokenHeader: [], clientTokenQuery: [], basicAuth: []] // parameters: // - name: limit // in: query @@ -133,7 +133,7 @@ func withPaging(ctx *gin.Context, f func(pagingParams *pagingParams)) { // // --- // produces: [application/json] -// security: [clientTokenHeader: [], clientTokenQuery: [], basicAuth: []] +// security: [clientTokenAuthorizationHeader: [], clientTokenHeader: [], clientTokenQuery: [], basicAuth: []] // parameters: // - name: id // in: path @@ -205,7 +205,7 @@ func (a *MessageAPI) GetMessagesWithApplication(ctx *gin.Context) { // // --- // produces: [application/json] -// security: [clientTokenHeader: [], clientTokenQuery: [], basicAuth: []] +// security: [clientTokenAuthorizationHeader: [], clientTokenHeader: [], clientTokenQuery: [], basicAuth: []] // responses: // 200: // description: Ok @@ -229,7 +229,7 @@ func (a *MessageAPI) DeleteMessages(ctx *gin.Context) { // // --- // produces: [application/json] -// security: [clientTokenHeader: [], clientTokenQuery: [], basicAuth: []] +// security: [clientTokenAuthorizationHeader: [], clientTokenHeader: [], clientTokenQuery: [], basicAuth: []] // parameters: // - name: id // in: path @@ -277,7 +277,7 @@ func (a *MessageAPI) DeleteMessageWithApplication(ctx *gin.Context) { // // --- // produces: [application/json] -// security: [clientTokenHeader: [], clientTokenQuery: [], basicAuth: []] +// security: [clientTokenAuthorizationHeader: [], clientTokenHeader: [], clientTokenQuery: [], basicAuth: []] // parameters: // - name: id // in: path @@ -335,7 +335,7 @@ func (a *MessageAPI) DeleteMessage(ctx *gin.Context) { // --- // consumes: [application/json] // produces: [application/json] -// security: [appTokenHeader: [], appTokenQuery: []] +// security: [appTokenAuthorizationHeader: [], appTokenHeader: [], appTokenQuery: []] // parameters: // - name: body // in: body diff --git a/api/plugin.go b/api/plugin.go index cbf30db..52fbd73 100644 --- a/api/plugin.go +++ b/api/plugin.go @@ -36,7 +36,7 @@ type PluginAPI struct { // --- // consumes: [application/json] // produces: [application/json] -// security: [clientTokenHeader: [], clientTokenQuery: [], basicAuth: []] +// security: [clientTokenAuthorizationHeader: [], clientTokenHeader: [], clientTokenQuery: [], basicAuth: []] // responses: // 200: // description: Ok @@ -101,7 +101,7 @@ func (c *PluginAPI) GetPlugins(ctx *gin.Context) { // required: true // type: integer // format: int64 -// security: [clientTokenHeader: [], clientTokenQuery: [], basicAuth: []] +// security: [clientTokenAuthorizationHeader: [], clientTokenHeader: [], clientTokenQuery: [], basicAuth: []] // responses: // 200: // description: Ok @@ -159,7 +159,7 @@ func (c *PluginAPI) EnablePlugin(ctx *gin.Context) { // required: true // type: integer // format: int64 -// security: [clientTokenHeader: [], clientTokenQuery: [], basicAuth: []] +// security: [clientTokenAuthorizationHeader: [], clientTokenHeader: [], clientTokenQuery: [], basicAuth: []] // responses: // 200: // description: Ok @@ -217,7 +217,7 @@ func (c *PluginAPI) DisablePlugin(ctx *gin.Context) { // required: true // type: integer // format: int64 -// security: [clientTokenHeader: [], clientTokenQuery: [], basicAuth: []] +// security: [clientTokenAuthorizationHeader: [], clientTokenHeader: [], clientTokenQuery: [], basicAuth: []] // responses: // 200: // description: Ok @@ -273,7 +273,7 @@ func (c *PluginAPI) GetDisplay(ctx *gin.Context) { // required: true // type: integer // format: int64 -// security: [clientTokenHeader: [], clientTokenQuery: [], basicAuth: []] +// security: [clientTokenAuthorizationHeader: [], clientTokenHeader: [], clientTokenQuery: [], basicAuth: []] // responses: // 200: // description: Ok @@ -340,7 +340,7 @@ func (c *PluginAPI) GetConfig(ctx *gin.Context) { // required: true // type: integer // format: int64 -// security: [clientTokenHeader: [], clientTokenQuery: [], basicAuth: []] +// security: [clientTokenAuthorizationHeader: [], clientTokenHeader: [], clientTokenQuery: [], basicAuth: []] // responses: // 200: // description: Ok diff --git a/api/stream/stream.go b/api/stream/stream.go index 7217907..e659157 100644 --- a/api/stream/stream.go +++ b/api/stream/stream.go @@ -105,7 +105,7 @@ func (a *API) register(client *client) { // --- // schema: ws, wss // produces: [application/json] -// security: [clientTokenHeader: [], clientTokenQuery: [], basicAuth: []] +// security: [clientTokenAuthorizationHeader: [], clientTokenHeader: [], clientTokenQuery: [], basicAuth: []] // responses: // 200: // description: Ok diff --git a/api/user.go b/api/user.go index b27345b..9bc41cd 100644 --- a/api/user.go +++ b/api/user.go @@ -71,7 +71,7 @@ type UserAPI struct { // // --- // produces: [application/json] -// security: [clientTokenHeader: [], clientTokenQuery: [], basicAuth: []] +// security: [clientTokenAuthorizationHeader: [], clientTokenHeader: [], clientTokenQuery: [], basicAuth: []] // responses: // 200: // description: Ok @@ -107,7 +107,7 @@ func (a *UserAPI) GetUsers(ctx *gin.Context) { // // --- // produces: [application/json] -// security: [clientTokenHeader: [], clientTokenQuery: [], basicAuth: []] +// security: [clientTokenAuthorizationHeader: [], clientTokenHeader: [], clientTokenQuery: [], basicAuth: []] // responses: // 200: // description: Ok @@ -140,7 +140,7 @@ func (a *UserAPI) GetCurrentUser(ctx *gin.Context) { // --- // consumes: [application/json] // produces: [application/json] -// security: [clientTokenHeader: [], clientTokenQuery: [], basicAuth: []] +// security: [clientTokenAuthorizationHeader: [], clientTokenHeader: [], clientTokenQuery: [], basicAuth: []] // parameters: // - name: body // in: body @@ -226,7 +226,7 @@ func (a *UserAPI) CreateUser(ctx *gin.Context) { // --- // consumes: [application/json] // produces: [application/json] -// security: [clientTokenHeader: [], clientTokenQuery: [], basicAuth: []] +// security: [clientTokenAuthorizationHeader: [], clientTokenHeader: [], clientTokenQuery: [], basicAuth: []] // parameters: // - name: id // in: path @@ -276,7 +276,7 @@ func (a *UserAPI) GetUserByID(ctx *gin.Context) { // // --- // produces: [application/json] -// security: [clientTokenHeader: [], clientTokenQuery: [], basicAuth: []] +// security: [clientTokenAuthorizationHeader: [], clientTokenHeader: [], clientTokenQuery: [], basicAuth: []] // parameters: // - name: id // in: path @@ -337,7 +337,7 @@ func (a *UserAPI) DeleteUserByID(ctx *gin.Context) { // --- // consumes: [application/json] // produces: [application/json] -// security: [clientTokenHeader: [], clientTokenQuery: [], basicAuth: []] +// security: [clientTokenAuthorizationHeader: [], clientTokenHeader: [], clientTokenQuery: [], basicAuth: []] // parameters: // - name: body // in: body @@ -380,7 +380,7 @@ func (a *UserAPI) ChangePassword(ctx *gin.Context) { // --- // consumes: [application/json] // produces: [application/json] -// security: [clientTokenHeader: [], clientTokenQuery: [], basicAuth: []] +// security: [clientTokenAuthorizationHeader: [], clientTokenHeader: [], clientTokenQuery: [], basicAuth: []] // parameters: // - name: id // in: path diff --git a/auth/authentication.go b/auth/authentication.go index 397d077..bf0a9ef 100644 --- a/auth/authentication.go +++ b/auth/authentication.go @@ -2,10 +2,11 @@ package auth import ( "errors" + "strings" + "github.com/gin-gonic/gin" "github.com/gotify/server/v2/auth/password" "github.com/gotify/server/v2/model" - "strings" ) const ( diff --git a/docs/package.go b/docs/package.go index 6cd9529..a9748e6 100644 --- a/docs/package.go +++ b/docs/package.go @@ -7,7 +7,8 @@ // __clientToken__: a client is something that receives message and manages stuff like creating new tokens or delete messages. (f.ex this token should be used for an android app) // __appToken__: an application is something that sends messages (f.ex. this token should be used for a shell script) // -// The token can be either transmitted through a header named `X-Gotify-Key` or a query parameter named `token`. +// The token can be transmitted in a header named `X-Gotify-Key`, in a query parameter named `token` or +// through a header named `Authorization` with the value prefixed with `Bearer` (Ex. `Bearer randomtoken`). // There is also the possibility to authenticate through basic auth, this should only be used for creating a clientToken. // // \--- @@ -16,7 +17,7 @@ // // Schemes: http, https // Host: localhost -// Version: 2.0.1 +// Version: 2.0.2 // License: MIT https://github.com/gotify/server/blob/master/LICENSE // // Consumes: @@ -42,6 +43,18 @@ // type: apiKey // name: X-Gotify-Key // in: header +// appTokenAuthorizationHeader: +// type: apiKey +// name: Authorization +// in: header +// description: >- +// Enter an application token with the `Bearer` prefix, e.g. `Bearer Axxxxxxxxxx`. +// clientTokenAuthorizationHeader: +// type: apiKey +// name: Authorization +// in: header +// description: >- +// Enter a client token with the `Bearer` prefix, e.g. `Bearer Cxxxxxxxxxx`. // basicAuth: // type: basic // diff --git a/docs/spec.json b/docs/spec.json index 5d83fd0..bc26043 100644 --- a/docs/spec.json +++ b/docs/spec.json @@ -11,19 +11,22 @@ ], "swagger": "2.0", "info": { - "description": "This is the documentation of the Gotify REST-API.\n\n# Authentication\nIn Gotify there are two token types:\n__clientToken__: a client is something that receives message and manages stuff like creating new tokens or delete messages. (f.ex this token should be used for an android app)\n__appToken__: an application is something that sends messages (f.ex. this token should be used for a shell script)\n\nThe token can be either transmitted through a header named `X-Gotify-Key` or a query parameter named `token`.\nThere is also the possibility to authenticate through basic auth, this should only be used for creating a clientToken.\n\n\\---\n\nFound a bug or have some questions? [Create an issue on GitHub](https://github.com/gotify/server/issues)", + "description": "This is the documentation of the Gotify REST-API.\n\n# Authentication\nIn Gotify there are two token types:\n__clientToken__: a client is something that receives message and manages stuff like creating new tokens or delete messages. (f.ex this token should be used for an android app)\n__appToken__: an application is something that sends messages (f.ex. this token should be used for a shell script)\n\nThe token can be transmitted in a header named `X-Gotify-Key`, in a query parameter named `token` or\nthrough a header named `Authorization` with the value prefixed with `Bearer` (Ex. `Bearer randomtoken`).\nThere is also the possibility to authenticate through basic auth, this should only be used for creating a clientToken.\n\n\\---\n\nFound a bug or have some questions? [Create an issue on GitHub](https://github.com/gotify/server/issues)", "title": "Gotify REST-API.", "license": { "name": "MIT", "url": "https://github.com/gotify/server/blob/master/LICENSE" }, - "version": "2.0.1" + "version": "2.0.2" }, "host": "localhost", "paths": { "/application": { "get": { "security": [ + { + "clientTokenAuthorizationHeader": [] + }, { "clientTokenHeader": [] }, @@ -71,6 +74,9 @@ }, "post": { "security": [ + { + "clientTokenAuthorizationHeader": [] + }, { "clientTokenHeader": [] }, @@ -134,6 +140,9 @@ "/application/{id}": { "put": { "security": [ + { + "clientTokenAuthorizationHeader": [] + }, { "clientTokenHeader": [] }, @@ -209,6 +218,9 @@ }, "delete": { "security": [ + { + "clientTokenAuthorizationHeader": [] + }, { "clientTokenHeader": [] }, @@ -274,6 +286,9 @@ "/application/{id}/image": { "post": { "security": [ + { + "clientTokenAuthorizationHeader": [] + }, { "clientTokenHeader": [] }, @@ -355,6 +370,9 @@ "/application/{id}/message": { "get": { "security": [ + { + "clientTokenAuthorizationHeader": [] + }, { "clientTokenHeader": [] }, @@ -435,6 +453,9 @@ }, "delete": { "security": [ + { + "clientTokenAuthorizationHeader": [] + }, { "clientTokenHeader": [] }, @@ -497,6 +518,9 @@ "/client": { "get": { "security": [ + { + "clientTokenAuthorizationHeader": [] + }, { "clientTokenHeader": [] }, @@ -544,6 +568,9 @@ }, "post": { "security": [ + { + "clientTokenAuthorizationHeader": [] + }, { "clientTokenHeader": [] }, @@ -607,6 +634,9 @@ "/client/{id}": { "put": { "security": [ + { + "clientTokenAuthorizationHeader": [] + }, { "clientTokenHeader": [] }, @@ -682,6 +712,9 @@ }, "delete": { "security": [ + { + "clientTokenAuthorizationHeader": [] + }, { "clientTokenHeader": [] }, @@ -747,6 +780,9 @@ "/current/user": { "get": { "security": [ + { + "clientTokenAuthorizationHeader": [] + }, { "clientTokenHeader": [] }, @@ -790,6 +826,9 @@ "/current/user/password": { "post": { "security": [ + { + "clientTokenAuthorizationHeader": [] + }, { "clientTokenHeader": [] }, @@ -876,6 +915,9 @@ "/message": { "get": { "security": [ + { + "clientTokenAuthorizationHeader": [] + }, { "clientTokenHeader": [] }, @@ -942,6 +984,9 @@ }, "post": { "security": [ + { + "appTokenAuthorizationHeader": [] + }, { "appTokenHeader": [] }, @@ -1001,6 +1046,9 @@ }, "delete": { "security": [ + { + "clientTokenAuthorizationHeader": [] + }, { "clientTokenHeader": [] }, @@ -1041,6 +1089,9 @@ "/message/{id}": { "delete": { "security": [ + { + "clientTokenAuthorizationHeader": [] + }, { "clientTokenHeader": [] }, @@ -1103,6 +1154,9 @@ "/plugin": { "get": { "security": [ + { + "clientTokenAuthorizationHeader": [] + }, { "clientTokenHeader": [] }, @@ -1164,6 +1218,9 @@ "/plugin/{id}/config": { "get": { "security": [ + { + "clientTokenAuthorizationHeader": [] + }, { "clientTokenHeader": [] }, @@ -1237,6 +1294,9 @@ }, "post": { "security": [ + { + "clientTokenAuthorizationHeader": [] + }, { "clientTokenHeader": [] }, @@ -1308,6 +1368,9 @@ "/plugin/{id}/disable": { "post": { "security": [ + { + "clientTokenAuthorizationHeader": [] + }, { "clientTokenHeader": [] }, @@ -1373,6 +1436,9 @@ "/plugin/{id}/display": { "get": { "security": [ + { + "clientTokenAuthorizationHeader": [] + }, { "clientTokenHeader": [] }, @@ -1441,6 +1507,9 @@ "/plugin/{id}/enable": { "post": { "security": [ + { + "clientTokenAuthorizationHeader": [] + }, { "clientTokenHeader": [] }, @@ -1506,6 +1575,9 @@ "/stream": { "get": { "security": [ + { + "clientTokenAuthorizationHeader": [] + }, { "clientTokenHeader": [] }, @@ -1561,6 +1633,9 @@ "/user": { "get": { "security": [ + { + "clientTokenAuthorizationHeader": [] + }, { "clientTokenHeader": [] }, @@ -1605,6 +1680,9 @@ }, "post": { "security": [ + { + "clientTokenAuthorizationHeader": [] + }, { "clientTokenHeader": [] }, @@ -1669,6 +1747,9 @@ "/user/{id}": { "get": { "security": [ + { + "clientTokenAuthorizationHeader": [] + }, { "clientTokenHeader": [] }, @@ -1735,6 +1816,9 @@ }, "post": { "security": [ + { + "clientTokenAuthorizationHeader": [] + }, { "clientTokenHeader": [] }, @@ -1810,6 +1894,9 @@ }, "delete": { "security": [ + { + "clientTokenAuthorizationHeader": [] + }, { "clientTokenHeader": [] }, @@ -2435,6 +2522,12 @@ } }, "securityDefinitions": { + "appTokenAuthorizationHeader": { + "description": "Enter an application token with the `Bearer` prefix, e.g. `Bearer Axxxxxxxxxx`.", + "type": "apiKey", + "name": "Authorization", + "in": "header" + }, "appTokenHeader": { "type": "apiKey", "name": "X-Gotify-Key", @@ -2448,6 +2541,12 @@ "basicAuth": { "type": "basic" }, + "clientTokenAuthorizationHeader": { + "description": "Enter a client token with the `Bearer` prefix, e.g. `Bearer Cxxxxxxxxxx`.", + "type": "apiKey", + "name": "Authorization", + "in": "header" + }, "clientTokenHeader": { "type": "apiKey", "name": "X-Gotify-Key",