An atproto PDS written in Go
at v0.5.1 5.9 kB view raw
1package server 2 3import ( 4 "fmt" 5 6 "github.com/Azure/go-autorest/autorest/to" 7 "github.com/labstack/echo/v4" 8) 9 10var ( 11 CocoonSupportedScopes = []string{ 12 "atproto", 13 "transition:email", 14 "transition:generic", 15 "transition:chat.bsky", 16 } 17) 18 19type OauthAuthorizationMetadata struct { 20 Issuer string `json:"issuer"` 21 RequestParameterSupported bool `json:"request_parameter_supported"` 22 RequestUriParameterSupported bool `json:"request_uri_parameter_supported"` 23 RequireRequestUriRegistration *bool `json:"require_request_uri_registration,omitempty"` 24 ScopesSupported []string `json:"scopes_supported"` 25 SubjectTypesSupported []string `json:"subject_types_supported"` 26 ResponseTypesSupported []string `json:"response_types_supported"` 27 ResponseModesSupported []string `json:"response_modes_supported"` 28 GrantTypesSupported []string `json:"grant_types_supported"` 29 CodeChallengeMethodsSupported []string `json:"code_challenge_methods_supported"` 30 UILocalesSupported []string `json:"ui_locales_supported"` 31 DisplayValuesSupported []string `json:"display_values_supported"` 32 RequestObjectSigningAlgValuesSupported []string `json:"request_object_signing_alg_values_supported"` 33 AuthorizationResponseISSParameterSupported bool `json:"authorization_response_iss_parameter_supported"` 34 RequestObjectEncryptionAlgValuesSupported []string `json:"request_object_encryption_alg_values_supported"` 35 RequestObjectEncryptionEncValuesSupported []string `json:"request_object_encryption_enc_values_supported"` 36 JwksUri string `json:"jwks_uri"` 37 AuthorizationEndpoint string `json:"authorization_endpoint"` 38 TokenEndpoint string `json:"token_endpoint"` 39 TokenEndpointAuthMethodsSupported []string `json:"token_endpoint_auth_methods_supported"` 40 TokenEndpointAuthSigningAlgValuesSupported []string `json:"token_endpoint_auth_signing_alg_values_supported"` 41 RevocationEndpoint string `json:"revocation_endpoint"` 42 IntrospectionEndpoint string `json:"introspection_endpoint"` 43 PushedAuthorizationRequestEndpoint string `json:"pushed_authorization_request_endpoint"` 44 RequirePushedAuthorizationRequests bool `json:"require_pushed_authorization_requests"` 45 DpopSigningAlgValuesSupported []string `json:"dpop_signing_alg_values_supported"` 46 ProtectedResources []string `json:"protected_resources"` 47 ClientIDMetadataDocumentSupported bool `json:"client_id_metadata_document_supported"` 48} 49 50func (s *Server) handleWellKnown(e echo.Context) error { 51 return e.JSON(200, map[string]any{ 52 "@context": []string{ 53 "https://www.w3.org/ns/did/v1", 54 }, 55 "id": s.config.Did, 56 "service": []map[string]string{ 57 { 58 "id": "#atproto_pds", 59 "type": "AtprotoPersonalDataServer", 60 "serviceEndpoint": "https://" + s.config.Hostname, 61 }, 62 }, 63 }) 64} 65 66func (s *Server) handleOauthProtectedResource(e echo.Context) error { 67 return e.JSON(200, map[string]any{ 68 "resource": "https://" + s.config.Hostname, 69 "authorization_servers": []string{ 70 "https://" + s.config.Hostname, 71 }, 72 "scopes_supported": []string{}, 73 "bearer_methods_supported": []string{"header"}, 74 "resource_documentation": "https://atproto.com", 75 }) 76} 77 78func (s *Server) handleOauthAuthorizationServer(e echo.Context) error { 79 return e.JSON(200, OauthAuthorizationMetadata{ 80 Issuer: "https://" + s.config.Hostname, 81 RequestParameterSupported: true, 82 RequestUriParameterSupported: true, 83 RequireRequestUriRegistration: to.BoolPtr(true), 84 ScopesSupported: CocoonSupportedScopes, 85 SubjectTypesSupported: []string{"public"}, 86 ResponseTypesSupported: []string{"code"}, 87 ResponseModesSupported: []string{"query", "fragment", "form_post"}, 88 GrantTypesSupported: []string{"authorization_code", "refresh_token"}, 89 CodeChallengeMethodsSupported: []string{"S256"}, 90 UILocalesSupported: []string{"en-US"}, 91 DisplayValuesSupported: []string{"page", "popup", "touch"}, 92 RequestObjectSigningAlgValuesSupported: []string{"ES256"}, // only es256 for now... 93 AuthorizationResponseISSParameterSupported: true, 94 RequestObjectEncryptionAlgValuesSupported: []string{}, 95 RequestObjectEncryptionEncValuesSupported: []string{}, 96 JwksUri: fmt.Sprintf("https://%s/oauth/jwks", s.config.Hostname), 97 AuthorizationEndpoint: fmt.Sprintf("https://%s/oauth/authorize", s.config.Hostname), 98 TokenEndpoint: fmt.Sprintf("https://%s/oauth/token", s.config.Hostname), 99 TokenEndpointAuthMethodsSupported: []string{"none", "private_key_jwt"}, 100 TokenEndpointAuthSigningAlgValuesSupported: []string{"ES256"}, // Same as above, just es256 101 RevocationEndpoint: fmt.Sprintf("https://%s/oauth/revoke", s.config.Hostname), 102 IntrospectionEndpoint: fmt.Sprintf("https://%s/oauth/introspect", s.config.Hostname), 103 PushedAuthorizationRequestEndpoint: fmt.Sprintf("https://%s/oauth/par", s.config.Hostname), 104 RequirePushedAuthorizationRequests: true, 105 DpopSigningAlgValuesSupported: []string{"ES256"}, // again same as above 106 ProtectedResources: []string{"https://" + s.config.Hostname}, 107 ClientIDMetadataDocumentSupported: true, 108 }) 109}