diff --git a/config.go b/config.go index cb7242651f8b499a2720b7415e4006b762d36da5..821cb23d4542de6f1abf6b26e72bfacf03ecf72d 100644 --- a/config.go +++ b/config.go @@ -8,7 +8,10 @@ import ( "strconv" ) -var administrators map[string]bool +var ( + administrators map[string]bool + guildID string +) type conf struct { System systemConf `toml:"system"` @@ -32,9 +35,11 @@ type systemConf struct { } type discordConf struct { + BotToken string `toml:"bot_token"` ClientID string `toml:"client_id"` ClientSecret string `toml:"client_secret"` Administrators []int `toml:"administrators"` + GuildID int `toml:"guild_id"` } var ( @@ -79,6 +84,10 @@ func confLoad() { administrators[strconv.Itoa(id)] = true } } + + if config.Discord.GuildID > 0 { + guildID = strconv.Itoa(config.Discord.GuildID) + } } var defConf = conf{ @@ -100,8 +109,10 @@ var defConf = conf{ Secret: "RANDOM_STRING", }, Discord: discordConf{ + BotToken: "", ClientID: "", ClientSecret: "", Administrators: []int{-1}, + GuildID: -1, }, } diff --git a/routes.go b/routes.go index 96b2ada7e0d5b41483d5088b72166015dc3af338..9cc97292de9542a355d0e2af08d4ac764ff97f80 100644 --- a/routes.go +++ b/routes.go @@ -120,6 +120,12 @@ func registerRoutes() { return } + if err := ensureJoinEnrollment(context, user); err != nil { + log.Printf("error ensuring guild membership of user %s: %s", user.ID, err) + context.String(http.StatusInternalServerError, "Internal Server Error") + return + } + if s, err := existsTeam(t.ID, user.ID); err != nil { log.Printf("error querying team existance for team %s in tournament %s: %s", user.ID, t.ID.String(), err) diff --git a/user.go b/user.go index 7445463114f77547dbc0a47308143c3214db4fa5..2e81f5e639f19ea01d8a4a76202bcbab793df611 100644 --- a/user.go +++ b/user.go @@ -2,13 +2,16 @@ package main import ( "fmt" + "git.randomchars.net/levatax/tournament-website/oauth" "github.com/bwmarrin/discordgo" "github.com/gin-gonic/gin" "github.com/google/uuid" json "github.com/json-iterator/go" "github.com/syndtr/goleveldb/leveldb" + "io" "log" "net/http" + "strings" "sync" ) @@ -224,6 +227,32 @@ func getAuthButton(user *discordgo.User, logout bool) (authText, authRef string) return } +func ensureJoinEnrollment(context *gin.Context, user *discordgo.User) error { + if req, err := http.NewRequest(http.MethodPut, + fmt.Sprintf("https://discordapp.com/api/guilds/%s/members/%s", guildID, user.ID), + strings.NewReader(fmt.Sprintf(`{"access_token": "%s"}`, + oauth.GetToken(context).AccessToken))); err != nil { + return err + } else { + req.Header.Set("Content-Type", "application/json; charset=utf-8") + req.Header.Set("Authorization", "Bot "+config.Discord.BotToken) + var resp *http.Response + if resp, err = http.DefaultClient.Do(req); err != nil { + return err + } else { + var body []byte + if body, err = io.ReadAll(resp.Body); err != nil { + return err + } else { + if resp.StatusCode != 201 && resp.StatusCode != 204 { + return fmt.Errorf("discord returned %d: %s", resp.StatusCode, string(body)) + } + } + return resp.Body.Close() + } + } +} + func validateEnrollment(payload *userEnrollment) bool { return len(payload.TeamName) <= 64 && len(payload.FirstName) > 0 && len(payload.FirstName) <= 64 && diff --git a/web.go b/web.go index e7f75d44d05e5433c83c9d8d910cf82df30cd7d4..f1d1f520fb0e217dbfa5c0bf0e98d2e235e521da 100644 --- a/web.go +++ b/web.go @@ -79,7 +79,10 @@ func webSetup() { ClientSecret: config.Discord.ClientSecret, Endpoint: oauth.Endpoint(), RedirectURL: config.Server.BaseURL + "auth/callback", - Scopes: []string{oauth.ScopeIdentify}, + Scopes: []string{ + oauth.ScopeIdentify, + oauth.ScopeGuildsJoin, + }, } registerRoutes()