made LoginHandler slightly less awful
Signed-off-by: ari melody <ari@arimelody.me>
This commit is contained in:
parent
5631c4bd87
commit
4b58a27fdc
|
@ -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{}
|
||||||
|
|
|
@ -1,44 +1,105 @@
|
||||||
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"
|
||||||
|
|
||||||
type (
|
type (
|
||||||
AccessTokenResponse struct {
|
AccessTokenResponse struct {
|
||||||
TokenType string `json:"token_type"`
|
TokenType string `json:"token_type"`
|
||||||
AccessToken string `json:"access_token"`
|
AccessToken string `json:"access_token"`
|
||||||
ExpiresIn int `json:"expires_in"`
|
ExpiresIn int `json:"expires_in"`
|
||||||
RefreshToken string `json:"refresh_token"`
|
RefreshToken string `json:"refresh_token"`
|
||||||
Scope string `json:"scope"`
|
Scope string `json:"scope"`
|
||||||
}
|
}
|
||||||
|
|
||||||
AuthInfoResponse struct {
|
AuthInfoResponse struct {
|
||||||
Application struct {
|
Application struct {
|
||||||
Id string
|
Id string
|
||||||
Name string
|
Name string
|
||||||
Icon string
|
Icon string
|
||||||
Description string
|
Description string
|
||||||
Hook bool
|
Hook bool
|
||||||
BotPublic bool
|
BotPublic bool
|
||||||
botRequireCodeGrant bool
|
botRequireCodeGrant bool
|
||||||
VerifyKey bool
|
VerifyKey bool
|
||||||
}
|
}
|
||||||
Scopes []string
|
Scopes []string
|
||||||
Expires string
|
Expires string
|
||||||
User struct {
|
User DiscordUser
|
||||||
Id string
|
}
|
||||||
Username string
|
|
||||||
Avatar string
|
DiscordUser struct {
|
||||||
Discriminator string
|
Id string
|
||||||
GlobalName string
|
Username string
|
||||||
PublicFlags int
|
Avatar string
|
||||||
}
|
Discriminator string
|
||||||
|
GlobalName string
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue