Files
orbit/internal/transport/httpserver/console_scope.go

65 lines
1.9 KiB
Go

package httpserver
import (
"net/http"
"strings"
"git.yuntuo.hk/k2safe/orbit/internal/consoleauth"
"git.yuntuo.hk/k2safe/orbit/internal/fault"
core "git.yuntuo.hk/k2safe/orbit/model"
"git.yuntuo.hk/k2safe/orbit/platform/auth"
)
type consoleScopeKey struct{}
func scopedConsoleToken(r *http.Request, original auth.Token) auth.Token {
if t, ok := r.Context().Value(consoleScopeKey{}).(auth.Token); ok && t.Console != nil && t.Console.SessionNamespaceID == original.NamespaceID && t.CredentialID == original.CredentialID && t.Digest == original.Digest {
return t
}
return original
}
// consoleScopePath 仅开放已有管理读写,不允许借控制台范围启动 Worker/结果消费或创建业务资源。
func consoleScopePath(r *http.Request) bool {
p := r.URL.Path
if p == "/console/scope" {
return r.Method == "GET"
}
if p == "/console/retention" || strings.HasPrefix(p, "/console/retention/") || strings.HasPrefix(p, "/console/archive/") {
return true
}
for _, resource := range []string{"tasks", "schedules", "workflows", "subscriptions", "queues"} {
prefix := "/v1/" + resource
if p == prefix {
return r.Method == "GET"
}
if strings.HasPrefix(p, prefix+"/") {
return r.Method == "GET" || (resource != "queues" && r.Method == "POST")
}
}
return false
}
func RegisterConsoleScopes(server *http.Server, store consoleauth.Scopes) {
if server == nil {
return
}
mux, ok := server.Handler.(*http.ServeMux)
if !ok || store == nil {
return
}
mux.HandleFunc("GET /console/scope", func(w http.ResponseWriter, r *http.Request) {
t, ok := consoleCookieToken(r)
if !ok {
writeError(w, "", fault.Unauthorized)
return
}
out, err := store.GetScope(r.Context(), scopedConsoleToken(r, t), core.ID(r.URL.Query().Get("after")))
if err != nil {
writeError(w, "", err)
return
}
writeConsoleJSON(w, 200, map[string]any{"data": out})
})
}