Support webSSH Origin Allowlist

This commit is contained in:
MengMengCode
2026-06-09 22:48:09 +08:00
parent e6551bf4ae
commit 63611dc932
9 changed files with 386 additions and 88 deletions
+80
View File
@@ -0,0 +1,80 @@
package api
import (
"encoding/json"
"net/http"
"strings"
"clicd/internal/config"
)
type webSSHOriginSettingsRequest struct {
Origins []string `json:"origins"`
WebSSHAllowedOrigins []string `json:"webssh_allowed_origins"`
}
type webSSHOriginSettingsResponse struct {
Origins []string `json:"origins"`
CurrentOrigin string `json:"current_origin,omitempty"`
}
func HandleWebSSHOriginSettings(w http.ResponseWriter, r *http.Request) {
switch r.Method {
case http.MethodGet:
jsonResponse(w, http.StatusOK, APIResponse{Success: true, Data: webSSHOriginSettingsStatus(r)})
case http.MethodPut:
updateWebSSHOriginSettings(w, r)
default:
jsonResponse(w, http.StatusMethodNotAllowed, APIResponse{Success: false, Message: "Method not allowed"})
}
}
func updateWebSSHOriginSettings(w http.ResponseWriter, r *http.Request) {
var req webSSHOriginSettingsRequest
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
jsonResponse(w, http.StatusBadRequest, APIResponse{Success: false, Message: "Invalid request body"})
return
}
origins := req.Origins
if len(origins) == 0 && len(req.WebSSHAllowedOrigins) > 0 {
origins = req.WebSSHAllowedOrigins
}
normalized, err := config.NormalizeAllowedOrigins(origins)
if err != nil {
jsonResponse(w, http.StatusBadRequest, APIResponse{Success: false, Message: err.Error()})
return
}
config.AppConfig.WebSSHAllowedOrigins = normalized
if err := config.SaveConfig(); err != nil {
jsonResponse(w, http.StatusInternalServerError, APIResponse{Success: false, Message: "Save Origin allowlist failed"})
return
}
auditRequest(r, "settings.webssh_origins", "WebSSH Origin", "origins="+strings.Join(normalized, ","), true, "")
jsonResponse(w, http.StatusOK, APIResponse{Success: true, Message: "Origin allowlist saved", Data: webSSHOriginSettingsStatus(r)})
}
func webSSHOriginSettingsStatus(r *http.Request) webSSHOriginSettingsResponse {
origins := config.AppConfig.WebSSHAllowedOrigins
if origins == nil {
origins = []string{}
}
return webSSHOriginSettingsResponse{
Origins: origins,
CurrentOrigin: requestOrigin(r),
}
}
func requestOrigin(r *http.Request) string {
host := strings.TrimSpace(r.Host)
if host == "" {
return ""
}
scheme := "http"
if r.TLS != nil {
scheme = "https"
}
if forwarded := strings.TrimSpace(r.Header.Get("X-Forwarded-Proto")); forwarded != "" {
scheme = strings.ToLower(strings.Split(forwarded, ",")[0])
}
return scheme + "://" + host
}
+3 -17
View File
@@ -1,10 +1,9 @@
package api
import (
"net"
"net/http"
"net/url"
"strings"
"clicd/internal/config"
"github.com/gorilla/websocket"
)
@@ -17,19 +16,6 @@ var upgrader = websocket.Upgrader{
if origin == "" {
return true
}
originURL, err := url.Parse(origin)
if err != nil {
return false
}
originHost := strings.ToLower(stripPort(originURL.Host))
requestHost := strings.ToLower(stripPort(r.Host))
return originHost != "" && originHost == requestHost
return config.IsOriginAllowed(origin, r.Host)
},
}
func stripPort(host string) string {
if parsedHost, _, err := net.SplitHostPort(host); err == nil {
return parsedHost
}
return strings.Trim(host, "[]")
}