refactor: unify internal api authentication
This commit is contained in:
@@ -1,16 +1,21 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"crypto/hmac"
|
||||
"crypto/sha256"
|
||||
"encoding/hex"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"strconv"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
func TestInternalCultivateRequiresSignedServiceRequest(t *testing.T) {
|
||||
previous := internalAPI
|
||||
defer func() { internalAPI = previous }()
|
||||
internalAPI = internalAPIRuntime{config: internalAPIConfig{Enabled: true, Services: map[string]internalAPIServiceConfig{"cultivate-server": {Secret: "secret", Allow: []string{internalCapabilityCultivate}}}}}
|
||||
internalAPI = internalAPIRuntime{config: internalAPIConfig{Enabled: true, Services: map[string]internalAPIServiceConfig{"hotgo-admin": {Secret: "secret"}}}}
|
||||
req := httptest.NewRequest(http.MethodPost, "/internal/cultivate/tenants/default/users/batch", strings.NewReader(`{"user_ids":[1]}`))
|
||||
rec := httptest.NewRecorder()
|
||||
serveInternalCultivate(rec, req, "/internal/cultivate/")
|
||||
@@ -19,18 +24,25 @@ func TestInternalCultivateRequiresSignedServiceRequest(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestInternalCultivateRejectsWrongCapability(t *testing.T) {
|
||||
func TestInternalCultivateUsesSharedInternalCredential(t *testing.T) {
|
||||
previous := internalAPI
|
||||
defer func() { internalAPI = previous }()
|
||||
internalAPI = internalAPIRuntime{config: internalAPIConfig{Enabled: true, Services: map[string]internalAPIServiceConfig{"cultivate-server": {Secret: "secret", Allow: []string{internalCapabilityAdminQuery}}}}}
|
||||
internalAPI = internalAPIRuntime{config: internalAPIConfig{Enabled: true, TimeWindowSeconds: 300, Services: map[string]internalAPIServiceConfig{
|
||||
"hotgo-admin": {Secret: "shared-secret", Allow: []string{"admin_query"}},
|
||||
"cultivate-server": {Secret: "ignored-separate-secret", Allow: []string{"cultivate"}},
|
||||
}}}
|
||||
req := httptest.NewRequest(http.MethodPost, "/internal/cultivate/tenants/default/users/batch", strings.NewReader(`{"user_ids":[1]}`))
|
||||
req.Header.Set(internalHeaderService, "cultivate-server")
|
||||
req.Header.Set(internalHeaderTimestamp, "1")
|
||||
timestamp := strconv.FormatInt(time.Now().Unix(), 10)
|
||||
req.Header.Set(internalHeaderTimestamp, timestamp)
|
||||
req.Header.Set(internalHeaderNonce, "nonce")
|
||||
req.Header.Set(internalHeaderSignature, "signature")
|
||||
bodyHash := sha256.Sum256([]byte(`{"user_ids":[1]}`))
|
||||
signingText := strings.Join([]string{req.Method, req.URL.RequestURI(), hex.EncodeToString(bodyHash[:]), timestamp, "nonce"}, "\n")
|
||||
mac := hmac.New(sha256.New, []byte("shared-secret"))
|
||||
_, _ = mac.Write([]byte(signingText))
|
||||
req.Header.Set(internalHeaderSignature, hex.EncodeToString(mac.Sum(nil)))
|
||||
rec := httptest.NewRecorder()
|
||||
serveInternalCultivate(rec, req, "/internal/cultivate/")
|
||||
if rec.Code != http.StatusForbidden {
|
||||
t.Fatalf("status=%d body=%s", rec.Code, rec.Body.String())
|
||||
if !authorizeInternalAPI(rec, req) {
|
||||
t.Fatalf("shared internal credential was rejected: status=%d body=%s", rec.Code, rec.Body.String())
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user