mirror of
https://github.com/roleypoly/roleypoly.git
synced 2025-04-24 19:39:11 +00:00
feat: add skeleton of discord-auth, resolve gazelle issues.. again
This commit is contained in:
parent
deb6c194e9
commit
fce28b5b37
19 changed files with 257 additions and 23 deletions
6
deps.bzl
6
deps.bzl
|
@ -499,6 +499,12 @@ def go_repositories():
|
|||
sum = "h1:lPqVAte+HuHNfhJ/0LC98ESWRz8afy9tM/0RK8m9o+Q=",
|
||||
version = "v2.0.1",
|
||||
)
|
||||
go_repository(
|
||||
name = "com_github_segmentio_ksuid",
|
||||
importpath = "github.com/segmentio/ksuid",
|
||||
sum = "h1:FoResxvleQwYiPAVKe1tMUlEirodZqlqglIuFsdDntY=",
|
||||
version = "v1.0.3",
|
||||
)
|
||||
go_repository(
|
||||
name = "com_github_shurcool_sanitized_anchor_name",
|
||||
importpath = "github.com/shurcooL/sanitized_anchor_name",
|
||||
|
|
2
go.mod
2
go.mod
|
@ -6,8 +6,10 @@ require (
|
|||
github.com/bwmarrin/discordgo v0.22.0
|
||||
github.com/facebook/ent v0.4.3
|
||||
github.com/joho/godotenv v1.3.0
|
||||
github.com/julienschmidt/httprouter v1.2.0
|
||||
github.com/lampjaw/discordclient v0.0.0-20200923011548-6558fc9e89df
|
||||
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e // indirect
|
||||
github.com/segmentio/ksuid v1.0.3
|
||||
go.uber.org/fx v1.13.1
|
||||
go.uber.org/multierr v1.6.0 // indirect
|
||||
golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a // indirect
|
||||
|
|
|
@ -36,10 +36,10 @@ go_library(
|
|||
"//src/db/ent/predicate",
|
||||
"//src/db/ent/schema",
|
||||
"//src/db/ent/session",
|
||||
"@com_github_facebook_ent//:go_default_library",
|
||||
"@com_github_facebook_ent//dialect:go_default_library",
|
||||
"@com_github_facebook_ent//dialect/sql:go_default_library",
|
||||
"@com_github_facebook_ent//dialect/sql/sqlgraph:go_default_library",
|
||||
"@com_github_facebook_ent//schema/field:go_default_library",
|
||||
"@com_github_facebook_ent//:ent",
|
||||
"@com_github_facebook_ent//dialect",
|
||||
"@com_github_facebook_ent//dialect/sql",
|
||||
"@com_github_facebook_ent//dialect/sql/sqlgraph",
|
||||
"@com_github_facebook_ent//schema/field",
|
||||
],
|
||||
)
|
||||
|
|
|
@ -10,6 +10,6 @@ go_library(
|
|||
visibility = ["//visibility:public"],
|
||||
deps = [
|
||||
"//src/db/ent/predicate",
|
||||
"@com_github_facebook_ent//dialect/sql:go_default_library",
|
||||
"@com_github_facebook_ent//dialect/sql",
|
||||
],
|
||||
)
|
||||
|
|
|
@ -8,6 +8,6 @@ go_library(
|
|||
deps = [
|
||||
"//src/db/ent",
|
||||
"//src/db/ent/runtime",
|
||||
"@com_github_facebook_ent//dialect/sql/schema:go_default_library",
|
||||
"@com_github_facebook_ent//dialect/sql/schema",
|
||||
],
|
||||
)
|
||||
|
|
|
@ -10,6 +10,6 @@ go_library(
|
|||
visibility = ["//visibility:public"],
|
||||
deps = [
|
||||
"//src/db/ent/predicate",
|
||||
"@com_github_facebook_ent//dialect/sql:go_default_library",
|
||||
"@com_github_facebook_ent//dialect/sql",
|
||||
],
|
||||
)
|
||||
|
|
|
@ -9,8 +9,8 @@ go_library(
|
|||
importpath = "github.com/roleypoly/roleypoly/src/db/ent/migrate",
|
||||
visibility = ["//visibility:public"],
|
||||
deps = [
|
||||
"@com_github_facebook_ent//dialect:go_default_library",
|
||||
"@com_github_facebook_ent//dialect/sql/schema:go_default_library",
|
||||
"@com_github_facebook_ent//schema/field:go_default_library",
|
||||
"@com_github_facebook_ent//dialect",
|
||||
"@com_github_facebook_ent//dialect/sql/schema",
|
||||
"@com_github_facebook_ent//schema/field",
|
||||
],
|
||||
)
|
||||
|
|
|
@ -5,5 +5,5 @@ go_library(
|
|||
srcs = ["predicate.go"],
|
||||
importpath = "github.com/roleypoly/roleypoly/src/db/ent/predicate",
|
||||
visibility = ["//visibility:public"],
|
||||
deps = ["@com_github_facebook_ent//dialect/sql:go_default_library"],
|
||||
deps = ["@com_github_facebook_ent//dialect/sql"],
|
||||
)
|
||||
|
|
|
@ -10,8 +10,8 @@ go_library(
|
|||
importpath = "github.com/roleypoly/roleypoly/src/db/ent/schema",
|
||||
visibility = ["//visibility:public"],
|
||||
deps = [
|
||||
"@com_github_facebook_ent//:go_default_library",
|
||||
"@com_github_facebook_ent//schema/field:go_default_library",
|
||||
"@com_github_facebook_ent//schema/mixin:go_default_library",
|
||||
"@com_github_facebook_ent//:ent",
|
||||
"@com_github_facebook_ent//schema/field",
|
||||
"@com_github_facebook_ent//schema/mixin",
|
||||
],
|
||||
)
|
||||
|
|
|
@ -10,6 +10,6 @@ go_library(
|
|||
visibility = ["//visibility:public"],
|
||||
deps = [
|
||||
"//src/db/ent/predicate",
|
||||
"@com_github_facebook_ent//dialect/sql:go_default_library",
|
||||
"@com_github_facebook_ent//dialect/sql",
|
||||
],
|
||||
)
|
||||
|
|
|
@ -7,7 +7,13 @@ go_library(
|
|||
srcs = ["discord-auth.go"],
|
||||
importpath = "github.com/roleypoly/roleypoly/src/discord-auth",
|
||||
visibility = ["//visibility:private"],
|
||||
deps = ["@org_uber_go_fx//:go_default_library"],
|
||||
deps = [
|
||||
"//src/common/version",
|
||||
"//src/discord-auth/http",
|
||||
"@com_github_julienschmidt_httprouter//:httprouter",
|
||||
"@io_k8s_klog//:klog",
|
||||
"@org_uber_go_fx//:fx",
|
||||
],
|
||||
)
|
||||
|
||||
go_binary(
|
||||
|
|
21
src/discord-auth/README.md
Normal file
21
src/discord-auth/README.md
Normal file
|
@ -0,0 +1,21 @@
|
|||
# Discord Auth
|
||||
|
||||
Service for handling Discord OAuth flow.
|
||||
|
||||
## Responsibilities
|
||||
|
||||
- Redirect users to relevant Discord OAuth page w/ state
|
||||
- Handle redirect from Discord OAuth flow and process the token
|
||||
- Modify active session to include relevant data
|
||||
- v3: for parity, this is just user data
|
||||
- _vNext: get guilds from oauth and cache_
|
||||
- _vNext: Source of truth for user guilds_
|
||||
|
||||
## Boundaries & Services
|
||||
|
||||
- **Inbound**
|
||||
- HTTP: /discord-auth/\*
|
||||
- gRPC: DiscordAuthService
|
||||
- **Outbound**
|
||||
- Redis
|
||||
- gRPC: SessionService
|
|
@ -1,11 +1,54 @@
|
|||
package main
|
||||
|
||||
import "go.uber.org/fx"
|
||||
import (
|
||||
"context"
|
||||
"net/http"
|
||||
|
||||
"github.com/julienschmidt/httprouter"
|
||||
"go.uber.org/fx"
|
||||
"k8s.io/klog"
|
||||
|
||||
"github.com/roleypoly/roleypoly/src/common/version"
|
||||
httpservice "github.com/roleypoly/roleypoly/src/discord-auth/http"
|
||||
)
|
||||
|
||||
func main() {
|
||||
klog.Info(version.StartupInfo("discord-auth"))
|
||||
|
||||
app := fx.New(
|
||||
// fx.Invoke(StartDiscordAuthService),
|
||||
fx.Provide(
|
||||
httprouter.New,
|
||||
httpservice.NewHTTPService,
|
||||
),
|
||||
fx.Invoke(
|
||||
httpservice.RegisterRoutes,
|
||||
newHTTPServer,
|
||||
),
|
||||
)
|
||||
|
||||
app.Run()
|
||||
}
|
||||
|
||||
func newHTTPServer(lc fx.Lifecycle, router *httprouter.Router) *http.Server {
|
||||
server := &http.Server{
|
||||
Addr: ":8080",
|
||||
Handler: router,
|
||||
}
|
||||
|
||||
lc.Append(fx.Hook{
|
||||
OnStart: func(context.Context) error {
|
||||
klog.Info("Starting HTTP Server")
|
||||
go server.ListenAndServe()
|
||||
|
||||
return nil
|
||||
},
|
||||
OnStop: func(ctx context.Context) error {
|
||||
klog.Info("Stopping HTTP Server")
|
||||
return server.Shutdown(ctx)
|
||||
},
|
||||
})
|
||||
|
||||
return server
|
||||
}
|
||||
|
||||
func startupHTTP()
|
||||
|
|
25
src/discord-auth/http/BUILD.bazel
Normal file
25
src/discord-auth/http/BUILD.bazel
Normal file
|
@ -0,0 +1,25 @@
|
|||
load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test")
|
||||
|
||||
go_library(
|
||||
name = "http",
|
||||
srcs = [
|
||||
"httpservice.go",
|
||||
"oauth.go",
|
||||
],
|
||||
importpath = "github.com/roleypoly/roleypoly/src/discord-auth/http",
|
||||
visibility = ["//visibility:public"],
|
||||
deps = [
|
||||
"@com_github_julienschmidt_httprouter//:httprouter",
|
||||
"@com_github_segmentio_ksuid//:ksuid",
|
||||
],
|
||||
)
|
||||
|
||||
go_test(
|
||||
name = "http_test",
|
||||
srcs = [
|
||||
"httpservice_test.go",
|
||||
"oauth_test.go",
|
||||
],
|
||||
embed = [":http"],
|
||||
deps = ["@com_github_julienschmidt_httprouter//:httprouter"],
|
||||
)
|
34
src/discord-auth/http/httpservice.go
Normal file
34
src/discord-auth/http/httpservice.go
Normal file
|
@ -0,0 +1,34 @@
|
|||
package httpservice
|
||||
|
||||
import "github.com/julienschmidt/httprouter"
|
||||
|
||||
type HTTPService struct {
|
||||
config struct {
|
||||
ClientID string
|
||||
PublicURL string
|
||||
}
|
||||
}
|
||||
|
||||
func NewHTTPService() *HTTPService {
|
||||
return &HTTPService{}
|
||||
}
|
||||
|
||||
func RegisterRoutes(s *HTTPService, router *httprouter.Router) {
|
||||
s.RegisterRoutes(router)
|
||||
}
|
||||
|
||||
func (h *HTTPService) RegisterRoutes(router *httprouter.Router) {
|
||||
router.GET(h.v3("/oauth-handoff"), h.oauthHandoffv3)
|
||||
}
|
||||
|
||||
func (*HTTPService) v3(path string) string {
|
||||
return `/discord-auth/v3` + path
|
||||
}
|
||||
|
||||
func (*HTTPService) v4(path string) string {
|
||||
return `/discord-auth/v4` + path
|
||||
}
|
||||
|
||||
func (h *HTTPService) getOauthRedirectURL() string {
|
||||
return h.config.PublicURL + h.v3("/oauth-callback")
|
||||
}
|
43
src/discord-auth/http/httpservice_test.go
Normal file
43
src/discord-auth/http/httpservice_test.go
Normal file
|
@ -0,0 +1,43 @@
|
|||
package httpservice
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/julienschmidt/httprouter"
|
||||
)
|
||||
|
||||
func TestV3Route(t *testing.T) {
|
||||
s := &HTTPService{}
|
||||
url := s.v3("/test")
|
||||
if url != "/discord-auth/v3/test" {
|
||||
t.FailNow()
|
||||
}
|
||||
}
|
||||
|
||||
func TestV4Route(t *testing.T) {
|
||||
s := &HTTPService{}
|
||||
url := s.v4("/test")
|
||||
if url != "/discord-auth/v4/test" {
|
||||
t.FailNow()
|
||||
}
|
||||
}
|
||||
|
||||
func TestRegisterRoutes(t *testing.T) {
|
||||
s := NewHTTPService()
|
||||
r := httprouter.New()
|
||||
RegisterRoutes(s, r)
|
||||
}
|
||||
|
||||
func TestOauthRedirectURL(t *testing.T) {
|
||||
s := &HTTPService{
|
||||
config: struct{ ClientID, PublicURL string }{
|
||||
ClientID: "",
|
||||
PublicURL: "https://roleypoly.local",
|
||||
},
|
||||
}
|
||||
|
||||
url := s.getOauthRedirectURL()
|
||||
if url != "https://roleypoly.local/discord-auth/v3/oauth-callback" {
|
||||
t.FailNow()
|
||||
}
|
||||
}
|
25
src/discord-auth/http/oauth.go
Normal file
25
src/discord-auth/http/oauth.go
Normal file
|
@ -0,0 +1,25 @@
|
|||
package httpservice
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
|
||||
"github.com/julienschmidt/httprouter"
|
||||
"github.com/segmentio/ksuid"
|
||||
)
|
||||
|
||||
// Handles flow start request by redirecting the user to Discord OAuth page
|
||||
func (h *HTTPService) oauthHandoffv3(rw http.ResponseWriter, r *http.Request, _ httprouter.Params) {
|
||||
// TODO: actually create and store this state
|
||||
requestState := ksuid.New().String()
|
||||
|
||||
redirectURL := fmt.Sprintf(
|
||||
`https://discord.com/oauth2/authorize?client_id=%s&redirect_uri=%s&response_type=code&scope=identify&state=%s`,
|
||||
h.config.ClientID,
|
||||
h.getOauthRedirectURL(),
|
||||
requestState,
|
||||
)
|
||||
|
||||
rw.Header().Add("location", redirectURL)
|
||||
rw.WriteHeader(303)
|
||||
}
|
29
src/discord-auth/http/oauth_test.go
Normal file
29
src/discord-auth/http/oauth_test.go
Normal file
|
@ -0,0 +1,29 @@
|
|||
package httpservice
|
||||
|
||||
import (
|
||||
"net/http/httptest"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/julienschmidt/httprouter"
|
||||
)
|
||||
|
||||
func TestOauthHandoffV3(t *testing.T) {
|
||||
s := NewHTTPService()
|
||||
s.config.ClientID = "test1234"
|
||||
s.config.PublicURL = "https://roleypoly.test"
|
||||
|
||||
rw := httptest.NewRecorder()
|
||||
r := httptest.NewRequest("GET", s.v3("/oauth-handoff"), nil)
|
||||
ps := httprouter.Params{}
|
||||
s.oauthHandoffv3(rw, r, ps)
|
||||
|
||||
if rw.Result().StatusCode != 303 {
|
||||
t.Error("Status code was not 303, got ", rw.Result().StatusCode)
|
||||
}
|
||||
|
||||
if !strings.Contains(rw.Result().Header.Get("location"), s.config.ClientID) &&
|
||||
!strings.Contains(rw.Result().Header.Get("location"), s.getOauthRedirectURL()) {
|
||||
t.Error("Location was not correct, got ", rw.Result().Header.Get("location"))
|
||||
}
|
||||
}
|
|
@ -13,10 +13,10 @@ go_library(
|
|||
deps = [
|
||||
"//src/common/version",
|
||||
"//src/discord-bot/internal/strings",
|
||||
"@com_github_bwmarrin_discordgo//:go_default_library",
|
||||
"@com_github_joho_godotenv//autoload:go_default_library",
|
||||
"@com_github_lampjaw_discordclient//:go_default_library",
|
||||
"@io_k8s_klog//:go_default_library",
|
||||
"@com_github_bwmarrin_discordgo//:discordgo",
|
||||
"@com_github_joho_godotenv//autoload",
|
||||
"@com_github_lampjaw_discordclient//:discordclient",
|
||||
"@io_k8s_klog//:klog",
|
||||
],
|
||||
)
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue