Merge pull request #527 from mateuscelio/add-authorization-header-auth

Adds Authorization header auth method
This commit is contained in:
Jannis Mattheis 2022-12-03 10:02:18 +00:00 committed by GitHub
commit fe8a80d82f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 198 additions and 45 deletions

View File

@ -54,7 +54,7 @@ type ApplicationParams struct {
// --- // ---
// consumes: [application/json] // consumes: [application/json]
// produces: [application/json] // produces: [application/json]
// security: [clientTokenHeader: [], clientTokenQuery: [], basicAuth: []] // security: [clientTokenAuthorizationHeader: [], clientTokenHeader: [], clientTokenQuery: [], basicAuth: []]
// parameters: // parameters:
// - name: body // - name: body
// in: body // in: body
@ -105,7 +105,7 @@ func (a *ApplicationAPI) CreateApplication(ctx *gin.Context) {
// --- // ---
// consumes: [application/json] // consumes: [application/json]
// produces: [application/json] // produces: [application/json]
// security: [clientTokenHeader: [], clientTokenQuery: [], basicAuth: []] // security: [clientTokenAuthorizationHeader: [], clientTokenHeader: [], clientTokenQuery: [], basicAuth: []]
// responses: // responses:
// 200: // 200:
// description: Ok // description: Ok
@ -148,7 +148,7 @@ func (a *ApplicationAPI) GetApplications(ctx *gin.Context) {
// required: true // required: true
// type: integer // type: integer
// format: int64 // format: int64
// security: [clientTokenHeader: [], clientTokenQuery: [], basicAuth: []] // security: [clientTokenAuthorizationHeader: [], clientTokenHeader: [], clientTokenQuery: [], basicAuth: []]
// responses: // responses:
// 200: // 200:
// description: Ok // description: Ok
@ -199,7 +199,7 @@ func (a *ApplicationAPI) DeleteApplication(ctx *gin.Context) {
// --- // ---
// consumes: [application/json] // consumes: [application/json]
// produces: [application/json] // produces: [application/json]
// security: [clientTokenHeader: [], clientTokenQuery: [], basicAuth: []] // security: [clientTokenAuthorizationHeader: [], clientTokenHeader: [], clientTokenQuery: [], basicAuth: []]
// parameters: // parameters:
// - name: body // - name: body
// in: body // in: body
@ -266,7 +266,7 @@ func (a *ApplicationAPI) UpdateApplication(ctx *gin.Context) {
// consumes: // consumes:
// - multipart/form-data // - multipart/form-data
// produces: [application/json] // produces: [application/json]
// security: [clientTokenHeader: [], clientTokenQuery: [], basicAuth: []] // security: [clientTokenAuthorizationHeader: [], clientTokenHeader: [], clientTokenQuery: [], basicAuth: []]
// parameters: // parameters:
// - name: file // - name: file
// in: formData // in: formData

View File

@ -33,7 +33,7 @@ type ClientAPI struct {
// --- // ---
// consumes: [application/json] // consumes: [application/json]
// produces: [application/json] // produces: [application/json]
// security: [clientTokenHeader: [], clientTokenQuery: [], basicAuth: []] // security: [clientTokenAuthorizationHeader: [], clientTokenHeader: [], clientTokenQuery: [], basicAuth: []]
// parameters: // parameters:
// - name: body // - name: body
// in: body // in: body
@ -98,7 +98,7 @@ func (a *ClientAPI) UpdateClient(ctx *gin.Context) {
// --- // ---
// consumes: [application/json] // consumes: [application/json]
// produces: [application/json] // produces: [application/json]
// security: [clientTokenHeader: [], clientTokenQuery: [], basicAuth: []] // security: [clientTokenAuthorizationHeader: [], clientTokenHeader: [], clientTokenQuery: [], basicAuth: []]
// parameters: // parameters:
// - name: body // - name: body
// in: body // in: body
@ -143,7 +143,7 @@ func (a *ClientAPI) CreateClient(ctx *gin.Context) {
// --- // ---
// consumes: [application/json] // consumes: [application/json]
// produces: [application/json] // produces: [application/json]
// security: [clientTokenHeader: [], clientTokenQuery: [], basicAuth: []] // security: [clientTokenAuthorizationHeader: [], clientTokenHeader: [], clientTokenQuery: [], basicAuth: []]
// responses: // responses:
// 200: // 200:
// description: Ok // description: Ok
@ -183,7 +183,7 @@ func (a *ClientAPI) GetClients(ctx *gin.Context) {
// required: true // required: true
// type: integer // type: integer
// format: int64 // format: int64
// security: [clientTokenHeader: [], clientTokenQuery: [], basicAuth: []] // security: [clientTokenAuthorizationHeader: [], clientTokenHeader: [], clientTokenQuery: [], basicAuth: []]
// responses: // responses:
// 200: // 200:
// description: Ok // description: Ok

View File

@ -52,7 +52,7 @@ type pagingParams struct {
// //
// --- // ---
// produces: [application/json] // produces: [application/json]
// security: [clientTokenHeader: [], clientTokenQuery: [], basicAuth: []] // security: [clientTokenAuthorizationHeader: [], clientTokenHeader: [], clientTokenQuery: [], basicAuth: []]
// parameters: // parameters:
// - name: limit // - name: limit
// in: query // in: query
@ -133,7 +133,7 @@ func withPaging(ctx *gin.Context, f func(pagingParams *pagingParams)) {
// //
// --- // ---
// produces: [application/json] // produces: [application/json]
// security: [clientTokenHeader: [], clientTokenQuery: [], basicAuth: []] // security: [clientTokenAuthorizationHeader: [], clientTokenHeader: [], clientTokenQuery: [], basicAuth: []]
// parameters: // parameters:
// - name: id // - name: id
// in: path // in: path
@ -205,7 +205,7 @@ func (a *MessageAPI) GetMessagesWithApplication(ctx *gin.Context) {
// //
// --- // ---
// produces: [application/json] // produces: [application/json]
// security: [clientTokenHeader: [], clientTokenQuery: [], basicAuth: []] // security: [clientTokenAuthorizationHeader: [], clientTokenHeader: [], clientTokenQuery: [], basicAuth: []]
// responses: // responses:
// 200: // 200:
// description: Ok // description: Ok
@ -229,7 +229,7 @@ func (a *MessageAPI) DeleteMessages(ctx *gin.Context) {
// //
// --- // ---
// produces: [application/json] // produces: [application/json]
// security: [clientTokenHeader: [], clientTokenQuery: [], basicAuth: []] // security: [clientTokenAuthorizationHeader: [], clientTokenHeader: [], clientTokenQuery: [], basicAuth: []]
// parameters: // parameters:
// - name: id // - name: id
// in: path // in: path
@ -277,7 +277,7 @@ func (a *MessageAPI) DeleteMessageWithApplication(ctx *gin.Context) {
// //
// --- // ---
// produces: [application/json] // produces: [application/json]
// security: [clientTokenHeader: [], clientTokenQuery: [], basicAuth: []] // security: [clientTokenAuthorizationHeader: [], clientTokenHeader: [], clientTokenQuery: [], basicAuth: []]
// parameters: // parameters:
// - name: id // - name: id
// in: path // in: path
@ -335,7 +335,7 @@ func (a *MessageAPI) DeleteMessage(ctx *gin.Context) {
// --- // ---
// consumes: [application/json] // consumes: [application/json]
// produces: [application/json] // produces: [application/json]
// security: [appTokenHeader: [], appTokenQuery: []] // security: [appTokenAuthorizationHeader: [], appTokenHeader: [], appTokenQuery: []]
// parameters: // parameters:
// - name: body // - name: body
// in: body // in: body

View File

@ -36,7 +36,7 @@ type PluginAPI struct {
// --- // ---
// consumes: [application/json] // consumes: [application/json]
// produces: [application/json] // produces: [application/json]
// security: [clientTokenHeader: [], clientTokenQuery: [], basicAuth: []] // security: [clientTokenAuthorizationHeader: [], clientTokenHeader: [], clientTokenQuery: [], basicAuth: []]
// responses: // responses:
// 200: // 200:
// description: Ok // description: Ok
@ -101,7 +101,7 @@ func (c *PluginAPI) GetPlugins(ctx *gin.Context) {
// required: true // required: true
// type: integer // type: integer
// format: int64 // format: int64
// security: [clientTokenHeader: [], clientTokenQuery: [], basicAuth: []] // security: [clientTokenAuthorizationHeader: [], clientTokenHeader: [], clientTokenQuery: [], basicAuth: []]
// responses: // responses:
// 200: // 200:
// description: Ok // description: Ok
@ -159,7 +159,7 @@ func (c *PluginAPI) EnablePlugin(ctx *gin.Context) {
// required: true // required: true
// type: integer // type: integer
// format: int64 // format: int64
// security: [clientTokenHeader: [], clientTokenQuery: [], basicAuth: []] // security: [clientTokenAuthorizationHeader: [], clientTokenHeader: [], clientTokenQuery: [], basicAuth: []]
// responses: // responses:
// 200: // 200:
// description: Ok // description: Ok
@ -217,7 +217,7 @@ func (c *PluginAPI) DisablePlugin(ctx *gin.Context) {
// required: true // required: true
// type: integer // type: integer
// format: int64 // format: int64
// security: [clientTokenHeader: [], clientTokenQuery: [], basicAuth: []] // security: [clientTokenAuthorizationHeader: [], clientTokenHeader: [], clientTokenQuery: [], basicAuth: []]
// responses: // responses:
// 200: // 200:
// description: Ok // description: Ok
@ -273,7 +273,7 @@ func (c *PluginAPI) GetDisplay(ctx *gin.Context) {
// required: true // required: true
// type: integer // type: integer
// format: int64 // format: int64
// security: [clientTokenHeader: [], clientTokenQuery: [], basicAuth: []] // security: [clientTokenAuthorizationHeader: [], clientTokenHeader: [], clientTokenQuery: [], basicAuth: []]
// responses: // responses:
// 200: // 200:
// description: Ok // description: Ok
@ -340,7 +340,7 @@ func (c *PluginAPI) GetConfig(ctx *gin.Context) {
// required: true // required: true
// type: integer // type: integer
// format: int64 // format: int64
// security: [clientTokenHeader: [], clientTokenQuery: [], basicAuth: []] // security: [clientTokenAuthorizationHeader: [], clientTokenHeader: [], clientTokenQuery: [], basicAuth: []]
// responses: // responses:
// 200: // 200:
// description: Ok // description: Ok

View File

@ -105,7 +105,7 @@ func (a *API) register(client *client) {
// --- // ---
// schema: ws, wss // schema: ws, wss
// produces: [application/json] // produces: [application/json]
// security: [clientTokenHeader: [], clientTokenQuery: [], basicAuth: []] // security: [clientTokenAuthorizationHeader: [], clientTokenHeader: [], clientTokenQuery: [], basicAuth: []]
// responses: // responses:
// 200: // 200:
// description: Ok // description: Ok

View File

@ -71,7 +71,7 @@ type UserAPI struct {
// //
// --- // ---
// produces: [application/json] // produces: [application/json]
// security: [clientTokenHeader: [], clientTokenQuery: [], basicAuth: []] // security: [clientTokenAuthorizationHeader: [], clientTokenHeader: [], clientTokenQuery: [], basicAuth: []]
// responses: // responses:
// 200: // 200:
// description: Ok // description: Ok
@ -107,7 +107,7 @@ func (a *UserAPI) GetUsers(ctx *gin.Context) {
// //
// --- // ---
// produces: [application/json] // produces: [application/json]
// security: [clientTokenHeader: [], clientTokenQuery: [], basicAuth: []] // security: [clientTokenAuthorizationHeader: [], clientTokenHeader: [], clientTokenQuery: [], basicAuth: []]
// responses: // responses:
// 200: // 200:
// description: Ok // description: Ok
@ -140,7 +140,7 @@ func (a *UserAPI) GetCurrentUser(ctx *gin.Context) {
// --- // ---
// consumes: [application/json] // consumes: [application/json]
// produces: [application/json] // produces: [application/json]
// security: [clientTokenHeader: [], clientTokenQuery: [], basicAuth: []] // security: [clientTokenAuthorizationHeader: [], clientTokenHeader: [], clientTokenQuery: [], basicAuth: []]
// parameters: // parameters:
// - name: body // - name: body
// in: body // in: body
@ -226,7 +226,7 @@ func (a *UserAPI) CreateUser(ctx *gin.Context) {
// --- // ---
// consumes: [application/json] // consumes: [application/json]
// produces: [application/json] // produces: [application/json]
// security: [clientTokenHeader: [], clientTokenQuery: [], basicAuth: []] // security: [clientTokenAuthorizationHeader: [], clientTokenHeader: [], clientTokenQuery: [], basicAuth: []]
// parameters: // parameters:
// - name: id // - name: id
// in: path // in: path
@ -276,7 +276,7 @@ func (a *UserAPI) GetUserByID(ctx *gin.Context) {
// //
// --- // ---
// produces: [application/json] // produces: [application/json]
// security: [clientTokenHeader: [], clientTokenQuery: [], basicAuth: []] // security: [clientTokenAuthorizationHeader: [], clientTokenHeader: [], clientTokenQuery: [], basicAuth: []]
// parameters: // parameters:
// - name: id // - name: id
// in: path // in: path
@ -337,7 +337,7 @@ func (a *UserAPI) DeleteUserByID(ctx *gin.Context) {
// --- // ---
// consumes: [application/json] // consumes: [application/json]
// produces: [application/json] // produces: [application/json]
// security: [clientTokenHeader: [], clientTokenQuery: [], basicAuth: []] // security: [clientTokenAuthorizationHeader: [], clientTokenHeader: [], clientTokenQuery: [], basicAuth: []]
// parameters: // parameters:
// - name: body // - name: body
// in: body // in: body
@ -380,7 +380,7 @@ func (a *UserAPI) ChangePassword(ctx *gin.Context) {
// --- // ---
// consumes: [application/json] // consumes: [application/json]
// produces: [application/json] // produces: [application/json]
// security: [clientTokenHeader: [], clientTokenQuery: [], basicAuth: []] // security: [clientTokenAuthorizationHeader: [], clientTokenHeader: [], clientTokenQuery: [], basicAuth: []]
// parameters: // parameters:
// - name: id // - name: id
// in: path // in: path

View File

@ -2,6 +2,7 @@ package auth
import ( import (
"errors" "errors"
"strings"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
"github.com/gotify/server/v2/auth/password" "github.com/gotify/server/v2/auth/password"
@ -82,7 +83,9 @@ func (a *Auth) RequireApplicationToken() gin.HandlerFunc {
func (a *Auth) tokenFromQueryOrHeader(ctx *gin.Context) string { func (a *Auth) tokenFromQueryOrHeader(ctx *gin.Context) string {
if token := a.tokenFromQuery(ctx); token != "" { if token := a.tokenFromQuery(ctx); token != "" {
return 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 token
} }
return "" return ""
@ -92,10 +95,25 @@ func (a *Auth) tokenFromQuery(ctx *gin.Context) string {
return ctx.Request.URL.Query().Get("token") 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) 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) { func (a *Auth) userFromBasicAuth(ctx *gin.Context) (*model.User, error) {
if name, pass, ok := ctx.Request.BasicAuth(); ok { if name, pass, ok := ctx.Request.BasicAuth(); ok {
if user, err := a.DB.GetUserByName(name); err != nil { if user, err := a.DB.GetUserByName(name); err != nil {

View File

@ -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.RequireClient, 401)
s.assertHeaderRequest("X-Gotify-Key", "ergerogerg", s.auth.RequireAdmin, 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 // not existing key
s.assertHeaderRequest("X-Gotify-Keyx", "clienttoken", s.auth.RequireApplicationToken, 401) s.assertHeaderRequest("X-Gotify-Keyx", "clienttoken", s.auth.RequireApplicationToken, 401)
s.assertHeaderRequest("X-Gotify-Keyx", "clienttoken", s.auth.RequireClient, 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) 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() { func (s *AuthenticationSuite) TestBasicAuth() {
s.assertHeaderRequest("Authorization", "Basic ergerogerg", s.auth.RequireApplicationToken, 401) s.assertHeaderRequest("Authorization", "Basic ergerogerg", s.auth.RequireApplicationToken, 401)
s.assertHeaderRequest("Authorization", "Basic ergerogerg", s.auth.RequireClient, 401) s.assertHeaderRequest("Authorization", "Basic ergerogerg", s.auth.RequireClient, 401)

View File

@ -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) // __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) // __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. // 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 // Schemes: http, https
// Host: localhost // Host: localhost
// Version: 2.0.1 // Version: 2.0.2
// License: MIT https://github.com/gotify/server/blob/master/LICENSE // License: MIT https://github.com/gotify/server/blob/master/LICENSE
// //
// Consumes: // Consumes:
@ -42,6 +43,18 @@
// type: apiKey // type: apiKey
// name: X-Gotify-Key // name: X-Gotify-Key
// in: header // 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: // basicAuth:
// type: basic // type: basic
// //

View File

@ -11,19 +11,22 @@
], ],
"swagger": "2.0", "swagger": "2.0",
"info": { "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.", "title": "Gotify REST-API.",
"license": { "license": {
"name": "MIT", "name": "MIT",
"url": "https://github.com/gotify/server/blob/master/LICENSE" "url": "https://github.com/gotify/server/blob/master/LICENSE"
}, },
"version": "2.0.1" "version": "2.0.2"
}, },
"host": "localhost", "host": "localhost",
"paths": { "paths": {
"/application": { "/application": {
"get": { "get": {
"security": [ "security": [
{
"clientTokenAuthorizationHeader": []
},
{ {
"clientTokenHeader": [] "clientTokenHeader": []
}, },
@ -71,6 +74,9 @@
}, },
"post": { "post": {
"security": [ "security": [
{
"clientTokenAuthorizationHeader": []
},
{ {
"clientTokenHeader": [] "clientTokenHeader": []
}, },
@ -134,6 +140,9 @@
"/application/{id}": { "/application/{id}": {
"put": { "put": {
"security": [ "security": [
{
"clientTokenAuthorizationHeader": []
},
{ {
"clientTokenHeader": [] "clientTokenHeader": []
}, },
@ -209,6 +218,9 @@
}, },
"delete": { "delete": {
"security": [ "security": [
{
"clientTokenAuthorizationHeader": []
},
{ {
"clientTokenHeader": [] "clientTokenHeader": []
}, },
@ -274,6 +286,9 @@
"/application/{id}/image": { "/application/{id}/image": {
"post": { "post": {
"security": [ "security": [
{
"clientTokenAuthorizationHeader": []
},
{ {
"clientTokenHeader": [] "clientTokenHeader": []
}, },
@ -355,6 +370,9 @@
"/application/{id}/message": { "/application/{id}/message": {
"get": { "get": {
"security": [ "security": [
{
"clientTokenAuthorizationHeader": []
},
{ {
"clientTokenHeader": [] "clientTokenHeader": []
}, },
@ -435,6 +453,9 @@
}, },
"delete": { "delete": {
"security": [ "security": [
{
"clientTokenAuthorizationHeader": []
},
{ {
"clientTokenHeader": [] "clientTokenHeader": []
}, },
@ -497,6 +518,9 @@
"/client": { "/client": {
"get": { "get": {
"security": [ "security": [
{
"clientTokenAuthorizationHeader": []
},
{ {
"clientTokenHeader": [] "clientTokenHeader": []
}, },
@ -544,6 +568,9 @@
}, },
"post": { "post": {
"security": [ "security": [
{
"clientTokenAuthorizationHeader": []
},
{ {
"clientTokenHeader": [] "clientTokenHeader": []
}, },
@ -607,6 +634,9 @@
"/client/{id}": { "/client/{id}": {
"put": { "put": {
"security": [ "security": [
{
"clientTokenAuthorizationHeader": []
},
{ {
"clientTokenHeader": [] "clientTokenHeader": []
}, },
@ -682,6 +712,9 @@
}, },
"delete": { "delete": {
"security": [ "security": [
{
"clientTokenAuthorizationHeader": []
},
{ {
"clientTokenHeader": [] "clientTokenHeader": []
}, },
@ -747,6 +780,9 @@
"/current/user": { "/current/user": {
"get": { "get": {
"security": [ "security": [
{
"clientTokenAuthorizationHeader": []
},
{ {
"clientTokenHeader": [] "clientTokenHeader": []
}, },
@ -790,6 +826,9 @@
"/current/user/password": { "/current/user/password": {
"post": { "post": {
"security": [ "security": [
{
"clientTokenAuthorizationHeader": []
},
{ {
"clientTokenHeader": [] "clientTokenHeader": []
}, },
@ -876,6 +915,9 @@
"/message": { "/message": {
"get": { "get": {
"security": [ "security": [
{
"clientTokenAuthorizationHeader": []
},
{ {
"clientTokenHeader": [] "clientTokenHeader": []
}, },
@ -942,6 +984,9 @@
}, },
"post": { "post": {
"security": [ "security": [
{
"appTokenAuthorizationHeader": []
},
{ {
"appTokenHeader": [] "appTokenHeader": []
}, },
@ -1001,6 +1046,9 @@
}, },
"delete": { "delete": {
"security": [ "security": [
{
"clientTokenAuthorizationHeader": []
},
{ {
"clientTokenHeader": [] "clientTokenHeader": []
}, },
@ -1041,6 +1089,9 @@
"/message/{id}": { "/message/{id}": {
"delete": { "delete": {
"security": [ "security": [
{
"clientTokenAuthorizationHeader": []
},
{ {
"clientTokenHeader": [] "clientTokenHeader": []
}, },
@ -1103,6 +1154,9 @@
"/plugin": { "/plugin": {
"get": { "get": {
"security": [ "security": [
{
"clientTokenAuthorizationHeader": []
},
{ {
"clientTokenHeader": [] "clientTokenHeader": []
}, },
@ -1164,6 +1218,9 @@
"/plugin/{id}/config": { "/plugin/{id}/config": {
"get": { "get": {
"security": [ "security": [
{
"clientTokenAuthorizationHeader": []
},
{ {
"clientTokenHeader": [] "clientTokenHeader": []
}, },
@ -1237,6 +1294,9 @@
}, },
"post": { "post": {
"security": [ "security": [
{
"clientTokenAuthorizationHeader": []
},
{ {
"clientTokenHeader": [] "clientTokenHeader": []
}, },
@ -1308,6 +1368,9 @@
"/plugin/{id}/disable": { "/plugin/{id}/disable": {
"post": { "post": {
"security": [ "security": [
{
"clientTokenAuthorizationHeader": []
},
{ {
"clientTokenHeader": [] "clientTokenHeader": []
}, },
@ -1373,6 +1436,9 @@
"/plugin/{id}/display": { "/plugin/{id}/display": {
"get": { "get": {
"security": [ "security": [
{
"clientTokenAuthorizationHeader": []
},
{ {
"clientTokenHeader": [] "clientTokenHeader": []
}, },
@ -1441,6 +1507,9 @@
"/plugin/{id}/enable": { "/plugin/{id}/enable": {
"post": { "post": {
"security": [ "security": [
{
"clientTokenAuthorizationHeader": []
},
{ {
"clientTokenHeader": [] "clientTokenHeader": []
}, },
@ -1506,6 +1575,9 @@
"/stream": { "/stream": {
"get": { "get": {
"security": [ "security": [
{
"clientTokenAuthorizationHeader": []
},
{ {
"clientTokenHeader": [] "clientTokenHeader": []
}, },
@ -1561,6 +1633,9 @@
"/user": { "/user": {
"get": { "get": {
"security": [ "security": [
{
"clientTokenAuthorizationHeader": []
},
{ {
"clientTokenHeader": [] "clientTokenHeader": []
}, },
@ -1605,6 +1680,9 @@
}, },
"post": { "post": {
"security": [ "security": [
{
"clientTokenAuthorizationHeader": []
},
{ {
"clientTokenHeader": [] "clientTokenHeader": []
}, },
@ -1669,6 +1747,9 @@
"/user/{id}": { "/user/{id}": {
"get": { "get": {
"security": [ "security": [
{
"clientTokenAuthorizationHeader": []
},
{ {
"clientTokenHeader": [] "clientTokenHeader": []
}, },
@ -1735,6 +1816,9 @@
}, },
"post": { "post": {
"security": [ "security": [
{
"clientTokenAuthorizationHeader": []
},
{ {
"clientTokenHeader": [] "clientTokenHeader": []
}, },
@ -1810,6 +1894,9 @@
}, },
"delete": { "delete": {
"security": [ "security": [
{
"clientTokenAuthorizationHeader": []
},
{ {
"clientTokenHeader": [] "clientTokenHeader": []
}, },
@ -2435,6 +2522,12 @@
} }
}, },
"securityDefinitions": { "securityDefinitions": {
"appTokenAuthorizationHeader": {
"description": "Enter an application token with the `Bearer` prefix, e.g. `Bearer Axxxxxxxxxx`.",
"type": "apiKey",
"name": "Authorization",
"in": "header"
},
"appTokenHeader": { "appTokenHeader": {
"type": "apiKey", "type": "apiKey",
"name": "X-Gotify-Key", "name": "X-Gotify-Key",
@ -2448,6 +2541,12 @@
"basicAuth": { "basicAuth": {
"type": "basic" "type": "basic"
}, },
"clientTokenAuthorizationHeader": {
"description": "Enter a client token with the `Bearer` prefix, e.g. `Bearer Cxxxxxxxxxx`.",
"type": "apiKey",
"name": "Authorization",
"in": "header"
},
"clientTokenHeader": { "clientTokenHeader": {
"type": "apiKey", "type": "apiKey",
"name": "X-Gotify-Key", "name": "X-Gotify-Key",