add: api key middleware
This commit is contained in:
31
internal/middlewares/api.go
Normal file
31
internal/middlewares/api.go
Normal file
@@ -0,0 +1,31 @@
|
||||
package middlewares
|
||||
|
||||
import (
|
||||
"crypto/subtle"
|
||||
"net/http"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
|
||||
"GoMembership/internal/config"
|
||||
)
|
||||
|
||||
func APIKeyMiddleware() gin.HandlerFunc {
|
||||
return func(c *gin.Context) {
|
||||
clientAPIKey := c.GetHeader("X-API-Key")
|
||||
|
||||
if clientAPIKey == "" {
|
||||
c.JSON(http.StatusUnauthorized, gin.H{"error": "API key is missing"})
|
||||
c.Abort()
|
||||
return
|
||||
}
|
||||
|
||||
// Using subtle.ConstantTimeCompare to mitigate timing attacks
|
||||
if subtle.ConstantTimeCompare([]byte(clientAPIKey), []byte(config.Auth.APIKEY)) != 1 {
|
||||
c.JSON(http.StatusUnauthorized, gin.H{"error": "Invalid API key"})
|
||||
c.Abort()
|
||||
return
|
||||
}
|
||||
|
||||
c.Next()
|
||||
}
|
||||
}
|
||||
61
internal/middlewares/api_test.go
Normal file
61
internal/middlewares/api_test.go
Normal file
@@ -0,0 +1,61 @@
|
||||
package middlewares
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"testing"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
"GoMembership/internal/config"
|
||||
)
|
||||
|
||||
func TestAPIKeyMiddleware(t *testing.T) {
|
||||
// Set up a test API key
|
||||
testAPIKey := "test-api-key-12345"
|
||||
config.Auth.APIKEY = testAPIKey
|
||||
|
||||
// Set Gin to Test Mode
|
||||
gin.SetMode(gin.TestMode)
|
||||
|
||||
// Tests table
|
||||
tests := []struct {
|
||||
name string
|
||||
apiKey string
|
||||
wantStatus int
|
||||
}{
|
||||
{"Valid API Key", testAPIKey, http.StatusOK},
|
||||
{"Missing API Key", "", http.StatusUnauthorized},
|
||||
{"Invalid API Key", "wrong-key", http.StatusUnauthorized},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
// Set up a new test router and handler
|
||||
router := gin.New()
|
||||
router.Use(APIKeyMiddleware())
|
||||
router.GET("/test", func(c *gin.Context) {
|
||||
c.Status(http.StatusOK)
|
||||
})
|
||||
|
||||
// Create a test request
|
||||
w := httptest.NewRecorder()
|
||||
req, _ := http.NewRequest("GET", "/test", nil)
|
||||
if tt.apiKey != "" {
|
||||
req.Header.Set("X-API-Key", tt.apiKey)
|
||||
}
|
||||
|
||||
// Serve the request
|
||||
router.ServeHTTP(w, req)
|
||||
|
||||
// Assert the response
|
||||
assert.Equal(t, tt.wantStatus, w.Code)
|
||||
|
||||
// Additional assertions for specific cases
|
||||
if tt.wantStatus == http.StatusUnauthorized {
|
||||
assert.Contains(t, w.Body.String(), "API key")
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user