github.com/soulteary/pocket-bookcase@v0.0.0-20240428065142-0b5a9a0fc98a/internal/http/middleware/auth_test.go (about)

     1  package middleware
     2  
     3  import (
     4  	"context"
     5  	"net/http"
     6  	"net/http/httptest"
     7  	"testing"
     8  	"time"
     9  
    10  	"github.com/gin-gonic/gin"
    11  	"github.com/sirupsen/logrus"
    12  	"github.com/soulteary/pocket-bookcase/internal/http/response"
    13  	"github.com/soulteary/pocket-bookcase/internal/model"
    14  	"github.com/soulteary/pocket-bookcase/internal/testutil"
    15  	"github.com/stretchr/testify/require"
    16  )
    17  
    18  func TestAuthenticationRequiredMiddleware(t *testing.T) {
    19  	t.Run("test unauthorized", func(t *testing.T) {
    20  		g := testutil.NewGin()
    21  		g.Use(AuthenticationRequired())
    22  		g.Handle("GET", "/", func(c *gin.Context) {
    23  			response.Send(c, http.StatusOK, nil)
    24  		})
    25  		w := testutil.PerformRequest(g, "GET", "/")
    26  		require.Equal(t, http.StatusUnauthorized, w.Code)
    27  		// This ensures we are aborting the request and not sending more data
    28  		require.Equal(t, `{"ok":false,"message":null}`, w.Body.String())
    29  	})
    30  
    31  	t.Run("test authorized", func(t *testing.T) {
    32  		g := testutil.NewGin()
    33  		// Fake a logged in user in the context, which is the way the AuthMiddleware works.
    34  		g.Use(func(ctx *gin.Context) {
    35  			ctx.Set(model.ContextAccountKey, "test")
    36  		})
    37  		g.Use(AuthenticationRequired())
    38  		g.GET("/", func(c *gin.Context) {
    39  			c.Status(http.StatusOK)
    40  		})
    41  		w := testutil.PerformRequest(g, "GET", "/")
    42  		require.Equal(t, http.StatusOK, w.Code)
    43  	})
    44  }
    45  
    46  func TestAuthMiddleware(t *testing.T) {
    47  	ctx := context.TODO()
    48  	logger := logrus.New()
    49  	_, deps := testutil.GetTestConfigurationAndDependencies(t, ctx, logger)
    50  	middleware := AuthMiddleware(deps)
    51  
    52  	t.Run("test no authorization method", func(t *testing.T) {
    53  		w := httptest.NewRecorder()
    54  		c, router := gin.CreateTestContext(w)
    55  		req := httptest.NewRequest(http.MethodGet, "/", nil)
    56  		router.Use(middleware)
    57  		router.ServeHTTP(w, req)
    58  
    59  		_, exists := c.Get("account")
    60  		require.False(t, exists)
    61  	})
    62  
    63  	t.Run("test authorization header", func(t *testing.T) {
    64  		account := model.Account{Username: "shiori"}
    65  		token, err := deps.Domains.Auth.CreateTokenForAccount(&account, time.Now().Add(time.Minute))
    66  		require.NoError(t, err)
    67  		w := httptest.NewRecorder()
    68  		c, _ := gin.CreateTestContext(w)
    69  		c.Request, _ = http.NewRequest("GET", "/", nil)
    70  		c.Request.Header.Set(model.AuthorizationHeader, model.AuthorizationTokenType+" "+token)
    71  		middleware(c)
    72  		_, exists := c.Get(model.ContextAccountKey)
    73  		require.True(t, exists)
    74  	})
    75  
    76  	t.Run("test authorization cookie", func(t *testing.T) {
    77  		account := model.Account{Username: "shiori"}
    78  		token, err := deps.Domains.Auth.CreateTokenForAccount(&account, time.Now().Add(time.Minute))
    79  		require.NoError(t, err)
    80  		w := httptest.NewRecorder()
    81  		c, _ := gin.CreateTestContext(w)
    82  		c.Request, _ = http.NewRequest("GET", "/", nil)
    83  		c.Request.AddCookie(&http.Cookie{
    84  			Name:   "token",
    85  			Value:  token,
    86  			MaxAge: int(time.Now().Add(time.Minute).Unix()),
    87  		})
    88  		middleware(c)
    89  		_, exists := c.Get(model.ContextAccountKey)
    90  		require.True(t, exists)
    91  	})
    92  }