An atproto PDS written in Go
1package provider 2 3import ( 4 "database/sql/driver" 5 "encoding/json" 6 "fmt" 7 "time" 8 9 "github.com/haileyok/cocoon/oauth/client_manager" 10 "github.com/haileyok/cocoon/oauth/dpop/dpop_manager" 11 "gorm.io/gorm" 12) 13 14type Provider struct { 15 ClientManager *client_manager.ClientManager 16 DpopManager *dpop_manager.DpopManager 17 18 hostname string 19} 20 21type Args struct { 22 Hostname string 23 ClientManagerArgs client_manager.Args 24 DpopManagerArgs dpop_manager.Args 25} 26 27func NewProvider(args Args) *Provider { 28 return &Provider{ 29 ClientManager: client_manager.New(args.ClientManagerArgs), 30 DpopManager: dpop_manager.New(args.DpopManagerArgs), 31 hostname: args.Hostname, 32 } 33} 34 35func (p *Provider) NextNonce() string { 36 return p.DpopManager.NextNonce() 37} 38 39type ParRequest struct { 40 AuthenticateClientRequestBase 41 ResponseType string `form:"response_type" json:"response_type" validate:"required"` 42 CodeChallenge *string `form:"code_challenge" json:"code_challenge" validate:"required"` 43 CodeChallengeMethod string `form:"code_challenge_method" json:"code_challenge_method" validate:"required"` 44 State string `form:"state" json:"state" validate:"required"` 45 RedirectURI string `form:"redirect_uri" json:"redirect_uri" validate:"required"` 46 Scope string `form:"scope" json:"scope" validate:"required"` 47 LoginHint *string `form:"login_hint" json:"login_hint,omitempty"` 48 DpopJkt *string `form:"dpop_jkt" json:"dpop_jkt,omitempty"` 49} 50 51func (opr *ParRequest) Scan(value any) error { 52 b, ok := value.([]byte) 53 if !ok { 54 return fmt.Errorf("failed to unmarshal OauthParRequest value") 55 } 56 return json.Unmarshal(b, opr) 57} 58 59func (opr ParRequest) Value() (driver.Value, error) { 60 return json.Marshal(opr) 61} 62 63type OauthToken struct { 64 gorm.Model 65 ClientId string `gorm:"index"` 66 ClientAuth ClientAuth `gorm:"type:json"` 67 Parameters ParRequest `gorm:"type:json"` 68 ExpiresAt time.Time `gorm:"index"` 69 DeviceId string 70 Sub string `gorm:"index"` 71 Code string `gorm:"index"` 72 Token string `gorm:"uniqueIndex"` 73 RefreshToken string `gorm:"uniqueIndex"` 74} 75 76type OauthAuthorizationRequest struct { 77 gorm.Model 78 RequestId string `gorm:"primaryKey"` 79 ClientId string `gorm:"index"` 80 ClientAuth ClientAuth `gorm:"type:json"` 81 Parameters ParRequest `gorm:"type:json"` 82 ExpiresAt time.Time `gorm:"index"` 83 DeviceId *string 84 Sub *string 85 Code *string 86 Accepted *bool 87}