this repo has no description
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

cleanup stuff

Hailey e39d8a88 8f8a47fd

+66 -89
+2 -2
cmd/client_test/main.go
··· 50 50 httpd *http.Server 51 51 e *echo.Echo 52 52 db *gorm.DB 53 - oauthClient *oauth.OauthClient 53 + oauthClient *oauth.Client 54 54 xrpcCli *oauth.XrpcClient 55 55 jwksResponse *oauth.JwksResponseObject 56 56 } ··· 111 111 return nil, err 112 112 } 113 113 114 - c, err := oauth.NewOauthClient(oauth.OauthClientArgs{ 114 + c, err := oauth.NewClient(oauth.ClientArgs{ 115 115 ClientJwk: k, 116 116 ClientId: serverMetadataUrl, 117 117 RedirectUri: serverCallbackUrl,
+2 -1
go.mod
··· 4 4 5 5 require ( 6 6 github.com/bluesky-social/indigo v0.0.0-20250301025210-a4e0cc37e188 7 + github.com/carlmjohnson/versioninfo v0.22.5 7 8 github.com/golang-jwt/jwt/v5 v5.2.1 8 9 github.com/google/uuid v1.6.0 9 10 github.com/gorilla/sessions v1.4.0 ··· 14 15 github.com/samber/slog-echo v1.15.1 15 16 github.com/stretchr/testify v1.10.0 16 17 github.com/urfave/cli/v2 v2.27.5 18 + golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa 17 19 gorm.io/driver/sqlite v1.5.7 18 20 gorm.io/gorm v1.25.9 19 21 ) 20 22 21 23 require ( 22 - github.com/carlmjohnson/versioninfo v0.22.5 // indirect 23 24 github.com/cpuguy83/go-md2man/v2 v2.0.5 // indirect 24 25 github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect 25 26 github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0 // indirect
+2
go.sum
··· 232 232 golang.org/x/crypto v0.12.0/go.mod h1:NF0Gs7EO5K4qLn+Ylc+fih8BSTeIjAP05siRnAh98yw= 233 233 golang.org/x/crypto v0.31.0 h1:ihbySMvVjLAeSH1IbfcRTkD/iNscyz8rGzjF/E5hV6U= 234 234 golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk= 235 + golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa h1:FRnLl4eNAQl8hwxVVC17teOw8kdjVDVAiFMtgUdTSRQ= 236 + golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa/go.mod h1:zk2irFbV9DP96SEBUUAy67IdHUaZuSnrz1n472HUCLE= 235 237 golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= 236 238 golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= 237 239 golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
-11
helpers.go
··· 1 - package oauth 2 - 3 - func tokenInSet(tok string, set []string) bool { 4 - for _, setTok := range set { 5 - if tok == setTok { 6 - return true 7 - } 8 - } 9 - 10 - return false 11 - }
+16 -51
oauth.go
··· 20 20 "github.com/lestrrat-go/jwx/v2/jwk" 21 21 ) 22 22 23 - type OauthClient struct { 23 + type Client struct { 24 24 h *http.Client 25 25 clientPrivateKey *ecdsa.PrivateKey 26 26 clientKid string ··· 28 28 redirectUri string 29 29 } 30 30 31 - type OauthClientArgs struct { 31 + type ClientArgs struct { 32 32 H *http.Client 33 33 ClientJwk jwk.Key 34 34 ClientId string 35 35 RedirectUri string 36 36 } 37 37 38 - func NewOauthClient(args OauthClientArgs) (*OauthClient, error) { 38 + func NewClient(args ClientArgs) (*Client, error) { 39 39 if args.ClientId == "" { 40 40 return nil, fmt.Errorf("no client id provided") 41 41 } ··· 57 57 58 58 kid := args.ClientJwk.KeyID() 59 59 60 - return &OauthClient{ 60 + return &Client{ 61 61 h: args.H, 62 62 clientKid: kid, 63 63 clientPrivateKey: clientPkey, ··· 66 66 }, nil 67 67 } 68 68 69 - func (c *OauthClient) ResolvePDSAuthServer(ctx context.Context, ustr string) (string, error) { 69 + func (c *Client) ResolvePDSAuthServer(ctx context.Context, ustr string) (string, error) { 70 70 u, err := isSafeAndParsed(ustr) 71 71 if err != nil { 72 72 return "", err ··· 107 107 return resource.AuthorizationServers[0], nil 108 108 } 109 109 110 - func (c *OauthClient) FetchAuthServerMetadata( 111 - ctx context.Context, 112 - ustr string, 113 - ) (*OauthAuthorizationMetadata, error) { 110 + func (c *Client) FetchAuthServerMetadata(ctx context.Context, ustr string) (*OauthAuthorizationMetadata, error) { 114 111 u, err := isSafeAndParsed(ustr) 115 112 if err != nil { 116 113 return nil, err ··· 154 151 return &metadata, nil 155 152 } 156 153 157 - func (c *OauthClient) ClientAssertionJwt(authServerUrl string) (string, error) { 154 + func (c *Client) ClientAssertionJwt(authServerUrl string) (string, error) { 158 155 claims := jwt.MapClaims{ 159 156 "iss": c.clientId, 160 157 "sub": c.clientId, ··· 174 171 return tokenString, nil 175 172 } 176 173 177 - func (c *OauthClient) AuthServerDpopJwt(method, url, nonce string, privateJwk jwk.Key) (string, error) { 174 + func (c *Client) AuthServerDpopJwt(method, url, nonce string, privateJwk jwk.Key) (string, error) { 178 175 pubJwk, err := privateJwk.PublicKey() 179 176 if err != nil { 180 177 return "", err ··· 222 219 return tokenString, nil 223 220 } 224 221 225 - type SendParAuthResponse struct { 226 - PkceVerifier string 227 - State string 228 - DpopAuthserverNonce string 229 - Resp map[string]any 230 - } 231 - 232 - func (c *OauthClient) SendParAuthRequest(ctx context.Context, authServerUrl string, authServerMeta *OauthAuthorizationMetadata, loginHint, scope string, dpopPrivateKey jwk.Key) (*SendParAuthResponse, error) { 222 + func (c *Client) SendParAuthRequest(ctx context.Context, authServerUrl string, authServerMeta *OauthAuthorizationMetadata, loginHint, scope string, dpopPrivateKey jwk.Key) (*SendParAuthResponse, error) { 233 223 if authServerMeta == nil { 234 224 return nil, fmt.Errorf("nil metadata provided") 235 225 } ··· 330 320 if err := json.NewDecoder(resp2.Body).Decode(&rmap); err != nil { 331 321 return nil, err 332 322 } 333 - 334 - fmt.Println(rmap) 335 323 } 336 324 337 325 return &SendParAuthResponse{ ··· 342 330 }, nil 343 331 } 344 332 345 - type TokenResponse struct { 346 - DpopAuthserverNonce string 347 - Resp map[string]any 348 - } 349 - 350 - func (c *OauthClient) InitialTokenRequest( 333 + func (c *Client) InitialTokenRequest( 351 334 ctx context.Context, 352 335 code, 353 336 appUrl, ··· 405 388 } 406 389 defer resp.Body.Close() 407 390 408 - // TODO: use nonce if needed, same as in par 409 - 410 391 var rmap map[string]any 411 392 if err := json.NewDecoder(resp.Body).Decode(&rmap); err != nil { 412 393 return nil, err ··· 418 399 }, nil 419 400 } 420 401 421 - type RefreshTokenArgs struct { 422 - AuthserverUrl string 423 - RefreshToken string 424 - DpopPrivateJwk string 425 - DpopAuthserverNonce string 426 - } 427 - 428 - func (c *OauthClient) RefreshTokenRequest( 429 - ctx context.Context, 430 - args RefreshTokenArgs, 431 - appUrl string, 432 - ) (any, error) { 433 - authserverMeta, err := c.FetchAuthServerMetadata(ctx, args.AuthserverUrl) 402 + func (c *Client) RefreshTokenRequest(ctx context.Context, authserverUrl, refreshToken, dpopAuthserverNonce string, dpopPrivateJwk jwk.Key) (*TokenResponse, error) { 403 + authserverMeta, err := c.FetchAuthServerMetadata(ctx, authserverUrl) 434 404 if err != nil { 435 405 return nil, err 436 406 } 437 407 438 - clientAssertion, err := c.ClientAssertionJwt(args.AuthserverUrl) 408 + clientAssertion, err := c.ClientAssertionJwt(authserverUrl) 439 409 if err != nil { 440 410 return nil, err 441 411 } ··· 443 413 params := url.Values{ 444 414 "client_id": {c.clientId}, 445 415 "grant_type": {"refresh_token"}, 446 - "refresh_token": {args.RefreshToken}, 416 + "refresh_token": {refreshToken}, 447 417 "client_assertion_type": {"urn:ietf:params:oauth:client-assertion-type:jwt-bearer"}, 448 418 "client_assertion": {clientAssertion}, 449 419 } 450 420 451 - dpopPrivateJwk, err := parsePrivateJwkFromString(args.DpopPrivateJwk) 452 - if err != nil { 453 - return nil, err 454 - } 455 - 456 421 dpopProof, err := c.AuthServerDpopJwt( 457 422 "POST", 458 423 authserverMeta.TokenEndpoint, 459 - args.DpopAuthserverNonce, 424 + dpopAuthserverNonce, 460 425 dpopPrivateJwk, 461 426 ) 462 427 if err != nil { ··· 495 460 } 496 461 497 462 return &TokenResponse{ 498 - DpopAuthserverNonce: args.DpopAuthserverNonce, 463 + DpopAuthserverNonce: dpopAuthserverNonce, 499 464 Resp: rmap, 500 465 }, nil 501 466 }
+2 -2
oauth_test.go
··· 21 21 pdsUrl = os.Getenv("OAUTH_TEST_PDS_URL") 22 22 ) 23 23 24 - func newTestOauthClient() *OauthClient { 24 + func newTestOauthClient() *Client { 25 25 b, err := os.ReadFile("./jwks.json") 26 26 if err != nil { 27 27 panic(err) ··· 32 32 panic(err) 33 33 } 34 34 35 - c, err := NewOauthClient(OauthClientArgs{ 35 + c, err := NewClient(ClientArgs{ 36 36 ClientJwk: k, 37 37 ClientId: serverMetadataUrl, 38 38 RedirectUri: serverCallbackUrl,
+42 -22
types.go
··· 4 4 "encoding/json" 5 5 "fmt" 6 6 "net/url" 7 + "slices" 7 8 ) 9 + 10 + type TokenResponse struct { 11 + DpopAuthserverNonce string 12 + Resp map[string]any 13 + } 14 + 15 + type RefreshTokenArgs struct { 16 + AuthserverUrl string 17 + RefreshToken string 18 + DpopPrivateJwk string 19 + DpopAuthserverNonce string 20 + } 21 + 22 + type SendParAuthResponse struct { 23 + PkceVerifier string 24 + State string 25 + DpopAuthserverNonce string 26 + Resp map[string]any 27 + } 8 28 9 29 type OauthProtectedResource struct { 10 30 Resource string `json:"resource"` ··· 58 78 ClientIDMetadataDocumentSupported bool `json:"client_id_metadata_document_supported"` 59 79 } 60 80 81 + func (oam *OauthAuthorizationMetadata) UnmarshalJSON(b []byte) error { 82 + type Tmp OauthAuthorizationMetadata 83 + var tmp Tmp 84 + 85 + if err := json.Unmarshal(b, &tmp); err != nil { 86 + return err 87 + } 88 + 89 + *oam = OauthAuthorizationMetadata(tmp) 90 + 91 + return nil 92 + } 93 + 61 94 func (oam *OauthAuthorizationMetadata) Validate(fetch_url *url.URL) error { 62 95 if fetch_url == nil { 63 96 return fmt.Errorf("fetch_url was nil") ··· 88 121 return fmt.Errorf("issuer url params are not empty") 89 122 } 90 123 91 - if !tokenInSet("code", oam.ResponseTypesSupported) { 124 + if !slices.Contains(oam.ResponseTypesSupported, "code") { 92 125 return fmt.Errorf("`code` is not in response_types_supported") 93 126 } 94 127 95 - if !tokenInSet("authorization_code", oam.GrantTypesSupported) { 128 + if !slices.Contains(oam.GrantTypesSupported, "authorization_code") { 96 129 return fmt.Errorf("`authorization_code` is not in grant_types_supported") 97 130 } 98 131 99 - if !tokenInSet("refresh_token", oam.GrantTypesSupported) { 132 + if !slices.Contains(oam.GrantTypesSupported, "refresh_token") { 100 133 return fmt.Errorf("`refresh_token` is not in grant_types_supported") 101 134 } 102 135 103 - if !tokenInSet("S256", oam.CodeChallengeMethodsSupported) { 136 + if !slices.Contains(oam.CodeChallengeMethodsSupported, "S256") { 104 137 return fmt.Errorf("`S256` is not in code_challenge_methods_supported") 105 138 } 106 139 107 - if !tokenInSet("none", oam.TokenEndpointAuthMethodsSupported) { 140 + if !slices.Contains(oam.TokenEndpointAuthMethodsSupported, "none") { 108 141 return fmt.Errorf("`none` is not in token_endpoint_auth_methods_supported") 109 142 } 110 143 111 - if !tokenInSet("private_key_jwt", oam.TokenEndpointAuthMethodsSupported) { 144 + if !slices.Contains(oam.TokenEndpointAuthMethodsSupported, "private_key_jwt") { 112 145 return fmt.Errorf("`private_key_jwt` is not in token_endpoint_auth_methods_supported") 113 146 } 114 147 115 - if !tokenInSet("ES256", oam.TokenEndpointAuthSigningAlgValuesSupported) { 148 + if !slices.Contains(oam.TokenEndpointAuthSigningAlgValuesSupported, "ES256") { 116 149 return fmt.Errorf("`ES256` is not in token_endpoint_auth_signing_alg_values_supported") 117 150 } 118 151 119 - if !tokenInSet("atproto", oam.ScopesSupported) { 152 + if !slices.Contains(oam.ScopesSupported, "atproto") { 120 153 return fmt.Errorf("`atproto` is not in scopes_supported") 121 154 } 122 155 ··· 132 165 return fmt.Errorf("require_pushed_authorization_requests is false") 133 166 } 134 167 135 - if !tokenInSet("ES256", oam.DpopSigningAlgValuesSupported) { 168 + if !slices.Contains(oam.DpopSigningAlgValuesSupported, "ES256") { 136 169 return fmt.Errorf("`ES256` is not in dpop_signing_alg_values_supported") 137 170 } 138 171 ··· 146 179 147 180 return nil 148 181 } 149 - 150 - func (oam *OauthAuthorizationMetadata) UnmarshalJSON(b []byte) error { 151 - type Tmp OauthAuthorizationMetadata 152 - var tmp Tmp 153 - 154 - if err := json.Unmarshal(b, &tmp); err != nil { 155 - return err 156 - } 157 - 158 - *oam = OauthAuthorizationMetadata(tmp) 159 - 160 - return nil 161 - }