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 "github.com/sotangled/tangled/appview" 15) 16 17type Auth struct { 18 Store *sessions.CookieStore 19} 20 21type AtSessionCreate struct { 22 comatproto.ServerCreateSession_Output 23 PDSEndpoint string 24} 25 26type AtSessionRefresh struct { 27 comatproto.ServerRefreshSession_Output 28 PDSEndpoint string 29} 30 31func Make() (*Auth, error) { 32 store := sessions.NewCookieStore([]byte(appview.SessionCookieSecret)) 33 return &Auth{store}, nil 34} 35 36func ResolveIdent(ctx context.Context, arg string) (*identity.Identity, error) { 37 id, err := syntax.ParseAtIdentifier(arg) 38 if err != nil { 39 return nil, err 40 } 41 42 dir := identity.DefaultDirectory() 43 return dir.Lookup(ctx, *id) 44} 45 46func (a *Auth) CreateInitialSession(ctx context.Context, resolved *identity.Identity, appPassword string) (*comatproto.ServerCreateSession_Output, error) { 47 48 pdsUrl := resolved.PDSEndpoint() 49 client := xrpc.Client{ 50 Host: pdsUrl, 51 } 52 53 atSession, err := comatproto.ServerCreateSession(ctx, &client, &comatproto.ServerCreateSession_Input{ 54 Identifier: resolved.DID.String(), 55 Password: appPassword, 56 }) 57 if err != nil { 58 return nil, fmt.Errorf("invalid app password") 59 } 60 61 return atSession, nil 62} 63 64// Sessionish is an interface that provides access to the common fields of both types. 65type Sessionish interface { 66 GetAccessJwt() string 67 GetActive() *bool 68 GetDid() string 69 GetDidDoc() *interface{} 70 GetHandle() string 71 GetRefreshJwt() string 72 GetStatus() *string 73} 74 75// Create a wrapper type for ServerRefreshSession_Output 76type RefreshSessionWrapper struct { 77 *comatproto.ServerRefreshSession_Output 78} 79 80func (s *RefreshSessionWrapper) GetAccessJwt() string { 81 return s.AccessJwt 82} 83 84func (s *RefreshSessionWrapper) GetActive() *bool { 85 return s.Active 86} 87 88func (s *RefreshSessionWrapper) GetDid() string { 89 return s.Did 90} 91 92func (s *RefreshSessionWrapper) GetDidDoc() *interface{} { 93 return s.DidDoc 94} 95 96func (s *RefreshSessionWrapper) GetHandle() string { 97 return s.Handle 98} 99 100func (s *RefreshSessionWrapper) GetRefreshJwt() string { 101 return s.RefreshJwt 102} 103 104func (s *RefreshSessionWrapper) GetStatus() *string { 105 return s.Status 106} 107 108// Create a wrapper type for ServerRefreshSession_Output 109type CreateSessionWrapper struct { 110 *comatproto.ServerCreateSession_Output 111} 112 113func (s *CreateSessionWrapper) GetAccessJwt() string { 114 return s.AccessJwt 115} 116 117func (s *CreateSessionWrapper) GetActive() *bool { 118 return s.Active 119} 120 121func (s *CreateSessionWrapper) GetDid() string { 122 return s.Did 123} 124 125func (s *CreateSessionWrapper) GetDidDoc() *interface{} { 126 return s.DidDoc 127} 128 129func (s *CreateSessionWrapper) GetHandle() string { 130 return s.Handle 131} 132 133func (s *CreateSessionWrapper) GetRefreshJwt() string { 134 return s.RefreshJwt 135} 136 137func (s *CreateSessionWrapper) GetStatus() *string { 138 return s.Status 139} 140 141func (a *Auth) StoreSession(r *http.Request, w http.ResponseWriter, atSessionish Sessionish, pdsEndpoint string) error { 142 clientSession, _ := a.Store.Get(r, appview.SessionName) 143 clientSession.Values[appview.SessionHandle] = atSessionish.GetHandle() 144 clientSession.Values[appview.SessionDid] = atSessionish.GetDid() 145 clientSession.Values[appview.SessionPds] = pdsEndpoint 146 clientSession.Values[appview.SessionAccessJwt] = atSessionish.GetAccessJwt() 147 clientSession.Values[appview.SessionRefreshJwt] = atSessionish.GetRefreshJwt() 148 clientSession.Values[appview.SessionExpiry] = time.Now().Add(time.Hour).Format(appview.TimeLayout) 149 clientSession.Values[appview.SessionAuthenticated] = true 150 return clientSession.Save(r, w) 151} 152 153func (a *Auth) AuthorizedClient(r *http.Request) (*xrpc.Client, error) { 154 clientSession, err := a.Store.Get(r, "appview-session") 155 156 if err != nil || clientSession.IsNew { 157 return nil, err 158 } 159 160 did := clientSession.Values["did"].(string) 161 pdsUrl := clientSession.Values["pds"].(string) 162 accessJwt := clientSession.Values["accessJwt"].(string) 163 refreshJwt := clientSession.Values["refreshJwt"].(string) 164 165 client := &xrpc.Client{ 166 Host: pdsUrl, 167 Auth: &xrpc.AuthInfo{ 168 AccessJwt: accessJwt, 169 RefreshJwt: refreshJwt, 170 Did: did, 171 }, 172 } 173 174 return client, nil 175} 176 177func (a *Auth) GetSession(r *http.Request) (*sessions.Session, error) { 178 return a.Store.Get(r, appview.SessionName) 179} 180 181func (a *Auth) GetDID(r *http.Request) string { 182 clientSession, err := a.Store.Get(r, appview.SessionName) 183 if err != nil || clientSession.IsNew { 184 return "" 185 } 186 187 return clientSession.Values[appview.SessionDid].(string) 188} 189 190func (a *Auth) GetHandle(r *http.Request) string { 191 clientSession, err := a.Store.Get(r, appview.SessionName) 192 if err != nil || clientSession.IsNew { 193 return "" 194 } 195 196 return clientSession.Values[appview.SessionHandle].(string) 197} 198 199type User struct { 200 Handle string 201 Did string 202 Pds string 203} 204 205func (a *Auth) GetUser(r *http.Request) *User { 206 clientSession, err := a.Store.Get(r, appview.SessionName) 207 208 if err != nil || clientSession.IsNew { 209 return nil 210 } 211 212 return &User{ 213 Handle: clientSession.Values[appview.SessionHandle].(string), 214 Did: clientSession.Values[appview.SessionDid].(string), 215 Pds: clientSession.Values[appview.SessionPds].(string), 216 } 217}