fix integration, test more stuff
This commit is contained in:
parent
c50bfc1a7f
commit
7b8cdcfd7b
11 changed files with 147 additions and 51 deletions
|
@ -21,6 +21,16 @@ type AuthMiddleware struct {
|
||||||
superuserIDs []string
|
superuserIDs []string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func New(discordClient discord.IDiscordClient, supportIDs []string, superuserIDs []string) func(fiber.Ctx) error {
|
||||||
|
am := AuthMiddleware{
|
||||||
|
Client: discordClient,
|
||||||
|
supportIDs: supportIDs,
|
||||||
|
superuserIDs: superuserIDs,
|
||||||
|
}
|
||||||
|
|
||||||
|
return am.Handle
|
||||||
|
}
|
||||||
|
|
||||||
func (am *AuthMiddleware) Handle(c fiber.Ctx) error {
|
func (am *AuthMiddleware) Handle(c fiber.Ctx) error {
|
||||||
sc := session.FromContext(c)
|
sc := session.FromContext(c)
|
||||||
sess := am.Init(sc)
|
sess := am.Init(sc)
|
||||||
|
@ -52,16 +62,6 @@ func (am *AuthMiddleware) Commit(sc *session.Middleware, sess *Session) {
|
||||||
sc.Set(SessionKey, sess.AsJSON())
|
sc.Set(SessionKey, sess.AsJSON())
|
||||||
}
|
}
|
||||||
|
|
||||||
func SessionFrom(c fiber.Ctx) (s *Session) {
|
|
||||||
sess := session.FromContext(c)
|
|
||||||
sessionJSON := sess.Get(SessionKey).([]byte)
|
|
||||||
s, err := SessionFromJSON(sessionJSON)
|
|
||||||
if err != nil {
|
|
||||||
log.Panicln("session failed to parse", err)
|
|
||||||
}
|
|
||||||
return s
|
|
||||||
}
|
|
||||||
|
|
||||||
func (am *AuthMiddleware) isSupport(userID string) bool {
|
func (am *AuthMiddleware) isSupport(userID string) bool {
|
||||||
return slices.Contains(am.supportIDs, userID)
|
return slices.Contains(am.supportIDs, userID)
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,10 +4,15 @@ import (
|
||||||
"log"
|
"log"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"git.sapphic.engineer/roleypoly/v4/discord"
|
|
||||||
"git.sapphic.engineer/roleypoly/v4/types"
|
"git.sapphic.engineer/roleypoly/v4/types"
|
||||||
"github.com/goccy/go-json"
|
"github.com/goccy/go-json"
|
||||||
"github.com/gofiber/fiber/v3"
|
"github.com/gofiber/fiber/v3"
|
||||||
|
"github.com/gofiber/fiber/v3/middleware/session"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
SessionKey uint8
|
||||||
|
DefaultSession *Session = &Session{Permissions: PermAnonymous}
|
||||||
)
|
)
|
||||||
|
|
||||||
type Session struct {
|
type Session struct {
|
||||||
|
@ -32,16 +37,12 @@ func SessionFromJSON(input []byte) (*Session, error) {
|
||||||
return &s, err
|
return &s, err
|
||||||
}
|
}
|
||||||
|
|
||||||
var SessionKey uint8
|
func SessionFrom(c fiber.Ctx) (s *Session) {
|
||||||
|
sess := session.FromContext(c)
|
||||||
func New(discordClient discord.IDiscordClient, supportIDs []string, superuserIDs []string) func(fiber.Ctx) error {
|
sessionJSON := sess.Get(SessionKey).([]byte)
|
||||||
am := AuthMiddleware{
|
s, err := SessionFromJSON(sessionJSON)
|
||||||
Client: discordClient,
|
if err != nil {
|
||||||
supportIDs: supportIDs,
|
log.Panicln("session failed to parse", err)
|
||||||
superuserIDs: superuserIDs,
|
|
||||||
}
|
}
|
||||||
|
return s
|
||||||
return am.Handle
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var DefaultSession *Session = &Session{Permissions: PermAnonymous}
|
|
||||||
|
|
|
@ -9,6 +9,7 @@ import (
|
||||||
"git.sapphic.engineer/roleypoly/v4/authmiddleware"
|
"git.sapphic.engineer/roleypoly/v4/authmiddleware"
|
||||||
"git.sapphic.engineer/roleypoly/v4/discord"
|
"git.sapphic.engineer/roleypoly/v4/discord"
|
||||||
"git.sapphic.engineer/roleypoly/v4/discord/clientmock"
|
"git.sapphic.engineer/roleypoly/v4/discord/clientmock"
|
||||||
|
"git.sapphic.engineer/roleypoly/v4/roleypoly"
|
||||||
"git.sapphic.engineer/roleypoly/v4/types"
|
"git.sapphic.engineer/roleypoly/v4/types"
|
||||||
"github.com/goccy/go-json"
|
"github.com/goccy/go-json"
|
||||||
"github.com/gofiber/fiber/v3"
|
"github.com/gofiber/fiber/v3"
|
||||||
|
@ -102,7 +103,7 @@ func ok(c fiber.Ctx) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func getApp(dc discord.IDiscordClient) *fiber.App {
|
func getApp(dc discord.IDiscordClient) *fiber.App {
|
||||||
app := fiber.New(fiber.Config{})
|
app := roleypoly.CreateFiberApp()
|
||||||
sessionMiddleware, sessionStore := session.NewWithStore()
|
sessionMiddleware, sessionStore := session.NewWithStore()
|
||||||
sessionStore.RegisterType(authmiddleware.Session{})
|
sessionStore.RegisterType(authmiddleware.Session{})
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
pkgs ? import <nixpkgs> {},
|
pkgs ? import <nixpkgs> {},
|
||||||
vendorHash ? "sha256-TvGGu74AWLrWRQvfAesVGJFTp4omPGVmIgyzB3QUKnc=",
|
vendorHash ? "sha256-ilEuRNE61UN22Jm6Yyv80S6VdRa1mB6J/Pde1x/DgEk=",
|
||||||
}:
|
}:
|
||||||
rec {
|
rec {
|
||||||
default = roleypoly;
|
default = roleypoly;
|
||||||
|
|
|
@ -27,7 +27,6 @@ type Interactions struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewInteractions(publicKey string, publicBaseURL string, guildsService *discord.GuildService) *Interactions {
|
func NewInteractions(publicKey string, publicBaseURL string, guildsService *discord.GuildService) *Interactions {
|
||||||
|
|
||||||
return &Interactions{
|
return &Interactions{
|
||||||
PublicKey: ed25519.PublicKey(publicKey),
|
PublicKey: ed25519.PublicKey(publicKey),
|
||||||
PublicBaseURL: publicBaseURL,
|
PublicBaseURL: publicBaseURL,
|
||||||
|
@ -41,6 +40,7 @@ func (i *Interactions) Routes(r fiber.Router) {
|
||||||
r.Post("/", i.PostHandler)
|
r.Post("/", i.PostHandler)
|
||||||
|
|
||||||
i.Router.Add("hello-world", i.CmdHelloWorld)
|
i.Router.Add("hello-world", i.CmdHelloWorld)
|
||||||
|
i.Router.Add("roleypoly", i.CmdRoleypoly)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i *Interactions) PostHandler(c fiber.Ctx) error {
|
func (i *Interactions) PostHandler(c fiber.Ctx) error {
|
||||||
|
|
|
@ -7,11 +7,13 @@ import (
|
||||||
"net/http"
|
"net/http"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"git.sapphic.engineer/roleypoly/v4/authmiddleware"
|
||||||
"git.sapphic.engineer/roleypoly/v4/discord"
|
"git.sapphic.engineer/roleypoly/v4/discord"
|
||||||
"git.sapphic.engineer/roleypoly/v4/interactions"
|
"git.sapphic.engineer/roleypoly/v4/interactions"
|
||||||
"git.sapphic.engineer/roleypoly/v4/roleypoly"
|
"git.sapphic.engineer/roleypoly/v4/roleypoly"
|
||||||
"github.com/goccy/go-json"
|
"github.com/goccy/go-json"
|
||||||
"github.com/gofiber/fiber/v3"
|
"github.com/gofiber/fiber/v3"
|
||||||
|
"github.com/gofiber/fiber/v3/middleware/session"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -28,7 +30,37 @@ func TestNewInteractions(t *testing.T) {
|
||||||
|
|
||||||
func TestPostHandler(t *testing.T) {
|
func TestPostHandler(t *testing.T) {
|
||||||
i, _, key := makeInteractions(t)
|
i, _, key := makeInteractions(t)
|
||||||
app := fiber.New()
|
app := roleypoly.CreateFiberApp()
|
||||||
|
i.Routes(app)
|
||||||
|
|
||||||
|
body, err := json.Marshal(map[string]any{
|
||||||
|
"type": 1,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
sig, ts := sign(t, key, body)
|
||||||
|
|
||||||
|
req, _ := http.NewRequest("POST", "/", bytes.NewBuffer(body))
|
||||||
|
req.Header.Add("X-Signature-Ed25519", sig)
|
||||||
|
req.Header.Add("X-Signature-Timestamp", ts)
|
||||||
|
|
||||||
|
res, err := app.Test(req, fiber.TestConfig{})
|
||||||
|
|
||||||
|
assert.Nil(t, err)
|
||||||
|
assert.Equal(t, http.StatusOK, res.StatusCode)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestPostHandlerIntegration(t *testing.T) {
|
||||||
|
i, dsm, key := makeInteractions(t)
|
||||||
|
app := roleypoly.CreateFiberApp()
|
||||||
|
sessionMiddleware, sessionStore := session.NewWithStore()
|
||||||
|
sessionStore.RegisterType(authmiddleware.Session{})
|
||||||
|
app.Use(sessionMiddleware)
|
||||||
|
app.Use(authmiddleware.New(dsm, []string{}, []string{}))
|
||||||
|
|
||||||
i.Routes(app)
|
i.Routes(app)
|
||||||
|
|
||||||
body, err := json.Marshal(map[string]any{
|
body, err := json.Marshal(map[string]any{
|
||||||
|
@ -54,6 +86,7 @@ func TestPostHandler(t *testing.T) {
|
||||||
func TestPostHandlerSigFail(t *testing.T) {
|
func TestPostHandlerSigFail(t *testing.T) {
|
||||||
i, _, _ := makeInteractions(t)
|
i, _, _ := makeInteractions(t)
|
||||||
app := roleypoly.CreateFiberApp()
|
app := roleypoly.CreateFiberApp()
|
||||||
|
|
||||||
i.Routes(app)
|
i.Routes(app)
|
||||||
|
|
||||||
body, err := json.Marshal(map[string]any{
|
body, err := json.Marshal(map[string]any{
|
||||||
|
|
1
main.go
1
main.go
|
@ -17,6 +17,7 @@ func main() {
|
||||||
utils.DiscordBotToken,
|
utils.DiscordBotToken,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
roleypoly.SetupStatic(app)
|
||||||
roleypoly.SetupControllers(
|
roleypoly.SetupControllers(
|
||||||
app,
|
app,
|
||||||
dc,
|
dc,
|
||||||
|
|
|
@ -19,6 +19,7 @@ import (
|
||||||
staticfs "git.sapphic.engineer/roleypoly/v4/static"
|
staticfs "git.sapphic.engineer/roleypoly/v4/static"
|
||||||
"git.sapphic.engineer/roleypoly/v4/templates"
|
"git.sapphic.engineer/roleypoly/v4/templates"
|
||||||
"git.sapphic.engineer/roleypoly/v4/testing"
|
"git.sapphic.engineer/roleypoly/v4/testing"
|
||||||
|
"git.sapphic.engineer/roleypoly/v4/types"
|
||||||
)
|
)
|
||||||
|
|
||||||
func CreateFiberApp() *fiber.App {
|
func CreateFiberApp() *fiber.App {
|
||||||
|
@ -31,24 +32,6 @@ func CreateFiberApp() *fiber.App {
|
||||||
ViewsLayout: "layouts/main",
|
ViewsLayout: "layouts/main",
|
||||||
})
|
})
|
||||||
|
|
||||||
sessionMiddleware, sessionStore := session.NewWithStore()
|
|
||||||
sessionStore.RegisterType(authmiddleware.Session{})
|
|
||||||
|
|
||||||
app.Use(sessionMiddleware)
|
|
||||||
app.Use(csrf.New(csrf.Config{
|
|
||||||
Session: sessionStore,
|
|
||||||
}))
|
|
||||||
|
|
||||||
app.Get("/static*", static.New("", static.Config{
|
|
||||||
FS: staticfs.FS,
|
|
||||||
Compress: true,
|
|
||||||
CacheDuration: 24 * 8 * time.Hour,
|
|
||||||
}))
|
|
||||||
app.Get("/favicon.ico", oneStatic)
|
|
||||||
app.Get("/manifest.json", oneStatic)
|
|
||||||
app.Get("/robots.txt", oneStatic)
|
|
||||||
app.Get("/humans.txt", oneStatic)
|
|
||||||
|
|
||||||
return app
|
return app
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -63,16 +46,49 @@ func oneStatic(c fiber.Ctx) error {
|
||||||
return c.SendStream(f)
|
return c.SendStream(f)
|
||||||
}
|
}
|
||||||
|
|
||||||
func SetupControllers(app *fiber.App, dc *discord.DiscordClient, publicKey string, publicBaseURL string) {
|
func SetupStatic(app *fiber.App) {
|
||||||
gs := discord.NewGuildService(dc)
|
app.Get("/static*", static.New("", static.Config{
|
||||||
|
FS: staticfs.FS,
|
||||||
|
Compress: true,
|
||||||
|
CacheDuration: 24 * 8 * time.Hour,
|
||||||
|
}))
|
||||||
|
app.Get("/favicon.ico", oneStatic)
|
||||||
|
app.Get("/manifest.json", oneStatic)
|
||||||
|
app.Get("/robots.txt", oneStatic)
|
||||||
|
app.Get("/humans.txt", oneStatic)
|
||||||
|
}
|
||||||
|
|
||||||
(&testing.TestingController{
|
type ControllerConfig struct {
|
||||||
Guilds: gs,
|
DiscordClient discord.IDiscordClient
|
||||||
}).Routes(app.Group("/testing"))
|
PublicKey string
|
||||||
|
PublicBaseURL string
|
||||||
|
SupportIDs []string
|
||||||
|
SuperuserIDs []string
|
||||||
|
}
|
||||||
|
|
||||||
interactions.NewInteractions(publicKey, publicBaseURL, gs).Routes(app.Group("/interactions"))
|
func SetupControllers(app *fiber.App, cfg ControllerConfig) {
|
||||||
|
app.Use(func(c fiber.Ctx) error {
|
||||||
|
c.Locals(types.ConfigKey, cfg)
|
||||||
|
return c.Next()
|
||||||
|
})
|
||||||
|
|
||||||
|
sessionMiddleware, sessionStore := session.NewWithStore()
|
||||||
|
sessionStore.RegisterType(authmiddleware.Session{})
|
||||||
|
|
||||||
|
app.Use(sessionMiddleware)
|
||||||
|
app.Use(csrf.New(csrf.Config{
|
||||||
|
Session: sessionStore,
|
||||||
|
}))
|
||||||
|
app.Use(authmiddleware.New(cfg.DiscordClient, cfg.SupportIDs, cfg.SuperuserIDs))
|
||||||
|
|
||||||
|
gs := discord.NewGuildService(cfg.DiscordClient)
|
||||||
|
|
||||||
|
(&testing.TestingController{Guilds: gs}).
|
||||||
|
Routes(app.Group("/testing"))
|
||||||
|
|
||||||
|
interactions.NewInteractions(cfg.PublicKey, cfg.PublicBaseURL, gs).
|
||||||
|
Routes(app.Group("/interactions"))
|
||||||
|
|
||||||
app.Use(authmiddleware.New(dc, []string{}, []string{}))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// func getStorageDirectory() string {
|
// func getStorageDirectory() string {
|
||||||
|
|
40
roleypoly/fiber_test.go
Normal file
40
roleypoly/fiber_test.go
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
package roleypoly_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"net/http"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"git.sapphic.engineer/roleypoly/v4/roleypoly"
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestStaticRoot(t *testing.T) {
|
||||||
|
app := roleypoly.CreateFiberApp()
|
||||||
|
roleypoly.SetupStatic(app)
|
||||||
|
|
||||||
|
req, err := http.NewRequest("GET", "/humans.txt", nil)
|
||||||
|
assert.Nil(t, err)
|
||||||
|
|
||||||
|
resp, err := app.Test(req)
|
||||||
|
assert.Nil(t, err)
|
||||||
|
|
||||||
|
buf := bytes.Buffer{}
|
||||||
|
buf.ReadFrom(resp.Body)
|
||||||
|
assert.Equal(t, "you're on thin ice, soup head.", buf.String())
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestStaticPath(t *testing.T) {
|
||||||
|
app := roleypoly.CreateFiberApp()
|
||||||
|
roleypoly.SetupStatic(app)
|
||||||
|
|
||||||
|
req, err := http.NewRequest("GET", "/static/humans.txt", nil)
|
||||||
|
assert.Nil(t, err)
|
||||||
|
|
||||||
|
resp, err := app.Test(req)
|
||||||
|
assert.Nil(t, err)
|
||||||
|
|
||||||
|
buf := bytes.Buffer{}
|
||||||
|
buf.ReadFrom(resp.Body)
|
||||||
|
assert.Equal(t, "you're on thin ice, soup head.", buf.String())
|
||||||
|
}
|
1
static/humans.txt
Normal file
1
static/humans.txt
Normal file
|
@ -0,0 +1 @@
|
||||||
|
you're on thin ice, soup head.
|
3
types/keys.go
Normal file
3
types/keys.go
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
package types
|
||||||
|
|
||||||
|
var ConfigKey int
|
Loading…
Add table
Reference in a new issue