package authmiddleware_test import ( "bytes" "encoding/json" "errors" "net/http" "testing" "git.sapphic.engineer/roleypoly/v4/auth/authmiddleware" "git.sapphic.engineer/roleypoly/v4/discord" "git.sapphic.engineer/roleypoly/v4/discord/clientmock" "git.sapphic.engineer/roleypoly/v4/roleypoly" "git.sapphic.engineer/roleypoly/v4/types" "github.com/gofiber/fiber/v3" "github.com/gofiber/fiber/v3/middleware/session" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" ) func mockUser(dc *clientmock.DiscordClientMock, user *types.DiscordUser) { if user == nil { dc.MockResponse("GET", "/users/@me", http.StatusUnauthorized, "unauthorized").Once() } dc.MockResponse("GET", "/users/@me", 200, user).Once() } func setSession(app *fiber.App, dc *clientmock.DiscordClientMock, sess authmiddleware.Session, inputCookie *http.Cookie) (*http.Cookie, error) { dc.On("ClientAuth", mock.AnythingOfType("*http.Request"), "access-token") body := bytes.Buffer{} json.NewEncoder(&body).Encode(sess) req, _ := http.NewRequest("POST", "/updateSession", &body) if inputCookie != nil { req.AddCookie(inputCookie) } resp, err := app.Test(req) if err != nil { return nil, err } cookie := resp.Cookies()[0] return cookie, err } func authState(c fiber.Ctx) error { s := authmiddleware.SessionFrom(c) permList := []string{} if s.Permissions >= authmiddleware.PermAnonymous { permList = append(permList, "anonymous") } if s.Permissions >= authmiddleware.PermUser { permList = append(permList, "user") } if s.Permissions >= authmiddleware.PermSupport { permList = append(permList, "support") } if s.Permissions >= authmiddleware.PermSuperuser { permList = append(permList, "superuser") } return c.JSON(permList) } func updateSession(c fiber.Ctx) error { var newSession *authmiddleware.Session c.Bind().JSON(&newSession) sc := session.FromContext(c) sc.Set(authmiddleware.SessionKey, newSession.AsJSON()) return c.SendString("ok") } var errUnauthorized = errors.New("unauthorized") func get(t *testing.T, app *fiber.App, cookie *http.Cookie, path string) error { req, err := http.NewRequest("GET", path, nil) req.AddCookie(cookie) assert.Nil(t, err) resp, err := app.Test(req) assert.Nil(t, err) if resp.StatusCode == http.StatusForbidden { return errUnauthorized } return nil } func ok(c fiber.Ctx) error { return c.SendString("ok") } func getApp(dc discord.IDiscordClient) *fiber.App { app := roleypoly.CreateFiberApp() sessionMiddleware, sessionStore := session.NewWithStore() sessionStore.RegisterType(authmiddleware.Session{}) app.Use(sessionMiddleware, authmiddleware.New(dc, []string{"support-user"}, []string{"superuser-user"})) app.Get("/", authState) app.Post("/updateSession", updateSession) app.Get("/must/user", ok, authmiddleware.MustHavePermission(authmiddleware.PermUser)) app.Get("/must/support", ok, authmiddleware.MustHavePermission(authmiddleware.PermSupport)) app.Get("/must/superuser", ok, authmiddleware.MustHavePermission(authmiddleware.PermSuperuser)) return app }