made LoginHandler slightly less awful

Signed-off-by: ari melody <ari@arimelody.me>
This commit is contained in:
ari melody 2024-07-31 04:21:52 +01:00
parent 5631c4bd87
commit 4b58a27fdc
2 changed files with 87 additions and 67 deletions

View file

@ -100,64 +100,23 @@ func LoginHandler() http.Handler {
return return
} }
// let's get an oauth token! auth_token, err := discord.GetOAuthTokenFromCode(code)
req, err := http.NewRequest(http.MethodPost, fmt.Sprintf("%s/oauth2/token", discord.API_ENDPOINT),
strings.NewReader(url.Values{
"client_id": {discord.CLIENT_ID},
"client_secret": {discord.CLIENT_SECRET},
"grant_type": {"authorization_code"},
"code": {code},
"redirect_uri": {discord.MY_REDIRECT_URI},
}.Encode()))
req.Header.Add("Content-Type", "application/x-www-form-urlencoded")
res, err := http.DefaultClient.Do(req)
if err != nil { if err != nil {
fmt.Printf("Failed to retrieve OAuth token: %s\n", err) fmt.Printf("Failed to retrieve discord access token: %s\n", err)
w.WriteHeader(500) w.WriteHeader(500)
w.Write([]byte("Internal server error")) w.Write([]byte("Internal server error"))
return return
} }
oauth := discord.AccessTokenResponse{} discord_user, err := discord.GetDiscordUserFromAuth(auth_token)
err = json.NewDecoder(res.Body).Decode(&oauth)
if err != nil { if err != nil {
fmt.Printf("Failed to parse OAuth response data from discord: %s\n", err) fmt.Printf("Failed to retrieve discord user information: %s\n", err)
w.WriteHeader(500)
w.Write([]byte("Internal server error"))
return
}
res.Body.Close()
discord_access_token := oauth.AccessToken
// let's get authorisation information!
req, err = http.NewRequest(http.MethodGet, fmt.Sprintf("%s/oauth2/@me", discord.API_ENDPOINT), nil)
req.Header.Add("Authorization", "Bearer " + discord_access_token)
res, err = http.DefaultClient.Do(req)
if err != nil {
fmt.Printf("Failed to retrieve discord auth information: %s\n", err)
w.WriteHeader(500) w.WriteHeader(500)
w.Write([]byte("Internal server error")) w.Write([]byte("Internal server error"))
return return
} }
auth_info := discord.AuthInfoResponse{} if discord_user.Id != ADMIN_ID_DISCORD {
err = json.NewDecoder(res.Body).Decode(&auth_info)
if err != nil {
fmt.Printf("Failed to parse auth information from discord: %s\n", err)
w.WriteHeader(500)
w.Write([]byte("Internal server error"))
return
}
res.Body.Close()
discord_user_id := auth_info.User.Id
if discord_user_id != ADMIN_ID_DISCORD {
// TODO: unauthorized user. revoke the token // TODO: unauthorized user. revoke the token
w.WriteHeader(401) w.WriteHeader(401)
w.Write([]byte("Unauthorized")) w.Write([]byte("Unauthorized"))
@ -165,7 +124,7 @@ func LoginHandler() http.Handler {
} }
// login success! // login success!
session := CreateSession(auth_info.User.Username) session := CreateSession(discord_user.Username)
sessions = append(sessions, &session) sessions = append(sessions, &session)
cookie := http.Cookie{} cookie := http.Cookie{}

View file

@ -1,11 +1,22 @@
package discord package discord
import (
"encoding/json"
"errors"
"fmt"
"net/http"
"net/url"
"strings"
)
const API_ENDPOINT = "https://discord.com/api/v10" const API_ENDPOINT = "https://discord.com/api/v10"
const CLIENT_ID = "1268013769578119208" const CLIENT_ID = "1268013769578119208"
// TODO: good GOD change this later please i beg you. we've already broken // TODO: good GOD change this later please i beg you. we've already broken
// the rules by doing this at all // the rules by doing this at all
const CLIENT_SECRET = "JUEZnixhN7BxmLIHmbECiKETMP85VT0E" const CLIENT_SECRET = "JUEZnixhN7BxmLIHmbECiKETMP85VT0E"
const REDIRECT_URI = "https://discord.com/oauth2/authorize?client_id=1268013769578119208&response_type=code&redirect_uri=http%3A%2F%2F127.0.0.1%3A8080%2Fapi%2Fv1%2Fadmin%2Flogin&scope=identify" const REDIRECT_URI = "https://discord.com/oauth2/authorize?client_id=1268013769578119208&response_type=code&redirect_uri=http%3A%2F%2F127.0.0.1%3A8080%2Fapi%2Fv1%2Fadmin%2Flogin&scope=identify"
// TODO: change before prod // TODO: change before prod
const MY_REDIRECT_URI = "http://127.0.0.1:8080/api/v1/admin/login" const MY_REDIRECT_URI = "http://127.0.0.1:8080/api/v1/admin/login"
@ -31,7 +42,10 @@ type (
} }
Scopes []string Scopes []string
Expires string Expires string
User struct { User DiscordUser
}
DiscordUser struct {
Id string Id string
Username string Username string
Avatar string Avatar string
@ -39,6 +53,53 @@ type (
GlobalName string GlobalName string
PublicFlags int PublicFlags int
} }
}
) )
func GetOAuthTokenFromCode(code string) (string, error) {
// let's get an oauth token!
req, err := http.NewRequest(http.MethodPost, fmt.Sprintf("%s/oauth2/token", API_ENDPOINT),
strings.NewReader(url.Values{
"client_id": {CLIENT_ID},
"client_secret": {CLIENT_SECRET},
"grant_type": {"authorization_code"},
"code": {code},
"redirect_uri": {MY_REDIRECT_URI},
}.Encode()))
req.Header.Add("Content-Type", "application/x-www-form-urlencoded")
res, err := http.DefaultClient.Do(req)
if err != nil {
return "", errors.New(fmt.Sprintf("Failed while contacting discord API: %s", err))
}
oauth := AccessTokenResponse{}
err = json.NewDecoder(res.Body).Decode(&oauth)
if err != nil {
return "", errors.New(fmt.Sprintf("Failed to parse OAuth response data from discord: %s\n", err))
}
res.Body.Close()
return oauth.AccessToken, nil
}
func GetDiscordUserFromAuth(token string) (DiscordUser, error) {
// let's get authorisation information!
req, err := http.NewRequest(http.MethodGet, fmt.Sprintf("%s/oauth2/@me", API_ENDPOINT), nil)
req.Header.Add("Authorization", "Bearer " + token)
res, err := http.DefaultClient.Do(req)
if err != nil {
return DiscordUser{}, errors.New(fmt.Sprintf("Failed to retrieve discord auth information: %s\n", err))
}
auth_info := AuthInfoResponse{}
err = json.NewDecoder(res.Body).Decode(&auth_info)
if err != nil {
return DiscordUser{}, errors.New(fmt.Sprintf("Failed to parse auth information from discord: %s\n", err))
}
defer res.Body.Close()
return auth_info.User, nil
}