diff --git a/chaoscenter/authentication/api/middleware/jwt_middlware_test.go b/chaoscenter/authentication/api/middleware/jwt_middlware_test.go new file mode 100644 index 00000000000..7731c21996e --- /dev/null +++ b/chaoscenter/authentication/api/middleware/jwt_middlware_test.go @@ -0,0 +1,125 @@ +package middleware_test + +import ( + "errors" + "net/http" + "net/http/httptest" + "testing" + + "github.com/gin-gonic/gin" + "github.com/golang-jwt/jwt" + "github.com/litmuschaos/litmus/chaoscenter/authentication/api/middleware" + "github.com/litmuschaos/litmus/chaoscenter/authentication/api/mocks" + "github.com/litmuschaos/litmus/chaoscenter/authentication/pkg/utils" + "github.com/stretchr/testify/assert" +) + +func TestJwtMiddleware(t *testing.T) { + router := gin.Default() + mockService := new(mocks.MockedApplicationService) + router.Use(middleware.JwtMiddleware(mockService)) + + router.GET("/status", func(c *gin.Context) { + c.JSON(http.StatusOK, gin.H{"message": "Access Granted"}) + }) + + createRequest := func(token string) *httptest.ResponseRecorder { + req := httptest.NewRequest("GET", "/status", nil) + req.Header.Set("Authorization", "Bearer "+token) + w := httptest.NewRecorder() + return w + } + + t.Run("Valid Token", func(t *testing.T) { + wValid := createRequest("jwtstring") + assert.Equal(t, http.StatusOK, wValid.Code) + }) + + t.Run("Missing Authorization Header", func(t *testing.T) { + wMissingHeader := httptest.NewRecorder() + reqMissingHeader := httptest.NewRequest("GET", "/status", nil) + router.ServeHTTP(wMissingHeader, reqMissingHeader) + assert.Equal(t, http.StatusUnauthorized, wMissingHeader.Code) + }) +} + +func TestJwtMiddleware_SetClaimsAndCallNextHandler(t *testing.T) { + router := gin.Default() + + mockService := new(mocks.MockedApplicationService) + router.Use(middleware.JwtMiddleware(mockService)) + + router.GET("/status", func(c *gin.Context) { + username, _ := c.Get("username") + uid, _ := c.Get("uid") + role, _ := c.Get("role") + assert.Equal(t, "testuser", username) + assert.Equal(t, "12345", uid) + assert.Equal(t, "admin", role) + c.JSON(http.StatusOK, gin.H{"message": "Access Granted"}) + }) + + mockService.On("ValidateToken", "jwtstring").Return(&jwt.Token{ + Valid: true, + Claims: jwt.MapClaims{ + "username": "testuser", + "uid": "12345", + "role": "admin", + }, + }, nil) + + w := httptest.NewRecorder() + req, _ := http.NewRequest("GET", "/status", nil) + req.Header.Set("Authorization", "Bearer jwtstring") + router.ServeHTTP(w, req) + assert.Equal(t, http.StatusOK, w.Code) +} + +func TestJwtMiddleware_TokenValidationFailure(t *testing.T) { + router := gin.Default() + + mockService := new(mocks.MockedApplicationService) + router.Use(middleware.JwtMiddleware(mockService)) + + router.GET("/status", func(c *gin.Context) { + c.JSON(http.StatusOK, gin.H{"message": "Access Granted"}) + }) + + mockService.On("ValidateToken", "invalidtoken").Return(&jwt.Token{ + Valid: false, + }, nil) + + w := httptest.NewRecorder() + req, _ := http.NewRequest("GET", "/status", nil) + req.Header.Set("Authorization", "Bearer invalidtoken") + router.ServeHTTP(w, req) + + assert.Equal(t, http.StatusUnauthorized, w.Code) +} + +func TestJwtMiddleware_Error(t *testing.T) { + router := gin.Default() + + mockService := new(mocks.MockedApplicationService) + router.Use(middleware.JwtMiddleware(mockService)) + + dummyToken := &jwt.Token{ + Raw: "DummyToken", + Method: jwt.SigningMethodHS256, + Header: map[string]interface{}{"alg": "HS256"}, + Claims: jwt.MapClaims{"foo": "bar"}, + Signature: "", + Valid: false, + } + + mockService.On("ValidateToken", "dummy").Return(dummyToken, errors.New("mock error")) + + req, _ := http.NewRequest("GET", "/", nil) + req.Header.Set("Authorization", "Bearer dummy") + resp := httptest.NewRecorder() + router.ServeHTTP(resp, req) + + if status := resp.Code; status != utils.ErrorStatusCodes[utils.ErrUnauthorized] { + t.Errorf("Handler returned wrong status code: got %v want %v", status, utils.ErrorStatusCodes[utils.ErrUnauthorized]) + } +} \ No newline at end of file