style: code maid is here!

refactored the project significantly to reduce the single-file monolith
This commit is contained in:
Lewis Crichton
2023-08-07 21:52:57 +01:00
parent 476c0b4994
commit c85af2641b
7 changed files with 322 additions and 248 deletions
+115
View File
@@ -0,0 +1,115 @@
package routes
import (
"crypto/rand"
"encoding/hex"
"github.com/gofiber/fiber/v2"
"github.com/imroc/req/v3"
"github.com/redis/go-redis/v9"
g "github.com/vencord/backend/globals"
"github.com/vencord/backend/util"
)
// /v1/oauth
type DiscordAccessTokenResult struct {
AccessToken string `json:"access_token"`
}
type DiscordUserResult struct {
Id string `json:"id"`
}
// /v1/oauth/callback
func GETOAuthCallback(c *fiber.Ctx) error {
code := c.Query("code")
if code == "" {
return c.Status(400).JSON(&fiber.Map{
"error": "Missing code",
})
}
var accessTokenResult DiscordAccessTokenResult
res, err := req.R().SetFormData(map[string]string{
"client_id": g.DISCORD_CLIENT_ID,
"client_secret": g.DISCORD_CLIENT_SECRET,
"grant_type": "authorization_code",
"code": code,
"redirect_uri": g.DISCORD_REDIRECT_URI,
"scope": "identify",
}).SetSuccessResult(&accessTokenResult).Post("https://discord.com/api/oauth2/token")
if err != nil {
return c.Status(500).JSON(&fiber.Map{
"error": "Failed to request access token",
})
}
if res.IsErrorState() {
return c.Status(400).JSON(&fiber.Map{
"error": "Invalid code",
})
}
accessToken := accessTokenResult.AccessToken
var userResult DiscordUserResult
res, err = req.R().SetHeaders(map[string]string{
"Authorization": "Bearer " + accessToken,
}).SetSuccessResult(&userResult).Get("https://discord.com/api/users/@me")
if err != nil {
return c.Status(500).JSON(&fiber.Map{
"error": "Failed to request user",
})
}
if res.IsErrorState() {
return c.Status(500).JSON(&fiber.Map{
"error": "Failed to request user",
})
}
userId := userResult.Id
if g.ALLOWED_USERS != nil && !g.ALLOWED_USERS[userId] {
return c.Status(403).JSON(&fiber.Map{
"error": "User is not whitelisted",
})
}
secret, err := g.RDB.Get(c.Context(), "secrets:"+util.Hash(g.PEPPER_SECRETS+userId)).Result()
if err == redis.Nil {
key := make([]byte, 48)
_, err := rand.Read(key)
if err != nil {
return c.Status(500).JSON(&fiber.Map{
"error": "Failed to generate secret",
})
}
secret = hex.EncodeToString(key)
g.RDB.Set(c.Context(), "secrets:"+util.Hash(g.PEPPER_SECRETS+userId), secret, 0)
} else if err != nil {
panic(err)
}
return c.JSON(&fiber.Map{
"secret": secret,
})
}
// /v1/oauth/settings
func GETOAuthSettings(c *fiber.Ctx) error {
return c.JSON(&fiber.Map{
"clientId": g.DISCORD_CLIENT_ID,
"redirectUri": g.DISCORD_REDIRECT_URI,
})
}
+25
View File
@@ -0,0 +1,25 @@
package routes
import (
"github.com/gofiber/fiber/v2"
g "github.com/vencord/backend/globals"
"github.com/vencord/backend/util"
)
// /v1
func DELETE(c *fiber.Ctx) error {
userId := c.Context().UserValue("userId").(string)
g.RDB.Del(c.Context(), "settings:"+util.Hash(g.PEPPER_SETTINGS+userId))
g.RDB.Del(c.Context(), "secrets:"+util.Hash(g.PEPPER_SECRETS+userId))
return c.SendStatus(204)
}
func GET(c *fiber.Ctx) error {
return c.JSON(&fiber.Map{
"ping": "pong",
})
}
+93
View File
@@ -0,0 +1,93 @@
package routes
import (
"time"
"github.com/gofiber/fiber/v2"
"github.com/redis/go-redis/v9"
g "github.com/vencord/backend/globals"
"github.com/vencord/backend/util"
)
// /v1/settings
func HEADSettings(c *fiber.Ctx) error {
userId := c.Context().UserValue("userId").(string)
written, err := g.RDB.HGet(c.Context(), "settings:"+util.Hash(g.PEPPER_SETTINGS+userId), "written").Result()
if err == redis.Nil {
return c.Status(404).Send(nil)
} else if err != nil {
panic(err)
}
c.Set("ETag", written)
return c.SendStatus(204)
}
func GETSettings(c *fiber.Ctx) error {
userId := c.Context().UserValue("userId").(string)
settings, err := g.RDB.HMGet(c.Context(), "settings:"+util.Hash(g.PEPPER_SETTINGS+userId), "value", "written").Result()
// we shouldn't expect an error here, HMGet doesn't return one
if err != nil {
panic(err)
}
if settings[0] == nil {
return c.Status(404).Send(nil)
}
// value is compressed data, written is a timestamp
value, written := []byte(settings[0].(string)), settings[1].(string)
if ifm := c.Get("if-none-match"); ifm == written {
return c.SendStatus(304)
}
c.Set("Content-Type", "application/octet-stream")
c.Set("ETag", written)
return c.Send(value)
}
func PUTSettings(c *fiber.Ctx) error {
if c.Get("Content-Type") != "application/octet-stream" {
return c.Status(415).JSON(&fiber.Map{
"error": "Content type must be application/octet-stream",
})
}
if len(c.Body()) > g.SIZE_LIMIT {
return c.Status(413).JSON(&fiber.Map{
"error": "Settings are too large",
})
}
userId := c.Context().UserValue("userId").(string)
now := time.Now().UnixMilli()
_, err := g.RDB.HSet(c.Context(), "settings:"+util.Hash(g.PEPPER_SETTINGS+userId), map[string]interface{}{
"value": c.Body(),
"written": now,
}).Result()
if err != nil {
panic(err)
}
return c.JSON(&fiber.Map{
"written": now,
})
}
func DELETESettings(c *fiber.Ctx) error {
userId := c.Context().UserValue("userId").(string)
g.RDB.Del(c.Context(), "settings:"+util.Hash(g.PEPPER_SETTINGS+userId))
return c.SendStatus(204)
}