feat: Added Discord auth module

This commit is contained in:
ptrcnull 2020-12-05 03:24:54 +01:00
parent c008854f63
commit 9f2cc58005
6 changed files with 185 additions and 61 deletions

7
go.mod
View file

@ -4,8 +4,9 @@ go 1.15
require (
github.com/UnnoTed/fileb0x v1.1.4 // indirect
github.com/gofiber/fiber/v2 v2.2.0
github.com/gofiber/fiber/v2 v2.2.3
github.com/gofiber/session/v2 v2.0.2
github.com/gofiber/template v1.6.4
golang.org/x/net v0.0.0-20201016165138-7b1cca2348c0
github.com/gofiber/template v1.6.5
github.com/klauspost/compress v1.11.3 // indirect
golang.org/x/net v0.0.0-20201202161906-c7110b5ffcbb
)

11
go.sum
View file

@ -106,10 +106,15 @@ github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJA
github.com/gofiber/fiber/v2 v2.1.0/go.mod h1:aG+lMkwy3LyVit4CnmYUbUdgjpc3UYOltvlJZ78rgQ0=
github.com/gofiber/fiber/v2 v2.2.0 h1:U9IkTlomVnR+Q5aBhgC0R6ePTiwTnNLXWQR+h+oYUN8=
github.com/gofiber/fiber/v2 v2.2.0/go.mod h1:Slpou87elSO9qom9nwIo/IoQJ2qfRuMAQ/qQ9F0o4b0=
github.com/gofiber/fiber/v2 v2.2.2/go.mod h1:Aso7/M+EQOinVkWp4LUYjdlTpKTBoCk2Qo4djnMsyHE=
github.com/gofiber/fiber/v2 v2.2.3 h1:mnaX66dpJOQYS0uii2Nd8fVzpqXMjiXqI5ci1QhM0EI=
github.com/gofiber/fiber/v2 v2.2.3/go.mod h1:Aso7/M+EQOinVkWp4LUYjdlTpKTBoCk2Qo4djnMsyHE=
github.com/gofiber/session/v2 v2.0.2 h1:VuLOb+QpMHaXZ6JXZnp3xCRv8TPRc1VLB9ddaA0MMGU=
github.com/gofiber/session/v2 v2.0.2/go.mod h1:H+M+PENuiMTQJf9cTx+DJ7Jw8IqBAJ3QSbS6PbmvA78=
github.com/gofiber/template v1.6.4 h1:BA/qZs0s5Afksnmn9HGOip5BXZTdrFsQ3ijxYoYH+Yc=
github.com/gofiber/template v1.6.4/go.mod h1:IsW5D1qMTskGQjromCxs9PNYIdoRWqEYMj04Ff93k9Q=
github.com/gofiber/template v1.6.5 h1:lRQmEggpdSBa0I9aLphsBJpcnXb7u+llgTnZkhbSAhg=
github.com/gofiber/template v1.6.5/go.mod h1:rRenAmgjISwhHPoLVQPGnIErs7133LWU4b4cJcRZLLE=
github.com/gofrs/flock v0.7.1/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU=
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4=
@ -210,6 +215,8 @@ github.com/klauspost/compress v1.10.7 h1:7rix8v8GpI3ZBb0nSozFRgbtXKv+hOe+qfEpZqy
github.com/klauspost/compress v1.10.7/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=
github.com/klauspost/compress v1.11.0 h1:wJbzvpYMVGG9iTI9VxpnNZfd4DzMPoCWze3GgSqz8yg=
github.com/klauspost/compress v1.11.0/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=
github.com/klauspost/compress v1.11.3 h1:dB4Bn0tN3wdCzQxnS8r06kV74qN/TAfaIS0bVE8h3jc=
github.com/klauspost/compress v1.11.3/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
@ -442,6 +449,8 @@ golang.org/x/net v0.0.0-20200602114024-627f9648deb9 h1:pNX+40auqi2JqRfOP1akLGtYc
golang.org/x/net v0.0.0-20200602114024-627f9648deb9/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20201016165138-7b1cca2348c0 h1:5kGOVHlq0euqwzgTC9Vu15p6fV1Wi0ArVi8da2urnVg=
golang.org/x/net v0.0.0-20201016165138-7b1cca2348c0/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.0.0-20201202161906-c7110b5ffcbb h1:eBmm0M9fYhWpKZLjQUUKka/LtIxf46G4fxeEz5KJr9U=
golang.org/x/net v0.0.0-20201202161906-c7110b5ffcbb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
@ -482,6 +491,8 @@ golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20201015000850-e3ed0017c211/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201101102859-da207088b7d1 h1:a/mKvvZr9Jcc8oKfcmgzyp7OwF73JPWsQLvH1z2Kxck=
golang.org/x/sys v0.0.0-20201101102859-da207088b7d1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68 h1:nxC68pudNYkKU6jWhgrqdreuFiOQWj1Fs7T3VrH4Pjw=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=

View file

@ -0,0 +1,44 @@
package discord_auth
import (
"encoding/json"
"io/ioutil"
"net/http"
)
type MeResponse struct {
ID string `json:"id"`
Username string `json:"username"`
Avatar string `json:"avatar"`
Discriminator string `json:"discriminator"`
Email string `json:"email"`
Verified bool `json:"verified"`
Locale string `json:"locale"`
MfaEnabled bool `json:"mfa_enabled"`
Flags int `json:"flags"`
PremiumType int `json:"premium_type"`
}
func getMe(token *TokenResponse) (*MeResponse, error) {
req, err := http.NewRequest("GET", API_ENDPOINT+"/users/@me", nil)
if err != nil {
return nil, err
}
req.Header.Set("Authorization", token.TokenType+" "+token.AccessToken)
client := http.Client{}
res, err := client.Do(req)
if err != nil {
return nil, err
}
body, err := ioutil.ReadAll(res.Body)
if err != nil {
return nil, err
}
var resp MeResponse
err = json.Unmarshal(body, &resp)
return &resp, nil
}

View file

@ -0,0 +1,39 @@
package discord_auth
import (
"encoding/json"
"io/ioutil"
"net/http"
"net/url"
)
type TokenResponse struct {
AccessToken string `json:"access_token"`
TokenType string `json:"token_type"`
ExpiresIn int `json:"expires_in"`
RefreshToken string `json:"refresh_token"`
Scope string `json:"scope"`
}
func (m *Module) getToken(code string) (*TokenResponse, error) {
res, err := http.PostForm(API_ENDPOINT+"/oauth2/token", url.Values{
"client_id": {m.ClientID},
"client_secret": {m.ClientSecret},
"grant_type": {"authorization_code"},
"code": {code},
"redirect_uri": {m.RedirectURI},
"scope": {m.Scope},
})
if err != nil {
return nil, err
}
body, err := ioutil.ReadAll(res.Body)
if err != nil {
return nil, err
}
var resp TokenResponse
err = json.Unmarshal(body, &resp)
return &resp, nil
}

View file

@ -0,0 +1,87 @@
package discord_auth
import (
"log"
"net/url"
"git.ddd.rip/ptrcnull/modweb"
"github.com/gofiber/fiber/v2"
)
type Module struct {
ClientID string
ClientSecret string
RedirectURI string
Scope string
Callback func(me *MeResponse) *modweb.User
}
const API_ENDPOINT = "https://discord.com/api/v6"
func (m *Module) LoginURL() string {
params := url.Values{}
params.Set("client_id", m.ClientID)
params.Set("redirect_uri", m.RedirectURI)
params.Set("response_type", "code")
params.Set("scope", m.Scope)
return "https://discord.com/api/oauth2/authorize?" + params.Encode()
}
func (m *Module) RegisterURL() string {
return ""
}
func (m *Module) FriendlyName() string {
return "Discord"
}
func (m *Module) Name() string {
return "discord"
}
func (m *Module) MinAccessLevel() int64 {
return -1
}
func (m *Module) Hidden() bool {
return true
}
type User struct {
ID string
AccessLevel int64
}
func (m *Module) Init(mm *modweb.ModuleManager) {
app := mm.Fiber()
app.Get("/callback", func(ctx *fiber.Ctx) error {
session := mm.Session(ctx)
defer session.Save()
if session.Get("user") != nil {
return ctx.Redirect("/")
}
code := ctx.Query("code")
if code == "" {
return ctx.Redirect("/")
}
token, err := m.getToken(code)
if err != nil {
log.Println(err)
return ctx.Redirect("/")
}
me, err := getMe(token)
if err != nil {
log.Println(err)
return ctx.Redirect("/")
}
user := m.Callback(me)
user.Save(session)
return ctx.Redirect("/")
})
}

View file

@ -1,58 +0,0 @@
package modweb
import (
"git.ddd.rip/ptrcnull/modweb/config"
"git.ddd.rip/ptrcnull/modweb/module"
"github.com/gofiber/fiber/v2"
"github.com/gofiber/session/v2"
"github.com/gofiber/template/html"
_ "github.com/hashicorp/go-plugin"
)
func main() {
views := html.New("./templates", ".html")
conf, _ := config.Load()
app := fiber.New(fiber.Config{Views: views})
sessions := session.New()
modules, err := module.LoadAll(conf.ModulePath)
//for _, mod := range modules {
//app.Get("/" + mod.Name() + "/", func(ctx *fiber.Ctx) error {
// //ctx.Render("module", "")
// //templates.Send(ctx, fiber.Map{
// // "modules": modules,
// // "currentModule": mod,
// //}, static.Navbar, static.ModulePage)
// return nil
//})
//}
data := func(d fiber.Map) fiber.Map {
base := fiber.Map{
"appName": conf.AppName,
"modules": modules,
"username": "ptrcnull",
"allowRegistration": conf.AllowRegistration,
}
for k, v := range d {
base[k] = v
}
return base
}
app.Get("/", func(ctx *fiber.Ctx) error {
store := sessions.Get(ctx)
defer store.Save()
// _, loggedIn := store.Get("discordId")
return ctx.Render("homepage", data(fiber.Map{
"title": "Homepage",
}), "layouts/main")
})
err = app.Listen(conf.ListenAddress)
if err != nil {
panic(err)
}
}