150 lines
3.3 KiB
Go
150 lines
3.3 KiB
Go
|
|
package middleware
|
||
|
|
|
||
|
|
import (
|
||
|
|
"net/http"
|
||
|
|
"net/http/httptest"
|
||
|
|
"testing"
|
||
|
|
|
||
|
|
"veza-backend-api/internal/models"
|
||
|
|
"veza-backend-api/internal/services"
|
||
|
|
|
||
|
|
"github.com/gin-gonic/gin"
|
||
|
|
"github.com/google/uuid"
|
||
|
|
"github.com/lib/pq"
|
||
|
|
"go.uber.org/zap"
|
||
|
|
)
|
||
|
|
|
||
|
|
func TestRequireAPIKeyScope_PassthroughWithoutAPIKey(t *testing.T) {
|
||
|
|
svc := services.NewAPIKeyService(nil, zap.NewNop())
|
||
|
|
|
||
|
|
router := gin.New()
|
||
|
|
router.Use(RequireAPIKeyScope(svc))
|
||
|
|
router.GET("/test", func(c *gin.Context) {
|
||
|
|
c.JSON(http.StatusOK, gin.H{"ok": true})
|
||
|
|
})
|
||
|
|
|
||
|
|
w := httptest.NewRecorder()
|
||
|
|
req, _ := http.NewRequest("GET", "/test", nil)
|
||
|
|
router.ServeHTTP(w, req)
|
||
|
|
|
||
|
|
if w.Code != http.StatusOK {
|
||
|
|
t.Errorf("expected 200, got %d", w.Code)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
func TestRequireAPIKeyScope_AllowsReadScopeOnGET(t *testing.T) {
|
||
|
|
svc := services.NewAPIKeyService(nil, zap.NewNop())
|
||
|
|
|
||
|
|
apiKey := &models.APIKey{
|
||
|
|
ID: uuid.New(),
|
||
|
|
UserID: uuid.New(),
|
||
|
|
Name: "test",
|
||
|
|
Scopes: pq.StringArray{"read"},
|
||
|
|
}
|
||
|
|
|
||
|
|
router := gin.New()
|
||
|
|
router.Use(func(c *gin.Context) {
|
||
|
|
c.Set("api_key", apiKey)
|
||
|
|
c.Next()
|
||
|
|
})
|
||
|
|
router.Use(RequireAPIKeyScope(svc))
|
||
|
|
router.GET("/test", func(c *gin.Context) {
|
||
|
|
c.JSON(http.StatusOK, gin.H{"ok": true})
|
||
|
|
})
|
||
|
|
|
||
|
|
w := httptest.NewRecorder()
|
||
|
|
req, _ := http.NewRequest("GET", "/test", nil)
|
||
|
|
router.ServeHTTP(w, req)
|
||
|
|
|
||
|
|
if w.Code != http.StatusOK {
|
||
|
|
t.Errorf("expected 200, got %d", w.Code)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
func TestRequireAPIKeyScope_DeniesWriteWithReadOnlyScope(t *testing.T) {
|
||
|
|
svc := services.NewAPIKeyService(nil, zap.NewNop())
|
||
|
|
|
||
|
|
apiKey := &models.APIKey{
|
||
|
|
ID: uuid.New(),
|
||
|
|
UserID: uuid.New(),
|
||
|
|
Name: "test",
|
||
|
|
Scopes: pq.StringArray{"read"},
|
||
|
|
}
|
||
|
|
|
||
|
|
router := gin.New()
|
||
|
|
router.Use(func(c *gin.Context) {
|
||
|
|
c.Set("api_key", apiKey)
|
||
|
|
c.Next()
|
||
|
|
})
|
||
|
|
router.Use(RequireAPIKeyScope(svc))
|
||
|
|
router.POST("/test", func(c *gin.Context) {
|
||
|
|
c.JSON(http.StatusOK, gin.H{"ok": true})
|
||
|
|
})
|
||
|
|
|
||
|
|
w := httptest.NewRecorder()
|
||
|
|
req, _ := http.NewRequest("POST", "/test", nil)
|
||
|
|
router.ServeHTTP(w, req)
|
||
|
|
|
||
|
|
if w.Code != http.StatusForbidden {
|
||
|
|
t.Errorf("expected 403, got %d", w.Code)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
func TestRequireAPIKeyScope_AllowsWriteWithWriteScope(t *testing.T) {
|
||
|
|
svc := services.NewAPIKeyService(nil, zap.NewNop())
|
||
|
|
|
||
|
|
apiKey := &models.APIKey{
|
||
|
|
ID: uuid.New(),
|
||
|
|
UserID: uuid.New(),
|
||
|
|
Name: "test",
|
||
|
|
Scopes: pq.StringArray{"read", "write"},
|
||
|
|
}
|
||
|
|
|
||
|
|
router := gin.New()
|
||
|
|
router.Use(func(c *gin.Context) {
|
||
|
|
c.Set("api_key", apiKey)
|
||
|
|
c.Next()
|
||
|
|
})
|
||
|
|
router.Use(RequireAPIKeyScope(svc))
|
||
|
|
router.POST("/test", func(c *gin.Context) {
|
||
|
|
c.JSON(http.StatusOK, gin.H{"ok": true})
|
||
|
|
})
|
||
|
|
|
||
|
|
w := httptest.NewRecorder()
|
||
|
|
req, _ := http.NewRequest("POST", "/test", nil)
|
||
|
|
router.ServeHTTP(w, req)
|
||
|
|
|
||
|
|
if w.Code != http.StatusOK {
|
||
|
|
t.Errorf("expected 200, got %d", w.Code)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
func TestRequireAPIKeyScope_AdminScopeAllowsAll(t *testing.T) {
|
||
|
|
svc := services.NewAPIKeyService(nil, zap.NewNop())
|
||
|
|
|
||
|
|
apiKey := &models.APIKey{
|
||
|
|
ID: uuid.New(),
|
||
|
|
UserID: uuid.New(),
|
||
|
|
Name: "test",
|
||
|
|
Scopes: pq.StringArray{"admin"},
|
||
|
|
}
|
||
|
|
|
||
|
|
router := gin.New()
|
||
|
|
router.Use(func(c *gin.Context) {
|
||
|
|
c.Set("api_key", apiKey)
|
||
|
|
c.Next()
|
||
|
|
})
|
||
|
|
router.Use(RequireAPIKeyScope(svc))
|
||
|
|
router.DELETE("/test", func(c *gin.Context) {
|
||
|
|
c.JSON(http.StatusOK, gin.H{"ok": true})
|
||
|
|
})
|
||
|
|
|
||
|
|
w := httptest.NewRecorder()
|
||
|
|
req, _ := http.NewRequest("DELETE", "/test", nil)
|
||
|
|
router.ServeHTTP(w, req)
|
||
|
|
|
||
|
|
if w.Code != http.StatusOK {
|
||
|
|
t.Errorf("expected 200, got %d (admin should have write access)", w.Code)
|
||
|
|
}
|
||
|
|
}
|