Live video on the AT Protocol
1package oproxy
2
3import (
4 "log/slog"
5 "net/http"
6 "os"
7
8 "github.com/labstack/echo/v4"
9 "github.com/lestrrat-go/jwx/v2/jwk"
10)
11
12type OProxy struct {
13 createOAuthSession func(id string, session *OAuthSession) error
14 updateOAuthSession func(id string, session *OAuthSession) error
15 userLoadOAuthSession func(id string) (*OAuthSession, error)
16 e *echo.Echo
17 host string
18 scope string
19 upstreamJWK jwk.Key
20 downstreamJWK jwk.Key
21 slog *slog.Logger
22}
23
24type Config struct {
25 CreateOAuthSession func(id string, session *OAuthSession) error
26 UpdateOAuthSession func(id string, session *OAuthSession) error
27 LoadOAuthSession func(id string) (*OAuthSession, error)
28 Host string
29 Scope string
30 UpstreamJWK jwk.Key
31 DownstreamJWK jwk.Key
32 Slog *slog.Logger
33}
34
35func New(conf *Config) *OProxy {
36 e := echo.New()
37 mySlog := conf.Slog
38 if mySlog == nil {
39 mySlog = slog.New(slog.NewTextHandler(os.Stderr, nil))
40 }
41 o := &OProxy{
42 createOAuthSession: conf.CreateOAuthSession,
43 updateOAuthSession: conf.UpdateOAuthSession,
44 userLoadOAuthSession: conf.LoadOAuthSession,
45 e: e,
46 host: conf.Host,
47 scope: conf.Scope,
48 upstreamJWK: conf.UpstreamJWK,
49 downstreamJWK: conf.DownstreamJWK,
50 slog: mySlog,
51 }
52 o.e.GET("/.well-known/oauth-authorization-server", o.HandleOAuthAuthorizationServer)
53 o.e.GET("/.well-known/oauth-protected-resource", o.HandleOAuthProtectedResource)
54 o.e.POST("/oauth/par", o.HandleOAuthPAR)
55 o.e.GET("/oauth/authorize", o.HandleOAuthAuthorize)
56 o.e.GET("/oauth/return", o.HandleOAuthReturn)
57 o.e.POST("/oauth/token", o.DPoPNonceMiddleware(o.HandleOAuthToken))
58 o.e.POST("/oauth/revoke", o.DPoPNonceMiddleware(o.HandleOAuthRevoke))
59 o.e.GET("/oauth/upstream/client-metadata.json", o.HandleClientMetadataUpstream)
60 o.e.GET("/oauth/upstream/jwks.json", o.HandleJwksUpstream)
61 o.e.GET("/oauth/downstream/client-metadata.json", o.HandleClientMetadataDownstream)
62 o.e.Use(o.ErrorHandlingMiddleware)
63 return o
64}
65
66func (o *OProxy) Handler() http.Handler {
67 return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
68 w.Header().Set("Access-Control-Allow-Origin", "*") // todo: ehhhhhhhhhhhh
69 w.Header().Set("Access-Control-Allow-Headers", "Content-Type,DPoP")
70 w.Header().Set("Access-Control-Allow-Methods", "*")
71 w.Header().Set("Access-Control-Expose-Headers", "DPoP-Nonce")
72 o.e.ServeHTTP(w, r)
73 })
74}