Skip to content

Commit

Permalink
:sparcles: サーバーに入っていなかった場合サーバーに追加する処理を追加
Browse files Browse the repository at this point in the history
  • Loading branch information
pikachu0310 committed Feb 6, 2024
1 parent fe35ea1 commit d05baa5
Show file tree
Hide file tree
Showing 3 changed files with 138 additions and 10 deletions.
87 changes: 82 additions & 5 deletions internal/api/discord.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package api

import (
"bytes"
"encoding/json"
"errors"
"github.com/traPtitech/game3-back/internal/enum"
Expand All @@ -14,12 +15,22 @@ import (
"github.com/labstack/echo/v4"
)

type DiscordUserResponse struct {
type GetDiscordUserInfoResponse struct {
ID string `json:"id"`
Username string `json:"username"`
Avatar string `json:"avatar"`
}

type GetDiscordUserGuildsResponse struct {
ID string `json:"id"`
Name string `json:"name"`
Icon *string `json:"icon"`
Owner bool `json:"owner"`
Permissions int `json:"permissions"`
PermissionsNew string `json:"permissions_new"`
Features []string `json:"features"`
}

type TokenResponse struct {
TokenType *string `json:"token_type"`
AccessToken *string `json:"access_token"`
Expand All @@ -28,7 +39,7 @@ type TokenResponse struct {
Scope *string `json:"scope"`
}

func GetDiscordUserInfo(accessToken *string) (*DiscordUserResponse, error) {
func GetDiscordUserInfo(accessToken *string) (*GetDiscordUserInfoResponse, error) {
req, err := http.NewRequest("GET", "https://discordapp.com/api/users/@me", nil)
if err != nil {
return nil, echo.NewHTTPError(http.StatusInternalServerError, err.Error())
Expand All @@ -51,16 +62,82 @@ func GetDiscordUserInfo(accessToken *string) (*DiscordUserResponse, error) {
return nil, echo.NewHTTPError(http.StatusInternalServerError, err.Error())
}

var discordUser DiscordUserResponse
var discordUser GetDiscordUserInfoResponse
if err = json.Unmarshal(body, &discordUser); err != nil {
return nil, echo.NewHTTPError(http.StatusInternalServerError, err.Error())
}

return &discordUser, nil
}

func GetDiscordUserServers(accessToken *string) ([]GetDiscordUserGuildsResponse, error) {
req, err := http.NewRequest("GET", "https://discordapp.com/api/users/@me/guilds", nil)
if err != nil {
return nil, echo.NewHTTPError(http.StatusInternalServerError, err.Error())
}
req.Header.Set("Authorization", "Bearer "+*accessToken)

client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
return nil, echo.NewHTTPError(http.StatusInternalServerError, err.Error())
}
defer resp.Body.Close()

if resp.StatusCode != http.StatusOK {
return nil, echo.NewHTTPError(http.StatusInternalServerError, "Failed to get Discord user guilds: status "+resp.Status)
}

body, err := io.ReadAll(resp.Body)
if err != nil {
return nil, echo.NewHTTPError(http.StatusInternalServerError, err.Error())
}

var discordUserGuilds []GetDiscordUserGuildsResponse
if err = json.Unmarshal(body, &discordUserGuilds); err != nil {
return nil, echo.NewHTTPError(http.StatusInternalServerError, err.Error())
}

return discordUserGuilds, nil
}

func AddUserToGuild(accessToken *string, guildID string, userID string) error {
var buf bytes.Buffer
err := json.NewEncoder(&buf).Encode(map[string]string{
"access_token": *accessToken,
})
if err != nil {
return err
}

req, err := http.NewRequest("PUT", "https://discord.com/api/guilds/"+guildID+"/members/"+userID, &buf)
if err != nil {
return err
}

botToken, err := util.GetEnvOrErr("DISCORD_BOT_TOKEN")
if err != nil {
return err
}
req.Header.Set("Authorization", "Bot "+botToken)
req.Header.Set("Content-Type", "application/json")

client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
return err
}

defer resp.Body.Close()
if resp.StatusCode != http.StatusCreated {
return errors.New("Failed to add user to guild: status " + resp.Status)
}

return nil
}

func GetDiscordUserToken(params models.OauthCallbackParams) (*TokenResponse, error) {
clientId, err := util.GetEnvOrErr("DISCORD_CLIENT_ID")
clientID, err := util.GetEnvOrErr("DISCORD_CLIENT_ID")
if err != nil {
return nil, err
}
Expand All @@ -74,7 +151,7 @@ func GetDiscordUserToken(params models.OauthCallbackParams) (*TokenResponse, err
}

formData := url.Values{}
formData.Set("client_id", clientId)
formData.Set("client_id", clientID)
formData.Set("client_secret", clientSecret)
formData.Set("grant_type", "authorization_code")
formData.Set("code", params.Code)
Expand Down
53 changes: 52 additions & 1 deletion internal/handler/auth.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"github.com/traPtitech/game3-back/internal/api"
"github.com/traPtitech/game3-back/internal/apperrors"
"github.com/traPtitech/game3-back/internal/domain"
"github.com/traPtitech/game3-back/internal/pkg/util"
"github.com/traPtitech/game3-back/openapi/models"
"net/http"
"time"
Expand All @@ -31,7 +32,7 @@ func (h *Handler) Test(c echo.Context) error {
<title>リダイレクトテスト</title>
<script>
function sendGetRequest() {
window.location.href = 'https://game3.trap.games/api/auth/login?redirect=https://game3.trap.games/api/ping';
window.location.href = 'http://localhost:8080/api/auth/login?redirect=http://localhost:8080/api/ping';
}
</script>
</head>
Expand All @@ -41,6 +42,7 @@ func (h *Handler) Test(c echo.Context) error {
</html>
`

return c.HTML(http.StatusOK, html)
}

Expand All @@ -55,12 +57,30 @@ func (h *Handler) OauthCallback(c echo.Context, params models.OauthCallbackParam
return echo.NewHTTPError(http.StatusInternalServerError, err.Error())
}

userServers, err := api.GetDiscordUserServers(tokenResponse.AccessToken)
if err != nil {
return err
}

isInGame3Server, err := checkUserIsInGame3Server(userServers)
if err != nil {
return echo.NewHTTPError(http.StatusInternalServerError, err.Error())
}

if isInGame3Server == false {
err = addUserToGame3Guild(tokenResponse.AccessToken)
if err != nil {
return err
}
}

CreateSessionParams := &domain.Session{
ID: sessionID,
AccessToken: tokenResponse.AccessToken,
RefreshToken: tokenResponse.RefreshToken,
ExpiresIn: tokenResponse.ExpiresIn,
}

if err = h.repo.UpdateSession(CreateSessionParams); err != nil {
return apperrors.HandleDbError(err)
}
Expand All @@ -72,6 +92,37 @@ func (h *Handler) OauthCallback(c echo.Context, params models.OauthCallbackParam
return c.Redirect(http.StatusSeeOther, *session.Redirect)
}

func checkUserIsInGame3Server(userServers []api.GetDiscordUserGuildsResponse) (bool, error) {
game3ServerID, err := util.GetEnvOrErr("DISCORD_SERVER_ID")
if err != nil {
return false, err
}
for _, server := range userServers {
if server.ID == game3ServerID {
return true, nil
}
}

return false, nil
}

func addUserToGame3Guild(accessToken *string) error {
game3ServerID, err := util.GetEnvOrErr("DISCORD_SERVER_ID")
if err != nil {
return err
}
user, err := api.GetDiscordUserInfo(accessToken)
if err != nil {
return err
}
err = api.AddUserToGuild(accessToken, game3ServerID, user.ID)
if err != nil {
return err
}

return nil
}

func (h *Handler) Login(c echo.Context, params models.LoginParams) error {
sessionToken := uuid.New()
CreateSessionParams := &domain.Session{
Expand Down
8 changes: 4 additions & 4 deletions internal/handler/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ func getSessionIDByCookie(c echo.Context) (*uuid.UUID, error) {
return &sessionID, nil
}

func (h *Handler) getDiscordUserInfoByCookie(c echo.Context) (*api.DiscordUserResponse, error) {
func (h *Handler) getDiscordUserInfoByCookie(c echo.Context) (*api.GetDiscordUserInfoResponse, error) {
sessionID, err := getSessionIDByCookie(c)
if err != nil {
return nil, err
Expand All @@ -100,7 +100,7 @@ func (h *Handler) getDiscordUserInfoByCookie(c echo.Context) (*api.DiscordUserRe
return api.GetDiscordUserInfo(session.AccessToken)
}

func (h *Handler) getDiscordUserInfoAndRoleByCookie(c echo.Context) (*api.DiscordUserResponse, enum.UserRole, error) {
func (h *Handler) getDiscordUserInfoAndRoleByCookie(c echo.Context) (*api.GetDiscordUserInfoResponse, enum.UserRole, error) {
user, err := h.getDiscordUserInfoByCookie(c)

var notFoundErr *apperrors.SessionTokenNotFoundError
Expand All @@ -116,7 +116,7 @@ func (h *Handler) getDiscordUserInfoAndRoleByCookie(c echo.Context) (*api.Discor
return user, role, nil
}

func (h *Handler) enforceAdminAccess(c echo.Context) (user *api.DiscordUserResponse, role enum.UserRole, err error) {
func (h *Handler) enforceAdminAccess(c echo.Context) (user *api.GetDiscordUserInfoResponse, role enum.UserRole, err error) {
user, role, err = h.getDiscordUserInfoAndRoleByCookie(c)
if err != nil {
err = apperrors.HandleInternalServerError(err)
Expand All @@ -129,7 +129,7 @@ func (h *Handler) enforceAdminAccess(c echo.Context) (user *api.DiscordUserRespo
return
}

func (h *Handler) enforceUserOrAboveAccess(c echo.Context) (user *api.DiscordUserResponse, role enum.UserRole, err error) {
func (h *Handler) enforceUserOrAboveAccess(c echo.Context) (user *api.GetDiscordUserInfoResponse, role enum.UserRole, err error) {
user, role, err = h.getDiscordUserInfoAndRoleByCookie(c)
if err != nil {
err = apperrors.HandleInternalServerError(err)
Expand Down

0 comments on commit d05baa5

Please sign in to comment.