Start Discord Auth
This commit is contained in:
parent
98a30263a6
commit
0dc1423b9d
|
@ -13,6 +13,11 @@ type CS struct {
|
|||
Type string
|
||||
DropAllTables bool
|
||||
}
|
||||
Discord struct {
|
||||
ID string
|
||||
Secret string
|
||||
Token string
|
||||
}
|
||||
Output struct {
|
||||
Level string
|
||||
}
|
||||
|
@ -61,6 +66,21 @@ func LoadConfig(file []byte) {
|
|||
panic("Output Level must be either dev or prod")
|
||||
}
|
||||
|
||||
Config.Discord.ID = cfg.Section("discord").Key("id").String()
|
||||
if Config.Discord.ID == "" {
|
||||
panic("Discord Client ID is empty")
|
||||
}
|
||||
|
||||
Config.Discord.Secret = cfg.Section("discord").Key("secret").String()
|
||||
if Config.Discord.Secret == "" {
|
||||
panic("Discord Client Secret is empty")
|
||||
}
|
||||
|
||||
Config.Discord.Token = cfg.Section("discord").Key("token").String()
|
||||
if Config.Discord.Token == "" {
|
||||
panic("Discord Bot Token is empty")
|
||||
}
|
||||
|
||||
Config.API.Host = cfg.Section("api").Key("host").String()
|
||||
if Config.API.Host == "" {
|
||||
panic("API Host is empty")
|
||||
|
|
|
@ -6,6 +6,14 @@ type="postgres"
|
|||
; drop all tables at start of program
|
||||
drop=false
|
||||
|
||||
[discord]
|
||||
; discord oauth2 client id
|
||||
id="1234567890..."
|
||||
; discord oauth2 client secret
|
||||
secret="abcdefg..."
|
||||
; discord bot token
|
||||
token="OTK...."
|
||||
|
||||
[output]
|
||||
; level of logging
|
||||
; info = everything
|
||||
|
@ -19,7 +27,7 @@ port=":3000"
|
|||
; host that the api is running on
|
||||
; e.g. if you are running the api on your local machine, you would set this to 127.0.0.1
|
||||
; if you are running the api on a server, you would set this to the ip of the server or the domain name
|
||||
host="127.0.0.1"
|
||||
host="http://127.0.0.1"
|
||||
|
||||
[jwt]
|
||||
; secret for jwt signing
|
||||
|
|
|
@ -10,20 +10,20 @@ import (
|
|||
)
|
||||
|
||||
var (
|
||||
oauthTokenGrantTypes = map[string]func(c *fiber.Ctx, body *OAuthTokenBody) error{
|
||||
"client_credentials": PostOAuthTokenClientCredentials,
|
||||
"password": PostOAuthTokenPassword,
|
||||
oauthTokenGrantTypes = map[string]func(c *fiber.Ctx, body *FortniteTokenBody) error{
|
||||
"client_credentials": PostTokenClientCredentials,
|
||||
"password": PostTokenPassword,
|
||||
}
|
||||
)
|
||||
|
||||
type OAuthTokenBody struct {
|
||||
type FortniteTokenBody struct {
|
||||
GrantType string `form:"grant_type" binding:"required"`
|
||||
Username string `form:"username"`
|
||||
Password string `form:"password"`
|
||||
}
|
||||
|
||||
func PostOAuthToken(c *fiber.Ctx) error {
|
||||
var body OAuthTokenBody
|
||||
func PostFortniteToken(c *fiber.Ctx) error {
|
||||
var body FortniteTokenBody
|
||||
|
||||
if err := c.BodyParser(&body); err != nil {
|
||||
return c.Status(fiber.StatusBadRequest).JSON(aid.ErrorBadRequest("Invalid Request Body"))
|
||||
|
@ -36,7 +36,7 @@ func PostOAuthToken(c *fiber.Ctx) error {
|
|||
return c.Status(fiber.StatusBadRequest).JSON(aid.ErrorBadRequest("Invalid Grant Type"))
|
||||
}
|
||||
|
||||
func PostOAuthTokenClientCredentials(c *fiber.Ctx, body *OAuthTokenBody) error {
|
||||
func PostTokenClientCredentials(c *fiber.Ctx, body *FortniteTokenBody) error {
|
||||
credentials, err := aid.JWTSign(aid.JSON{
|
||||
"snow_id": 0, // custom
|
||||
"creation_date": time.Now().Format("2006-01-02T15:04:05.999Z"),
|
||||
|
@ -56,7 +56,7 @@ func PostOAuthTokenClientCredentials(c *fiber.Ctx, body *OAuthTokenBody) error {
|
|||
})
|
||||
}
|
||||
|
||||
func PostOAuthTokenPassword(c *fiber.Ctx, body *OAuthTokenBody) error {
|
||||
func PostTokenPassword(c *fiber.Ctx, body *FortniteTokenBody) error {
|
||||
if body.Username == "" || body.Password == "" {
|
||||
return c.Status(fiber.StatusBadRequest).JSON(aid.ErrorBadRequest("Username/Password is empty"))
|
||||
}
|
||||
|
@ -150,7 +150,7 @@ func GetOAuthVerify(c *fiber.Ctx) error {
|
|||
})
|
||||
}
|
||||
|
||||
func OAuthMiddleware(c *fiber.Ctx) error {
|
||||
func FortniteMiddleware(c *fiber.Ctx) error {
|
||||
auth := c.Get("Authorization")
|
||||
if auth == "" {
|
||||
return c.Status(fiber.StatusForbidden).JSON(aid.ErrorBadRequest("Authorization Header is empty"))
|
||||
|
@ -177,7 +177,39 @@ func OAuthMiddleware(c *fiber.Ctx) error {
|
|||
}
|
||||
|
||||
c.Locals("person", person)
|
||||
return c.Next()
|
||||
}
|
||||
|
||||
func FrontendMiddleware(c *fiber.Ctx) error {
|
||||
auth := c.Get("Authorization")
|
||||
if auth == "" {
|
||||
return c.Status(fiber.StatusForbidden).JSON(aid.ErrorBadRequest("Authorization Header is empty"))
|
||||
}
|
||||
|
||||
claims, err := aid.JWTVerify(auth)
|
||||
if err != nil {
|
||||
return c.Status(fiber.StatusForbidden).JSON(aid.ErrorBadRequest("Invalid Access Token"))
|
||||
}
|
||||
|
||||
if claims["snow_id"] == nil {
|
||||
return c.Status(fiber.StatusForbidden).JSON(aid.ErrorBadRequest("Invalid Access Token"))
|
||||
}
|
||||
|
||||
if claims["frontend"] == nil {
|
||||
return c.Status(fiber.StatusForbidden).JSON(aid.ErrorBadRequest("Invalid Claims"))
|
||||
}
|
||||
|
||||
snowId, ok := claims["snow_id"].(string)
|
||||
if !ok {
|
||||
return c.Status(fiber.StatusForbidden).JSON(aid.ErrorBadRequest("Invalid Access Token"))
|
||||
}
|
||||
|
||||
person := p.Find(snowId)
|
||||
if person == nil {
|
||||
return c.Status(fiber.StatusForbidden).JSON(aid.ErrorBadRequest("Invalid Access Token"))
|
||||
}
|
||||
|
||||
c.Locals("person", person)
|
||||
return c.Next()
|
||||
}
|
||||
|
||||
|
|
12
handlers/discord.go
Normal file
12
handlers/discord.go
Normal file
|
@ -0,0 +1,12 @@
|
|||
package handlers
|
||||
|
||||
import (
|
||||
"net/url"
|
||||
|
||||
"github.com/ectrc/snow/aid"
|
||||
"github.com/gofiber/fiber/v2"
|
||||
)
|
||||
|
||||
func GetDiscordOAuthURL(c *fiber.Ctx) error {
|
||||
return c.Status(200).SendString("https://discord.com/api/oauth2/authorize?client_id="+ aid.Config.Discord.ID +"&redirect_uri="+ url.QueryEscape(aid.Config.API.Host + aid.Config.API.Port +"/snow/discord/callback") + "&response_type=code&scope=identify")
|
||||
}
|
|
@ -76,7 +76,7 @@ func createPlaylist(mnemonic string, image string) aid.JSON {
|
|||
func PostDiscovery(c *fiber.Ctx) error {
|
||||
results := []aid.JSON{}
|
||||
for playlist := range fortnite.PlaylistImages {
|
||||
results = append(results, createPlaylist(playlist, "http://" + aid.Config.API.Host + aid.Config.API.Port + "/snow/image/" + playlist + ".png?cache="+strconv.Itoa(rand.Intn(9999))))
|
||||
results = append(results, createPlaylist(playlist, aid.Config.API.Host + aid.Config.API.Port + "/snow/image/" + playlist + ".png?cache="+strconv.Itoa(rand.Intn(9999))))
|
||||
}
|
||||
results = append(results, createPlaylist("Playlist_DefaultSolo", "http://bucket.retrac.site/55737fa15677cd57fab9e7f4499d62f89cfde320.png"))
|
||||
|
||||
|
@ -157,7 +157,7 @@ func GetContentPages(c *fiber.Ctx) error {
|
|||
playlists := []aid.JSON{}
|
||||
for playlist := range fortnite.PlaylistImages {
|
||||
playlists = append(playlists, aid.JSON{
|
||||
"image": "http://" + aid.Config.API.Host + aid.Config.API.Port + "/snow/image/" + playlist + ".png?cache="+strconv.Itoa(rand.Intn(9999)),
|
||||
"image": aid.Config.API.Host + aid.Config.API.Port + "/snow/image/" + playlist + ".png?cache="+strconv.Itoa(rand.Intn(9999)),
|
||||
"playlist_name": playlist,
|
||||
"hidden": false,
|
||||
})
|
||||
|
|
|
@ -4,6 +4,7 @@ import (
|
|||
"strings"
|
||||
|
||||
"github.com/ectrc/snow/fortnite"
|
||||
"github.com/ectrc/snow/person"
|
||||
"github.com/gofiber/fiber/v2"
|
||||
)
|
||||
|
||||
|
@ -26,3 +27,8 @@ func GetPlaylistImage(c *fiber.Ctx) error {
|
|||
c.Set("Content-Type", "image/png")
|
||||
return c.Send(image)
|
||||
}
|
||||
|
||||
func GetPlayerLocker(c *fiber.Ctx) error {
|
||||
person := c.Locals("person").(*person.Person)
|
||||
return c.JSON(person.AthenaProfile.Items)
|
||||
}
|
21
main.go
21
main.go
|
@ -8,8 +8,8 @@ import (
|
|||
"github.com/ectrc/snow/fortnite"
|
||||
"github.com/ectrc/snow/handlers"
|
||||
"github.com/ectrc/snow/storage"
|
||||
"github.com/goccy/go-json"
|
||||
|
||||
"github.com/goccy/go-json"
|
||||
"github.com/gofiber/fiber/v2"
|
||||
)
|
||||
|
||||
|
@ -70,7 +70,7 @@ func main() {
|
|||
account.Get("/public/account/:accountId/externalAuths", handlers.GetPublicAccountExternalAuths)
|
||||
account.Get("/public/account/displayName/:displayName", handlers.GetPublicAccountByDisplayName)
|
||||
account.Get("/oauth/verify", handlers.GetOAuthVerify)
|
||||
account.Post("/oauth/token", handlers.PostOAuthToken)
|
||||
account.Post("/oauth/token", handlers.PostFortniteToken)
|
||||
account.Delete("/oauth/sessions/kill", handlers.DeleteOAuthSessions)
|
||||
|
||||
fortnite := r.Group("/fortnite/api")
|
||||
|
@ -79,7 +79,7 @@ func main() {
|
|||
fortnite.Get("/calendar/v1/timeline", handlers.GetFortniteTimeline)
|
||||
|
||||
storefront := fortnite.Group("/storefront/v2")
|
||||
storefront.Use(handlers.OAuthMiddleware)
|
||||
storefront.Use(handlers.FortniteMiddleware)
|
||||
storefront.Get("/catalog", handlers.GetStorefrontCatalog)
|
||||
storefront.Get("/keychain", handlers.GetStorefrontKeychain)
|
||||
|
||||
|
@ -92,7 +92,7 @@ func main() {
|
|||
storage.Get("/system/:fileName", handlers.GetCloudStorageFile)
|
||||
|
||||
user := storage.Group("/user")
|
||||
user.Use(handlers.OAuthMiddleware)
|
||||
user.Use(handlers.FortniteMiddleware)
|
||||
user.Get("/:accountId", handlers.GetUserStorageFiles)
|
||||
user.Get("/:accountId/:fileName", handlers.GetUserStorageFile)
|
||||
user.Put("/:accountId/:fileName", handlers.PutUserStorageFile)
|
||||
|
@ -105,7 +105,7 @@ func main() {
|
|||
game.Post("/profileToken/verify/:accountId", handlers.AnyNoContent)
|
||||
|
||||
profile := game.Group("/profile/:accountId")
|
||||
profile.Use(handlers.OAuthMiddleware)
|
||||
profile.Use(handlers.FortniteMiddleware)
|
||||
profile.Post("/client/:action", handlers.PostProfileAction)
|
||||
|
||||
lightswitch := r.Group("/lightswitch/api")
|
||||
|
@ -115,14 +115,21 @@ func main() {
|
|||
snow.Get("/cosmetics", handlers.GetPreloadedCosmetics)
|
||||
snow.Get("/image/:playlist", handlers.GetPlaylistImage)
|
||||
|
||||
discord := snow.Group("/discord")
|
||||
discord.Get("/", handlers.GetDiscordOAuthURL)
|
||||
|
||||
player := snow.Group("/player")
|
||||
player.Use(handlers.FrontendMiddleware)
|
||||
player.Get("/locker", handlers.GetPlayerLocker)
|
||||
|
||||
r.Hooks().OnListen(func(ld fiber.ListenData) error {
|
||||
aid.Print("Listening on " + "0.0.0.0:" + ld.Port)
|
||||
aid.Print("Listening on " + aid.Config.API.Host + ":" + ld.Port)
|
||||
return nil
|
||||
})
|
||||
|
||||
r.All("*", func(c *fiber.Ctx) error { return c.Status(fiber.StatusNotFound).JSON(aid.ErrorNotFound) })
|
||||
|
||||
err := r.Listen(aid.Config.API.Host + aid.Config.API.Port)
|
||||
err := r.Listen("0.0.0.0" + aid.Config.API.Port)
|
||||
if err != nil {
|
||||
panic(fmt.Sprintf("Failed to listen: %v", err))
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user