From fd72565011100b4ae562eccd558e8822da179d78 Mon Sep 17 00:00:00 2001 From: ckt1031 <65409152+ckt1031@users.noreply.github.com> Date: Tue, 18 Jul 2023 22:24:38 +0800 Subject: [PATCH] feat: support Discord Guild Join --- common/constants.go | 3 ++ controller/discord.go | 44 +++++++++++++++++++++++- controller/misc.go | 40 +++++++++++----------- model/option.go | 9 +++++ web/src/components/LoginForm.jsx | 2 +- web/src/components/SystemSetting.jsx | 50 ++++++++++++++++++++++++++++ 6 files changed, 127 insertions(+), 21 deletions(-) diff --git a/common/constants.go b/common/constants.go index c77ed748..47b5946e 100644 --- a/common/constants.go +++ b/common/constants.go @@ -56,6 +56,9 @@ var GitHubClientSecret = "" var DiscordClientId = "" var DiscordClientSecret = "" +var DiscordGuildId = "" +var DiscordAllowJoiningGuild = "false" +var DiscordBotToken = "" var WeChatServerAddress = "" var WeChatServerToken = "" diff --git a/controller/discord.go b/controller/discord.go index f33ae60a..defbef4d 100644 --- a/controller/discord.go +++ b/controller/discord.go @@ -1,9 +1,11 @@ package controller import ( + "bytes" "encoding/json" "errors" "fmt" + "log" "net/http" "one-api/common" "one-api/model" @@ -36,7 +38,7 @@ func getDiscordUserInfoByCode(codeFromURLParamaters string, host string) (*Disco ClientID: common.DiscordClientId, ClientSecret: common.DiscordClientSecret, RedirectURI: fmt.Sprintf("https://%s/oauth/discord", host), - Scopes: []string{disgoauth.ScopeIdentify, disgoauth.ScopeEmail}, + Scopes: []string{disgoauth.ScopeIdentify, disgoauth.ScopeEmail, disgoauth.ScopeGuilds, disgoauth.ScopeGuildsJoin}, }) accessToken, _ := dc.GetOnlyAccessToken(codeFromURLParamaters) @@ -58,6 +60,46 @@ func getDiscordUserInfoByCode(codeFromURLParamaters string, host string) (*Disco return nil, err } + // Add guild member. + if common.DiscordGuildId != "" && discordUser.Id != "" && common.DiscordBotToken != "" && common.DiscordAllowJoiningGuild == "true" { + url := fmt.Sprintf("https://discord.com/api/guilds/%s/members/%s", common.DiscordGuildId, discordUser.Id) + + // Set JSON + map1 := map[string]interface{}{ + // accessToken remove "Bearer " + "access_token": string(accessToken[7:]), + } + + // Convert map to JSON + jsonData, _ := json.Marshal(map1) + + req, _ := http.NewRequest("PUT", url, bytes.NewBuffer(jsonData)) + + // Set Header + req.Header.Set("Authorization", fmt.Sprintf("Bot %s", common.DiscordBotToken)) + req.Header.Set("Content-Type", "application/json") + + // Create a new HTTP Client + client := &http.Client{} + resp, err := client.Do(req) + + log.Print(resp.StatusCode) + + if err != nil || (resp.StatusCode != 200 && resp.StatusCode != 201) { + // Print content + stringBuff := new(bytes.Buffer) + stringBuff.ReadFrom(resp.Body) + + // Print error + fmt.Println("Error: ", stringBuff.String()) + + return nil, errors.New("You must join the discord server first or be verified member to be able to login!") + } + + // Close the response body + defer resp.Body.Close() + } + if discordUser.Username == "" { return nil, errors.New("Invalid return value, user field is empty, please try again later!") } diff --git a/controller/misc.go b/controller/misc.go index 248024d4..3275dd10 100644 --- a/controller/misc.go +++ b/controller/misc.go @@ -15,25 +15,27 @@ func GetStatus(c *gin.Context) { "success": true, "message": "", "data": gin.H{ - "version": common.Version, - "start_time": common.StartTime, - "email_verification": common.EmailVerificationEnabled, - "github_oauth": common.GitHubOAuthEnabled, - "github_client_id": common.GitHubClientId, - "discord_oauth": common.DiscordOAuthEnabled, - "discord_client_id": common.DiscordClientId, - "system_name": common.SystemName, - "logo": common.Logo, - "footer_html": common.Footer, - "wechat_qrcode": common.WeChatAccountQRCodeImageURL, - "wechat_login": common.WeChatAuthEnabled, - "server_address": common.ServerAddress, - "turnstile_check": common.TurnstileCheckEnabled, - "turnstile_site_key": common.TurnstileSiteKey, - "top_up_link": common.TopUpLink, - "chat_link": common.ChatLink, - "quota_per_unit": common.QuotaPerUnit, - "display_in_currency": common.DisplayInCurrencyEnabled, + "version": common.Version, + "start_time": common.StartTime, + "email_verification": common.EmailVerificationEnabled, + "github_oauth": common.GitHubOAuthEnabled, + "github_client_id": common.GitHubClientId, + "discord_oauth": common.DiscordOAuthEnabled, + "discord_client_id": common.DiscordClientId, + "discord_guild_id": common.DiscordGuildId, + "discord_allow_joining_guild": common.DiscordAllowJoiningGuild, + "system_name": common.SystemName, + "logo": common.Logo, + "footer_html": common.Footer, + "wechat_qrcode": common.WeChatAccountQRCodeImageURL, + "wechat_login": common.WeChatAuthEnabled, + "server_address": common.ServerAddress, + "turnstile_check": common.TurnstileCheckEnabled, + "turnstile_site_key": common.TurnstileSiteKey, + "top_up_link": common.TopUpLink, + "chat_link": common.ChatLink, + "quota_per_unit": common.QuotaPerUnit, + "display_in_currency": common.DisplayInCurrencyEnabled, }, }) return diff --git a/model/option.go b/model/option.go index dd2e563e..7612c96a 100644 --- a/model/option.go +++ b/model/option.go @@ -56,6 +56,9 @@ func InitOptionMap() { common.OptionMap["GitHubClientSecret"] = "" common.OptionMap["DiscordClientId"] = "" common.OptionMap["DiscordClientSecret"] = "" + common.OptionMap["DiscordGuildId"] = "" + common.OptionMap["DiscordBotToken"] = "" + common.OptionMap["DiscordAllowJoiningGuild"] = "" common.OptionMap["WeChatServerAddress"] = "" common.OptionMap["WeChatServerToken"] = "" common.OptionMap["WeChatAccountQRCodeImageURL"] = "" @@ -178,6 +181,12 @@ func updateOptionMap(key string, value string) (err error) { common.GitHubClientSecret = value case "DiscordClientId": common.DiscordClientId = value + case "DiscordGuildId": + common.DiscordGuildId = value + case "DiscordBotToken": + common.DiscordBotToken = value + case "DiscordAllowJoiningGuild": + common.DiscordAllowJoiningGuild = value case "DiscordClientSecret": common.DiscordClientSecret = value case "Footer": diff --git a/web/src/components/LoginForm.jsx b/web/src/components/LoginForm.jsx index e54ef780..b8cd3d49 100644 --- a/web/src/components/LoginForm.jsx +++ b/web/src/components/LoginForm.jsx @@ -59,7 +59,7 @@ const LoginForm = () => { const onDiscordOAuthClicked = () => { window.open( - `https://discord.com/oauth2/authorize?response_type=code&client_id=${status.discord_client_id}&redirect_uri=${window.location.origin}/oauth/discord&scope=identify`, + `https://discord.com/oauth2/authorize?response_type=code&client_id=${status.discord_client_id}&redirect_uri=${window.location.origin}/oauth/discord&scope=identify%20guilds%20email%20guilds.join`, ); }; diff --git a/web/src/components/SystemSetting.jsx b/web/src/components/SystemSetting.jsx index 5937d53d..be411ccc 100644 --- a/web/src/components/SystemSetting.jsx +++ b/web/src/components/SystemSetting.jsx @@ -12,6 +12,9 @@ const SystemSetting = () => { GitHubClientId: '', GitHubClientSecret: '', DiscordClientId: '', + DiscordAllowJoiningGuild: 'false', + DiscordGuildId: '', + DiscordBotToken: '', DiscordClientSecret: '', Notice: '', SMTPServer: '', @@ -87,6 +90,9 @@ const SystemSetting = () => { name.startsWith('SMTP') || name === 'ServerAddress' || name === 'DiscordClientId' || + name === 'DiscordGuildId' || + name === 'DiscordAllowJoiningGuild' || + name === 'DiscordBotToken' || name === 'DiscordClientSecret' || name === 'GitHubClientId' || name === 'GitHubClientSecret' || @@ -177,6 +183,24 @@ const SystemSetting = () => { ) { await updateOption('DiscordClientSecret', inputs.DiscordClientSecret); } + if (originInputs['DiscordGuildId'] !== inputs.DiscordGuildId) { + await updateOption('DiscordGuildId', inputs.DiscordGuildId); + } + if ( + originInputs['DiscordBotToken'] !== inputs.DiscordBotToken && + inputs.DiscordBotToken !== '' + ) { + await updateOption('DiscordBotToken', inputs.DiscordBotToken); + } + if ( + originInputs['DiscordAllowJoiningGuild'] !== + inputs.DiscordAllowJoiningGuild + ) { + await updateOption( + 'DiscordAllowJoiningGuild', + inputs.DiscordAllowJoiningGuild, + ); + } }; const submitTurnstile = async () => { @@ -352,6 +376,32 @@ const SystemSetting = () => { value={inputs.DiscordClientSecret} placeholder='Sensitive information will not be displayed in the frontend' /> +