Commit fdc81742 authored by robwa's avatar robwa
Browse files

feat: Add API doc for auth and other endpoints

parent b1141910
...@@ -25,7 +25,7 @@ SWAG := swag ...@@ -25,7 +25,7 @@ SWAG := swag
ifdef GOPATH ifdef GOPATH
SWAG = $(GOPATH)/bin/swag SWAG = $(GOPATH)/bin/swag
endif endif
SWAG_ARGS := -d api/v1/ -g api.go SWAG_ARGS := -d api/v1/,cmd/tank/ -g api.go
EXECUTEABLE := tank EXECUTEABLE := tank
......
...@@ -1172,9 +1172,323 @@ const docTemplate = `{ ...@@ -1172,9 +1172,323 @@ const docTemplate = `{
} }
} }
} }
},
"/auth/backends": {
"get": {
"description": "Lists authentication backends.",
"produces": [
"application/json"
],
"summary": "List authentication backends",
"responses": {
"200": {
"description": "OK",
"schema": {
"type": "array",
"items": {
"$ref": "#/definitions/auth.AuthBackendInfo"
}
}
},
"404": {
"description": "Not Found",
"schema": {
"$ref": "#/definitions/auth.HTTPErrorResponse"
}
}
}
}
},
"/auth/oidc/callback": {
"get": {
"description": "Completes OIDC login.",
"produces": [
"application/json"
],
"summary": "Complete OIDC login",
"parameters": [
{
"type": "string",
"description": "OIDC state",
"name": "state",
"in": "query",
"required": true
},
{
"type": "string",
"description": "OIDC code",
"name": "code",
"in": "query",
"required": true
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"type": "string"
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/auth.HTTPErrorResponse"
}
},
"401": {
"description": "Unauthorized",
"schema": {
"$ref": "#/definitions/auth.HTTPErrorResponse"
}
},
"409": {
"description": "Conflict",
"schema": {
"$ref": "#/definitions/auth.HTTPErrorResponse"
}
},
"410": {
"description": "Gone",
"schema": {
"$ref": "#/definitions/auth.HTTPErrorResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/auth.HTTPErrorResponse"
}
}
}
}
},
"/auth/oidc/login": {
"get": {
"description": "Creates a session via OIDC. Redirects to identity provider.",
"produces": [
"application/json"
],
"summary": "Create OIDC session",
"parameters": [
{
"type": "string",
"description": "OIDC session ID",
"name": "session-id",
"in": "query",
"required": true
}
],
"responses": {
"302": {
"description": ""
},
"401": {
"description": "Unauthorized",
"schema": {
"$ref": "#/definitions/auth.HTTPErrorResponse"
}
},
"409": {
"description": "Conflict",
"schema": {
"$ref": "#/definitions/auth.HTTPErrorResponse"
}
}
}
}
},
"/auth/session": {
"get": {
"description": "Retrieves session info.",
"produces": [
"application/json"
],
"summary": "Retrieve session info",
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/auth.Session"
}
},
"404": {
"description": "Not Found",
"schema": {
"$ref": "#/definitions/auth.HTTPErrorResponse"
}
},
"408": {
"description": "Request Timeout",
"schema": {
"$ref": "#/definitions/auth.HTTPErrorResponse"
}
}
}
},
"post": {
"description": "Creates a new session.",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"summary": "Create session",
"parameters": [
{
"description": "Request data according to backend",
"name": "request",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/auth.NewSessionRequest"
}
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/auth.NewSessionResponse"
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/auth.HTTPErrorResponse"
}
},
"409": {
"description": "Conflict",
"schema": {
"$ref": "#/definitions/auth.HTTPErrorResponse"
}
}
}
},
"delete": {
"description": "Deletes the session.",
"produces": [
"application/json"
],
"summary": "Delete session",
"responses": {
"200": {
"description": "OK",
"schema": {
"type": "string"
}
},
"401": {
"description": "Unauthorized",
"schema": {
"$ref": "#/definitions/auth.HTTPErrorResponse"
}
}
}
}
},
"/healthz": {
"get": {
"description": "Checks daemon health.",
"produces": [
"application/json"
],
"summary": "Check health",
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/main.Health"
}
},
"503": {
"description": "Service Unavailable",
"schema": {
"$ref": "#/definitions/main.Health"
}
}
}
}
} }
}, },
"definitions": { "definitions": {
"auth.AuthBackendInfo": {
"type": "object",
"properties": {
"description": {
"type": "string"
},
"name": {
"type": "string"
},
"state": {
"type": "integer"
}
}
},
"auth.HTTPErrorResponse": {
"type": "object",
"properties": {
"error": {
"type": "string"
}
}
},
"auth.NewSessionRequest": {
"type": "object",
"properties": {
"arguments": {
"type": "array",
"items": {
"type": "integer"
}
},
"backend": {
"type": "string"
}
}
},
"auth.NewSessionResponse": {
"type": "object",
"properties": {
"session": {
"$ref": "#/definitions/auth.Session"
},
"token": {
"type": "string"
}
}
},
"auth.Session": {
"type": "object",
"properties": {
"all-shows": {
"type": "boolean"
},
"privileged": {
"type": "boolean"
},
"public-shows": {
"type": "array",
"items": {
"type": "string"
}
},
"readonly": {
"type": "boolean"
},
"shows": {
"type": "array",
"items": {
"type": "string"
}
},
"username": {
"type": "string"
}
}
},
"importer.Job": { "importer.Job": {
"type": "object", "type": "object",
"properties": { "properties": {
...@@ -1251,6 +1565,23 @@ const docTemplate = `{ ...@@ -1251,6 +1565,23 @@ const docTemplate = `{
} }
} }
}, },
"main.Health": {
"type": "object",
"properties": {
"auth": {
"$ref": "#/definitions/main.HealthStatus"
},
"importer": {
"$ref": "#/definitions/main.HealthStatus"
},
"store": {
"$ref": "#/definitions/main.HealthStatus"
}
}
},
"main.HealthStatus": {
"type": "object"
},
"store.File": { "store.File": {
"type": "object", "type": "object",
"properties": { "properties": {
......
...@@ -87,6 +87,16 @@ func Init(c *Config, infoLog, errLog, dbgLog *log.Logger) (err error) { ...@@ -87,6 +87,16 @@ func Init(c *Config, infoLog, errLog, dbgLog *log.Logger) (err error) {
return return
} }
// newSession creates a new session.
// @Summary Create session
// @Description Creates a new session.
// @Accept json
// @Produce json
// @Param request body NewSessionRequest true "Request data according to backend"
// @Success 200 {object} NewSessionResponse
// @Failure 400 {object} HTTPErrorResponse
// @Failure 409 {object} HTTPErrorResponse
// @Router /auth/session [post]
func newSession(c *gin.Context) { func newSession(c *gin.Context) {
request := &NewSessionRequest{} request := &NewSessionRequest{}
err := json.NewDecoder(c.Request.Body).Decode(request) err := json.NewDecoder(c.Request.Body).Decode(request)
...@@ -128,6 +138,14 @@ func newSession(c *gin.Context) { ...@@ -128,6 +138,14 @@ func newSession(c *gin.Context) {
c.JSON(http.StatusOK, response) c.JSON(http.StatusOK, response)
} }
// getSession retrieves session info.
// @Summary Retrieve session info
// @Description Retrieves session info.
// @Produce json
// @Success 200 {object} Session
// @Failure 404 {object} HTTPErrorResponse
// @Failure 408 {object} HTTPErrorResponse
// @Router /auth/session [get]
func getSession(c *gin.Context) { func getSession(c *gin.Context) {
s := getSessionFromBearerToken(c.Request) s := getSessionFromBearerToken(c.Request)
if s == nil { if s == nil {
...@@ -161,6 +179,13 @@ func getSession(c *gin.Context) { ...@@ -161,6 +179,13 @@ func getSession(c *gin.Context) {
} }
} }
// deleteSession deletes the session.
// @Summary Delete session
// @Description Deletes the session.
// @Produce json
// @Success 200 {object} string
// @Failure 401 {object} HTTPErrorResponse
// @Router /auth/session [delete]
func deleteSession(c *gin.Context) { func deleteSession(c *gin.Context) {
s := getSessionFromBearerToken(c.Request) s := getSessionFromBearerToken(c.Request)
if s == nil || s.State() > SessionStateLoggedIn { if s == nil || s.State() > SessionStateLoggedIn {
...@@ -175,6 +200,13 @@ func deleteSession(c *gin.Context) { ...@@ -175,6 +200,13 @@ func deleteSession(c *gin.Context) {
c.JSON(http.StatusOK, "you are now logged out") c.JSON(http.StatusOK, "you are now logged out")
} }
// listBackends lists authentication backends.
// @Summary List authentication backends
// @Description Lists authentication backends.
// @Produce json
// @Success 200 {object} []AuthBackendInfo
// @Failure 404 {object} HTTPErrorResponse
// @Router /auth/backends [get]
func listBackends(c *gin.Context) { func listBackends(c *gin.Context) {
backends := []AuthBackendInfo{} backends := []AuthBackendInfo{}
if auth.backends.oidc != nil { if auth.backends.oidc != nil {
......
...@@ -225,6 +225,15 @@ func (b *OIDCBackend) NewSession(ctx context.Context, arguments json.RawMessage) ...@@ -225,6 +225,15 @@ func (b *OIDCBackend) NewSession(ctx context.Context, arguments json.RawMessage)
return return
} }
// Login creates a session via OIDC.
// @Summary Create OIDC session
// @Description Creates a session via OIDC. Redirects to identity provider.
// @Produce json
// @Param session-id query string true "OIDC session ID"
// @Success 302
// @Failure 401 {object} HTTPErrorResponse
// @Failure 409 {object} HTTPErrorResponse
// @Router /auth/oidc/login [get]
func (b *OIDCBackend) Login(c *gin.Context) { func (b *OIDCBackend) Login(c *gin.Context) {
s := auth.sessions.get(c.Query("session-id")) s := auth.sessions.get(c.Query("session-id"))
if s == nil { if s == nil {
...@@ -244,6 +253,19 @@ func (b *OIDCBackend) Login(c *gin.Context) { ...@@ -244,6 +253,19 @@ func (b *OIDCBackend) Login(c *gin.Context) {
c.Redirect(http.StatusFound, b.oauth2Config.AuthCodeURL(s.ID(), oidc.Nonce(s.oidc.nonce))) c.Redirect(http.StatusFound, b.oauth2Config.AuthCodeURL(s.ID(), oidc.Nonce(s.oidc.nonce)))
} }
// Callback completes OIDC login.
// @Summary Complete OIDC login
// @Description Completes OIDC login.
// @Produce json
// @Param state query string true "OIDC state"
// @Param code query string true "OIDC code"
// @Success 200 {object} string
// @Failure 400 {object} HTTPErrorResponse
// @Failure 401 {object} HTTPErrorResponse
// @Failure 409 {object} HTTPErrorResponse
// @Failure 410 {object} HTTPErrorResponse
// @Failure 500 {object} HTTPErrorResponse
// @Router /auth/oidc/callback [get]
func (b *OIDCBackend) Callback(c *gin.Context) { func (b *OIDCBackend) Callback(c *gin.Context) {
s := auth.sessions.get(c.Query("state")) s := auth.sessions.get(c.Query("state"))
if s == nil { if s == nil {
......
...@@ -114,6 +114,13 @@ type Health struct { ...@@ -114,6 +114,13 @@ type Health struct {
Importer HealthStatus `json:"importer"` Importer HealthStatus `json:"importer"`
} }
// healthzHandler checks daemon health.
// @Summary Check health
// @Description Checks daemon health.
// @Produce json
// @Success 200 {object} Health
// @Failure 503 {object} Health
// @Router /healthz [get]
func healthzHandler(c *gin.Context, st *store.Store, im *importer.Importer) { func healthzHandler(c *gin.Context, st *store.Store, im *importer.Importer) {
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) // TODO: hardcoded value ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) // TODO: hardcoded value
defer cancel() defer cancel()
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment