diff --git a/internal/controller/context_controller.go b/internal/controller/context_controller.go index 780edd04..b0cbf1d7 100644 --- a/internal/controller/context_controller.go +++ b/internal/controller/context_controller.go @@ -75,6 +75,16 @@ type AppContextResponse struct { App ACRApp `json:"app"` } +// VR -> Version Response + +type VersionResponse struct { + Status int `json:"status"` + Message string `json:"message"` + Version string `json:"version"` + CommitHash string `json:"commitHash"` + BuildTimestamp string `json:"buildTimestamp"` +} + type ContextControllerInput struct { dig.In @@ -105,6 +115,8 @@ func NewContextController(i ContextControllerInput) *ContextController { contextGroup.GET("/user", controller.userContextHandler) contextGroup.GET("/app", controller.appContextHandler) + i.RouterGroup.GET("/version", controller.versionHandler) + return controller } @@ -148,6 +160,37 @@ func (controller *ContextController) userContextHandler(c *gin.Context) { c.JSON(200, userContext) } +func (controller *ContextController) versionHandler(c *gin.Context) { + context, err := new(model.UserContext).NewFromGin(c) + + if err != nil { + if !errors.Is(err, model.ErrUserContextNotFound) { + controller.log.App.Error().Err(err).Msg("Failed to create user context from request") + } + c.JSON(200, VersionResponse{ + Status: 401, + Message: "Unauthorized", + }) + return + } + + if !context.IsAuthenticated() { + c.JSON(200, VersionResponse{ + Status: 401, + Message: "Unauthorized", + }) + return + } + + c.JSON(200, VersionResponse{ + Status: 200, + Message: "Success", + Version: model.Version, + CommitHash: model.CommitHash, + BuildTimestamp: model.BuildTimestamp, + }) +} + func (controller *ContextController) appContextHandler(c *gin.Context) { c.JSON(200, AppContextResponse{ Status: 200, diff --git a/internal/controller/context_controller_test.go b/internal/controller/context_controller_test.go index c188adec..e54b2d56 100644 --- a/internal/controller/context_controller_test.go +++ b/internal/controller/context_controller_test.go @@ -108,6 +108,70 @@ func TestContextController(t *testing.T) { return string(bytes) }(), }, + { + description: "Ensure version returns 401 when unauthorized", + middlewares: []gin.HandlerFunc{}, + path: "/api/version", + expected: func() string { + expectedVersionResponse := VersionResponse{ + Status: 401, + Message: "Unauthorized", + } + bytes, err := json.Marshal(expectedVersionResponse) + require.NoError(t, err) + return string(bytes) + }(), + }, + { + description: "Ensure version returns 401 when context is unauthenticated", + middlewares: []gin.HandlerFunc{ + func(c *gin.Context) { + c.Set("context", &model.UserContext{ + Authenticated: false, + Provider: model.ProviderTailscale, + }) + }, + }, + path: "/api/version", + expected: func() string { + expectedVersionResponse := VersionResponse{ + Status: 401, + Message: "Unauthorized", + } + bytes, err := json.Marshal(expectedVersionResponse) + require.NoError(t, err) + return string(bytes) + }(), + }, + { + description: "Ensure version returns the build info when authorized", + middlewares: []gin.HandlerFunc{ + func(c *gin.Context) { + c.Set("context", &model.UserContext{ + Authenticated: true, + Provider: model.ProviderLocal, + Local: &model.LocalContext{ + BaseContext: model.BaseContext{ + Username: "johndoe", + }, + }, + }) + }, + }, + path: "/api/version", + expected: func() string { + expectedVersionResponse := VersionResponse{ + Status: 200, + Message: "Success", + Version: model.Version, + CommitHash: model.CommitHash, + BuildTimestamp: model.BuildTimestamp, + } + bytes, err := json.Marshal(expectedVersionResponse) + require.NoError(t, err) + return string(bytes) + }(), + }, } for _, test := range tests {