this repo has no description
1package auth 2 3import ( 4 "context" 5 "encoding/json" 6 "fmt" 7 "net/http" 8 "time" 9 10 comatproto "github.com/bluesky-social/indigo/api/atproto" 11 "github.com/bluesky-social/indigo/atproto/identity" 12 "github.com/bluesky-social/indigo/atproto/syntax" 13 "github.com/bluesky-social/indigo/xrpc" 14 "github.com/gorilla/sessions" 15 "github.com/icyphox/bild/appview" 16) 17 18type Auth struct { 19 Store *sessions.CookieStore 20} 21 22type AtSessionCreate struct { 23 comatproto.ServerCreateSession_Output 24 PDSEndpoint string 25} 26 27type AtSessionRefresh struct { 28 comatproto.ServerRefreshSession_Output 29 PDSEndpoint string 30} 31 32func Make() (*Auth, error) { 33 store := sessions.NewCookieStore([]byte(appview.SESSION_COOKIE_SECRET)) 34 return &Auth{store}, nil 35} 36 37func ResolveIdent(ctx context.Context, arg string) (*identity.Identity, error) { 38 id, err := syntax.ParseAtIdentifier(arg) 39 if err != nil { 40 return nil, err 41 } 42 43 dir := identity.DefaultDirectory() 44 return dir.Lookup(ctx, *id) 45} 46 47func (a *Auth) CreateInitialSession(ctx context.Context, username, appPassword string) (*comatproto.ServerCreateSession_Output, error) { 48 resolved, err := ResolveIdent(ctx, username) 49 if err != nil { 50 return nil, fmt.Errorf("invalid handle: %s", err) 51 } 52 53 pdsUrl := resolved.PDSEndpoint() 54 client := xrpc.Client{ 55 Host: pdsUrl, 56 } 57 58 atSession, err := comatproto.ServerCreateSession(ctx, &client, &comatproto.ServerCreateSession_Input{ 59 Identifier: resolved.DID.String(), 60 Password: appPassword, 61 }) 62 if err != nil { 63 return nil, fmt.Errorf("invalid app password") 64 } 65 66 return atSession, nil 67} 68 69// Sessionish is an interface that provides access to the common fields of both types. 70type Sessionish interface { 71 GetAccessJwt() string 72 GetActive() *bool 73 GetDid() string 74 GetDidDoc() *interface{} 75 GetHandle() string 76 GetRefreshJwt() string 77 GetStatus() *string 78} 79 80// Create a wrapper type for ServerRefreshSession_Output 81type RefreshSessionWrapper struct { 82 *comatproto.ServerRefreshSession_Output 83} 84 85func (s *RefreshSessionWrapper) GetAccessJwt() string { 86 return s.AccessJwt 87} 88 89func (s *RefreshSessionWrapper) GetActive() *bool { 90 return s.Active 91} 92 93func (s *RefreshSessionWrapper) GetDid() string { 94 return s.Did 95} 96 97func (s *RefreshSessionWrapper) GetDidDoc() *interface{} { 98 return s.DidDoc 99} 100 101func (s *RefreshSessionWrapper) GetHandle() string { 102 return s.Handle 103} 104 105func (s *RefreshSessionWrapper) GetRefreshJwt() string { 106 return s.RefreshJwt 107} 108 109func (s *RefreshSessionWrapper) GetStatus() *string { 110 return s.Status 111} 112 113// Create a wrapper type for ServerRefreshSession_Output 114type CreateSessionWrapper struct { 115 *comatproto.ServerCreateSession_Output 116} 117 118func (s *CreateSessionWrapper) GetAccessJwt() string { 119 return s.AccessJwt 120} 121 122func (s *CreateSessionWrapper) GetActive() *bool { 123 return s.Active 124} 125 126func (s *CreateSessionWrapper) GetDid() string { 127 return s.Did 128} 129 130func (s *CreateSessionWrapper) GetDidDoc() *interface{} { 131 return s.DidDoc 132} 133 134func (s *CreateSessionWrapper) GetHandle() string { 135 return s.Handle 136} 137 138func (s *CreateSessionWrapper) GetRefreshJwt() string { 139 return s.RefreshJwt 140} 141 142func (s *CreateSessionWrapper) GetStatus() *string { 143 return s.Status 144} 145 146func (a *Auth) StoreSession(r *http.Request, w http.ResponseWriter, atSessionish Sessionish) error { 147 var didDoc identity.DIDDocument 148 149 bytes, _ := json.Marshal(atSessionish.GetDidDoc()) 150 err := json.Unmarshal(bytes, &didDoc) 151 if err != nil { 152 return fmt.Errorf("invalid did document for session") 153 } 154 155 identity := identity.ParseIdentity(&didDoc) 156 pdsEndpoint := identity.PDSEndpoint() 157 158 if pdsEndpoint == "" { 159 return fmt.Errorf("no pds endpoint found") 160 } 161 162 clientSession, _ := a.Store.Get(r, appview.SESSION_NAME) 163 clientSession.Values[appview.SESSION_HANDLE] = atSessionish.GetHandle() 164 clientSession.Values[appview.SESSION_DID] = atSessionish.GetDid() 165 clientSession.Values[appview.SESSION_PDS] = pdsEndpoint 166 clientSession.Values[appview.SESSION_ACCESSJWT] = atSessionish.GetAccessJwt() 167 clientSession.Values[appview.SESSION_REFRESHJWT] = atSessionish.GetRefreshJwt() 168 clientSession.Values[appview.SESSION_EXPIRY] = time.Now().Add(time.Hour).Format(appview.TIME_LAYOUT) 169 clientSession.Values[appview.SESSION_AUTHENTICATED] = true 170 171 return clientSession.Save(r, w) 172}