this repo has no description
1package auth 2 3import ( 4 "context" 5 "fmt" 6 "net/http" 7 "time" 8 9 comatproto "github.com/bluesky-social/indigo/api/atproto" 10 "github.com/bluesky-social/indigo/atproto/identity" 11 "github.com/bluesky-social/indigo/atproto/syntax" 12 "github.com/bluesky-social/indigo/xrpc" 13 "github.com/gorilla/sessions" 14) 15 16type Auth struct { 17 s sessions.Store 18} 19 20func NewAuth(store sessions.Store) *Auth { 21 return &Auth{store} 22} 23 24func ResolveIdent(ctx context.Context, arg string) (*identity.Identity, error) { 25 id, err := syntax.ParseAtIdentifier(arg) 26 if err != nil { 27 return nil, err 28 } 29 30 dir := identity.DefaultDirectory() 31 return dir.Lookup(ctx, *id) 32} 33 34func (a *Auth) AuthorizedClient(r *http.Request) (*xrpc.Client, error) { 35 clientSession, err := a.s.Get(r, "bild-session") 36 37 if err != nil || clientSession.IsNew { 38 return nil, err 39 } 40 41 did := clientSession.Values["did"].(string) 42 pdsUrl := clientSession.Values["pds"].(string) 43 accessJwt := clientSession.Values["accessJwt"].(string) 44 refreshJwt := clientSession.Values["refreshJwt"].(string) 45 46 client := &xrpc.Client{ 47 Host: pdsUrl, 48 Auth: &xrpc.AuthInfo{ 49 AccessJwt: accessJwt, 50 RefreshJwt: refreshJwt, 51 Did: did, 52 }, 53 } 54 55 return client, nil 56} 57 58func (a *Auth) CreateInitialSession(w http.ResponseWriter, r *http.Request, username, appPassword string) (AtSessionCreate, error) { 59 ctx := r.Context() 60 resolved, err := ResolveIdent(ctx, username) 61 if err != nil { 62 return AtSessionCreate{}, fmt.Errorf("invalid handle: %s", err) 63 } 64 65 pdsUrl := resolved.PDSEndpoint() 66 client := xrpc.Client{ 67 Host: pdsUrl, 68 } 69 70 atSession, err := comatproto.ServerCreateSession(ctx, &client, &comatproto.ServerCreateSession_Input{ 71 Identifier: resolved.DID.String(), 72 Password: appPassword, 73 }) 74 if err != nil { 75 return AtSessionCreate{}, fmt.Errorf("invalid app password") 76 } 77 78 return AtSessionCreate{ 79 ServerCreateSession_Output: *atSession, 80 PDSEndpoint: pdsUrl, 81 }, nil 82} 83 84func (a *Auth) StoreSession(r *http.Request, w http.ResponseWriter, atSessionCreate *AtSessionCreate, atSessionRefresh *AtSessionRefresh) error { 85 if atSessionCreate != nil { 86 atSession := atSessionCreate 87 88 clientSession, _ := a.s.Get(r, "bild-session") 89 clientSession.Values["handle"] = atSession.Handle 90 clientSession.Values["did"] = atSession.Did 91 clientSession.Values["accessJwt"] = atSession.AccessJwt 92 clientSession.Values["refreshJwt"] = atSession.RefreshJwt 93 clientSession.Values["expiry"] = time.Now().Add(time.Hour).String() 94 clientSession.Values["pds"] = atSession.PDSEndpoint 95 clientSession.Values["authenticated"] = true 96 97 return clientSession.Save(r, w) 98 } else { 99 atSession := atSessionRefresh 100 101 clientSession, _ := a.s.Get(r, "bild-session") 102 clientSession.Values["handle"] = atSession.Handle 103 clientSession.Values["did"] = atSession.Did 104 clientSession.Values["accessJwt"] = atSession.AccessJwt 105 clientSession.Values["refreshJwt"] = atSession.RefreshJwt 106 clientSession.Values["expiry"] = time.Now().Add(time.Hour).String() 107 clientSession.Values["pds"] = atSession.PDSEndpoint 108 clientSession.Values["authenticated"] = true 109 110 return clientSession.Save(r, w) 111 } 112} 113 114func (a *Auth) GetSessionUser(r *http.Request) (*identity.Identity, error) { 115 session, _ := a.s.Get(r, "bild-session") 116 did, ok := session.Values["did"].(string) 117 if !ok { 118 return nil, fmt.Errorf("user is not authenticated") 119 } 120 121 return ResolveIdent(r.Context(), did) 122}