···
25
-
ctx = context.Background()
26
-
serverAddr = os.Getenv("OAUTH_TEST_SERVER_ADDR")
27
-
serverUrlRoot = os.Getenv("OAUTH_TEST_SERVER_URL_ROOT")
28
-
staticFilePath = os.Getenv("OAUTH_TEST_SERVER_STATIC_PATH")
29
-
sessionSecret = os.Getenv("OAUTH_TEST_SESSION_SECRET")
30
-
serverMetadataUrl = fmt.Sprintf("%s/oauth/client-metadata.json", serverUrlRoot)
31
-
serverCallbackUrl = fmt.Sprintf("%s/callback", serverUrlRoot)
32
-
pdsUrl = os.Getenv("OAUTH_TEST_PDS_URL")
33
-
scope = "atproto transition:generic"
25
+
ctx = context.Background()
26
+
serverMetadataPath = "/oauth/client-metadata.json"
27
+
serverCallbackPath = "/callback"
28
+
scope = "atproto transition:generic"
Name: "atproto-goauth-demo-webserver",
42
-
if serverUrlRoot == "" {
43
-
panic(fmt.Errorf("no server url root set in env file"))
39
+
EnvVars: []string{"OAUTH_TEST_SERVER_ADDR"},
44
+
EnvVars: []string{"OAUTH_TEST_SERVER_URL_ROOT"},
47
+
Name: "static-file-path",
48
+
Value: "./cmd/web_server_demo/html",
49
+
EnvVars: []string{"OAUTH_TEST_SERVER_STATIC_PATH"},
52
+
Name: "session-secret",
53
+
Value: "session-secret",
54
+
EnvVars: []string{"OAUTH_TEST_SERVER_SESSION_SECRET"},
46
-
app.RunAndExitOnError()
···
oauthClient *oauth.Client
xrpcCli *oauth.XrpcClient
jwksResponse *oauth_helpers.JwksResponseObject
type TemplateRenderer struct {
templates *template.Template
62
-
func (t *TemplateRenderer) Render(w io.Writer, name string, data interface{}, c echo.Context) error {
63
-
if viewContext, isMap := data.(map[string]interface{}); isMap {
76
+
func (t *TemplateRenderer) Render(w io.Writer, name string, data any, c echo.Context) error {
77
+
if viewContext, isMap := data.(map[string]any); isMap {
viewContext["reverse"] = c.Echo().Reverse
···
func run(cmd *cli.Context) error {
71
-
s, err := NewServer()
85
+
s, err := NewServer(ServerArgs{
86
+
Addr: cmd.String("addr"),
87
+
UrlRoot: cmd.String("url-root"),
88
+
StaticFilePath: cmd.String("static-file-path"),
89
+
SessionSecret: cmd.String("session-secret"),
···
81
-
func NewServer() (*TestServer, error) {
100
+
type ServerArgs struct {
103
+
StaticFilePath string
104
+
SessionSecret string
107
+
func NewServer(args ServerArgs) (*TestServer, error) {
e.Use(slogecho.New(slog.Default()))
85
-
e.Use(session.Middleware(sessions.NewCookieStore([]byte(sessionSecret))))
87
-
renderer := &TemplateRenderer{
88
-
templates: template.Must(template.ParseGlob(getFilePath("*.html"))),
90
-
e.Renderer = renderer
111
+
e.Use(session.Middleware(sessions.NewCookieStore([]byte(args.SessionSecret))))
fmt.Println("atproto goauth demo webserver")
···
c, err := oauth.NewClient(oauth.ClientArgs{
116
-
ClientId: serverMetadataUrl,
117
-
RedirectUri: serverCallbackUrl,
137
+
ClientId: args.UrlRoot + serverMetadataPath,
138
+
RedirectUri: args.UrlRoot + serverCallbackPath,
···
143
-
return &TestServer{
jwksResponse: oauth_helpers.CreateJwksResponseObject(pubKey),
174
+
renderer := &TemplateRenderer{
175
+
templates: template.Must(template.ParseGlob(s.getFilePath("*.html"))),
177
+
e.Renderer = renderer
func (s *TestServer) run() error {
s.e.GET("/", s.handleHome)
155
-
s.e.File("/login", getFilePath("login.html"))
184
+
s.e.File("/login", s.getFilePath("login.html"))
s.e.POST("/login", s.handleLoginSubmit)
s.e.GET("/logout", s.handleLogout)
s.e.GET("/profile", s.handleProfile)
···
s.e.GET("/oauth/client-metadata.json", s.handleClientMetadata)
s.e.GET("/oauth/jwks.json", s.handleJwks)
193
+
slog.Default().Info("starting http server", "addr", s.args.Addr)
if err := s.httpd.ListenAndServe(); err != nil {
···
func (s *TestServer) handleClientMetadata(e echo.Context) error {
metadata := map[string]any{
184
-
"client_id": serverMetadataUrl,
215
+
"client_id": s.args.UrlRoot + serverMetadataPath,
"client_name": "Atproto GoAuth Demo Webserver",
186
-
"client_uri": serverUrlRoot,
187
-
"logo_uri": fmt.Sprintf("%s/logo.png", serverUrlRoot),
188
-
"tos_uri": fmt.Sprintf("%s/tos", serverUrlRoot),
189
-
"policy_url": fmt.Sprintf("%s/policy", serverUrlRoot),
190
-
"redirect_uris": []string{serverCallbackUrl},
217
+
"client_uri": s.args.UrlRoot,
218
+
"logo_uri": fmt.Sprintf("%s/logo.png", s.args.UrlRoot),
219
+
"tos_uri": fmt.Sprintf("%s/tos", s.args.UrlRoot),
220
+
"policy_url": fmt.Sprintf("%s/policy", s.args.UrlRoot),
221
+
"redirect_uris": []string{s.args.UrlRoot + serverCallbackPath},
"grant_types": []string{"authorization_code", "refresh_token"},
"response_types": []string{"code"},
"application_type": "web",
"dpop_bound_access_tokens": true,
195
-
"jwks_uri": fmt.Sprintf("%s/oauth/jwks.json", serverUrlRoot),
226
+
"jwks_uri": fmt.Sprintf("%s/oauth/jwks.json", s.args.UrlRoot),
"scope": "atproto transition:generic",
"token_endpoint_auth_method": "private_key_jwt",
"token_endpoint_auth_signing_alg": "ES256",
···
return e.JSON(200, s.jwksResponse)
208
-
func getFilePath(file string) string {
209
-
return fmt.Sprintf("%s/%s", staticFilePath, file)
239
+
func (s *TestServer) getFilePath(file string) string {
240
+
return fmt.Sprintf("%s/%s", s.args.StaticFilePath, file)