mirror of
https://github.com/roleypoly/roleypoly.git
synced 2025-06-16 09:39:09 +00:00
add basic oauth bounces
This commit is contained in:
parent
bebfc862e8
commit
a23184efd2
13 changed files with 262 additions and 1 deletions
10
src/functions/bot-join/README.md
Normal file
10
src/functions/bot-join/README.md
Normal file
|
@ -0,0 +1,10 @@
|
|||
# Bot Join Bounce Service
|
||||
|
||||
This function sends a user to the necessary Discord.com Bot OAuth flow.
|
||||
|
||||
Two cases may be present:
|
||||
|
||||
- General: The user will be sent to allow any of their relevant servers to join
|
||||
- This flow would be triggered from a generalized button
|
||||
- Specific: The user will be sent to join one of their servers.
|
||||
- This flow would be triggered from server picker
|
45
src/functions/bot-join/botjoin.go
Normal file
45
src/functions/bot-join/botjoin.go
Normal file
|
@ -0,0 +1,45 @@
|
|||
package botjoin
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"net/http"
|
||||
"regexp"
|
||||
"text/template"
|
||||
|
||||
"github.com/roleypoly/roleypoly/src/common"
|
||||
"github.com/roleypoly/roleypoly/src/common/faas"
|
||||
)
|
||||
|
||||
var (
|
||||
validGuildID = regexp.MustCompile(`^[0-9]+$`)
|
||||
redirectPathTemplate = template.Must(
|
||||
template.New("redirect").Parse(
|
||||
`https://discord.com/api/oauth2/authorize?client_id={{.ClientID}}&scope=bot&permissions={{.Permissions}}{{if .GuildID}}&guild_id={{.GuildID}}&disable_guild_select=true{{end}}`,
|
||||
),
|
||||
)
|
||||
clientID = common.Getenv("BOT_CLIENT_ID").String()
|
||||
)
|
||||
|
||||
type redirectPathData struct {
|
||||
ClientID string
|
||||
Permissions int
|
||||
GuildID string
|
||||
}
|
||||
|
||||
func BotJoin(rw http.ResponseWriter, r *http.Request) {
|
||||
guildID := r.URL.Query().Get("guild")
|
||||
if !validGuildID.MatchString(guildID) {
|
||||
guildID = ""
|
||||
}
|
||||
|
||||
pathData := redirectPathData{
|
||||
ClientID: clientID,
|
||||
Permissions: 268435456, // MANAGE_ROLES
|
||||
GuildID: guildID,
|
||||
}
|
||||
|
||||
pathBuffer := bytes.Buffer{}
|
||||
redirectPathTemplate.Execute(&pathBuffer, pathData)
|
||||
|
||||
faas.Bounce(rw, pathBuffer.String())
|
||||
}
|
36
src/functions/bot-join/botjoin_test.go
Normal file
36
src/functions/bot-join/botjoin_test.go
Normal file
|
@ -0,0 +1,36 @@
|
|||
package botjoin_test
|
||||
|
||||
import (
|
||||
"net/http/httptest"
|
||||
"testing"
|
||||
|
||||
"github.com/onsi/gomega"
|
||||
botjoin "github.com/roleypoly/roleypoly/src/functions/bot-join"
|
||||
)
|
||||
|
||||
func TestGeneral(t *testing.T) {
|
||||
O := gomega.NewWithT(t)
|
||||
|
||||
req := httptest.NewRequest("GET", "/bot-join", nil)
|
||||
resp := httptest.NewRecorder()
|
||||
|
||||
botjoin.BotJoin(resp, req)
|
||||
|
||||
result := resp.Result()
|
||||
O.Expect(result.StatusCode).Should(gomega.BeIdenticalTo(303))
|
||||
O.Expect(result.Header.Get("location")).ShouldNot(gomega.ContainSubstring("guild_id"))
|
||||
|
||||
}
|
||||
|
||||
func TestGeneralSpecific(t *testing.T) {
|
||||
O := gomega.NewWithT(t)
|
||||
|
||||
req := httptest.NewRequest("GET", "/bot-join?guild=386659935687147521", nil)
|
||||
resp := httptest.NewRecorder()
|
||||
|
||||
botjoin.BotJoin(resp, req)
|
||||
|
||||
result := resp.Result()
|
||||
O.Expect(result.StatusCode).Should(gomega.BeIdenticalTo(303))
|
||||
O.Expect(result.Header.Get("location")).Should(gomega.ContainSubstring("guild_id=386659935687147521"))
|
||||
}
|
|
@ -1,60 +0,0 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"log"
|
||||
"net/http"
|
||||
"os"
|
||||
|
||||
"github.com/GoogleCloudPlatform/functions-framework-go/funcframework"
|
||||
sessiondata "github.com/roleypoly/roleypoly/src/functions/session-data"
|
||||
sessionprewarm "github.com/roleypoly/roleypoly/src/functions/session-prewarm"
|
||||
)
|
||||
|
||||
var mappings map[string]http.HandlerFunc = map[string]http.HandlerFunc{
|
||||
"/session-prewarm": sessionprewarm.SessionPrewarm,
|
||||
"/session-data": sessiondata.SessionData,
|
||||
}
|
||||
|
||||
var port string
|
||||
|
||||
func main() {
|
||||
ctx := context.Background()
|
||||
|
||||
err := funcframework.RegisterHTTPFunctionContext(ctx, "/", rootHandler)
|
||||
if err != nil {
|
||||
log.Fatalf("funcframework.RegisterHTTPFunctionContext: %v\n", err)
|
||||
}
|
||||
|
||||
for path, handler := range mappings {
|
||||
err := funcframework.RegisterHTTPFunctionContext(ctx, path, handler)
|
||||
if err != nil {
|
||||
log.Fatalf("funcframework.RegisterHTTPFunctionContext: %v\n", err)
|
||||
}
|
||||
|
||||
fmt.Println("Added", path)
|
||||
}
|
||||
|
||||
// Use PORT environment variable, or default to 6600.
|
||||
port = "6600"
|
||||
if envPort := os.Getenv("PORT"); envPort != "" {
|
||||
port = envPort
|
||||
}
|
||||
|
||||
fmt.Printf("Starting on http://localhost:%s\n", port)
|
||||
|
||||
if err := funcframework.Start(port); err != nil {
|
||||
log.Fatalf("funcframework.Start: %v\n", err)
|
||||
}
|
||||
}
|
||||
|
||||
func rootHandler(rw http.ResponseWriter, r *http.Request) {
|
||||
body := `<!doctype html><meta charset="utf-8"><title>Roleypoly Functions</title><style>body{font-family: sans-serif; font-size: 1.4em}</style><h1>Function Index</h1>`
|
||||
|
||||
for path := range mappings {
|
||||
body += fmt.Sprintf(`<a href="http://localhost:%s%s">%s</a><br>`, port, path, path)
|
||||
}
|
||||
|
||||
fmt.Fprintln(rw, body)
|
||||
}
|
43
src/functions/login-bounce/loginbounce.go
Normal file
43
src/functions/login-bounce/loginbounce.go
Normal file
|
@ -0,0 +1,43 @@
|
|||
package loginbounce
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"net/http"
|
||||
"text/template"
|
||||
|
||||
"github.com/segmentio/ksuid"
|
||||
|
||||
"github.com/roleypoly/roleypoly/src/common"
|
||||
"github.com/roleypoly/roleypoly/src/common/faas"
|
||||
)
|
||||
|
||||
var (
|
||||
redirectPathTemplate = template.Must(
|
||||
template.New("redirect").Parse(
|
||||
`https://discord.com/api/oauth2/authorize?client_id={{.ClientID}}&scope=identify,guilds&redirect_uri={{.RedirectURI}}&state={{.State}}`,
|
||||
),
|
||||
)
|
||||
clientID = common.Getenv("BOT_CLIENT_ID").String()
|
||||
redirectURI = common.Getenv("OAUTH_REDIRECT_URI").String()
|
||||
)
|
||||
|
||||
type redirectPathData struct {
|
||||
ClientID string
|
||||
RedirectURI string
|
||||
State string
|
||||
}
|
||||
|
||||
func LoginBounce(rw http.ResponseWriter, r *http.Request) {
|
||||
faas.Stash(rw, r.URL.Query().Get("redirect_url"))
|
||||
|
||||
pathData := redirectPathData{
|
||||
ClientID: clientID,
|
||||
RedirectURI: redirectURI,
|
||||
State: ksuid.New().String(),
|
||||
}
|
||||
|
||||
pathBuffer := bytes.Buffer{}
|
||||
redirectPathTemplate.Execute(&pathBuffer, pathData)
|
||||
|
||||
faas.Bounce(rw, pathBuffer.String())
|
||||
}
|
24
src/functions/login-bounce/loginbounce_test.go
Normal file
24
src/functions/login-bounce/loginbounce_test.go
Normal file
|
@ -0,0 +1,24 @@
|
|||
package loginbounce_test
|
||||
|
||||
import (
|
||||
"net/http/httptest"
|
||||
"testing"
|
||||
|
||||
"github.com/onsi/gomega"
|
||||
loginbounce "github.com/roleypoly/roleypoly/src/functions/login-bounce"
|
||||
)
|
||||
|
||||
func TestBounce(t *testing.T) {
|
||||
O := gomega.NewWithT(t)
|
||||
|
||||
req := httptest.NewRequest("GET", "/login-bounce?redirect_url=https://localhost:6600/test", nil)
|
||||
rw := httptest.NewRecorder()
|
||||
|
||||
loginbounce.LoginBounce(rw, req)
|
||||
|
||||
resp := rw.Result()
|
||||
|
||||
O.Expect(resp.StatusCode).Should(gomega.BeIdenticalTo(303))
|
||||
O.Expect(resp.Header.Get("location")).Should(gomega.ContainSubstring("identify,guild"))
|
||||
O.Expect(resp.Header.Get("set-cookie")).Should(gomega.ContainSubstring("https://localhost:6600/test"))
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue