hub v0.148.0 (code): SECURITY — the customer list and box reports need the operator key (R-951); R-950 rotated; R-952, R-953 filed (97 -> 99 rows)
gates / gates (push) Successful in 6m8s
gates / gates (push) Successful in 6m8s
This commit is contained in:
@@ -230,6 +230,17 @@ func (h *Handler) checkAuthHost(r *http.Request) (hostID, customerID string, isG
|
||||
return host.HostID, host.CustomerID, false, true
|
||||
}
|
||||
|
||||
// requireGlobalKey answers 403 and returns false unless the request carries the operator/global key.
|
||||
// The same check as the /admin/wg/* handlers (wg.go), in one place for routes that read every customer.
|
||||
func (h *Handler) requireGlobalKey(w http.ResponseWriter, r *http.Request) bool {
|
||||
_, _, isGlobal, ok := h.checkAuthHost(r)
|
||||
if !ok || !isGlobal {
|
||||
http.Error(w, "Forbidden: global key required", http.StatusForbidden)
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// ServeHTTP routes API requests.
|
||||
func (h *Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
path := strings.TrimPrefix(r.URL.Path, "/api/v1")
|
||||
@@ -2415,6 +2426,12 @@ func (h *Handler) handleEvent(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
|
||||
func (h *Handler) handleCustomers(w http.ResponseWriter, r *http.Request) {
|
||||
// R-951: operator/global key only. These routes return every customer's name, dashboard address and
|
||||
// stored box report; until v0.148.0 they answered with no credential at all. A box's own key must not
|
||||
// list customers either (TestCustomersRoutes_*).
|
||||
if !h.requireGlobalKey(w, r) {
|
||||
return
|
||||
}
|
||||
customers, err := h.store.GetCustomers()
|
||||
if err != nil {
|
||||
h.logger.Printf("[ERROR] Failed to get customers: %v", err)
|
||||
@@ -2458,6 +2475,12 @@ func (h *Handler) handleCustomers(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
|
||||
func (h *Handler) handleCustomer(w http.ResponseWriter, r *http.Request, customerID string) {
|
||||
// R-951: operator/global key only. These routes return every customer's name, dashboard address and
|
||||
// stored box report; until v0.148.0 they answered with no credential at all. A box's own key must not
|
||||
// list customers either (TestCustomersRoutes_*).
|
||||
if !h.requireGlobalKey(w, r) {
|
||||
return
|
||||
}
|
||||
customer, err := h.store.GetCustomer(customerID)
|
||||
if err != nil {
|
||||
h.logger.Printf("[ERROR] Failed to get customer %s: %v", customerID, err)
|
||||
@@ -2475,6 +2498,12 @@ func (h *Handler) handleCustomer(w http.ResponseWriter, r *http.Request, custome
|
||||
}
|
||||
|
||||
func (h *Handler) handleCustomerHistory(w http.ResponseWriter, r *http.Request, customerID string) {
|
||||
// R-951: operator/global key only. These routes return every customer's name, dashboard address and
|
||||
// stored box report; until v0.148.0 they answered with no credential at all. A box's own key must not
|
||||
// list customers either (TestCustomersRoutes_*).
|
||||
if !h.requireGlobalKey(w, r) {
|
||||
return
|
||||
}
|
||||
period := r.URL.Query().Get("period")
|
||||
var since time.Duration
|
||||
switch period {
|
||||
|
||||
Reference in New Issue
Block a user