Files

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")
}