appview: add helper to create ServiceClients #374

merged
opened by oppi.li targeting master from push-vynsusnqpmus
Changed files
+73
appview
oauth
+73
appview/oauth/oauth.go
··· 7 "net/url" 8 "time" 9 10 "github.com/gorilla/sessions" 11 oauth "tangled.sh/icyphox.sh/atproto-oauth" 12 "tangled.sh/icyphox.sh/atproto-oauth/helpers" ··· 206 return xrpcClient, nil 207 } 208 209 type ClientMetadata struct { 210 ClientID string `json:"client_id"` 211 ClientName string `json:"client_name"`
··· 7 "net/url" 8 "time" 9 10 + indigo_xrpc "github.com/bluesky-social/indigo/xrpc" 11 "github.com/gorilla/sessions" 12 oauth "tangled.sh/icyphox.sh/atproto-oauth" 13 "tangled.sh/icyphox.sh/atproto-oauth/helpers" ··· 207 return xrpcClient, nil 208 } 209 210 + // use this to create a client to communicate with knots or spindles 211 + // 212 + // this is a higher level abstraction on ServerGetServiceAuth 213 + type ServiceClientOpts struct { 214 + service string 215 + exp int64 216 + lxm string 217 + dev bool 218 + } 219 + 220 + type ServiceClientOpt func(*ServiceClientOpts) 221 + 222 + func WithService(service string) ServiceClientOpt { 223 + return func(s *ServiceClientOpts) { 224 + s.service = service 225 + } 226 + } 227 + func WithExp(exp int64) ServiceClientOpt { 228 + return func(s *ServiceClientOpts) { 229 + s.exp = exp 230 + } 231 + } 232 + 233 + func WithLxm(lxm string) ServiceClientOpt { 234 + return func(s *ServiceClientOpts) { 235 + s.lxm = lxm 236 + } 237 + } 238 + 239 + func WithDev(dev bool) ServiceClientOpt { 240 + return func(s *ServiceClientOpts) { 241 + s.dev = dev 242 + } 243 + } 244 + 245 + func (s *ServiceClientOpts) Audience() string { 246 + return fmt.Sprintf("did:web:%s", s.service) 247 + } 248 + 249 + func (s *ServiceClientOpts) Host() string { 250 + scheme := "https://" 251 + if s.dev { 252 + scheme = "http://" 253 + } 254 + 255 + return scheme + s.service 256 + } 257 + 258 + func (o *OAuth) ServiceClient(r *http.Request, os ...ServiceClientOpt) (*indigo_xrpc.Client, error) { 259 + opts := ServiceClientOpts{} 260 + for _, o := range os { 261 + o(&opts) 262 + } 263 + 264 + authorizedClient, err := o.AuthorizedClient(r) 265 + if err != nil { 266 + return nil, err 267 + } 268 + 269 + resp, err := authorizedClient.ServerGetServiceAuth(r.Context(), opts.Audience(), opts.exp, opts.lxm) 270 + if err != nil { 271 + return nil, err 272 + } 273 + 274 + return &indigo_xrpc.Client{ 275 + Auth: &indigo_xrpc.AuthInfo{ 276 + AccessJwt: resp.Token, 277 + }, 278 + Host: opts.Host(), 279 + }, nil 280 + } 281 + 282 type ClientMetadata struct { 283 ClientID string `json:"client_id"` 284 ClientName string `json:"client_name"`