diff --git a/go.mod b/go.mod index cea16dd..c4855ff 100644 --- a/go.mod +++ b/go.mod @@ -5,6 +5,7 @@ go 1.23.2 require ( github.com/cenkalti/backoff/v5 v5.0.3 github.com/gin-gonic/gin v1.10.1 + github.com/glebarez/sqlite v1.11.0 github.com/go-playground/validator/v10 v10.27.0 github.com/golang-migrate/migrate/v4 v4.18.3 github.com/google/go-querystring v1.1.0 @@ -15,9 +16,9 @@ require ( github.com/spf13/viper v1.20.1 github.com/traefik/paerser v0.2.2 golang.org/x/crypto v0.41.0 - gorm.io/driver/sqlite v1.6.0 + golang.org/x/exp v0.0.0-20250620022241-b7579e27df2b gorm.io/gorm v1.30.1 - modernc.org/sqlite v1.38.2 + gotest.tools/v3 v3.5.2 ) require ( @@ -28,9 +29,9 @@ require ( github.com/containerd/errdefs/pkg v0.3.0 // indirect github.com/containerd/log v0.1.0 // indirect github.com/glebarez/go-sqlite v1.21.2 // indirect - github.com/glebarez/sqlite v1.11.0 // indirect github.com/go-asn1-ber/asn1-ber v1.5.8-0.20250403174932-29230038a667 // indirect github.com/go-viper/mapstructure/v2 v2.4.0 // indirect + github.com/google/go-cmp v0.6.0 // indirect github.com/hashicorp/errwrap v1.1.0 // indirect github.com/hashicorp/go-multierror v1.1.1 // indirect github.com/jinzhu/inflection v1.0.0 // indirect @@ -44,12 +45,11 @@ require ( go.opentelemetry.io/auto/sdk v1.1.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.34.0 // indirect go.opentelemetry.io/otel/sdk v1.34.0 // indirect - golang.org/x/exp v0.0.0-20250620022241-b7579e27df2b // indirect golang.org/x/term v0.34.0 // indirect - gotest.tools/v3 v3.5.2 // indirect modernc.org/libc v1.66.3 // indirect modernc.org/mathutil v1.7.1 // indirect modernc.org/memory v1.11.0 // indirect + modernc.org/sqlite v1.38.2 // indirect rsc.io/qr v0.2.0 // indirect ) @@ -86,8 +86,6 @@ require ( github.com/go-playground/universal-translator v0.18.1 // indirect github.com/goccy/go-json v0.10.4 // indirect github.com/gogo/protobuf v1.3.2 // indirect - github.com/gorilla/securecookie v1.1.2 // indirect - github.com/gorilla/sessions v1.4.0 github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/json-iterator/go v1.1.12 // indirect github.com/klauspost/cpuid/v2 v2.2.9 // indirect diff --git a/go.sum b/go.sum index 0b0aceb..6e7d9c7 100644 --- a/go.sum +++ b/go.sum @@ -132,16 +132,10 @@ github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeN github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8= github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= -github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= -github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/pprof v0.0.0-20250317173921-a4b03ec1a45e h1:ijClszYn+mADRFY17kjQEVQ1XRhq2/JR1M3sGqeJoxs= github.com/google/pprof v0.0.0-20250317173921-a4b03ec1a45e/go.mod h1:boTsfXsheKC2y+lKOCMpSfarhxDeIzfZG1jqGcPl3cA= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/gorilla/securecookie v1.1.2 h1:YCIWL56dvtr73r6715mJs5ZvhtnY73hBvEF8kXD8ePA= -github.com/gorilla/securecookie v1.1.2/go.mod h1:NfCASbcHqRSY+3a8tlWJwsQap2VX5pwzwo4h3eOamfo= -github.com/gorilla/sessions v1.4.0 h1:kpIYOp/oi6MG/p5PgxApU8srsSw9tuFbt46Lt7auzqQ= -github.com/gorilla/sessions v1.4.0/go.mod h1:FLWm50oby91+hl7p/wRxDth9bWSuk0qVL2emc7lT5ik= github.com/grpc-ecosystem/grpc-gateway/v2 v2.25.1 h1:VNqngBF40hVlDloBruUehVYC3ArSgIyScOAyMRqBxRg= github.com/grpc-ecosystem/grpc-gateway/v2 v2.25.1/go.mod h1:RBRO7fro65R6tjKzYgLAFo0t1QEXY1Dp+i/bvpRiqiQ= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= @@ -380,8 +374,6 @@ gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EV gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gorm.io/driver/sqlite v1.6.0 h1:WHRRrIiulaPiPFmDcod6prc4l2VGVWHz80KspNsxSfQ= -gorm.io/driver/sqlite v1.6.0/go.mod h1:AO9V1qIQddBESngQUKWL9yoH93HIeA1X6V633rBwyT8= gorm.io/gorm v1.30.1 h1:lSHg33jJTBxs2mgJRfRZeLDG+WZaHYCk3Wtfl6Ngzo4= gorm.io/gorm v1.30.1/go.mod h1:8Z33v652h4//uMA76KjeDH8mJXPm1QNCYrMeatR0DOE= gotest.tools/v3 v3.5.2 h1:7koQfIKdy+I8UTetycgUqXWSDwpgv193Ka+qRsmBY8Q= diff --git a/internal/controller/context_controller_test.go b/internal/controller/context_controller_test.go new file mode 100644 index 0000000..ecfdf51 --- /dev/null +++ b/internal/controller/context_controller_test.go @@ -0,0 +1,116 @@ +package controller_test + +import ( + "encoding/json" + "net/http/httptest" + "testing" + "tinyauth/internal/config" + "tinyauth/internal/controller" + + "github.com/gin-gonic/gin" + "gotest.tools/v3/assert" +) + +func TestAppContextHandler(t *testing.T) { + // Setup + controllerCfg := controller.ContextControllerConfig{ + ConfiguredProviders: []string{"github", "google", "generic"}, + Title: "Test App", + GenericName: "Generic", + AppURL: "http://localhost:8080", + RootDomain: "localhost", + ForgotPasswordMessage: "Contact admin to reset your password.", + BackgroundImage: "/assets/bg.jpg", + OAuthAutoRedirect: "google", + } + + expectedRes := controller.AppContextResponse{ + Status: 200, + Message: "Success", + ConfiguredProviders: controllerCfg.ConfiguredProviders, + Title: controllerCfg.Title, + GenericName: controllerCfg.GenericName, + AppURL: controllerCfg.AppURL, + RootDomain: controllerCfg.RootDomain, + ForgotPasswordMessage: controllerCfg.ForgotPasswordMessage, + BackgroundImage: controllerCfg.BackgroundImage, + OAuthAutoRedirect: controllerCfg.OAuthAutoRedirect, + } + + gin.SetMode(gin.TestMode) + router := gin.Default() + group := router.Group("/api") + recorder := httptest.NewRecorder() + + // Test + ctrl := controller.NewContextController(controllerCfg, group) + ctrl.SetupRoutes() + + req := httptest.NewRequest("GET", "/api/context/app", nil) + router.ServeHTTP(recorder, req) + + assert.Equal(t, 200, recorder.Code) + + var ctrlRes controller.AppContextResponse + + err := json.Unmarshal(recorder.Body.Bytes(), &ctrlRes) + + assert.NilError(t, err) + assert.DeepEqual(t, expectedRes, ctrlRes) +} + +func TestUserContextController(t *testing.T) { + // Setup + controllerCfg := controller.ContextControllerConfig{} + + userContext := config.UserContext{ + Username: "testuser", + Name: "testuser", + Email: "test@example.com", + IsLoggedIn: true, + OAuth: false, + Provider: "username", + TotpPending: false, + OAuthGroups: "", + TotpEnabled: false, + } + + expectedRes := controller.UserContextResponse{ + Status: 200, + Message: "Success", + IsLoggedIn: userContext.IsLoggedIn, + Username: userContext.Username, + Name: userContext.Name, + Email: userContext.Email, + Provider: userContext.Provider, + OAuth: userContext.OAuth, + TotpPending: userContext.TotpPending, + } + + gin.SetMode(gin.TestMode) + router := gin.Default() + recorder := httptest.NewRecorder() + + router.Use(func(c *gin.Context) { + c.Set("context", &userContext) + c.Next() + }) + + group := router.Group("/api") + + // Test + ctrl := controller.NewContextController(controllerCfg, group) + ctrl.SetupRoutes() + + req := httptest.NewRequest("GET", "/api/context/user", nil) + router.ServeHTTP(recorder, req) + + assert.Equal(t, 200, recorder.Code) + + var ctrlRes controller.UserContextResponse + + err := json.Unmarshal(recorder.Body.Bytes(), &ctrlRes) + + assert.NilError(t, err) + assert.DeepEqual(t, expectedRes, ctrlRes) +}