72 lines
2.1 KiB
Go
72 lines
2.1 KiB
Go
package api
|
|
|
|
import (
|
|
"linkport/internal/store"
|
|
"net/http"
|
|
"strings"
|
|
)
|
|
|
|
func tokenPermits(t store.APIToken, path, method string) bool {
|
|
if strings.HasPrefix(path, "configuration/webdav/") || strings.HasPrefix(path, "configuration/s3/") || path == "configuration/export" {
|
|
return false
|
|
}
|
|
// Automation credentials cannot create credentials or reveal stored secrets.
|
|
if path == "session" || path == "logout" || path == "users" || strings.HasPrefix(path, "users/") || path == "tokens" || strings.HasPrefix(path, "tokens/") || strings.Contains(path, "reveal-password") || path == "configuration/backup" || path == "alerts/settings" {
|
|
return false
|
|
}
|
|
scope := "read"
|
|
if method != "GET" {
|
|
scope = "write"
|
|
} else if path == "commands" || path == "events" {
|
|
scope = "audit"
|
|
} else if path == "metrics" {
|
|
scope = "metrics"
|
|
}
|
|
for _, v := range t.Scopes {
|
|
if v == scope {
|
|
return true
|
|
}
|
|
}
|
|
return false
|
|
}
|
|
func (s *Server) tokens(w http.ResponseWriter, r *http.Request, path string, sess session) {
|
|
if path == "tokens" && r.Method == "GET" {
|
|
list, err := s.store.Tokens()
|
|
if err != nil {
|
|
fail(w, 500, "cannot load tokens")
|
|
return
|
|
}
|
|
respond(w, 200, list)
|
|
return
|
|
}
|
|
if path == "tokens" && r.Method == "POST" {
|
|
var body struct {
|
|
Name string `json:"name"`
|
|
Scopes []string `json:"scopes"`
|
|
ExpiresAt string `json:"expiresAt"`
|
|
}
|
|
if !decode(w, r, &body) {
|
|
return
|
|
}
|
|
t, secret, err := s.store.CreateToken(store.APIToken{Name: body.Name, Scopes: body.Scopes, ExpiresAt: body.ExpiresAt, Owner: sess.User})
|
|
if err != nil {
|
|
fail(w, 400, err.Error())
|
|
return
|
|
}
|
|
s.store.Event("", source(r), "api_token_created", t.ID)
|
|
respond(w, 201, map[string]any{"token": t, "secret": secret})
|
|
return
|
|
}
|
|
if strings.HasPrefix(path, "tokens/") && r.Method == "DELETE" {
|
|
id := strings.TrimPrefix(path, "tokens/")
|
|
if err := s.store.RevokeToken(id); err != nil {
|
|
fail(w, 404, "token not found")
|
|
return
|
|
}
|
|
s.store.Event("", source(r), "api_token_revoked", id)
|
|
respond(w, 200, map[string]bool{"ok": true})
|
|
return
|
|
}
|
|
fail(w, 405, "method not allowed")
|
|
}
|