diff --git a/.github/workflows/deploy-golang-develop.yml b/.github/workflows/deploy-golang-develop.yml index 152484f1..91e977ad 100644 --- a/.github/workflows/deploy-golang-develop.yml +++ b/.github/workflows/deploy-golang-develop.yml @@ -54,6 +54,18 @@ jobs: uses: actions/setup-go@v5 with: go-version: '1.21' # Specify the Go version you are using + + - name: Decrypt env variables + run: | + echo "${{ secrets.GPG_PASSPHRASE }}" | gpg --quiet --batch --yes --decrypt --passphrase-fd 0 .env.gpg > .env + + - name: Decrypt key file + run: | + echo "${{ secrets.GPG_PASSPHRASE }}" | gpg --quiet --batch --yes --decrypt --passphrase-fd 0 key.pem.gpg > key.pem + + - name: Decrypt cert file + run: | + echo "${{ secrets.GPG_PASSPHRASE }}" | gpg --quiet --batch --yes --decrypt --passphrase-fd 0 cert.pem.gpg > cert.pem - name: Run tests run: | @@ -114,7 +126,6 @@ jobs: file: occupi-backend/Dockerfile.dev platforms: linux/amd64,linux/arm64 push: true - no-cache: true tags: ${{ secrets.DOCKER_USERNAME }}/occupi-backend:latest-develop deploy: diff --git a/.github/workflows/deploy-golang-prod.yml b/.github/workflows/deploy-golang-prod.yml index 578d3c91..d130de75 100644 --- a/.github/workflows/deploy-golang-prod.yml +++ b/.github/workflows/deploy-golang-prod.yml @@ -47,6 +47,18 @@ jobs: with: go-version: '1.21' # Specify the Go version you are using + - name: Decrypt env variables + run: | + echo "${{ secrets.GPG_PASSPHRASE }}" | gpg --quiet --batch --yes --decrypt --passphrase-fd 0 .env.gpg > .env + + - name: Decrypt key file + run: | + echo "${{ secrets.GPG_PASSPHRASE }}" | gpg --quiet --batch --yes --decrypt --passphrase-fd 0 key.pem.gpg > key.pem + + - name: Decrypt cert file + run: | + echo "${{ secrets.GPG_PASSPHRASE }}" | gpg --quiet --batch --yes --decrypt --passphrase-fd 0 cert.pem.gpg > cert.pem + - name: Run tests run: | go test -v -coverpkg=github.com/COS301-SE-2024/occupi/occupi-backend/pkg/utils,github.com/COS301-SE-2024/occupi/occupi-backend/pkg/handlers ./tests/... -coverprofile=coverage.out @@ -106,7 +118,6 @@ jobs: file: occupi-backend/Dockerfile.prod platforms: linux/amd64,linux/arm64 push: true - no-cache: true tags: ${{ secrets.DOCKER_USERNAME }}/occupi-backend:latest deploy: diff --git a/.github/workflows/lint-test-build-golang.yml b/.github/workflows/lint-test-build-golang.yml index 14594537..67fe6784 100644 --- a/.github/workflows/lint-test-build-golang.yml +++ b/.github/workflows/lint-test-build-golang.yml @@ -11,6 +11,17 @@ on: "occupi-backend/tests/**", ".github/workflows/lint-test-build-golang.yml" ] + + push: + branches: ["feat/actions/adding-env-variables-for-backend"] + paths: [ + "occupi-backend/cmd/**", + "occupi-backend/configs/**", + "occupi-backend/pkg/**", + "occupi-backend/.golangci.yml", + "occupi-backend/tests/**", + ".github/workflows/lint-test-build-golang.yml" + ] workflow_dispatch: @@ -52,6 +63,18 @@ jobs: uses: actions/setup-go@v5 with: go-version: '1.21' # Specify the Go version you are using + + - name: Decrypt env variables + run: | + echo "${{ secrets.GPG_PASSPHRASE }}" | gpg --quiet --batch --yes --decrypt --passphrase-fd 0 .env.gpg > .env + + - name: Decrypt key file + run: | + echo "${{ secrets.GPG_PASSPHRASE }}" | gpg --quiet --batch --yes --decrypt --passphrase-fd 0 key.pem.gpg > key.pem + + - name: Decrypt cert file + run: | + echo "${{ secrets.GPG_PASSPHRASE }}" | gpg --quiet --batch --yes --decrypt --passphrase-fd 0 cert.pem.gpg > cert.pem - name: Run tests run: | diff --git a/occupi-backend/.env.gpg b/occupi-backend/.env.gpg new file mode 100644 index 00000000..7dd85a2c Binary files /dev/null and b/occupi-backend/.env.gpg differ diff --git a/occupi-backend/cert.pem.gpg b/occupi-backend/cert.pem.gpg new file mode 100644 index 00000000..368c1b83 Binary files /dev/null and b/occupi-backend/cert.pem.gpg differ diff --git a/occupi-backend/cmd/occupi-backend/main.go b/occupi-backend/cmd/occupi-backend/main.go index 7e4ddff9..a154db55 100644 --- a/occupi-backend/cmd/occupi-backend/main.go +++ b/occupi-backend/cmd/occupi-backend/main.go @@ -61,7 +61,7 @@ func main() { logrus.Infof("Server running with key file: %s", keyFile) // Listening on the port with TLS - if err := ginRouter.Run(":"+configs.GetPort()); err != nil { + if err := ginRouter.RunTLS(":"+configs.GetPort(), certFile, keyFile); err != nil { logrus.Fatal("Failed to run server: ", err) } } diff --git a/occupi-backend/key.pem.gpg b/occupi-backend/key.pem.gpg new file mode 100644 index 00000000..60947e2d Binary files /dev/null and b/occupi-backend/key.pem.gpg differ diff --git a/occupi-backend/tests/handlers_test.go b/occupi-backend/tests/handlers_test.go index bd280595..6423e529 100644 --- a/occupi-backend/tests/handlers_test.go +++ b/occupi-backend/tests/handlers_test.go @@ -2,17 +2,23 @@ package tests import ( "encoding/json" + "fmt" "net/http" "net/http/httptest" "sync" "testing" "time" + "github.com/joho/godotenv" "github.com/stretchr/testify/assert" "github.com/gin-gonic/gin" + "github.com/COS301-SE-2024/occupi/occupi-backend/configs" + "github.com/COS301-SE-2024/occupi/occupi-backend/pkg/database" "github.com/COS301-SE-2024/occupi/occupi-backend/pkg/middleware" + "github.com/COS301-SE-2024/occupi/occupi-backend/pkg/router" + "github.com/COS301-SE-2024/occupi/occupi-backend/pkg/utils" // "github.com/joho/godotenv" // "github.com/stretchr/testify/assert" // "github.com/stretchr/testify/mock" @@ -141,13 +147,28 @@ func TestVerifyOTP_EmailNotRegistered(t *testing.T) { }*/ func TestPingRoute(t *testing.T) { - // Create a new Gin router - r := gin.Default() + // Load environment variables from .env file + if err := godotenv.Load("../.env"); err != nil { + t.Fatal(fmt.Printf("Error loading .env file with error as %s", err)) + } - // Register the route - r.GET("/ping", func(c *gin.Context) { - c.JSON(http.StatusOK, gin.H{"message": "pong -> I am alive and kicking"}) - }) + // setup logger to log all server interactions + utils.SetupLogger() + + // connect to the database + db := database.ConnectToDatabase() + + // set gin run mode + gin.SetMode(configs.GetGinRunMode()) + + // Create a Gin router + ginRouter := gin.Default() + + // adding rate limiting middleware + middleware.AttachRateLimitMiddleware(ginRouter) + + // Register routes + router.OccupiRouter(ginRouter, db) // Create a request to pass to the handler req, err := http.NewRequest("GET", "/ping", nil) @@ -159,7 +180,7 @@ func TestPingRoute(t *testing.T) { rr := httptest.NewRecorder() // Serve the request - r.ServeHTTP(rr, req) + ginRouter.ServeHTTP(rr, req) // Check the status code is what we expect. if status := rr.Code; status != http.StatusOK { @@ -183,18 +204,30 @@ func TestPingRoute(t *testing.T) { } func TestRateLimit(t *testing.T) { - // Create a new Gin router - router := gin.Default() + // Load environment variables from .env file + if err := godotenv.Load("../.env"); err != nil { + t.Fatal(fmt.Printf("Error loading .env file with error as %s", err)) + } - // attach rate limit middleware - middleware.AttachRateLimitMiddleware(router) + // setup logger to log all server interactions + utils.SetupLogger() - // Register the route - router.GET("/ping", func(c *gin.Context) { - c.JSON(http.StatusOK, gin.H{"message": "pong -> I am alive and kicking"}) - }) + // connect to the database + db := database.ConnectToDatabase() - server := httptest.NewServer(router) + // set gin run mode + gin.SetMode(configs.GetGinRunMode()) + + // Create a Gin router + ginRouter := gin.Default() + + // adding rate limiting middleware + middleware.AttachRateLimitMiddleware(ginRouter) + + // Register routes + router.OccupiRouter(ginRouter, db) + + server := httptest.NewServer(ginRouter) defer server.Close() var wg sync.WaitGroup @@ -230,18 +263,30 @@ func TestRateLimit(t *testing.T) { } func TestRateLimitWithMultipleIPs(t *testing.T) { - // Create a new Gin router - router := gin.Default() + // Load environment variables from .env file + if err := godotenv.Load("../.env"); err != nil { + t.Fatal(fmt.Printf("Error loading .env file with error as %s", err)) + } - // attach rate limit middleware - middleware.AttachRateLimitMiddleware(router) + // setup logger to log all server interactions + utils.SetupLogger() - // Register the route - router.GET("/ping", func(c *gin.Context) { - c.JSON(http.StatusOK, gin.H{"message": "pong -> I am alive and kicking"}) - }) + // connect to the database + db := database.ConnectToDatabase() - server := httptest.NewServer(router) + // set gin run mode + gin.SetMode(configs.GetGinRunMode()) + + // Create a Gin router + ginRouter := gin.Default() + + // adding rate limiting middleware + middleware.AttachRateLimitMiddleware(ginRouter) + + // Register routes + router.OccupiRouter(ginRouter, db) + + server := httptest.NewServer(ginRouter) defer server.Close() var wg sync.WaitGroup @@ -320,26 +365,26 @@ func TestRateLimitWithMultipleIPs(t *testing.T) { assert.Equal(t, rateLimitedCountIP2, 0, "There should be no requests from IP2 that are rate limited") } -/* func TestGetResource(t *testing.T) { // Load environment variables from .env file if err := godotenv.Load("../.env"); err != nil { t.Fatal("Error loading .env file: ", err) } - // Connect to the database + // setup logger to log all server interactions + utils.SetupLogger() + + // connect to the database db := database.ConnectToDatabase() + // set gin run mode + gin.SetMode(configs.GetGinRunMode()) + // Create a Gin router r := gin.Default() - // create a new valid session for management of shared variables - appsession := models.New(nil, db) - // Register the route - r.GET("/api/resource", func(c *gin.Context) { - handlers.FetchResource(c, appsession) - }) + router.OccupiRouter(r, db) // Create a request to pass to the handler req, err := http.NewRequest("GET", "/api/resource", nil) @@ -354,8 +399,7 @@ func TestGetResource(t *testing.T) { r.ServeHTTP(rr, req) // Check the status code is what we expect. - if status := rr.Code; status != http.StatusOK { - t.Errorf("handler returned wrong status code: got %v want %v", status, http.StatusOK) + if status := rr.Code; status != http.StatusNotFound { + t.Errorf("handler returned wrong status code: got %v want %v", status, http.StatusNotFound) } } -*/